aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitattributes1
-rw-r--r--.gitignore126
-rw-r--r--.travis.yml72
-rw-r--r--.tx/config7
-rw-r--r--COPYING19
-rw-r--r--INSTALL5
-rw-r--r--Makefile.am214
-rw-r--r--README.md173
-rwxr-xr-xautogen.sh9
-rw-r--r--build-aux/m4/ax_boost_base.m4281
-rw-r--r--build-aux/m4/ax_boost_chrono.m4119
-rw-r--r--build-aux/m4/ax_boost_filesystem.m4119
-rw-r--r--build-aux/m4/ax_boost_program_options.m4109
-rw-r--r--build-aux/m4/ax_boost_system.m4121
-rw-r--r--build-aux/m4/ax_boost_thread.m4150
-rw-r--r--build-aux/m4/ax_boost_unit_test_framework.m4138
-rw-r--r--build-aux/m4/ax_check_compile_flag.m472
-rw-r--r--build-aux/m4/ax_check_link_flag.m471
-rw-r--r--build-aux/m4/ax_check_preproc_flag.m472
-rw-r--r--build-aux/m4/ax_gcc_func_attribute.m4217
-rw-r--r--build-aux/m4/ax_pthread.m4332
-rw-r--r--build-aux/m4/bitcoin_find_bdb48.m466
-rw-r--r--build-aux/m4/bitcoin_qt.m4433
-rw-r--r--build-aux/m4/bitcoin_subdir_to_include.m414
-rw-r--r--configure.ac927
-rw-r--r--contrib/README.md59
-rw-r--r--contrib/bitcoin-qt.pro21
-rw-r--r--contrib/bitcoind.bash-completion145
-rw-r--r--contrib/bitrpc/README.md8
-rw-r--r--contrib/bitrpc/bitrpc.py335
-rw-r--r--contrib/debian/README.md21
-rw-r--r--contrib/debian/bitcoin-qt.desktop12
-rw-r--r--contrib/debian/bitcoin-qt.install6
-rw-r--r--contrib/debian/bitcoin-qt.lintian-overrides2
-rw-r--r--contrib/debian/bitcoin-qt.protocol11
-rw-r--r--contrib/debian/bitcoind.bash-completion1
-rw-r--r--contrib/debian/bitcoind.examples1
-rw-r--r--contrib/debian/bitcoind.install2
-rw-r--r--contrib/debian/bitcoind.lintian-overrides2
-rw-r--r--contrib/debian/bitcoind.manpages3
-rw-r--r--contrib/debian/changelog429
-rw-r--r--contrib/debian/compat1
-rw-r--r--contrib/debian/control58
-rw-r--r--contrib/debian/copyright161
-rw-r--r--contrib/debian/examples/bitcoin.conf133
-rw-r--r--contrib/debian/gbp.conf5
-rw-r--r--contrib/debian/manpages/bitcoin-cli.148
-rw-r--r--contrib/debian/manpages/bitcoin-qt.1203
-rw-r--r--contrib/debian/manpages/bitcoin.conf.589
-rw-r--r--contrib/debian/manpages/bitcoind.1209
-rw-r--r--contrib/debian/patches/README3
-rw-r--r--contrib/debian/patches/series1
-rwxr-xr-xcontrib/debian/rules24
-rw-r--r--contrib/debian/source/format1
-rw-r--r--contrib/debian/watch7
-rw-r--r--contrib/devtools/README.md96
-rwxr-xr-xcontrib/devtools/fix-copyright-headers.py53
-rwxr-xr-xcontrib/devtools/git-subtree-check.sh74
-rwxr-xr-xcontrib/devtools/github-merge.sh181
-rwxr-xr-xcontrib/devtools/optimize-pngs.py73
-rwxr-xr-xcontrib/devtools/symbol-check.py119
-rwxr-xr-xcontrib/devtools/update-translations.py186
-rw-r--r--contrib/gitian-descriptors/README.md66
-rw-r--r--contrib/gitian-descriptors/gitian-linux.yml118
-rw-r--r--contrib/gitian-descriptors/gitian-osx-signer.yml38
-rw-r--r--contrib/gitian-descriptors/gitian-osx.yml134
-rw-r--r--contrib/gitian-descriptors/gitian-win-signer.yml39
-rw-r--r--contrib/gitian-descriptors/gitian-win.yml118
-rw-r--r--contrib/gitian-downloader/aschildbach-key.pgpbin0 -> 1993 bytes
-rw-r--r--contrib/gitian-downloader/bluematt-key.pgpbin0 -> 4113 bytes
-rw-r--r--contrib/gitian-downloader/cfields-key.pgp52
-rw-r--r--contrib/gitian-downloader/devrandom-key.pgpbin0 -> 2213 bytes
-rw-r--r--contrib/gitian-downloader/fanquake-key.pgp63
-rw-r--r--contrib/gitian-downloader/gavinandresen-key.pgpbin0 -> 1176 bytes
-rw-r--r--contrib/gitian-downloader/jonasschnelli-key.pgpbin0 -> 2230 bytes
-rw-r--r--contrib/gitian-downloader/laanwj-key.pgp28
-rw-r--r--contrib/gitian-downloader/linux-download-config42
-rw-r--r--contrib/gitian-downloader/luke-jr-key.pgpbin0 -> 6518 bytes
-rw-r--r--contrib/gitian-downloader/michagogo-key.pgp59
-rw-r--r--contrib/gitian-downloader/sipa-key.pgpbin0 -> 109468 bytes
-rw-r--r--contrib/gitian-downloader/tcatm-key.pgpbin0 -> 1554 bytes
-rw-r--r--contrib/gitian-downloader/win32-download-config42
-rw-r--r--contrib/gitian-downloader/wtogami-key.pgp131
-rw-r--r--contrib/init/README.md11
-rw-r--r--contrib/init/bitcoind.conf65
-rw-r--r--contrib/init/bitcoind.init67
-rw-r--r--contrib/init/bitcoind.openrc88
-rw-r--r--contrib/init/bitcoind.openrcconf27
-rw-r--r--contrib/init/bitcoind.service22
-rw-r--r--contrib/linearize/README.md33
-rw-r--r--contrib/linearize/example-linearize.cfg29
-rwxr-xr-xcontrib/linearize/linearize-data.py301
-rwxr-xr-xcontrib/linearize/linearize-hashes.py113
-rw-r--r--contrib/macdeploy/Base.lproj/InfoPlist.strings1
-rw-r--r--contrib/macdeploy/DS_Storebin0 -> 10244 bytes
-rw-r--r--contrib/macdeploy/LICENSE674
-rw-r--r--contrib/macdeploy/README.md15
-rw-r--r--contrib/macdeploy/background.pngbin0 -> 48690 bytes
-rw-r--r--contrib/macdeploy/background.psdbin0 -> 982442 bytes
-rw-r--r--contrib/macdeploy/background.tiffbin0 -> 202136 bytes
-rw-r--r--contrib/macdeploy/background@2x.pngbin0 -> 138890 bytes
-rwxr-xr-xcontrib/macdeploy/detached-sig-apply.sh52
-rwxr-xr-xcontrib/macdeploy/detached-sig-create.sh47
-rw-r--r--contrib/macdeploy/fancy.plist32
-rwxr-xr-xcontrib/macdeploy/macdeployqtplus883
-rw-r--r--contrib/qos/README.md5
-rw-r--r--contrib/qos/tc.sh41
-rwxr-xr-xcontrib/qt_translations.py22
-rw-r--r--contrib/seeds/README.md8
-rwxr-xr-xcontrib/seeds/generate-seeds.py138
-rwxr-xr-xcontrib/seeds/makeseeds.py169
-rw-r--r--contrib/seeds/nodes_main.txt879
-rw-r--r--contrib/seeds/nodes_test.txt11
-rw-r--r--contrib/spendfrom/README.md35
-rw-r--r--contrib/spendfrom/setup.py9
-rwxr-xr-xcontrib/spendfrom/spendfrom.py267
-rw-r--r--contrib/test-patches/README.md7
-rw-r--r--contrib/test-patches/temp-revert-2.patch20
-rw-r--r--contrib/testgen/README.md8
-rw-r--r--contrib/testgen/base58.py104
-rwxr-xr-xcontrib/testgen/gen_base58_test_vectors.py126
-rwxr-xr-xcontrib/tidy_datadir.sh59
-rwxr-xr-xcontrib/verify-commits/gpg.sh15
-rwxr-xr-xcontrib/verify-commits/pre-push-hook.sh16
-rw-r--r--contrib/verify-commits/trusted-git-root1
-rw-r--r--contrib/verify-commits/trusted-keys5
-rwxr-xr-xcontrib/verify-commits/verify-commits.sh51
-rw-r--r--contrib/verifysfbinaries/README.md6
-rwxr-xr-xcontrib/verifysfbinaries/verify.sh119
-rw-r--r--depends/.gitignore9
-rw-r--r--depends/Makefile161
-rw-r--r--depends/README.md56
-rw-r--r--depends/builders/darwin.mk22
-rw-r--r--depends/builders/default.mk20
-rw-r--r--depends/builders/linux.mk2
-rwxr-xr-xdepends/config.guess1438
-rw-r--r--depends/config.site.in100
-rwxr-xr-xdepends/config.sub1810
-rw-r--r--depends/description.md53
-rw-r--r--depends/funcs.mk241
-rw-r--r--depends/hosts/darwin.mk17
-rw-r--r--depends/hosts/default.mk26
-rw-r--r--depends/hosts/linux.mk31
-rw-r--r--depends/hosts/mingw32.mk10
-rw-r--r--depends/packages.md147
-rw-r--r--depends/packages/bdb.mk28
-rw-r--r--depends/packages/boost.mk45
-rw-r--r--depends/packages/dbus.mk23
-rw-r--r--depends/packages/expat.mk21
-rw-r--r--depends/packages/fontconfig.mk22
-rw-r--r--depends/packages/freetype.mk22
-rw-r--r--depends/packages/libICE.mk23
-rw-r--r--depends/packages/libSM.mk23
-rw-r--r--depends/packages/libX11.mk23
-rw-r--r--depends/packages/libXau.mk23
-rw-r--r--depends/packages/libXext.mk22
-rw-r--r--depends/packages/libxcb.mk35
-rw-r--r--depends/packages/miniupnpc.mk28
-rw-r--r--depends/packages/native_ccache.mk25
-rw-r--r--depends/packages/native_cctools.mk58
-rw-r--r--depends/packages/native_cdrkit.mk26
-rw-r--r--depends/packages/native_comparisontool.mk21
-rw-r--r--depends/packages/native_libdmg-hfsplus.mk22
-rw-r--r--depends/packages/native_protobuf.mk25
-rw-r--r--depends/packages/openssl.mk44
-rw-r--r--depends/packages/packages.mk18
-rw-r--r--depends/packages/protobuf.mk28
-rw-r--r--depends/packages/qrencode.mk22
-rw-r--r--depends/packages/qt.mk174
-rw-r--r--depends/packages/qt46.mk66
-rw-r--r--depends/packages/xcb_proto.mk27
-rw-r--r--depends/packages/xextproto.mk21
-rw-r--r--depends/packages/xproto.mk21
-rw-r--r--depends/packages/xtrans.mk22
-rw-r--r--depends/patches/boost/darwin_boost_atomic-1.patch35
-rw-r--r--depends/patches/boost/darwin_boost_atomic-2.patch55
-rw-r--r--depends/patches/boost/gcc_5_no_cxx11.patch37
-rw-r--r--depends/patches/native_cdrkit/cdrkit-deterministic.patch86
-rw-r--r--depends/patches/qt/fix-xcb-include-order.patch45
-rw-r--r--depends/patches/qt/mac-qmake.conf26
-rw-r--r--depends/patches/qt/mingw-uuidof.patch44
-rw-r--r--depends/patches/qt46/stlfix.patch10
-rw-r--r--doc/Doxyfile1752
-rw-r--r--doc/README.md78
-rw-r--r--doc/README_osx.txt83
-rw-r--r--doc/README_windows.txt23
-rw-r--r--doc/REST-interface.md81
-rw-r--r--doc/assets-attribution.md46
-rw-r--r--doc/bips.md18
-rw-r--r--doc/bitcoin_logo_doxygen.pngbin0 -> 3272 bytes
-rw-r--r--doc/build-osx.md117
-rw-r--r--doc/build-unix.md230
-rw-r--r--doc/developer-notes.md186
-rw-r--r--doc/dnsseed-policy.md54
-rw-r--r--doc/files.md27
-rw-r--r--doc/gitian-building.md396
-rw-r--r--doc/gitian-building/create_vm_file_location_size.pngbin0 -> 71743 bytes
-rw-r--r--doc/gitian-building/create_vm_hard_drive.pngbin0 -> 79798 bytes
-rw-r--r--doc/gitian-building/create_vm_hard_drive_file_type.pngbin0 -> 82281 bytes
-rw-r--r--doc/gitian-building/create_vm_memsize.pngbin0 -> 53772 bytes
-rw-r--r--doc/gitian-building/create_vm_page1.pngbin0 -> 131585 bytes
-rw-r--r--doc/gitian-building/create_vm_storage_physical_hard_drive.pngbin0 -> 90350 bytes
-rw-r--r--doc/gitian-building/debian_install_10_configure_clock.pngbin0 -> 7892 bytes
-rw-r--r--doc/gitian-building/debian_install_11_partition_disks.pngbin0 -> 9511 bytes
-rw-r--r--doc/gitian-building/debian_install_12_choose_disk.pngbin0 -> 6613 bytes
-rw-r--r--doc/gitian-building/debian_install_13_partition_scheme.pngbin0 -> 8082 bytes
-rw-r--r--doc/gitian-building/debian_install_14_finish.pngbin0 -> 10467 bytes
-rw-r--r--doc/gitian-building/debian_install_15_write_changes.pngbin0 -> 8790 bytes
-rw-r--r--doc/gitian-building/debian_install_16_choose_a_mirror.pngbin0 -> 11340 bytes
-rw-r--r--doc/gitian-building/debian_install_17_choose_a_mirror2.pngbin0 -> 9788 bytes
-rw-r--r--doc/gitian-building/debian_install_18_proxy_settings.pngbin0 -> 7582 bytes
-rw-r--r--doc/gitian-building/debian_install_19_software_selection.pngbin0 -> 8939 bytes
-rw-r--r--doc/gitian-building/debian_install_1_boot_menu.pngbin0 -> 76176 bytes
-rw-r--r--doc/gitian-building/debian_install_20_install_grub.pngbin0 -> 9784 bytes
-rw-r--r--doc/gitian-building/debian_install_21_finish_installation.pngbin0 -> 6964 bytes
-rw-r--r--doc/gitian-building/debian_install_2_select_a_language.pngbin0 -> 13118 bytes
-rw-r--r--doc/gitian-building/debian_install_3_select_location.pngbin0 -> 9613 bytes
-rw-r--r--doc/gitian-building/debian_install_4_configure_keyboard.pngbin0 -> 10220 bytes
-rw-r--r--doc/gitian-building/debian_install_5_configure_the_network.pngbin0 -> 6774 bytes
-rw-r--r--doc/gitian-building/debian_install_6_domain_name.pngbin0 -> 6526 bytes
-rw-r--r--doc/gitian-building/debian_install_6a_set_up_root_password.pngbin0 -> 11876 bytes
-rw-r--r--doc/gitian-building/debian_install_7_set_up_user_fullname.pngbin0 -> 7528 bytes
-rw-r--r--doc/gitian-building/debian_install_8_set_up_username.pngbin0 -> 6304 bytes
-rw-r--r--doc/gitian-building/debian_install_9_user_password.pngbin0 -> 6323 bytes
-rw-r--r--doc/gitian-building/network_settings.pngbin0 -> 59986 bytes
-rw-r--r--doc/gitian-building/port_forwarding_rules.pngbin0 -> 14044 bytes
-rw-r--r--doc/gitian-building/select_startup_disk.pngbin0 -> 86323 bytes
-rw-r--r--doc/init.md102
-rw-r--r--doc/multiwallet-qt.md48
-rw-r--r--doc/release-notes.md172
-rw-r--r--doc/release-notes/release-notes-0.10.0.md762
-rw-r--r--doc/release-notes/release-notes-0.10.1.md143
-rw-r--r--doc/release-notes/release-notes-0.10.2.md86
-rw-r--r--doc/release-notes/release-notes-0.10.3.md165
-rw-r--r--doc/release-notes/release-notes-0.11.1.md172
-rw-r--r--doc/release-notes/release-notes-0.3.12.md13
-rw-r--r--doc/release-notes/release-notes-0.3.13.md26
-rw-r--r--doc/release-notes/release-notes-0.3.14.md11
-rw-r--r--doc/release-notes/release-notes-0.3.15.md6
-rw-r--r--doc/release-notes/release-notes-0.3.16.md1
-rw-r--r--doc/release-notes/release-notes-0.3.17.md12
-rw-r--r--doc/release-notes/release-notes-0.3.18.md11
-rw-r--r--doc/release-notes/release-notes-0.3.19.md9
-rw-r--r--doc/release-notes/release-notes-0.3.20.1.md1
-rw-r--r--doc/release-notes/release-notes-0.3.20.2.md17
-rw-r--r--doc/release-notes/release-notes-0.3.20.md22
-rw-r--r--doc/release-notes/release-notes-0.3.21.md20
-rw-r--r--doc/release-notes/release-notes-0.3.22.md16
-rw-r--r--doc/release-notes/release-notes-0.3.23.md10
-rw-r--r--doc/release-notes/release-notes-0.3.24.md20
-rw-r--r--doc/release-notes/release-notes-0.4.0.md70
-rw-r--r--doc/release-notes/release-notes-0.4.1.md38
-rw-r--r--doc/release-notes/release-notes-0.4.2.md1
-rw-r--r--doc/release-notes/release-notes-0.4.3.md21
-rw-r--r--doc/release-notes/release-notes-0.4.4.md30
-rw-r--r--doc/release-notes/release-notes-0.4.5.md1
-rw-r--r--doc/release-notes/release-notes-0.4.6.md37
-rw-r--r--doc/release-notes/release-notes-0.5.0.md70
-rw-r--r--doc/release-notes/release-notes-0.5.1.md43
-rw-r--r--doc/release-notes/release-notes-0.5.2.md22
-rw-r--r--doc/release-notes/release-notes-0.5.3.md42
-rw-r--r--doc/release-notes/release-notes-0.5.4.md39
-rw-r--r--doc/release-notes/release-notes-0.5.5.md37
-rw-r--r--doc/release-notes/release-notes-0.6.0.md138
-rw-r--r--doc/release-notes/release-notes-0.6.1.md2
-rw-r--r--doc/release-notes/release-notes-0.6.2.md50
-rw-r--r--doc/release-notes/release-notes-0.6.3.md29
-rw-r--r--doc/release-notes/release-notes-0.7.0.md169
-rw-r--r--doc/release-notes/release-notes-0.7.1.md110
-rw-r--r--doc/release-notes/release-notes-0.7.2.md68
-rw-r--r--doc/release-notes/release-notes-0.8.0.md139
-rw-r--r--doc/release-notes/release-notes-0.8.1.md22
-rw-r--r--doc/release-notes/release-notes-0.8.2.md137
-rw-r--r--doc/release-notes/release-notes-0.8.3.md18
-rw-r--r--doc/release-notes/release-notes-0.8.4.md83
-rw-r--r--doc/release-notes/release-notes-0.8.5.md44
-rw-r--r--doc/release-notes/release-notes-0.8.6.md66
-rw-r--r--doc/release-notes/release-notes-0.9.0.md411
-rw-r--r--doc/release-notes/release-notes-0.9.1.md53
-rw-r--r--doc/release-notes/release-notes-0.9.2.1.md207
-rw-r--r--doc/release-notes/release-notes-0.9.2.md207
-rw-r--r--doc/release-notes/release-notes-0.9.3.md101
-rw-r--r--doc/release-notes/release-notes-0.9.4.md95
-rw-r--r--doc/release-notes/release-notes-0.9.5.md60
-rw-r--r--doc/release-process.md172
-rw-r--r--doc/tor.md85
-rw-r--r--doc/translation_process.md111
-rw-r--r--doc/translation_strings_policy.md72
-rw-r--r--doc/travis-ci.txt39
-rw-r--r--doc/unit-tests.md18
-rw-r--r--libbitcoinconsensus.pc.in11
-rwxr-xr-xqa/pull-tester/rpc-tests.sh74
-rwxr-xr-xqa/pull-tester/run-bitcoin-cli13
-rwxr-xr-xqa/pull-tester/run-bitcoind-for-test.sh.in36
-rwxr-xr-xqa/pull-tester/tests-config.sh.in16
-rw-r--r--qa/rpc-tests/.gitignore2
-rw-r--r--qa/rpc-tests/README.md51
-rwxr-xr-xqa/rpc-tests/bip65-cltv-p2p.py175
-rwxr-xr-xqa/rpc-tests/bip65-cltv.py89
-rwxr-xr-xqa/rpc-tests/bipdersig-p2p.py183
-rwxr-xr-xqa/rpc-tests/bipdersig.py89
-rwxr-xr-xqa/rpc-tests/forknotify.py63
-rwxr-xr-xqa/rpc-tests/getblocktemplate_longpoll.py91
-rwxr-xr-xqa/rpc-tests/getblocktemplate_proposals.py182
-rwxr-xr-xqa/rpc-tests/getchaintips.py59
-rwxr-xr-xqa/rpc-tests/httpbasics.py102
-rwxr-xr-xqa/rpc-tests/invalidateblock.py75
-rwxr-xr-xqa/rpc-tests/invalidblockrequest.py115
-rwxr-xr-xqa/rpc-tests/keypool.py130
-rwxr-xr-xqa/rpc-tests/listtransactions.py98
-rwxr-xr-xqa/rpc-tests/maxblocksinflight.py101
-rwxr-xr-xqa/rpc-tests/mempool_coinbase_spends.py93
-rwxr-xr-xqa/rpc-tests/mempool_resurrect_test.py86
-rwxr-xr-xqa/rpc-tests/mempool_spendcoinbase.py68
-rwxr-xr-xqa/rpc-tests/merkle_blocks.py89
-rwxr-xr-xqa/rpc-tests/p2p-acceptblock.py291
-rwxr-xr-xqa/rpc-tests/proxy_test.py146
-rwxr-xr-xqa/rpc-tests/pruning.py359
-rwxr-xr-xqa/rpc-tests/rawtransactions.py144
-rwxr-xr-xqa/rpc-tests/receivedby.py166
-rwxr-xr-xqa/rpc-tests/reindex.py33
-rwxr-xr-xqa/rpc-tests/rest.py288
-rwxr-xr-xqa/rpc-tests/rpcbind_test.py152
-rwxr-xr-xqa/rpc-tests/script_test.py253
-rwxr-xr-xqa/rpc-tests/signrawtransactions.py109
-rwxr-xr-xqa/rpc-tests/smartfees.py258
-rw-r--r--qa/rpc-tests/test_framework/__init__.py0
-rw-r--r--qa/rpc-tests/test_framework/authproxy.py156
-rw-r--r--qa/rpc-tests/test_framework/bignum.py102
-rw-r--r--qa/rpc-tests/test_framework/blockstore.py127
-rw-r--r--qa/rpc-tests/test_framework/blocktools.py65
-rwxr-xr-xqa/rpc-tests/test_framework/comptool.py343
-rwxr-xr-xqa/rpc-tests/test_framework/mininode.py1256
-rw-r--r--qa/rpc-tests/test_framework/netutil.py139
-rw-r--r--qa/rpc-tests/test_framework/script.py896
-rw-r--r--qa/rpc-tests/test_framework/socks5.py160
-rwxr-xr-xqa/rpc-tests/test_framework/test_framework.py179
-rw-r--r--qa/rpc-tests/test_framework/util.py356
-rwxr-xr-xqa/rpc-tests/txn_doublespend.py119
-rwxr-xr-xqa/rpc-tests/wallet.py222
-rwxr-xr-xqa/rpc-tests/walletbackup.py200
-rwxr-xr-xqa/rpc-tests/zapwallettxes.py82
-rw-r--r--share/certs/BitcoinFoundation_Apple_Cert.pem37
-rw-r--r--share/certs/BitcoinFoundation_Comodo_Cert.pem37
-rw-r--r--share/certs/PrivateKeyNotes.md46
-rwxr-xr-xshare/genbuild.sh51
-rw-r--r--share/pixmaps/addressbook16.bmpbin0 -> 1334 bytes
-rw-r--r--share/pixmaps/addressbook16mask.bmpbin0 -> 126 bytes
-rw-r--r--share/pixmaps/addressbook20.bmpbin0 -> 1478 bytes
-rw-r--r--share/pixmaps/addressbook20mask.bmpbin0 -> 142 bytes
-rw-r--r--share/pixmaps/bitcoin-bc.icobin0 -> 22486 bytes
-rw-r--r--share/pixmaps/bitcoin.icobin0 -> 68756 bytes
-rw-r--r--share/pixmaps/bitcoin128.pngbin0 -> 10639 bytes
-rw-r--r--share/pixmaps/bitcoin128.xpm384
-rw-r--r--share/pixmaps/bitcoin16.pngbin0 -> 827 bytes
-rw-r--r--share/pixmaps/bitcoin16.xpm181
-rw-r--r--share/pixmaps/bitcoin256.pngbin0 -> 28182 bytes
-rw-r--r--share/pixmaps/bitcoin256.xpm465
-rw-r--r--share/pixmaps/bitcoin32.pngbin0 -> 1982 bytes
-rw-r--r--share/pixmaps/bitcoin32.xpm140
-rw-r--r--share/pixmaps/bitcoin64.pngbin0 -> 4592 bytes
-rw-r--r--share/pixmaps/bitcoin64.xpm242
-rw-r--r--share/pixmaps/check.icobin0 -> 766 bytes
-rw-r--r--share/pixmaps/favicon.icobin0 -> 1150 bytes
-rw-r--r--share/pixmaps/nsis-header.bmpbin0 -> 25818 bytes
-rw-r--r--share/pixmaps/nsis-wizard.bmpbin0 -> 154542 bytes
-rw-r--r--share/pixmaps/send16.bmpbin0 -> 1334 bytes
-rw-r--r--share/pixmaps/send16mask.bmpbin0 -> 126 bytes
-rw-r--r--share/pixmaps/send16masknoshadow.bmpbin0 -> 126 bytes
-rw-r--r--share/pixmaps/send20.bmpbin0 -> 1478 bytes
-rw-r--r--share/pixmaps/send20mask.bmpbin0 -> 142 bytes
-rw-r--r--share/qt/Info.plist.in106
-rwxr-xr-xshare/qt/extract_strings_qt.py78
-rw-r--r--share/qt/img/reload.pngbin0 -> 9886 bytes
-rw-r--r--share/qt/img/reload.xcfbin0 -> 25292 bytes
-rwxr-xr-xshare/qt/make_spinner.py38
-rwxr-xr-xshare/qt/make_windows_icon.sh9
-rw-r--r--share/qt/protobuf.pri35
-rw-r--r--share/setup.nsi.in179
-rw-r--r--share/ui.rc15
-rw-r--r--src/.clang-format51
-rw-r--r--src/Makefile.am436
-rw-r--r--src/Makefile.qt.include418
-rw-r--r--src/Makefile.qttest.include48
-rw-r--r--src/Makefile.test.include134
-rw-r--r--src/addrman.cpp490
-rw-r--r--src/addrman.h572
-rw-r--r--src/alert.cpp265
-rw-r--r--src/alert.h113
-rw-r--r--src/amount.cpp31
-rw-r--r--src/amount.h54
-rw-r--r--src/arith_uint256.cpp260
-rw-r--r--src/arith_uint256.h290
-rw-r--r--src/base58.cpp311
-rw-r--r--src/base58.h163
-rw-r--r--src/bitcoin-cli-res.rc35
-rw-r--r--src/bitcoin-cli.cpp257
-rw-r--r--src/bitcoin-tx-res.rc35
-rw-r--r--src/bitcoin-tx.cpp638
-rw-r--r--src/bitcoind-res.rc35
-rw-r--r--src/bitcoind.cpp177
-rw-r--r--src/bloom.cpp272
-rw-r--r--src/bloom.h138
-rw-r--r--src/chain.cpp108
-rw-r--r--src/chain.h406
-rw-r--r--src/chainparams.cpp272
-rw-r--r--src/chainparams.h116
-rw-r--r--src/chainparamsbase.cpp118
-rw-r--r--src/chainparamsbase.h63
-rw-r--r--src/chainparamsseeds.h901
-rw-r--r--src/checkpoints.cpp90
-rw-r--r--src/checkpoints.h42
-rw-r--r--src/checkqueue.h215
-rw-r--r--src/clientversion.cpp112
-rw-r--r--src/clientversion.h70
-rw-r--r--src/coincontrol.h62
-rw-r--r--src/coins.cpp266
-rw-r--r--src/coins.h465
-rw-r--r--src/compat.h104
-rw-r--r--src/compat/byteswap.h47
-rw-r--r--src/compat/endian.h196
-rw-r--r--src/compat/glibc_compat.cpp29
-rw-r--r--src/compat/glibc_sanity.cpp68
-rw-r--r--src/compat/glibcxx_sanity.cpp61
-rw-r--r--src/compat/sanity.h11
-rw-r--r--src/compat/strnlen.cpp18
-rw-r--r--src/compressor.cpp185
-rw-r--r--src/compressor.h123
-rw-r--r--src/config/.empty0
-rw-r--r--src/consensus/consensus.h16
-rw-r--r--src/consensus/params.h31
-rw-r--r--src/consensus/validation.h80
-rw-r--r--src/core_io.h32
-rw-r--r--src/core_read.cpp153
-rw-r--r--src/core_write.cpp134
-rw-r--r--src/crypto/common.h66
-rw-r--r--src/crypto/hmac_sha256.cpp34
-rw-r--r--src/crypto/hmac_sha256.h32
-rw-r--r--src/crypto/hmac_sha512.cpp34
-rw-r--r--src/crypto/hmac_sha512.h32
-rw-r--r--src/crypto/ripemd160.cpp292
-rw-r--r--src/crypto/ripemd160.h28
-rw-r--r--src/crypto/sha1.cpp199
-rw-r--r--src/crypto/sha1.h28
-rw-r--r--src/crypto/sha256.cpp189
-rw-r--r--src/crypto/sha256.h28
-rw-r--r--src/crypto/sha512.cpp207
-rw-r--r--src/crypto/sha512.h28
-rw-r--r--src/eccryptoverify.cpp68
-rw-r--r--src/eccryptoverify.h21
-rw-r--r--src/ecwrapper.cpp218
-rw-r--r--src/ecwrapper.h40
-rw-r--r--src/hash.cpp83
-rw-r--r--src/hash.h166
-rw-r--r--src/init.cpp1453
-rw-r--r--src/init.h37
-rw-r--r--src/json/LICENSE.txt24
-rw-r--r--src/json/json_spirit.h18
-rw-r--r--src/json/json_spirit_error_position.h54
-rw-r--r--src/json/json_spirit_reader.cpp137
-rw-r--r--src/json/json_spirit_reader.h62
-rw-r--r--src/json/json_spirit_reader_template.h612
-rw-r--r--src/json/json_spirit_stream_reader.h70
-rw-r--r--src/json/json_spirit_utils.h61
-rw-r--r--src/json/json_spirit_value.cpp8
-rw-r--r--src/json/json_spirit_value.h534
-rw-r--r--src/json/json_spirit_writer.cpp95
-rw-r--r--src/json/json_spirit_writer.h50
-rw-r--r--src/json/json_spirit_writer_template.h249
-rw-r--r--src/key.cpp223
-rw-r--r--src/key.h183
-rw-r--r--src/keystore.cpp85
-rw-r--r--src/keystore.h111
-rw-r--r--src/leveldb/.gitignore13
-rw-r--r--src/leveldb/AUTHORS (renamed from AUTHORS)0
-rw-r--r--src/leveldb/CONTRIBUTING.md (renamed from CONTRIBUTING.md)0
-rw-r--r--src/leveldb/LICENSE (renamed from LICENSE)0
-rw-r--r--src/leveldb/Makefile (renamed from Makefile)0
-rw-r--r--src/leveldb/NEWS (renamed from NEWS)0
-rw-r--r--src/leveldb/README (renamed from README)0
-rw-r--r--src/leveldb/README.md138
-rw-r--r--src/leveldb/TODO (renamed from TODO)0
-rw-r--r--src/leveldb/WINDOWS.md (renamed from WINDOWS.md)0
-rwxr-xr-xsrc/leveldb/build_detect_platform (renamed from build_detect_platform)0
-rw-r--r--src/leveldb/db/autocompact_test.cc (renamed from db/autocompact_test.cc)0
-rw-r--r--src/leveldb/db/builder.cc (renamed from db/builder.cc)0
-rw-r--r--src/leveldb/db/builder.h (renamed from db/builder.h)0
-rw-r--r--src/leveldb/db/c.cc (renamed from db/c.cc)0
-rw-r--r--src/leveldb/db/c_test.c (renamed from db/c_test.c)0
-rw-r--r--src/leveldb/db/corruption_test.cc (renamed from db/corruption_test.cc)0
-rw-r--r--src/leveldb/db/db_bench.cc (renamed from db/db_bench.cc)0
-rw-r--r--src/leveldb/db/db_impl.cc (renamed from db/db_impl.cc)0
-rw-r--r--src/leveldb/db/db_impl.h (renamed from db/db_impl.h)0
-rw-r--r--src/leveldb/db/db_iter.cc (renamed from db/db_iter.cc)0
-rw-r--r--src/leveldb/db/db_iter.h (renamed from db/db_iter.h)0
-rw-r--r--src/leveldb/db/db_test.cc (renamed from db/db_test.cc)0
-rw-r--r--src/leveldb/db/dbformat.cc (renamed from db/dbformat.cc)0
-rw-r--r--src/leveldb/db/dbformat.h (renamed from db/dbformat.h)0
-rw-r--r--src/leveldb/db/dbformat_test.cc (renamed from db/dbformat_test.cc)0
-rw-r--r--src/leveldb/db/dumpfile.cc (renamed from db/dumpfile.cc)0
-rw-r--r--src/leveldb/db/filename.cc (renamed from db/filename.cc)0
-rw-r--r--src/leveldb/db/filename.h (renamed from db/filename.h)0
-rw-r--r--src/leveldb/db/filename_test.cc (renamed from db/filename_test.cc)0
-rw-r--r--src/leveldb/db/leveldb_main.cc (renamed from db/leveldb_main.cc)0
-rw-r--r--src/leveldb/db/log_format.h (renamed from db/log_format.h)0
-rw-r--r--src/leveldb/db/log_reader.cc (renamed from db/log_reader.cc)0
-rw-r--r--src/leveldb/db/log_reader.h (renamed from db/log_reader.h)0
-rw-r--r--src/leveldb/db/log_test.cc (renamed from db/log_test.cc)0
-rw-r--r--src/leveldb/db/log_writer.cc (renamed from db/log_writer.cc)0
-rw-r--r--src/leveldb/db/log_writer.h (renamed from db/log_writer.h)0
-rw-r--r--src/leveldb/db/memtable.cc (renamed from db/memtable.cc)0
-rw-r--r--src/leveldb/db/memtable.h (renamed from db/memtable.h)0
-rw-r--r--src/leveldb/db/repair.cc (renamed from db/repair.cc)0
-rw-r--r--src/leveldb/db/skiplist.h (renamed from db/skiplist.h)0
-rw-r--r--src/leveldb/db/skiplist_test.cc (renamed from db/skiplist_test.cc)0
-rw-r--r--src/leveldb/db/snapshot.h (renamed from db/snapshot.h)0
-rw-r--r--src/leveldb/db/table_cache.cc (renamed from db/table_cache.cc)0
-rw-r--r--src/leveldb/db/table_cache.h (renamed from db/table_cache.h)0
-rw-r--r--src/leveldb/db/version_edit.cc (renamed from db/version_edit.cc)0
-rw-r--r--src/leveldb/db/version_edit.h (renamed from db/version_edit.h)0
-rw-r--r--src/leveldb/db/version_edit_test.cc (renamed from db/version_edit_test.cc)0
-rw-r--r--src/leveldb/db/version_set.cc (renamed from db/version_set.cc)0
-rw-r--r--src/leveldb/db/version_set.h (renamed from db/version_set.h)0
-rw-r--r--src/leveldb/db/version_set_test.cc (renamed from db/version_set_test.cc)0
-rw-r--r--src/leveldb/db/write_batch.cc (renamed from db/write_batch.cc)0
-rw-r--r--src/leveldb/db/write_batch_internal.h (renamed from db/write_batch_internal.h)0
-rw-r--r--src/leveldb/db/write_batch_test.cc (renamed from db/write_batch_test.cc)0
-rw-r--r--src/leveldb/doc/bench/db_bench_sqlite3.cc (renamed from doc/bench/db_bench_sqlite3.cc)0
-rw-r--r--src/leveldb/doc/bench/db_bench_tree_db.cc (renamed from doc/bench/db_bench_tree_db.cc)0
-rw-r--r--src/leveldb/doc/benchmark.html (renamed from doc/benchmark.html)0
-rw-r--r--src/leveldb/doc/doc.css (renamed from doc/doc.css)0
-rw-r--r--src/leveldb/doc/impl.html (renamed from doc/impl.html)0
-rw-r--r--src/leveldb/doc/index.html (renamed from doc/index.html)0
-rw-r--r--src/leveldb/doc/log_format.txt (renamed from doc/log_format.txt)0
-rw-r--r--src/leveldb/doc/table_format.txt (renamed from doc/table_format.txt)0
-rw-r--r--src/leveldb/helpers/memenv/memenv.cc (renamed from helpers/memenv/memenv.cc)0
-rw-r--r--src/leveldb/helpers/memenv/memenv.h (renamed from helpers/memenv/memenv.h)0
-rw-r--r--src/leveldb/helpers/memenv/memenv_test.cc (renamed from helpers/memenv/memenv_test.cc)0
-rw-r--r--src/leveldb/include/leveldb/c.h (renamed from include/leveldb/c.h)0
-rw-r--r--src/leveldb/include/leveldb/cache.h (renamed from include/leveldb/cache.h)0
-rw-r--r--src/leveldb/include/leveldb/comparator.h (renamed from include/leveldb/comparator.h)0
-rw-r--r--src/leveldb/include/leveldb/db.h (renamed from include/leveldb/db.h)0
-rw-r--r--src/leveldb/include/leveldb/dumpfile.h (renamed from include/leveldb/dumpfile.h)0
-rw-r--r--src/leveldb/include/leveldb/env.h (renamed from include/leveldb/env.h)0
-rw-r--r--src/leveldb/include/leveldb/filter_policy.h (renamed from include/leveldb/filter_policy.h)0
-rw-r--r--src/leveldb/include/leveldb/iterator.h (renamed from include/leveldb/iterator.h)0
-rw-r--r--src/leveldb/include/leveldb/options.h (renamed from include/leveldb/options.h)0
-rw-r--r--src/leveldb/include/leveldb/slice.h (renamed from include/leveldb/slice.h)0
-rw-r--r--src/leveldb/include/leveldb/status.h (renamed from include/leveldb/status.h)0
-rw-r--r--src/leveldb/include/leveldb/table.h (renamed from include/leveldb/table.h)0
-rw-r--r--src/leveldb/include/leveldb/table_builder.h (renamed from include/leveldb/table_builder.h)0
-rw-r--r--src/leveldb/include/leveldb/write_batch.h (renamed from include/leveldb/write_batch.h)0
-rw-r--r--src/leveldb/issues/issue178_test.cc (renamed from issues/issue178_test.cc)0
-rw-r--r--src/leveldb/issues/issue200_test.cc (renamed from issues/issue200_test.cc)0
-rw-r--r--src/leveldb/port/README (renamed from port/README)0
-rw-r--r--src/leveldb/port/atomic_pointer.h (renamed from port/atomic_pointer.h)0
-rw-r--r--src/leveldb/port/port.h (renamed from port/port.h)0
-rw-r--r--src/leveldb/port/port_example.h (renamed from port/port_example.h)0
-rw-r--r--src/leveldb/port/port_posix.cc (renamed from port/port_posix.cc)0
-rw-r--r--src/leveldb/port/port_posix.h (renamed from port/port_posix.h)0
-rw-r--r--src/leveldb/port/port_win.cc (renamed from port/port_win.cc)0
-rw-r--r--src/leveldb/port/port_win.h (renamed from port/port_win.h)0
-rw-r--r--src/leveldb/port/thread_annotations.h (renamed from port/thread_annotations.h)0
-rw-r--r--src/leveldb/port/win/stdint.h (renamed from port/win/stdint.h)0
-rw-r--r--src/leveldb/table/block.cc (renamed from table/block.cc)0
-rw-r--r--src/leveldb/table/block.h (renamed from table/block.h)0
-rw-r--r--src/leveldb/table/block_builder.cc (renamed from table/block_builder.cc)0
-rw-r--r--src/leveldb/table/block_builder.h (renamed from table/block_builder.h)0
-rw-r--r--src/leveldb/table/filter_block.cc (renamed from table/filter_block.cc)0
-rw-r--r--src/leveldb/table/filter_block.h (renamed from table/filter_block.h)0
-rw-r--r--src/leveldb/table/filter_block_test.cc (renamed from table/filter_block_test.cc)0
-rw-r--r--src/leveldb/table/format.cc (renamed from table/format.cc)0
-rw-r--r--src/leveldb/table/format.h (renamed from table/format.h)0
-rw-r--r--src/leveldb/table/iterator.cc (renamed from table/iterator.cc)0
-rw-r--r--src/leveldb/table/iterator_wrapper.h (renamed from table/iterator_wrapper.h)0
-rw-r--r--src/leveldb/table/merger.cc (renamed from table/merger.cc)0
-rw-r--r--src/leveldb/table/merger.h (renamed from table/merger.h)0
-rw-r--r--src/leveldb/table/table.cc (renamed from table/table.cc)0
-rw-r--r--src/leveldb/table/table_builder.cc (renamed from table/table_builder.cc)0
-rw-r--r--src/leveldb/table/table_test.cc (renamed from table/table_test.cc)0
-rw-r--r--src/leveldb/table/two_level_iterator.cc (renamed from table/two_level_iterator.cc)0
-rw-r--r--src/leveldb/table/two_level_iterator.h (renamed from table/two_level_iterator.h)0
-rw-r--r--src/leveldb/util/arena.cc (renamed from util/arena.cc)0
-rw-r--r--src/leveldb/util/arena.h (renamed from util/arena.h)0
-rw-r--r--src/leveldb/util/arena_test.cc (renamed from util/arena_test.cc)0
-rw-r--r--src/leveldb/util/bloom.cc (renamed from util/bloom.cc)0
-rw-r--r--src/leveldb/util/bloom_test.cc (renamed from util/bloom_test.cc)0
-rw-r--r--src/leveldb/util/cache.cc (renamed from util/cache.cc)0
-rw-r--r--src/leveldb/util/cache_test.cc (renamed from util/cache_test.cc)0
-rw-r--r--src/leveldb/util/coding.cc (renamed from util/coding.cc)0
-rw-r--r--src/leveldb/util/coding.h (renamed from util/coding.h)0
-rw-r--r--src/leveldb/util/coding_test.cc (renamed from util/coding_test.cc)0
-rw-r--r--src/leveldb/util/comparator.cc (renamed from util/comparator.cc)0
-rw-r--r--src/leveldb/util/crc32c.cc (renamed from util/crc32c.cc)0
-rw-r--r--src/leveldb/util/crc32c.h (renamed from util/crc32c.h)0
-rw-r--r--src/leveldb/util/crc32c_test.cc (renamed from util/crc32c_test.cc)0
-rw-r--r--src/leveldb/util/env.cc (renamed from util/env.cc)0
-rw-r--r--src/leveldb/util/env_posix.cc (renamed from util/env_posix.cc)0
-rw-r--r--src/leveldb/util/env_test.cc (renamed from util/env_test.cc)0
-rw-r--r--src/leveldb/util/env_win.cc (renamed from util/env_win.cc)0
-rw-r--r--src/leveldb/util/filter_policy.cc (renamed from util/filter_policy.cc)0
-rw-r--r--src/leveldb/util/hash.cc (renamed from util/hash.cc)0
-rw-r--r--src/leveldb/util/hash.h (renamed from util/hash.h)0
-rw-r--r--src/leveldb/util/hash_test.cc (renamed from util/hash_test.cc)0
-rw-r--r--src/leveldb/util/histogram.cc (renamed from util/histogram.cc)0
-rw-r--r--src/leveldb/util/histogram.h (renamed from util/histogram.h)0
-rw-r--r--src/leveldb/util/logging.cc (renamed from util/logging.cc)0
-rw-r--r--src/leveldb/util/logging.h (renamed from util/logging.h)0
-rw-r--r--src/leveldb/util/mutexlock.h (renamed from util/mutexlock.h)0
-rw-r--r--src/leveldb/util/options.cc (renamed from util/options.cc)0
-rw-r--r--src/leveldb/util/posix_logger.h (renamed from util/posix_logger.h)0
-rw-r--r--src/leveldb/util/random.h (renamed from util/random.h)0
-rw-r--r--src/leveldb/util/status.cc (renamed from util/status.cc)0
-rw-r--r--src/leveldb/util/testharness.cc (renamed from util/testharness.cc)0
-rw-r--r--src/leveldb/util/testharness.h (renamed from util/testharness.h)0
-rw-r--r--src/leveldb/util/testutil.cc (renamed from util/testutil.cc)0
-rw-r--r--src/leveldb/util/testutil.h (renamed from util/testutil.h)0
-rw-r--r--src/leveldbwrapper.cpp89
-rw-r--r--src/leveldbwrapper.h173
-rw-r--r--src/limitedmap.h94
-rw-r--r--src/main.cpp5205
-rw-r--r--src/main.h493
-rw-r--r--src/memusage.h111
-rw-r--r--src/merkleblock.cpp181
-rw-r--r--src/merkleblock.h156
-rw-r--r--src/miner.cpp581
-rw-r--r--src/miner.h35
-rw-r--r--src/mruset.h65
-rw-r--r--src/net.cpp2099
-rw-r--r--src/net.h640
-rw-r--r--src/netbase.cpp1417
-rw-r--r--src/netbase.h206
-rw-r--r--src/noui.cpp52
-rw-r--r--src/noui.h10
-rw-r--r--src/obj-test/.gitignore2
-rw-r--r--src/obj/.gitignore2
-rw-r--r--src/policy/fees.cpp530
-rw-r--r--src/policy/fees.h276
-rw-r--r--src/pow.cpp133
-rw-r--r--src/pow.h28
-rw-r--r--src/primitives/block.cpp131
-rw-r--r--src/primitives/block.h168
-rw-r--r--src/primitives/transaction.cpp142
-rw-r--r--src/primitives/transaction.h282
-rw-r--r--src/protocol.cpp142
-rw-r--r--src/protocol.h158
-rw-r--r--src/pubkey.cpp97
-rw-r--r--src/pubkey.h208
-rw-r--r--src/qt/Makefile9
-rw-r--r--src/qt/addressbookpage.cpp313
-rw-r--r--src/qt/addressbookpage.h87
-rw-r--r--src/qt/addresstablemodel.cpp454
-rw-r--r--src/qt/addresstablemodel.h95
-rw-r--r--src/qt/askpassphrasedialog.cpp258
-rw-r--r--src/qt/askpassphrasedialog.h51
-rw-r--r--src/qt/bitcoin.cpp658
-rw-r--r--src/qt/bitcoin.qrc88
-rw-r--r--src/qt/bitcoin_locale.qrc75
-rw-r--r--src/qt/bitcoinaddressvalidator.cpp97
-rw-r--r--src/qt/bitcoinaddressvalidator.h35
-rw-r--r--src/qt/bitcoinamountfield.cpp302
-rw-r--r--src/qt/bitcoinamountfield.h75
-rw-r--r--src/qt/bitcoingui.cpp1116
-rw-r--r--src/qt/bitcoingui.h242
-rw-r--r--src/qt/bitcoinstrings.cpp319
-rw-r--r--src/qt/bitcoinunits.cpp220
-rw-r--r--src/qt/bitcoinunits.h127
-rw-r--r--src/qt/clientmodel.cpp243
-rw-r--r--src/qt/clientmodel.h103
-rw-r--r--src/qt/coincontroldialog.cpp828
-rw-r--r--src/qt/coincontroldialog.h130
-rw-r--r--src/qt/coincontroltreewidget.cpp33
-rw-r--r--src/qt/coincontroltreewidget.h22
-rw-r--r--src/qt/csvmodelwriter.cpp91
-rw-r--r--src/qt/csvmodelwriter.h46
-rw-r--r--src/qt/editaddressdialog.cpp144
-rw-r--r--src/qt/editaddressdialog.h57
-rw-r--r--src/qt/forms/addressbookpage.ui159
-rw-r--r--src/qt/forms/askpassphrasedialog.ui160
-rw-r--r--src/qt/forms/coincontroldialog.ui534
-rw-r--r--src/qt/forms/editaddressdialog.ui112
-rw-r--r--src/qt/forms/helpmessagedialog.ui192
-rw-r--r--src/qt/forms/intro.ui266
-rw-r--r--src/qt/forms/openuridialog.ui118
-rw-r--r--src/qt/forms/optionsdialog.ui602
-rw-r--r--src/qt/forms/overviewpage.ui538
-rw-r--r--src/qt/forms/receivecoinsdialog.ui338
-rw-r--r--src/qt/forms/receiverequestdialog.ui168
-rw-r--r--src/qt/forms/rpcconsole.ui1106
-rw-r--r--src/qt/forms/sendcoinsdialog.ui1389
-rw-r--r--src/qt/forms/sendcoinsentry.ui1275
-rw-r--r--src/qt/forms/signverifymessagedialog.ui390
-rw-r--r--src/qt/forms/transactiondescdialog.ui74
-rw-r--r--src/qt/guiconstants.h52
-rw-r--r--src/qt/guiutil.cpp908
-rw-r--r--src/qt/guiutil.h211
-rw-r--r--src/qt/intro.cpp293
-rw-r--r--src/qt/intro.h73
-rw-r--r--src/qt/locale/bitcoin_ach.ts110
-rw-r--r--src/qt/locale/bitcoin_af_ZA.ts674
-rw-r--r--src/qt/locale/bitcoin_ar.ts1730
-rw-r--r--src/qt/locale/bitcoin_be_BY.ts1536
-rw-r--r--src/qt/locale/bitcoin_bg.ts2534
-rw-r--r--src/qt/locale/bitcoin_bs.ts166
-rw-r--r--src/qt/locale/bitcoin_ca.ts3575
-rw-r--r--src/qt/locale/bitcoin_ca@valencia.ts3571
-rw-r--r--src/qt/locale/bitcoin_ca_ES.ts3575
-rw-r--r--src/qt/locale/bitcoin_cmn.ts114
-rw-r--r--src/qt/locale/bitcoin_cs.ts3576
-rw-r--r--src/qt/locale/bitcoin_cy.ts506
-rw-r--r--src/qt/locale/bitcoin_da.ts3590
-rw-r--r--src/qt/locale/bitcoin_de.ts3584
-rw-r--r--src/qt/locale/bitcoin_el_GR.ts2935
-rw-r--r--src/qt/locale/bitcoin_en.ts4576
-rw-r--r--src/qt/locale/bitcoin_eo.ts2402
-rw-r--r--src/qt/locale/bitcoin_es.ts3588
-rw-r--r--src/qt/locale/bitcoin_es_CL.ts1425
-rw-r--r--src/qt/locale/bitcoin_es_DO.ts2430
-rw-r--r--src/qt/locale/bitcoin_es_MX.ts1094
-rw-r--r--src/qt/locale/bitcoin_es_UY.ts470
-rw-r--r--src/qt/locale/bitcoin_et.ts1920
-rw-r--r--src/qt/locale/bitcoin_eu_ES.ts686
-rw-r--r--src/qt/locale/bitcoin_fa.ts2070
-rw-r--r--src/qt/locale/bitcoin_fa_IR.ts1112
-rw-r--r--src/qt/locale/bitcoin_fi.ts3272
-rw-r--r--src/qt/locale/bitcoin_fr.ts3560
-rw-r--r--src/qt/locale/bitcoin_fr_CA.ts206
-rw-r--r--src/qt/locale/bitcoin_gl.ts2226
-rw-r--r--src/qt/locale/bitcoin_gu_IN.ts110
-rw-r--r--src/qt/locale/bitcoin_he.ts2926
-rw-r--r--src/qt/locale/bitcoin_hi_IN.ts861
-rw-r--r--src/qt/locale/bitcoin_hr.ts1904
-rw-r--r--src/qt/locale/bitcoin_hu.ts2326
-rw-r--r--src/qt/locale/bitcoin_id_ID.ts2490
-rw-r--r--src/qt/locale/bitcoin_it.ts3568
-rw-r--r--src/qt/locale/bitcoin_ja.ts3593
-rw-r--r--src/qt/locale/bitcoin_ka.ts2518
-rw-r--r--src/qt/locale/bitcoin_kk_KZ.ts442
-rw-r--r--src/qt/locale/bitcoin_ko_KR.ts2624
-rw-r--r--src/qt/locale/bitcoin_ky.ts330
-rw-r--r--src/qt/locale/bitcoin_la.ts1642
-rw-r--r--src/qt/locale/bitcoin_lt.ts1746
-rw-r--r--src/qt/locale/bitcoin_lv_LV.ts2290
-rw-r--r--src/qt/locale/bitcoin_mn.ts1078
-rw-r--r--src/qt/locale/bitcoin_ms_MY.ts190
-rw-r--r--src/qt/locale/bitcoin_nb.ts3592
-rw-r--r--src/qt/locale/bitcoin_nl.ts3496
-rw-r--r--src/qt/locale/bitcoin_pam.ts1502
-rw-r--r--src/qt/locale/bitcoin_pl.ts3564
-rw-r--r--src/qt/locale/bitcoin_pt_BR.ts3380
-rw-r--r--src/qt/locale/bitcoin_pt_PT.ts3217
-rw-r--r--src/qt/locale/bitcoin_ro_RO.ts3204
-rw-r--r--src/qt/locale/bitcoin_ru.ts3528
-rw-r--r--src/qt/locale/bitcoin_sah.ts110
-rw-r--r--src/qt/locale/bitcoin_sk.ts3446
-rw-r--r--src/qt/locale/bitcoin_sl_SI.ts3312
-rw-r--r--src/qt/locale/bitcoin_sq.ts774
-rw-r--r--src/qt/locale/bitcoin_sr.ts806
-rw-r--r--src/qt/locale/bitcoin_sv.ts3577
-rw-r--r--src/qt/locale/bitcoin_th_TH.ts386
-rw-r--r--src/qt/locale/bitcoin_tr.ts3576
-rw-r--r--src/qt/locale/bitcoin_uk.ts3592
-rw-r--r--src/qt/locale/bitcoin_ur_PK.ts366
-rw-r--r--src/qt/locale/bitcoin_uz@Cyrl.ts1914
-rw-r--r--src/qt/locale/bitcoin_vi.ts210
-rw-r--r--src/qt/locale/bitcoin_vi_VN.ts734
-rw-r--r--src/qt/locale/bitcoin_zh_CN.ts3593
-rw-r--r--src/qt/locale/bitcoin_zh_HK.ts110
-rw-r--r--src/qt/locale/bitcoin_zh_TW.ts3585
-rw-r--r--src/qt/macdockiconhandler.h44
-rw-r--r--src/qt/macdockiconhandler.mm134
-rw-r--r--src/qt/macnotificationhandler.h30
-rw-r--r--src/qt/macnotificationhandler.mm91
-rw-r--r--src/qt/networkstyle.cpp97
-rw-r--r--src/qt/networkstyle.h33
-rw-r--r--src/qt/notificator.cpp326
-rw-r--r--src/qt/notificator.h80
-rw-r--r--src/qt/openuridialog.cpp52
-rw-r--r--src/qt/openuridialog.h34
-rw-r--r--src/qt/optionsdialog.cpp288
-rw-r--r--src/qt/optionsdialog.h61
-rw-r--r--src/qt/optionsmodel.cpp359
-rw-r--r--src/qt/optionsmodel.h89
-rw-r--r--src/qt/overviewpage.cpp264
-rw-r--r--src/qt/overviewpage.h66
-rw-r--r--src/qt/paymentrequest.proto46
-rw-r--r--src/qt/paymentrequestplus.cpp209
-rw-r--r--src/qt/paymentrequestplus.h46
-rw-r--r--src/qt/paymentserver.cpp805
-rw-r--r--src/qt/paymentserver.h151
-rw-r--r--src/qt/peertablemodel.cpp241
-rw-r--r--src/qt/peertablemodel.h81
-rw-r--r--src/qt/qvalidatedlineedit.cpp107
-rw-r--r--src/qt/qvalidatedlineedit.h39
-rw-r--r--src/qt/qvaluecombobox.cpp31
-rw-r--r--src/qt/qvaluecombobox.h37
-rw-r--r--src/qt/receivecoinsdialog.cpp269
-rw-r--r--src/qt/receivecoinsdialog.h76
-rw-r--r--src/qt/receiverequestdialog.cpp197
-rw-r--r--src/qt/receiverequestdialog.h70
-rw-r--r--src/qt/recentrequeststablemodel.cpp245
-rw-r--r--src/qt/recentrequeststablemodel.h108
-rw-r--r--src/qt/res/bitcoin-qt-res.rc37
-rw-r--r--src/qt/res/icons/about.pngbin0 -> 4726 bytes
-rw-r--r--src/qt/res/icons/about_qt.pngbin0 -> 2338 bytes
-rw-r--r--src/qt/res/icons/add.pngbin0 -> 784 bytes
-rw-r--r--src/qt/res/icons/address-book.pngbin0 -> 1275 bytes
-rw-r--r--src/qt/res/icons/bitcoin.icnsbin0 -> 919273 bytes
-rwxr-xr-xsrc/qt/res/icons/bitcoin.icobin0 -> 57964 bytes
-rw-r--r--src/qt/res/icons/bitcoin.pngbin0 -> 312944 bytes
-rw-r--r--src/qt/res/icons/clock1.pngbin0 -> 1921 bytes
-rw-r--r--src/qt/res/icons/clock2.pngbin0 -> 1731 bytes
-rw-r--r--src/qt/res/icons/clock3.pngbin0 -> 1557 bytes
-rw-r--r--src/qt/res/icons/clock4.pngbin0 -> 1395 bytes
-rw-r--r--src/qt/res/icons/clock5.pngbin0 -> 1889 bytes
-rw-r--r--src/qt/res/icons/configure.pngbin0 -> 2865 bytes
-rw-r--r--src/qt/res/icons/connect0.pngbin0 -> 2290 bytes
-rw-r--r--src/qt/res/icons/connect1.pngbin0 -> 2242 bytes
-rw-r--r--src/qt/res/icons/connect2.pngbin0 -> 1966 bytes
-rw-r--r--src/qt/res/icons/connect3.pngbin0 -> 1966 bytes
-rw-r--r--src/qt/res/icons/connect4.pngbin0 -> 1490 bytes
-rw-r--r--src/qt/res/icons/debugwindow.pngbin0 -> 1327 bytes
-rw-r--r--src/qt/res/icons/edit.pngbin0 -> 1847 bytes
-rw-r--r--src/qt/res/icons/editcopy.pngbin0 -> 883 bytes
-rw-r--r--src/qt/res/icons/editpaste.pngbin0 -> 1024 bytes
-rw-r--r--src/qt/res/icons/export.pngbin0 -> 1750 bytes
-rw-r--r--src/qt/res/icons/eye.pngbin0 -> 2241 bytes
-rw-r--r--src/qt/res/icons/eye_minus.pngbin0 -> 2438 bytes
-rw-r--r--src/qt/res/icons/eye_plus.pngbin0 -> 2599 bytes
-rw-r--r--src/qt/res/icons/filesave.pngbin0 -> 2359 bytes
-rw-r--r--src/qt/res/icons/history.pngbin0 -> 762 bytes
-rw-r--r--src/qt/res/icons/info.pngbin0 -> 2028 bytes
-rw-r--r--src/qt/res/icons/key.pngbin0 -> 1759 bytes
-rw-r--r--src/qt/res/icons/lock_closed.pngbin0 -> 1197 bytes
-rw-r--r--src/qt/res/icons/lock_open.pngbin0 -> 1257 bytes
-rw-r--r--src/qt/res/icons/open.pngbin0 -> 1694 bytes
-rw-r--r--src/qt/res/icons/overview.pngbin0 -> 1662 bytes
-rw-r--r--src/qt/res/icons/quit.pngbin0 -> 1091 bytes
-rw-r--r--src/qt/res/icons/receive.pngbin0 -> 2067 bytes
-rw-r--r--src/qt/res/icons/remove.pngbin0 -> 1723 bytes
-rw-r--r--src/qt/res/icons/send.pngbin0 -> 1750 bytes
-rw-r--r--src/qt/res/icons/synced.pngbin0 -> 1619 bytes
-rw-r--r--src/qt/res/icons/transaction0.pngbin0 -> 1220 bytes
-rw-r--r--src/qt/res/icons/transaction2.pngbin0 -> 1619 bytes
-rw-r--r--src/qt/res/icons/transaction_conflicted.pngbin0 -> 1091 bytes
-rw-r--r--src/qt/res/icons/tx_inout.pngbin0 -> 1655 bytes
-rw-r--r--src/qt/res/icons/tx_input.pngbin0 -> 1783 bytes
-rw-r--r--src/qt/res/icons/tx_mined.pngbin0 -> 1578 bytes
-rw-r--r--src/qt/res/icons/tx_output.pngbin0 -> 1771 bytes
-rw-r--r--src/qt/res/icons/verify.pngbin0 -> 2034 bytes
-rw-r--r--src/qt/res/icons/warning.pngbin0 -> 3810 bytes
-rwxr-xr-xsrc/qt/res/movies/makespinner.sh6
-rw-r--r--src/qt/res/movies/spinner-000.pngbin0 -> 1835 bytes
-rw-r--r--src/qt/res/movies/spinner-001.pngbin0 -> 2376 bytes
-rw-r--r--src/qt/res/movies/spinner-002.pngbin0 -> 2376 bytes
-rw-r--r--src/qt/res/movies/spinner-003.pngbin0 -> 2355 bytes
-rw-r--r--src/qt/res/movies/spinner-004.pngbin0 -> 2349 bytes
-rw-r--r--src/qt/res/movies/spinner-005.pngbin0 -> 2305 bytes
-rw-r--r--src/qt/res/movies/spinner-006.pngbin0 -> 2304 bytes
-rw-r--r--src/qt/res/movies/spinner-007.pngbin0 -> 2283 bytes
-rw-r--r--src/qt/res/movies/spinner-008.pngbin0 -> 2312 bytes
-rw-r--r--src/qt/res/movies/spinner-009.pngbin0 -> 1810 bytes
-rw-r--r--src/qt/res/movies/spinner-010.pngbin0 -> 2305 bytes
-rw-r--r--src/qt/res/movies/spinner-011.pngbin0 -> 2338 bytes
-rw-r--r--src/qt/res/movies/spinner-012.pngbin0 -> 2352 bytes
-rw-r--r--src/qt/res/movies/spinner-013.pngbin0 -> 2377 bytes
-rw-r--r--src/qt/res/movies/spinner-014.pngbin0 -> 2358 bytes
-rw-r--r--src/qt/res/movies/spinner-015.pngbin0 -> 2405 bytes
-rw-r--r--src/qt/res/movies/spinner-016.pngbin0 -> 2429 bytes
-rw-r--r--src/qt/res/movies/spinner-017.pngbin0 -> 2408 bytes
-rw-r--r--src/qt/res/movies/spinner-018.pngbin0 -> 1831 bytes
-rw-r--r--src/qt/res/movies/spinner-019.pngbin0 -> 2380 bytes
-rw-r--r--src/qt/res/movies/spinner-020.pngbin0 -> 2366 bytes
-rw-r--r--src/qt/res/movies/spinner-021.pngbin0 -> 2368 bytes
-rw-r--r--src/qt/res/movies/spinner-022.pngbin0 -> 2356 bytes
-rw-r--r--src/qt/res/movies/spinner-023.pngbin0 -> 2311 bytes
-rw-r--r--src/qt/res/movies/spinner-024.pngbin0 -> 2315 bytes
-rw-r--r--src/qt/res/movies/spinner-025.pngbin0 -> 2298 bytes
-rw-r--r--src/qt/res/movies/spinner-026.pngbin0 -> 2291 bytes
-rw-r--r--src/qt/res/movies/spinner-027.pngbin0 -> 1816 bytes
-rw-r--r--src/qt/res/movies/spinner-028.pngbin0 -> 2308 bytes
-rw-r--r--src/qt/res/movies/spinner-029.pngbin0 -> 2356 bytes
-rw-r--r--src/qt/res/movies/spinner-030.pngbin0 -> 2346 bytes
-rw-r--r--src/qt/res/movies/spinner-031.pngbin0 -> 2380 bytes
-rw-r--r--src/qt/res/movies/spinner-032.pngbin0 -> 2345 bytes
-rw-r--r--src/qt/res/movies/spinner-033.pngbin0 -> 2401 bytes
-rw-r--r--src/qt/res/movies/spinner-034.pngbin0 -> 2422 bytes
-rw-r--r--src/qt/res/movies/spinner-035.pngbin0 -> 2406 bytes
-rw-r--r--src/qt/res/spinner.pngbin0 -> 16636 bytes
-rw-r--r--src/qt/res/src/bitcoin.svg58
-rw-r--r--src/qt/res/src/clock_0.svg14
-rw-r--r--src/qt/res/src/clock_1.svg13
-rw-r--r--src/qt/res/src/clock_2.svg14
-rw-r--r--src/qt/res/src/clock_3.svg15
-rw-r--r--src/qt/res/src/clock_4.svg18
-rw-r--r--src/qt/res/src/connect-0.svg11
-rw-r--r--src/qt/res/src/connect-1.svg21
-rw-r--r--src/qt/res/src/connect-2.svg22
-rw-r--r--src/qt/res/src/connect-3.svg16
-rw-r--r--src/qt/res/src/mine.svg12
-rw-r--r--src/qt/res/src/qt.svg25
-rw-r--r--src/qt/res/src/tx_in.svg9
-rw-r--r--src/qt/res/src/tx_inout.svg11
-rw-r--r--src/qt/res/src/verify.svg14
-rw-r--r--src/qt/rpcconsole.cpp661
-rw-r--r--src/qt/rpcconsole.h103
-rw-r--r--src/qt/scicon.cpp98
-rw-r--r--src/qt/scicon.h24
-rw-r--r--src/qt/sendcoinsdialog.cpp816
-rw-r--r--src/qt/sendcoinsdialog.h101
-rw-r--r--src/qt/sendcoinsentry.cpp266
-rw-r--r--src/qt/sendcoinsentry.h71
-rw-r--r--src/qt/signverifymessagedialog.cpp283
-rw-r--r--src/qt/signverifymessagedialog.h51
-rw-r--r--src/qt/splashscreen.cpp202
-rw-r--r--src/qt/splashscreen.h49
-rw-r--r--src/qt/test/Makefile6
-rw-r--r--src/qt/test/paymentrequestdata.h460
-rw-r--r--src/qt/test/paymentservertests.cpp210
-rw-r--r--src/qt/test/paymentservertests.h35
-rw-r--r--src/qt/test/test_main.cpp49
-rw-r--r--src/qt/test/uritests.cpp66
-rw-r--r--src/qt/test/uritests.h19
-rw-r--r--src/qt/trafficgraphwidget.cpp175
-rw-r--r--src/qt/trafficgraphwidget.h48
-rw-r--r--src/qt/transactiondesc.cpp320
-rw-r--r--src/qt/transactiondesc.h31
-rw-r--r--src/qt/transactiondescdialog.cpp24
-rw-r--r--src/qt/transactiondescdialog.h31
-rw-r--r--src/qt/transactionfilterproxy.cpp114
-rw-r--r--src/qt/transactionfilterproxy.h68
-rw-r--r--src/qt/transactionrecord.cpp270
-rw-r--r--src/qt/transactionrecord.h143
-rw-r--r--src/qt/transactiontablemodel.cpp733
-rw-r--r--src/qt/transactiontablemodel.h114
-rw-r--r--src/qt/transactionview.cpp536
-rw-r--r--src/qt/transactionview.h115
-rw-r--r--src/qt/utilitydialog.cpp173
-rw-r--r--src/qt/utilitydialog.h52
-rw-r--r--src/qt/walletframe.cpp196
-rw-r--r--src/qt/walletframe.h80
-rw-r--r--src/qt/walletmodel.cpp663
-rw-r--r--src/qt/walletmodel.h268
-rw-r--r--src/qt/walletmodeltransaction.cpp99
-rw-r--r--src/qt/walletmodeltransaction.h47
-rw-r--r--src/qt/walletview.cpp312
-rw-r--r--src/qt/walletview.h119
-rw-r--r--src/qt/winshutdownmonitor.cpp70
-rw-r--r--src/qt/winshutdownmonitor.h29
-rw-r--r--src/random.cpp139
-rw-r--r--src/random.h49
-rw-r--r--src/rest.cpp573
-rw-r--r--src/reverselock.h31
-rw-r--r--src/rpcblockchain.cpp767
-rw-r--r--src/rpcclient.cpp146
-rw-r--r--src/rpcclient.h15
-rw-r--r--src/rpcmining.cpp728
-rw-r--r--src/rpcmisc.cpp397
-rw-r--r--src/rpcnet.cpp445
-rw-r--r--src/rpcprotocol.cpp290
-rw-r--r--src/rpcprotocol.h168
-rw-r--r--src/rpcrawtransaction.cpp808
-rw-r--r--src/rpcserver.cpp1038
-rw-r--r--src/rpcserver.h246
-rw-r--r--src/scheduler.cpp131
-rw-r--r--src/scheduler.h83
-rw-r--r--src/script/bitcoinconsensus.cpp91
-rw-r--r--src/script/bitcoinconsensus.h69
-rw-r--r--src/script/interpreter.cpp1229
-rw-r--r--src/script/interpreter.h131
-rw-r--r--src/script/script.cpp262
-rw-r--r--src/script/script.h612
-rw-r--r--src/script/script_error.cpp75
-rw-r--r--src/script/script_error.h62
-rw-r--r--src/script/sigcache.cpp90
-rw-r--r--src/script/sigcache.h26
-rw-r--r--src/script/sign.cpp277
-rw-r--r--src/script/sign.h59
-rw-r--r--src/script/standard.cpp318
-rw-r--r--src/script/standard.h97
-rw-r--r--src/secp256k1/.gitignore37
-rw-r--r--src/secp256k1/.travis.yml59
-rw-r--r--src/secp256k1/COPYING19
-rw-r--r--src/secp256k1/Makefile.am77
-rw-r--r--src/secp256k1/README.md61
-rw-r--r--src/secp256k1/TODO3
-rwxr-xr-xsrc/secp256k1/autogen.sh3
-rw-r--r--src/secp256k1/build-aux/m4/bitcoin_secp.m461
-rw-r--r--src/secp256k1/configure.ac330
-rw-r--r--src/secp256k1/include/secp256k1.h347
-rw-r--r--src/secp256k1/libsecp256k1.pc.in13
-rw-r--r--src/secp256k1/obj/.gitignore0
-rw-r--r--src/secp256k1/src/bench.h56
-rw-r--r--src/secp256k1/src/bench_internal.c318
-rw-r--r--src/secp256k1/src/bench_recover.c51
-rw-r--r--src/secp256k1/src/bench_sign.c50
-rw-r--r--src/secp256k1/src/bench_verify.c56
-rw-r--r--src/secp256k1/src/ecdsa.h24
-rw-r--r--src/secp256k1/src/ecdsa_impl.h263
-rw-r--r--src/secp256k1/src/eckey.h26
-rw-r--r--src/secp256k1/src/eckey_impl.h202
-rw-r--r--src/secp256k1/src/ecmult.h31
-rw-r--r--src/secp256k1/src/ecmult_gen.h43
-rw-r--r--src/secp256k1/src/ecmult_gen_impl.h184
-rw-r--r--src/secp256k1/src/ecmult_impl.h317
-rw-r--r--src/secp256k1/src/field.h119
-rw-r--r--src/secp256k1/src/field_10x26.h47
-rw-r--r--src/secp256k1/src/field_10x26_impl.h1136
-rw-r--r--src/secp256k1/src/field_5x52.h47
-rw-r--r--src/secp256k1/src/field_5x52_asm_impl.h502
-rw-r--r--src/secp256k1/src/field_5x52_impl.h454
-rw-r--r--src/secp256k1/src/field_5x52_int128_impl.h277
-rw-r--r--src/secp256k1/src/field_impl.h263
-rw-r--r--src/secp256k1/src/group.h121
-rw-r--r--src/secp256k1/src/group_impl.h443
-rw-r--r--src/secp256k1/src/hash.h41
-rw-r--r--src/secp256k1/src/hash_impl.h293
-rw-r--r--src/secp256k1/src/java/org/bitcoin/NativeSecp256k1.java60
-rw-r--r--src/secp256k1/src/java/org_bitcoin_NativeSecp256k1.c23
-rw-r--r--src/secp256k1/src/java/org_bitcoin_NativeSecp256k1.h21
-rw-r--r--src/secp256k1/src/num.h68
-rw-r--r--src/secp256k1/src/num_gmp.h20
-rw-r--r--src/secp256k1/src/num_gmp_impl.h260
-rw-r--r--src/secp256k1/src/num_impl.h24
-rw-r--r--src/secp256k1/src/scalar.h93
-rw-r--r--src/secp256k1/src/scalar_4x64.h19
-rw-r--r--src/secp256k1/src/scalar_4x64_impl.h920
-rw-r--r--src/secp256k1/src/scalar_8x32.h19
-rw-r--r--src/secp256k1/src/scalar_8x32_impl.h681
-rw-r--r--src/secp256k1/src/scalar_impl.h327
-rw-r--r--src/secp256k1/src/secp256k1.c419
-rw-r--r--src/secp256k1/src/testrand.h28
-rw-r--r--src/secp256k1/src/testrand_impl.h60
-rw-r--r--src/secp256k1/src/tests.c2083
-rw-r--r--src/secp256k1/src/util.h104
-rw-r--r--src/serialize.h860
-rw-r--r--src/streams.h572
-rw-r--r--src/support/allocators/secure.h62
-rw-r--r--src/support/allocators/zeroafterfree.h48
-rw-r--r--src/support/cleanse.cpp13
-rw-r--r--src/support/cleanse.h13
-rw-r--r--src/support/pagelocker.cpp70
-rw-r--r--src/support/pagelocker.h177
-rw-r--r--src/sync.cpp147
-rw-r--r--src/sync.h280
-rw-r--r--src/test/Checkpoints_tests.cpp41
-rw-r--r--src/test/DoS_tests.cpp201
-rw-r--r--src/test/Makefile6
-rw-r--r--src/test/README.md21
-rw-r--r--src/test/accounting_tests.cpp141
-rw-r--r--src/test/alert_tests.cpp257
-rw-r--r--src/test/allocator_tests.cpp120
-rw-r--r--src/test/arith_uint256_tests.cpp567
-rw-r--r--src/test/base32_tests.cpp25
-rw-r--r--src/test/base58_tests.cpp280
-rw-r--r--src/test/base64_tests.cpp25
-rw-r--r--src/test/bctest.py54
-rw-r--r--src/test/bignum.h180
-rw-r--r--src/test/bip32_tests.cpp122
-rwxr-xr-xsrc/test/bitcoin-util-test.py13
-rw-r--r--src/test/bloom_tests.cpp540
-rw-r--r--src/test/buildenv.py.in2
-rw-r--r--src/test/checkblock_tests.cpp65
-rw-r--r--src/test/coins_tests.cpp200
-rw-r--r--src/test/compress_tests.cpp65
-rw-r--r--src/test/crypto_tests.cpp251
-rw-r--r--src/test/data/README.md12
-rw-r--r--src/test/data/alertTests.rawbin0 -> 1279 bytes
-rw-r--r--src/test/data/base58_encode_decode.json14
-rw-r--r--src/test/data/base58_keys_invalid.json152
-rw-r--r--src/test/data/base58_keys_valid.json452
-rw-r--r--src/test/data/bitcoin-util-test.json60
-rw-r--r--src/test/data/blanktx.hex1
-rw-r--r--src/test/data/script_invalid.json814
-rw-r--r--src/test/data/script_valid.json911
-rw-r--r--src/test/data/sighash.json503
-rw-r--r--src/test/data/tt-delin1-out.hex1
-rw-r--r--src/test/data/tt-delout1-out.hex1
-rw-r--r--src/test/data/tt-locktime317000-out.hex1
-rw-r--r--src/test/data/tx394b54bb.hex1
-rw-r--r--src/test/data/tx_invalid.json197
-rw-r--r--src/test/data/tx_valid.json233
-rw-r--r--src/test/data/txcreate1.hex1
-rw-r--r--src/test/data/txcreate2.hex1
-rw-r--r--src/test/data/txcreatesign.hex1
-rw-r--r--src/test/getarg_tests.cpp162
-rw-r--r--src/test/hash_tests.cpp50
-rw-r--r--src/test/key_tests.cpp191
-rw-r--r--src/test/main_tests.cpp76
-rw-r--r--src/test/mempool_tests.cpp104
-rw-r--r--src/test/miner_tests.cpp271
-rw-r--r--src/test/mruset_tests.cpp81
-rw-r--r--src/test/multisig_tests.cpp320
-rw-r--r--src/test/netbase_tests.cpp165
-rw-r--r--src/test/pmt_tests.cpp127
-rw-r--r--src/test/policyestimator_tests.cpp186
-rw-r--r--src/test/pow_tests.cpp96
-rw-r--r--src/test/reverselock_tests.cpp64
-rw-r--r--src/test/rpc_tests.cpp176
-rw-r--r--src/test/rpc_wallet_tests.cpp221
-rw-r--r--src/test/sanity_tests.cpp20
-rw-r--r--src/test/scheduler_tests.cpp119
-rw-r--r--src/test/script_P2SH_tests.cpp382
-rw-r--r--src/test/script_tests.cpp988
-rw-r--r--src/test/scriptnum_tests.cpp199
-rw-r--r--src/test/serialize_tests.cpp279
-rw-r--r--src/test/sighash_tests.cpp217
-rw-r--r--src/test/sigopcount_tests.cpp67
-rw-r--r--src/test/skiplist_tests.cpp103
-rw-r--r--src/test/test_bitcoin.cpp102
-rw-r--r--src/test/test_bitcoin.h30
-rw-r--r--src/test/timedata_tests.cpp39
-rw-r--r--src/test/transaction_tests.cpp381
-rw-r--r--src/test/uint256_tests.cpp269
-rw-r--r--src/test/univalue_tests.cpp276
-rw-r--r--src/test/util_tests.cpp358
-rw-r--r--src/threadsafety.h55
-rw-r--r--src/timedata.cpp116
-rw-r--r--src/timedata.h76
-rw-r--r--src/tinyformat.h1013
-rw-r--r--src/txdb.cpp241
-rw-r--r--src/txdb.h65
-rw-r--r--src/txmempool.cpp421
-rw-r--r--src/txmempool.h182
-rw-r--r--src/ui_interface.h102
-rw-r--r--src/uint256.cpp146
-rw-r--r--src/uint256.h158
-rw-r--r--src/undo.h85
-rw-r--r--src/univalue/gen.cpp78
-rw-r--r--src/univalue/univalue.cpp211
-rw-r--r--src/univalue/univalue.h155
-rw-r--r--src/univalue/univalue_escapes.h262
-rw-r--r--src/univalue/univalue_read.cpp390
-rw-r--r--src/univalue/univalue_write.cpp125
-rw-r--r--src/util.cpp765
-rw-r--r--src/util.h233
-rw-r--r--src/utilmoneystr.cpp81
-rw-r--r--src/utilmoneystr.h21
-rw-r--r--src/utilstrencodings.cpp499
-rw-r--r--src/utilstrencodings.h98
-rw-r--r--src/utiltime.cpp69
-rw-r--r--src/utiltime.h20
-rw-r--r--src/validationinterface.cpp47
-rw-r--r--src/validationinterface.h62
-rw-r--r--src/version.h37
-rw-r--r--src/wallet/crypter.cpp292
-rw-r--r--src/wallet/crypter.h196
-rw-r--r--src/wallet/db.cpp462
-rw-r--r--src/wallet/db.h309
-rw-r--r--src/wallet/rpcdump.cpp425
-rw-r--r--src/wallet/rpcwallet.cpp2345
-rw-r--r--src/wallet/test/wallet_tests.cpp310
-rw-r--r--src/wallet/wallet.cpp2759
-rw-r--r--src/wallet/wallet.h874
-rw-r--r--src/wallet/wallet_ismine.cpp91
-rw-r--r--src/wallet/wallet_ismine.h29
-rw-r--r--src/wallet/walletdb.cpp987
-rw-r--r--src/wallet/walletdb.h143
1158 files changed, 294842 insertions, 125 deletions
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000000..c9cf4a7d9c
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1 @@
+src/clientversion.cpp export-subst
diff --git a/.gitignore b/.gitignore
index 71d87a4eeb..9f1e522803 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,13 +1,115 @@
-build_config.mk
-*.a
+*.tar.gz
+
+*.exe
+src/bitcoin
+src/bitcoind
+src/bitcoin-cli
+src/bitcoin-tx
+src/test/test_bitcoin
+src/qt/test/test_bitcoin-qt
+
+# autoreconf
+Makefile.in
+aclocal.m4
+autom4te.cache/
+build-aux/config.guess
+build-aux/config.sub
+build-aux/depcomp
+build-aux/install-sh
+build-aux/ltmain.sh
+build-aux/m4/libtool.m4
+build-aux/m4/lt~obsolete.m4
+build-aux/m4/ltoptions.m4
+build-aux/m4/ltsugar.m4
+build-aux/m4/ltversion.m4
+build-aux/missing
+build-aux/compile
+build-aux/test-driver
+config.log
+config.status
+configure
+libtool
+src/config/bitcoin-config.h
+src/config/bitcoin-config.h.in
+src/config/stamp-h1
+share/setup.nsi
+share/qt/Info.plist
+
+src/univalue/gen
+
+src/qt/*.moc
+src/qt/moc_*.cpp
+src/qt/forms/ui_*.h
+
+src/qt/test/moc*.cpp
+
+.deps
+.dirstamp
+.libs
+.*.swp
+*.*~*
+*.bak
+*.rej
+*.orig
+*.pyc
*.o
-*.dylib*
-*.so
-*.so.*
-*_test
-db_bench
-leveldbutil
-Release
-Debug
-Benchmark
-vs2010.*
+*.o-*
+*.patch
+.bitcoin
+*.a
+*.pb.cc
+*.pb.h
+
+*.log
+*.trs
+*.dmg
+
+*.json.h
+*.raw.h
+
+#libtool object files
+*.lo
+*.la
+
+# Compilation and Qt preprocessor part
+*.qm
+Makefile
+bitcoin-qt
+Bitcoin-Qt.app
+
+# Unit-tests
+Makefile.test
+bitcoin-qt_test
+src/test/buildenv.py
+
+# Resources cpp
+qrc_*.cpp
+
+# Qt creator
+*.pro.user
+
+# Mac specific
+.DS_Store
+build
+
+#lcov
+*.gcno
+/*.info
+test_bitcoin.coverage/
+total.coverage/
+coverage_percent.txt
+
+#build tests
+linux-coverage-build
+linux-build
+win32-build
+qa/pull-tester/run-bitcoind-for-test.sh
+qa/pull-tester/tests-config.sh
+qa/pull-tester/cache/*
+qa/pull-tester/test.*/*
+
+!src/leveldb*/Makefile
+
+/doc/doxygen/
+
+libbitcoinconsensus.pc
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000000..0537d69a46
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,72 @@
+# errata:
+# - A travis bug causes caches to trample eachother when using the same
+# compiler key (which we don't use anyway). This is worked around for now by
+# replacing the "compilers" with a build name prefixed by the no-op ":"
+# command. See: https://github.com/travis-ci/casher/issues/6
+
+os: linux
+language: cpp
+compiler: gcc
+env:
+ global:
+ - MAKEJOBS=-j3
+ - RUN_TESTS=false
+ - BOOST_TEST_RANDOM=1$TRAVIS_BUILD_ID
+ - CCACHE_SIZE=100M
+ - CCACHE_TEMPDIR=/tmp/.ccache-temp
+ - CCACHE_COMPRESS=1
+ - BASE_OUTDIR=$TRAVIS_BUILD_DIR/out
+ - SDK_URL=https://bitcoincore.org/depends-sources/sdks
+ - PYTHON_DEBUG=1
+ - WINEDEBUG=fixme-all
+cache:
+ apt: true
+ directories:
+ - depends/built
+ - depends/sdk-sources
+ - $HOME/.ccache
+matrix:
+ fast_finish: true
+ include:
+ - compiler: ": ARM"
+ env: HOST=arm-linux-gnueabihf PACKAGES="g++-arm-linux-gnueabihf" DEP_OPTS="NO_QT=1" GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports"
+ - compiler: ": Win32"
+ env: HOST=i686-w64-mingw32 PACKAGES="nsis gcc-mingw-w64-i686 g++-mingw-w64-i686 binutils-mingw-w64-i686 mingw-w64-dev wine bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui --enable-reduce-exports" MAKEJOBS="-j2"
+ - compiler: ": 32-bit + dash"
+ env: HOST=i686-pc-linux-gnu PACKAGES="g++-multilib bc" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++" USE_SHELL="/bin/dash"
+ - compiler: ": Win64"
+ env: HOST=x86_64-w64-mingw32 PACKAGES="nsis gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 binutils-mingw-w64-x86-64 mingw-w64-dev wine bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui --enable-reduce-exports" MAKEJOBS="-j2"
+ - compiler: ": bitcoind"
+ env: HOST=x86_64-unknown-linux-gnu PACKAGES="bc" DEP_OPTS="NO_QT=1 NO_UPNP=1 DEBUG=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports CPPFLAGS=-DDEBUG_LOCKORDER"
+ - compiler: ": No wallet"
+ env: HOST=x86_64-unknown-linux-gnu DEP_OPTS="NO_WALLET=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports"
+ - compiler: ": Cross-Mac"
+ env: HOST=x86_64-apple-darwin11 PACKAGES="cmake libcap-dev libz-dev libbz2-dev" BITCOIN_CONFIG="--enable-reduce-exports" OSX_SDK=10.9 GOAL="deploy"
+ exclude:
+ - compiler: gcc
+install:
+ - if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get update; fi
+ - if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get install --no-install-recommends --no-upgrade -qq $PACKAGES; fi
+before_script:
+ - unset CC; unset CXX
+ - mkdir -p depends/SDKs depends/sdk-sources
+ - if [ -n "$OSX_SDK" -a ! -f depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then wget $SDK_URL/MacOSX${OSX_SDK}.sdk.tar.gz -O depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz; fi
+ - if [ -n "$OSX_SDK" -a -f depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then tar -C depends/SDKs -xf depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz; fi
+ - make $MAKEJOBS -C depends HOST=$HOST $DEP_OPTS
+script:
+ - if [ -n "$USE_SHELL" ]; then export CONFIG_SHELL="$USE_SHELL"; fi
+ - OUTDIR=$BASE_OUTDIR/$TRAVIS_PULL_REQUEST/$TRAVIS_JOB_NUMBER-$HOST
+ - BITCOIN_CONFIG_ALL="--disable-dependency-tracking --prefix=$TRAVIS_BUILD_DIR/depends/$HOST --bindir=$OUTDIR/bin --libdir=$OUTDIR/lib"
+ - depends/$HOST/native/bin/ccache --max-size=$CCACHE_SIZE
+ - if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then export CCACHE_READONLY=1; fi
+ - test -n "$USE_SHELL" && eval '"$USE_SHELL" -c "./autogen.sh"' || ./autogen.sh
+ - ./configure --cache-file=config.cache $BITCOIN_CONFIG_ALL $BITCOIN_CONFIG || ( cat config.log && false)
+ - make distdir PACKAGE=bitcoin VERSION=$HOST
+ - cd bitcoin-$HOST
+ - ./configure --cache-file=../config.cache $BITCOIN_CONFIG_ALL $BITCOIN_CONFIG || ( cat config.log && false)
+ - make $MAKEJOBS $GOAL || ( echo "Build failure. Verbose build follows." && make $GOAL V=1 ; false )
+ - export LD_LIBRARY_PATH=$TRAVIS_BUILD_DIR/depends/$HOST/lib
+ - if [ "$RUN_TESTS" = "true" ]; then make check; fi
+ - if [ "$RUN_TESTS" = "true" ]; then qa/pull-tester/rpc-tests.sh; fi
+after_script:
+ - if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then (echo "Upload goes here. Something like: scp -r $BASE_OUTDIR server" || echo "upload failed"); fi
diff --git a/.tx/config b/.tx/config
new file mode 100644
index 0000000000..6c534f06e4
--- /dev/null
+++ b/.tx/config
@@ -0,0 +1,7 @@
+[main]
+host = https://www.transifex.com
+
+[bitcoin.qt-translation-011x]
+file_filter = src/qt/locale/bitcoin_<lang>.ts
+source_file = src/qt/locale/bitcoin_en.ts
+source_lang = en
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000000..cae0f5b6f4
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,19 @@
+Copyright (c) 2009-2015 The Bitcoin Core 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 0000000000..07ee48427c
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,5 @@
+Building Bitcoin
+
+See doc/build-*.md for instructions on building bitcoind,
+the intended-for-services, no-graphical-interface, reference
+implementation of Bitcoin. \ No newline at end of file
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000000..ab68d8fa6d
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,214 @@
+ACLOCAL_AMFLAGS = -I build-aux/m4
+SUBDIRS = src
+.PHONY: deploy FORCE
+
+GZIP_ENV="-9n"
+
+if BUILD_BITCOIN_LIBS
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = libbitcoinconsensus.pc
+endif
+
+BITCOIND_BIN=$(top_builddir)/src/bitcoind$(EXEEXT)
+BITCOIN_QT_BIN=$(top_builddir)/src/qt/bitcoin-qt$(EXEEXT)
+BITCOIN_CLI_BIN=$(top_builddir)/src/bitcoin-cli$(EXEEXT)
+BITCOIN_WIN_INSTALLER=$(PACKAGE)-$(PACKAGE_VERSION)-win$(WINDOWS_BITS)-setup$(EXEEXT)
+
+OSX_APP=Bitcoin-Qt.app
+OSX_DMG=Bitcoin-Core.dmg
+OSX_BACKGROUND_IMAGE=background.tiff
+OSX_DEPLOY_SCRIPT=$(top_srcdir)/contrib/macdeploy/macdeployqtplus
+OSX_FANCY_PLIST=$(top_srcdir)/contrib/macdeploy/fancy.plist
+OSX_BASE_LPROJ_DIR=$(top_srcdir)/contrib/macdeploy/Base.lproj/InfoPlist.strings
+OSX_INSTALLER_ICONS=$(top_srcdir)/src/qt/res/icons/bitcoin.icns
+OSX_PLIST=$(top_srcdir)/share/qt/Info.plist #not installed
+OSX_QT_TRANSLATIONS = da,de,es,hu,ru,uk,zh_CN,zh_TW
+
+DIST_DOCS = $(wildcard doc/*.md) $(wildcard doc/release-notes/*.md)
+
+WINDOWS_PACKAGING = $(top_srcdir)/share/pixmaps/bitcoin.ico \
+ $(top_srcdir)/share/pixmaps/nsis-header.bmp \
+ $(top_srcdir)/share/pixmaps/nsis-wizard.bmp \
+ $(top_srcdir)/doc/README_windows.txt
+
+OSX_PACKAGING = $(OSX_DEPLOY_SCRIPT) $(OSX_FANCY_PLIST) $(OSX_INSTALLER_ICONS) $(OSX_BASE_LPROJ_DIR) \
+ $(top_srcdir)/contrib/macdeploy/$(OSX_BACKGROUND_IMAGE) \
+ $(top_srcdir)/contrib/macdeploy/DS_Store \
+ $(top_srcdir)/contrib/macdeploy/detached-sig-apply.sh \
+ $(top_srcdir)/contrib/macdeploy/detached-sig-create.sh
+
+COVERAGE_INFO = baseline_filtered_combined.info baseline.info block_test.info \
+ leveldb_baseline.info test_bitcoin_filtered.info total_coverage.info \
+ baseline_filtered.info block_test_filtered.info \
+ leveldb_baseline_filtered.info test_bitcoin_coverage.info test_bitcoin.info
+
+dist-hook:
+ -$(MAKE) -C $(top_distdir)/src/leveldb clean
+ -$(MAKE) -C $(top_distdir)/src/secp256k1 distclean
+ -$(GIT) archive --format=tar HEAD -- src/clientversion.cpp | $(AMTAR) -C $(top_distdir) -xf -
+
+distcheck-hook:
+ $(MKDIR_P) $(top_distdir)/_build/src/leveldb
+ cp -rf $(top_srcdir)/src/leveldb/* $(top_distdir)/_build/src/leveldb/
+ -$(MAKE) -C $(top_distdir)/_build/src/leveldb clean
+
+distcleancheck:
+ @:
+
+$(BITCOIN_WIN_INSTALLER): all-recursive
+ $(MKDIR_P) $(top_builddir)/release
+ STRIPPROG="$(STRIP)" $(INSTALL_STRIP_PROGRAM) $(BITCOIND_BIN) $(top_builddir)/release
+ STRIPPROG="$(STRIP)" $(INSTALL_STRIP_PROGRAM) $(BITCOIN_QT_BIN) $(top_builddir)/release
+ STRIPPROG="$(STRIP)" $(INSTALL_STRIP_PROGRAM) $(BITCOIN_CLI_BIN) $(top_builddir)/release
+ @test -f $(MAKENSIS) && $(MAKENSIS) -V2 $(top_builddir)/share/setup.nsi || \
+ echo error: could not build $@
+ @echo built $@
+
+$(if $(findstring src/,$(MAKECMDGOALS)),$(MAKECMDGOALS), none): FORCE
+ $(MAKE) -C src $(patsubst src/%,%,$@)
+
+$(OSX_APP)/Contents/PkgInfo:
+ $(MKDIR_P) $(@D)
+ @echo "APPL????" > $@
+
+$(OSX_APP)/Contents/Resources/empty.lproj:
+ $(MKDIR_P) $(@D)
+ @touch $@
+
+$(OSX_APP)/Contents/Info.plist: $(OSX_PLIST)
+ $(MKDIR_P) $(@D)
+ $(INSTALL_DATA) $< $@
+
+$(OSX_APP)/Contents/Resources/bitcoin.icns: $(OSX_INSTALLER_ICONS)
+ $(MKDIR_P) $(@D)
+ $(INSTALL_DATA) $< $@
+
+$(OSX_APP)/Contents/MacOS/Bitcoin-Qt: $(BITCOIN_QT_BIN)
+ $(MKDIR_P) $(@D)
+ STRIPPROG="$(STRIP)" $(INSTALL_STRIP_PROGRAM) $< $@
+
+$(OSX_APP)/Contents/Resources/Base.lproj/InfoPlist.strings: $(OSX_BASE_LPROJ_DIR)
+ $(MKDIR_P) $(@D)
+ $(INSTALL_DATA) $< $@
+
+OSX_APP_BUILT=$(OSX_APP)/Contents/PkgInfo $(OSX_APP)/Contents/Resources/empty.lproj \
+ $(OSX_APP)/Contents/Resources/bitcoin.icns $(OSX_APP)/Contents/Info.plist \
+ $(OSX_APP)/Contents/MacOS/Bitcoin-Qt $(OSX_APP)/Contents/Resources/Base.lproj/InfoPlist.strings
+
+if BUILD_DARWIN
+$(OSX_DMG): $(OSX_APP_BUILT) $(OSX_PACKAGING)
+ $(OSX_DEPLOY_SCRIPT) $(OSX_APP) -add-qt-tr $(OSX_QT_TRANSLATIONS) -translations-dir=$(QT_TRANSLATION_DIR) -dmg -fancy $(OSX_FANCY_PLIST) -verbose 2
+
+deploydir: $(OSX_DMG)
+else
+APP_DIST_DIR=$(top_builddir)/dist
+APP_DIST_EXTRAS=$(APP_DIST_DIR)/.background/$(OSX_BACKGROUND_IMAGE) $(APP_DIST_DIR)/.DS_Store $(APP_DIST_DIR)/Applications
+
+$(APP_DIST_DIR)/Applications:
+ @rm -f $@
+ @cd $(@D); $(LN_S) /Applications $(@F)
+
+$(APP_DIST_EXTRAS): $(APP_DIST_DIR)/$(OSX_APP)/Contents/MacOS/Bitcoin-Qt
+
+$(OSX_DMG): $(APP_DIST_EXTRAS)
+ $(GENISOIMAGE) -no-cache-inodes -D -l -probe -V "Bitcoin-Core" -no-pad -r -apple -o $@ dist
+
+$(APP_DIST_DIR)/.background/$(OSX_BACKGROUND_IMAGE): contrib/macdeploy/$(OSX_BACKGROUND_IMAGE)
+ $(MKDIR_P) $(@D)
+ $(INSTALL) $< $@
+$(APP_DIST_DIR)/.DS_Store: contrib/macdeploy/DS_Store
+ $(INSTALL) $< $@
+
+$(APP_DIST_DIR)/$(OSX_APP)/Contents/MacOS/Bitcoin-Qt: $(OSX_APP_BUILT) $(OSX_PACKAGING)
+ INSTALLNAMETOOL=$(INSTALLNAMETOOL) OTOOL=$(OTOOL) STRIP=$(STRIP) $(OSX_DEPLOY_SCRIPT) $(OSX_APP) -translations-dir=$(QT_TRANSLATION_DIR) -add-qt-tr $(OSX_QT_TRANSLATIONS) -verbose 2
+
+deploydir: $(APP_DIST_EXTRAS)
+endif
+
+if TARGET_DARWIN
+appbundle: $(OSX_APP_BUILT)
+deploy: $(OSX_DMG)
+endif
+if TARGET_WINDOWS
+deploy: $(BITCOIN_WIN_INSTALLER)
+endif
+
+$(BITCOIN_QT_BIN): FORCE
+ $(MAKE) -C src qt/$(@F)
+
+$(BITCOIND_BIN): FORCE
+ $(MAKE) -C src $(@F)
+
+$(BITCOIN_CLI_BIN): FORCE
+ $(MAKE) -C src $(@F)
+
+if USE_LCOV
+
+baseline.info:
+ $(LCOV) -c -i -d $(abs_builddir)/src -o $@
+
+baseline_filtered.info: baseline.info
+ $(LCOV) -r $< "/usr/include/*" -o $@
+
+leveldb_baseline.info: baseline_filtered.info
+ $(LCOV) -c -i -d $(abs_builddir)/src/leveldb -b $(abs_builddir)/src/leveldb -o $@
+
+leveldb_baseline_filtered.info: leveldb_baseline.info
+ $(LCOV) -r $< "/usr/include/*" -o $@
+
+baseline_filtered_combined.info: leveldb_baseline_filtered.info baseline_filtered.info
+ $(LCOV) -a leveldb_baseline_filtered.info -a baseline_filtered.info -o $@
+
+test_bitcoin.info: baseline_filtered_combined.info
+ $(MAKE) -C src/ check
+ $(LCOV) -c -d $(abs_builddir)/src -t test_bitcoin -o $@
+ $(LCOV) -z -d $(abs_builddir)/src
+ $(LCOV) -z -d $(abs_builddir)/src/leveldb
+
+test_bitcoin_filtered.info: test_bitcoin.info
+ $(LCOV) -r $< "/usr/include/*" -o $@
+
+block_test.info: test_bitcoin_filtered.info
+ $(MKDIR_P) qa/tmp
+ -@TIMEOUT=15 qa/pull-tester/run-bitcoind-for-test.sh $(JAVA) -jar $(JAVA_COMPARISON_TOOL) qa/tmp/compTool 0
+ $(LCOV) -c -d $(abs_builddir)/src --t BitcoinJBlockTest -o $@
+ $(LCOV) -z -d $(abs_builddir)/src
+ $(LCOV) -z -d $(abs_builddir)/src/leveldb
+
+block_test_filtered.info: block_test.info
+ $(LCOV) -r $< "/usr/include/*" -o $@
+
+test_bitcoin_coverage.info: baseline_filtered_combined.info test_bitcoin_filtered.info
+ $(LCOV) -a baseline_filtered.info -a leveldb_baseline_filtered.info -a test_bitcoin_filtered.info -o $@
+
+total_coverage.info: baseline_filtered_combined.info test_bitcoin_filtered.info block_test_filtered.info
+ $(LCOV) -a baseline_filtered.info -a leveldb_baseline_filtered.info -a test_bitcoin_filtered.info -a block_test_filtered.info -o $@ | $(GREP) "\%" | $(AWK) '{ print substr($$3,2,50) "/" $$5 }' > coverage_percent.txt
+
+test_bitcoin.coverage/.dirstamp: test_bitcoin_coverage.info
+ $(GENHTML) -s $< -o $(@D)
+ @touch $@
+
+total.coverage/.dirstamp: total_coverage.info
+ $(GENHTML) -s $< -o $(@D)
+ @touch $@
+
+cov: test_bitcoin.coverage/.dirstamp total.coverage/.dirstamp
+
+endif
+
+if USE_COMPARISON_TOOL
+check-local:
+ $(MKDIR_P) qa/tmp
+ @qa/pull-tester/run-bitcoind-for-test.sh $(JAVA) -jar $(JAVA_COMPARISON_TOOL) qa/tmp/compTool $(COMPARISON_TOOL_REORG_TESTS) 2>&1
+endif
+
+dist_noinst_SCRIPTS = autogen.sh
+
+EXTRA_DIST = $(top_srcdir)/share/genbuild.sh qa/pull-tester/rpc-tests.sh qa/pull-tester/run-bitcoin-cli qa/rpc-tests $(DIST_DOCS) $(WINDOWS_PACKAGING) $(OSX_PACKAGING)
+
+CLEANFILES = $(OSX_DMG) $(BITCOIN_WIN_INSTALLER)
+
+.INTERMEDIATE: $(COVERAGE_INFO)
+
+clean-local:
+ rm -rf test_bitcoin.coverage/ total.coverage/ $(OSX_APP)
diff --git a/README.md b/README.md
index 480affb5ca..4fe6a87495 100644
--- a/README.md
+++ b/README.md
@@ -1,138 +1,85 @@
-**LevelDB is a fast key-value storage library written at Google that provides an ordered mapping from string keys to string values.**
-
-Authors: Sanjay Ghemawat (sanjay@google.com) and Jeff Dean (jeff@google.com)
-
-# Features
- * Keys and values are arbitrary byte arrays.
- * Data is stored sorted by key.
- * Callers can provide a custom comparison function to override the sort order.
- * The basic operations are `Put(key,value)`, `Get(key)`, `Delete(key)`.
- * Multiple changes can be made in one atomic batch.
- * Users can create a transient snapshot to get a consistent view of data.
- * Forward and backward iteration is supported over the data.
- * Data is automatically compressed using the [Snappy compression library](http://code.google.com/p/snappy).
- * External activity (file system operations etc.) is relayed through a virtual interface so users can customize the operating system interactions.
- * [Detailed documentation](http://htmlpreview.github.io/?https://github.com/google/leveldb/blob/master/doc/index.html) about how to use the library is included with the source code.
-
-
-# Limitations
- * This is not a SQL database. It does not have a relational data model, it does not support SQL queries, and it has no support for indexes.
- * Only a single process (possibly multi-threaded) can access a particular database at a time.
- * There is no client-server support builtin to the library. An application that needs such support will have to wrap their own server around the library.
-
-# Performance
-
-Here is a performance report (with explanations) from the run of the
-included db_bench program. The results are somewhat noisy, but should
-be enough to get a ballpark performance estimate.
-
-## Setup
+Bitcoin Core integration/staging tree
+=====================================
-We use a database with a million entries. Each entry has a 16 byte
-key, and a 100 byte value. Values used by the benchmark compress to
-about half their original size.
+[![Build Status](https://travis-ci.org/bitcoin/bitcoin.svg?branch=master)](https://travis-ci.org/bitcoin/bitcoin)
- LevelDB: version 1.1
- Date: Sun May 1 12:11:26 2011
- CPU: 4 x Intel(R) Core(TM)2 Quad CPU Q6600 @ 2.40GHz
- CPUCache: 4096 KB
- Keys: 16 bytes each
- Values: 100 bytes each (50 bytes after compression)
- Entries: 1000000
- Raw Size: 110.6 MB (estimated)
- File Size: 62.9 MB (estimated)
+https://www.bitcoin.org
-## Write performance
+What is Bitcoin?
+----------------
-The "fill" benchmarks create a brand new database, in either
-sequential, or random order. The "fillsync" benchmark flushes data
-from the operating system to the disk after every operation; the other
-write operations leave the data sitting in the operating system buffer
-cache for a while. The "overwrite" benchmark does random writes that
-update existing keys in the database.
+Bitcoin is an experimental new digital currency that enables instant payments to
+anyone, anywhere in the world. Bitcoin uses peer-to-peer technology to operate
+with no central authority: managing transactions and issuing money are carried
+out collectively by the network. Bitcoin Core is the name of open source
+software which enables the use of this currency.
- fillseq : 1.765 micros/op; 62.7 MB/s
- fillsync : 268.409 micros/op; 0.4 MB/s (10000 ops)
- fillrandom : 2.460 micros/op; 45.0 MB/s
- overwrite : 2.380 micros/op; 46.5 MB/s
+For more information, as well as an immediately useable, binary version of
+the Bitcoin Core software, see https://www.bitcoin.org/en/download.
-Each "op" above corresponds to a write of a single key/value pair.
-I.e., a random write benchmark goes at approximately 400,000 writes per second.
+License
+-------
-Each "fillsync" operation costs much less (0.3 millisecond)
-than a disk seek (typically 10 milliseconds). We suspect that this is
-because the hard disk itself is buffering the update in its memory and
-responding before the data has been written to the platter. This may
-or may not be safe based on whether or not the hard disk has enough
-power to save its memory in the event of a power failure.
+Bitcoin Core is released under the terms of the MIT license. See [COPYING](COPYING) for more
+information or see http://opensource.org/licenses/MIT.
-## Read performance
+Development process
+-------------------
-We list the performance of reading sequentially in both the forward
-and reverse direction, and also the performance of a random lookup.
-Note that the database created by the benchmark is quite small.
-Therefore the report characterizes the performance of leveldb when the
-working set fits in memory. The cost of reading a piece of data that
-is not present in the operating system buffer cache will be dominated
-by the one or two disk seeks needed to fetch the data from disk.
-Write performance will be mostly unaffected by whether or not the
-working set fits in memory.
+Developers work in their own trees, then submit pull requests when they think
+their feature or bug fix is ready.
- readrandom : 16.677 micros/op; (approximately 60,000 reads per second)
- readseq : 0.476 micros/op; 232.3 MB/s
- readreverse : 0.724 micros/op; 152.9 MB/s
+If it is a simple/trivial/non-controversial change, then one of the Bitcoin
+development team members simply pulls it.
-LevelDB compacts its underlying storage data in the background to
-improve read performance. The results listed above were done
-immediately after a lot of random writes. The results after
-compactions (which are usually triggered automatically) are better.
+If it is a *more complicated or potentially controversial* change, then the patch
+submitter will be asked to start a discussion (if they haven't already) on the
+[mailing list](https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev)
- readrandom : 11.602 micros/op; (approximately 85,000 reads per second)
- readseq : 0.423 micros/op; 261.8 MB/s
- readreverse : 0.663 micros/op; 166.9 MB/s
+The patch will be accepted if there is broad consensus that it is a good thing.
+Developers should expect to rework and resubmit patches if the code doesn't
+match the project's coding conventions (see [doc/developer-notes.md](doc/developer-notes.md)) or are
+controversial.
-Some of the high cost of reads comes from repeated decompression of blocks
-read from disk. If we supply enough cache to the leveldb so it can hold the
-uncompressed blocks in memory, the read performance improves again:
+The `master` branch is regularly built and tested, but is not guaranteed to be
+completely stable. [Tags](https://github.com/bitcoin/bitcoin/tags) are created
+regularly to indicate new official, stable release versions of Bitcoin.
- readrandom : 9.775 micros/op; (approximately 100,000 reads per second before compaction)
- readrandom : 5.215 micros/op; (approximately 190,000 reads per second after compaction)
+Testing
+-------
-## Repository contents
+Testing and code review is the bottleneck for development; we get more pull
+requests than we can review and test on short notice. Please be patient and help out by testing
+other people's pull requests, and remember this is a security-critical project where any mistake might cost people
+lots of money.
-See doc/index.html for more explanation. See doc/impl.html for a brief overview of the implementation.
+### Automated Testing
-The public interface is in include/*.h. Callers should not include or
-rely on the details of any other header files in this package. Those
-internal APIs may be changed without warning.
+Developers are strongly encouraged to write unit tests for new code, and to
+submit new unit tests for old code. Unit tests can be compiled and run (assuming they weren't disabled in configure) with: `make check`
-Guide to header files:
+Every pull request is built for both Windows and Linux on a dedicated server,
+and unit and sanity tests are automatically run. The binaries produced may be
+used for manual QA testing — a link to them will appear in a comment on the
+pull request posted by [BitcoinPullTester](https://github.com/BitcoinPullTester). See https://github.com/TheBlueMatt/test-scripts
+for the build/test scripts.
-* **include/db.h**: Main interface to the DB: Start here
+### Manual Quality Assurance (QA) Testing
-* **include/options.h**: Control over the behavior of an entire database,
-and also control over the behavior of individual reads and writes.
+Large changes should have a test plan, and should be tested by somebody other
+than the developer who wrote the code.
+See https://github.com/bitcoin/QA/ for how to create a test plan.
-* **include/comparator.h**: Abstraction for user-specified comparison function.
-If you want just bytewise comparison of keys, you can use the default
-comparator, but clients can write their own comparator implementations if they
-want custom ordering (e.g. to handle different character encodings, etc.)
+Translations
+------------
-* **include/iterator.h**: Interface for iterating over data. You can get
-an iterator from a DB object.
+Changes to translations as well as new translations can be submitted to
+[Bitcoin Core's Transifex page](https://www.transifex.com/projects/p/bitcoin/).
-* **include/write_batch.h**: Interface for atomically applying multiple
-updates to a database.
+Translations are periodically pulled from Transifex and merged into the git repository. See the
+[translation process](doc/translation_process.md) for details on how this works.
-* **include/slice.h**: A simple module for maintaining a pointer and a
-length into some other byte array.
+**Important**: We do not accept translation changes as GitHub pull requests because the next
+pull from Transifex would automatically overwrite them again.
-* **include/status.h**: Status is returned from many of the public interfaces
-and is used to report success and various kinds of errors.
-
-* **include/env.h**:
-Abstraction of the OS environment. A posix implementation of this interface is
-in util/env_posix.cc
-
-* **include/table.h, include/table_builder.h**: Lower-level modules that most
-clients probably won't use directly
+Translators should also subscribe to the [mailing list](https://groups.google.com/forum/#!forum/bitcoin-translators).
diff --git a/autogen.sh b/autogen.sh
new file mode 100755
index 0000000000..3e26a18305
--- /dev/null
+++ b/autogen.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+set -e
+srcdir="$(dirname $0)"
+cd "$srcdir"
+if [ -z ${LIBTOOLIZE} ] && GLIBTOOLIZE="`which glibtoolize 2>/dev/null`"; then
+ LIBTOOLIZE="${GLIBTOOLIZE}"
+ export LIBTOOLIZE
+fi
+autoreconf --install --force --warnings=all
diff --git a/build-aux/m4/ax_boost_base.m4 b/build-aux/m4/ax_boost_base.m4
new file mode 100644
index 0000000000..3f24d5ddc6
--- /dev/null
+++ b/build-aux/m4/ax_boost_base.m4
@@ -0,0 +1,281 @@
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_boost_base.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_BOOST_BASE([MINIMUM-VERSION], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+#
+# DESCRIPTION
+#
+# Test for the Boost C++ libraries of a particular version (or newer)
+#
+# If no path to the installed boost library is given the macro searchs
+# under /usr, /usr/local, /opt and /opt/local and evaluates the
+# $BOOST_ROOT environment variable. Further documentation is available at
+# <http://randspringer.de/boost/index.html>.
+#
+# This macro calls:
+#
+# AC_SUBST(BOOST_CPPFLAGS) / AC_SUBST(BOOST_LDFLAGS)
+#
+# And sets:
+#
+# HAVE_BOOST
+#
+# LICENSE
+#
+# Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de>
+# Copyright (c) 2009 Peter Adolphs
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 23
+
+AC_DEFUN([AX_BOOST_BASE],
+[
+AC_ARG_WITH([boost],
+ [AS_HELP_STRING([--with-boost@<:@=ARG@:>@],
+ [use Boost library from a standard location (ARG=yes),
+ from the specified location (ARG=<path>),
+ or disable it (ARG=no)
+ @<:@ARG=yes@:>@ ])],
+ [
+ if test "$withval" = "no"; then
+ want_boost="no"
+ elif test "$withval" = "yes"; then
+ want_boost="yes"
+ ac_boost_path=""
+ else
+ want_boost="yes"
+ ac_boost_path="$withval"
+ fi
+ ],
+ [want_boost="yes"])
+
+
+AC_ARG_WITH([boost-libdir],
+ AS_HELP_STRING([--with-boost-libdir=LIB_DIR],
+ [Force given directory for boost libraries. Note that this will override library path detection, so use this parameter only if default library detection fails and you know exactly where your boost libraries are located.]),
+ [
+ if test -d "$withval"
+ then
+ ac_boost_lib_path="$withval"
+ else
+ AC_MSG_ERROR(--with-boost-libdir expected directory name)
+ fi
+ ],
+ [ac_boost_lib_path=""]
+)
+
+if test "x$want_boost" = "xyes"; then
+ boost_lib_version_req=ifelse([$1], ,1.20.0,$1)
+ boost_lib_version_req_shorten=`expr $boost_lib_version_req : '\([[0-9]]*\.[[0-9]]*\)'`
+ boost_lib_version_req_major=`expr $boost_lib_version_req : '\([[0-9]]*\)'`
+ boost_lib_version_req_minor=`expr $boost_lib_version_req : '[[0-9]]*\.\([[0-9]]*\)'`
+ boost_lib_version_req_sub_minor=`expr $boost_lib_version_req : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'`
+ if test "x$boost_lib_version_req_sub_minor" = "x" ; then
+ boost_lib_version_req_sub_minor="0"
+ fi
+ WANT_BOOST_VERSION=`expr $boost_lib_version_req_major \* 100000 \+ $boost_lib_version_req_minor \* 100 \+ $boost_lib_version_req_sub_minor`
+ AC_MSG_CHECKING(for boostlib >= $boost_lib_version_req)
+ succeeded=no
+
+ dnl On 64-bit systems check for system libraries in both lib64 and lib.
+ dnl The former is specified by FHS, but e.g. Debian does not adhere to
+ dnl this (as it rises problems for generic multi-arch support).
+ dnl The last entry in the list is chosen by default when no libraries
+ dnl are found, e.g. when only header-only libraries are installed!
+ libsubdirs="lib"
+ ax_arch=`uname -m`
+ case $ax_arch in
+ x86_64)
+ libsubdirs="lib64 libx32 lib lib64"
+ ;;
+ ppc64|s390x|sparc64|aarch64)
+ libsubdirs="lib64 lib lib64"
+ ;;
+ esac
+
+ dnl allow for real multi-arch paths e.g. /usr/lib/x86_64-linux-gnu. Give
+ dnl them priority over the other paths since, if libs are found there, they
+ dnl are almost assuredly the ones desired.
+ AC_REQUIRE([AC_CANONICAL_HOST])
+ libsubdirs="lib/${host_cpu}-${host_os} $libsubdirs"
+
+ case ${host_cpu} in
+ i?86)
+ libsubdirs="lib/i386-${host_os} $libsubdirs"
+ ;;
+ esac
+
+ dnl some arches may advertise a cpu type that doesn't line up with their
+ dnl prefix's cpu type. For example, uname may report armv7l while libs are
+ dnl installed to /usr/lib/arm-linux-gnueabihf. Try getting the compiler's
+ dnl value for an extra chance of finding the correct path.
+ libsubdirs="lib/`$CXX -dumpmachine 2>/dev/null` $libsubdirs"
+
+ dnl first we check the system location for boost libraries
+ dnl this location ist chosen if boost libraries are installed with the --layout=system option
+ dnl or if you install boost with RPM
+ if test "$ac_boost_path" != ""; then
+ BOOST_CPPFLAGS="-I$ac_boost_path/include"
+ for ac_boost_path_tmp in $libsubdirs; do
+ if test -d "$ac_boost_path"/"$ac_boost_path_tmp" ; then
+ BOOST_LDFLAGS="-L$ac_boost_path/$ac_boost_path_tmp"
+ break
+ fi
+ done
+ elif test "$cross_compiling" != yes; then
+ for ac_boost_path_tmp in /usr /usr/local /opt /opt/local ; do
+ if test -d "$ac_boost_path_tmp/include/boost" && test -r "$ac_boost_path_tmp/include/boost"; then
+ for libsubdir in $libsubdirs ; do
+ if ls "$ac_boost_path_tmp/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi
+ done
+ BOOST_LDFLAGS="-L$ac_boost_path_tmp/$libsubdir"
+ BOOST_CPPFLAGS="-I$ac_boost_path_tmp/include"
+ break;
+ fi
+ done
+ fi
+
+ dnl overwrite ld flags if we have required special directory with
+ dnl --with-boost-libdir parameter
+ if test "$ac_boost_lib_path" != ""; then
+ BOOST_LDFLAGS="-L$ac_boost_lib_path"
+ fi
+
+ CPPFLAGS_SAVED="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
+ export CPPFLAGS
+
+ LDFLAGS_SAVED="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
+ export LDFLAGS
+
+ AC_REQUIRE([AC_PROG_CXX])
+ AC_LANG_PUSH(C++)
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+ @%:@include <boost/version.hpp>
+ ]], [[
+ #if BOOST_VERSION >= $WANT_BOOST_VERSION
+ // Everything is okay
+ #else
+ # error Boost version is too old
+ #endif
+ ]])],[
+ AC_MSG_RESULT(yes)
+ succeeded=yes
+ found_system=yes
+ ],[:
+ ])
+ AC_LANG_POP([C++])
+
+
+
+ dnl if we found no boost with system layout we search for boost libraries
+ dnl built and installed without the --layout=system option or for a staged(not installed) version
+ if test "x$succeeded" != "xyes"; then
+ _version=0
+ if test "$ac_boost_path" != ""; then
+ if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then
+ for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do
+ _version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'`
+ V_CHECK=`expr $_version_tmp \> $_version`
+ if test "$V_CHECK" = "1" ; then
+ _version=$_version_tmp
+ fi
+ VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'`
+ BOOST_CPPFLAGS="-I$ac_boost_path/include/boost-$VERSION_UNDERSCORE"
+ done
+ fi
+ else
+ if test "$cross_compiling" != yes; then
+ for ac_boost_path in /usr /usr/local /opt /opt/local ; do
+ if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then
+ for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do
+ _version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'`
+ V_CHECK=`expr $_version_tmp \> $_version`
+ if test "$V_CHECK" = "1" ; then
+ _version=$_version_tmp
+ best_path=$ac_boost_path
+ fi
+ done
+ fi
+ done
+
+ VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'`
+ BOOST_CPPFLAGS="-I$best_path/include/boost-$VERSION_UNDERSCORE"
+ if test "$ac_boost_lib_path" = ""; then
+ for libsubdir in $libsubdirs ; do
+ if ls "$best_path/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi
+ done
+ BOOST_LDFLAGS="-L$best_path/$libsubdir"
+ fi
+ fi
+
+ if test "x$BOOST_ROOT" != "x"; then
+ for libsubdir in $libsubdirs ; do
+ if ls "$BOOST_ROOT/stage/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi
+ done
+ if test -d "$BOOST_ROOT" && test -r "$BOOST_ROOT" && test -d "$BOOST_ROOT/stage/$libsubdir" && test -r "$BOOST_ROOT/stage/$libsubdir"; then
+ version_dir=`expr //$BOOST_ROOT : '.*/\(.*\)'`
+ stage_version=`echo $version_dir | sed 's/boost_//' | sed 's/_/./g'`
+ stage_version_shorten=`expr $stage_version : '\([[0-9]]*\.[[0-9]]*\)'`
+ V_CHECK=`expr $stage_version_shorten \>\= $_version`
+ if test "$V_CHECK" = "1" -a "$ac_boost_lib_path" = "" ; then
+ AC_MSG_NOTICE(We will use a staged boost library from $BOOST_ROOT)
+ BOOST_CPPFLAGS="-I$BOOST_ROOT"
+ BOOST_LDFLAGS="-L$BOOST_ROOT/stage/$libsubdir"
+ fi
+ fi
+ fi
+ fi
+
+ CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
+ export CPPFLAGS
+ LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
+ export LDFLAGS
+
+ AC_LANG_PUSH(C++)
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+ @%:@include <boost/version.hpp>
+ ]], [[
+ #if BOOST_VERSION >= $WANT_BOOST_VERSION
+ // Everything is okay
+ #else
+ # error Boost version is too old
+ #endif
+ ]])],[
+ AC_MSG_RESULT(yes)
+ succeeded=yes
+ found_system=yes
+ ],[:
+ ])
+ AC_LANG_POP([C++])
+ fi
+
+ if test "$succeeded" != "yes" ; then
+ if test "$_version" = "0" ; then
+ AC_MSG_NOTICE([[We could not detect the boost libraries (version $boost_lib_version_req_shorten or higher). If you have a staged boost library (still not installed) please specify \$BOOST_ROOT in your environment and do not give a PATH to --with-boost option. If you are sure you have boost installed, then check your version number looking in <boost/version.hpp>. See http://randspringer.de/boost for more documentation.]])
+ else
+ AC_MSG_NOTICE([Your boost libraries seems to old (version $_version).])
+ fi
+ # execute ACTION-IF-NOT-FOUND (if present):
+ ifelse([$3], , :, [$3])
+ else
+ AC_SUBST(BOOST_CPPFLAGS)
+ AC_SUBST(BOOST_LDFLAGS)
+ AC_DEFINE(HAVE_BOOST,,[define if the Boost library is available])
+ # execute ACTION-IF-FOUND (if present):
+ ifelse([$2], , :, [$2])
+ fi
+
+ CPPFLAGS="$CPPFLAGS_SAVED"
+ LDFLAGS="$LDFLAGS_SAVED"
+fi
+
+])
diff --git a/build-aux/m4/ax_boost_chrono.m4 b/build-aux/m4/ax_boost_chrono.m4
new file mode 100644
index 0000000000..318ecea17f
--- /dev/null
+++ b/build-aux/m4/ax_boost_chrono.m4
@@ -0,0 +1,119 @@
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_boost_chrono.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_BOOST_CHRONO
+#
+# DESCRIPTION
+#
+# Test for System library from the Boost C++ libraries. The macro requires
+# a preceding call to AX_BOOST_BASE. Further documentation is available at
+# <http://randspringer.de/boost/index.html>.
+#
+# This macro calls:
+#
+# AC_SUBST(BOOST_CHRONO_LIB)
+#
+# And sets:
+#
+# HAVE_BOOST_CHRONO
+#
+# LICENSE
+#
+# Copyright (c) 2012 Xiyue Deng <manphiz@gmail.com>
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 1
+
+AC_DEFUN([AX_BOOST_CHRONO],
+[
+ AC_ARG_WITH([boost-chrono],
+ AS_HELP_STRING([--with-boost-chrono@<:@=special-lib@:>@],
+ [use the Chrono library from boost - it is possible to specify a certain library for the linker
+ e.g. --with-boost-chrono=boost_chrono-gcc-mt ]),
+ [
+ if test "$withval" = "no"; then
+ want_boost="no"
+ elif test "$withval" = "yes"; then
+ want_boost="yes"
+ ax_boost_user_chrono_lib=""
+ else
+ want_boost="yes"
+ ax_boost_user_chrono_lib="$withval"
+ fi
+ ],
+ [want_boost="yes"]
+ )
+
+ if test "x$want_boost" = "xyes"; then
+ AC_REQUIRE([AC_PROG_CC])
+ AC_REQUIRE([AC_CANONICAL_BUILD])
+ CPPFLAGS_SAVED="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
+ export CPPFLAGS
+
+ LDFLAGS_SAVED="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
+ export LDFLAGS
+
+ AC_CACHE_CHECK(whether the Boost::Chrono library is available,
+ ax_cv_boost_chrono,
+ [AC_LANG_PUSH([C++])
+ CXXFLAGS_SAVE=$CXXFLAGS
+
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include <boost/chrono.hpp>]],
+ [[boost::chrono::system_clock::time_point time;]])],
+ ax_cv_boost_chrono=yes, ax_cv_boost_chrono=no)
+ CXXFLAGS=$CXXFLAGS_SAVE
+ AC_LANG_POP([C++])
+ ])
+ if test "x$ax_cv_boost_chrono" = "xyes"; then
+ AC_SUBST(BOOST_CPPFLAGS)
+
+ AC_DEFINE(HAVE_BOOST_CHRONO,,[define if the Boost::Chrono library is available])
+ BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'`
+
+ LDFLAGS_SAVE=$LDFLAGS
+ if test "x$ax_boost_user_chrono_lib" = "x"; then
+ ax_lib=
+ for libextension in `ls $BOOSTLIBDIR/libboost_chrono*.so* $BOOSTLIBDIR/libboost_chrono*.dylib* $BOOSTLIBDIR/libboost_chrono*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_chrono.*\)\.so.*$;\1;' -e 's;^lib\(boost_chrono.*\)\.dylib.*$;\1;' -e 's;^lib\(boost_chrono.*\)\.a.*$;\1;'` ; do
+ ax_lib=${libextension}
+ AC_CHECK_LIB($ax_lib, exit,
+ [BOOST_CHRONO_LIB="-l$ax_lib"; AC_SUBST(BOOST_CHRONO_LIB) link_chrono="yes"; break],
+ [link_chrono="no"])
+ done
+ if test "x$link_chrono" != "xyes"; then
+ for libextension in `ls $BOOSTLIBDIR/boost_chrono*.dll* $BOOSTLIBDIR/boost_chrono*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_chrono.*\)\.dll.*$;\1;' -e 's;^\(boost_chrono.*\)\.a.*$;\1;'` ; do
+ ax_lib=${libextension}
+ AC_CHECK_LIB($ax_lib, exit,
+ [BOOST_CHRONO_LIB="-l$ax_lib"; AC_SUBST(BOOST_CHRONO_LIB) link_chrono="yes"; break],
+ [link_chrono="no"])
+ done
+ fi
+
+ else
+ for ax_lib in $ax_boost_user_chrono_lib boost_chrono-$ax_boost_user_chrono_lib; do
+ AC_CHECK_LIB($ax_lib, exit,
+ [BOOST_CHRONO_LIB="-l$ax_lib"; AC_SUBST(BOOST_CHRONO_LIB) link_chrono="yes"; break],
+ [link_chrono="no"])
+ done
+
+ fi
+ if test "x$ax_lib" = "x"; then
+ AC_MSG_ERROR(Could not find a version of the boost_chrono library!)
+ fi
+ if test "x$link_chrono" = "xno"; then
+ AC_MSG_ERROR(Could not link against $ax_lib !)
+ fi
+ fi
+
+ CPPFLAGS="$CPPFLAGS_SAVED"
+ LDFLAGS="$LDFLAGS_SAVED"
+ fi
+])
diff --git a/build-aux/m4/ax_boost_filesystem.m4 b/build-aux/m4/ax_boost_filesystem.m4
new file mode 100644
index 0000000000..f5c9d56470
--- /dev/null
+++ b/build-aux/m4/ax_boost_filesystem.m4
@@ -0,0 +1,119 @@
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_boost_filesystem.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_BOOST_FILESYSTEM
+#
+# DESCRIPTION
+#
+# Test for Filesystem library from the Boost C++ libraries. The macro
+# requires a preceding call to AX_BOOST_BASE. Further documentation is
+# available at <http://randspringer.de/boost/index.html>.
+#
+# This macro calls:
+#
+# AC_SUBST(BOOST_FILESYSTEM_LIB)
+#
+# And sets:
+#
+# HAVE_BOOST_FILESYSTEM
+#
+# LICENSE
+#
+# Copyright (c) 2009 Thomas Porschberg <thomas@randspringer.de>
+# Copyright (c) 2009 Michael Tindal
+# Copyright (c) 2009 Roman Rybalko <libtorrent@romanr.info>
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 26
+
+AC_DEFUN([AX_BOOST_FILESYSTEM],
+[
+ AC_ARG_WITH([boost-filesystem],
+ AS_HELP_STRING([--with-boost-filesystem@<:@=special-lib@:>@],
+ [use the Filesystem library from boost - it is possible to specify a certain library for the linker
+ e.g. --with-boost-filesystem=boost_filesystem-gcc-mt ]),
+ [
+ if test "$withval" = "no"; then
+ want_boost="no"
+ elif test "$withval" = "yes"; then
+ want_boost="yes"
+ ax_boost_user_filesystem_lib=""
+ else
+ want_boost="yes"
+ ax_boost_user_filesystem_lib="$withval"
+ fi
+ ],
+ [want_boost="yes"]
+ )
+
+ if test "x$want_boost" = "xyes"; then
+ AC_REQUIRE([AC_PROG_CC])
+ CPPFLAGS_SAVED="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
+ export CPPFLAGS
+
+ LDFLAGS_SAVED="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
+ export LDFLAGS
+
+ LIBS_SAVED=$LIBS
+ LIBS="$LIBS $BOOST_SYSTEM_LIB"
+ export LIBS
+
+ AC_CACHE_CHECK(whether the Boost::Filesystem library is available,
+ ax_cv_boost_filesystem,
+ [AC_LANG_PUSH([C++])
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include <boost/filesystem/path.hpp>]],
+ [[using namespace boost::filesystem;
+ path my_path( "foo/bar/data.txt" );
+ return 0;]])],
+ ax_cv_boost_filesystem=yes, ax_cv_boost_filesystem=no)
+ AC_LANG_POP([C++])
+ ])
+ if test "x$ax_cv_boost_filesystem" = "xyes"; then
+ AC_DEFINE(HAVE_BOOST_FILESYSTEM,,[define if the Boost::Filesystem library is available])
+ BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'`
+ ax_lib=
+ if test "x$ax_boost_user_filesystem_lib" = "x"; then
+ for libextension in `ls -r $BOOSTLIBDIR/libboost_filesystem* 2>/dev/null | sed 's,.*/lib,,' | sed 's,\..*,,'` ; do
+ ax_lib=${libextension}
+ AC_CHECK_LIB($ax_lib, exit,
+ [BOOST_FILESYSTEM_LIB="-l$ax_lib"; AC_SUBST(BOOST_FILESYSTEM_LIB) link_filesystem="yes"; break],
+ [link_filesystem="no"])
+ done
+ if test "x$link_filesystem" != "xyes"; then
+ for libextension in `ls -r $BOOSTLIBDIR/boost_filesystem* 2>/dev/null | sed 's,.*/,,' | sed -e 's,\..*,,'` ; do
+ ax_lib=${libextension}
+ AC_CHECK_LIB($ax_lib, exit,
+ [BOOST_FILESYSTEM_LIB="-l$ax_lib"; AC_SUBST(BOOST_FILESYSTEM_LIB) link_filesystem="yes"; break],
+ [link_filesystem="no"])
+ done
+ fi
+ else
+ for ax_lib in $ax_boost_user_filesystem_lib boost_filesystem-$ax_boost_user_filesystem_lib; do
+ AC_CHECK_LIB($ax_lib, exit,
+ [BOOST_FILESYSTEM_LIB="-l$ax_lib"; AC_SUBST(BOOST_FILESYSTEM_LIB) link_filesystem="yes"; break],
+ [link_filesystem="no"])
+ done
+
+ fi
+ if test "x$ax_lib" = "x"; then
+ AC_MSG_ERROR(Could not find a version of the boost_filesystem library!)
+ fi
+ if test "x$link_filesystem" != "xyes"; then
+ AC_MSG_ERROR(Could not link against $ax_lib !)
+ fi
+ fi
+
+ CPPFLAGS="$CPPFLAGS_SAVED"
+ LDFLAGS="$LDFLAGS_SAVED"
+ LIBS="$LIBS_SAVED"
+ fi
+])
diff --git a/build-aux/m4/ax_boost_program_options.m4 b/build-aux/m4/ax_boost_program_options.m4
new file mode 100644
index 0000000000..f591441854
--- /dev/null
+++ b/build-aux/m4/ax_boost_program_options.m4
@@ -0,0 +1,109 @@
+# ============================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_boost_program_options.html
+# ============================================================================
+#
+# SYNOPSIS
+#
+# AX_BOOST_PROGRAM_OPTIONS
+#
+# DESCRIPTION
+#
+# Test for program options library from the Boost C++ libraries. The macro
+# requires a preceding call to AX_BOOST_BASE. Further documentation is
+# available at <http://randspringer.de/boost/index.html>.
+#
+# This macro calls:
+#
+# AC_SUBST(BOOST_PROGRAM_OPTIONS_LIB)
+#
+# And sets:
+#
+# HAVE_BOOST_PROGRAM_OPTIONS
+#
+# LICENSE
+#
+# Copyright (c) 2009 Thomas Porschberg <thomas@randspringer.de>
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 22
+
+AC_DEFUN([AX_BOOST_PROGRAM_OPTIONS],
+[
+ AC_ARG_WITH([boost-program-options],
+ AS_HELP_STRING([--with-boost-program-options@<:@=special-lib@:>@],
+ [use the program options library from boost - it is possible to specify a certain library for the linker
+ e.g. --with-boost-program-options=boost_program_options-gcc-mt-1_33_1 ]),
+ [
+ if test "$withval" = "no"; then
+ want_boost="no"
+ elif test "$withval" = "yes"; then
+ want_boost="yes"
+ ax_boost_user_program_options_lib=""
+ else
+ want_boost="yes"
+ ax_boost_user_program_options_lib="$withval"
+ fi
+ ],
+ [want_boost="yes"]
+ )
+
+ if test "x$want_boost" = "xyes"; then
+ AC_REQUIRE([AC_PROG_CC])
+ export want_boost
+ CPPFLAGS_SAVED="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
+ export CPPFLAGS
+ LDFLAGS_SAVED="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
+ export LDFLAGS
+ AC_CACHE_CHECK([whether the Boost::Program_Options library is available],
+ ax_cv_boost_program_options,
+ [AC_LANG_PUSH(C++)
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include <boost/program_options.hpp>
+ ]],
+ [[boost::program_options::options_description generic("Generic options");
+ return 0;]])],
+ ax_cv_boost_program_options=yes, ax_cv_boost_program_options=no)
+ AC_LANG_POP([C++])
+ ])
+ if test "$ax_cv_boost_program_options" = yes; then
+ AC_DEFINE(HAVE_BOOST_PROGRAM_OPTIONS,,[define if the Boost::PROGRAM_OPTIONS library is available])
+ BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'`
+ if test "x$ax_boost_user_program_options_lib" = "x"; then
+ ax_lib=
+ for libextension in `ls $BOOSTLIBDIR/libboost_program_options*.so* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_program_options.*\)\.so.*$;\1;'` `ls $BOOSTLIBDIR/libboost_program_options*.dylib* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_program_options.*\)\.dylib.*$;\1;'` `ls $BOOSTLIBDIR/libboost_program_options*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_program_options.*\)\.a.*$;\1;'` ; do
+ ax_lib=${libextension}
+ AC_CHECK_LIB($ax_lib, exit,
+ [BOOST_PROGRAM_OPTIONS_LIB="-l$ax_lib"; AC_SUBST(BOOST_PROGRAM_OPTIONS_LIB) link_program_options="yes"; break],
+ [link_program_options="no"])
+ done
+ if test "x$link_program_options" != "xyes"; then
+ for libextension in `ls $BOOSTLIBDIR/boost_program_options*.dll* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_program_options.*\)\.dll.*$;\1;'` `ls $BOOSTLIBDIR/boost_program_options*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_program_options.*\)\.a.*$;\1;'` ; do
+ ax_lib=${libextension}
+ AC_CHECK_LIB($ax_lib, exit,
+ [BOOST_PROGRAM_OPTIONS_LIB="-l$ax_lib"; AC_SUBST(BOOST_PROGRAM_OPTIONS_LIB) link_program_options="yes"; break],
+ [link_program_options="no"])
+ done
+ fi
+ else
+ for ax_lib in $ax_boost_user_program_options_lib boost_program_options-$ax_boost_user_program_options_lib; do
+ AC_CHECK_LIB($ax_lib, main,
+ [BOOST_PROGRAM_OPTIONS_LIB="-l$ax_lib"; AC_SUBST(BOOST_PROGRAM_OPTIONS_LIB) link_program_options="yes"; break],
+ [link_program_options="no"])
+ done
+ fi
+ if test "x$ax_lib" = "x"; then
+ AC_MSG_ERROR(Could not find a version of the boost_program_options library!)
+ fi
+ if test "x$link_program_options" != "xyes"; then
+ AC_MSG_ERROR([Could not link against [$ax_lib] !])
+ fi
+ fi
+ CPPFLAGS="$CPPFLAGS_SAVED"
+ LDFLAGS="$LDFLAGS_SAVED"
+ fi
+])
diff --git a/build-aux/m4/ax_boost_system.m4 b/build-aux/m4/ax_boost_system.m4
new file mode 100644
index 0000000000..9c78280fca
--- /dev/null
+++ b/build-aux/m4/ax_boost_system.m4
@@ -0,0 +1,121 @@
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_boost_system.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_BOOST_SYSTEM
+#
+# DESCRIPTION
+#
+# Test for System library from the Boost C++ libraries. The macro requires
+# a preceding call to AX_BOOST_BASE. Further documentation is available at
+# <http://randspringer.de/boost/index.html>.
+#
+# This macro calls:
+#
+# AC_SUBST(BOOST_SYSTEM_LIB)
+#
+# And sets:
+#
+# HAVE_BOOST_SYSTEM
+#
+# LICENSE
+#
+# Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de>
+# Copyright (c) 2008 Michael Tindal
+# Copyright (c) 2008 Daniel Casimiro <dan.casimiro@gmail.com>
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 17
+
+AC_DEFUN([AX_BOOST_SYSTEM],
+[
+ AC_ARG_WITH([boost-system],
+ AS_HELP_STRING([--with-boost-system@<:@=special-lib@:>@],
+ [use the System library from boost - it is possible to specify a certain library for the linker
+ e.g. --with-boost-system=boost_system-gcc-mt ]),
+ [
+ if test "$withval" = "no"; then
+ want_boost="no"
+ elif test "$withval" = "yes"; then
+ want_boost="yes"
+ ax_boost_user_system_lib=""
+ else
+ want_boost="yes"
+ ax_boost_user_system_lib="$withval"
+ fi
+ ],
+ [want_boost="yes"]
+ )
+
+ if test "x$want_boost" = "xyes"; then
+ AC_REQUIRE([AC_PROG_CC])
+ AC_REQUIRE([AC_CANONICAL_BUILD])
+ CPPFLAGS_SAVED="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
+ export CPPFLAGS
+
+ LDFLAGS_SAVED="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
+ export LDFLAGS
+
+ AC_CACHE_CHECK(whether the Boost::System library is available,
+ ax_cv_boost_system,
+ [AC_LANG_PUSH([C++])
+ CXXFLAGS_SAVE=$CXXFLAGS
+
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include <boost/system/error_code.hpp>]],
+ [[boost::system::system_category]])],
+ ax_cv_boost_system=yes, ax_cv_boost_system=no)
+ CXXFLAGS=$CXXFLAGS_SAVE
+ AC_LANG_POP([C++])
+ ])
+ if test "x$ax_cv_boost_system" = "xyes"; then
+ AC_SUBST(BOOST_CPPFLAGS)
+
+ AC_DEFINE(HAVE_BOOST_SYSTEM,,[define if the Boost::System library is available])
+ BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'`
+
+ LDFLAGS_SAVE=$LDFLAGS
+ if test "x$ax_boost_user_system_lib" = "x"; then
+ ax_lib=
+ for libextension in `ls -r $BOOSTLIBDIR/libboost_system* 2>/dev/null | sed 's,.*/lib,,' | sed 's,\..*,,'` ; do
+ ax_lib=${libextension}
+ AC_CHECK_LIB($ax_lib, exit,
+ [BOOST_SYSTEM_LIB="-l$ax_lib"; AC_SUBST(BOOST_SYSTEM_LIB) link_system="yes"; break],
+ [link_system="no"])
+ done
+ if test "x$link_system" != "xyes"; then
+ for libextension in `ls -r $BOOSTLIBDIR/boost_system* 2>/dev/null | sed 's,.*/,,' | sed -e 's,\..*,,'` ; do
+ ax_lib=${libextension}
+ AC_CHECK_LIB($ax_lib, exit,
+ [BOOST_SYSTEM_LIB="-l$ax_lib"; AC_SUBST(BOOST_SYSTEM_LIB) link_system="yes"; break],
+ [link_system="no"])
+ done
+ fi
+
+ else
+ for ax_lib in $ax_boost_user_system_lib boost_system-$ax_boost_user_system_lib; do
+ AC_CHECK_LIB($ax_lib, exit,
+ [BOOST_SYSTEM_LIB="-l$ax_lib"; AC_SUBST(BOOST_SYSTEM_LIB) link_system="yes"; break],
+ [link_system="no"])
+ done
+
+ fi
+ if test "x$ax_lib" = "x"; then
+ AC_MSG_ERROR(Could not find a version of the boost_system library!)
+ fi
+ if test "x$link_system" = "xno"; then
+ AC_MSG_ERROR(Could not link against $ax_lib !)
+ fi
+ fi
+
+ CPPFLAGS="$CPPFLAGS_SAVED"
+ LDFLAGS="$LDFLAGS_SAVED"
+ fi
+])
diff --git a/build-aux/m4/ax_boost_thread.m4 b/build-aux/m4/ax_boost_thread.m4
new file mode 100644
index 0000000000..9f0bd0b23c
--- /dev/null
+++ b/build-aux/m4/ax_boost_thread.m4
@@ -0,0 +1,150 @@
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_boost_thread.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_BOOST_THREAD
+#
+# DESCRIPTION
+#
+# Test for Thread library from the Boost C++ libraries. The macro requires
+# a preceding call to AX_BOOST_BASE. Further documentation is available at
+# <http://randspringer.de/boost/index.html>.
+#
+# This macro calls:
+#
+# AC_SUBST(BOOST_THREAD_LIB)
+#
+# And sets:
+#
+# HAVE_BOOST_THREAD
+#
+# LICENSE
+#
+# Copyright (c) 2009 Thomas Porschberg <thomas@randspringer.de>
+# Copyright (c) 2009 Michael Tindal
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 27
+
+AC_DEFUN([AX_BOOST_THREAD],
+[
+ AC_ARG_WITH([boost-thread],
+ AS_HELP_STRING([--with-boost-thread@<:@=special-lib@:>@],
+ [use the Thread library from boost - it is possible to specify a certain library for the linker
+ e.g. --with-boost-thread=boost_thread-gcc-mt ]),
+ [
+ if test "$withval" = "no"; then
+ want_boost="no"
+ elif test "$withval" = "yes"; then
+ want_boost="yes"
+ ax_boost_user_thread_lib=""
+ else
+ want_boost="yes"
+ ax_boost_user_thread_lib="$withval"
+ fi
+ ],
+ [want_boost="yes"]
+ )
+
+ if test "x$want_boost" = "xyes"; then
+ AC_REQUIRE([AC_PROG_CC])
+ AC_REQUIRE([AC_CANONICAL_BUILD])
+ CPPFLAGS_SAVED="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
+ export CPPFLAGS
+
+ LDFLAGS_SAVED="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
+ export LDFLAGS
+
+ AC_CACHE_CHECK(whether the Boost::Thread library is available,
+ ax_cv_boost_thread,
+ [AC_LANG_PUSH([C++])
+ CXXFLAGS_SAVE=$CXXFLAGS
+
+ if test "x$host_os" = "xsolaris" ; then
+ CXXFLAGS="-pthreads $CXXFLAGS"
+ elif test "x$host_os" = "xmingw32" ; then
+ CXXFLAGS="-mthreads $CXXFLAGS"
+ else
+ CXXFLAGS="-pthread $CXXFLAGS"
+ fi
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include <boost/thread/thread.hpp>]],
+ [[boost::thread_group thrds;
+ return 0;]])],
+ ax_cv_boost_thread=yes, ax_cv_boost_thread=no)
+ CXXFLAGS=$CXXFLAGS_SAVE
+ AC_LANG_POP([C++])
+ ])
+ if test "x$ax_cv_boost_thread" = "xyes"; then
+ if test "x$host_os" = "xsolaris" ; then
+ BOOST_CPPFLAGS="-pthreads $BOOST_CPPFLAGS"
+ elif test "x$host_os" = "xmingw32" ; then
+ BOOST_CPPFLAGS="-mthreads $BOOST_CPPFLAGS"
+ else
+ BOOST_CPPFLAGS="-pthread $BOOST_CPPFLAGS"
+ fi
+
+ AC_SUBST(BOOST_CPPFLAGS)
+
+ AC_DEFINE(HAVE_BOOST_THREAD,,[define if the Boost::Thread library is available])
+ BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'`
+
+ LDFLAGS_SAVE=$LDFLAGS
+ case "x$host_os" in
+ *bsd* )
+ LDFLAGS="-pthread $LDFLAGS"
+ break;
+ ;;
+ esac
+ if test "x$ax_boost_user_thread_lib" = "x"; then
+ ax_lib=
+ for libextension in `ls -r $BOOSTLIBDIR/libboost_thread* 2>/dev/null | sed 's,.*/lib,,' | sed 's,\..*,,'`; do
+ ax_lib=${libextension}
+ AC_CHECK_LIB($ax_lib, exit,
+ [BOOST_THREAD_LIB="-l$ax_lib"; AC_SUBST(BOOST_THREAD_LIB) link_thread="yes"; break],
+ [link_thread="no"])
+ done
+ if test "x$link_thread" != "xyes"; then
+ for libextension in `ls -r $BOOSTLIBDIR/boost_thread* 2>/dev/null | sed 's,.*/,,' | sed 's,\..*,,'`; do
+ ax_lib=${libextension}
+ AC_CHECK_LIB($ax_lib, exit,
+ [BOOST_THREAD_LIB="-l$ax_lib"; AC_SUBST(BOOST_THREAD_LIB) link_thread="yes"; break],
+ [link_thread="no"])
+ done
+ fi
+
+ else
+ for ax_lib in $ax_boost_user_thread_lib boost_thread-$ax_boost_user_thread_lib; do
+ AC_CHECK_LIB($ax_lib, exit,
+ [BOOST_THREAD_LIB="-l$ax_lib"; AC_SUBST(BOOST_THREAD_LIB) link_thread="yes"; break],
+ [link_thread="no"])
+ done
+
+ fi
+ if test "x$ax_lib" = "x"; then
+ AC_MSG_ERROR(Could not find a version of the boost_thread library!)
+ fi
+ if test "x$link_thread" = "xno"; then
+ AC_MSG_ERROR(Could not link against $ax_lib !)
+ else
+ case "x$host_os" in
+ *bsd* )
+ BOOST_LDFLAGS="-pthread $BOOST_LDFLAGS"
+ break;
+ ;;
+ esac
+
+ fi
+ fi
+
+ CPPFLAGS="$CPPFLAGS_SAVED"
+ LDFLAGS="$LDFLAGS_SAVED"
+ fi
+])
diff --git a/build-aux/m4/ax_boost_unit_test_framework.m4 b/build-aux/m4/ax_boost_unit_test_framework.m4
new file mode 100644
index 0000000000..4efd1e2f18
--- /dev/null
+++ b/build-aux/m4/ax_boost_unit_test_framework.m4
@@ -0,0 +1,138 @@
+# ================================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_boost_unit_test_framework.html
+# ================================================================================
+#
+# SYNOPSIS
+#
+# AX_BOOST_UNIT_TEST_FRAMEWORK
+#
+# DESCRIPTION
+#
+# Test for Unit_Test_Framework library from the Boost C++ libraries. The
+# macro requires a preceding call to AX_BOOST_BASE. Further documentation
+# is available at <http://randspringer.de/boost/index.html>.
+#
+# This macro calls:
+#
+# AC_SUBST(BOOST_UNIT_TEST_FRAMEWORK_LIB)
+#
+# And sets:
+#
+# HAVE_BOOST_UNIT_TEST_FRAMEWORK
+#
+# LICENSE
+#
+# Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de>
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 19
+
+AC_DEFUN([AX_BOOST_UNIT_TEST_FRAMEWORK],
+[
+ AC_ARG_WITH([boost-unit-test-framework],
+ AS_HELP_STRING([--with-boost-unit-test-framework@<:@=special-lib@:>@],
+ [use the Unit_Test_Framework library from boost - it is possible to specify a certain library for the linker
+ e.g. --with-boost-unit-test-framework=boost_unit_test_framework-gcc ]),
+ [
+ if test "$withval" = "no"; then
+ want_boost="no"
+ elif test "$withval" = "yes"; then
+ want_boost="yes"
+ ax_boost_user_unit_test_framework_lib=""
+ else
+ want_boost="yes"
+ ax_boost_user_unit_test_framework_lib="$withval"
+ fi
+ ],
+ [want_boost="yes"]
+ )
+
+ if test "x$want_boost" = "xyes"; then
+ AC_REQUIRE([AC_PROG_CC])
+ CPPFLAGS_SAVED="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
+ export CPPFLAGS
+
+ LDFLAGS_SAVED="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
+ export LDFLAGS
+
+ AC_CACHE_CHECK(whether the Boost::Unit_Test_Framework library is available,
+ ax_cv_boost_unit_test_framework,
+ [AC_LANG_PUSH([C++])
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include <boost/test/unit_test.hpp>]],
+ [[using boost::unit_test::test_suite;
+ test_suite* test= BOOST_TEST_SUITE( "Unit test example 1" ); return 0;]])],
+ ax_cv_boost_unit_test_framework=yes, ax_cv_boost_unit_test_framework=no)
+ AC_LANG_POP([C++])
+ ])
+ if test "x$ax_cv_boost_unit_test_framework" = "xyes"; then
+ AC_DEFINE(HAVE_BOOST_UNIT_TEST_FRAMEWORK,,[define if the Boost::Unit_Test_Framework library is available])
+ BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'`
+
+ if test "x$ax_boost_user_unit_test_framework_lib" = "x"; then
+ saved_ldflags="${LDFLAGS}"
+ ax_lib=
+ for monitor_library in `ls $BOOSTLIBDIR/libboost_unit_test_framework*.so* $BOOSTLIBDIR/libboost_unit_test_framework*.dylib* $BOOSTLIBDIR/libboost_unit_test_framework*.a* 2>/dev/null` ; do
+ if test -r $monitor_library ; then
+ libextension=`echo $monitor_library | sed 's,.*/,,' | sed -e 's;^lib\(boost_unit_test_framework.*\)\.so.*$;\1;' -e 's;^lib\(boost_unit_test_framework.*\)\.dylib.*$;\1;' -e 's;^lib\(boost_unit_test_framework.*\)\.a.*$;\1;'`
+ ax_lib=${libextension}
+ link_unit_test_framework="yes"
+ else
+ link_unit_test_framework="no"
+ fi
+
+ if test "x$link_unit_test_framework" = "xyes"; then
+ BOOST_UNIT_TEST_FRAMEWORK_LIB="-l$ax_lib"
+ AC_SUBST(BOOST_UNIT_TEST_FRAMEWORK_LIB)
+ break
+ fi
+ done
+ if test "x$link_unit_test_framework" != "xyes"; then
+ for libextension in `ls $BOOSTLIBDIR/boost_unit_test_framework*.dll* $BOOSTLIBDIR/boost_unit_test_framework*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_unit_test_framework.*\)\.dll.*$;\1;' -e 's;^\(boost_unit_test_framework.*\)\.a.*$;\1;'` ; do
+ ax_lib=${libextension}
+ AC_CHECK_LIB($ax_lib, exit,
+ [BOOST_UNIT_TEST_FRAMEWORK_LIB="-l$ax_lib"; AC_SUBST(BOOST_UNIT_TEST_FRAMEWORK_LIB) link_unit_test_framework="yes"; break],
+ [link_unit_test_framework="no"])
+ done
+ fi
+ else
+ link_unit_test_framework="no"
+ saved_ldflags="${LDFLAGS}"
+ for ax_lib in boost_unit_test_framework-$ax_boost_user_unit_test_framework_lib $ax_boost_user_unit_test_framework_lib ; do
+ if test "x$link_unit_test_framework" = "xyes"; then
+ break;
+ fi
+ for unittest_library in `ls $BOOSTLIBDIR/lib${ax_lib}.so* $BOOSTLIBDIR/lib${ax_lib}.a* 2>/dev/null` ; do
+ if test -r $unittest_library ; then
+ libextension=`echo $unittest_library | sed 's,.*/,,' | sed -e 's;^lib\(boost_unit_test_framework.*\)\.so.*$;\1;' -e 's;^lib\(boost_unit_test_framework.*\)\.a*$;\1;'`
+ ax_lib=${libextension}
+ link_unit_test_framework="yes"
+ else
+ link_unit_test_framework="no"
+ fi
+
+ if test "x$link_unit_test_framework" = "xyes"; then
+ BOOST_UNIT_TEST_FRAMEWORK_LIB="-l$ax_lib"
+ AC_SUBST(BOOST_UNIT_TEST_FRAMEWORK_LIB)
+ break
+ fi
+ done
+ done
+ fi
+ if test "x$ax_lib" = "x"; then
+ AC_MSG_ERROR(Could not find a version of the boost_unit_test_framework library!)
+ fi
+ if test "x$link_unit_test_framework" != "xyes"; then
+ AC_MSG_ERROR(Could not link against $ax_lib !)
+ fi
+ fi
+
+ CPPFLAGS="$CPPFLAGS_SAVED"
+ LDFLAGS="$LDFLAGS_SAVED"
+ fi
+])
diff --git a/build-aux/m4/ax_check_compile_flag.m4 b/build-aux/m4/ax_check_compile_flag.m4
new file mode 100644
index 0000000000..c3a8d695a1
--- /dev/null
+++ b/build-aux/m4/ax_check_compile_flag.m4
@@ -0,0 +1,72 @@
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS])
+#
+# DESCRIPTION
+#
+# Check whether the given FLAG works with the current language's compiler
+# or gives an error. (Warnings, however, are ignored)
+#
+# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
+# success/failure.
+#
+# If EXTRA-FLAGS is defined, it is added to the current language's default
+# flags (e.g. CFLAGS) when the check is done. The check is thus made with
+# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to
+# force the compiler to issue an error when a bad flag is given.
+#
+# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
+# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
+# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
+#
+# 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 <http://www.gnu.org/licenses/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 2
+
+AC_DEFUN([AX_CHECK_COMPILE_FLAG],
+[AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX
+AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl
+AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [
+ ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS
+ _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM()],
+ [AS_VAR_SET(CACHEVAR,[yes])],
+ [AS_VAR_SET(CACHEVAR,[no])])
+ _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags])
+AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes],
+ [m4_default([$2], :)],
+ [m4_default([$3], :)])
+AS_VAR_POPDEF([CACHEVAR])dnl
+])dnl AX_CHECK_COMPILE_FLAGS
diff --git a/build-aux/m4/ax_check_link_flag.m4 b/build-aux/m4/ax_check_link_flag.m4
new file mode 100644
index 0000000000..e2d0d363e4
--- /dev/null
+++ b/build-aux/m4/ax_check_link_flag.m4
@@ -0,0 +1,71 @@
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_check_link_flag.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_CHECK_LINK_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS])
+#
+# DESCRIPTION
+#
+# Check whether the given FLAG works with the linker or gives an error.
+# (Warnings, however, are ignored)
+#
+# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
+# success/failure.
+#
+# If EXTRA-FLAGS is defined, it is added to the linker's default flags
+# when the check is done. The check is thus made with the flags: "LDFLAGS
+# EXTRA-FLAGS FLAG". This can for example be used to force the linker to
+# issue an error when a bad flag is given.
+#
+# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
+# macro in sync with AX_CHECK_{PREPROC,COMPILE}_FLAG.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
+# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
+#
+# 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 <http://www.gnu.org/licenses/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 2
+
+AC_DEFUN([AX_CHECK_LINK_FLAG],
+[AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_ldflags_$4_$1])dnl
+AC_CACHE_CHECK([whether the linker accepts $1], CACHEVAR, [
+ ax_check_save_flags=$LDFLAGS
+ LDFLAGS="$LDFLAGS $4 $1"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM()],
+ [AS_VAR_SET(CACHEVAR,[yes])],
+ [AS_VAR_SET(CACHEVAR,[no])])
+ LDFLAGS=$ax_check_save_flags])
+AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes],
+ [m4_default([$2], :)],
+ [m4_default([$3], :)])
+AS_VAR_POPDEF([CACHEVAR])dnl
+])dnl AX_CHECK_LINK_FLAGS
diff --git a/build-aux/m4/ax_check_preproc_flag.m4 b/build-aux/m4/ax_check_preproc_flag.m4
new file mode 100644
index 0000000000..b1cfef6b86
--- /dev/null
+++ b/build-aux/m4/ax_check_preproc_flag.m4
@@ -0,0 +1,72 @@
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_check_preproc_flag.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_CHECK_PREPROC_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS])
+#
+# DESCRIPTION
+#
+# Check whether the given FLAG works with the current language's
+# preprocessor or gives an error. (Warnings, however, are ignored)
+#
+# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
+# success/failure.
+#
+# If EXTRA-FLAGS is defined, it is added to the preprocessor's default
+# flags when the check is done. The check is thus made with the flags:
+# "CPPFLAGS EXTRA-FLAGS FLAG". This can for example be used to force the
+# preprocessor to issue an error when a bad flag is given.
+#
+# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
+# macro in sync with AX_CHECK_{COMPILE,LINK}_FLAG.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
+# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
+#
+# 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 <http://www.gnu.org/licenses/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 2
+
+AC_DEFUN([AX_CHECK_PREPROC_FLAG],
+[AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX
+AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]cppflags_$4_$1])dnl
+AC_CACHE_CHECK([whether _AC_LANG preprocessor accepts $1], CACHEVAR, [
+ ax_check_save_flags=$CPPFLAGS
+ CPPFLAGS="$CPPFLAGS $4 $1"
+ AC_PREPROC_IFELSE([AC_LANG_PROGRAM()],
+ [AS_VAR_SET(CACHEVAR,[yes])],
+ [AS_VAR_SET(CACHEVAR,[no])])
+ CPPFLAGS=$ax_check_save_flags])
+AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes],
+ [m4_default([$2], :)],
+ [m4_default([$3], :)])
+AS_VAR_POPDEF([CACHEVAR])dnl
+])dnl AX_CHECK_PREPROC_FLAGS
diff --git a/build-aux/m4/ax_gcc_func_attribute.m4 b/build-aux/m4/ax_gcc_func_attribute.m4
new file mode 100644
index 0000000000..275ca63a2c
--- /dev/null
+++ b/build-aux/m4/ax_gcc_func_attribute.m4
@@ -0,0 +1,217 @@
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_gcc_func_attribute.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_GCC_FUNC_ATTRIBUTE(ATTRIBUTE)
+#
+# DESCRIPTION
+#
+# This macro checks if the compiler supports one of GCC's function
+# attributes; many other compilers also provide function attributes with
+# the same syntax. Compiler warnings are used to detect supported
+# attributes as unsupported ones are ignored by default so quieting
+# warnings when using this macro will yield false positives.
+#
+# The ATTRIBUTE parameter holds the name of the attribute to be checked.
+#
+# If ATTRIBUTE is supported define HAVE_FUNC_ATTRIBUTE_<ATTRIBUTE>.
+#
+# The macro caches its result in the ax_cv_have_func_attribute_<attribute>
+# variable.
+#
+# The macro currently supports the following function attributes:
+#
+# alias
+# aligned
+# alloc_size
+# always_inline
+# artificial
+# cold
+# const
+# constructor
+# deprecated
+# destructor
+# dllexport
+# dllimport
+# error
+# externally_visible
+# flatten
+# format
+# format_arg
+# gnu_inline
+# hot
+# ifunc
+# leaf
+# malloc
+# noclone
+# noinline
+# nonnull
+# noreturn
+# nothrow
+# optimize
+# pure
+# unused
+# used
+# visibility
+# warning
+# warn_unused_result
+# weak
+# weakref
+#
+# Unsuppored function attributes will be tested with a prototype returning
+# an int and not accepting any arguments and the result of the check might
+# be wrong or meaningless so use with care.
+#
+# LICENSE
+#
+# Copyright (c) 2013 Gabriele Svelto <gabriele.svelto@gmail.com>
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 2
+
+AC_DEFUN([AX_GCC_FUNC_ATTRIBUTE], [
+ AS_VAR_PUSHDEF([ac_var], [ax_cv_have_func_attribute_$1])
+
+ AC_CACHE_CHECK([for __attribute__(($1))], [ac_var], [
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([
+ m4_case([$1],
+ [alias], [
+ int foo( void ) { return 0; }
+ int bar( void ) __attribute__(($1("foo")));
+ ],
+ [aligned], [
+ int foo( void ) __attribute__(($1(32)));
+ ],
+ [alloc_size], [
+ void *foo(int a) __attribute__(($1(1)));
+ ],
+ [always_inline], [
+ inline __attribute__(($1)) int foo( void ) { return 0; }
+ ],
+ [artificial], [
+ inline __attribute__(($1)) int foo( void ) { return 0; }
+ ],
+ [cold], [
+ int foo( void ) __attribute__(($1));
+ ],
+ [const], [
+ int foo( void ) __attribute__(($1));
+ ],
+ [constructor], [
+ int foo( void ) __attribute__(($1));
+ ],
+ [deprecated], [
+ int foo( void ) __attribute__(($1("")));
+ ],
+ [destructor], [
+ int foo( void ) __attribute__(($1));
+ ],
+ [dllexport], [
+ __attribute__(($1)) int foo( void ) { return 0; }
+ ],
+ [dllimport], [
+ int foo( void ) __attribute__(($1));
+ ],
+ [error], [
+ int foo( void ) __attribute__(($1("")));
+ ],
+ [externally_visible], [
+ int foo( void ) __attribute__(($1));
+ ],
+ [flatten], [
+ int foo( void ) __attribute__(($1));
+ ],
+ [format], [
+ int foo(const char *p, ...) __attribute__(($1(printf, 1, 2)));
+ ],
+ [format_arg], [
+ char *foo(const char *p) __attribute__(($1(1)));
+ ],
+ [gnu_inline], [
+ inline __attribute__(($1)) int foo( void ) { return 0; }
+ ],
+ [hot], [
+ int foo( void ) __attribute__(($1));
+ ],
+ [ifunc], [
+ int my_foo( void ) { return 0; }
+ static int (*resolve_foo(void))(void) { return my_foo; }
+ int foo( void ) __attribute__(($1("resolve_foo")));
+ ],
+ [leaf], [
+ __attribute__(($1)) int foo( void ) { return 0; }
+ ],
+ [malloc], [
+ void *foo( void ) __attribute__(($1));
+ ],
+ [noclone], [
+ int foo( void ) __attribute__(($1));
+ ],
+ [noinline], [
+ __attribute__(($1)) int foo( void ) { return 0; }
+ ],
+ [nonnull], [
+ int foo(char *p) __attribute__(($1(1)));
+ ],
+ [noreturn], [
+ void foo( void ) __attribute__(($1));
+ ],
+ [nothrow], [
+ int foo( void ) __attribute__(($1));
+ ],
+ [optimize], [
+ __attribute__(($1(3))) int foo( void ) { return 0; }
+ ],
+ [pure], [
+ int foo( void ) __attribute__(($1));
+ ],
+ [unused], [
+ int foo( void ) __attribute__(($1));
+ ],
+ [used], [
+ int foo( void ) __attribute__(($1));
+ ],
+ [visibility], [
+ int foo_def( void ) __attribute__(($1("default")));
+ int foo_hid( void ) __attribute__(($1("hidden")));
+ ],
+ [warning], [
+ int foo( void ) __attribute__(($1("")));
+ ],
+ [warn_unused_result], [
+ int foo( void ) __attribute__(($1));
+ ],
+ [weak], [
+ int foo( void ) __attribute__(($1));
+ ],
+ [weakref], [
+ static int foo( void ) { return 0; }
+ static int bar( void ) __attribute__(($1("foo")));
+ ],
+ [
+ m4_warn([syntax], [Unsupported attribute $1, the test may fail])
+ int foo( void ) __attribute__(($1));
+ ]
+ )], [])
+ ],
+ dnl GCC doesn't exit with an error if an unknown attribute is
+ dnl provided but only outputs a warning, so accept the attribute
+ dnl only if no warning were issued.
+ [AS_IF([test -s conftest.err],
+ [AS_VAR_SET([ac_var], [no])],
+ [AS_VAR_SET([ac_var], [yes])])],
+ [AS_VAR_SET([ac_var], [no])])
+ ])
+
+ AS_IF([test yes = AS_VAR_GET([ac_var])],
+ [AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_FUNC_ATTRIBUTE_$1), 1,
+ [Define to 1 if the system has the `$1' function attribute])], [])
+
+ AS_VAR_POPDEF([ac_var])
+])
diff --git a/build-aux/m4/ax_pthread.m4 b/build-aux/m4/ax_pthread.m4
new file mode 100644
index 0000000000..d383ad5c6d
--- /dev/null
+++ b/build-aux/m4/ax_pthread.m4
@@ -0,0 +1,332 @@
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_pthread.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+#
+# DESCRIPTION
+#
+# This macro figures out how to build C programs using POSIX threads. It
+# sets the PTHREAD_LIBS output variable to the threads library and linker
+# flags, and the PTHREAD_CFLAGS output variable to any special C compiler
+# flags that are needed. (The user can also force certain compiler
+# flags/libs to be tested by setting these environment variables.)
+#
+# Also sets PTHREAD_CC to any special C compiler that is needed for
+# multi-threaded programs (defaults to the value of CC otherwise). (This
+# is necessary on AIX to use the special cc_r compiler alias.)
+#
+# NOTE: You are assumed to not only compile your program with these flags,
+# but also link it with them as well. e.g. you should link with
+# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
+#
+# If you are only building threads programs, you may wish to use these
+# variables in your default LIBS, CFLAGS, and CC:
+#
+# LIBS="$PTHREAD_LIBS $LIBS"
+# CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+# CC="$PTHREAD_CC"
+#
+# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant
+# has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name
+# (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
+#
+# Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the
+# PTHREAD_PRIO_INHERIT symbol is defined when compiling with
+# PTHREAD_CFLAGS.
+#
+# ACTION-IF-FOUND is a list of shell commands to run if a threads library
+# is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it
+# is not found. If ACTION-IF-FOUND is not specified, the default action
+# will define HAVE_PTHREAD.
+#
+# Please let the authors know if this macro fails on any platform, or if
+# you have any other suggestions or comments. This macro was based on work
+# by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help
+# from M. Frigo), as well as ac_pthread and hb_pthread macros posted by
+# Alejandro Forero Cuervo to the autoconf macro repository. We are also
+# grateful for the helpful feedback of numerous users.
+#
+# Updated for Autoconf 2.68 by Daniel Richard G.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
+# Copyright (c) 2011 Daniel Richard G. <skunk@iSKUNK.ORG>
+#
+# 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 <http://www.gnu.org/licenses/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 21
+
+AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD])
+AC_DEFUN([AX_PTHREAD], [
+AC_REQUIRE([AC_CANONICAL_HOST])
+AC_LANG_PUSH([C])
+ax_pthread_ok=no
+
+# We used to check for pthread.h first, but this fails if pthread.h
+# requires special compiler flags (e.g. on True64 or Sequent).
+# It gets checked for in the link test anyway.
+
+# First of all, check if the user has set any of the PTHREAD_LIBS,
+# etcetera environment variables, and if threads linking works using
+# them:
+if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+ save_LIBS="$LIBS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+ AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
+ AC_TRY_LINK_FUNC([pthread_join], [ax_pthread_ok=yes])
+ AC_MSG_RESULT([$ax_pthread_ok])
+ if test x"$ax_pthread_ok" = xno; then
+ PTHREAD_LIBS=""
+ PTHREAD_CFLAGS=""
+ fi
+ LIBS="$save_LIBS"
+ CFLAGS="$save_CFLAGS"
+fi
+
+# We must check for the threads library under a number of different
+# names; the ordering is very important because some systems
+# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
+# libraries is broken (non-POSIX).
+
+# Create a list of thread flags to try. Items starting with a "-" are
+# C compiler flags, and other items are library names, except for "none"
+# which indicates that we try without any flags at all, and "pthread-config"
+# which is a program returning the flags for the Pth emulation library.
+
+ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
+
+# The ordering *is* (sometimes) important. Some notes on the
+# individual items follow:
+
+# pthreads: AIX (must check this before -lpthread)
+# none: in case threads are in libc; should be tried before -Kthread and
+# other compiler flags to prevent continual compiler warnings
+# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
+# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
+# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
+# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
+# -pthreads: Solaris/gcc
+# -mthreads: Mingw32/gcc, Lynx/gcc
+# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
+# doesn't hurt to check since this sometimes defines pthreads too;
+# also defines -D_REENTRANT)
+# ... -mt is also the pthreads flag for HP/aCC
+# pthread: Linux, etcetera
+# --thread-safe: KAI C++
+# pthread-config: use pthread-config program (for GNU Pth library)
+
+case ${host_os} in
+ solaris*)
+
+ # On Solaris (at least, for some versions), libc contains stubbed
+ # (non-functional) versions of the pthreads routines, so link-based
+ # tests will erroneously succeed. (We need to link with -pthreads/-mt/
+ # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
+ # a function called by this macro, so we could check for that, but
+ # who knows whether they'll stub that too in a future libc.) So,
+ # we'll just look for -pthreads and -lpthread first:
+
+ ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags"
+ ;;
+
+ darwin*)
+ ax_pthread_flags="-pthread $ax_pthread_flags"
+ ;;
+esac
+
+# Clang doesn't consider unrecognized options an error unless we specify
+# -Werror. We throw in some extra Clang-specific options to ensure that
+# this doesn't happen for GCC, which also accepts -Werror.
+
+AC_MSG_CHECKING([if compiler needs -Werror to reject unknown flags])
+save_CFLAGS="$CFLAGS"
+ax_pthread_extra_flags="-Werror"
+CFLAGS="$CFLAGS $ax_pthread_extra_flags -Wunknown-warning-option -Wsizeof-array-argument"
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([int foo(void);],[foo()])],
+ [AC_MSG_RESULT([yes])],
+ [ax_pthread_extra_flags=
+ AC_MSG_RESULT([no])])
+CFLAGS="$save_CFLAGS"
+
+if test x"$ax_pthread_ok" = xno; then
+for flag in $ax_pthread_flags; do
+
+ case $flag in
+ none)
+ AC_MSG_CHECKING([whether pthreads work without any flags])
+ ;;
+
+ -*)
+ AC_MSG_CHECKING([whether pthreads work with $flag])
+ PTHREAD_CFLAGS="$flag"
+ ;;
+
+ pthread-config)
+ AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no])
+ if test x"$ax_pthread_config" = xno; then continue; fi
+ PTHREAD_CFLAGS="`pthread-config --cflags`"
+ PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
+ ;;
+
+ *)
+ AC_MSG_CHECKING([for the pthreads library -l$flag])
+ PTHREAD_LIBS="-l$flag"
+ ;;
+ esac
+
+ save_LIBS="$LIBS"
+ save_CFLAGS="$CFLAGS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS $ax_pthread_extra_flags"
+
+ # Check for various functions. We must include pthread.h,
+ # since some functions may be macros. (On the Sequent, we
+ # need a special flag -Kthread to make this header compile.)
+ # We check for pthread_join because it is in -lpthread on IRIX
+ # while pthread_create is in libc. We check for pthread_attr_init
+ # due to DEC craziness with -lpthreads. We check for
+ # pthread_cleanup_push because it is one of the few pthread
+ # functions on Solaris that doesn't have a non-functional libc stub.
+ # We try pthread_create on general principles.
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>
+ static void routine(void *a) { a = 0; }
+ static void *start_routine(void *a) { return a; }],
+ [pthread_t th; pthread_attr_t attr;
+ pthread_create(&th, 0, start_routine, 0);
+ pthread_join(th, 0);
+ pthread_attr_init(&attr);
+ pthread_cleanup_push(routine, 0);
+ pthread_cleanup_pop(0) /* ; */])],
+ [ax_pthread_ok=yes],
+ [])
+
+ LIBS="$save_LIBS"
+ CFLAGS="$save_CFLAGS"
+
+ AC_MSG_RESULT([$ax_pthread_ok])
+ if test "x$ax_pthread_ok" = xyes; then
+ break;
+ fi
+
+ PTHREAD_LIBS=""
+ PTHREAD_CFLAGS=""
+done
+fi
+
+# Various other checks:
+if test "x$ax_pthread_ok" = xyes; then
+ save_LIBS="$LIBS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+ # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
+ AC_MSG_CHECKING([for joinable pthread attribute])
+ attr_name=unknown
+ for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>],
+ [int attr = $attr; return attr /* ; */])],
+ [attr_name=$attr; break],
+ [])
+ done
+ AC_MSG_RESULT([$attr_name])
+ if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
+ AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], [$attr_name],
+ [Define to necessary symbol if this constant
+ uses a non-standard name on your system.])
+ fi
+
+ AC_MSG_CHECKING([if more special flags are required for pthreads])
+ flag=no
+ case ${host_os} in
+ aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";;
+ osf* | hpux*) flag="-D_REENTRANT";;
+ solaris*)
+ if test "$GCC" = "yes"; then
+ flag="-D_REENTRANT"
+ else
+ # TODO: What about Clang on Solaris?
+ flag="-mt -D_REENTRANT"
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT([$flag])
+ if test "x$flag" != xno; then
+ PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
+ fi
+
+ AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT],
+ [ax_cv_PTHREAD_PRIO_INHERIT], [
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]],
+ [[int i = PTHREAD_PRIO_INHERIT;]])],
+ [ax_cv_PTHREAD_PRIO_INHERIT=yes],
+ [ax_cv_PTHREAD_PRIO_INHERIT=no])
+ ])
+ AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"],
+ [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.])])
+
+ LIBS="$save_LIBS"
+ CFLAGS="$save_CFLAGS"
+
+ # More AIX lossage: compile with *_r variant
+ if test "x$GCC" != xyes; then
+ case $host_os in
+ aix*)
+ AS_CASE(["x/$CC"],
+ [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6],
+ [#handle absolute path differently from PATH based program lookup
+ AS_CASE(["x$CC"],
+ [x/*],
+ [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])],
+ [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])])
+ ;;
+ esac
+ fi
+fi
+
+test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
+
+AC_SUBST([PTHREAD_LIBS])
+AC_SUBST([PTHREAD_CFLAGS])
+AC_SUBST([PTHREAD_CC])
+
+# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
+if test x"$ax_pthread_ok" = xyes; then
+ ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1])
+ :
+else
+ ax_pthread_ok=no
+ $2
+fi
+AC_LANG_POP
+])dnl AX_PTHREAD
diff --git a/build-aux/m4/bitcoin_find_bdb48.m4 b/build-aux/m4/bitcoin_find_bdb48.m4
new file mode 100644
index 0000000000..0bf558d25b
--- /dev/null
+++ b/build-aux/m4/bitcoin_find_bdb48.m4
@@ -0,0 +1,66 @@
+AC_DEFUN([BITCOIN_FIND_BDB48],[
+ AC_MSG_CHECKING([for Berkeley DB C++ headers])
+ BDB_CPPFLAGS=
+ BDB_LIBS=
+ bdbpath=X
+ bdb48path=X
+ bdbdirlist=
+ for _vn in 4.8 48 4 5 ''; do
+ for _pfx in b lib ''; do
+ bdbdirlist="$bdbdirlist ${_pfx}db${_vn}"
+ done
+ done
+ for searchpath in $bdbdirlist ''; do
+ test -n "${searchpath}" && searchpath="${searchpath}/"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+ #include <${searchpath}db_cxx.h>
+ ]],[[
+ #if !((DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 8) || DB_VERSION_MAJOR > 4)
+ #error "failed to find bdb 4.8+"
+ #endif
+ ]])],[
+ if test "x$bdbpath" = "xX"; then
+ bdbpath="${searchpath}"
+ fi
+ ],[
+ continue
+ ])
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+ #include <${searchpath}db_cxx.h>
+ ]],[[
+ #if !(DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR == 8)
+ #error "failed to find bdb 4.8"
+ #endif
+ ]])],[
+ bdb48path="${searchpath}"
+ break
+ ],[])
+ done
+ if test "x$bdbpath" = "xX"; then
+ AC_MSG_RESULT([no])
+ AC_MSG_ERROR([libdb_cxx headers missing, Bitcoin Core requires this library for wallet functionality (--disable-wallet to disable wallet functionality)])
+ elif test "x$bdb48path" = "xX"; then
+ BITCOIN_SUBDIR_TO_INCLUDE(BDB_CPPFLAGS,[${bdbpath}],db_cxx)
+ AC_ARG_WITH([incompatible-bdb],[AS_HELP_STRING([--with-incompatible-bdb], [allow using a bdb version other than 4.8])],[
+ AC_MSG_WARN([Found Berkeley DB other than 4.8; wallets opened by this build will not be portable!])
+ ],[
+ AC_MSG_ERROR([Found Berkeley DB other than 4.8, required for portable wallets (--with-incompatible-bdb to ignore or --disable-wallet to disable wallet functionality)])
+ ])
+ else
+ BITCOIN_SUBDIR_TO_INCLUDE(BDB_CPPFLAGS,[${bdb48path}],db_cxx)
+ bdbpath="${bdb48path}"
+ fi
+ AC_SUBST(BDB_CPPFLAGS)
+
+ # TODO: Ideally this could find the library version and make sure it matches the headers being used
+ for searchlib in db_cxx-4.8 db_cxx; do
+ AC_CHECK_LIB([$searchlib],[main],[
+ BDB_LIBS="-l${searchlib}"
+ break
+ ])
+ done
+ if test "x$BDB_LIBS" = "x"; then
+ AC_MSG_ERROR([libdb_cxx missing, Bitcoin Core requires this library for wallet functionality (--disable-wallet to disable wallet functionality)])
+ fi
+ AC_SUBST(BDB_LIBS)
+])
diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4
new file mode 100644
index 0000000000..100b8653a8
--- /dev/null
+++ b/build-aux/m4/bitcoin_qt.m4
@@ -0,0 +1,433 @@
+dnl Helper for cases where a qt dependency is not met.
+dnl Output: If qt version is auto, set bitcoin_enable_qt to false. Else, exit.
+AC_DEFUN([BITCOIN_QT_FAIL],[
+ if test "x$bitcoin_qt_want_version" = "xauto" && test x$bitcoin_qt_force != xyes; then
+ if test x$bitcoin_enable_qt != xno; then
+ AC_MSG_WARN([$1; bitcoin-qt frontend will not be built])
+ fi
+ bitcoin_enable_qt=no
+ bitcoin_enable_qt_test=no
+ else
+ AC_MSG_ERROR([$1])
+ fi
+])
+
+AC_DEFUN([BITCOIN_QT_CHECK],[
+ if test "x$bitcoin_enable_qt" != "xno" && test x$bitcoin_qt_want_version != xno; then
+ true
+ $1
+ else
+ true
+ $2
+ fi
+])
+
+dnl BITCOIN_QT_PATH_PROGS([FOO], [foo foo2], [/path/to/search/first], [continue if missing])
+dnl Helper for finding the path of programs needed for Qt.
+dnl Inputs: $1: Variable to be set
+dnl Inputs: $2: List of programs to search for
+dnl Inputs: $3: Look for $2 here before $PATH
+dnl Inputs: $4: If "yes", don't fail if $2 is not found.
+dnl Output: $1 is set to the path of $2 if found. $2 are searched in order.
+AC_DEFUN([BITCOIN_QT_PATH_PROGS],[
+ BITCOIN_QT_CHECK([
+ if test "x$3" != "x"; then
+ AC_PATH_PROGS($1,$2,,$3)
+ else
+ AC_PATH_PROGS($1,$2)
+ fi
+ if test "x$$1" = "x" && test "x$4" != "xyes"; then
+ BITCOIN_QT_FAIL([$1 not found])
+ fi
+ ])
+])
+
+dnl Initialize qt input.
+dnl This must be called before any other BITCOIN_QT* macros to ensure that
+dnl input variables are set correctly.
+dnl CAUTION: Do not use this inside of a conditional.
+AC_DEFUN([BITCOIN_QT_INIT],[
+ dnl enable qt support
+ AC_ARG_WITH([gui],
+ [AS_HELP_STRING([--with-gui@<:@=no|qt4|qt5|auto@:>@],
+ [build bitcoin-qt GUI (default=auto, qt4 tried first)])],
+ [
+ bitcoin_qt_want_version=$withval
+ if test x$bitcoin_qt_want_version = xyes; then
+ bitcoin_qt_force=yes
+ bitcoin_qt_want_version=auto
+ fi
+ ],
+ [bitcoin_qt_want_version=auto])
+
+ AC_ARG_WITH([qt-incdir],[AS_HELP_STRING([--with-qt-incdir=INC_DIR],[specify qt include path (overridden by pkgconfig)])], [qt_include_path=$withval], [])
+ AC_ARG_WITH([qt-libdir],[AS_HELP_STRING([--with-qt-libdir=LIB_DIR],[specify qt lib path (overridden by pkgconfig)])], [qt_lib_path=$withval], [])
+ AC_ARG_WITH([qt-plugindir],[AS_HELP_STRING([--with-qt-plugindir=PLUGIN_DIR],[specify qt plugin path (overridden by pkgconfig)])], [qt_plugin_path=$withval], [])
+ AC_ARG_WITH([qt-translationdir],[AS_HELP_STRING([--with-qt-translationdir=PLUGIN_DIR],[specify qt translation path (overridden by pkgconfig)])], [qt_translation_path=$withval], [])
+ AC_ARG_WITH([qt-bindir],[AS_HELP_STRING([--with-qt-bindir=BIN_DIR],[specify qt bin path])], [qt_bin_path=$withval], [])
+
+ AC_ARG_WITH([qtdbus],
+ [AS_HELP_STRING([--with-qtdbus],
+ [enable DBus support (default is yes if qt is enabled and QtDBus is found)])],
+ [use_dbus=$withval],
+ [use_dbus=auto])
+
+ AC_SUBST(QT_TRANSLATION_DIR,$qt_translation_path)
+])
+
+dnl Find the appropriate version of Qt libraries and includes.
+dnl Inputs: $1: Whether or not pkg-config should be used. yes|no. Default: yes.
+dnl Inputs: $2: If $1 is "yes" and --with-gui=auto, which qt version should be
+dnl tried first.
+dnl Outputs: See _BITCOIN_QT_FIND_LIBS_*
+dnl Outputs: Sets variables for all qt-related tools.
+dnl Outputs: bitcoin_enable_qt, bitcoin_enable_qt_dbus, bitcoin_enable_qt_test
+AC_DEFUN([BITCOIN_QT_CONFIGURE],[
+ use_pkgconfig=$1
+
+ if test x$use_pkgconfig = x; then
+ use_pkgconfig=yes
+ fi
+
+ if test x$use_pkgconfig = xyes; then
+ BITCOIN_QT_CHECK([_BITCOIN_QT_FIND_LIBS_WITH_PKGCONFIG([$2])])
+ else
+ BITCOIN_QT_CHECK([_BITCOIN_QT_FIND_LIBS_WITHOUT_PKGCONFIG])
+ fi
+
+ dnl This is ugly and complicated. Yuck. Works as follows:
+ dnl We can't discern whether Qt4 builds are static or not. For Qt5, we can
+ dnl check a header to find out. When Qt is built statically, some plugins must
+ dnl be linked into the final binary as well. These plugins have changed between
+ dnl Qt4 and Qt5. With Qt5, languages moved into core and the WindowsIntegration
+ dnl plugin was added. Since we can't tell if Qt4 is static or not, it is
+ dnl assumed for windows builds.
+ dnl _BITCOIN_QT_CHECK_STATIC_PLUGINS does a quick link-check and appends the
+ dnl results to QT_LIBS.
+ BITCOIN_QT_CHECK([
+ TEMP_CPPFLAGS=$CPPFLAGS
+ CPPFLAGS="$QT_INCLUDES $CPPFLAGS"
+ if test x$bitcoin_qt_got_major_vers = x5; then
+ _BITCOIN_QT_IS_STATIC
+ if test x$bitcoin_cv_static_qt = xyes; then
+ AC_DEFINE(QT_STATICPLUGIN, 1, [Define this symbol if qt plugins are static])
+ if test x$qt_plugin_path != x; then
+ QT_LIBS="$QT_LIBS -L$qt_plugin_path/platforms"
+ fi
+ if test x$use_pkgconfig = xyes; then
+ PKG_CHECK_MODULES([QTPLATFORM], [Qt5PlatformSupport], [QT_LIBS="$QTPLATFORM_LIBS $QT_LIBS"])
+ fi
+ AC_CACHE_CHECK(for Qt < 5.4, bitcoin_cv_need_acc_widget,[AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
+ [[#include <QtCore>]],[[
+ #if QT_VERSION >= 0x050400
+ choke;
+ #endif
+ ]])],
+ [bitcoin_cv_need_acc_widget=yes],
+ [bitcoin_cv_need_acc_widget=no])
+ ])
+ if test "x$bitcoin_cv_need_acc_widget" = "xyes"; then
+ if test x$qt_plugin_path != x; then
+ QT_LIBS="$QT_LIBS -L$qt_plugin_path/accessible"
+ fi
+ _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(AccessibleFactory)], [-lqtaccessiblewidgets])
+ fi
+ if test x$TARGET_OS = xwindows; then
+ _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin)],[-lqwindows])
+ AC_DEFINE(QT_QPA_PLATFORM_WINDOWS, 1, [Define this symbol if the qt platform is windows])
+ elif test x$TARGET_OS = xlinux; then
+ PKG_CHECK_MODULES([X11XCB], [x11-xcb], [QT_LIBS="$X11XCB_LIBS $QT_LIBS"])
+ if ${PKG_CONFIG} --exists "Qt5Core >= 5.5" 2>/dev/null; then
+ PKG_CHECK_MODULES([QTXCBQPA], [Qt5XcbQpa], [QT_LIBS="$QTXCBQPA_LIBS $QT_LIBS"])
+ fi
+ _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(QXcbIntegrationPlugin)],[-lqxcb -lxcb-static])
+ AC_DEFINE(QT_QPA_PLATFORM_XCB, 1, [Define this symbol if the qt platform is xcb])
+ elif test x$TARGET_OS = xdarwin; then
+ if test x$use_pkgconfig = xyes; then
+ PKG_CHECK_MODULES([QTPRINT], [Qt5PrintSupport], [QT_LIBS="$QTPRINT_LIBS $QT_LIBS"])
+ fi
+ AX_CHECK_LINK_FLAG([[-framework IOKit]],[QT_LIBS="$QT_LIBS -framework IOKit"],[AC_MSG_ERROR(could not iokit framework)])
+ _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin)],[-lqcocoa])
+ AC_DEFINE(QT_QPA_PLATFORM_COCOA, 1, [Define this symbol if the qt platform is cocoa])
+ fi
+ fi
+ else
+ if test x$TARGET_OS = xwindows; then
+ AC_DEFINE(QT_STATICPLUGIN, 1, [Define this symbol if qt plugins are static])
+ if test x$qt_plugin_path != x; then
+ QT_LIBS="$QT_LIBS -L$qt_plugin_path/accessible"
+ QT_LIBS="$QT_LIBS -L$qt_plugin_path/codecs"
+ fi
+ _BITCOIN_QT_CHECK_STATIC_PLUGINS([
+ Q_IMPORT_PLUGIN(qcncodecs)
+ Q_IMPORT_PLUGIN(qjpcodecs)
+ Q_IMPORT_PLUGIN(qtwcodecs)
+ Q_IMPORT_PLUGIN(qkrcodecs)
+ Q_IMPORT_PLUGIN(AccessibleFactory)],
+ [-lqcncodecs -lqjpcodecs -lqtwcodecs -lqkrcodecs -lqtaccessiblewidgets])
+ fi
+ fi
+ CPPFLAGS=$TEMP_CPPFLAGS
+ ])
+
+ if test x$use_pkgconfig$qt_bin_path = xyes; then
+ if test x$bitcoin_qt_got_major_vers = x5; then
+ qt_bin_path="`$PKG_CONFIG --variable=host_bins Qt5Core 2>/dev/null`"
+ fi
+ fi
+
+ BITCOIN_QT_PATH_PROGS([MOC], [moc-qt${bitcoin_qt_got_major_vers} moc${bitcoin_qt_got_major_vers} moc], $qt_bin_path)
+ BITCOIN_QT_PATH_PROGS([UIC], [uic-qt${bitcoin_qt_got_major_vers} uic${bitcoin_qt_got_major_vers} uic], $qt_bin_path)
+ BITCOIN_QT_PATH_PROGS([RCC], [rcc-qt${bitcoin_qt_got_major_vers} rcc${bitcoin_qt_got_major_vers} rcc], $qt_bin_path)
+ BITCOIN_QT_PATH_PROGS([LRELEASE], [lrelease-qt${bitcoin_qt_got_major_vers} lrelease${bitcoin_qt_got_major_vers} lrelease], $qt_bin_path)
+ BITCOIN_QT_PATH_PROGS([LUPDATE], [lupdate-qt${bitcoin_qt_got_major_vers} lupdate${bitcoin_qt_got_major_vers} lupdate],$qt_bin_path, yes)
+
+ MOC_DEFS='-DHAVE_CONFIG_H -I$(srcdir)'
+ case $host in
+ *darwin*)
+ BITCOIN_QT_CHECK([
+ MOC_DEFS="${MOC_DEFS} -DQ_OS_MAC"
+ base_frameworks="-framework Foundation -framework ApplicationServices -framework AppKit"
+ AX_CHECK_LINK_FLAG([[$base_frameworks]],[QT_LIBS="$QT_LIBS $base_frameworks"],[AC_MSG_ERROR(could not find base frameworks)])
+ ])
+ ;;
+ *mingw*)
+ BITCOIN_QT_CHECK([
+ AX_CHECK_LINK_FLAG([[-mwindows]],[QT_LDFLAGS="$QT_LDFLAGS -mwindows"],[AC_MSG_WARN(-mwindows linker support not detected)])
+ ])
+ esac
+
+
+ dnl enable qt support
+ AC_MSG_CHECKING(whether to build Bitcoin Core GUI)
+ BITCOIN_QT_CHECK([
+ bitcoin_enable_qt=yes
+ bitcoin_enable_qt_test=yes
+ if test x$have_qt_test = xno; then
+ bitcoin_enable_qt_test=no
+ fi
+ bitcoin_enable_qt_dbus=no
+ if test x$use_dbus != xno && test x$have_qt_dbus = xyes; then
+ bitcoin_enable_qt_dbus=yes
+ fi
+ if test x$use_dbus = xyes && test x$have_qt_dbus = xno; then
+ AC_MSG_ERROR("libQtDBus not found. Install libQtDBus or remove --with-qtdbus.")
+ fi
+ if test x$LUPDATE = x; then
+ AC_MSG_WARN("lupdate is required to update qt translations")
+ fi
+ ],[
+ bitcoin_enable_qt=no
+ ])
+ AC_MSG_RESULT([$bitcoin_enable_qt (Qt${bitcoin_qt_got_major_vers})])
+
+ AC_SUBST(QT_INCLUDES)
+ AC_SUBST(QT_LIBS)
+ AC_SUBST(QT_LDFLAGS)
+ AC_SUBST(QT_DBUS_INCLUDES)
+ AC_SUBST(QT_DBUS_LIBS)
+ AC_SUBST(QT_TEST_INCLUDES)
+ AC_SUBST(QT_TEST_LIBS)
+ AC_SUBST(QT_SELECT, qt${bitcoin_qt_got_major_vers})
+ AC_SUBST(MOC_DEFS)
+])
+
+dnl All macros below are internal and should _not_ be used from the main
+dnl configure.ac.
+dnl ----
+
+dnl Internal. Check if the included version of Qt is Qt5.
+dnl Requires: INCLUDES must be populated as necessary.
+dnl Output: bitcoin_cv_qt5=yes|no
+AC_DEFUN([_BITCOIN_QT_CHECK_QT5],[
+ AC_CACHE_CHECK(for Qt 5, bitcoin_cv_qt5,[
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
+ [[#include <QtCore>]],
+ [[
+ #if QT_VERSION < 0x050000
+ choke me
+ #else
+ return 0;
+ #endif
+ ]])],
+ [bitcoin_cv_qt5=yes],
+ [bitcoin_cv_qt5=no])
+])])
+
+dnl Internal. Check if the linked version of Qt was built as static libs.
+dnl Requires: Qt5. This check cannot determine if Qt4 is static.
+dnl Requires: INCLUDES and LIBS must be populated as necessary.
+dnl Output: bitcoin_cv_static_qt=yes|no
+dnl Output: Defines QT_STATICPLUGIN if plugins are static.
+AC_DEFUN([_BITCOIN_QT_IS_STATIC],[
+ AC_CACHE_CHECK(for static Qt, bitcoin_cv_static_qt,[
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
+ [[#include <QtCore>]],
+ [[
+ #if defined(QT_STATIC)
+ return 0;
+ #else
+ choke me
+ #endif
+ ]])],
+ [bitcoin_cv_static_qt=yes],
+ [bitcoin_cv_static_qt=no])
+ ])
+ if test xbitcoin_cv_static_qt = xyes; then
+ AC_DEFINE(QT_STATICPLUGIN, 1, [Define this symbol for static Qt plugins])
+ fi
+])
+
+dnl Internal. Check if the link-requirements for static plugins are met.
+dnl Requires: INCLUDES and LIBS must be populated as necessary.
+dnl Inputs: $1: A series of Q_IMPORT_PLUGIN().
+dnl Inputs: $2: The libraries that resolve $1.
+dnl Output: QT_LIBS is prepended or configure exits.
+AC_DEFUN([_BITCOIN_QT_CHECK_STATIC_PLUGINS],[
+ AC_MSG_CHECKING(for static Qt plugins: $2)
+ CHECK_STATIC_PLUGINS_TEMP_LIBS="$LIBS"
+ LIBS="$2 $QT_LIBS $LIBS"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+ #define QT_STATICPLUGIN
+ #include <QtPlugin>
+ $1]],
+ [[return 0;]])],
+ [AC_MSG_RESULT(yes); QT_LIBS="$2 $QT_LIBS"],
+ [AC_MSG_RESULT(no); BITCOIN_QT_FAIL(Could not resolve: $2)])
+ LIBS="$CHECK_STATIC_PLUGINS_TEMP_LIBS"
+])
+
+dnl Internal. Find Qt libraries using pkg-config.
+dnl Inputs: bitcoin_qt_want_version (from --with-gui=). The version to check
+dnl first.
+dnl Inputs: $1: If bitcoin_qt_want_version is "auto", check for this version
+dnl first.
+dnl Outputs: All necessary QT_* variables are set.
+dnl Outputs: bitcoin_qt_got_major_vers is set to "4" or "5".
+dnl Outputs: have_qt_test and have_qt_dbus are set (if applicable) to yes|no.
+AC_DEFUN([_BITCOIN_QT_FIND_LIBS_WITH_PKGCONFIG],[
+ m4_ifdef([PKG_CHECK_MODULES],[
+ auto_priority_version=$1
+ if test x$auto_priority_version = x; then
+ auto_priority_version=qt5
+ fi
+ if test x$bitcoin_qt_want_version = xqt5 || ( test x$bitcoin_qt_want_version = xauto && test x$auto_priority_version = xqt5 ); then
+ QT_LIB_PREFIX=Qt5
+ bitcoin_qt_got_major_vers=5
+ else
+ QT_LIB_PREFIX=Qt
+ bitcoin_qt_got_major_vers=4
+ fi
+ qt5_modules="Qt5Core Qt5Gui Qt5Network Qt5Widgets"
+ qt4_modules="QtCore QtGui QtNetwork"
+ BITCOIN_QT_CHECK([
+ if test x$bitcoin_qt_want_version = xqt5 || ( test x$bitcoin_qt_want_version = xauto && test x$auto_priority_version = xqt5 ); then
+ PKG_CHECK_MODULES([QT], [$qt5_modules], [QT_INCLUDES="$QT_CFLAGS"; have_qt=yes],[have_qt=no])
+ elif test x$bitcoin_qt_want_version = xqt4 || ( test x$bitcoin_qt_want_version = xauto && test x$auto_priority_version = xqt4 ); then
+ PKG_CHECK_MODULES([QT], [$qt4_modules], [QT_INCLUDES="$QT_CFLAGS"; have_qt=yes], [have_qt=no])
+ fi
+
+ dnl qt version is set to 'auto' and the preferred version wasn't found. Now try the other.
+ if test x$have_qt = xno && test x$bitcoin_qt_want_version = xauto; then
+ if test x$auto_priority_version = x$qt5; then
+ PKG_CHECK_MODULES([QT], [$qt4_modules], [QT_INCLUDES="$QT_CFLAGS"; have_qt=yes; QT_LIB_PREFIX=Qt; bitcoin_qt_got_major_vers=4], [have_qt=no])
+ else
+ PKG_CHECK_MODULES([QT], [$qt5_modules], [QT_INCLUDES="$QT_CFLAGS"; have_qt=yes; QT_LIB_PREFIX=Qt5; bitcoin_qt_got_major_vers=5], [have_qt=no])
+ fi
+ fi
+ if test x$have_qt != xyes; then
+ have_qt=no
+ BITCOIN_QT_FAIL([Qt dependencies not found])
+ fi
+ ])
+ BITCOIN_QT_CHECK([
+ PKG_CHECK_MODULES([QT_TEST], [${QT_LIB_PREFIX}Test], [QT_TEST_INCLUDES="$QT_TEST_CFLAGS"; have_qt_test=yes], [have_qt_test=no])
+ if test x$use_dbus != xno; then
+ PKG_CHECK_MODULES([QT_DBUS], [${QT_LIB_PREFIX}DBus], [QT_DBUS_INCLUDES="$QT_DBUS_CFLAGS"; have_qt_dbus=yes], [have_qt_dbus=no])
+ fi
+ ])
+ ])
+ true; dnl
+])
+
+dnl Internal. Find Qt libraries without using pkg-config. Version is deduced
+dnl from the discovered headers.
+dnl Inputs: bitcoin_qt_want_version (from --with-gui=). The version to use.
+dnl If "auto", the version will be discovered by _BITCOIN_QT_CHECK_QT5.
+dnl Outputs: All necessary QT_* variables are set.
+dnl Outputs: bitcoin_qt_got_major_vers is set to "4" or "5".
+dnl Outputs: have_qt_test and have_qt_dbus are set (if applicable) to yes|no.
+AC_DEFUN([_BITCOIN_QT_FIND_LIBS_WITHOUT_PKGCONFIG],[
+ TEMP_CPPFLAGS="$CPPFLAGS"
+ TEMP_LIBS="$LIBS"
+ BITCOIN_QT_CHECK([
+ if test x$qt_include_path != x; then
+ QT_INCLUDES="-I$qt_include_path -I$qt_include_path/QtCore -I$qt_include_path/QtGui -I$qt_include_path/QtWidgets -I$qt_include_path/QtNetwork -I$qt_include_path/QtTest -I$qt_include_path/QtDBus"
+ CPPFLAGS="$QT_INCLUDES $CPPFLAGS"
+ fi
+ ])
+
+ BITCOIN_QT_CHECK([AC_CHECK_HEADER([QtPlugin],,BITCOIN_QT_FAIL(QtCore headers missing))])
+ BITCOIN_QT_CHECK([AC_CHECK_HEADER([QApplication],, BITCOIN_QT_FAIL(QtGui headers missing))])
+ BITCOIN_QT_CHECK([AC_CHECK_HEADER([QLocalSocket],, BITCOIN_QT_FAIL(QtNetwork headers missing))])
+
+ BITCOIN_QT_CHECK([
+ if test x$bitcoin_qt_want_version = xauto; then
+ _BITCOIN_QT_CHECK_QT5
+ fi
+ if test x$bitcoin_cv_qt5 = xyes || test x$bitcoin_qt_want_version = xqt5; then
+ QT_LIB_PREFIX=Qt5
+ bitcoin_qt_got_major_vers=5
+ else
+ QT_LIB_PREFIX=Qt
+ bitcoin_qt_got_major_vers=4
+ fi
+ ])
+
+ BITCOIN_QT_CHECK([
+ LIBS=
+ if test x$qt_lib_path != x; then
+ LIBS="$LIBS -L$qt_lib_path"
+ fi
+
+ if test x$TARGET_OS = xwindows; then
+ AC_CHECK_LIB([imm32], [main],, BITCOIN_QT_FAIL(libimm32 not found))
+ fi
+ ])
+
+ BITCOIN_QT_CHECK(AC_CHECK_LIB([z] ,[main],,AC_MSG_WARN([zlib not found. Assuming qt has it built-in])))
+ BITCOIN_QT_CHECK(AC_CHECK_LIB([png] ,[main],,AC_MSG_WARN([libpng not found. Assuming qt has it built-in])))
+ BITCOIN_QT_CHECK(AC_CHECK_LIB([jpeg] ,[main],,AC_MSG_WARN([libjpeg not found. Assuming qt has it built-in])))
+ BITCOIN_QT_CHECK(AC_SEARCH_LIBS([pcre16_exec], [qtpcre pcre16],,AC_MSG_WARN([libpcre16 not found. Assuming qt has it built-in])))
+ BITCOIN_QT_CHECK(AC_SEARCH_LIBS([hb_ot_tags_from_script] ,[qtharfbuzzng harfbuzz],,AC_MSG_WARN([libharfbuzz not found. Assuming qt has it built-in or support is disabled])))
+ BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}Core] ,[main],,BITCOIN_QT_FAIL(lib$QT_LIB_PREFIXCore not found)))
+ BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}Gui] ,[main],,BITCOIN_QT_FAIL(lib$QT_LIB_PREFIXGui not found)))
+ BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}Network],[main],,BITCOIN_QT_FAIL(lib$QT_LIB_PREFIXNetwork not found)))
+ if test x$bitcoin_qt_got_major_vers = x5; then
+ BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}Widgets],[main],,BITCOIN_QT_FAIL(lib$QT_LIB_PREFIXWidgets not found)))
+ fi
+ QT_LIBS="$LIBS"
+ LIBS="$TEMP_LIBS"
+
+ BITCOIN_QT_CHECK([
+ LIBS=
+ if test x$qt_lib_path != x; then
+ LIBS="-L$qt_lib_path"
+ fi
+ AC_CHECK_LIB([${QT_LIB_PREFIX}Test], [main],, have_qt_test=no)
+ AC_CHECK_HEADER([QTest],, have_qt_test=no)
+ QT_TEST_LIBS="$LIBS"
+ if test x$use_dbus != xno; then
+ LIBS=
+ if test x$qt_lib_path != x; then
+ LIBS="-L$qt_lib_path"
+ fi
+ AC_CHECK_LIB([${QT_LIB_PREFIX}DBus], [main],, have_qt_dbus=no)
+ AC_CHECK_HEADER([QtDBus],, have_qt_dbus=no)
+ QT_DBUS_LIBS="$LIBS"
+ fi
+ ])
+ CPPFLAGS="$TEMP_CPPFLAGS"
+ LIBS="$TEMP_LIBS"
+])
+
diff --git a/build-aux/m4/bitcoin_subdir_to_include.m4 b/build-aux/m4/bitcoin_subdir_to_include.m4
new file mode 100644
index 0000000000..66f106c7d4
--- /dev/null
+++ b/build-aux/m4/bitcoin_subdir_to_include.m4
@@ -0,0 +1,14 @@
+dnl BITCOIN_SUBDIR_TO_INCLUDE([CPPFLAGS-VARIABLE-NAME],[SUBDIRECTORY-NAME],[HEADER-FILE])
+dnl SUBDIRECTORY-NAME must end with a path separator
+AC_DEFUN([BITCOIN_SUBDIR_TO_INCLUDE],[
+ if test "x$2" = "x"; then
+ AC_MSG_RESULT([default])
+ else
+ echo "#include <$2$3.h>" >conftest.cpp
+ newinclpath=`${CXXCPP} ${CPPFLAGS} -M conftest.cpp 2>/dev/null | [ tr -d '\\n\\r\\\\' | sed -e 's/^.*[[:space:]:]\(\/[^[:space:]]*\)]$3[\.h[[:space:]].*$/\1/' -e t -e d`]
+ AC_MSG_RESULT([${newinclpath}])
+ if test "x${newinclpath}" != "x"; then
+ eval "$1=\"\$$1\"' -I${newinclpath}'"
+ fi
+ fi
+])
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000000..fd74aef269
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,927 @@
+dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N)
+AC_PREREQ([2.60])
+define(_CLIENT_VERSION_MAJOR, 0)
+define(_CLIENT_VERSION_MINOR, 11)
+define(_CLIENT_VERSION_REVISION, 1)
+define(_CLIENT_VERSION_BUILD, 0)
+define(_CLIENT_VERSION_IS_RELEASE, true)
+define(_COPYRIGHT_YEAR, 2015)
+AC_INIT([Bitcoin Core],[_CLIENT_VERSION_MAJOR._CLIENT_VERSION_MINOR._CLIENT_VERSION_REVISION],[https://github.com/bitcoin/bitcoin/issues],[bitcoin])
+AC_CONFIG_SRCDIR([src/main.cpp])
+AC_CONFIG_HEADERS([src/config/bitcoin-config.h])
+AC_CONFIG_AUX_DIR([build-aux])
+AC_CONFIG_MACRO_DIR([build-aux/m4])
+
+AC_CANONICAL_HOST
+
+AH_TOP([#ifndef BITCOIN_CONFIG_H])
+AH_TOP([#define BITCOIN_CONFIG_H])
+AH_BOTTOM([#endif //BITCOIN_CONFIG_H])
+
+dnl faketime breaks configure and is only needed for make. Disable it here.
+unset FAKETIME
+
+dnl Automake init set-up and checks
+AM_INIT_AUTOMAKE([no-define subdir-objects foreign])
+
+dnl faketime messes with timestamps and causes configure to be re-run.
+dnl --disable-maintainer-mode can be used to bypass this.
+AM_MAINTAINER_MODE([enable])
+
+dnl make the compilation flags quiet unless V=1 is used
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
+
+dnl Compiler checks (here before libtool).
+if test "x${CXXFLAGS+set}" = "xset"; then
+ CXXFLAGS_overridden=yes
+else
+ CXXFLAGS_overridden=no
+fi
+AC_PROG_CXX
+m4_ifdef([AC_PROG_OBJCXX],[AC_PROG_OBJCXX])
+
+dnl By default, libtool for mingw refuses to link static libs into a dll for
+dnl fear of mixing pic/non-pic objects, and import/export complications. Since
+dnl we have those under control, re-enable that functionality.
+case $host in
+ *mingw*)
+ lt_cv_deplibs_check_method="pass_all"
+ ;;
+esac
+dnl Libtool init checks.
+LT_INIT([pic-only])
+
+dnl Check/return PATH for base programs.
+AC_PATH_TOOL(AR, ar)
+AC_PATH_TOOL(RANLIB, ranlib)
+AC_PATH_TOOL(STRIP, strip)
+AC_PATH_TOOL(GCOV, gcov)
+AC_PATH_PROG(LCOV, lcov)
+AC_PATH_PROG(JAVA, java)
+AC_PATH_PROG(GENHTML, genhtml)
+AC_PATH_PROG([GIT], [git])
+AC_PATH_PROG(CCACHE,ccache)
+AC_PATH_PROG(XGETTEXT,xgettext)
+AC_PATH_PROG(HEXDUMP,hexdump)
+
+dnl pkg-config check.
+PKG_PROG_PKG_CONFIG
+
+# Enable wallet
+AC_ARG_ENABLE([wallet],
+ [AS_HELP_STRING([--enable-wallet],
+ [enable wallet (default is yes)])],
+ [enable_wallet=$enableval],
+ [enable_wallet=yes])
+
+AC_ARG_WITH([miniupnpc],
+ [AS_HELP_STRING([--with-miniupnpc],
+ [enable UPNP (default is yes if libminiupnpc is found)])],
+ [use_upnp=$withval],
+ [use_upnp=auto])
+
+AC_ARG_ENABLE([upnp-default],
+ [AS_HELP_STRING([--enable-upnp-default],
+ [if UPNP is enabled, turn it on at startup (default is no)])],
+ [use_upnp_default=$enableval],
+ [use_upnp_default=no])
+
+AC_ARG_ENABLE(tests,
+ AS_HELP_STRING([--enable-tests],[compile tests (default is yes)]),
+ [use_tests=$enableval],
+ [use_tests=yes])
+
+AC_ARG_WITH([comparison-tool],
+ AS_HELP_STRING([--with-comparison-tool],[path to java comparison tool (requires --enable-tests)]),
+ [use_comparison_tool=$withval],
+ [use_comparison_tool=no])
+
+AC_ARG_ENABLE([comparison-tool-reorg-tests],
+ AS_HELP_STRING([--enable-comparison-tool-reorg-tests],[enable expensive reorg tests in the comparison tool (default no)]),
+ [use_comparison_tool_reorg_tests=$enableval],
+ [use_comparison_tool_reorg_tests=no])
+
+AC_ARG_WITH([qrencode],
+ [AS_HELP_STRING([--with-qrencode],
+ [enable QR code support (default is yes if qt is enabled and libqrencode is found)])],
+ [use_qr=$withval],
+ [use_qr=auto])
+
+AC_ARG_ENABLE([hardening],
+ [AS_HELP_STRING([--enable-hardening],
+ [attempt to harden the resulting executables (default is yes)])],
+ [use_hardening=$enableval],
+ [use_hardening=yes])
+
+AC_ARG_ENABLE([reduce-exports],
+ [AS_HELP_STRING([--enable-reduce-exports],
+ [attempt to reduce exported symbols in the resulting executables (default is no)])],
+ [use_reduce_exports=$enableval],
+ [use_reduce_exports=no])
+
+AC_ARG_ENABLE([ccache],
+ [AS_HELP_STRING([--enable-ccache],
+ [use ccache for building (default is yes if ccache is found)])],
+ [use_ccache=$enableval],
+ [use_ccache=auto])
+
+AC_ARG_ENABLE([lcov],
+ [AS_HELP_STRING([--enable-lcov],
+ [enable lcov testing (default is no)])],
+ [use_lcov=yes],
+ [use_lcov=no])
+
+AC_ARG_ENABLE([glibc-back-compat],
+ [AS_HELP_STRING([--enable-glibc-back-compat],
+ [enable backwards compatibility with glibc])],
+ [use_glibc_compat=$enableval],
+ [use_glibc_compat=no])
+
+AC_ARG_WITH([protoc-bindir],[AS_HELP_STRING([--with-protoc-bindir=BIN_DIR],[specify protoc bin path])], [protoc_bin_path=$withval], [])
+
+# Enable debug
+AC_ARG_ENABLE([debug],
+ [AS_HELP_STRING([--enable-debug],
+ [use debug compiler flags and macros (default is no)])],
+ [enable_debug=$enableval],
+ [enable_debug=no])
+
+if test "x$enable_debug" = xyes; then
+ if test "x$GCC" = xyes; then
+ CFLAGS="-g3 -O0 -DDEBUG"
+ fi
+
+ if test "x$GXX" = xyes; then
+ CXXFLAGS="-g3 -O0 -DDEBUG"
+ fi
+fi
+
+## TODO: Remove these hard-coded paths and flags. They are here for the sake of
+## compatibility with the legacy buildsystem.
+##
+if test "x$CXXFLAGS_overridden" = "xno"; then
+ CXXFLAGS="$CXXFLAGS -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter"
+fi
+CPPFLAGS="$CPPFLAGS -DBOOST_SPIRIT_THREADSAFE -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS"
+
+AC_ARG_WITH([utils],
+ [AS_HELP_STRING([--with-utils],
+ [build bitcoin-cli bitcoin-tx (default=yes)])],
+ [build_bitcoin_utils=$withval],
+ [build_bitcoin_utils=yes])
+
+AC_ARG_WITH([libs],
+ [AS_HELP_STRING([--with-libs],
+ [build libraries (default=yes)])],
+ [build_bitcoin_libs=$withval],
+ [build_bitcoin_libs=yes])
+
+AC_ARG_WITH([daemon],
+ [AS_HELP_STRING([--with-daemon],
+ [build bitcoind daemon (default=yes)])],
+ [build_bitcoind=$withval],
+ [build_bitcoind=yes])
+
+AC_LANG_PUSH([C++])
+
+use_pkgconfig=yes
+case $host in
+ *mingw*)
+
+ #pkgconfig does more harm than good with MinGW
+ use_pkgconfig=no
+
+ TARGET_OS=windows
+ AC_CHECK_LIB([mingwthrd], [main],, AC_MSG_ERROR(lib missing))
+ AC_CHECK_LIB([kernel32], [main],, AC_MSG_ERROR(lib missing))
+ AC_CHECK_LIB([user32], [main],, AC_MSG_ERROR(lib missing))
+ AC_CHECK_LIB([gdi32], [main],, AC_MSG_ERROR(lib missing))
+ AC_CHECK_LIB([comdlg32], [main],, AC_MSG_ERROR(lib missing))
+ AC_CHECK_LIB([winspool], [main],, AC_MSG_ERROR(lib missing))
+ AC_CHECK_LIB([winmm], [main],, AC_MSG_ERROR(lib missing))
+ AC_CHECK_LIB([shell32], [main],, AC_MSG_ERROR(lib missing))
+ AC_CHECK_LIB([comctl32], [main],, AC_MSG_ERROR(lib missing))
+ AC_CHECK_LIB([ole32], [main],, AC_MSG_ERROR(lib missing))
+ AC_CHECK_LIB([oleaut32], [main],, AC_MSG_ERROR(lib missing))
+ AC_CHECK_LIB([uuid], [main],, AC_MSG_ERROR(lib missing))
+ AC_CHECK_LIB([rpcrt4], [main],, AC_MSG_ERROR(lib missing))
+ AC_CHECK_LIB([advapi32], [main],, AC_MSG_ERROR(lib missing))
+ AC_CHECK_LIB([ws2_32], [main],, AC_MSG_ERROR(lib missing))
+ AC_CHECK_LIB([mswsock], [main],, AC_MSG_ERROR(lib missing))
+ AC_CHECK_LIB([shlwapi], [main],, AC_MSG_ERROR(lib missing))
+ AC_CHECK_LIB([iphlpapi], [main],, AC_MSG_ERROR(lib missing))
+ AC_CHECK_LIB([crypt32], [main],, AC_MSG_ERROR(lib missing))
+
+ # -static is interpreted by libtool, where it has a different meaning.
+ # In libtool-speak, it's -all-static.
+ AX_CHECK_LINK_FLAG([[-static]],[LIBTOOL_APP_LDFLAGS="$LIBTOOL_APP_LDFLAGS -all-static"])
+
+ AC_PATH_PROG([MAKENSIS], [makensis], none)
+ if test x$MAKENSIS = xnone; then
+ AC_MSG_WARN("makensis not found. Cannot create installer.")
+ fi
+
+ AC_PATH_TOOL(WINDRES, windres, none)
+ if test x$WINDRES = xnone; then
+ AC_MSG_ERROR("windres not found")
+ fi
+
+ CPPFLAGS="$CPPFLAGS -D_MT -DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB"
+ LEVELDB_TARGET_FLAGS="TARGET_OS=OS_WINDOWS_CROSSCOMPILE"
+ if test "x$CXXFLAGS_overridden" = "xno"; then
+ CXXFLAGS="$CXXFLAGS -w"
+ fi
+ case $host in
+ i?86-*) WINDOWS_BITS=32 ;;
+ x86_64-*) WINDOWS_BITS=64 ;;
+ *) AC_MSG_ERROR("Could not determine win32/win64 for installer") ;;
+ esac
+ AC_SUBST(WINDOWS_BITS)
+
+ dnl libtool insists upon adding -nostdlib and a list of objects/libs to link against.
+ dnl That breaks our ability to build dll's with static libgcc/libstdc++/libssp. Override
+ dnl its command here, with the predeps/postdeps removed, and -static inserted. Postdeps are
+ dnl also overridden to prevent their insertion later.
+ dnl This should only affect dll's.
+ archive_cmds_CXX="\$CC -shared \$libobjs \$deplibs \$compiler_flags -static -o \$output_objdir/\$soname \${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker \$lib"
+ postdeps_CXX=
+
+ ;;
+ *darwin*)
+ TARGET_OS=darwin
+ LEVELDB_TARGET_FLAGS="TARGET_OS=Darwin"
+ if test x$cross_compiling != xyes; then
+ BUILD_OS=darwin
+ AC_CHECK_PROG([PORT],port, port)
+ if test x$PORT = xport; then
+ dnl add default macports paths
+ CPPFLAGS="$CPPFLAGS -isystem /opt/local/include"
+ LIBS="$LIBS -L/opt/local/lib"
+ if test -d /opt/local/include/db48; then
+ CPPFLAGS="$CPPFLAGS -I/opt/local/include/db48"
+ LIBS="$LIBS -L/opt/local/lib/db48"
+ fi
+ fi
+
+ AC_CHECK_PROG([BREW],brew, brew)
+ if test x$BREW = xbrew; then
+ dnl These Homebrew packages may be keg-only, meaning that they won't be found
+ dnl in expected paths because they may conflict with system files. Ask
+ dnl Homebrew where each one is located, then adjust paths accordingly.
+ dnl It's safe to add these paths even if the functionality is disabled by
+ dnl the user (--without-wallet or --without-gui for example).
+
+ openssl_prefix=`$BREW --prefix openssl 2>/dev/null`
+ bdb_prefix=`$BREW --prefix berkeley-db4 2>/dev/null`
+ qt5_prefix=`$BREW --prefix qt5 2>/dev/null`
+ if test x$openssl_prefix != x; then
+ PKG_CONFIG_PATH="$openssl_prefix/lib/pkgconfig:$PKG_CONFIG_PATH"
+ export PKG_CONFIG_PATH
+ fi
+ if test x$bdb_prefix != x; then
+ CPPFLAGS="$CPPFLAGS -I$bdb_prefix/include"
+ LIBS="$LIBS -L$bdb_prefix/lib"
+ fi
+ if test x$qt5_prefix != x; then
+ PKG_CONFIG_PATH="$qt5_prefix/lib/pkgconfig:$PKG_CONFIG_PATH"
+ export PKG_CONFIG_PATH
+ fi
+ fi
+ else
+ case $build_os in
+ *darwin*)
+ BUILD_OS=darwin
+ ;;
+ *)
+ AC_PATH_TOOL([INSTALLNAMETOOL], [install_name_tool], install_name_tool)
+ AC_PATH_TOOL([OTOOL], [otool], otool)
+ AC_PATH_PROGS([GENISOIMAGE], [genisoimage mkisofs],genisoimage)
+
+ dnl libtool will try to strip the static lib, which is a problem for
+ dnl cross-builds because strip attempts to call a hard-coded ld,
+ dnl which may not exist in the path. Stripping the .a is not
+ dnl necessary, so just disable it.
+ old_striplib=
+ ;;
+ esac
+ fi
+
+ AX_CHECK_LINK_FLAG([[-Wl,-headerpad_max_install_names]], [LDFLAGS="$LDFLAGS -Wl,-headerpad_max_install_names"])
+ CPPFLAGS="$CPPFLAGS -DMAC_OSX"
+ ;;
+ *linux*)
+ TARGET_OS=linux
+ ;;
+ *)
+ ;;
+esac
+
+if test x$use_comparison_tool != xno; then
+ AC_SUBST(JAVA_COMPARISON_TOOL, $use_comparison_tool)
+fi
+
+if test x$use_comparison_tool_reorg_tests != xno; then
+ if test x$use_comparison_tool = x; then
+ AC_MSG_ERROR("comparison tool reorg tests but comparison tool was not specified")
+ fi
+ AC_SUBST(COMPARISON_TOOL_REORG_TESTS, 1)
+else
+ AC_SUBST(COMPARISON_TOOL_REORG_TESTS, 0)
+fi
+
+if test x$use_lcov = xyes; then
+ if test x$LCOV = x; then
+ AC_MSG_ERROR("lcov testing requested but lcov not found")
+ fi
+ if test x$GCOV = x; then
+ AC_MSG_ERROR("lcov testing requested but gcov not found")
+ fi
+ if test x$JAVA = x; then
+ AC_MSG_ERROR("lcov testing requested but java not found")
+ fi
+ if test x$GENHTML = x; then
+ AC_MSG_ERROR("lcov testing requested but genhtml not found")
+ fi
+ if test x$use_comparison_tool = x; then
+ AC_MSG_ERROR("lcov testing requested but comparison tool was not specified")
+ fi
+ LCOV="$LCOV --gcov-tool=$GCOV"
+ AX_CHECK_COMPILE_FLAG([--coverage],[CXXFLAGS="$CXXFLAGS --coverage"],
+ [AC_MSG_ERROR("lcov testing requested but --coverage flag does not work")])
+fi
+
+dnl Check for endianness
+AC_C_BIGENDIAN
+
+dnl Check for pthread compile/link requirements
+AX_PTHREAD
+
+# The following macro will add the necessary defines to bitcoin-config.h, but
+# they also need to be passed down to any subprojects. Pull the results out of
+# the cache and add them to CPPFLAGS.
+AC_SYS_LARGEFILE
+# detect POSIX or GNU variant of strerror_r
+AC_FUNC_STRERROR_R
+
+if test x$ac_cv_sys_file_offset_bits != x &&
+ test x$ac_cv_sys_file_offset_bits != xno &&
+ test x$ac_cv_sys_file_offset_bits != xunknown; then
+ CPPFLAGS="$CPPFLAGS -D_FILE_OFFSET_BITS=$ac_cv_sys_file_offset_bits"
+fi
+
+if test x$ac_cv_sys_large_files != x &&
+ test x$ac_cv_sys_large_files != xno &&
+ test x$ac_cv_sys_large_files != xunknown; then
+ CPPFLAGS="$CPPFLAGS -D_LARGE_FILES=$ac_cv_sys_large_files"
+fi
+
+AX_CHECK_LINK_FLAG([[-Wl,--large-address-aware]], [LDFLAGS="$LDFLAGS -Wl,--large-address-aware"])
+
+AX_GCC_FUNC_ATTRIBUTE([visibility])
+AX_GCC_FUNC_ATTRIBUTE([dllexport])
+AX_GCC_FUNC_ATTRIBUTE([dllimport])
+
+if test x$use_glibc_compat != xno; then
+
+ #__fdelt_chk's params and return type have changed from long unsigned int to long int.
+ # See which one is present here.
+ AC_MSG_CHECKING(__fdelt_chk type)
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#ifdef _FORTIFY_SOURCE
+ #undef _FORTIFY_SOURCE
+ #endif
+ #define _FORTIFY_SOURCE 2
+ #include <sys/select.h>
+ extern "C" long unsigned int __fdelt_warn(long unsigned int);]],[[]])],
+ [ fdelt_type="long unsigned int"],
+ [ fdelt_type="long int"])
+ AC_MSG_RESULT($fdelt_type)
+ AC_DEFINE_UNQUOTED(FDELT_TYPE, $fdelt_type,[parameter and return value type for __fdelt_chk])
+
+fi
+
+if test x$use_hardening != xno; then
+ AX_CHECK_COMPILE_FLAG([-Wstack-protector],[HARDENED_CXXFLAGS="$HARDENED_CXXFLAGS -Wstack-protector"])
+ AX_CHECK_COMPILE_FLAG([-fstack-protector-all],[HARDENED_CXXFLAGS="$HARDENED_CXXFLAGS -fstack-protector-all"])
+
+ AX_CHECK_PREPROC_FLAG([-D_FORTIFY_SOURCE=2],[
+ AX_CHECK_PREPROC_FLAG([-U_FORTIFY_SOURCE],[
+ HARDENED_CPPFLAGS="$HARDENED_CPPFLAGS -U_FORTIFY_SOURCE"
+ ])
+ HARDENED_CPPFLAGS="$HARDENED_CPPFLAGS -D_FORTIFY_SOURCE=2"
+ ])
+
+ AX_CHECK_LINK_FLAG([[-Wl,--dynamicbase]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,--dynamicbase"])
+ AX_CHECK_LINK_FLAG([[-Wl,--nxcompat]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,--nxcompat"])
+ AX_CHECK_LINK_FLAG([[-Wl,-z,relro]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,-z,relro"])
+ AX_CHECK_LINK_FLAG([[-Wl,-z,now]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,-z,now"])
+
+ if test x$TARGET_OS != xwindows; then
+ # All windows code is PIC, forcing it on just adds useless compile warnings
+ AX_CHECK_COMPILE_FLAG([-fPIE],[HARDENED_CXXFLAGS="$HARDENED_CXXFLAGS -fPIE"])
+ AX_CHECK_LINK_FLAG([[-pie]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -pie"])
+ fi
+
+ case $host in
+ *mingw*)
+ AC_CHECK_LIB([ssp], [main],, AC_MSG_ERROR(lib missing))
+ ;;
+ esac
+
+ CXXFLAGS="$CXXFLAGS $HARDENED_CXXFLAGS"
+ CPPFLAGS="$CPPFLAGS $HARDENED_CPPFLAGS"
+ LDFLAGS="$LDFLAGS $HARDENED_LDFLAGS"
+ OBJCXXFLAGS="$CXXFLAGS"
+fi
+
+dnl this flag screws up non-darwin gcc even when the check fails. special-case it.
+if test x$TARGET_OS = xdarwin; then
+ AX_CHECK_LINK_FLAG([[-Wl,-dead_strip]], [LDFLAGS="$LDFLAGS -Wl,-dead_strip"])
+fi
+
+AC_CHECK_HEADERS([endian.h sys/endian.h byteswap.h stdio.h stdlib.h unistd.h strings.h sys/types.h sys/stat.h sys/select.h sys/prctl.h])
+AC_SEARCH_LIBS([getaddrinfo_a], [anl], [AC_DEFINE(HAVE_GETADDRINFO_A, 1, [Define this symbol if you have getaddrinfo_a])])
+AC_SEARCH_LIBS([inet_pton], [nsl resolv], [AC_DEFINE(HAVE_INET_PTON, 1, [Define this symbol if you have inet_pton])])
+
+AC_CHECK_DECLS([strnlen])
+
+AC_CHECK_DECLS([le16toh, le32toh, le64toh, htole16, htole32, htole64, be16toh, be32toh, be64toh, htobe16, htobe32, htobe64],,,
+ [#if HAVE_ENDIAN_H
+ #include <endian.h>
+ #elif HAVE_SYS_ENDIAN_H
+ #include <sys/endian.h>
+ #endif])
+
+AC_CHECK_DECLS([bswap_16, bswap_32, bswap_64],,,
+ [#if HAVE_BYTESWAP_H
+ #include <byteswap.h>
+ #endif])
+
+dnl Check for MSG_NOSIGNAL
+AC_MSG_CHECKING(for MSG_NOSIGNAL)
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/socket.h>]],
+ [[ int f = MSG_NOSIGNAL; ]])],
+ [ AC_MSG_RESULT(yes); AC_DEFINE(HAVE_MSG_NOSIGNAL, 1,[Define this symbol if you have MSG_NOSIGNAL]) ],
+ [ AC_MSG_RESULT(no)]
+)
+
+AC_SEARCH_LIBS([clock_gettime],[rt])
+
+AC_MSG_CHECKING([for visibility attribute])
+AC_LINK_IFELSE([AC_LANG_SOURCE([
+ int foo_def( void ) __attribute__((visibility("default")));
+ int main(){}
+ ])],
+ [
+ AC_DEFINE(HAVE_VISIBILITY_ATTRIBUTE,1,[Define if the visibility attribute is supported.])
+ AC_MSG_RESULT(yes)
+ ],
+ [
+ AC_MSG_RESULT(no)
+ if test x$use_reduce_exports = xyes; then
+ AC_MSG_ERROR([Cannot find a working visibility attribute. Use --disable-reduce-exports.])
+ fi
+ ]
+)
+
+if test x$use_reduce_exports = xyes; then
+ AX_CHECK_COMPILE_FLAG([-fvisibility=hidden],[RE_CXXFLAGS="-fvisibility=hidden"],
+ [AC_MSG_ERROR([Cannot set default symbol visibility. Use --disable-reduce-exports.])])
+fi
+
+LEVELDB_CPPFLAGS=
+LIBLEVELDB=
+LIBMEMENV=
+AM_CONDITIONAL([EMBEDDED_LEVELDB],[true])
+AC_SUBST(LEVELDB_CPPFLAGS)
+AC_SUBST(LIBLEVELDB)
+AC_SUBST(LIBMEMENV)
+
+if test x$enable_wallet != xno; then
+ dnl Check for libdb_cxx only if wallet enabled
+ BITCOIN_FIND_BDB48
+fi
+
+dnl Check for libminiupnpc (optional)
+if test x$use_upnp != xno; then
+ AC_CHECK_HEADERS(
+ [miniupnpc/miniwget.h miniupnpc/miniupnpc.h miniupnpc/upnpcommands.h miniupnpc/upnperrors.h],
+ [AC_CHECK_LIB([miniupnpc], [main],[MINIUPNPC_LIBS=-lminiupnpc], [have_miniupnpc=no])],
+ [have_miniupnpc=no]
+ )
+fi
+
+BITCOIN_QT_INIT
+
+dnl sets $bitcoin_enable_qt, $bitcoin_enable_qt_test, $bitcoin_enable_qt_dbus
+BITCOIN_QT_CONFIGURE([$use_pkgconfig], [qt4])
+
+if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests = xnononono; then
+ use_boost=no
+else
+ use_boost=yes
+fi
+
+if test x$use_boost = xyes; then
+
+dnl Check for boost libs
+AX_BOOST_BASE
+AX_BOOST_SYSTEM
+AX_BOOST_FILESYSTEM
+AX_BOOST_PROGRAM_OPTIONS
+AX_BOOST_THREAD
+AX_BOOST_CHRONO
+
+
+if test x$use_reduce_exports = xyes; then
+ AC_MSG_CHECKING([for working boost reduced exports])
+ TEMP_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$BOOST_CPPFLAGS $CPPFLAGS"
+ AC_PREPROC_IFELSE([AC_LANG_PROGRAM([[
+ @%:@include <boost/version.hpp>
+ ]], [[
+ #if BOOST_VERSION >= 104900
+ // Everything is okay
+ #else
+ # error Boost version is too old
+ #endif
+ ]])],[
+ AC_MSG_RESULT(yes)
+ ],[
+ AC_MSG_ERROR([boost versions < 1.49 are known to be broken with reduced exports. Use --disable-reduce-exports.])
+ ])
+ CPPFLAGS="$TEMP_CPPFLAGS"
+fi
+fi
+
+if test x$use_reduce_exports = xyes; then
+ CXXFLAGS="$CXXFLAGS $RE_CXXFLAGS"
+ AX_CHECK_LINK_FLAG([[-Wl,--exclude-libs,ALL]], [RELDFLAGS="-Wl,--exclude-libs,ALL"])
+fi
+
+if test x$use_tests = xyes; then
+
+ if test x$HEXDUMP = x; then
+ AC_MSG_ERROR(hexdump is required for tests)
+ fi
+
+
+ if test x$use_boost = xyes; then
+
+ AX_BOOST_UNIT_TEST_FRAMEWORK
+
+ dnl Determine if -DBOOST_TEST_DYN_LINK is needed
+ AC_MSG_CHECKING([for dynamic linked boost test])
+ TEMP_LIBS="$LIBS"
+ LIBS="$LIBS $BOOST_LDFLAGS $BOOST_UNIT_TEST_FRAMEWORK_LIB"
+ TEMP_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
+ AC_LINK_IFELSE([AC_LANG_SOURCE([
+ #define BOOST_TEST_DYN_LINK
+ #define BOOST_TEST_MAIN
+ #include <boost/test/unit_test.hpp>
+
+ ])],
+ [AC_MSG_RESULT(yes)]
+ [TESTDEFS="$TESTDEFS -DBOOST_TEST_DYN_LINK"],
+ [AC_MSG_RESULT(no)])
+ LIBS="$TEMP_LIBS"
+ CPPFLAGS="$TEMP_CPPFLAGS"
+
+ fi
+fi
+
+if test x$use_boost = xyes; then
+
+BOOST_LIBS="$BOOST_LDFLAGS $BOOST_SYSTEM_LIB $BOOST_FILESYSTEM_LIB $BOOST_PROGRAM_OPTIONS_LIB $BOOST_THREAD_LIB $BOOST_CHRONO_LIB"
+
+dnl Boost >= 1.50 uses sleep_for rather than the now-deprecated sleep, however
+dnl it was broken from 1.50 to 1.52 when backed by nanosleep. Use sleep_for if
+dnl a working version is available, else fall back to sleep. sleep was removed
+dnl after 1.56.
+dnl If neither is available, abort.
+TEMP_LIBS="$LIBS"
+LIBS="$BOOST_LIBS $LIBS"
+TEMP_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
+AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+ #include <boost/thread/thread.hpp>
+ #include <boost/version.hpp>
+ ]],[[
+ #if BOOST_VERSION >= 105000 && (!defined(BOOST_HAS_NANOSLEEP) || BOOST_VERSION >= 105200)
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(0));
+ #else
+ choke me
+ #endif
+ ]])],
+ [boost_sleep=yes;
+ AC_DEFINE(HAVE_WORKING_BOOST_SLEEP_FOR, 1, [Define this symbol if boost sleep_for works])],
+ [boost_sleep=no])
+LIBS="$TEMP_LIBS"
+CPPFLAGS="$TEMP_CPPFLAGS"
+
+if test x$boost_sleep != xyes; then
+TEMP_LIBS="$LIBS"
+LIBS="$BOOST_LIBS $LIBS"
+TEMP_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
+AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+ #include <boost/version.hpp>
+ #include <boost/thread.hpp>
+ #include <boost/date_time/posix_time/posix_time_types.hpp>
+ ]],[[
+ #if BOOST_VERSION <= 105600
+ boost::this_thread::sleep(boost::posix_time::milliseconds(0));
+ #else
+ choke me
+ #endif
+ ]])],
+ [boost_sleep=yes; AC_DEFINE(HAVE_WORKING_BOOST_SLEEP, 1, [Define this symbol if boost sleep works])],
+ [boost_sleep=no])
+LIBS="$TEMP_LIBS"
+CPPFLAGS="$TEMP_CPPFLAGS"
+fi
+
+if test x$boost_sleep != xyes; then
+ AC_MSG_ERROR(No working boost sleep implementation found.)
+fi
+
+fi
+
+if test x$use_pkgconfig = xyes; then
+
+ if test x"$PKG_CONFIG" = "x"; then
+ AC_MSG_ERROR(pkg-config not found.)
+ fi
+
+ : #NOP
+ m4_ifdef(
+ [PKG_CHECK_MODULES],
+ [
+ PKG_CHECK_MODULES([SSL], [libssl],, [AC_MSG_ERROR(openssl not found.)])
+ PKG_CHECK_MODULES([CRYPTO], [libcrypto],,[AC_MSG_ERROR(libcrypto not found.)])
+ BITCOIN_QT_CHECK([PKG_CHECK_MODULES([PROTOBUF], [protobuf], [have_protobuf=yes], [BITCOIN_QT_FAIL(libprotobuf not found)])])
+ if test x$use_qr != xno; then
+ BITCOIN_QT_CHECK([PKG_CHECK_MODULES([QR], [libqrencode], [have_qrencode=yes], [have_qrencode=no])])
+ fi
+ ]
+ )
+else
+ AC_CHECK_HEADER([openssl/crypto.h],,AC_MSG_ERROR(libcrypto headers missing))
+ AC_CHECK_LIB([crypto], [main],CRYPTO_LIBS=-lcrypto, AC_MSG_ERROR(libcrypto missing))
+
+ AC_CHECK_HEADER([openssl/ssl.h],, AC_MSG_ERROR(libssl headers missing),)
+ AC_CHECK_LIB([ssl], [main],SSL_LIBS=-lssl, AC_MSG_ERROR(libssl missing))
+
+ BITCOIN_QT_CHECK(AC_CHECK_LIB([protobuf] ,[main],[PROTOBUF_LIBS=-lprotobuf], BITCOIN_QT_FAIL(libprotobuf not found)))
+ if test x$use_qr != xno; then
+ BITCOIN_QT_CHECK([AC_CHECK_LIB([qrencode], [main],[QR_LIBS=-lqrencode], [have_qrencode=no])])
+ BITCOIN_QT_CHECK([AC_CHECK_HEADER([qrencode.h],, have_qrencode=no)])
+ fi
+fi
+
+AC_CHECK_LIB([crypto],[RAND_egd],[],[
+ AC_ARG_WITH([libressl],
+ [AS_HELP_STRING([--with-libressl],[Build with system LibreSSL (default is no; DANGEROUS; NOT SUPPORTED)])],
+ [AC_MSG_WARN([Detected LibreSSL: This is NOT supported, and may break consensus compatibility!])],
+ [AC_MSG_ERROR([Detected LibreSSL: This is NOT supported, and may break consensus compatibility!])]
+ )
+])
+
+CFLAGS_TEMP="$CFLAGS"
+LIBS_TEMP="$LIBS"
+CFLAGS="$CFLAGS $SSL_CFLAGS $CRYPTO_CFLAGS"
+LIBS="$LIBS $SSL_LIBS $CRYPTO_LIBS"
+AC_CHECK_HEADER([openssl/ec.h],, AC_MSG_ERROR(OpenSSL ec header missing),)
+
+AC_MSG_CHECKING(for a supported OpenSSL version)
+AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+ #include <openssl/rand.h>
+ ]],
+ [[RAND_egd(NULL);]])],
+ [AC_MSG_RESULT(yes)],
+ [
+ AC_ARG_WITH([libressl],
+ [AS_HELP_STRING([--with-libressl],[Build with system LibreSSL (default is no; DANGEROUS; NOT SUPPORTED)])],
+ [AC_MSG_WARN([Detected LibreSSL: This is NOT supported, and may break consensus compatibility!])],
+ [AC_MSG_ERROR([Detected LibreSSL: This is NOT supported, and may break consensus compatibility!])]
+ )]
+)
+
+CFLAGS="$CFLAGS_TEMP"
+LIBS="$LIBS_TEMP"
+
+BITCOIN_QT_PATH_PROGS([PROTOC], [protoc],$protoc_bin_path)
+
+AC_MSG_CHECKING([whether to build bitcoind])
+AM_CONDITIONAL([BUILD_BITCOIND], [test x$build_bitcoind = xyes])
+AC_MSG_RESULT($build_bitcoind)
+
+AC_MSG_CHECKING([whether to build utils (bitcoin-cli bitcoin-tx)])
+AM_CONDITIONAL([BUILD_BITCOIN_UTILS], [test x$build_bitcoin_utils = xyes])
+AC_MSG_RESULT($build_bitcoin_utils)
+
+AC_MSG_CHECKING([whether to build libraries])
+AM_CONDITIONAL([BUILD_BITCOIN_LIBS], [test x$build_bitcoin_libs = xyes])
+if test x$build_bitcoin_libs = xyes; then
+ AC_DEFINE(HAVE_CONSENSUS_LIB, 1, [Define this symbol if the consensus lib has been built])
+ AC_CONFIG_FILES([libbitcoinconsensus.pc:libbitcoinconsensus.pc.in])
+fi
+AC_MSG_RESULT($build_bitcoin_libs)
+
+AC_LANG_POP
+
+if test "x$use_ccache" != "xno"; then
+ AC_MSG_CHECKING(if ccache should be used)
+ if test x$CCACHE = x; then
+ if test "x$use_ccache" = "xyes"; then
+ AC_MSG_ERROR([ccache not found.]);
+ else
+ use_ccache=no
+ fi
+ else
+ use_ccache=yes
+ CC="$ac_cv_path_CCACHE $CC"
+ CXX="$ac_cv_path_CCACHE $CXX"
+ fi
+ AC_MSG_RESULT($use_ccache)
+fi
+if test "x$use_ccache" = "xyes"; then
+ AX_CHECK_PREPROC_FLAG([-Qunused-arguments],[CPPFLAGS="-Qunused-arguments $CPPFLAGS"])
+fi
+
+dnl enable wallet
+AC_MSG_CHECKING([if wallet should be enabled])
+if test x$enable_wallet != xno; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE_UNQUOTED([ENABLE_WALLET],[1],[Define to 1 to enable wallet functions])
+
+else
+ AC_MSG_RESULT(no)
+fi
+
+dnl enable upnp support
+AC_MSG_CHECKING([whether to build with support for UPnP])
+if test x$have_miniupnpc = xno; then
+ if test x$use_upnp = xyes; then
+ AC_MSG_ERROR("UPnP requested but cannot be built. use --without-miniupnpc")
+ fi
+ AC_MSG_RESULT(no)
+else
+ if test x$use_upnp != xno; then
+ AC_MSG_RESULT(yes)
+ AC_MSG_CHECKING([whether to build with UPnP enabled by default])
+ use_upnp=yes
+ upnp_setting=0
+ if test x$use_upnp_default != xno; then
+ use_upnp_default=yes
+ upnp_setting=1
+ fi
+ AC_MSG_RESULT($use_upnp_default)
+ AC_DEFINE_UNQUOTED([USE_UPNP],[$upnp_setting],[UPnP support not compiled if undefined, otherwise value (0 or 1) determines default state])
+ if test x$TARGET_OS = xwindows; then
+ MINIUPNPC_CPPFLAGS="-DSTATICLIB -DMINIUPNP_STATICLIB"
+ fi
+ else
+ AC_MSG_RESULT(no)
+ fi
+fi
+
+dnl these are only used when qt is enabled
+if test x$bitcoin_enable_qt != xno; then
+ BUILD_QT=qt
+ dnl enable dbus support
+ AC_MSG_CHECKING([whether to build GUI with support for D-Bus])
+ if test x$bitcoin_enable_qt_dbus != xno; then
+ AC_DEFINE([USE_DBUS],[1],[Define if dbus support should be compiled in])
+ fi
+ AC_MSG_RESULT($bitcoin_enable_qt_dbus)
+
+ dnl enable qr support
+ AC_MSG_CHECKING([whether to build GUI with support for QR codes])
+ if test x$have_qrencode = xno; then
+ if test x$use_qr = xyes; then
+ AC_MSG_ERROR("QR support requested but cannot be built. use --without-qrencode")
+ fi
+ AC_MSG_RESULT(no)
+ else
+ if test x$use_qr != xno; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE([USE_QRCODE],[1],[Define if QR support should be compiled in])
+ use_qr=yes
+ else
+ AC_MSG_RESULT(no)
+ fi
+ fi
+
+ if test x$XGETTEXT = x; then
+ AC_MSG_WARN("xgettext is required to update qt translations")
+ fi
+
+ AC_MSG_CHECKING([whether to build test_bitcoin-qt])
+ if test x$use_tests$bitcoin_enable_qt_test = xyesyes; then
+ AC_MSG_RESULT([yes])
+ BUILD_TEST_QT="test"
+ else
+ AC_MSG_RESULT([no])
+ fi
+fi
+
+AC_MSG_CHECKING([whether to build test_bitcoin])
+if test x$use_tests = xyes; then
+ AC_MSG_RESULT([yes])
+ BUILD_TEST="test"
+else
+ AC_MSG_RESULT([no])
+fi
+
+AC_MSG_CHECKING([whether to reduce exports])
+if test x$use_reduce_exports = xyes; then
+ AC_MSG_RESULT([yes])
+else
+ AC_MSG_RESULT([no])
+fi
+
+if test x$build_bitcoin_utils$build_bitcoin_libs$build_bitcoind$bitcoin_enable_qt$use_tests = xnonononono; then
+ AC_MSG_ERROR([No targets! Please specify at least one of: --with-utils --with-libs --with-daemon --with-gui or --enable-tests])
+fi
+
+AM_CONDITIONAL([TARGET_DARWIN], [test x$TARGET_OS = xdarwin])
+AM_CONDITIONAL([BUILD_DARWIN], [test x$BUILD_OS = xdarwin])
+AM_CONDITIONAL([TARGET_WINDOWS], [test x$TARGET_OS = xwindows])
+AM_CONDITIONAL([ENABLE_WALLET],[test x$enable_wallet = xyes])
+AM_CONDITIONAL([ENABLE_TESTS],[test x$use_tests = xyes])
+AM_CONDITIONAL([ENABLE_QT],[test x$bitcoin_enable_qt = xyes])
+AM_CONDITIONAL([ENABLE_QT_TESTS],[test x$use_tests$bitcoin_enable_qt_test = xyesyes])
+AM_CONDITIONAL([USE_QRCODE], [test x$use_qr = xyes])
+AM_CONDITIONAL([USE_LCOV],[test x$use_lcov = xyes])
+AM_CONDITIONAL([USE_COMPARISON_TOOL],[test x$use_comparison_tool != xno])
+AM_CONDITIONAL([USE_COMPARISON_TOOL_REORG_TESTS],[test x$use_comparison_tool_reorg_test != xno])
+AM_CONDITIONAL([GLIBC_BACK_COMPAT],[test x$use_glibc_compat = xyes])
+
+AC_DEFINE(CLIENT_VERSION_MAJOR, _CLIENT_VERSION_MAJOR, [Major version])
+AC_DEFINE(CLIENT_VERSION_MINOR, _CLIENT_VERSION_MINOR, [Minor version])
+AC_DEFINE(CLIENT_VERSION_REVISION, _CLIENT_VERSION_REVISION, [Build revision])
+AC_DEFINE(CLIENT_VERSION_BUILD, _CLIENT_VERSION_BUILD, [Version Build])
+AC_DEFINE(CLIENT_VERSION_IS_RELEASE, _CLIENT_VERSION_IS_RELEASE, [Version is release])
+AC_DEFINE(COPYRIGHT_YEAR, _COPYRIGHT_YEAR, [Version is release])
+AC_SUBST(CLIENT_VERSION_MAJOR, _CLIENT_VERSION_MAJOR)
+AC_SUBST(CLIENT_VERSION_MINOR, _CLIENT_VERSION_MINOR)
+AC_SUBST(CLIENT_VERSION_REVISION, _CLIENT_VERSION_REVISION)
+AC_SUBST(CLIENT_VERSION_BUILD, _CLIENT_VERSION_BUILD)
+AC_SUBST(CLIENT_VERSION_IS_RELEASE, _CLIENT_VERSION_IS_RELEASE)
+AC_SUBST(COPYRIGHT_YEAR, _COPYRIGHT_YEAR)
+
+AC_SUBST(RELDFLAGS)
+AC_SUBST(LIBTOOL_APP_LDFLAGS)
+AC_SUBST(USE_UPNP)
+AC_SUBST(USE_QRCODE)
+AC_SUBST(BOOST_LIBS)
+AC_SUBST(TESTDEFS)
+AC_SUBST(LEVELDB_TARGET_FLAGS)
+AC_SUBST(BUILD_TEST)
+AC_SUBST(BUILD_QT)
+AC_SUBST(BUILD_TEST_QT)
+AC_SUBST(MINIUPNPC_CPPFLAGS)
+AC_SUBST(MINIUPNPC_LIBS)
+AC_CONFIG_FILES([Makefile src/Makefile share/setup.nsi share/qt/Info.plist src/test/buildenv.py])
+AC_CONFIG_FILES([qa/pull-tester/run-bitcoind-for-test.sh],[chmod +x qa/pull-tester/run-bitcoind-for-test.sh])
+AC_CONFIG_FILES([qa/pull-tester/tests-config.sh],[chmod +x qa/pull-tester/tests-config.sh])
+
+dnl boost's m4 checks do something really nasty: they export these vars. As a
+dnl result, they leak into secp256k1's configure and crazy things happen.
+dnl Until this is fixed upstream and we've synced, we'll just un-export them.
+CPPFLAGS_TEMP="$CPPFLAGS"
+unset CPPFLAGS
+CPPFLAGS="$CPPFLAGS_TEMP"
+
+LDFLAGS_TEMP="$LDFLAGS"
+unset LDFLAGS
+LDFLAGS="$LDFLAGS_TEMP"
+
+LIBS_TEMP="$LIBS"
+unset LIBS
+LIBS="$LIBS_TEMP"
+
+PKGCONFIG_PATH_TEMP="$PKG_CONFIG_PATH"
+unset PKG_CONFIG_PATH
+PKG_CONFIG_PATH="$PKGCONFIG_PATH_TEMP"
+
+PKGCONFIG_LIBDIR_TEMP="$PKG_CONFIG_LIBDIR"
+unset PKG_CONFIG_LIBDIR
+PKG_CONFIG_LIBDIR="$PKGCONFIG_LIBDIR_TEMP"
+
+ac_configure_args="${ac_configure_args} --disable-shared --with-pic --with-bignum=no"
+AC_CONFIG_SUBDIRS([src/secp256k1])
+
+AC_OUTPUT
+
+dnl Taken from https://wiki.debian.org/RpathIssue
+case $host in
+ *-*-linux-gnu)
+ AC_MSG_RESULT([Fixing libtool for -rpath problems.])
+ sed < libtool > libtool-2 \
+ 's/^hardcode_libdir_flag_spec.*$'/'hardcode_libdir_flag_spec=" -D__LIBTOOL_IS_A_FOOL__ "/'
+ mv libtool-2 libtool
+ chmod 755 libtool
+ ;;
+esac
diff --git a/contrib/README.md b/contrib/README.md
new file mode 100644
index 0000000000..7d4b91e887
--- /dev/null
+++ b/contrib/README.md
@@ -0,0 +1,59 @@
+Wallet Tools
+---------------------
+
+### [BitRPC](/contrib/bitrpc) ###
+Allows for sending of all standard Bitcoin commands via RPC rather than as command line args.
+
+### [SpendFrom](/contrib/spendfrom) ###
+
+Use the raw transactions API to send coins received on a particular
+address (or addresses).
+
+Repository Tools
+---------------------
+
+### [Developer tools](/contrib/devtools) ###
+Specific tools for developers working on this repository.
+Contains the script `github-merge.sh` for merging github pull requests securely and signing them using GPG.
+
+### [Verify-Commits](/contrib/verify-commits) ###
+Tool to verify that every merge commit was signed by a developer using the above `github-merge.sh` script.
+
+### [Linearize](/contrib/linearize) ###
+Construct a linear, no-fork, best version of the blockchain.
+
+### [Qos](/contrib/qos) ###
+
+A Linux bash script that will set up traffic control (tc) to limit the outgoing bandwidth for connections to the Bitcoin network. This means one can have an always-on bitcoind instance running, and another local bitcoind/bitcoin-qt instance which connects to this node and receives blocks from it.
+
+### [Seeds](/contrib/seeds) ###
+Utility to generate the pnSeed[] array that is compiled into the client.
+
+Build Tools and Keys
+---------------------
+
+### [Debian](/contrib/debian) ###
+Contains files used to package bitcoind/bitcoin-qt
+for Debian-based Linux systems. If you compile bitcoind/bitcoin-qt yourself, there are some useful files here.
+
+### [Gitian-descriptors](/contrib/gitian-descriptors) ###
+Gavin's notes on getting gitian builds up and running using KVM.
+
+### [Gitian-downloader](/contrib/gitian-downloader)
+Various PGP files of core developers.
+
+### [MacDeploy](/contrib/macdeploy) ###
+Scripts and notes for Mac builds.
+
+Test and Verify Tools
+---------------------
+
+### [TestGen](/contrib/testgen) ###
+Utilities to generate test vectors for the data-driven Bitcoin tests.
+
+### [Test Patches](/contrib/test-patches) ###
+These patches are applied when the automated pull-tester
+tests each pull and when master is tested using jenkins.
+
+### [Verify SF Binaries](/contrib/verifysfbinaries) ###
+This script attempts to download and verify the signature file SHA256SUMS.asc from SourceForge.
diff --git a/contrib/bitcoin-qt.pro b/contrib/bitcoin-qt.pro
new file mode 100644
index 0000000000..3a72d10f47
--- /dev/null
+++ b/contrib/bitcoin-qt.pro
@@ -0,0 +1,21 @@
+FORMS += \
+ ../src/qt/forms/aboutdialog.ui \
+ ../src/qt/forms/addressbookpage.ui \
+ ../src/qt/forms/askpassphrasedialog.ui \
+ ../src/qt/forms/coincontroldialog.ui \
+ ../src/qt/forms/editaddressdialog.ui \
+ ../src/qt/forms/helpmessagedialog.ui \
+ ../src/qt/forms/intro.ui \
+ ../src/qt/forms/openuridialog.ui \
+ ../src/qt/forms/optionsdialog.ui \
+ ../src/qt/forms/overviewpage.ui \
+ ../src/qt/forms/receivecoinsdialog.ui \
+ ../src/qt/forms/receiverequestdialog.ui \
+ ../src/qt/forms/rpcconsole.ui \
+ ../src/qt/forms/sendcoinsdialog.ui \
+ ../src/qt/forms/sendcoinsentry.ui \
+ ../src/qt/forms/signverifymessagedialog.ui \
+ ../src/qt/forms/transactiondescdialog.ui \
+
+RESOURCES += \
+ ../src/qt/bitcoin.qrc
diff --git a/contrib/bitcoind.bash-completion b/contrib/bitcoind.bash-completion
new file mode 100644
index 0000000000..3cc959c0a6
--- /dev/null
+++ b/contrib/bitcoind.bash-completion
@@ -0,0 +1,145 @@
+# bash programmable completion for bitcoind(1) and bitcoin-cli(1)
+# Copyright (c) 2012,2014 Christian von Roques <roques@mti.ag>
+# Distributed under the MIT 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 > 4)); then
+ case ${words[cword-4]} in
+ listtransactions)
+ COMPREPLY=( $( compgen -W "true false" -- "$cur" ) )
+ return 0
+ ;;
+ signrawtransaction)
+ COMPREPLY=( $( compgen -W "ALL NONE SINGLE ALL|ANYONECANPAY NONE|ANYONECANPAY SINGLE|ANYONECANPAY" -- "$cur" ) )
+ return 0
+ ;;
+ esac
+ fi
+
+ if ((cword > 3)); then
+ case ${words[cword-3]} in
+ addmultisigaddress)
+ _bitcoin_accounts
+ return 0
+ ;;
+ getbalance|gettxout|importaddress|importprivkey|listreceivedbyaccount|listreceivedbyaddress|listsinceblock)
+ COMPREPLY=( $( compgen -W "true false" -- "$cur" ) )
+ return 0
+ ;;
+ esac
+ fi
+
+ if ((cword > 2)); then
+ case ${words[cword-2]} in
+ addnode)
+ COMPREPLY=( $( compgen -W "add remove onetry" -- "$cur" ) )
+ return 0
+ ;;
+ getblock|getrawtransaction|gettransaction|listaccounts|listreceivedbyaccount|listreceivedbyaddress|sendrawtransaction)
+ COMPREPLY=( $( compgen -W "true false" -- "$cur" ) )
+ return 0
+ ;;
+ move|setaccount)
+ _bitcoin_accounts
+ return 0
+ ;;
+ esac
+ fi
+
+ case "$prev" in
+ backupwallet|dumpwallet|importwallet)
+ _filedir
+ return 0
+ ;;
+ getmempool|lockunspent|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=*|-loadblock=*|-wallet=*|-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 '$1 ~ /^[a-z]/ { 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 bitcoin-cli
+}
+
+# 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/README.md b/contrib/bitrpc/README.md
new file mode 100644
index 0000000000..f5ef2f0405
--- /dev/null
+++ b/contrib/bitrpc/README.md
@@ -0,0 +1,8 @@
+### BitRPC
+Allows for sending of all standard Bitcoin commands via RPC rather than as command line args.
+
+### Looking for Wallet Tools?
+BitRPC.py is able to do the exact same thing as `walletchangepass.py` and `walletunlock.py`. Their respective commands in BitRPC.py are:
+
+ bitrpc.py walletpassphrasechange
+ bitrpc.py walletpassphrase \ No newline at end of file
diff --git a/contrib/bitrpc/bitrpc.py b/contrib/bitrpc/bitrpc.py
new file mode 100644
index 0000000000..c3ce9d7936
--- /dev/null
+++ b/contrib/bitrpc/bitrpc.py
@@ -0,0 +1,335 @@
+from jsonrpc import ServiceProxy
+import sys
+import string
+import getpass
+
+# ===== 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 Exception as inst:
+ print inst
+
+elif cmd == "encryptwallet":
+ try:
+ pwd = getpass.getpass(prompt="Enter passphrase: ")
+ pwd2 = getpass.getpass(prompt="Repeat passphrase: ")
+ if pwd == pwd2:
+ access.encryptwallet(pwd)
+ print "\n---Wallet encrypted. Server stopping, restart to run with encrypted wallet---\n"
+ else:
+ print "\n---Passphrases do not match---\n"
+ except Exception as inst:
+ print inst
+
+elif cmd == "getaccount":
+ try:
+ addr = raw_input("Enter a Bitcoin address: ")
+ print access.getaccount(addr)
+ except Exception as inst:
+ print inst
+
+elif cmd == "getaccountaddress":
+ try:
+ acct = raw_input("Enter an account name: ")
+ print access.getaccountaddress(acct)
+ except Exception as inst:
+ print inst
+
+elif cmd == "getaddressesbyaccount":
+ try:
+ acct = raw_input("Enter an account name: ")
+ print access.getaddressesbyaccount(acct)
+ except Exception as inst:
+ print inst
+
+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 Exception as inst:
+ print inst
+
+elif cmd == "getblockbycount":
+ try:
+ height = raw_input("Height: ")
+ print access.getblockbycount(height)
+ except Exception as inst:
+ print inst
+
+elif cmd == "getblockcount":
+ try:
+ print access.getblockcount()
+ except Exception as inst:
+ print inst
+
+elif cmd == "getblocknumber":
+ try:
+ print access.getblocknumber()
+ except Exception as inst:
+ print inst
+
+elif cmd == "getconnectioncount":
+ try:
+ print access.getconnectioncount()
+ except Exception as inst:
+ print inst
+
+elif cmd == "getdifficulty":
+ try:
+ print access.getdifficulty()
+ except Exception as inst:
+ print inst
+
+elif cmd == "getgenerate":
+ try:
+ print access.getgenerate()
+ except Exception as inst:
+ print inst
+
+elif cmd == "gethashespersec":
+ try:
+ print access.gethashespersec()
+ except Exception as inst:
+ print inst
+
+elif cmd == "getinfo":
+ try:
+ print access.getinfo()
+ except Exception as inst:
+ print inst
+
+elif cmd == "getnewaddress":
+ try:
+ acct = raw_input("Enter an account name: ")
+ try:
+ print access.getnewaddress(acct)
+ except:
+ print access.getnewaddress()
+ except Exception as inst:
+ print inst
+
+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 Exception as inst:
+ print inst
+
+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 Exception as inst:
+ print inst
+
+elif cmd == "gettransaction":
+ try:
+ txid = raw_input("Enter a transaction ID: ")
+ print access.gettransaction(txid)
+ except Exception as inst:
+ print inst
+
+elif cmd == "getwork":
+ try:
+ data = raw_input("Data (optional): ")
+ try:
+ print access.gettransaction(data)
+ except:
+ print access.gettransaction()
+ except Exception as inst:
+ print inst
+
+elif cmd == "help":
+ try:
+ cmd = raw_input("Command (optional): ")
+ try:
+ print access.help(cmd)
+ except:
+ print access.help()
+ except Exception as inst:
+ print inst
+
+elif cmd == "listaccounts":
+ try:
+ mc = raw_input("Minimum confirmations (optional): ")
+ try:
+ print access.listaccounts(mc)
+ except:
+ print access.listaccounts()
+ except Exception as inst:
+ print inst
+
+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 Exception as inst:
+ print inst
+
+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 Exception as inst:
+ print inst
+
+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 Exception as inst:
+ print inst
+
+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 Exception as inst:
+ print inst
+
+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 Exception as inst:
+ print inst
+
+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 Exception as inst:
+ print inst
+
+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 Exception as inst:
+ print inst
+
+elif cmd == "setaccount":
+ try:
+ addr = raw_input("Address: ")
+ acct = raw_input("Account:")
+ print access.setaccount(addr,acct)
+ except Exception as inst:
+ print inst
+
+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 Exception as inst:
+ print inst
+
+elif cmd == "settxfee":
+ try:
+ amt = raw_input("Amount:")
+ print access.settxfee(amt)
+ except Exception as inst:
+ print inst
+
+elif cmd == "stop":
+ try:
+ print access.stop()
+ except Exception as inst:
+ print inst
+
+elif cmd == "validateaddress":
+ try:
+ addr = raw_input("Address: ")
+ print access.validateaddress(addr)
+ except Exception as inst:
+ print inst
+
+elif cmd == "walletpassphrase":
+ try:
+ pwd = getpass.getpass(prompt="Enter wallet passphrase: ")
+ access.walletpassphrase(pwd, 60)
+ print "\n---Wallet unlocked---\n"
+ except Exception as inst:
+ print inst
+
+elif cmd == "walletpassphrasechange":
+ try:
+ pwd = getpass.getpass(prompt="Enter old wallet passphrase: ")
+ pwd2 = getpass.getpass(prompt="Enter new wallet passphrase: ")
+ access.walletpassphrasechange(pwd, pwd2)
+ print
+ print "\n---Passphrase changed---\n"
+ except Exception as inst:
+ print inst
+
+else:
+ print "Command not found or not supported"
diff --git a/contrib/debian/README.md b/contrib/debian/README.md
new file mode 100644
index 0000000000..fab9cc2381
--- /dev/null
+++ b/contrib/debian/README.md
@@ -0,0 +1,21 @@
+
+Debian
+====================
+This directory contains files used to package bitcoind/bitcoin-qt
+for Debian-based Linux systems. If you compile bitcoind/bitcoin-qt yourself, there are some useful files here.
+
+## bitcoin: URI support ##
+
+
+bitcoin-qt.desktop (Gnome / Open Desktop)
+To install:
+
+ sudo desktop-file-install bitcoin-qt.desktop
+ sudo update-desktop-database
+
+If you build yourself, you will either need to modify the paths in
+the .desktop file or copy or symlink your bitcoin-qt binary to `/usr/bin`
+and the `../../share/pixmaps/bitcoin128.png` to `/usr/share/pixmaps`
+
+bitcoin-qt.protocol (KDE)
+
diff --git a/contrib/debian/bitcoin-qt.desktop b/contrib/debian/bitcoin-qt.desktop
new file mode 100644
index 0000000000..61e1aca6ad
--- /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=bitcoin-qt %u
+Terminal=false
+Type=Application
+Icon=bitcoin128
+MimeType=x-scheme-handler/bitcoin;
+Categories=Office;Finance;
diff --git a/contrib/debian/bitcoin-qt.install b/contrib/debian/bitcoin-qt.install
new file mode 100644
index 0000000000..e0b32373be
--- /dev/null
+++ b/contrib/debian/bitcoin-qt.install
@@ -0,0 +1,6 @@
+usr/local/bin/bitcoin-qt usr/bin
+share/pixmaps/bitcoin32.xpm usr/share/pixmaps
+share/pixmaps/bitcoin16.xpm usr/share/pixmaps
+share/pixmaps/bitcoin128.png 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 0000000000..7fb230eca8
--- /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 0000000000..014588d536
--- /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 0000000000..0f84707b66
--- /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 0000000000..4ded67d98e
--- /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 0000000000..798ea851f6
--- /dev/null
+++ b/contrib/debian/bitcoind.install
@@ -0,0 +1,2 @@
+usr/local/bin/bitcoind usr/bin
+usr/local/bin/bitcoin-cli usr/bin
diff --git a/contrib/debian/bitcoind.lintian-overrides b/contrib/debian/bitcoind.lintian-overrides
new file mode 100644
index 0000000000..3f9f140bd8
--- /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 0000000000..6d3e683855
--- /dev/null
+++ b/contrib/debian/bitcoind.manpages
@@ -0,0 +1,3 @@
+debian/manpages/bitcoind.1
+debian/manpages/bitcoin.conf.5
+debian/manpages/bitcoin-cli.1
diff --git a/contrib/debian/changelog b/contrib/debian/changelog
new file mode 100644
index 0000000000..bd7ab3524c
--- /dev/null
+++ b/contrib/debian/changelog
@@ -0,0 +1,429 @@
+bitcoin (0.10.0-precise1) precise; urgency=medium
+
+ * New upstream releases.
+
+ -- Matt Corallo (BlueMatt) <matt@mattcorallo.com> Wed, 18 Feb 2015 13:22:00 -1000
+
+bitcoin (0.9.4-precise1) precise; urgency=high
+
+ * New upstream releases.
+
+ -- Matt Corallo (laptop - only while traveling) <matt@mattcorallo.com> Mon, 12 Jan 2015 23:30:00 -1000
+
+bitcoin (0.9.3-precise1) precise; urgency=medium
+
+ * New upstream releases.
+
+ -- Matt Corallo (BlueMatt) <matt@mattcorallo.com> Fri, 26 Sep 2014 12:01:00 -0700
+
+bitcoin (0.9.1-precise1) precise; urgency=medium
+
+ * New upstream release.
+ * Backport pull #4019
+
+ -- Matt Corallo <matt@bluematt.me> Sat, 19 Apr 2014 17:29:00 -0400
+
+bitcoin (0.9.0-precise1) precise; urgency=medium
+
+ * New upstream release.
+
+ -- Matt Corallo <matt@bluematt.me> Thu, 20 Mar 2014 13:10:00 -0400
+
+bitcoin (0.8.6-precise1) precise; urgency=medium
+
+ * New upstream release.
+ * Make .desktop paths non-fixed (suggested by prusnak@github)
+
+ -- Matt Corallo <matt@bluematt.me> Fri, 13 Dec 2013 13:31:00 -0400
+
+bitcoin (0.8.5-precise1) precise; urgency=medium
+
+ * New upstream release.
+
+ -- Matt Corallo <matt@bluematt.me> Sun, 15 Sep 2013 14:02:00 -0400
+
+bitcoin (0.8.4-precise1) precise; urgency=medium
+
+ * New upstream release.
+
+ -- Matt Corallo <matt@bluematt.me> Wed, 4 Sep 2013 10:25:00 -0400
+
+bitcoin (0.8.3-natty1) natty; urgency=low
+
+ * New upstream release.
+
+ -- Matt Corallo <matt@bluematt.me> Wed, 26 Jun 2013 00:18:00 +0100
+
+bitcoin (0.8.2-natty1) natty; urgency=low
+
+ * New upstream release.
+
+ -- Matt Corallo <matt@bluematt.me> Wed, 29 Mar 2013 23:23:00 +0100
+
+bitcoin (0.8.1-natty3) natty; urgency=low
+
+ * New pixmaps
+
+ -- Jonas Schnelli <jonas.schnelli@include7.ch> Mon, 13 May 2013 16:14:00 +0100
+
+bitcoin (0.8.1-natty2) natty; urgency=low
+
+ * Remove dumb broken launcher script
+
+ -- Matt Corallo <matt@bluematt.me> Sun, 24 Mar 2013 20:01:00 -0400
+
+bitcoin (0.8.1-natty1) natty; urgency=low
+
+ * New upstream release.
+
+ -- Matt Corallo <matt@bluematt.me> Tue, 19 Mar 2013 13:03:00 -0400
+
+bitcoin (0.8.0-natty1) natty; urgency=low
+
+ * New upstream release.
+
+ -- Matt Corallo <matt@bluematt.me> Sat, 23 Feb 2013 16:01:00 -0500
+
+bitcoin (0.7.2-natty1) natty; urgency=low
+
+ * New upstream release.
+
+ -- Matt Corallo <matt@bluematt.me> Sat, 15 Dec 2012 10:59:00 -0400
+
+bitcoin (0.7.1-natty1) natty; urgency=low
+
+ * New upstream release.
+
+ -- Matt Corallo <matt@bluematt.me> Wed, 24 Oct 2012 15:06:00 -0400
+
+bitcoin (0.7.0-natty1) natty; urgency=low
+
+ * New upstream release.
+
+ -- Matt Corallo <matt@bluematt.me> Mon, 17 Sep 2012 13:45:00 +0200
+
+bitcoin (0.6.3-natty1) natty; urgency=low
+
+ * New upstream release.
+
+ -- Matt Corallo <matt@bluematt.me> Mon, 25 Jun 2012 23:47:00 +0200
+
+bitcoin (0.6.2-natty1) natty; urgency=low
+
+ * Update package description and launch scripts.
+
+ -- Matt Corallo <matt@bluematt.me> Sat, 2 Jun 2012 16:41:00 +0200
+
+bitcoin (0.6.2-natty0) natty; urgency=low
+
+ * New upstream release.
+
+ -- Matt Corallo <matt@bluematt.me> Tue, 8 May 2012 16:27:00 -0500
+
+bitcoin (0.6.1-natty0) natty; urgency=low
+
+ * New upstream release.
+
+ -- Matt Corallo <matt@bluematt.me> 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 <matt@bluematt.me> Sat, 31 Mar 2012 15:35:00 -0500
+
+bitcoin (0.5.3-natty1) natty; urgency=low
+
+ * Mark for upload to PPA.
+
+ -- Matt Corallo <matt@bluematt.me> Wed, 14 Mar 2012 23:06:00 -0400
+
+bitcoin (0.5.3-natty0) natty; urgency=low
+
+ * New upstream release.
+
+ -- Luke Dashjr <luke+bitcoin+deb@dashjr.org> 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 isn't anonymous without
+ a ton of work that virtually no users will ever be willing and
+ capable of doing
+
+ -- Matt Corallo <matt@bluematt.me> Sat, 7 Jan 2012 13:37:00 -0500
+
+bitcoin (0.5.2-natty0) natty; urgency=low
+
+ * New upstream release.
+
+ -- Luke Dashjr <luke+bitcoin+deb@dashjr.org> Fri, 16 Dec 2011 17:57:00 -0500
+
+bitcoin (0.5.1-natty0) natty; urgency=low
+
+ * New upstream release.
+
+ -- Matt Corallo <matt@bluematt.me> Fri, 16 Dec 2011 13:27:00 -0500
+
+bitcoin (0.5.0-natty0) natty; urgency=low
+
+ * New upstream release.
+
+ -- Matt Corallo <matt@bluematt.me> Mon, 21 Nov 2011 11:32:00 -0500
+
+bitcoin (0.5.0~rc7-natty0) natty; urgency=low
+
+ * New upstream release candidate.
+
+ -- Matt Corallo <matt@bluematt.me> 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 <matt@bluematt.me> 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 unnecessary build-dependancies
+
+ -- Matt Corallo <matt@bluematt.me> 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 <matt@bluematt.me> Wed, 26 Oct 2011 14:37:18 -0400
+
+bitcoin (0.5.0~rc1-2) experimental; urgency=low
+
+ * Add bitcoin-qt
+
+ -- Matt Corallo <matt@bluematt.me> 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 <dr@jones.dk> 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 <dr@jones.dk> 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 <dr@jones.dk> 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 <dr@jones.dk> 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 <dr@jones.dk> 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 <dr@jones.dk> 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 <dr@jones.dk> 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 <dr@jones.dk> Tue, 01 Mar 2011 15:55:04 +0100
+
+bitcoin (0.3.19~dfsg-6) unstable; urgency=low
+
+ * Fix override aggressive 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 <dr@jones.dk> 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 <dr@jones.dk> 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 <dr@jones.dk> 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 <dr@jones.dk> 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 <dr@jones.dk> 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 <dr@jones.dk> Tue, 28 Dec 2010 15:49:22 +0100
diff --git a/contrib/debian/compat b/contrib/debian/compat
new file mode 100644
index 0000000000..7f8f011eb7
--- /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 0000000000..4392bb3385
--- /dev/null
+++ b/contrib/debian/control
@@ -0,0 +1,58 @@
+Source: bitcoin
+Section: utils
+Priority: optional
+Maintainer: Jonas Smedegaard <dr@jones.dk>
+Uploaders: Micah Anderson <micah@debian.org>
+Build-Depends: debhelper,
+ devscripts,
+ automake,
+ libtool,
+ bash-completion,
+ libboost-system-dev (>> 1.35) | libboost-system1.35-dev,
+ libdb4.8++-dev,
+ libssl-dev,
+ pkg-config,
+ libminiupnpc8-dev | libminiupnpc-dev (>> 1.6),
+ 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,
+ libprotobuf-dev, protobuf-compiler
+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.
+ .
+ Full transaction history is stored locally at each client. This
+ requires 20+ GB of space, slowly growing.
+ .
+ This package provides the daemon, bitcoind, and the CLI tool
+ bitcoin-cli 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.
+ .
+ Full transaction history is stored locally at each client. This
+ requires 20+ 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 0000000000..55ebcaab42
--- /dev/null
+++ b/contrib/debian/copyright
@@ -0,0 +1,161 @@
+Format: http://svn.debian.org/wsvn/dep/web/deps/dep5.mdwn?rev=174
+Upstream-Name: Bitcoin
+Upstream-Contact: Satoshi Nakamoto <satoshin@gmx.com>
+ irc://#bitcoin@freenode.net
+Source: https://github.com/bitcoin/bitcoin
+
+Files: *
+Copyright: 2009-2012, Bitcoin Core Developers
+License: Expat
+Comment: The Bitcoin Core 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: debian/*
+Copyright: 2010-2011, Jonas Smedegaard <dr@jones.dk>
+ 2011, Matt Corallo <matt@bluematt.me>
+License: GPL-2+
+
+Files: debian/manpages/*
+Copyright: Micah Anderson <micah@debian.org>
+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: Expat
+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/*.png
+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 <http://www.gnu.org/licenses/>.
+
+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 <http://www.gnu.org/licenses/>.
+
+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 <http://www.gnu.org/licenses/>.
+
+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 0000000000..ade80d60ea
--- /dev/null
+++ b/contrib/debian/examples/bitcoin.conf
@@ -0,0 +1,133 @@
+##
+## bitcoin.conf configuration file. Lines beginning with # are comments.
+##
+
+# Network-related settings:
+
+# Run on the test network instead of the real bitcoin network.
+#testnet=0
+
+# Run a regression test network
+#regtest=0
+
+# Connect via a SOCKS5 proxy
+#proxy=127.0.0.1:9050
+
+# Bind to given address and always listen on it. Use [host]:port notation for IPv6
+#bind=<addr>
+
+# Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6
+#whitebind=<addr>
+
+##############################################################
+## Quick Primer on addnode vs connect ##
+## Let's say for instance you use addnode=4.2.2.4 ##
+## addnode will connect you to and tell you about the ##
+## nodes connected to 4.2.2.4. In addition it will tell ##
+## the other nodes connected to it that you exist so ##
+## they can connect to you. ##
+## connect will not do the above when you 'connect' to it. ##
+## It will *only* connect you to 4.2.2.4 and no one else.##
+## ##
+## So if you're behind a firewall, or have other problems ##
+## finding nodes, add some using 'addnode'. ##
+## ##
+## If you want to stay private, use 'connect' to only ##
+## connect to "trusted" nodes. ##
+## ##
+## If you run multiple nodes on a LAN, there's no need for ##
+## all of them to open lots of connections. Instead ##
+## 'connect' them all to one node that is port forwarded ##
+## and has lots of connections. ##
+## Thanks goes to [Noodle] on Freenode. ##
+##############################################################
+
+# Use as many addnode= settings as you like to connect to specific peers
+#addnode=69.164.218.197
+#addnode=10.0.0.2:8333
+
+# Alternatively 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
+
+# Listening mode, enabled by default except when 'connect' is being used
+#listen=1
+
+# Maximum number of inbound+outbound connections.
+#maxconnections=
+
+#
+# JSON-RPC options (for controlling a running Bitcoin/bitcoind process)
+#
+
+# server=1 tells Bitcoin-QT and bitcoind to accept JSON-RPC commands
+#server=0
+
+# Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6.
+# This option can be specified multiple times (default: bind to all interfaces)
+#rpcbind=<addr>
+
+# You must set rpcuser and rpcpassword to secure the JSON-RPC api
+#rpcuser=Ulysseys
+#rpcpassword=YourSuperGreatPasswordNumber_DO_NOT_USE_THIS_OR_YOU_WILL_GET_ROBBED_385593
+
+# How many seconds bitcoin will wait for a complete RPC HTTP request.
+# after the HTTP connection is established.
+#rpctimeout=30
+
+# By default, only RPC connections from localhost are allowed.
+# Specify as many rpcallowip= settings as you like to allow connections from other hosts,
+# either as a single IPv4/IPv6 or with a subnet specification.
+
+# NOTE: opening up the RPC port to hosts outside your local trusted network is NOT RECOMMENDED,
+# because the rpcpassword is transmitted over the network unencrypted.
+
+# server=1 tells Bitcoin-QT to accept JSON-RPC commands.
+# it is also read by bitcoind to determine if RPC should be enabled
+#rpcallowip=10.1.1.34/255.255.255.0
+#rpcallowip=1.2.3.4/24
+#rpcallowip=2001:db8:85a3:0:0:8a2e:370:7334/96
+
+# 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
+
+# Transaction Fee Changes in 0.10.0
+
+# Send transactions as zero-fee transactions if possible (default: 0)
+#sendfreetransactions=0
+
+# Create transactions that have enough fees (or priority) so they are likely to begin confirmation within n blocks (default: 1).
+# This setting is over-ridden by the -paytxfee option.
+#txconfirmtarget=n
+
+# Miscellaneous options
+
+# 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
+
+# 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 0000000000..a7281f94b2
--- /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-cli.1 b/contrib/debian/manpages/bitcoin-cli.1
new file mode 100644
index 0000000000..f953ae9db7
--- /dev/null
+++ b/contrib/debian/manpages/bitcoin-cli.1
@@ -0,0 +1,48 @@
+.TH BITCOIN-CLI "1" "February 2015" "bitcoin-cli 0.10"
+.SH NAME
+bitcoin-cli \- a remote procedure call client for Bitcoin Core.
+.SH SYNOPSIS
+bitcoin-cli [options] <command> [params] \- Send command to Bitcoin Core.
+.TP
+bitcoin-cli [options] help \- Asks Bitcoin Core for a list of supported commands.
+.SH DESCRIPTION
+This manual page documents the bitcoin-cli program. bitcoin-cli is an RPC client used to send commands to Bitcoin Core.
+
+.SH OPTIONS
+.TP
+\fB\-?\fR
+Show the help message.
+.TP
+\fB\-conf=\fR<file>
+Specify configuration file (default: bitcoin.conf).
+.TP
+\fB\-datadir=\fR<dir>
+Specify data directory.
+.TP
+\fB\-testnet\fR
+Connect to a Bitcoin Core instance running in testnet mode.
+.TP
+\fB\-regtest\fR
+Connect to a Bitcoin Core instance running in regtest mode (see documentation for -regtest on bitcoind).
+.TP
+\fB\-rpcuser=\fR<user>
+Username for JSON\-RPC connections.
+.TP
+\fB\-rpcpassword=\fR<pw>
+Password for JSON\-RPC connections.
+.TP
+\fB\-rpcport=\fR<port>
+Listen for JSON\-RPC connections on <port> (default: 8332 or testnet: 18332).
+.TP
+\fB\-rpcconnect=\fR<ip>
+Send commands to node running on <ip> (default: 127.0.0.1).
+.TP
+\fB\-rpcssl\fR=\fI1\fR
+Use OpenSSL (https) for JSON\-RPC connections (see the Bitcoin Wiki for SSL setup instructions).
+
+.SH "SEE ALSO"
+\fBbitcoind\fP, \fBbitcoin.conf\fP
+.SH AUTHOR
+This manual page was written by Ciemon Dunville <ciemon@gmail.com>. Permission is granted to copy, distribute and/or modify this document under the terms of the MIT License.
+
+The complete text of the MIT License can be found on the web at \fIhttp://opensource.org/licenses/MIT\fP.
diff --git a/contrib/debian/manpages/bitcoin-qt.1 b/contrib/debian/manpages/bitcoin-qt.1
new file mode 100644
index 0000000000..a023582bc0
--- /dev/null
+++ b/contrib/debian/manpages/bitcoin-qt.1
@@ -0,0 +1,203 @@
+.TH BITCOIN-QT "1" "April 2013" "bitcoin-qt 1"
+.SH NAME
+bitcoin-qt \- peer-to-peer network based digital currency
+.SH DESCRIPTION
+.SS "Usage:"
+.IP
+bitcoin\-qt [command\-line options]
+.SH OPTIONS
+.TP
+\-?
+This help message
+.TP
+\fB\-conf=\fR<file>
+Specify configuration file (default: bitcoin.conf)
+.TP
+\fB\-pid=\fR<file>
+Specify pid file (default: bitcoind.pid)
+.TP
+\fB\-gen\fR
+Generate coins
+.TP
+\fB\-gen\fR=\fI0\fR
+Don't generate coins
+.TP
+\fB\-datadir=\fR<dir>
+Specify data directory
+.TP
+\fB\-dbcache=\fR<n>
+Set database cache size in megabytes (default: 25)
+.TP
+\fB\-timeout=\fR<n>
+Specify connection timeout in milliseconds (default: 5000)
+.TP
+\fB\-proxy=\fR<ip:port>
+Connect through SOCKS5 proxy
+.TP
+\fB\-tor=\fR<ip:port>
+Use proxy to reach tor hidden services (default: same as \fB\-proxy\fR)
+.TP
+\fB\-dns\fR
+Allow DNS lookups for \fB\-addnode\fR, \fB\-seednode\fR and \fB\-connect\fR
+.TP
+\fB\-port=\fR<port>
+Listen for connections on <port> (default: 8333 or testnet: 18333)
+.TP
+\fB\-maxconnections=\fR<n>
+Maintain at most <n> connections to peers (default: 125)
+.TP
+\fB\-addnode=\fR<ip>
+Add a node to connect to and attempt to keep the connection open
+.TP
+\fB\-connect=\fR<ip>
+Connect only to the specified node(s)
+.TP
+\fB\-seednode=\fR<ip>
+Connect to a node to retrieve peer addresses, and disconnect
+.TP
+\fB\-externalip=\fR<ip>
+Specify your own public address
+.TP
+\fB\-onlynet=\fR<net>
+Only connect to nodes in network <net> (IPv4, IPv6 or Tor)
+.TP
+\fB\-discover\fR
+Discover own IP address (default: 1 when listening and no \fB\-externalip\fR)
+.TP
+\fB\-checkpoints\fR
+Only accept block chain matching built\-in checkpoints (default: 1)
+.TP
+\fB\-listen\fR
+Accept connections from outside (default: 1 if no \fB\-proxy\fR or \fB\-connect\fR)
+.TP
+\fB\-bind=\fR<addr>
+Bind to given address and always listen on it. Use [host]:port notation for IPv6
+.TP
+\fB\-dnsseed\fR
+Find peers using DNS lookup (default: 1 unless \fB\-connect\fR)
+.TP
+\fB\-banscore=\fR<n>
+Threshold for disconnecting misbehaving peers (default: 100)
+.TP
+\fB\-bantime=\fR<n>
+Number of seconds to keep misbehaving peers from reconnecting (default: 86400)
+.TP
+\fB\-maxreceivebuffer=\fR<n>
+Maximum per\-connection receive buffer, <n>*1000 bytes (default: 5000)
+.TP
+\fB\-maxsendbuffer=\fR<n>
+Maximum per\-connection send buffer, <n>*1000 bytes (default: 1000)
+.TP
+\fB\-upnp\fR
+Use UPnP to map the listening port (default: 1 when listening)
+.TP
+\fB\-paytxfee=\fR<amt>
+Fee per KB to add to transactions you send
+.TP
+\fB\-server\fR
+Accept command line and JSON\-RPC commands
+.TP
+\fB\-testnet\fR
+Use the test network
+.TP
+\fB\-debug\fR
+Output extra debugging information. Implies all other \fB\-debug\fR* options
+.TP
+\fB\-debugnet\fR
+Output extra network debugging information
+.TP
+\fB\-logtimestamps\fR
+Prepend debug output with timestamp
+.TP
+\fB\-shrinkdebugfile\fR
+Shrink debug.log file on client startup (default: 1 when no \fB\-debug\fR)
+.TP
+\fB\-printtoconsole\fR
+Send trace/debug info to console instead of debug.log file
+.TP
+\fB\-rpcuser=\fR<user>
+Username for JSON\-RPC connections
+.TP
+\fB\-rpcpassword=\fR<pw>
+Password for JSON\-RPC connections
+.TP
+\fB\-rpcport=\fR<port>
+Listen for JSON\-RPC connections on <port> (default: 8332 or testnet: 18332)
+.TP
+\fB\-rpcallowip=\fR<ip>
+Allow JSON\-RPC connections from specified IP address
+.TP
+\fB\-rpcthreads=\fR<n>
+Set the number of threads to service RPC calls (default: 4)
+.TP
+\fB\-blocknotify=\fR<cmd>
+Execute command when the best block changes (%s in cmd is replaced by block hash)
+.TP
+\fB\-walletnotify=\fR<cmd>
+Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)
+.TP
+\fB\-alertnotify=\fR<cmd>
+Execute command when a relevant alert is received (%s in cmd is replaced by message)
+.TP
+\fB\-upgradewallet\fR
+Upgrade wallet to latest format
+.TP
+\fB\-keypool=\fR<n>
+Set key pool size to <n> (default: 100)
+.TP
+\fB\-rescan\fR
+Rescan the block chain for missing wallet transactions
+.TP
+\fB\-salvagewallet\fR
+Attempt to recover private keys from a corrupt wallet.dat
+.TP
+\fB\-checkblocks=\fR<n>
+How many blocks to check at startup (default: 288, 0 = all)
+.TP
+\fB\-checklevel=\fR<n>
+How thorough the block verification is (0\-4, default: 3)
+.TP
+\fB\-txindex\fR
+Maintain a full transaction index (default: 0)
+.TP
+\fB\-loadblock=\fR<file>
+Imports blocks from external blk000??.dat file
+.TP
+\fB\-reindex\fR
+Rebuild block chain index from current blk000??.dat files
+.TP
+\fB\-par=\fR<n>
+Set the number of script verification threads (1\-16, 0=auto, default: 0)
+.SS "Block creation options:"
+.TP
+\fB\-blockminsize=\fR<n>
+Set minimum block size in bytes (default: 0)
+.TP
+\fB\-blockmaxsize=\fR<n>
+Set maximum block size in bytes (default: 250000)
+.HP
+\fB\-blockprioritysize=\fR<n> Set maximum size of high\-priority/low\-fee transactions in bytes (default: 27000)
+.PP
+SSL options: (see the Bitcoin Wiki for SSL setup instructions)
+.TP
+\fB\-rpcssl\fR
+Use OpenSSL (https) for JSON\-RPC connections
+.TP
+\fB\-rpcsslcertificatechainfile=\fR<file.cert>
+Server certificate file (default: server.cert)
+.TP
+\fB\-rpcsslprivatekeyfile=\fR<file.pem>
+Server private key (default: server.pem)
+.TP
+\fB\-rpcsslciphers=\fR<ciphers>
+Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)
+.SS "UI options:"
+.TP
+\fB\-lang=\fR<lang>
+Set language, for example "de_DE" (default: system locale)
+.TP
+\fB\-min\fR
+Start minimized
+.TP
+\fB\-splash\fR
+Show splash screen on startup (default: 1)
diff --git a/contrib/debian/manpages/bitcoin.conf.5 b/contrib/debian/manpages/bitcoin.conf.5
new file mode 100644
index 0000000000..8a0078d5d5
--- /dev/null
+++ b/contrib/debian/manpages/bitcoin.conf.5
@@ -0,0 +1,89 @@
+.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 '\-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
+\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
+\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
+\fB\-rpcsslciphers=\fR<ciphers>
+Acceptable ciphers (default: TLSv1+HIGH:\:!SSLv2:\:!aNULL:\:!eNULL:\:!AH:\:!3DES:\:@STRENGTH)
+.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 <micah@debian.org> 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 0000000000..c225b9f3e9
--- /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] <command> [params]
+.TP
+bitcoin [options] help <command> \- 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<file>
+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<dir>
+Specify data directory
+.TP
+\fB\-proxy=\fR<ip:port>
+Connect through SOCKS5 proxy
+.TP
+\fB\-addnode=\fR<ip>
+Add a node to connect to
+.TP
+\fB\-connect=\fR<ip>
+Connect only to the specified node
+.TP
+\fB\-paytxfee=\fR<amt>
+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<user>
+Username for JSON\-RPC connections
+.TP
+\fB\-rpcpassword=\fR<pw>
+Password for JSON\-RPC connections
+.TP
+\fB\-rpcport=\fR<port>
+Listen for JSON\-RPC connections on <port>
+.TP
+\fB\-rpcallowip=\fR<ip>
+Allow JSON\-RPC connections from specified IP address
+.TP
+\fB\-rpcconnect=\fR<ip>
+Send commands to node running on <ip>
+.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<file.cert>
+Server certificate file (default: server.cert)
+.TP
+\fB\-rpcsslprivatekeyfile=\fR<file.pem>
+Server private key (default: server.pem)
+.TP
+\fB\-rpcsslciphers=\fR<ciphers>
+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
+DEPRECATED. Returns the account associated with the given address.
+.TP
+\fBsetaccount 'bitcoinaddress' ['account']\fR
+DEPRECATED. Sets the ['account'] associated with the given address. ['account'] may be omitted to remove an address from ['account'].
+.TP
+\fBgetaccountaddress 'account'\fR
+DEPRECATED. Returns a new bitcoin address for 'account'.
+.TP
+\fBgetaddressesbyaccount 'account'\fR
+DEPRECATED. 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' (accounts are deprecated).
+.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 (deprecated), it is added to the address book so payments received with the address will be credited to 'account'.
+.TP
+\fBgetreceivedbyaccount 'account' ['minconf=1']\fR
+DEPRECATED. 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
+DEPRECATED. 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" : DEPRECATED. 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" : DEPRECATED. 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
+DEPRECATED. Moves funds between accounts.
+.TP
+\fBsendfrom* <'account'> <'bitcoinaddress'> <'amount'> ['minconf=1'] ['comment'] ['comment-to']\fR
+DEPRECATED. 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 <micah@debian.org> 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 0000000000..80c1584376
--- /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 0000000000..8b13789179
--- /dev/null
+++ b/contrib/debian/patches/series
@@ -0,0 +1 @@
+
diff --git a/contrib/debian/rules b/contrib/debian/rules
new file mode 100755
index 0000000000..52b357cf01
--- /dev/null
+++ b/contrib/debian/rules
@@ -0,0 +1,24 @@
+#!/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_clean:
+ if [ -f Makefile ]; then $(MAKE) distclean; fi
+ rm -rf Makefile.in aclocal.m4 configure src/Makefile.in src/bitcoin-config.h.in src/build-aux src/qt/Makefile.in src/qt/test/Makefile.in src/test/Makefile.in
+
+# Yea, autogen should be run on the source archive, but I like doing git archive
+override_dh_auto_configure:
+ ./autogen.sh
+ ./configure
+
+override_dh_auto_test:
+ make check
diff --git a/contrib/debian/source/format b/contrib/debian/source/format
new file mode 100644
index 0000000000..163aaf8d82
--- /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 0000000000..c96d2f8e75
--- /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/devtools/README.md b/contrib/devtools/README.md
new file mode 100644
index 0000000000..f90afa7f20
--- /dev/null
+++ b/contrib/devtools/README.md
@@ -0,0 +1,96 @@
+Contents
+===========
+This directory contains tools for developers working on this repository.
+
+github-merge.sh
+==================
+
+A small script to automate merging pull-requests securely and sign them with GPG.
+
+For example:
+
+ ./github-merge.sh bitcoin/bitcoin 3077
+
+(in any git repository) will help you merge pull request #3077 for the
+bitcoin/bitcoin repository.
+
+What it does:
+* Fetch master and the pull request.
+* Locally construct a merge commit.
+* Show the diff that merge results in.
+* Ask you to verify the resulting source tree (so you can do a make
+check or whatever).
+* Ask you whether to GPG sign the merge commit.
+* Ask you whether to push the result upstream.
+
+This means that there are no potential race conditions (where a
+pullreq gets updated while you're reviewing it, but before you click
+merge), and when using GPG signatures, that even a compromised github
+couldn't mess with the sources.
+
+Setup
+---------
+Configuring the github-merge tool for the bitcoin repository is done in the following way:
+
+ git config githubmerge.repository bitcoin/bitcoin
+ git config githubmerge.testcmd "make -j4 check" (adapt to whatever you want to use for testing)
+ git config --global user.signingkey mykeyid (if you want to GPG sign)
+
+fix-copyright-headers.py
+===========================
+
+Every year newly updated files need to have its copyright headers updated to reflect the current year.
+If you run this script from src/ it will automatically update the year on the copyright header for all
+.cpp and .h files if these have a git commit from the current year.
+
+For example a file changed in 2014 (with 2014 being the current year):
+```// Copyright (c) 2009-2013 The Bitcoin Core developers```
+
+would be changed to:
+```// Copyright (c) 2009-2014 The Bitcoin Core developers```
+
+symbol-check.py
+==================
+
+A script to check that the (Linux) executables produced by gitian only contain
+allowed gcc, glibc and libstdc++ version symbols. This makes sure they are
+still compatible with the minimum supported Linux distribution versions.
+
+Example usage after a gitian build:
+
+ find ../gitian-builder/build -type f -executable | xargs python contrib/devtools/symbol-check.py
+
+If only supported symbols are used the return value will be 0 and the output will be empty.
+
+If there are 'unsupported' symbols, the return value will be 1 a list like this will be printed:
+
+ .../64/test_bitcoin: symbol memcpy from unsupported version GLIBC_2.14
+ .../64/test_bitcoin: symbol __fdelt_chk from unsupported version GLIBC_2.15
+ .../64/test_bitcoin: symbol std::out_of_range::~out_of_range() from unsupported version GLIBCXX_3.4.15
+ .../64/test_bitcoin: symbol _ZNSt8__detail15_List_nod from unsupported version GLIBCXX_3.4.15
+
+update-translations.py
+=======================
+
+Run this script from the root of the repository to update all translations from transifex.
+It will do the following automatically:
+
+- fetch all translations
+- post-process them into valid and committable format
+- add missing translations to the build system (TODO)
+
+See doc/translation-process.md for more information.
+
+git-subtree-check.sh
+====================
+
+Run this script from the root of the repository to verify that a subtree matches the contents of
+the commit it claims to have been updated to.
+
+To use, make sure that you have fetched the upstream repository branch in which the subtree is
+maintained:
+* for src/secp256k1: https://github.com/bitcoin/secp256k1.git (branch master)
+* for sec/leveldb: https://github.com/bitcoin/leveldb.git (branch bitcoin-fork)
+
+Usage: git-subtree-check.sh DIR COMMIT
+COMMIT may be omitted, in which case HEAD is used.
diff --git a/contrib/devtools/fix-copyright-headers.py b/contrib/devtools/fix-copyright-headers.py
new file mode 100755
index 0000000000..5e84952548
--- /dev/null
+++ b/contrib/devtools/fix-copyright-headers.py
@@ -0,0 +1,53 @@
+#!/usr/bin/env python
+'''
+Run this script inside of src/ and it will look for all the files
+that were changed this year that still have the last year in the
+copyright headers, and it will fix the headers on that file using
+a perl regex one liner.
+
+For example: if it finds something like this and we're in 2014
+
+// Copyright (c) 2009-2013 The Bitcoin Core developers
+
+it will change it to
+
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+
+It will do this for all the files in the folder and its children.
+
+Author: @gubatron
+'''
+import os
+import time
+
+year = time.gmtime()[0]
+last_year = year - 1
+command = "perl -pi -e 's/%s The Bitcoin/%s The Bitcoin/' %s"
+listFilesCommand = "find . | grep %s"
+
+extensions = [".cpp",".h"]
+
+def getLastGitModifiedDate(filePath):
+ gitGetLastCommitDateCommand = "git log " + filePath +" | grep Date | head -n 1"
+ p = os.popen(gitGetLastCommitDateCommand)
+ result = ""
+ for l in p:
+ result = l
+ break
+ result = result.replace("\n","")
+ return result
+
+n=1
+for extension in extensions:
+ foundFiles = os.popen(listFilesCommand % extension)
+ for filePath in foundFiles:
+ filePath = filePath[1:-1]
+ if filePath.endswith(extension):
+ filePath = os.getcwd() + filePath
+ modifiedTime = getLastGitModifiedDate(filePath)
+ if len(modifiedTime) > 0 and str(year) in modifiedTime:
+ print n,"Last Git Modified: ", modifiedTime, " - ", filePath
+ os.popen(command % (last_year,year,filePath))
+ n = n + 1
+
+
diff --git a/contrib/devtools/git-subtree-check.sh b/contrib/devtools/git-subtree-check.sh
new file mode 100755
index 0000000000..1cb82fe682
--- /dev/null
+++ b/contrib/devtools/git-subtree-check.sh
@@ -0,0 +1,74 @@
+#!/bin/sh
+
+DIR="$1"
+COMMIT="$2"
+if [ -z "$COMMIT" ]; then
+ COMMIT=HEAD
+fi
+
+# Taken from git-subtree (Copyright (C) 2009 Avery Pennarun <apenwarr@gmail.com>)
+find_latest_squash()
+{
+ dir="$1"
+ sq=
+ main=
+ sub=
+ git log --grep="^git-subtree-dir: $dir/*\$" \
+ --pretty=format:'START %H%n%s%n%n%b%nEND%n' "$COMMIT" |
+ while read a b junk; do
+ case "$a" in
+ START) sq="$b" ;;
+ git-subtree-mainline:) main="$b" ;;
+ git-subtree-split:) sub="$b" ;;
+ END)
+ if [ -n "$sub" ]; then
+ if [ -n "$main" ]; then
+ # a rejoin commit?
+ # Pretend its sub was a squash.
+ sq="$sub"
+ fi
+ echo "$sq" "$sub"
+ break
+ fi
+ sq=
+ main=
+ sub=
+ ;;
+ esac
+ done
+}
+
+latest_squash="$(find_latest_squash "$DIR")"
+if [ -z "$latest_squash" ]; then
+ echo "ERROR: $DIR is not a subtree" >&2
+ exit 2
+fi
+
+set $latest_squash
+old=$1
+rev=$2
+if [ "d$(git cat-file -t $rev 2>/dev/null)" != dcommit ]; then
+ echo "ERROR: subtree commit $rev unavailable. Fetch/update the subtree repository" >&2
+ exit 2
+fi
+tree_subtree=$(git show -s --format="%T" $rev)
+echo "$DIR in $COMMIT was last updated to upstream commit $rev (tree $tree_subtree)"
+tree_actual=$(git ls-tree -d "$COMMIT" "$DIR" | head -n 1)
+if [ -z "$tree_actual" ]; then
+ echo "FAIL: subtree directory $DIR not found in $COMMIT" >&2
+ exit 1
+fi
+set $tree_actual
+tree_actual_type=$2
+tree_actual_tree=$3
+echo "$DIR in $COMMIT currently refers to $tree_actual_type $tree_actual_tree"
+if [ "d$tree_actual_type" != "dtree" ]; then
+ echo "FAIL: subtree directory $DIR is not a tree in $COMMIT" >&2
+ exit 1
+fi
+if [ "$tree_actual_tree" != "$tree_subtree" ]; then
+ git diff-tree $tree_actual_tree $tree_subtree >&2
+ echo "FAIL: subtree directory tree doesn't match subtree commit tree" >&2
+ exit 1
+fi
+echo "GOOD"
diff --git a/contrib/devtools/github-merge.sh b/contrib/devtools/github-merge.sh
new file mode 100755
index 0000000000..ec7a1f4c4b
--- /dev/null
+++ b/contrib/devtools/github-merge.sh
@@ -0,0 +1,181 @@
+#!/bin/bash
+
+# This script will locally construct a merge commit for a pull request on a
+# github repository, inspect it, sign it and optionally push it.
+
+# The following temporary branches are created/overwritten and deleted:
+# * pull/$PULL/base (the current master we're merging onto)
+# * pull/$PULL/head (the current state of the remote pull request)
+# * pull/$PULL/merge (github's merge)
+# * pull/$PULL/local-merge (our merge)
+
+# In case of a clean merge that is accepted by the user, the local branch with
+# name $BRANCH is overwritten with the merged result, and optionally pushed.
+
+REPO="$(git config --get githubmerge.repository)"
+if [[ "d$REPO" == "d" ]]; then
+ echo "ERROR: No repository configured. Use this command to set:" >&2
+ echo "git config githubmerge.repository <owner>/<repo>" >&2
+ echo "In addition, you can set the following variables:" >&2
+ echo "- githubmerge.host (default git@github.com)" >&2
+ echo "- githubmerge.branch (default master)" >&2
+ echo "- githubmerge.testcmd (default none)" >&2
+ exit 1
+fi
+
+HOST="$(git config --get githubmerge.host)"
+if [[ "d$HOST" == "d" ]]; then
+ HOST="git@github.com"
+fi
+
+BRANCH="$(git config --get githubmerge.branch)"
+if [[ "d$BRANCH" == "d" ]]; then
+ BRANCH="master"
+fi
+
+TESTCMD="$(git config --get githubmerge.testcmd)"
+
+PULL="$1"
+
+if [[ "d$PULL" == "d" ]]; then
+ echo "Usage: $0 pullnumber [branch]" >&2
+ exit 2
+fi
+
+if [[ "d$2" != "d" ]]; then
+ BRANCH="$2"
+fi
+
+# Initialize source branches.
+git checkout -q "$BRANCH"
+if git fetch -q "$HOST":"$REPO" "+refs/pull/$PULL/*:refs/heads/pull/$PULL/*"; then
+ if ! git log -q -1 "refs/heads/pull/$PULL/head" >/dev/null 2>&1; then
+ echo "ERROR: Cannot find head of pull request #$PULL on $HOST:$REPO." >&2
+ exit 3
+ fi
+ if ! git log -q -1 "refs/heads/pull/$PULL/merge" >/dev/null 2>&1; then
+ echo "ERROR: Cannot find merge of pull request #$PULL on $HOST:$REPO." >&2
+ exit 3
+ fi
+else
+ echo "ERROR: Cannot find pull request #$PULL on $HOST:$REPO." >&2
+ exit 3
+fi
+if git fetch -q "$HOST":"$REPO" +refs/heads/"$BRANCH":refs/heads/pull/"$PULL"/base; then
+ true
+else
+ echo "ERROR: Cannot find branch $BRANCH on $HOST:$REPO." >&2
+ exit 3
+fi
+git checkout -q pull/"$PULL"/base
+git branch -q -D pull/"$PULL"/local-merge 2>/dev/null
+git checkout -q -b pull/"$PULL"/local-merge
+TMPDIR="$(mktemp -d -t ghmXXXXX)"
+
+function cleanup() {
+ git checkout -q "$BRANCH"
+ git branch -q -D pull/"$PULL"/head 2>/dev/null
+ git branch -q -D pull/"$PULL"/base 2>/dev/null
+ git branch -q -D pull/"$PULL"/merge 2>/dev/null
+ git branch -q -D pull/"$PULL"/local-merge 2>/dev/null
+ rm -rf "$TMPDIR"
+}
+
+# Create unsigned merge commit.
+(
+ echo "Merge pull request #$PULL"
+ echo ""
+ git log --no-merges --topo-order --pretty='format:%h %s (%an)' pull/"$PULL"/base..pull/"$PULL"/head
+)>"$TMPDIR/message"
+if git merge -q --commit --no-edit --no-ff -m "$(<"$TMPDIR/message")" pull/"$PULL"/head; then
+ if [ "d$(git log --pretty='format:%s' -n 1)" != "dMerge pull request #$PULL" ]; then
+ echo "ERROR: Creating merge failed (already merged?)." >&2
+ cleanup
+ exit 4
+ fi
+else
+ echo "ERROR: Cannot be merged cleanly." >&2
+ git merge --abort
+ cleanup
+ exit 4
+fi
+
+# Run test command if configured.
+if [[ "d$TESTCMD" != "d" ]]; then
+ # Go up to the repository's root.
+ while [ ! -d .git ]; do cd ..; done
+ if ! $TESTCMD; then
+ echo "ERROR: Running $TESTCMD failed." >&2
+ cleanup
+ exit 5
+ fi
+ # Show the created merge.
+ git diff pull/"$PULL"/merge..pull/"$PULL"/local-merge >"$TMPDIR"/diff
+ git diff pull/"$PULL"/base..pull/"$PULL"/local-merge
+ if [[ "$(<"$TMPDIR"/diff)" != "" ]]; then
+ echo "WARNING: merge differs from github!" >&2
+ read -p "Type 'ignore' to continue. " -r >&2
+ if [[ "d$REPLY" =~ ^d[iI][gG][nN][oO][rR][eE]$ ]]; then
+ echo "Difference with github ignored." >&2
+ else
+ cleanup
+ exit 6
+ fi
+ fi
+ read -p "Press 'd' to accept the diff. " -n 1 -r >&2
+ echo
+ if [[ "d$REPLY" =~ ^d[dD]$ ]]; then
+ echo "Diff accepted." >&2
+ else
+ echo "ERROR: Diff rejected." >&2
+ cleanup
+ exit 6
+ fi
+else
+ # Verify the result.
+ echo "Dropping you on a shell so you can try building/testing the merged source." >&2
+ echo "Run 'git diff HEAD~' to show the changes being merged." >&2
+ echo "Type 'exit' when done." >&2
+ if [[ -f /etc/debian_version ]]; then # Show pull number in prompt on Debian default prompt
+ export debian_chroot="$PULL"
+ fi
+ bash -i
+ read -p "Press 'm' to accept the merge. " -n 1 -r >&2
+ echo
+ if [[ "d$REPLY" =~ ^d[Mm]$ ]]; then
+ echo "Merge accepted." >&2
+ else
+ echo "ERROR: Merge rejected." >&2
+ cleanup
+ exit 7
+ fi
+fi
+
+# Sign the merge commit.
+read -p "Press 's' to sign off on the merge. " -n 1 -r >&2
+echo
+if [[ "d$REPLY" =~ ^d[Ss]$ ]]; then
+ if [[ "$(git config --get user.signingkey)" == "" ]]; then
+ echo "ERROR: No GPG signing key set, not signing. Set one using:" >&2
+ echo "git config --global user.signingkey <key>" >&2
+ cleanup
+ exit 1
+ else
+ git commit -q --gpg-sign --amend --no-edit
+ fi
+else
+ echo "Not signing off on merge, exiting."
+ cleanup
+ exit 1
+fi
+
+# Clean up temporary branches, and put the result in $BRANCH.
+git checkout -q "$BRANCH"
+git reset -q --hard pull/"$PULL"/local-merge
+cleanup
+
+# Push the result.
+read -p "Type 'push' to push the result to $HOST:$REPO, branch $BRANCH. " -r >&2
+if [[ "d$REPLY" =~ ^d[Pp][Uu][Ss][Hh]$ ]]; then
+ git push "$HOST":"$REPO" refs/heads/"$BRANCH"
+fi
diff --git a/contrib/devtools/optimize-pngs.py b/contrib/devtools/optimize-pngs.py
new file mode 100755
index 0000000000..38aaa00f31
--- /dev/null
+++ b/contrib/devtools/optimize-pngs.py
@@ -0,0 +1,73 @@
+#!/usr/bin/env python
+
+import os
+import sys
+import subprocess
+import hashlib
+from PIL import Image
+
+def file_hash(filename):
+ '''Return hash of raw file contents'''
+ with open(filename, 'rb') as f:
+ return hashlib.sha256(f.read()).hexdigest()
+
+def content_hash(filename):
+ '''Return hash of RGBA contents of image'''
+ i = Image.open(filename)
+ i = i.convert('RGBA')
+ data = i.tostring()
+ return hashlib.sha256(data).hexdigest()
+
+#optimize png, remove various color profiles, remove ancillary chunks (alla) and text chunks (text)
+#pngcrush -brute -ow -rem gAMA -rem cHRM -rem iCCP -rem sRGB -rem alla -rem text
+
+pngcrush = 'pngcrush'
+git = 'git'
+folders = ["src/qt/res/movies", "src/qt/res/icons", "src/qt/res/images"]
+basePath = subprocess.check_output([git, 'rev-parse', '--show-toplevel']).rstrip('\n')
+totalSaveBytes = 0
+
+outputArray = []
+for folder in folders:
+ absFolder=os.path.join(basePath, folder)
+ for file in os.listdir(absFolder):
+ extension = os.path.splitext(file)[1]
+ if extension.lower() == '.png':
+ print("optimizing "+file+"..."),
+ file_path = os.path.join(absFolder, file)
+ fileMetaMap = {'file' : file, 'osize': os.path.getsize(file_path), 'sha256Old' : file_hash(file_path)};
+ fileMetaMap['contentHashPre'] = content_hash(file_path)
+
+ pngCrushOutput = ""
+ try:
+ pngCrushOutput = subprocess.check_output(
+ [pngcrush, "-brute", "-ow", "-rem", "gAMA", "-rem", "cHRM", "-rem", "iCCP", "-rem", "sRGB", "-rem", "alla", "-rem", "text", file_path],
+ stderr=subprocess.STDOUT).rstrip('\n')
+ except:
+ print "pngcrush is not installed, aborting..."
+ sys.exit(0)
+
+ #verify
+ if "Not a PNG file" in subprocess.check_output([pngcrush, "-n", "-v", file_path], stderr=subprocess.STDOUT):
+ print "PNG file "+file+" is corrupted after crushing, check out pngcursh version"
+ sys.exit(1)
+
+ fileMetaMap['sha256New'] = file_hash(file_path)
+ fileMetaMap['contentHashPost'] = content_hash(file_path)
+
+ if fileMetaMap['contentHashPre'] != fileMetaMap['contentHashPost']:
+ print "Image contents of PNG file "+file+" before and after crushing don't match"
+ sys.exit(1)
+
+ fileMetaMap['psize'] = os.path.getsize(file_path)
+ outputArray.append(fileMetaMap)
+ print("done\n"),
+
+print "summary:\n+++++++++++++++++"
+for fileDict in outputArray:
+ oldHash = fileDict['sha256Old']
+ newHash = fileDict['sha256New']
+ totalSaveBytes += fileDict['osize'] - fileDict['psize']
+ print fileDict['file']+"\n size diff from: "+str(fileDict['osize'])+" to: "+str(fileDict['psize'])+"\n old sha256: "+oldHash+"\n new sha256: "+newHash+"\n"
+
+print "completed. Total reduction: "+str(totalSaveBytes)+" bytes"
diff --git a/contrib/devtools/symbol-check.py b/contrib/devtools/symbol-check.py
new file mode 100755
index 0000000000..fad891f800
--- /dev/null
+++ b/contrib/devtools/symbol-check.py
@@ -0,0 +1,119 @@
+#!/usr/bin/python
+# Copyright (c) 2014 Wladimir J. van der Laan
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+'''
+A script to check that the (Linux) executables produced by gitian only contain
+allowed gcc, glibc and libstdc++ version symbols. This makes sure they are
+still compatible with the minimum supported Linux distribution versions.
+
+Example usage:
+
+ find ../gitian-builder/build -type f -executable | xargs python contrib/devtools/symbol-check.py
+'''
+from __future__ import division, print_function
+import subprocess
+import re
+import sys
+
+# Debian 6.0.9 (Squeeze) has:
+#
+# - g++ version 4.4.5 (https://packages.debian.org/search?suite=default&section=all&arch=any&searchon=names&keywords=g%2B%2B)
+# - libc version 2.11.3 (https://packages.debian.org/search?suite=default&section=all&arch=any&searchon=names&keywords=libc6)
+# - libstdc++ version 4.4.5 (https://packages.debian.org/search?suite=default&section=all&arch=any&searchon=names&keywords=libstdc%2B%2B6)
+#
+# Ubuntu 10.04.4 (Lucid Lynx) has:
+#
+# - g++ version 4.4.3 (http://packages.ubuntu.com/search?keywords=g%2B%2B&searchon=names&suite=lucid&section=all)
+# - libc version 2.11.1 (http://packages.ubuntu.com/search?keywords=libc6&searchon=names&suite=lucid&section=all)
+# - libstdc++ version 4.4.3 (http://packages.ubuntu.com/search?suite=lucid&section=all&arch=any&keywords=libstdc%2B%2B&searchon=names)
+#
+# Taking the minimum of these as our target.
+#
+# According to GNU ABI document (http://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html) this corresponds to:
+# GCC 4.4.0: GCC_4.4.0
+# GCC 4.4.2: GLIBCXX_3.4.13, CXXABI_1.3.3
+# (glibc) GLIBC_2_11
+#
+MAX_VERSIONS = {
+'GCC': (4,4,0),
+'CXXABI': (1,3,3),
+'GLIBCXX': (3,4,13),
+'GLIBC': (2,11)
+}
+# Ignore symbols that are exported as part of every executable
+IGNORE_EXPORTS = {
+'_edata', '_end', '_init', '__bss_start', '_fini'
+}
+READELF_CMD = '/usr/bin/readelf'
+CPPFILT_CMD = '/usr/bin/c++filt'
+
+class CPPFilt(object):
+ '''
+ Demangle C++ symbol names.
+
+ Use a pipe to the 'c++filt' command.
+ '''
+ def __init__(self):
+ self.proc = subprocess.Popen(CPPFILT_CMD, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
+
+ def __call__(self, mangled):
+ self.proc.stdin.write(mangled + '\n')
+ return self.proc.stdout.readline().rstrip()
+
+ def close(self):
+ self.proc.stdin.close()
+ self.proc.stdout.close()
+ self.proc.wait()
+
+def read_symbols(executable, imports=True):
+ '''
+ Parse an ELF executable and return a list of (symbol,version) tuples
+ for dynamic, imported symbols.
+ '''
+ p = subprocess.Popen([READELF_CMD, '--dyn-syms', '-W', executable], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
+ (stdout, stderr) = p.communicate()
+ if p.returncode:
+ raise IOError('Could not read symbols for %s: %s' % (executable, stderr.strip()))
+ syms = []
+ for line in stdout.split('\n'):
+ line = line.split()
+ if len(line)>7 and re.match('[0-9]+:$', line[0]):
+ (sym, _, version) = line[7].partition('@')
+ is_import = line[6] == 'UND'
+ if version.startswith('@'):
+ version = version[1:]
+ if is_import == imports:
+ syms.append((sym, version))
+ return syms
+
+def check_version(max_versions, version):
+ if '_' in version:
+ (lib, _, ver) = version.rpartition('_')
+ else:
+ lib = version
+ ver = '0'
+ ver = tuple([int(x) for x in ver.split('.')])
+ if not lib in max_versions:
+ return False
+ return ver <= max_versions[lib]
+
+if __name__ == '__main__':
+ cppfilt = CPPFilt()
+ retval = 0
+ for filename in sys.argv[1:]:
+ # Check imported symbols
+ for sym,version in read_symbols(filename, True):
+ if version and not check_version(MAX_VERSIONS, version):
+ print('%s: symbol %s from unsupported version %s' % (filename, cppfilt(sym), version))
+ retval = 1
+ # Check exported symbols
+ for sym,version in read_symbols(filename, False):
+ if sym in IGNORE_EXPORTS:
+ continue
+ print('%s: export of symbol %s not allowed' % (filename, cppfilt(sym)))
+ retval = 1
+
+ exit(retval)
+
+
diff --git a/contrib/devtools/update-translations.py b/contrib/devtools/update-translations.py
new file mode 100755
index 0000000000..f955e4a1f2
--- /dev/null
+++ b/contrib/devtools/update-translations.py
@@ -0,0 +1,186 @@
+#!/usr/bin/python
+# Copyright (c) 2014 Wladimir J. van der Laan
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+'''
+Run this script from the root of the repository to update all translations from
+transifex.
+It will do the following automatically:
+
+- fetch all translations using the tx tool
+- post-process them into valid and committable format
+ - remove invalid control characters
+ - remove location tags (makes diffs less noisy)
+
+TODO:
+- auto-add new translations to the build system according to the translation process
+'''
+from __future__ import division, print_function
+import subprocess
+import re
+import sys
+import os
+import io
+import xml.etree.ElementTree as ET
+
+# Name of transifex tool
+TX = 'tx'
+# Name of source language file
+SOURCE_LANG = 'bitcoin_en.ts'
+# Directory with locale files
+LOCALE_DIR = 'src/qt/locale'
+
+def check_at_repository_root():
+ if not os.path.exists('.git'):
+ print('No .git directory found')
+ print('Execute this script at the root of the repository', file=sys.stderr)
+ exit(1)
+
+def fetch_all_translations():
+ if subprocess.call([TX, 'pull', '-f']):
+ print('Error while fetching translations', file=sys.stderr)
+ exit(1)
+
+def find_format_specifiers(s):
+ '''Find all format specifiers in a string.'''
+ pos = 0
+ specifiers = []
+ while True:
+ percent = s.find('%', pos)
+ if percent < 0:
+ break
+ specifiers.append(s[percent+1])
+ pos = percent+2
+ return specifiers
+
+def split_format_specifiers(specifiers):
+ '''Split format specifiers between numeric (Qt) and others (strprintf)'''
+ numeric = []
+ other = []
+ for s in specifiers:
+ if s in {'1','2','3','4','5','6','7','8','9'}:
+ numeric.append(s)
+ else:
+ other.append(s)
+
+ # numeric (Qt) can be present in any order, others (strprintf) must be in specified order
+ return set(numeric),other
+
+def sanitize_string(s):
+ '''Sanitize string for printing'''
+ return s.replace('\n',' ')
+
+def check_format_specifiers(source, translation, errors):
+ source_f = split_format_specifiers(find_format_specifiers(source))
+ # assert that no source messages contain both Qt and strprintf format specifiers
+ # if this fails, go change the source as this is hacky and confusing!
+ assert(not(source_f[0] and source_f[1]))
+ try:
+ translation_f = split_format_specifiers(find_format_specifiers(translation))
+ except IndexError:
+ errors.append("Parse error in translation '%s'" % sanitize_string(translation))
+ return False
+ else:
+ if source_f != translation_f:
+ errors.append("Mismatch between '%s' and '%s'" % (sanitize_string(source), sanitize_string(translation)))
+ return False
+ return True
+
+def all_ts_files(suffix=''):
+ for filename in os.listdir(LOCALE_DIR):
+ # process only language files, and do not process source language
+ if not filename.endswith('.ts'+suffix) or filename == SOURCE_LANG+suffix:
+ continue
+ if suffix: # remove provided suffix
+ filename = filename[0:-len(suffix)]
+ filepath = os.path.join(LOCALE_DIR, filename)
+ yield(filename, filepath)
+
+FIX_RE = re.compile(b'[\x00-\x09\x0b\x0c\x0e-\x1f]')
+def remove_invalid_characters(s):
+ '''Remove invalid characters from translation string'''
+ return FIX_RE.sub(b'', s)
+
+# Override cdata escape function to make our output match Qt's (optional, just for cleaner diffs for
+# comparison, disable by default)
+_orig_escape_cdata = None
+def escape_cdata(text):
+ text = _orig_escape_cdata(text)
+ text = text.replace("'", '&apos;')
+ text = text.replace('"', '&quot;')
+ return text
+
+def postprocess_translations(reduce_diff_hacks=False):
+ print('Checking and postprocessing...')
+
+ if reduce_diff_hacks:
+ global _orig_escape_cdata
+ _orig_escape_cdata = ET._escape_cdata
+ ET._escape_cdata = escape_cdata
+
+ for (filename,filepath) in all_ts_files():
+ os.rename(filepath, filepath+'.orig')
+
+ have_errors = False
+ for (filename,filepath) in all_ts_files('.orig'):
+ # pre-fixups to cope with transifex output
+ parser = ET.XMLParser(encoding='utf-8') # need to override encoding because 'utf8' is not understood only 'utf-8'
+ with open(filepath + '.orig', 'rb') as f:
+ data = f.read()
+ # remove control characters; this must be done over the entire file otherwise the XML parser will fail
+ data = remove_invalid_characters(data)
+ tree = ET.parse(io.BytesIO(data), parser=parser)
+
+ # iterate over all messages in file
+ root = tree.getroot()
+ for context in root.findall('context'):
+ for message in context.findall('message'):
+ numerus = message.get('numerus') == 'yes'
+ source = message.find('source').text
+ translation_node = message.find('translation')
+ # pick all numerusforms
+ if numerus:
+ translations = [i.text for i in translation_node.findall('numerusform')]
+ else:
+ translations = [translation_node.text]
+
+ for translation in translations:
+ if translation is None:
+ continue
+ errors = []
+ valid = check_format_specifiers(source, translation, errors)
+
+ for error in errors:
+ print('%s: %s' % (filename, error))
+
+ if not valid: # set type to unfinished and clear string if invalid
+ translation_node.clear()
+ translation_node.set('type', 'unfinished')
+ have_errors = True
+
+ # Remove location tags
+ for location in message.findall('location'):
+ message.remove(location)
+
+ # Remove entire message if it is an unfinished translation
+ if translation_node.get('type') == 'unfinished':
+ context.remove(message)
+
+ # write fixed-up tree
+ # if diff reduction requested, replace some XML to 'sanitize' to qt formatting
+ if reduce_diff_hacks:
+ out = io.BytesIO()
+ tree.write(out, encoding='utf-8')
+ out = out.getvalue()
+ out = out.replace(b' />', b'/>')
+ with open(filepath, 'wb') as f:
+ f.write(out)
+ else:
+ tree.write(filepath, encoding='utf-8')
+ return have_errors
+
+if __name__ == '__main__':
+ check_at_repository_root()
+ fetch_all_translations()
+ postprocess_translations()
+
diff --git a/contrib/gitian-descriptors/README.md b/contrib/gitian-descriptors/README.md
new file mode 100644
index 0000000000..061b897d2a
--- /dev/null
+++ b/contrib/gitian-descriptors/README.md
@@ -0,0 +1,66 @@
+### Gavin's notes on getting gitian builds up and running using KVM:###
+
+These instructions distilled from:
+[ https://help.ubuntu.com/community/KVM/Installation]( https://help.ubuntu.com/community/KVM/Installation)
+... see there for complete details.
+
+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 ruby 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
+ cd gitian-builder/inputs
+
+ # Create base images
+ cd gitian-builder
+ bin/make-base-vm --suite precise --arch amd64
+ cd ..
+
+ # Get inputs (see doc/release-process.md for exact inputs needed and where to get them)
+ ...
+
+ # For further build instructions see doc/release-notes.md
+ ...
+
+---------------------
+
+`gitian-builder` now also supports building using LXC. See
+[ https://help.ubuntu.com/12.04/serverguide/lxc.html]( https://help.ubuntu.com/12.04/serverguide/lxc.html)
+... for how to get LXC up and running under Ubuntu.
+
+If your main machine is a 64-bit Mac or PC with a few gigabytes of memory
+and at least 10 gigabytes of free disk space, you can `gitian-build` using
+LXC running inside a virtual machine.
+
+Here's a description of Gavin's setup on OSX 10.6:
+
+1. Download and install VirtualBox from [https://www.virtualbox.org/](https://www.virtualbox.org/)
+
+2. Download the 64-bit Ubuntu Desktop 12.04 LTS .iso CD image from
+ [http://www.ubuntu.com/](http://www.ubuntu.com/)
+
+3. Run VirtualBox and create a new virtual machine, using the Ubuntu .iso (see the [VirtualBox documentation](https://www.virtualbox.org/wiki/Documentation) for details). Create it with at least 2 gigabytes of memory and a disk that is at least 20 gigabytes big.
+
+4. Inside the running Ubuntu desktop, install:
+
+ sudo apt-get install debootstrap lxc ruby apache2 git apt-cacher-ng python-vm-builder
+
+5. Still inside Ubuntu, tell gitian-builder to use LXC, then follow the "Once you've got the right hardware and software" instructions above:
+
+ export USE_LXC=1
+ git clone git://github.com/bitcoin/bitcoin.git
+ ... etc
diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml
new file mode 100644
index 0000000000..0f7c5ad59e
--- /dev/null
+++ b/contrib/gitian-descriptors/gitian-linux.yml
@@ -0,0 +1,118 @@
+---
+name: "bitcoin-linux-0.11"
+enable_cache: true
+suites:
+- "precise"
+architectures:
+- "amd64"
+packages:
+- "g++-multilib"
+- "git-core"
+- "pkg-config"
+- "autoconf2.13"
+- "libtool"
+- "automake"
+- "faketime"
+- "bsdmainutils"
+- "binutils-gold"
+- "libstdc++6-4.6-pic"
+reference_datetime: "2015-06-01 00:00:00"
+remotes:
+- "url": "https://github.com/bitcoin/bitcoin.git"
+ "dir": "bitcoin"
+files: []
+script: |
+ WRAP_DIR=$HOME/wrapped
+ HOSTS="i686-pc-linux-gnu x86_64-unknown-linux-gnu"
+ CONFIGFLAGS="--enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++"
+ FAKETIME_HOST_PROGS=""
+ FAKETIME_PROGS="date ar ranlib nm strip"
+
+ export QT_RCC_TEST=1
+ export GZIP="-9n"
+ export TAR_OPTIONS="--mtime="$REFERENCE_DATE\\\ $REFERENCE_TIME""
+ export TZ="UTC"
+ export BUILD_DIR=`pwd`
+ mkdir -p ${WRAP_DIR}
+ if test -n "$GBUILD_CACHE_ENABLED"; then
+ export SOURCES_PATH=${GBUILD_COMMON_CACHE}
+ export BASE_CACHE=${GBUILD_PACKAGE_CACHE}
+ mkdir -p ${BASE_CACHE} ${SOURCES_PATH}
+ fi
+
+ # Create global faketime wrappers
+ for prog in ${FAKETIME_PROGS}; do
+ echo '#!/bin/bash' > ${WRAP_DIR}/${prog}
+ echo "REAL=\`which -a ${prog} | grep -v ${WRAP_DIR}/${prog} | head -1\`" >> ${WRAP_DIR}/${prog}
+ echo 'export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${prog}
+ echo "export FAKETIME=\"${REFERENCE_DATETIME}\"" >> ${WRAP_DIR}/${prog}
+ echo "\$REAL \$@" >> $WRAP_DIR/${prog}
+ chmod +x ${WRAP_DIR}/${prog}
+ done
+
+ # Create per-host faketime wrappers
+ for i in $HOSTS; do
+ for prog in ${FAKETIME_HOST_PROGS}; do
+ echo '#!/bin/bash' > ${WRAP_DIR}/${i}-${prog}
+ echo "REAL=\`which -a ${i}-${prog} | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog}
+ echo 'export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${i}-${prog}
+ echo "export FAKETIME=\"${REFERENCE_DATETIME}\"" >> ${WRAP_DIR}/${i}-${prog}
+ echo "\$REAL \$@" >> $WRAP_DIR/${i}-${prog}
+ chmod +x ${WRAP_DIR}/${i}-${prog}
+ done
+ done
+ export PATH=${WRAP_DIR}:${PATH}
+
+ cd bitcoin
+ BASEPREFIX=`pwd`/depends
+ # Build dependencies for each host
+ for i in $HOSTS; do
+ make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}"
+ done
+
+ # Ubuntu precise hack: Not an issue in later versions.
+ # Precise's libstdc++.a is non-pic. There's an optional libstdc++6-4.6-pic
+ # package which provides libstdc++_pic.a, but the linker can't find it.
+ # Symlink it to a path that will be included in our link-line so that the
+ # linker picks it up before the default libstdc++.a.
+ # This is only necessary for 64bit.
+ ln -s /usr/lib/gcc/x86_64-linux-gnu/4.6/libstdc++_pic.a ${BASEPREFIX}/x86_64-unknown-linux-gnu/lib/libstdc++.a
+
+ # Create the release tarball using (arbitrarily) the first host
+ ./autogen.sh
+ ./configure --prefix=${BASEPREFIX}/`echo "${HOSTS}" | awk '{print $1;}'`
+ make dist
+ SOURCEDIST=`echo bitcoin-*.tar.gz`
+ DISTNAME=`echo ${SOURCEDIST} | sed 's/.tar.*//'`
+ # Correct tar file order
+ mkdir -p temp
+ pushd temp
+ tar xf ../$SOURCEDIST
+ find bitcoin-* | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ../$SOURCEDIST
+ popd
+
+ ORIGPATH="$PATH"
+ # Extract the release tarball into a dir for each host and build
+ for i in ${HOSTS}; do
+ export PATH=${BASEPREFIX}/${i}/native/bin:${ORIGPATH}
+ mkdir -p distsrc-${i}
+ cd distsrc-${i}
+ INSTALLPATH=`pwd`/installed/${DISTNAME}
+ mkdir -p ${INSTALLPATH}
+ tar --strip-components=1 -xf ../$SOURCEDIST
+
+ ./configure --prefix=${BASEPREFIX}/${i} --bindir=${INSTALLPATH}/bin --includedir=${INSTALLPATH}/include --libdir=${INSTALLPATH}/lib --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS}
+ make ${MAKEOPTS}
+ make install-strip
+ cd installed
+ find . -name "lib*.la" -delete
+ find . -name "lib*.a" -delete
+ rm -rf ${DISTNAME}/lib/pkgconfig
+ find ${DISTNAME} | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}.tar.gz
+ cd ../../
+ done
+ mkdir -p $OUTDIR/src
+ mv $SOURCEDIST $OUTDIR/src
+ mv ${OUTDIR}/${DISTNAME}-x86_64-*.tar.gz ${OUTDIR}/${DISTNAME}-linux64.tar.gz
+ mv ${OUTDIR}/${DISTNAME}-i686-*.tar.gz ${OUTDIR}/${DISTNAME}-linux32.tar.gz
+
diff --git a/contrib/gitian-descriptors/gitian-osx-signer.yml b/contrib/gitian-descriptors/gitian-osx-signer.yml
new file mode 100644
index 0000000000..36d7b01264
--- /dev/null
+++ b/contrib/gitian-descriptors/gitian-osx-signer.yml
@@ -0,0 +1,38 @@
+---
+name: "bitcoin-dmg-signer"
+suites:
+- "precise"
+architectures:
+- "amd64"
+packages:
+- "libc6:i386"
+- "faketime"
+reference_datetime: "2015-06-01 00:00:00"
+remotes:
+- "url": "https://github.com/bitcoin/bitcoin-detached-sigs.git"
+ "dir": "signature"
+files:
+- "bitcoin-osx-unsigned.tar.gz"
+script: |
+ WRAP_DIR=$HOME/wrapped
+ mkdir -p ${WRAP_DIR}
+ export PATH=`pwd`:$PATH
+ FAKETIME_PROGS="dmg genisoimage"
+
+ # Create global faketime wrappers
+ for prog in ${FAKETIME_PROGS}; do
+ echo '#!/bin/bash' > ${WRAP_DIR}/${prog}
+ echo "REAL=\`which -a ${prog} | grep -v ${WRAP_DIR}/${prog} | head -1\`" >> ${WRAP_DIR}/${prog}
+ echo 'export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${prog}
+ echo "export FAKETIME=\"${REFERENCE_DATETIME}\"" >> ${WRAP_DIR}/${prog}
+ echo "\$REAL \$@" >> $WRAP_DIR/${prog}
+ chmod +x ${WRAP_DIR}/${prog}
+ done
+
+ UNSIGNED=bitcoin-osx-unsigned.tar.gz
+ SIGNED=bitcoin-osx-signed.dmg
+
+ tar -xf ${UNSIGNED}
+ ./detached-sig-apply.sh ${UNSIGNED} signature/osx
+ ${WRAP_DIR}/genisoimage -no-cache-inodes -D -l -probe -V "Bitcoin-Core" -no-pad -r -apple -o uncompressed.dmg signed-app
+ ${WRAP_DIR}/dmg dmg uncompressed.dmg ${OUTDIR}/${SIGNED}
diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml
new file mode 100644
index 0000000000..47eaf647c4
--- /dev/null
+++ b/contrib/gitian-descriptors/gitian-osx.yml
@@ -0,0 +1,134 @@
+---
+name: "bitcoin-osx-0.11"
+enable_cache: true
+suites:
+- "precise"
+architectures:
+- "amd64"
+packages:
+- "g++"
+- "git-core"
+- "pkg-config"
+- "autoconf2.13"
+- "libtool"
+- "automake"
+- "faketime"
+- "bsdmainutils"
+- "cmake"
+- "libcap-dev"
+- "libz-dev"
+- "libbz2-dev"
+reference_datetime: "2015-06-01 00:00:00"
+remotes:
+- "url": "https://github.com/bitcoin/bitcoin.git"
+ "dir": "bitcoin"
+files:
+- "MacOSX10.9.sdk.tar.gz"
+script: |
+ WRAP_DIR=$HOME/wrapped
+ HOSTS="x86_64-apple-darwin11"
+ CONFIGFLAGS="--enable-reduce-exports GENISOIMAGE=$WRAP_DIR/genisoimage"
+ FAKETIME_HOST_PROGS=""
+ FAKETIME_PROGS="ar ranlib date dmg genisoimage"
+
+ export QT_RCC_TEST=1
+ export GZIP="-9n"
+ export TAR_OPTIONS="--mtime="$REFERENCE_DATE\\\ $REFERENCE_TIME""
+ export TZ="UTC"
+ export BUILD_DIR=`pwd`
+ mkdir -p ${WRAP_DIR}
+ if test -n "$GBUILD_CACHE_ENABLED"; then
+ export SOURCES_PATH=${GBUILD_COMMON_CACHE}
+ export BASE_CACHE=${GBUILD_PACKAGE_CACHE}
+ mkdir -p ${BASE_CACHE} ${SOURCES_PATH}
+ fi
+
+ export ZERO_AR_DATE=1
+
+ # Create global faketime wrappers
+ for prog in ${FAKETIME_PROGS}; do
+ echo '#!/bin/bash' > ${WRAP_DIR}/${prog}
+ echo "REAL=\`which -a ${prog} | grep -v ${WRAP_DIR}/${prog} | head -1\`" >> ${WRAP_DIR}/${prog}
+ echo 'export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${prog}
+ echo "export FAKETIME=\"${REFERENCE_DATETIME}\"" >> ${WRAP_DIR}/${prog}
+ echo "\$REAL \$@" >> $WRAP_DIR/${prog}
+ chmod +x ${WRAP_DIR}/${prog}
+ done
+
+ # Create per-host faketime wrappers
+ for i in $HOSTS; do
+ for prog in ${FAKETIME_HOST_PROGS}; do
+ echo '#!/bin/bash' > ${WRAP_DIR}/${i}-${prog}
+ echo "REAL=\`which -a ${i}-${prog} | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog}
+ echo 'export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${i}-${prog}
+ echo "export FAKETIME=\"${REFERENCE_DATETIME}\"" >> ${WRAP_DIR}/${i}-${prog}
+ echo "\$REAL \$@" >> $WRAP_DIR/${i}-${prog}
+ chmod +x ${WRAP_DIR}/${i}-${prog}
+ done
+ done
+ export PATH=${WRAP_DIR}:${PATH}
+
+ cd bitcoin
+ BASEPREFIX=`pwd`/depends
+
+ mkdir -p ${BASEPREFIX}/SDKs
+ tar -C ${BASEPREFIX}/SDKs -xf ${BUILD_DIR}/MacOSX10.9.sdk.tar.gz
+
+ # Build dependencies for each host
+ for i in $HOSTS; do
+ make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}"
+ done
+
+ # Create the release tarball using (arbitrarily) the first host
+ ./autogen.sh
+ ./configure --prefix=${BASEPREFIX}/`echo "${HOSTS}" | awk '{print $1;}'`
+ make dist
+ SOURCEDIST=`echo bitcoin-*.tar.gz`
+ DISTNAME=`echo ${SOURCEDIST} | sed 's/.tar.*//'`
+
+ # Correct tar file order
+ mkdir -p temp
+ pushd temp
+ tar xf ../$SOURCEDIST
+ find bitcoin-* | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ../$SOURCEDIST
+ popd
+
+ ORIGPATH="$PATH"
+ # Extract the release tarball into a dir for each host and build
+ for i in ${HOSTS}; do
+ export PATH=${BASEPREFIX}/${i}/native/bin:${ORIGPATH}
+ mkdir -p distsrc-${i}
+ cd distsrc-${i}
+ INSTALLPATH=`pwd`/installed/${DISTNAME}
+ mkdir -p ${INSTALLPATH}
+ tar --strip-components=1 -xf ../$SOURCEDIST
+
+ ./configure --prefix=${BASEPREFIX}/${i} --bindir=${INSTALLPATH}/bin --includedir=${INSTALLPATH}/include --libdir=${INSTALLPATH}/lib --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS}
+ make ${MAKEOPTS}
+ make install-strip
+
+ make deploydir
+ mkdir -p unsigned-app-${i}
+ cp contrib/macdeploy/detached-sig-apply.sh unsigned-app-${i}
+ cp contrib/macdeploy/detached-sig-create.sh unsigned-app-${i}
+ cp ${BASEPREFIX}/${i}/native/bin/dmg ${BASEPREFIX}/${i}/native/bin/genisoimage unsigned-app-${i}
+ cp ${BASEPREFIX}/${i}/native/bin/${i}-codesign_allocate unsigned-app-${i}/codesign_allocate
+ cp ${BASEPREFIX}/${i}/native/bin/${i}-pagestuff unsigned-app-${i}/pagestuff
+ mv dist unsigned-app-${i}
+ pushd unsigned-app-${i}
+ find . | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-osx-unsigned.tar.gz
+ popd
+
+ make deploy
+ ${WRAP_DIR}/dmg dmg Bitcoin-Core.dmg ${OUTDIR}/${DISTNAME}-osx-unsigned.dmg
+
+ cd installed
+ find . -name "lib*.la" -delete
+ find . -name "lib*.a" -delete
+ rm -rf ${DISTNAME}/lib/pkgconfig
+ find ${DISTNAME} | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}.tar.gz
+ cd ../../
+ done
+ mkdir -p $OUTDIR/src
+ mv $SOURCEDIST $OUTDIR/src
+ mv ${OUTDIR}/${DISTNAME}-x86_64-*.tar.gz ${OUTDIR}/${DISTNAME}-osx64.tar.gz
diff --git a/contrib/gitian-descriptors/gitian-win-signer.yml b/contrib/gitian-descriptors/gitian-win-signer.yml
new file mode 100644
index 0000000000..2a73050e0e
--- /dev/null
+++ b/contrib/gitian-descriptors/gitian-win-signer.yml
@@ -0,0 +1,39 @@
+---
+name: "bitcoin-win-signer"
+suites:
+- "precise"
+architectures:
+- "amd64"
+packages:
+- "libssl-dev"
+- "autoconf"
+reference_datetime: "2015-06-01 00:00:00"
+remotes:
+- "url": "https://github.com/bitcoin/bitcoin-detached-sigs.git"
+ "dir": "signature"
+files:
+- "osslsigncode-1.7.1.tar.gz"
+- "osslsigncode-Backports-to-1.7.1.patch"
+- "bitcoin-win-unsigned.tar.gz"
+script: |
+ BUILD_DIR=`pwd`
+ SIGDIR=${BUILD_DIR}/signature/win
+ UNSIGNED_DIR=${BUILD_DIR}/unsigned
+
+ echo "f9a8cdb38b9c309326764ebc937cba1523a3a751a7ab05df3ecc99d18ae466c9 osslsigncode-1.7.1.tar.gz" | sha256sum -c
+ echo "a8c4e9cafba922f89de0df1f2152e7be286aba73f78505169bc351a7938dd911 osslsigncode-Backports-to-1.7.1.patch" | sha256sum -c
+
+ mkdir -p ${UNSIGNED_DIR}
+ tar -C ${UNSIGNED_DIR} -xf bitcoin-win-unsigned.tar.gz
+
+ tar xf osslsigncode-1.7.1.tar.gz
+ cd osslsigncode-1.7.1
+ patch -p1 < ${BUILD_DIR}/osslsigncode-Backports-to-1.7.1.patch
+
+ ./configure --without-gsf --without-curl --disable-dependency-tracking
+ make
+ find ${UNSIGNED_DIR} -name "*-unsigned.exe" | while read i; do
+ INFILE="`basename "${i}"`"
+ OUTFILE="`echo "${INFILE}" | sed s/-unsigned//`"
+ ./osslsigncode attach-signature -in "${i}" -out "${OUTDIR}/${OUTFILE}" -sigin "${SIGDIR}/${INFILE}.pem"
+ done
diff --git a/contrib/gitian-descriptors/gitian-win.yml b/contrib/gitian-descriptors/gitian-win.yml
new file mode 100644
index 0000000000..1ba200c8a2
--- /dev/null
+++ b/contrib/gitian-descriptors/gitian-win.yml
@@ -0,0 +1,118 @@
+---
+name: "bitcoin-win-0.11"
+enable_cache: true
+suites:
+- "precise"
+architectures:
+- "amd64"
+packages:
+- "g++"
+- "git-core"
+- "pkg-config"
+- "autoconf2.13"
+- "libtool"
+- "automake"
+- "faketime"
+- "bsdmainutils"
+- "mingw-w64"
+- "g++-mingw-w64"
+- "nsis"
+- "zip"
+reference_datetime: "2015-06-01 00:00:00"
+remotes:
+- "url": "https://github.com/bitcoin/bitcoin.git"
+ "dir": "bitcoin"
+files: []
+script: |
+ WRAP_DIR=$HOME/wrapped
+ HOSTS="x86_64-w64-mingw32 i686-w64-mingw32"
+ CONFIGFLAGS="--enable-reduce-exports"
+ FAKETIME_HOST_PROGS="g++ ar ranlib nm windres strip"
+ FAKETIME_PROGS="date makensis zip"
+
+ export QT_RCC_TEST=1
+ export GZIP="-9n"
+ export TAR_OPTIONS="--mtime="$REFERENCE_DATE\\\ $REFERENCE_TIME""
+ export TZ="UTC"
+ export BUILD_DIR=`pwd`
+ mkdir -p ${WRAP_DIR}
+ if test -n "$GBUILD_CACHE_ENABLED"; then
+ export SOURCES_PATH=${GBUILD_COMMON_CACHE}
+ export BASE_CACHE=${GBUILD_PACKAGE_CACHE}
+ mkdir -p ${BASE_CACHE} ${SOURCES_PATH}
+ fi
+
+ # Create global faketime wrappers
+ for prog in ${FAKETIME_PROGS}; do
+ echo '#!/bin/bash' > ${WRAP_DIR}/${prog}
+ echo "REAL=\`which -a ${prog} | grep -v ${WRAP_DIR}/${prog} | head -1\`" >> ${WRAP_DIR}/${prog}
+ echo 'export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${prog}
+ echo "export FAKETIME=\"${REFERENCE_DATETIME}\"" >> ${WRAP_DIR}/${prog}
+ echo "\$REAL \$@" >> $WRAP_DIR/${prog}
+ chmod +x ${WRAP_DIR}/${prog}
+ done
+
+ # Create per-host faketime wrappers
+ for i in $HOSTS; do
+ for prog in ${FAKETIME_HOST_PROGS}; do
+ echo '#!/bin/bash' > ${WRAP_DIR}/${i}-${prog}
+ echo "REAL=\`which -a ${i}-${prog} | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog}
+ echo 'export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${i}-${prog}
+ echo "export FAKETIME=\"${REFERENCE_DATETIME}\"" >> ${WRAP_DIR}/${i}-${prog}
+ echo "\$REAL \$@" >> $WRAP_DIR/${i}-${prog}
+ chmod +x ${WRAP_DIR}/${i}-${prog}
+ done
+ done
+ export PATH=${WRAP_DIR}:${PATH}
+
+ cd bitcoin
+ BASEPREFIX=`pwd`/depends
+ # Build dependencies for each host
+ for i in $HOSTS; do
+ make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}"
+ done
+
+ # Create the release tarball using (arbitrarily) the first host
+ ./autogen.sh
+ ./configure --prefix=${BASEPREFIX}/`echo "${HOSTS}" | awk '{print $1;}'`
+ make dist
+ SOURCEDIST=`echo bitcoin-*.tar.gz`
+ DISTNAME=`echo ${SOURCEDIST} | sed 's/.tar.*//'`
+
+ # Correct tar file order
+ mkdir -p temp
+ pushd temp
+ tar xf ../$SOURCEDIST
+ find bitcoin-* | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ../$SOURCEDIST
+ mkdir -p $OUTDIR/src
+ cp ../$SOURCEDIST $OUTDIR/src
+ popd
+
+ ORIGPATH="$PATH"
+ # Extract the release tarball into a dir for each host and build
+ for i in ${HOSTS}; do
+ export PATH=${BASEPREFIX}/${i}/native/bin:${ORIGPATH}
+ mkdir -p distsrc-${i}
+ cd distsrc-${i}
+ INSTALLPATH=`pwd`/installed/${DISTNAME}
+ mkdir -p ${INSTALLPATH}
+ tar --strip-components=1 -xf ../$SOURCEDIST
+
+ ./configure --prefix=${BASEPREFIX}/${i} --bindir=${INSTALLPATH}/bin --includedir=${INSTALLPATH}/include --libdir=${INSTALLPATH}/lib --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS}
+ make ${MAKEOPTS}
+ make deploy
+ make install-strip
+ cp -f bitcoin-*setup*.exe $OUTDIR/
+ cd installed
+ mv ${DISTNAME}/bin/*.dll ${DISTNAME}/lib/
+ find . -name "lib*.la" -delete
+ find . -name "lib*.a" -delete
+ rm -rf ${DISTNAME}/lib/pkgconfig
+ find ${DISTNAME} -type f | sort | zip -X@ ${OUTDIR}/${DISTNAME}-${i}.zip
+ cd ../..
+ done
+ cd $OUTDIR
+ rename 's/-setup\.exe$/-setup-unsigned.exe/' *-setup.exe
+ find . -name "*-setup-unsigned.exe" | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-win-unsigned.tar.gz
+ mv ${OUTDIR}/${DISTNAME}-x86_64-*.zip ${OUTDIR}/${DISTNAME}-win64.zip
+ mv ${OUTDIR}/${DISTNAME}-i686-*.zip ${OUTDIR}/${DISTNAME}-win32.zip
diff --git a/contrib/gitian-downloader/aschildbach-key.pgp b/contrib/gitian-downloader/aschildbach-key.pgp
new file mode 100644
index 0000000000..df06e19fa4
--- /dev/null
+++ b/contrib/gitian-downloader/aschildbach-key.pgp
Binary files differ
diff --git a/contrib/gitian-downloader/bluematt-key.pgp b/contrib/gitian-downloader/bluematt-key.pgp
new file mode 100644
index 0000000000..fb6d9eb284
--- /dev/null
+++ b/contrib/gitian-downloader/bluematt-key.pgp
Binary files differ
diff --git a/contrib/gitian-downloader/cfields-key.pgp b/contrib/gitian-downloader/cfields-key.pgp
new file mode 100644
index 0000000000..6b0bd240ba
--- /dev/null
+++ b/contrib/gitian-downloader/cfields-key.pgp
@@ -0,0 +1,52 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.12 (GNU/Linux)
+
+mQINBFOHTh4BEADdKsRvmNhX+B+bcPsgMkp8ztwJA5g/rmrOlHQpKOOf4P2tAr6w
+FmXCChWF9Iq3pDFQ0t0iq5rgisFPyrGVT/VToMmH+/PSLTyIdAlgkRYDMAPsMAFV
+MaADH4yiAgJ3cdXtysjaNQV5O25ypqq6/obUjZJD5Enn6b/UgHe2+7LTmTNsskOx
+5s/WPPht79EY1kM4JQfmDx68CsmqeSAlT6yeO3RQcLn/l46cfXiwzMO4h1hsZS1r
+pgciRp0EHK9uAjF2rjqt8v4SDxwyTnwfpBBulzvH9mBf+HRXWzoTMR4sC/oOZext
+hKAH/ex47BxN3HU3ftNhCK2c1xcU1UOGSjbf0RdbwuSCxxa7mktEDumvOxAk9EBB
++PDPv7jO1FBK3rsJdscYQIL0AiRyO49VfNLARa34OqUi8pOAxKBQ9plO02W1gp7a
+DVBPI05TZ46Y8dTR2Bc1raAgOyxnXM7jfiQG2gSULiKAJAI4HwOiodaiiHAxDaIo
+a3mtsmfN25TZUQuA0I0BvHbJvLRlVnyZm3XVOcwReKJpZJV4qRhd3XNrERZdz6ZK
+cAZnyC/X+Uzo4HfnVSsJk1GpIa4seYyrVCFfHMiAA6SkgAUFbV26KCOv4rNR2GlV
+l2fVhu1RKOEUJ8nRcEqf93SehRVYdI67LepIPgmIwi0KG4HhoTbIHDAKWQARAQAB
+tCtDb3J5IEZpZWxkcyA8Y2ZpZWxkc0BiaXRjb2luZm91bmRhdGlvbi5vcmc+iQI4
+BBMBAgAiBQJTh04eAhsDBgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAKCRAcJJH/
+6w73cBTiEADIGZSueBFmaOTJCgasKGguHns/n8P94EQBZr07rrgN99Rzp85WvDUN
+Qa72wj3GNcAffN7aZlIWv4g+fjyr9AzHekjI/7iwwSYIfjfTR/xRUW7czRfKAOrK
+iwpEzgv440i7PBvkS/AhNdUNkm+cJvaQUej/F2/O52qDLEpHuzvjAUUWlSeF9/oO
+AjM9dfC24L5k5cVwQvH9noxk3EyuE7BuiGE5a+kKiORrtxiHeUG6GYQxuqrPucLU
+fI67ETyXa0YSpYm5/O65BKMTMpmkMvv1JC2kqqsYTrO5p158CrKzq2xvpuG4ABsb
+9KwICUGW31Ndr6TXwQJFa1b7VK4G1g6M1DFkVTOLJnEyOwgYxsXrV5QFpzpAOAji
+6KcxNGeow1avAFYbqjjLgu9UNuq6b8du13hjkQxVs2NAP1Kd/u2ADwxQHMhZGVEC
+9LIcLVSP9ShY6fR8m6fwSlJfpiV81uLNVD8KIyvp+pYTQ/FnxoPhPIwalYquBZKi
+0u38igW75IzZ0fYvJgTumE/8ofSVkutVtrQb21eJclVrJGMNweTlJcJhAWdKkjDC
+e6mSj8GItKV1ef+eusXSzs/wPyTaqgkELvvAOZdwUq3kobQErE5HOuPEOvcwuY96
+DcxLexirCGW5wCUq7Db0c0dUjQwzzb5OTW2jdnPVR0qxi29TnOJ2aLkCDQRTh04e
+ARAAuJKpI6NTCQrjEqe9AYywN8676+fPS5bqXkyb/iub6MXeQdwpH0K42lXAaYMq
+ow/0aLlvGWCHuJJGozoOWpTzQ+VPbhpdARoLCop5fYTpy8Q17ubLeeODDtr6jtDN
+lmg+9PBIErIVUnUS2wNZuJRVsfwlLaU3T2v8kQnQ6AEbl/QwyWW9nB8rAWBu6Hvs
+VdtcBmtHSr9xAGBGfW6rSVhTitikR4lWJPdNJxI3pLaswpLIUIQ1rssKO4glljcp
+C6nhMvRkDLvDFvDP9QnmwY/A4ch5S6ANPrhOjQuu9njjQ+/ImrJTjAXqHwg5KdTc
+NKxufgvi9elOQ422o0No3yKdRoRA4kdcUmqA9gNZDyX0ZTd17aNqc42Zt3aYLJ11
+bLZZp0qnfhkmhbsBZZtaLNkuF+RGPWysxY7KPMm+nHn6f3Wpr18E+T02wi02r4nS
+HOQI+gppDqy3Vq3ZZNoUZynctiLZVHkqi+WYXqfD2tEn8UJKpht7jrZlNgkHFgT7
+T0/U4+JmaQ/HltE+IexAIH0GP0Jt6hmRoZimdoy8Q8NY5t/fn9CQNJm5InrHvooN
+aFmZMvzGTGiTqBqnA/7k9FCUEG98LK11MsIssY8YE/F6HD69R3ISyRvhUbpFvhD8
+c6zOkEKngTWvyRevrDrDz2yoZ1+T1X350+92rbEc/8WyutcAEQEAAYkCHwQYAQIA
+CQUCU4dOHgIbDAAKCRAcJJH/6w73cAakEACv4EUEjtFjqnGB0Lru5FKs1obWcf37
+c4a5yYvOw58dkEZ9hsq34qWGLT128n6R24KEG+3O4CbplAD5Kt2eAPracbPHMAn8
+TGmC+KjiGlBR5xCY9dD0fn5EbRWOa+Fdcj1DpneaqMl9vLnBbqGp7pa/MwSOc+FB
+0Ms2rcGJJMNHgITfP22eCf6pvf/xq7kKbUJ3Kjqdc2hWlRMjC/OOeITdrgycfDk/
+AOzLNqk5q7bYOxna6rWDLGSkCATyQKaBTVK7wRd1VrIhI4vfFqy+BWYXyXJ0pxjS
+eaCDwbWHX/KW+0qLsmHxFMAyHJPjs8LEwK/DRbmWhe1HzPcBKmpyjqlkuxPjAdSl
+hP4+IBvVNLf2Kh3uFHehk9A6oCYZGe3lLfQnOxIantXF7IROTmiZZsb+08w6cIXE
++r6kWG6vP2aCVtzYNfY+2p5xfg3yMxcxENJki1WSCOq6WVf9IWFzSJu+0+eazD3L
+3QpZoSX5VvT6x05C0Ay1ert0Q5MyF84Eh8mDqL4PhpWtQhZMp8SG4jqFVgrhM4sl
+vWGYXGns4tbnNPiiksjBD8TTvG3+mt48sNJIpHThjdWJSZjllYG7jV8oi7HrX8M2
+LOwWWLYxHkqi9wpmrWHSmniex6ABozcqrb+EgSMnHuSd7glmOJxHToJIudJbKG5D
+MrD0ofsytfy1LQ==
+=DE4h
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/contrib/gitian-downloader/devrandom-key.pgp b/contrib/gitian-downloader/devrandom-key.pgp
new file mode 100644
index 0000000000..71898127ba
--- /dev/null
+++ b/contrib/gitian-downloader/devrandom-key.pgp
Binary files differ
diff --git a/contrib/gitian-downloader/fanquake-key.pgp b/contrib/gitian-downloader/fanquake-key.pgp
new file mode 100644
index 0000000000..9c03ff4522
--- /dev/null
+++ b/contrib/gitian-downloader/fanquake-key.pgp
@@ -0,0 +1,63 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG/MacGPG2 v2.0.26
+
+mQINBFFlV7oBEAC3dRAS7gSWQ1fV4JySD0HMBOtY+Y2oCX8vEuTI4atGcxbwXr4/
+OElRYhDK6Zirk8rMoKPxmr8OVek5LNnY3gcDffco6NXmZ+wTstQm6oqUxFfgzznG
+X/ExEVuCqiaPAwdWSKn9tC1GuOqRFcD+p2zmxw5mNH5XdsqaPSEGsKESY1IK+dMv
+K+YUrfrtexZyb66wCtupYziEeag6iEK/i2x2wewOji6IvtI+wB5FO+YMXw+LKucw
+PoHUOxjoz6YX3s04UxFaZo4R8x6J9XnJBSB2E5kfsSAzz3xR+zuapXY6H6mo/grq
+nr3c6ACcbAHnMWwQLYvWzde6iwswhyl0whebsajJH7Rd3G4c1U3L/oj4RwUFmZYU
+5Prs+Q5PepKAJfBeWCXZtUY2BNFCFj7b2H2NXYFR92Oc2GtoHAYACNeP070I9d3m
+IeuYhOrOckkunwaijUczq4rb3n3Vaq6YrdwZIzs8fALwc9Th98jj2dCUq0fljpSh
+UQFnPG83UsNkeWzUSgw+lBeEQqgOqUQQ293MbgRg0mJ8q677Iv+WaFqPKZzXxkwT
+QCCXhjcBmUKgXIHLFcbfmkR8pCcCToWXBD8CU441cBsootDD7SanPHbpcwZjt74x
+uLrVoCIyaju0T1jSrsPnm2A/8VkWLSCh1WRAlbjvMr7DwizGnRtzTiB6HQARAQAB
+tC9NaWNoYWVsIEZvcmQgKGJpdGNvaW4tb3RjKSA8ZmFucXVha2VAZ21haWwuY29t
+PokCNwQTAQoAIQUCUWVXugIbLwULCQgHAwUVCgkICwUWAgMBAAIeAQIXgAAKCRCU
+TTX5rD23agJgEAC0ouDjufjCMHL4DkaVkOnFbHzP+nR2Mq7pcjdiPNIt9tj8B6cI
+PRh/E+tt2iEJJ4lzlfj0uEqjqexmSBaMgY+pFb6ESg42EPQjRQ95oBoyZfp+uL/0
+KC3+Hh+EgmZGIFPZy2HneVfusiBUz2/YTOoqFkzmHalJe9Yvl2+dO0SUC7i6TUdJ
++ugSr/91hkjQC52LXgHzurH4zOz7ZjzRtZgUIG3oOx8mtEDf46eJ0IUsr+tWJqOp
+ce5xFh6nkKfS92B7YjGJ4YrkBHC7F9vmbrtIeuWiaxGzVqhHFmLvQe+4xyOpRgHM
+kcyD5uJNmSMO9gT3udut4hd0yUKg5rdqaUzqsvv19eNL/pZ7aBK2aDAK/yAi1T7X
+/nrhBJAU49zg1JRS6atRnhKSyd7wRSwVPJAXfVuelHsUgenSdLmSBxRha+9mL6Lb
+bLK/Dij/0r2fyhBJx4pV6V1n4BpHjv5ivkpgCvOupx8wx3PIxZq/rx+hK+ZBe2EQ
+7vq8rmLfBkSavHWyNxXEKWQed+mFS3d+Qsoy90bi7gQygIYNZOIBYwsy+qjCZ3om
+LwkzRjypH23ps7WmiaoenOaCjRYooNL4qtQwNVaDGYwvbMnXJ8Vb4/2j/Riz7+Ui
+BBVww+Wd72Fml/OFPDFep6HG/PuwFB9m5hmfSzrA01TIdjcWljtTDneufbkCDQRR
+ZVe6ARAAvi1IAxn9xKQCCqhsoKOiXNbpnmf6lYnoEwGtgI+0a0YQwtzm39P5T8P0
+esZ65/Re6jCCHLc23/urFPfW9VfrKPmNJncyzlx7OopJ7G1MWdRLEUzwqSaglC6x
+Zb4r1xR6eq2lBX6CAa5Q+AuAqkoGCEiYBpTyKij4sXE0c+Y9nIDIZhru7EnZvpL3
+SQvxzFryQLbWCGri0x9GKXZ2ZcDM7jRi/P+iX6yX6sVvOvyKz6NW2BI5OmpI1JbJ
+3fIXt/R6Wl2xpAFL/pxtYTYbfL6277HWtLDTqIkkRFKh64JdkH8n4G4m6VNUtGEu
+qP3SxtyShauxY44WzR0YX4rag6tU2Hks6h1JmyF8aQTBAkdP7UrQ0oxZ8f+iG9n6
+3GtTxgw2NyrqVMx3kBLm8DipyslbA2wCeZLrW6Co0j3pebJsDrMP/3zcmbJqRSLq
+qnkcxA4gn5j/N0oe8t26Y2WjovndhoR0QQxw8D/BKoMXbl0lvvRAtcnWtyG0COut
+AGB2PUbGdAX2Ky+uYKrG4uhu1edfV8JZVvB7NIQGzM2P8F9PrDRz7EtG6z7ky/pq
+HQwRbqwLWGs4QpQmHZchFmXH7pHmLC8i29W+xYhdeUstvx7oESbunICGrPjJOShJ
+G4191Zg0m/M6jeWV/v+piUXe3YVrgs42UWFusm5ZIduPUfgqUtkAEQEAAYkEPgQY
+AQoACQUCUWVXugIbLgIpCRCUTTX5rD23asFdIAQZAQoABgUCUWVXugAKCRAu659c
+wJUmwaduEACCiiRpBeKF5fSaM0cTb97hAHVQJL9Wk3xvA49YuROsSwtCzq9v+js5
+f/fE+QV/dIQUNwifEPQk8MqUVKpe1lIXwRp23GinzDAnOhfWnECqrMdR0dP99D49
+Zb7Dd4LDvP9c0mYtnX/78qQilxWmXhzDXcunnPsfCqsrduk9hMwkjmIrWFeSWSAg
+BEJDuZ4WLuqjni1udth0iZtZYrDaDgX/RWcTFW8QCc5hLsCRcInAxb75AWfWq6i/
+s3Ibg5tGm4+UfqGbFPuNyy6ow3ggqkovBp6ABMxe8dAYVXSmM2tKWZXBb3L6eho8
+QKKzyoezqpbQ2YUaYZ8XAdLuumXCtAHKP3/DI1JBefE0mxi1CXjdLK9sE5OO5KNt
+FXR8Dnot5C4BHrcaF6Iq2sqbhPxnhcDrEwv2mUgruD7n04LKIztAG0A35rcu6A2i
+IUq/PsXjS/5rX/p4CeYvnTTspXkhXgkvfhWz1cISXyfcNTWBKwOsLW4lY8bi05cv
+4Axl88tTg2dNYXIxSK7Jtu1YCEsZ8uaT3AAiTp1sKAOcRX8hIOTmPPxMxbIm8yg1
+jl71ovsV5rAyuVTUouFnljXyuLWXLotUOkmC6DjJUuRaxzt23/eByJ45x94T/A2U
+iT1oU+voigQGARrDkApXlgSI4oekg3Zgq57y6toV9F7o9A1PMtBq3AvDD/0as1K0
+wCRZIXinSwW2F6tFnVV+z+vvE0i54yHaskkuJYZRSQ/yJR1VgmW/BtAr7ooXF7l+
+9g7XOH7D8T28h+m4ABLN5ZDOxfTMZuV5Y4MnELh4dlBIfKGG2kjmW8+y/PUqMMGE
+BYRmGOD1qtWvFYoZ2ss5yrlvfenRRhQbIYSRz/YiT8OTogaNcYNpArUwT4z+05af
+kdxx0AaqauHqKRo/XTO5GIZQ6NbtPH6G++2Ie+oP8AyBWEpL3rvjZpzn7jxTBXMc
+MOMmhnb0Go4hD+BSphgDTZOgMLOLcorjb1Ct2VnajxPZD0aTB13SCgZjJhs9j3on
+EoI3gTHkRgiBjMBNtw7iaAumIRgrDwGzyuIL6bbyfDnbE02zxCqkYP6P0u48FGLs
+E4U60GrYSlFxa1MexF+HIPgqWsTOv4D2zXEJYvm1XEu1VOGQUkw7J5RFTDxHgkbh
+qvmkZ492iW2IC4L9hSdSqiZ5LhD2JwpgrMt8vrCzVitkjYQnXJ6WbWYfCybPsmLb
+mfQ03i9E+a50UC2SGDf8e3oxImAbbXLP/LyI7oczCxyb0EzcQlIIOtBgl3gI6KAh
+PTRQGeHCzIOSgUf7B0ihY7qiDeR1OshvTY0wdykdS0c+hzwuS5TZvfY4YM7Tssvt
+XwbdK0Zpx/oDtRHpuDMGKJBV2LWAZYkEbFsmtg==
+=3o2I
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/contrib/gitian-downloader/gavinandresen-key.pgp b/contrib/gitian-downloader/gavinandresen-key.pgp
new file mode 100644
index 0000000000..f81f44e874
--- /dev/null
+++ b/contrib/gitian-downloader/gavinandresen-key.pgp
Binary files differ
diff --git a/contrib/gitian-downloader/jonasschnelli-key.pgp b/contrib/gitian-downloader/jonasschnelli-key.pgp
new file mode 100644
index 0000000000..fe44c0fbd4
--- /dev/null
+++ b/contrib/gitian-downloader/jonasschnelli-key.pgp
Binary files differ
diff --git a/contrib/gitian-downloader/laanwj-key.pgp b/contrib/gitian-downloader/laanwj-key.pgp
new file mode 100644
index 0000000000..559295109d
--- /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 0000000000..4c03779526
--- /dev/null
+++ b/contrib/gitian-downloader/linux-download-config
@@ -0,0 +1,42 @@
+---
+name: bitcoin
+urls:
+- http://bitcoin.org/bitcoin-latest-linux-gitian.zip
+rss:
+- url:
+ xpath: //item/link/text()
+ pattern: bitcoin-\d+.\d+.\d+-linux-gitian.zip
+signers:
+ 0A82509767C7D4A5D14DA2301AE1D35043E08E54:
+ name: BlueMatt
+ key: bluematt
+ BF6273FAEF7CC0BA1F562E50989F6B3048A116B5:
+ name: Devrandom
+ key: devrandom
+ E463A93F5F3117EEDE6C7316BD02942421F4889F:
+ name: Luke-Jr
+ key: luke-jr
+ D762373D24904A3E42F33B08B9A408E71DAAC974:
+ name: "Pieter Wuille"
+ key: sipa
+ 77E72E69DA7EE0A148C06B21B34821D4944DE5F7:
+ name: tcatm
+ key: tcatm
+ 01CDF4627A3B88AAE4A571C87588242FBE38D3A8:
+ name: "Gavin Andresen"
+ key: gavinandresen
+ 71A3B16735405025D447E8F274810B012346C9A6:
+ name: "Wladimir J. van der Laan"
+ key: laanwj
+ AEC1884398647C47413C1C3FB1179EB7347DC10D:
+ name: "Warren Togami"
+ key: wtogami
+ 9692B91BBF0E8D34DFD33B1882C5C009628ECF0C:
+ name: michagogo
+ key: michagogo
+ E944AE667CF960B1004BC32FCA662BE18B877A60:
+ name: "Andreas Schildbach"
+ key: aschildbach
+ C060A6635913D98A3587D7DB1C2491FFEB0EF770:
+ name: "Cory Fields"
+ key: "cfields"
diff --git a/contrib/gitian-downloader/luke-jr-key.pgp b/contrib/gitian-downloader/luke-jr-key.pgp
new file mode 100644
index 0000000000..4406e6d5be
--- /dev/null
+++ b/contrib/gitian-downloader/luke-jr-key.pgp
Binary files differ
diff --git a/contrib/gitian-downloader/michagogo-key.pgp b/contrib/gitian-downloader/michagogo-key.pgp
new file mode 100644
index 0000000000..47bc404554
--- /dev/null
+++ b/contrib/gitian-downloader/michagogo-key.pgp
@@ -0,0 +1,59 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.12 (GNU/Linux)
+
+mQENBFGeqJ4BCADb7SI3/+q93gIvN0AGRg9Mtz73OLIOzCHeeoyn+tp7JcYNzxkQ
+9lfeXiEfn72Sh8gHkLtLIqr7HlIMo8DxSS8JPRVjlJGkNyAW4SeEwN2wNa5OV8k0
+N4jBa9a1csFyCyrEkPKvkUpBkQDvNXjNxyEhHwyZqPanKxy6NXIHOJji8ObOMQXI
+T9HwJrpjRth3u4uKG968JBTEyAXAmkt0Zidl1Ykgzcedk4mJSE9uZCW8DjSv2wML
+XcQz8+dYsoskT3KRdkowLHxAfj1BNyNc1+rKLghliM5vSQWi+Lbhi1Bxh4sY1UwA
+lKnAGqrnAGyIvCtkwTq5QI6ufF2ZY44bvVgpABEBAAG0IU1pY2hhZ29nbyA8bWlj
+aGFnb2dvQHNlcnZlci5mYWtlPokBOAQTAQIAIgUCUZ6ongIbAwYLCQgHAwIGFQgC
+CQoLBBYCAwECHgECF4AACgkQgsXACWKOzwzMUAgAuqUmK10xE5C3lUym2f72z0t6
+a2NM5Wfjr9//Y1/okC36C5XAMEtN2UwckPzzJ5p5D5y5yzwfZq5Jd8Py29VQIMsV
+7FbC1a0H3D+bCyX+JJ6FAmUbnWOQ/+mydYc74RvD8iwjePNT6kziZNv6dMGctJTl
+0alwjtQYgyGkeYKnIxbcyjHX/IawLUrunb/6mSKun87T8+NM/omfFCTc3l8TakpM
+0wyNYRiUkIfUBvB8sDUU3A80qKN/hqRKvlFu3+/kMiAc9ZYQrbmsB+sYWdmM+4zw
+8NBw3yuYzWyPuoa4PR5ZmS9F11WLMR5vTRCdLudAqYsWu3LtV6vAIvlOUa2LMLRg
+TWljaGFnb2dvIChSZWdpc3RlcmVkIG5pY2sgbWljaGFnb2dvIG9uIGZyZWVub2Rl
+IGFzIG9mIE9jdG9iZXIgMTIsIDIwMTMpIDxtaWNoYWdvZ29Ac2VydmVyLmZha2U+
+iQE4BBMBAgAiBQJSWarzAhsDBgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAKCRCC
+xcAJYo7PDA7nB/91wAiaMlU5nHLUu0anhNQbGvUdFgKK1zO90S5KzUdJcY438jcS
+UJW1az8l9U9JBRIfPRYVhz/Z1TAJ+dCzD7D8BXHFeGEr0zNOh87ly9aB5du7dpN2
+oSBD6wLcJpqxt4h+XjSS2CX98/2ZIJxXENE2KySaTXP39Xl3eNwvJTUBA4XlcMey
+J8KMp/IERli4H0O7vRyLgu3yYpUArTqAonzG1g2lfB35PQJfeInrRSniQ336otnZ
+A8qwJ63kfUtWVDRz0g1fnvtiLGPivDJaI5hyIaUeJPaXU1+sg7YNroDu60o2NGZh
+F+0IjHlvRfzzA+F9Vw38rpSqR3BmCdjf6Sv3iQEcBBABAgAGBQJSWa9/AAoJEH+r
+EUJn5PoE/hgH/1T2dAthVucA/hzY0nl4SMjbg+dzNlYBq00Qwx8DRKVjk5et8+kY
+oPI3DGILcr+ELnxNekeMv9WQBBtJanUh1K5ohZ6ohoR7lG18LXf5HCdspflB5Me6
+LMA6iMryEP6gIs9GFuoGe2YQavm58YrkqhcPu34dGN7kdurfEXLvDfVlh5ZbKCsP
+Gyd7Pbz04SpqykgK1udiTsLVjc70Xhv+jAMqeaCugDX6TLEwjVmZH/xsyKk2Uh3V
+Oib5FXADAtKH+vSqqhFpXrw7R/NaBzvCbas8l61DFHiUg1/bo8vsV8MtGcyZmzXJ
+C5Gm0njtGOil/g7JF9siUrpxs9Yyt/h+T2W0W01pY2hhZ29nbyAoVXNlciBhY2Nv
+dW50IG1pY2hhZ29nbyBvbiBHaXRodWIgYXMgb2YgT2N0b2JlciAxMiwgMjAxMykg
+PG1pY2hhZ29nb0BzZXJ2ZXIuZmFrZT6JATcEEwECACIFAlJZqxkCGwMGCwkIBwMC
+BhUIAgkKCwQWAgMBAh4BAheAAAoJEILFwAlijs8M+1AH+IU78ARblqTnJeSl0iWH
+mEsg4IBK30Q6/exDAcqOEm1Yc171uw2WnGmIvPYOQqxrRTvj3LoQ816dU6jrj6vY
+s+XX0R2hxy7ILh17D/3UKnHcddu7rmc7pNEqZeBXaMughqQaPOWkAIe52+qK5tsl
+sWllzTYE4jo29uZ3dAtDcKEJjBo/pIXnu1GOslE1+V4X1H9WDlwrS/JXHzyDQAjt
+maPR+3gNesDanhrRmrnT3ZXW2ZVd3vGBibhia8PWUhU1uwOH23ySWXncgsHH0Zad
+UMjd4w3YliZP/mLn2ghAxHB70IO7lgAgN3HYZeFoufP3pcK440A+CezfQiRcjHl/
+oIkBHAQQAQIABgUCUlmvfwAKCRB/qxFCZ+T6BOq9CACItsrUZPKGeWSTkMHknMrV
+K5vxIXJVCBb+Tppc0Q/J5p4EkW/RFhTwIP2zw8NLDKMh5oO9md4LXhvfIZkqQJFo
+6ZtLa3Vf+Kj7uyxezBo4QHA+G7tDsRGaMKVrEMiyLCwS1+hg9VaNzsf7zmQW7mYE
+vTLMHp3cVaSU7Mh2Dl8rnAaM/DpTUZQwZ+32Qrb/Z4HSa4f278iqoFpjEbBE2KCr
+vT5yEVvpCZ4lwSgA2a+uTlRTvVV6NA/kpsxU64tmhuEOjy+ToDqJ8wv4mqvWZxMv
+C6OhfVaXBy3U9gG8aQV0ffXGs+TbCtv8ApHd6E1/AVk0oyZGJaBVrEl688bBIWd/
+uQENBFGeqJ4BCADFmgR7oEGkFFB5qXnuNYFq1nUGDAh0dLNtAD3J6EMxUZEXdmp+
+DQHJw6/eDRQaG9EbjNZheycbVUoI8K2Y/Z268HQueGuIEIJv6cZYXoXdWCbDD4fn
+HMNUX2wNlpDqWxb7PNUEtfU9hI3gmHGlr5OiEh3iV06uiZg4n2rbWPbj45m5LJzv
+wpCrUA+pLcl9Xjw2cajaSTjdXHk9gvXTCo6s2ZS3/3Q4l+xuzZp1MGNzPQHASMKs
+wecSJKkYg6W8I5WsVlPd9a8oQCc/Nfz7BPw31MRVR/SF5FAMqaXx5uLwghVdHB2i
+cLURsOtJlCfP8W06gB7yS+MH45Jq/oxBRiJBABEBAAGJAR8EGAECAAkFAlGeqJ4C
+GwwACgkQgsXACWKOzwwT4wgAy6ICcnBZ9l2jSu+ldy57F6jf5kpKZgB9NV8V2mMA
+NeY1wMQ4VTVpU4t3s4E2LYtGNJNkPQVHbt1Pf4dGPasvMPaHMamgwgyqgYixqs0x
+D5PdKzVrfnjwTTr/ZAFdccSPmvy5/hbY0geQ/+mzdbL07+xaT58JIoG5nySDKhmC
+VeOvhDZtXMVAhEWBDPEgh/H9sEuBgMgZrzfE1j3q802qiXeQs6WtadWlQ1RN9Iq1
+ZzIi6u9/BifEIRI0pO/WwKOZdXLTemFUoakoe7uT3A74N96t0G9LZVihYbEoO+Pc
+5IaHPBV5VLeR3TB1LnnjHVf/Fwi8cnGy50kNWjcbMyEDag==
+=jyQ4
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/contrib/gitian-downloader/sipa-key.pgp b/contrib/gitian-downloader/sipa-key.pgp
new file mode 100644
index 0000000000..ffa09bb4ad
--- /dev/null
+++ b/contrib/gitian-downloader/sipa-key.pgp
Binary files differ
diff --git a/contrib/gitian-downloader/tcatm-key.pgp b/contrib/gitian-downloader/tcatm-key.pgp
new file mode 100644
index 0000000000..baaec76b8c
--- /dev/null
+++ b/contrib/gitian-downloader/tcatm-key.pgp
Binary files differ
diff --git a/contrib/gitian-downloader/win32-download-config b/contrib/gitian-downloader/win32-download-config
new file mode 100644
index 0000000000..083bce5de8
--- /dev/null
+++ b/contrib/gitian-downloader/win32-download-config
@@ -0,0 +1,42 @@
+---
+name: bitcoin
+urls:
+- http://bitcoin.org/bitcoin-latest-win32-gitian.zip
+rss:
+- url:
+ xpath: //item/link/text()
+ pattern: bitcoin-\d+.\d+.\d+-win32-gitian.zip
+signers:
+ 0A82509767C7D4A5D14DA2301AE1D35043E08E54:
+ name: BlueMatt
+ key: bluematt
+ BF6273FAEF7CC0BA1F562E50989F6B3048A116B5:
+ name: Devrandom
+ key: devrandom
+ E463A93F5F3117EEDE6C7316BD02942421F4889F:
+ name: Luke-Jr
+ key: luke-jr
+ D762373D24904A3E42F33B08B9A408E71DAAC974:
+ name: "Pieter Wuille"
+ key: sipa
+ 77E72E69DA7EE0A148C06B21B34821D4944DE5F7:
+ name: tcatm
+ key: tcatm
+ 01CDF4627A3B88AAE4A571C87588242FBE38D3A8:
+ name: "Gavin Andresen"
+ key: gavinandresen
+ 71A3B16735405025D447E8F274810B012346C9A6:
+ name: "Wladimir J. van der Laan"
+ key: laanwj
+ AEC1884398647C47413C1C3FB1179EB7347DC10D:
+ name: "Warren Togami"
+ key: wtogami
+ 9692B91BBF0E8D34DFD33B1882C5C009628ECF0C:
+ name: michagogo
+ key: michagogo
+ E944AE667CF960B1004BC32FCA662BE18B877A60:
+ name: "Andreas Schildbach"
+ key: aschildbach
+ C060A6635913D98A3587D7DB1C2491FFEB0EF770:
+ name: "Cory Fields"
+ key: "cfields"
diff --git a/contrib/gitian-downloader/wtogami-key.pgp b/contrib/gitian-downloader/wtogami-key.pgp
new file mode 100644
index 0000000000..e0f6c4c5fd
--- /dev/null
+++ b/contrib/gitian-downloader/wtogami-key.pgp
@@ -0,0 +1,131 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.13 (GNU/Linux)
+
+mQQNBFHOzpUBIADYwJ1vC5npnYCthOtiSna/siS6tdol0OXc82QRgK4Q2YeFCkpN
+Fw/T5YK34BLVGWDHPoafG2+r1nXIuMZnJIiGw6QVOL2sP9f7PrMmzck5KJPHD14Y
+GRd9BPkhmt3dXzOCjhig7jI6hKEYayfJNUNs9nlZEvl4QWIBMmk+IyqQz3f1HMfl
+/GkFDShBYF8Ny7Ktlx7AaXymajm4DCrTkbj5V2ZDqJgyQM549EoPSwXBQYrEjye3
+g2viC8rUFRFWFjdnx7jFEb1uhx71YGuqiLxKihUW9pbSNK2cLweFazHSVmh+B/pz
+fxHfUn+ijLSIAnprTmc/rq89un/iiPt0O/mspcCZ6hE5pFIyX+SC+9PrGz+bFSmw
+PkMOZzG489G8k4t/uZsit6helkl0emg6JiXLTmS/oTuT7B9Z9/MeEhOXFcxUb0fr
+2aZkEmH5d1oxSBis3D5nylmNJXOUSCpJAZ8E5Sr/5FbF9IPR+NSzosVacqCx5Dxj
+vJ7HpZKn6pJfmwrghVXQv04NRTcxbHNmwd98cofBtWX8yBO8M2M+jZrU+BVDUbb/
+A1oAyIbUUswBP768Oh11bELhCly774VwBqTojm2yodLGSyysx4zoa6qL7myfor0m
+a+K29y8WH9XGmKGMdUOg+q9z+ODky9aToGvEo2eVhKIlJsk0aFAGy/8awy6qRIIj
+UqLMq6XoFcYlE7SmnFUDDDPlBK/NkFFqySpFhKNRyt69Ea9kYXOxDnf/EnBwHn8m
+PiFQpeZqgnmhyj8Nk1SSQBgUi07NyXdQ/WIYpWmqqqfHRVQgSE9C1920T1zg/E97
+n5yYjI/gQQwq9wikkJmog6Ny7MSiwIU4LYV0pTUdI4//EJMId2FH8YEUfvG5ds+F
+H/o/D4CAJ86KjspizfH8jEjhn0Rm/OtrxLz1rwA1gtF//P3TYNWw5qruL4stP3Rx
+9Gve8Bm7oCBU73UT2ZJomEsWE3oqXinLRl3YCsjGDg/d3ySD6i0/BBROLIeXkh3M
+M1CNCqREDGLA0vxQi1o7Zi7ZA4gWPSzvi/8KtSzY1iAQODxWUmOICRP7KQODWJmt
+roTqhKgZ39wlR6eqkO8ZfAvRYsjvkL+EZFbbKbHxVJLhKchd2qHS+/Q3ov4SFzWY
+/cE0ChOPDM587Jkps2bynKQAzQ6810FXmJc0ztrPeD3PEbuyY4KNJV8HGViRDJXi
+wvs8eqfvTDGDPl4aLYVCKO9VqZ2OJvqhRhh71LQ2xRrX1LGnYLnUGCMuEQYKvMcI
+TSssM/VAfeWAPJDklD0lVNJ7d9Z5ugvJHFc01SaaB47Aod2SPWp5DeiY4A8dcy2w
+7f4Wx6FcdP1RXqaRZKCapBooN04vsvGllCshABEBAAG0KFdhcnJlbiBUb2dhbWkg
+KDIwMTMpIDx3dG9nYW1pQGdtYWlsLmNvbT6JBDgEEwECACIFAlHOzpUCGwMGCwkI
+BwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJELEXnrc0fcENY4Ef/23L9iC/39ekJ8Is
+1IZdCoDD7/DgVaZqydDcy/ha9uaDFY4MQ0h9RZYo1axVBth/Yxzh1XnvitW8HFKn
+DXn5wJI++KWpdLMUsTrc2iWsjAGgicmN5bkQvfTnRwn2pF17EUUEhZ8YyE3qMSVD
+rDBECLAswT4Oiq9r9yw3VCFsRaxz5bhk9AAzWjam4H7mAfaEAOUvuX221v+KGSDM
+UsGAAe+GjMPL8KnGgEbISlSUF1Ubcw3EChcqjf3BID2gMLkAnGAoxlCZSYievytg
+71mcHyIf9yF861QrGcrCh6/objtRdt4IDUVwo9wapunRmYCdZux4ApD0Hit8nAsm
+QtxftSK6FWBTOCIRoOQTjwE8qj9GYTIbUFppX66Dzh00td5NKkWz0PVze7YSk2hC
+KCVBYyUYHgkQYVlYLZw7dBrXSXv7ph95vc93RDS031cU7tPOrthqnMmhtg1WAwzH
+xc2v3az9Gsw1RyxBAOVpkB0AFODiEiVg46xqmxaBPXfQOg/buZA2l4gK4U/pVUZH
+72lle2CbBw6FoSx40Y3GYZWB2uEdXBTNLlhX7q2Jvo8WdeTxEv5ACZsjI7K/wrzt
+nmvCHefOmVf4tefkXy1MyEvBt2+Ek9bHmHDL1BSk/JdJzJtam2uaP5pGum/PwIUW
+KBatmHKZUKwgOIml9btB413C4zSK3GQmC5Y/+TxYybACIdxTDqPSczVZ5Q+jSywX
+shdOoLXDRyrYhT2sHjZ1W29B8ebokqwousF77EA94sqfQvDDnmFpvfq9+m0WYtOh
+PFF/yxOtlbPJYX7mnC8+dUgobSA4AR5Yrclt+levgivIyNuBwzevHRDMreMZKl2J
+uiOT8tkuu66fAwEltIowjjV7TBRfij4QLXl/zfFo8jKU8efL3xluXoRn7g+E5FZ3
+19KTF/DWMcttfeTUYVnv0QTnstb1RGnVj7w8JMy90mKdMQFpl7IzHd2n6LrhEw1V
+1AaPF7EcQBOlvsvlZdIFQrFyhKozKoGi3wRrl/bNdebxjIjPzfN9GgbiufFjz2d7
+DMR9GFXfUMVxLncaqBBy1X7MV17ZF7K4uw6DET4fRoecb4N5mJVUxvYq4iZApnNP
+npgGdmlcyPD6o3ynx/vkw78m13Gfgw8i2OaUY7xBdOyNVEvkJZBLaC2hw+TKLaZa
+v0RExtAO0i0QO4Y1eo78Pl9jOpz0wkJ4KG0270l1Jza4IyaIhYRDWagWOfOp/cXU
+cvKKiuJhLOsX1Bapz+O2Aor9+EwWRdPd3BzE2ABdmKHPwrKobNp75wrCpQ5mZifn
+DSTJRMPQQJV3wGfB2sP0NE47U8w5CCmVK8gEuqYr6wBl/CCq5tjiRc63VM+to5V4
+tVNTCJWIRgQQEQIABgUCUc7PqwAKCRBr3f6OVKKs8cYAAKCFCLJ5wc+iAVCFRevh
+xTcJct0fiQCePHpY37CIeP8s9BH8GqCDftUqh8SIRgQQEQIABgUCUc7YwAAKCRDd
+f+mrhdawLOVxAJ9Tjud26LtbM2mWcPj2eT7dhqgZrQCdGyMwMMVzp40lsCK44PrV
++mpFO7KJAhwEEAECAAYFAlHO0BkACgkQw35HI5aSdvXfLw//c2zZxXg4bI2W7gkB
+ZQJIOWnmPZfhrXQNeFuetyGoWTm4ZWxW362AdDGiQSGNNkXqeBPOitKOkRyZP/Z3
+h1vwkLkwdFZyWXK00BzYBKfjThWV1BAnArQLewSiLlE7qSnsPEY6FW0PNv711cbL
+lXSUP1/lW25Nx7L76GAF6sHreoIdglE8YH5y310JuFnqPa0uaJG+qDo8Mb+WkyLy
+Q2A3Atws1tIB9vHsq2FCt9ACyAEA3AqtHR4uMFmIWpUYy77fJAZdzLZTWf0X5XYw
+XILNPOl/I0iZrq3LYQAvJfIwjWAC/lm6uTLlvkIJHKyhcIT+RocjMV7bY9ezrC5i
+Cag3gaOZ7USMt0h59KdmBaHHNa32n3PSHg9XWljqoWMRjuaRdcA7ofK0BHDJbHWE
+cldKXC09laWOXbyNmJsfug/23vNE7fS/cAKSIgEWszEwHJCahB2i/HqOQF0DUGpq
+3s5oIXs2xIuN0yT6yIIiQnTU/FkWDDu4D1OZNrDW6QG3cde0PRak/0fr4Kv4iB3E
+CAzlsRBlWKNu/eE4QBx6cbvLqjriijhGAF+8Y1zvRKNKPr96hSsETfVytuKDTp6F
+u7PAarrSATGXI92Hy3ThAZla0VOYUyeWPktqUMDNq90tIBZbwKpOMMqvJmZfgdOU
+4ldDq1f5+2WhAt1aTL1GJVCuYcCJAhwEEAECAAYFAlHO3MQACgkQnSOpPExjO3Gi
+jxAAsD+luooqqoz3A28ZxwfCDV+ovazQ4Bw6hVU0zKKZIz/2H4jwmLtLSHtucCRM
+xRksZmnqf1p2nn+BKBXDInx9vI9HziMu7fWkzhuovAIf9+X/l6EYV1kQx0bIM1qU
+BxXWPgGdrgSZZHl9Qff/BOBnrI8NJmVBDzOh3BSs0BrSR7aFbkSNbjk/JcP0JEyk
+j6wDKQsop/Ca5AboLL0uQPgTvhxCu4VROKjhu7o3s7G3xlxTpimwYklDQuYFaGKj
+ZNIGFq2orfIMBnj7ZEQVXzhWltlHcgPVP5TDfgd4pVUbyUB6ras7odJWWIHnUFmj
+1l5bGidIwRXGFusE4iR8pR528LG2KxNDNQYipsKRY9m+wH+N7gbSgK8DxmocvieV
+vcILFS5VrPLbEO2oC13NMljmvua3ovDB0CEh9rybaH+/oA+VDS2L3pkgATTju+Vx
+6+mVdlvnrA4mJ5BoLHzrleKybS4ZkbtVBh1KOYmo95NgVifRvpVPB6hKzwqcjYFV
+fVYBxTryTBRyd9MLsqpPKnGLBENTFvKDxRCK3iioNyVhXdS0z/UyF1C2hwNTpnjY
+pGCu+Es3SILJg2TvQcwLM0OoYBA1bcONm2XbkTrdCpTOtQcSewQSkijREunx14iu
+pvNSWeNmbjQU7gNYhvwcBgh90tWgNCfqTtSa5xSe46tmv0SJAhwEEAECAAYFAlHQ
+1hgACgkQZwn/QC8Dr2hT/g/+OFUYPXfWo0+ILdxyTGP/v2mSw/X3dBCEYUqefWxD
+umcwnksey+thEGFBlxbwpyOfAoTzZLUupaG6BacVgRUvv8bTne4v2H1d22aBXyjC
+HMtQPhupn/giamu8q8hCPFrDp6inIAeFuz1GmQaH6xWO5eYBuYXQtxlvZLWBsuMT
+74en4e3vjczxGmJu/nvM9ugcYsexA/zcN6SRGr7t2pV4ZElPzPBRyAzhYqhP1YlB
+Rydz60OjgcWYEoJKWhJOfmFJ3ZoNGAz4TGoBkDIq4olCF0/cxqrtHN+ZnEOLwiZ7
+4ZX90avcjEFtM+Wb5dBHNpni4ISoHcVI1X0ye6tuAOOt7RywbET/0oIW5iSNMgJ0
+X4XYgOIQ2+a8yjGBjo9I57k0vp1mL6Ji/eaa0dlppcCGnzvSHss+O0qO212pg5Yk
+GGfjX1y1ZeSP3ca9C2XyOGIVw2d2Iu7OyqAv/N81xt6ZgG3qixQC0nmgOmn7Kh2B
+20W12KpLxKS8RQdHawGau3MBGKeqbfK6/eAzm22yD4/yJAoW4hKgm84z3FbKUN8w
+ulYMK9hS2c4egpoDAOJ/QZLLXFWiyi7/sHZz69G2AweWCjOJh28Otg0cUHoLo7jw
+oO/L0rCsOQMbUuIumYXBPHNnDwv1xfv2lT8tVzf6GksFJBAw0DybxOMTaOg45Lhz
+jGS5BA0EUc7OlQEgAN6t+BV705uoCsdHtQBq/HKGGD5tBiOzy7Wd4nF/c6EWzET4
+QUnmw6bDnqjxrk9MWniPDf1O9MvuB4qIY6g9kEjZ+VSQpWUZpZ5bMXCNHrfh9J2Q
+6oLWqDmpeZv2OI0O9wxT62QaFei2qBtimSnBudLSCnvmU3S0h1PflmJsbj+tVcko
+w2yOh2bjH1jkVAODHvEbxqyD6fiZhbfUVbPC49SBmXv8Gv0UywNSkP+iqJdwZAb0
+XtjRx4WjZCkTwJAnbM4CJ63+5Hd83BtWZAZbGAh76XY/cSkDirXtXC+2LNUmP5W2
+QY+ur5Bvz8LHaqJMXLAtePdkv5kpd+jXBrZieXUtqovxZaQTinl7C3L2TZd/ivxD
+F3Rko9BFDuXXcdZrxBY5b3146IvSPp1y0WmHRxhAPb+RuiHQMt8K92nOhPyvtWXB
+mWz0GnW9L6+CW4LKSPRSnE057hyxYNP/DcDd+fWFH+MmhU9noqHfJXSaLVzdI5PI
+L8N44AndPIojnlxrxRs7Ik/nW6cTV9H3agg+24yyTdFkACbfIS6wWXOHeHuBzmO6
+VI7pXOZJ9vZT7zI7M/hVci0R3putsGqgRfByRWWQ2DNeyrwUHexZNR/NYz1uhvA6
+dBfKcuAwqxbdSrW/BxJ+iJWdkgYGCV67VLlO6S9sO33HgOanpPr5R9V1KsFVh4dN
+j6BjZ4ALE5FPNW+iONnuXvtZbN2cBlBzMDeFC9oZoYCs1Pkmk8xUY2sAXPUt1R0G
+D/miIb7ig1N52j9P6vv6fPs1ghmc/hGkhaXyjS54B5T33V6M9g+yba9mIgi8ZxZa
+G+4rlFFKA4HS7wYYRJoqMvnc/qBYvoWLaPu3Xq6AXrJyuAaN+e3L8++cWbYHBXF9
+qt+Q2RFL0FNiYUQuwkiaerysnm1a0H7ZtJ4zjl4ZgA1Ej7QcylTIbgFW3L7FnyMH
+/5weLLN2wdjAtzjhRPYJLbV6V/gFbbpCpr+caDUaxSNizQuhhzVI5UrJegaHCCrx
+DCiwWRFYzN5pqhtgzcaImK76DmPIk+Yrsum5KJZQeGfzKxvF0YnwxU0bxFzcDZJD
+X2oCJn828Aw2j0nIlVlrrao0JMkvTBeZehO/11U68M2vKGEqrsQOb/BTXyLCeZwn
+UGow1WvYfRxEZTrhhiYw94EH06gbqmKG1xsuV4LDI5z63/6ACcQW3orMbMymJCky
+4HiNVZ7SNeGoYe380CJCwv6GN1opKTAWp84cr2KzhAzONGqNWNpUhznAXlI+GzCc
+D2H330L1atMqZHjgpEfrkowvJ7WBM5KFKDfylaTKhYvfZcTOZs5OmRZSW3U54wRD
+RMP0d2+k3vRililNhHIErHbjhYFc6zubVbBhvUMAEQEAAYkEHwQYAQIACQUCUc7O
+lQIbDAAKCRCxF563NH3BDSX2IACugAdZqX+o/+pTkSrj+NEAcP0ZMci8w5nm/yOP
+VlGyY6PXGuQKcBtvz3LWtIDdddMc/bD/zmZPwSzTx1MMOWc+gjR0azXe2RrdMHYk
+8pb4X4Op2Nkasoc/8hNsRKaU24WUAQMqrRREIVBEOuHGl1A52Lj+aFB04rRHrkMl
+AqjB5bwArPorIBdM417EEl4hjEZ9BpQxbUgBhTgGTZuc1u9PsKz1YvQ79YJIRmSH
+n72Zaf35zY55eOQeoVBzGmFPq+/UFqtRNWA7jmRhHvMz/yR33B/RSxyTJuPb79zi
+2mIZOrViG3X/UNL4qtOc1cKXQBi+FjHAMlGrCc+D5lnyOhEvqoEuvQic7V6C8Pvk
+9q+jngn2Gs4pdJO8FOnwaC5xp/ZNE0v7x/KtAHyBA6iKcaepgoRQPSt1ONiHyfh1
+iGgJn+Y6IHx4YDYKEY0UIzHhCfWUl8XZWcf4wLGEbGztkRbkCFqrsja5IeaO7umB
+i6C4f95uSGjV7SiIMJOE8xo/m2g4VCnnmk7U996JwtBMKREMMqa3ABK4trfBL3Kq
+P6I6ZTlA/C5svkVUVwWOMZau9kLDsxv8keGrFteZtfYa1KPAROFwNuBU82UW0KtX
+QQbZoBKt1o3LhqEu+hXU3iKocYWSbBThH8u6vPNgSnW2Qcv3gcUU3jGmYeHrGiUO
+SuEWxwlKUxCxBNfmz1FGswlwve1LsS3RTz/XB/L6Ubhq5L7FevrXz8152kuMqnpy
+m93sXkL1eJVo07hH+otcRnMzy4vUar9z/N12t3hfTffx29PBKUCc2PKPVpLfJX2i
+hieHk23fhLnptjc3lm9S+bHO3rqEWHqgNgNp9bpuwiLRsIy6qTtmC8jxXkGXvQrS
++2Hv6+jRfDcqEAK3vqi1XL7Td81KRjnheBtsKpjS2PFatK3uTo6v1oRWJCdRCxg1
+HT6a9KvZ+DNKcxlQISKAOLX72qpziaDl4CpBdQy4Zg2pr9oYkLdlfkaDK/OH4J3M
+wJiVf/uNPPd+yy6xZXK0SPZHf+mf5Yt+Sim93hIbdS9AMdvHKB5n3DR27H+/okPj
+w3J9z85hxgP5KspizQR6t77AWddPRy/l3BBZeb+HiaeKGBJeSNWXpkPXHkdjLW8U
+QStzFR8r15FWJTmamIknjJ3XNbytMCpu8cj2ZVZdyjPcHEBL3WbNYYtauSuYmyUO
+yXBaecM/KoTdvHiERU/mMuf7f1ftftCHehZoNaP+BeIbIud9IHIdrSQBCW+RC1Y1
+8opDLMtnIOX3OnyCN38ELYcuNLMJxBqnQgi7MVDVcT1+BN/+lFQtG44+rPUkK+T1
+Jk1/tIJqcyc1BfY6uFHFXWWnqQnjl0XpZo+/bMDxTVy8yND2
+=icdI
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/contrib/init/README.md b/contrib/init/README.md
new file mode 100644
index 0000000000..0d19da3039
--- /dev/null
+++ b/contrib/init/README.md
@@ -0,0 +1,11 @@
+Sample configuration files for:
+
+SystemD: bitcoind.service
+Upstart: bitcoind.conf
+OpenRC: bitcoind.openrc
+ bitcoind.openrcconf
+CentOS: bitcoind.init
+
+have been made available to assist packagers in creating node packages here.
+
+See doc/init.md for more information.
diff --git a/contrib/init/bitcoind.conf b/contrib/init/bitcoind.conf
new file mode 100644
index 0000000000..f9554eecde
--- /dev/null
+++ b/contrib/init/bitcoind.conf
@@ -0,0 +1,65 @@
+description "Bitcoin Core Daemon"
+
+start on runlevel [2345]
+stop on starting rc RUNLEVEL=[016]
+
+env BITCOIND_BIN="/usr/bin/bitcoind"
+env BITCOIND_USER="bitcoin"
+env BITCOIND_GROUP="bitcoin"
+env BITCOIND_PIDDIR="/var/run/bitcoind"
+# upstart can't handle variables constructed with other variables
+env BITCOIND_PIDFILE="/var/run/bitcoind/bitcoind.pid"
+env BITCOIND_CONFIGFILE="/etc/bitcoin/bitcoin.conf"
+env BITCOIND_DATADIR="/var/lib/bitcoind"
+
+expect fork
+
+respawn
+respawn limit 5 120
+kill timeout 60
+
+pre-start script
+ # this will catch non-existent config files
+ # bitcoind will check and exit with this very warning, but it can do so
+ # long after forking, leaving upstart to think everything started fine.
+ # since this is a commonly encountered case on install, just check and
+ # warn here.
+ if ! grep -qs '^rpcpassword=' "$BITCOIND_CONFIGFILE" ; then
+ echo "ERROR: You must set a secure rpcpassword to run bitcoind."
+ echo "The setting must appear in $BITCOIND_CONFIGFILE"
+ echo
+ echo "This password is security critical to securing wallets "
+ echo "and must not be the same as the rpcuser setting."
+ echo "You can generate a suitable random password using the following"
+ echo "command from the shell:"
+ echo
+ echo "bash -c 'tr -dc a-zA-Z0-9 < /dev/urandom | head -c32 && echo'"
+ echo
+ echo "It is also recommended that you also set alertnotify so you are "
+ echo "notified of problems:"
+ echo
+ echo "ie: alertnotify=echo %%s | mail -s \"Bitcoin Alert\"" \
+ "admin@foo.com"
+ echo
+ exit 1
+ fi
+
+ mkdir -p "$BITCOIND_PIDDIR"
+ chmod 0755 "$BITCOIND_PIDDIR"
+ chown $BITCOIND_USER:$BITCOIND_GROUP "$BITCOIND_PIDDIR"
+ chown $BITCOIND_USER:$BITCOIND_GROUP "$BITCOIND_CONFIGFILE"
+ chmod 0660 "$BITCOIND_CONFIGFILE"
+end script
+
+exec start-stop-daemon \
+ --start \
+ --pidfile "$BITCOIND_PIDFILE" \
+ --chuid $BITCOIND_USER:$BITCOIND_GROUP \
+ --exec "$BITCOIND_BIN" \
+ -- \
+ -pid="$BITCOIND_PIDFILE" \
+ -conf="$BITCOIND_CONFIGFILE" \
+ -datadir="$BITCOIND_DATADIR" \
+ -disablewallet \
+ -daemon
+
diff --git a/contrib/init/bitcoind.init b/contrib/init/bitcoind.init
new file mode 100644
index 0000000000..db5061874b
--- /dev/null
+++ b/contrib/init/bitcoind.init
@@ -0,0 +1,67 @@
+#!/bin/bash
+#
+# bitcoind The bitcoin core server.
+#
+#
+# chkconfig: 345 80 20
+# description: bitcoind
+# processname: bitcoind
+#
+
+# Source function library.
+. /etc/init.d/functions
+
+# you can override defaults in /etc/sysconfig/bitcoind, see below
+if [ -f /etc/sysconfig/bitcoind ]; then
+ . /etc/sysconfig/bitcoind
+fi
+
+RETVAL=0
+
+prog=bitcoind
+# you can override the lockfile via BITCOIND_LOCKFILE in /etc/sysconfig/bitcoind
+lockfile=${BITCOIND_LOCKFILE-/var/lock/subsys/bitcoind}
+
+# bitcoind defaults to /usr/bin/bitcoind, override with BITCOIND_BIN
+bitcoind=${BITCOIND_BIN-/usr/bin/bitcoind}
+
+# bitcoind opts default to -disablewallet, override with BITCOIND_OPTS
+bitcoind_opts=${BITCOIND_OPTS--disablewallet}
+
+start() {
+ echo -n $"Starting $prog: "
+ daemon $DAEMONOPTS $bitcoind $bitcoind_opts
+ RETVAL=$?
+ echo
+ [ $RETVAL -eq 0 ] && touch $lockfile
+ return $RETVAL
+}
+
+stop() {
+ echo -n $"Stopping $prog: "
+ killproc $prog
+ RETVAL=$?
+ echo
+ [ $RETVAL -eq 0 ] && rm -f $lockfile
+ return $RETVAL
+}
+
+case "$1" in
+ start)
+ start
+ ;;
+ stop)
+ stop
+ ;;
+ status)
+ status $prog
+ ;;
+ restart)
+ stop
+ start
+ ;;
+ *)
+ echo "Usage: service $prog {start|stop|status|restart}"
+ exit 1
+ ;;
+esac
diff --git a/contrib/init/bitcoind.openrc b/contrib/init/bitcoind.openrc
new file mode 100644
index 0000000000..a94f03680d
--- /dev/null
+++ b/contrib/init/bitcoind.openrc
@@ -0,0 +1,88 @@
+#!/sbin/runscript
+
+# backward compatibility for existing gentoo layout
+#
+if [ -d "/var/lib/bitcoin/.bitcoin" ]; then
+ BITCOIND_DEFAULT_DATADIR="/var/lib/bitcoin/.bitcoin"
+else
+ BITCOIND_DEFAULT_DATADIR="/var/lib/bitcoind"
+fi
+
+BITCOIND_CONFIGFILE=${BITCOIND_CONFIGFILE:-/etc/bitcoin/bitcoin.conf}
+BITCOIND_PIDDIR=${BITCOIND_PIDDIR:-/var/run/bitcoind}
+BITCOIND_PIDFILE=${BITCOIND_PIDFILE:-${BITCOIND_PIDDIR}/bitcoind.pid}
+BITCOIND_DATADIR=${BITCOIND_DATADIR:-${BITCOIND_DEFAULT_DATADIR}}
+BITCOIND_USER=${BITCOIND_USER:-${BITCOIN_USER:-bitcoin}}
+BITCOIND_GROUP=${BITCOIND_GROUP:-bitcoin}
+BITCOIND_BIN=${BITCOIND_BIN:-/usr/bin/bitcoind}
+BITCOIND_NICE=${BITCOIND_NICE:-${NICELEVEL:-0}}
+BITCOIND_OPTS="${BITCOIND_OPTS:-${BITCOIN_OPTS}}"
+
+name="Bitcoin Core Daemon"
+description="Bitcoin cryptocurrency P2P network daemon"
+
+command="/usr/bin/bitcoind"
+command_args="-pid=\"${BITCOIND_PIDFILE}\" \
+ -conf=\"${BITCOIND_CONFIGFILE}\" \
+ -datadir=\"${BITCOIND_DATADIR}\" \
+ -daemon \
+ ${BITCOIND_OPTS}"
+
+required_files="${BITCOIND_CONFIGFILE}"
+start_stop_daemon_args="-u ${BITCOIND_USER} \
+ -N ${BITCOIND_NICE} -w 2000"
+pidfile="${BITCOIND_PIDFILE}"
+retry=60
+
+depend() {
+ need localmount net
+}
+
+# verify
+# 1) that the datadir exists and is writable (or create it)
+# 2) that a directory for the pid exists and is writable
+# 3) ownership and permissions on the config file
+start_pre() {
+ checkpath \
+ -d \
+ --mode 0750 \
+ --owner "${BITCOIND_USER}:${BITCOIND_GROUP}" \
+ "${BITCOIND_DATADIR}"
+
+ checkpath \
+ -d \
+ --mode 0755 \
+ --owner "${BITCOIND_USER}:${BITCOIND_GROUP}" \
+ "${BITCOIND_PIDDIR}"
+
+ checkpath -f \
+ -o ${BITCOIND_USER}:${BITCOIND_GROUP} \
+ -m 0660 \
+ ${BITCOIND_CONFIGFILE}
+
+ checkconfig || return 1
+}
+
+checkconfig()
+{
+ if ! grep -qs '^rpcpassword=' "${BITCOIND_CONFIGFILE}" ; then
+ eerror ""
+ eerror "ERROR: You must set a secure rpcpassword to run bitcoind."
+ eerror "The setting must appear in ${BITCOIND_CONFIGFILE}"
+ eerror ""
+ eerror "This password is security critical to securing wallets "
+ eerror "and must not be the same as the rpcuser setting."
+ eerror "You can generate a suitable random password using the following"
+ eerror "command from the shell:"
+ eerror ""
+ eerror "bash -c 'tr -dc a-zA-Z0-9 < /dev/urandom | head -c32 && echo'"
+ eerror ""
+ eerror "It is also recommended that you also set alertnotify so you are "
+ eerror "notified of problems:"
+ eerror ""
+ eerror "ie: alertnotify=echo %%s | mail -s \"Bitcoin Alert\"" \
+ "admin@foo.com"
+ eerror ""
+ return 1
+ fi
+}
diff --git a/contrib/init/bitcoind.openrcconf b/contrib/init/bitcoind.openrcconf
new file mode 100644
index 0000000000..d8d7f58337
--- /dev/null
+++ b/contrib/init/bitcoind.openrcconf
@@ -0,0 +1,27 @@
+# /etc/conf.d/bitcoind: config file for /etc/init.d/bitcoind
+
+# Config file location
+#BITCOIND_CONFIGFILE="/etc/bitcoin/bitcoin.conf"
+
+# What directory to write pidfile to? (created and owned by $BITCOIND_USER)
+#BITCOIND_PIDDIR="/var/run/bitcoind"
+
+# What filename to give the pidfile
+#BITCOIND_PIDFILE="${BITCOIND_PIDDIR}/bitcoind.pid"
+
+# Where to write bitcoind data (be mindful that the blockchain is large)
+#BITCOIND_DATADIR="/var/lib/bitcoind"
+
+# User and group to own bitcoind process
+#BITCOIND_USER="bitcoin"
+#BITCOIND_GROUP="bitcoin"
+
+# Path to bitcoind executable
+#BITCOIND_BIN="/usr/bin/bitcoind"
+
+# Nice value to run bitcoind under
+#BITCOIND_NICE=0
+
+# Additional options (avoid -conf and -datadir, use flags above)
+BITCOIND_OPTS="-disablewallet"
+
diff --git a/contrib/init/bitcoind.service b/contrib/init/bitcoind.service
new file mode 100644
index 0000000000..9132957c38
--- /dev/null
+++ b/contrib/init/bitcoind.service
@@ -0,0 +1,22 @@
+[Unit]
+Description=Bitcoin's distributed currency daemon
+After=network.target
+
+[Service]
+User=bitcoin
+Group=bitcoin
+
+Type=forking
+PIDFile=/var/lib/bitcoind/bitcoind.pid
+ExecStart=/usr/bin/bitcoind -daemon -pid=/var/lib/bitcoind/bitcoind.pid \
+-conf=/etc/bitcoin/bitcoin.conf -datadir=/var/lib/bitcoind -disablewallet
+
+Restart=always
+PrivateTmp=true
+TimeoutStopSec=60s
+TimeoutStartSec=2s
+StartLimitInterval=120s
+StartLimitBurst=5
+
+[Install]
+WantedBy=multi-user.target
diff --git a/contrib/linearize/README.md b/contrib/linearize/README.md
new file mode 100644
index 0000000000..157586e4d4
--- /dev/null
+++ b/contrib/linearize/README.md
@@ -0,0 +1,33 @@
+# Linearize
+Construct a linear, no-fork, best version of the blockchain.
+
+## Step 1: Download hash list
+
+ $ ./linearize-hashes.py linearize.cfg > hashlist.txt
+
+Required configuration file settings for linearize-hashes:
+* RPC: rpcuser, rpcpassword
+
+Optional config file setting for linearize-hashes:
+* RPC: host, port
+* Block chain: min_height, max_height
+
+## Step 2: Copy local block data
+
+ $ ./linearize-data.py linearize.cfg
+
+Required configuration file settings:
+* "input": bitcoind blocks/ directory containing blkNNNNN.dat
+* "hashlist": text file containing list of block hashes, linearized-hashes.py
+output.
+* "output_file": bootstrap.dat
+ or
+* "output": output directory for linearized blocks/blkNNNNN.dat output
+
+Optional config file setting for linearize-data:
+* "netmagic": network magic number
+* "max_out_sz": maximum output file size (default 1000*1000*1000)
+* "split_timestamp": Split files when a new month is first seen, in addition to
+reaching a maximum file size.
+* "file_timestamp": Set each file's last-modified time to that of the
+most recent block in that file.
diff --git a/contrib/linearize/example-linearize.cfg b/contrib/linearize/example-linearize.cfg
new file mode 100644
index 0000000000..38da02e66c
--- /dev/null
+++ b/contrib/linearize/example-linearize.cfg
@@ -0,0 +1,29 @@
+
+# bitcoind RPC settings (linearize-hashes)
+rpcuser=someuser
+rpcpassword=somepassword
+host=127.0.0.1
+port=8332
+#port=18332
+
+# bootstrap.dat hashlist settings (linearize-hashes)
+max_height=313000
+
+# bootstrap.dat input/output settings (linearize-data)
+
+# mainnet
+netmagic=f9beb4d9
+genesis=000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
+input=/home/example/.bitcoin/blocks
+
+# testnet
+#netmagic=0b110907
+#genesis=000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943
+#input=/home/example/.bitcoin/testnet3/blocks
+
+output_file=/home/example/Downloads/bootstrap.dat
+hashlist=hashlist.txt
+split_year=1
+
+# Maxmimum size in bytes of out-of-order blocks cache in memory
+out_of_order_cache_sz = 100000000
diff --git a/contrib/linearize/linearize-data.py b/contrib/linearize/linearize-data.py
new file mode 100755
index 0000000000..7947c6bf72
--- /dev/null
+++ b/contrib/linearize/linearize-data.py
@@ -0,0 +1,301 @@
+#!/usr/bin/python
+#
+# linearize-data.py: Construct a linear, no-fork version of the chain.
+#
+# Copyright (c) 2013-2014 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#
+
+from __future__ import print_function, division
+import json
+import struct
+import re
+import os
+import base64
+import httplib
+import sys
+import hashlib
+import datetime
+import time
+from collections import namedtuple
+
+settings = {}
+
+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)
+
+def calc_hdr_hash(blk_hdr):
+ hash1 = hashlib.sha256()
+ hash1.update(blk_hdr)
+ hash1_o = hash1.digest()
+
+ hash2 = hashlib.sha256()
+ hash2.update(hash1_o)
+ hash2_o = hash2.digest()
+
+ return hash2_o
+
+def calc_hash_str(blk_hdr):
+ hash = calc_hdr_hash(blk_hdr)
+ hash = bufreverse(hash)
+ hash = wordreverse(hash)
+ hash_str = hash.encode('hex')
+ return hash_str
+
+def get_blk_dt(blk_hdr):
+ members = struct.unpack("<I", blk_hdr[68:68+4])
+ nTime = members[0]
+ dt = datetime.datetime.fromtimestamp(nTime)
+ dt_ym = datetime.datetime(dt.year, dt.month, 1)
+ return (dt_ym, nTime)
+
+def get_block_hashes(settings):
+ blkindex = []
+ f = open(settings['hashlist'], "r")
+ for line in f:
+ line = line.rstrip()
+ blkindex.append(line)
+
+ print("Read " + str(len(blkindex)) + " hashes")
+
+ return blkindex
+
+def mkblockmap(blkindex):
+ blkmap = {}
+ for height,hash in enumerate(blkindex):
+ blkmap[hash] = height
+ return blkmap
+
+# Block header and extent on disk
+BlockExtent = namedtuple('BlockExtent', ['fn', 'offset', 'inhdr', 'blkhdr', 'size'])
+
+class BlockDataCopier:
+ def __init__(self, settings, blkindex, blkmap):
+ self.settings = settings
+ self.blkindex = blkindex
+ self.blkmap = blkmap
+
+ self.inFn = 0
+ self.inF = None
+ self.outFn = 0
+ self.outsz = 0
+ self.outF = None
+ self.outFname = None
+ self.blkCountIn = 0
+ self.blkCountOut = 0
+
+ self.lastDate = datetime.datetime(2000, 1, 1)
+ self.highTS = 1408893517 - 315360000
+ self.timestampSplit = False
+ self.fileOutput = True
+ self.setFileTime = False
+ self.maxOutSz = settings['max_out_sz']
+ if 'output' in settings:
+ self.fileOutput = False
+ if settings['file_timestamp'] != 0:
+ self.setFileTime = True
+ if settings['split_timestamp'] != 0:
+ self.timestampSplit = True
+ # Extents and cache for out-of-order blocks
+ self.blockExtents = {}
+ self.outOfOrderData = {}
+ self.outOfOrderSize = 0 # running total size for items in outOfOrderData
+
+ def writeBlock(self, inhdr, blk_hdr, rawblock):
+ if not self.fileOutput and ((self.outsz + self.inLen) > self.maxOutSz):
+ self.outF.close()
+ if self.setFileTime:
+ os.utime(outFname, (int(time.time()), highTS))
+ self.outF = None
+ self.outFname = None
+ self.outFn = outFn + 1
+ self.outsz = 0
+
+ (blkDate, blkTS) = get_blk_dt(blk_hdr)
+ if self.timestampSplit and (blkDate > self.lastDate):
+ print("New month " + blkDate.strftime("%Y-%m") + " @ " + hash_str)
+ lastDate = blkDate
+ if outF:
+ outF.close()
+ if setFileTime:
+ os.utime(outFname, (int(time.time()), highTS))
+ self.outF = None
+ self.outFname = None
+ self.outFn = self.outFn + 1
+ self.outsz = 0
+
+ if not self.outF:
+ if self.fileOutput:
+ outFname = self.settings['output_file']
+ else:
+ outFname = "%s/blk%05d.dat" % (self.settings['output'], outFn)
+ print("Output file " + outFname)
+ self.outF = open(outFname, "wb")
+
+ self.outF.write(inhdr)
+ self.outF.write(blk_hdr)
+ self.outF.write(rawblock)
+ self.outsz = self.outsz + len(inhdr) + len(blk_hdr) + len(rawblock)
+
+ self.blkCountOut = self.blkCountOut + 1
+ if blkTS > self.highTS:
+ self.highTS = blkTS
+
+ if (self.blkCountOut % 1000) == 0:
+ print('%i blocks scanned, %i blocks written (of %i, %.1f%% complete)' %
+ (self.blkCountIn, self.blkCountOut, len(self.blkindex), 100.0 * self.blkCountOut / len(self.blkindex)))
+
+ def inFileName(self, fn):
+ return "%s/blk%05d.dat" % (self.settings['input'], fn)
+
+ def fetchBlock(self, extent):
+ '''Fetch block contents from disk given extents'''
+ with open(self.inFileName(extent.fn), "rb") as f:
+ f.seek(extent.offset)
+ return f.read(extent.size)
+
+ def copyOneBlock(self):
+ '''Find the next block to be written in the input, and copy it to the output.'''
+ extent = self.blockExtents.pop(self.blkCountOut)
+ if self.blkCountOut in self.outOfOrderData:
+ # If the data is cached, use it from memory and remove from the cache
+ rawblock = self.outOfOrderData.pop(self.blkCountOut)
+ self.outOfOrderSize -= len(rawblock)
+ else: # Otherwise look up data on disk
+ rawblock = self.fetchBlock(extent)
+
+ self.writeBlock(extent.inhdr, extent.blkhdr, rawblock)
+
+ def run(self):
+ while self.blkCountOut < len(self.blkindex):
+ if not self.inF:
+ fname = self.inFileName(self.inFn)
+ print("Input file " + fname)
+ try:
+ self.inF = open(fname, "rb")
+ except IOError:
+ print("Premature end of block data")
+ return
+
+ inhdr = self.inF.read(8)
+ if (not inhdr or (inhdr[0] == "\0")):
+ self.inF.close()
+ self.inF = None
+ self.inFn = self.inFn + 1
+ continue
+
+ inMagic = inhdr[:4]
+ if (inMagic != self.settings['netmagic']):
+ print("Invalid magic: " + inMagic.encode('hex'))
+ return
+ inLenLE = inhdr[4:]
+ su = struct.unpack("<I", inLenLE)
+ inLen = su[0] - 80 # length without header
+ blk_hdr = self.inF.read(80)
+ inExtent = BlockExtent(self.inFn, self.inF.tell(), inhdr, blk_hdr, inLen)
+
+ hash_str = calc_hash_str(blk_hdr)
+ if not hash_str in blkmap:
+ print("Skipping unknown block " + hash_str)
+ self.inF.seek(inLen, os.SEEK_CUR)
+ continue
+
+ blkHeight = self.blkmap[hash_str]
+ self.blkCountIn += 1
+
+ if self.blkCountOut == blkHeight:
+ # If in-order block, just copy
+ rawblock = self.inF.read(inLen)
+ self.writeBlock(inhdr, blk_hdr, rawblock)
+
+ # See if we can catch up to prior out-of-order blocks
+ while self.blkCountOut in self.blockExtents:
+ self.copyOneBlock()
+
+ else: # If out-of-order, skip over block data for now
+ self.blockExtents[blkHeight] = inExtent
+ if self.outOfOrderSize < self.settings['out_of_order_cache_sz']:
+ # If there is space in the cache, read the data
+ # Reading the data in file sequence instead of seeking and fetching it later is preferred,
+ # but we don't want to fill up memory
+ self.outOfOrderData[blkHeight] = self.inF.read(inLen)
+ self.outOfOrderSize += inLen
+ else: # If no space in cache, seek forward
+ self.inF.seek(inLen, os.SEEK_CUR)
+
+ print("Done (%i blocks written)" % (self.blkCountOut))
+
+if __name__ == '__main__':
+ if len(sys.argv) != 2:
+ print("Usage: linearize-data.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 'netmagic' not in settings:
+ settings['netmagic'] = 'f9beb4d9'
+ if 'genesis' not in settings:
+ settings['genesis'] = '000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f'
+ if 'input' not in settings:
+ settings['input'] = 'input'
+ if 'hashlist' not in settings:
+ settings['hashlist'] = 'hashlist.txt'
+ if 'file_timestamp' not in settings:
+ settings['file_timestamp'] = 0
+ if 'split_timestamp' not in settings:
+ settings['split_timestamp'] = 0
+ if 'max_out_sz' not in settings:
+ settings['max_out_sz'] = 1000L * 1000 * 1000
+ if 'out_of_order_cache_sz' not in settings:
+ settings['out_of_order_cache_sz'] = 100 * 1000 * 1000
+
+ settings['max_out_sz'] = long(settings['max_out_sz'])
+ settings['split_timestamp'] = int(settings['split_timestamp'])
+ settings['file_timestamp'] = int(settings['file_timestamp'])
+ settings['netmagic'] = settings['netmagic'].decode('hex')
+ settings['out_of_order_cache_sz'] = int(settings['out_of_order_cache_sz'])
+
+ if 'output_file' not in settings and 'output' not in settings:
+ print("Missing output file / directory")
+ sys.exit(1)
+
+ blkindex = get_block_hashes(settings)
+ blkmap = mkblockmap(blkindex)
+
+ if not settings['genesis'] in blkmap:
+ print("Genesis block not found in hashlist")
+ else:
+ BlockDataCopier(settings, blkindex, blkmap).run()
+
+
diff --git a/contrib/linearize/linearize-hashes.py b/contrib/linearize/linearize-hashes.py
new file mode 100755
index 0000000000..854cf1f9ee
--- /dev/null
+++ b/contrib/linearize/linearize-hashes.py
@@ -0,0 +1,113 @@
+#!/usr/bin/python
+#
+# linearize-hashes.py: List blocks in a linear, no-fork version of the chain.
+#
+# Copyright (c) 2013-2014 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#
+
+from __future__ import print_function
+import json
+import struct
+import re
+import base64
+import httplib
+import sys
+
+settings = {}
+
+class BitcoinRPC:
+ 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 execute(self, obj):
+ 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", file=sys.stderr)
+ return None
+
+ body = resp.read()
+ resp_obj = json.loads(body)
+ return resp_obj
+
+ @staticmethod
+ def build_request(idx, method, params):
+ obj = { 'version' : '1.1',
+ 'method' : method,
+ 'id' : idx }
+ if params is None:
+ obj['params'] = []
+ else:
+ obj['params'] = params
+ return obj
+
+ @staticmethod
+ def response_is_error(resp_obj):
+ return 'error' in resp_obj and resp_obj['error'] is not None
+
+def get_block_hashes(settings, max_blocks_per_call=10000):
+ rpc = BitcoinRPC(settings['host'], settings['port'],
+ settings['rpcuser'], settings['rpcpassword'])
+
+ height = settings['min_height']
+ while height < settings['max_height']+1:
+ num_blocks = min(settings['max_height']+1-height, max_blocks_per_call)
+ batch = []
+ for x in range(num_blocks):
+ batch.append(rpc.build_request(x, 'getblockhash', [height + x]))
+
+ reply = rpc.execute(batch)
+
+ for x,resp_obj in enumerate(reply):
+ if rpc.response_is_error(resp_obj):
+ print('JSON-RPC: error at height', height+x, ': ', resp_obj['error'], file=sys.stderr)
+ exit(1)
+ assert(resp_obj['id'] == x) # assume replies are in-sequence
+ print(resp_obj['result'])
+
+ height += num_blocks
+
+if __name__ == '__main__':
+ if len(sys.argv) != 2:
+ print("Usage: linearize-hashes.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 'min_height' not in settings:
+ settings['min_height'] = 0
+ if 'max_height' not in settings:
+ settings['max_height'] = 313000
+ if 'rpcuser' not in settings or 'rpcpassword' not in settings:
+ print("Missing username and/or password in cfg file", file=stderr)
+ sys.exit(1)
+
+ settings['port'] = int(settings['port'])
+ settings['min_height'] = int(settings['min_height'])
+ settings['max_height'] = int(settings['max_height'])
+
+ get_block_hashes(settings)
+
diff --git a/contrib/macdeploy/Base.lproj/InfoPlist.strings b/contrib/macdeploy/Base.lproj/InfoPlist.strings
new file mode 100644
index 0000000000..b259ea141c
--- /dev/null
+++ b/contrib/macdeploy/Base.lproj/InfoPlist.strings
@@ -0,0 +1 @@
+{ CFBundleDisplayName = "Bitcoin Core"; CFBundleName = "Bitcoin Core"; }
diff --git a/contrib/macdeploy/DS_Store b/contrib/macdeploy/DS_Store
new file mode 100644
index 0000000000..db9d16f1d7
--- /dev/null
+++ b/contrib/macdeploy/DS_Store
Binary files differ
diff --git a/contrib/macdeploy/LICENSE b/contrib/macdeploy/LICENSE
new file mode 100644
index 0000000000..94a9ed024d
--- /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. <http://fsf.org/>
+ 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.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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 <http://www.gnu.org/licenses/>.
+
+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:
+
+ <program> Copyright (C) <year> <name of author>
+ 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
+<http://www.gnu.org/licenses/>.
+
+ 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
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/contrib/macdeploy/README.md b/contrib/macdeploy/README.md
new file mode 100644
index 0000000000..6163734e62
--- /dev/null
+++ b/contrib/macdeploy/README.md
@@ -0,0 +1,15 @@
+### MacDeploy ###
+
+For Snow Leopard (which uses [Python 2.6](http://www.python.org/download/releases/2.6/)), you will need the param_parser package:
+
+ sudo easy_install argparse
+
+This script should not be run manually, instead, after building as usual:
+
+ make deploy
+
+During the process, the disk image window will pop up briefly where the fancy
+settings are applied. This is normal, please do not interfere.
+
+When finished, it will produce `Bitcoin-Core.dmg`.
+
diff --git a/contrib/macdeploy/background.png b/contrib/macdeploy/background.png
new file mode 100644
index 0000000000..f88a2ae74b
--- /dev/null
+++ b/contrib/macdeploy/background.png
Binary files differ
diff --git a/contrib/macdeploy/background.psd b/contrib/macdeploy/background.psd
new file mode 100644
index 0000000000..fdc4f4ca4a
--- /dev/null
+++ b/contrib/macdeploy/background.psd
Binary files differ
diff --git a/contrib/macdeploy/background.tiff b/contrib/macdeploy/background.tiff
new file mode 100644
index 0000000000..4b44ac672e
--- /dev/null
+++ b/contrib/macdeploy/background.tiff
Binary files differ
diff --git a/contrib/macdeploy/background@2x.png b/contrib/macdeploy/background@2x.png
new file mode 100644
index 0000000000..4858183f75
--- /dev/null
+++ b/contrib/macdeploy/background@2x.png
Binary files differ
diff --git a/contrib/macdeploy/detached-sig-apply.sh b/contrib/macdeploy/detached-sig-apply.sh
new file mode 100755
index 0000000000..781fe315ed
--- /dev/null
+++ b/contrib/macdeploy/detached-sig-apply.sh
@@ -0,0 +1,52 @@
+#!/bin/sh
+set -e
+
+UNSIGNED="$1"
+SIGNATURE="$2"
+ARCH=x86_64
+ROOTDIR=dist
+TEMPDIR=signed.temp
+OUTDIR=signed-app
+
+if [ -z "$UNSIGNED" ]; then
+ echo "usage: $0 <unsigned app> <signature>"
+ exit 1
+fi
+
+if [ -z "$SIGNATURE" ]; then
+ echo "usage: $0 <unsigned app> <signature>"
+ exit 1
+fi
+
+rm -rf ${TEMPDIR} && mkdir -p ${TEMPDIR}
+tar -C ${TEMPDIR} -xf ${UNSIGNED}
+cp -rf "${SIGNATURE}"/* ${TEMPDIR}
+
+if [ -z "${PAGESTUFF}" ]; then
+ PAGESTUFF=${TEMPDIR}/pagestuff
+fi
+
+if [ -z "${CODESIGN_ALLOCATE}" ]; then
+ CODESIGN_ALLOCATE=${TEMPDIR}/codesign_allocate
+fi
+
+find ${TEMPDIR} -name "*.sign" | while read i; do
+ SIZE=`stat -c %s "${i}"`
+ TARGET_FILE="`echo "${i}" | sed 's/\.sign$//'`"
+
+ echo "Allocating space for the signature of size ${SIZE} in ${TARGET_FILE}"
+ ${CODESIGN_ALLOCATE} -i "${TARGET_FILE}" -a ${ARCH} ${SIZE} -o "${i}.tmp"
+
+ OFFSET=`${PAGESTUFF} "${i}.tmp" -p | tail -2 | grep offset | sed 's/[^0-9]*//g'`
+ if [ -z ${QUIET} ]; then
+ echo "Attaching signature at offset ${OFFSET}"
+ fi
+
+ dd if="$i" of="${i}.tmp" bs=1 seek=${OFFSET} count=${SIZE} 2>/dev/null
+ mv "${i}.tmp" "${TARGET_FILE}"
+ rm "${i}"
+ echo "Success."
+done
+mv ${TEMPDIR}/${ROOTDIR} ${OUTDIR}
+rm -rf ${TEMPDIR}
+echo "Signed: ${OUTDIR}"
diff --git a/contrib/macdeploy/detached-sig-create.sh b/contrib/macdeploy/detached-sig-create.sh
new file mode 100755
index 0000000000..89a2da32f7
--- /dev/null
+++ b/contrib/macdeploy/detached-sig-create.sh
@@ -0,0 +1,47 @@
+#!/bin/sh
+set -e
+
+ROOTDIR=dist
+BUNDLE="${ROOTDIR}/Bitcoin-Qt.app"
+CODESIGN=codesign
+TEMPDIR=sign.temp
+TEMPLIST=${TEMPDIR}/signatures.txt
+OUT=signature.tar.gz
+OUTROOT=osx
+
+if [ ! -n "$1" ]; then
+ echo "usage: $0 <codesign args>"
+ echo "example: $0 -s MyIdentity"
+ exit 1
+fi
+
+rm -rf ${TEMPDIR} ${TEMPLIST}
+mkdir -p ${TEMPDIR}
+
+${CODESIGN} -f --file-list ${TEMPLIST} "$@" "${BUNDLE}"
+
+grep -v CodeResources < "${TEMPLIST}" | while read i; do
+ TARGETFILE="${BUNDLE}/`echo "${i}" | sed "s|.*${BUNDLE}/||"`"
+ SIZE=`pagestuff "$i" -p | tail -2 | grep size | sed 's/[^0-9]*//g'`
+ OFFSET=`pagestuff "$i" -p | tail -2 | grep offset | sed 's/[^0-9]*//g'`
+ SIGNFILE="${TEMPDIR}/${OUTROOT}/${TARGETFILE}.sign"
+ DIRNAME="`dirname "${SIGNFILE}"`"
+ mkdir -p "${DIRNAME}"
+ echo "Adding detached signature for: ${TARGETFILE}. Size: ${SIZE}. Offset: ${OFFSET}"
+ dd if="$i" of="${SIGNFILE}" bs=1 skip=${OFFSET} count=${SIZE} 2>/dev/null
+done
+
+grep CodeResources < "${TEMPLIST}" | while read i; do
+ TARGETFILE="${BUNDLE}/`echo "${i}" | sed "s|.*${BUNDLE}/||"`"
+ RESOURCE="${TEMPDIR}/${OUTROOT}/${TARGETFILE}"
+ DIRNAME="`dirname "${RESOURCE}"`"
+ mkdir -p "${DIRNAME}"
+ echo "Adding resource for: "${TARGETFILE}""
+ cp "${i}" "${RESOURCE}"
+done
+
+rm ${TEMPLIST}
+
+tar -C "${TEMPDIR}" -czf "${OUT}" .
+rm -rf "${TEMPDIR}"
+echo "Created ${OUT}"
diff --git a/contrib/macdeploy/fancy.plist b/contrib/macdeploy/fancy.plist
new file mode 100644
index 0000000000..ef277a7f14
--- /dev/null
+++ b/contrib/macdeploy/fancy.plist
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>window_bounds</key>
+ <array>
+ <integer>300</integer>
+ <integer>300</integer>
+ <integer>800</integer>
+ <integer>620</integer>
+ </array>
+ <key>background_picture</key>
+ <string>background.tiff</string>
+ <key>icon_size</key>
+ <integer>96</integer>
+ <key>applications_symlink</key>
+ <true/>
+ <key>items_position</key>
+ <dict>
+ <key>Applications</key>
+ <array>
+ <integer>370</integer>
+ <integer>156</integer>
+ </array>
+ <key>Bitcoin-Qt.app</key>
+ <array>
+ <integer>128</integer>
+ <integer>156</integer>
+ </array>
+ </dict>
+</dict>
+</plist>
diff --git a/contrib/macdeploy/macdeployqtplus b/contrib/macdeploy/macdeployqtplus
new file mode 100755
index 0000000000..2253c40af1
--- /dev/null
+++ b/contrib/macdeploy/macdeployqtplus
@@ -0,0 +1,883 @@
+#!/usr/bin/env python
+
+#
+# Copyright (C) 2011 Patrick "p2k" Schneider <me@p2k-network.org>
+#
+# 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 <http://www.gnu.org/licenses/>.
+#
+
+import subprocess, sys, re, os, shutil, stat, os.path, time
+from string import Template
+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.sourceVersionContentsDirectory = ""
+ self.sourceContentsDirectory = ""
+ self.destinationResourcesDirectory = ""
+ self.destinationVersionContentsDirectory = ""
+
+ 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.sourceContentsDirectory = os.path.join(info.frameworkPath, "Contents")
+ info.sourceVersionContentsDirectory = os.path.join(info.frameworkPath, "Versions", info.version, "Contents")
+ info.destinationResourcesDirectory = os.path.join(cls.bundleFrameworkDirectory, info.frameworkName, "Resources")
+ info.destinationContentsDirectory = os.path.join(cls.bundleFrameworkDirectory, info.frameworkName, "Contents")
+ info.destinationVersionContentsDirectory = os.path.join(cls.bundleFrameworkDirectory, info.frameworkName, "Versions", info.version, "Contents")
+
+ return info
+
+class ApplicationBundleInfo(object):
+ def __init__(self, path):
+ self.path = path
+ appName = "Bitcoin-Qt"
+ 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")
+ elif os.path.exists(os.path.join(os.path.dirname(parentDir), "share", "qt4", "translations")):
+ # Newer Macports layout
+ self.qtPath = os.path.join(os.path.dirname(parentDir), "share", "qt4")
+ else:
+ self.qtPath = os.getenv("QTDIR", None)
+
+ 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
+ otoolbin=os.getenv("OTOOL", "otool")
+ otool = subprocess.Popen([otoolbin, "-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:
+ line = line.replace("@loader_path", os.path.dirname(binaryPath))
+ 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):
+ installnametoolbin=os.getenv("INSTALLNAMETOOL", "install_name_tool")
+ subprocess.check_call([installnametoolbin, "-"+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):
+ stripbin=os.getenv("STRIP", "strip")
+ if verbose >= 3:
+ print "Using strip:"
+ print " stripped", binaryPath
+ subprocess.check_call([stripbin, "-x", binaryPath])
+
+def copyFramework(framework, path, verbose):
+ if framework.sourceFilePath.startswith("Qt"):
+ #standard place for Nokia Qt installer's frameworks
+ fromPath = "/Library/Frameworks/" + framework.sourceFilePath
+ else:
+ 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
+
+ linkfrom = os.path.join(path, "Contents","Frameworks", framework.frameworkName, "Versions", "Current")
+ linkto = framework.version
+ if not os.path.exists(linkfrom):
+ os.symlink(linkto, linkfrom)
+ if verbose >= 2:
+ print "Linked:", linkfrom, "->", linkto
+ fromResourcesDir = framework.sourceResourcesDirectory
+ if os.path.exists(fromResourcesDir):
+ toResourcesDir = os.path.join(path, framework.destinationResourcesDirectory)
+ shutil.copytree(fromResourcesDir, toResourcesDir, symlinks=True)
+ if verbose >= 3:
+ print "Copied resources:", fromResourcesDir
+ print " to:", toResourcesDir
+ fromContentsDir = framework.sourceVersionContentsDirectory
+ if not os.path.exists(fromContentsDir):
+ fromContentsDir = framework.sourceContentsDirectory
+ if os.path.exists(fromContentsDir):
+ toContentsDir = os.path.join(path, framework.destinationVersionContentsDirectory)
+ shutil.copytree(fromContentsDir, toContentsDir, symlinks=True)
+ contentslinkfrom = os.path.join(path, framework.destinationContentsDirectory)
+ if verbose >= 3:
+ print "Copied Contents:", fromContentsDir
+ print " to:", toContentsDir
+ 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, symlinks=True)
+ 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") or framework.installName.startswith(bundlePath):
+ 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 = []
+ if deploymentInfo.pluginPath is None:
+ return
+ 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" or pluginDirectory == "phonon_backend":
+ # 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" or pluginDirectory == "qml1tooling":
+ # 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
+ elif pluginDirectory == "position":
+ # Deploy the position plugins only if QtPositioning is in use
+ if not deploymentInfo.usesFramework("QtPositioning"):
+ continue
+ elif pluginDirectory == "sensors" or pluginDirectory == "sensorgestures":
+ # Deploy the sensor plugins only if QtSensors is in use
+ if not deploymentInfo.usesFramework("QtSensors"):
+ continue
+ elif pluginDirectory == "audio" or pluginDirectory == "playlistformats":
+ # Deploy the audio plugins only if QtMultimedia is in use
+ if not deploymentInfo.usesFramework("QtMultimedia"):
+ continue
+ elif pluginDirectory == "mediaservice":
+ # Deploy the mediaservice plugins only if QtMultimediaWidgets is in use
+ if not deploymentInfo.usesFramework("QtMultimediaWidgets"):
+ 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
+ elif pluginPath == "accessible/libqtaccessiblequick.dylib":
+ # Deploy the accessible qtquick plugin only if QtQuick is in use
+ if not deploymentInfo.usesFramework("QtQuick"):
+ 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.
+
+Also optionally signs the .app bundle; set the CODESIGNARGS environment variable to pass arguments
+to the codesign tool.
+E.g. CODESIGNARGS='--sign "Developer ID Application: ..." --keychain /encrypted/foo.keychain'""")
+
+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("-sign", dest="sign", action="store_true", default=False, help="sign .app bundle with codesign tool")
+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("-translations-dir", nargs=1, metavar="path", default=None, help="Path to Qt's translation files")
+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]
+
+# ------------------------------------------------
+translations_dir = None
+if config.translations_dir and config.translations_dir[0]:
+ if os.path.exists(config.translations_dir[0]):
+ translations_dir = config.translations_dir[0]
+ else:
+ if verbose >= 1:
+ sys.stderr.write("Error: Could not find translation dir \"%s\"\n" % (translations_dir))
+ sys.exit(1)
+# ------------------------------------------------
+
+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)
+
+ 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", "Bitcoin-Qt.app")
+
+if verbose >= 2:
+ print "+ Copying source bundle +"
+if verbose >= 3:
+ print app_bundle, "->", target
+
+os.mkdir("dist")
+shutil.copytree(app_bundle, target, symlinks=True)
+
+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(1)
+
+# ------------------------------------------------
+
+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(1)
+
+# ------------------------------------------------
+
+if len(config.add_qt_tr) == 0:
+ add_qt_tr = []
+else:
+ if translations_dir is not None:
+ qt_tr_dir = translations_dir
+ else:
+ if deploymentInfo.qtPath is not None:
+ qt_tr_dir = os.path.join(deploymentInfo.qtPath, "translations")
+ else:
+ sys.stderr.write("Error: Could not find Qt translation path\n")
+ sys.exit(1)
+ 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, symlinks=True)
+ else:
+ shutil.copy2(p, t)
+
+# ------------------------------------------------
+
+if config.sign and 'CODESIGNARGS' not in os.environ:
+ print "You must set the CODESIGNARGS environment variable. Skipping signing."
+elif config.sign:
+ if verbose >= 1:
+ print "Code-signing app bundle %s"%(target,)
+ subprocess.check_call("codesign --force %s %s"%(os.environ['CODESIGNARGS'], target), shell=True)
+
+# ------------------------------------------------
+
+if config.dmg is not None:
+
+ #Patch in check_output for Python 2.6
+ if "check_output" not in dir( subprocess ):
+ def f(*popenargs, **kwargs):
+ if 'stdout' in kwargs:
+ raise ValueError('stdout argument not allowed, it will be overridden.')
+ process = subprocess.Popen(stdout=subprocess.PIPE, *popenargs, **kwargs)
+ output, unused_err = process.communicate()
+ retcode = process.poll()
+ if retcode:
+ cmd = kwargs.get("args")
+ if cmd is None:
+ cmd = popenargs[0]
+ raise CalledProcessError(retcode, cmd)
+ return output
+ subprocess.check_output = f
+
+ 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="Bitcoin-Core", 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.15)
+
+ if verbose >= 3:
+ print "Creating temp image for modification..."
+ try:
+ runHDIUtil("create", dmg_name + ".temp", srcfolder="dist", format="UDRW", size=size, volname="Bitcoin-Core", 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, ".background", os.path.basename(fancy["background_picture"]))
+ os.mkdir(os.path.dirname(bg_path))
+ 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"))
+
+ # The Python appscript package broke with OSX 10.8 and isn't being fixed.
+ # So we now build up an AppleScript string and use the osascript command
+ # to make the .dmg file pretty:
+ appscript = Template( """
+ on run argv
+ tell application "Finder"
+ tell disk "$disk"
+ open
+ set current view of container window to icon view
+ set toolbar visible of container window to false
+ set statusbar visible of container window to false
+ set the bounds of container window to {$window_bounds}
+ set theViewOptions to the icon view options of container window
+ set arrangement of theViewOptions to not arranged
+ set icon size of theViewOptions to $icon_size
+ $background_commands
+ $items_positions
+ close -- close/reopen works around a bug...
+ open
+ update without registering applications
+ delay 5
+ eject
+ end tell
+ end tell
+ end run
+ """)
+
+ itemscript = Template('set position of item "${item}" of container window to {${position}}')
+ items_positions = []
+ if fancy.has_key("items_position"):
+ for name, position in fancy["items_position"].iteritems():
+ params = { "item" : name, "position" : ",".join([str(p) for p in position]) }
+ items_positions.append(itemscript.substitute(params))
+
+ params = {
+ "disk" : "Bitcoin-Core",
+ "window_bounds" : "300,300,800,620",
+ "icon_size" : "96",
+ "background_commands" : "",
+ "items_positions" : "\n ".join(items_positions)
+ }
+ if fancy.has_key("window_bounds"):
+ params["window.bounds"] = ",".join([str(p) for p in fancy["window_bounds"]])
+ if fancy.has_key("icon_size"):
+ params["icon_size"] = str(fancy["icon_size"])
+ if bg_path is not None:
+ # Set background file, then call SetFile to make it invisible.
+ # (note: making it invisible first makes set background picture fail)
+ bgscript = Template("""set background picture of theViewOptions to file ".background:$bgpic"
+ do shell script "SetFile -a V /Volumes/$disk/.background/$bgpic" """)
+ params["background_commands"] = bgscript.substitute({"bgpic" : os.path.basename(bg_path), "disk" : params["disk"]})
+
+ s = appscript.substitute(params)
+ if verbose >= 2:
+ print("Running AppleScript:")
+ print(s)
+
+ p = subprocess.Popen(['osascript', '-'], stdin=subprocess.PIPE)
+ p.communicate(input=s)
+ if p.returncode:
+ print("Error running osascript.")
+
+ if verbose >= 2:
+ print "+ Finalizing .dmg disk image +"
+ time.sleep(5)
+
+ 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/qos/README.md b/contrib/qos/README.md
new file mode 100644
index 0000000000..5e0a975fc6
--- /dev/null
+++ b/contrib/qos/README.md
@@ -0,0 +1,5 @@
+### Qos ###
+
+This is a Linux bash script that will set up tc to limit the outgoing bandwidth for connections to the Bitcoin network. It limits outbound TCP traffic with a source or destination port of 8333, but not if the destination IP is within a LAN (defined as 192.168.x.x).
+
+This means one can have an always-on bitcoind instance running, and another local bitcoind/bitcoin-qt instance which connects to this node and receives blocks from it.
diff --git a/contrib/qos/tc.sh b/contrib/qos/tc.sh
new file mode 100644
index 0000000000..f620604212
--- /dev/null
+++ b/contrib/qos/tc.sh
@@ -0,0 +1,41 @@
+#network interface on which to limit traffic
+IF="eth0"
+#limit of the network interface in question
+LINKCEIL="1gbit"
+#limit outbound Bitcoin protocol traffic to this rate
+LIMIT="160kbit"
+#defines the address space for which you wish to disable rate limiting
+LOCALNET="192.168.0.0/16"
+
+#delete existing rules
+tc qdisc del dev ${IF} root
+
+#add root class
+tc qdisc add dev ${IF} root handle 1: htb default 10
+
+#add parent class
+tc class add dev ${IF} parent 1: classid 1:1 htb rate ${LINKCEIL} ceil ${LINKCEIL}
+
+#add our two classes. one unlimited, another limited
+tc class add dev ${IF} parent 1:1 classid 1:10 htb rate ${LINKCEIL} ceil ${LINKCEIL} prio 0
+tc class add dev ${IF} parent 1:1 classid 1:11 htb rate ${LIMIT} ceil ${LIMIT} prio 1
+
+#add handles to our classes so packets marked with <x> go into the class with "... handle <x> fw ..."
+tc filter add dev ${IF} parent 1: protocol ip prio 1 handle 1 fw classid 1:10
+tc filter add dev ${IF} parent 1: protocol ip prio 2 handle 2 fw classid 1:11
+
+#delete any existing rules
+#disable for now
+#ret=0
+#while [ $ret -eq 0 ]; do
+# iptables -t mangle -D OUTPUT 1
+# ret=$?
+#done
+
+#limit outgoing traffic to and from port 8333. but not when dealing with a host on the local network
+# (defined by $LOCALNET)
+# --set-mark marks packages matching these criteria with the number "2"
+# these packages are filtered by the tc filter with "handle 2"
+# this filter sends the packages into the 1:11 class, and this class is limited to ${LIMIT}
+iptables -t mangle -A OUTPUT -p tcp -m tcp --dport 8333 ! -d ${LOCALNET} -j MARK --set-mark 0x2
+iptables -t mangle -A OUTPUT -p tcp -m tcp --sport 8333 ! -d ${LOCALNET} -j MARK --set-mark 0x2
diff --git a/contrib/qt_translations.py b/contrib/qt_translations.py
new file mode 100755
index 0000000000..fd8a8b7129
--- /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/seeds/README.md b/contrib/seeds/README.md
new file mode 100644
index 0000000000..63647fa11a
--- /dev/null
+++ b/contrib/seeds/README.md
@@ -0,0 +1,8 @@
+### Seeds ###
+
+Utility to generate the seeds.txt list that is compiled into the client
+(see [src/chainparamsseeds.h](/src/chainparamsseeds.h) and other utilities in [contrib/seeds](/contrib/seeds)).
+
+The 512 seeds compiled into the 0.10 release were created from sipa's DNS seed data, like this:
+
+ curl -s http://bitcoin.sipa.be/seeds.txt | makeseeds.py
diff --git a/contrib/seeds/generate-seeds.py b/contrib/seeds/generate-seeds.py
new file mode 100755
index 0000000000..167c219c6e
--- /dev/null
+++ b/contrib/seeds/generate-seeds.py
@@ -0,0 +1,138 @@
+#!/usr/bin/python
+# Copyright (c) 2014 Wladmir J. van der Laan
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+'''
+Script to generate list of seed nodes for chainparams.cpp.
+
+This script expects two text files in the directory that is passed as an
+argument:
+
+ nodes_main.txt
+ nodes_test.txt
+
+These files must consist of lines in the format
+
+ <ip>
+ <ip>:<port>
+ [<ipv6>]
+ [<ipv6>]:<port>
+ <onion>.onion
+ 0xDDBBCCAA (IPv4 little-endian old pnSeeds format)
+
+The output will be two data structures with the peers in binary format:
+
+ static SeedSpec6 pnSeed6_main[]={
+ ...
+ }
+ static SeedSpec6 pnSeed6_test[]={
+ ...
+ }
+
+These should be pasted into `src/chainparamsseeds.h`.
+'''
+from __future__ import print_function, division
+from base64 import b32decode
+from binascii import a2b_hex
+import sys, os
+import re
+
+# ipv4 in ipv6 prefix
+pchIPv4 = bytearray([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff])
+# tor-specific ipv6 prefix
+pchOnionCat = bytearray([0xFD,0x87,0xD8,0x7E,0xEB,0x43])
+
+def name_to_ipv6(addr):
+ if len(addr)>6 and addr.endswith('.onion'):
+ vchAddr = b32decode(addr[0:-6], True)
+ if len(vchAddr) != 16-len(pchOnionCat):
+ raise ValueError('Invalid onion %s' % s)
+ return pchOnionCat + vchAddr
+ elif '.' in addr: # IPv4
+ return pchIPv4 + bytearray((int(x) for x in addr.split('.')))
+ elif ':' in addr: # IPv6
+ sub = [[], []] # prefix, suffix
+ x = 0
+ addr = addr.split(':')
+ for i,comp in enumerate(addr):
+ if comp == '':
+ if i == 0 or i == (len(addr)-1): # skip empty component at beginning or end
+ continue
+ x += 1 # :: skips to suffix
+ assert(x < 2)
+ else: # two bytes per component
+ val = int(comp, 16)
+ sub[x].append(val >> 8)
+ sub[x].append(val & 0xff)
+ nullbytes = 16 - len(sub[0]) - len(sub[1])
+ assert((x == 0 and nullbytes == 0) or (x == 1 and nullbytes > 0))
+ return bytearray(sub[0] + ([0] * nullbytes) + sub[1])
+ elif addr.startswith('0x'): # IPv4-in-little-endian
+ return pchIPv4 + bytearray(reversed(a2b_hex(addr[2:])))
+ else:
+ raise ValueError('Could not parse address %s' % addr)
+
+def parse_spec(s, defaultport):
+ match = re.match('\[([0-9a-fA-F:]+)\](?::([0-9]+))?$', s)
+ if match: # ipv6
+ host = match.group(1)
+ port = match.group(2)
+ elif s.count(':') > 1: # ipv6, no port
+ host = s
+ port = ''
+ else:
+ (host,_,port) = s.partition(':')
+
+ if not port:
+ port = defaultport
+ else:
+ port = int(port)
+
+ host = name_to_ipv6(host)
+
+ return (host,port)
+
+def process_nodes(g, f, structname, defaultport):
+ g.write('static SeedSpec6 %s[] = {\n' % structname)
+ first = True
+ for line in f:
+ comment = line.find('#')
+ if comment != -1:
+ line = line[0:comment]
+ line = line.strip()
+ if not line:
+ continue
+ if not first:
+ g.write(',\n')
+ first = False
+
+ (host,port) = parse_spec(line, defaultport)
+ hoststr = ','.join(('0x%02x' % b) for b in host)
+ g.write(' {{%s}, %i}' % (hoststr, port))
+ g.write('\n};\n')
+
+def main():
+ if len(sys.argv)<2:
+ print(('Usage: %s <path_to_nodes_txt>' % sys.argv[0]), file=sys.stderr)
+ exit(1)
+ g = sys.stdout
+ indir = sys.argv[1]
+ g.write('#ifndef BITCOIN_CHAINPARAMSSEEDS_H\n')
+ g.write('#define BITCOIN_CHAINPARAMSSEEDS_H\n')
+ g.write('/**\n')
+ g.write(' * List of fixed seed nodes for the bitcoin network\n')
+ g.write(' * AUTOGENERATED by contrib/seeds/generate-seeds.py\n')
+ g.write(' *\n')
+ g.write(' * Each line contains a 16-byte IPv6 address and a port.\n')
+ g.write(' * IPv4 as well as onion addresses are wrapped inside a IPv6 address accordingly.\n')
+ g.write(' */\n')
+ with open(os.path.join(indir,'nodes_main.txt'),'r') as f:
+ process_nodes(g, f, 'pnSeed6_main', 8333)
+ g.write('\n')
+ with open(os.path.join(indir,'nodes_test.txt'),'r') as f:
+ process_nodes(g, f, 'pnSeed6_test', 18333)
+ g.write('#endif // BITCOIN_CHAINPARAMSSEEDS_H\n')
+
+if __name__ == '__main__':
+ main()
+
diff --git a/contrib/seeds/makeseeds.py b/contrib/seeds/makeseeds.py
new file mode 100755
index 0000000000..4072405ef5
--- /dev/null
+++ b/contrib/seeds/makeseeds.py
@@ -0,0 +1,169 @@
+#!/usr/bin/env python
+#
+# Generate seeds.txt from Pieter's DNS seeder
+#
+
+NSEEDS=512
+
+MAX_SEEDS_PER_ASN=2
+
+MIN_BLOCKS = 337600
+
+# These are hosts that have been observed to be behaving strangely (e.g.
+# aggressively connecting to every node).
+SUSPICIOUS_HOSTS = set([
+ "130.211.129.106", "178.63.107.226",
+ "83.81.130.26", "88.198.17.7", "148.251.238.178", "176.9.46.6",
+ "54.173.72.127", "54.174.10.182", "54.183.64.54", "54.194.231.211",
+ "54.66.214.167", "54.66.220.137", "54.67.33.14", "54.77.251.214",
+ "54.94.195.96", "54.94.200.247"
+])
+
+import re
+import sys
+import dns.resolver
+import collections
+
+PATTERN_IPV4 = re.compile(r"^((\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})):(\d+)$")
+PATTERN_IPV6 = re.compile(r"^\[([0-9a-z:]+)\]:(\d+)$")
+PATTERN_ONION = re.compile(r"^([abcdefghijklmnopqrstuvwxyz234567]{16}\.onion):(\d+)$")
+PATTERN_AGENT = re.compile(r"^(\/Satoshi:0\.8\.6\/|\/Satoshi:0\.9\.(2|3|4|5)\/|\/Satoshi:0\.10\.\d{1,2}\/|\/Satoshi:0\.11\.\d{1,2}\/)$")
+
+def parseline(line):
+ sline = line.split()
+ if len(sline) < 11:
+ return None
+ m = PATTERN_IPV4.match(sline[0])
+ sortkey = None
+ ip = None
+ if m is None:
+ m = PATTERN_IPV6.match(sline[0])
+ if m is None:
+ m = PATTERN_ONION.match(sline[0])
+ if m is None:
+ return None
+ else:
+ net = 'onion'
+ ipstr = sortkey = m.group(1)
+ port = int(m.group(2))
+ else:
+ net = 'ipv6'
+ if m.group(1) in ['::']: # Not interested in localhost
+ return None
+ ipstr = m.group(1)
+ sortkey = ipstr # XXX parse IPv6 into number, could use name_to_ipv6 from generate-seeds
+ port = int(m.group(2))
+ else:
+ # Do IPv4 sanity check
+ ip = 0
+ for i in range(0,4):
+ if int(m.group(i+2)) < 0 or int(m.group(i+2)) > 255:
+ return None
+ ip = ip + (int(m.group(i+2)) << (8*(3-i)))
+ if ip == 0:
+ return None
+ net = 'ipv4'
+ sortkey = ip
+ ipstr = m.group(1)
+ port = int(m.group(6))
+ # Skip bad results.
+ if sline[1] == 0:
+ return None
+ # Extract uptime %.
+ uptime30 = float(sline[7][:-1])
+ # Extract Unix timestamp of last success.
+ lastsuccess = int(sline[2])
+ # Extract protocol version.
+ version = int(sline[10])
+ # Extract user agent.
+ agent = sline[11][1:-1]
+ # Extract service flags.
+ service = int(sline[9], 16)
+ # Extract blocks.
+ blocks = int(sline[8])
+ # Construct result.
+ return {
+ 'net': net,
+ 'ip': ipstr,
+ 'port': port,
+ 'ipnum': ip,
+ 'uptime': uptime30,
+ 'lastsuccess': lastsuccess,
+ 'version': version,
+ 'agent': agent,
+ 'service': service,
+ 'blocks': blocks,
+ 'sortkey': sortkey,
+ }
+
+def filtermultiport(ips):
+ '''Filter out hosts with more nodes per IP'''
+ hist = collections.defaultdict(list)
+ for ip in ips:
+ hist[ip['sortkey']].append(ip)
+ return [value[0] for (key,value) in hist.items() if len(value)==1]
+
+# Based on Greg Maxwell's seed_filter.py
+def filterbyasn(ips, max_per_asn, max_total):
+ # Sift out ips by type
+ ips_ipv4 = [ip for ip in ips if ip['net'] == 'ipv4']
+ ips_ipv6 = [ip for ip in ips if ip['net'] == 'ipv6']
+ ips_onion = [ip for ip in ips if ip['net'] == 'onion']
+
+ # Filter IPv4 by ASN
+ result = []
+ asn_count = {}
+ for ip in ips_ipv4:
+ if len(result) == max_total:
+ break
+ try:
+ asn = int([x.to_text() for x in dns.resolver.query('.'.join(reversed(ip['ip'].split('.'))) + '.origin.asn.cymru.com', 'TXT').response.answer][0].split('\"')[1].split(' ')[0])
+ if asn not in asn_count:
+ asn_count[asn] = 0
+ if asn_count[asn] == max_per_asn:
+ continue
+ asn_count[asn] += 1
+ result.append(ip)
+ except:
+ sys.stderr.write('ERR: Could not resolve ASN for "' + ip['ip'] + '"\n')
+
+ # TODO: filter IPv6 by ASN
+
+ # Add back non-IPv4
+ result.extend(ips_ipv6)
+ result.extend(ips_onion)
+ return result
+
+def main():
+ lines = sys.stdin.readlines()
+ ips = [parseline(line) for line in lines]
+
+ # Skip entries with valid address.
+ ips = [ip for ip in ips if ip is not None]
+ # Skip entries from suspicious hosts.
+ ips = [ip for ip in ips if ip['ip'] not in SUSPICIOUS_HOSTS]
+ # Enforce minimal number of blocks.
+ ips = [ip for ip in ips if ip['blocks'] >= MIN_BLOCKS]
+ # Require service bit 1.
+ ips = [ip for ip in ips if (ip['service'] & 1) == 1]
+ # Require at least 50% 30-day uptime.
+ ips = [ip for ip in ips if ip['uptime'] > 50]
+ # Require a known and recent user agent.
+ ips = [ip for ip in ips if PATTERN_AGENT.match(ip['agent'])]
+ # Sort by availability (and use last success as tie breaker)
+ ips.sort(key=lambda x: (x['uptime'], x['lastsuccess'], x['ip']), reverse=True)
+ # Filter out hosts with multiple bitcoin ports, these are likely abusive
+ ips = filtermultiport(ips)
+ # Look up ASNs and limit results, both per ASN and globally.
+ ips = filterbyasn(ips, MAX_SEEDS_PER_ASN, NSEEDS)
+ # Sort the results by IP address (for deterministic output).
+ ips.sort(key=lambda x: (x['net'], x['sortkey']))
+
+ for ip in ips:
+ if ip['net'] == 'ipv6':
+ print '[%s]:%i' % (ip['ip'], ip['port'])
+ else:
+ print '%s:%i' % (ip['ip'], ip['port'])
+
+if __name__ == '__main__':
+ main()
diff --git a/contrib/seeds/nodes_main.txt b/contrib/seeds/nodes_main.txt
new file mode 100644
index 0000000000..17339d514a
--- /dev/null
+++ b/contrib/seeds/nodes_main.txt
@@ -0,0 +1,879 @@
+1.34.168.128:8333
+1.202.128.218:8333
+2.30.0.210:8333
+5.9.96.203:8333
+5.45.71.130:8333
+5.45.98.141:8333
+5.102.145.68:8333
+5.135.160.77:8333
+5.189.134.246:8333
+5.199.164.132:8333
+5.249.135.102:8333
+8.19.44.110:8333
+8.22.230.8:8333
+14.200.200.145:8333
+18.228.0.188:8333
+18.228.0.200:8333
+23.24.168.97:8333
+23.28.35.227:8333
+23.92.76.170:8333
+23.99.64.119:8333
+23.228.166.128:8333
+23.229.45.32:8333
+24.8.105.128:8333
+24.16.69.137:8333
+24.94.98.96:8333
+24.102.118.7:8333
+24.118.166.228:8333
+24.122.133.49:8333
+24.166.97.162:8333
+24.213.235.242:8333
+24.226.107.64:8333
+24.228.192.171:8333
+27.140.133.18:8333
+31.41.40.25:8333
+31.43.101.59:8333
+31.184.195.181:8333
+31.193.139.66:8333
+37.200.70.102:8333
+37.205.10.151:8333
+42.3.106.227:8333
+42.60.133.106:8333
+45.56.85.231:8333
+45.56.102.228:8333
+45.79.130.235:8333
+46.28.204.61:11101
+46.38.235.229:8333
+46.59.2.74:8333
+46.101.132.37:8333
+46.101.168.50:8333
+46.163.76.230:8333
+46.166.161.103:8333
+46.182.132.100:8333
+46.223.36.94:8333
+46.227.66.132:8333
+46.227.66.138:8333
+46.239.107.74:8333
+46.249.39.100:8333
+46.250.98.108:8333
+50.7.37.114:8333
+50.81.53.151:8333
+50.115.43.253:8333
+50.116.20.87:8333
+50.116.33.92:8333
+50.125.167.245:8333
+50.143.9.51:8333
+50.188.192.133:8333
+54.77.162.76:8333
+54.153.97.109:8333
+54.165.192.125:8333
+58.96.105.85:8333
+59.167.196.135:8333
+60.29.227.163:8333
+61.35.225.19:8333
+62.43.130.178:8333
+62.109.49.26:8333
+62.202.0.97:8333
+62.210.66.227:8333
+62.210.192.169:8333
+64.74.98.205:8333
+64.156.193.100:8333
+64.203.102.86:8333
+64.229.142.48:8333
+65.96.193.165:8333
+66.30.3.7:8333
+66.114.33.49:8333
+66.118.133.194:8333
+66.135.10.126:8333
+66.172.10.4:8333
+66.194.38.250:8333
+66.194.38.253:8333
+66.215.192.104:8333
+67.60.98.115:8333
+67.164.35.36:8333
+67.191.162.244:8333
+67.207.195.77:8333
+67.219.233.140:8333
+67.221.193.55:8333
+67.228.162.228:8333
+68.50.67.199:8333
+68.62.3.203:8333
+68.65.205.226:9000
+68.106.42.191:8333
+68.150.181.198:8333
+68.196.196.106:8333
+68.224.194.81:8333
+69.46.5.194:8333
+69.50.171.238:8333
+69.64.43.152:8333
+69.65.41.13:8333
+69.90.132.200:8333
+69.143.1.243:8333
+69.146.98.216:8333
+69.165.246.38:8333
+69.207.6.135:8333
+69.251.208.26:8333
+70.38.1.101:8333
+70.38.9.66:8333
+70.90.2.18:8333
+71.58.228.226:8333
+71.199.11.189:8333
+71.199.193.202:8333
+71.205.232.181:8333
+71.236.200.162:8333
+72.24.73.186:8333
+72.52.130.110:8333
+72.53.111.37:8333
+72.235.38.70:8333
+73.31.171.149:8333
+73.32.137.72:8333
+73.137.133.238:8333
+73.181.192.103:8333
+73.190.2.60:8333
+73.195.192.137:8333
+73.222.35.117:8333
+74.57.199.180:8333
+74.82.233.205:8333
+74.85.66.82:8333
+74.101.224.127:8333
+74.113.69.16:8333
+74.122.235.68:8333
+74.193.68.141:8333
+74.208.164.219:8333
+75.100.37.122:8333
+75.145.149.169:8333
+75.168.34.20:8333
+76.20.44.240:8333
+76.100.70.17:8333
+76.168.3.239:8333
+76.186.140.103:8333
+77.92.68.221:8333
+77.109.101.142:8333
+77.110.11.86:8333
+77.242.108.18:8333
+78.46.96.150:9020
+78.84.100.95:8333
+79.132.230.144:8333
+79.133.43.63:8333
+79.160.76.153:8333
+79.169.34.24:8333
+79.188.7.78:8333
+80.217.226.25:8333
+80.223.100.179:8333
+80.240.129.221:8333
+81.1.173.243:8333
+81.7.11.50:8333
+81.7.16.17:8333
+81.66.111.3:8333
+81.80.9.71:8333
+81.140.43.138:8333
+81.171.34.37:8333
+81.174.247.50:8333
+81.181.155.53:8333
+81.184.5.253:8333
+81.187.69.130:8333
+81.230.3.84:8333
+82.42.128.51:8333
+82.74.226.21:8333
+82.142.75.50:8333
+82.199.102.10:8333
+82.200.205.30:8333
+82.221.108.21:8333
+82.221.128.35:8333
+82.238.124.41:8333
+82.242.0.245:8333
+83.76.123.110:8333
+83.150.9.196:8333
+83.162.196.192:8333
+83.162.234.224:8333
+83.170.104.91:8333
+83.255.66.118:8334
+84.2.34.104:8333
+84.45.98.91:8333
+84.47.161.150:8333
+84.212.192.131:8333
+84.215.169.101:8333
+84.238.140.176:8333
+84.245.71.31:8333
+85.17.4.212:8333
+85.114.128.134:8333
+85.159.237.191:8333
+85.166.130.189:8333
+85.199.4.228:8333
+85.214.66.168:8333
+85.214.195.210:8333
+85.229.0.73:8333
+86.21.96.45:8333
+87.48.42.199:8333
+87.81.143.82:8333
+87.81.251.72:8333
+87.104.24.185:8333
+87.104.168.104:8333
+87.117.234.71:8333
+87.118.96.197:8333
+87.145.12.57:8333
+87.159.170.190:8333
+88.150.168.160:8333
+88.208.0.79:8333
+88.208.0.149:8333
+88.214.194.226:8343
+89.1.11.32:8333
+89.36.235.108:8333
+89.67.96.2:15321
+89.98.16.41:8333
+89.108.72.195:8333
+89.156.35.157:8333
+89.163.227.28:8333
+89.212.33.237:8333
+89.212.160.165:8333
+89.231.96.83:8333
+89.248.164.64:8333
+90.149.193.199:8333
+91.77.239.245:8333
+91.106.194.97:8333
+91.126.77.77:8333
+91.134.38.195:8333
+91.156.97.181:8333
+91.207.68.144:8333
+91.209.77.101:8333
+91.214.200.205:8333
+91.220.131.242:8333
+91.220.163.18:8333
+91.233.23.35:8333
+92.13.96.93:8333
+92.14.74.114:8333
+92.27.7.209:8333
+92.221.228.13:8333
+92.255.207.73:8333
+93.72.167.148:8333
+93.74.163.234:8333
+93.123.174.66:8333
+93.152.166.29:8333
+93.181.45.188:8333
+94.19.12.244:8333
+94.190.227.112:8333
+94.198.135.29:8333
+94.224.162.65:8333
+94.226.107.86:8333
+94.242.198.161:8333
+95.31.10.209:8333
+95.65.72.244:8333
+95.84.162.95:8333
+95.90.139.46:8333
+95.183.49.27:8005
+95.215.47.133:8333
+96.23.67.85:8333
+96.44.166.190:8333
+97.93.225.74:8333
+98.26.0.34:8333
+98.27.225.102:8333
+98.229.117.229:8333
+98.249.68.125:8333
+98.255.5.155:8333
+99.101.240.114:8333
+101.100.174.138:8333
+101.251.203.6:8333
+103.3.60.61:8333
+103.30.42.189:8333
+103.224.165.48:8333
+104.36.83.233:8333
+104.37.129.22:8333
+104.54.192.251:8333
+104.128.228.252:8333
+104.128.230.185:8334
+104.130.161.47:8333
+104.131.33.60:8333
+104.143.0.156:8333
+104.156.111.72:8333
+104.167.111.84:8333
+104.193.40.248:8333
+104.197.7.174:8333
+104.197.8.250:8333
+104.223.1.133:8333
+104.236.97.140:8333
+104.238.128.214:8333
+104.238.130.182:8333
+106.38.234.84:8333
+106.185.36.204:8333
+107.6.4.145:8333
+107.150.2.6:8333
+107.150.40.234:8333
+107.155.108.130:8333
+107.161.182.115:8333
+107.170.66.231:8333
+107.190.128.226:8333
+107.191.106.115:8333
+108.16.2.61:8333
+109.70.4.168:8333
+109.162.35.196:8333
+109.163.235.239:8333
+109.190.196.220:8333
+109.191.39.60:8333
+109.234.106.191:8333
+109.238.81.82:8333
+114.76.147.27:8333
+115.28.224.127:8333
+115.68.110.82:18333
+118.97.79.218:8333
+118.189.207.197:8333
+119.228.96.233:8333
+120.147.178.81:8333
+121.41.123.5:8333
+121.67.5.230:8333
+122.107.143.110:8333
+123.2.170.98:8333
+123.110.65.94:8333
+123.193.139.19:8333
+125.239.160.41:8333
+128.101.162.193:8333
+128.111.73.10:8333
+128.140.229.73:8333
+128.175.195.31:8333
+128.199.107.63:8333
+128.199.192.153:8333
+128.253.3.193:20020
+129.123.7.7:8333
+130.89.160.234:8333
+131.72.139.164:8333
+131.191.112.98:8333
+133.1.134.162:8333
+134.19.132.53:8333
+137.226.34.42:8333
+141.41.2.172:8333
+141.255.128.204:8333
+142.217.12.106:8333
+143.215.129.126:8333
+146.0.32.101:8337
+147.229.13.199:8333
+149.210.133.244:8333
+149.210.162.187:8333
+150.101.163.241:8333
+151.236.11.189:8333
+153.121.66.211:8333
+154.20.2.139:8333
+159.253.23.132:8333
+162.209.106.123:8333
+162.210.198.184:8333
+162.218.65.121:8333
+162.222.161.49:8333
+162.243.132.6:8333
+162.243.132.58:8333
+162.248.99.164:53011
+162.248.102.117:8333
+163.158.35.110:8333
+164.15.10.189:8333
+164.40.134.171:8333
+166.230.71.67:8333
+167.160.161.199:8333
+168.103.195.250:8333
+168.144.27.112:8333
+168.158.129.29:8333
+170.75.162.86:8333
+172.90.99.174:8333
+172.245.5.156:8333
+173.23.166.47:8333
+173.32.11.194:8333
+173.34.203.76:8333
+173.171.1.52:8333
+173.175.136.13:8333
+173.230.228.139:8333
+173.247.193.70:8333
+174.49.132.28:8333
+174.52.202.72:8333
+174.53.76.87:8333
+174.109.33.28:8333
+176.28.12.169:8333
+176.35.182.214:8333
+176.36.33.113:8333
+176.36.33.121:8333
+176.58.96.173:8333
+176.121.76.84:8333
+178.62.70.16:8333
+178.62.111.26:8333
+178.76.169.59:8333
+178.79.131.32:8333
+178.162.199.216:8333
+178.175.134.35:8333
+178.248.111.4:8333
+178.254.1.170:8333
+178.254.34.161:8333
+179.43.143.120:8333
+179.208.156.198:8333
+180.200.128.58:8333
+183.78.169.108:8333
+183.96.96.152:8333
+184.68.2.46:8333
+184.73.160.160:8333
+184.94.227.58:8333
+184.152.68.163:8333
+185.7.35.114:8333
+185.28.76.179:8333
+185.31.160.202:8333
+185.45.192.129:8333
+185.66.140.15:8333
+186.2.167.23:8333
+186.220.101.142:8333
+188.26.5.33:8333
+188.75.136.146:8333
+188.120.194.140:8333
+188.121.5.150:8333
+188.138.0.114:8333
+188.138.33.239:8333
+188.166.0.82:8333
+188.182.108.129:8333
+188.191.97.208:8333
+188.226.198.102:8001
+190.10.9.217:8333
+190.75.143.144:8333
+190.139.102.146:8333
+191.237.64.28:8333
+192.3.131.61:8333
+192.99.225.3:8333
+192.110.160.122:8333
+192.146.137.1:8333
+192.183.198.204:8333
+192.203.228.71:8333
+193.0.109.3:8333
+193.12.238.204:8333
+193.91.200.85:8333
+193.234.225.156:8333
+194.6.233.38:8333
+194.63.143.136:8333
+194.126.100.246:8333
+195.134.99.195:8333
+195.159.111.98:8333
+195.159.226.139:8333
+195.197.175.190:8333
+198.48.199.108:8333
+198.57.208.134:8333
+198.57.210.27:8333
+198.62.109.223:8333
+198.167.140.8:8333
+198.167.140.18:8333
+199.91.173.234:8333
+199.127.226.245:8333
+199.180.134.116:8333
+200.7.96.99:8333
+201.160.106.86:8333
+202.55.87.45:8333
+202.60.68.242:8333
+202.60.69.232:8333
+202.124.109.103:8333
+203.30.197.77:8333
+203.88.160.43:8333
+203.151.140.14:8333
+203.219.14.204:8333
+205.147.40.62:8333
+207.235.39.214:8333
+207.244.73.8:8333
+208.12.64.225:8333
+208.76.200.200:8333
+209.40.96.121:8333
+209.126.107.176:8333
+209.141.40.149:8333
+209.190.75.59:8333
+209.208.111.142:8333
+210.54.34.164:8333
+211.72.66.229:8333
+212.51.144.42:8333
+212.112.33.157:8333
+212.116.72.63:8333
+212.126.14.122:8333
+213.66.205.194:8333
+213.111.196.21:8333
+213.122.107.102:8333
+213.136.75.175:8333
+213.155.7.24:8333
+213.163.64.31:8333
+213.163.64.208:8333
+213.165.86.136:8333
+213.184.8.22:8333
+216.15.78.182:8333
+216.55.143.154:8333
+216.115.235.32:8333
+216.126.226.166:8333
+216.145.67.87:8333
+216.169.141.169:8333
+216.249.92.230:8333
+216.250.138.230:8333
+217.20.171.43:8333
+217.23.2.71:8333
+217.23.2.242:8333
+217.25.9.76:8333
+217.40.226.169:8333
+217.123.98.9:8333
+217.155.36.62:8333
+217.172.32.18:20993
+218.61.196.202:8333
+218.231.205.41:8333
+220.233.77.200:8333
+223.18.226.85:8333
+223.197.203.82:8333
+223.255.166.142:8333
+[2001:1291:2bf:1::100]:8333
+[2001:1418:100:5c2::2]:8333
+[2001:16d8:dd24:0:86c9:681e:f931:256]:8333
+[2001:19f0:1624:e6::579d:9428]:8333
+[2001:19f0:300:1340:225:90ff:fec9:2b6d]:8333
+[2001:19f0:4009:1405::64]:8333
+[2001:1b40:5000:2e::3fb0:6571]:8333
+[2001:410:a000:4050:8463:90b0:fffb:4e58]:8333
+[2001:410:a002:cafe:8463:90b0:fffb:4e58]:8333
+[2001:41d0:1:541e::1]:8333
+[2001:41d0:1:6a34::3]:8333
+[2001:41d0:1:6cd3::]:8333
+[2001:41d0:1:8b26::1]:8333
+[2001:41d0:1:a33d::1]:8333
+[2001:41d0:1:b855::1]:8333
+[2001:41d0:1:c139::1]:8333
+[2001:41d0:1:c8d7::1]:8333
+[2001:41d0:1:dd3f::1]:8333
+[2001:41d0:1:e29d::1]:8333
+[2001:41d0:1:f59f::33]:8333
+[2001:41d0:1:f7cc::1]:8333
+[2001:41d0:1:ff87::1]:8333
+[2001:41d0:2:2f05::1]:8333
+[2001:41d0:2:37c3::]:8200
+[2001:41d0:2:3e13::1]:8333
+[2001:41d0:2:8619::]:8333
+[2001:41d0:2:9c94::1]:8333
+[2001:41d0:2:a24f::]:8333
+[2001:41d0:2:adbf::]:8333
+[2001:41d0:2:b721::1]:8333
+[2001:41d0:2:ee52::1]:8333
+[2001:41d0:2:f1a5::]:8333
+[2001:41d0:2:fa54::1]:8333
+[2001:41d0:51:1::2036]:8333
+[2001:41d0:52:a00::1a1]:8333
+[2001:41d0:52:cff::6f5]:8333
+[2001:41d0:52:d00::2c0]:8333
+[2001:41d0:52:d00::cf2]:8333
+[2001:41d0:8:1087::1]:8333
+[2001:41d0:8:4a3c::b7c]:8333
+[2001:41d0:8:6728::]:8333
+[2001:41d0:8:b779::1]:8333
+[2001:41d0:8:c30f::1]:8333
+[2001:41d0:8:d2b2::1]:8333
+[2001:41d0:8:d5c3::1]:8333
+[2001:41d0:8:eb8b::]:8333
+[2001:41d0:a:16d0::1]:8333
+[2001:41d0:a:2b18::1]:8333
+[2001:41d0:a:3a9c::1]:8333
+[2001:41d0:a:4903::]:8333
+[2001:41d0:a:57b::1]:8333
+[2001:41d0:a:5c7a::]:8333
+[2001:41d0:a:6c29::1]:8333
+[2001:41d0:a:f482::1]:8333
+[2001:41d0:b:854:b7c:b7c:b7c:b7c]:8333
+[2001:41d0:d:111c::]:8333
+[2001:44b8:4116:7801:4216:7eff:fe78:3fe4]:8333
+[2001:470:1f08:837::2]:8333
+[2001:470:1f08:c33::2]:8333
+[2001:470:1f09:bca:218:7dff:fe10:be33]:8333
+[2001:470:1f0f:22d::212:26]:8333
+[2001:470:1f11:12d5::ae1:5611]:8333
+[2001:470:1f14:57a::2]:8333
+[2001:470:1f14:7d::2]:8333
+[2001:470:1f15:57c::1]:8333
+[2001:470:1f15:dda:3d9a:3f11:9a56:ed64]:8333
+[2001:470:25:482::2]:8333
+[2001:470:25:e4::2]:8333
+[2001:470:4:26b::2]:8333
+[2001:470:5f:5f::232]:8333
+[2001:470:66:119::2]:8333
+[2001:470:67:39d::71]:8333
+[2001:470:6c4f::cafe]:8333
+[2001:470:8:2e1::43]:8333
+[2001:470:90a7:96::afe:6021]:8333
+[2001:470:95c1::2]:8333
+[2001:470:b1d0:ffff::1000]:8333
+[2001:470:c1f2:3::201]:8333
+[2001:470:d00d:0:3664:a9ff:fe9a:5150]:8333
+[2001:470:e250:0:211:11ff:feb9:924c]:8333
+[2001:4800:7817:101:be76:4eff:fe04:dc52]:8333
+[2001:4800:7819:104:be76:4eff:fe04:7809]:8333
+[2001:4800:7819:104:be76:4eff:fe05:c828]:8333
+[2001:4802:7800:2:30d7:1775:ff20:1858]:8333
+[2001:4802:7802:101:be76:4eff:fe20:256]:8333
+[2001:4802:7802:103:be76:4eff:fe20:2de8]:8333
+[2001:4830:1100:2e8::2]:8333
+[2001:4ba0:fff7:181:dead::1]:8333
+[2001:4ba0:fffa:5d::93]:8333
+[2001:4ba0:ffff:1be:1:1005:0:1]:8335
+[2001:4c48:110:101:216:3eff:fe24:1162]:8333
+[2001:4dd0:f101::32]:8333
+[2001:4dd0:ff00:867f::3]:8333
+[2001:4dd0:ff00:9a67::9]:8333
+[2001:4dd0:ff00:9c55:c23f:d5ff:fe6c:7ee9]:8333
+[2001:5c0:1400:b::3cc7]:8333
+[2001:5c0:1400:b::3d01]:8333
+[2001:5c0:1400:b::8df]:8333
+[2001:5c0:1501:300::3]:8333
+[2001:610:1b19::3]:8333
+[2001:620:500:fff0:f21f:afff:fecf:91cc]:8333
+[2001:67c:1220:80c:ad:8de2:f7e2:c784]:8333
+[2001:67c:21ec:1000::b]:8333
+[2001:6f8:1296:0:76d4:35ff:feba:1d26]:8333
+[2001:840:f000:4250:3e4a:92ff:fe6d:145f]:8333
+[2001:8d8:840:500::39:1ae]:8333
+[2001:980:efd8:0:21:de4a:2709:912]:8333
+[2001:981:46:1::3]:8333
+[2001:981:9319:2:c0:a8:c8:8]:8333
+[2001:9d8:cafe:3::91]:8333
+[2001:ad0:1:1:26be:5ff:fe25:959d]:8333
+[2001:ba8:1f1:f34c::2]:8333
+[2001:bc8:381c:100::1]:8333
+[2002:175c:4caa::175c:4caa]:8333
+[2002:4404:82f1:0:8d55:8fbb:15fa:f4e0]:8333
+[2002:4475:2233:0:21f:5bff:fe33:9f70]:8333
+[2002:596c:48c3::596c:48c3]:8333
+[2002:8c6d:6521:9617:12bf:48ff:fed8:1724]:8333
+[2002:a646:5e6a::1:2]:8333
+[2002:b009:20c5::b009:20c5]:8333
+[2400:8900::f03c:91ff:fe6e:823e]:8333
+[2400:8900::f03c:91ff:fe70:d164]:8333
+[2400:8901::f03c:91ff:fe37:9761]:8333
+[2403:4200:403:2::ff]:8333
+[2403:b800:1000:64:40a:e9ff:fe5f:94c1]:8333
+[2403:b800:1000:64:9879:17ff:fe6a:a59f]:8333
+[2600:3c00::f03c:91ff:fe18:59b2]:8333
+[2600:3c00::f03c:91ff:fe37:a4b1]:8333
+[2600:3c00::f03c:91ff:fe56:2973]:8333
+[2600:3c00::f03c:91ff:fe6e:7297]:8333
+[2600:3c00::f03c:91ff:fe84:8a6e]:8333
+[2600:3c01::f03c:91ff:fe18:6adf]:8333
+[2600:3c01::f03c:91ff:fe18:e217]:8333
+[2600:3c01::f03c:91ff:fe33:1b31]:8333
+[2600:3c01::f03c:91ff:fe33:2fe1]:8333
+[2600:3c01::f03c:91ff:fe33:a03f]:8333
+[2600:3c01::f03c:91ff:fe50:5e06]:8333
+[2600:3c01::f03c:91ff:fe56:d645]:8333
+[2600:3c01::f03c:91ff:fe6e:a3dc]:8333
+[2600:3c01::f03c:91ff:fe89:a659]:8333
+[2600:3c02::f03c:91ff:fe6e:6f0b]:8333
+[2600:3c03::f03c:91ff:fe33:f6fb]:8333
+[2600:3c03::f03c:91ff:fe50:5fa7]:8333
+[2600:3c03::f03c:91ff:fe6e:1803]:8333
+[2600:3c03::f03c:91ff:fe6e:4ac0]:8333
+[2601:6:4800:47f:1e4e:1f4d:332c:3bf6]:8333
+[2601:d:5400:fed:8d54:c1e8:7ed7:d45e]:8333
+[2602:100:4b8f:6d2a:20c:29ff:feaf:c4c2]:8333
+[2602:ffc5:1f::1f:2d61]:8333
+[2602:ffc5:1f::1f:9211]:8333
+[2602:ffc5::ffc5:b844]:8333
+[2602:ffe8:100:2::457:936b]:8333
+[2602:ffea:1001:125::2ad4]:8333
+[2602:ffea:1001:6ff::837d]:8333
+[2602:ffea:1001:72b::578b]:8333
+[2602:ffea:1001:77a::9cae]:8333
+[2602:ffea:1:2fe::6bc8]:8333
+[2602:ffea:1:701::7968]:8333
+[2602:ffea:1:70d::82ec]:8333
+[2602:ffea:1:9ff::e957]:8333
+[2602:ffea:1:a5d::4acb]:8333
+[2602:ffea:a::24c4:d9fd]:8333
+[2602:ffea:a::c06:ae32]:8333
+[2604:0:c1:100:1ec1:deff:fe54:2235]:8333
+[2604:180:1:1af::42a9]:8333
+[2604:180::b208:398]:8333
+[2604:2880::6072:aed]:8333
+[2604:4080:1114:0:3285:a9ff:fe93:850c]:8333
+[2604:7c00:17:3d0::5a4d]:8333
+[2604:9a00:2100:a009:2::]:8333
+[2604:a880:1:20::22a:4001]:8333
+[2604:a880:800:10::752:f001]:8333
+[2604:c00:88:32:216:3eff:fee4:fcca]:8333
+[2604:c00:88:32:216:3eff:fef5:bc21]:8333
+[2605:7980:1:2::1761:3d4e]:8333
+[2605:e000:1417:4068:223:32ff:fe96:e2d]:8333
+[2606:6000:a441:9903:5054:ff:fe78:66ff]:8333
+[2606:df00:2::ae85:8fc6]:8333
+[2607:5300:100:200::e7f]:8333
+[2607:5300:10::a1]:8333
+[2607:5300:60:116e::1]:8333
+[2607:5300:60:1535::]:8333
+[2607:5300:60:1b32::1]:8333
+[2607:5300:60:2337::1]:8333
+[2607:5300:60:2b90::1]:8333
+[2607:5300:60:2d99::1]:8333
+[2607:5300:60:3cb::1]:8333
+[2607:5300:60:4a85::]:8333
+[2607:5300:60:5112:0:2:4af5:63fe]:8333
+[2607:5300:60:6dd5::]:8333
+[2607:5300:60:a91::1]:8333
+[2607:f1c0:820:1500::7f:3f44]:8333
+[2607:f1c0:848:1000::48:943c]:8333
+[2607:f948:0:1::7]:8333
+[2607:fcd0:100:2300::4ad:e594]:8333
+[2607:fcd0:100:2300::659e:9cb3]:8333
+[2607:fcd0:100:2300::c74b:a8ae]:8333
+[2607:fcd0:100:2300::d82:d8c2]:8333
+[2607:fcd0:100:4300::8795:2fa8]:8333
+[2607:fcd0:daaa:901::9561:e043]:8333
+[2a00:1178:2:43:5054:ff:fee7:2eb6]:8333
+[2a00:1328:e100:cc42:230:48ff:fe92:55d]:8333
+[2a00:14f0:e000:80d2:cd1a::1]:8333
+[2a00:16d8:c::5b6a:c261]:8333
+[2a00:61e0:4083:6d01:6852:1376:e972:2091]:8333
+[2a00:c98:2030:a02f:2::2]:8333
+[2a01:1b0:7999:402::131]:8333
+[2a01:1e8:e100:811c:700f:65f0:f72a:1084]:8333
+[2a01:238:42da:c500:6546:1293:5422:ab40]:8333
+[2a01:348:6:473::2]:8333
+[2a01:368:e010:2::2]:8333
+[2a01:430:17:1::ffff:549]:8333
+[2a01:430:17:1::ffff:830]:8333
+[2a01:488:66:1000:53a9:d04:0:1]:8333
+[2a01:488:66:1000:57e6:578c:0:1]:8333
+[2a01:488:66:1000:b01c:178d:0:1]:8333
+[2a01:488:67:1000:523:fdce:0:1]:8333
+[2a01:488:67:1000:b01c:30ab:0:1]:8333
+[2a01:4f8:100:24aa::2]:8333
+[2a01:4f8:100:44e7::2]:8333
+[2a01:4f8:100:5128::2]:8333
+[2a01:4f8:100:84a7::1:1]:8333
+[2a01:4f8:110:516c::2]:8333
+[2a01:4f8:110:536e::2]:8333
+[2a01:4f8:120:62e6::2]:8333
+[2a01:4f8:120:702e::2]:8333
+[2a01:4f8:120:8005::2]:8333
+[2a01:4f8:120:8203::2]:8333
+[2a01:4f8:120:8422::2]:8333
+[2a01:4f8:121:11eb::2]:8333
+[2a01:4f8:121:261::2]:8333
+[2a01:4f8:130:242b::10]:8333
+[2a01:4f8:130:242b::5]:8333
+[2a01:4f8:130:2468::3]:8333
+[2a01:4f8:130:632c::2]:8333
+[2a01:4f8:130:6366::2]:8333
+[2a01:4f8:130:6426::2]:8333
+[2a01:4f8:130:934f::2]:8333
+[2a01:4f8:131:2070::2]:8333
+[2a01:4f8:131:54a2::2]:8333
+[2a01:4f8:140:80ad::2]:8333
+[2a01:4f8:141:186::2]:8333
+[2a01:4f8:150:210b::2]:8333
+[2a01:4f8:150:2263::5]:8333
+[2a01:4f8:150:2349::2]:8333
+[2a01:4f8:150:61ee::2]:8333
+[2a01:4f8:150:7088:5054:ff:fe45:bff2]:8333
+[2a01:4f8:150:8324::2]:9001
+[2a01:4f8:151:1d8::2]:8333
+[2a01:4f8:151:5128::2]:8333
+[2a01:4f8:151:6347::2]:9001
+[2a01:4f8:161:526d::2]:8333
+[2a01:4f8:161:9349::2]:8333
+[2a01:4f8:162:23c6::2]:8333
+[2a01:4f8:162:4348::2]:8333
+[2a01:4f8:162:7345::2]:8333
+[2a01:4f8:162:7383::2]:8333
+[2a01:4f8:162:74e3::2]:8333
+[2a01:4f8:190:6065::2]:8333
+[2a01:4f8:190:6349::2]:8333
+[2a01:4f8:190:64c9::2]:8333
+[2a01:4f8:190:91ce::2]:8333
+[2a01:4f8:191:2194::83]:8333
+[2a01:4f8:191:40a1::2]:8333
+[2a01:4f8:191:4a7::2]:8333
+[2a01:4f8:191:63b4:5000::1]:8333
+[2a01:4f8:191:7121::2]:8333
+[2a01:4f8:191:83a2::2]:8333
+[2a01:4f8:191:93c4::2]:8333
+[2a01:4f8:192:60a9:0:1:5:2]:8333
+[2a01:4f8:192:73b2::2]:8333
+[2a01:4f8:192:8098::2]:8333
+[2a01:4f8:192:db::2]:8333
+[2a01:4f8:200:1012::2]:8333
+[2a01:4f8:200:22e3::2]:8333
+[2a01:4f8:200:414e::2]:8333
+[2a01:4f8:200:63af::222]:8333
+[2a01:4f8:200:71e3:78b4:f3ff:fead:e8cf]:8333
+[2a01:4f8:201:5164::2]:8333
+[2a01:4f8:201:6011::4]:8333
+[2a01:4f8:201:60d5::2]:8333
+[2a01:4f8:202:53c3::2]:8333
+[2a01:4f8:210:24aa::2]:8333
+[2a01:4f8:210:502f::2]:8333
+[2a01:4f8:211:14cf::2]:8333
+[2a01:4f8:211:1a59::2]:8333
+[2a01:4f8:211:2ac1::2]:8333
+[2a01:4f8:211:cca::2]:8333
+[2a01:4f8:a0:22a5::2]:8333
+[2a01:4f8:a0:5023::2]:8333
+[2a01:4f8:a0:5243::2]:8333
+[2a01:4f8:a0:74c8::2]:8333
+[2a01:4f8:a0:8227::2]:8333
+[2a01:4f8:a0:822d::2]:8333
+[2a01:4f8:d13:2183::2]:8333
+[2a01:608:ffff:a009:8bf5:879d:e51a:f837]:8333
+[2a01:79d:469e:ed94:c23f:d5ff:fe65:20c5]:8333
+[2a01:7c8:aab5:3e6:5054:ff:fed7:4e54]:8333
+[2a01:7e00::f03c:91ff:fe18:301e]:8333
+[2a01:7e00::f03c:91ff:fe18:7749]:8333
+[2a01:7e00::f03c:91ff:fe33:2d67]:8333
+[2a01:7e00::f03c:91ff:fe33:347c]:8333
+[2a01:7e00::f03c:91ff:fe33:ae50]:8333
+[2a01:7e00::f03c:91ff:fe56:6b5c]:8333
+[2a01:7e00::f03c:91ff:fe56:bee6]:8333
+[2a01:7e00::f03c:91ff:fe69:4895]:8333
+[2a01:7e00::f03c:91ff:fe69:9912]:8333
+[2a01:7e00::f03c:91ff:fe6e:26ee]:8333
+[2a01:7e00::f03c:91ff:fe73:42f1]:8333
+[2a01:7e00::f03c:91ff:fe84:434f]:8333
+[2a01:7e00::f03c:91ff:fe84:b36b]:8333
+[2a01:7e00::f03c:91ff:fe89:1faa]:8333
+[2a01:7e00::f03c:91ff:fe98:816]:8333
+[2a01:7e00::f03c:91ff:fedb:352e]:8333
+[2a01:7e00::f03c:91ff:fedb:4a1d]:8333
+[2a01:e34:edbb:6750:224:1dff:fe89:3897]:8333
+[2a01:e35:2f1d:3fb0:7187:c7ba:bcfc:80ce]:8333
+[2a01:e35:8787:96f0:9032:9297:39ae:496d]:8333
+[2a01:e35:8a3f:47c0:c617:feff:fe3c:9fbd]:8333
+[2a01:e35:8b66:6a0:4900:9dfd:d841:d025]:8333
+[2a02:168:4a01::39]:8333
+[2a02:168:5404:2:c23f:d5ff:fe6a:512e]:8333
+[2a02:180:1:1::5b8f:538c]:8333
+[2a02:2028:1016::2]:8333
+[2a02:2528:503:2::14]:8333
+[2a02:2528:503:2::15]:8333
+[2a02:2528:ff00:81a6:21e:c5ff:fe8d:f9a5]:8333
+[2a02:2770:5:0:21a:4aff:fee4:c7db]:8333
+[2a02:2770:8:0:21a:4aff:fe7b:3dcd]:8333
+[2a02:348:5e:5a29::1]:8333
+[2a02:7aa0:1619::202f:c06a]:8333
+[2a02:8109:8e40:35fc:ba27:ebff:feae:cf16]:8333
+[2a02:af8:6:1500::1:130]:8333
+[2a02:c200:0:10:1:0:6314:2222]:8333
+[2a02:c200:0:10:2:3:3295:1]:8332
+[2a02:c200:0:10:3:0:5449:1]:8333
+[2a02:c200:1:10:2:3:5899:1]:8333
+[2a02:c200:1:10::2705:1]:8333
+[2a02:ce80:0:20::1]:8333
+[2a02:fe0:c321:27e0:6ef0:49ff:fe11:a61d]:8333
+[2a03:4000:2:496::8]:8333
+[2a03:b0c0:0:1010::62:f001]:8333
+[2a03:f80:ed16:ca7:ea75:b12d:2af:9e2a]:8333
+3ffk7iumtx3cegbi.onion:8333
+3hshaantu6ot4upz.onion:8333
+45c5lc77qgpikafy.onion:8333
+77mx2jsxaoyesz2p.onion:8333
+7g7j54btiaxhtsiy.onion:8333
+b6fr7dlbu2kpiysf.onion:8333
+bitcoincfqcssig5.onion:8333
+bitcoinostk4e4re.onion:8333
+bmutjfrj5btseddb.onion:8333
+drp4pvejybx2ejdr.onion:8333
+gixnv56d63buypan.onion:8333
+h2vlpudzphzqxutd.onion:8333
+hhiv5pnxenvbf4am.onion:8333
+lzxpkn6ptp3ohh63.onion:8333
+msphsgfiqfq5stne.onion:8333
+ncwk3lutemffcpc4.onion:8333
+okdzjarwekbshnof.onion:8333
+sjdomi4yb2dwkjbc.onion:8333
+uvwozwxlihntigbb.onion:8333
+v6ylz45dn5ybpk4d.onion:8333
+vk3qjdehyy4dwcxw.onion:8333
+vqpye2k5rcqvj5mq.onion:8333
+xudkoztdfrsuyyou.onion:8333
+z55v4ostefnwfy32.onion:8333
diff --git a/contrib/seeds/nodes_test.txt b/contrib/seeds/nodes_test.txt
new file mode 100644
index 0000000000..98365ee505
--- /dev/null
+++ b/contrib/seeds/nodes_test.txt
@@ -0,0 +1,11 @@
+# List of fixed seed nodes for testnet
+
+# Onion nodes
+thfsmmn2jbitcoin.onion
+it2pj4f7657g3rhi.onion
+nkf5e6b7pl4jfd4a.onion
+4zhkir2ofl7orfom.onion
+t6xj6wilh4ytvcs7.onion
+i6y6ivorwakd7nw3.onion
+ubqj4rsu3nqtxmtp.onion
+
diff --git a/contrib/spendfrom/README.md b/contrib/spendfrom/README.md
new file mode 100644
index 0000000000..c0a9c9ccf9
--- /dev/null
+++ b/contrib/spendfrom/README.md
@@ -0,0 +1,35 @@
+### SpendFrom ###
+
+Use the raw transactions API to send coins received on a particular
+address (or addresses).
+
+### Usage: ###
+Depends on [jsonrpc](http://json-rpc.org/).
+
+ spendfrom.py --from=FROMADDRESS1[,FROMADDRESS2] --to=TOADDRESS --amount=amount \
+ --fee=fee --datadir=/path/to/.bitcoin --testnet --dry_run
+
+With no arguments, outputs a list of amounts associated with addresses.
+
+With arguments, sends coins received by the `FROMADDRESS` addresses to the `TOADDRESS`.
+
+### Notes ###
+
+- You may explicitly specify how much fee to pay (a fee more than 1% of the amount
+will fail, though, to prevent bitcoin-losing accidents). Spendfrom may fail if
+it thinks the transaction would never be confirmed (if the amount being sent is
+too small, or if the transaction is too many bytes for the fee).
+
+- If a change output needs to be created, the change will be sent to the last
+`FROMADDRESS` (if you specify just one `FROMADDRESS`, change will go back to it).
+
+- If `--datadir` is not specified, the default datadir is used.
+
+- The `--dry_run` option will just create and sign the transaction and print
+the transaction data (as hexadecimal), instead of broadcasting it.
+
+- If the transaction is created and broadcast successfully, a transaction id
+is printed.
+
+- If this was a tool for end-users and not programmers, it would have much friendlier
+error-handling.
diff --git a/contrib/spendfrom/setup.py b/contrib/spendfrom/setup.py
new file mode 100644
index 0000000000..01b9768a5b
--- /dev/null
+++ b/contrib/spendfrom/setup.py
@@ -0,0 +1,9 @@
+from distutils.core import setup
+setup(name='btcspendfrom',
+ version='1.0',
+ description='Command-line utility for bitcoin "coin control"',
+ author='Gavin Andresen',
+ author_email='gavin@bitcoinfoundation.org',
+ requires=['jsonrpc'],
+ scripts=['spendfrom.py'],
+ )
diff --git a/contrib/spendfrom/spendfrom.py b/contrib/spendfrom/spendfrom.py
new file mode 100755
index 0000000000..72ee0425eb
--- /dev/null
+++ b/contrib/spendfrom/spendfrom.py
@@ -0,0 +1,267 @@
+#!/usr/bin/env python
+#
+# Use the raw transactions API to spend bitcoins received on particular addresses,
+# and send any change back to that same address.
+#
+# Example usage:
+# spendfrom.py # Lists available funds
+# spendfrom.py --from=ADDRESS --to=ADDRESS --amount=11.00
+#
+# Assumes it will talk to a bitcoind or Bitcoin-Qt running
+# on localhost.
+#
+# Depends on jsonrpc
+#
+
+from decimal import *
+import getpass
+import math
+import os
+import os.path
+import platform
+import sys
+import time
+from jsonrpc import ServiceProxy, json
+
+BASE_FEE=Decimal("0.001")
+
+def check_json_precision():
+ """Make sure json library being used does not lose precision converting BTC values"""
+ n = Decimal("20000000.00000003")
+ satoshis = int(json.loads(json.dumps(float(n)))*1.0e8)
+ if satoshis != 2000000000000003:
+ raise RuntimeError("JSON encode/decode loses precision")
+
+def determine_db_dir():
+ """Return the default location of the bitcoin data directory"""
+ if platform.system() == "Darwin":
+ return os.path.expanduser("~/Library/Application Support/Bitcoin/")
+ elif platform.system() == "Windows":
+ return os.path.join(os.environ['APPDATA'], "Bitcoin")
+ return os.path.expanduser("~/.bitcoin")
+
+def read_bitcoin_config(dbdir):
+ """Read the bitcoin.conf file from dbdir, returns dictionary of settings"""
+ from ConfigParser import SafeConfigParser
+
+ class FakeSecHead(object):
+ def __init__(self, fp):
+ self.fp = fp
+ self.sechead = '[all]\n'
+ def readline(self):
+ if self.sechead:
+ try: return self.sechead
+ finally: self.sechead = None
+ else:
+ s = self.fp.readline()
+ if s.find('#') != -1:
+ s = s[0:s.find('#')].strip() +"\n"
+ return s
+
+ config_parser = SafeConfigParser()
+ config_parser.readfp(FakeSecHead(open(os.path.join(dbdir, "bitcoin.conf"))))
+ return dict(config_parser.items("all"))
+
+def connect_JSON(config):
+ """Connect to a bitcoin JSON-RPC server"""
+ testnet = config.get('testnet', '0')
+ testnet = (int(testnet) > 0) # 0/1 in config file, convert to True/False
+ if not 'rpcport' in config:
+ config['rpcport'] = 18332 if testnet else 8332
+ connect = "http://%s:%s@127.0.0.1:%s"%(config['rpcuser'], config['rpcpassword'], config['rpcport'])
+ try:
+ result = ServiceProxy(connect)
+ # ServiceProxy is lazy-connect, so send an RPC command mostly to catch connection errors,
+ # but also make sure the bitcoind we're talking to is/isn't testnet:
+ if result.getmininginfo()['testnet'] != testnet:
+ sys.stderr.write("RPC server at "+connect+" testnet setting mismatch\n")
+ sys.exit(1)
+ return result
+ except:
+ sys.stderr.write("Error connecting to RPC server at "+connect+"\n")
+ sys.exit(1)
+
+def unlock_wallet(bitcoind):
+ info = bitcoind.getinfo()
+ if 'unlocked_until' not in info:
+ return True # wallet is not encrypted
+ t = int(info['unlocked_until'])
+ if t <= time.time():
+ try:
+ passphrase = getpass.getpass("Wallet is locked; enter passphrase: ")
+ bitcoind.walletpassphrase(passphrase, 5)
+ except:
+ sys.stderr.write("Wrong passphrase\n")
+
+ info = bitcoind.getinfo()
+ return int(info['unlocked_until']) > time.time()
+
+def list_available(bitcoind):
+ address_summary = dict()
+
+ address_to_account = dict()
+ for info in bitcoind.listreceivedbyaddress(0):
+ address_to_account[info["address"]] = info["account"]
+
+ unspent = bitcoind.listunspent(0)
+ for output in unspent:
+ # listunspent doesn't give addresses, so:
+ rawtx = bitcoind.getrawtransaction(output['txid'], 1)
+ vout = rawtx["vout"][output['vout']]
+ pk = vout["scriptPubKey"]
+
+ # This code only deals with ordinary pay-to-bitcoin-address
+ # or pay-to-script-hash outputs right now; anything exotic is ignored.
+ if pk["type"] != "pubkeyhash" and pk["type"] != "scripthash":
+ continue
+
+ address = pk["addresses"][0]
+ if address in address_summary:
+ address_summary[address]["total"] += vout["value"]
+ address_summary[address]["outputs"].append(output)
+ else:
+ address_summary[address] = {
+ "total" : vout["value"],
+ "outputs" : [output],
+ "account" : address_to_account.get(address, "")
+ }
+
+ return address_summary
+
+def select_coins(needed, inputs):
+ # Feel free to improve this, this is good enough for my simple needs:
+ outputs = []
+ have = Decimal("0.0")
+ n = 0
+ while have < needed and n < len(inputs):
+ outputs.append({ "txid":inputs[n]["txid"], "vout":inputs[n]["vout"]})
+ have += inputs[n]["amount"]
+ n += 1
+ return (outputs, have-needed)
+
+def create_tx(bitcoind, fromaddresses, toaddress, amount, fee):
+ all_coins = list_available(bitcoind)
+
+ total_available = Decimal("0.0")
+ needed = amount+fee
+ potential_inputs = []
+ for addr in fromaddresses:
+ if addr not in all_coins:
+ continue
+ potential_inputs.extend(all_coins[addr]["outputs"])
+ total_available += all_coins[addr]["total"]
+
+ if total_available < needed:
+ sys.stderr.write("Error, only %f BTC available, need %f\n"%(total_available, needed));
+ sys.exit(1)
+
+ #
+ # Note:
+ # Python's json/jsonrpc modules have inconsistent support for Decimal numbers.
+ # Instead of wrestling with getting json.dumps() (used by jsonrpc) to encode
+ # Decimals, I'm casting amounts to float before sending them to bitcoind.
+ #
+ outputs = { toaddress : float(amount) }
+ (inputs, change_amount) = select_coins(needed, potential_inputs)
+ if change_amount > BASE_FEE: # don't bother with zero or tiny change
+ change_address = fromaddresses[-1]
+ if change_address in outputs:
+ outputs[change_address] += float(change_amount)
+ else:
+ outputs[change_address] = float(change_amount)
+
+ rawtx = bitcoind.createrawtransaction(inputs, outputs)
+ signed_rawtx = bitcoind.signrawtransaction(rawtx)
+ if not signed_rawtx["complete"]:
+ sys.stderr.write("signrawtransaction failed\n")
+ sys.exit(1)
+ txdata = signed_rawtx["hex"]
+
+ return txdata
+
+def compute_amount_in(bitcoind, txinfo):
+ result = Decimal("0.0")
+ for vin in txinfo['vin']:
+ in_info = bitcoind.getrawtransaction(vin['txid'], 1)
+ vout = in_info['vout'][vin['vout']]
+ result = result + vout['value']
+ return result
+
+def compute_amount_out(txinfo):
+ result = Decimal("0.0")
+ for vout in txinfo['vout']:
+ result = result + vout['value']
+ return result
+
+def sanity_test_fee(bitcoind, txdata_hex, max_fee):
+ class FeeError(RuntimeError):
+ pass
+ try:
+ txinfo = bitcoind.decoderawtransaction(txdata_hex)
+ total_in = compute_amount_in(bitcoind, txinfo)
+ total_out = compute_amount_out(txinfo)
+ if total_in-total_out > max_fee:
+ raise FeeError("Rejecting transaction, unreasonable fee of "+str(total_in-total_out))
+
+ tx_size = len(txdata_hex)/2
+ kb = tx_size/1000 # integer division rounds down
+ if kb > 1 and fee < BASE_FEE:
+ raise FeeError("Rejecting no-fee transaction, larger than 1000 bytes")
+ if total_in < 0.01 and fee < BASE_FEE:
+ raise FeeError("Rejecting no-fee, tiny-amount transaction")
+ # Exercise for the reader: compute transaction priority, and
+ # warn if this is a very-low-priority transaction
+
+ except FeeError as err:
+ sys.stderr.write((str(err)+"\n"))
+ sys.exit(1)
+
+def main():
+ import optparse
+
+ parser = optparse.OptionParser(usage="%prog [options]")
+ parser.add_option("--from", dest="fromaddresses", default=None,
+ help="addresses to get bitcoins from")
+ parser.add_option("--to", dest="to", default=None,
+ help="address to get send bitcoins to")
+ parser.add_option("--amount", dest="amount", default=None,
+ help="amount to send")
+ parser.add_option("--fee", dest="fee", default="0.0",
+ help="fee to include")
+ parser.add_option("--datadir", dest="datadir", default=determine_db_dir(),
+ help="location of bitcoin.conf file with RPC username/password (default: %default)")
+ parser.add_option("--testnet", dest="testnet", default=False, action="store_true",
+ help="Use the test network")
+ parser.add_option("--dry_run", dest="dry_run", default=False, action="store_true",
+ help="Don't broadcast the transaction, just create and print the transaction data")
+
+ (options, args) = parser.parse_args()
+
+ check_json_precision()
+ config = read_bitcoin_config(options.datadir)
+ if options.testnet: config['testnet'] = True
+ bitcoind = connect_JSON(config)
+
+ if options.amount is None:
+ address_summary = list_available(bitcoind)
+ for address,info in address_summary.iteritems():
+ n_transactions = len(info['outputs'])
+ if n_transactions > 1:
+ print("%s %.8f %s (%d transactions)"%(address, info['total'], info['account'], n_transactions))
+ else:
+ print("%s %.8f %s"%(address, info['total'], info['account']))
+ else:
+ fee = Decimal(options.fee)
+ amount = Decimal(options.amount)
+ while unlock_wallet(bitcoind) == False:
+ pass # Keep asking for passphrase until they get it right
+ txdata = create_tx(bitcoind, options.fromaddresses.split(","), options.to, amount, fee)
+ sanity_test_fee(bitcoind, txdata, amount*Decimal("0.01"))
+ if options.dry_run:
+ print(txdata)
+ else:
+ txid = bitcoind.sendrawtransaction(txdata)
+ print(txid)
+
+if __name__ == '__main__':
+ main()
diff --git a/contrib/test-patches/README.md b/contrib/test-patches/README.md
new file mode 100644
index 0000000000..def40b0d6c
--- /dev/null
+++ b/contrib/test-patches/README.md
@@ -0,0 +1,7 @@
+### Test Patches ###
+
+These patches are applied when the automated pull-tester
+tests each pull and when master is tested using jenkins.
+You can find more information about the tests run at
+[http://jenkins.bluematt.me/pull-tester/files/
+](http://jenkins.bluematt.me/pull-tester/files/) \ No newline at end of file
diff --git a/contrib/test-patches/temp-revert-2.patch b/contrib/test-patches/temp-revert-2.patch
new file mode 100644
index 0000000000..1cd043d0d7
--- /dev/null
+++ b/contrib/test-patches/temp-revert-2.patch
@@ -0,0 +1,20 @@
+commit cfae26916dba311f6f75d444301c1f9362267c3e
+Author: Matt Corallo <git@bluematt.me>
+Date: Sun Mar 24 20:45:50 2013 -0400
+
+ Revert "Checkpoint at first block in 11 March chain fork"
+
+ This reverts commit f817c496a1482d05b22c8e539de67f07db1c09d9.
+
+diff --git a/src/checkpoints.cpp b/src/checkpoints.cpp
+index 62234b9..9b11f0b 100644
+--- a/src/checkpoints.cpp
++++ b/src/checkpoints.cpp
+@@ -44,7 +44,6 @@ namespace Checkpoints
+ (193000, uint256("0x000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317"))
+ (210000, uint256("0x000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e"))
+ (216116, uint256("0x00000000000001b4f4b433e81ee46494af945cf96014816a4e2370f11b23df4e"))
+- (225430, uint256("0x00000000000001c108384350f74090433e7fcf79a606b8e797f065b130575932"))
+ ;
+ static const CCheckpointData data = {
+ &mapCheckpoints,
diff --git a/contrib/testgen/README.md b/contrib/testgen/README.md
new file mode 100644
index 0000000000..83624f443a
--- /dev/null
+++ b/contrib/testgen/README.md
@@ -0,0 +1,8 @@
+### TestGen ###
+
+Utilities to generate test vectors for the data-driven Bitcoin tests.
+
+Usage:
+
+ gen_base58_test_vectors.py valid 50 > ../../src/test/data/base58_keys_valid.json
+ gen_base58_test_vectors.py invalid 50 > ../../src/test/data/base58_keys_invalid.json \ No newline at end of file
diff --git a/contrib/testgen/base58.py b/contrib/testgen/base58.py
new file mode 100644
index 0000000000..b716495145
--- /dev/null
+++ b/contrib/testgen/base58.py
@@ -0,0 +1,104 @@
+'''
+Bitcoin base58 encoding and decoding.
+
+Based on https://bitcointalk.org/index.php?topic=1026.0 (public domain)
+'''
+import hashlib
+
+# for compatibility with following code...
+class SHA256:
+ new = hashlib.sha256
+
+if str != bytes:
+ # Python 3.x
+ def ord(c):
+ return c
+ def chr(n):
+ return bytes( (n,) )
+
+__b58chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
+__b58base = len(__b58chars)
+b58chars = __b58chars
+
+def b58encode(v):
+ """ encode v, which is a string of bytes, to base58.
+ """
+ long_value = 0
+ for (i, c) in enumerate(v[::-1]):
+ long_value += (256**i) * ord(c)
+
+ result = ''
+ while long_value >= __b58base:
+ div, mod = divmod(long_value, __b58base)
+ result = __b58chars[mod] + result
+ long_value = div
+ result = __b58chars[long_value] + result
+
+ # Bitcoin does a little leading-zero-compression:
+ # leading 0-bytes in the input become leading-1s
+ nPad = 0
+ for c in v:
+ if c == '\0': nPad += 1
+ else: break
+
+ return (__b58chars[0]*nPad) + result
+
+def b58decode(v, length = None):
+ """ decode v into a string of len bytes
+ """
+ long_value = 0
+ for (i, c) in enumerate(v[::-1]):
+ long_value += __b58chars.find(c) * (__b58base**i)
+
+ result = bytes()
+ while long_value >= 256:
+ div, mod = divmod(long_value, 256)
+ result = chr(mod) + result
+ long_value = div
+ result = chr(long_value) + result
+
+ nPad = 0
+ for c in v:
+ if c == __b58chars[0]: nPad += 1
+ else: break
+
+ result = chr(0)*nPad + result
+ if length is not None and len(result) != length:
+ return None
+
+ return result
+
+def checksum(v):
+ """Return 32-bit checksum based on SHA256"""
+ return SHA256.new(SHA256.new(v).digest()).digest()[0:4]
+
+def b58encode_chk(v):
+ """b58encode a string, with 32-bit checksum"""
+ return b58encode(v + checksum(v))
+
+def b58decode_chk(v):
+ """decode a base58 string, check and remove checksum"""
+ result = b58decode(v)
+ if result is None:
+ return None
+ h3 = checksum(result[:-4])
+ if result[-4:] == checksum(result[:-4]):
+ return result[:-4]
+ else:
+ return None
+
+def get_bcaddress_version(strAddress):
+ """ Returns None if strAddress is invalid. Otherwise returns integer version of address. """
+ addr = b58decode_chk(strAddress)
+ if addr is None or len(addr)!=21: return None
+ version = addr[0]
+ return ord(version)
+
+if __name__ == '__main__':
+ # Test case (from http://gitorious.org/bitcoin/python-base58.git)
+ assert get_bcaddress_version('15VjRaDX9zpbA8LVnbrCAFzrVzN7ixHNsC') is 0
+ _ohai = 'o hai'.encode('ascii')
+ _tmp = b58encode(_ohai)
+ assert _tmp == 'DYB3oMS'
+ assert b58decode(_tmp, 5) == _ohai
+ print("Tests passed")
diff --git a/contrib/testgen/gen_base58_test_vectors.py b/contrib/testgen/gen_base58_test_vectors.py
new file mode 100755
index 0000000000..1813436953
--- /dev/null
+++ b/contrib/testgen/gen_base58_test_vectors.py
@@ -0,0 +1,126 @@
+#!/usr/bin/env python
+'''
+Generate valid and invalid base58 address and private key test vectors.
+
+Usage:
+ gen_base58_test_vectors.py valid 50 > ../../src/test/data/base58_keys_valid.json
+ gen_base58_test_vectors.py invalid 50 > ../../src/test/data/base58_keys_invalid.json
+'''
+# 2012 Wladimir J. van der Laan
+# Released under MIT License
+import os
+from itertools import islice
+from base58 import b58encode, b58decode, b58encode_chk, b58decode_chk, b58chars
+import random
+from binascii import b2a_hex
+
+# key types
+PUBKEY_ADDRESS = 0
+SCRIPT_ADDRESS = 5
+PUBKEY_ADDRESS_TEST = 111
+SCRIPT_ADDRESS_TEST = 196
+PRIVKEY = 128
+PRIVKEY_TEST = 239
+
+metadata_keys = ['isPrivkey', 'isTestnet', 'addrType', 'isCompressed']
+# templates for valid sequences
+templates = [
+ # prefix, payload_size, suffix, metadata
+ # None = N/A
+ ((PUBKEY_ADDRESS,), 20, (), (False, False, 'pubkey', None)),
+ ((SCRIPT_ADDRESS,), 20, (), (False, False, 'script', None)),
+ ((PUBKEY_ADDRESS_TEST,), 20, (), (False, True, 'pubkey', None)),
+ ((SCRIPT_ADDRESS_TEST,), 20, (), (False, True, 'script', None)),
+ ((PRIVKEY,), 32, (), (True, False, None, False)),
+ ((PRIVKEY,), 32, (1,), (True, False, None, True)),
+ ((PRIVKEY_TEST,), 32, (), (True, True, None, False)),
+ ((PRIVKEY_TEST,), 32, (1,), (True, True, None, True))
+]
+
+def is_valid(v):
+ '''Check vector v for validity'''
+ result = b58decode_chk(v)
+ if result is None:
+ return False
+ valid = False
+ for template in templates:
+ prefix = str(bytearray(template[0]))
+ suffix = str(bytearray(template[2]))
+ if result.startswith(prefix) and result.endswith(suffix):
+ if (len(result) - len(prefix) - len(suffix)) == template[1]:
+ return True
+ return False
+
+def gen_valid_vectors():
+ '''Generate valid test vectors'''
+ while True:
+ for template in templates:
+ prefix = str(bytearray(template[0]))
+ payload = os.urandom(template[1])
+ suffix = str(bytearray(template[2]))
+ rv = b58encode_chk(prefix + payload + suffix)
+ assert is_valid(rv)
+ metadata = dict([(x,y) for (x,y) in zip(metadata_keys,template[3]) if y is not None])
+ yield (rv, b2a_hex(payload), metadata)
+
+def gen_invalid_vector(template, corrupt_prefix, randomize_payload_size, corrupt_suffix):
+ '''Generate possibly invalid vector'''
+ if corrupt_prefix:
+ prefix = os.urandom(1)
+ else:
+ prefix = str(bytearray(template[0]))
+
+ if randomize_payload_size:
+ payload = os.urandom(max(int(random.expovariate(0.5)), 50))
+ else:
+ payload = os.urandom(template[1])
+
+ if corrupt_suffix:
+ suffix = os.urandom(len(template[2]))
+ else:
+ suffix = str(bytearray(template[2]))
+
+ return b58encode_chk(prefix + payload + suffix)
+
+def randbool(p = 0.5):
+ '''Return True with P(p)'''
+ return random.random() < p
+
+def gen_invalid_vectors():
+ '''Generate invalid test vectors'''
+ # start with some manual edge-cases
+ yield "",
+ yield "x",
+ while True:
+ # kinds of invalid vectors:
+ # invalid prefix
+ # invalid payload length
+ # invalid (randomized) suffix (add random data)
+ # corrupt checksum
+ for template in templates:
+ val = gen_invalid_vector(template, randbool(0.2), randbool(0.2), randbool(0.2))
+ if random.randint(0,10)<1: # line corruption
+ if randbool(): # add random character to end
+ val += random.choice(b58chars)
+ else: # replace random character in the middle
+ n = random.randint(0, len(val))
+ val = val[0:n] + random.choice(b58chars) + val[n+1:]
+ if not is_valid(val):
+ yield val,
+
+if __name__ == '__main__':
+ import sys, json
+ iters = {'valid':gen_valid_vectors, 'invalid':gen_invalid_vectors}
+ try:
+ uiter = iters[sys.argv[1]]
+ except IndexError:
+ uiter = gen_valid_vectors
+ try:
+ count = int(sys.argv[2])
+ except IndexError:
+ count = 0
+
+ data = list(islice(uiter(), count))
+ json.dump(data, sys.stdout, sort_keys=True, indent=4)
+ sys.stdout.write('\n')
+
diff --git a/contrib/tidy_datadir.sh b/contrib/tidy_datadir.sh
new file mode 100755
index 0000000000..5d6d826444
--- /dev/null
+++ b/contrib/tidy_datadir.sh
@@ -0,0 +1,59 @@
+#!/bin/bash
+
+if [ -d "$1" ]; then
+ cd "$1"
+else
+ echo "Usage: $0 <datadir>" >&2
+ echo "Removes obsolete Bitcoin database files" >&2
+ exit 1
+fi
+
+LEVEL=0
+if [ -f wallet.dat -a -f addr.dat -a -f blkindex.dat -a -f blk0001.dat ]; then LEVEL=1; fi
+if [ -f wallet.dat -a -f peers.dat -a -f blkindex.dat -a -f blk0001.dat ]; then LEVEL=2; fi
+if [ -f wallet.dat -a -f peers.dat -a -f coins/CURRENT -a -f blktree/CURRENT -a -f blocks/blk00000.dat ]; then LEVEL=3; fi
+if [ -f wallet.dat -a -f peers.dat -a -f chainstate/CURRENT -a -f blocks/index/CURRENT -a -f blocks/blk00000.dat ]; then LEVEL=4; fi
+
+case $LEVEL in
+ 0)
+ echo "Error: no Bitcoin datadir detected."
+ exit 1
+ ;;
+ 1)
+ echo "Detected old Bitcoin datadir (before 0.7)."
+ echo "Nothing to do."
+ exit 0
+ ;;
+ 2)
+ echo "Detected Bitcoin 0.7 datadir."
+ ;;
+ 3)
+ echo "Detected Bitcoin pre-0.8 datadir."
+ ;;
+ 4)
+ echo "Detected Bitcoin 0.8 datadir."
+ ;;
+esac
+
+FILES=""
+DIRS=""
+
+if [ $LEVEL -ge 3 ]; then FILES=$(echo $FILES blk????.dat blkindex.dat); fi
+if [ $LEVEL -ge 2 ]; then FILES=$(echo $FILES addr.dat); fi
+if [ $LEVEL -ge 4 ]; then DIRS=$(echo $DIRS coins blktree); fi
+
+for FILE in $FILES; do
+ if [ -f $FILE ]; then
+ echo "Deleting: $FILE"
+ rm -f $FILE
+ fi
+done
+
+for DIR in $DIRS; do
+ if [ -d $DIR ]; then
+ echo "Deleting: $DIR/"
+ rm -rf $DIR
+ fi
+done
+
+echo "Done."
diff --git a/contrib/verify-commits/gpg.sh b/contrib/verify-commits/gpg.sh
new file mode 100755
index 0000000000..6b5137e7b5
--- /dev/null
+++ b/contrib/verify-commits/gpg.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+INPUT=$(</dev/stdin)
+VALID=false
+IFS=$'\n'
+for LINE in $(echo "$INPUT" | gpg --trust-model always "$@" 2>/dev/null); do
+ case "$LINE" in "[GNUPG:] VALIDSIG"*)
+ while read KEY; do
+ case "$LINE" in "[GNUPG:] VALIDSIG $KEY "*) VALID=true;; esac
+ done < ./contrib/verify-commits/trusted-keys
+ esac
+done
+if ! $VALID; then
+ exit 1
+fi
+echo "$INPUT" | gpg --trust-model always "$@" 2>/dev/null
diff --git a/contrib/verify-commits/pre-push-hook.sh b/contrib/verify-commits/pre-push-hook.sh
new file mode 100755
index 0000000000..607c0cac45
--- /dev/null
+++ b/contrib/verify-commits/pre-push-hook.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+if ! [[ "$2" =~ [git@]?[www.]?github.com[:|/]bitcoin/bitcoin[.git]? ]]; then
+ exit 0
+fi
+
+while read LINE; do
+ set -- A $LINE
+ if [ "$4" != "refs/heads/master" ]; then
+ continue
+ fi
+ if ! ./contrib/verify-commits/verify-commits.sh $3 > /dev/null 2>&1; then
+ echo "ERROR: A commit is not signed, can't push"
+ ./contrib/verify-commits/verify-commits.sh
+ exit 1
+ fi
+done < /dev/stdin
diff --git a/contrib/verify-commits/trusted-git-root b/contrib/verify-commits/trusted-git-root
new file mode 100644
index 0000000000..eb13f8762e
--- /dev/null
+++ b/contrib/verify-commits/trusted-git-root
@@ -0,0 +1 @@
+053038e5ba116cb319fb85f3cb3e062cf1b3df15
diff --git a/contrib/verify-commits/trusted-keys b/contrib/verify-commits/trusted-keys
new file mode 100644
index 0000000000..658ad0375b
--- /dev/null
+++ b/contrib/verify-commits/trusted-keys
@@ -0,0 +1,5 @@
+71A3B16735405025D447E8F274810B012346C9A6
+1F4410F6A89268CE3197A84C57896D2FF8F0B657
+01CDF4627A3B88AAE4A571C87588242FBE38D3A8
+AF8BE07C7049F3A26B239D5325B3083201782B2F
+81291FA67D2C379A006A053FEAB5AF94D9E9ABE7
diff --git a/contrib/verify-commits/verify-commits.sh b/contrib/verify-commits/verify-commits.sh
new file mode 100755
index 0000000000..5841fa2077
--- /dev/null
+++ b/contrib/verify-commits/verify-commits.sh
@@ -0,0 +1,51 @@
+#!/bin/sh
+
+DIR=$(dirname "$0")
+
+echo "Please verify all commits in the following list are not evil:"
+git log "$DIR"
+
+VERIFIED_ROOT=$(cat "${DIR}/trusted-git-root")
+
+HAVE_FAILED=false
+IS_SIGNED () {
+ if [ $1 = $VERIFIED_ROOT ]; then
+ return 0;
+ fi
+ if ! git -c "gpg.program=${DIR}/gpg.sh" verify-commit $1 > /dev/null 2>&1; then
+ return 1;
+ fi
+ local PARENTS=$(git show -s --format=format:%P $1)
+ for PARENT in $PARENTS; do
+ if IS_SIGNED $PARENT > /dev/null; then
+ return 0;
+ fi
+ done
+ if ! "$HAVE_FAILED"; then
+ echo "No parent of $1 was signed with a trusted key!" > /dev/stderr
+ echo "Parents are:" > /dev/stderr
+ for PARENT in $PARENTS; do
+ git show -s $PARENT > /dev/stderr
+ done
+ HAVE_FAILED=true
+ fi
+ return 1;
+}
+
+if [ x"$1" = "x" ]; then
+ TEST_COMMIT="HEAD"
+else
+ TEST_COMMIT="$1"
+fi
+
+IS_SIGNED "$TEST_COMMIT"
+RES=$?
+if [ "$RES" = 1 ]; then
+ if ! "$HAVE_FAILED"; then
+ echo "$TEST_COMMIT was not signed with a trusted key!"
+ fi
+else
+ echo "There is a valid path from $TEST_COMMIT to $VERIFIED_ROOT where all commits are signed!"
+fi
+
+exit $RES
diff --git a/contrib/verifysfbinaries/README.md b/contrib/verifysfbinaries/README.md
new file mode 100644
index 0000000000..8c038865bd
--- /dev/null
+++ b/contrib/verifysfbinaries/README.md
@@ -0,0 +1,6 @@
+### Verify SF Binaries ###
+This script attempts to download the signature file `SHA256SUMS.asc` from https://bitcoin.org.
+
+It first checks if the signature passes, and then downloads the files specified in the file, and checks if the hashes of these files match those that are specified in the signature file.
+
+The script returns 0 if everything passes the checks. It returns 1 if either the signature check or the hash check doesn't pass. If an error occurs the return value is 2. \ No newline at end of file
diff --git a/contrib/verifysfbinaries/verify.sh b/contrib/verifysfbinaries/verify.sh
new file mode 100755
index 0000000000..3eb4693883
--- /dev/null
+++ b/contrib/verifysfbinaries/verify.sh
@@ -0,0 +1,119 @@
+#!/bin/bash
+
+### This script attempts to download the signature file SHA256SUMS.asc from bitcoin.org
+### It first checks if the signature passes, and then downloads the files specified in
+### the file, and checks if the hashes of these files match those that are specified
+### in the signature file.
+### The script returns 0 if everything passes the checks. It returns 1 if either the
+### signature check or the hash check doesn't pass. If an error occurs the return value is 2
+
+function clean_up {
+ for file in $*
+ do
+ rm "$file" 2> /dev/null
+ done
+}
+
+WORKINGDIR="/tmp/bitcoin"
+TMPFILE="hashes.tmp"
+
+#this URL is used if a version number is not specified as an argument to the script
+SIGNATUREFILE="https://bitcoin.org/bin/0.9.2.1/SHA256SUMS.asc"
+
+SIGNATUREFILENAME="SHA256SUMS.asc"
+RCSUBDIR="test/"
+BASEDIR="https://bitcoin.org/bin/"
+VERSIONPREFIX="bitcoin-"
+RCVERSIONSTRING="rc"
+
+if [ ! -d "$WORKINGDIR" ]; then
+ mkdir "$WORKINGDIR"
+fi
+
+cd "$WORKINGDIR"
+
+#test if a version number has been passed as an argument
+if [ -n "$1" ]; then
+ #let's also check if the version number includes the prefix 'bitcoin-',
+ # and add this prefix if it doesn't
+ if [[ $1 == "$VERSIONPREFIX"* ]]; then
+ VERSION="$1"
+ else
+ VERSION="$VERSIONPREFIX$1"
+ fi
+
+ #now let's see if the version string contains "rc", and strip it off if it does
+ # and simultaneously add RCSUBDIR to BASEDIR, where we will look for SIGNATUREFILENAME
+ if [[ $VERSION == *"$RCVERSIONSTRING"* ]]; then
+ BASEDIR="$BASEDIR${VERSION/%-$RCVERSIONSTRING*}/"
+ BASEDIR="$BASEDIR$RCSUBDIR"
+ else
+ BASEDIR="$BASEDIR$VERSION/"
+ fi
+
+ SIGNATUREFILE="$BASEDIR$SIGNATUREFILENAME"
+else
+ BASEDIR="${SIGNATUREFILE%/*}/"
+fi
+
+#first we fetch the file containing the signature
+WGETOUT=$(wget -N "$BASEDIR$SIGNATUREFILENAME" 2>&1)
+
+#and then see if wget completed successfully
+if [ $? -ne 0 ]; then
+ echo "Error: couldn't fetch signature file. Have you specified the version number in the following format?"
+ echo "[bitcoin-]<version>-[rc[0-9]] (example: bitcoin-0.9.2-rc1)"
+ echo "wget output:"
+ echo "$WGETOUT"|sed 's/^/\t/g'
+ exit 2
+fi
+
+#then we check it
+GPGOUT=$(gpg --yes --decrypt --output "$TMPFILE" "$SIGNATUREFILENAME" 2>&1)
+
+#return value 0: good signature
+#return value 1: bad signature
+#return value 2: gpg error
+
+RET="$?"
+if [ $RET -ne 0 ]; then
+ if [ $RET -eq 1 ]; then
+ #and notify the user if it's bad
+ echo "Bad signature."
+ elif [ $RET -eq 2 ]; then
+ #or if a gpg error has occurred
+ echo "gpg error. Do you have Gavin's code signing key installed?"
+ fi
+
+ echo "gpg output:"
+ echo "$GPGOUT"|sed 's/^/\t/g'
+ clean_up $SIGNATUREFILENAME $TMPFILE
+ exit "$RET"
+fi
+
+#here we extract the filenames from the signature file
+FILES=$(awk '{print $2}' "$TMPFILE")
+
+#and download these one by one
+for file in in $FILES
+do
+ wget --quiet -N "$BASEDIR$file"
+done
+
+#check hashes
+DIFF=$(diff <(sha256sum $FILES) "$TMPFILE")
+
+if [ $? -eq 1 ]; then
+ echo "Hashes don't match."
+ echo "Offending files:"
+ echo "$DIFF"|grep "^<"|awk '{print "\t"$3}'
+ exit 1
+elif [ $? -gt 1 ]; then
+ echo "Error executing 'diff'"
+ exit 2
+fi
+
+#everything matches! clean up the mess
+clean_up $FILES $SIGNATUREFILENAME $TMPFILE
+
+exit 0
diff --git a/depends/.gitignore b/depends/.gitignore
new file mode 100644
index 0000000000..1f163897b9
--- /dev/null
+++ b/depends/.gitignore
@@ -0,0 +1,9 @@
+SDKs/
+work/
+built/
+sources/
+config.site
+x86_64*
+i686*
+mips*
+arm*
diff --git a/depends/Makefile b/depends/Makefile
new file mode 100644
index 0000000000..ef5a20e6c3
--- /dev/null
+++ b/depends/Makefile
@@ -0,0 +1,161 @@
+.NOTPARALLEL :
+
+SOURCES_PATH ?= $(BASEDIR)/sources
+BASE_CACHE ?= $(BASEDIR)/built
+SDK_PATH ?= $(BASEDIR)/SDKs
+NO_QT ?=
+NO_WALLET ?=
+NO_UPNP ?=
+FALLBACK_DOWNLOAD_PATH ?= https://bitcoincore.org/depends-sources
+
+BUILD = $(shell ./config.guess)
+HOST ?= $(BUILD)
+PATCHES_PATH = $(BASEDIR)/patches
+BASEDIR = $(CURDIR)
+HASH_LENGTH:=11
+DOWNLOAD_CONNECT_TIMEOUT:=10
+DOWNLOAD_RETRIES:=3
+
+host:=$(BUILD)
+ifneq ($(HOST),)
+host:=$(HOST)
+host_toolchain:=$(HOST)-
+endif
+
+ifneq ($(DEBUG),)
+release_type=debug
+else
+release_type=release
+endif
+
+base_build_dir=$(BASEDIR)/work/build
+base_staging_dir=$(BASEDIR)/work/staging
+base_download_dir=$(BASEDIR)/work/download
+canonical_host:=$(shell ./config.sub $(HOST))
+build:=$(shell ./config.sub $(BUILD))
+
+build_arch =$(firstword $(subst -, ,$(build)))
+build_vendor=$(word 2,$(subst -, ,$(build)))
+full_build_os:=$(subst $(build_arch)-$(build_vendor)-,,$(build))
+build_os:=$(findstring linux,$(full_build_os))
+build_os+=$(findstring darwin,$(full_build_os))
+build_os:=$(strip $(build_os))
+ifeq ($(build_os),)
+build_os=$(full_build_os)
+endif
+
+host_arch=$(firstword $(subst -, ,$(canonical_host)))
+host_vendor=$(word 2,$(subst -, ,$(canonical_host)))
+full_host_os:=$(subst $(host_arch)-$(host_vendor)-,,$(canonical_host))
+host_os:=$(findstring linux,$(full_host_os))
+host_os+=$(findstring darwin,$(full_host_os))
+host_os+=$(findstring mingw32,$(full_host_os))
+host_os:=$(strip $(host_os))
+ifeq ($(host_os),)
+host_os=$(full_host_os)
+endif
+
+$(host_arch)_$(host_os)_prefix=$(BASEDIR)/$(host)
+$(host_arch)_$(host_os)_host=$(host)
+host_prefix=$($(host_arch)_$(host_os)_prefix)
+build_prefix=$(host_prefix)/native
+build_host=$(build)
+
+AT_$(V):=
+AT_:=@
+AT:=$(AT_$(V))
+
+all: install
+
+include hosts/$(host_os).mk
+include hosts/default.mk
+include builders/$(build_os).mk
+include builders/default.mk
+include packages/packages.mk
+
+qt_packages_$(NO_QT) = $(qt_packages) $(qt_$(host_os)_packages)
+qt_native_packages_$(NO_QT) = $(qt_native_packages)
+wallet_packages_$(NO_WALLET) = $(wallet_packages)
+upnp_packages_$(NO_UPNP) = $(upnp_packages)
+
+packages += $($(host_arch)_$(host_os)_packages) $($(host_os)_packages) $(qt_packages_) $(wallet_packages_) $(upnp_packages_)
+native_packages += $($(host_arch)_$(host_os)_native_packages) $($(host_os)_native_packages) $(qt_native_packages_)
+all_packages = $(packages) $(native_packages)
+
+meta_depends = Makefile funcs.mk builders/default.mk hosts/default.mk hosts/$(host_os).mk builders/$(build_os).mk
+
+$(host_arch)_$(host_os)_native_toolchain?=$($(host_os)_native_toolchain)
+
+include funcs.mk
+
+toolchain_path=$($($(host_arch)_$(host_os)_native_toolchain)_prefixbin)
+final_build_id_long+=$(shell $(build_SHA256SUM) config.site.in)
+final_build_id+=$(shell echo -n $(final_build_id_long) | $(build_SHA256SUM) | cut -c-$(HASH_LENGTH))
+$(host_prefix)/.stamp_$(final_build_id): $(native_packages) $(packages)
+ $(AT)rm -rf $(@D)
+ $(AT)mkdir -p $(@D)
+ $(AT)echo copying packages: $^
+ $(AT)echo to: $(@D)
+ $(AT)cd $(@D); $(foreach package,$^, tar xf $($(package)_cached); )
+ $(AT)touch $@
+
+$(host_prefix)/share/config.site : config.site.in $(host_prefix)/.stamp_$(final_build_id)
+ $(AT)@mkdir -p $(@D)
+ $(AT)sed -e 's|@HOST@|$(host)|' \
+ -e 's|@CC@|$(toolchain_path)$(host_CC)|' \
+ -e 's|@CXX@|$(toolchain_path)$(host_CXX)|' \
+ -e 's|@AR@|$(toolchain_path)$(host_AR)|' \
+ -e 's|@RANLIB@|$(toolchain_path)$(host_RANLIB)|' \
+ -e 's|@NM@|$(toolchain_path)$(host_NM)|' \
+ -e 's|@STRIP@|$(toolchain_path)$(host_STRIP)|' \
+ -e 's|@build_os@|$(build_os)|' \
+ -e 's|@host_os@|$(host_os)|' \
+ -e 's|@CFLAGS@|$(strip $(host_CFLAGS) $(host_$(release_type)_CFLAGS))|' \
+ -e 's|@CXXFLAGS@|$(strip $(host_CXXFLAGS) $(host_$(release_type)_CXXFLAGS))|' \
+ -e 's|@CPPFLAGS@|$(strip $(host_CPPFLAGS) $(host_$(release_type)_CPPFLAGS))|' \
+ -e 's|@LDFLAGS@|$(strip $(host_LDFLAGS) $(host_$(release_type)_LDFLAGS))|' \
+ -e 's|@no_qt@|$(NO_QT)|' \
+ -e 's|@no_wallet@|$(NO_WALLET)|' \
+ -e 's|@no_upnp@|$(NO_UPNP)|' \
+ -e 's|@debug@|$(DEBUG)|' \
+ $< > $@
+ $(AT)touch $@
+
+
+define check_or_remove_cached
+ mkdir -p $(BASE_CACHE)/$(host)/$(package) && cd $(BASE_CACHE)/$(host)/$(package); \
+ $(build_SHA256SUM) -c $($(package)_cached_checksum) >/dev/null 2>/dev/null || \
+ ( rm -f $($(package)_cached_checksum); \
+ if test -f "$($(package)_cached)"; then echo "Checksum mismatch for $(package). Forcing rebuild.."; rm -f $($(package)_cached_checksum) $($(package)_cached); fi )
+endef
+
+define check_or_remove_sources
+ mkdir -p $($(package)_source_dir); cd $($(package)_source_dir); \
+ $(build_SHA256SUM) -c $($(package)_fetched) >/dev/null 2>/dev/null || \
+ ( if test -f $($(package)_all_sources); then echo "Checksum missing or mismatched for $(package) source. Forcing re-download."; fi; \
+ rm -f $($(package)_all_sources) $($(1)_fetched))
+endef
+
+check-packages:
+ @$(foreach package,$(all_packages),$(call check_or_remove_cached,$(package));)
+check-sources:
+ @$(foreach package,$(all_packages),$(call check_or_remove_sources,$(package));)
+
+$(host_prefix)/share/config.site: check-packages
+
+check-packages: check-sources
+
+install: check-packages $(host_prefix)/share/config.site
+
+
+download-one: check-sources $(all_sources)
+
+download-osx:
+ @$(MAKE) -s HOST=x86_64-apple-darwin11 download-one
+download-linux:
+ @$(MAKE) -s HOST=x86_64-unknown-linux-gnu download-one
+download-win:
+ @$(MAKE) -s HOST=x86_64-w64-mingw32 download-one
+download: download-osx download-linux download-win
+
+.PHONY: install cached download-one download-osx download-linux download-win download check-packages check-sources
diff --git a/depends/README.md b/depends/README.md
new file mode 100644
index 0000000000..2dc0b9e47e
--- /dev/null
+++ b/depends/README.md
@@ -0,0 +1,56 @@
+### Usage
+
+To build dependencies for the current arch+OS:
+
+ make
+
+To build for another arch/OS:
+
+ make HOST=host-platform-triplet
+
+For example:
+
+ make HOST=x86_64-w64-mingw32 -j4
+
+A prefix will be generated that's suitable for plugging into Bitcoin's
+configure. In the above example, a dir named i686-w64-mingw32 will be
+created. To use it for Bitcoin:
+
+ ./configure --prefix=`pwd`/depends/x86_64-w64-mingw32
+
+Common `host-platform-triplets` for cross compilation are:
+
+- `i686-w64-mingw32` for Win32
+- `x86_64-w64-mingw32` for Win64
+- `x86_64-apple-darwin11` for MacOSX
+- `arm-linux-gnueabihf` for Linux ARM
+
+No other options are needed, the paths are automatically configured.
+
+Dependency Options:
+The following can be set when running make: make FOO=bar
+
+ SOURCES_PATH: downloaded sources will be placed here
+ BASE_CACHE: built packages will be placed here
+ SDK_PATH: Path where sdk's can be found (used by OSX)
+ FALLBACK_DOWNLOAD_PATH: If a source file can't be fetched, try here before giving up
+ NO_QT: Don't download/build/cache qt and its dependencies
+ NO_WALLET: Don't download/build/cache libs needed to enable the wallet
+ NO_UPNP: Don't download/build/cache packages needed for enabling upnp
+ DEBUG: disable some optimizations and enable more runtime checking
+
+If some packages are not built, for example `make NO_WALLET=1`, the appropriate
+options will be passed to bitcoin's configure. In this case, `--disable-wallet`.
+
+Additional targets:
+
+ download: run 'make download' to fetch all sources without building them
+ download-osx: run 'make download-osx' to fetch all sources needed for osx builds
+ download-win: run 'make download-win' to fetch all sources needed for win builds
+ download-linux: run 'make download-linux' to fetch all sources needed for linux builds
+
+### Other documentation
+
+- [description.md](description.md): General description of the depends system
+- [packages.md](packages.md): Steps for adding packages
+
diff --git a/depends/builders/darwin.mk b/depends/builders/darwin.mk
new file mode 100644
index 0000000000..b366460e64
--- /dev/null
+++ b/depends/builders/darwin.mk
@@ -0,0 +1,22 @@
+build_darwin_CC: = $(shell xcrun -f clang)
+build_darwin_CXX: = $(shell xcrun -f clang++)
+build_darwin_AR: = $(shell xcrun -f ar)
+build_darwin_RANLIB: = $(shell xcrun -f ranlib)
+build_darwin_STRIP: = $(shell xcrun -f strip)
+build_darwin_OTOOL: = $(shell xcrun -f otool)
+build_darwin_NM: = $(shell xcrun -f nm)
+build_darwin_INSTALL_NAME_TOOL:=$(shell xcrun -f install_name_tool)
+build_darwin_SHA256SUM = shasum -a 256
+build_darwin_DOWNLOAD = curl --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -L -o
+
+#darwin host on darwin builder. overrides darwin host preferences.
+darwin_CC=$(shell xcrun -f clang) -mmacosx-version-min=$(OSX_MIN_VERSION)
+darwin_CXX:=$(shell xcrun -f clang++) -mmacosx-version-min=$(OSX_MIN_VERSION)
+darwin_AR:=$(shell xcrun -f ar)
+darwin_RANLIB:=$(shell xcrun -f ranlib)
+darwin_STRIP:=$(shell xcrun -f strip)
+darwin_LIBTOOL:=$(shell xcrun -f libtool)
+darwin_OTOOL:=$(shell xcrun -f otool)
+darwin_NM:=$(shell xcrun -f nm)
+darwin_INSTALL_NAME_TOOL:=$(shell xcrun -f install_name_tool)
+darwin_native_toolchain=
diff --git a/depends/builders/default.mk b/depends/builders/default.mk
new file mode 100644
index 0000000000..f097db65d6
--- /dev/null
+++ b/depends/builders/default.mk
@@ -0,0 +1,20 @@
+default_build_CC = gcc
+default_build_CXX = g++
+default_build_AR = ar
+default_build_RANLIB = ranlib
+default_build_STRIP = strip
+default_build_NM = nm
+default_build_OTOOL = otool
+default_build_INSTALL_NAME_TOOL = install_name_tool
+
+define add_build_tool_func
+build_$(build_os)_$1 ?= $$(default_build_$1)
+build_$(build_arch)_$(build_os)_$1 ?= $$(build_$(build_os)_$1)
+build_$1=$$(build_$(build_arch)_$(build_os)_$1)
+endef
+$(foreach var,CC CXX AR RANLIB NM STRIP SHA256SUM DOWNLOAD OTOOL INSTALL_NAME_TOOL,$(eval $(call add_build_tool_func,$(var))))
+define add_build_flags_func
+build_$(build_arch)_$(build_os)_$1 += $(build_$(build_os)_$1)
+build_$1=$$(build_$(build_arch)_$(build_os)_$1)
+endef
+$(foreach flags, CFLAGS CXXFLAGS LDFLAGS, $(eval $(call add_build_flags_func,$(flags))))
diff --git a/depends/builders/linux.mk b/depends/builders/linux.mk
new file mode 100644
index 0000000000..98d0e9de34
--- /dev/null
+++ b/depends/builders/linux.mk
@@ -0,0 +1,2 @@
+build_linux_SHA256SUM = sha256sum
+build_linux_DOWNLOAD = wget --timeout=$(DOWNLOAD_CONNECT_TIMEOUT) --tries=$(DOWNLOAD_RETRIES) -nv -O
diff --git a/depends/config.guess b/depends/config.guess
new file mode 100755
index 0000000000..f357ec6c8f
--- /dev/null
+++ b/depends/config.guess
@@ -0,0 +1,1438 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+# Copyright 1992-2015 Free Software Foundation, Inc.
+
+timestamp='2015-03-04'
+
+# This file 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 <http://www.gnu.org/licenses/>.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that
+# program. This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
+#
+# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
+#
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+#
+# Please send patches to <config-patches@gnu.org>.
+
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright 1992-2015 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help" >&2
+ exit 1 ;;
+ * )
+ break ;;
+ esac
+done
+
+if test $# != 0; then
+ echo "$me: too many arguments$help" >&2
+ exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,) echo "int x;" > $dummy.c ;
+ for c in cc gcc c89 c99 ; do
+ if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+ CC_FOR_BUILD="$c"; break ;
+ fi ;
+ done ;
+ if test x"$CC_FOR_BUILD" = x ; then
+ CC_FOR_BUILD=no_compiler_found ;
+ fi
+ ;;
+ ,,*) CC_FOR_BUILD=$CC ;;
+ ,*,*) CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+ PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+case "${UNAME_SYSTEM}" in
+Linux|GNU|GNU/*)
+ # If the system lacks a compiler, then just pick glibc.
+ # We could probably try harder.
+ LIBC=gnu
+
+ eval $set_cc_for_build
+ cat <<-EOF > $dummy.c
+ #include <features.h>
+ #if defined(__UCLIBC__)
+ LIBC=uclibc
+ #elif defined(__dietlibc__)
+ LIBC=dietlibc
+ #else
+ LIBC=gnu
+ #endif
+ EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
+ ;;
+esac
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ *:NetBSD:*:*)
+ # NetBSD (nbsd) targets should (where applicable) match one or
+ # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
+ # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
+ # switched to ELF, *-*-netbsd* would select the old
+ # object file format. This provides both forward
+ # compatibility and a consistent mechanism for selecting the
+ # object file format.
+ #
+ # Note: NetBSD doesn't particularly care about the vendor
+ # portion of the name. We always set it to "unknown".
+ sysctl="sysctl -n hw.machine_arch"
+ UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
+ /sbin/$sysctl 2>/dev/null || \
+ /usr/sbin/$sysctl 2>/dev/null || \
+ echo unknown)`
+ case "${UNAME_MACHINE_ARCH}" in
+ armeb) machine=armeb-unknown ;;
+ arm*) machine=arm-unknown ;;
+ sh3el) machine=shl-unknown ;;
+ sh3eb) machine=sh-unknown ;;
+ sh5el) machine=sh5le-unknown ;;
+ earmv*)
+ arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
+ endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'`
+ machine=${arch}${endian}-unknown
+ ;;
+ *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+ esac
+ # The Operating System including object format, if it has switched
+ # to ELF recently, or will in the future.
+ case "${UNAME_MACHINE_ARCH}" in
+ arm*|earm*|i386|m68k|ns32k|sh3*|sparc|vax)
+ eval $set_cc_for_build
+ if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ELF__
+ then
+ # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+ # Return netbsd for either. FIX?
+ os=netbsd
+ else
+ os=netbsdelf
+ fi
+ ;;
+ *)
+ os=netbsd
+ ;;
+ esac
+ # Determine ABI tags.
+ case "${UNAME_MACHINE_ARCH}" in
+ earm*)
+ expr='s/^earmv[0-9]/-eabi/;s/eb$//'
+ abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"`
+ ;;
+ esac
+ # The OS release
+ # Debian GNU/NetBSD machines have a different userland, and
+ # thus, need a distinct triplet. However, they do not need
+ # kernel version information, so it can be replaced with a
+ # suitable tag, in the style of linux-gnu.
+ case "${UNAME_VERSION}" in
+ Debian*)
+ release='-gnu'
+ ;;
+ *)
+ release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ ;;
+ esac
+ # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+ # contains redundant information, the shorter form:
+ # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+ echo "${machine}-${os}${release}${abi}"
+ exit ;;
+ *:Bitrig:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
+ exit ;;
+ *:OpenBSD:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+ exit ;;
+ *:ekkoBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+ exit ;;
+ *:SolidBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+ exit ;;
+ macppc:MirBSD:*:*)
+ echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ *:MirBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ alpha:OSF1:*:*)
+ case $UNAME_RELEASE in
+ *4.0)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ ;;
+ *5.*)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+ ;;
+ esac
+ # According to Compaq, /usr/sbin/psrinfo has been available on
+ # OSF/1 and Tru64 systems produced since 1995. I hope that
+ # covers most systems running today. This code pipes the CPU
+ # types through head -n 1, so we only detect the type of CPU 0.
+ ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+ case "$ALPHA_CPU_TYPE" in
+ "EV4 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "EV4.5 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "LCA4 (21066/21068)")
+ UNAME_MACHINE="alpha" ;;
+ "EV5 (21164)")
+ UNAME_MACHINE="alphaev5" ;;
+ "EV5.6 (21164A)")
+ UNAME_MACHINE="alphaev56" ;;
+ "EV5.6 (21164PC)")
+ UNAME_MACHINE="alphapca56" ;;
+ "EV5.7 (21164PC)")
+ UNAME_MACHINE="alphapca57" ;;
+ "EV6 (21264)")
+ UNAME_MACHINE="alphaev6" ;;
+ "EV6.7 (21264A)")
+ UNAME_MACHINE="alphaev67" ;;
+ "EV6.8CB (21264C)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8AL (21264B)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8CX (21264D)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.9A (21264/EV69A)")
+ UNAME_MACHINE="alphaev69" ;;
+ "EV7 (21364)")
+ UNAME_MACHINE="alphaev7" ;;
+ "EV7.9 (21364A)")
+ UNAME_MACHINE="alphaev79" ;;
+ esac
+ # A Pn.n version is a patched version.
+ # A Vn.n version is a released version.
+ # A Tn.n version is a released field test version.
+ # A Xn.n version is an unreleased experimental baselevel.
+ # 1.2 uses "1.2" for uname -r.
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+ exitcode=$?
+ trap '' 0
+ exit $exitcode ;;
+ Alpha\ *:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # Should we change UNAME_MACHINE based on the output of uname instead
+ # of the specific Alpha model?
+ echo alpha-pc-interix
+ exit ;;
+ 21064:Windows_NT:50:3)
+ echo alpha-dec-winnt3.5
+ exit ;;
+ Amiga*:UNIX_System_V:4.0:*)
+ echo m68k-unknown-sysv4
+ exit ;;
+ *:[Aa]miga[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-amigaos
+ exit ;;
+ *:[Mm]orph[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-morphos
+ exit ;;
+ *:OS/390:*:*)
+ echo i370-ibm-openedition
+ exit ;;
+ *:z/VM:*:*)
+ echo s390-ibm-zvmoe
+ exit ;;
+ *:OS400:*:*)
+ echo powerpc-ibm-os400
+ exit ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix${UNAME_RELEASE}
+ exit ;;
+ arm*:riscos:*:*|arm*:RISCOS:*:*)
+ echo arm-unknown-riscos
+ exit ;;
+ SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+ echo hppa1.1-hitachi-hiuxmpp
+ exit ;;
+ Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+ # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+ if test "`(/bin/universe) 2>/dev/null`" = att ; then
+ echo pyramid-pyramid-sysv3
+ else
+ echo pyramid-pyramid-bsd
+ fi
+ exit ;;
+ NILE*:*:*:dcosx)
+ echo pyramid-pyramid-svr4
+ exit ;;
+ DRS?6000:unix:4.0:6*)
+ echo sparc-icl-nx6
+ exit ;;
+ DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+ case `/usr/bin/uname -p` in
+ sparc) echo sparc-icl-nx7; exit ;;
+ esac ;;
+ s390x:SunOS:*:*)
+ echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4H:SunOS:5.*:*)
+ echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+ echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
+ echo i386-pc-auroraux${UNAME_RELEASE}
+ exit ;;
+ i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+ eval $set_cc_for_build
+ SUN_ARCH="i386"
+ # If there is a compiler, see if it is configured for 64-bit objects.
+ # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+ # This test works for both compilers.
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ SUN_ARCH="x86_64"
+ fi
+ fi
+ echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:6*:*)
+ # According to config.sub, this is the proper way to canonicalize
+ # SunOS6. Hard to guess exactly what SunOS6 will be like, but
+ # it's likely to be more like Solaris than SunOS4.
+ echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:*:*)
+ case "`/usr/bin/arch -k`" in
+ Series*|S4*)
+ UNAME_RELEASE=`uname -v`
+ ;;
+ esac
+ # Japanese Language versions have a version number like `4.1.3-JL'.
+ echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+ exit ;;
+ sun3*:SunOS:*:*)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ exit ;;
+ sun*:*:4.2BSD:*)
+ UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+ test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+ case "`/bin/arch`" in
+ sun3)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ ;;
+ sun4)
+ echo sparc-sun-sunos${UNAME_RELEASE}
+ ;;
+ esac
+ exit ;;
+ aushp:SunOS:*:*)
+ echo sparc-auspex-sunos${UNAME_RELEASE}
+ exit ;;
+ # The situation for MiNT is a little confusing. The machine name
+ # can be virtually everything (everything which is not
+ # "atarist" or "atariste" at least should have a processor
+ # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
+ # to the lowercase version "mint" (or "freemint"). Finally
+ # the system name "TOS" denotes a system which is actually not
+ # MiNT. But MiNT is downward compatible to TOS, so this should
+ # be no problem.
+ atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+ echo m68k-milan-mint${UNAME_RELEASE}
+ exit ;;
+ hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+ echo m68k-hades-mint${UNAME_RELEASE}
+ exit ;;
+ *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+ echo m68k-unknown-mint${UNAME_RELEASE}
+ exit ;;
+ m68k:machten:*:*)
+ echo m68k-apple-machten${UNAME_RELEASE}
+ exit ;;
+ powerpc:machten:*:*)
+ echo powerpc-apple-machten${UNAME_RELEASE}
+ exit ;;
+ RISC*:Mach:*:*)
+ echo mips-dec-mach_bsd4.3
+ exit ;;
+ RISC*:ULTRIX:*:*)
+ echo mips-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ VAX*:ULTRIX*:*:*)
+ echo vax-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ 2020:CLIX:*:* | 2430:CLIX:*:*)
+ echo clipper-intergraph-clix${UNAME_RELEASE}
+ exit ;;
+ mips:*:*:UMIPS | mips:*:*:RISCos)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h> /* for printf() prototype */
+ int main (int argc, char *argv[]) {
+#else
+ int main (argc, argv) int argc; char *argv[]; {
+#endif
+ #if defined (host_mips) && defined (MIPSEB)
+ #if defined (SYSTYPE_SYSV)
+ printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_SVR4)
+ printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+ printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ #endif
+ #endif
+ exit (-1);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c &&
+ dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+ SYSTEM_NAME=`$dummy $dummyarg` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo mips-mips-riscos${UNAME_RELEASE}
+ exit ;;
+ Motorola:PowerMAX_OS:*:*)
+ echo powerpc-motorola-powermax
+ exit ;;
+ Motorola:*:4.3:PL8-*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:Power_UNIX:*:*)
+ echo powerpc-harris-powerunix
+ exit ;;
+ m88k:CX/UX:7*:*)
+ echo m88k-harris-cxux7
+ exit ;;
+ m88k:*:4*:R4*)
+ echo m88k-motorola-sysv4
+ exit ;;
+ m88k:*:3*:R3*)
+ echo m88k-motorola-sysv3
+ exit ;;
+ AViiON:dgux:*:*)
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+ then
+ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+ [ ${TARGET_BINARY_INTERFACE}x = x ]
+ then
+ echo m88k-dg-dgux${UNAME_RELEASE}
+ else
+ echo m88k-dg-dguxbcs${UNAME_RELEASE}
+ fi
+ else
+ echo i586-dg-dgux${UNAME_RELEASE}
+ fi
+ exit ;;
+ M88*:DolphinOS:*:*) # DolphinOS (SVR3)
+ echo m88k-dolphin-sysv3
+ exit ;;
+ M88*:*:R3*:*)
+ # Delta 88k system running SVR3
+ echo m88k-motorola-sysv3
+ exit ;;
+ XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+ echo m88k-tektronix-sysv3
+ exit ;;
+ Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+ echo m68k-tektronix-bsd
+ exit ;;
+ *:IRIX*:*:*)
+ echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+ exit ;;
+ ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+ echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ exit ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ i*86:AIX:*:*)
+ echo i386-ibm-aix
+ exit ;;
+ ia64:AIX:*:*)
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+ exit ;;
+ *:AIX:2:3)
+ if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <sys/systemcfg.h>
+
+ main()
+ {
+ if (!__power_pc())
+ exit(1);
+ puts("powerpc-ibm-aix3.2.5");
+ exit(0);
+ }
+EOF
+ if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+ then
+ echo "$SYSTEM_NAME"
+ else
+ echo rs6000-ibm-aix3.2.5
+ fi
+ elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+ echo rs6000-ibm-aix3.2.4
+ else
+ echo rs6000-ibm-aix3.2
+ fi
+ exit ;;
+ *:AIX:*:[4567])
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+ if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+ IBM_ARCH=rs6000
+ else
+ IBM_ARCH=powerpc
+ fi
+ if [ -x /usr/bin/lslpp ] ; then
+ IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
+ awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+ exit ;;
+ *:AIX:*:*)
+ echo rs6000-ibm-aix
+ exit ;;
+ ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+ echo romp-ibm-bsd4.4
+ exit ;;
+ ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
+ echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ exit ;; # report: romp-ibm BSD 4.3
+ *:BOSX:*:*)
+ echo rs6000-bull-bosx
+ exit ;;
+ DPX/2?00:B.O.S.:*:*)
+ echo m68k-bull-sysv3
+ exit ;;
+ 9000/[34]??:4.3bsd:1.*:*)
+ echo m68k-hp-bsd
+ exit ;;
+ hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+ echo m68k-hp-bsd4.4
+ exit ;;
+ 9000/[34678]??:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ case "${UNAME_MACHINE}" in
+ 9000/31? ) HP_ARCH=m68000 ;;
+ 9000/[34]?? ) HP_ARCH=m68k ;;
+ 9000/[678][0-9][0-9])
+ if [ -x /usr/bin/getconf ]; then
+ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+ case "${sc_cpu_version}" in
+ 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+ 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+ 532) # CPU_PA_RISC2_0
+ case "${sc_kernel_bits}" in
+ 32) HP_ARCH="hppa2.0n" ;;
+ 64) HP_ARCH="hppa2.0w" ;;
+ '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
+ esac ;;
+ esac
+ fi
+ if [ "${HP_ARCH}" = "" ]; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+
+ #define _HPUX_SOURCE
+ #include <stdlib.h>
+ #include <unistd.h>
+
+ int main ()
+ {
+ #if defined(_SC_KERNEL_BITS)
+ long bits = sysconf(_SC_KERNEL_BITS);
+ #endif
+ long cpu = sysconf (_SC_CPU_VERSION);
+
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+ case CPU_PA_RISC2_0:
+ #if defined(_SC_KERNEL_BITS)
+ switch (bits)
+ {
+ case 64: puts ("hppa2.0w"); break;
+ case 32: puts ("hppa2.0n"); break;
+ default: puts ("hppa2.0"); break;
+ } break;
+ #else /* !defined(_SC_KERNEL_BITS) */
+ puts ("hppa2.0"); break;
+ #endif
+ default: puts ("hppa1.0"); break;
+ }
+ exit (0);
+ }
+EOF
+ (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+ test -z "$HP_ARCH" && HP_ARCH=hppa
+ fi ;;
+ esac
+ if [ ${HP_ARCH} = "hppa2.0w" ]
+ then
+ eval $set_cc_for_build
+
+ # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+ # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
+ # generating 64-bit code. GNU and HP use different nomenclature:
+ #
+ # $ CC_FOR_BUILD=cc ./config.guess
+ # => hppa2.0w-hp-hpux11.23
+ # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+ # => hppa64-hp-hpux11.23
+
+ if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+ grep -q __LP64__
+ then
+ HP_ARCH="hppa2.0w"
+ else
+ HP_ARCH="hppa64"
+ fi
+ fi
+ echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+ exit ;;
+ ia64:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ echo ia64-hp-hpux${HPUX_REV}
+ exit ;;
+ 3050*:HI-UX:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <unistd.h>
+ int
+ main ()
+ {
+ long cpu = sysconf (_SC_CPU_VERSION);
+ /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+ true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
+ results, however. */
+ if (CPU_IS_PA_RISC (cpu))
+ {
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+ default: puts ("hppa-hitachi-hiuxwe2"); break;
+ }
+ }
+ else if (CPU_IS_HP_MC68K (cpu))
+ puts ("m68k-hitachi-hiuxwe2");
+ else puts ("unknown-hitachi-hiuxwe2");
+ exit (0);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo unknown-hitachi-hiuxwe2
+ exit ;;
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+ echo hppa1.1-hp-bsd
+ exit ;;
+ 9000/8??:4.3bsd:*:*)
+ echo hppa1.0-hp-bsd
+ exit ;;
+ *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+ echo hppa1.0-hp-mpeix
+ exit ;;
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ echo hppa1.1-hp-osf
+ exit ;;
+ hp8??:OSF1:*:*)
+ echo hppa1.0-hp-osf
+ exit ;;
+ i*86:OSF1:*:*)
+ if [ -x /usr/sbin/sysversion ] ; then
+ echo ${UNAME_MACHINE}-unknown-osf1mk
+ else
+ echo ${UNAME_MACHINE}-unknown-osf1
+ fi
+ exit ;;
+ parisc*:Lites*:*:*)
+ echo hppa1.1-hp-lites
+ exit ;;
+ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ echo c1-convex-bsd
+ exit ;;
+ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit ;;
+ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ echo c34-convex-bsd
+ exit ;;
+ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ echo c38-convex-bsd
+ exit ;;
+ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ echo c4-convex-bsd
+ exit ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*[A-Z]90:*:*:*)
+ echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+ -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*TS:*:*:*)
+ echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*T3E:*:*:*)
+ echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*SV1:*:*:*)
+ echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ *:UNICOS/mp:*:*)
+ echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+ FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ 5000:UNIX_System_V:4.*:*)
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+ echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+ exit ;;
+ sparc*:BSD/OS:*:*)
+ echo sparc-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:FreeBSD:*:*)
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ case ${UNAME_PROCESSOR} in
+ amd64)
+ echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ *)
+ echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ esac
+ exit ;;
+ i*:CYGWIN*:*)
+ echo ${UNAME_MACHINE}-pc-cygwin
+ exit ;;
+ *:MINGW64*:*)
+ echo ${UNAME_MACHINE}-pc-mingw64
+ exit ;;
+ *:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit ;;
+ *:MSYS*:*)
+ echo ${UNAME_MACHINE}-pc-msys
+ exit ;;
+ i*:windows32*:*)
+ # uname -m includes "-pc" on this system.
+ echo ${UNAME_MACHINE}-mingw32
+ exit ;;
+ i*:PW*:*)
+ echo ${UNAME_MACHINE}-pc-pw32
+ exit ;;
+ *:Interix*:*)
+ case ${UNAME_MACHINE} in
+ x86)
+ echo i586-pc-interix${UNAME_RELEASE}
+ exit ;;
+ authenticamd | genuineintel | EM64T)
+ echo x86_64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ IA64)
+ echo ia64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ esac ;;
+ [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+ echo i${UNAME_MACHINE}-pc-mks
+ exit ;;
+ 8664:Windows_NT:*)
+ echo x86_64-pc-mks
+ exit ;;
+ i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+ # UNAME_MACHINE based on the output of uname instead of i386?
+ echo i586-pc-interix
+ exit ;;
+ i*:UWIN*:*)
+ echo ${UNAME_MACHINE}-pc-uwin
+ exit ;;
+ amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+ echo x86_64-unknown-cygwin
+ exit ;;
+ p*:CYGWIN*:*)
+ echo powerpcle-unknown-cygwin
+ exit ;;
+ prep*:SunOS:5.*:*)
+ echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ *:GNU:*:*)
+ # the GNU system
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ exit ;;
+ *:GNU/*:*:*)
+ # other systems with GNU libc and userland
+ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
+ exit ;;
+ i*86:Minix:*:*)
+ echo ${UNAME_MACHINE}-pc-minix
+ exit ;;
+ aarch64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ aarch64_be:Linux:*:*)
+ UNAME_MACHINE=aarch64_be
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ alpha:Linux:*:*)
+ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+ EV5) UNAME_MACHINE=alphaev5 ;;
+ EV56) UNAME_MACHINE=alphaev56 ;;
+ PCA56) UNAME_MACHINE=alphapca56 ;;
+ PCA57) UNAME_MACHINE=alphapca56 ;;
+ EV6) UNAME_MACHINE=alphaev6 ;;
+ EV67) UNAME_MACHINE=alphaev67 ;;
+ EV68*) UNAME_MACHINE=alphaev68 ;;
+ esac
+ objdump --private-headers /bin/sh | grep -q ld.so.1
+ if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ arc:Linux:*:* | arceb:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ arm*:Linux:*:*)
+ eval $set_cc_for_build
+ if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_EABI__
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ else
+ if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_PCS_VFP
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
+ else
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
+ fi
+ fi
+ exit ;;
+ avr32*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ cris:Linux:*:*)
+ echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+ exit ;;
+ crisv32:Linux:*:*)
+ echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+ exit ;;
+ e2k:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ frv:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ hexagon:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ i*86:Linux:*:*)
+ echo ${UNAME_MACHINE}-pc-linux-${LIBC}
+ exit ;;
+ ia64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ m32r*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ m68*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ mips:Linux:*:* | mips64:Linux:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #undef CPU
+ #undef ${UNAME_MACHINE}
+ #undef ${UNAME_MACHINE}el
+ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+ CPU=${UNAME_MACHINE}el
+ #else
+ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+ CPU=${UNAME_MACHINE}
+ #else
+ CPU=
+ #endif
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
+ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
+ ;;
+ openrisc*:Linux:*:*)
+ echo or1k-unknown-linux-${LIBC}
+ exit ;;
+ or32:Linux:*:* | or1k*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ padre:Linux:*:*)
+ echo sparc-unknown-linux-${LIBC}
+ exit ;;
+ parisc64:Linux:*:* | hppa64:Linux:*:*)
+ echo hppa64-unknown-linux-${LIBC}
+ exit ;;
+ parisc:Linux:*:* | hppa:Linux:*:*)
+ # Look for CPU level
+ case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+ PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
+ PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
+ *) echo hppa-unknown-linux-${LIBC} ;;
+ esac
+ exit ;;
+ ppc64:Linux:*:*)
+ echo powerpc64-unknown-linux-${LIBC}
+ exit ;;
+ ppc:Linux:*:*)
+ echo powerpc-unknown-linux-${LIBC}
+ exit ;;
+ ppc64le:Linux:*:*)
+ echo powerpc64le-unknown-linux-${LIBC}
+ exit ;;
+ ppcle:Linux:*:*)
+ echo powerpcle-unknown-linux-${LIBC}
+ exit ;;
+ s390:Linux:*:* | s390x:Linux:*:*)
+ echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
+ exit ;;
+ sh64*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ sh*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ sparc:Linux:*:* | sparc64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ tile*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ vax:Linux:*:*)
+ echo ${UNAME_MACHINE}-dec-linux-${LIBC}
+ exit ;;
+ x86_64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ xtensa*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ i*86:DYNIX/ptx:4*:*)
+ # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+ # earlier versions are messed up and put the nodename in both
+ # sysname and nodename.
+ echo i386-sequent-sysv4
+ exit ;;
+ i*86:UNIX_SV:4.2MP:2.*)
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+ # Use sysv4.2uw... so that sysv4* matches it.
+ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ exit ;;
+ i*86:OS/2:*:*)
+ # If we were able to find `uname', then EMX Unix compatibility
+ # is probably installed.
+ echo ${UNAME_MACHINE}-pc-os2-emx
+ exit ;;
+ i*86:XTS-300:*:STOP)
+ echo ${UNAME_MACHINE}-unknown-stop
+ exit ;;
+ i*86:atheos:*:*)
+ echo ${UNAME_MACHINE}-unknown-atheos
+ exit ;;
+ i*86:syllable:*:*)
+ echo ${UNAME_MACHINE}-pc-syllable
+ exit ;;
+ i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ i*86:*DOS:*:*)
+ echo ${UNAME_MACHINE}-pc-msdosdjgpp
+ exit ;;
+ i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+ UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+ if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+ echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+ else
+ echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+ fi
+ exit ;;
+ i*86:*:5:[678]*)
+ # UnixWare 7.x, OpenUNIX and OpenServer 6.
+ case `/bin/uname -X | grep "^Machine"` in
+ *486*) UNAME_MACHINE=i486 ;;
+ *Pentium) UNAME_MACHINE=i586 ;;
+ *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+ esac
+ echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+ exit ;;
+ i*86:*:3.2:*)
+ if test -f /usr/options/cb.name; then
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+ elif /bin/uname -X 2>/dev/null >/dev/null ; then
+ UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+ && UNAME_MACHINE=i586
+ (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+ && UNAME_MACHINE=i686
+ (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+ && UNAME_MACHINE=i686
+ echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+ else
+ echo ${UNAME_MACHINE}-pc-sysv32
+ fi
+ exit ;;
+ pc:*:*:*)
+ # Left here for compatibility:
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i586.
+ # Note: whatever this is, it MUST be the same as what config.sub
+ # prints for the "djgpp" host, or else GDB configure will decide that
+ # this is a cross-build.
+ echo i586-pc-msdosdjgpp
+ exit ;;
+ Intel:Mach:3*:*)
+ echo i386-pc-mach3
+ exit ;;
+ paragon:*:*:*)
+ echo i860-intel-osf1
+ exit ;;
+ i860:*:4.*:*) # i860-SVR4
+ if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+ echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+ else # Add other i860-SVR4 vendors below as they are discovered.
+ echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
+ fi
+ exit ;;
+ mini*:CTIX:SYS*5:*)
+ # "miniframe"
+ echo m68010-convergent-sysv
+ exit ;;
+ mc68k:UNIX:SYSTEM5:3.51m)
+ echo m68k-convergent-sysv
+ exit ;;
+ M680?0:D-NIX:5.3:*)
+ echo m68k-diab-dnix
+ exit ;;
+ M68*:*:R3V[5678]*:*)
+ test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+ 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+ OS_REL=''
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4; exit; } ;;
+ NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+ OS_REL='.3'
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+ echo m68k-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ mc68030:UNIX_System_V:4.*:*)
+ echo m68k-atari-sysv4
+ exit ;;
+ TSUNAMI:LynxOS:2.*:*)
+ echo sparc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ rs6000:LynxOS:2.*:*)
+ echo rs6000-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
+ echo powerpc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ SM[BE]S:UNIX_SV:*:*)
+ echo mips-dde-sysv${UNAME_RELEASE}
+ exit ;;
+ RM*:ReliantUNIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ RM*:SINIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ *:SINIX-*:*:*)
+ if uname -p 2>/dev/null >/dev/null ; then
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ echo ${UNAME_MACHINE}-sni-sysv4
+ else
+ echo ns32k-sni-sysv
+ fi
+ exit ;;
+ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes@openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+ echo hppa1.1-stratus-sysv4
+ exit ;;
+ *:*:*:FTX*)
+ # From seanf@swdc.stratus.com.
+ echo i860-stratus-sysv4
+ exit ;;
+ i*86:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo ${UNAME_MACHINE}-stratus-vos
+ exit ;;
+ *:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo hppa1.1-stratus-vos
+ exit ;;
+ mc68*:A/UX:*:*)
+ echo m68k-apple-aux${UNAME_RELEASE}
+ exit ;;
+ news*:NEWS-OS:6*:*)
+ echo mips-sony-newsos6
+ exit ;;
+ R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+ if [ -d /usr/nec ]; then
+ echo mips-nec-sysv${UNAME_RELEASE}
+ else
+ echo mips-unknown-sysv${UNAME_RELEASE}
+ fi
+ exit ;;
+ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
+ echo powerpc-be-beos
+ exit ;;
+ BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
+ echo powerpc-apple-beos
+ exit ;;
+ BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
+ echo i586-pc-beos
+ exit ;;
+ BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
+ echo i586-pc-haiku
+ exit ;;
+ x86_64:Haiku:*:*)
+ echo x86_64-unknown-haiku
+ exit ;;
+ SX-4:SUPER-UX:*:*)
+ echo sx4-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-5:SUPER-UX:*:*)
+ echo sx5-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-6:SUPER-UX:*:*)
+ echo sx6-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-7:SUPER-UX:*:*)
+ echo sx7-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8:SUPER-UX:*:*)
+ echo sx8-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8R:SUPER-UX:*:*)
+ echo sx8r-nec-superux${UNAME_RELEASE}
+ exit ;;
+ Power*:Rhapsody:*:*)
+ echo powerpc-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Rhapsody:*:*)
+ echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Darwin:*:*)
+ UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+ eval $set_cc_for_build
+ if test "$UNAME_PROCESSOR" = unknown ; then
+ UNAME_PROCESSOR=powerpc
+ fi
+ if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ case $UNAME_PROCESSOR in
+ i386) UNAME_PROCESSOR=x86_64 ;;
+ powerpc) UNAME_PROCESSOR=powerpc64 ;;
+ esac
+ fi
+ fi
+ elif test "$UNAME_PROCESSOR" = i386 ; then
+ # Avoid executing cc on OS X 10.9, as it ships with a stub
+ # that puts up a graphical alert prompting to install
+ # developer tools. Any system running Mac OS X 10.7 or
+ # later (Darwin 11 and later) is required to have a 64-bit
+ # processor. This is not true of the ARM version of Darwin
+ # that Apple uses in portable devices.
+ UNAME_PROCESSOR=x86_64
+ fi
+ echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+ exit ;;
+ *:procnto*:*:* | *:QNX:[0123456789]*:*)
+ UNAME_PROCESSOR=`uname -p`
+ if test "$UNAME_PROCESSOR" = "x86"; then
+ UNAME_PROCESSOR=i386
+ UNAME_MACHINE=pc
+ fi
+ echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+ exit ;;
+ *:QNX:*:4*)
+ echo i386-pc-qnx
+ exit ;;
+ NEO-?:NONSTOP_KERNEL:*:*)
+ echo neo-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSE-*:NONSTOP_KERNEL:*:*)
+ echo nse-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSR-?:NONSTOP_KERNEL:*:*)
+ echo nsr-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ *:NonStop-UX:*:*)
+ echo mips-compaq-nonstopux
+ exit ;;
+ BS2000:POSIX*:*:*)
+ echo bs2000-siemens-sysv
+ exit ;;
+ DS/*:UNIX_System_V:*:*)
+ echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+ exit ;;
+ *:Plan9:*:*)
+ # "uname -m" is not consistent, so use $cputype instead. 386
+ # is converted to i386 for consistency with other x86
+ # operating systems.
+ if test "$cputype" = "386"; then
+ UNAME_MACHINE=i386
+ else
+ UNAME_MACHINE="$cputype"
+ fi
+ echo ${UNAME_MACHINE}-unknown-plan9
+ exit ;;
+ *:TOPS-10:*:*)
+ echo pdp10-unknown-tops10
+ exit ;;
+ *:TENEX:*:*)
+ echo pdp10-unknown-tenex
+ exit ;;
+ KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+ echo pdp10-dec-tops20
+ exit ;;
+ XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+ echo pdp10-xkl-tops20
+ exit ;;
+ *:TOPS-20:*:*)
+ echo pdp10-unknown-tops20
+ exit ;;
+ *:ITS:*:*)
+ echo pdp10-unknown-its
+ exit ;;
+ SEI:*:*:SEIUX)
+ echo mips-sei-seiux${UNAME_RELEASE}
+ exit ;;
+ *:DragonFly:*:*)
+ echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit ;;
+ *:*VMS:*:*)
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ case "${UNAME_MACHINE}" in
+ A*) echo alpha-dec-vms ; exit ;;
+ I*) echo ia64-dec-vms ; exit ;;
+ V*) echo vax-dec-vms ; exit ;;
+ esac ;;
+ *:XENIX:*:SysV)
+ echo i386-pc-xenix
+ exit ;;
+ i*86:skyos:*:*)
+ echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+ exit ;;
+ i*86:rdos:*:*)
+ echo ${UNAME_MACHINE}-pc-rdos
+ exit ;;
+ i*86:AROS:*:*)
+ echo ${UNAME_MACHINE}-pc-aros
+ exit ;;
+ x86_64:VMkernel:*:*)
+ echo ${UNAME_MACHINE}-unknown-esx
+ exit ;;
+esac
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+and
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo = `(hostinfo) 2>/dev/null`
+/bin/universe = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/depends/config.site.in b/depends/config.site.in
new file mode 100644
index 0000000000..873f66018d
--- /dev/null
+++ b/depends/config.site.in
@@ -0,0 +1,100 @@
+cross_compiling=maybe
+host_alias=@HOST@
+ac_tool_prefix=${host_alias}-
+
+if test -z $with_boost; then
+ with_boost=$prefix
+fi
+if test -z $with_qt_plugindir; then
+ with_qt_plugindir=$prefix/plugins
+fi
+if test -z $with_qt_translationdir; then
+ with_qt_translationdir=$prefix/translations
+fi
+if test -z $with_qt_bindir; then
+ with_qt_bindir=$prefix/native/bin
+fi
+if test -z $with_protoc_bindir; then
+ with_protoc_bindir=$prefix/native/bin
+fi
+if test -z $with_comparison_tool; then
+ with_comparison_tool=$prefix/native/share/BitcoindComparisonTool_jar/BitcoindComparisonTool.jar
+fi
+
+
+if test -z $enable_wallet && test -n "@no_wallet@"; then
+ enable_wallet=no
+fi
+
+if test -z $with_miniupnpc && test -n "@no_upnp@"; then
+ with_miniupnpc=no
+fi
+
+if test -z $with_gui && test -n "@no_qt@"; then
+ with_gui=no
+fi
+
+if test x@host_os@ = xdarwin; then
+ BREW=no
+ PORT=no
+fi
+
+if test x@host_os@ = xmingw32; then
+ if test -z $with_qt_incdir; then
+ with_qt_incdir=$prefix/include
+ fi
+ if test -z $with_qt_libdir; then
+ with_qt_libdir=$prefix/lib
+ fi
+fi
+
+PATH=$prefix/native/bin:$PATH
+PKG_CONFIG="`which pkg-config` --static"
+
+# These two need to remain exported because pkg-config does not see them
+# otherwise. That means they must be unexported at the end of configure.ac to
+# avoid ruining the cache. Sigh.
+
+export PKG_CONFIG_LIBDIR=$prefix/lib/pkgconfig
+export PKG_CONFIG_PATH=$prefix/share/pkgconfig
+
+CPPFLAGS="-I$prefix/include/ $CPPFLAGS"
+LDFLAGS="-L$prefix/lib $LDFLAGS"
+
+CC="@CC@"
+CXX="@CXX@"
+OBJC="${CC}"
+OBJCXX="${CXX}"
+CCACHE=$prefix/native/bin/ccache
+
+if test -n "@AR@"; then
+ AR=@AR@
+ ac_cv_path_ac_pt_AR=${AR}
+fi
+
+if test -n "@RANLIB@"; then
+ RANLIB=@RANLIB@
+ ac_cv_path_ac_pt_RANLIB=${RANLIB}
+fi
+
+if test -n "@NM@"; then
+ NM=@NM@
+ ac_cv_path_ac_pt_NM=${NM}
+fi
+
+if test -n "@debug@"; then
+ enable_reduce_exports=no
+fi
+
+if test -n "@CFLAGS@"; then
+ CFLAGS="@CFLAGS@ $CFLAGS"
+fi
+if test -n "@CXXFLAGS@"; then
+ CXXFLAGS="@CXXFLAGS@ $CXXFLAGS"
+fi
+if test -n "@CPPFLAGS@"; then
+ CPPFLAGS="@CPPFLAGS@ $CPPFLAGS"
+fi
+if test -n "@LDFLAGS@"; then
+ LDFLAGS="@LDFLAGS@ $LDFLAGS"
+fi
diff --git a/depends/config.sub b/depends/config.sub
new file mode 100755
index 0000000000..8f1229c6f7
--- /dev/null
+++ b/depends/config.sub
@@ -0,0 +1,1810 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+# Copyright 1992-2015 Free Software Foundation, Inc.
+
+timestamp='2015-03-08'
+
+# This file 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 <http://www.gnu.org/licenses/>.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that
+# program. This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
+
+
+# Please send patches to <config-patches@gnu.org>.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support. The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+ $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright 1992-2015 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help"
+ exit 1 ;;
+
+ *local*)
+ # First pass through any local machine types.
+ echo $1
+ exit ;;
+
+ * )
+ break ;;
+ esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+ exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+ exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+ nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
+ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+ knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
+ kopensolaris*-gnu* | \
+ storm-chaos* | os2-emx* | rtmk-nova*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+ android-linux)
+ os=-linux-android
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
+ ;;
+ *)
+ basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+ if [ $basic_machine != $1 ]
+ then os=`echo $1 | sed 's/.*-/-/'`
+ else os=; fi
+ ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work. We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+ -sun*os*)
+ # Prevent following clause from handling this invalid input.
+ ;;
+ -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+ -apple | -axis | -knuth | -cray | -microblaze*)
+ os=
+ basic_machine=$1
+ ;;
+ -bluegene*)
+ os=-cnk
+ ;;
+ -sim | -cisco | -oki | -wec | -winbond)
+ os=
+ basic_machine=$1
+ ;;
+ -scout)
+ ;;
+ -wrs)
+ os=-vxworks
+ basic_machine=$1
+ ;;
+ -chorusos*)
+ os=-chorusos
+ basic_machine=$1
+ ;;
+ -chorusrdb)
+ os=-chorusrdb
+ basic_machine=$1
+ ;;
+ -hiux*)
+ os=-hiuxwe2
+ ;;
+ -sco6)
+ os=-sco5v6
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5)
+ os=-sco3.2v5
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco4)
+ os=-sco3.2v4
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2.[4-9]*)
+ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2v[4-9]*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5v6*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco*)
+ os=-sco3.2v2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -udk*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -isc)
+ os=-isc2.2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -clix*)
+ basic_machine=clipper-intergraph
+ ;;
+ -isc*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -lynx*178)
+ os=-lynxos178
+ ;;
+ -lynx*5)
+ os=-lynxos5
+ ;;
+ -lynx*)
+ os=-lynxos
+ ;;
+ -ptx*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+ ;;
+ -windowsnt*)
+ os=`echo $os | sed -e 's/windowsnt/winnt/'`
+ ;;
+ -psos*)
+ os=-psos
+ ;;
+ -mint | -mint[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+ # Recognize the basic CPU types without company name.
+ # Some are omitted here because they have special meanings below.
+ 1750a | 580 \
+ | a29k \
+ | aarch64 | aarch64_be \
+ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+ | am33_2.0 \
+ | arc | arceb \
+ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
+ | avr | avr32 \
+ | be32 | be64 \
+ | bfin \
+ | c4x | c8051 | clipper \
+ | d10v | d30v | dlx | dsp16xx \
+ | e2k | epiphany \
+ | fido | fr30 | frv | ft32 \
+ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+ | hexagon \
+ | i370 | i860 | i960 | ia64 \
+ | ip2k | iq2000 \
+ | k1om \
+ | le32 | le64 \
+ | lm32 \
+ | m32c | m32r | m32rle | m68000 | m68k | m88k \
+ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \
+ | mips | mipsbe | mipseb | mipsel | mipsle \
+ | mips16 \
+ | mips64 | mips64el \
+ | mips64octeon | mips64octeonel \
+ | mips64orion | mips64orionel \
+ | mips64r5900 | mips64r5900el \
+ | mips64vr | mips64vrel \
+ | mips64vr4100 | mips64vr4100el \
+ | mips64vr4300 | mips64vr4300el \
+ | mips64vr5000 | mips64vr5000el \
+ | mips64vr5900 | mips64vr5900el \
+ | mipsisa32 | mipsisa32el \
+ | mipsisa32r2 | mipsisa32r2el \
+ | mipsisa32r6 | mipsisa32r6el \
+ | mipsisa64 | mipsisa64el \
+ | mipsisa64r2 | mipsisa64r2el \
+ | mipsisa64r6 | mipsisa64r6el \
+ | mipsisa64sb1 | mipsisa64sb1el \
+ | mipsisa64sr71k | mipsisa64sr71kel \
+ | mipsr5900 | mipsr5900el \
+ | mipstx39 | mipstx39el \
+ | mn10200 | mn10300 \
+ | moxie \
+ | mt \
+ | msp430 \
+ | nds32 | nds32le | nds32be \
+ | nios | nios2 | nios2eb | nios2el \
+ | ns16k | ns32k \
+ | open8 | or1k | or1knd | or32 \
+ | pdp10 | pdp11 | pj | pjl \
+ | powerpc | powerpc64 | powerpc64le | powerpcle \
+ | pyramid \
+ | riscv32 | riscv64 \
+ | rl78 | rx \
+ | score \
+ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+ | sh64 | sh64le \
+ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+ | spu \
+ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
+ | ubicom32 \
+ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
+ | visium \
+ | we32k \
+ | x86 | xc16x | xstormy16 | xtensa \
+ | z8k | z80)
+ basic_machine=$basic_machine-unknown
+ ;;
+ c54x)
+ basic_machine=tic54x-unknown
+ ;;
+ c55x)
+ basic_machine=tic55x-unknown
+ ;;
+ c6x)
+ basic_machine=tic6x-unknown
+ ;;
+ leon|leon[3-9])
+ basic_machine=sparc-$basic_machine
+ ;;
+ m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+ ;;
+ ms1)
+ basic_machine=mt-unknown
+ ;;
+
+ strongarm | thumb | xscale)
+ basic_machine=arm-unknown
+ ;;
+ xgate)
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ xscaleeb)
+ basic_machine=armeb-unknown
+ ;;
+
+ xscaleel)
+ basic_machine=armel-unknown
+ ;;
+
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i*86 | x86_64)
+ basic_machine=$basic_machine-pc
+ ;;
+ # Object if more than one company name word.
+ *-*-*)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+ # Recognize the basic CPU types with company name.
+ 580-* \
+ | a29k-* \
+ | aarch64-* | aarch64_be-* \
+ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
+ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
+ | avr-* | avr32-* \
+ | be32-* | be64-* \
+ | bfin-* | bs2000-* \
+ | c[123]* | c30-* | [cjt]90-* | c4x-* \
+ | c8051-* | clipper-* | craynv-* | cydra-* \
+ | d10v-* | d30v-* | dlx-* \
+ | e2k-* | elxsi-* \
+ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+ | h8300-* | h8500-* \
+ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+ | hexagon-* \
+ | i*86-* | i860-* | i960-* | ia64-* \
+ | ip2k-* | iq2000-* \
+ | k1om-* \
+ | le32-* | le64-* \
+ | lm32-* \
+ | m32c-* | m32r-* | m32rle-* \
+ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
+ | microblaze-* | microblazeel-* \
+ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+ | mips16-* \
+ | mips64-* | mips64el-* \
+ | mips64octeon-* | mips64octeonel-* \
+ | mips64orion-* | mips64orionel-* \
+ | mips64r5900-* | mips64r5900el-* \
+ | mips64vr-* | mips64vrel-* \
+ | mips64vr4100-* | mips64vr4100el-* \
+ | mips64vr4300-* | mips64vr4300el-* \
+ | mips64vr5000-* | mips64vr5000el-* \
+ | mips64vr5900-* | mips64vr5900el-* \
+ | mipsisa32-* | mipsisa32el-* \
+ | mipsisa32r2-* | mipsisa32r2el-* \
+ | mipsisa32r6-* | mipsisa32r6el-* \
+ | mipsisa64-* | mipsisa64el-* \
+ | mipsisa64r2-* | mipsisa64r2el-* \
+ | mipsisa64r6-* | mipsisa64r6el-* \
+ | mipsisa64sb1-* | mipsisa64sb1el-* \
+ | mipsisa64sr71k-* | mipsisa64sr71kel-* \
+ | mipsr5900-* | mipsr5900el-* \
+ | mipstx39-* | mipstx39el-* \
+ | mmix-* \
+ | mt-* \
+ | msp430-* \
+ | nds32-* | nds32le-* | nds32be-* \
+ | nios-* | nios2-* | nios2eb-* | nios2el-* \
+ | none-* | np1-* | ns16k-* | ns32k-* \
+ | open8-* \
+ | or1k*-* \
+ | orion-* \
+ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+ | pyramid-* \
+ | rl78-* | romp-* | rs6000-* | rx-* \
+ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+ | sparclite-* \
+ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
+ | tahoe-* \
+ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+ | tile*-* \
+ | tron-* \
+ | ubicom32-* \
+ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
+ | vax-* \
+ | visium-* \
+ | we32k-* \
+ | x86-* | x86_64-* | xc16x-* | xps100-* \
+ | xstormy16-* | xtensa*-* \
+ | ymp-* \
+ | z8k-* | z80-*)
+ ;;
+ # Recognize the basic CPU types without company name, with glob match.
+ xtensa*)
+ basic_machine=$basic_machine-unknown
+ ;;
+ # Recognize the various machine names and aliases which stand
+ # for a CPU type and a company and sometimes even an OS.
+ 386bsd)
+ basic_machine=i386-unknown
+ os=-bsd
+ ;;
+ 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+ basic_machine=m68000-att
+ ;;
+ 3b*)
+ basic_machine=we32k-att
+ ;;
+ a29khif)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ abacus)
+ basic_machine=abacus-unknown
+ ;;
+ adobe68k)
+ basic_machine=m68010-adobe
+ os=-scout
+ ;;
+ alliant | fx80)
+ basic_machine=fx80-alliant
+ ;;
+ altos | altos3068)
+ basic_machine=m68k-altos
+ ;;
+ am29k)
+ basic_machine=a29k-none
+ os=-bsd
+ ;;
+ amd64)
+ basic_machine=x86_64-pc
+ ;;
+ amd64-*)
+ basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ amdahl)
+ basic_machine=580-amdahl
+ os=-sysv
+ ;;
+ amiga | amiga-*)
+ basic_machine=m68k-unknown
+ ;;
+ amigaos | amigados)
+ basic_machine=m68k-unknown
+ os=-amigaos
+ ;;
+ amigaunix | amix)
+ basic_machine=m68k-unknown
+ os=-sysv4
+ ;;
+ apollo68)
+ basic_machine=m68k-apollo
+ os=-sysv
+ ;;
+ apollo68bsd)
+ basic_machine=m68k-apollo
+ os=-bsd
+ ;;
+ aros)
+ basic_machine=i386-pc
+ os=-aros
+ ;;
+ asmjs)
+ basic_machine=asmjs-unknown
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=-dynix
+ ;;
+ blackfin)
+ basic_machine=bfin-unknown
+ os=-linux
+ ;;
+ blackfin-*)
+ basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ bluegene*)
+ basic_machine=powerpc-ibm
+ os=-cnk
+ ;;
+ c54x-*)
+ basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c55x-*)
+ basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c6x-*)
+ basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c90)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
+ cegcc)
+ basic_machine=arm-unknown
+ os=-cegcc
+ ;;
+ convex-c1)
+ basic_machine=c1-convex
+ os=-bsd
+ ;;
+ convex-c2)
+ basic_machine=c2-convex
+ os=-bsd
+ ;;
+ convex-c32)
+ basic_machine=c32-convex
+ os=-bsd
+ ;;
+ convex-c34)
+ basic_machine=c34-convex
+ os=-bsd
+ ;;
+ convex-c38)
+ basic_machine=c38-convex
+ os=-bsd
+ ;;
+ cray | j90)
+ basic_machine=j90-cray
+ os=-unicos
+ ;;
+ craynv)
+ basic_machine=craynv-cray
+ os=-unicosmp
+ ;;
+ cr16 | cr16-*)
+ basic_machine=cr16-unknown
+ os=-elf
+ ;;
+ crds | unos)
+ basic_machine=m68k-crds
+ ;;
+ crisv32 | crisv32-* | etraxfs*)
+ basic_machine=crisv32-axis
+ ;;
+ cris | cris-* | etrax*)
+ basic_machine=cris-axis
+ ;;
+ crx)
+ basic_machine=crx-unknown
+ os=-elf
+ ;;
+ da30 | da30-*)
+ basic_machine=m68k-da30
+ ;;
+ decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+ basic_machine=mips-dec
+ ;;
+ decsystem10* | dec10*)
+ basic_machine=pdp10-dec
+ os=-tops10
+ ;;
+ decsystem20* | dec20*)
+ basic_machine=pdp10-dec
+ os=-tops20
+ ;;
+ delta | 3300 | motorola-3300 | motorola-delta \
+ | 3300-motorola | delta-motorola)
+ basic_machine=m68k-motorola
+ ;;
+ delta88)
+ basic_machine=m88k-motorola
+ os=-sysv3
+ ;;
+ dicos)
+ basic_machine=i686-pc
+ os=-dicos
+ ;;
+ djgpp)
+ basic_machine=i586-pc
+ os=-msdosdjgpp
+ ;;
+ dpx20 | dpx20-*)
+ basic_machine=rs6000-bull
+ os=-bosx
+ ;;
+ dpx2* | dpx2*-bull)
+ basic_machine=m68k-bull
+ os=-sysv3
+ ;;
+ ebmon29k)
+ basic_machine=a29k-amd
+ os=-ebmon
+ ;;
+ elxsi)
+ basic_machine=elxsi-elxsi
+ os=-bsd
+ ;;
+ encore | umax | mmax)
+ basic_machine=ns32k-encore
+ ;;
+ es1800 | OSE68k | ose68k | ose | OSE)
+ basic_machine=m68k-ericsson
+ os=-ose
+ ;;
+ fx2800)
+ basic_machine=i860-alliant
+ ;;
+ genix)
+ basic_machine=ns32k-ns
+ ;;
+ gmicro)
+ basic_machine=tron-gmicro
+ os=-sysv
+ ;;
+ go32)
+ basic_machine=i386-pc
+ os=-go32
+ ;;
+ h3050r* | hiux*)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ h8300hms)
+ basic_machine=h8300-hitachi
+ os=-hms
+ ;;
+ h8300xray)
+ basic_machine=h8300-hitachi
+ os=-xray
+ ;;
+ h8500hms)
+ basic_machine=h8500-hitachi
+ os=-hms
+ ;;
+ harris)
+ basic_machine=m88k-harris
+ os=-sysv3
+ ;;
+ hp300-*)
+ basic_machine=m68k-hp
+ ;;
+ hp300bsd)
+ basic_machine=m68k-hp
+ os=-bsd
+ ;;
+ hp300hpux)
+ basic_machine=m68k-hp
+ os=-hpux
+ ;;
+ hp3k9[0-9][0-9] | hp9[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k2[0-9][0-9] | hp9k31[0-9])
+ basic_machine=m68000-hp
+ ;;
+ hp9k3[2-9][0-9])
+ basic_machine=m68k-hp
+ ;;
+ hp9k6[0-9][0-9] | hp6[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k7[0-79][0-9] | hp7[0-79][0-9])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k78[0-9] | hp78[0-9])
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][13679] | hp8[0-9][13679])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][0-9] | hp8[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hppa-next)
+ os=-nextstep3
+ ;;
+ hppaosf)
+ basic_machine=hppa1.1-hp
+ os=-osf
+ ;;
+ hppro)
+ basic_machine=hppa1.1-hp
+ os=-proelf
+ ;;
+ i370-ibm* | ibm*)
+ basic_machine=i370-ibm
+ ;;
+ i*86v32)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv32
+ ;;
+ i*86v4*)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv4
+ ;;
+ i*86v)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv
+ ;;
+ i*86sol2)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-solaris2
+ ;;
+ i386mach)
+ basic_machine=i386-mach
+ os=-mach
+ ;;
+ i386-vsta | vsta)
+ basic_machine=i386-unknown
+ os=-vsta
+ ;;
+ iris | iris4d)
+ basic_machine=mips-sgi
+ case $os in
+ -irix*)
+ ;;
+ *)
+ os=-irix4
+ ;;
+ esac
+ ;;
+ isi68 | isi)
+ basic_machine=m68k-isi
+ os=-sysv
+ ;;
+ leon-*|leon[3-9]-*)
+ basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'`
+ ;;
+ m68knommu)
+ basic_machine=m68k-unknown
+ os=-linux
+ ;;
+ m68knommu-*)
+ basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ m88k-omron*)
+ basic_machine=m88k-omron
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ os=-sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ os=-sysv
+ ;;
+ microblaze*)
+ basic_machine=microblaze-xilinx
+ ;;
+ mingw64)
+ basic_machine=x86_64-pc
+ os=-mingw64
+ ;;
+ mingw32)
+ basic_machine=i686-pc
+ os=-mingw32
+ ;;
+ mingw32ce)
+ basic_machine=arm-unknown
+ os=-mingw32ce
+ ;;
+ miniframe)
+ basic_machine=m68000-convergent
+ ;;
+ *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+ mips3*-*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+ ;;
+ mips3*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+ ;;
+ monitor)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ morphos)
+ basic_machine=powerpc-unknown
+ os=-morphos
+ ;;
+ moxiebox)
+ basic_machine=moxie-unknown
+ os=-moxiebox
+ ;;
+ msdos)
+ basic_machine=i386-pc
+ os=-msdos
+ ;;
+ ms1-*)
+ basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+ ;;
+ msys)
+ basic_machine=i686-pc
+ os=-msys
+ ;;
+ mvs)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
+ nacl)
+ basic_machine=le32-unknown
+ os=-nacl
+ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=-sysv4
+ ;;
+ netbsd386)
+ basic_machine=i386-unknown
+ os=-netbsd
+ ;;
+ netwinder)
+ basic_machine=armv4l-rebel
+ os=-linux
+ ;;
+ news | news700 | news800 | news900)
+ basic_machine=m68k-sony
+ os=-newsos
+ ;;
+ news1000)
+ basic_machine=m68030-sony
+ os=-newsos
+ ;;
+ news-3600 | risc-news)
+ basic_machine=mips-sony
+ os=-newsos
+ ;;
+ necv70)
+ basic_machine=v70-nec
+ os=-sysv
+ ;;
+ next | m*-next )
+ basic_machine=m68k-next
+ case $os in
+ -nextstep* )
+ ;;
+ -ns2*)
+ os=-nextstep2
+ ;;
+ *)
+ os=-nextstep3
+ ;;
+ esac
+ ;;
+ nh3000)
+ basic_machine=m68k-harris
+ os=-cxux
+ ;;
+ nh[45]000)
+ basic_machine=m88k-harris
+ os=-cxux
+ ;;
+ nindy960)
+ basic_machine=i960-intel
+ os=-nindy
+ ;;
+ mon960)
+ basic_machine=i960-intel
+ os=-mon960
+ ;;
+ nonstopux)
+ basic_machine=mips-compaq
+ os=-nonstopux
+ ;;
+ np1)
+ basic_machine=np1-gould
+ ;;
+ neo-tandem)
+ basic_machine=neo-tandem
+ ;;
+ nse-tandem)
+ basic_machine=nse-tandem
+ ;;
+ nsr-tandem)
+ basic_machine=nsr-tandem
+ ;;
+ op50n-* | op60c-*)
+ basic_machine=hppa1.1-oki
+ os=-proelf
+ ;;
+ openrisc | openrisc-*)
+ basic_machine=or32-unknown
+ ;;
+ os400)
+ basic_machine=powerpc-ibm
+ os=-os400
+ ;;
+ OSE68000 | ose68000)
+ basic_machine=m68000-ericsson
+ os=-ose
+ ;;
+ os68k)
+ basic_machine=m68k-none
+ os=-os68k
+ ;;
+ pa-hitachi)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ paragon)
+ basic_machine=i860-intel
+ os=-osf
+ ;;
+ parisc)
+ basic_machine=hppa-unknown
+ os=-linux
+ ;;
+ parisc-*)
+ basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ pbd)
+ basic_machine=sparc-tti
+ ;;
+ pbb)
+ basic_machine=m68k-tti
+ ;;
+ pc532 | pc532-*)
+ basic_machine=ns32k-pc532
+ ;;
+ pc98)
+ basic_machine=i386-pc
+ ;;
+ pc98-*)
+ basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium | p5 | k5 | k6 | nexgen | viac3)
+ basic_machine=i586-pc
+ ;;
+ pentiumpro | p6 | 6x86 | athlon | athlon_*)
+ basic_machine=i686-pc
+ ;;
+ pentiumii | pentium2 | pentiumiii | pentium3)
+ basic_machine=i686-pc
+ ;;
+ pentium4)
+ basic_machine=i786-pc
+ ;;
+ pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+ basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumpro-* | p6-* | 6x86-* | athlon-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium4-*)
+ basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pn)
+ basic_machine=pn-gould
+ ;;
+ power) basic_machine=power-ibm
+ ;;
+ ppc | ppcbe) basic_machine=powerpc-unknown
+ ;;
+ ppc-* | ppcbe-*)
+ basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppcle | powerpclittle | ppc-le | powerpc-little)
+ basic_machine=powerpcle-unknown
+ ;;
+ ppcle-* | powerpclittle-*)
+ basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64) basic_machine=powerpc64-unknown
+ ;;
+ ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+ basic_machine=powerpc64le-unknown
+ ;;
+ ppc64le-* | powerpc64little-*)
+ basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ps2)
+ basic_machine=i386-ibm
+ ;;
+ pw32)
+ basic_machine=i586-unknown
+ os=-pw32
+ ;;
+ rdos | rdos64)
+ basic_machine=x86_64-pc
+ os=-rdos
+ ;;
+ rdos32)
+ basic_machine=i386-pc
+ os=-rdos
+ ;;
+ rom68k)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ rm[46]00)
+ basic_machine=mips-siemens
+ ;;
+ rtpc | rtpc-*)
+ basic_machine=romp-ibm
+ ;;
+ s390 | s390-*)
+ basic_machine=s390-ibm
+ ;;
+ s390x | s390x-*)
+ basic_machine=s390x-ibm
+ ;;
+ sa29200)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ sb1)
+ basic_machine=mipsisa64sb1-unknown
+ ;;
+ sb1el)
+ basic_machine=mipsisa64sb1el-unknown
+ ;;
+ sde)
+ basic_machine=mipsisa32-sde
+ os=-elf
+ ;;
+ sei)
+ basic_machine=mips-sei
+ os=-seiux
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ ;;
+ sh)
+ basic_machine=sh-hitachi
+ os=-hms
+ ;;
+ sh5el)
+ basic_machine=sh5le-unknown
+ ;;
+ sh64)
+ basic_machine=sh64-unknown
+ ;;
+ sparclite-wrs | simso-wrs)
+ basic_machine=sparclite-wrs
+ os=-vxworks
+ ;;
+ sps7)
+ basic_machine=m68k-bull
+ os=-sysv2
+ ;;
+ spur)
+ basic_machine=spur-unknown
+ ;;
+ st2000)
+ basic_machine=m68k-tandem
+ ;;
+ stratus)
+ basic_machine=i860-stratus
+ os=-sysv4
+ ;;
+ strongarm-* | thumb-*)
+ basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ sun2)
+ basic_machine=m68000-sun
+ ;;
+ sun2os3)
+ basic_machine=m68000-sun
+ os=-sunos3
+ ;;
+ sun2os4)
+ basic_machine=m68000-sun
+ os=-sunos4
+ ;;
+ sun3os3)
+ basic_machine=m68k-sun
+ os=-sunos3
+ ;;
+ sun3os4)
+ basic_machine=m68k-sun
+ os=-sunos4
+ ;;
+ sun4os3)
+ basic_machine=sparc-sun
+ os=-sunos3
+ ;;
+ sun4os4)
+ basic_machine=sparc-sun
+ os=-sunos4
+ ;;
+ sun4sol2)
+ basic_machine=sparc-sun
+ os=-solaris2
+ ;;
+ sun3 | sun3-*)
+ basic_machine=m68k-sun
+ ;;
+ sun4)
+ basic_machine=sparc-sun
+ ;;
+ sun386 | sun386i | roadrunner)
+ basic_machine=i386-sun
+ ;;
+ sv1)
+ basic_machine=sv1-cray
+ os=-unicos
+ ;;
+ symmetry)
+ basic_machine=i386-sequent
+ os=-dynix
+ ;;
+ t3e)
+ basic_machine=alphaev5-cray
+ os=-unicos
+ ;;
+ t90)
+ basic_machine=t90-cray
+ os=-unicos
+ ;;
+ tile*)
+ basic_machine=$basic_machine-unknown
+ os=-linux-gnu
+ ;;
+ tx39)
+ basic_machine=mipstx39-unknown
+ ;;
+ tx39el)
+ basic_machine=mipstx39el-unknown
+ ;;
+ toad1)
+ basic_machine=pdp10-xkl
+ os=-tops20
+ ;;
+ tower | tower-32)
+ basic_machine=m68k-ncr
+ ;;
+ tpf)
+ basic_machine=s390x-ibm
+ os=-tpf
+ ;;
+ udi29k)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ ultra3)
+ basic_machine=a29k-nyu
+ os=-sym1
+ ;;
+ v810 | necv810)
+ basic_machine=v810-nec
+ os=-none
+ ;;
+ vaxv)
+ basic_machine=vax-dec
+ os=-sysv
+ ;;
+ vms)
+ basic_machine=vax-dec
+ os=-vms
+ ;;
+ vpp*|vx|vx-*)
+ basic_machine=f301-fujitsu
+ ;;
+ vxworks960)
+ basic_machine=i960-wrs
+ os=-vxworks
+ ;;
+ vxworks68)
+ basic_machine=m68k-wrs
+ os=-vxworks
+ ;;
+ vxworks29k)
+ basic_machine=a29k-wrs
+ os=-vxworks
+ ;;
+ w65*)
+ basic_machine=w65-wdc
+ os=-none
+ ;;
+ w89k-*)
+ basic_machine=hppa1.1-winbond
+ os=-proelf
+ ;;
+ xbox)
+ basic_machine=i686-pc
+ os=-mingw32
+ ;;
+ xps | xps100)
+ basic_machine=xps100-honeywell
+ ;;
+ xscale-* | xscalee[bl]-*)
+ basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
+ ;;
+ ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+ ;;
+ z8k-*-coff)
+ basic_machine=z8k-unknown
+ os=-sim
+ ;;
+ z80-*-coff)
+ basic_machine=z80-unknown
+ os=-sim
+ ;;
+ none)
+ basic_machine=none-none
+ os=-none
+ ;;
+
+# Here we handle the default manufacturer of certain CPU types. It is in
+# some cases the only manufacturer, in others, it is the most popular.
+ w89k)
+ basic_machine=hppa1.1-winbond
+ ;;
+ op50n)
+ basic_machine=hppa1.1-oki
+ ;;
+ op60c)
+ basic_machine=hppa1.1-oki
+ ;;
+ romp)
+ basic_machine=romp-ibm
+ ;;
+ mmix)
+ basic_machine=mmix-knuth
+ ;;
+ rs6000)
+ basic_machine=rs6000-ibm
+ ;;
+ vax)
+ basic_machine=vax-dec
+ ;;
+ pdp10)
+ # there are many clones, so DEC is not a safe bet
+ basic_machine=pdp10-unknown
+ ;;
+ pdp11)
+ basic_machine=pdp11-dec
+ ;;
+ we32k)
+ basic_machine=we32k-att
+ ;;
+ sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
+ basic_machine=sh-unknown
+ ;;
+ sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+ basic_machine=sparc-sun
+ ;;
+ cydra)
+ basic_machine=cydra-cydrome
+ ;;
+ orion)
+ basic_machine=orion-highlevel
+ ;;
+ orion105)
+ basic_machine=clipper-highlevel
+ ;;
+ mac | mpw | mac-mpw)
+ basic_machine=m68k-apple
+ ;;
+ pmac | pmac-mpw)
+ basic_machine=powerpc-apple
+ ;;
+ *-unknown)
+ # Make sure to match an already-canonicalized machine name.
+ ;;
+ *)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+ *-digital*)
+ basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+ ;;
+ *-commodore*)
+ basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+ ;;
+ *)
+ ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+ # First match some system type aliases
+ # that might get confused with valid system types.
+ # -solaris* is a basic system type, with this one exception.
+ -auroraux)
+ os=-auroraux
+ ;;
+ -solaris1 | -solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ ;;
+ -solaris)
+ os=-solaris2
+ ;;
+ -svr4*)
+ os=-sysv4
+ ;;
+ -unixware*)
+ os=-sysv4.2uw
+ ;;
+ -gnu/linux*)
+ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+ ;;
+ # First accept the basic system types.
+ # The portable systems comes first.
+ # Each alternative MUST END IN A *, to match a version number.
+ # -sysv* is not here because it comes later, after sysvr4.
+ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+ | -sym* | -kopensolaris* | -plan9* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* | -aros* | -cloudabi* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+ | -bitrig* | -openbsd* | -solidbsd* \
+ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ | -chorusos* | -chorusrdb* | -cegcc* \
+ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
+ | -linux-newlib* | -linux-musl* | -linux-uclibc* \
+ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
+ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*)
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ -qnx*)
+ case $basic_machine in
+ x86-* | i*86-*)
+ ;;
+ *)
+ os=-nto$os
+ ;;
+ esac
+ ;;
+ -nto-qnx*)
+ ;;
+ -nto*)
+ os=`echo $os | sed -e 's|nto|nto-qnx|'`
+ ;;
+ -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+ ;;
+ -mac*)
+ os=`echo $os | sed -e 's|mac|macos|'`
+ ;;
+ -linux-dietlibc)
+ os=-linux-dietlibc
+ ;;
+ -linux*)
+ os=`echo $os | sed -e 's|linux|linux-gnu|'`
+ ;;
+ -sunos5*)
+ os=`echo $os | sed -e 's|sunos5|solaris2|'`
+ ;;
+ -sunos6*)
+ os=`echo $os | sed -e 's|sunos6|solaris3|'`
+ ;;
+ -opened*)
+ os=-openedition
+ ;;
+ -os400*)
+ os=-os400
+ ;;
+ -wince*)
+ os=-wince
+ ;;
+ -osfrose*)
+ os=-osfrose
+ ;;
+ -osf*)
+ os=-osf
+ ;;
+ -utek*)
+ os=-bsd
+ ;;
+ -dynix*)
+ os=-bsd
+ ;;
+ -acis*)
+ os=-aos
+ ;;
+ -atheos*)
+ os=-atheos
+ ;;
+ -syllable*)
+ os=-syllable
+ ;;
+ -386bsd)
+ os=-bsd
+ ;;
+ -ctix* | -uts*)
+ os=-sysv
+ ;;
+ -nova*)
+ os=-rtmk-nova
+ ;;
+ -ns2 )
+ os=-nextstep2
+ ;;
+ -nsk*)
+ os=-nsk
+ ;;
+ # Preserve the version number of sinix5.
+ -sinix5.*)
+ os=`echo $os | sed -e 's|sinix|sysv|'`
+ ;;
+ -sinix*)
+ os=-sysv4
+ ;;
+ -tpf*)
+ os=-tpf
+ ;;
+ -triton*)
+ os=-sysv3
+ ;;
+ -oss*)
+ os=-sysv3
+ ;;
+ -svr4)
+ os=-sysv4
+ ;;
+ -svr3)
+ os=-sysv3
+ ;;
+ -sysvr4)
+ os=-sysv4
+ ;;
+ # This must come after -sysvr4.
+ -sysv*)
+ ;;
+ -ose*)
+ os=-ose
+ ;;
+ -es1800*)
+ os=-ose
+ ;;
+ -xenix)
+ os=-xenix
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ os=-mint
+ ;;
+ -aros*)
+ os=-aros
+ ;;
+ -zvmoe)
+ os=-zvmoe
+ ;;
+ -dicos*)
+ os=-dicos
+ ;;
+ -nacl*)
+ ;;
+ -none)
+ ;;
+ *)
+ # Get rid of the `-' at the beginning of $os.
+ os=`echo $os | sed 's/[^-]*-//'`
+ echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system. Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+ score-*)
+ os=-elf
+ ;;
+ spu-*)
+ os=-elf
+ ;;
+ *-acorn)
+ os=-riscix1.2
+ ;;
+ arm*-rebel)
+ os=-linux
+ ;;
+ arm*-semi)
+ os=-aout
+ ;;
+ c4x-* | tic4x-*)
+ os=-coff
+ ;;
+ c8051-*)
+ os=-elf
+ ;;
+ hexagon-*)
+ os=-elf
+ ;;
+ tic54x-*)
+ os=-coff
+ ;;
+ tic55x-*)
+ os=-coff
+ ;;
+ tic6x-*)
+ os=-coff
+ ;;
+ # This must come before the *-dec entry.
+ pdp10-*)
+ os=-tops20
+ ;;
+ pdp11-*)
+ os=-none
+ ;;
+ *-dec | vax-*)
+ os=-ultrix4.2
+ ;;
+ m68*-apollo)
+ os=-domain
+ ;;
+ i386-sun)
+ os=-sunos4.0.2
+ ;;
+ m68000-sun)
+ os=-sunos3
+ ;;
+ m68*-cisco)
+ os=-aout
+ ;;
+ mep-*)
+ os=-elf
+ ;;
+ mips*-cisco)
+ os=-elf
+ ;;
+ mips*-*)
+ os=-elf
+ ;;
+ or32-*)
+ os=-coff
+ ;;
+ *-tti) # must be before sparc entry or we get the wrong os.
+ os=-sysv3
+ ;;
+ sparc-* | *-sun)
+ os=-sunos4.1.1
+ ;;
+ *-be)
+ os=-beos
+ ;;
+ *-haiku)
+ os=-haiku
+ ;;
+ *-ibm)
+ os=-aix
+ ;;
+ *-knuth)
+ os=-mmixware
+ ;;
+ *-wec)
+ os=-proelf
+ ;;
+ *-winbond)
+ os=-proelf
+ ;;
+ *-oki)
+ os=-proelf
+ ;;
+ *-hp)
+ os=-hpux
+ ;;
+ *-hitachi)
+ os=-hiux
+ ;;
+ i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+ os=-sysv
+ ;;
+ *-cbm)
+ os=-amigaos
+ ;;
+ *-dg)
+ os=-dgux
+ ;;
+ *-dolphin)
+ os=-sysv3
+ ;;
+ m68k-ccur)
+ os=-rtu
+ ;;
+ m88k-omron*)
+ os=-luna
+ ;;
+ *-next )
+ os=-nextstep
+ ;;
+ *-sequent)
+ os=-ptx
+ ;;
+ *-crds)
+ os=-unos
+ ;;
+ *-ns)
+ os=-genix
+ ;;
+ i370-*)
+ os=-mvs
+ ;;
+ *-next)
+ os=-nextstep3
+ ;;
+ *-gould)
+ os=-sysv
+ ;;
+ *-highlevel)
+ os=-bsd
+ ;;
+ *-encore)
+ os=-bsd
+ ;;
+ *-sgi)
+ os=-irix
+ ;;
+ *-siemens)
+ os=-sysv4
+ ;;
+ *-masscomp)
+ os=-rtu
+ ;;
+ f30[01]-fujitsu | f700-fujitsu)
+ os=-uxpv
+ ;;
+ *-rom68k)
+ os=-coff
+ ;;
+ *-*bug)
+ os=-coff
+ ;;
+ *-apple)
+ os=-macos
+ ;;
+ *-atari*)
+ os=-mint
+ ;;
+ *)
+ os=-none
+ ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer. We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+ *-unknown)
+ case $os in
+ -riscix*)
+ vendor=acorn
+ ;;
+ -sunos*)
+ vendor=sun
+ ;;
+ -cnk*|-aix*)
+ vendor=ibm
+ ;;
+ -beos*)
+ vendor=be
+ ;;
+ -hpux*)
+ vendor=hp
+ ;;
+ -mpeix*)
+ vendor=hp
+ ;;
+ -hiux*)
+ vendor=hitachi
+ ;;
+ -unos*)
+ vendor=crds
+ ;;
+ -dgux*)
+ vendor=dg
+ ;;
+ -luna*)
+ vendor=omron
+ ;;
+ -genix*)
+ vendor=ns
+ ;;
+ -mvs* | -opened*)
+ vendor=ibm
+ ;;
+ -os400*)
+ vendor=ibm
+ ;;
+ -ptx*)
+ vendor=sequent
+ ;;
+ -tpf*)
+ vendor=ibm
+ ;;
+ -vxsim* | -vxworks* | -windiss*)
+ vendor=wrs
+ ;;
+ -aux*)
+ vendor=apple
+ ;;
+ -hms*)
+ vendor=hitachi
+ ;;
+ -mpw* | -macos*)
+ vendor=apple
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ vendor=atari
+ ;;
+ -vos*)
+ vendor=stratus
+ ;;
+ esac
+ basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+ ;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/depends/description.md b/depends/description.md
new file mode 100644
index 0000000000..74f9ef3f20
--- /dev/null
+++ b/depends/description.md
@@ -0,0 +1,53 @@
+This is a system of building and caching dependencies necessary for building Bitcoin.
+There are several features that make it different from most similar systems:
+
+### It is designed to be builder and host agnostic
+
+In theory, binaries for any target OS/architecture can be created, from a
+builder running any OS/architecture. In practice, build-side tools must be
+specified when the defaults don't fit, and packages must be amended to work
+on new hosts. For now, a build architecture of x86_64 is assumed, either on
+Linux or OSX.
+
+### No reliance on timestamps
+
+File presence is used to determine what needs to be built. This makes the
+results distributable and easily digestable by automated builders.
+
+### Each build only has its specified dependencies available at build-time.
+
+For each build, the sysroot is wiped and the (recursive) dependencies are
+installed. This makes each build deterministic, since there will never be any
+unknown files available to cause side-effects.
+
+### Each package is cached and only rebuilt as needed.
+
+Before building, a unique build-id is generated for each package. This id
+consists of a hash of all files used to build the package (Makefiles, packages,
+etc), and as well as a hash of the same data for each recursive dependency. If
+any portion of a package's build recipe changes, it will be rebuilt as well as
+any other package that depends on it. If any of the main makefiles (Makefile,
+funcs.mk, etc) are changed, all packages will be rebuilt. After building, the
+results are cached into a tarball that can be re-used and distributed.
+
+### Package build results are (relatively) deterministic.
+
+Each package is configured and patched so that it will yield the same
+build-results with each consequent build, within a reasonable set of
+constraints. Some things like timestamp insertion are unavoidable, and are
+beyond the scope of this system. Additionally, the toolchain itself must be
+capable of deterministic results. When revisions are properly bumped, a cached
+build should represent an exact single payload.
+
+### Sources are fetched and verified automatically
+
+Each package must define its source location and checksum. The build will fail
+if the fetched source does not match. Sources may be pre-seeded and/or cached
+as desired.
+
+### Self-cleaning
+
+Build and staging dirs are wiped after use, and any previous version of a
+cached result is removed following a successful build. Automated builders
+should be able to build each revision and store the results with no further
+intervention.
diff --git a/depends/funcs.mk b/depends/funcs.mk
new file mode 100644
index 0000000000..050a9b1321
--- /dev/null
+++ b/depends/funcs.mk
@@ -0,0 +1,241 @@
+define int_vars
+#Set defaults for vars which may be overridden per-package
+$(1)_cc=$($($(1)_type)_CC)
+$(1)_cxx=$($($(1)_type)_CXX)
+$(1)_objc=$($($(1)_type)_OBJC)
+$(1)_objcxx=$($($(1)_type)_OBJCXX)
+$(1)_ar=$($($(1)_type)_AR)
+$(1)_ranlib=$($($(1)_type)_RANLIB)
+$(1)_libtool=$($($(1)_type)_LIBTOOL)
+$(1)_nm=$($($(1)_type)_NM)
+$(1)_cflags=$($($(1)_type)_CFLAGS) $($($(1)_type)_$(release_type)_CFLAGS)
+$(1)_cxxflags=$($($(1)_type)_CXXFLAGS) $($($(1)_type)_$(release_type)_CXXFLAGS)
+$(1)_ldflags=$($($(1)_type)_LDFLAGS) $($($(1)_type)_$(release_type)_LDFLAGS) -L$($($(1)_type)_prefix)/lib
+$(1)_cppflags=$($($(1)_type)_CPPFLAGS) $($($(1)_type)_$(release_type)_CPPFLAGS) -I$($($(1)_type)_prefix)/include
+$(1)_recipe_hash:=
+endef
+
+define int_get_all_dependencies
+$(sort $(foreach dep,$(2),$(2) $(call int_get_all_dependencies,$(1),$($(dep)_dependencies))))
+endef
+
+define fetch_file
+(test -f $$($(1)_source_dir)/$(4) || \
+ ( mkdir -p $$($(1)_download_dir) && echo Fetching $(1)... && \
+ ( $(build_DOWNLOAD) "$$($(1)_download_dir)/$(4).temp" "$(2)/$(3)" || \
+ $(build_DOWNLOAD) "$$($(1)_download_dir)/$(4).temp" "$(FALLBACK_DOWNLOAD_PATH)/$(3)" ) && \
+ echo "$(5) $$($(1)_download_dir)/$(4).temp" > $$($(1)_download_dir)/.$(4).hash && \
+ $(build_SHA256SUM) -c $$($(1)_download_dir)/.$(4).hash && \
+ mv $$($(1)_download_dir)/$(4).temp $$($(1)_source_dir)/$(4) && \
+ rm -rf $$($(1)_download_dir) ))
+endef
+
+define int_get_build_recipe_hash
+$(eval $(1)_all_file_checksums:=$(shell $(build_SHA256SUM) $(meta_depends) packages/$(1).mk $(addprefix $(PATCHES_PATH)/$(1)/,$($(1)_patches)) | cut -d" " -f1))
+$(eval $(1)_recipe_hash:=$(shell echo -n "$($(1)_all_file_checksums)" | $(build_SHA256SUM) | cut -d" " -f1))
+endef
+
+define int_get_build_id
+$(eval $(1)_dependencies += $($(1)_$(host_arch)_$(host_os)_dependencies) $($(1)_$(host_os)_dependencies))
+$(eval $(1)_all_dependencies:=$(call int_get_all_dependencies,$(1),$($($(1)_type)_native_toolchain) $($(1)_dependencies)))
+$(foreach dep,$($(1)_all_dependencies),$(eval $(1)_build_id_deps+=$(dep)-$($(dep)_version)-$($(dep)_recipe_hash)))
+$(eval $(1)_build_id_long:=$(1)-$($(1)_version)-$($(1)_recipe_hash)-$(release_type) $($(1)_build_id_deps))
+$(eval $(1)_build_id:=$(shell echo -n "$($(1)_build_id_long)" | $(build_SHA256SUM) | cut -c-$(HASH_LENGTH)))
+final_build_id_long+=$($(package)_build_id_long)
+
+#compute package-specific paths
+$(1)_build_subdir?=.
+$(1)_download_file?=$($(1)_file_name)
+$(1)_source_dir:=$(SOURCES_PATH)
+$(1)_source:=$$($(1)_source_dir)/$($(1)_file_name)
+$(1)_staging_dir=$(base_staging_dir)/$(host)/$(1)/$($(1)_version)-$($(1)_build_id)
+$(1)_staging_prefix_dir:=$$($(1)_staging_dir)$($($(1)_type)_prefix)
+$(1)_extract_dir:=$(base_build_dir)/$(host)/$(1)/$($(1)_version)-$($(1)_build_id)
+$(1)_download_dir:=$(base_download_dir)/$(1)-$($(1)_version)
+$(1)_build_dir:=$$($(1)_extract_dir)/$$($(1)_build_subdir)
+$(1)_cached_checksum:=$(BASE_CACHE)/$(host)/$(1)/$(1)-$($(1)_version)-$($(1)_build_id).tar.gz.hash
+$(1)_patch_dir:=$(base_build_dir)/$(host)/$(1)/$($(1)_version)-$($(1)_build_id)/.patches-$($(1)_build_id)
+$(1)_prefixbin:=$($($(1)_type)_prefix)/bin/
+$(1)_cached:=$(BASE_CACHE)/$(host)/$(1)/$(1)-$($(1)_version)-$($(1)_build_id).tar.gz
+$(1)_all_sources=$($(1)_file_name) $($(1)_extra_sources)
+
+#stamps
+$(1)_fetched=$(SOURCES_PATH)/download-stamps/.stamp_fetched-$(1)-$($(1)_file_name).hash
+$(1)_extracted=$$($(1)_extract_dir)/.stamp_extracted
+$(1)_preprocessed=$$($(1)_extract_dir)/.stamp_preprocessed
+$(1)_cleaned=$$($(1)_extract_dir)/.stamp_cleaned
+$(1)_built=$$($(1)_build_dir)/.stamp_built
+$(1)_configured=$$($(1)_build_dir)/.stamp_configured
+$(1)_staged=$$($(1)_staging_dir)/.stamp_staged
+$(1)_postprocessed=$$($(1)_staging_prefix_dir)/.stamp_postprocessed
+$(1)_download_path_fixed=$(subst :,\:,$$($(1)_download_path))
+
+
+#default commands
+$(1)_fetch_cmds ?= $(call fetch_file,$(1),$(subst \:,:,$$($(1)_download_path_fixed)),$$($(1)_download_file),$($(1)_file_name),$($(1)_sha256_hash))
+$(1)_extract_cmds ?= mkdir -p $$($(1)_extract_dir) && echo "$$($(1)_sha256_hash) $$($(1)_source)" > $$($(1)_extract_dir)/.$$($(1)_file_name).hash && $(build_SHA256SUM) -c $$($(1)_extract_dir)/.$$($(1)_file_name).hash && tar --strip-components=1 -xf $$($(1)_source)
+$(1)_preprocess_cmds ?=
+$(1)_build_cmds ?=
+$(1)_config_cmds ?=
+$(1)_stage_cmds ?=
+$(1)_set_vars ?=
+
+
+all_sources+=$$($(1)_fetched)
+endef
+#$(foreach dep_target,$($(1)_all_dependencies),$(eval $(1)_dependency_targets=$($(dep_target)_cached)))
+
+
+define int_config_attach_build_config
+$(eval $(call $(1)_set_vars,$(1)))
+$(1)_cflags+=$($(1)_cflags_$(release_type))
+$(1)_cflags+=$($(1)_cflags_$(host_arch)) $($(1)_cflags_$(host_arch)_$(release_type))
+$(1)_cflags+=$($(1)_cflags_$(host_os)) $($(1)_cflags_$(host_os)_$(release_type))
+$(1)_cflags+=$($(1)_cflags_$(host_arch)_$(host_os)) $($(1)_cflags_$(host_arch)_$(host_os)_$(release_type))
+
+$(1)_cxxflags+=$($(1)_cxxflags_$(release_type))
+$(1)_cxxflags+=$($(1)_cxxflags_$(host_arch)) $($(1)_cxxflags_$(host_arch)_$(release_type))
+$(1)_cxxflags+=$($(1)_cxxflags_$(host_os)) $($(1)_cxxflags_$(host_os)_$(release_type))
+$(1)_cxxflags+=$($(1)_cxxflags_$(host_arch)_$(host_os)) $($(1)_cxxflags_$(host_arch)_$(host_os)_$(release_type))
+
+$(1)_cppflags+=$($(1)_cppflags_$(release_type))
+$(1)_cppflags+=$($(1)_cppflags_$(host_arch)) $($(1)_cppflags_$(host_arch)_$(release_type))
+$(1)_cppflags+=$($(1)_cppflags_$(host_os)) $($(1)_cppflags_$(host_os)_$(release_type))
+$(1)_cppflags+=$($(1)_cppflags_$(host_arch)_$(host_os)) $($(1)_cppflags_$(host_arch)_$(host_os)_$(release_type))
+
+$(1)_ldflags+=$($(1)_ldflags_$(release_type))
+$(1)_ldflags+=$($(1)_ldflags_$(host_arch)) $($(1)_ldflags_$(host_arch)_$(release_type))
+$(1)_ldflags+=$($(1)_ldflags_$(host_os)) $($(1)_ldflags_$(host_os)_$(release_type))
+$(1)_ldflags+=$($(1)_ldflags_$(host_arch)_$(host_os)) $($(1)_ldflags_$(host_arch)_$(host_os)_$(release_type))
+
+$(1)_build_opts+=$$($(1)_build_opts_$(release_type))
+$(1)_build_opts+=$$($(1)_build_opts_$(host_arch)) $$($(1)_build_opts_$(host_arch)_$(release_type))
+$(1)_build_opts+=$$($(1)_build_opts_$(host_os)) $$($(1)_build_opts_$(host_os)_$(release_type))
+$(1)_build_opts+=$$($(1)_build_opts_$(host_arch)_$(host_os)) $$($(1)_build_opts_$(host_arch)_$(host_os)_$(release_type))
+
+$(1)_config_opts+=$$($(1)_config_opts_$(release_type))
+$(1)_config_opts+=$$($(1)_config_opts_$(host_arch)) $$($(1)_config_opts_$(host_arch)_$(release_type))
+$(1)_config_opts+=$$($(1)_config_opts_$(host_os)) $$($(1)_config_opts_$(host_os)_$(release_type))
+$(1)_config_opts+=$$($(1)_config_opts_$(host_arch)_$(host_os)) $$($(1)_config_opts_$(host_arch)_$(host_os)_$(release_type))
+
+$(1)_config_env+=$$($(1)_config_env_$(release_type))
+$(1)_config_env+=$($(1)_config_env_$(host_arch)) $($(1)_config_env_$(host_arch)_$(release_type))
+$(1)_config_env+=$($(1)_config_env_$(host_os)) $($(1)_config_env_$(host_os)_$(release_type))
+$(1)_config_env+=$($(1)_config_env_$(host_arch)_$(host_os)) $($(1)_config_env_$(host_arch)_$(host_os)_$(release_type))
+
+$(1)_config_env+=PKG_CONFIG_LIBDIR=$($($(1)_type)_prefix)/lib/pkgconfig
+$(1)_config_env+=PKG_CONFIG_PATH=$($($(1)_type)_prefix)/share/pkgconfig
+$(1)_config_env+=PATH=$(build_prefix)/bin:$(PATH)
+$(1)_build_env+=PATH=$(build_prefix)/bin:$(PATH)
+$(1)_stage_env+=PATH=$(build_prefix)/bin:$(PATH)
+$(1)_autoconf=./configure --host=$($($(1)_type)_host) --disable-dependency-tracking --prefix=$($($(1)_type)_prefix) $$($(1)_config_opts) CC="$$($(1)_cc)" CXX="$$($(1)_cxx)"
+
+ifneq ($($(1)_nm),)
+$(1)_autoconf += NM="$$($(1)_nm)"
+endif
+ifneq ($($(1)_ranlib),)
+$(1)_autoconf += RANLIB="$$($(1)_ranlib)"
+endif
+ifneq ($($(1)_ar),)
+$(1)_autoconf += AR="$$($(1)_ar)"
+endif
+ifneq ($($(1)_cflags),)
+$(1)_autoconf += CFLAGS="$$($(1)_cflags)"
+endif
+ifneq ($($(1)_cxxflags),)
+$(1)_autoconf += CXXFLAGS="$$($(1)_cxxflags)"
+endif
+ifneq ($($(1)_cppflags),)
+$(1)_autoconf += CPPFLAGS="$$($(1)_cppflags)"
+endif
+ifneq ($($(1)_ldflags),)
+$(1)_autoconf += LDFLAGS="$$($(1)_ldflags)"
+endif
+endef
+
+define int_add_cmds
+$($(1)_fetched):
+ $(AT)mkdir -p $$(@D) $(SOURCES_PATH)
+ $(AT)rm -f $$@
+ $(AT)touch $$@
+ $(AT)cd $$(@D); $(call $(1)_fetch_cmds,$(1))
+ $(AT)cd $($(1)_source_dir); $(foreach source,$($(1)_all_sources),$(build_SHA256SUM) $(source) >> $$(@);)
+ $(AT)touch $$@
+$($(1)_extracted): | $($(1)_fetched)
+ $(AT)echo Extracting $(1)...
+ $(AT)mkdir -p $$(@D)
+ $(AT)cd $$(@D); $(call $(1)_extract_cmds,$(1))
+ $(AT)touch $$@
+$($(1)_preprocessed): | $($(1)_dependencies) $($(1)_extracted)
+ $(AT)echo Preprocessing $(1)...
+ $(AT)mkdir -p $$(@D) $($(1)_patch_dir)
+ $(AT)$(foreach patch,$($(1)_patches),cd $(PATCHES_PATH)/$(1); cp $(patch) $($(1)_patch_dir) ;)
+ $(AT)cd $$(@D); $(call $(1)_preprocess_cmds, $(1))
+ $(AT)touch $$@
+$($(1)_configured): | $($(1)_preprocessed)
+ $(AT)echo Configuring $(1)...
+ $(AT)rm -rf $(host_prefix); mkdir -p $(host_prefix)/lib; cd $(host_prefix); $(foreach package,$($(1)_all_dependencies), tar xf $($(package)_cached); )
+ $(AT)mkdir -p $$(@D)
+ $(AT)+cd $$(@D); $($(1)_config_env) $(call $(1)_config_cmds, $(1))
+ $(AT)touch $$@
+$($(1)_built): | $($(1)_configured)
+ $(AT)echo Building $(1)...
+ $(AT)mkdir -p $$(@D)
+ $(AT)+cd $$(@D); $($(1)_build_env) $(call $(1)_build_cmds, $(1))
+ $(AT)touch $$@
+$($(1)_staged): | $($(1)_built)
+ $(AT)echo Staging $(1)...
+ $(AT)mkdir -p $($(1)_staging_dir)/$(host_prefix)
+ $(AT)cd $($(1)_build_dir); $($(1)_stage_env) $(call $(1)_stage_cmds, $(1))
+ $(AT)rm -rf $($(1)_extract_dir)
+ $(AT)touch $$@
+$($(1)_postprocessed): | $($(1)_staged)
+ $(AT)echo Postprocessing $(1)...
+ $(AT)cd $($(1)_staging_prefix_dir); $(call $(1)_postprocess_cmds)
+ $(AT)touch $$@
+$($(1)_cached): | $($(1)_dependencies) $($(1)_postprocessed)
+ $(AT)echo Caching $(1)...
+ $(AT)cd $$($(1)_staging_dir)/$(host_prefix); find . | sort | tar --no-recursion -czf $$($(1)_staging_dir)/$$(@F) -T -
+ $(AT)mkdir -p $$(@D)
+ $(AT)rm -rf $$(@D) && mkdir -p $$(@D)
+ $(AT)mv $$($(1)_staging_dir)/$$(@F) $$(@)
+ $(AT)rm -rf $($(1)_staging_dir)
+$($(1)_cached_checksum): $($(1)_cached)
+ $(AT)cd $$(@D); $(build_SHA256SUM) $$(<F) > $$(@)
+
+.PHONY: $(1)
+$(1): | $($(1)_cached_checksum)
+.SECONDARY: $($(1)_cached) $($(1)_postprocessed) $($(1)_staged) $($(1)_built) $($(1)_configured) $($(1)_preprocessed) $($(1)_extracted) $($(1)_fetched)
+
+endef
+
+# These functions create the build targets for each package. They must be
+# broken down into small steps so that each part is done for all packages
+# before moving on to the next step. Otherwise, a package's info
+# (build-id for example) would only be available to another package if it
+# happened to be computed already.
+
+#set the type for host/build packages.
+$(foreach native_package,$(native_packages),$(eval $(native_package)_type=build))
+$(foreach package,$(packages),$(eval $(package)_type=$(host_arch)_$(host_os)))
+
+#set overridable defaults
+$(foreach package,$(all_packages),$(eval $(call int_vars,$(package))))
+
+#include package files
+$(foreach package,$(all_packages),$(eval include packages/$(package).mk))
+
+#compute a hash of all files that comprise this package's build recipe
+$(foreach package,$(all_packages),$(eval $(call int_get_build_recipe_hash,$(package))))
+
+#generate a unique id for this package, incorporating its dependencies as well
+$(foreach package,$(all_packages),$(eval $(call int_get_build_id,$(package))))
+
+#compute final vars after reading package vars
+$(foreach package,$(all_packages),$(eval $(call int_config_attach_build_config,$(package))))
+
+#create build targets
+$(foreach package,$(all_packages),$(eval $(call int_add_cmds,$(package))))
+
+#special exception: if a toolchain package exists, all non-native packages depend on it
+$(foreach package,$(packages),$(eval $($(package)_unpacked): |$($($(host_arch)_$(host_os)_native_toolchain)_cached) ))
diff --git a/depends/hosts/darwin.mk b/depends/hosts/darwin.mk
new file mode 100644
index 0000000000..2958dc50cc
--- /dev/null
+++ b/depends/hosts/darwin.mk
@@ -0,0 +1,17 @@
+OSX_MIN_VERSION=10.7
+OSX_SDK_VERSION=10.9
+OSX_SDK=$(SDK_PATH)/MacOSX$(OSX_SDK_VERSION).sdk
+LD64_VERSION=241.9
+darwin_CC=clang -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION)
+darwin_CXX=clang++ -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION)
+
+darwin_CFLAGS=-pipe
+darwin_CXXFLAGS=$(darwin_CFLAGS)
+
+darwin_release_CFLAGS=-O2
+darwin_release_CXXFLAGS=$(darwin_release_CFLAGS)
+
+darwin_debug_CFLAGS=-O1
+darwin_debug_CXXFLAGS=$(darwin_debug_CFLAGS)
+
+darwin_native_toolchain=native_cctools
diff --git a/depends/hosts/default.mk b/depends/hosts/default.mk
new file mode 100644
index 0000000000..6f60d6b3fd
--- /dev/null
+++ b/depends/hosts/default.mk
@@ -0,0 +1,26 @@
+default_host_CC = $(host_toolchain)gcc
+default_host_CXX = $(host_toolchain)g++
+default_host_AR = $(host_toolchain)ar
+default_host_RANLIB = $(host_toolchain)ranlib
+default_host_STRIP = $(host_toolchain)strip
+default_host_LIBTOOL = $(host_toolchain)libtool
+default_host_INSTALL_NAME_TOOL = $(host_toolchain)install_name_tool
+default_host_OTOOL = $(host_toolchain)otool
+default_host_NM = $(host_toolchain)nm
+
+define add_host_tool_func
+$(host_os)_$1?=$$(default_host_$1)
+$(host_arch)_$(host_os)_$1?=$$($(host_os)_$1)
+$(host_arch)_$(host_os)_$(release_type)_$1?=$$($(host_os)_$1)
+host_$1=$$($(host_arch)_$(host_os)_$1)
+endef
+
+define add_host_flags_func
+$(host_arch)_$(host_os)_$1 += $($(host_os)_$1)
+$(host_arch)_$(host_os)_$(release_type)_$1 += $($(host_os)_$(release_type)_$1)
+host_$1 = $$($(host_arch)_$(host_os)_$1)
+host_$(release_type)_$1 = $$($(host_arch)_$(host_os)_$(release_type)_$1)
+endef
+
+$(foreach tool,CC CXX AR RANLIB STRIP NM LIBTOOL OTOOL INSTALL_NAME_TOOL,$(eval $(call add_host_tool_func,$(tool))))
+$(foreach flags,CFLAGS CXXFLAGS CPPFLAGS LDFLAGS, $(eval $(call add_host_flags_func,$(flags))))
diff --git a/depends/hosts/linux.mk b/depends/hosts/linux.mk
new file mode 100644
index 0000000000..b13a0f1ad7
--- /dev/null
+++ b/depends/hosts/linux.mk
@@ -0,0 +1,31 @@
+linux_CFLAGS=-pipe
+linux_CXXFLAGS=$(linux_CFLAGS)
+
+linux_release_CFLAGS=-O2
+linux_release_CXXFLAGS=$(linux_release_CFLAGS)
+
+linux_debug_CFLAGS=-O1
+linux_debug_CXXFLAGS=$(linux_debug_CFLAGS)
+
+linux_debug_CPPFLAGS=-D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC
+
+ifeq (86,$(findstring 86,$(build_arch)))
+i686_linux_CC=gcc -m32
+i686_linux_CXX=g++ -m32
+i686_linux_AR=ar
+i686_linux_RANLIB=ranlib
+i686_linux_NM=nm
+i686_linux_STRIP=strip
+
+x86_64_linux_CC=gcc -m64
+x86_64_linux_CXX=g++ -m64
+x86_64_linux_AR=ar
+x86_64_linux_RANLIB=ranlib
+x86_64_linux_NM=nm
+x86_64_linux_STRIP=strip
+else
+i686_linux_CC=$(default_host_CC) -m32
+i686_linux_CXX=$(default_host_CXX) -m32
+x86_64_linux_CC=$(default_host_CC) -m64
+x86_64_linux_CXX=$(default_host_CXX) -m64
+endif
diff --git a/depends/hosts/mingw32.mk b/depends/hosts/mingw32.mk
new file mode 100644
index 0000000000..dbfb62fdcf
--- /dev/null
+++ b/depends/hosts/mingw32.mk
@@ -0,0 +1,10 @@
+mingw32_CFLAGS=-pipe
+mingw32_CXXFLAGS=$(mingw32_CFLAGS)
+
+mingw32_release_CFLAGS=-O2
+mingw32_release_CXXFLAGS=$(mingw32_release_CFLAGS)
+
+mingw32_debug_CFLAGS=-O1
+mingw32_debug_CXXFLAGS=$(mingw32_debug_CFLAGS)
+
+mingw32_debug_CPPFLAGS=-D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC
diff --git a/depends/packages.md b/depends/packages.md
new file mode 100644
index 0000000000..7c80362509
--- /dev/null
+++ b/depends/packages.md
@@ -0,0 +1,147 @@
+Each recipe consists of 3 main parts: defining identifiers, setting build
+variables, and defining build commands.
+
+The package "mylib" will be used here as an example
+
+General tips:
+- mylib_foo is written as $(package)_foo in order to make recipes more similar.
+
+## Identifiers
+Each package is required to define at least these variables:
+
+ $(package)_version:
+ Version of the upstream library or program. If there is no version, a
+ placeholder such as 1.0 can be used.
+
+ $(package)_download_path:
+ Location of the upstream source, without the file-name. Usually http or
+ ftp.
+
+ $(package)_file_name:
+ The upstream source filename available at the download path.
+
+ $(package)_sha256_hash:
+ The sha256 hash of the upstream file
+
+These variables are optional:
+
+ $(package)_build_subdir:
+ cd to this dir before running configure/build/stage commands.
+
+ $(package)_download_file:
+ The file-name of the upstream source if it differs from how it should be
+ stored locally. This can be used to avoid storing file-names with strange
+ characters.
+
+ $(package)_dependencies:
+ Names of any other packages that this one depends on.
+
+ $(package)_patches:
+ Filenames of any patches needed to build the package
+
+ $(package)_extra_sources:
+ Any extra files that will be fetched via $(package)_fetch_cmds. These are
+ specified so that they can be fetched and verified via 'make download'.
+
+
+## Build Variables:
+After defining the main identifiers, build variables may be added or customized
+before running the build commands. They should be added to a function called
+$(package)_set_vars. For example:
+
+ define $(package)_set_vars
+ ...
+ endef
+
+Most variables can be prefixed with the host, architecture, or both, to make
+the modifications specific to that case. For example:
+
+ Universal: $(package)_cc=gcc
+ Linux only: $(package)_linux_cc=gcc
+ x86_64 only: $(package)_x86_64_cc = gcc
+ x86_64 linux only: $(package)_x86_64_linux_cc = gcc
+
+These variables may be set to override or append their default values.
+
+ $(package)_cc
+ $(package)_cxx
+ $(package)_objc
+ $(package)_objcxx
+ $(package)_ar
+ $(package)_ranlib
+ $(package)_libtool
+ $(package)_nm
+ $(package)_cflags
+ $(package)_cxxflags
+ $(package)_ldflags
+ $(package)_cppflags
+ $(package)_config_env
+ $(package)_build_env
+ $(package)_stage_env
+ $(package)_build_opts
+ $(package)_config_opts
+
+The *_env variables are used to add environment variables to the respective
+commands.
+
+Many variables respect a debug/release suffix as well, in order to use them for
+only the appropriate build config. For example:
+
+ $(package)_cflags_release = -O3
+ $(package)_cflags_i686_debug = -g
+ $(package)_config_opts_release = --disable-debug
+
+These will be used in addition to the options that do not specify
+debug/release. All builds are considered to be release unless DEBUG=1 is set by
+the user. Other variables may be defined as needed.
+
+## Build commands:
+
+ For each build, a unique build dir and staging dir are created. For example,
+ `work/build/mylib/1.0-1adac830f6e` and `work/staging/mylib/1.0-1adac830f6e`.
+
+ The following build commands are available for each recipe:
+
+ $(package)_fetch_cmds:
+ Runs from: build dir
+ Fetch the source file. If undefined, it will be fetched and verified
+ against its hash.
+
+ $(package)_extract_cmds:
+ Runs from: build dir
+ Verify the source file against its hash and extract it. If undefined, the
+ source is assumed to be a tarball.
+
+ $(package)_preprocess_cmds:
+ Runs from: build dir/$(package)_build_subdir
+ Preprocess the source as necessary. If undefined, does nothing.
+
+ $(package)_config_cmds:
+ Runs from: build dir/$(package)_build_subdir
+ Configure the source. If undefined, does nothing.
+
+ $(package)_build_cmds:
+ Runs from: build dir/$(package)_build_subdir
+ Build the source. If undefined, does nothing.
+
+ $(package)_stage_cmds:
+ Runs from: build dir/$(package)_build_subdir
+ Stage the build results. If undefined, does nothing.
+
+ The following variables are available for each recipe:
+
+ $(1)_staging_dir: package's destination sysroot path
+ $(1)_staging_prefix_dir: prefix path inside of the package's staging dir
+ $(1)_extract_dir: path to the package's extracted sources
+ $(1)_build_dir: path where configure/build/stage commands will be run
+ $(1)_patch_dir: path where the package's patches (if any) are found
+
+Notes on build commands:
+
+For packages built with autotools, $($(package)_autoconf) can be used in the
+configure step to (usually) correctly configure automatically. Any
+$($(package)_config_opts) will be appended.
+
+Most autotools projects can be properly staged using:
+
+ $(MAKE) DESTDIR=$($(package)_staging_dir) install
diff --git a/depends/packages/bdb.mk b/depends/packages/bdb.mk
new file mode 100644
index 0000000000..68841afdb8
--- /dev/null
+++ b/depends/packages/bdb.mk
@@ -0,0 +1,28 @@
+package=bdb
+$(package)_version=4.8.30
+$(package)_download_path=http://download.oracle.com/berkeley-db
+$(package)_file_name=db-$($(package)_version).NC.tar.gz
+$(package)_sha256_hash=12edc0df75bf9abd7f82f821795bcee50f42cb2e5f76a6a281b85732798364ef
+$(package)_build_subdir=build_unix
+
+define $(package)_set_vars
+$(package)_config_opts=--disable-shared --enable-cxx --disable-replication
+$(package)_config_opts_mingw32=--enable-mingw
+$(package)_config_opts_linux=--with-pic
+endef
+
+define $(package)_preprocess_cmds
+ sed -i.old 's/__atomic_compare_exchange/__atomic_compare_exchange_db/' dbinc/atomic.h
+endef
+
+define $(package)_config_cmds
+ ../dist/$($(package)_autoconf)
+endef
+
+define $(package)_build_cmds
+ $(MAKE) libdb_cxx-4.8.a libdb-4.8.a
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) DESTDIR=$($(package)_staging_dir) install_lib install_include
+endef
diff --git a/depends/packages/boost.mk b/depends/packages/boost.mk
new file mode 100644
index 0000000000..e7aa48ddf8
--- /dev/null
+++ b/depends/packages/boost.mk
@@ -0,0 +1,45 @@
+package=boost
+$(package)_version=1_55_0
+$(package)_download_path=http://sourceforge.net/projects/boost/files/boost/1.55.0
+$(package)_file_name=$(package)_$($(package)_version).tar.bz2
+$(package)_sha256_hash=fff00023dd79486d444c8e29922f4072e1d451fc5a4d2b6075852ead7f2b7b52
+$(package)_patches=darwin_boost_atomic-1.patch darwin_boost_atomic-2.patch gcc_5_no_cxx11.patch
+
+define $(package)_set_vars
+$(package)_config_opts_release=variant=release
+$(package)_config_opts_debug=variant=debug
+$(package)_config_opts=--layout=tagged --build-type=complete --user-config=user-config.jam
+$(package)_config_opts+=threading=multi link=static -sNO_BZIP2=1 -sNO_ZLIB=1
+$(package)_config_opts_linux=threadapi=pthread runtime-link=shared
+$(package)_config_opts_darwin=--toolset=darwin-4.2.1 runtime-link=shared
+$(package)_config_opts_mingw32=binary-format=pe target-os=windows threadapi=win32 runtime-link=static
+$(package)_config_opts_x86_64_mingw32=address-model=64
+$(package)_config_opts_i686_mingw32=address-model=32
+$(package)_config_opts_i686_linux=address-model=32 architecture=x86
+$(package)_toolset_$(host_os)=gcc
+$(package)_archiver_$(host_os)=$($(package)_ar)
+$(package)_toolset_darwin=darwin
+$(package)_archiver_darwin=$($(package)_libtool)
+$(package)_config_libraries=chrono,filesystem,program_options,system,thread,test
+$(package)_cxxflags=-fvisibility=hidden
+$(package)_cxxflags_linux=-fPIC
+endef
+
+define $(package)_preprocess_cmds
+ patch -p2 < $($(package)_patch_dir)/darwin_boost_atomic-1.patch && \
+ patch -p2 < $($(package)_patch_dir)/darwin_boost_atomic-2.patch && \
+ patch -p2 < $($(package)_patch_dir)/gcc_5_no_cxx11.patch && \
+ echo "using $(boost_toolset_$(host_os)) : : $($(package)_cxx) : <cxxflags>\"$($(package)_cxxflags) $($(package)_cppflags)\" <linkflags>\"$($(package)_ldflags)\" <archiver>\"$(boost_archiver_$(host_os))\" <striper>\"$(host_STRIP)\" <ranlib>\"$(host_RANLIB)\" <rc>\"$(host_WINDRES)\" : ;" > user-config.jam
+endef
+
+define $(package)_config_cmds
+ ./bootstrap.sh --without-icu --with-libraries=$(boost_config_libraries)
+endef
+
+define $(package)_build_cmds
+ ./b2 -d2 -j2 -d1 --prefix=$($(package)_staging_prefix_dir) $($(package)_config_opts) stage
+endef
+
+define $(package)_stage_cmds
+ ./b2 -d0 -j4 --prefix=$($(package)_staging_prefix_dir) $($(package)_config_opts) install
+endef
diff --git a/depends/packages/dbus.mk b/depends/packages/dbus.mk
new file mode 100644
index 0000000000..8ac9ab742b
--- /dev/null
+++ b/depends/packages/dbus.mk
@@ -0,0 +1,23 @@
+package=dbus
+$(package)_version=1.8.6
+$(package)_download_path=http://dbus.freedesktop.org/releases/dbus
+$(package)_file_name=$(package)-$($(package)_version).tar.gz
+$(package)_sha256_hash=eded83ca007b719f32761e60fd8b9ffd0f5796a4caf455b01b5a5ef740ebd23f
+$(package)_dependencies=expat
+
+define $(package)_set_vars
+ $(package)_config_opts=--disable-tests --disable-doxygen-docs --disable-xml-docs --disable-static --without-x
+endef
+
+define $(package)_config_cmds
+ $($(package)_autoconf)
+endef
+
+define $(package)_build_cmds
+ $(MAKE) -C dbus libdbus-1.la
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) -C dbus DESTDIR=$($(package)_staging_dir) install-libLTLIBRARIES install-dbusincludeHEADERS install-nodist_dbusarchincludeHEADERS && \
+ $(MAKE) DESTDIR=$($(package)_staging_dir) install-pkgconfigDATA
+endef
diff --git a/depends/packages/expat.mk b/depends/packages/expat.mk
new file mode 100644
index 0000000000..1ac4435374
--- /dev/null
+++ b/depends/packages/expat.mk
@@ -0,0 +1,21 @@
+package=expat
+$(package)_version=2.1.0
+$(package)_download_path=http://sourceforge.net/projects/expat/files/expat/$($(package)_version)
+$(package)_file_name=$(package)-$($(package)_version).tar.gz
+$(package)_sha256_hash=823705472f816df21c8f6aa026dd162b280806838bb55b3432b0fb1fcca7eb86
+
+define $(package)_set_vars
+$(package)_config_opts=--disable-static
+endef
+
+define $(package)_config_cmds
+ $($(package)_autoconf)
+endef
+
+define $(package)_build_cmds
+ $(MAKE)
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) DESTDIR=$($(package)_staging_dir) install
+endef
diff --git a/depends/packages/fontconfig.mk b/depends/packages/fontconfig.mk
new file mode 100644
index 0000000000..2cf553ed96
--- /dev/null
+++ b/depends/packages/fontconfig.mk
@@ -0,0 +1,22 @@
+package=fontconfig
+$(package)_version=2.11.1
+$(package)_download_path=http://www.freedesktop.org/software/fontconfig/release/
+$(package)_file_name=$(package)-$($(package)_version).tar.bz2
+$(package)_sha256_hash=dc62447533bca844463a3c3fd4083b57c90f18a70506e7a9f4936b5a1e516a99
+$(package)_dependencies=freetype expat
+
+define $(package)_set_vars
+ $(package)_config_opts=--disable-docs --disable-static
+endef
+
+define $(package)_config_cmds
+ $($(package)_autoconf)
+endef
+
+define $(package)_build_cmds
+ $(MAKE)
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) DESTDIR=$($(package)_staging_dir) install
+endef
diff --git a/depends/packages/freetype.mk b/depends/packages/freetype.mk
new file mode 100644
index 0000000000..f7d6e0f9fc
--- /dev/null
+++ b/depends/packages/freetype.mk
@@ -0,0 +1,22 @@
+package=freetype
+$(package)_version=2.5.3
+$(package)_download_path=http://downloads.sourceforge.net/$(package)
+$(package)_file_name=$(package)-$($(package)_version).tar.bz2
+$(package)_sha256_hash=c0848b29d52ef3ca27ad92e08351f023c5e24ce8cea7d8fe69fc96358e65f75e
+
+define $(package)_set_vars
+ $(package)_config_opts=--without-zlib --without-png --disable-static
+ $(package)_config_opts_linux=--with-pic
+endef
+
+define $(package)_config_cmds
+ $($(package)_autoconf)
+endef
+
+define $(package)_build_cmds
+ $(MAKE)
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) DESTDIR=$($(package)_staging_dir) install
+endef
diff --git a/depends/packages/libICE.mk b/depends/packages/libICE.mk
new file mode 100644
index 0000000000..fc60323b1c
--- /dev/null
+++ b/depends/packages/libICE.mk
@@ -0,0 +1,23 @@
+package=libICE
+$(package)_version=1.0.9
+$(package)_download_path=http://xorg.freedesktop.org/releases/individual/lib/
+$(package)_file_name=$(package)-$($(package)_version).tar.bz2
+$(package)_sha256_hash=8f7032f2c1c64352b5423f6b48a8ebdc339cc63064af34d66a6c9aa79759e202
+$(package)_dependencies=xtrans xproto
+
+define $(package)_set_vars
+ $(package)_config_opts=--disable-static --disable-docs --disable-specs --without-xsltproc
+ $(package)_config_opts_linux=--with-pic
+endef
+
+define $(package)_config_cmds
+ $($(package)_autoconf)
+endef
+
+define $(package)_build_cmds
+ $(MAKE)
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) DESTDIR=$($(package)_staging_dir) install
+endef
diff --git a/depends/packages/libSM.mk b/depends/packages/libSM.mk
new file mode 100644
index 0000000000..0f9307ca76
--- /dev/null
+++ b/depends/packages/libSM.mk
@@ -0,0 +1,23 @@
+package=libSM
+$(package)_version=1.2.2
+$(package)_download_path=http://xorg.freedesktop.org/releases/individual/lib/
+$(package)_file_name=$(package)-$($(package)_version).tar.bz2
+$(package)_sha256_hash=0baca8c9f5d934450a70896c4ad38d06475521255ca63b717a6510fdb6e287bd
+$(package)_dependencies=xtrans xproto libICE
+
+define $(package)_set_vars
+ $(package)_config_opts=--without-libuuid --without-xsltproc --disable-docs --disable-static
+ $(package)_config_opts_linux=--with-pic
+endef
+
+define $(package)_config_cmds
+ $($(package)_autoconf)
+endef
+
+define $(package)_build_cmds
+ $(MAKE)
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) DESTDIR=$($(package)_staging_dir) install
+endef
diff --git a/depends/packages/libX11.mk b/depends/packages/libX11.mk
new file mode 100644
index 0000000000..178d592ee6
--- /dev/null
+++ b/depends/packages/libX11.mk
@@ -0,0 +1,23 @@
+package=libX11
+$(package)_version=1.6.2
+$(package)_download_path=http://xorg.freedesktop.org/releases/individual/lib/
+$(package)_file_name=$(package)-$($(package)_version).tar.bz2
+$(package)_sha256_hash=2aa027e837231d2eeea90f3a4afe19948a6eb4c8b2bec0241eba7dbc8106bd16
+$(package)_dependencies=libxcb xtrans xextproto xproto
+
+define $(package)_set_vars
+$(package)_config_opts=--disable-xkb --disable-static
+$(package)_config_opts_linux=--with-pic
+endef
+
+define $(package)_config_cmds
+ $($(package)_autoconf)
+endef
+
+define $(package)_build_cmds
+ $(MAKE)
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) DESTDIR=$($(package)_staging_dir) install
+endef
diff --git a/depends/packages/libXau.mk b/depends/packages/libXau.mk
new file mode 100644
index 0000000000..e87df2e4de
--- /dev/null
+++ b/depends/packages/libXau.mk
@@ -0,0 +1,23 @@
+package=libXau
+$(package)_version=1.0.8
+$(package)_download_path=http://xorg.freedesktop.org/releases/individual/lib/
+$(package)_file_name=$(package)-$($(package)_version).tar.bz2
+$(package)_sha256_hash=fdd477320aeb5cdd67272838722d6b7d544887dfe7de46e1e7cc0c27c2bea4f2
+$(package)_dependencies=xproto
+
+define $(package)_set_vars
+ $(package)_config_opts=--disable-shared
+ $(package)_config_opts_linux=--with-pic
+endef
+
+define $(package)_config_cmds
+ $($(package)_autoconf)
+endef
+
+define $(package)_build_cmds
+ $(MAKE)
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) DESTDIR=$($(package)_staging_dir) install
+endef
diff --git a/depends/packages/libXext.mk b/depends/packages/libXext.mk
new file mode 100644
index 0000000000..4db836066f
--- /dev/null
+++ b/depends/packages/libXext.mk
@@ -0,0 +1,22 @@
+package=libXext
+$(package)_version=1.3.2
+$(package)_download_path=http://xorg.freedesktop.org/releases/individual/lib/
+$(package)_file_name=$(package)-$($(package)_version).tar.bz2
+$(package)_sha256_hash=f829075bc646cdc085fa25d98d5885d83b1759ceb355933127c257e8e50432e0
+$(package)_dependencies=xproto xextproto libX11 libXau
+
+define $(package)_set_vars
+ $(package)_config_opts=--disable-static
+endef
+
+define $(package)_config_cmds
+ $($(package)_autoconf)
+endef
+
+define $(package)_build_cmds
+ $(MAKE)
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) DESTDIR=$($(package)_staging_dir) install
+endef
diff --git a/depends/packages/libxcb.mk b/depends/packages/libxcb.mk
new file mode 100644
index 0000000000..28f2bd6f25
--- /dev/null
+++ b/depends/packages/libxcb.mk
@@ -0,0 +1,35 @@
+package=libxcb
+$(package)_version=1.10
+$(package)_download_path=http://xcb.freedesktop.org/dist
+$(package)_file_name=$(package)-$($(package)_version).tar.bz2
+$(package)_sha256_hash=98d9ab05b636dd088603b64229dd1ab2d2cc02ab807892e107d674f9c3f2d5b5
+$(package)_dependencies=xcb_proto libXau xproto
+
+define $(package)_set_vars
+$(package)_config_opts=--disable-static
+endef
+
+define $(package)_preprocess_cmds
+ sed "s/pthread-stubs//" -i configure
+endef
+
+# Don't install xcb headers to the default path in order to work around a qt
+# build issue: https://bugreports.qt.io/browse/QTBUG-34748
+# When using qt's internal libxcb, it may end up finding the real headers in
+# depends staging. Use a non-default path to avoid that.
+
+define $(package)_config_cmds
+ $($(package)_autoconf) --includedir=$(host_prefix)/include/xcb-shared
+endef
+
+define $(package)_build_cmds
+ $(MAKE)
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) DESTDIR=$($(package)_staging_dir) install
+endef
+
+define $(package)_postprocess_cmds
+ rm -rf share/man share/doc
+endef
diff --git a/depends/packages/miniupnpc.mk b/depends/packages/miniupnpc.mk
new file mode 100644
index 0000000000..77bae10c79
--- /dev/null
+++ b/depends/packages/miniupnpc.mk
@@ -0,0 +1,28 @@
+package=miniupnpc
+$(package)_version=1.9.20151008
+$(package)_download_path=http://miniupnp.free.fr/files
+$(package)_file_name=$(package)-$($(package)_version).tar.gz
+$(package)_sha256_hash=e444ac3b587ce82709c4d0cfca1fe71f44f9fc433e9f946b12b9e1bfe667a633
+
+define $(package)_set_vars
+$(package)_build_opts=CC="$($(package)_cc)"
+$(package)_build_opts_darwin=OS=Darwin
+$(package)_build_opts_mingw32=-f Makefile.mingw
+$(package)_build_env+=CFLAGS="$($(package)_cflags) $($(package)_cppflags)" AR="$($(package)_ar)"
+endef
+
+define $(package)_preprocess_cmds
+ mkdir dll && \
+ sed -e 's|MINIUPNPC_VERSION_STRING \"version\"|MINIUPNPC_VERSION_STRING \"$($(package)_version)\"|' -e 's|OS/version|$(host)|' miniupnpcstrings.h.in > miniupnpcstrings.h && \
+ sed -i.old "s|miniupnpcstrings.h: miniupnpcstrings.h.in wingenminiupnpcstrings|miniupnpcstrings.h: miniupnpcstrings.h.in|" Makefile.mingw
+endef
+
+define $(package)_build_cmds
+ $(MAKE) libminiupnpc.a $($(package)_build_opts)
+endef
+
+define $(package)_stage_cmds
+ mkdir -p $($(package)_staging_prefix_dir)/include/miniupnpc $($(package)_staging_prefix_dir)/lib &&\
+ install *.h $($(package)_staging_prefix_dir)/include/miniupnpc &&\
+ install libminiupnpc.a $($(package)_staging_prefix_dir)/lib
+endef
diff --git a/depends/packages/native_ccache.mk b/depends/packages/native_ccache.mk
new file mode 100644
index 0000000000..3226e89a63
--- /dev/null
+++ b/depends/packages/native_ccache.mk
@@ -0,0 +1,25 @@
+package=native_ccache
+$(package)_version=3.1.9
+$(package)_download_path=http://samba.org/ftp/ccache
+$(package)_file_name=ccache-$($(package)_version).tar.bz2
+$(package)_sha256_hash=04d3e2e438ac8d4cc4b110b68cdd61bd59226c6588739a4a386869467f5ced7c
+
+define $(package)_set_vars
+$(package)_config_opts=
+endef
+
+define $(package)_config_cmds
+ $($(package)_autoconf)
+endef
+
+define $(package)_build_cmds
+ $(MAKE)
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) DESTDIR=$($(package)_staging_dir) install
+endef
+
+define $(package)_postprocess_cmds
+ rm -rf lib include
+endef
diff --git a/depends/packages/native_cctools.mk b/depends/packages/native_cctools.mk
new file mode 100644
index 0000000000..1c1bcf199a
--- /dev/null
+++ b/depends/packages/native_cctools.mk
@@ -0,0 +1,58 @@
+package=native_cctools
+$(package)_version=ee31ae567931c426136c94aad457c7b51d844beb
+$(package)_download_path=https://github.com/theuni/cctools-port/archive
+$(package)_file_name=$($(package)_version).tar.gz
+$(package)_sha256_hash=ef107e6ab1b3994cb22e14f4f5c59ea0c0b5a988e6b21d42ed9616b018bbcbf9
+$(package)_build_subdir=cctools
+$(package)_clang_version=3.3
+$(package)_clang_download_path=http://llvm.org/releases/$($(package)_clang_version)
+$(package)_clang_download_file=clang+llvm-$($(package)_clang_version)-amd64-Ubuntu-12.04.2.tar.gz
+$(package)_clang_file_name=clang-llvm-$($(package)_clang_version)-amd64-Ubuntu-12.04.2.tar.gz
+$(package)_clang_sha256_hash=60d8f69f032d62ef61bf527857ebb933741ec3352d4d328c5516aa520662dab7
+$(package)_extra_sources=$($(package)_clang_file_name)
+
+define $(package)_fetch_cmds
+$(call fetch_file,$(package),$($(package)_download_path),$($(package)_download_file),$($(package)_file_name),$($(package)_sha256_hash)) && \
+$(call fetch_file,$(package),$($(package)_clang_download_path),$($(package)_clang_download_file),$($(package)_clang_file_name),$($(package)_clang_sha256_hash))
+endef
+
+define $(package)_extract_cmds
+ mkdir -p toolchain/bin toolchain/lib/clang/3.5/include && \
+ tar --strip-components=1 -C toolchain -xf $($(package)_source_dir)/$($(package)_clang_file_name) && \
+ echo "#!/bin/sh" > toolchain/bin/$(host)-dsymutil && \
+ echo "exit 0" >> toolchain/bin/$(host)-dsymutil && \
+ chmod +x toolchain/bin/$(host)-dsymutil && \
+ tar --strip-components=1 -xf $($(package)_source)
+endef
+
+define $(package)_set_vars
+$(package)_config_opts=--target=$(host) --disable-libuuid
+$(package)_ldflags+=-Wl,-rpath=\\$$$$$$$$\$$$$$$$$ORIGIN/../lib
+$(package)_cc=$($(package)_extract_dir)/toolchain/bin/clang
+$(package)_cxx=$($(package)_extract_dir)/toolchain/bin/clang++
+endef
+
+define $(package)_preprocess_cmds
+ cd $($(package)_build_subdir); ./autogen.sh
+endef
+
+define $(package)_config_cmds
+ $($(package)_autoconf)
+endef
+
+define $(package)_build_cmds
+ $(MAKE)
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) DESTDIR=$($(package)_staging_dir) install && \
+ cd $($(package)_extract_dir)/toolchain && \
+ mkdir -p $($(package)_staging_prefix_dir)/lib/clang/$($(package)_clang_version)/include && \
+ mkdir -p $($(package)_staging_prefix_dir)/bin $($(package)_staging_prefix_dir)/include && \
+ cp -P bin/clang bin/clang++ $($(package)_staging_prefix_dir)/bin/ &&\
+ cp lib/libLTO.so $($(package)_staging_prefix_dir)/lib/ && \
+ cp -rf lib/clang/$($(package)_clang_version)/include/* $($(package)_staging_prefix_dir)/lib/clang/$($(package)_clang_version)/include/ && \
+ cp bin/$(host)-dsymutil $($(package)_staging_prefix_dir)/bin && \
+ if `test -d include/c++/`; then cp -rf include/c++/ $($(package)_staging_prefix_dir)/include/; fi && \
+ if `test -d lib/c++/`; then cp -rf lib/c++/ $($(package)_staging_prefix_dir)/lib/; fi
+endef
diff --git a/depends/packages/native_cdrkit.mk b/depends/packages/native_cdrkit.mk
new file mode 100644
index 0000000000..cf694edb30
--- /dev/null
+++ b/depends/packages/native_cdrkit.mk
@@ -0,0 +1,26 @@
+package=native_cdrkit
+$(package)_version=1.1.11
+$(package)_download_path=http://distro.ibiblio.org/fatdog/source/600/c
+$(package)_file_name=cdrkit-$($(package)_version).tar.bz2
+$(package)_sha256_hash=b50d64c214a65b1a79afe3a964c691931a4233e2ba605d793eb85d0ac3652564
+$(package)_patches=cdrkit-deterministic.patch
+
+define $(package)_preprocess_cmds
+ patch -p1 < $($(package)_patch_dir)/cdrkit-deterministic.patch
+endef
+
+define $(package)_config_cmds
+ cmake -DCMAKE_INSTALL_PREFIX=$(build_prefix)
+endef
+
+define $(package)_build_cmds
+ $(MAKE) genisoimage
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) DESTDIR=$($(package)_staging_dir) -C genisoimage install
+endef
+
+define $(package)_postprocess_cmds
+ rm bin/isovfy bin/isoinfo bin/isodump bin/isodebug bin/devdump
+endef
diff --git a/depends/packages/native_comparisontool.mk b/depends/packages/native_comparisontool.mk
new file mode 100644
index 0000000000..d1b86dc2de
--- /dev/null
+++ b/depends/packages/native_comparisontool.mk
@@ -0,0 +1,21 @@
+package=native_comparisontool
+$(package)_version=0f7b5d8
+$(package)_download_path=https://github.com/TheBlueMatt/test-scripts/raw/38b490a2599d422b12d5ce8f165792f63fd8f54f
+$(package)_file_name=pull-tests-$($(package)_version).jar
+$(package)_sha256_hash=ecd43b988a8b673b483e4f69f931596360a5e90fc415c75c4c259faa690df198
+$(package)_install_dirname=BitcoindComparisonTool_jar
+$(package)_install_filename=BitcoindComparisonTool.jar
+
+define $(package)_extract_cmds
+endef
+
+define $(package)_configure_cmds
+endef
+
+define $(package)_build_cmds
+endef
+
+define $(package)_stage_cmds
+ mkdir -p $($(package)_staging_prefix_dir)/share/$($(package)_install_dirname) && \
+ cp $($(package)_source) $($(package)_staging_prefix_dir)/share/$($(package)_install_dirname)/$($(package)_install_filename)
+endef
diff --git a/depends/packages/native_libdmg-hfsplus.mk b/depends/packages/native_libdmg-hfsplus.mk
new file mode 100644
index 0000000000..a4ffb6046c
--- /dev/null
+++ b/depends/packages/native_libdmg-hfsplus.mk
@@ -0,0 +1,22 @@
+package=native_libdmg-hfsplus
+$(package)_version=0.1
+$(package)_download_path=https://github.com/theuni/libdmg-hfsplus/archive
+$(package)_file_name=libdmg-hfsplus-v$($(package)_version).tar.gz
+$(package)_sha256_hash=6569a02eb31c2827080d7d59001869ea14484c281efab0ae7f2b86af5c3120b3
+$(package)_build_subdir=build
+
+define $(package)_preprocess_cmds
+ mkdir build
+endef
+
+define $(package)_config_cmds
+ cmake -DCMAKE_INSTALL_PREFIX:PATH=$(build_prefix)/bin ..
+endef
+
+define $(package)_build_cmds
+ $(MAKE) -C dmg
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) DESTDIR=$($(package)_staging_dir) -C dmg install
+endef
diff --git a/depends/packages/native_protobuf.mk b/depends/packages/native_protobuf.mk
new file mode 100644
index 0000000000..ed1a771f0d
--- /dev/null
+++ b/depends/packages/native_protobuf.mk
@@ -0,0 +1,25 @@
+package=native_protobuf
+$(package)_version=2.5.0
+$(package)_download_path=https://protobuf.googlecode.com/files
+$(package)_file_name=protobuf-$($(package)_version).tar.bz2
+$(package)_sha256_hash=13bfc5ae543cf3aa180ac2485c0bc89495e3ae711fc6fab4f8ffe90dfb4bb677
+
+define $(package)_set_vars
+$(package)_config_opts=--disable-shared
+endef
+
+define $(package)_config_cmds
+ $($(package)_autoconf)
+endef
+
+define $(package)_build_cmds
+ $(MAKE) -C src protoc
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) -C src DESTDIR=$($(package)_staging_dir) install-strip
+endef
+
+define $(package)_postprocess_cmds
+ rm -rf lib include
+endef
diff --git a/depends/packages/openssl.mk b/depends/packages/openssl.mk
new file mode 100644
index 0000000000..687aae6682
--- /dev/null
+++ b/depends/packages/openssl.mk
@@ -0,0 +1,44 @@
+package=openssl
+$(package)_version=1.0.1k
+$(package)_download_path=https://www.openssl.org/source
+$(package)_file_name=$(package)-$($(package)_version).tar.gz
+$(package)_sha256_hash=8f9faeaebad088e772f4ef5e38252d472be4d878c6b3a2718c10a4fcebe7a41c
+
+define $(package)_set_vars
+$(package)_config_env=AR="$($(package)_ar)" RANLIB="$($(package)_ranlib)" CC="$($(package)_cc)"
+$(package)_config_opts=--prefix=$(host_prefix) --openssldir=$(host_prefix)/etc/openssl no-zlib no-shared no-dso
+$(package)_config_opts+=no-krb5 no-camellia no-capieng no-cast no-cms no-dtls1 no-gost no-gmp no-heartbeats no-idea no-jpake no-md2
+$(package)_config_opts+=no-mdc2 no-rc5 no-rdrand no-rfc3779 no-rsax no-sctp no-seed no-sha0 no-static_engine no-whirlpool no-rc2 no-rc4 no-ssl2 no-ssl3
+$(package)_config_opts+=$($(package)_cflags) $($(package)_cppflags)
+$(package)_config_opts_linux=-fPIC -Wa,--noexecstack
+$(package)_config_opts_x86_64_linux=linux-x86_64
+$(package)_config_opts_i686_linux=linux-generic32
+$(package)_config_opts_arm_linux=linux-generic32
+$(package)_config_opts_aarch64_linux=linux-generic64
+$(package)_config_opts_mipsel_linux=linux-generic32
+$(package)_config_opts_mips_linux=linux-generic32
+$(package)_config_opts_x86_64_darwin=darwin64-x86_64-cc
+$(package)_config_opts_x86_64_mingw32=mingw64
+$(package)_config_opts_i686_mingw32=mingw
+endef
+
+define $(package)_preprocess_cmds
+ sed -i.old "/define DATE/d" util/mkbuildinf.pl && \
+ sed -i.old "s|engines apps test|engines|" Makefile.org
+endef
+
+define $(package)_config_cmds
+ ./Configure $($(package)_config_opts)
+endef
+
+define $(package)_build_cmds
+ $(MAKE) -j1 build_libs libcrypto.pc libssl.pc openssl.pc
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) INSTALL_PREFIX=$($(package)_staging_dir) -j1 install_sw
+endef
+
+define $(package)_postprocess_cmds
+ rm -rf share bin etc
+endef
diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk
new file mode 100644
index 0000000000..03908aba59
--- /dev/null
+++ b/depends/packages/packages.mk
@@ -0,0 +1,18 @@
+packages:=boost openssl
+native_packages := native_ccache native_comparisontool
+
+qt_native_packages = native_protobuf
+qt_packages = qrencode protobuf
+
+qt_linux_packages= qt expat dbus libxcb xcb_proto libXau xproto freetype fontconfig libX11 xextproto libXext xtrans
+qt_darwin_packages=qt
+qt_mingw32_packages=qt
+
+
+wallet_packages=bdb
+
+upnp_packages=miniupnpc
+
+ifneq ($(build_os),darwin)
+darwin_native_packages=native_cctools native_cdrkit native_libdmg-hfsplus
+endif
diff --git a/depends/packages/protobuf.mk b/depends/packages/protobuf.mk
new file mode 100644
index 0000000000..5affad2837
--- /dev/null
+++ b/depends/packages/protobuf.mk
@@ -0,0 +1,28 @@
+package=protobuf
+$(package)_version=$(native_$(package)_version)
+$(package)_download_path=$(native_$(package)_download_path)
+$(package)_file_name=$(native_$(package)_file_name)
+$(package)_sha256_hash=$(native_$(package)_sha256_hash)
+$(package)_dependencies=native_$(package)
+
+define $(package)_set_vars
+ $(package)_config_opts=--disable-shared --with-protoc=$(build_prefix)/bin/protoc
+ $(package)_config_opts_linux=--with-pic
+endef
+
+define $(package)_config_cmds
+ $($(package)_autoconf)
+endef
+
+define $(package)_build_cmds
+ $(MAKE) -C src libprotobuf.la
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) DESTDIR=$($(package)_staging_dir) -C src install-libLTLIBRARIES install-nobase_includeHEADERS &&\
+ $(MAKE) DESTDIR=$($(package)_staging_dir) install-pkgconfigDATA
+endef
+
+define $(package)_postprocess_cmds
+ rm lib/libprotoc.a
+endef
diff --git a/depends/packages/qrencode.mk b/depends/packages/qrencode.mk
new file mode 100644
index 0000000000..1ad329e94d
--- /dev/null
+++ b/depends/packages/qrencode.mk
@@ -0,0 +1,22 @@
+package=qrencode
+$(package)_version=3.4.3
+$(package)_download_path=https://fukuchi.org/works/qrencode/
+$(package)_file_name=qrencode-$(qrencode_version).tar.bz2
+$(package)_sha256_hash=dfd71487513c871bad485806bfd1fdb304dedc84d2b01a8fb8e0940b50597a98
+
+define $(package)_set_vars
+$(package)_config_opts=--disable-shared -without-tools --disable-sdltest
+$(package)_config_opts_linux=--with-pic
+endef
+
+define $(package)_config_cmds
+ $($(package)_autoconf)
+endef
+
+define $(package)_build_cmds
+ $(MAKE)
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) DESTDIR=$($(package)_staging_dir) install
+endef
diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk
new file mode 100644
index 0000000000..cba2fbd151
--- /dev/null
+++ b/depends/packages/qt.mk
@@ -0,0 +1,174 @@
+PACKAGE=qt
+$(package)_version=5.5.0
+$(package)_download_path=http://download.qt.io/official_releases/qt/5.5/$($(package)_version)/submodules
+$(package)_suffix=opensource-src-$($(package)_version).tar.gz
+$(package)_file_name=qtbase-$($(package)_suffix)
+$(package)_sha256_hash=7e82b1318f88e56a2a9376e069aa608d4fd96b48cb0e1b880ae658b0a1af0561
+$(package)_dependencies=openssl
+$(package)_linux_dependencies=freetype fontconfig dbus libxcb libX11 xproto libXext
+$(package)_build_subdir=qtbase
+$(package)_qt_libs=corelib network widgets gui plugins testlib
+$(package)_patches=mac-qmake.conf fix-xcb-include-order.patch mingw-uuidof.patch
+
+$(package)_qttranslations_file_name=qttranslations-$($(package)_suffix)
+$(package)_qttranslations_sha256_hash=c4bd6db6e426965c6f8824c54e81f68bbd61e2bae1bcadc328c6e81c45902a0d
+
+$(package)_qttools_file_name=qttools-$($(package)_suffix)
+$(package)_qttools_sha256_hash=d9e06bd19ecc86afba5e95d45a906d1bc1ad579aa70001e36143c1aaf695bdd6
+
+$(package)_extra_sources = $($(package)_qttranslations_file_name)
+$(package)_extra_sources += $($(package)_qttools_file_name)
+
+define $(package)_set_vars
+$(package)_config_opts_release = -release
+$(package)_config_opts_debug = -debug
+$(package)_config_opts += -opensource -confirm-license
+$(package)_config_opts += -no-audio-backend
+$(package)_config_opts += -no-glib
+$(package)_config_opts += -no-icu
+$(package)_config_opts += -no-cups
+$(package)_config_opts += -no-iconv
+$(package)_config_opts += -no-gif
+$(package)_config_opts += -no-freetype
+$(package)_config_opts += -no-nis
+$(package)_config_opts += -no-pch
+$(package)_config_opts += -no-qml-debug
+$(package)_config_opts += -nomake examples
+$(package)_config_opts += -nomake tests
+$(package)_config_opts += -no-feature-style-windowsmobile
+$(package)_config_opts += -no-feature-style-windowsce
+$(package)_config_opts += -no-sql-db2
+$(package)_config_opts += -no-sql-ibase
+$(package)_config_opts += -no-sql-oci
+$(package)_config_opts += -no-sql-tds
+$(package)_config_opts += -no-sql-mysql
+$(package)_config_opts += -no-sql-odbc
+$(package)_config_opts += -no-sql-psql
+$(package)_config_opts += -no-sql-sqlite
+$(package)_config_opts += -no-sql-sqlite2
+$(package)_config_opts += -prefix $(host_prefix)
+$(package)_config_opts += -hostprefix $(build_prefix)
+$(package)_config_opts += -bindir $(build_prefix)/bin
+$(package)_config_opts += -no-c++11
+$(package)_config_opts += -openssl-linked
+$(package)_config_opts += -v
+$(package)_config_opts += -static
+$(package)_config_opts += -silent
+$(package)_config_opts += -pkg-config
+$(package)_config_opts += -qt-libpng
+$(package)_config_opts += -qt-libjpeg
+$(package)_config_opts += -qt-zlib
+$(package)_config_opts += -qt-pcre
+$(package)_config_opts += -no-pulseaudio
+$(package)_config_opts += -no-openvg
+$(package)_config_opts += -no-xrender
+$(package)_config_opts += -no-alsa
+$(package)_config_opts += -no-mtdev
+$(package)_config_opts += -no-gstreamer
+$(package)_config_opts += -no-mitshm
+$(package)_config_opts += -no-kms
+$(package)_config_opts += -no-reduce-relocations
+$(package)_config_opts += -no-egl
+$(package)_config_opts += -no-eglfs
+$(package)_config_opts += -no-linuxfb
+$(package)_config_opts += -no-xinput2
+$(package)_config_opts += -no-libudev
+$(package)_config_opts += -no-use-gold-linker
+$(package)_config_opts += -reduce-exports
+$(package)_config_opts += -optimized-qmake
+
+ifneq ($(build_os),darwin)
+$(package)_config_opts_darwin = -xplatform macx-clang-linux
+$(package)_config_opts_darwin += -device-option MAC_SDK_PATH=$(OSX_SDK)
+$(package)_config_opts_darwin += -device-option MAC_SDK_VERSION=$(OSX_SDK_VERSION)
+$(package)_config_opts_darwin += -device-option CROSS_COMPILE="$(host)-"
+$(package)_config_opts_darwin += -device-option MAC_MIN_VERSION=$(OSX_MIN_VERSION)
+$(package)_config_opts_darwin += -device-option MAC_TARGET=$(host)
+$(package)_config_opts_darwin += -device-option MAC_LD64_VERSION=$(LD64_VERSION)
+endif
+
+$(package)_config_opts_linux = -qt-xkbcommon
+$(package)_config_opts_linux += -qt-xcb
+$(package)_config_opts_linux += -system-freetype
+$(package)_config_opts_linux += -no-sm
+$(package)_config_opts_linux += -fontconfig
+$(package)_config_opts_linux += -no-opengl
+$(package)_config_opts_arm_linux = -platform linux-g++ -xplatform $(host)
+$(package)_config_opts_i686_linux = -xplatform linux-g++-32
+$(package)_config_opts_mingw32 = -no-opengl -xplatform win32-g++ -device-option CROSS_COMPILE="$(host)-"
+$(package)_build_env = QT_RCC_TEST=1
+endef
+
+define $(package)_fetch_cmds
+$(call fetch_file,$(package),$($(package)_download_path),$($(package)_download_file),$($(package)_file_name),$($(package)_sha256_hash)) && \
+$(call fetch_file,$(package),$($(package)_download_path),$($(package)_qttranslations_file_name),$($(package)_qttranslations_file_name),$($(package)_qttranslations_sha256_hash)) && \
+$(call fetch_file,$(package),$($(package)_download_path),$($(package)_qttools_file_name),$($(package)_qttools_file_name),$($(package)_qttools_sha256_hash))
+endef
+
+define $(package)_extract_cmds
+ mkdir -p $($(package)_extract_dir) && \
+ echo "$($(package)_sha256_hash) $($(package)_source)" > $($(package)_extract_dir)/.$($(package)_file_name).hash && \
+ echo "$($(package)_qttranslations_sha256_hash) $($(package)_source_dir)/$($(package)_qttranslations_file_name)" > $($(package)_extract_dir)/.$($(package)_file_name).hash && \
+ echo "$($(package)_qttools_sha256_hash) $($(package)_source_dir)/$($(package)_qttools_file_name)" > $($(package)_extract_dir)/.$($(package)_file_name).hash && \
+ $(build_SHA256SUM) -c $($(package)_extract_dir)/.$($(package)_file_name).hash && \
+ mkdir qtbase && \
+ tar --strip-components=1 -xf $($(package)_source) -C qtbase && \
+ mkdir qttranslations && \
+ tar --strip-components=1 -xf $($(package)_source_dir)/$($(package)_qttranslations_file_name) -C qttranslations && \
+ mkdir qttools && \
+ tar --strip-components=1 -xf $($(package)_source_dir)/$($(package)_qttools_file_name) -C qttools
+endef
+
+define $(package)_preprocess_cmds
+ sed -i.old "s|updateqm.commands = \$$$$\$$$$LRELEASE|updateqm.commands = $($(package)_extract_dir)/qttools/bin/lrelease|" qttranslations/translations/translations.pro && \
+ sed -i.old "s/src_plugins.depends = src_sql src_xml src_network/src_plugins.depends = src_xml src_network/" qtbase/src/src.pro && \
+ sed -i.old "s/PIDLIST_ABSOLUTE/ITEMIDLIST */" qtbase/src/plugins/platforms/windows/qwindowscontext.h &&\
+ sed -i.old "s/PIDLIST_ABSOLUTE/ITEMIDLIST */" qtbase/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp &&\
+ sed -i.old "s/PCIDLIST_ABSOLUTE/const ITEMIDLIST */" qtbase/src/plugins/platforms/windows/qwindowscontext.h &&\
+ sed -i.old "s|X11/extensions/XIproto.h|X11/X.h|" qtbase/src/plugins/platforms/xcb/qxcbxsettings.cpp && \
+ sed -i.old 's/if \[ "$$$$XPLATFORM_MAC" = "yes" \]; then xspecvals=$$$$(macSDKify/if \[ "$$$$BUILD_ON_MAC" = "yes" \]; then xspecvals=$$$$(macSDKify/' qtbase/configure && \
+ mkdir -p qtbase/mkspecs/macx-clang-linux &&\
+ cp -f qtbase/mkspecs/macx-clang/Info.plist.lib qtbase/mkspecs/macx-clang-linux/ &&\
+ cp -f qtbase/mkspecs/macx-clang/Info.plist.app qtbase/mkspecs/macx-clang-linux/ &&\
+ cp -f qtbase/mkspecs/macx-clang/qplatformdefs.h qtbase/mkspecs/macx-clang-linux/ &&\
+ cp -f $($(package)_patch_dir)/mac-qmake.conf qtbase/mkspecs/macx-clang-linux/qmake.conf && \
+ patch -p1 < $($(package)_patch_dir)/fix-xcb-include-order.patch && \
+ patch -p1 < $($(package)_patch_dir)/mingw-uuidof.patch && \
+ echo "QMAKE_CFLAGS += $($(package)_cflags) $($(package)_cppflags)" >> qtbase/mkspecs/common/gcc-base.conf && \
+ echo "QMAKE_CXXFLAGS += $($(package)_cxxflags) $($(package)_cppflags)" >> qtbase/mkspecs/common/gcc-base.conf && \
+ echo "QMAKE_LFLAGS += $($(package)_ldflags)" >> qtbase/mkspecs/common/gcc-base.conf && \
+ sed -i.old "s|QMAKE_CFLAGS = |QMAKE_CFLAGS = $($(package)_cflags) $($(package)_cppflags) |" qtbase/mkspecs/win32-g++/qmake.conf && \
+ sed -i.old "s|QMAKE_LFLAGS = |QMAKE_LFLAGS = $($(package)_ldflags) |" qtbase/mkspecs/win32-g++/qmake.conf && \
+ sed -i.old "s|QMAKE_CXXFLAGS = |QMAKE_CXXFLAGS = $($(package)_cxxflags) $($(package)_cppflags) |" qtbase/mkspecs/win32-g++/qmake.conf
+endef
+
+define $(package)_config_cmds
+ export PKG_CONFIG_SYSROOT_DIR=/ && \
+ export PKG_CONFIG_LIBDIR=$(host_prefix)/lib/pkgconfig && \
+ export PKG_CONFIG_PATH=$(host_prefix)/share/pkgconfig && \
+ ./configure $($(package)_config_opts) && \
+ $(MAKE) sub-src-clean && \
+ cd ../qttranslations && ../qtbase/bin/qmake qttranslations.pro -o Makefile && \
+ cd translations && ../../qtbase/bin/qmake translations.pro -o Makefile && cd ../.. &&\
+ cd qttools/src/linguist/lrelease/ && ../../../../qtbase/bin/qmake lrelease.pro -o Makefile
+endef
+
+define $(package)_build_cmds
+ $(MAKE) -C src $(addprefix sub-,$($(package)_qt_libs)) && \
+ $(MAKE) -C ../qttools/src/linguist/lrelease && \
+ $(MAKE) -C ../qttranslations
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) -C src INSTALL_ROOT=$($(package)_staging_dir) $(addsuffix -install_subtargets,$(addprefix sub-,$($(package)_qt_libs))) && cd .. &&\
+ $(MAKE) -C qttools/src/linguist/lrelease INSTALL_ROOT=$($(package)_staging_dir) install_target && \
+ $(MAKE) -C qttranslations INSTALL_ROOT=$($(package)_staging_dir) install_subtargets && \
+ if `test -f qtbase/src/plugins/platforms/xcb/xcb-static/libxcb-static.a`; then \
+ cp qtbase/src/plugins/platforms/xcb/xcb-static/libxcb-static.a $($(package)_staging_prefix_dir)/lib; \
+ fi
+endef
+
+define $(package)_postprocess_cmds
+ rm -rf native/mkspecs/ native/lib/ lib/cmake/ && \
+ rm -f lib/lib*.la lib/*.prl plugins/*/*.prl
+endef
diff --git a/depends/packages/qt46.mk b/depends/packages/qt46.mk
new file mode 100644
index 0000000000..8fb30a5c44
--- /dev/null
+++ b/depends/packages/qt46.mk
@@ -0,0 +1,66 @@
+PACKAGE=qt46
+$(package)_version=4.6.4
+$(package)_download_path=http://download.qt-project.org/archive/qt/4.6/
+$(package)_file_name=qt-everywhere-opensource-src-$($(package)_version).tar.gz
+$(package)_sha256_hash=9ad4d46c721b53a429ed5a2eecfd3c239a9ab566562f183f99d3125f1a234250
+$(package)_dependencies=openssl freetype dbus libX11 xproto libXext libICE libSM
+$(package)_patches=stlfix.patch
+
+define $(package)_set_vars
+$(package)_config_opts = -prefix $(host_prefix) -headerdir $(host_prefix)/include/qt4 -bindir $(build_prefix)/bin
+$(package)_config_opts += -release -no-separate-debug-info -opensource -confirm-license
+$(package)_config_opts += -stl -qt-zlib
+
+$(package)_config_opts += -nomake examples -nomake tests -nomake tools -nomake translations -nomake demos -nomake docs
+$(package)_config_opts += -no-audio-backend -no-glib -no-nis -no-cups -no-iconv -no-gif -no-pch
+$(package)_config_opts += -no-xkb -no-xrender -no-xrandr -no-xfixes -no-xcursor -no-xinerama -no-xsync -no-xinput -no-mitshm -no-xshape
+$(package)_config_opts += -no-libtiff -no-fontconfig -openssl-linked
+$(package)_config_opts += -no-sql-db2 -no-sql-ibase -no-sql-oci -no-sql-tds -no-sql-mysql
+$(package)_config_opts += -no-sql-odbc -no-sql-psql -no-sql-sqlite -no-sql-sqlite2
+$(package)_config_opts += -no-xmlpatterns -no-multimedia -no-phonon -no-scripttools -no-declarative
+$(package)_config_opts += -no-phonon-backend -no-webkit -no-javascript-jit -no-script
+$(package)_config_opts += -no-svg -no-libjpeg -no-libtiff -no-libpng -no-libmng -no-qt3support -no-opengl
+
+$(package)_config_opts_x86_64_linux += -platform linux-g++-64
+$(package)_config_opts_i686_linux = -platform linux-g++-32
+$(package)_build_env = QT_RCC_TEST=1
+endef
+
+define $(package)_preprocess_cmds
+ sed -i.old "s|/include /usr/include||" config.tests/unix/freetype/freetype.pri && \
+ sed -i.old "s|src_plugins.depends = src_gui src_sql src_svg|src_plugins.depends = src_gui src_sql|" src/src.pro && \
+ sed -i.old "s|\.lower(|\.toLower(|g" src/network/ssl/qsslsocket_openssl.cpp && \
+ sed -i.old "s|Key_BackSpace|Key_Backspace|" src/gui/itemviews/qabstractitemview.cpp && \
+ sed -i.old "s|/usr/X11R6/lib64|$(host_prefix)/lib|" mkspecs/*/*.conf && \
+ sed -i.old "s|/usr/X11R6/lib|$(host_prefix)/lib|" mkspecs/*/*.conf && \
+ sed -i.old "s|/usr/X11R6/include|$(host_prefix)/include|" mkspecs/*/*.conf && \
+ sed -i.old "s|QMAKE_LFLAGS_SHLIB\t+= -shared|QMAKE_LFLAGS_SHLIB\t+= -shared -Wl,--exclude-libs,ALL|" mkspecs/common/g++.conf && \
+ sed -i.old "/SSLv2_client_method/d" src/network/ssl/qsslsocket_openssl.cpp src/network/ssl/qsslsocket_openssl_symbols.cpp && \
+ sed -i.old "/SSLv2_server_method/d" src/network/ssl/qsslsocket_openssl.cpp src/network/ssl/qsslsocket_openssl_symbols.cpp && \
+ patch -p1 < $($(package)_patch_dir)/stlfix.patch
+endef
+
+define $(package)_config_cmds
+ export PKG_CONFIG_SYSROOT_DIR=/ && \
+ export PKG_CONFIG_LIBDIR=$(host_prefix)/lib/pkgconfig && \
+ export PKG_CONFIG_PATH=$(host_prefix)/share/pkgconfig && \
+ export CPATH=$(host_prefix)/include && \
+ OPENSSL_LIBS='-L$(host_prefix)/lib -lssl -lcrypto' ./configure $($(package)_config_opts) && \
+ cd tools/linguist/lrelease; ../../../bin/qmake -o Makefile lrelease.pro
+endef
+
+define $(package)_build_cmds
+ export CPATH=$(host_prefix)/include && \
+ $(MAKE) -C src && \
+ $(MAKE) -C tools/linguist/lrelease
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) -C src INSTALL_ROOT=$($(package)_staging_dir) install && \
+ $(MAKE) -C tools/linguist/lrelease INSTALL_ROOT=$($(package)_staging_dir) install
+endef
+
+define $(package)_postprocess_cmds
+ rm -rf mkspecs/ lib/cmake/ lib/*.prl lib/*.la && \
+ find native/bin -type f -exec mv {} {}-qt4 \;
+endef
diff --git a/depends/packages/xcb_proto.mk b/depends/packages/xcb_proto.mk
new file mode 100644
index 0000000000..0c7c958d62
--- /dev/null
+++ b/depends/packages/xcb_proto.mk
@@ -0,0 +1,27 @@
+package=xcb_proto
+$(package)_version=1.10
+$(package)_download_path=http://xcb.freedesktop.org/dist
+$(package)_file_name=xcb-proto-$($(package)_version).tar.bz2
+$(package)_sha256_hash=7ef40ddd855b750bc597d2a435da21e55e502a0fefa85b274f2c922800baaf05
+
+define $(package)_set_vars
+ $(package)_config_opts=--disable-shared
+ $(package)_config_opts_linux=--with-pic
+endef
+
+define $(package)_config_cmds
+ $($(package)_autoconf)
+endef
+
+define $(package)_build_cmds
+ $(MAKE)
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) DESTDIR=$($(package)_staging_dir) install
+endef
+
+define $(package)_postprocess_cmds
+ find -name "*.pyc" -delete && \
+ find -name "*.pyo" -delete
+endef
diff --git a/depends/packages/xextproto.mk b/depends/packages/xextproto.mk
new file mode 100644
index 0000000000..98a11eb497
--- /dev/null
+++ b/depends/packages/xextproto.mk
@@ -0,0 +1,21 @@
+package=xextproto
+$(package)_version=7.3.0
+$(package)_download_path=http://xorg.freedesktop.org/releases/individual/proto
+$(package)_file_name=$(package)-$($(package)_version).tar.bz2
+$(package)_sha256_hash=f3f4b23ac8db9c3a9e0d8edb591713f3d70ef9c3b175970dd8823dfc92aa5bb0
+
+define $(package)_set_vars
+$(package)_config_opts=--disable-shared
+endef
+
+define $(package)_config_cmds
+ $($(package)_autoconf)
+endef
+
+define $(package)_build_cmds
+ $(MAKE)
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) DESTDIR=$($(package)_staging_dir) install
+endef
diff --git a/depends/packages/xproto.mk b/depends/packages/xproto.mk
new file mode 100644
index 0000000000..50a90b2685
--- /dev/null
+++ b/depends/packages/xproto.mk
@@ -0,0 +1,21 @@
+package=xproto
+$(package)_version=7.0.26
+$(package)_download_path=http://xorg.freedesktop.org/releases/individual/proto
+$(package)_file_name=$(package)-$($(package)_version).tar.bz2
+$(package)_sha256_hash=636162c1759805a5a0114a369dffdeccb8af8c859ef6e1445f26a4e6e046514f
+
+define $(package)_set_vars
+$(package)_config_opts=--disable-shared
+endef
+
+define $(package)_config_cmds
+ $($(package)_autoconf)
+endef
+
+define $(package)_build_cmds
+ $(MAKE)
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) DESTDIR=$($(package)_staging_dir) install
+endef
diff --git a/depends/packages/xtrans.mk b/depends/packages/xtrans.mk
new file mode 100644
index 0000000000..99eefa6d5e
--- /dev/null
+++ b/depends/packages/xtrans.mk
@@ -0,0 +1,22 @@
+package=xtrans
+$(package)_version=1.3.4
+$(package)_download_path=http://xorg.freedesktop.org/releases/individual/lib/
+$(package)_file_name=$(package)-$($(package)_version).tar.bz2
+$(package)_sha256_hash=054d4ee3efd52508c753e9f7bc655ef185a29bd2850dd9e2fc2ccc33544f583a
+$(package)_dependencies=
+
+define $(package)_set_vars
+$(package)_config_opts_linux=--with-pic --disable-static
+endef
+
+define $(package)_config_cmds
+ $($(package)_autoconf)
+endef
+
+define $(package)_build_cmds
+ $(MAKE)
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) DESTDIR=$($(package)_staging_dir) install
+endef
diff --git a/depends/patches/boost/darwin_boost_atomic-1.patch b/depends/patches/boost/darwin_boost_atomic-1.patch
new file mode 100644
index 0000000000..97f59cb7e4
--- /dev/null
+++ b/depends/patches/boost/darwin_boost_atomic-1.patch
@@ -0,0 +1,35 @@
+diff --git a/include/boost/atomic/detail/cas128strong.hpp b/include/boost/atomic/detail/cas128strong.hpp
+index 906c13e..dcb4d7d 100644
+--- a/include/boost/atomic/detail/cas128strong.hpp
++++ b/include/boost/atomic/detail/cas128strong.hpp
+@@ -196,15 +196,17 @@ class base_atomic<T, void, 16, Sign>
+
+ public:
+ BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
+- explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0)
++ explicit base_atomic(value_type const& v) BOOST_NOEXCEPT
+ {
++ memset(&v_, 0, sizeof(v_));
+ memcpy(&v_, &v, sizeof(value_type));
+ }
+
+ void
+ store(value_type const& value, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+ {
+- storage_type value_s = 0;
++ storage_type value_s;
++ memset(&value_s, 0, sizeof(value_s));
+ memcpy(&value_s, &value, sizeof(value_type));
+ platform_fence_before_store(order);
+ platform_store128(value_s, &v_);
+@@ -247,7 +249,9 @@ class base_atomic<T, void, 16, Sign>
+ memory_order success_order,
+ memory_order failure_order) volatile BOOST_NOEXCEPT
+ {
+- storage_type expected_s = 0, desired_s = 0;
++ storage_type expected_s, desired_s;
++ memset(&expected_s, 0, sizeof(expected_s));
++ memset(&desired_s, 0, sizeof(desired_s));
+ memcpy(&expected_s, &expected, sizeof(value_type));
+ memcpy(&desired_s, &desired, sizeof(value_type));
+
diff --git a/depends/patches/boost/darwin_boost_atomic-2.patch b/depends/patches/boost/darwin_boost_atomic-2.patch
new file mode 100644
index 0000000000..ca50765200
--- /dev/null
+++ b/depends/patches/boost/darwin_boost_atomic-2.patch
@@ -0,0 +1,55 @@
+diff --git a/include/boost/atomic/detail/gcc-atomic.hpp b/include/boost/atomic/detail/gcc-atomic.hpp
+index a130590..4af99a1 100644
+--- a/include/boost/atomic/detail/gcc-atomic.hpp
++++ b/include/boost/atomic/detail/gcc-atomic.hpp
+@@ -958,14 +958,16 @@ class base_atomic<T, void, 16, Sign>
+
+ public:
+ BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
+- explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0)
++ explicit base_atomic(value_type const& v) BOOST_NOEXCEPT
+ {
++ memset(&v_, 0, sizeof(v_));
+ memcpy(&v_, &v, sizeof(value_type));
+ }
+
+ void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+ {
+- storage_type tmp = 0;
++ storage_type tmp;
++ memset(&tmp, 0, sizeof(tmp));
+ memcpy(&tmp, &v, sizeof(value_type));
+ __atomic_store_n(&v_, tmp, atomics::detail::convert_memory_order_to_gcc(order));
+ }
+@@ -980,7 +982,8 @@ class base_atomic<T, void, 16, Sign>
+
+ value_type exchange(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+ {
+- storage_type tmp = 0;
++ storage_type tmp;
++ memset(&tmp, 0, sizeof(tmp));
+ memcpy(&tmp, &v, sizeof(value_type));
+ tmp = __atomic_exchange_n(&v_, tmp, atomics::detail::convert_memory_order_to_gcc(order));
+ value_type res;
+@@ -994,7 +997,9 @@ class base_atomic<T, void, 16, Sign>
+ memory_order success_order,
+ memory_order failure_order) volatile BOOST_NOEXCEPT
+ {
+- storage_type expected_s = 0, desired_s = 0;
++ storage_type expected_s, desired_s;
++ memset(&expected_s, 0, sizeof(expected_s));
++ memset(&desired_s, 0, sizeof(desired_s));
+ memcpy(&expected_s, &expected, sizeof(value_type));
+ memcpy(&desired_s, &desired, sizeof(value_type));
+ const bool success = __atomic_compare_exchange_n(&v_, &expected_s, desired_s, false,
+@@ -1010,7 +1015,9 @@ class base_atomic<T, void, 16, Sign>
+ memory_order success_order,
+ memory_order failure_order) volatile BOOST_NOEXCEPT
+ {
+- storage_type expected_s = 0, desired_s = 0;
++ storage_type expected_s, desired_s;
++ memset(&expected_s, 0, sizeof(expected_s));
++ memset(&desired_s, 0, sizeof(desired_s));
+ memcpy(&expected_s, &expected, sizeof(value_type));
+ memcpy(&desired_s, &desired, sizeof(value_type));
+ const bool success = __atomic_compare_exchange_n(&v_, &expected_s, desired_s, true,
diff --git a/depends/patches/boost/gcc_5_no_cxx11.patch b/depends/patches/boost/gcc_5_no_cxx11.patch
new file mode 100644
index 0000000000..04514c593a
--- /dev/null
+++ b/depends/patches/boost/gcc_5_no_cxx11.patch
@@ -0,0 +1,37 @@
+From eec808554936ae068b23df07ab54d4dc6302a695 Mon Sep 17 00:00:00 2001
+From: jzmaddock <jzmaddock@gmail.com>
+Date: Sat, 23 Aug 2014 09:38:02 +0100
+Subject: [PATCH] Fix BOOST_NO_CXX11_VARIADIC_TEMPLATES definition - the
+ feature was introduced in GCC 4.4.
+
+---
+ include/boost/config/compiler/gcc.hpp | 9 +--------
+ 1 file changed, 1 insertion(+), 8 deletions(-)
+
+diff --git a/include/boost/config/compiler/gcc.hpp b/include/boost/config/compiler/gcc.hpp
+index f37159d..97d8a18 100644
+--- a/include/boost/config/compiler/gcc.hpp
++++ b/include/boost/config/compiler/gcc.hpp
+@@ -154,14 +154,6 @@
+ # define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS
+ # define BOOST_NO_CXX11_RVALUE_REFERENCES
+ # define BOOST_NO_CXX11_STATIC_ASSERT
+-
+-// Variadic templates compiler:
+-// http://www.generic-programming.org/~dgregor/cpp/variadic-templates.html
+-# if defined(__VARIADIC_TEMPLATES) || (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4) && defined(__GXX_EXPERIMENTAL_CXX0X__))
+-# define BOOST_HAS_VARIADIC_TMPL
+-# else
+-# define BOOST_NO_CXX11_VARIADIC_TEMPLATES
+-# endif
+ #endif
+
+ // C++0x features in 4.4.n and later
+@@ -176,6 +168,7 @@
+ # define BOOST_NO_CXX11_DELETED_FUNCTIONS
+ # define BOOST_NO_CXX11_TRAILING_RESULT_TYPES
+ # define BOOST_NO_CXX11_INLINE_NAMESPACES
++# define BOOST_NO_CXX11_VARIADIC_TEMPLATES
+ #endif
+
+ #if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5)
diff --git a/depends/patches/native_cdrkit/cdrkit-deterministic.patch b/depends/patches/native_cdrkit/cdrkit-deterministic.patch
new file mode 100644
index 0000000000..8ab0993dc4
--- /dev/null
+++ b/depends/patches/native_cdrkit/cdrkit-deterministic.patch
@@ -0,0 +1,86 @@
+--- cdrkit-1.1.11.old/genisoimage/tree.c 2008-10-21 19:57:47.000000000 -0400
++++ cdrkit-1.1.11/genisoimage/tree.c 2013-12-06 00:23:18.489622668 -0500
+@@ -1139,8 +1139,9 @@
+ scan_directory_tree(struct directory *this_dir, char *path,
+ struct directory_entry *de)
+ {
+- DIR *current_dir;
++ int current_file;
+ char whole_path[PATH_MAX];
++ struct dirent **d_list;
+ struct dirent *d_entry;
+ struct directory *parent;
+ int dflag;
+@@ -1164,7 +1165,8 @@
+ this_dir->dir_flags |= DIR_WAS_SCANNED;
+
+ errno = 0; /* Paranoia */
+- current_dir = opendir(path);
++ //current_dir = opendir(path);
++ current_file = scandir(path, &d_list, NULL, alphasort);
+ d_entry = NULL;
+
+ /*
+@@ -1173,12 +1175,12 @@
+ */
+ old_path = path;
+
+- if (current_dir) {
++ if (current_file >= 0) {
+ errno = 0;
+- d_entry = readdir(current_dir);
++ d_entry = d_list[0];
+ }
+
+- if (!current_dir || !d_entry) {
++ if (current_file < 0 || !d_entry) {
+ int ret = 1;
+
+ #ifdef USE_LIBSCHILY
+@@ -1191,8 +1193,8 @@
+ de->isorec.flags[0] &= ~ISO_DIRECTORY;
+ ret = 0;
+ }
+- if (current_dir)
+- closedir(current_dir);
++ if(d_list)
++ free(d_list);
+ return (ret);
+ }
+ #ifdef ABORT_DEEP_ISO_ONLY
+@@ -1208,7 +1210,7 @@
+ errmsgno(EX_BAD, "use Rock Ridge extensions via -R or -r,\n");
+ errmsgno(EX_BAD, "or allow deep ISO9660 directory nesting via -D.\n");
+ }
+- closedir(current_dir);
++ free(d_list);
+ return (1);
+ }
+ #endif
+@@ -1250,13 +1252,13 @@
+ * The first time through, skip this, since we already asked
+ * for the first entry when we opened the directory.
+ */
+- if (dflag)
+- d_entry = readdir(current_dir);
++ if (dflag && current_file >= 0)
++ d_entry = d_list[current_file];
+ dflag++;
+
+- if (!d_entry)
++ if (current_file < 0)
+ break;
+-
++ current_file--;
+ /* OK, got a valid entry */
+
+ /* If we do not want all files, then pitch the backups. */
+@@ -1348,7 +1350,7 @@
+ insert_file_entry(this_dir, whole_path, d_entry->d_name);
+ #endif /* APPLE_HYB */
+ }
+- closedir(current_dir);
++ free(d_list);
+
+ #ifdef APPLE_HYB
+ /*
diff --git a/depends/patches/qt/fix-xcb-include-order.patch b/depends/patches/qt/fix-xcb-include-order.patch
new file mode 100644
index 0000000000..ae469ea94b
--- /dev/null
+++ b/depends/patches/qt/fix-xcb-include-order.patch
@@ -0,0 +1,45 @@
+--- old/qtbase/src/plugins/platforms/xcb/xcb_qpa_lib.pro 2015-03-17 02:06:42.705930685 +0000
++++ new/qtbase/src/plugins/platforms/xcb/xcb_qpa_lib.pro 2015-03-17 02:08:41.281926351 +0000
+@@ -94,8 +94,6 @@
+
+ DEFINES += $$QMAKE_DEFINES_XCB
+ LIBS += $$QMAKE_LIBS_XCB
+-QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_XCB
+-QMAKE_CFLAGS += $$QMAKE_CFLAGS_XCB
+
+ CONFIG += qpa/genericunixfontdatabase
+
+@@ -104,7 +102,8 @@
+ contains(QT_CONFIG, xcb-qt) {
+ DEFINES += XCB_USE_RENDER
+ XCB_DIR = ../../../3rdparty/xcb
+- INCLUDEPATH += $$XCB_DIR/include $$XCB_DIR/sysinclude
++ QMAKE_CFLAGS += -I$$XCB_DIR/include -I$$XCB_DIR/sysinclude $$QMAKE_CFLAGS_XCB
++ QMAKE_CXXFLAGS += -I$$XCB_DIR/include -I$$XCB_DIR/sysinclude $$QMAKE_CFLAGS_XCB
+ LIBS += -lxcb -L$$OUT_PWD/xcb-static -lxcb-static
+ } else {
+ LIBS += -lxcb -lxcb-image -lxcb-icccm -lxcb-sync -lxcb-xfixes -lxcb-shm -lxcb-randr -lxcb-shape -lxcb-keysyms
+--- old/qtbase/src/plugins/platforms/xcb/xcb-static/xcb-static.pro 2015-03-17 02:07:04.641929383 +0000
++++ new/qtbase/src/plugins/platforms/xcb/xcb-static/xcb-static.pro 2015-03-17 02:10:15.485922059 +0000
+@@ -8,7 +8,8 @@
+
+ XCB_DIR = ../../../../3rdparty/xcb
+
+-INCLUDEPATH += $$XCB_DIR/include $$XCB_DIR/include/xcb $$XCB_DIR/sysinclude
++QMAKE_CFLAGS += -I$$XCB_DIR/include -I$$XCB_DIR/include/xcb -I$$XCB_DIR/sysinclude
++QMAKE_CXXFLAGS += -I$$XCB_DIR/include -I$$XCB_DIR/include/xcb -I$$XCB_DIR/sysinclude
+
+ QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_XCB
+ QMAKE_CFLAGS += $$QMAKE_CFLAGS_XCB
+--- old/qtbase/src/plugins/platforms/xcb/xcb-plugin.pro 2015-07-24 16:02:59.530038830 -0400
++++ new/qtbase/src/plugins/platforms/xcb/xcb-plugin.pro 2015-07-24 16:01:22.106037459 -0400
+@@ -11,3 +11,9 @@
+ qxcbmain.cpp
+ OTHER_FILES += xcb.json README
+
++contains(QT_CONFIG, xcb-qt) {
++ DEFINES += XCB_USE_RENDER
++ XCB_DIR = ../../../3rdparty/xcb
++ QMAKE_CFLAGS += -I$$XCB_DIR/include -I$$XCB_DIR/sysinclude $$QMAKE_CFLAGS_XCB
++ QMAKE_CXXFLAGS += -I$$XCB_DIR/include -I$$XCB_DIR/sysinclude $$QMAKE_CFLAGS_XCB
++}
diff --git a/depends/patches/qt/mac-qmake.conf b/depends/patches/qt/mac-qmake.conf
new file mode 100644
index 0000000000..a6d0070cca
--- /dev/null
+++ b/depends/patches/qt/mac-qmake.conf
@@ -0,0 +1,26 @@
+MAKEFILE_GENERATOR = UNIX
+CONFIG += app_bundle incremental global_init_link_order lib_version_first plugin_no_soname absolute_library_soname
+DEFINES += QT_NO_PRINTER QT_NO_PRINTDIALOG
+QMAKE_INCREMENTAL_STYLE = sublib
+include(../common/macx.conf)
+include(../common/gcc-base-mac.conf)
+include(../common/clang.conf)
+include(../common/clang-mac.conf)
+QMAKE_MAC_SDK_PATH=$${MAC_SDK_PATH}
+QMAKE_XCODE_VERSION=4.3
+QMAKE_XCODE_DEVELOPER_PATH=/Developer
+QMAKE_MACOSX_DEPLOYMENT_TARGET = $${MAC_MIN_VERSION}
+QMAKE_MAC_SDK=macosx
+QMAKE_MAC_SDK.macosx.path = $${MAC_SDK_PATH}
+QMAKE_MAC_SDK.macosx.platform_name = macosx
+QMAKE_MAC_SDK.macosx.version = $${MAC_SDK_VERSION}
+QMAKE_MAC_SDK.macosx.platform_path = /phony
+QMAKE_CFLAGS += -target $${MAC_TARGET}
+QMAKE_OBJECTIVE_CFLAGS += $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS += $$QMAKE_CFLAGS
+QMAKE_LFLAGS += -target $${MAC_TARGET} -mlinker-version=$${MAC_LD64_VERSION}
+QMAKE_AR = $${CROSS_COMPILE}ar cq
+QMAKE_RANLIB=$${CROSS_COMPILE}ranlib
+QMAKE_LIBTOOL=$${CROSS_COMPILE}libtool
+QMAKE_INSTALL_NAME_TOOL=$${CROSS_COMPILE}install_name_tool
+load(qt_config)
diff --git a/depends/patches/qt/mingw-uuidof.patch b/depends/patches/qt/mingw-uuidof.patch
new file mode 100644
index 0000000000..975366e612
--- /dev/null
+++ b/depends/patches/qt/mingw-uuidof.patch
@@ -0,0 +1,44 @@
+--- old/qtbase/src/plugins/platforms/windows/qwindowscontext.cpp 2015-06-20 17:40:20.956781548 -0400
++++ new/qtbase/src/plugins/platforms/windows/qwindowscontext.cpp 2015-06-20 17:29:32.052772416 -0400
+@@ -69,7 +69,7 @@
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <windowsx.h>
+-#ifndef Q_OS_WINCE
++#if !defined(Q_OS_WINCE) && (!defined(USE___UUIDOF) || (defined(USE___UUIDOF) && USE___UUIDOF == 1))
+ # include <comdef.h>
+ #endif
+
+@@ -762,7 +762,7 @@
+ HWND_MESSAGE, NULL, (HINSTANCE)GetModuleHandle(0), NULL);
+ }
+
+-#ifndef Q_OS_WINCE
++#if !defined(Q_OS_WINCE) && (!defined(USE___UUIDOF) || (defined(USE___UUIDOF) && USE___UUIDOF == 1))
+ // Re-engineered from the inline function _com_error::ErrorMessage().
+ // We cannot use it directly since it uses swprintf_s(), which is not
+ // present in the MSVCRT.DLL found on Windows XP (QTBUG-35617).
+@@ -781,7 +781,7 @@
+ return QStringLiteral("IDispatch error #") + QString::number(wCode);
+ return QStringLiteral("Unknown error 0x0") + QString::number(comError.Error(), 16);
+ }
+-#endif // !Q_OS_WINCE
++#endif // !defined(Q_OS_WINCE) && (!defined(USE___UUIDOF) || (defined(USE___UUIDOF) && USE___UUIDOF == 1))
+
+ /*!
+ \brief Common COM error strings.
+@@ -846,12 +846,12 @@
+ default:
+ break;
+ }
+-#ifndef Q_OS_WINCE
++#if !defined(Q_OS_WINCE) && (!defined(USE___UUIDOF) || (defined(USE___UUIDOF) && USE___UUIDOF == 1))
+ _com_error error(hr);
+ result += QByteArrayLiteral(" (");
+ result += errorMessageFromComError(error);
+ result += ')';
+-#endif // !Q_OS_WINCE
++#endif // !defined(Q_OS_WINCE) && (!defined(USE___UUIDOF) || (defined(USE___UUIDOF) && USE___UUIDOF == 1))
+ return result;
+ }
+
diff --git a/depends/patches/qt46/stlfix.patch b/depends/patches/qt46/stlfix.patch
new file mode 100644
index 0000000000..f8f6fb04b0
--- /dev/null
+++ b/depends/patches/qt46/stlfix.patch
@@ -0,0 +1,10 @@
+--- old/config.tests/unix/stl/stltest.cpp 2011-06-23 03:45:23.000000000 -0400
++++ new/config.tests/unix/stl/stltest.cpp 2014-08-28 00:54:04.154837604 -0400
+@@ -49,6 +49,7 @@
+ #include <vector>
+ #include <algorithm>
+ #include <iostream>
++#include <cstddef>
+
+ // something mean to see if the compiler and C++ standard lib are good enough
+ template<class K, class T>
diff --git a/doc/Doxyfile b/doc/Doxyfile
new file mode 100644
index 0000000000..af89338ff2
--- /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.11.1
+
+# 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 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 <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> 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 = src/leveldb src/json src/test /src/qt/test
+
+# 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 = boost google
+
+# 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 <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> 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
+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">
+# Qt Help Project / Custom Filters</a>.
+
+QHP_CUST_FILTER_ATTRS =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's
+# filter section matches.
+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">
+# Qt Help Project / Filter Attributes</a>.
+
+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 = YES
+
+# 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 = YES
+
+# 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 = YES
+
+# 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 = svg
+
+# 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.md b/doc/README.md
new file mode 100644
index 0000000000..60636dee61
--- /dev/null
+++ b/doc/README.md
@@ -0,0 +1,78 @@
+Bitcoin Core 0.11.1
+=====================
+
+Setup
+---------------------
+[Bitcoin Core](http://bitcoin.org/en/download) is the original Bitcoin client and it builds the backbone of the network. However, it downloads and stores the entire history of Bitcoin transactions (which is currently several GBs); depending on the speed of your computer and network connection, the synchronization process can take anywhere from a few hours to a day or more.
+
+Running
+---------------------
+The following are some helpful notes on how to run Bitcoin on your native platform.
+
+### Unix
+
+You need the Qt4 run-time libraries to run Bitcoin-Qt. On Debian or Ubuntu:
+
+ sudo apt-get install libqtgui4
+
+Unpack the files into a directory and run:
+
+- bin/32/bitcoin-qt (GUI, 32-bit) or bin/32/bitcoind (headless, 32-bit)
+- bin/64/bitcoin-qt (GUI, 64-bit) or bin/64/bitcoind (headless, 64-bit)
+
+
+
+### Windows
+
+Unpack the files into a directory, and then run bitcoin-qt.exe.
+
+### OSX
+
+Drag Bitcoin-Qt to your applications folder, and then run Bitcoin-Qt.
+
+### Need Help?
+
+* See the documentation at the [Bitcoin Wiki](https://en.bitcoin.it/wiki/Main_Page)
+for help and more information.
+* Ask for help on [#bitcoin](http://webchat.freenode.net?channels=bitcoin) on Freenode. If you don't have an IRC client use [webchat here](http://webchat.freenode.net?channels=bitcoin).
+* Ask for help on the [BitcoinTalk](https://bitcointalk.org/) forums, in the [Technical Support board](https://bitcointalk.org/index.php?board=4.0).
+
+Building
+---------------------
+The following are developer notes on how to build Bitcoin on your native platform. They are not complete guides, but include notes on the necessary libraries, compile flags, etc.
+
+- [OSX Build Notes](build-osx.md)
+- [Unix Build Notes](build-unix.md)
+- [Gitian Building Guide](gitian-building.md)
+
+Development
+---------------------
+The Bitcoin repo's [root README](https://github.com/bitcoin/bitcoin/blob/master/README.md) contains relevant information on the development process and automated testing.
+
+- [Developer Notes](developer-notes.md)
+- [Multiwallet Qt Development](multiwallet-qt.md)
+- [Release Notes](release-notes.md)
+- [Release Process](release-process.md)
+- [Source Code Documentation (External Link)](https://dev.visucore.com/bitcoin/doxygen/)
+- [Translation Process](translation_process.md)
+- [Translation Strings Policy](translation_strings_policy.md)
+- [Unit Tests](unit-tests.md)
+- [Unauthenticated REST Interface](REST-interface.md)
+- [BIPS](bips.md)
+- [Dnsseed Policy](dnsseed-policy.md)
+
+### Resources
+* Discuss on the [BitcoinTalk](https://bitcointalk.org/) forums, in the [Development & Technical Discussion board](https://bitcointalk.org/index.php?board=6.0).
+* Discuss on [#bitcoin-dev](http://webchat.freenode.net/?channels=bitcoin) on Freenode. If you don't have an IRC client use [webchat here](http://webchat.freenode.net/?channels=bitcoin-dev).
+
+### Miscellaneous
+- [Assets Attribution](assets-attribution.md)
+- [Files](files.md)
+- [Tor Support](tor.md)
+- [Init Scripts (systemd/upstart/openrc)](init.md)
+
+License
+---------------------
+Distributed under the [MIT software license](http://www.opensource.org/licenses/mit-license.php).
+This product includes software developed by the OpenSSL Project for use in the [OpenSSL Toolkit](https://www.openssl.org/). This product includes
+cryptographic software written by Eric Young ([eay@cryptsoft.com](mailto:eay@cryptsoft.com)), and UPnP software written by Thomas Bernard.
diff --git a/doc/README_osx.txt b/doc/README_osx.txt
new file mode 100644
index 0000000000..a572c7a241
--- /dev/null
+++ b/doc/README_osx.txt
@@ -0,0 +1,83 @@
+Deterministic OSX Dmg Notes.
+
+Working OSX DMGs are created in Linux by combining a recent clang,
+the Apple's binutils (ld, ar, etc), and DMG authoring tools.
+
+Apple uses clang extensively for development and has upstreamed the necessary
+functionality so that a vanilla clang can take advantage. It supports the use
+of -F, -target, -mmacosx-version-min, and --sysroot, which are all necessary
+when building for OSX. A pre-compiled version of 3.2 is used because it was not
+available in the Precise repositories at the time this work was started. In the
+future, it can be switched to use system packages instead.
+
+Apple's version of binutils (called cctools) contains lots of functionality
+missing in the FSF's binutils. In addition to extra linker options for
+frameworks and sysroots, several other tools are needed as well such as
+install_name_tool, lipo, and nmedit. These do not build under linux, so they
+have been patched to do so. The work here was used as a starting point:
+https://github.com/mingwandroid/toolchain4
+
+In order to build a working toolchain, the following source packages are needed
+from Apple: cctools, dyld, and ld64.
+
+These tools inject timestamps by default, which produce non-deterministic
+binaries. The ZERO_AR_DATE environment variable is used to disable that.
+
+This version of cctools has been patched to use the current version of clang's
+headers and and its libLTO.so rather than those from llvmgcc, as it was
+originally done in toolchain4.
+
+To complicate things further, all builds must target an Apple SDK. These SDKs
+are free to download, but not redistributable.
+To obtain it, register for a developer account, then download the XCode 6.1.1 dmg:
+https://developer.apple.com/devcenter/download.action?path=/Developer_Tools/xcode_6.1.1/xcode_6.1.1.dmg
+
+This file is several gigabytes in size, but only a single directory inside is
+needed: Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk
+
+Unfortunately, the usual linux tools (7zip, hpmount, loopback mount) are incapable of opening this file.
+To create a tarball suitable for gitian input, mount the dmg in OSX, then create it with:
+ $ tar -C /Volumes/Xcode/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/ -czf MacOSX10.9.sdk.tar.gz MacOSX10.9.sdk
+
+
+The gitian descriptors build 2 sets of files: Linux tools, then Apple binaries
+which are created using these tools. The build process has been designed to
+avoid including the SDK's files in Gitian's outputs. All interim tarballs are
+fully deterministic and may be freely redistributed.
+
+genisoimage is used to create the initial DMG. It is not deterministic as-is,
+so it has been patched. A system genisoimage will work fine, but it will not
+be deterministic because the file-order will change between invocations.
+The patch can be seen here:
+https://raw.githubusercontent.com/theuni/osx-cross-depends/master/patches/cdrtools/genisoimage.diff
+No effort was made to fix this cleanly, so it likely leaks memory badly. But
+it's only used for a single invocation, so that's no real concern.
+
+genisoimage cannot compress DMGs, so afterwards, the 'dmg' tool from the
+libdmg-hfsplus project is used to compress it. There are several bugs in this
+tool and its maintainer has seemingly abandoned the project. It has been forked
+and is available (with fixes) here: https://github.com/theuni/libdmg-hfsplus .
+
+The 'dmg' tool has the ability to create DMGs from scratch as well, but this
+functionality is broken. Only the compression feature is currently used.
+Ideally, the creation could be fixed and genisoimage would no longer be necessary.
+
+Background images and other features can be added to DMG files by inserting a
+.DS_Store before creation. The easiest way to create this file is to build a
+DMG without one, move it to a device running OSX, customize the layout, then
+grab the .DS_Store file for later use. That is the approach taken here.
+
+As of OSX Mavericks (10.9), using an Apple-blessed key to sign binaries is a
+requirement in order to satisfy the new Gatekeeper requirements. Because this
+private key cannot be shared, we'll have to be a bit creative in order for the
+build process to remain somewhat deterministic. Here's how it works:
+
+- Builders use gitian to create an unsigned release. This outputs an unsigned
+ dmg which users may choose to bless and run. It also outputs an unsigned app
+ structure in the form of a tarball, which also contains all of the tools
+ that have been previously (deterministically) built in order to create a
+ final dmg.
+- The Apple keyholder uses this unsigned app to create a detached signature,
+ using the script that is also included there.
+- Builders feed the unsigned app + detached signature back into gitian. It
+ uses the pre-built tools to recombine the pieces into a deterministic dmg.
diff --git a/doc/README_windows.txt b/doc/README_windows.txt
new file mode 100644
index 0000000000..9c26cad08d
--- /dev/null
+++ b/doc/README_windows.txt
@@ -0,0 +1,23 @@
+Bitcoin Core 0.11.1
+=====================
+
+Intro
+-----
+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.
+
+
+Setup
+-----
+Unpack the files into a directory and run bitcoin-qt.exe.
+
+Bitcoin Core is the original Bitcoin client and it builds the backbone of the network.
+However, it downloads and stores the entire history of Bitcoin transactions;
+depending on the speed of your computer and network connection, the synchronization
+process can take anywhere from a few hours to a day or more.
+
+See the bitcoin wiki at:
+ https://en.bitcoin.it/wiki/Main_Page
+for more help and information.
diff --git a/doc/REST-interface.md b/doc/REST-interface.md
new file mode 100644
index 0000000000..7bb6e8821c
--- /dev/null
+++ b/doc/REST-interface.md
@@ -0,0 +1,81 @@
+Unauthenticated REST Interface
+==============================
+
+The REST API can be enabled with the `-rest` option.
+
+Supported API
+-------------
+
+####Transactions
+`GET /rest/tx/<TX-HASH>.<bin|hex|json>`
+
+Given a transaction hash: returns a transaction in binary, hex-encoded binary, or JSON formats.
+
+For full TX query capability, one must enable the transaction index via "txindex=1" command line / configuration option.
+
+####Blocks
+`GET /rest/block/<BLOCK-HASH>.<bin|hex|json>`
+`GET /rest/block/notxdetails/<BLOCK-HASH>.<bin|hex|json>`
+
+Given a block hash: returns a block, in binary, hex-encoded binary or JSON formats.
+
+The HTTP request and response are both handled entirely in-memory, thus making maximum memory usage at least 2.66MB (1 MB max block, plus hex encoding) per request.
+
+With the /notxdetails/ option JSON response will only contain the transaction hash instead of the complete transaction details. The option only affects the JSON response.
+
+####Blockheaders
+`GET /rest/headers/<COUNT>/<BLOCK-HASH>.<bin|hex>`
+
+Given a block hash: returns <COUNT> amount of blockheaders in upward direction.
+
+JSON is not supported.
+
+####Chaininfos
+`GET /rest/chaininfo.json`
+
+Returns various state info regarding block chain processing.
+Only supports JSON as output format.
+* chain : (string) current network name as defined in BIP70 (main, test, regtest)
+* blocks : (numeric) the current number of blocks processed in the server
+* headers : (numeric) the current number of headers we have validated
+* bestblockhash : (string) the hash of the currently best block
+* difficulty : (numeric) the current difficulty
+* verificationprogress : (numeric) estimate of verification progress [0..1]
+* chainwork : (string) total amount of work in active chain, in hexadecimal
+
+####Query UTXO set
+`GET /rest/getutxos/<checkmempool>/<txid>-<n>/<txid>-<n>/.../<txid>-<n>.<bin|hex|json>`
+
+The getutxo command allows querying of the UTXO set given a set of outpoints.
+See BIP64 for input and output serialisation:
+https://github.com/bitcoin/bips/blob/master/bip-0064.mediawiki
+
+Example:
+```
+$ curl localhost:18332/rest/getutxos/checkmempool/b2cdfd7b89def827ff8af7cd9bff7627ff72e5e8b0f71210f92ea7a4000c5d75-0.json 2>/dev/null | json_pp
+{
+ "chaintipHash" : "00000000fb01a7f3745a717f8caebee056c484e6e0bfe4a9591c235bb70506fb",
+ "chainHeight" : 325347,
+ "utxos" : [
+ {
+ "scriptPubKey" : {
+ "addresses" : [
+ "mi7as51dvLJsizWnTMurtRmrP8hG2m1XvD"
+ ],
+ "type" : "pubkeyhash",
+ "hex" : "76a9141c7cebb529b86a04c683dfa87be49de35bcf589e88ac",
+ "reqSigs" : 1,
+ "asm" : "OP_DUP OP_HASH160 1c7cebb529b86a04c683dfa87be49de35bcf589e OP_EQUALVERIFY OP_CHECKSIG"
+ },
+ "value" : 8.8687,
+ "height" : 2147483647,
+ "txvers" : 1
+ }
+ ],
+ "bitmap" : "1"
+}
+```
+
+Risks
+-------------
+Running a web browser on the same node with a REST enabled bitcoind can be a risk. Accessing prepared XSS websites could read out tx/block data of your node by placing links like `<script src="http://127.0.0.1:8332/rest/tx/1234567890.json">` which might break the nodes privacy.
diff --git a/doc/assets-attribution.md b/doc/assets-attribution.md
new file mode 100644
index 0000000000..c6da1a4586
--- /dev/null
+++ b/doc/assets-attribution.md
@@ -0,0 +1,46 @@
+The following is a list of assets used in the bitcoin source and their proper attribution.
+
+[Typicons/Stephen Hutchings](http://typicons.com)
+-----------------------
+
+### Info
+* Icon Pack: Typicons (http://typicons.com)
+* Designer: Stephen Hutchings (and more)
+* License: MIT
+* Site: [https://github.com/stephenhutchings/typicons.font](https://github.com/stephenhutchings/typicons.font)
+
+### Assets Used
+ src/qt/res/icons/add.png, src/qt/res/icons/address-book.png,
+ src/qt/res/icons/configure.png, src/qt/res/icons/connect4.png,
+ src/qt/res/icons/debugwindow.png, src/qt/res/icons/edit.png,
+ src/qt/res/icons/exitcopy.png, src/qt/res/icons/editpaste.png,
+ src/qt/res/icons/export.png, src/qt/res/icons/eye.png,
+ src/qt/res/icons/filesave.png, src/qt/res/icons/history.png,
+ src/qt/res/icons/info.png, src/qt/res/icons/key.png,
+ src/qt/res/icons/lock_*.png, src/qt/res/icons/open.png,
+ src/qt/res/icons/overview.png, src/qt/res/icons/quit.png,
+ src/qt/res/icons/receive.png, src/qt/res/icons/remove.png,
+ src/qt/res/icons/send.png, src/qt/res/icons/synced.png,
+ src/qt/res/icons/transaction*.png, src/qt/res/icons/tx_output.png,
+ src/qt/res/icons/warning.png
+
+Jonas Schnelli
+-----------------------
+
+### Info
+* Designer: Jonas Schnelli
+* Bitcoin Icon: (based on the original bitcoin logo from Bitboy)
+* Some icons are based on Stephan Hutchings Typicons
+* License: MIT
+
+### Assets Used
+ src/qt/res/icons/about.png, src/qt/res/icons/about_qt.png,
+ src/qt/res/icons/bitcoin.icns, src/qt/res/icons/bitcoin.ico,
+ src/qt/res/icons/bitcoin.png, src/qt/res/icons/clock*.png,
+ src/qt/res/icons/connect[0-3].png, src/qt/res/icons/eye_minus.png,
+ src/qt/res/icons/eye_plus.png, src/qt/res/icons/verify.png,
+ src/qt/res/icons/tx_inout.png, src/qt/res/icons/tx_input.png,
+ src/qt/res/src/verify.svg, src/qt/res/src/bitcoin.svg,
+ src/qt/res/src/clock*.svg, src/qt/res/src/connect*.svg,
+ src/qt/res/src/mine.svg, src/qt/res/src/qt.svg, src/qt/res/src/tx*.svg,
+ src/qt/res/src/verify.svg,
diff --git a/doc/bips.md b/doc/bips.md
new file mode 100644
index 0000000000..90e98ed419
--- /dev/null
+++ b/doc/bips.md
@@ -0,0 +1,18 @@
+BIPs that are implemented by Bitcoin Core (up-to-date up to **v0.10.0**):
+
+* [`BIP 11`](https://github.com/bitcoin/bips/blob/master/bip-0011.mediawiki): Multisig outputs are standard since **v0.6.0** ([PR #669](https://github.com/bitcoin/bitcoin/pull/669)).
+* [`BIP 13`](https://github.com/bitcoin/bips/blob/master/bip-0013.mediawiki): The address format for P2SH addresses has been implemented since **v0.6.0** ([PR #669](https://github.com/bitcoin/bitcoin/pull/669)).
+* [`BIP 14`](https://github.com/bitcoin/bips/blob/master/bip-0014.mediawiki): The subversion string is being used as User Agent since **v0.6.0** ([PR #669](https://github.com/bitcoin/bitcoin/pull/669)).
+* [`BIP 16`](https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki): The pay-to-script-hash evaluation rules have been implemented since **v0.6.0**, and took effect on *April 1st 2012* ([PR #748](https://github.com/bitcoin/bitcoin/pull/748)).
+* [`BIP 21`](https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki): The URI format for Bitcoin payments has been implemented since **v0.6.0** ([PR #176](https://github.com/bitcoin/bitcoin/pull/176)).
+* [`BIP 22`](https://github.com/bitcoin/bips/blob/master/bip-0022.mediawiki): The 'getblocktemplate' (GBT) RPC protocol for mining has been implemented since **v0.7.0** ([PR #936](https://github.com/bitcoin/bitcoin/pull/936)).
+* [`BIP 23`](https://github.com/bitcoin/bips/blob/master/bip-0023.mediawiki): Some extensions to GBT have been implemented since **v0.10.0rc1**, including longpolling and block proposals ([PR #1816](https://github.com/bitcoin/bitcoin/pull/1816)).
+* [`BIP 30`](https://github.com/bitcoin/bips/blob/master/bip-0030.mediawiki): The evaluation rules to forbid creating new transactions with the same txid as previous not-fully-spent transactions were implemented since **v0.6.0**, and the rule took effect on *March 15th 2012* ([PR #915](https://github.com/bitcoin/bitcoin/pull/915)).
+* [`BIP 31`](https://github.com/bitcoin/bips/blob/master/bip-0031.mediawiki): The 'pong' protocol message (and the protocol version bump to 60001) has been implemented since **v0.6.1** ([PR #1081](https://github.com/bitcoin/bitcoin/pull/1081)).
+* [`BIP 34`](https://github.com/bitcoin/bips/blob/master/bip-0034.mediawiki): The rule that requires blocks to contain their height (number) in the coinbase input, and the introduction of version 2 blocks has been implemented since **v0.7.0**. The rule took effect for version 2 blocks as of *block 224413* (March 5th 2013), and version 1 blocks are no longer allowed since *block 227931* (March 25th 2013) ([PR #1526](https://github.com/bitcoin/bitcoin/pull/1526)).
+* [`BIP 35`](https://github.com/bitcoin/bips/blob/master/bip-0035.mediawiki): The 'mempool' protocol message (and the protocol version bump to 60002) has been implemented since **v0.7.0** ([PR #1641](https://github.com/bitcoin/bitcoin/pull/1641)).
+* [`BIP 37`](https://github.com/bitcoin/bips/blob/master/bip-0037.mediawiki): The bloom filtering for transaction relaying, partial merkle trees for blocks, and the protocol version bump to 70001 (enabling low-bandwidth SPV clients) has been implemented since **v0.8.0** ([PR #1795](https://github.com/bitcoin/bitcoin/pull/1795)).
+* [`BIP 42`](https://github.com/bitcoin/bips/blob/master/bip-0042.mediawiki): The bug that would have caused the subsidy schedule to resume after block 13440000 was fixed in **v0.9.2** ([PR #3842](https://github.com/bitcoin/bitcoin/pull/3842)).
+* [`BIP 61`](https://github.com/bitcoin/bips/blob/master/bip-0061.mediawiki): The 'reject' protocol message (and the protocol version bump to 70002) was added in **v0.9.0** ([PR #3185](https://github.com/bitcoin/bitcoin/pull/3185)).
+* [`BIP 66`](https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki): The strict DER rules and associated version 3 blocks have been implemented since **v0.10.0** ([PR #5713](https://github.com/bitcoin/bitcoin/pull/5713)).
+* [`BIP 70`](https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki) [`71`](https://github.com/bitcoin/bips/blob/master/bip-0071.mediawiki) [`72`](https://github.com/bitcoin/bips/blob/master/bip-0072.mediawiki): Payment Protocol support has been available in Bitcoin Core GUI since **v0.9.0** ([PR #5216](https://github.com/bitcoin/bitcoin/pull/5216)).
diff --git a/doc/bitcoin_logo_doxygen.png b/doc/bitcoin_logo_doxygen.png
new file mode 100644
index 0000000000..258be86ede
--- /dev/null
+++ b/doc/bitcoin_logo_doxygen.png
Binary files differ
diff --git a/doc/build-osx.md b/doc/build-osx.md
new file mode 100644
index 0000000000..dc319dd1c4
--- /dev/null
+++ b/doc/build-osx.md
@@ -0,0 +1,117 @@
+Mac OS X Build Instructions and Notes
+====================================
+This guide will show you how to build bitcoind (headless client) for OSX.
+
+Notes
+-----
+
+* Tested on OS X 10.7 through 10.10 on 64-bit Intel processors only.
+
+* All of the commands should be executed in a Terminal application. The
+built-in one is located in `/Applications/Utilities`.
+
+Preparation
+-----------
+
+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 installation media, but if not, you can get the
+current version from https://developer.apple.com/xcode/. If you install
+Xcode 4.3 or later, you'll need to install its command line tools. This can
+be done in `Xcode > Preferences > Downloads > Components` and generally must
+be re-done or updated every time Xcode is updated.
+
+You will also need to install [Homebrew](http://brew.sh) in order to install library
+dependencies.
+
+The installation of the actual dependencies is covered in the Instructions
+sections below.
+
+Instructions: Homebrew
+----------------------
+
+#### Install dependencies using Homebrew
+
+ brew install autoconf automake berkeley-db4 libtool boost miniupnpc openssl pkg-config protobuf qt5
+
+NOTE: Building with Qt4 is still supported, however, could result in a broken UI. As such, building with Qt5 is recommended.
+
+### Building `bitcoind`
+
+1. Clone the github tree to get the source code and go into the directory.
+
+ git clone https://github.com/bitcoin/bitcoin.git
+ cd bitcoin
+
+2. Build bitcoind:
+
+ ./autogen.sh
+ ./configure --with-gui=qt5
+ make
+
+3. It is also a good idea to build and run the unit tests:
+
+ make check
+
+4. (Optional) You can also install bitcoind to your path:
+
+ make install
+
+Use Qt Creator as IDE
+------------------------
+You can use Qt Creator as IDE, for debugging and for manipulating forms, etc.
+Download Qt Creator from http://www.qt.io/download/. Download the "community edition" and only install Qt Creator (uncheck the rest during the installation process).
+
+1. Make sure you installed everything through homebrew mentioned above
+2. Do a proper ./configure --with-gui=qt5 --enable-debug
+3. In Qt Creator do "New Project" -> Import Project -> Import Existing Project
+4. Enter "bitcoin-qt" as project name, enter src/qt as location
+5. Leave the file selection as it is
+6. Confirm the "summary page"
+7. In the "Projects" tab select "Manage Kits..."
+8. Select the default "Desktop" kit and select "Clang (x86 64bit in /usr/bin)" as compiler
+9. Select LLDB as debugger (you might need to set the path to your installtion)
+10. Start debugging with Qt Creator
+
+Creating a release build
+------------------------
+You can ignore this section if you are building `bitcoind` for your own use.
+
+bitcoind/bitcoin-cli binaries are not included in the Bitcoin-Qt.app bundle.
+
+If you are building `bitcoind` or `Bitcoin-Qt` for others, your build machine should be set up
+as follows for maximum compatibility:
+
+All dependencies should be compiled with these flags:
+
+ -mmacosx-version-min=10.7
+ -arch x86_64
+ -isysroot $(xcode-select --print-path)/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk
+
+Once dependencies are compiled, see [doc/release-process.md](release-process.md) for how the Bitcoin-Qt.app
+bundle is packaged and signed to create the .dmg disk image that is distributed.
+
+Running
+-------
+
+It's now available at `./bitcoind`, provided that you are still in the `src`
+directory. We have to first create the RPC configuration file, though.
+
+Run `./bitcoind` to get the filename where it should be put, or just try these
+commands:
+
+ echo -e "rpcuser=bitcoinrpc\nrpcpassword=$(xxd -l 16 -p /dev/urandom)" > "/Users/${USER}/Library/Application Support/Bitcoin/bitcoin.conf"
+ chmod 600 "/Users/${USER}/Library/Application Support/Bitcoin/bitcoin.conf"
+
+The next time you run it, it will start downloading the blockchain, but it won't
+output anything while it's doing this. This process may take several hours;
+you can monitor its process by looking at the debug.log file, like this:
+
+ tail -f $HOME/Library/Application\ Support/Bitcoin/debug.log
+
+Other commands:
+-------
+
+ ./bitcoind -daemon # to start the bitcoin daemon.
+ ./bitcoin-cli --help # for a list of command-line options.
+ ./bitcoin-cli help # When the daemon is running, to get a list of RPC commands
diff --git a/doc/build-unix.md b/doc/build-unix.md
new file mode 100644
index 0000000000..92aed7725e
--- /dev/null
+++ b/doc/build-unix.md
@@ -0,0 +1,230 @@
+UNIX BUILD NOTES
+====================
+Some notes on how to build Bitcoin in Unix.
+
+Note
+---------------------
+Always use absolute paths to configure and compile bitcoin and the dependencies,
+for example, when specifying the the path of the dependency:
+
+ ../dist/configure --enable-cxx --disable-shared --with-pic --prefix=$BDB_PREFIX
+
+Here BDB_PREFIX must absolute path - it is defined using $(pwd) which ensures
+the usage of the absolute path.
+
+To Build
+---------------------
+
+```bash
+./autogen.sh
+./configure
+make
+make install # optional
+```
+
+This will build bitcoin-qt as well if the dependencies are met.
+
+Dependencies
+---------------------
+
+These dependencies are required:
+
+ Library | Purpose | Description
+ ------------|------------------|----------------------
+ libssl | SSL Support | Secure communications
+ libboost | Boost | C++ Library
+
+Optional dependencies:
+
+ Library | Purpose | Description
+ ------------|------------------|----------------------
+ miniupnpc | UPnP Support | Firewall-jumping support
+ libdb4.8 | Berkeley DB | Wallet storage (only needed when wallet enabled)
+ qt | GUI | GUI toolkit (only needed when GUI enabled)
+ protobuf | Payments in GUI | Data interchange format used for payment protocol (only needed when GUI enabled)
+ libqrencode | QR codes in GUI | Optional for generating QR codes (only needed when GUI enabled)
+
+For the versions used in the release, see [release-process.md](release-process.md) under *Fetch and build inputs*.
+
+System requirements
+--------------------
+
+C++ compilers are memory-hungry. It is recommended to have at least 1 GB of
+memory available when compiling Bitcoin Core. With 512MB of memory or less
+compilation will take much longer due to swap thrashing.
+
+Dependency Build Instructions: Ubuntu & Debian
+----------------------------------------------
+Build requirements:
+
+ sudo apt-get install build-essential libtool autotools-dev autoconf pkg-config libssl-dev
+
+For Ubuntu 12.04 and later or Debian 7 and later libboost-all-dev has to be installed:
+
+ sudo apt-get install libboost-all-dev
+
+ db4.8 packages are available [here](https://launchpad.net/~bitcoin/+archive/bitcoin).
+ You can add the repository using the following command:
+
+ sudo add-apt-repository ppa:bitcoin/bitcoin
+ sudo apt-get update
+
+ Ubuntu 12.04 and later have packages for libdb5.1-dev and libdb5.1++-dev,
+ but using these will break binary wallet compatibility, and is not recommended.
+
+For other Debian & Ubuntu (with ppa):
+
+ sudo apt-get install libdb4.8-dev libdb4.8++-dev
+
+Optional:
+
+ sudo apt-get install libminiupnpc-dev (see --with-miniupnpc and --enable-upnp-default)
+
+Dependencies for the GUI: Ubuntu & Debian
+-----------------------------------------
+
+If you want to build Bitcoin-Qt, make sure that the required packages for Qt development
+are installed. Either Qt 4 or Qt 5 are necessary to build the GUI.
+If both Qt 4 and Qt 5 are installed, Qt 4 will be used. Pass `--with-gui=qt5` to configure to choose Qt5.
+To build without GUI pass `--without-gui`.
+
+To build with Qt 4 you need the following:
+
+ sudo apt-get install libqt4-dev libprotobuf-dev protobuf-compiler
+
+For Qt 5 you need the following:
+
+ sudo apt-get install libqt5gui5 libqt5core5a libqt5dbus5 qttools5-dev qttools5-dev-tools libprotobuf-dev protobuf-compiler
+
+libqrencode (optional) can be installed with:
+
+ sudo apt-get install libqrencode-dev
+
+Once these are installed, they will be found by configure and a bitcoin-qt executable will be
+built by default.
+
+Notes
+-----
+The release is built with GCC and then "strip bitcoind" to strip the debug
+symbols, which reduces the executable size by about 90%.
+
+
+miniupnpc
+---------
+
+[miniupnpc](http://miniupnp.free.fr/) may be used for UPnP port mapping. It can be downloaded from [here](
+http://miniupnp.tuxfamily.org/files/). UPnP support is compiled in and
+turned off by default. See the configure options for upnp behavior desired:
+
+ --without-miniupnpc No UPnP support miniupnp not required
+ --disable-upnp-default (the default) UPnP support turned off by default at runtime
+ --enable-upnp-default UPnP support turned on by default at runtime
+
+To build:
+
+ tar -xzvf miniupnpc-1.6.tar.gz
+ cd miniupnpc-1.6
+ make
+ sudo su
+ make install
+
+
+Berkeley DB
+-----------
+It is recommended to use Berkeley DB 4.8. If you have to build it yourself:
+
+```bash
+BITCOIN_ROOT=$(pwd)
+
+# Pick some path to install BDB to, here we create a directory within the bitcoin directory
+BDB_PREFIX="${BITCOIN_ROOT}/db4"
+mkdir -p $BDB_PREFIX
+
+# Fetch the source and verify that it is not tampered with
+wget 'http://download.oracle.com/berkeley-db/db-4.8.30.NC.tar.gz'
+echo '12edc0df75bf9abd7f82f821795bcee50f42cb2e5f76a6a281b85732798364ef db-4.8.30.NC.tar.gz' | sha256sum -c
+# -> db-4.8.30.NC.tar.gz: OK
+tar -xzvf db-4.8.30.NC.tar.gz
+
+# Build the library and install to our prefix
+cd db-4.8.30.NC/build_unix/
+# Note: Do a static build so that it can be embedded into the executable, instead of having to find a .so at runtime
+../dist/configure --enable-cxx --disable-shared --with-pic --prefix=$BDB_PREFIX
+make install
+
+# Configure Bitcoin Core to use our own-built instance of BDB
+cd $BITCOIN_ROOT
+./configure (other args...) LDFLAGS="-L${BDB_PREFIX}/lib/" CPPFLAGS="-I${BDB_PREFIX}/include/"
+```
+
+**Note**: You only need Berkeley DB if the wallet is enabled (see the section *Disable-Wallet mode* below).
+
+Boost
+-----
+If you need to build Boost yourself:
+
+ sudo su
+ ./bootstrap.sh
+ ./bjam install
+
+
+Security
+--------
+To help make your bitcoin installation more secure by making certain attacks impossible to
+exploit even if a vulnerability is found, binaries are hardened by default.
+This can be disabled with:
+
+Hardening Flags:
+
+ ./configure --enable-hardening
+ ./configure --disable-hardening
+
+
+Hardening enables the following features:
+
+* Position Independent Executable
+ Build position independent code to take advantage of Address Space Layout Randomization
+ offered by some kernels. Attackers who can cause execution of code at an arbitrary memory
+ location are thwarted if they don'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 test that you have built PIE executable, install scanelf, part of paxutils, and use:
+
+ scanelf -e ./bitcoin
+
+ 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, bitcoin 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 ./bitcoin`
+
+ the output should contain:
+ STK/REL/PTL
+ RW- R-- RW-
+
+ The STK RW- means that the stack is readable and writeable but not executable.
+
+Disable-wallet mode
+--------------------
+When the intention is to run only a P2P node without a wallet, bitcoin may be compiled in
+disable-wallet mode with:
+
+ ./configure --disable-wallet
+
+In this case there is no dependency on Berkeley DB 4.8.
+
+Mining is also possible in disable-wallet mode, but only using the `getblocktemplate` RPC
+call not `getwork`.
+
diff --git a/doc/developer-notes.md b/doc/developer-notes.md
new file mode 100644
index 0000000000..8f7db31d59
--- /dev/null
+++ b/doc/developer-notes.md
@@ -0,0 +1,186 @@
+Coding
+====================
+
+Various coding styles have been used during the history of the codebase,
+and the result is not very consistent. However, we're now trying to converge to
+a single style, so please use it in new code. Old code will be converted
+gradually.
+- Basic rules specified in src/.clang-format. Use a recent clang-format-3.5 to format automatically.
+ - Braces on new lines for namespaces, classes, functions, methods.
+ - Braces on the same line for everything else.
+ - 4 space indentation (no tabs) for every block except namespaces.
+ - No indentation for public/protected/private or for namespaces.
+ - No extra spaces inside parenthesis; don't do ( this )
+ - No space after function names; one space after if, for and while.
+
+Block style example:
+```c++
+namespace foo
+{
+class Class
+{
+ 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;
+ }
+}
+}
+```
+
+Doxygen comments
+-----------------
+
+To facilitate the generation of documentation, use doxygen-compatible comment blocks for functions, methods and fields.
+
+For example, to describe a function use:
+```c++
+/**
+ * ... text ...
+ * @param[in] arg1 A description
+ * @param[in] arg2 Another argument description
+ * @pre Precondition for function...
+ */
+bool function(int arg1, const char *arg2)
+```
+A complete list of `@xxx` commands can be found at http://www.stack.nl/~dimitri/doxygen/manual/commands.html.
+As Doxygen recognizes the comments by the delimiters (`/**` and `*/` in this case), you don't
+*need* to provide any commands for a comment to be valid; just a description text is fine.
+
+To describe a class use the same construct above the class definition:
+```c++
+/**
+ * Alerts are for notifying old versions if they become too obsolete and
+ * need to upgrade. The message is displayed in the status bar.
+ * @see GetWarnings()
+ */
+class CAlert
+{
+```
+
+To describe a member or variable use:
+```c++
+int var; //!< Detailed description after the member
+```
+
+Also OK:
+```c++
+///
+/// ... text ...
+///
+bool function2(int arg1, const char *arg2)
+```
+
+Not OK (used plenty in the current source, but not picked up):
+```c++
+//
+// ... text ...
+//
+```
+
+A full list of comment syntaxes picked up by doxygen can be found at http://www.stack.nl/~dimitri/doxygen/manual/docblocks.html,
+but if possible use one of the above styles.
+
+Development tips and tricks
+---------------------------
+
+**compiling for debugging**
+
+Run configure with the --enable-debug option, then make. Or run configure with
+CXXFLAGS="-g -ggdb -O0" or whatever debug flags you need.
+
+**debug.log**
+
+If the code is behaving strangely, take a look in the debug.log file in the data directory;
+error and debugging messages are written there.
+
+The -debug=... command-line option controls debugging; running with just -debug will turn
+on all categories (and give you a very large debug.log file).
+
+The Qt code routes qDebug() output to debug.log under category "qt": run with -debug=qt
+to see it.
+
+**testnet and regtest modes**
+
+Run with the -testnet option to run with "play bitcoins" on the test network, if you
+are testing multi-machine code that needs to operate across the internet.
+
+If you are testing something that can run on one machine, run with the -regtest option.
+In regression test mode, blocks can be created on-demand; see qa/rpc-tests/ for tests
+that run in -regtest mode.
+
+**DEBUG_LOCKORDER**
+
+Bitcoin Core is a multithreaded application, and deadlocks or other multithreading bugs
+can be very difficult to track down. Compiling with -DDEBUG_LOCKORDER (configure
+CXXFLAGS="-DDEBUG_LOCKORDER -g") inserts run-time checks to keep track of which locks
+are held, and adds warnings to the debug.log file if inconsistencies are detected.
+
+Locking/mutex usage notes
+-------------------------
+
+The code is multi-threaded, and uses mutexes and the
+LOCK/TRY_LOCK 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
+-------
+
+- ThreadScriptCheck : Verifies block scripts.
+
+- ThreadImport : Loads blocks from blk*.dat files or bootstrap.dat.
+
+- StartNode : Starts other threads.
+
+- ThreadDNSAddressSeed : Loads addresses of peers from the DNS.
+
+- ThreadMapPort : Universal plug-and-play startup/shutdown
+
+- ThreadSocketHandler : Sends/Receives data from peers on port 8333.
+
+- ThreadOpenAddedConnections : Opens network connections to added nodes.
+
+- ThreadOpenConnections : Initiates new connections to peers.
+
+- ThreadMessageHandler : Higher-level message handling (sending and receiving).
+
+- DumpAddresses : Dumps IP addresses of nodes to peers.dat.
+
+- ThreadFlushWalletDB : Close the wallet.dat file if it hasn't been used in 500ms.
+
+- ThreadRPCServer : Remote procedure call handler, listens on port 8332 for connections and services them.
+
+- BitcoinMiner : Generates bitcoins (if wallet is enabled).
+
+- Shutdown : Does an orderly shutdown of everything.
+
+Pull Request Terminology
+------------------------
+
+Concept ACK - Agree with the idea and overall direction, but have neither reviewed nor tested the code changes.
+
+utACK (untested ACK) - Reviewed and agree with the code changes but haven't actually tested them.
+
+Tested ACK - Reviewed the code changes and have verified the functionality or bug fix.
+
+ACK - A loose ACK can be confusing. It's best to avoid them unless it's a documentation/comment only change in which case there is nothing to test/verify; therefore the tested/untested distinction is not there.
+
+NACK - Disagree with the code changes/concept. Should be accompanied by an explanation.
diff --git a/doc/dnsseed-policy.md b/doc/dnsseed-policy.md
new file mode 100644
index 0000000000..814ae3876a
--- /dev/null
+++ b/doc/dnsseed-policy.md
@@ -0,0 +1,54 @@
+Expectations for DNS Seed operators
+====================================
+
+Bitcoin Core attempts to minimize the level of trust in DNS seeds,
+but DNS seeds still pose a small amount of risk for the network.
+As such, DNS seeds must be run by entities which have some minimum
+level of trust within the Bitcoin community.
+
+Other implementations of Bitcoin software may also use the same
+seeds and may be more exposed. In light of this exposure, this
+document establishes some basic expectations for operating dnsseeds.
+
+0. A DNS seed operating organization or person is expected to follow good
+host security practices, maintain control of applicable infrastructure,
+and not sell or transfer control of the DNS seed. Any hosting services
+contracted by the operator are equally expected to uphold these expectations.
+
+1. The DNS seed results must consist exclusively of fairly selected and
+functioning Bitcoin nodes from the public network to the best of the
+operator's understanding and capability.
+
+2. For the avoidance of doubt, the results may be randomized but must not
+single-out any group of hosts to receive different results unless due to an
+urgent technical necessity and disclosed.
+
+3. The results may not be served with a DNS TTL of less than one minute.
+
+4. Any logging of DNS queries should be only that which is necessary
+for the operation of the service or urgent health of the Bitcoin
+network and must not be retained longer than necessary nor disclosed
+to any third party.
+
+5. Information gathered as a result of the operators node-spidering
+(not from DNS queries) may be freely published or retained, but only
+if this data was not made more complete by biasing node connectivity
+(a violation of expectation (1)).
+
+6. Operators are encouraged, but not required, to publicly document the
+details of their operating practices.
+
+7. A reachable email contact address must be published for inquiries
+related to the DNS seed operation.
+
+If these expectations cannot be satisfied the operator should
+discontinue providing services and contact the active Bitcoin
+Core development team as well as posting on
+[bitcoin-dev](https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev).
+
+Behavior outside of these expectations may be reasonable in some
+situations but should be discussed in public in advance.
+
+See also
+----------
+- [bitcoin-seeder](https://github.com/sipa/bitcoin-seeder) is a reference implementation of a DNS seed.
diff --git a/doc/files.md b/doc/files.md
new file mode 100644
index 0000000000..ec767e0486
--- /dev/null
+++ b/doc/files.md
@@ -0,0 +1,27 @@
+
+* bitcoin.conf: contains configuration settings for bitcoind or bitcoin-qt
+* bitcoind.pid: stores the process id of bitcoind while running
+* blocks/blk000??.dat: block data (custom, 128 MiB per file); since 0.8.0
+* blocks/rev000??.dat; block undo data (custom); since 0.8.0 (format changed since pre-0.8)
+* blocks/index/*; block index (LevelDB); since 0.8.0
+* chainstate/*; block chain state database (LevelDB); since 0.8.0
+* database/*: BDB database environment; only used for wallet since 0.8.0
+* db.log: wallet database log file
+* debug.log: contains debug information and general logging generated by bitcoind or bitcoin-qt
+* fee_estimates.dat: stores statistics used to estimate minimum transaction fees and priorities required for confirmation; since 0.10.0
+* peers.dat: peer IP address database (custom format); since 0.7.0
+* wallet.dat: personal wallet (BDB) with keys and transactions
+
+Only used in pre-0.8.0
+---------------------
+* blktree/*; block chain index (LevelDB); since pre-0.8, replaced by blocks/index/* in 0.8.0
+* coins/*; unspent transaction output database (LevelDB); since pre-0.8, replaced by chainstate/* in 0.8.0
+
+Only used before 0.8.0
+---------------------
+* blkindex.dat: block chain index database (BDB); replaced by {chainstate/*,blocks/index/*,blocks/rev000??.dat} in 0.8.0
+* blk000?.dat: block data (custom, 2 GiB per file); replaced by blocks/blk000??.dat in 0.8.0
+
+Only used before 0.7.0
+---------------------
+* addr.dat: peer IP address database (BDB); replaced by peers.dat in 0.7.0
diff --git a/doc/gitian-building.md b/doc/gitian-building.md
new file mode 100644
index 0000000000..630b3c04a7
--- /dev/null
+++ b/doc/gitian-building.md
@@ -0,0 +1,396 @@
+Gitian building
+================
+
+*Setup instructions for a gitian build of Bitcoin using a Debian VM or physical system.*
+
+Gitian is the deterministic build process that is used to build the Bitcoin
+Core executables. It provides a way to be reasonably sure that the
+executables are really built from source on GitHub. It also makes sure that
+the same, tested dependencies are used and statically built into the executable.
+
+Multiple developers build the source code by following a specific descriptor
+("recipe"), cryptographically sign the result, and upload the resulting signature.
+These results are compared and only if they match, the build is accepted and uploaded
+to bitcoin.org.
+
+More independent gitian builders are needed, which is why I wrote this
+guide. It is preferred to follow these steps yourself instead of using someone else's
+VM image to avoid 'contaminating' the build.
+
+Table of Contents
+------------------
+
+- [Create a new VirtualBox VM](#create-a-new-virtualbox-vm)
+- [Connecting to the VM](#connecting-to-the-vm)
+- [Setting up Debian for gitian building](#setting-up-debian-for-gitian-building)
+- [Installing gitian](#installing-gitian)
+- [Setting up the gitian image](#setting-up-the-gitian-image)
+- [Getting and building the inputs](#getting-and-building-the-inputs)
+- [Building Bitcoin](#building-bitcoin)
+- [Building an alternative repository](#building-an-alternative-repository)
+- [Signing externally](#signing-externally)
+- [Uploading signatures](#uploading-signatures)
+
+Preparing the Gitian builder host
+---------------------------------
+
+The first step is to prepare the host environment that will be used to perform the Gitian builds.
+This guide explains how to set up the environment, and how to start the builds.
+
+Debian Linux was chosen as the host distribution because it has a lightweight install (in contrast to Ubuntu) and is readily available.
+Any kind of virtualization can be used, for example:
+- [VirtualBox](https://www.virtualbox.org/), covered by this guide
+- [KVM](http://www.linux-kvm.org/page/Main_Page)
+- [LXC](https://linuxcontainers.org/), see also [Gitian host docker container](https://github.com/gdm85/tenku/tree/master/docker/gitian-bitcoin-host/README.md).
+
+You can also install on actual hardware instead of using virtualization.
+
+Create a new VirtualBox VM
+---------------------------
+In the VirtualBox GUI click "Create" and choose the following parameters in the wizard:
+
+![](gitian-building/create_vm_page1.png)
+
+- Type: Linux, Debian (64 bit)
+
+![](gitian-building/create_vm_memsize.png)
+
+- Memory Size: at least 1024MB, anything lower will really slow the build down
+
+![](gitian-building/create_vm_hard_drive.png)
+
+- Hard Drive: Create a virtual hard drive now
+
+![](gitian-building/create_vm_hard_drive_file_type.png)
+
+- Hard Drive file type: Use the default, VDI (VirtualBox Disk Image)
+
+![](gitian-building/create_vm_storage_physical_hard_drive.png)
+
+- Storage on Physical hard drive: Dynamically Allocated
+
+![](gitian-building/create_vm_file_location_size.png)
+
+- Disk size: at least 40GB; as low as 20GB *may* be possible, but better to err on the safe side
+- Push the `Create` button
+
+Get the [Debian 7.8 net installer](http://cdimage.debian.org/cdimage/archive/7.8.0/amd64/iso-cd/debian-7.8.0-amd64-netinst.iso) (a more recent minor version should also work, see also [Debian Network installation](https://www.debian.org/CD/netinst/)).
+This DVD image can be validated using a SHA256 hashing tool, for example on
+Unixy OSes by entering the following in a terminal:
+
+ echo "e39c36d6adc0fd86c6edb0e03e22919086c883b37ca194d063b8e3e8f6ff6a3a debian-7.8.0-amd64-netinst.iso" | sha256sum -c
+ # (must return OK)
+
+After creating the VM, we need to configure it.
+
+- Click the `Settings` button, then go to the `Network` tab. Adapter 1 should be attached to `NAT`.
+
+![](gitian-building/network_settings.png)
+
+- Click `Advanced`, then `Port Forwarding`. We want to set up a port through which we can reach the VM to get files in and out.
+- Create a new rule by clicking the plus icon.
+
+![](gitian-building/port_forwarding_rules.png)
+
+- Set up the new rule the following way:
+ - Name: `SSH`
+ - Protocol: `TCP`
+ - Leave Host IP empty
+ - Host Port: `22222`
+ - Leave Guest IP empty
+ - Guest Port: `22`
+
+- Click `Ok` twice to save.
+
+Then start the VM. On the first launch you will be asked for a CD or DVD image. Choose the downloaded iso.
+
+![](gitian-building/select_startup_disk.png)
+
+Installing Debian
+------------------
+
+This section will explain how to install Debian on the newly created VM.
+
+- Choose the non-graphical installer. We do not need the graphical environment; it will only increase installation time and disk usage.
+
+![](gitian-building/debian_install_1_boot_menu.png)
+
+**Note**: Navigation in the Debian installer: To keep a setting at the default
+and proceed, just press `Enter`. To select a different button, press `Tab`.
+
+- Choose locale and keyboard settings (doesn't matter, you can just go with the defaults or select your own information)
+
+![](gitian-building/debian_install_2_select_a_language.png)
+![](gitian-building/debian_install_3_select_location.png)
+![](gitian-building/debian_install_4_configure_keyboard.png)
+
+- The VM will detect network settings using DHCP, this should all proceed automatically
+- Configure the network:
+ - System name `debian`.
+ - Leave domain name empty.
+
+![](gitian-building/debian_install_5_configure_the_network.png)
+
+- Choose a root password and enter it twice (remember it for later)
+
+![](gitian-building/debian_install_6a_set_up_root_password.png)
+
+- Name the new user `debian` (the full name doesn't matter, you can leave it empty)
+
+![](gitian-building/debian_install_7_set_up_user_fullname.png)
+![](gitian-building/debian_install_8_set_up_username.png)
+
+- Choose a user password and enter it twice (remember it for later)
+
+![](gitian-building/debian_install_9_user_password.png)
+
+- The installer will set up the clock using a time server; this process should be automatic
+- Set up the clock: choose a time zone (depends on the locale settings that you picked earlier; specifics don't matter)
+
+![](gitian-building/debian_install_10_configure_clock.png)
+
+- Disk setup
+ - Partitioning method: Guided - Use the entire disk
+
+![](gitian-building/debian_install_11_partition_disks.png)
+
+ - Select disk to partition: SCSI1 (0,0,0)
+
+![](gitian-building/debian_install_12_choose_disk.png)
+
+ - Partitioning scheme: All files in one partition
+
+![](gitian-building/debian_install_13_partition_scheme.png)
+
+ - Finish partitioning and write changes to disk -> *Yes* (`Tab`, `Enter` to select the `Yes` button)
+
+![](gitian-building/debian_install_14_finish.png)
+![](gitian-building/debian_install_15_write_changes.png)
+
+- The base system will be installed, this will take a minute or so
+- Choose a mirror (any will do)
+
+![](gitian-building/debian_install_16_choose_a_mirror.png)
+
+- Enter proxy information (unless you are on an intranet, you can leave this empty)
+
+![](gitian-building/debian_install_18_proxy_settings.png)
+
+- Wait a bit while 'Select and install software' runs
+- Participate in popularity contest -> *No*
+- Choose software to install. We need just the base system.
+
+![](gitian-building/debian_install_19_software_selection.png)
+
+- Make sure only 'SSH server' and 'Standard System Utilities' are checked
+- Uncheck 'Debian Desktop Environment' and 'Print Server'
+
+![](gitian-building/debian_install_20_install_grub.png)
+
+- Install the GRUB boot loader to the master boot record? -> Yes
+
+![](gitian-building/debian_install_21_finish_installation.png)
+
+- Installation Complete -> *Continue*
+- After installation, the VM will reboot and you will have a working Debian VM. Congratulations!
+
+Connecting to the VM
+----------------------
+
+After the VM has booted you can connect to it using SSH, and files can be copied from and to the VM using a SFTP utility.
+Connect to `localhost`, port `22222` (or the port configured when installing the VM).
+On Windows you can use putty[1] and WinSCP[2].
+
+For example to connect as `root` from a Linux command prompt use
+
+ $ ssh root@localhost -p 22222
+ The authenticity of host '[localhost]:22222 ([127.0.0.1]:22222)' can't be established.
+ ECDSA key fingerprint is 8e:71:f9:5b:62:46:de:44:01:da:fb:5f:34:b5:f2:18.
+ Are you sure you want to continue connecting (yes/no)? yes
+ Warning: Permanently added '[localhost]:22222' (ECDSA) to the list of known hosts.
+ root@localhost's password: (enter root password configured during install)
+ Linux debian 3.2.0-4-amd64 #1 SMP Debian 3.2.54-2 x86_64
+ root@debian:~#
+
+Replace `root` with `debian` to log in as user.
+
+[1] http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html
+[2] http://winscp.net/eng/index.php
+
+Setting up Debian for gitian building
+--------------------------------------
+
+In this section we will be setting up the Debian installation for Gitian building.
+
+First we need to log in as `root` to set up dependencies and make sure that our
+user can use the sudo command. Type/paste the following in the terminal:
+
+```bash
+apt-get install git ruby sudo apt-cacher-ng qemu-utils debootstrap lxc python-cheetah parted kpartx bridge-utils
+adduser debian sudo
+```
+
+When you get a colorful screen with a question about the 'LXC directory', just
+go with the default (`/var/lib/lxc`).
+
+Then set up LXC and the rest with the following, which is a complex jumble of settings and workarounds:
+
+```bash
+# the version of lxc-start in Debian 7.4 needs to run as root, so make sure
+# that the build script can exectute it without providing a password
+echo "%sudo ALL=NOPASSWD: /usr/bin/lxc-start" > /etc/sudoers.d/gitian-lxc
+# add cgroup for LXC
+echo "cgroup /sys/fs/cgroup cgroup defaults 0 0" >> /etc/fstab
+# make /etc/rc.local script that sets up bridge between guest and host
+echo '#!/bin/sh -e' > /etc/rc.local
+echo 'brctl addbr br0' >> /etc/rc.local
+echo 'ifconfig br0 10.0.3.2/24 up' >> /etc/rc.local
+echo 'exit 0' >> /etc/rc.local
+# make sure that USE_LXC is always set when logging in as debian,
+# and configure LXC IP addresses
+echo 'export USE_LXC=1' >> /home/debian/.profile
+echo 'export GITIAN_HOST_IP=10.0.3.2' >> /home/debian/.profile
+echo 'export LXC_GUEST_IP=10.0.3.5' >> /home/debian/.profile
+reboot
+```
+
+At the end the VM is rebooted to make sure that the changes take effect. The steps in this
+section need only to be performed once.
+
+Installing gitian
+------------------
+
+Re-login as the user `debian` that was created during installation.
+The rest of the steps in this guide will be performed as that user.
+
+There is no `python-vm-builder` package in Debian, so we need to install it from source ourselves,
+
+```bash
+wget http://archive.ubuntu.com/ubuntu/pool/universe/v/vm-builder/vm-builder_0.12.4+bzr489.orig.tar.gz
+echo "ec12e0070a007989561bfee5862c89a32c301992dd2771c4d5078ef1b3014f03 vm-builder_0.12.4+bzr489.orig.tar.gz" | sha256sum -c
+# (verification -- must return OK)
+tar -zxvf vm-builder_0.12.4+bzr489.orig.tar.gz
+cd vm-builder-0.12.4+bzr489
+sudo python setup.py install
+cd ..
+```
+
+**Note**: When sudo asks for a password, enter the password for the user *debian* not for *root*.
+
+Clone the git repositories for bitcoin and gitian.
+
+```bash
+git clone https://github.com/devrandom/gitian-builder.git
+git clone https://github.com/bitcoin/bitcoin
+```
+
+Setting up the gitian image
+-------------------------
+
+Gitian needs a virtual image of the operating system to build in.
+Currently this is Ubuntu Precise x86_64.
+This image will be copied and used every time that a build is started to
+make sure that the build is deterministic.
+Creating the image will take a while, but only has to be done once.
+
+Execute the following as user `debian`:
+
+```bash
+cd gitian-builder
+bin/make-base-vm --lxc --arch amd64 --suite precise
+```
+
+There will be a lot of warnings printed during build of the image. These can be ignored.
+
+**Note**: When sudo asks for a password, enter the password for the user *debian* not for *root*.
+
+Getting and building the inputs
+--------------------------------
+
+Follow the instructions in [doc/release-process.md](release-process.md) in the bitcoin repository
+under 'Fetch and build inputs' to install sources which require manual intervention. Also follow
+the next step: 'Seed the Gitian sources cache', which will fetch all necessary source files allowing
+for gitian to work offline.
+
+Building Bitcoin
+----------------
+
+To build Bitcoin (for Linux, OSX and Windows) just follow the steps under 'perform
+gitian builds' in [doc/release-process.md](release-process.md) in the bitcoin repository.
+
+This may take a long time as it also builds the dependencies needed for each descriptor.
+These dependencies will be cached after a successful build to avoid rebuilding them where possible.
+
+At any time you can check the package installation and build progress with
+
+```bash
+tail -f var/install.log
+tail -f var/build.log
+```
+
+Output from `gbuild` will look something like
+
+ Initialized empty Git repository in /home/debian/gitian-builder/inputs/bitcoin/.git/
+ remote: Reusing existing pack: 35606, done.
+ remote: Total 35606 (delta 0), reused 0 (delta 0)
+ Receiving objects: 100% (35606/35606), 26.52 MiB | 4.28 MiB/s, done.
+ Resolving deltas: 100% (25724/25724), done.
+ From https://github.com/bitcoin/bitcoin
+ ... (new tags, new branch etc)
+ --- Building for precise x86_64 ---
+ Stopping target if it is up
+ Making a new image copy
+ stdin: is not a tty
+ Starting target
+ Checking if target is up
+ Preparing build environment
+ Updating apt-get repository (log in var/install.log)
+ Installing additional packages (log in var/install.log)
+ Grabbing package manifest
+ stdin: is not a tty
+ Creating build script (var/build-script)
+ lxc-start: Connection refused - inotify event with no name (mask 32768)
+ Running build script (log in var/build.log)
+
+Building an alternative repository
+-----------------------------------
+
+If you want to do a test build of a pull on GitHub it can be useful to point
+the gitian builder at an alternative repository, using the same descriptors
+and inputs.
+
+For example:
+```bash
+URL=https://github.com/laanwj/bitcoin.git
+COMMIT=2014_03_windows_unicode_path
+./bin/gbuild --commit bitcoin=${COMMIT} --url bitcoin=${URL} ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml
+./bin/gbuild --commit bitcoin=${COMMIT} --url bitcoin=${URL} ../bitcoin/contrib/gitian-descriptors/gitian-win.yml
+./bin/gbuild --commit bitcoin=${COMMIT} --url bitcoin=${URL} ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml
+```
+
+Signing externally
+-------------------
+
+If you want to do the PGP signing on another device, that's also possible; just define `SIGNER` as mentioned
+and follow the steps in the build process as normal.
+
+ gpg: skipped "laanwj": secret key not available
+
+When you execute `gsign` you will get an error from GPG, which can be ignored. Copy the resulting `.assert` files
+in `gitian.sigs` to your signing machine and do
+
+```bash
+ gpg --detach-sign ${VERSION}-linux/${SIGNER}/bitcoin-linux-build.assert
+ gpg --detach-sign ${VERSION}-win/${SIGNER}/bitcoin-win-build.assert
+ gpg --detach-sign ${VERSION}-osx-unsigned/${SIGNER}/bitcoin-osx-build.assert
+```
+
+This will create the `.sig` files that can be committed together with the `.assert` files to assert your
+gitian build.
+
+Uploading signatures
+---------------------
+
+After building and signing you can push your signatures (both the `.assert` and `.assert.sig` files) to the
+[bitcoin/gitian.sigs](https://github.com/bitcoin/gitian.sigs/) repository, or if that's not possible create a pull
+request. You can also mail the files to Wladimir (laanwj@gmail.com) and he will commit them.
diff --git a/doc/gitian-building/create_vm_file_location_size.png b/doc/gitian-building/create_vm_file_location_size.png
new file mode 100644
index 0000000000..14aef5abae
--- /dev/null
+++ b/doc/gitian-building/create_vm_file_location_size.png
Binary files differ
diff --git a/doc/gitian-building/create_vm_hard_drive.png b/doc/gitian-building/create_vm_hard_drive.png
new file mode 100644
index 0000000000..a1706e14fd
--- /dev/null
+++ b/doc/gitian-building/create_vm_hard_drive.png
Binary files differ
diff --git a/doc/gitian-building/create_vm_hard_drive_file_type.png b/doc/gitian-building/create_vm_hard_drive_file_type.png
new file mode 100644
index 0000000000..251b8ee3e2
--- /dev/null
+++ b/doc/gitian-building/create_vm_hard_drive_file_type.png
Binary files differ
diff --git a/doc/gitian-building/create_vm_memsize.png b/doc/gitian-building/create_vm_memsize.png
new file mode 100644
index 0000000000..33717867a5
--- /dev/null
+++ b/doc/gitian-building/create_vm_memsize.png
Binary files differ
diff --git a/doc/gitian-building/create_vm_page1.png b/doc/gitian-building/create_vm_page1.png
new file mode 100644
index 0000000000..edaebc6223
--- /dev/null
+++ b/doc/gitian-building/create_vm_page1.png
Binary files differ
diff --git a/doc/gitian-building/create_vm_storage_physical_hard_drive.png b/doc/gitian-building/create_vm_storage_physical_hard_drive.png
new file mode 100644
index 0000000000..987efaa40c
--- /dev/null
+++ b/doc/gitian-building/create_vm_storage_physical_hard_drive.png
Binary files differ
diff --git a/doc/gitian-building/debian_install_10_configure_clock.png b/doc/gitian-building/debian_install_10_configure_clock.png
new file mode 100644
index 0000000000..467c79018e
--- /dev/null
+++ b/doc/gitian-building/debian_install_10_configure_clock.png
Binary files differ
diff --git a/doc/gitian-building/debian_install_11_partition_disks.png b/doc/gitian-building/debian_install_11_partition_disks.png
new file mode 100644
index 0000000000..18110734df
--- /dev/null
+++ b/doc/gitian-building/debian_install_11_partition_disks.png
Binary files differ
diff --git a/doc/gitian-building/debian_install_12_choose_disk.png b/doc/gitian-building/debian_install_12_choose_disk.png
new file mode 100644
index 0000000000..a00d4abf17
--- /dev/null
+++ b/doc/gitian-building/debian_install_12_choose_disk.png
Binary files differ
diff --git a/doc/gitian-building/debian_install_13_partition_scheme.png b/doc/gitian-building/debian_install_13_partition_scheme.png
new file mode 100644
index 0000000000..2f80f19b63
--- /dev/null
+++ b/doc/gitian-building/debian_install_13_partition_scheme.png
Binary files differ
diff --git a/doc/gitian-building/debian_install_14_finish.png b/doc/gitian-building/debian_install_14_finish.png
new file mode 100644
index 0000000000..411d457e95
--- /dev/null
+++ b/doc/gitian-building/debian_install_14_finish.png
Binary files differ
diff --git a/doc/gitian-building/debian_install_15_write_changes.png b/doc/gitian-building/debian_install_15_write_changes.png
new file mode 100644
index 0000000000..f26093982c
--- /dev/null
+++ b/doc/gitian-building/debian_install_15_write_changes.png
Binary files differ
diff --git a/doc/gitian-building/debian_install_16_choose_a_mirror.png b/doc/gitian-building/debian_install_16_choose_a_mirror.png
new file mode 100644
index 0000000000..d2c2e9523b
--- /dev/null
+++ b/doc/gitian-building/debian_install_16_choose_a_mirror.png
Binary files differ
diff --git a/doc/gitian-building/debian_install_17_choose_a_mirror2.png b/doc/gitian-building/debian_install_17_choose_a_mirror2.png
new file mode 100644
index 0000000000..cef2db0781
--- /dev/null
+++ b/doc/gitian-building/debian_install_17_choose_a_mirror2.png
Binary files differ
diff --git a/doc/gitian-building/debian_install_18_proxy_settings.png b/doc/gitian-building/debian_install_18_proxy_settings.png
new file mode 100644
index 0000000000..24ba25c109
--- /dev/null
+++ b/doc/gitian-building/debian_install_18_proxy_settings.png
Binary files differ
diff --git a/doc/gitian-building/debian_install_19_software_selection.png b/doc/gitian-building/debian_install_19_software_selection.png
new file mode 100644
index 0000000000..d462757aff
--- /dev/null
+++ b/doc/gitian-building/debian_install_19_software_selection.png
Binary files differ
diff --git a/doc/gitian-building/debian_install_1_boot_menu.png b/doc/gitian-building/debian_install_1_boot_menu.png
new file mode 100644
index 0000000000..27fd849b4f
--- /dev/null
+++ b/doc/gitian-building/debian_install_1_boot_menu.png
Binary files differ
diff --git a/doc/gitian-building/debian_install_20_install_grub.png b/doc/gitian-building/debian_install_20_install_grub.png
new file mode 100644
index 0000000000..de4f9be0c9
--- /dev/null
+++ b/doc/gitian-building/debian_install_20_install_grub.png
Binary files differ
diff --git a/doc/gitian-building/debian_install_21_finish_installation.png b/doc/gitian-building/debian_install_21_finish_installation.png
new file mode 100644
index 0000000000..b967c3550d
--- /dev/null
+++ b/doc/gitian-building/debian_install_21_finish_installation.png
Binary files differ
diff --git a/doc/gitian-building/debian_install_2_select_a_language.png b/doc/gitian-building/debian_install_2_select_a_language.png
new file mode 100644
index 0000000000..1c9e0bcfc1
--- /dev/null
+++ b/doc/gitian-building/debian_install_2_select_a_language.png
Binary files differ
diff --git a/doc/gitian-building/debian_install_3_select_location.png b/doc/gitian-building/debian_install_3_select_location.png
new file mode 100644
index 0000000000..005c395656
--- /dev/null
+++ b/doc/gitian-building/debian_install_3_select_location.png
Binary files differ
diff --git a/doc/gitian-building/debian_install_4_configure_keyboard.png b/doc/gitian-building/debian_install_4_configure_keyboard.png
new file mode 100644
index 0000000000..580c8af7c5
--- /dev/null
+++ b/doc/gitian-building/debian_install_4_configure_keyboard.png
Binary files differ
diff --git a/doc/gitian-building/debian_install_5_configure_the_network.png b/doc/gitian-building/debian_install_5_configure_the_network.png
new file mode 100644
index 0000000000..a7fdffc66b
--- /dev/null
+++ b/doc/gitian-building/debian_install_5_configure_the_network.png
Binary files differ
diff --git a/doc/gitian-building/debian_install_6_domain_name.png b/doc/gitian-building/debian_install_6_domain_name.png
new file mode 100644
index 0000000000..7a986d92f4
--- /dev/null
+++ b/doc/gitian-building/debian_install_6_domain_name.png
Binary files differ
diff --git a/doc/gitian-building/debian_install_6a_set_up_root_password.png b/doc/gitian-building/debian_install_6a_set_up_root_password.png
new file mode 100644
index 0000000000..31bd210f38
--- /dev/null
+++ b/doc/gitian-building/debian_install_6a_set_up_root_password.png
Binary files differ
diff --git a/doc/gitian-building/debian_install_7_set_up_user_fullname.png b/doc/gitian-building/debian_install_7_set_up_user_fullname.png
new file mode 100644
index 0000000000..bffc6ccd7a
--- /dev/null
+++ b/doc/gitian-building/debian_install_7_set_up_user_fullname.png
Binary files differ
diff --git a/doc/gitian-building/debian_install_8_set_up_username.png b/doc/gitian-building/debian_install_8_set_up_username.png
new file mode 100644
index 0000000000..9e2750ad4e
--- /dev/null
+++ b/doc/gitian-building/debian_install_8_set_up_username.png
Binary files differ
diff --git a/doc/gitian-building/debian_install_9_user_password.png b/doc/gitian-building/debian_install_9_user_password.png
new file mode 100644
index 0000000000..a26d30cba5
--- /dev/null
+++ b/doc/gitian-building/debian_install_9_user_password.png
Binary files differ
diff --git a/doc/gitian-building/network_settings.png b/doc/gitian-building/network_settings.png
new file mode 100644
index 0000000000..1d9b6428a7
--- /dev/null
+++ b/doc/gitian-building/network_settings.png
Binary files differ
diff --git a/doc/gitian-building/port_forwarding_rules.png b/doc/gitian-building/port_forwarding_rules.png
new file mode 100644
index 0000000000..e45c9efffc
--- /dev/null
+++ b/doc/gitian-building/port_forwarding_rules.png
Binary files differ
diff --git a/doc/gitian-building/select_startup_disk.png b/doc/gitian-building/select_startup_disk.png
new file mode 100644
index 0000000000..729b368fd1
--- /dev/null
+++ b/doc/gitian-building/select_startup_disk.png
Binary files differ
diff --git a/doc/init.md b/doc/init.md
new file mode 100644
index 0000000000..1f206a6c02
--- /dev/null
+++ b/doc/init.md
@@ -0,0 +1,102 @@
+Sample init scripts and service configuration for bitcoind
+==========================================================
+
+Sample scripts and configuration files for systemd, Upstart and OpenRC
+can be found in the contrib/init folder.
+
+ contrib/init/bitcoind.service: systemd service unit configuration
+ contrib/init/bitcoind.openrc: OpenRC compatible SysV style init script
+ contrib/init/bitcoind.openrcconf: OpenRC conf.d file
+ contrib/init/bitcoind.conf: Upstart service configuration file
+ contrib/init/bitcoind.init: CentOS compatible SysV style init script
+
+1. Service User
+---------------------------------
+
+All three startup configurations assume the existence of a "bitcoin" user
+and group. They must be created before attempting to use these scripts.
+
+2. Configuration
+---------------------------------
+
+At a bare minimum, bitcoind requires that the rpcpassword setting be set
+when running as a daemon. If the configuration file does not exist or this
+setting is not set, bitcoind will shutdown promptly after startup.
+
+This password does not have to be remembered or typed as it is mostly used
+as a fixed token that bitcoind and client programs read from the configuration
+file, however it is recommended that a strong and secure password be used
+as this password is security critical to securing the wallet should the
+wallet be enabled.
+
+If bitcoind is run with "-daemon" flag, and no rpcpassword is set, it will
+print a randomly generated suitable password to stderr. You can also
+generate one from the shell yourself like this:
+
+bash -c 'tr -dc a-zA-Z0-9 < /dev/urandom | head -c32 && echo'
+
+Once you have a password in hand, set rpcpassword= in /etc/bitcoin/bitcoin.conf
+
+For an example configuration file that describes the configuration settings,
+see contrib/debian/examples/bitcoin.conf.
+
+3. Paths
+---------------------------------
+
+All three configurations assume several paths that might need to be adjusted.
+
+Binary: /usr/bin/bitcoind
+Configuration file: /etc/bitcoin/bitcoin.conf
+Data directory: /var/lib/bitcoind
+PID file: /var/run/bitcoind/bitcoind.pid (OpenRC and Upstart)
+ /var/lib/bitcoind/bitcoind.pid (systemd)
+Lock file: /var/lock/subsys/bitcoind (CentOS)
+
+The configuration file, PID directory (if applicable) and data directory
+should all be owned by the bitcoin user and group. It is advised for security
+reasons to make the configuration file and data directory only readable by the
+bitcoin user and group. Access to bitcoin-cli and other bitcoind rpc clients
+can then be controlled by group membership.
+
+4. Installing Service Configuration
+-----------------------------------
+
+4a) systemd
+
+Installing this .service file consists of just copying it to
+/usr/lib/systemd/system directory, followed by the command
+"systemctl daemon-reload" in order to update running systemd configuration.
+
+To test, run "systemctl start bitcoind" and to enable for system startup run
+"systemctl enable bitcoind"
+
+4b) OpenRC
+
+Rename bitcoind.openrc to bitcoind and drop it in /etc/init.d. Double
+check ownership and permissions and make it executable. Test it with
+"/etc/init.d/bitcoind start" and configure it to run on startup with
+"rc-update add bitcoind"
+
+4c) Upstart (for Debian/Ubuntu based distributions)
+
+Drop bitcoind.conf in /etc/init. Test by running "service bitcoind start"
+it will automatically start on reboot.
+
+NOTE: This script is incompatible with CentOS 5 and Amazon Linux 2014 as they
+use old versions of Upstart and do not supply the start-stop-daemon utility.
+
+4d) CentOS
+
+Copy bitcoind.init to /etc/init.d/bitcoind. Test by running "service bitcoind start".
+
+Using this script, you can adjust the path and flags to the bitcoind program by
+setting the BITCOIND and FLAGS environment variables in the file
+/etc/sysconfig/bitcoind. You can also use the DAEMONOPTS environment variable here.
+
+5. Auto-respawn
+-----------------------------------
+
+Auto respawning is currently only configured for Upstart and systemd.
+Reasonable defaults have been chosen but YMMV.
+
+
diff --git a/doc/multiwallet-qt.md b/doc/multiwallet-qt.md
new file mode 100644
index 0000000000..3caab81807
--- /dev/null
+++ b/doc/multiwallet-qt.md
@@ -0,0 +1,48 @@
+Multiwallet Qt Development and Integration Strategy
+===================================================
+
+In order to support loading of multiple wallets in bitcoin-qt, a few changes in the UI architecture will be needed.
+Fortunately, only four of the files in the existing project are affected by this change.
+
+Two new classes have been implemented in two new .h/.cpp file pairs, with much of the functionality that was previously
+implemented in the BitcoinGUI class moved over to these new classes.
+
+The two existing files most affected, by far, are bitcoingui.h and bitcoingui.cpp, as the BitcoinGUI class will require
+some major retrofitting.
+
+Only requiring some minor changes is bitcoin.cpp.
+
+Finally, two new headers and source files will have to be added to bitcoin-qt.pro.
+
+Changes to class BitcoinGUI
+---------------------------
+The principal change to the BitcoinGUI class concerns the QStackedWidget instance called centralWidget.
+This widget owns five page views: overviewPage, transactionsPage, addressBookPage, receiveCoinsPage, and sendCoinsPage.
+
+A new class called *WalletView* inheriting from QStackedWidget has been written to handle all renderings and updates of
+these page views. In addition to owning these five page views, a WalletView also has a pointer to a WalletModel instance.
+This allows the construction of multiple WalletView objects, each rendering a distinct wallet.
+
+A second class called *WalletFrame* inheriting from QFrame has been written as a container for embedding all wallet-related
+controls into BitcoinGUI. At present it contains the WalletView instances for the wallets and does little more than passing on messages
+from BitcoinGUI to the currently selected WalletView. It is a WalletFrame instance
+that takes the place of what used to be centralWidget in BitcoinGUI. The purpose of this class is to allow future
+refinements of the wallet controls with minimal need for further modifications to BitcoinGUI, thus greatly simplifying
+merges while reducing the risk of breaking top-level stuff.
+
+Changes to bitcoin.cpp
+----------------------
+bitcoin.cpp is the entry point into bitcoin-qt, and as such, will require some minor modifications to provide hooks for
+multiple wallet support. Most importantly will be the way it instantiates WalletModels and passes them to the
+singleton BitcoinGUI instance called window. Formerly, BitcoinGUI kept a pointer to a single instance of a WalletModel.
+The initial change required is very simple: rather than calling `window.setWalletModel(&walletModel);` we perform the
+following two steps:
+
+ window.addWallet("~Default", &walletModel);
+ window.setCurrentWallet("~Default");
+
+The string parameter is just an arbitrary name given to the default wallet. It's been prepended with a tilde to avoid name collisions in the future with additional wallets.
+
+The shutdown call `window.setWalletModel(0)` has also been removed. In its place is now:
+
+window.removeAllWallets();
diff --git a/doc/release-notes.md b/doc/release-notes.md
new file mode 100644
index 0000000000..799205691e
--- /dev/null
+++ b/doc/release-notes.md
@@ -0,0 +1,172 @@
+Bitcoin Core version 0.11.1 is now available from:
+
+ <https://bitcoin.org/bin/bitcoin-core-0.11.1/>
+
+This is a new minor version release, bringing security fixes. It is recommended
+to upgrade to this version as soon as possible.
+
+Please report bugs using the issue tracker at github:
+
+ <https://github.com/bitcoin/bitcoin/issues>
+
+Upgrading and downgrading
+=========================
+
+How to Upgrade
+--------------
+
+If you are running an older version, shut it down. Wait until it has completely
+shut down (which might take a few minutes for older versions), then run the
+installer (on Windows) or just copy over /Applications/Bitcoin-Qt (on Mac) or
+bitcoind/bitcoin-qt (on Linux).
+
+Downgrade warning
+------------------
+
+Because release 0.10.0 and later makes use of headers-first synchronization and
+parallel block download (see further), the block files and databases are not
+backwards-compatible with pre-0.10 versions of Bitcoin Core or other software:
+
+* Blocks will be stored on disk out of order (in the order they are
+received, really), which makes it incompatible with some tools or
+other programs. Reindexing using earlier versions will also not work
+anymore as a result of this.
+
+* The block index database will now hold headers for which no block is
+stored on disk, which earlier versions won't support.
+
+If you want to be able to downgrade smoothly, make a backup of your entire data
+directory. Without this your node will need start syncing (or importing from
+bootstrap.dat) anew afterwards. It is possible that the data from a completely
+synchronised 0.10 node may be usable in older versions as-is, but this is not
+supported and may break as soon as the older version attempts to reindex.
+
+This does not affect wallet forward or backward compatibility. There are no
+known problems when downgrading from 0.11.x to 0.10.x.
+
+Notable changes
+===============
+
+Fix buffer overflow in bundled upnp
+------------------------------------
+
+Bundled miniupnpc was updated to 1.9.20151008. This fixes a buffer overflow in
+the XML parser during initial network discovery.
+
+Details can be found here: http://talosintel.com/reports/TALOS-2015-0035/
+
+This applies to the distributed executables only, not when building from source or
+using distribution provided packages.
+
+Additionally, upnp has been disabled by default. This may result in a lower
+number of reachable nodes on IPv4, however this prevents future libupnpc
+vulnerabilities from being a structural risk to the network
+(see https://github.com/bitcoin/bitcoin/pull/6795).
+
+Test for LowS signatures before relaying
+-----------------------------------------
+
+Make the node require the canonical 'low-s' encoding for ECDSA signatures when
+relaying or mining. This removes a nuisance malleability vector.
+
+Consensus behavior is unchanged.
+
+If widely deployed this change would eliminate the last remaining known vector
+for nuisance malleability on SIGHASH_ALL P2PKH transactions. On the down-side
+it will block most transactions made by sufficiently out of date software.
+
+Unlike the other avenues to change txids on transactions this
+one was randomly violated by all deployed bitcoin software prior to
+its discovery. So, while other malleability vectors where made
+non-standard as soon as they were discovered, this one has remained
+permitted. Even BIP62 did not propose applying this rule to
+old version transactions, but conforming implementations have become
+much more common since BIP62 was initially written.
+
+Bitcoin Core has produced compatible signatures since a28fb70e in
+September 2013, but this didn't make it into a release until 0.9
+in March 2014; Bitcoinj has done so for a similar span of time.
+Bitcoinjs and electrum have been more recently updated.
+
+This does not replace the need for BIP62 or similar, as miners can
+still cooperate to break transactions. Nor does it replace the
+need for wallet software to handle malleability sanely[1]. This
+only eliminates the cheap and irritating DOS attack.
+
+[1] On the Malleability of Bitcoin Transactions
+Marcin Andrychowicz, Stefan Dziembowski, Daniel Malinowski, Łukasz Mazurek
+http://fc15.ifca.ai/preproceedings/bitcoin/paper_9.pdf
+
+Minimum relay fee default increase
+-----------------------------------
+
+The default for the `-minrelaytxfee` setting has been increased from `0.00001`
+to `0.00005`.
+
+This is necessitated by the current transaction flooding, causing
+outrageous memory usage on nodes due to the mempool ballooning. This is a
+temporary measure, bridging the time until a dynamic method for determining
+this fee is merged (which will be in 0.12).
+
+(see https://github.com/bitcoin/bitcoin/pull/6793, as well as the 0.11
+release notes, in which this value was suggested)
+
+0.11.1 Change log
+=================
+
+Detailed release notes follow. This overview includes changes that affect
+behavior, not code moves, refactors and string updates. For convenience in locating
+the code changes and accompanying discussion, both the pull request and
+git merge commit are mentioned.
+
+- #6438 `2531438` openssl: avoid config file load/race
+- #6439 `980f820` Updated URL location of netinstall for Debian
+- #6384 `8e5a969` qt: Force TLS1.0+ for SSL connections
+- #6471 `92401c2` Depends: bump to qt 5.5
+- #6224 `93b606a` Be even stricter in processing unrequested blocks
+- #6571 `100ac4e` libbitcoinconsensus: avoid a crash in multi-threaded environments
+- #6545 `649f5d9` Do not store more than 200 timedata samples.
+- #6694 `834e299` [QT] fix thin space word wrap line break issue
+- #6703 `1cd7952` Backport bugfixes to 0.11
+- #6750 `5ed8d0b` Recent rejects backport to v0.11
+- #6769 `71cc9d9` Test LowS in standardness, removes nuisance malleability vector.
+- #6789 `b4ad73f` Update miniupnpc to 1.9.20151008
+- #6785 `b4dc33e` Backport to v0.11: In (strCommand == "tx"), return if AlreadyHave()
+- #6412 `0095b9a` Test whether created sockets are select()able
+- #6795 `4dbcec0` net: Disable upnp by default
+- #6793 `e7bcc4a` Bump minrelaytxfee default
+
+Credits
+=======
+
+Thanks to everyone who directly contributed to this release:
+
+- Adam Weiss
+- Alex Morcos
+- Casey Rodarmor
+- Cory Fields
+- fanquake
+- Gregory Maxwell
+- Jonas Schnelli
+- J Ross Nicoll
+- Luke Dashjr
+- Pavel Janík
+- Pavel Vasin
+- Peter Todd
+- Pieter Wuille
+- randy-waterhouse
+- Ross Nicoll
+- Suhas Daftuar
+- tailsjoin
+- ฿tcDrak
+- Tom Harding
+- Veres Lajos
+- Wladimir J. van der Laan
+
+And those who contributed additional code review and/or security research:
+
+- timothy on IRC for reporting the issue
+- Vulnerability in miniupnp discovered by Aleksandar Nikolic of Cisco Talos
+
+As well as everyone that helped translating on [Transifex](https://www.transifex.com/projects/p/bitcoin/).
+
diff --git a/doc/release-notes/release-notes-0.10.0.md b/doc/release-notes/release-notes-0.10.0.md
new file mode 100644
index 0000000000..986b8832ec
--- /dev/null
+++ b/doc/release-notes/release-notes-0.10.0.md
@@ -0,0 +1,762 @@
+Bitcoin Core version 0.10.0 is now available from:
+
+ https://bitcoin.org/bin/0.10.0/
+
+This is a new major version release, bringing both new features and
+bug fixes.
+
+Please report bugs using the issue tracker at github:
+
+ https://github.com/bitcoin/bitcoin/issues
+
+Upgrading and downgrading
+=========================
+
+How to Upgrade
+--------------
+
+If you are running an older version, shut it down. Wait until it has completely
+shut down (which might take a few minutes for older versions), then run the
+installer (on Windows) or just copy over /Applications/Bitcoin-Qt (on Mac) or
+bitcoind/bitcoin-qt (on Linux).
+
+Downgrading warning
+---------------------
+
+Because release 0.10.0 makes use of headers-first synchronization and parallel
+block download (see further), the block files and databases are not
+backwards-compatible with older versions of Bitcoin Core or other software:
+
+* Blocks will be stored on disk out of order (in the order they are
+received, really), which makes it incompatible with some tools or
+other programs. Reindexing using earlier versions will also not work
+anymore as a result of this.
+
+* The block index database will now hold headers for which no block is
+stored on disk, which earlier versions won't support.
+
+If you want to be able to downgrade smoothly, make a backup of your entire data
+directory. Without this your node will need start syncing (or importing from
+bootstrap.dat) anew afterwards. It is possible that the data from a completely
+synchronised 0.10 node may be usable in older versions as-is, but this is not
+supported and may break as soon as the older version attempts to reindex.
+
+This does not affect wallet forward or backward compatibility.
+
+
+Notable changes
+===============
+
+Faster synchronization
+----------------------
+
+Bitcoin Core now uses 'headers-first synchronization'. This means that we first
+ask peers for block headers (a total of 27 megabytes, as of December 2014) and
+validate those. In a second stage, when the headers have been discovered, we
+download the blocks. However, as we already know about the whole chain in
+advance, the blocks can be downloaded in parallel from all available peers.
+
+In practice, this means a much faster and more robust synchronization. On
+recent hardware with a decent network link, it can be as little as 3 hours
+for an initial full synchronization. You may notice a slower progress in the
+very first few minutes, when headers are still being fetched and verified, but
+it should gain speed afterwards.
+
+A few RPCs were added/updated as a result of this:
+- `getblockchaininfo` now returns the number of validated headers in addition to
+the number of validated blocks.
+- `getpeerinfo` lists both the number of blocks and headers we know we have in
+common with each peer. While synchronizing, the heights of the blocks that we
+have requested from peers (but haven't received yet) are also listed as
+'inflight'.
+- A new RPC `getchaintips` lists all known branches of the block chain,
+including those we only have headers for.
+
+Transaction fee changes
+-----------------------
+
+This release automatically estimates how high a transaction fee (or how
+high a priority) transactions require to be confirmed quickly. The default
+settings will create transactions that confirm quickly; see the new
+'txconfirmtarget' setting to control the tradeoff between fees and
+confirmation times. Fees are added by default unless the 'sendfreetransactions'
+setting is enabled.
+
+Prior releases used hard-coded fees (and priorities), and would
+sometimes create transactions that took a very long time to confirm.
+
+Statistics used to estimate fees and priorities are saved in the
+data directory in the `fee_estimates.dat` file just before
+program shutdown, and are read in at startup.
+
+New command line options for transaction fee changes:
+- `-txconfirmtarget=n` : create transactions that have enough fees (or priority)
+so they are likely to begin confirmation within n blocks (default: 1). This setting
+is over-ridden by the -paytxfee option.
+- `-sendfreetransactions` : Send transactions as zero-fee transactions if possible
+(default: 0)
+
+New RPC commands for fee estimation:
+- `estimatefee nblocks` : Returns approximate fee-per-1,000-bytes needed for
+a transaction to begin confirmation within nblocks. Returns -1 if not enough
+transactions have been observed to compute a good estimate.
+- `estimatepriority nblocks` : Returns approximate priority needed for
+a zero-fee transaction to begin confirmation within nblocks. Returns -1 if not
+enough free transactions have been observed to compute a good
+estimate.
+
+RPC access control changes
+--------------------------
+
+Subnet matching for the purpose of access control is now done
+by matching the binary network address, instead of with string wildcard matching.
+For the user this means that `-rpcallowip` takes a subnet specification, which can be
+
+- a single IP address (e.g. `1.2.3.4` or `fe80::0012:3456:789a:bcde`)
+- a network/CIDR (e.g. `1.2.3.0/24` or `fe80::0000/64`)
+- a network/netmask (e.g. `1.2.3.4/255.255.255.0` or `fe80::0012:3456:789a:bcde/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff`)
+
+An arbitrary number of `-rpcallow` arguments can be given. An incoming connection will be accepted if its origin address
+matches one of them.
+
+For example:
+
+| 0.9.x and before | 0.10.x |
+|--------------------------------------------|---------------------------------------|
+| `-rpcallowip=192.168.1.1` | `-rpcallowip=192.168.1.1` (unchanged) |
+| `-rpcallowip=192.168.1.*` | `-rpcallowip=192.168.1.0/24` |
+| `-rpcallowip=192.168.*` | `-rpcallowip=192.168.0.0/16` |
+| `-rpcallowip=*` (dangerous!) | `-rpcallowip=::/0` (still dangerous!) |
+
+Using wildcards will result in the rule being rejected with the following error in debug.log:
+
+ Error: Invalid -rpcallowip subnet specification: *. Valid are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24).
+
+
+REST interface
+--------------
+
+A new HTTP API is exposed when running with the `-rest` flag, which allows
+unauthenticated access to public node data.
+
+It is served on the same port as RPC, but does not need a password, and uses
+plain HTTP instead of JSON-RPC.
+
+Assuming a local RPC server running on port 8332, it is possible to request:
+- Blocks: http://localhost:8332/rest/block/*HASH*.*EXT*
+- Blocks without transactions: http://localhost:8332/rest/block/notxdetails/*HASH*.*EXT*
+- Transactions (requires `-txindex`): http://localhost:8332/rest/tx/*HASH*.*EXT*
+
+In every case, *EXT* can be `bin` (for raw binary data), `hex` (for hex-encoded
+binary) or `json`.
+
+For more details, see the `doc/REST-interface.md` document in the repository.
+
+RPC Server "Warm-Up" Mode
+-------------------------
+
+The RPC server is started earlier now, before most of the expensive
+intialisations like loading the block index. It is available now almost
+immediately after starting the process. However, until all initialisations
+are done, it always returns an immediate error with code -28 to all calls.
+
+This new behaviour can be useful for clients to know that a server is already
+started and will be available soon (for instance, so that they do not
+have to start it themselves).
+
+Improved signing security
+-------------------------
+
+For 0.10 the security of signing against unusual attacks has been
+improved by making the signatures constant time and deterministic.
+
+This change is a result of switching signing to use libsecp256k1
+instead of OpenSSL. Libsecp256k1 is a cryptographic library
+optimized for the curve Bitcoin uses which was created by Bitcoin
+Core developer Pieter Wuille.
+
+There exist attacks[1] against most ECC implementations where an
+attacker on shared virtual machine hardware could extract a private
+key if they could cause a target to sign using the same key hundreds
+of times. While using shared hosts and reusing keys are inadvisable
+for other reasons, it's a better practice to avoid the exposure.
+
+OpenSSL has code in their source repository for derandomization
+and reduction in timing leaks that we've eagerly wanted to use for a
+long time, but this functionality has still not made its
+way into a released version of OpenSSL. Libsecp256k1 achieves
+significantly stronger protection: As far as we're aware this is
+the only deployed implementation of constant time signing for
+the curve Bitcoin uses and we have reason to believe that
+libsecp256k1 is better tested and more thoroughly reviewed
+than the implementation in OpenSSL.
+
+[1] https://eprint.iacr.org/2014/161.pdf
+
+Watch-only wallet support
+-------------------------
+
+The wallet can now track transactions to and from wallets for which you know
+all addresses (or scripts), even without the private keys.
+
+This can be used to track payments without needing the private keys online on a
+possibly vulnerable system. In addition, it can help for (manual) construction
+of multisig transactions where you are only one of the signers.
+
+One new RPC, `importaddress`, is added which functions similarly to
+`importprivkey`, but instead takes an address or script (in hexadecimal) as
+argument. After using it, outputs credited to this address or script are
+considered to be received, and transactions consuming these outputs will be
+considered to be sent.
+
+The following RPCs have optional support for watch-only:
+`getbalance`, `listreceivedbyaddress`, `listreceivedbyaccount`,
+`listtransactions`, `listaccounts`, `listsinceblock`, `gettransaction`. See the
+RPC documentation for those methods for more information.
+
+Compared to using `getrawtransaction`, this mechanism does not require
+`-txindex`, scales better, integrates better with the wallet, and is compatible
+with future block chain pruning functionality. It does mean that all relevant
+addresses need to added to the wallet before the payment, though.
+
+Consensus library
+-----------------
+
+Starting from 0.10.0, the Bitcoin Core distribution includes a consensus library.
+
+The purpose of this library is to make the verification functionality that is
+critical to Bitcoin's consensus available to other applications, e.g. to language
+bindings such as [python-bitcoinlib](https://pypi.python.org/pypi/python-bitcoinlib) or
+alternative node implementations.
+
+This library is called `libbitcoinconsensus.so` (or, `.dll` for Windows).
+Its interface is defined in the C header [bitcoinconsensus.h](https://github.com/bitcoin/bitcoin/blob/0.10/src/script/bitcoinconsensus.h).
+
+In its initial version the API includes two functions:
+
+- `bitcoinconsensus_verify_script` verifies a script. It returns whether the indicated input of the provided serialized transaction
+correctly spends the passed scriptPubKey under additional constraints indicated by flags
+- `bitcoinconsensus_version` returns the API version, currently at an experimental `0`
+
+The functionality is planned to be extended to e.g. UTXO management in upcoming releases, but the interface
+for existing methods should remain stable.
+
+Standard script rules relaxed for P2SH addresses
+------------------------------------------------
+
+The IsStandard() rules have been almost completely removed for P2SH
+redemption scripts, allowing applications to make use of any valid
+script type, such as "n-of-m OR y", hash-locked oracle addresses, etc.
+While the Bitcoin protocol has always supported these types of script,
+actually using them on mainnet has been previously inconvenient as
+standard Bitcoin Core nodes wouldn't relay them to miners, nor would
+most miners include them in blocks they mined.
+
+bitcoin-tx
+----------
+
+It has been observed that many of the RPC functions offered by bitcoind are
+"pure functions", and operate independently of the bitcoind wallet. This
+included many of the RPC "raw transaction" API functions, such as
+createrawtransaction.
+
+bitcoin-tx is a newly introduced command line utility designed to enable easy
+manipulation of bitcoin transactions. A summary of its operation may be
+obtained via "bitcoin-tx --help" Transactions may be created or signed in a
+manner similar to the RPC raw tx API. Transactions may be updated, deleting
+inputs or outputs, or appending new inputs and outputs. Custom scripts may be
+easily composed using a simple text notation, borrowed from the bitcoin test
+suite.
+
+This tool may be used for experimenting with new transaction types, signing
+multi-party transactions, and many other uses. Long term, the goal is to
+deprecate and remove "pure function" RPC API calls, as those do not require a
+server round-trip to execute.
+
+Other utilities "bitcoin-key" and "bitcoin-script" have been proposed, making
+key and script operations easily accessible via command line.
+
+Mining and relay policy enhancements
+------------------------------------
+
+Bitcoin Core's block templates are now for version 3 blocks only, and any mining
+software relying on its `getblocktemplate` must be updated in parallel to use
+libblkmaker either version 0.4.2 or any version from 0.5.1 onward.
+If you are solo mining, this will affect you the moment you upgrade Bitcoin
+Core, which must be done prior to BIP66 achieving its 951/1001 status.
+If you are mining with the stratum mining protocol: this does not affect you.
+If you are mining with the getblocktemplate protocol to a pool: this will affect
+you at the pool operator's discretion, which must be no later than BIP66
+achieving its 951/1001 status.
+
+The `prioritisetransaction` RPC method has been added to enable miners to
+manipulate the priority of transactions on an individual basis.
+
+Bitcoin Core now supports BIP 22 long polling, so mining software can be
+notified immediately of new templates rather than having to poll periodically.
+
+Support for BIP 23 block proposals is now available in Bitcoin Core's
+`getblocktemplate` method. This enables miners to check the basic validity of
+their next block before expending work on it, reducing risks of accidental
+hardforks or mining invalid blocks.
+
+Two new options to control mining policy:
+- `-datacarrier=0/1` : Relay and mine "data carrier" (OP_RETURN) transactions
+if this is 1.
+- `-datacarriersize=n` : Maximum size, in bytes, we consider acceptable for
+"data carrier" outputs.
+
+The relay policy has changed to more properly implement the desired behavior of not
+relaying free (or very low fee) transactions unless they have a priority above the
+AllowFreeThreshold(), in which case they are relayed subject to the rate limiter.
+
+BIP 66: strict DER encoding for signatures
+------------------------------------------
+
+Bitcoin Core 0.10 implements BIP 66, which introduces block version 3, and a new
+consensus rule, which prohibits non-DER signatures. Such transactions have been
+non-standard since Bitcoin v0.8.0 (released in February 2013), but were
+technically still permitted inside blocks.
+
+This change breaks the dependency on OpenSSL's signature parsing, and is
+required if implementations would want to remove all of OpenSSL from the
+consensus code.
+
+The same miner-voting mechanism as in BIP 34 is used: when 751 out of a
+sequence of 1001 blocks have version number 3 or higher, the new consensus
+rule becomes active for those blocks. When 951 out of a sequence of 1001
+blocks have version number 3 or higher, it becomes mandatory for all blocks.
+
+Backward compatibility with current mining software is NOT provided, thus miners
+should read the first paragraph of "Mining and relay policy enhancements" above.
+
+0.10.0 Change log
+=================
+
+Detailed release notes follow. This overview includes changes that affect external
+behavior, not code moves, refactors or string updates.
+
+RPC:
+- `f923c07` Support IPv6 lookup in bitcoin-cli even when IPv6 only bound on localhost
+- `b641c9c` Fix addnode "onetry": Connect with OpenNetworkConnection
+- `171ca77` estimatefee / estimatepriority RPC methods
+- `b750cf1` Remove cli functionality from bitcoind
+- `f6984e8` Add "chain" to getmininginfo, improve help in getblockchaininfo
+- `99ddc6c` Add nLocalServices info to RPC getinfo
+- `cf0c47b` Remove getwork() RPC call
+- `2a72d45` prioritisetransaction <txid> <priority delta> <priority tx fee>
+- `e44fea5` Add an option `-datacarrier` to allow users to disable relaying/mining data carrier transactions
+- `2ec5a3d` Prevent easy RPC memory exhaustion attack
+- `d4640d7` Added argument to getbalance to include watchonly addresses and fixed errors in balance calculation
+- `83f3543` Added argument to listaccounts to include watchonly addresses
+- `952877e` Showing 'involvesWatchonly' property for transactions returned by 'listtransactions' and 'listsinceblock'. It is only appended when the transaction involves a watchonly address
+- `d7d5d23` Added argument to listtransactions and listsinceblock to include watchonly addresses
+- `f87ba3d` added includeWatchonly argument to 'gettransaction' because it affects balance calculation
+- `0fa2f88` added includedWatchonly argument to listreceivedbyaddress/...account
+- `6c37f7f` `getrawchangeaddress`: fail when keypool exhausted and wallet locked
+- `ff6a7af` getblocktemplate: longpolling support
+- `c4a321f` Add peerid to getpeerinfo to allow correlation with the logs
+- `1b4568c` Add vout to ListTransactions output
+- `b33bd7a` Implement "getchaintips" RPC command to monitor blockchain forks
+- `733177e` Remove size limit in RPC client, keep it in server
+- `6b5b7cb` Categorize rpc help overview
+- `6f2c26a` Closely track mempool byte total. Add "getmempoolinfo" RPC
+- `aa82795` Add detailed network info to getnetworkinfo RPC
+- `01094bd` Don't reveal whether password is <20 or >20 characters in RPC
+- `57153d4` rpc: Compute number of confirmations of a block from block height
+- `ff36cbe` getnetworkinfo: export local node's client sub-version string
+- `d14d7de` SanitizeString: allow '(' and ')'
+- `31d6390` Fixed setaccount accepting foreign address
+- `b5ec5fe` update getnetworkinfo help with subversion
+- `ad6e601` RPC additions after headers-first
+- `33dfbf5` rpc: Fix leveldb iterator leak, and flush before `gettxoutsetinfo`
+- `2aa6329` Enable customising node policy for datacarrier data size with a -datacarriersize option
+- `f877aaa` submitblock: Use a temporary CValidationState to determine accurately the outcome of ProcessBlock
+- `e69a587` submitblock: Support for returning specific rejection reasons
+- `af82884` Add "warmup mode" for RPC server
+- `e2655e0` Add unauthenticated HTTP REST interface to public blockchain data
+- `683dc40` Disable SSLv3 (in favor of TLS) for the RPC client and server
+- `44b4c0d` signrawtransaction: validate private key
+- `9765a50` Implement BIP 23 Block Proposal
+- `f9de17e` Add warning comment to getinfo
+
+Command-line options:
+- `ee21912` Use netmasks instead of wildcards for IP address matching
+- `deb3572` Add `-rpcbind` option to allow binding RPC port on a specific interface
+- `96b733e` Add `-version` option to get just the version
+- `1569353` Add `-stopafterblockimport` option
+- `77cbd46` Let -zapwallettxes recover transaction meta data
+- `1c750db` remove -tor compatibility code (only allow -onion)
+- `4aaa017` rework help messages for fee-related options
+- `4278b1d` Clarify error message when invalid -rpcallowip
+- `6b407e4` -datadir is now allowed in config files
+- `bdd5b58` Add option `-sysperms` to disable 077 umask (create new files with system default umask)
+- `cbe39a3` Add "bitcoin-tx" command line utility and supporting modules
+- `dbca89b` Trigger -alertnotify if network is upgrading without you
+- `ad96e7c` Make -reindex cope with out-of-order blocks
+- `16d5194` Skip reindexed blocks individually
+- `ec01243` --tracerpc option for regression tests
+- `f654f00` Change -genproclimit default to 1
+- `3c77714` Make -proxy set all network types, avoiding a connect leak
+- `57be955` Remove -printblock, -printblocktree, and -printblockindex
+- `ad3d208` remove -maxorphanblocks config parameter since it is no longer functional
+
+Block and transaction handling:
+- `7a0e84d` ProcessGetData(): abort if a block file is missing from disk
+- `8c93bf4` LoadBlockIndexDB(): Require block db reindex if any `blk*.dat` files are missing
+- `77339e5` Get rid of the static chainMostWork (optimization)
+- `4e0eed8` Allow ActivateBestChain to release its lock on cs_main
+- `18e7216` Push cs_mains down in ProcessBlock
+- `fa126ef` Avoid undefined behavior using CFlatData in CScript serialization
+- `7f3b4e9` Relax IsStandard rules for pay-to-script-hash transactions
+- `c9a0918` Add a skiplist to the CBlockIndex structure
+- `bc42503` Use unordered_map for CCoinsViewCache with salted hash (optimization)
+- `d4d3fbd` Do not flush the cache after every block outside of IBD (optimization)
+- `ad08d0b` Bugfix: make CCoinsViewMemPool support pruned entries in underlying cache
+- `5734d4d` Only remove actualy failed blocks from setBlockIndexValid
+- `d70bc52` Rework block processing benchmark code
+- `714a3e6` Only keep setBlockIndexValid entries that are possible improvements
+- `ea100c7` Reduce maximum coinscache size during verification (reduce memory usage)
+- `4fad8e6` Reject transactions with excessive numbers of sigops
+- `b0875eb` Allow BatchWrite to destroy its input, reducing copying (optimization)
+- `92bb6f2` Bypass reloading blocks from disk (optimization)
+- `2e28031` Perform CVerifyDB on pcoinsdbview instead of pcoinsTip (reduce memory usage)
+- `ab15b2e` Avoid copying undo data (optimization)
+- `341735e` Headers-first synchronization
+- `afc32c5` Fix rebuild-chainstate feature and improve its performance
+- `e11b2ce` Fix large reorgs
+- `ed6d1a2` Keep information about all block files in memory
+- `a48f2d6` Abstract context-dependent block checking from acceptance
+- `7e615f5` Fixed mempool sync after sending a transaction
+- `51ce901` Improve chainstate/blockindex disk writing policy
+- `a206950` Introduce separate flushing modes
+- `9ec75c5` Add a locking mechanism to IsInitialBlockDownload to ensure it never goes from false to true
+- `868d041` Remove coinbase-dependant transactions during reorg
+- `723d12c` Remove txn which are invalidated by coinbase maturity during reorg
+- `0cb8763` Check against MANDATORY flags prior to accepting to mempool
+- `8446262` Reject headers that build on an invalid parent
+- `008138c` Bugfix: only track UTXO modification after lookup
+
+P2P protocol and network code:
+- `f80cffa` Do not trigger a DoS ban if SCRIPT_VERIFY_NULLDUMMY fails
+- `c30329a` Add testnet DNS seed of Alex Kotenko
+- `45a4baf` Add testnet DNS seed of Andreas Schildbach
+- `f1920e8` Ping automatically every 2 minutes (unconditionally)
+- `806fd19` Allocate receive buffers in on the fly
+- `6ecf3ed` Display unknown commands received
+- `aa81564` Track peers' available blocks
+- `caf6150` Use async name resolving to improve net thread responsiveness
+- `9f4da19` Use pong receive time rather than processing time
+- `0127a9b` remove SOCKS4 support from core and GUI, use SOCKS5
+- `40f5cb8` Send rejects and apply DoS scoring for errors in direct block validation
+- `dc942e6` Introduce whitelisted peers
+- `c994d2e` prevent SOCKET leak in BindListenPort()
+- `a60120e` Add built-in seeds for .onion
+- `60dc8e4` Allow -onlynet=onion to be used
+- `3a56de7` addrman: Do not propagate obviously poor addresses onto the network
+- `6050ab6` netbase: Make SOCKS5 negotiation interruptible
+- `604ee2a` Remove tx from AlreadyAskedFor list once we receive it, not when we process it
+- `efad808` Avoid reject message feedback loops
+- `71697f9` Separate protocol versioning from clientversion
+- `20a5f61` Don't relay alerts to peers before version negotiation
+- `b4ee0bd` Introduce preferred download peers
+- `845c86d` Do not use third party services for IP detection
+- `12a49ca` Limit the number of new addressses to accumulate
+- `35e408f` Regard connection failures as attempt for addrman
+- `a3a7317` Introduce 10 minute block download timeout
+- `3022e7d` Require sufficent priority for relay of free transactions
+- `58fda4d` Update seed IPs, based on bitcoin.sipa.be crawler data
+- `18021d0` Remove bitnodes.io from dnsseeds.
+
+Validation:
+- `6fd7ef2` Also switch the (unused) verification code to low-s instead of even-s
+- `584a358` Do merkle root and txid duplicates check simultaneously
+- `217a5c9` When transaction outputs exceed inputs, show the offending amounts so as to aid debugging
+- `f74fc9b` Print input index when signature validation fails, to aid debugging
+- `6fd59ee` script.h: set_vch() should shift a >32 bit value
+- `d752ba8` Add SCRIPT_VERIFY_SIGPUSHONLY (BIP62 rule 2) (test only)
+- `698c6ab` Add SCRIPT_VERIFY_MINIMALDATA (BIP62 rules 3 and 4) (test only)
+- `ab9edbd` script: create sane error return codes for script validation and remove logging
+- `219a147` script: check ScriptError values in script tests
+- `0391423` Discourage NOPs reserved for soft-fork upgrades
+- `98b135f` Make STRICTENC invalid pubkeys fail the script rather than the opcode
+- `307f7d4` Report script evaluation failures in log and reject messages
+- `ace39db` consensus: guard against openssl's new strict DER checks
+- `12b7c44` Improve robustness of DER recoding code
+- `76ce5c8` fail immediately on an empty signature
+
+Build system:
+- `f25e3ad` Fix build in OS X 10.9
+- `65e8ba4` build: Switch to non-recursive make
+- `460b32d` build: fix broken boost chrono check on some platforms
+- `9ce0774` build: Fix windows configure when using --with-qt-libdir
+- `ea96475` build: Add mention of --disable-wallet to bdb48 error messages
+- `1dec09b` depends: add shared dependency builder
+- `c101c76` build: Add --with-utils (bitcoin-cli and bitcoin-tx, default=yes). Help string consistency tweaks. Target sanity check fix
+- `e432a5f` build: add option for reducing exports (v2)
+- `6134b43` Fixing condition 'sabotaging' MSVC build
+- `af0bd5e` osx: fix signing to make Gatekeeper happy (again)
+- `a7d1f03` build: fix dynamic boost check when --with-boost= is used
+- `d5fd094` build: fix qt test build when libprotobuf is in a non-standard path
+- `2cf5f16` Add libbitcoinconsensus library
+- `914868a` build: add a deterministic dmg signer
+- `2d375fe` depends: bump openssl to 1.0.1k
+- `b7a4ecc` Build: Only check for boost when building code that requires it
+
+Wallet:
+- `b33d1f5` Use fee/priority estimates in wallet CreateTransaction
+- `4b7b1bb` Sanity checks for estimates
+- `c898846` Add support for watch-only addresses
+- `d5087d1` Use script matching rather than destination matching for watch-only
+- `d88af56` Fee fixes
+- `a35b55b` Dont run full check every time we decrypt wallet
+- `3a7c348` Fix make_change to not create half-satoshis
+- `f606bb9` fix a possible memory leak in CWalletDB::Recover
+- `870da77` fix possible memory leaks in CWallet::EncryptWallet
+- `ccca27a` Watch-only fixes
+- `9b1627d` [Wallet] Reduce minTxFee for transaction creation to 1000 satoshis
+- `a53fd41` Deterministic signing
+- `15ad0b5` Apply AreSane() checks to the fees from the network
+- `11855c1` Enforce minRelayTxFee on wallet created tx and add a maxtxfee option
+
+GUI:
+- `c21c74b` osx: Fix missing dock menu with qt5
+- `b90711c` Fix Transaction details shows wrong To:
+- `516053c` Make links in 'About Bitcoin Core' clickable
+- `bdc83e8` Ensure payment request network matches client network
+- `65f78a1` Add GUI view of peer information
+- `06a91d9` VerifyDB progress reporting
+- `fe6bff2` Add BerkeleyDB version info to RPCConsole
+- `b917555` PeerTableModel: Fix potential deadlock. #4296
+- `dff0e3b` Improve rpc console history behavior
+- `95a9383` Remove CENT-fee-rule from coin control completely
+- `56b07d2` Allow setting listen via GUI
+- `d95ba75` Log messages with type>QtDebugMsg as non-debug
+- `8969828` New status bar Unit Display Control and related changes
+- `674c070` seed OpenSSL PNRG with Windows event data
+- `509f926` Payment request parsing on startup now only changes network if a valid network name is specified
+- `acd432b` Prevent balloon-spam after rescan
+- `7007402` Implement SI-style (thin space) thoudands separator
+- `91cce17` Use fixed-point arithmetic in amount spinbox
+- `bdba2dd` Remove an obscure option no-one cares about
+- `bd0aa10` Replace the temporary file hack currently used to change Bitcoin-Qt's dock icon (OS X) with a buffer-based solution
+- `94e1b9e` Re-work overviewpage UI
+- `8bfdc9a` Better looking trayicon
+- `b197bf3` disable tray interactions when client model set to 0
+- `1c5f0af` Add column Watch-only to transactions list
+- `21f139b` Fix tablet crash. closes #4854
+- `e84843c` Broken addresses on command line no longer trigger testnet
+- `a49f11d` Change splash screen to normal window
+- `1f9be98` Disable App Nap on OSX 10.9+
+- `27c3e91` Add proxy to options overridden if necessary
+- `4bd1185` Allow "emergency" shutdown during startup
+- `d52f072` Don't show wallet options in the preferences menu when running with -disablewallet
+- `6093aa1` Qt: QProgressBar CPU-Issue workaround
+- `0ed9675` [Wallet] Add global boolean whether to send free transactions (default=true)
+- `ed3e5e4` [Wallet] Add global boolean whether to pay at least the custom fee (default=true)
+- `e7876b2` [Wallet] Prevent user from paying a non-sense fee
+- `c1c9d5b` Add Smartfee to GUI
+- `e0a25c5` Make askpassphrase dialog behave more sanely
+- `94b362d` On close of splashscreen interrupt verifyDB
+- `b790d13` English translation update
+- `8543b0d` Correct tooltip on address book page
+
+Tests:
+- `b41e594` Fix script test handling of empty scripts
+- `d3a33fc` Test CHECKMULTISIG with m == 0 and n == 0
+- `29c1749` Let tx (in)valid tests use any SCRIPT_VERIFY flag
+- `6380180` Add rejection of non-null CHECKMULTISIG dummy values
+- `21bf3d2` Add tests for BoostAsioToCNetAddr
+- `b5ad5e7` Add Python test for -rpcbind and -rpcallowip
+- `9ec0306` Add CODESEPARATOR/FindAndDelete() tests
+- `75ebced` Added many rpc wallet tests
+- `0193fb8` Allow multiple regression tests to run at once
+- `92a6220` Hook up sanity checks
+- `3820e01` Extend and move all crypto tests to crypto_tests.cpp
+- `3f9a019` added list/get received by address/ account tests
+- `a90689f` Remove timing-based signature cache unit test
+- `236982c` Add skiplist unit tests
+- `f4b00be` Add CChain::GetLocator() unit test
+- `b45a6e8` Add test for getblocktemplate longpolling
+- `cdf305e` Set -discover=0 in regtest framework
+- `ed02282` additional test for OP_SIZE in script_valid.json
+- `0072d98` script tests: BOOLAND, BOOLOR decode to integer
+- `833ff16` script tests: values that overflow to 0 are true
+- `4cac5db` script tests: value with trailing 0x00 is true
+- `89101c6` script test: test case for 5-byte bools
+- `d2d9dc0` script tests: add tests for CHECKMULTISIG limits
+- `d789386` Add "it works" test for bitcoin-tx
+- `df4d61e` Add bitcoin-tx tests
+- `aa41ac2` Test IsPushOnly() with invalid push
+- `6022b5d` Make `script_{valid,invalid}.json` validation flags configurable
+- `8138cbe` Add automatic script test generation, and actual checksig tests
+- `ed27e53` Add coins_tests with a large randomized CCoinViewCache test
+- `9df9cf5` Make SCRIPT_VERIFY_STRICTENC compatible with BIP62
+- `dcb9846` Extend getchaintips RPC test
+- `554147a` Ensure MINIMALDATA invalid tests can only fail one way
+- `dfeec18` Test every numeric-accepting opcode for correct handling of the numeric minimal encoding rule
+- `2b62e17` Clearly separate PUSHDATA and numeric argument MINIMALDATA tests
+- `16d78bd` Add valid invert of invalid every numeric opcode tests
+- `f635269` tests: enable alertnotify test for Windows
+- `7a41614` tests: allow rpc-tests to get filenames for bitcoind and bitcoin-cli from the environment
+- `5122ea7` tests: fix forknotify.py on windows
+- `fa7f8cd` tests: remove old pull-tester scripts
+- `7667850` tests: replace the old (unused since Travis) tests with new rpc test scripts
+- `f4e0aef` Do signature-s negation inside the tests
+- `1837987` Optimize -regtest setgenerate block generation
+- `2db4c8a` Fix node ranges in the test framework
+- `a8b2ce5` regression test only setmocktime RPC call
+- `daf03e7` RPC tests: create initial chain with specific timestamps
+- `8656dbb` Port/fix txnmall.sh regression test
+- `ca81587` Test the exact order of CHECKMULTISIG sig/pubkey evaluation
+- `7357893` Prioritize and display -testsafemode status in UI
+- `f321d6b` Add key generation/verification to ECC sanity check
+- `132ea9b` miner_tests: Disable checkpoints so they don't fail the subsidy-change test
+- `bc6cb41` QA RPC tests: Add tests block block proposals
+- `f67a9ce` Use deterministically generated script tests
+- `11d7a7d` [RPC] add rpc-test for http keep-alive (persistent connections)
+- `34318d7` RPC-test based on invalidateblock for mempool coinbase spends
+- `76ec867` Use actually valid transactions for script tests
+- `c8589bf` Add actual signature tests
+- `e2677d7` Fix smartfees test for change to relay policy
+- `263b65e` tests: run sanity checks in tests too
+
+Miscellaneous:
+- `122549f` Fix incorrect checkpoint data for testnet3
+- `5bd02cf` Log used config file to debug.log on startup
+- `68ba85f` Updated Debian example bitcoin.conf with config from wiki + removed some cruft and updated comments
+- `e5ee8f0` Remove -beta suffix
+- `38405ac` Add comment regarding experimental-use service bits
+- `be873f6` Issue warning if collecting RandSeed data failed
+- `8ae973c` Allocate more space if necessary in RandSeedAddPerfMon
+- `675bcd5` Correct comment for 15-of-15 p2sh script size
+- `fda3fed` libsecp256k1 integration
+- `2e36866` Show nodeid instead of addresses in log (for anonymity) unless otherwise requested
+- `cd01a5e` Enable paranoid corruption checks in LevelDB >= 1.16
+- `9365937` Add comment about never updating nTimeOffset past 199 samples
+- `403c1bf` contrib: remove getwork-based pyminer (as getwork API call has been removed)
+- `0c3e101` contrib: Added systemd .service file in order to help distributions integrate bitcoind
+- `0a0878d` doc: Add new DNSseed policy
+- `2887bff` Update coding style and add .clang-format
+- `5cbda4f` Changed LevelDB cursors to use scoped pointers to ensure destruction when going out of scope
+- `b4a72a7` contrib/linearize: split output files based on new-timestamp-year or max-file-size
+- `e982b57` Use explicit fflush() instead of setvbuf()
+- `234bfbf` contrib: Add init scripts and docs for Upstart and OpenRC
+- `01c2807` Add warning about the merkle-tree algorithm duplicate txid flaw
+- `d6712db` Also create pid file in non-daemon mode
+- `772ab0e` contrib: use batched JSON-RPC in linarize-hashes (optimization)
+- `7ab4358` Update bash-completion for v0.10
+- `6e6a36c` contrib: show pull # in prompt for github-merge script
+- `5b9f842` Upgrade leveldb to 1.18, make chainstate databases compatible between ARM and x86 (issue #2293)
+- `4e7c219` Catch UTXO set read errors and shutdown
+- `867c600` Catch LevelDB errors during flush
+- `06ca065` Fix CScriptID(const CScript& in) in empty script case
+
+Credits
+=======
+
+Thanks to everyone who contributed to this release:
+
+- 21E14
+- Adam Weiss
+- Aitor Pazos
+- Alexander Jeng
+- Alex Morcos
+- Alon Muroch
+- Andreas Schildbach
+- Andrew Poelstra
+- Andy Alness
+- Ashley Holman
+- Benedict Chan
+- Ben Holden-Crowther
+- Bryan Bishop
+- BtcDrak
+- Christian von Roques
+- Clinton Christian
+- Cory Fields
+- Cozz Lovan
+- daniel
+- Daniel Kraft
+- David Hill
+- Derek701
+- dexX7
+- dllud
+- Dominyk Tiller
+- Doug
+- elichai
+- elkingtowa
+- ENikS
+- Eric Shaw
+- Federico Bond
+- Francis GASCHET
+- Gavin Andresen
+- Giuseppe Mazzotta
+- Glenn Willen
+- Gregory Maxwell
+- gubatron
+- HarryWu
+- himynameismartin
+- Huang Le
+- Ian Carroll
+- imharrywu
+- Jameson Lopp
+- Janusz Lenar
+- JaSK
+- Jeff Garzik
+- JL2035
+- Johnathan Corgan
+- Jonas Schnelli
+- jtimon
+- Julian Haight
+- Kamil Domanski
+- kazcw
+- kevin
+- kiwigb
+- Kosta Zertsekel
+- LongShao007
+- Luke Dashjr
+- Mark Friedenbach
+- Mathy Vanvoorden
+- Matt Corallo
+- Matthew Bogosian
+- Micha
+- Michael Ford
+- Mike Hearn
+- mrbandrews
+- mruddy
+- ntrgn
+- Otto Allmendinger
+- paveljanik
+- Pavel Vasin
+- Peter Todd
+- phantomcircuit
+- Philip Kaufmann
+- Pieter Wuille
+- pryds
+- randy-waterhouse
+- R E Broadley
+- Rose Toomey
+- Ross Nicoll
+- Roy Badami
+- Ruben Dario Ponticelli
+- Rune K. Svendsen
+- Ryan X. Charles
+- Saivann
+- sandakersmann
+- SergioDemianLerner
+- shshshsh
+- sinetek
+- Stuart Cardall
+- Suhas Daftuar
+- Tawanda Kembo
+- Teran McKinney
+- tm314159
+- Tom Harding
+- Trevin Hofmann
+- Whit J
+- Wladimir J. van der Laan
+- Yoichi Hirai
+- Zak Wilcox
+
+As well as everyone that helped translating on [Transifex](https://www.transifex.com/projects/p/bitcoin/).
+
diff --git a/doc/release-notes/release-notes-0.10.1.md b/doc/release-notes/release-notes-0.10.1.md
new file mode 100644
index 0000000000..5e939600a0
--- /dev/null
+++ b/doc/release-notes/release-notes-0.10.1.md
@@ -0,0 +1,143 @@
+Bitcoin Core version 0.10.1 is now available from:
+
+ <https://bitcoin.org/bin/bitcoin-core-0.10.1/>
+
+This is a new minor version release, bringing bug fixes and translation
+updates. It is recommended to upgrade to this version.
+
+Please report bugs using the issue tracker at github:
+
+ <https://github.com/bitcoin/bitcoin/issues>
+
+Upgrading and downgrading
+=========================
+
+How to Upgrade
+--------------
+
+If you are running an older version, shut it down. Wait until it has completely
+shut down (which might take a few minutes for older versions), then run the
+installer (on Windows) or just copy over /Applications/Bitcoin-Qt (on Mac) or
+bitcoind/bitcoin-qt (on Linux).
+
+Downgrade warning
+------------------
+
+Because release 0.10.0 and later makes use of headers-first synchronization and
+parallel block download (see further), the block files and databases are not
+backwards-compatible with pre-0.10 versions of Bitcoin Core or other software:
+
+* Blocks will be stored on disk out of order (in the order they are
+received, really), which makes it incompatible with some tools or
+other programs. Reindexing using earlier versions will also not work
+anymore as a result of this.
+
+* The block index database will now hold headers for which no block is
+stored on disk, which earlier versions won't support.
+
+If you want to be able to downgrade smoothly, make a backup of your entire data
+directory. Without this your node will need start syncing (or importing from
+bootstrap.dat) anew afterwards. It is possible that the data from a completely
+synchronised 0.10 node may be usable in older versions as-is, but this is not
+supported and may break as soon as the older version attempts to reindex.
+
+This does not affect wallet forward or backward compatibility.
+
+Notable changes
+===============
+
+This is a minor release and hence there are no notable changes.
+For the notable changes in 0.10, refer to the release notes for the
+0.10.0 release at https://github.com/bitcoin/bitcoin/blob/v0.10.0/doc/release-notes.md
+
+0.10.1 Change log
+=================
+
+Detailed release notes follow. This overview includes changes that affect external
+behavior, not code moves, refactors or string updates.
+
+RPC:
+- `7f502be` fix crash: createmultisig and addmultisigaddress
+- `eae305f` Fix missing lock in submitblock
+
+Block (database) and transaction handling:
+- `1d2cdd2` Fix InvalidateBlock to add chainActive.Tip to setBlockIndexCandidates
+- `c91c660` fix InvalidateBlock to repopulate setBlockIndexCandidates
+- `002c8a2` fix possible block db breakage during re-index
+- `a1f425b` Add (optional) consistency check for the block chain data structures
+- `1c62e84` Keep mempool consistent during block-reorgs
+- `57d1f46` Fix CheckBlockIndex for reindex
+- `bac6fca` Set nSequenceId when a block is fully linked
+
+P2P protocol and network code:
+- `78f64ef` don't trickle for whitelisted nodes
+- `ca301bf` Reduce fingerprinting through timestamps in 'addr' messages.
+- `200f293` Ignore getaddr messages on Outbound connections.
+- `d5d8998` Limit message sizes before transfer
+- `aeb9279` Better fingerprinting protection for non-main-chain getdatas.
+- `cf0218f` Make addrman's bucket placement deterministic (countermeasure 1 against eclipse attacks, see http://cs-people.bu.edu/heilman/eclipse/)
+- `0c6f334` Always use a 50% chance to choose between tried and new entries (countermeasure 2 against eclipse attacks)
+- `214154e` Do not bias outgoing connections towards fresh addresses (countermeasure 2 against eclipse attacks)
+- `aa587d4` Scale up addrman (countermeasure 6 against eclipse attacks)
+- `139cd81` Cap nAttempts penalty at 8 and switch to pow instead of a division loop
+
+Validation:
+- `d148f62` Acquire CCheckQueue's lock to avoid race condition
+
+Build system:
+- `8752b5c` 0.10 fix for crashes on OSX 10.6
+
+Wallet:
+- N/A
+
+GUI:
+- `2c08406` some mac specifiy cleanup (memory handling, unnecessary code)
+- `81145a6` fix OSX dock icon window reopening
+- `786cf72` fix a issue where "command line options"-action overwrite "Preference"-action (on OSX)
+
+Tests:
+- `1117378` add RPC test for InvalidateBlock
+
+Miscellaneous:
+- `c9e022b` Initialization: set Boost path locale in main thread
+- `23126a0` Sanitize command strings before logging them.
+- `323de27` Initialization: setup environment before starting QT tests
+- `7494e09` Initialization: setup environment before starting tests
+- `df45564` Initialization: set fallback locale as environment variable
+
+Credits
+=======
+
+Thanks to everyone who directly contributed to this release:
+
+- Alex Morcos
+- Cory Fields
+- dexX7
+- fsb4000
+- Gavin Andresen
+- Gregory Maxwell
+- Ivan Pustogarov
+- Jonas Schnelli
+- Matt Corallo
+- mrbandrews
+- Pieter Wuille
+- Ruben de Vries
+- Suhas Daftuar
+- Wladimir J. van der Laan
+
+And all those who contributed additional code review and/or security research:
+- 21E14
+- Alison Kendler
+- Aviv Zohar
+- Ethan Heilman
+- Evil-Knievel
+- fanquake
+- Jeff Garzik
+- Jonas Nick
+- Luke Dashjr
+- Patrick Strateman
+- Philip Kaufmann
+- Sergio Demian Lerner
+- Sharon Goldberg
+
+As well as everyone that helped translating on [Transifex](https://www.transifex.com/projects/p/bitcoin/).
diff --git a/doc/release-notes/release-notes-0.10.2.md b/doc/release-notes/release-notes-0.10.2.md
new file mode 100644
index 0000000000..192ed69d29
--- /dev/null
+++ b/doc/release-notes/release-notes-0.10.2.md
@@ -0,0 +1,86 @@
+Bitcoin Core version 0.10.2 is now available from:
+
+ <https://bitcoin.org/bin/bitcoin-core-0.10.2/>
+
+This is a new minor version release, bringing minor bug fixes and translation
+updates. It is recommended to upgrade to this version.
+
+Please report bugs using the issue tracker at github:
+
+ <https://github.com/bitcoin/bitcoin/issues>
+
+Upgrading and downgrading
+=========================
+
+How to Upgrade
+--------------
+
+If you are running an older version, shut it down. Wait until it has completely
+shut down (which might take a few minutes for older versions), then run the
+installer (on Windows) or just copy over /Applications/Bitcoin-Qt (on Mac) or
+bitcoind/bitcoin-qt (on Linux).
+
+Downgrade warning
+------------------
+
+Because release 0.10.0 and later makes use of headers-first synchronization and
+parallel block download (see further), the block files and databases are not
+backwards-compatible with pre-0.10 versions of Bitcoin Core or other software:
+
+* Blocks will be stored on disk out of order (in the order they are
+received, really), which makes it incompatible with some tools or
+other programs. Reindexing using earlier versions will also not work
+anymore as a result of this.
+
+* The block index database will now hold headers for which no block is
+stored on disk, which earlier versions won't support.
+
+If you want to be able to downgrade smoothly, make a backup of your entire data
+directory. Without this your node will need start syncing (or importing from
+bootstrap.dat) anew afterwards. It is possible that the data from a completely
+synchronised 0.10 node may be usable in older versions as-is, but this is not
+supported and may break as soon as the older version attempts to reindex.
+
+This does not affect wallet forward or backward compatibility.
+
+Notable changes
+===============
+
+This fixes a serious problem on Windows with data directories that have non-ASCII
+characters (https://github.com/bitcoin/bitcoin/issues/6078).
+
+For other platforms there are no notable changes.
+
+For the notable changes in 0.10, refer to the release notes
+at https://github.com/bitcoin/bitcoin/blob/v0.10.0/doc/release-notes.md
+
+0.10.2 Change log
+=================
+
+Detailed release notes follow. This overview includes changes that affect external
+behavior, not code moves, refactors or string updates.
+
+Wallet:
+- `824c011` fix boost::get usage with boost 1.58
+
+Miscellaneous:
+- `da65606` Avoid crash on start in TestBlockValidity with gen=1.
+- `424ae66` don't imbue boost::filesystem::path with locale "C" on windows (fixes #6078)
+
+Credits
+=======
+
+Thanks to everyone who directly contributed to this release:
+
+- Cory Fields
+- Gregory Maxwell
+- Jonas Schnelli
+- Wladimir J. van der Laan
+
+And all those who contributed additional code review and/or security research:
+
+- dexX7
+- Pieter Wuille
+- vayvanne
+
+As well as everyone that helped translating on [Transifex](https://www.transifex.com/projects/p/bitcoin/).
diff --git a/doc/release-notes/release-notes-0.10.3.md b/doc/release-notes/release-notes-0.10.3.md
new file mode 100644
index 0000000000..8a110e562c
--- /dev/null
+++ b/doc/release-notes/release-notes-0.10.3.md
@@ -0,0 +1,165 @@
+Bitcoin Core version 0.10.3 is now available from:
+
+ <https://bitcoin.org/bin/bitcoin-core-0.10.3/>
+
+This is a new minor version release, bringing security fixes and translation
+updates. It is recommended to upgrade to this version as soon as possible.
+
+Please report bugs using the issue tracker at github:
+
+ <https://github.com/bitcoin/bitcoin/issues>
+
+Upgrading and downgrading
+=========================
+
+How to Upgrade
+--------------
+
+If you are running an older version, shut it down. Wait until it has completely
+shut down (which might take a few minutes for older versions), then run the
+installer (on Windows) or just copy over /Applications/Bitcoin-Qt (on Mac) or
+bitcoind/bitcoin-qt (on Linux).
+
+Downgrade warning
+------------------
+
+Because release 0.10.0 and later makes use of headers-first synchronization and
+parallel block download (see further), the block files and databases are not
+backwards-compatible with pre-0.10 versions of Bitcoin Core or other software:
+
+* Blocks will be stored on disk out of order (in the order they are
+received, really), which makes it incompatible with some tools or
+other programs. Reindexing using earlier versions will also not work
+anymore as a result of this.
+
+* The block index database will now hold headers for which no block is
+stored on disk, which earlier versions won't support.
+
+If you want to be able to downgrade smoothly, make a backup of your entire data
+directory. Without this your node will need start syncing (or importing from
+bootstrap.dat) anew afterwards. It is possible that the data from a completely
+synchronised 0.10 node may be usable in older versions as-is, but this is not
+supported and may break as soon as the older version attempts to reindex.
+
+This does not affect wallet forward or backward compatibility.
+
+Notable changes
+===============
+
+Fix buffer overflow in bundled upnp
+------------------------------------
+
+Bundled miniupnpc was updated to 1.9.20151008. This fixes a buffer overflow in
+the XML parser during initial network discovery.
+
+Details can be found here: http://talosintel.com/reports/TALOS-2015-0035/
+
+This applies to the distributed executables only, not when building from source or
+using distribution provided packages.
+
+Additionally, upnp has been disabled by default. This may result in a lower
+number of reachable nodes on IPv4, however this prevents future libupnpc
+vulnerabilities from being a structural risk to the network
+(see https://github.com/bitcoin/bitcoin/pull/6795).
+
+Test for LowS signatures before relaying
+-----------------------------------------
+
+Make the node require the canonical 'low-s' encoding for ECDSA signatures when
+relaying or mining. This removes a nuisance malleability vector.
+
+Consensus behavior is unchanged.
+
+If widely deployed this change would eliminate the last remaining known vector
+for nuisance malleability on SIGHASH_ALL P2PKH transactions. On the down-side
+it will block most transactions made by sufficiently out of date software.
+
+Unlike the other avenues to change txids on transactions this
+one was randomly violated by all deployed bitcoin software prior to
+its discovery. So, while other malleability vectors where made
+non-standard as soon as they were discovered, this one has remained
+permitted. Even BIP62 did not propose applying this rule to
+old version transactions, but conforming implementations have become
+much more common since BIP62 was initially written.
+
+Bitcoin Core has produced compatible signatures since a28fb70e in
+September 2013, but this didn't make it into a release until 0.9
+in March 2014; Bitcoinj has done so for a similar span of time.
+Bitcoinjs and electrum have been more recently updated.
+
+This does not replace the need for BIP62 or similar, as miners can
+still cooperate to break transactions. Nor does it replace the
+need for wallet software to handle malleability sanely[1]. This
+only eliminates the cheap and irritating DOS attack.
+
+[1] On the Malleability of Bitcoin Transactions
+Marcin Andrychowicz, Stefan Dziembowski, Daniel Malinowski, Łukasz Mazurek
+http://fc15.ifca.ai/preproceedings/bitcoin/paper_9.pdf
+
+Minimum relay fee default increase
+-----------------------------------
+
+The default for the `-minrelaytxfee` setting has been increased from `0.00001`
+to `0.00005`.
+
+This is necessitated by the current transaction flooding, causing
+outrageous memory usage on nodes due to the mempool ballooning. This is a
+temporary measure, bridging the time until a dynamic method for determining
+this fee is merged (which will be in 0.12).
+
+(see https://github.com/bitcoin/bitcoin/pull/6793, as well as the 0.11.0
+release notes, in which this value was suggested)
+
+0.10.3 Change log
+=================
+
+Detailed release notes follow. This overview includes changes that affect external
+behavior, not code moves, refactors or string updates.
+
+- #6186 `e4a7d51` Fix two problems in CSubnet parsing
+- #6153 `ebd7d8d` Parameter interaction: disable upnp if -proxy set
+- #6203 `ecc96f5` Remove P2SH coinbase flag, no longer interesting
+- #6226 `181771b` json: fail read_string if string contains trailing garbage
+- #6244 `09334e0` configure: Detect (and reject) LibreSSL
+- #6276 `0fd8464` Fix getbalance * 0
+- #6274 `be64204` Add option `-alerts` to opt out of alert system
+- #6319 `3f55638` doc: update mailing list address
+- #6438 `7e66e9c` openssl: avoid config file load/race
+- #6439 `255eced` Updated URL location of netinstall for Debian
+- #6412 `0739e6e` Test whether created sockets are select()able
+- #6694 `f696ea1` [QT] fix thin space word wrap line brake issue
+- #6704 `743cc9e` Backport bugfixes to 0.10
+- #6769 `1cea6b0` Test LowS in standardness, removes nuisance malleability vector.
+- #6789 `093d7b5` Update miniupnpc to 1.9.20151008
+- #6795 `f2778e0` net: Disable upnp by default
+- #6797 `91ef4d9` Do not store more than 200 timedata samples
+- #6793 `842c48d` Bump minrelaytxfee default
+
+Credits
+=======
+
+Thanks to everyone who directly contributed to this release:
+
+- Adam Weiss
+- Alex Morcos
+- Casey Rodarmor
+- Cory Fields
+- fanquake
+- Gregory Maxwell
+- Jonas Schnelli
+- J Ross Nicoll
+- Luke Dashjr
+- Pavel Vasin
+- Pieter Wuille
+- randy-waterhouse
+- ฿tcDrak
+- Tom Harding
+- Veres Lajos
+- Wladimir J. van der Laan
+
+And all those who contributed additional code review and/or security research:
+
+- timothy on IRC for reporting the issue
+- Vulnerability in miniupnp discovered by Aleksandar Nikolic of Cisco Talos
+
+As well as everyone that helped translating on [Transifex](https://www.transifex.com/projects/p/bitcoin/).
diff --git a/doc/release-notes/release-notes-0.11.1.md b/doc/release-notes/release-notes-0.11.1.md
new file mode 100644
index 0000000000..799205691e
--- /dev/null
+++ b/doc/release-notes/release-notes-0.11.1.md
@@ -0,0 +1,172 @@
+Bitcoin Core version 0.11.1 is now available from:
+
+ <https://bitcoin.org/bin/bitcoin-core-0.11.1/>
+
+This is a new minor version release, bringing security fixes. It is recommended
+to upgrade to this version as soon as possible.
+
+Please report bugs using the issue tracker at github:
+
+ <https://github.com/bitcoin/bitcoin/issues>
+
+Upgrading and downgrading
+=========================
+
+How to Upgrade
+--------------
+
+If you are running an older version, shut it down. Wait until it has completely
+shut down (which might take a few minutes for older versions), then run the
+installer (on Windows) or just copy over /Applications/Bitcoin-Qt (on Mac) or
+bitcoind/bitcoin-qt (on Linux).
+
+Downgrade warning
+------------------
+
+Because release 0.10.0 and later makes use of headers-first synchronization and
+parallel block download (see further), the block files and databases are not
+backwards-compatible with pre-0.10 versions of Bitcoin Core or other software:
+
+* Blocks will be stored on disk out of order (in the order they are
+received, really), which makes it incompatible with some tools or
+other programs. Reindexing using earlier versions will also not work
+anymore as a result of this.
+
+* The block index database will now hold headers for which no block is
+stored on disk, which earlier versions won't support.
+
+If you want to be able to downgrade smoothly, make a backup of your entire data
+directory. Without this your node will need start syncing (or importing from
+bootstrap.dat) anew afterwards. It is possible that the data from a completely
+synchronised 0.10 node may be usable in older versions as-is, but this is not
+supported and may break as soon as the older version attempts to reindex.
+
+This does not affect wallet forward or backward compatibility. There are no
+known problems when downgrading from 0.11.x to 0.10.x.
+
+Notable changes
+===============
+
+Fix buffer overflow in bundled upnp
+------------------------------------
+
+Bundled miniupnpc was updated to 1.9.20151008. This fixes a buffer overflow in
+the XML parser during initial network discovery.
+
+Details can be found here: http://talosintel.com/reports/TALOS-2015-0035/
+
+This applies to the distributed executables only, not when building from source or
+using distribution provided packages.
+
+Additionally, upnp has been disabled by default. This may result in a lower
+number of reachable nodes on IPv4, however this prevents future libupnpc
+vulnerabilities from being a structural risk to the network
+(see https://github.com/bitcoin/bitcoin/pull/6795).
+
+Test for LowS signatures before relaying
+-----------------------------------------
+
+Make the node require the canonical 'low-s' encoding for ECDSA signatures when
+relaying or mining. This removes a nuisance malleability vector.
+
+Consensus behavior is unchanged.
+
+If widely deployed this change would eliminate the last remaining known vector
+for nuisance malleability on SIGHASH_ALL P2PKH transactions. On the down-side
+it will block most transactions made by sufficiently out of date software.
+
+Unlike the other avenues to change txids on transactions this
+one was randomly violated by all deployed bitcoin software prior to
+its discovery. So, while other malleability vectors where made
+non-standard as soon as they were discovered, this one has remained
+permitted. Even BIP62 did not propose applying this rule to
+old version transactions, but conforming implementations have become
+much more common since BIP62 was initially written.
+
+Bitcoin Core has produced compatible signatures since a28fb70e in
+September 2013, but this didn't make it into a release until 0.9
+in March 2014; Bitcoinj has done so for a similar span of time.
+Bitcoinjs and electrum have been more recently updated.
+
+This does not replace the need for BIP62 or similar, as miners can
+still cooperate to break transactions. Nor does it replace the
+need for wallet software to handle malleability sanely[1]. This
+only eliminates the cheap and irritating DOS attack.
+
+[1] On the Malleability of Bitcoin Transactions
+Marcin Andrychowicz, Stefan Dziembowski, Daniel Malinowski, Łukasz Mazurek
+http://fc15.ifca.ai/preproceedings/bitcoin/paper_9.pdf
+
+Minimum relay fee default increase
+-----------------------------------
+
+The default for the `-minrelaytxfee` setting has been increased from `0.00001`
+to `0.00005`.
+
+This is necessitated by the current transaction flooding, causing
+outrageous memory usage on nodes due to the mempool ballooning. This is a
+temporary measure, bridging the time until a dynamic method for determining
+this fee is merged (which will be in 0.12).
+
+(see https://github.com/bitcoin/bitcoin/pull/6793, as well as the 0.11
+release notes, in which this value was suggested)
+
+0.11.1 Change log
+=================
+
+Detailed release notes follow. This overview includes changes that affect
+behavior, not code moves, refactors and string updates. For convenience in locating
+the code changes and accompanying discussion, both the pull request and
+git merge commit are mentioned.
+
+- #6438 `2531438` openssl: avoid config file load/race
+- #6439 `980f820` Updated URL location of netinstall for Debian
+- #6384 `8e5a969` qt: Force TLS1.0+ for SSL connections
+- #6471 `92401c2` Depends: bump to qt 5.5
+- #6224 `93b606a` Be even stricter in processing unrequested blocks
+- #6571 `100ac4e` libbitcoinconsensus: avoid a crash in multi-threaded environments
+- #6545 `649f5d9` Do not store more than 200 timedata samples.
+- #6694 `834e299` [QT] fix thin space word wrap line break issue
+- #6703 `1cd7952` Backport bugfixes to 0.11
+- #6750 `5ed8d0b` Recent rejects backport to v0.11
+- #6769 `71cc9d9` Test LowS in standardness, removes nuisance malleability vector.
+- #6789 `b4ad73f` Update miniupnpc to 1.9.20151008
+- #6785 `b4dc33e` Backport to v0.11: In (strCommand == "tx"), return if AlreadyHave()
+- #6412 `0095b9a` Test whether created sockets are select()able
+- #6795 `4dbcec0` net: Disable upnp by default
+- #6793 `e7bcc4a` Bump minrelaytxfee default
+
+Credits
+=======
+
+Thanks to everyone who directly contributed to this release:
+
+- Adam Weiss
+- Alex Morcos
+- Casey Rodarmor
+- Cory Fields
+- fanquake
+- Gregory Maxwell
+- Jonas Schnelli
+- J Ross Nicoll
+- Luke Dashjr
+- Pavel Janík
+- Pavel Vasin
+- Peter Todd
+- Pieter Wuille
+- randy-waterhouse
+- Ross Nicoll
+- Suhas Daftuar
+- tailsjoin
+- ฿tcDrak
+- Tom Harding
+- Veres Lajos
+- Wladimir J. van der Laan
+
+And those who contributed additional code review and/or security research:
+
+- timothy on IRC for reporting the issue
+- Vulnerability in miniupnp discovered by Aleksandar Nikolic of Cisco Talos
+
+As well as everyone that helped translating on [Transifex](https://www.transifex.com/projects/p/bitcoin/).
+
diff --git a/doc/release-notes/release-notes-0.3.12.md b/doc/release-notes/release-notes-0.3.12.md
new file mode 100644
index 0000000000..38715bc75f
--- /dev/null
+++ b/doc/release-notes/release-notes-0.3.12.md
@@ -0,0 +1,13 @@
+Version 0.3.12 is now available.
+
+Features:
+* json-rpc errors return a more standard error object. (thanks to Gavin Andresen)
+* json-rpc command line returns exit codes.
+* json-rpc "backupwallet" command.
+* Recovers and continues if an exception is caused by a message you received. Other nodes shouldn't be able to cause an exception, and it hasn't happened before, but if a way is found to cause an exception, this would keep it from being used to stop network nodes.
+
+If you have json-rpc code that checks the contents of the error string, you need to change it to expect error objects of the form {"code":<number>,"message":<string>}, which is the standard. See this thread:
+http://www.bitcoin.org/smf/index.php?topic=969.0
+
+Download:
+http://sourceforge.net/projects/bitcoin/files/Bitcoin/bitcoin-0.3.12/
diff --git a/doc/release-notes/release-notes-0.3.13.md b/doc/release-notes/release-notes-0.3.13.md
new file mode 100644
index 0000000000..2b95ff233d
--- /dev/null
+++ b/doc/release-notes/release-notes-0.3.13.md
@@ -0,0 +1,26 @@
+Version 0.3.13 is now available. You should upgrade to prevent potential problems with 0/unconfirmed transactions. Note: 0.3.13 prevents problems if you haven't already spent a 0/unconfirmed transaction, but if that already happened, you need 0.3.13.2.
+
+Changes:
+* Don't count or spend payments until they have 1 confirmation.
+* Internal version number from 312 to 31300.
+* Only accept transactions sent by IP address if -allowreceivebyip is specified.
+* Dropped DB_PRIVATE Berkeley DB flag.
+* Fix problem sending the last cent with sub-cent fractional change.
+* Auto-detect whether to use 128-bit 4-way SSE2 on Linux.
+Gavin Andresen:
+* Option -rpcallowip= to accept json-rpc connections from another machine.
+* Clean shutdown on SIGTERM on Linux.
+
+Download:
+http://sourceforge.net/projects/bitcoin/files/Bitcoin/bitcoin-0.3.13/
+
+(Thanks Laszlo for the Mac OSX build!)
+
+Note:
+The SSE2 auto-detect in the Linux 64-bit version doesn't work with AMD in 64-bit mode. Please try this instead and let me know if it gets it right:
+http://www.bitcoin.org/download/bitcoin-0.3.13.1-specialbuild-linux64.tar.gz
+
+You can still control the SSE2 use manually with -4way and -4way=0.
+
+Version 0.3.13.2 (SVN rev 161) has improvements for the case where you already had 0/unconfirmed transactions that you might have already spent. Here's a Windows build of it:
+http://www.bitcoin.org/download/bitcoin-0.3.13.2-win32-setup.exe
diff --git a/doc/release-notes/release-notes-0.3.14.md b/doc/release-notes/release-notes-0.3.14.md
new file mode 100644
index 0000000000..e73052ed9b
--- /dev/null
+++ b/doc/release-notes/release-notes-0.3.14.md
@@ -0,0 +1,11 @@
+Version 0.3.14 is now available
+http://sourceforge.net/projects/bitcoin/files/Bitcoin/bitcoin-0.3.14/
+
+Changes:
+* Key pool feature for safer wallet backup
+Gavin Andresen:
+* TEST network mode with switch -testnet
+* Option to use SSL for JSON-RPC connections on unix/osx
+* validateaddress RPC command
+eurekafag:
+* Russian translation
diff --git a/doc/release-notes/release-notes-0.3.15.md b/doc/release-notes/release-notes-0.3.15.md
new file mode 100644
index 0000000000..b98052ef59
--- /dev/null
+++ b/doc/release-notes/release-notes-0.3.15.md
@@ -0,0 +1,6 @@
+* paytxfee switch is now per KB, so it adds the correct fee for large transactions
+* sending avoids using coins with less than 6 confirmations if it can
+* BitcoinMiner processes transactions in priority order based on age of dependencies
+* make sure generation doesn't start before block 74000 downloaded
+* bugfixes by Dean Gores
+* testnet, keypoololdest and paytxfee added to getinfo
diff --git a/doc/release-notes/release-notes-0.3.16.md b/doc/release-notes/release-notes-0.3.16.md
new file mode 100644
index 0000000000..743f84f30e
--- /dev/null
+++ b/doc/release-notes/release-notes-0.3.16.md
@@ -0,0 +1 @@
+Never released.
diff --git a/doc/release-notes/release-notes-0.3.17.md b/doc/release-notes/release-notes-0.3.17.md
new file mode 100644
index 0000000000..d3604b8f88
--- /dev/null
+++ b/doc/release-notes/release-notes-0.3.17.md
@@ -0,0 +1,12 @@
+Version 0.3.17 is now available.
+
+Changes:
+* new getwork, thanks m0mchil
+* added transaction fee setting in UI options menu
+* free transaction limits
+* sendtoaddress returns transaction id instead of "sent"
+* getaccountaddress <account>
+
+The UI transaction fee setting was easy since it was still there from 0.1.5 and all I had to do was re-enable it.
+
+The accounts-based commands: move, sendfrom and getbalance <account> will be in the next release. We still have some more changes to make first.
diff --git a/doc/release-notes/release-notes-0.3.18.md b/doc/release-notes/release-notes-0.3.18.md
new file mode 100644
index 0000000000..ab1c2e0692
--- /dev/null
+++ b/doc/release-notes/release-notes-0.3.18.md
@@ -0,0 +1,11 @@
+Changes:
+* Fixed a wallet.dat compatibility problem if you downgraded from 0.3.17 and then upgraded again
+* IsStandard() check to only include known transaction types in blocks
+* Jgarzik's optimisation to speed up the initial block download a little
+
+The main addition in this release is the Accounts-Based JSON-RPC commands that Gavin's been working on (more details at http://www.bitcoin.org/smf/index.php?topic=1886.0).
+* getaccountaddress
+* sendfrom
+* move
+* getbalance
+* listtransactions
diff --git a/doc/release-notes/release-notes-0.3.19.md b/doc/release-notes/release-notes-0.3.19.md
new file mode 100644
index 0000000000..fcd867561d
--- /dev/null
+++ b/doc/release-notes/release-notes-0.3.19.md
@@ -0,0 +1,9 @@
+There's more work to do on DoS, but I'm doing a quick build of what I have so far in case it's needed, before venturing into more complex ideas. The build for this is version 0.3.19.
+
+- Added some DoS controls
+As Gavin and I have said clearly before, the software is not at all resistant to DoS attack. This is one improvement, but there are still more ways to attack than I can count.
+
+I'm leaving the -limitfreerelay part as a switch for now and it's there if you need it.
+
+- Removed "safe mode" alerts
+"safe mode" alerts was a temporary measure after the 0.3.9 overflow bug. We can say all we want that users can just run with "-disablesafemode", but it's better just not to have it for the sake of appearances. It was never intended as a long term feature. Safe mode can still be triggered by seeing a longer (greater total PoW) invalid block chain.
diff --git a/doc/release-notes/release-notes-0.3.20.1.md b/doc/release-notes/release-notes-0.3.20.1.md
new file mode 100644
index 0000000000..6c5682ea4e
--- /dev/null
+++ b/doc/release-notes/release-notes-0.3.20.1.md
@@ -0,0 +1 @@
+Never released or release notes were lost.
diff --git a/doc/release-notes/release-notes-0.3.20.2.md b/doc/release-notes/release-notes-0.3.20.2.md
new file mode 100644
index 0000000000..09ecb736bd
--- /dev/null
+++ b/doc/release-notes/release-notes-0.3.20.2.md
@@ -0,0 +1,17 @@
+The maxsendbuffer bug (0.3.20.1 clients not being able to download the block chain from other 0.3.20.1 clients) was only going to get
+worse as people upgraded, so I cherry-picked the bug fix and created a minor release yesterday.
+
+The Amazon Machine Images I used to do the builds are available:
+
+ ami-38a05251 Bitcoin-v0.3.20.2 Mingw (Windows; Administrator password 'bitcoin development')
+ ami-30a05259 Bitcoin_0.3.20.2 Linux32
+ ami-8abc4ee3 Bitcoin_0.3.20.2 Linux64
+
+(mac build will be done soon)
+
+If you have already downloaded version 0.3.20.1, please either add this to your bitcoin.conf file:
+
+ maxsendbuffer=10000
+ maxreceivebuffer=10000
+
+... or download the new version.
diff --git a/doc/release-notes/release-notes-0.3.20.md b/doc/release-notes/release-notes-0.3.20.md
new file mode 100644
index 0000000000..9ae21802ee
--- /dev/null
+++ b/doc/release-notes/release-notes-0.3.20.md
@@ -0,0 +1,22 @@
+Please checkout the git integration branch from:
+
+https://github.com/bitcoin/bitcoin
+
+... and help test. The new features that need testing are:
+
+* -nolisten : https://github.com/bitcoin/bitcoin/pull/11
+* -rescan : scan block chain for missing wallet transactions
+* -printtoconsole : https://github.com/bitcoin/bitcoin/pull/37
+* RPC gettransaction details : https://github.com/bitcoin/bitcoin/pull/24
+* listtransactions new features : https://github.com/bitcoin/bitcoin/pull/10
+
+Bug fixes that also need testing:
+
+* -maxconnections= : https://github.com/bitcoin/bitcoin/pull/42
+* RPC listaccounts minconf : https://github.com/bitcoin/bitcoin/pull/27
+* RPC move, add time to output : https://github.com/bitcoin/bitcoin/pull/21
+* ...and several improvements to --help output.
+
+This needs more testing on Windows! Please drop me a quick private message, email, or IRC message if you are able to do some testing. If you find bugs, please open an issue at:
+
+https://github.com/bitcoin/bitcoin/issues
diff --git a/doc/release-notes/release-notes-0.3.21.md b/doc/release-notes/release-notes-0.3.21.md
new file mode 100644
index 0000000000..f3b6bc4264
--- /dev/null
+++ b/doc/release-notes/release-notes-0.3.21.md
@@ -0,0 +1,20 @@
+Binaries for Bitcoin version 0.3.21 are available at:
+ https://sourceforge.net/projects/bitcoin/files/Bitcoin/bitcoin-0.3.21/
+
+Changes and new features from the 0.3.20 release include:
+
+* Universal Plug and Play support. Enable automatic opening of a port for incoming connections by running bitcoin or bitcoind with the - -upnp=1 command line switch or using the Options dialog box.
+
+* Support for full-precision bitcoin amounts. You can now send, and bitcoin will display, bitcoin amounts smaller than 0.01. However, sending fewer than 0.01 bitcoins still requires a 0.01 bitcoin fee (so you can send 1.0001 bitcoins without a fee, but you will be asked to pay a fee if you try to send 0.0001).
+
+* A new method of finding bitcoin nodes to connect with, via DNS A records. Use the -dnsseed option to enable.
+
+For developers, changes to bitcoin's remote-procedure-call API:
+
+* New rpc command "sendmany" to send bitcoins to more than one address in a single transaction.
+
+* Several bug fixes, including a serious intermittent bug that would sometimes cause bitcoind to stop accepting rpc requests.
+
+* -logtimestamps option, to add a timestamp to each line in debug.log.
+
+* Immature blocks (newly generated, under 120 confirmations) are now shown in listtransactions.
diff --git a/doc/release-notes/release-notes-0.3.22.md b/doc/release-notes/release-notes-0.3.22.md
new file mode 100644
index 0000000000..4c05e3e5e7
--- /dev/null
+++ b/doc/release-notes/release-notes-0.3.22.md
@@ -0,0 +1,16 @@
+Download URL: https://sourceforge.net/projects/bitcoin/files/Bitcoin/bitcoin-0.3.22/
+
+This is largely a bugfix and TX fee schedule release. We also hope to make 0.3.23 a quick release, to fix problems that the network has seen due to explosive growth in the past week.
+
+Notable changes:
+* Client will accept and relay TX's with 0.0005 BTC fee schedule (users still pay 0.01 BTC per kb, until next version)
+* Non-standard transactions accepted on testnet
+* Source code tree reorganized (prep for autotools build)
+* Remove "Generate Coins" option from GUI, and remove 4way SSE miner. Internal reference CPU miner remains available, but users are directed to external miners for best hash production.
+* IRC is overflowing. Client now bootstraps to channels #bitcoin00 - #bitcoin99
+* DNS names now may be used with -addnode, -connect (requires -dns to enable)
+
+RPC changes:
+* 'listtransactions' adds 'from' param, for range queries
+* 'move' may take account balances negative
+* 'settxfee' added, to manually set TX fee
diff --git a/doc/release-notes/release-notes-0.3.23.md b/doc/release-notes/release-notes-0.3.23.md
new file mode 100644
index 0000000000..c1d520e492
--- /dev/null
+++ b/doc/release-notes/release-notes-0.3.23.md
@@ -0,0 +1,10 @@
+Win32, Linux, MacOSX and source releases for bitcoin v0.3.23 have been uploaded to
+https://sourceforge.net/projects/bitcoin/files/Bitcoin/bitcoin-0.3.23/
+
+This is another quick bugfix release, trying to deal with the influx of new bitcoin users.
+
+Main items of note:
+
+* P2P connect-to-node logic changed to reduce timeout a bit. The network saw a huge influx of new users, who do not permit incoming connections. This change is a short-term hack, to more quickly hunt for useful P2P connections. Better "leaf node" logic is in the works, but this should let us limp along until then. One may use -upnp to properly forward ports, and help the network.
+* Transaction fee reduced to 0.0005 for new transactions
+* Client will relay transactions with fees as low as 0.0001 BTC
diff --git a/doc/release-notes/release-notes-0.3.24.md b/doc/release-notes/release-notes-0.3.24.md
new file mode 100644
index 0000000000..d35ac66f2c
--- /dev/null
+++ b/doc/release-notes/release-notes-0.3.24.md
@@ -0,0 +1,20 @@
+Bitcoin v0.3.24 is now available for download at
+https://sourceforge.net/projects/bitcoin/files/Bitcoin/bitcoin-0.3.24/
+
+This is another bug fix release. We had hoped to have wallet encryption ready for release, but more urgent fixes for existing clients were needed -- most notably block download problems were getting severe. Wallet encryption is ready for testing at https://github.com/bitcoin/bitcoin/pull/352 for the git-savvy, and hopefully will follow shortly in the next release, v0.4.
+
+Notable fixes in v0.3.24, and the main reasons for this release:
+
+F1) Block downloads were failing or taking unreasonable amounts of time to complete, because the increased size of the block chain was bumping up against some earlier buffer-size DoS limits.
+
+F2) Fix crash caused by loss/lack of network connection.
+
+Notable changes in v0.3.24:
+
+C1) DNS seeding enabled by default.
+
+C2) UPNP enabled by default in the GUI client. The percentage of bitcoin clients that accept incoming connections is quite small, and that is a problem. This should help. bitcoind, and unofficial builds, are unchanged (though we encourage use of "-upnp" to help the network!)
+
+C3) Initial unit testing framework. Bitcoin sorely needs automated tests, and this is a beginning. Contributions welcome.
+
+C4) Internal wallet code cleanup. While invisible to an end user, this change provides the basis for v0.4's wallet encryption.
diff --git a/doc/release-notes/release-notes-0.4.0.md b/doc/release-notes/release-notes-0.4.0.md
new file mode 100644
index 0000000000..145072a369
--- /dev/null
+++ b/doc/release-notes/release-notes-0.4.0.md
@@ -0,0 +1,70 @@
+Bitcoin version 0.4.0 is now available for download at:
+http://sourceforge.net/projects/bitcoin/files/Bitcoin/bitcoin-0.4.0/
+
+The main feature in this release is wallet private key encryption;
+you can set a passphrase that must be entered before sending coins.
+See below for more information; if you decide to encrypt your wallet,
+WRITE DOWN YOUR PASSPHRASE AND PUT IT IN A SECURE LOCATION. If you
+forget or lose your wallet passphrase, you lose your bitcoins.
+Previous versions of bitcoin are unable to read encrypted wallets,
+and will crash on startup if the wallet is encrypted.
+
+Also note: bitcoin version 0.4 uses a newer version of Berkeley DB
+(bdb version 4.8) than previous versions (bdb 4.7). If you upgrade
+to version 0.4 and then revert back to an earlier version of bitcoin
+the it may be unable to start because bdb 4.7 cannot read bdb 4.8
+"log" files.
+
+
+Notable bug fixes from version 0.3.24:
+
+Fix several bitcoin-becomes-unresponsive bugs due to multithreading
+deadlocks.
+
+Optimize database writes for large (lots of inputs) transactions
+(fixes a potential denial-of-service attack)
+
+
+Wallet Encryption
+
+Bitcoin supports native wallet encryption so that people who steal your
+wallet file don't automatically get access to all of your Bitcoins.
+In order to enable this feature, choose "Encrypt Wallet" from the
+Options menu. You will be prompted to enter a passphrase, which
+will be used as the key to encrypt your wallet and will be needed
+every time you wish to send Bitcoins. If you lose this passphrase,
+you will lose access to spend all of the bitcoins in your wallet,
+no one, not even the Bitcoin developers can recover your Bitcoins.
+This means you are responsible for your own security, store your
+passphrase in a secure location and do not forget it.
+
+Remember that the encryption built into bitcoin only encrypts the
+actual keys which are required to send your bitcoins, not the full
+wallet. This means that someone who steals your wallet file will
+be able to see all the addresses which belong to you, as well as the
+relevant transactions, you are only protected from someone spending
+your coins.
+
+It is recommended that you backup your wallet file before you
+encrypt your wallet. To do this, close the Bitcoin client and
+copy the wallet.dat file from ~/.bitcoin/ on Linux, /Users/(user
+name)/Application Support/Bitcoin/ on Mac OSX, and %APPDATA%/Bitcoin/
+on Windows (that is /Users/(user name)/AppData/Roaming/Bitcoin on
+Windows Vista and 7 and /Documents and Settings/(user name)/Application
+Data/Bitcoin on Windows XP). Once you have copied that file to a
+safe location, reopen the Bitcoin client and Encrypt your wallet.
+If everything goes fine, delete the backup and enjoy your encrypted
+wallet. Note that once you encrypt your wallet, you will never be
+able to go back to a version of the Bitcoin client older than 0.4.
+
+Keep in mind that you are always responsible for your own security.
+All it takes is a slightly more advanced wallet-stealing trojan which
+installs a keylogger to steal your wallet passphrase as you enter it
+in addition to your wallet file and you have lost all your Bitcoins.
+Wallet encryption cannot keep you safe if you do not practice
+good security, such as running up-to-date antivirus software, only
+entering your wallet passphrase in the Bitcoin client and using the
+same passphrase only as your wallet passphrase.
+
+See the doc/README file in the bitcoin source for technical details
+of wallet encryption.
diff --git a/doc/release-notes/release-notes-0.4.1.md b/doc/release-notes/release-notes-0.4.1.md
new file mode 100644
index 0000000000..ac471a8d7f
--- /dev/null
+++ b/doc/release-notes/release-notes-0.4.1.md
@@ -0,0 +1,38 @@
+Bitcoin version 0.4.1 is now available for download at:
+http://sourceforge.net/projects/bitcoin/files/Bitcoin/bitcoin-0.4.1/
+
+This is a bugfix only release based on 0.4.0.
+
+Please report bugs by replying to this forum thread.
+
+MAJOR BUG FIX (CVE-2011-4447)
+
+The wallet encryption feature introduced in Bitcoin version 0.4.0 did not sufficiently secure the private keys. An attacker who
+managed to get a copy of your encrypted wallet.dat file might be able to recover some or all of the unencrypted keys and steal the
+associated coins.
+
+If you have a previously encrypted wallet.dat, the first time you run wxbitcoin or bitcoind the wallet will be rewritten, Bitcoin will
+shut down, and you will be prompted to restart it to run with the new, properly encrypted file.
+
+If you had a previously encrypted wallet.dat that might have been copied or stolen (for example, you backed it up to a public
+location) you should send all of your bitcoins to yourself using a new bitcoin address and stop using any previously generated addresses.
+
+Wallets encrypted with this version of Bitcoin are written properly.
+
+Technical note: the encrypted wallet's 'keypool' will be regenerated the first time you request a new bitcoin address; to be certain that the
+new private keys are properly backed up you should:
+
+1. Run Bitcoin and let it rewrite the wallet.dat file
+
+2. Run it again, then ask it for a new bitcoin address.
+wxBitcoin: new address visible on main window
+bitcoind: run the 'walletpassphrase' RPC command to unlock the wallet, then run the 'getnewaddress' RPC command.
+
+3. If your encrypted wallet.dat may have been copied or stolen, send all of your bitcoins to the new bitcoin address.
+
+4. Shut down Bitcoin, then backup the wallet.dat file.
+IMPORTANT: be sure to request a new bitcoin address before backing up, so that the 'keypool' is regenerated and backed up.
+
+"Security in depth" is always a good idea, so choosing a secure location for the backup and/or encrypting the backup before uploading it is recommended. And as in previous releases, if your machine is infected by malware there are several ways an attacker might steal your bitcoins.
+
+Thanks to Alan Reiner (etotheipi) for finding and reporting this bug.
diff --git a/doc/release-notes/release-notes-0.4.2.md b/doc/release-notes/release-notes-0.4.2.md
new file mode 100644
index 0000000000..6c5682ea4e
--- /dev/null
+++ b/doc/release-notes/release-notes-0.4.2.md
@@ -0,0 +1 @@
+Never released or release notes were lost.
diff --git a/doc/release-notes/release-notes-0.4.3.md b/doc/release-notes/release-notes-0.4.3.md
new file mode 100644
index 0000000000..fea1ae75b5
--- /dev/null
+++ b/doc/release-notes/release-notes-0.4.3.md
@@ -0,0 +1,21 @@
+bitcoind version 0.4.3 is now available for download at:
+http://luke.dashjr.org/programs/bitcoin/files/bitcoind-0.4.3/ (until Gavin uploads to SourceForge)
+
+This is a bugfix-only release based on 0.4.0.
+
+Please note that the wxBitcoin GUI client is no longer maintained nor supported. If someone would like to step up to maintain this, they should contact Luke-Jr.
+
+Please report bugs for the daemon only using the issue tracker at github:
+https://github.com/bitcoin/bitcoin/issues
+
+Stable source code is hosted at Gitorious:
+http://gitorious.org/bitcoin/bitcoind-stable/archive-tarball/v0.4.3#.tar.gz
+
+BUG FIXES
+
+Cease locking memory used by non-sensitive information (this caused a huge performance hit on some platforms, especially noticable during initial blockchain download).
+Fixed some address-handling deadlocks (client freezes).
+No longer accept inbound connections over the internet when Bitcoin is being used with Tor (identity leak).
+Use the correct base transaction fee of 0.0005 BTC for accepting transactions into mined blocks (since 0.4.0, it was incorrectly accepting 0.0001 BTC which was only meant to be relayed).
+Add new DNS seeds (maintained by Pieter Wuille and Luke Dashjr).
+
diff --git a/doc/release-notes/release-notes-0.4.4.md b/doc/release-notes/release-notes-0.4.4.md
new file mode 100644
index 0000000000..f435ba7160
--- /dev/null
+++ b/doc/release-notes/release-notes-0.4.4.md
@@ -0,0 +1,30 @@
+Bitcoin version 0.4.4 is now available for download at:
+http://luke.dashjr.org/programs/bitcoin/files/bitcoind-0.4.4/
+
+This is a bugfix-only release based on 0.4.0.
+
+Please note that the wxBitcoin GUI client is no longer maintained nor supported. If someone would like to step up to maintain this, they should contact Luke-Jr.
+
+Please report bugs for the daemon only using the issue tracker at github:
+https://github.com/bitcoin/bitcoin/issues
+
+Stable source code is hosted at Gitorious:
+http://gitorious.org/bitcoin/bitcoind-stable/archive-tarball/v0.4.4#.tar.gz
+
+BUG FIXES
+
+Limit the number of orphan transactions stored in memory, to prevent a potential denial-of-service attack by flooding orphan transactions. Also never store invalid transactions at all.
+Fix possible buffer overflow on systems with very long application data paths. This is not exploitable.
+Resolved multiple bugs preventing long-term unlocking of encrypted wallets (issue #922).
+Only send local IP in "version" messages if it is globally routable (ie, not private), and try to get such an IP from UPnP if applicable.
+Reannounce UPnP port forwards every 20 minutes, to workaround routers expiring old entries, and allow the -upnp option to override any stored setting.
+Various memory leaks and potential null pointer deferences have been
+fixed.
+Several shutdown issues have been fixed.
+Check that keys stored in the wallet are valid at startup, and if not,
+report corruption.
+Various build fixes.
+If no password is specified to bitcoind, recommend a secure password.
+Update hard-coded fallback seed nodes, choosing recent ones with long uptime and versions at least 0.4.0.
+Add checkpoint at block 168,000.
+
diff --git a/doc/release-notes/release-notes-0.4.5.md b/doc/release-notes/release-notes-0.4.5.md
new file mode 100644
index 0000000000..6c5682ea4e
--- /dev/null
+++ b/doc/release-notes/release-notes-0.4.5.md
@@ -0,0 +1 @@
+Never released or release notes were lost.
diff --git a/doc/release-notes/release-notes-0.4.6.md b/doc/release-notes/release-notes-0.4.6.md
new file mode 100644
index 0000000000..07c5e4b694
--- /dev/null
+++ b/doc/release-notes/release-notes-0.4.6.md
@@ -0,0 +1,37 @@
+bitcoind version 0.4.6 is now available for download at:
+Windows: installer | zip (sig)
+Source: tar.gz
+bitcoind and Bitcoin-Qt version 0.6.0.7 are also tagged in git, but it is recommended to upgrade to 0.6.1.
+
+These are bugfix-only releases.
+
+Please report bugs by replying to this forum thread. Note that the 0.4.x wxBitcoin GUI client is no longer maintained nor supported. If someone would like to step up to maintain this, they should contact Luke-Jr.
+
+BUG FIXES
+
+Version 0.6.0 allowed importing invalid "private keys", which would be unspendable; 0.6.0.7 will now verify the private key is valid, and refuse to import an invalid one
+Verify status of encrypt/decrypt calls to detect failed padding
+Check blocks for duplicate transactions earlier. Fixes #1167
+Upgrade Windows builds to OpenSSL 1.0.1b
+Set label when selecting an address that already has a label. Fixes #1080 (Bitcoin-Qt)
+JSON-RPC listtransactions's from/count handling is now fixed
+Optimize and fix multithreaded access, when checking whether we already know about transactions
+Fix potential networking deadlock
+Proper support for Growl 1.3 notifications
+Display an error, rather than crashing, if encoding a QR Code failed (0.6.0.7)
+Don't erroneously set "Display addresses" for users who haven't explicitly enabled it (Bitcoin-Qt)
+Some non-ASCII input in JSON-RPC expecting hexadecimal may have been misinterpreted rather than rejected
+Missing error condition checking added
+Do not show green tick unless all known blocks are downloaded. Fixes #921 (Bitcoin-Qt)
+Increase time ago of last block for "up to date" status from 30 to 90 minutes
+Show a message box when runaway exception happens (Bitcoin-Qt)
+Use a messagebox to display the error when -server is provided without providing a rpc password
+Show error message instead of exception crash when unable to bind RPC port (Bitcoin-Qt)
+Correct sign message bitcoin address tooltip. Fixes #1050 (Bitcoin-Qt)
+Removed "(no label)" from QR Code dialog titlebar if we have no label (0.6.0.7)
+Removed an ugly line break in tooltip for mature transactions (0.6.0.7)
+Add missing tooltip and key shortcut in settings dialog (part of #1088) (Bitcoin-Qt)
+Work around issue in boost::program_options that prevents from compiling in clang
+Fixed bugs occurring only on platforms with unsigned characters (such as ARM).
+Rename make_windows_icon.py to .sh as it is a shell script. Fixes #1099 (Bitcoin-Qt)
+Various trivial internal corrections to types used for counting/size loops and warnings
diff --git a/doc/release-notes/release-notes-0.5.0.md b/doc/release-notes/release-notes-0.5.0.md
new file mode 100644
index 0000000000..baa409b5f2
--- /dev/null
+++ b/doc/release-notes/release-notes-0.5.0.md
@@ -0,0 +1,70 @@
+Bitcoin version 0.5.0 is now available for download at:
+http://sourceforge.net/projects/bitcoin/files/Bitcoin/bitcoin-0.5.0/
+
+The major change for this release is a completely new graphical interface that uses the Qt user interface toolkit.
+
+This release include German, Spanish, Spanish-Castilian, Norwegian and Dutch translations. More translations are welcome; join the project at Transifex if you can help:
+https://www.transifex.net/projects/p/bitcoin/
+
+Please report bugs using the issue tracker at github:
+https://github.com/bitcoin/bitcoin/issues
+
+For Ubuntu users, there is a new ppa maintained by Matt Corallo which you can add to your system so that it will automatically keep bitcoin up-to-date. Just type "sudo apt-add-repository ppa:bitcoin/bitcoin" in your terminal, then install the bitcoin-qt package.
+
+MAJOR BUG FIX (CVE-2011-4447)
+
+The wallet encryption feature introduced in Bitcoin version 0.4.0 did not sufficiently secure the private keys. An attacker who
+managed to get a copy of your encrypted wallet.dat file might be able to recover some or all of the unencrypted keys and steal the
+associated coins.
+
+If you have a previously encrypted wallet.dat, the first time you run bitcoin-qt or bitcoind the wallet will be rewritten, Bitcoin will
+shut down, and you will be prompted to restart it to run with the new, properly encrypted file.
+
+If you had a previously encrypted wallet.dat that might have been copied or stolen (for example, you backed it up to a public
+location) you should send all of your bitcoins to yourself using a new bitcoin address and stop using any previously generated addresses.
+
+Wallets encrypted with this version of Bitcoin are written properly.
+
+Technical note: the encrypted wallet's 'keypool' will be regenerated the first time you request a new bitcoin address; to be certain that the
+new private keys are properly backed up you should:
+
+1. Run Bitcoin and let it rewrite the wallet.dat file
+
+2. Run it again, then ask it for a new bitcoin address.
+Bitcoin-Qt: Address Book, then New Address...
+bitcoind: run the 'walletpassphrase' RPC command to unlock the wallet, then run the 'getnewaddress' RPC command.
+
+3. If your encrypted wallet.dat may have been copied or stolen, send all of your bitcoins to the new bitcoin address.
+
+4. Shut down Bitcoin, then backup the wallet.dat file.
+IMPORTANT: be sure to request a new bitcoin address before backing up, so that the 'keypool' is regenerated and backed up.
+
+"Security in depth" is always a good idea, so choosing a secure location for the backup and/or encrypting the backup before uploading it is recommended. And as in previous releases, if your machine is infected by malware there are several ways an attacker might steal your bitcoins.
+
+Thanks to Alan Reiner (etotheipi) for finding and reporting this bug.
+
+MAJOR GUI CHANGES
+
+"Splash" graphics at startup that show address/wallet/blockchain loading progress.
+
+"Synchronizing with network" progress bar to show block-chain download progress.
+
+Icons at the bottom of the window that show how well connected you are to the network, with tooltips to display details.
+
+Drag and drop support for bitcoin: URIs on web pages.
+
+Export transactions as a .csv file.
+
+Many other GUI improvements, large and small.
+
+RPC CHANGES
+
+getmemorypool : new RPC command, provides everything needed to construct a block with a custom generation transaction and submit a solution
+
+listsinceblock : new RPC command, list transactions since given block
+
+signmessage/verifymessage : new RPC commands to sign a message with one of your private keys or verify that a message signed by the private key associated with a bitcoin address.
+
+GENERAL CHANGES
+
+Faster initial block download.
diff --git a/doc/release-notes/release-notes-0.5.1.md b/doc/release-notes/release-notes-0.5.1.md
new file mode 100644
index 0000000000..d56bff6d95
--- /dev/null
+++ b/doc/release-notes/release-notes-0.5.1.md
@@ -0,0 +1,43 @@
+Bitcoin version 0.5.1 is now available for download at:
+http://sourceforge.net/projects/bitcoin/files/Bitcoin/bitcoin-0.5.1/
+
+This is a bugfix-only release.
+
+This release includes 13 translations, including 5 new translations:
+Italian, Hungarian, Ukranian, Portuguese (Brazilian) and Simplified Chinese.
+More translations are welcome; join the project at Transifex if you can help:
+https://www.transifex.net/projects/p/bitcoin/
+
+Please report bugs using the issue tracker at github:
+https://github.com/bitcoin/bitcoin/issues
+
+Project source code is hosted at github; we are no longer
+distributing .tar.gz files here, you can get them
+directly from github:
+https://github.com/bitcoin/bitcoin/tarball/v0.5.1 # .tar.gz
+https://github.com/bitcoin/bitcoin/zipball/v0.5.1 # .zip
+
+For Ubuntu users, there is a new ppa maintained by Matt Corallo which
+you can add to your system so that it will automatically keep
+bitcoin up-to-date. Just type
+sudo apt-add-repository ppa:bitcoin/bitcoin
+in your terminal, then install the bitcoin-qt package.
+
+
+BUG FIXES
+
+Re-enable SSL support for the JSON-RPC interface (it was unintentionally
+disabled for the 0.5.0 release binaries).
+
+The code that finds peers via "dns seeds" no longer stops bitcoin startup
+if one of the dns seed machines is down.
+
+Tooltips on the transaction list view were rendering incorrectly (as black boxes
+or with a transparent background).
+
+Prevent a denial-of-service attack involving flooding a bitcoin node with
+orphan blocks.
+
+The wallet passphrase dialog now warns you if the caps lock key was pressed.
+
+Improved searching in addresses and labels in bitcoin-qt.
diff --git a/doc/release-notes/release-notes-0.5.2.md b/doc/release-notes/release-notes-0.5.2.md
new file mode 100644
index 0000000000..f79816668d
--- /dev/null
+++ b/doc/release-notes/release-notes-0.5.2.md
@@ -0,0 +1,22 @@
+Bitcoin version 0.5.2 is now available for download at:
+http://sourceforge.net/projects/bitcoin/files/Bitcoin/bitcoin-0.5.2/
+
+This is a bugfix-only release based on 0.5.1.
+
+Please report bugs using the issue tracker at github:
+https://github.com/bitcoin/bitcoin/issues
+
+Stable source code is hosted at Gitorious:
+http://gitorious.org/bitcoin/bitcoind-stable/archive-tarball/v0.5.2#.tar.gz
+
+BUG FIXES
+
+Check all transactions in blocks after the last checkpoint (0.5.0 and 0.5.1 skipped checking ECDSA signatures during initial blockchain download).
+Cease locking memory used by non-sensitive information (this caused a huge performance hit on some platforms, especially noticable during initial blockchain download; this was
+not a security vulnerability).
+Fixed some address-handling deadlocks (client freezes).
+No longer accept inbound connections over the internet when Bitcoin is being used with Tor (identity leak).
+Re-enable SSL support for the JSON-RPC interface (it was unintentionally disabled for the 0.5.0 and 0.5.1 release Linux binaries).
+Use the correct base transaction fee of 0.0005 BTC for accepting transactions into mined blocks (since 0.4.0, it was incorrectly accepting 0.0001 BTC which was only meant to be relayed).
+Don't show "IP" for transactions which are not necessarily IP transactions.
+Add new DNS seeds (maintained by Pieter Wuille and Luke Dashjr).
diff --git a/doc/release-notes/release-notes-0.5.3.md b/doc/release-notes/release-notes-0.5.3.md
new file mode 100644
index 0000000000..7c84c53325
--- /dev/null
+++ b/doc/release-notes/release-notes-0.5.3.md
@@ -0,0 +1,42 @@
+Bitcoin version 0.5.3 is now available for download at:
+http://sourceforge.net/projects/bitcoin/files/Bitcoin/bitcoin-0.5.3/
+
+This is a bugfix-only release based on 0.5.1.
+It also includes a few protocol updates.
+
+Please report bugs using the issue tracker at github:
+https://github.com/bitcoin/bitcoin/issues
+
+Stable source code is hosted at Gitorious:
+http://gitorious.org/bitcoin/bitcoind-stable/archive-tarball/v0.5.3#.tar.gz
+
+PROTOCOL UPDATES
+
+BIP 30: Introduce a new network rule: "a block is not valid if it contains a transaction whose hash already exists in the block chain, unless all that transaction's outputs were already spent before said block" beginning on March 15, 2012, 00:00 UTC.
+On testnet, allow mining of min-difficulty blocks if 20 minutes have gone by without mining a regular-difficulty block. This is to make testing Bitcoin easier, and will not affect normal mode.
+
+BUG FIXES
+
+Limit the number of orphan transactions stored in memory, to prevent a potential denial-of-service attack by flooding orphan transactions. Also never store invalid transactions at all.
+Fix possible buffer overflow on systems with very long application data paths. This is not exploitable.
+Resolved multiple bugs preventing long-term unlocking of encrypted wallets
+(issue #922).
+Only send local IP in "version" messages if it is globally routable (ie, not private), and try to get such an IP from UPnP if applicable.
+Reannounce UPnP port forwards every 20 minutes, to workaround routers expiring old entries, and allow the -upnp option to override any stored setting.
+Skip splash screen when -min is used, and fix Minimize to Tray function.
+Do not blank "label" in Bitcoin-Qt "Send" tab, if the user has already entered something.
+Correct various labels and messages.
+Various memory leaks and potential null pointer deferences have been fixed.
+Handle invalid Bitcoin URIs using "bitcoin://" instead of "bitcoin:".
+Several shutdown issues have been fixed.
+Revert to "global progress indication", as starting from zero every time was considered too confusing for many users.
+Check that keys stored in the wallet are valid at startup, and if not, report corruption.
+Enable accessible widgets on Windows, so that people with screen readers such as NVDA can make sense of it.
+Various build fixes.
+If no password is specified to bitcoind, recommend a secure password.
+Automatically focus and scroll to new "Send coins" entries in Bitcoin-Qt.
+Show a message box for --help on Windows, for Bitcoin-Qt.
+Add missing "About Qt" menu option to show built-in Qt About dialog.
+Don't show "-daemon" as an option for Bitcoin-Qt, since it isn't available.
+Update hard-coded fallback seed nodes, choosing recent ones with long uptime and versions at least 0.4.0.
+Add checkpoint at block 168,000.
diff --git a/doc/release-notes/release-notes-0.5.4.md b/doc/release-notes/release-notes-0.5.4.md
new file mode 100644
index 0000000000..fcde3ac4e3
--- /dev/null
+++ b/doc/release-notes/release-notes-0.5.4.md
@@ -0,0 +1,39 @@
+Bitcoin version 0.5.4 is now available for download at:
+http://sourceforge.net/projects/bitcoin/files/Bitcoin/bitcoin-0.5.4/
+NOTE: 0.5.4rc3 is being renamed to 0.5.4 final with no changes.
+
+This is a bugfix-only release in the 0.5.x series, plus a few protocol updates.
+
+Please report bugs using the issue tracker at github:
+https://github.com/bitcoin/bitcoin/issues
+
+Stable source code is hosted at Gitorious:
+http://gitorious.org/bitcoin/bitcoind-stable/archive-tarball/v0.5.4#.tar.gz
+
+PROTOCOL UPDATES
+
+BIP 16: Special-case "pay to script hash" logic to enable minimal validation of new transactions.
+Support for validating message signatures produced with compressed public keys.
+
+BUG FIXES
+
+Build with thread-safe MingW libraries for Windows, fixing a dangerous memory corruption scenario when exceptions are thrown.
+Fix broken testnet mining.
+Stop excess inventory relay during initial block download.
+When disconnecting a node, clear the received buffer so that we do not process any already received messages.
+Yet another attempt at implementing "minimize to tray" that works on all operating systems.
+Fix Bitcoin-Qt notifications under Growl 1.3.
+Increase required age of Bitcoin-Qt's "not up to date" status from 30 to 90 minutes.
+Implemented missing verifications that led to crash on entering some wrong passphrases for encrypted wallets.
+Fix default filename suffixes in GNOME save dialog.
+Make the "Send coins" tab use the configured unit type, even on the first attempt.
+Print detailed wallet loading errors to debug.log when it is corrupt.
+Allocate exactly the amount of space needed for signing transactions, instead of a fixed 10k buffer.
+Workaround for improbable memory access violation.
+Check wallet's minimum version before trying to load it.
+Remove wxBitcoin properly when installing Bitcoin-Qt over it. (Windows)
+Detail reorganization information better in debug log.
+Use a messagebox to display the error when -server is provided without configuring a RPC password.
+Testing suite build now honours provided CXXFLAGS.
+Removed an extraneous line-break in mature transaction tooltips.
+Fix some grammatical errors in translation process documentation.
diff --git a/doc/release-notes/release-notes-0.5.5.md b/doc/release-notes/release-notes-0.5.5.md
new file mode 100644
index 0000000000..75ebc3e6b6
--- /dev/null
+++ b/doc/release-notes/release-notes-0.5.5.md
@@ -0,0 +1,37 @@
+bitcoind and Bitcoin-Qt version 0.5.5 are now available for download at:
+Windows: installer | zip (sig)
+Source: tar.gz
+bitcoind and Bitcoin-Qt version 0.6.0.7 are also tagged in git, but it is recommended to upgrade to 0.6.1.
+
+These are bugfix-only releases.
+
+Please report bugs by replying to this forum thread. Note that the 0.4.x wxBitcoin GUI client is no longer maintained nor supported. If someone would like to step up to maintain this, they should contact Luke-Jr.
+
+BUG FIXES
+
+Version 0.6.0 allowed importing invalid "private keys", which would be unspendable; 0.6.0.7 will now verify the private key is valid, and refuse to import an invalid one
+Verify status of encrypt/decrypt calls to detect failed padding
+Check blocks for duplicate transactions earlier. Fixes #1167
+Upgrade Windows builds to OpenSSL 1.0.1b
+Set label when selecting an address that already has a label. Fixes #1080 (Bitcoin-Qt)
+JSON-RPC listtransactions's from/count handling is now fixed
+Optimize and fix multithreaded access, when checking whether we already know about transactions
+Fix potential networking deadlock
+Proper support for Growl 1.3 notifications
+Display an error, rather than crashing, if encoding a QR Code failed (0.6.0.7)
+Don't erroneously set "Display addresses" for users who haven't explicitly enabled it (Bitcoin-Qt)
+Some non-ASCII input in JSON-RPC expecting hexadecimal may have been misinterpreted rather than rejected
+Missing error condition checking added
+Do not show green tick unless all known blocks are downloaded. Fixes #921 (Bitcoin-Qt)
+Increase time ago of last block for "up to date" status from 30 to 90 minutes
+Show a message box when runaway exception happens (Bitcoin-Qt)
+Use a messagebox to display the error when -server is provided without providing a rpc password
+Show error message instead of exception crash when unable to bind RPC port (Bitcoin-Qt)
+Correct sign message bitcoin address tooltip. Fixes #1050 (Bitcoin-Qt)
+Removed "(no label)" from QR Code dialog titlebar if we have no label (0.6.0.7)
+Removed an ugly line break in tooltip for mature transactions (0.6.0.7)
+Add missing tooltip and key shortcut in settings dialog (part of #1088) (Bitcoin-Qt)
+Work around issue in boost::program_options that prevents from compiling in clang
+Fixed bugs occurring only on platforms with unsigned characters (such as ARM).
+Rename make_windows_icon.py to .sh as it is a shell script. Fixes #1099 (Bitcoin-Qt)
+Various trivial internal corrections to types used for counting/size loops and warnings
diff --git a/doc/release-notes/release-notes-0.6.0.md b/doc/release-notes/release-notes-0.6.0.md
new file mode 100644
index 0000000000..1963a36259
--- /dev/null
+++ b/doc/release-notes/release-notes-0.6.0.md
@@ -0,0 +1,138 @@
+Bitcoin version 0.6.0 is now available for download at:
+http://sourceforge.net/projects/bitcoin/files/Bitcoin/bitcoin-0.6.0/test/
+
+This release includes more than 20 language localizations.
+More translations are welcome; join the
+project at Transifex to help:
+https://www.transifex.net/projects/p/bitcoin/
+
+Please report bugs using the issue tracker at github:
+https://github.com/bitcoin/bitcoin/issues
+
+Project source code is hosted at github; we are no longer
+distributing .tar.gz files here, you can get them
+directly from github:
+https://github.com/bitcoin/bitcoin/tarball/v0.6.0 # .tar.gz
+https://github.com/bitcoin/bitcoin/zipball/v0.6.0 # .zip
+
+For Ubuntu users, there is a ppa maintained by Matt Corallo which
+you can add to your system so that it will automatically keep
+bitcoin up-to-date. Just type
+sudo apt-add-repository ppa:bitcoin/bitcoin
+in your terminal, then install the bitcoin-qt package.
+
+
+KNOWN ISSUES
+
+Shutting down while synchronizing with the network
+(downloading the blockchain) can take more than a minute,
+because database writes are queued to speed up download
+time.
+
+
+NEW FEATURES SINCE BITCOIN VERSION 0.5
+
+Initial network synchronization should be much faster
+(one or two hours on a typical machine instead of ten or more
+hours).
+
+Backup Wallet menu option.
+
+Bitcoin-Qt can display and save QR codes for sending
+and receiving addresses.
+
+New context menu on addresses to copy/edit/delete them.
+
+New Sign Message dialog that allows you to prove that you
+own a bitcoin address by creating a digital
+signature.
+
+New wallets created with this version will
+use 33-byte 'compressed' public keys instead of
+65-byte public keys, resulting in smaller
+transactions and less traffic on the bitcoin
+network. The shorter keys are already supported
+by the network but wallet.dat files containing
+short keys are not compatible with earlier
+versions of Bitcoin-Qt/bitcoind.
+
+New command-line argument -blocknotify=<command>
+that will spawn a shell process to run <command>
+when a new block is accepted.
+
+New command-line argument -splash=0 to disable
+Bitcoin-Qt's initial splash screen
+
+validateaddress JSON-RPC api command output includes
+two new fields for addresses in the wallet:
+pubkey : hexadecimal public key
+iscompressed : true if pubkey is a short 33-byte key
+
+New JSON-RPC api commands for dumping/importing
+private keys from the wallet (dumprivkey, importprivkey).
+
+New JSON-RPC api command for getting information about
+blocks (getblock, getblockhash).
+
+New JSON-RPC api command (getmininginfo) for getting
+extra information related to mining. The getinfo
+JSON-RPC command no longer includes mining-related
+information (generate/genproclimit/hashespersec).
+
+
+
+NOTABLE CHANGES
+
+BIP30 implemented (security fix for an attack involving
+duplicate "coinbase transactions").
+
+The -nolisten, -noupnp and -nodnsseed command-line
+options were renamed to -listen, -upnp and -dnsseed,
+with a default value of 1. The old names are still
+supported for compatibility (so specifying -nolisten
+is automatically interpreted as -listen=0; every
+boolean argument can now be specified as either
+-foo or -nofoo).
+
+The -noirc command-line options was renamed to
+-irc, with a default value of 0. Run -irc=1 to
+get the old behavior.
+
+Three fill-up-available-memory denial-of-service
+attacks were fixed.
+
+
+NOT YET IMPLEMENTED FEATURES
+
+Support for clicking on bitcoin: URIs and
+opening/launching Bitcoin-Qt is available only on Linux,
+and only if you configure your desktop to launch
+Bitcoin-Qt. All platforms support dragging and dropping
+bitcoin: URIs onto the Bitcoin-Qt window to start
+payment.
+
+
+PRELIMINARY SUPPORT FOR MULTISIGNATURE TRANSACTIONS
+
+This release has preliminary support for multisignature
+transactions-- transactions that require authorization
+from more than one person or device before they
+will be accepted by the bitcoin network.
+
+Prior to this release, multisignature transactions
+were considered 'non-standard' and were ignored;
+with this release multisignature transactions are
+considered standard and will start to be relayed
+and accepted into blocks.
+
+It is expected that future releases of Bitcoin-Qt
+will support the creation of multisignature transactions,
+once enough of the network has upgraded so relaying
+and validating them is robust.
+
+For this release, creation and testing of multisignature
+transactions is limited to the bitcoin test network using
+the "addmultisigaddress" JSON-RPC api call.
+
+Short multisignature address support is included in this
+release, as specified in BIP 13 and BIP 16.
diff --git a/doc/release-notes/release-notes-0.6.1.md b/doc/release-notes/release-notes-0.6.1.md
new file mode 100644
index 0000000000..ef7966ecd6
--- /dev/null
+++ b/doc/release-notes/release-notes-0.6.1.md
@@ -0,0 +1,2 @@
+Never released
+
diff --git a/doc/release-notes/release-notes-0.6.2.md b/doc/release-notes/release-notes-0.6.2.md
new file mode 100644
index 0000000000..bb85fb23a0
--- /dev/null
+++ b/doc/release-notes/release-notes-0.6.2.md
@@ -0,0 +1,50 @@
+Bitcoin version 0.6.2 is now available for download at:
+http://sourceforge.net/projects/bitcoin/files/Bitcoin/bitcoin-0.6.2/
+
+This is a bug-fix and code-cleanup release, with no major new features.
+
+Please report bugs using the github issue tracker at:
+https://github.com/bitcoin/bitcoin/issues
+
+
+NOTABLE CHANGES
+
+Much faster shutdowns. However, the blkindex.dat file is no longer
+portable to different data directories by default. If you need a
+portable blkindex.dat file then run with the new -detachdb=1 option
+or the "Detach databases at shutdown" GUI preference.
+
+Fixed https://github.com/bitcoin/bitcoin/issues/1065, a bug that
+could cause long-running nodes to crash.
+
+Mac and Windows binaries are compiled against OpenSSL 1.0.1b (Linux
+binaries are dynamically linked to the version of OpenSSL on the system).
+
+
+CHANGE SUMMARY
+
+Use 'git shortlog --no-merges v0.6.0..' for a summary of this release.
+
+Source codebase changes:
+- Many source code cleanups and warnings fixes. Close to building with -Wall
+- Locking overhaul, and several minor locking fixes
+- Several source code portability fixes, e.g. FreeBSD
+
+JSON-RPC interface changes:
+- addmultisigaddress enabled for mainnet (previously only enabled for testnet)
+
+Network protocol changes:
+- protocol version 60001
+- added nonce value to "ping" message (BIP 31)
+- added new "pong" message (BIP 31)
+
+Backend storage changes:
+- Less redundant database flushing, especially during initial block download
+- Shutdown improvements (see above)
+
+Qt user interface:
+- minor URI handling improvements
+- progressbar improvements
+- error handling improvements (show message box rather than console exception,
+etc.)
+- by popular request, make 4th bar of connection icon green
diff --git a/doc/release-notes/release-notes-0.6.3.md b/doc/release-notes/release-notes-0.6.3.md
new file mode 100644
index 0000000000..28bb20e104
--- /dev/null
+++ b/doc/release-notes/release-notes-0.6.3.md
@@ -0,0 +1,29 @@
+Bitcoin version 0.6.3 is now available for download at:
+ http://sourceforge.net/projects/bitcoin/files/Bitcoin/bitcoin-0.6.3/
+
+This is a bug-fix release, with no new features.
+
+Please report bugs using the issue tracker at github:
+ https://github.com/bitcoin/bitcoin/issues
+
+CHANGE SUMMARY
+
+Fixed a serious denial-of-service attack that could cause the
+bitcoin process to become unresponsive. Thanks to Sergio Lerner
+for finding and responsibly reporting the problem. (CVE-2012-3789)
+
+Optimized the process of checking transaction signatures, to
+speed up processing of new block messages and make propagating
+blocks across the network faster.
+
+Fixed an obscure bug that could cause the bitcoin process to get
+stuck on an invalid block-chain, if the invalid chain was
+hundreds of blocks long.
+
+Bitcoin-Qt no longer automatically selects the first address
+in the address book (Issue #1384).
+
+Fixed minimize-to-dock behavior of Bitcon-Qt on the Mac.
+
+Added a block checkpoint at block 185,333 to speed up initial
+blockchain download.
diff --git a/doc/release-notes/release-notes-0.7.0.md b/doc/release-notes/release-notes-0.7.0.md
new file mode 100644
index 0000000000..d33a58f99f
--- /dev/null
+++ b/doc/release-notes/release-notes-0.7.0.md
@@ -0,0 +1,169 @@
+Bitcoin version 0.7.0 is now available for download at:
+ http://sourceforge.net/projects/bitcoin/files/Bitcoin/bitcoin-0.7.0/
+
+We recommend that everybody running prior versions of bitcoind/Bitcoin-Qt
+upgrade to this release, except for users running Mac OSX 10.5.
+
+Please report bugs using the issue tracker at github:
+ https://github.com/bitcoin/bitcoin/issues
+
+Project source code is hosted at github; you can get
+source-only tarballs/zipballs directly from there:
+ https://github.com/bitcoin/bitcoin/tarball/v0.7.0 # .tar.gz
+ https://github.com/bitcoin/bitcoin/zipball/v0.7.0 # .zip
+
+Ubuntu Linux users can use the "Personal Package Archive" (PPA)
+maintained by Matt Corallo to automatically keep
+bitcoin up-to-date. Just type
+ sudo apt-add-repository ppa:bitcoin/bitcoin
+ sudo apt-get update
+in your terminal, then install the bitcoin-qt package:
+ sudo apt-get install bitcoin-qt
+
+
+How to Upgrade
+
+If you are running an older version, shut it down. Wait
+until it has completely shut down (which might take a few minutes for older
+versions), then run the installer (on Windows) or just copy over
+Code:
+/Applications/Bitcoin-Qt
+(on Mac) or
+Code:
+bitcoind/bitcoin-qt
+(on Linux).
+
+If you were running on Linux with a version that might have been compiled
+with a different version of Berkeley DB (for example, if you were using the
+PPA and are switching to the binary release), then run the old version again
+with the -detachdb argument and shut it down; if you do not, then the new
+version will not be able to read the database files and will exit with an error.
+
+Incompatible Changes
+
+* Replaced the 'getmemorypool' RPC command with 'getblocktemplate/submitblock'
+ and 'getrawmempool' commands.
+* Remove deprecated RPC 'getblocknumber'
+
+Bitcoin Improvement Proposals implemented
+
+BIP 22 - 'getblocktemplate', 'submitblock' RPCs
+BIP 34 - block version 2, height in coinbase
+BIP 35 - 'mempool' message, extended 'getdata' message behavior
+
+
+Core bitcoin handling and blockchain database
+
+* Reduced CPU usage, by eliminating some redundant hash calculations
+* Cache signature verifications, to eliminate redundant signature checks
+* Transactions with zero-value outputs are considered non-standard
+* Mining: when creating new blocks, sort 'paid' area by fee-per-kb
+* Database: better validation of on-disk stored data
+* Database: minor optimizations and reliability improvements
+* -loadblock=FILE will import an external block file
+* Additional DoS (denial-of-service) prevention measures
+* New blockchain checkpoint at block 193,000
+
+
+JSON-RPC API
+
+* Internal HTTP server is now thread-per-connection, rather than
+ a single-threaded queue that would stall on network I/O.
+* Internal HTTP server supports HTTP/1.1, pipelined requests and
+ connection keep-alive.
+* Support JSON-RPC 2.0 batches, to encapsulate multiple JSON-RPC requests
+ within a single HTTP request.
+* IPv6 support
+* Added raw transaction API. See https://gist.github.com/2839617
+* Added 'getrawmempool', to list contents of TX memory pool
+* Added 'getpeerinfo', to list data about each connected network peer
+* Added 'listaddressgroupings' for better coin control
+* Rework getblock call.
+* Remove deprecated RPC 'getblocknumber'
+* Remove superceded RPC 'getmemorypool' (see BIP 22, above)
+* listtransactions output now displays "smart" times for transactions,
+ and 'blocktime' and 'timereceived' fields were added
+
+
+P2P networking
+
+* IPv6 support
+* Tor hidden service support (see doc/Tor.txt)
+* Attempts to fix "stuck blockchain download" problems
+* Replace BDB database "addr.dat" with internally-managed "peers.dat"
+ file containing peer address data.
+* Lower default send buffer from 10MB to 1MB
+* proxy: SOCKS5 by default
+* Support connecting by hostnames passed to proxy
+* Add -seednode connections, and use this instead of DNS seeds when proxied
+* Added -externalip and -discover
+* Add -onlynet to connect only to a given network (IPv4, IPv6, or Tor)
+* Separate listening sockets, -bind=<addr>
+
+
+Qt GUI
+
+* Add UI RPC console / debug window
+* Re-Enable URI handling on Windows, add safety checks and tray-notifications
+* Harmonize the use of ellipsis ("...") to be used in menus, but not on buttons
+* Add 2 labels to the overviewpage that display Wallet and Transaction status (obsolete or current)
+* Extend the optionsdialog (e.g. language selection) and re-work it to a tabbed UI
+* Merge sign/verify message into a single window with tabbed UI
+* Ensure a changed bitcoin unit immediately updates all GUI elements that use units
+* Update QR Code dialog
+* Improve error reporting at startup
+* Fine-grained UI updates for a much smoother UI during block downloads
+* Remove autocorrection of 0/i in addresses in UI
+* Reorganize tray icon menu into more logical order
+* Persistently poll for balance change when number of blocks changed
+* Much better translations
+* Override progress bar design on platforms with segmented progress bars to assist with readability
+* Added 'immature balance' display on the overview page
+* (Windows only): enable ASLR and DEP for bitcoin-qt.exe
+* (Windows only): add meta-data to bitcoin-qt.exe (e.g. description)
+
+Internal codebase
+
+* Additional unit tests
+* Compile warning fixes
+
+
+Miscellaneous
+
+* Reopen debug.log upon SIGHUP
+* Bash programmable completion for bitcoind(1)
+* On supported OS's, each thread is given a useful name
+
+
+Thanks to everybody who contributed to this release:
+
+Chris Moore
+Christian von Roques
+David Joel Schwartz
+Douglas Huff
+Fordy
+Gavin Andresen
+Giel van Schijndel
+Gregory Maxwell
+Jeff Garzik
+Luke Dashjr
+Matt Corallo
+Michael Ford
+Michael Hendricks
+Peter Todd
+Philip Kaufmann
+Pieter Wuille
+R E Broadley
+Ricardo M. Correia
+Rune K. Svendsen
+Scott Ellis
+Stephane Glondu
+Wladimir J. van der Laan
+cardpuncher
+coderrr
+fanquake
+grimd34th
+sje397
+xanatos
+
+Thanks to Sergio Lerner for reporting denial-of-service vulnerabilities fixed in this release.
diff --git a/doc/release-notes/release-notes-0.7.1.md b/doc/release-notes/release-notes-0.7.1.md
new file mode 100644
index 0000000000..22e910c09f
--- /dev/null
+++ b/doc/release-notes/release-notes-0.7.1.md
@@ -0,0 +1,110 @@
+Bitcoin version 0.7.1 is now available from:
+ http://sourceforge.net/projects/bitcoin/files/Bitcoin/bitcoin-0.7.1/
+
+This is a bug-fix minor release.
+
+Please report bugs using the issue tracker at github:
+ https://github.com/bitcoin/bitcoin/issues
+
+Project source code is hosted at github; you can get
+source-only tarballs/zipballs directly from there:
+ https://github.com/bitcoin/bitcoin/tarball/v0.7.1 # .tar.gz
+ https://github.com/bitcoin/bitcoin/zipball/v0.7.1 # .zip
+
+Ubuntu Linux users can use the "Personal Package Archive" (PPA)
+maintained by Matt Corallo to automatically keep
+up-to-date. Just type:
+ sudo apt-add-repository ppa:bitcoin/bitcoin
+ sudo apt-get update
+in your terminal, then install the bitcoin-qt package:
+ sudo apt-get install bitcoin-qt
+
+KNOWN ISSUES
+------------
+
+Mac OSX 10.5 is no longer supported.
+
+How to Upgrade
+--------------
+
+If you are running an older version, shut it down. Wait
+until it has completely shut down (which might take a few minutes for older
+versions), then run the installer (on Windows) or just copy over
+/Applications/Bitcoin-Qt (on Mac) or bitcoind/bitcoin-qt (on Linux).
+
+If you were running on Linux with a version that might have been compiled
+with a different version of Berkeley DB (for example, if you were using an
+Ubuntu PPA version), then run the old version again with the -detachdb
+argument and shut it down; if you do not, then the new version will not
+be able to read the database files and will exit with an error.
+
+Explanation of -detachdb (and the new "stop true" RPC command):
+The Berkeley DB database library stores data in both ".dat" and
+"log" files, so the database is always in a consistent state,
+even in case of power failure or other sudden shutdown. The
+format of the ".dat" files is portable between different
+versions of Berkeley DB, but the "log" files are not-- even minor
+version differences may have incompatible "log" files. The
+-detachdb option moves any pending changes from the "log" files
+to the "blkindex.dat" file for maximum compatibility, but makes
+shutdown much slower. Note that the "wallet.dat" file is always
+detached, and versions prior to 0.6.0 detached all databases
+at shutdown.
+
+New features
+------------
+
+* Added a boolean argument to the RPC 'stop' command, if true sets
+ -detachdb to create standalone database .dat files before shutting down.
+
+* -salvagewallet command-line option, which moves any existing wallet.dat
+ to wallet.{timestamp}.dat and then attempts to salvage public/private
+ keys and master encryption keys (if the wallet is encrypted) into
+ a new wallet.dat. This should only be used if your wallet becomes
+ corrupted, and is not intended to replace regular wallet backups.
+
+* Import $DataDir/bootstrap.dat automatically, if it exists.
+
+Dependency changes
+------------------
+
+* Qt 4.8.2 for Windows builds
+
+* openssl 1.0.1c
+
+Bug fixes
+---------
+
+* Clicking on a bitcoin: URI on Windows should now launch Bitcoin-Qt properly.
+
+* When running -testnet, use RPC port 18332 by default.
+
+* Better detection and handling of corrupt wallet.dat and blkindex.dat files.
+ Previous versions would crash with a DB_RUNRECOVERY exception, this
+ version detects most problems and tells you how to recover if it
+ cannot recover itself.
+
+* Fixed an uninitialized variable bug that could cause transactions to
+ be reported out of order.
+
+* Fixed a bug that could cause occasional crashes on exit.
+
+* Warn the user that they need to create fresh wallet backups after they
+ encrypt their wallet.
+
+----------------------------------------------------
+Thanks to everybody who contributed to this release:
+
+Gavin Andresen
+Jeff Garzik
+Luke Dashjr
+Mark Friedenbach
+Matt Corallo
+Philip Kaufmann
+Pieter Wuille
+Rune K. Svendsen
+Virgil Dupras
+Wladimir J. van der Laan
+fanquake
+kjj2
+xanatos
diff --git a/doc/release-notes/release-notes-0.7.2.md b/doc/release-notes/release-notes-0.7.2.md
new file mode 100644
index 0000000000..40af34962b
--- /dev/null
+++ b/doc/release-notes/release-notes-0.7.2.md
@@ -0,0 +1,68 @@
+Bitcoin version 0.7.2 is now available from:
+ http://sourceforge.net/projects/bitcoin/files/Bitcoin/bitcoin-0.7.2
+
+This is a bug-fix minor release.
+
+Please report bugs using the issue tracker at github:
+ https://github.com/bitcoin/bitcoin/issues
+
+How to Upgrade
+--------------
+
+If you are running an older version, shut it down. Wait
+until it has completely shut down (which might take a few minutes for older
+versions), then run the installer (on Windows) or just copy over
+/Applications/Bitcoin-Qt (on Mac) or bitcoind/bitcoin-qt (on Linux).
+
+If you were running on Linux with a version that might have been compiled
+with a different version of Berkeley DB (for example, if you were using an
+Ubuntu PPA version), then run the old version again with the -detachdb
+argument and shut it down; if you do not, then the new version will not
+be able to read the database files and will exit with an error.
+
+Explanation of -detachdb (and the new "stop true" RPC command):
+The Berkeley DB database library stores data in both ".dat" and
+"log" files, so the database is always in a consistent state,
+even in case of power failure or other sudden shutdown. The
+format of the ".dat" files is portable between different
+versions of Berkeley DB, but the "log" files are not-- even minor
+version differences may have incompatible "log" files. The
+-detachdb option moves any pending changes from the "log" files
+to the "blkindex.dat" file for maximum compatibility, but makes
+shutdown much slower. Note that the "wallet.dat" file is always
+detached, and versions prior to 0.6.0 detached all databases
+at shutdown.
+
+Bug fixes
+---------
+
+* Prevent RPC 'move' from deadlocking. This was caused by trying to lock the
+ database twice.
+
+* Fix use-after-free problems in initialization and shutdown, the latter of
+ which caused Bitcoin-Qt to crash on Windows when exiting.
+
+* Correct library linking so building on Windows natively works.
+
+* Avoid a race condition and out-of-bounds read in block creation/mining code.
+
+* Improve platform compatibility quirks, including fix for 100% CPU utilization
+ on FreeBSD 9.
+
+* A few minor corrections to error handling, and updated translations.
+
+* OSX 10.5 supported again
+
+----------------------------------------------------
+Thanks to everybody who contributed to this release:
+
+Alex
+dansmith
+Gavin Andresen
+Gregory Maxwell
+Jeff Garzik
+Luke Dashjr
+Philip Kaufmann
+Pieter Wuille
+Wladimir J. van der Laan
+grimd34th
diff --git a/doc/release-notes/release-notes-0.8.0.md b/doc/release-notes/release-notes-0.8.0.md
new file mode 100644
index 0000000000..4e98a7740f
--- /dev/null
+++ b/doc/release-notes/release-notes-0.8.0.md
@@ -0,0 +1,139 @@
+Bitcoin-Qt version 0.8.0 is now available from:
+ http://sourceforge.net/projects/bitcoin/files/Bitcoin/bitcoin-0.8.0/
+
+This is a major release designed to improve performance and handle the
+increasing volume of transactions on the network.
+
+Please report bugs using the issue tracker at github:
+ https://github.com/bitcoin/bitcoin/issues
+
+How to Upgrade
+--------------
+
+If you are running an older version, shut it down. Wait
+until it has completely shut down (which might take a few minutes for older
+versions), then run the installer (on Windows) or just copy over
+/Applications/Bitcoin-Qt (on Mac) or bitcoind/bitcoin-qt (on Linux).
+
+The first time you run after the upgrade a re-indexing process will be
+started that will take anywhere from 30 minutes to several hours,
+depending on the speed of your machine.
+
+Incompatible Changes
+--------------------
+
+This release no longer maintains a full index of historical transaction ids
+by default, so looking up an arbitrary transaction using the getrawtransaction
+RPC call will not work. If you need that functionality, you must run once
+with -txindex=1 -reindex=1 to rebuild block-chain indices (see below for more
+details).
+
+Improvements
+------------
+
+Mac and Windows binaries are signed with certificates owned by the Bitcoin
+Foundation, to be compatible with the new security features in OSX 10.8 and
+Windows 8.
+
+LevelDB, a fast, open-source, non-relational database from Google, is
+now used to store transaction and block indices. LevelDB works much better
+on machines with slow I/O and is faster in general. Berkeley DB is now only
+used for the wallet.dat file (public and private wallet keys and transactions
+relevant to you).
+
+Pieter Wuille implemented many optimizations to the way transactions are
+verified, so a running, synchronized node uses less working memory and does
+much less I/O. He also implemented parallel signature checking, so if you
+have a multi-CPU machine all CPUs will be used to verify transactions.
+
+New Features
+------------
+
+"Bloom filter" support in the network protocol for sending only relevant transactions to
+lightweight clients.
+
+contrib/verifysfbinaries is a shell-script to verify that the binary downloads
+at sourceforge have not been tampered with. If you are able, you can help make
+everybody's downloads more secure by running this occasionally to check PGP
+signatures against download file checksums.
+
+contrib/spendfrom is a python-language command-line utility that demonstrates
+how to use the "raw transactions" JSON-RPC api to send coins received from particular
+addresses (also known as "coin control").
+
+New/changed settings (command-line or bitcoin.conf file)
+--------------------------------------------------------
+
+dbcache : controls LevelDB memory usage.
+
+par : controls how many threads to use to validate transactions. Defaults to the number
+of CPUs on your machine, use -par=1 to limit to a single CPU.
+
+txindex : maintains an extra index of old, spent transaction ids so they will be found
+by the getrawtransaction JSON-RPC method.
+
+reindex : rebuild block and transaction indices from the downloaded block data.
+
+New JSON-RPC API Features
+-------------------------
+
+lockunspent / listlockunspent allow locking transaction outputs for a period of time so
+they will not be spent by other processes that might be accessing the same wallet.
+
+addnode / getaddednodeinfo methods, to connect to specific peers without restarting.
+
+importprivkey now takes an optional boolean parameter (default true) to control whether
+or not to rescan the blockchain for transactions after importing a new private key.
+
+Important Bug Fixes
+-------------------
+
+Privacy leak: the position of the "change" output in most transactions was not being
+properly randomized, making network analysis of the transaction graph to identify
+users' wallets easier.
+
+Zero-confirmation transaction vulnerability: accepting zero-confirmation transactions
+(transactions that have not yet been included in a block) from somebody you do not
+trust is still not recommended, because there will always be ways for attackers to
+double-spend zero-confirmation transactions. However, this release includes a bug
+fix that makes it a little bit more difficult for attackers to double-spend a
+certain type ("lockTime in the future") of zero-confirmation transaction.
+
+Dependency Changes
+------------------
+
+Qt 4.8.3 (compiling against older versions of Qt 4 should continue to work)
+
+
+Thanks to everybody who contributed to this release:
+----------------------------------------------------
+
+Alexander Kjeldaas
+Andrey Alekseenko
+Arnav Singh
+Christian von Roques
+Eric Lombrozo
+Forrest Voight
+Gavin Andresen
+Gregory Maxwell
+Jeff Garzik
+Luke Dashjr
+Matt Corallo
+Mike Cassano
+Mike Hearn
+Peter Todd
+Philip Kaufmann
+Pieter Wuille
+Richard Schwab
+Robert Backhaus
+Rune K. Svendsen
+Sergio Demian Lerner
+Wladimir J. van der Laan
+burger2
+default
+fanquake
+grimd34th
+justmoon
+redshark1802
+tucenaber
+xanatos
diff --git a/doc/release-notes/release-notes-0.8.1.md b/doc/release-notes/release-notes-0.8.1.md
new file mode 100644
index 0000000000..4fd546bee0
--- /dev/null
+++ b/doc/release-notes/release-notes-0.8.1.md
@@ -0,0 +1,22 @@
+Bitcoin-Qt/bitcoind version 0.8.1 is now available from:
+ http://sourceforge.net/projects/bitcoin/files/Bitcoin/bitcoin-0.8.1/
+
+This is a maintenance release that adds a new network rule to avoid
+a chain-forking incompatibility with versions 0.7.2 and earlier.
+
+Please report bugs using the issue tracker at github:
+ https://github.com/bitcoin/bitcoin/issues
+
+
+How to Upgrade
+--------------
+
+If you are running an older version, shut it down. Wait
+until it has completely shut down (which might take a few minutes for older
+versions), then run the installer (on Windows) or just copy over
+/Applications/Bitcoin-Qt (on Mac) or bitcoind/bitcoin-qt (on Linux).
+
+If you are upgrading from version 0.7.2 or earlier, the first time you
+run 0.8.1 your blockchain files will be re-indexed, which will take
+anywhere from 30 minutes to several hours, depending on the speed of
+your machine.
diff --git a/doc/release-notes/release-notes-0.8.2.md b/doc/release-notes/release-notes-0.8.2.md
new file mode 100644
index 0000000000..eea9ba2a2c
--- /dev/null
+++ b/doc/release-notes/release-notes-0.8.2.md
@@ -0,0 +1,137 @@
+Bitcoin-Qt version 0.8.2 is now available from:
+ http://sourceforge.net/projects/bitcoin/files/Bitcoin/bitcoin-0.8.2/
+
+This is a maintenance release that fixes many bugs and includes
+a few small new features.
+
+Please report bugs using the issue tracker at github:
+ https://github.com/bitcoin/bitcoin/issues
+
+
+How to Upgrade
+
+If you are running an older version, shut it down. Wait
+until it has completely shut down (which might take a few minutes for older
+versions), then run the installer (on Windows) or just copy over
+/Applications/Bitcoin-Qt (on Mac) or bitcoind/bitcoin-qt (on Linux).
+
+If you are upgrading from version 0.7.2 or earlier, the first time you
+run 0.8.2 your blockchain files will be re-indexed, which will take
+anywhere from 30 minutes to several hours, depending on the speed of
+your machine.
+
+0.8.2 Release notes
+
+Fee Policy changes
+
+The default fee for low-priority transactions is lowered from 0.0005 BTC
+(for each 1,000 bytes in the transaction; an average transaction is
+about 500 bytes) to 0.0001 BTC.
+
+Payments (transaction outputs) of 0.543 times the minimum relay fee
+(0.00005430 BTC) are now considered 'non-standard', because storing them
+costs the network more than they are worth and spending them will usually
+cost their owner more in transaction fees than they are worth.
+
+Non-standard transactions are not relayed across the network, are not included
+in blocks by most miners, and will not show up in your wallet until they are
+included in a block.
+
+The default fee policy can be overridden using the -mintxfee and -minrelaytxfee
+command-line options, but note that we intend to replace the hard-coded fees
+with code that automatically calculates and suggests appropriate fees in the
+0.9 release and note that if you set a fee policy significantly different from
+the rest of the network your transactions may never confirm.
+
+Bitcoin-Qt changes
+
+* New icon and splash screen
+* Improve reporting of synchronization process
+* Remove hardcoded fee recommendations
+* Improve metadata of executable on MacOSX and Windows
+* Move export button to individual tabs instead of toolbar
+* Add "send coins" command to context menu in address book
+* Add "copy txid" command to copy transaction IDs from transaction overview
+* Save & restore window size and position when showing & hiding window
+* New translations: Arabic (ar), Bosnian (bs), Catalan (ca), Welsh (cy),
+ Esperanto (eo), Interlingua (la), Latvian (lv) and many improvements
+ to current translations
+
+MacOSX:
+* OSX support for click-to-pay (bitcoin:) links
+* Fix GUI disappearing problem on MacOSX (issue #1522)
+
+Linux/Unix:
+* Copy addresses to middle-mouse-button clipboard
+
+
+Command-line options
+
+* -walletnotify will call a command on receiving transactions that affect the wallet.
+* -alertnotify will call a command on receiving an alert from the network.
+* -par now takes a negative number, to leave a certain amount of cores free.
+
+JSON-RPC API changes
+
+* fixed a getblocktemplate bug that caused excessive CPU creating blocks.
+* listunspent now lists account and address information.
+* getinfo now also returns the time adjustment estimated from your peers.
+* getpeerinfo now returns bytessent, bytesrecv and syncnode.
+* gettxoutsetinfo returns statistics about the unspent transaction output database.
+* gettxout returns information about a specific unspent transaction output.
+
+
+Networking changes
+
+* Significant changes to the networking code, reducing latency and memory consumption.
+* Avoid initial block download stalling.
+* Remove IRC seeding support.
+* Performance tweaks.
+* Added testnet DNS seeds.
+
+Wallet compatibility/rescuing
+
+* Cases where wallets cannot be opened in another version/installation should be reduced.
+* -salvagewallet now works for encrypted wallets.
+
+
+Known Bugs
+
+* Entering the 'getblocktemplate' or 'getwork' RPC commands into the Bitcoin-Qt debug
+console will cause Bitcoin-Qt to crash. Run Bitcoin-Qt with the -server command-line
+option to workaround.
+
+Thanks to everybody who contributed to the 0.8.2 release!
+
+APerson241
+Andrew Poelstra
+Calvin Owens
+Chuck LeDuc Díaz
+Colin Dean
+David Griffith
+David Serrano
+Eric Lombrozo
+Gavin Andresen
+Gregory Maxwell
+Jeff Garzik
+Jonas Schnelli
+Larry Gilbert
+Luke Dashjr
+Matt Corallo
+Michael Ford
+Mike Hearn
+Patrick Brown
+Peter Todd
+Philip Kaufmann
+Pieter Wuille
+Richard Schwab
+Roman Mindalev
+Scott Howard
+Tariq Bashir
+Warren Togami
+Wladimir J. van der Laan
+freewil
+gladoscc
+kjj2
+mb300sd
+super3
diff --git a/doc/release-notes/release-notes-0.8.3.md b/doc/release-notes/release-notes-0.8.3.md
new file mode 100644
index 0000000000..856c20aa33
--- /dev/null
+++ b/doc/release-notes/release-notes-0.8.3.md
@@ -0,0 +1,18 @@
+Bitcoin-Qt version 0.8.3 is now available from:
+ http://sourceforge.net/projects/bitcoin/files/Bitcoin/bitcoin-0.8.3/
+
+This is a maintenance release to fix a denial-of-service attack that
+can cause nodes to crash.
+
+Please report bugs using the issue tracker at github:
+ https://github.com/bitcoin/bitcoin/issues
+
+0.8.3 Release notes
+
+Truncate over-size messages to prevent a memory exhaustion attack.
+
+Fix a regression that causes excessive re-writing of the 'peers.dat' file.
+
+
+Thanks to Peter Todd for responsibly disclosing the vulnerability
+( CVE-2013-4627 ) and creating a fix.
diff --git a/doc/release-notes/release-notes-0.8.4.md b/doc/release-notes/release-notes-0.8.4.md
new file mode 100644
index 0000000000..c6f31f1fa4
--- /dev/null
+++ b/doc/release-notes/release-notes-0.8.4.md
@@ -0,0 +1,83 @@
+Bitcoin-Qt version 0.8.4 is now available from:
+ http://sourceforge.net/projects/bitcoin/files/Bitcoin/bitcoin-0.8.4/
+
+This is a maintenance release to fix a critical bug and three
+security issues; we urge all users to upgrade.
+
+Please report bugs using the issue tracker at github:
+ https://github.com/bitcoin/bitcoin/issues
+
+
+How to Upgrade
+--------------
+
+If you are running an older version, shut it down. Wait
+until it has completely shut down (which might take a few minutes for older
+versions), then run the installer (on Windows) or just copy over
+/Applications/Bitcoin-Qt (on Mac) or bitcoind/bitcoin-qt (on Linux).
+
+If you are upgrading from version 0.7.2 or earlier, the first time you
+run 0.8.4 your blockchain files will be re-indexed, which will take
+anywhere from 30 minutes to several hours, depending on the speed of
+your machine.
+
+0.8.4 Release notes
+===================
+
+Security issues
+---------------
+
+An attacker could send a series of messages that resulted in
+an integer division-by-zero error in the Bloom Filter handling
+code, causing the Bitcoin-Qt or bitcoind process to crash.
+Bloom filters were introduced with version 0.8, so versions 0.8.0
+through 0.8.3 are vulnerable to this critical denial-of-service attack.
+
+A constant-time algorithm is now used to check RPC password
+guess attempts; fixes https://github.com/bitcoin/bitcoin/issues/2838
+(CVE-2013-4165)
+
+Implement a better fix for the fill-memory-with-orphan-transactions
+attack that was fixed in 0.8.3. See
+https://bitslog.wordpress.com/2013/07/18/buggy-cve-2013-4627-patch-open-new-vectors-of-attack/
+for a description of the weaknesses of the previous fix.
+(CVE-2013-4627)
+
+Bugs fixed
+----------
+
+Fix multi-block reorg transaction resurrection.
+
+Fix non-standard disconnected transactions causing mempool orphans.
+This bug could cause nodes running with the -debug flag to crash.
+
+OSX: use 'FD_FULLSYNC' with LevelDB, which will (hopefully!)
+prevent the database corruption issues many people have
+experienced on OSX.
+
+Linux: clicking on bitcoin: links was broken if you were using
+a Gnome-based desktop.
+
+Fix a hang-at-shutdown bug that only affects users that compile
+their own version of Bitcoin against Boost versions 1.50-1.52.
+
+Other changes
+-------------
+
+Checkpoint at block 250,000 to speed up initial block downloads
+and make the progress indicator when downloading more accurate.
+
+
+Thanks to everybody who contributed to the 0.8.4 releases!
+----------------------------------------------------------
+
+Pieter Wuille
+Warren Togami
+Patrick Strateman
+pakt
+Gregory Maxwell
+Sergio Demian Lerner
+grayleonard
+Cory Fields
+Matt Corallo
+Gavin Andresen
diff --git a/doc/release-notes/release-notes-0.8.5.md b/doc/release-notes/release-notes-0.8.5.md
new file mode 100644
index 0000000000..aa93fe7c71
--- /dev/null
+++ b/doc/release-notes/release-notes-0.8.5.md
@@ -0,0 +1,44 @@
+Bitcoin-Qt version 0.8.5 is now available from:
+ http://sourceforge.net/projects/bitcoin/files/Bitcoin/bitcoin-0.8.5/
+
+This is a maintenance release to fix a critical bug;
+we urge all users to upgrade.
+
+Please report bugs using the issue tracker at github:
+ https://github.com/bitcoin/bitcoin/issues
+
+
+How to Upgrade
+--------------
+
+If you are running an older version, shut it down. Wait
+until it has completely shut down (which might take a few minutes for older
+versions), then run the installer (on Windows) or just copy over
+/Applications/Bitcoin-Qt (on Mac) or bitcoind/bitcoin-qt (on Linux).
+
+If you are upgrading from version 0.7.2 or earlier, the first time you
+run 0.8.5 your blockchain files will be re-indexed, which will take
+anywhere from 30 minutes to several hours, depending on the speed of
+your machine.
+
+0.8.5 Release notes
+===================
+
+Bugs fixed
+----------
+
+Transactions with version numbers larger than 0x7fffffff were
+incorrectly being relayed and included in blocks.
+
+Blocks containing transactions with version numbers larger
+than 0x7fffffff caused the code that checks for LevelDB database
+inconsistencies at startup to erroneously report database
+corruption and suggest that you reindex your database.
+
+This release also contains a non-critical fix to the code that
+enforces BIP 34 (block height in the coinbase transaction).
+
+--
+
+Thanks to Gregory Maxwell and Pieter Wuille for quickly
+identifying and fixing the transaction version number bug.
diff --git a/doc/release-notes/release-notes-0.8.6.md b/doc/release-notes/release-notes-0.8.6.md
new file mode 100644
index 0000000000..39a45e0db5
--- /dev/null
+++ b/doc/release-notes/release-notes-0.8.6.md
@@ -0,0 +1,66 @@
+Bitcoin-Qt version 0.8.6 final is now available from:
+
+ http://sourceforge.net/projects/bitcoin/files/Bitcoin/bitcoin-0.8.6/
+
+This is a maintenance release to fix a critical bug; we urge all users to upgrade.
+
+Please report bugs using the issue tracker at github:
+
+ https://github.com/bitcoin/bitcoin/issues
+
+How to Upgrade
+--------------
+
+If you already downloaded 0.8.6rc1 you do not need to re-download. This release is exactly the same.
+
+If you are running an older version, shut it down. Wait
+until it has completely shut down (which might take a few minutes for older
+versions), then run the installer (on Windows) or just copy over
+/Applications/Bitcoin-Qt (on Mac) or bitcoind/bitcoin-qt (on Linux).
+
+If you are upgrading from version 0.7.2 or earlier, the first time you
+run 0.8.6 your blockchain files will be re-indexed, which will take
+anywhere from 30 minutes to several hours, depending on the speed of
+your machine.
+
+0.8.6 Release notes
+===================
+
+- Default block size increase for miners.
+ (see https://gist.github.com/gavinandresen/7670433#086-accept-into-block)
+
+- Remove the all-outputs-must-be-greater-than-CENT-to-qualify-as-free rule for relaying
+ (see https://gist.github.com/gavinandresen/7670433#086-relaying)
+
+- Lower maximum size for free transaction creation
+ (see https://gist.github.com/gavinandresen/7670433#086-wallet)
+
+- OSX block chain database corruption fixes
+ - Update leveldb to 1.13
+ - Use fcntl with `F_FULLSYNC` instead of fsync on OSX
+ - Use native Darwin memory barriers
+ - Replace use of mmap in leveldb for improved reliability (only on OSX)
+
+- Fix nodes forwarding transactions with empty vins and getting banned
+
+- Network code performance and robustness improvements
+
+- Additional debug.log logging for diagnosis of network problems, log timestamps by default
+
+- Fix Bitcoin-Qt startup crash when clicking dock icon on OSX
+
+- Fix memory leaks in CKey::SetCompactSignature() and Key::SignCompact()
+
+- Fix rare GUI crash on send
+
+- Various small GUI, documentation and build fixes
+
+Warning
+-------
+
+- There have been frequent reports of users running out of virtual memory on 32-bit systems
+ during the initial sync.
+ Hence it is recommended to use a 64-bit executable if possible.
+ A 64-bit executable for Windows is planned for 0.9.
+
+Note: Gavin Andresen's GPG signing key for SHA256SUMS.asc has been changed from key id 1FC730C1 to sub key 7BF6E212 (see https://github.com/bitcoin/bitcoin.org/pull/279).
diff --git a/doc/release-notes/release-notes-0.9.0.md b/doc/release-notes/release-notes-0.9.0.md
new file mode 100644
index 0000000000..170410ca40
--- /dev/null
+++ b/doc/release-notes/release-notes-0.9.0.md
@@ -0,0 +1,411 @@
+Bitcoin Core version 0.9.0 is now available from:
+
+ https://bitcoin.org/bin/0.9.0/
+
+This is a new major version release, bringing both new features and
+bug fixes.
+
+Please report bugs using the issue tracker at github:
+
+ https://github.com/bitcoin/bitcoin/issues
+
+How to Upgrade
+--------------
+
+If you are running an older version, shut it down. Wait until it has completely
+shut down (which might take a few minutes for older versions), uninstall all
+earlier versions of Bitcoin, then run the installer (on Windows) or just copy
+over /Applications/Bitcoin-Qt (on Mac) or bitcoind/bitcoin-qt (on Linux).
+
+If you are upgrading from version 0.7.2 or earlier, the first time you run
+0.9.0 your blockchain files will be re-indexed, which will take anywhere from
+30 minutes to several hours, depending on the speed of your machine.
+
+On Windows, do not forget to uninstall all earlier versions of the Bitcoin
+client first, especially if you are switching to the 64-bit version.
+
+Windows 64-bit installer
+-------------------------
+
+New in 0.9.0 is the Windows 64-bit version of the client. There have been
+frequent reports of users running out of virtual memory on 32-bit systems
+during the initial sync. Because of this it is recommended to install the
+64-bit version if your system supports it.
+
+NOTE: Release candidate 2 Windows binaries are not code-signed; use PGP
+and the SHA256SUMS.asc file to make sure your binaries are correct.
+In the final 0.9.0 release, Windows setup.exe binaries will be code-signed.
+
+OSX 10.5 / 32-bit no longer supported
+-------------------------------------
+
+0.9.0 drops support for older Macs. The minimum requirements are now:
+* A 64-bit-capable CPU (see http://support.apple.com/kb/ht3696);
+* Mac OS 10.6 or later (see https://support.apple.com/kb/ht1633).
+
+Downgrading warnings
+--------------------
+
+The 'chainstate' for this release is not always compatible with previous
+releases, so if you run 0.9 and then decide to switch back to a
+0.8.x release you might get a blockchain validation error when starting the
+old release (due to 'pruned outputs' being omitted from the index of
+unspent transaction outputs).
+
+Running the old release with the -reindex option will rebuild the chainstate
+data structures and correct the problem.
+
+Also, the first time you run a 0.8.x release on a 0.9 wallet it will rescan
+the blockchain for missing spent coins, which will take a long time (tens
+of minutes on a typical machine).
+
+Rebranding to Bitcoin Core
+---------------------------
+
+To reduce confusion between Bitcoin-the-network and Bitcoin-the-software we
+have renamed the reference client to Bitcoin Core.
+
+
+OP_RETURN and data in the block chain
+-------------------------------------
+On OP_RETURN: There was been some confusion and misunderstanding in
+the community, regarding the OP_RETURN feature in 0.9 and data in the
+blockchain. This change is not an endorsement of storing data in the
+blockchain. The OP_RETURN change creates a provably-prunable output,
+to avoid data storage schemes -- some of which were already deployed --
+that were storing arbitrary data such as images as forever-unspendable
+TX outputs, bloating bitcoin's UTXO database.
+
+Storing arbitrary data in the blockchain is still a bad idea; it is less
+costly and far more efficient to store non-currency data elsewhere.
+
+Autotools build system
+-----------------------
+
+For 0.9.0 we switched to an autotools-based build system instead of individual
+(q)makefiles.
+
+Using the standard "./autogen.sh; ./configure; make" to build Bitcoin-Qt and
+bitcoind makes it easier for experienced open source developers to contribute
+to the project.
+
+Be sure to check doc/build-*.md for your platform before building from source.
+
+Bitcoin-cli
+-------------
+
+Another change in the 0.9 release is moving away from the bitcoind executable
+functioning both as a server and as a RPC client. The RPC client functionality
+("tell the running bitcoin daemon to do THIS") was split into a separate
+executable, 'bitcoin-cli'. The RPC client code will eventually be removed from
+bitcoind, but will be kept for backwards compatibility for a release or two.
+
+`walletpassphrase` RPC
+-----------------------
+
+The behavior of the `walletpassphrase` RPC when the wallet is already unlocked
+has changed between 0.8 and 0.9.
+
+The 0.8 behavior of `walletpassphrase` is to fail when the wallet is already unlocked:
+
+ > walletpassphrase 1000
+ walletunlocktime = now + 1000
+ > walletpassphrase 10
+ Error: Wallet is already unlocked (old unlock time stays)
+
+The new behavior of `walletpassphrase` is to set a new unlock time overriding
+the old one:
+
+ > walletpassphrase 1000
+ walletunlocktime = now + 1000
+ > walletpassphrase 10
+ walletunlocktime = now + 10 (overriding the old unlock time)
+
+Transaction malleability-related fixes
+--------------------------------------
+
+This release contains a few fixes for transaction ID (TXID) malleability
+issues:
+
+- -nospendzeroconfchange command-line option, to avoid spending
+ zero-confirmation change
+- IsStandard() transaction rules tightened to prevent relaying and mining of
+ mutated transactions
+- Additional information in listtransactions/gettransaction output to
+ report wallet transactions that conflict with each other because
+ they spend the same outputs.
+- Bug fixes to the getbalance/listaccounts RPC commands, which would report
+ incorrect balances for double-spent (or mutated) transactions.
+- New option: -zapwallettxes to rebuild the wallet's transaction information
+
+Transaction Fees
+----------------
+
+This release drops the default fee required to relay transactions across the
+network and for miners to consider the transaction in their blocks to
+0.01mBTC per kilobyte.
+
+Note that getting a transaction relayed across the network does NOT guarantee
+that the transaction will be accepted by a miner; by default, miners fill
+their blocks with 50 kilobytes of high-priority transactions, and then with
+700 kilobytes of the highest-fee-per-kilobyte transactions.
+
+The minimum relay/mining fee-per-kilobyte may be changed with the
+minrelaytxfee option. Note that previous releases incorrectly used
+the mintxfee setting to determine which low-priority transactions should
+be considered for inclusion in blocks.
+
+The wallet code still uses a default fee for low-priority transactions of
+0.1mBTC per kilobyte. During periods of heavy transaction volume, even this
+fee may not be enough to get transactions confirmed quickly; the mintxfee
+option may be used to override the default.
+
+0.9.0 Release notes
+=======================
+
+RPC:
+
+- New notion of 'conflicted' transactions, reported as confirmations: -1
+- 'listreceivedbyaddress' now provides tx ids
+- Add raw transaction hex to 'gettransaction' output
+- Updated help and tests for 'getreceivedby(account|address)'
+- In 'getblock', accept 2nd 'verbose' parameter, similar to getrawtransaction,
+ but defaulting to 1 for backward compatibility
+- Add 'verifychain', to verify chain database at runtime
+- Add 'dumpwallet' and 'importwallet' RPCs
+- 'keypoolrefill' gains optional size parameter
+- Add 'getbestblockhash', to return tip of best chain
+- Add 'chainwork' (the total work done by all blocks since the genesis block)
+ to 'getblock' output
+- Make RPC password resistant to timing attacks
+- Clarify help messages and add examples
+- Add 'getrawchangeaddress' call for raw transaction change destinations
+- Reject insanely high fees by default in 'sendrawtransaction'
+- Add RPC call 'decodescript' to decode a hex-encoded transaction script
+- Make 'validateaddress' provide redeemScript
+- Add 'getnetworkhashps' to get the calculated network hashrate
+- New RPC 'ping' command to request ping, new 'pingtime' and 'pingwait' fields
+ in 'getpeerinfo' output
+- Adding new 'addrlocal' field to 'getpeerinfo' output
+- Add verbose boolean to 'getrawmempool'
+- Add rpc command 'getunconfirmedbalance' to obtain total unconfirmed balance
+- Explicitly ensure that wallet is unlocked in `importprivkey`
+- Add check for valid keys in `importprivkey`
+
+Command-line options:
+
+- New option: -nospendzeroconfchange to never spend unconfirmed change outputs
+- New option: -zapwallettxes to rebuild the wallet's transaction information
+- Rename option '-tor' to '-onion' to better reflect what it does
+- Add '-disablewallet' mode to let bitcoind run entirely without wallet (when
+ built with wallet)
+- Update default '-rpcsslciphers' to include TLSv1.2
+- make '-logtimestamps' default on and rework help-message
+- RPC client option: '-rpcwait', to wait for server start
+- Remove '-logtodebugger'
+- Allow `-noserver` with bitcoind
+
+Block-chain handling and storage:
+
+- Update leveldb to 1.15
+- Check for correct genesis (prevent cases where a datadir from the wrong
+ network is accidentally loaded)
+- Allow txindex to be removed and add a reindex dialog
+- Log aborted block database rebuilds
+- Store orphan blocks in serialized form, to save memory
+- Limit the number of orphan blocks in memory to 750
+- Fix non-standard disconnected transactions causing mempool orphans
+- Add a new checkpoint at block 279,000
+
+Wallet:
+
+- Bug fixes and new regression tests to correctly compute
+ the balance of wallets containing double-spent (or mutated) transactions
+- Store key creation time. Calculate whole-wallet birthday.
+- Optimize rescan to skip blocks prior to birthday
+- Let user select wallet file with -wallet=foo.dat
+- Consider generated coins mature at 101 instead of 120 blocks
+- Improve wallet load time
+- Don't count txins for priority to encourage sweeping
+- Don't create empty transactions when reading a corrupted wallet
+- Fix rescan to start from beginning after importprivkey
+- Only create signatures with low S values
+
+Mining:
+
+- Increase default -blockmaxsize/prioritysize to 750K/50K
+- 'getblocktemplate' does not require a key to create a block template
+- Mining code fee policy now matches relay fee policy
+
+Protocol and network:
+
+- Drop the fee required to relay a transaction to 0.01mBTC per kilobyte
+- Send tx relay flag with version
+- New 'reject' P2P message (BIP 0061, see
+ https://gist.github.com/gavinandresen/7079034 for draft)
+- Dump addresses every 15 minutes instead of 10 seconds
+- Relay OP_RETURN data TxOut as standard transaction type
+- Remove CENT-output free transaction rule when relaying
+- Lower maximum size for free transaction creation
+- Send multiple inv messages if mempool.size > MAX_INV_SZ
+- Split MIN_PROTO_VERSION into INIT_PROTO_VERSION and MIN_PEER_PROTO_VERSION
+- Do not treat fFromMe transaction differently when broadcasting
+- Process received messages one at a time without sleeping between messages
+- Improve logging of failed connections
+- Bump protocol version to 70002
+- Add some additional logging to give extra network insight
+- Added new DNS seed from bitcoinstats.com
+
+Validation:
+
+- Log reason for non-standard transaction rejection
+- Prune provably-unspendable outputs, and adapt consistency check for it.
+- Detect any sufficiently long fork and add a warning
+- Call the -alertnotify script when we see a long or invalid fork
+- Fix multi-block reorg transaction resurrection
+- Reject non-canonically-encoded serialization sizes
+- Reject dust amounts during validation
+- Accept nLockTime transactions that finalize in the next block
+
+Build system:
+
+- Switch to autotools-based build system
+- Build without wallet by passing `--disable-wallet` to configure, this
+ removes the BerkeleyDB dependency
+- Upgrade gitian dependencies (libpng, libz, libupnpc, boost, openssl) to more
+ recent versions
+- Windows 64-bit build support
+- Solaris compatibility fixes
+- Check integrity of gitian input source tarballs
+- Enable full GCC Stack-smashing protection for all OSes
+
+GUI:
+
+- Switch to Qt 5.2.0 for Windows build
+- Add payment request (BIP 0070) support
+- Improve options dialog
+- Show transaction fee in new send confirmation dialog
+- Add total balance in overview page
+- Allow user to choose data directory on first start, when data directory is
+ missing, or when the -choosedatadir option is passed
+- Save and restore window positions
+- Add vout index to transaction id in transactions details dialog
+- Add network traffic graph in debug window
+- Add open URI dialog
+- Add Coin Control Features
+- Improve receive coins workflow: make the 'Receive' tab into a form to request
+ payments, and move historical address list functionality to File menu.
+- Rebrand to `Bitcoin Core`
+- Move initialization/shutdown to a thread. This prevents "Not responding"
+ messages during startup. Also show a window during shutdown.
+- Don't regenerate autostart link on every client startup
+- Show and store message of normal bitcoin:URI
+- Fix richtext detection hang issue on very old Qt versions
+- OS X: Make use of the 10.8+ user notification center to display Growl-like
+ notifications
+- OS X: Added NSHighResolutionCapable flag to Info.plist for better font
+ rendering on Retina displays.
+- OS X: Fix bitcoin-qt startup crash when clicking dock icon
+- Linux: Fix Gnome bitcoin: URI handler
+
+Miscellaneous:
+
+- Add Linux script (contrib/qos/tc.sh) to limit outgoing bandwidth
+- Add '-regtest' mode, similar to testnet but private with instant block
+ generation with 'setgenerate' RPC.
+- Add 'linearize.py' script to contrib, for creating bootstrap.dat
+- Add separate bitcoin-cli client
+
+Credits
+--------
+
+Thanks to everyone who contributed to this release:
+
+- Andrey
+- Ashley Holman
+- b6393ce9-d324-4fe1-996b-acf82dbc3d53
+- bitsofproof
+- Brandon Dahler
+- Calvin Tam
+- Christian Decker
+- Christian von Roques
+- Christopher Latham
+- Chuck
+- coblee
+- constantined
+- Cory Fields
+- Cozz Lovan
+- daniel
+- Daniel Larimer
+- David Hill
+- Dmitry Smirnov
+- Drak
+- Eric Lombrozo
+- fanquake
+- fcicq
+- Florin
+- frewil
+- Gavin Andresen
+- Gregory Maxwell
+- gubatron
+- Guillermo Céspedes Tabárez
+- Haakon Nilsen
+- HaltingState
+- Han Lin Yap
+- harry
+- Ian Kelling
+- Jeff Garzik
+- Johnathan Corgan
+- Jonas Schnelli
+- Josh Lehan
+- Josh Triplett
+- Julian Langschaedel
+- Kangmo
+- Lake Denman
+- Luke Dashjr
+- Mark Friedenbach
+- Matt Corallo
+- Michael Bauer
+- Michael Ford
+- Michagogo
+- Midnight Magic
+- Mike Hearn
+- Nils Schneider
+- Noel Tiernan
+- Olivier Langlois
+- patrick s
+- Patrick Strateman
+- paveljanik
+- Peter Todd
+- phantomcircuit
+- phelixbtc
+- Philip Kaufmann
+- Pieter Wuille
+- Rav3nPL
+- R E Broadley
+- regergregregerrge
+- Robert Backhaus
+- Roman Mindalev
+- Rune K. Svendsen
+- Ryan Niebur
+- Scott Ellis
+- Scott Willeke
+- Sergey Kazenyuk
+- Shawn Wilkinson
+- Sined
+- sje
+- Subo1978
+- super3
+- Tamas Blummer
+- theuni
+- Thomas Holenstein
+- Timon Rapp
+- Timothy Stranex
+- Tom Geller
+- Torstein Husebø
+- Vaclav Vobornik
+- vhf / victor felder
+- Vinnie Falco
+- Warren Togami
+- Wil Bown
+- Wladimir J. van der Laan
diff --git a/doc/release-notes/release-notes-0.9.1.md b/doc/release-notes/release-notes-0.9.1.md
new file mode 100644
index 0000000000..0552053d27
--- /dev/null
+++ b/doc/release-notes/release-notes-0.9.1.md
@@ -0,0 +1,53 @@
+Bitcoin Core version 0.9.1 is now available from:
+
+ https://bitcoin.org/bin/0.9.1/
+
+This is a security update. It is recommended to upgrade to this release
+as soon as possible.
+
+It is especially important to upgrade if you currently have version
+0.9.0 installed and are using the graphical interface OR you are using
+bitcoind from any pre-0.9.1 version, and have enabled SSL for RPC and
+have configured allowip to allow rpc connections from potentially
+hostile hosts.
+
+Please report bugs using the issue tracker at github:
+
+ https://github.com/bitcoin/bitcoin/issues
+
+How to Upgrade
+--------------
+
+If you are running an older version, shut it down. Wait until it has completely
+shut down (which might take a few minutes for older versions), then run the
+installer (on Windows) or just copy over /Applications/Bitcoin-Qt (on Mac) or
+bitcoind/bitcoin-qt (on Linux).
+
+If you are upgrading from version 0.7.2 or earlier, the first time you run
+0.9.1 your blockchain files will be re-indexed, which will take anywhere from
+30 minutes to several hours, depending on the speed of your machine.
+
+0.9.1 Release notes
+=======================
+
+No code changes were made between 0.9.0 and 0.9.1. Only the dependencies were changed.
+
+- Upgrade OpenSSL to 1.0.1g. This release fixes the following vulnerabilities which can
+ affect the Bitcoin Core software:
+
+ - CVE-2014-0160 ("heartbleed")
+ A missing bounds check in the handling of the TLS heartbeat extension can
+ be used to reveal up to 64k of memory to a connected client or server.
+
+ - CVE-2014-0076
+ The Montgomery ladder implementation in OpenSSL does not ensure that
+ certain swap operations have a constant-time behavior, which makes it
+ easier for local users to obtain ECDSA nonces via a FLUSH+RELOAD cache
+ side-channel attack.
+
+- Add statically built executables to Linux build
+
+Credits
+--------
+
+Credits go to the OpenSSL team for fixing the vulnerabilities quickly.
diff --git a/doc/release-notes/release-notes-0.9.2.1.md b/doc/release-notes/release-notes-0.9.2.1.md
new file mode 100644
index 0000000000..3168ad1a5a
--- /dev/null
+++ b/doc/release-notes/release-notes-0.9.2.1.md
@@ -0,0 +1,207 @@
+Bitcoin Core version 0.9.2.1 is now available from:
+
+ https://bitcoin.org/bin/0.9.2.1/
+
+This is a new minor version release, bringing mostly bug fixes and some minor
+improvements. OpenSSL has been updated because of a security issue (CVE-2014-0224).
+Upgrading to this release is recommended.
+
+Please report bugs using the issue tracker at github:
+
+ https://github.com/bitcoin/bitcoin/issues
+
+How to Upgrade
+--------------
+
+If you are running an older version, shut it down. Wait until it has completely
+shut down (which might take a few minutes for older versions), then run the
+installer (on Windows) or just copy over /Applications/Bitcoin-Qt (on Mac) or
+bitcoind/bitcoin-qt (on Linux).
+
+If you are upgrading from version 0.7.2 or earlier, the first time you run
+0.9.2.1 your blockchain files will be re-indexed, which will take anywhere from
+30 minutes to several hours, depending on the speed of your machine.
+
+Downgrading warnings
+--------------------
+
+The 'chainstate' for this release is not always compatible with previous
+releases, so if you run 0.9.x and then decide to switch back to a
+0.8.x release you might get a blockchain validation error when starting the
+old release (due to 'pruned outputs' being omitted from the index of
+unspent transaction outputs).
+
+Running the old release with the -reindex option will rebuild the chainstate
+data structures and correct the problem.
+
+Also, the first time you run a 0.8.x release on a 0.9 wallet it will rescan
+the blockchain for missing spent coins, which will take a long time (tens
+of minutes on a typical machine).
+
+Important changes
+==================
+
+Gitian OSX build
+-----------------
+
+The deterministic build system that was already used for Windows and Linux
+builds is now used for OSX as well. Although the resulting executables have
+been tested quite a bit, there could be possible regressions. Be sure to report
+these on the Github bug tracker mentioned above.
+
+Compatibility of Linux build
+-----------------------------
+
+For Linux we now build against Qt 4.6, and filter the symbols for libstdc++ and glibc.
+This brings back compatibility with
+
+- Debian 6+ / Tails
+- Ubuntu 10.04
+- CentOS 6.5
+
+0.9.2 - 0.9.2.1 Release notes
+=======================
+
+The OpenSSL dependency in the gitian builds has been upgraded to 1.0.1h because of CVE-2014-0224.
+
+RPC:
+
+- Add `getwalletinfo`, `getblockchaininfo` and `getnetworkinfo` calls (will replace hodge-podge `getinfo` at some point)
+- Add a `relayfee` field to `getnetworkinfo`
+- Fix RPC related shutdown hangs and leaks
+- Always show syncnode in `getpeerinfo`
+- `sendrawtransaction`: report the reject code and reason, and make it possible to re-send transactions that are already in the mempool
+- `getmininginfo` show right genproclimit
+
+Command-line options:
+
+- Fix `-printblocktree` output
+- Show error message if ReadConfigFile fails
+
+Block-chain handling and storage:
+
+- Fix for GetBlockValue() after block 13,440,000 (BIP42)
+- Upgrade leveldb to 1.17
+
+Protocol and network code:
+
+- Per-peer block download tracking and stalled download detection
+- Add new DNS seed from bitnodes.io
+- Prevent socket leak in ThreadSocketHandler and correct some proxy related socket leaks
+- Use pnode->nLastRecv as sync score (was the wrong way around)
+
+Wallet:
+
+- Make GetAvailableCredit run GetHash() only once per transaction (performance improvement)
+- Lower paytxfee warning threshold from 0.25 BTC to 0.01 BTC
+- Fix importwallet nTimeFirstKey (trigger necessary rescans)
+- Log BerkeleyDB version at startup
+- CWallet init fix
+
+Build system:
+
+- Add OSX build descriptors to gitian
+- Fix explicit --disable-qt-dbus
+- Don't require db_cxx.h when compiling with wallet disabled and GUI enabled
+- Improve missing boost error reporting
+- Upgrade miniupnpc version to 1.9
+- gitian-linux: --enable-glibc-back-compat for binary compatibility with old distributions
+- gitian: don't export any symbols from executable
+- gitian: build against Qt 4.6
+- devtools: add script to check symbols from Linux gitian executables
+- Remove build-time no-IPv6 setting
+
+GUI:
+
+- Fix various coin control visual issues
+- Show number of in/out connections in debug console
+- Show weeks as well as years behind for long timespans behind
+- Enable and disable the Show and Remove buttons for requested payments history based on whether any entry is selected.
+- Show also value for options overridden on command line in options dialog
+- Fill in label from address book also for URIs
+- Fixes feel when resizing the last column on tables (issue #2862)
+- Fix ESC in disablewallet mode
+- Add expert section to wallet tab in optionsdialog
+- Do proper boost::path conversion (fixes unicode in datadir)
+- Only override -datadir if different from the default (fixes -datadir in config file)
+- Show rescan progress at start-up
+- Show importwallet progress
+- Get required locks upfront in polling functions (avoids hanging on locks)
+- Catch Windows shutdown events while client is running
+- Optionally add third party links to transaction context menu
+- Check for !pixmap() before trying to export QR code (avoids crashes when no QR code could be generated)
+- Fix "Start bitcoin on system login"
+
+Miscellaneous:
+
+- Replace non-threadsafe C functions (gmtime, strerror and setlocale)
+- Add missing cs_main and wallet locks
+- Avoid exception at startup when system locale not recognized
+- Changed bitrpc.py's raw_input to getpass for passwords to conceal characters during command line input
+- devtools: add a script to fetch and postprocess translations
+
+Credits
+--------
+
+Thanks to everyone who contributed to this release:
+
+- Addy Yeow
+- Altoidnerd
+- Andrea D'Amore
+- Andreas Schildbach
+- Bardi Harborow
+- Brandon Dahler
+- Bryan Bishop
+- Chris Beams
+- Christian von Roques
+- Cory Fields
+- Cozz Lovan
+- daniel
+- Daniel Newton
+- David A. Harding
+- ditto-b
+- duanemoody
+- Eric S. Bullington
+- Fabian Raetz
+- Gavin Andresen
+- Gregory Maxwell
+- gubatron
+- Haakon Nilsen
+- harry
+- Hector Jusforgues
+- Isidoro Ghezzi
+- Jeff Garzik
+- Johnathan Corgan
+- jtimon
+- Kamil Domanski
+- langerhans
+- Luke Dashjr
+- Manuel Araoz
+- Mark Friedenbach
+- Matt Corallo
+- Matthew Bogosian
+- Meeh
+- Michael Ford
+- Michagogo
+- Mikael Wikman
+- Mike Hearn
+- olalonde
+- paveljanik
+- peryaudo
+- Philip Kaufmann
+- philsong
+- Pieter Wuille
+- R E Broadley
+- richierichrawr
+- Rune K. Svendsen
+- rxl
+- shshshsh
+- Simon de la Rouviere
+- Stuart Cardall
+- super3
+- Telepatheic
+- Thomas Zander
+- Torstein Husebø
+- Warren Togami
+- Wladimir J. van der Laan
+- Yoichi Hirai
diff --git a/doc/release-notes/release-notes-0.9.2.md b/doc/release-notes/release-notes-0.9.2.md
new file mode 100644
index 0000000000..a2749e549f
--- /dev/null
+++ b/doc/release-notes/release-notes-0.9.2.md
@@ -0,0 +1,207 @@
+Bitcoin Core version 0.9.2 is now available from:
+
+ https://bitcoin.org/bin/0.9.2/
+
+This is a new minor version release, bringing mostly bug fixes and some minor
+improvements. OpenSSL has been updated because of a security issue (CVE-2014-0224).
+Upgrading to this release is recommended.
+
+Please report bugs using the issue tracker at github:
+
+ https://github.com/bitcoin/bitcoin/issues
+
+How to Upgrade
+--------------
+
+If you are running an older version, shut it down. Wait until it has completely
+shut down (which might take a few minutes for older versions), then run the
+installer (on Windows) or just copy over /Applications/Bitcoin-Qt (on Mac) or
+bitcoind/bitcoin-qt (on Linux).
+
+If you are upgrading from version 0.7.2 or earlier, the first time you run
+0.9.2 your blockchain files will be re-indexed, which will take anywhere from
+30 minutes to several hours, depending on the speed of your machine.
+
+Downgrading warnings
+--------------------
+
+The 'chainstate' for this release is not always compatible with previous
+releases, so if you run 0.9.x and then decide to switch back to a
+0.8.x release you might get a blockchain validation error when starting the
+old release (due to 'pruned outputs' being omitted from the index of
+unspent transaction outputs).
+
+Running the old release with the -reindex option will rebuild the chainstate
+data structures and correct the problem.
+
+Also, the first time you run a 0.8.x release on a 0.9 wallet it will rescan
+the blockchain for missing spent coins, which will take a long time (tens
+of minutes on a typical machine).
+
+Important changes
+==================
+
+Gitian OSX build
+-----------------
+
+The deterministic build system that was already used for Windows and Linux
+builds is now used for OSX as well. Although the resulting executables have
+been tested quite a bit, there could be possible regressions. Be sure to report
+these on the Github bug tracker mentioned above.
+
+Compatibility of Linux build
+-----------------------------
+
+For Linux we now build against Qt 4.6, and filter the symbols for libstdc++ and glibc.
+This brings back compatibility with
+
+- Debian 6+ / Tails
+- Ubuntu 10.04
+- CentOS 6.5
+
+0.9.2 Release notes
+=======================
+
+The OpenSSL dependency in the gitian builds has been upgraded to 1.0.1h because of CVE-2014-0224.
+
+RPC:
+
+- Add `getwalletinfo`, `getblockchaininfo` and `getnetworkinfo` calls (will replace hodge-podge `getinfo` at some point)
+- Add a `relayfee` field to `getnetworkinfo`
+- Fix RPC related shutdown hangs and leaks
+- Always show syncnode in `getpeerinfo`
+- `sendrawtransaction`: report the reject code and reason, and make it possible to re-send transactions that are already in the mempool
+- `getmininginfo` show right genproclimit
+
+Command-line options:
+
+- Fix `-printblocktree` output
+- Show error message if ReadConfigFile fails
+
+Block-chain handling and storage:
+
+- Fix for GetBlockValue() after block 13,440,000 (BIP42)
+- Upgrade leveldb to 1.17
+
+Protocol and network code:
+
+- Per-peer block download tracking and stalled download detection
+- Add new DNS seed from bitnodes.io
+- Prevent socket leak in ThreadSocketHandler and correct some proxy related socket leaks
+- Use pnode->nLastRecv as sync score (was the wrong way around)
+
+Wallet:
+
+- Make GetAvailableCredit run GetHash() only once per transaction (performance improvement)
+- Lower paytxfee warning threshold from 0.25 BTC to 0.01 BTC
+- Fix importwallet nTimeFirstKey (trigger necessary rescans)
+- Log BerkeleyDB version at startup
+- CWallet init fix
+
+Build system:
+
+- Add OSX build descriptors to gitian
+- Fix explicit --disable-qt-dbus
+- Don't require db_cxx.h when compiling with wallet disabled and GUI enabled
+- Improve missing boost error reporting
+- Upgrade miniupnpc version to 1.9
+- gitian-linux: --enable-glibc-back-compat for binary compatibility with old distributions
+- gitian: don't export any symbols from executable
+- gitian: build against Qt 4.6
+- devtools: add script to check symbols from Linux gitian executables
+- Remove build-time no-IPv6 setting
+
+GUI:
+
+- Fix various coin control visual issues
+- Show number of in/out connections in debug console
+- Show weeks as well as years behind for long timespans behind
+- Enable and disable the Show and Remove buttons for requested payments history based on whether any entry is selected.
+- Show also value for options overridden on command line in options dialog
+- Fill in label from address book also for URIs
+- Fixes feel when resizing the last column on tables (issue #2862)
+- Fix ESC in disablewallet mode
+- Add expert section to wallet tab in optionsdialog
+- Do proper boost::path conversion (fixes unicode in datadir)
+- Only override -datadir if different from the default (fixes -datadir in config file)
+- Show rescan progress at start-up
+- Show importwallet progress
+- Get required locks upfront in polling functions (avoids hanging on locks)
+- Catch Windows shutdown events while client is running
+- Optionally add third party links to transaction context menu
+- Check for !pixmap() before trying to export QR code (avoids crashes when no QR code could be generated)
+- Fix "Start bitcoin on system login"
+
+Miscellaneous:
+
+- Replace non-threadsafe C functions (gmtime, strerror and setlocale)
+- Add missing cs_main and wallet locks
+- Avoid exception at startup when system locale not recognized
+- Changed bitrpc.py's raw_input to getpass for passwords to conceal characters during command line input
+- devtools: add a script to fetch and postprocess translations
+
+Credits
+--------
+
+Thanks to everyone who contributed to this release:
+
+- Addy Yeow
+- Altoidnerd
+- Andrea D'Amore
+- Andreas Schildbach
+- Bardi Harborow
+- Brandon Dahler
+- Bryan Bishop
+- Chris Beams
+- Christian von Roques
+- Cory Fields
+- Cozz Lovan
+- daniel
+- Daniel Newton
+- David A. Harding
+- ditto-b
+- duanemoody
+- Eric S. Bullington
+- Fabian Raetz
+- Gavin Andresen
+- Gregory Maxwell
+- gubatron
+- Haakon Nilsen
+- harry
+- Hector Jusforgues
+- Isidoro Ghezzi
+- Jeff Garzik
+- Johnathan Corgan
+- jtimon
+- Kamil Domanski
+- langerhans
+- Luke Dashjr
+- Manuel Araoz
+- Mark Friedenbach
+- Matt Corallo
+- Matthew Bogosian
+- Meeh
+- Michael Ford
+- Michagogo
+- Mikael Wikman
+- Mike Hearn
+- olalonde
+- paveljanik
+- peryaudo
+- Philip Kaufmann
+- philsong
+- Pieter Wuille
+- R E Broadley
+- richierichrawr
+- Rune K. Svendsen
+- rxl
+- shshshsh
+- Simon de la Rouviere
+- Stuart Cardall
+- super3
+- Telepatheic
+- Thomas Zander
+- Torstein Husebø
+- Warren Togami
+- Wladimir J. van der Laan
+- Yoichi Hirai
diff --git a/doc/release-notes/release-notes-0.9.3.md b/doc/release-notes/release-notes-0.9.3.md
new file mode 100644
index 0000000000..0765a360b2
--- /dev/null
+++ b/doc/release-notes/release-notes-0.9.3.md
@@ -0,0 +1,101 @@
+Bitcoin Core version 0.9.3 is now available from:
+
+ https://bitcoin.org/bin/0.9.3/
+
+This is a new minor version release, bringing only bug fixes and updated
+translations. Upgrading to this release is recommended.
+
+Please report bugs using the issue tracker at github:
+
+ https://github.com/bitcoin/bitcoin/issues
+
+Upgrading and downgrading
+==========================
+
+How to Upgrade
+--------------
+
+If you are running an older version, shut it down. Wait until it has completely
+shut down (which might take a few minutes for older versions), then run the
+installer (on Windows) or just copy over /Applications/Bitcoin-Qt (on Mac) or
+bitcoind/bitcoin-qt (on Linux).
+
+If you are upgrading from version 0.7.2 or earlier, the first time you run
+0.9.3 your blockchain files will be re-indexed, which will take anywhere from
+30 minutes to several hours, depending on the speed of your machine.
+
+Downgrading warnings
+--------------------
+
+The 'chainstate' for this release is not always compatible with previous
+releases, so if you run 0.9.x and then decide to switch back to a
+0.8.x release you might get a blockchain validation error when starting the
+old release (due to 'pruned outputs' being omitted from the index of
+unspent transaction outputs).
+
+Running the old release with the -reindex option will rebuild the chainstate
+data structures and correct the problem.
+
+Also, the first time you run a 0.8.x release on a 0.9 wallet it will rescan
+the blockchain for missing spent coins, which will take a long time (tens
+of minutes on a typical machine).
+
+0.9.3 Release notes
+=======================
+
+RPC:
+- Avoid a segfault on getblock if it can't read a block from disk
+- Add paranoid return value checks in base58
+
+Protocol and network code:
+- Don't poll showmyip.com, it doesn't exist anymore
+- Add a way to limit deserialized string lengths and use it
+- Add a new checkpoint at block 295,000
+- Increase IsStandard() scriptSig length
+- Avoid querying DNS seeds, if we have open connections
+- Remove a useless millisleep in socket handler
+- Stricter memory limits on CNode
+- Better orphan transaction handling
+- Add `-maxorphantx=<n>` and `-maxorphanblocks=<n>` options for control over the maximum orphan transactions and blocks
+
+Wallet:
+- Check redeemScript size does not exceed 520 byte limit
+- Ignore (and warn about) too-long redeemScripts while loading wallet
+
+GUI:
+- fix 'opens in testnet mode when presented with a BIP-72 link with no fallback'
+- AvailableCoins: acquire cs_main mutex
+- Fix unicode character display on MacOSX
+
+Miscellaneous:
+- key.cpp: fail with a friendlier message on missing ssl EC support
+- Remove bignum dependency for scripts
+- Upgrade OpenSSL to 1.0.1i (see https://www.openssl.org/news/secadv_20140806.txt - just to be sure, no critical issues for Bitcoin Core)
+- Upgrade miniupnpc to 1.9.20140701
+- Fix boost detection in build system on some platforms
+
+Credits
+--------
+
+Thanks to everyone who contributed to this release:
+
+- Andrew Poelstra
+- Cory Fields
+- Gavin Andresen
+- Jeff Garzik
+- Johnathan Corgan
+- Julian Haight
+- Michael Ford
+- Pavel Vasin
+- Peter Todd
+- phantomcircuit
+- Pieter Wuille
+- Rose Toomey
+- Ruben Dario Ponticelli
+- shshshsh
+- Trevin Hofmann
+- Warren Togami
+- Wladimir J. van der Laan
+- Zak Wilcox
+
+As well as everyone that helped translating on [Transifex](https://www.transifex.com/projects/p/bitcoin/).
diff --git a/doc/release-notes/release-notes-0.9.4.md b/doc/release-notes/release-notes-0.9.4.md
new file mode 100644
index 0000000000..7ee73246a9
--- /dev/null
+++ b/doc/release-notes/release-notes-0.9.4.md
@@ -0,0 +1,95 @@
+Bitcoin Core version 0.9.4 is now available from:
+
+ https://bitcoin.org/bin/0.9.4/
+
+This is a new minor version release, bringing only bug fixes and updated
+translations. Upgrading to this release is recommended.
+
+Please report bugs using the issue tracker at github:
+
+ https://github.com/bitcoin/bitcoin/issues
+
+How to Upgrade
+===============
+
+If you are running an older version, shut it down. Wait until it has completely
+shut down (which might take a few minutes for older versions), then run the
+installer (on Windows) or just copy over /Applications/Bitcoin-Qt (on Mac) or
+bitcoind/bitcoin-qt (on Linux).
+
+OpenSSL Warning
+================
+
+OpenSSL 1.0.0p / 1.0.1k was recently released and is being pushed out by
+various operating system maintainers. Review by Gregory Maxwell determined that
+this update is incompatible with the Bitcoin system and could lead to consensus
+forks.
+
+Bitcoin Core released binaries from https://bitcoin.org are unaffected,
+as are any built with the gitian deterministic build system.
+
+However, if you are running either
+
+- The Ubuntu PPA from https://launchpad.net/~bitcoin/+archive/ubuntu/bitcoin
+- A third-party or self-compiled Bitcoin Core
+
+upgrade to Bitcoin Core 0.9.4, which includes a workaround, **before** updating
+OpenSSL.
+
+The incompatibility is due to the OpenSSL update changing the
+behavior of ECDSA validation to reject any signature which is
+not encoded in a very rigid manner. This was a result of
+OpenSSL's change for CVE-2014-8275 "Certificate fingerprints
+can be modified".
+
+We are specifically aware of potential hard-forks due to signature
+encoding handling and had been hoping to close them via BIP62 in 0.10.
+BIP62's purpose is to improve transaction malleability handling and
+as a side effect rigidly defines the encoding for signatures, but the
+overall scope of BIP62 has made it take longer than we'd like to
+deploy.
+
+0.9.4 changelog
+================
+
+Validation:
+- `b8e81b7` consensus: guard against openssl's new strict DER checks
+- `60c51f1` fail immediately on an empty signature
+- `037bfef` Improve robustness of DER recoding code
+
+Command-line options:
+- `cd5164a` Make -proxy set all network types, avoiding a connect leak.
+
+P2P:
+- `bb424e4` Limit the number of new addressses to accumulate
+
+RPC:
+- `0a94661` Disable SSLv3 (in favor of TLS) for the RPC client and server.
+
+Build system:
+- `f047dfa` gitian: openssl-1.0.1i.tar.gz -> openssl-1.0.1k.tar.gz
+- `5b9f78d` build: Fix OSX build when using Homebrew and qt5
+- `ffab1dd` Keep symlinks when copying into .app bundle
+- `613247f` osx: fix signing to make Gatekeeper happy (again)
+
+Miscellaneous:
+- `25b49b5` Refactor -alertnotify code
+- `2743529` doc: Add instructions for consistent Mac OS X build names
+
+Credits
+--------
+
+Thanks to who contributed to this release, at least:
+
+- Cory Fields
+- Gavin Andresen
+- Gregory Maxwell
+- Jeff Garzik
+- Luke Dashjr
+- Matt Corallo
+- Pieter Wuille
+- Saivann
+- Sergio Demian Lerner
+- Wladimir J. van der Laan
+
+As well as everyone that helped translating on [Transifex](https://www.transifex.com/projects/p/bitcoin/).
diff --git a/doc/release-notes/release-notes-0.9.5.md b/doc/release-notes/release-notes-0.9.5.md
new file mode 100644
index 0000000000..bed0af9879
--- /dev/null
+++ b/doc/release-notes/release-notes-0.9.5.md
@@ -0,0 +1,60 @@
+Bitcoin Core version 0.9.5 is now available from:
+
+ https://bitcoin.org/bin/0.9.5/
+
+This is a new minor version release, with the goal of backporting BIP66. There
+are also a few bug fixes and updated translations. Upgrading to this release is
+recommended.
+
+Please report bugs using the issue tracker at github:
+
+ https://github.com/bitcoin/bitcoin/issues
+
+How to Upgrade
+===============
+
+If you are running an older version, shut it down. Wait until it has completely
+shut down (which might take a few minutes for older versions), then run the
+installer (on Windows) or just copy over /Applications/Bitcoin-Qt (on Mac) or
+bitcoind/bitcoin-qt (on Linux).
+
+Notable changes
+================
+
+Mining and relay policy enhancements
+------------------------------------
+
+Bitcoin Core's block templates are now for version 3 blocks only, and any mining
+software relying on its `getblocktemplate` must be updated in parallel to use
+libblkmaker either version 0.4.2 or any version from 0.5.1 onward.
+If you are solo mining, this will affect you the moment you upgrade Bitcoin
+Core, which must be done prior to BIP66 achieving its 951/1001 status.
+If you are mining with the stratum mining protocol: this does not affect you.
+If you are mining with the getblocktemplate protocol to a pool: this will affect
+you at the pool operator's discretion, which must be no later than BIP66
+achieving its 951/1001 status.
+
+0.9.5 changelog
+================
+
+- `74f29c2` Check pindexBestForkBase for null
+- `9cd1dd9` Fix priority calculation in CreateTransaction
+- `6b4163b` Sanitize command strings before logging them.
+- `3230b32` Raise version of created blocks, and enforce DERSIG in mempool
+- `989d499` Backport of some of BIP66's tests
+- `ab03660` Implement BIP 66 validation rules and switchover logic
+- `8438074` build: fix dynamic boost check when --with-boost= is used
+
+Credits
+--------
+
+Thanks to who contributed to this release, at least:
+
+- 21E14
+- Alex Morcos
+- Cory Fields
+- Gregory Maxwell
+- Pieter Wuille
+- Wladimir J. van der Laan
+
+As well as everyone that helped translating on [Transifex](https://www.transifex.com/projects/p/bitcoin/).
diff --git a/doc/release-process.md b/doc/release-process.md
new file mode 100644
index 0000000000..5ecb9334f5
--- /dev/null
+++ b/doc/release-process.md
@@ -0,0 +1,172 @@
+Release Process
+====================
+
+* update translations (ping wumpus, Diapolo or tcatm on IRC)
+* see https://github.com/bitcoin/bitcoin/blob/master/doc/translation_process.md#syncing-with-transifex
+
+* * *
+
+###update (commit) version in sources
+
+ contrib/verifysfbinaries/verify.sh
+ doc/README*
+ share/setup.nsi
+ src/clientversion.h (change CLIENT_VERSION_IS_RELEASE to true)
+
+###tag version in git
+
+ git tag -s v(new version, e.g. 0.8.0)
+
+###write release notes. git shortlog helps a lot, for example:
+
+ git shortlog --no-merges v(current version, e.g. 0.7.2)..v(new version, e.g. 0.8.0)
+
+* * *
+
+###update gitian
+
+ In order to take advantage of the new caching features in gitian, be sure to update to a recent version (`e9741525c` or later is recommended)
+
+###perform gitian builds
+
+ From a directory containing the bitcoin source, gitian-builder and gitian.sigs
+
+ export SIGNER=(your gitian key, ie bluematt, sipa, etc)
+ export VERSION=(new version, e.g. 0.8.0)
+ pushd ./bitcoin
+ git checkout v${VERSION}
+ popd
+ pushd ./gitian-builder
+
+###fetch and build inputs: (first time, or when dependency versions change)
+
+ mkdir -p inputs
+ wget -P inputs https://bitcoincore.org/cfields/osslsigncode-Backports-to-1.7.1.patch
+ wget -P inputs http://downloads.sourceforge.net/project/osslsigncode/osslsigncode/osslsigncode-1.7.1.tar.gz
+
+ Register and download the Apple SDK: (see OSX Readme for details)
+
+ https://developer.apple.com/devcenter/download.action?path=/Developer_Tools/xcode_6.1.1/xcode_6.1.1.dmg
+
+ Using a Mac, create a tarball for the 10.9 SDK and copy it to the inputs directory:
+
+ tar -C /Volumes/Xcode/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/ -czf MacOSX10.9.sdk.tar.gz MacOSX10.9.sdk
+
+###Optional: Seed the Gitian sources cache
+
+ By default, gitian will fetch source files as needed. For offline builds, they can be fetched ahead of time:
+
+ make -C ../bitcoin/depends download SOURCES_PATH=`pwd`/cache/common
+
+ Only missing files will be fetched, so this is safe to re-run for each build.
+
+###Build Bitcoin Core for Linux, Windows, and OS X:
+
+ ./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml
+ ./bin/gsign --signer $SIGNER --release ${VERSION}-linux --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml
+ mv build/out/bitcoin-*.tar.gz build/out/src/bitcoin-*.tar.gz ../
+ ./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-win.yml
+ ./bin/gsign --signer $SIGNER --release ${VERSION}-win-unsigned --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-win.yml
+ mv build/out/bitcoin-*-win-unsigned.tar.gz inputs/bitcoin-win-unsigned.tar.gz
+ mv build/out/bitcoin-*.zip build/out/bitcoin-*.exe ../
+ ./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml
+ ./bin/gsign --signer $SIGNER --release ${VERSION}-osx-unsigned --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml
+ mv build/out/bitcoin-*-osx-unsigned.tar.gz inputs/bitcoin-osx-unsigned.tar.gz
+ mv build/out/bitcoin-*.tar.gz build/out/bitcoin-*.dmg ../
+ popd
+ Build output expected:
+
+ 1. source tarball (bitcoin-${VERSION}.tar.gz)
+ 2. linux 32-bit and 64-bit dist tarballs (bitcoin-${VERSION}-linux[32|64].tar.gz)
+ 3. windows 32-bit and 64-bit unsigned installers and dist zips (bitcoin-${VERSION}-win[32|64]-setup-unsigned.exe, bitcoin-${VERSION}-win[32|64].zip)
+ 4. OSX unsigned installer and dist tarball (bitcoin-${VERSION}-osx-unsigned.dmg, bitcoin-${VERSION}-osx64.tar.gz)
+ 5. Gitian signatures (in gitian.sigs/${VERSION}-<linux|{win,osx}-unsigned>/(your gitian key)/
+
+###Next steps:
+
+Commit your signature to gitian.sigs:
+
+ pushd gitian.sigs
+ git add ${VERSION}-linux/${SIGNER}
+ git add ${VERSION}-win-unsigned/${SIGNER}
+ git add ${VERSION}-osx-unsigned/${SIGNER}
+ git commit -a
+ git push # Assuming you can push to the gitian.sigs tree
+ popd
+
+ Wait for Windows/OSX detached signatures:
+ Once the Windows/OSX builds each have 3 matching signatures, they will be signed with their respective release keys.
+ Detached signatures will then be committed to the bitcoin-detached-sigs repository, which can be combined with the unsigned apps to create signed binaries.
+
+ Create the signed OSX binary:
+
+ pushd ./gitian-builder
+ ./bin/gbuild -i --commit signature=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-osx-signer.yml
+ ./bin/gsign --signer $SIGNER --release ${VERSION}-osx-signed --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-osx-signer.yml
+ mv build/out/bitcoin-osx-signed.dmg ../bitcoin-${VERSION}-osx.dmg
+ popd
+
+ Create the signed Windows binaries:
+
+ pushd ./gitian-builder
+ ./bin/gbuild -i --commit signature=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-win-signer.yml
+ ./bin/gsign --signer $SIGNER --release ${VERSION}-win-signed --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-win-signer.yml
+ mv build/out/bitcoin-*win64-setup.exe ../bitcoin-${VERSION}-win64-setup.exe
+ mv build/out/bitcoin-*win32-setup.exe ../bitcoin-${VERSION}-win32-setup.exe
+ popd
+
+Commit your signature for the signed OSX/Windows binaries:
+
+ pushd gitian.sigs
+ git add ${VERSION}-osx-signed/${SIGNER}
+ git add ${VERSION}-win-signed/${SIGNER}
+ git commit -a
+ git push # Assuming you can push to the gitian.sigs tree
+ popd
+
+-------------------------------------------------------------------------
+
+### After 3 or more people have gitian-built and their results match:
+
+- Create `SHA256SUMS.asc` for the builds, and GPG-sign it:
+```bash
+sha256sum * > SHA256SUMS
+gpg --digest-algo sha256 --clearsign SHA256SUMS # outputs SHA256SUMS.asc
+rm SHA256SUMS
+```
+(the digest algorithm is forced to sha256 to avoid confusion of the `Hash:` header that GPG adds with the SHA256 used for the files)
+Note: check that SHA256SUMS itself doesn't end up in SHA256SUMS, which is a spurious/nonsensical entry.
+
+- Upload zips and installers, as well as `SHA256SUMS.asc` from last step, to the bitcoin.org server
+ into `/var/www/bin/bitcoin-core-${VERSION}`
+
+- Update bitcoin.org version
+
+ - First, check to see if the Bitcoin.org maintainers have prepared a
+ release: https://github.com/bitcoin/bitcoin.org/labels/Releases
+
+ - If they have, it will have previously failed their Travis CI
+ checks because the final release files weren't uploaded.
+ Trigger a Travis CI rebuild---if it passes, merge.
+
+ - If they have not prepared a release, follow the Bitcoin.org release
+ instructions: https://github.com/bitcoin/bitcoin.org#release-notes
+
+ - After the pull request is merged, the website will automatically show the newest version within 15 minutes, as well
+ as update the OS download links. Ping @saivann/@harding (saivann/harding on Freenode) in case anything goes wrong
+
+- Announce the release:
+
+ - Release sticky on bitcointalk: https://bitcointalk.org/index.php?board=1.0
+
+ - Bitcoin-development mailing list
+
+ - Update title of #bitcoin on Freenode IRC
+
+ - Optionally reddit /r/Bitcoin, ... but this will usually sort out itself
+
+- Notify BlueMatt so that he can start building [https://launchpad.net/~bitcoin/+archive/ubuntu/bitcoin](the PPAs)
+
+- Add release notes for the new version to the directory `doc/release-notes` in git master
+
+- Celebrate
diff --git a/doc/tor.md b/doc/tor.md
new file mode 100644
index 0000000000..560f71fa27
--- /dev/null
+++ b/doc/tor.md
@@ -0,0 +1,85 @@
+TOR SUPPORT IN BITCOIN
+======================
+
+It is possible to run Bitcoin as a Tor hidden service, and connect to such services.
+
+The following directions assume 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 [Tor Project FAQ:TBBSocksPort](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 anonymized, but more is possible.
+
+ -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.
+
+ -onion=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 -noonion
+ to explicitly disable access to hidden service.
+
+ -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 8333 127.0.0.1:8333
+ HiddenServicePort 18333 127.0.0.1:18333
+
+The directory can be different of course, but (both) port numbers should be equal to
+your bitcoind's P2P listen port (8333 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 8333 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 -onion=127.0.0.1:9050 -externalip=57qr3yd1nyntf5k.onion -discover
+
diff --git a/doc/translation_process.md b/doc/translation_process.md
new file mode 100644
index 0000000000..3653e53021
--- /dev/null
+++ b/doc/translation_process.md
@@ -0,0 +1,111 @@
+Translations
+============
+
+The Bitcoin-Core project has been designed to support multiple localisations. This makes adding new phrases, and completely new languages easily achievable. For managing all application translations, Bitcoin-Core makes use of the Transifex online translation management tool.
+
+### Helping to translate (using Transifex)
+Transifex is setup to monitor the Github repo for updates, and when code containing new translations is found, Transifex will process any changes. It may take several hours after a pull-request has been merged, to appear in the Transifex web interface.
+
+Multiple language support is critical in assisting Bitcoin’s global adoption, and growth. One of Bitcoin’s greatest strengths is cross-boarder money transfers, any help making that easier is greatly appreciated.
+
+See the [Transifex Bitcoin project](https://www.transifex.com/projects/p/bitcoin/) to assist in translations. You should also join the translation mailing list for announcements - see details below.
+
+### Writing code with translations
+We use automated scripts to help extract translations in both Qt, and non-Qt source files. It is rarely necessary to manually edit the files in `src/qt/locale/`. The translation source files must adhere to the following format:
+`bitcoin_xx_YY.ts or bitcoin_xx.ts`
+
+`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 source code is changed, this file must be updated to reflect those changes. A custom script is used to extract strings from the non-Qt parts. This script makes use of `gettext`, so make sure that utility is installed (ie, `apt-get install gettext` on Ubuntu/Debian). Once this has been updated, `lupdate` (included in the Qt SDK) is used to update `bitcoin_en.ts`.
+
+To automatically regenerate the `bitcoin_en.ts` file, run the following commands:
+```sh
+cd src/
+make translate
+```
+
+`contrib/bitcoin-qt.pro` takes care of generating `.qm` (binary compiled) files from `.ts` (source files) files. It’s mostly automated, and you shouldn’t need to worry about it.
+
+**Example Qt translation**
+```cpp
+QToolBar *toolbar = addToolBar(tr("Tabs toolbar"));
+```
+
+### Creating a pull-request
+For general PRs, you shouldn’t include any updates to the translation source files. They will be updated periodically, primarily around pre-releases, allowing time for any new phrases to be translated before public releases. This is also important in avoiding translation related merge conflicts.
+
+When an updated source file is merged into the Github repo, Transifex will automatically detect it (although it can take several hours). Once processed, the new strings will show up as "Remaining" in the Transifex web interface and are ready for translators.
+
+To create the pull-request, use the following commands:
+```
+git add src/qt/bitcoinstrings.cpp src/qt/locale/bitcoin_en.ts
+git commit
+```
+
+### Creating a Transifex account
+Visit the [Transifex Signup](https://www.transifex.com/signup/) page to create an account. Take note of your username and password, as they will be required to configure the command-line tool.
+
+You can find the Bitcoin translation project at [https://www.transifex.com/projects/p/bitcoin/](https://www.transifex.com/projects/p/bitcoin/).
+
+### Installing the Transifex client command-line tool
+The client it used to fetch updated translations. If you are having problems, or need more details, see [http://docs.transifex.com/developer/client/setup](http://docs.transifex.com/developer/client/setup)
+
+**For Linux and Mac**
+
+`pip install transifex-client`
+
+Setup your transifex client config as follows. Please *ignore the token field*.
+
+```ini
+nano ~/.transifexrc
+
+[https://www.transifex.com]
+hostname = https://www.transifex.com
+password = PASSWORD
+token =
+username = USERNAME
+```
+
+**For Windows**
+
+Please see [http://docs.transifex.com/developer/client/setup#windows](http://docs.transifex.com/developer/client/setup#windows) for details on installation.
+
+The Transifex Bitcoin project config file is included as part of the repo. It can be found at `.tx/config`, however you shouldn’t need change anything.
+
+### Synchronising translations
+To assist in updating translations, we have created a script to help.
+
+1. `python contrib/devtools/update-translations.py`
+2. Update `src/qt/bitcoin.qrc` manually or via
+ `ls src/qt/locale/*ts|xargs -n1 basename|sed 's/\(bitcoin_\(.*\)\).ts/<file alias="\2">locale\/\1.qm<\/file>/'`
+3. Update `src/qt/Makefile.am` manually or via
+ `ls src/qt/locale/*ts|xargs -n1 basename|sed 's/\(bitcoin_\(.*\)\).ts/ locale\/\1.ts \\/'`
+4. `git add` new translations from `src/qt/locale/`
+
+**Do not directly download translations** one by one from the Transifex website, as we do a few post-processing steps before committing the translations.
+
+### Handling Plurals (in source files)
+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 (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
+
+### Translating a new language
+To create a new language template, you will need to edit the languages manifest file `src/qt/bitcoin.qrc` and add a new entry. Below is an example of the english language entry.
+
+```xml
+<qresource prefix="/translations">
+ <file alias="en">locale/bitcoin_en.qm</file>
+ ...
+</qresource>
+```
+
+**Note:** that the language translation file **must end in `.qm`** (the compiled extension), and not `.ts`.
+
+### Questions and general assistance
+The Bitcoin-Core translation maintainers include *tcatm, seone, Diapolo, wumpus and luke-jr*.You can find them, and others, in the Freenode IRC chatroom - `irc.freenode.net #bitcoin-dev`.
+
+If you are a translator, you should also subscribe to the mailing list, https://groups.google.com/forum/#!forum/bitcoin-translators. Announcements will be posted during application pre-releases to notify translators to check for updates.
diff --git a/doc/translation_strings_policy.md b/doc/translation_strings_policy.md
new file mode 100644
index 0000000000..6824b1d8ef
--- /dev/null
+++ b/doc/translation_strings_policy.md
@@ -0,0 +1,72 @@
+Translation Strings Policy
+===========================
+
+This document provides guidelines for internationalization of the Bitcoin Core software.
+
+How to translate?
+------------------
+
+To mark a message as translatable
+
+- In GUI source code (under `src/qt`): use `tr("...")`
+
+- In non-GUI source code (under `src`): use `_("...")`
+
+No internationalization is used for e.g. developer scripts outside `src`.
+
+Strings to be translated
+-------------------------
+
+On a high level, these strings are to be translated:
+
+- GUI strings, anything that appears in a dialog or window
+
+- Command-line option documentation
+
+### GUI strings
+
+Anything that appears to the user in the GUI is to be translated. This includes labels, menu items, button texts, tooltips and window titles.
+This includes messages passed to the GUI through the UI interface through `InitMessage`, `ThreadSafeMessageBox` or `ShowProgress`.
+
+### Command-line options
+
+Documentation for the command line options in the output of `--help` should be translated as well.
+
+Make sure that default values do not end up in the string, but use string formatting like `strprintf(_("Threshold for disconnecting misbehaving peers (default: %u)"), 100)`. Putting default values in strings has led to accidental translations in the past, and forces the string to be retranslated every time the value changes.
+
+Do not translate messages that are only shown to developers, such as those that only appear when `--help-debug` is used.
+
+General recommendations
+------------------------
+
+### Avoid unnecessary translation strings
+
+Try not to burden translators with translating messages that are e.g. slight variations of other messages.
+In the GUI, avoid the use of text where an icon or symbol will do.
+Make sure that placeholder texts in forms don't end up in the list of strings to be translated (use `<string notr="true">`).
+
+### Make translated strings understandable
+
+Try to write translation strings in an understandable way, for both the user and the translator. Avoid overly technical or detailed messages
+
+### Do not translate internal errors
+
+Do not translate internal errors, or log messages, or messages that appear on the RPC interface. If an error is to be shown to the user,
+use a generic message, then log the detailed message to the log. E.g. "Error: A fatal internal error occurred, see debug.log for details".
+This helps troubleshooting; if the error is the same for everyone, the likelihood is increased that it can be found using a search engine.
+
+### Avoid fragments
+
+Avoid dividing up a message into fragments. Translators see every string separately, so may misunderstand the context if the messages are not self-contained.
+
+### Avoid HTML in translation strings
+
+There have been difficulties with use of HTML in translation strings; translators should not be able to accidentally affect the formatting of messages.
+This may sometimes be at conflict with the recommendation in the previous section.
+
+### String freezes
+
+During a string freeze (often before a major release), no translation strings are to be added, modified or removed.
+
+This can be checked by executing `make translate` in the `src` directory, then verifying that `bitcoin_en.ts` remains unchanged.
+
diff --git a/doc/travis-ci.txt b/doc/travis-ci.txt
new file mode 100644
index 0000000000..01f7d02a86
--- /dev/null
+++ b/doc/travis-ci.txt
@@ -0,0 +1,39 @@
+Support for using travis-ci has been added in order to automate pull-testing.
+See https://travis-ci.org/ for more info
+
+This procedure is different than the pull-tester that came before it in a few
+ways.
+
+There is nothing to administer. This is a major feature as it means
+that builds have no local state. Because there is no ability to login to the
+builders to install packages (tools, dependencies, etc), the entire build
+procedure must instead be controlled by a declarative script (.travis.yml).
+This script declares each build configuration, creates virtual machines as
+necessary, builds, then discards the virtual machines.
+
+A build matrix is constructed to test a wide range of configurations, rather
+than a single pass/fail. This helps to catch build failures and logic errors
+that present on platforms other than the ones the author has tested. This
+matrix is defined in the build script and can be changed at any time.
+
+All builders use the dependency-generator in the depends dir, rather than
+using apt-get to install build dependencies. This guarantees that the tester
+is using the same versions as Gitian, so the build results are nearly identical
+to what would be found in a final release. However, this also means that builds
+will fail if new dependencies are introduced without being added to the
+dependency generator.
+
+In order to avoid rebuilding all dependencies for each build, the binaries are
+cached and re-used when possible. Changes in the dependency-generator will
+trigger cache-invalidation and rebuilds as necessary.
+
+These caches can be manually removed if necessary. This is one of the the very few
+manual operations that is possible with Travis, and it can be done by the
+Bitcoin Core committer via the Travis web interface.
+
+In some cases, secure strings may be needed for hiding sensitive info such as
+private keys or URLs. The travis client may be used to create these strings:
+http://docs.travis-ci.com/user/encryption-keys/
+
+For the details of the build descriptor, see the official docs:
+http://docs.travis-ci.com/user/build-configuration/
diff --git a/doc/unit-tests.md b/doc/unit-tests.md
new file mode 100644
index 0000000000..72613054b9
--- /dev/null
+++ b/doc/unit-tests.md
@@ -0,0 +1,18 @@
+Compiling/running unit tests
+------------------------------------
+
+Unit tests will be automatically compiled if dependencies were met in configure
+and tests weren't explicitly disabled.
+
+After configuring, they can be run with 'make check'.
+
+To run the bitcoind tests manually, launch src/test/test_bitcoin .
+
+To add more bitcoind tests, add `BOOST_AUTO_TEST_CASE` functions to the existing
+.cpp files in the test/ directory or add new .cpp files that
+implement new BOOST_AUTO_TEST_SUITE sections.
+
+To run the bitcoin-qt tests manually, launch src/qt/test/test_bitcoin-qt
+
+To add more bitcoin-qt tests, add them to the `src/qt/test/` directory and
+the `src/qt/test/test_main.cpp` file.
diff --git a/libbitcoinconsensus.pc.in b/libbitcoinconsensus.pc.in
new file mode 100644
index 0000000000..3ca1696a31
--- /dev/null
+++ b/libbitcoinconsensus.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: Bitcoin Core consensus library
+Description: Library for the Bitcoin consensus protocol.
+Version: @PACKAGE_VERSION@
+Libs: -L${libdir} -lbitcoinconsensus
+Cflags: -I${includedir}
+Requires.private: libcrypto
diff --git a/qa/pull-tester/rpc-tests.sh b/qa/pull-tester/rpc-tests.sh
new file mode 100755
index 0000000000..97aecc5e3c
--- /dev/null
+++ b/qa/pull-tester/rpc-tests.sh
@@ -0,0 +1,74 @@
+#!/bin/bash
+set -e
+
+CURDIR=$(cd $(dirname "$0"); pwd)
+# Get BUILDDIR and REAL_BITCOIND
+. "${CURDIR}/tests-config.sh"
+
+export BITCOINCLI=${BUILDDIR}/qa/pull-tester/run-bitcoin-cli
+export BITCOIND=${REAL_BITCOIND}
+
+#Run the tests
+
+testScripts=(
+ 'wallet.py'
+ 'listtransactions.py'
+ 'mempool_resurrect_test.py'
+ 'txn_doublespend.py'
+ 'txn_doublespend.py --mineblock'
+ 'getchaintips.py'
+ 'rawtransactions.py'
+ 'rest.py'
+ 'mempool_spendcoinbase.py'
+ 'mempool_coinbase_spends.py'
+ 'httpbasics.py'
+ 'zapwallettxes.py'
+ 'proxy_test.py'
+ 'merkle_blocks.py'
+ 'signrawtransactions.py'
+ 'walletbackup.py'
+);
+testScriptsExt=(
+ 'bipdersig-p2p.py'
+ 'bipdersig.py'
+ 'getblocktemplate_longpoll.py'
+ 'getblocktemplate_proposals.py'
+ 'pruning.py'
+ 'forknotify.py'
+ 'invalidateblock.py'
+ 'keypool.py'
+ 'receivedby.py'
+ 'reindex.py'
+ 'rpcbind_test.py'
+# 'script_test.py'
+ 'smartfees.py'
+ 'maxblocksinflight.py'
+ 'invalidblockrequest.py'
+ 'rawtransactions.py'
+# 'forknotify.py'
+ 'p2p-acceptblock.py'
+);
+
+extArg="-extended"
+passOn=${@#$extArg}
+
+if [ "x${ENABLE_BITCOIND}${ENABLE_UTILS}${ENABLE_WALLET}" = "x111" ]; then
+ for (( i = 0; i < ${#testScripts[@]}; i++ ))
+ do
+ if [ -z "$1" ] || [ "${1:0:1}" == "-" ] || [ "$1" == "${testScripts[$i]}" ] || [ "$1.py" == "${testScripts[$i]}" ]
+ then
+ echo -e "Running testscript \033[1m${testScripts[$i]}...\033[0m"
+ ${BUILDDIR}/qa/rpc-tests/${testScripts[$i]} --srcdir "${BUILDDIR}/src" ${passOn}
+ fi
+ done
+ for (( i = 0; i < ${#testScriptsExt[@]}; i++ ))
+ do
+ if [ "$1" == $extArg ] || [ "$1" == "${testScriptsExt[$i]}" ] || [ "$1.py" == "${testScriptsExt[$i]}" ]
+ then
+ echo -e "Running \033[1m2nd level\033[0m testscript \033[1m${testScriptsExt[$i]}...\033[0m"
+ ${BUILDDIR}/qa/rpc-tests/${testScriptsExt[$i]} --srcdir "${BUILDDIR}/src" ${passOn}
+ fi
+ done
+else
+ echo "No rpc tests to run. Wallet, utils, and bitcoind must all be enabled"
+fi
diff --git a/qa/pull-tester/run-bitcoin-cli b/qa/pull-tester/run-bitcoin-cli
new file mode 100755
index 0000000000..93c25bb9fc
--- /dev/null
+++ b/qa/pull-tester/run-bitcoin-cli
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+# This is a thin wrapper around bitcoin-cli that strips the Windows-style EOLs
+# from the output if present. It is necessary when using bitcoin-cli.exe on
+# Linux since shells will interpret the line-endings as part of the result.
+
+CURDIR=$(cd $(dirname "$0"); pwd)
+# Get BUILDDIR and REAL_BITCOIND
+
+# Grab the value of $REAL_BITCOINCLI which may be bitcoin-cli.exe.
+. "${CURDIR}/tests-config.sh"
+
+"${REAL_BITCOINCLI}" "$@" | sed 's/\r//'
diff --git a/qa/pull-tester/run-bitcoind-for-test.sh.in b/qa/pull-tester/run-bitcoind-for-test.sh.in
new file mode 100755
index 0000000000..14ae08e4e5
--- /dev/null
+++ b/qa/pull-tester/run-bitcoind-for-test.sh.in
@@ -0,0 +1,36 @@
+#!/bin/bash
+# Copyright (c) 2013-2014 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#
+DATADIR="@abs_top_builddir@/.bitcoin"
+rm -rf "$DATADIR"
+mkdir -p "$DATADIR"/regtest
+touch "$DATADIR/regtest/debug.log"
+tail -q -n 1 -F "$DATADIR/regtest/debug.log" | grep -m 1 -q "Done loading" &
+WAITER=$!
+PORT=`expr 10000 + $$ % 55536`
+"@abs_top_builddir@/src/bitcoind@EXEEXT@" -connect=0.0.0.0 -datadir="$DATADIR" -rpcuser=user -rpcpassword=pass -listen -keypool=3 -debug -debug=net -logtimestamps -checkmempool=0 -relaypriority=0 -port=$PORT -whitelist=127.0.0.1 -regtest -rpcport=`expr $PORT + 1` &
+BITCOIND=$!
+
+#Install a watchdog.
+(sleep 10 && kill -0 $WAITER 2>/dev/null && kill -9 $BITCOIND $$)&
+wait $WAITER
+
+if [ -n "$TIMEOUT" ]; then
+ timeout "$TIMEOUT"s "$@" $PORT
+ RETURN=$?
+else
+ "$@" $PORT
+ RETURN=$?
+fi
+
+(sleep 15 && kill -0 $BITCOIND 2>/dev/null && kill -9 $BITCOIND $$)&
+kill $BITCOIND && wait $BITCOIND
+
+# timeout returns 124 on timeout, otherwise the return value of the child
+
+# If $RETURN is not 0, the test failed. Dump the tail of the debug log.
+if [ $RETURN -ne 0 ]; then tail -n 200 $DATADIR/regtest/debug.log; fi
+
+exit $RETURN
diff --git a/qa/pull-tester/tests-config.sh.in b/qa/pull-tester/tests-config.sh.in
new file mode 100755
index 0000000000..10f4d33e47
--- /dev/null
+++ b/qa/pull-tester/tests-config.sh.in
@@ -0,0 +1,16 @@
+#!/bin/bash
+# Copyright (c) 2013-2014 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+BUILDDIR="@abs_top_builddir@"
+EXEEXT="@EXEEXT@"
+
+# These will turn into comments if they were disabled when configuring.
+@ENABLE_WALLET_TRUE@ENABLE_WALLET=1
+@BUILD_BITCOIN_UTILS_TRUE@ENABLE_UTILS=1
+@BUILD_BITCOIND_TRUE@ENABLE_BITCOIND=1
+
+REAL_BITCOIND="$BUILDDIR/src/bitcoind${EXEEXT}"
+REAL_BITCOINCLI="$BUILDDIR/src/bitcoin-cli${EXEEXT}"
+
diff --git a/qa/rpc-tests/.gitignore b/qa/rpc-tests/.gitignore
new file mode 100644
index 0000000000..cb41d94423
--- /dev/null
+++ b/qa/rpc-tests/.gitignore
@@ -0,0 +1,2 @@
+*.pyc
+cache
diff --git a/qa/rpc-tests/README.md b/qa/rpc-tests/README.md
new file mode 100644
index 0000000000..08c67c4ef1
--- /dev/null
+++ b/qa/rpc-tests/README.md
@@ -0,0 +1,51 @@
+Regression tests of RPC interface
+=================================
+
+### [python-bitcoinrpc](https://github.com/jgarzik/python-bitcoinrpc)
+Git subtree of [https://github.com/jgarzik/python-bitcoinrpc](https://github.com/jgarzik/python-bitcoinrpc).
+Changes to python-bitcoinrpc should be made upstream, and then
+pulled here using git subtree.
+
+### [test_framework/test_framework.py](test_framework/test_framework.py)
+Base class for new regression tests.
+
+### [test_framework/util.py](test_framework/util.py)
+Generally useful functions.
+
+Notes
+=====
+
+You can run a single test by calling `qa/pull-tester/rpc-tests.sh <testname>`.
+
+Run all possible tests with `qa/pull-tester/rpc-tests.sh -extended`.
+
+Possible options:
+
+````
+-h, --help show this help message and exit
+ --nocleanup Leave bitcoinds and test.* datadir on exit or error
+ --noshutdown Don't stop bitcoinds after the test execution
+ --srcdir=SRCDIR Source directory containing bitcoind/bitcoin-cli (default:
+ ../../src)
+ --tmpdir=TMPDIR Root directory for datadirs
+ --tracerpc Print out all RPC calls as they are made
+```
+
+If you set the environment variable `PYTHON_DEBUG=1` you will get some debug output (example: `PYTHON_DEBUG=1 qa/pull-tester/rpc-tests.sh wallet`).
+
+A 200-block -regtest blockchain and wallets for four nodes
+is created the first time a regression test is run and
+is stored in the cache/ directory. Each node has 25 mature
+blocks (25*50=1250 BTC) in its wallet.
+
+After the first run, the cache/ blockchain and wallets are
+copied into a temporary directory and used as the initial
+test state.
+
+If you get into a bad state, you should be able
+to recover with:
+
+```bash
+rm -rf cache
+killall bitcoind
+```
diff --git a/qa/rpc-tests/bip65-cltv-p2p.py b/qa/rpc-tests/bip65-cltv-p2p.py
new file mode 100755
index 0000000000..1f8548c219
--- /dev/null
+++ b/qa/rpc-tests/bip65-cltv-p2p.py
@@ -0,0 +1,175 @@
+#!/usr/bin/env python2
+#
+# Distributed under the MIT/X11 software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#
+
+from test_framework.test_framework import ComparisonTestFramework
+from test_framework.util import *
+from test_framework.mininode import CTransaction, NetworkThread
+from test_framework.blocktools import create_coinbase, create_block
+from test_framework.comptool import TestInstance, TestManager
+from test_framework.script import CScript, OP_1NEGATE, OP_NOP2, OP_DROP
+from binascii import hexlify, unhexlify
+import cStringIO
+import time
+
+def cltv_invalidate(tx):
+ '''Modify the signature in vin 0 of the tx to fail CLTV
+
+ Prepends -1 CLTV DROP in the scriptSig itself.
+ '''
+ tx.vin[0].scriptSig = CScript([OP_1NEGATE, OP_NOP2, OP_DROP] +
+ list(CScript(tx.vin[0].scriptSig)))
+
+'''
+This test is meant to exercise BIP65 (CHECKLOCKTIMEVERIFY)
+Connect to a single node.
+Mine 2 (version 3) blocks (save the coinbases for later).
+Generate 98 more version 3 blocks, verify the node accepts.
+Mine 749 version 4 blocks, verify the node accepts.
+Check that the new CLTV rules are not enforced on the 750th version 4 block.
+Check that the new CLTV rules are enforced on the 751st version 4 block.
+Mine 199 new version blocks.
+Mine 1 old-version block.
+Mine 1 new version block.
+Mine 1 old version block, see that the node rejects.
+'''
+
+class BIP65Test(ComparisonTestFramework):
+
+ def __init__(self):
+ self.num_nodes = 1
+
+ def setup_network(self):
+ # Must set the blockversion for this test
+ self.nodes = start_nodes(1, self.options.tmpdir,
+ extra_args=[['-debug', '-whitelist=127.0.0.1', '-blockversion=3']],
+ binary=[self.options.testbinary])
+
+ def run_test(self):
+ test = TestManager(self, self.options.tmpdir)
+ test.add_all_connections(self.nodes)
+ NetworkThread().start() # Start up network handling in another thread
+ test.run()
+
+ def create_transaction(self, node, coinbase, to_address, amount):
+ from_txid = node.getblock(coinbase)['tx'][0]
+ inputs = [{ "txid" : from_txid, "vout" : 0}]
+ outputs = { to_address : amount }
+ rawtx = node.createrawtransaction(inputs, outputs)
+ signresult = node.signrawtransaction(rawtx)
+ tx = CTransaction()
+ f = cStringIO.StringIO(unhexlify(signresult['hex']))
+ tx.deserialize(f)
+ return tx
+
+ def get_tests(self):
+
+ self.coinbase_blocks = self.nodes[0].generate(2)
+ self.tip = int ("0x" + self.nodes[0].getbestblockhash() + "L", 0)
+ self.nodeaddress = self.nodes[0].getnewaddress()
+ self.last_block_time = time.time()
+
+ ''' 98 more version 3 blocks '''
+ test_blocks = []
+ for i in xrange(98):
+ block = create_block(self.tip, create_coinbase(2), self.last_block_time + 1)
+ block.nVersion = 3
+ block.rehash()
+ block.solve()
+ test_blocks.append([block, True])
+ self.last_block_time += 1
+ self.tip = block.sha256
+ yield TestInstance(test_blocks, sync_every_block=False)
+
+ ''' Mine 749 version 4 blocks '''
+ test_blocks = []
+ for i in xrange(749):
+ block = create_block(self.tip, create_coinbase(2), self.last_block_time + 1)
+ block.nVersion = 4
+ block.rehash()
+ block.solve()
+ test_blocks.append([block, True])
+ self.last_block_time += 1
+ self.tip = block.sha256
+ yield TestInstance(test_blocks, sync_every_block=False)
+
+ '''
+ Check that the new CLTV rules are not enforced in the 750th
+ version 3 block.
+ '''
+ spendtx = self.create_transaction(self.nodes[0],
+ self.coinbase_blocks[0], self.nodeaddress, 1.0)
+ cltv_invalidate(spendtx)
+ spendtx.rehash()
+
+ block = create_block(self.tip, create_coinbase(2), self.last_block_time + 1)
+ block.nVersion = 4
+ block.vtx.append(spendtx)
+ block.hashMerkleRoot = block.calc_merkle_root()
+ block.rehash()
+ block.solve()
+
+ self.last_block_time += 1
+ self.tip = block.sha256
+ yield TestInstance([[block, True]])
+
+ '''
+ Check that the new CLTV rules are enforced in the 751st version 4
+ block.
+ '''
+ spendtx = self.create_transaction(self.nodes[0],
+ self.coinbase_blocks[1], self.nodeaddress, 1.0)
+ cltv_invalidate(spendtx)
+ spendtx.rehash()
+
+ block = create_block(self.tip, create_coinbase(1), self.last_block_time + 1)
+ block.nVersion = 4
+ block.vtx.append(spendtx)
+ block.hashMerkleRoot = block.calc_merkle_root()
+ block.rehash()
+ block.solve()
+ self.last_block_time += 1
+ yield TestInstance([[block, False]])
+
+ ''' Mine 199 new version blocks on last valid tip '''
+ test_blocks = []
+ for i in xrange(199):
+ block = create_block(self.tip, create_coinbase(1), self.last_block_time + 1)
+ block.nVersion = 4
+ block.rehash()
+ block.solve()
+ test_blocks.append([block, True])
+ self.last_block_time += 1
+ self.tip = block.sha256
+ yield TestInstance(test_blocks, sync_every_block=False)
+
+ ''' Mine 1 old version block '''
+ block = create_block(self.tip, create_coinbase(1), self.last_block_time + 1)
+ block.nVersion = 3
+ block.rehash()
+ block.solve()
+ self.last_block_time += 1
+ self.tip = block.sha256
+ yield TestInstance([[block, True]])
+
+ ''' Mine 1 new version block '''
+ block = create_block(self.tip, create_coinbase(1), self.last_block_time + 1)
+ block.nVersion = 4
+ block.rehash()
+ block.solve()
+ self.last_block_time += 1
+ self.tip = block.sha256
+ yield TestInstance([[block, True]])
+
+ ''' Mine 1 old version block, should be invalid '''
+ block = create_block(self.tip, create_coinbase(1), self.last_block_time + 1)
+ block.nVersion = 3
+ block.rehash()
+ block.solve()
+ self.last_block_time += 1
+ yield TestInstance([[block, False]])
+
+if __name__ == '__main__':
+ BIP65Test().main()
diff --git a/qa/rpc-tests/bip65-cltv.py b/qa/rpc-tests/bip65-cltv.py
new file mode 100755
index 0000000000..e60395dce6
--- /dev/null
+++ b/qa/rpc-tests/bip65-cltv.py
@@ -0,0 +1,89 @@
+#!/usr/bin/env python2
+# Copyright (c) 2015 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#
+# Test the CHECKLOCKTIMEVERIFY (BIP65) soft-fork logic
+#
+
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import *
+import os
+import shutil
+
+class BIP65Test(BitcoinTestFramework):
+
+ def setup_network(self):
+ self.nodes = []
+ self.nodes.append(start_node(0, self.options.tmpdir, []))
+ self.nodes.append(start_node(1, self.options.tmpdir, ["-blockversion=3"]))
+ self.nodes.append(start_node(2, self.options.tmpdir, ["-blockversion=4"]))
+ connect_nodes(self.nodes[1], 0)
+ connect_nodes(self.nodes[2], 0)
+ self.is_network_split = False
+ self.sync_all()
+
+ def run_test(self):
+ cnt = self.nodes[0].getblockcount()
+
+ # Mine some old-version blocks
+ self.nodes[1].generate(100)
+ self.sync_all()
+ if (self.nodes[0].getblockcount() != cnt + 100):
+ raise AssertionError("Failed to mine 100 version=3 blocks")
+
+ # Mine 750 new-version blocks
+ for i in xrange(15):
+ self.nodes[2].generate(50)
+ self.sync_all()
+ if (self.nodes[0].getblockcount() != cnt + 850):
+ raise AssertionError("Failed to mine 750 version=4 blocks")
+
+ # TODO: check that new CHECKLOCKTIMEVERIFY rules are not enforced
+
+ # Mine 1 new-version block
+ self.nodes[2].generate(1)
+ self.sync_all()
+ if (self.nodes[0].getblockcount() != cnt + 851):
+ raise AssertionFailure("Failed to mine a version=4 blocks")
+
+ # TODO: check that new CHECKLOCKTIMEVERIFY rules are enforced
+
+ # Mine 198 new-version blocks
+ for i in xrange(2):
+ self.nodes[2].generate(99)
+ self.sync_all()
+ if (self.nodes[0].getblockcount() != cnt + 1049):
+ raise AssertionError("Failed to mine 198 version=4 blocks")
+
+ # Mine 1 old-version block
+ self.nodes[1].generate(1)
+ self.sync_all()
+ if (self.nodes[0].getblockcount() != cnt + 1050):
+ raise AssertionError("Failed to mine a version=3 block after 949 version=4 blocks")
+
+ # Mine 1 new-version blocks
+ self.nodes[2].generate(1)
+ self.sync_all()
+ if (self.nodes[0].getblockcount() != cnt + 1051):
+ raise AssertionError("Failed to mine a version=3 block")
+
+ # Mine 1 old-version blocks
+ try:
+ self.nodes[1].generate(1)
+ raise AssertionError("Succeeded to mine a version=3 block after 950 version=4 blocks")
+ except JSONRPCException:
+ pass
+ self.sync_all()
+ if (self.nodes[0].getblockcount() != cnt + 1051):
+ raise AssertionError("Accepted a version=3 block after 950 version=4 blocks")
+
+ # Mine 1 new-version blocks
+ self.nodes[2].generate(1)
+ self.sync_all()
+ if (self.nodes[0].getblockcount() != cnt + 1052):
+ raise AssertionError("Failed to mine a version=4 block")
+
+if __name__ == '__main__':
+ BIP65Test().main()
diff --git a/qa/rpc-tests/bipdersig-p2p.py b/qa/rpc-tests/bipdersig-p2p.py
new file mode 100755
index 0000000000..41717377b2
--- /dev/null
+++ b/qa/rpc-tests/bipdersig-p2p.py
@@ -0,0 +1,183 @@
+#!/usr/bin/env python2
+#
+# Distributed under the MIT/X11 software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#
+
+from test_framework.test_framework import ComparisonTestFramework
+from test_framework.util import *
+from test_framework.mininode import CTransaction, NetworkThread
+from test_framework.blocktools import create_coinbase, create_block
+from test_framework.comptool import TestInstance, TestManager
+from test_framework.script import CScript
+from binascii import hexlify, unhexlify
+import cStringIO
+import time
+
+# A canonical signature consists of:
+# <30> <total len> <02> <len R> <R> <02> <len S> <S> <hashtype>
+def unDERify(tx):
+ '''
+ Make the signature in vin 0 of a tx non-DER-compliant,
+ by adding padding after the S-value.
+ '''
+ scriptSig = CScript(tx.vin[0].scriptSig)
+ newscript = []
+ for i in scriptSig:
+ if (len(newscript) == 0):
+ newscript.append(i[0:-1] + '\0' + i[-1])
+ else:
+ newscript.append(i)
+ tx.vin[0].scriptSig = CScript(newscript)
+
+'''
+This test is meant to exercise BIP66 (DER SIG).
+Connect to a single node.
+Mine 2 (version 2) blocks (save the coinbases for later).
+Generate 98 more version 2 blocks, verify the node accepts.
+Mine 749 version 3 blocks, verify the node accepts.
+Check that the new DERSIG rules are not enforced on the 750th version 3 block.
+Check that the new DERSIG rules are enforced on the 751st version 3 block.
+Mine 199 new version blocks.
+Mine 1 old-version block.
+Mine 1 new version block.
+Mine 1 old version block, see that the node rejects.
+'''
+
+class BIP66Test(ComparisonTestFramework):
+
+ def __init__(self):
+ self.num_nodes = 1
+
+ def setup_network(self):
+ # Must set the blockversion for this test
+ self.nodes = start_nodes(1, self.options.tmpdir,
+ extra_args=[['-debug', '-whitelist=127.0.0.1', '-blockversion=2']],
+ binary=[self.options.testbinary])
+
+ def run_test(self):
+ test = TestManager(self, self.options.tmpdir)
+ test.add_all_connections(self.nodes)
+ NetworkThread().start() # Start up network handling in another thread
+ test.run()
+
+ def create_transaction(self, node, coinbase, to_address, amount):
+ from_txid = node.getblock(coinbase)['tx'][0]
+ inputs = [{ "txid" : from_txid, "vout" : 0}]
+ outputs = { to_address : amount }
+ rawtx = node.createrawtransaction(inputs, outputs)
+ signresult = node.signrawtransaction(rawtx)
+ tx = CTransaction()
+ f = cStringIO.StringIO(unhexlify(signresult['hex']))
+ tx.deserialize(f)
+ return tx
+
+ def get_tests(self):
+
+ self.coinbase_blocks = self.nodes[0].generate(2)
+ self.tip = int ("0x" + self.nodes[0].getbestblockhash() + "L", 0)
+ self.nodeaddress = self.nodes[0].getnewaddress()
+ self.last_block_time = time.time()
+
+ ''' 98 more version 2 blocks '''
+ test_blocks = []
+ for i in xrange(98):
+ block = create_block(self.tip, create_coinbase(2), self.last_block_time + 1)
+ block.nVersion = 2
+ block.rehash()
+ block.solve()
+ test_blocks.append([block, True])
+ self.last_block_time += 1
+ self.tip = block.sha256
+ yield TestInstance(test_blocks, sync_every_block=False)
+
+ ''' Mine 749 version 3 blocks '''
+ test_blocks = []
+ for i in xrange(749):
+ block = create_block(self.tip, create_coinbase(2), self.last_block_time + 1)
+ block.nVersion = 3
+ block.rehash()
+ block.solve()
+ test_blocks.append([block, True])
+ self.last_block_time += 1
+ self.tip = block.sha256
+ yield TestInstance(test_blocks, sync_every_block=False)
+
+ '''
+ Check that the new DERSIG rules are not enforced in the 750th
+ version 3 block.
+ '''
+ spendtx = self.create_transaction(self.nodes[0],
+ self.coinbase_blocks[0], self.nodeaddress, 1.0)
+ unDERify(spendtx)
+ spendtx.rehash()
+
+ block = create_block(self.tip, create_coinbase(2), self.last_block_time + 1)
+ block.nVersion = 3
+ block.vtx.append(spendtx)
+ block.hashMerkleRoot = block.calc_merkle_root()
+ block.rehash()
+ block.solve()
+
+ self.last_block_time += 1
+ self.tip = block.sha256
+ yield TestInstance([[block, True]])
+
+ '''
+ Check that the new DERSIG rules are enforced in the 751st version 3
+ block.
+ '''
+ spendtx = self.create_transaction(self.nodes[0],
+ self.coinbase_blocks[1], self.nodeaddress, 1.0)
+ unDERify(spendtx)
+ spendtx.rehash()
+
+ block = create_block(self.tip, create_coinbase(1), self.last_block_time + 1)
+ block.nVersion = 3
+ block.vtx.append(spendtx)
+ block.hashMerkleRoot = block.calc_merkle_root()
+ block.rehash()
+ block.solve()
+ self.last_block_time += 1
+ yield TestInstance([[block, False]])
+
+ ''' Mine 199 new version blocks on last valid tip '''
+ test_blocks = []
+ for i in xrange(199):
+ block = create_block(self.tip, create_coinbase(1), self.last_block_time + 1)
+ block.nVersion = 3
+ block.rehash()
+ block.solve()
+ test_blocks.append([block, True])
+ self.last_block_time += 1
+ self.tip = block.sha256
+ yield TestInstance(test_blocks, sync_every_block=False)
+
+ ''' Mine 1 old version block '''
+ block = create_block(self.tip, create_coinbase(1), self.last_block_time + 1)
+ block.nVersion = 2
+ block.rehash()
+ block.solve()
+ self.last_block_time += 1
+ self.tip = block.sha256
+ yield TestInstance([[block, True]])
+
+ ''' Mine 1 new version block '''
+ block = create_block(self.tip, create_coinbase(1), self.last_block_time + 1)
+ block.nVersion = 3
+ block.rehash()
+ block.solve()
+ self.last_block_time += 1
+ self.tip = block.sha256
+ yield TestInstance([[block, True]])
+
+ ''' Mine 1 old version block, should be invalid '''
+ block = create_block(self.tip, create_coinbase(1), self.last_block_time + 1)
+ block.nVersion = 2
+ block.rehash()
+ block.solve()
+ self.last_block_time += 1
+ yield TestInstance([[block, False]])
+
+if __name__ == '__main__':
+ BIP66Test().main()
diff --git a/qa/rpc-tests/bipdersig.py b/qa/rpc-tests/bipdersig.py
new file mode 100755
index 0000000000..243f816f65
--- /dev/null
+++ b/qa/rpc-tests/bipdersig.py
@@ -0,0 +1,89 @@
+#!/usr/bin/env python2
+# Copyright (c) 2014 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#
+# Test the BIP66 changeover logic
+#
+
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import *
+import os
+import shutil
+
+class BIP66Test(BitcoinTestFramework):
+
+ def setup_network(self):
+ self.nodes = []
+ self.nodes.append(start_node(0, self.options.tmpdir, []))
+ self.nodes.append(start_node(1, self.options.tmpdir, ["-blockversion=2"]))
+ self.nodes.append(start_node(2, self.options.tmpdir, ["-blockversion=3"]))
+ connect_nodes(self.nodes[1], 0)
+ connect_nodes(self.nodes[2], 0)
+ self.is_network_split = False
+ self.sync_all()
+
+ def run_test(self):
+ cnt = self.nodes[0].getblockcount()
+
+ # Mine some old-version blocks
+ self.nodes[1].generate(100)
+ self.sync_all()
+ if (self.nodes[0].getblockcount() != cnt + 100):
+ raise AssertionError("Failed to mine 100 version=2 blocks")
+
+ # Mine 750 new-version blocks
+ for i in xrange(15):
+ self.nodes[2].generate(50)
+ self.sync_all()
+ if (self.nodes[0].getblockcount() != cnt + 850):
+ raise AssertionError("Failed to mine 750 version=3 blocks")
+
+ # TODO: check that new DERSIG rules are not enforced
+
+ # Mine 1 new-version block
+ self.nodes[2].generate(1)
+ self.sync_all()
+ if (self.nodes[0].getblockcount() != cnt + 851):
+ raise AssertionFailure("Failed to mine a version=3 blocks")
+
+ # TODO: check that new DERSIG rules are enforced
+
+ # Mine 198 new-version blocks
+ for i in xrange(2):
+ self.nodes[2].generate(99)
+ self.sync_all()
+ if (self.nodes[0].getblockcount() != cnt + 1049):
+ raise AssertionError("Failed to mine 198 version=3 blocks")
+
+ # Mine 1 old-version block
+ self.nodes[1].generate(1)
+ self.sync_all()
+ if (self.nodes[0].getblockcount() != cnt + 1050):
+ raise AssertionError("Failed to mine a version=2 block after 949 version=3 blocks")
+
+ # Mine 1 new-version blocks
+ self.nodes[2].generate(1)
+ self.sync_all()
+ if (self.nodes[0].getblockcount() != cnt + 1051):
+ raise AssertionError("Failed to mine a version=3 block")
+
+ # Mine 1 old-version blocks
+ try:
+ self.nodes[1].generate(1)
+ raise AssertionError("Succeeded to mine a version=2 block after 950 version=3 blocks")
+ except JSONRPCException:
+ pass
+ self.sync_all()
+ if (self.nodes[0].getblockcount() != cnt + 1051):
+ raise AssertionError("Accepted a version=2 block after 950 version=3 blocks")
+
+ # Mine 1 new-version blocks
+ self.nodes[2].generate(1)
+ self.sync_all()
+ if (self.nodes[0].getblockcount() != cnt + 1052):
+ raise AssertionError("Failed to mine a version=3 block")
+
+if __name__ == '__main__':
+ BIP66Test().main()
diff --git a/qa/rpc-tests/forknotify.py b/qa/rpc-tests/forknotify.py
new file mode 100755
index 0000000000..0acef8e30b
--- /dev/null
+++ b/qa/rpc-tests/forknotify.py
@@ -0,0 +1,63 @@
+#!/usr/bin/env python2
+# Copyright (c) 2014 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#
+# Test -alertnotify
+#
+
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import *
+import os
+import shutil
+
+class ForkNotifyTest(BitcoinTestFramework):
+
+ alert_filename = None # Set by setup_network
+
+ def setup_network(self):
+ self.nodes = []
+ self.alert_filename = os.path.join(self.options.tmpdir, "alert.txt")
+ with open(self.alert_filename, 'w') as f:
+ pass # Just open then close to create zero-length file
+ self.nodes.append(start_node(0, self.options.tmpdir,
+ ["-blockversion=2", "-alertnotify=echo %s >> \"" + self.alert_filename + "\""]))
+ # Node1 mines block.version=211 blocks
+ self.nodes.append(start_node(1, self.options.tmpdir,
+ ["-blockversion=211"]))
+ connect_nodes(self.nodes[1], 0)
+
+ self.is_network_split = False
+ self.sync_all()
+
+ def run_test(self):
+ # Mine 51 up-version blocks
+ self.nodes[1].generate(51)
+ self.sync_all()
+ # -alertnotify should trigger on the 51'st,
+ # but mine and sync another to give
+ # -alertnotify time to write
+ self.nodes[1].generate(1)
+ self.sync_all()
+
+ with open(self.alert_filename, 'r') as f:
+ alert_text = f.read()
+
+ if len(alert_text) == 0:
+ raise AssertionError("-alertnotify did not warn of up-version blocks")
+
+ # Mine more up-version blocks, should not get more alerts:
+ self.nodes[1].generate(1)
+ self.sync_all()
+ self.nodes[1].generate(1)
+ self.sync_all()
+
+ with open(self.alert_filename, 'r') as f:
+ alert_text2 = f.read()
+
+ if alert_text != alert_text2:
+ raise AssertionError("-alertnotify excessive warning of up-version blocks")
+
+if __name__ == '__main__':
+ ForkNotifyTest().main()
diff --git a/qa/rpc-tests/getblocktemplate_longpoll.py b/qa/rpc-tests/getblocktemplate_longpoll.py
new file mode 100755
index 0000000000..aab4562422
--- /dev/null
+++ b/qa/rpc-tests/getblocktemplate_longpoll.py
@@ -0,0 +1,91 @@
+#!/usr/bin/env python2
+# Copyright (c) 2014 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import *
+
+
+def check_array_result(object_array, to_match, expected):
+ """
+ Pass in array of JSON objects, a dictionary with key/value pairs
+ to match against, and another dictionary with expected key/value
+ pairs.
+ """
+ num_matched = 0
+ for item in object_array:
+ all_match = True
+ for key,value in to_match.items():
+ if item[key] != value:
+ all_match = False
+ if not all_match:
+ continue
+ for key,value in expected.items():
+ if item[key] != value:
+ raise AssertionError("%s : expected %s=%s"%(str(item), str(key), str(value)))
+ num_matched = num_matched+1
+ if num_matched == 0:
+ raise AssertionError("No objects matched %s"%(str(to_match)))
+
+import threading
+
+class LongpollThread(threading.Thread):
+ def __init__(self, node):
+ threading.Thread.__init__(self)
+ # query current longpollid
+ templat = node.getblocktemplate()
+ self.longpollid = templat['longpollid']
+ # create a new connection to the node, we can't use the same
+ # connection from two threads
+ self.node = AuthServiceProxy(node.url, timeout=600)
+
+ def run(self):
+ self.node.getblocktemplate({'longpollid':self.longpollid})
+
+class GetBlockTemplateLPTest(BitcoinTestFramework):
+ '''
+ Test longpolling with getblocktemplate.
+ '''
+
+ def run_test(self):
+ print "Warning: this test will take about 70 seconds in the best case. Be patient."
+ self.nodes[0].generate(10)
+ templat = self.nodes[0].getblocktemplate()
+ longpollid = templat['longpollid']
+ # longpollid should not change between successive invocations if nothing else happens
+ templat2 = self.nodes[0].getblocktemplate()
+ assert(templat2['longpollid'] == longpollid)
+
+ # Test 1: test that the longpolling wait if we do nothing
+ thr = LongpollThread(self.nodes[0])
+ thr.start()
+ # check that thread still lives
+ thr.join(5) # wait 5 seconds or until thread exits
+ assert(thr.is_alive())
+
+ # Test 2: test that longpoll will terminate if another node generates a block
+ self.nodes[1].generate(1) # generate a block on another node
+ # check that thread will exit now that new transaction entered mempool
+ thr.join(5) # wait 5 seconds or until thread exits
+ assert(not thr.is_alive())
+
+ # Test 3: test that longpoll will terminate if we generate a block ourselves
+ thr = LongpollThread(self.nodes[0])
+ thr.start()
+ self.nodes[0].generate(1) # generate a block on another node
+ thr.join(5) # wait 5 seconds or until thread exits
+ assert(not thr.is_alive())
+
+ # Test 4: test that introducing a new transaction into the mempool will terminate the longpoll
+ thr = LongpollThread(self.nodes[0])
+ thr.start()
+ # generate a random transaction and submit it
+ (txid, txhex, fee) = random_transaction(self.nodes, Decimal("1.1"), Decimal("0.0"), Decimal("0.001"), 20)
+ # after one minute, every 10 seconds the mempool is probed, so in 80 seconds it should have returned
+ thr.join(60 + 20)
+ assert(not thr.is_alive())
+
+if __name__ == '__main__':
+ GetBlockTemplateLPTest().main()
+
diff --git a/qa/rpc-tests/getblocktemplate_proposals.py b/qa/rpc-tests/getblocktemplate_proposals.py
new file mode 100755
index 0000000000..aca0cd7495
--- /dev/null
+++ b/qa/rpc-tests/getblocktemplate_proposals.py
@@ -0,0 +1,182 @@
+#!/usr/bin/env python2
+# Copyright (c) 2014 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import *
+
+from binascii import a2b_hex, b2a_hex
+from hashlib import sha256
+from struct import pack
+
+
+def check_array_result(object_array, to_match, expected):
+ """
+ Pass in array of JSON objects, a dictionary with key/value pairs
+ to match against, and another dictionary with expected key/value
+ pairs.
+ """
+ num_matched = 0
+ for item in object_array:
+ all_match = True
+ for key,value in to_match.items():
+ if item[key] != value:
+ all_match = False
+ if not all_match:
+ continue
+ for key,value in expected.items():
+ if item[key] != value:
+ raise AssertionError("%s : expected %s=%s"%(str(item), str(key), str(value)))
+ num_matched = num_matched+1
+ if num_matched == 0:
+ raise AssertionError("No objects matched %s"%(str(to_match)))
+
+def b2x(b):
+ return b2a_hex(b).decode('ascii')
+
+# NOTE: This does not work for signed numbers (set the high bit) or zero (use b'\0')
+def encodeUNum(n):
+ s = bytearray(b'\1')
+ while n > 127:
+ s[0] += 1
+ s.append(n % 256)
+ n //= 256
+ s.append(n)
+ return bytes(s)
+
+def varlenEncode(n):
+ if n < 0xfd:
+ return pack('<B', n)
+ if n <= 0xffff:
+ return b'\xfd' + pack('<H', n)
+ if n <= 0xffffffff:
+ return b'\xfe' + pack('<L', n)
+ return b'\xff' + pack('<Q', n)
+
+def dblsha(b):
+ return sha256(sha256(b).digest()).digest()
+
+def genmrklroot(leaflist):
+ cur = leaflist
+ while len(cur) > 1:
+ n = []
+ if len(cur) & 1:
+ cur.append(cur[-1])
+ for i in range(0, len(cur), 2):
+ n.append(dblsha(cur[i] + cur[i+1]))
+ cur = n
+ return cur[0]
+
+def template_to_bytes(tmpl, txlist):
+ blkver = pack('<L', tmpl['version'])
+ mrklroot = genmrklroot(list(dblsha(a) for a in txlist))
+ timestamp = pack('<L', tmpl['curtime'])
+ nonce = b'\0\0\0\0'
+ blk = blkver + a2b_hex(tmpl['previousblockhash'])[::-1] + mrklroot + timestamp + a2b_hex(tmpl['bits'])[::-1] + nonce
+ blk += varlenEncode(len(txlist))
+ for tx in txlist:
+ blk += tx
+ return blk
+
+def template_to_hex(tmpl, txlist):
+ return b2x(template_to_bytes(tmpl, txlist))
+
+def assert_template(node, tmpl, txlist, expect):
+ rsp = node.getblocktemplate({'data':template_to_hex(tmpl, txlist),'mode':'proposal'})
+ if rsp != expect:
+ raise AssertionError('unexpected: %s' % (rsp,))
+
+class GetBlockTemplateProposalTest(BitcoinTestFramework):
+ '''
+ Test block proposals with getblocktemplate.
+ '''
+
+ def run_test(self):
+ node = self.nodes[0]
+ node.generate(1) # Mine a block to leave initial block download
+ tmpl = node.getblocktemplate()
+ if 'coinbasetxn' not in tmpl:
+ rawcoinbase = encodeUNum(tmpl['height'])
+ rawcoinbase += b'\x01-'
+ hexcoinbase = b2x(rawcoinbase)
+ hexoutval = b2x(pack('<Q', tmpl['coinbasevalue']))
+ tmpl['coinbasetxn'] = {'data': '01000000' + '01' + '0000000000000000000000000000000000000000000000000000000000000000ffffffff' + ('%02x' % (len(rawcoinbase),)) + hexcoinbase + 'fffffffe' + '01' + hexoutval + '00' + '00000000'}
+ txlist = list(bytearray(a2b_hex(a['data'])) for a in (tmpl['coinbasetxn'],) + tuple(tmpl['transactions']))
+
+ # Test 0: Capability advertised
+ assert('proposal' in tmpl['capabilities'])
+
+ # NOTE: This test currently FAILS (regtest mode doesn't enforce block height in coinbase)
+ ## Test 1: Bad height in coinbase
+ #txlist[0][4+1+36+1+1] += 1
+ #assert_template(node, tmpl, txlist, 'FIXME')
+ #txlist[0][4+1+36+1+1] -= 1
+
+ # Test 2: Bad input hash for gen tx
+ txlist[0][4+1] += 1
+ assert_template(node, tmpl, txlist, 'bad-cb-missing')
+ txlist[0][4+1] -= 1
+
+ # Test 3: Truncated final tx
+ lastbyte = txlist[-1].pop()
+ try:
+ assert_template(node, tmpl, txlist, 'n/a')
+ except JSONRPCException:
+ pass # Expected
+ txlist[-1].append(lastbyte)
+
+ # Test 4: Add an invalid tx to the end (duplicate of gen tx)
+ txlist.append(txlist[0])
+ assert_template(node, tmpl, txlist, 'bad-txns-duplicate')
+ txlist.pop()
+
+ # Test 5: Add an invalid tx to the end (non-duplicate)
+ txlist.append(bytearray(txlist[0]))
+ txlist[-1][4+1] = b'\xff'
+ assert_template(node, tmpl, txlist, 'bad-txns-inputs-missingorspent')
+ txlist.pop()
+
+ # Test 6: Future tx lock time
+ txlist[0][-4:] = b'\xff\xff\xff\xff'
+ assert_template(node, tmpl, txlist, 'bad-txns-nonfinal')
+ txlist[0][-4:] = b'\0\0\0\0'
+
+ # Test 7: Bad tx count
+ txlist.append(b'')
+ try:
+ assert_template(node, tmpl, txlist, 'n/a')
+ except JSONRPCException:
+ pass # Expected
+ txlist.pop()
+
+ # Test 8: Bad bits
+ realbits = tmpl['bits']
+ tmpl['bits'] = '1c0000ff' # impossible in the real world
+ assert_template(node, tmpl, txlist, 'bad-diffbits')
+ tmpl['bits'] = realbits
+
+ # Test 9: Bad merkle root
+ rawtmpl = template_to_bytes(tmpl, txlist)
+ rawtmpl[4+32] = (rawtmpl[4+32] + 1) % 0x100
+ rsp = node.getblocktemplate({'data':b2x(rawtmpl),'mode':'proposal'})
+ if rsp != 'bad-txnmrklroot':
+ raise AssertionError('unexpected: %s' % (rsp,))
+
+ # Test 10: Bad timestamps
+ realtime = tmpl['curtime']
+ tmpl['curtime'] = 0x7fffffff
+ assert_template(node, tmpl, txlist, 'time-too-new')
+ tmpl['curtime'] = 0
+ assert_template(node, tmpl, txlist, 'time-too-old')
+ tmpl['curtime'] = realtime
+
+ # Test 11: Valid block
+ assert_template(node, tmpl, txlist, None)
+
+ # Test 12: Orphan block
+ tmpl['previousblockhash'] = 'ff00' * 16
+ assert_template(node, tmpl, txlist, 'inconclusive-not-best-prevblk')
+
+if __name__ == '__main__':
+ GetBlockTemplateProposalTest().main()
diff --git a/qa/rpc-tests/getchaintips.py b/qa/rpc-tests/getchaintips.py
new file mode 100755
index 0000000000..6a2bcb2969
--- /dev/null
+++ b/qa/rpc-tests/getchaintips.py
@@ -0,0 +1,59 @@
+#!/usr/bin/env python2
+# Copyright (c) 2014 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+# Exercise the getchaintips API. We introduce a network split, work
+# on chains of different lengths, and join the network together again.
+# This gives us two tips, verify that it works.
+
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import assert_equal
+
+class GetChainTipsTest (BitcoinTestFramework):
+
+ def run_test (self):
+ BitcoinTestFramework.run_test (self)
+
+ tips = self.nodes[0].getchaintips ()
+ assert_equal (len (tips), 1)
+ assert_equal (tips[0]['branchlen'], 0)
+ assert_equal (tips[0]['height'], 200)
+ assert_equal (tips[0]['status'], 'active')
+
+ # Split the network and build two chains of different lengths.
+ self.split_network ()
+ self.nodes[0].generate(10);
+ self.nodes[2].generate(20);
+ self.sync_all ()
+
+ tips = self.nodes[1].getchaintips ()
+ assert_equal (len (tips), 1)
+ shortTip = tips[0]
+ assert_equal (shortTip['branchlen'], 0)
+ assert_equal (shortTip['height'], 210)
+ assert_equal (tips[0]['status'], 'active')
+
+ tips = self.nodes[3].getchaintips ()
+ assert_equal (len (tips), 1)
+ longTip = tips[0]
+ assert_equal (longTip['branchlen'], 0)
+ assert_equal (longTip['height'], 220)
+ assert_equal (tips[0]['status'], 'active')
+
+ # Join the network halves and check that we now have two tips
+ # (at least at the nodes that previously had the short chain).
+ self.join_network ()
+
+ tips = self.nodes[0].getchaintips ()
+ assert_equal (len (tips), 2)
+ assert_equal (tips[0], longTip)
+
+ assert_equal (tips[1]['branchlen'], 10)
+ assert_equal (tips[1]['status'], 'valid-fork')
+ tips[1]['branchlen'] = 0
+ tips[1]['status'] = 'active'
+ assert_equal (tips[1], shortTip)
+
+if __name__ == '__main__':
+ GetChainTipsTest ().main ()
diff --git a/qa/rpc-tests/httpbasics.py b/qa/rpc-tests/httpbasics.py
new file mode 100755
index 0000000000..64ba49df64
--- /dev/null
+++ b/qa/rpc-tests/httpbasics.py
@@ -0,0 +1,102 @@
+#!/usr/bin/env python2
+# Copyright (c) 2014 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#
+# Test REST interface
+#
+
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import *
+import base64
+
+try:
+ import http.client as httplib
+except ImportError:
+ import httplib
+try:
+ import urllib.parse as urlparse
+except ImportError:
+ import urlparse
+
+class HTTPBasicsTest (BitcoinTestFramework):
+ def setup_nodes(self):
+ return start_nodes(4, self.options.tmpdir, extra_args=[['-rpckeepalive=1'], ['-rpckeepalive=0'], [], []])
+
+ def run_test(self):
+
+ #################################################
+ # lowlevel check for http persistent connection #
+ #################################################
+ url = urlparse.urlparse(self.nodes[0].url)
+ authpair = url.username + ':' + url.password
+ headers = {"Authorization": "Basic " + base64.b64encode(authpair)}
+
+ conn = httplib.HTTPConnection(url.hostname, url.port)
+ conn.connect()
+ conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
+ out1 = conn.getresponse().read();
+ assert_equal('"error":null' in out1, True)
+ assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open!
+
+ #send 2nd request without closing connection
+ conn.request('POST', '/', '{"method": "getchaintips"}', headers)
+ out2 = conn.getresponse().read();
+ assert_equal('"error":null' in out1, True) #must also response with a correct json-rpc message
+ assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open!
+ conn.close()
+
+ #same should be if we add keep-alive because this should be the std. behaviour
+ headers = {"Authorization": "Basic " + base64.b64encode(authpair), "Connection": "keep-alive"}
+
+ conn = httplib.HTTPConnection(url.hostname, url.port)
+ conn.connect()
+ conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
+ out1 = conn.getresponse().read();
+ assert_equal('"error":null' in out1, True)
+ assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open!
+
+ #send 2nd request without closing connection
+ conn.request('POST', '/', '{"method": "getchaintips"}', headers)
+ out2 = conn.getresponse().read();
+ assert_equal('"error":null' in out1, True) #must also response with a correct json-rpc message
+ assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open!
+ conn.close()
+
+ #now do the same with "Connection: close"
+ headers = {"Authorization": "Basic " + base64.b64encode(authpair), "Connection":"close"}
+
+ conn = httplib.HTTPConnection(url.hostname, url.port)
+ conn.connect()
+ conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
+ out1 = conn.getresponse().read();
+ assert_equal('"error":null' in out1, True)
+ assert_equal(conn.sock!=None, False) #now the connection must be closed after the response
+
+ #node1 (2nd node) is running with disabled keep-alive option
+ urlNode1 = urlparse.urlparse(self.nodes[1].url)
+ authpair = urlNode1.username + ':' + urlNode1.password
+ headers = {"Authorization": "Basic " + base64.b64encode(authpair)}
+
+ conn = httplib.HTTPConnection(urlNode1.hostname, urlNode1.port)
+ conn.connect()
+ conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
+ out1 = conn.getresponse().read();
+ assert_equal('"error":null' in out1, True)
+ assert_equal(conn.sock!=None, False) #connection must be closed because keep-alive was set to false
+
+ #node2 (third node) is running with standard keep-alive parameters which means keep-alive is off
+ urlNode2 = urlparse.urlparse(self.nodes[2].url)
+ authpair = urlNode2.username + ':' + urlNode2.password
+ headers = {"Authorization": "Basic " + base64.b64encode(authpair)}
+
+ conn = httplib.HTTPConnection(urlNode2.hostname, urlNode2.port)
+ conn.connect()
+ conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
+ out1 = conn.getresponse().read();
+ assert_equal('"error":null' in out1, True)
+ assert_equal(conn.sock!=None, True) #connection must be closed because bitcoind should use keep-alive by default
+
+if __name__ == '__main__':
+ HTTPBasicsTest ().main ()
diff --git a/qa/rpc-tests/invalidateblock.py b/qa/rpc-tests/invalidateblock.py
new file mode 100755
index 0000000000..2b9c8154e0
--- /dev/null
+++ b/qa/rpc-tests/invalidateblock.py
@@ -0,0 +1,75 @@
+#!/usr/bin/env python2
+# Copyright (c) 2014 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#
+# Test InvalidateBlock code
+#
+
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import *
+
+class InvalidateTest(BitcoinTestFramework):
+
+
+ def setup_chain(self):
+ print("Initializing test directory "+self.options.tmpdir)
+ initialize_chain_clean(self.options.tmpdir, 3)
+
+ def setup_network(self):
+ self.nodes = []
+ self.is_network_split = False
+ self.nodes.append(start_node(0, self.options.tmpdir, ["-debug"]))
+ self.nodes.append(start_node(1, self.options.tmpdir, ["-debug"]))
+ self.nodes.append(start_node(2, self.options.tmpdir, ["-debug"]))
+
+ def run_test(self):
+ print "Make sure we repopulate setBlockIndexCandidates after InvalidateBlock:"
+ print "Mine 4 blocks on Node 0"
+ self.nodes[0].generate(4)
+ assert(self.nodes[0].getblockcount() == 4)
+ besthash = self.nodes[0].getbestblockhash()
+
+ print "Mine competing 6 blocks on Node 1"
+ self.nodes[1].generate(6)
+ assert(self.nodes[1].getblockcount() == 6)
+
+ print "Connect nodes to force a reorg"
+ connect_nodes_bi(self.nodes,0,1)
+ sync_blocks(self.nodes[0:2])
+ assert(self.nodes[0].getblockcount() == 6)
+ badhash = self.nodes[1].getblockhash(2)
+
+ print "Invalidate block 2 on node 0 and verify we reorg to node 0's original chain"
+ self.nodes[0].invalidateblock(badhash)
+ newheight = self.nodes[0].getblockcount()
+ newhash = self.nodes[0].getbestblockhash()
+ if (newheight != 4 or newhash != besthash):
+ raise AssertionError("Wrong tip for node0, hash %s, height %d"%(newhash,newheight))
+
+ print "\nMake sure we won't reorg to a lower work chain:"
+ connect_nodes_bi(self.nodes,1,2)
+ print "Sync node 2 to node 1 so both have 6 blocks"
+ sync_blocks(self.nodes[1:3])
+ assert(self.nodes[2].getblockcount() == 6)
+ print "Invalidate block 5 on node 1 so its tip is now at 4"
+ self.nodes[1].invalidateblock(self.nodes[1].getblockhash(5))
+ assert(self.nodes[1].getblockcount() == 4)
+ print "Invalidate block 3 on node 2, so its tip is now 2"
+ self.nodes[2].invalidateblock(self.nodes[2].getblockhash(3))
+ assert(self.nodes[2].getblockcount() == 2)
+ print "..and then mine a block"
+ self.nodes[2].generate(1)
+ print "Verify all nodes are at the right height"
+ time.sleep(5)
+ for i in xrange(3):
+ print i,self.nodes[i].getblockcount()
+ assert(self.nodes[2].getblockcount() == 3)
+ assert(self.nodes[0].getblockcount() == 4)
+ node1height = self.nodes[1].getblockcount()
+ if node1height < 4:
+ raise AssertionError("Node 1 reorged to a lower height: %d"%node1height)
+
+if __name__ == '__main__':
+ InvalidateTest().main()
diff --git a/qa/rpc-tests/invalidblockrequest.py b/qa/rpc-tests/invalidblockrequest.py
new file mode 100755
index 0000000000..64b8e26395
--- /dev/null
+++ b/qa/rpc-tests/invalidblockrequest.py
@@ -0,0 +1,115 @@
+#!/usr/bin/env python2
+#
+# Distributed under the MIT/X11 software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#
+
+from test_framework.test_framework import ComparisonTestFramework
+from test_framework.util import *
+from test_framework.comptool import TestManager, TestInstance
+from test_framework.mininode import *
+from test_framework.blocktools import *
+import logging
+import copy
+import time
+
+
+'''
+In this test we connect to one node over p2p, and test block requests:
+1) Valid blocks should be requested and become chain tip.
+2) Invalid block with duplicated transaction should be re-requested.
+3) Invalid block with bad coinbase value should be rejected and not
+re-requested.
+'''
+
+# Use the ComparisonTestFramework with 1 node: only use --testbinary.
+class InvalidBlockRequestTest(ComparisonTestFramework):
+
+ ''' Can either run this test as 1 node with expected answers, or two and compare them.
+ Change the "outcome" variable from each TestInstance object to only do the comparison. '''
+ def __init__(self):
+ self.num_nodes = 1
+
+ def run_test(self):
+ test = TestManager(self, self.options.tmpdir)
+ test.add_all_connections(self.nodes)
+ self.tip = None
+ self.block_time = None
+ NetworkThread().start() # Start up network handling in another thread
+ test.run()
+
+ def get_tests(self):
+ if self.tip is None:
+ self.tip = int ("0x" + self.nodes[0].getbestblockhash() + "L", 0)
+ self.block_time = int(time.time())+1
+
+ '''
+ Create a new block with an anyone-can-spend coinbase
+ '''
+ block = create_block(self.tip, create_coinbase(), self.block_time)
+ self.block_time += 1
+ block.solve()
+ # Save the coinbase for later
+ self.block1 = block
+ self.tip = block.sha256
+ yield TestInstance([[block, True]])
+
+ '''
+ Now we need that block to mature so we can spend the coinbase.
+ '''
+ test = TestInstance(sync_every_block=False)
+ for i in xrange(100):
+ block = create_block(self.tip, create_coinbase(), self.block_time)
+ block.solve()
+ self.tip = block.sha256
+ self.block_time += 1
+ test.blocks_and_transactions.append([block, True])
+ yield test
+
+ '''
+ Now we use merkle-root malleability to generate an invalid block with
+ same blockheader.
+ Manufacture a block with 3 transactions (coinbase, spend of prior
+ coinbase, spend of that spend). Duplicate the 3rd transaction to
+ leave merkle root and blockheader unchanged but invalidate the block.
+ '''
+ block2 = create_block(self.tip, create_coinbase(), self.block_time)
+ self.block_time += 1
+
+ # chr(81) is OP_TRUE
+ tx1 = create_transaction(self.block1.vtx[0], 0, chr(81), 50*100000000)
+ tx2 = create_transaction(tx1, 0, chr(81), 50*100000000)
+
+ block2.vtx.extend([tx1, tx2])
+ block2.hashMerkleRoot = block2.calc_merkle_root()
+ block2.rehash()
+ block2.solve()
+ orig_hash = block2.sha256
+ block2_orig = copy.deepcopy(block2)
+
+ # Mutate block 2
+ block2.vtx.append(tx2)
+ assert_equal(block2.hashMerkleRoot, block2.calc_merkle_root())
+ assert_equal(orig_hash, block2.rehash())
+ assert(block2_orig.vtx != block2.vtx)
+
+ self.tip = block2.sha256
+ yield TestInstance([[block2, False], [block2_orig, True]])
+
+ '''
+ Make sure that a totally screwed up block is not valid.
+ '''
+ block3 = create_block(self.tip, create_coinbase(), self.block_time)
+ self.block_time += 1
+ block3.vtx[0].vout[0].nValue = 100*100000000 # Too high!
+ block3.vtx[0].sha256=None
+ block3.vtx[0].calc_sha256()
+ block3.hashMerkleRoot = block3.calc_merkle_root()
+ block3.rehash()
+ block3.solve()
+
+ yield TestInstance([[block3, False]])
+
+
+if __name__ == '__main__':
+ InvalidBlockRequestTest().main()
diff --git a/qa/rpc-tests/keypool.py b/qa/rpc-tests/keypool.py
new file mode 100755
index 0000000000..aee29a596a
--- /dev/null
+++ b/qa/rpc-tests/keypool.py
@@ -0,0 +1,130 @@
+#!/usr/bin/env python2
+# Copyright (c) 2014 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+# Exercise the wallet keypool, and interaction with wallet encryption/locking
+
+# Add python-bitcoinrpc to module search path:
+import os
+import sys
+
+import json
+import shutil
+import subprocess
+import tempfile
+import traceback
+
+from test_framework.util import *
+
+
+def check_array_result(object_array, to_match, expected):
+ """
+ Pass in array of JSON objects, a dictionary with key/value pairs
+ to match against, and another dictionary with expected key/value
+ pairs.
+ """
+ num_matched = 0
+ for item in object_array:
+ all_match = True
+ for key,value in to_match.items():
+ if item[key] != value:
+ all_match = False
+ if not all_match:
+ continue
+ for key,value in expected.items():
+ if item[key] != value:
+ raise AssertionError("%s : expected %s=%s"%(str(item), str(key), str(value)))
+ num_matched = num_matched+1
+ if num_matched == 0:
+ raise AssertionError("No objects matched %s"%(str(to_match)))
+
+def run_test(nodes, tmpdir):
+ # Encrypt wallet and wait to terminate
+ nodes[0].encryptwallet('test')
+ bitcoind_processes[0].wait()
+ # Restart node 0
+ nodes[0] = start_node(0, tmpdir)
+ # Keep creating keys
+ addr = nodes[0].getnewaddress()
+ try:
+ addr = nodes[0].getnewaddress()
+ raise AssertionError('Keypool should be exhausted after one address')
+ except JSONRPCException,e:
+ assert(e.error['code']==-12)
+
+ # put three new keys in the keypool
+ nodes[0].walletpassphrase('test', 12000)
+ nodes[0].keypoolrefill(3)
+ nodes[0].walletlock()
+
+ # drain the keys
+ addr = set()
+ addr.add(nodes[0].getrawchangeaddress())
+ addr.add(nodes[0].getrawchangeaddress())
+ addr.add(nodes[0].getrawchangeaddress())
+ addr.add(nodes[0].getrawchangeaddress())
+ # assert that four unique addresses were returned
+ assert(len(addr) == 4)
+ # the next one should fail
+ try:
+ addr = nodes[0].getrawchangeaddress()
+ raise AssertionError('Keypool should be exhausted after three addresses')
+ except JSONRPCException,e:
+ assert(e.error['code']==-12)
+
+
+def main():
+ import optparse
+
+ parser = optparse.OptionParser(usage="%prog [options]")
+ parser.add_option("--nocleanup", dest="nocleanup", default=False, action="store_true",
+ help="Leave bitcoinds and test.* datadir on exit or error")
+ parser.add_option("--srcdir", dest="srcdir", default="../../src",
+ help="Source directory containing bitcoind/bitcoin-cli (default: %default%)")
+ parser.add_option("--tmpdir", dest="tmpdir", default=tempfile.mkdtemp(prefix="test"),
+ help="Root directory for datadirs")
+ (options, args) = parser.parse_args()
+
+ os.environ['PATH'] = options.srcdir+":"+os.environ['PATH']
+
+ check_json_precision()
+
+ success = False
+ nodes = []
+ try:
+ print("Initializing test directory "+options.tmpdir)
+ if not os.path.isdir(options.tmpdir):
+ os.makedirs(options.tmpdir)
+ initialize_chain(options.tmpdir)
+
+ nodes = start_nodes(1, options.tmpdir)
+
+ run_test(nodes, options.tmpdir)
+
+ success = True
+
+ except AssertionError as e:
+ print("Assertion failed: "+e.message)
+ except JSONRPCException as e:
+ print("JSONRPC error: "+e.error['message'])
+ traceback.print_tb(sys.exc_info()[2])
+ except Exception as e:
+ print("Unexpected exception caught during testing: "+str(sys.exc_info()[0]))
+ traceback.print_tb(sys.exc_info()[2])
+
+ if not options.nocleanup:
+ print("Cleaning up")
+ stop_nodes(nodes)
+ wait_bitcoinds()
+ shutil.rmtree(options.tmpdir)
+
+ if success:
+ print("Tests successful")
+ sys.exit(0)
+ else:
+ print("Failed")
+ sys.exit(1)
+
+if __name__ == '__main__':
+ main()
diff --git a/qa/rpc-tests/listtransactions.py b/qa/rpc-tests/listtransactions.py
new file mode 100755
index 0000000000..eeae2d2fa2
--- /dev/null
+++ b/qa/rpc-tests/listtransactions.py
@@ -0,0 +1,98 @@
+#!/usr/bin/env python2
+# Copyright (c) 2014 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+# Exercise the listtransactions API
+
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import *
+
+
+def check_array_result(object_array, to_match, expected):
+ """
+ Pass in array of JSON objects, a dictionary with key/value pairs
+ to match against, and another dictionary with expected key/value
+ pairs.
+ """
+ num_matched = 0
+ for item in object_array:
+ all_match = True
+ for key,value in to_match.items():
+ if item[key] != value:
+ all_match = False
+ if not all_match:
+ continue
+ for key,value in expected.items():
+ if item[key] != value:
+ raise AssertionError("%s : expected %s=%s"%(str(item), str(key), str(value)))
+ num_matched = num_matched+1
+ if num_matched == 0:
+ raise AssertionError("No objects matched %s"%(str(to_match)))
+
+class ListTransactionsTest(BitcoinTestFramework):
+
+ def run_test(self):
+ # Simple send, 0 to 1:
+ txid = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.1)
+ self.sync_all()
+ check_array_result(self.nodes[0].listtransactions(),
+ {"txid":txid},
+ {"category":"send","account":"","amount":Decimal("-0.1"),"confirmations":0})
+ check_array_result(self.nodes[1].listtransactions(),
+ {"txid":txid},
+ {"category":"receive","account":"","amount":Decimal("0.1"),"confirmations":0})
+ # mine a block, confirmations should change:
+ self.nodes[0].generate(1)
+ self.sync_all()
+ check_array_result(self.nodes[0].listtransactions(),
+ {"txid":txid},
+ {"category":"send","account":"","amount":Decimal("-0.1"),"confirmations":1})
+ check_array_result(self.nodes[1].listtransactions(),
+ {"txid":txid},
+ {"category":"receive","account":"","amount":Decimal("0.1"),"confirmations":1})
+
+ # send-to-self:
+ txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 0.2)
+ check_array_result(self.nodes[0].listtransactions(),
+ {"txid":txid, "category":"send"},
+ {"amount":Decimal("-0.2")})
+ check_array_result(self.nodes[0].listtransactions(),
+ {"txid":txid, "category":"receive"},
+ {"amount":Decimal("0.2")})
+
+ # sendmany from node1: twice to self, twice to node2:
+ send_to = { self.nodes[0].getnewaddress() : 0.11,
+ self.nodes[1].getnewaddress() : 0.22,
+ self.nodes[0].getaccountaddress("from1") : 0.33,
+ self.nodes[1].getaccountaddress("toself") : 0.44 }
+ txid = self.nodes[1].sendmany("", send_to)
+ self.sync_all()
+ check_array_result(self.nodes[1].listtransactions(),
+ {"category":"send","amount":Decimal("-0.11")},
+ {"txid":txid} )
+ check_array_result(self.nodes[0].listtransactions(),
+ {"category":"receive","amount":Decimal("0.11")},
+ {"txid":txid} )
+ check_array_result(self.nodes[1].listtransactions(),
+ {"category":"send","amount":Decimal("-0.22")},
+ {"txid":txid} )
+ check_array_result(self.nodes[1].listtransactions(),
+ {"category":"receive","amount":Decimal("0.22")},
+ {"txid":txid} )
+ check_array_result(self.nodes[1].listtransactions(),
+ {"category":"send","amount":Decimal("-0.33")},
+ {"txid":txid} )
+ check_array_result(self.nodes[0].listtransactions(),
+ {"category":"receive","amount":Decimal("0.33")},
+ {"txid":txid, "account" : "from1"} )
+ check_array_result(self.nodes[1].listtransactions(),
+ {"category":"send","amount":Decimal("-0.44")},
+ {"txid":txid, "account" : ""} )
+ check_array_result(self.nodes[1].listtransactions(),
+ {"category":"receive","amount":Decimal("0.44")},
+ {"txid":txid, "account" : "toself"} )
+
+if __name__ == '__main__':
+ ListTransactionsTest().main()
+
diff --git a/qa/rpc-tests/maxblocksinflight.py b/qa/rpc-tests/maxblocksinflight.py
new file mode 100755
index 0000000000..a601147ce8
--- /dev/null
+++ b/qa/rpc-tests/maxblocksinflight.py
@@ -0,0 +1,101 @@
+#!/usr/bin/env python2
+#
+# Distributed under the MIT/X11 software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#
+
+from test_framework.mininode import *
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import *
+import logging
+
+'''
+In this test we connect to one node over p2p, send it numerous inv's, and
+compare the resulting number of getdata requests to a max allowed value. We
+test for exceeding 128 blocks in flight, which was the limit an 0.9 client will
+reach. [0.10 clients shouldn't request more than 16 from a single peer.]
+'''
+MAX_REQUESTS = 128
+
+class TestManager(NodeConnCB):
+ # set up NodeConnCB callbacks, overriding base class
+ def on_getdata(self, conn, message):
+ self.log.debug("got getdata %s" % repr(message))
+ # Log the requests
+ for inv in message.inv:
+ if inv.hash not in self.blockReqCounts:
+ self.blockReqCounts[inv.hash] = 0
+ self.blockReqCounts[inv.hash] += 1
+
+ def on_close(self, conn):
+ if not self.disconnectOkay:
+ raise EarlyDisconnectError(0)
+
+ def __init__(self):
+ NodeConnCB.__init__(self)
+ self.log = logging.getLogger("BlockRelayTest")
+ self.create_callback_map()
+
+ def add_new_connection(self, connection):
+ self.connection = connection
+ self.blockReqCounts = {}
+ self.disconnectOkay = False
+
+ def run(self):
+ try:
+ fail = False
+ self.connection.rpc.generate(1) # Leave IBD
+
+ numBlocksToGenerate = [ 8, 16, 128, 1024 ]
+ for count in range(len(numBlocksToGenerate)):
+ current_invs = []
+ for i in range(numBlocksToGenerate[count]):
+ current_invs.append(CInv(2, random.randrange(0, 1<<256)))
+ if len(current_invs) >= 50000:
+ self.connection.send_message(msg_inv(current_invs))
+ current_invs = []
+ if len(current_invs) > 0:
+ self.connection.send_message(msg_inv(current_invs))
+
+ # Wait and see how many blocks were requested
+ time.sleep(2)
+
+ total_requests = 0
+ with mininode_lock:
+ for key in self.blockReqCounts:
+ total_requests += self.blockReqCounts[key]
+ if self.blockReqCounts[key] > 1:
+ raise AssertionError("Error, test failed: block %064x requested more than once" % key)
+ if total_requests > MAX_REQUESTS:
+ raise AssertionError("Error, too many blocks (%d) requested" % total_requests)
+ print "Round %d: success (total requests: %d)" % (count, total_requests)
+ except AssertionError as e:
+ print "TEST FAILED: ", e.args
+
+ self.disconnectOkay = True
+ self.connection.disconnect_node()
+
+
+class MaxBlocksInFlightTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ parser.add_option("--testbinary", dest="testbinary",
+ default=os.getenv("BITCOIND", "bitcoind"),
+ help="Binary to test max block requests behavior")
+
+ def setup_chain(self):
+ print "Initializing test directory "+self.options.tmpdir
+ initialize_chain_clean(self.options.tmpdir, 1)
+
+ def setup_network(self):
+ self.nodes = start_nodes(1, self.options.tmpdir,
+ extra_args=[['-debug', '-whitelist=127.0.0.1']],
+ binary=[self.options.testbinary])
+
+ def run_test(self):
+ test = TestManager()
+ test.add_new_connection(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test))
+ NetworkThread().start() # Start up network handling in another thread
+ test.run()
+
+if __name__ == '__main__':
+ MaxBlocksInFlightTest().main()
diff --git a/qa/rpc-tests/mempool_coinbase_spends.py b/qa/rpc-tests/mempool_coinbase_spends.py
new file mode 100755
index 0000000000..c64a15b9f5
--- /dev/null
+++ b/qa/rpc-tests/mempool_coinbase_spends.py
@@ -0,0 +1,93 @@
+#!/usr/bin/env python2
+# Copyright (c) 2014 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#
+# Test re-org scenarios with a mempool that contains transactions
+# that spend (directly or indirectly) coinbase transactions.
+#
+
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import *
+import os
+import shutil
+
+# Create one-input, one-output, no-fee transaction:
+class MempoolCoinbaseTest(BitcoinTestFramework):
+
+ alert_filename = None # Set by setup_network
+
+ def setup_network(self):
+ args = ["-checkmempool", "-debug=mempool"]
+ self.nodes = []
+ self.nodes.append(start_node(0, self.options.tmpdir, args))
+ self.nodes.append(start_node(1, self.options.tmpdir, args))
+ connect_nodes(self.nodes[1], 0)
+ self.is_network_split = False
+ self.sync_all
+
+ def create_tx(self, from_txid, to_address, amount):
+ inputs = [{ "txid" : from_txid, "vout" : 0}]
+ outputs = { to_address : amount }
+ rawtx = self.nodes[0].createrawtransaction(inputs, outputs)
+ signresult = self.nodes[0].signrawtransaction(rawtx)
+ assert_equal(signresult["complete"], True)
+ return signresult["hex"]
+
+ def run_test(self):
+ start_count = self.nodes[0].getblockcount()
+
+ # Mine three blocks. After this, nodes[0] blocks
+ # 101, 102, and 103 are spend-able.
+ new_blocks = self.nodes[1].generate(4)
+ self.sync_all()
+
+ node0_address = self.nodes[0].getnewaddress()
+ node1_address = self.nodes[1].getnewaddress()
+
+ # Three scenarios for re-orging coinbase spends in the memory pool:
+ # 1. Direct coinbase spend : spend_101
+ # 2. Indirect (coinbase spend in chain, child in mempool) : spend_102 and spend_102_1
+ # 3. Indirect (coinbase and child both in chain) : spend_103 and spend_103_1
+ # Use invalidatblock to make all of the above coinbase spends invalid (immature coinbase),
+ # and make sure the mempool code behaves correctly.
+ b = [ self.nodes[0].getblockhash(n) for n in range(102, 105) ]
+ coinbase_txids = [ self.nodes[0].getblock(h)['tx'][0] for h in b ]
+ spend_101_raw = self.create_tx(coinbase_txids[0], node1_address, 50)
+ spend_102_raw = self.create_tx(coinbase_txids[1], node0_address, 50)
+ spend_103_raw = self.create_tx(coinbase_txids[2], node0_address, 50)
+
+ # Broadcast and mine spend_102 and 103:
+ spend_102_id = self.nodes[0].sendrawtransaction(spend_102_raw)
+ spend_103_id = self.nodes[0].sendrawtransaction(spend_103_raw)
+ self.nodes[0].generate(1)
+
+ # Create 102_1 and 103_1:
+ spend_102_1_raw = self.create_tx(spend_102_id, node1_address, 50)
+ spend_103_1_raw = self.create_tx(spend_103_id, node1_address, 50)
+
+ # Broadcast and mine 103_1:
+ spend_103_1_id = self.nodes[0].sendrawtransaction(spend_103_1_raw)
+ self.nodes[0].generate(1)
+
+ # ... now put spend_101 and spend_102_1 in memory pools:
+ spend_101_id = self.nodes[0].sendrawtransaction(spend_101_raw)
+ spend_102_1_id = self.nodes[0].sendrawtransaction(spend_102_1_raw)
+
+ self.sync_all()
+
+ assert_equal(set(self.nodes[0].getrawmempool()), set([ spend_101_id, spend_102_1_id ]))
+
+ # Use invalidateblock to re-org back and make all those coinbase spends
+ # immature/invalid:
+ for node in self.nodes:
+ node.invalidateblock(new_blocks[0])
+
+ self.sync_all()
+
+ # mempool should be empty.
+ assert_equal(set(self.nodes[0].getrawmempool()), set())
+
+if __name__ == '__main__':
+ MempoolCoinbaseTest().main()
diff --git a/qa/rpc-tests/mempool_resurrect_test.py b/qa/rpc-tests/mempool_resurrect_test.py
new file mode 100755
index 0000000000..19c74bb751
--- /dev/null
+++ b/qa/rpc-tests/mempool_resurrect_test.py
@@ -0,0 +1,86 @@
+#!/usr/bin/env python2
+# Copyright (c) 2014 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#
+# Test resurrection of mined transactions when
+# the blockchain is re-organized.
+#
+
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import *
+import os
+import shutil
+
+# Create one-input, one-output, no-fee transaction:
+class MempoolCoinbaseTest(BitcoinTestFramework):
+
+ def setup_network(self):
+ # Just need one node for this test
+ args = ["-checkmempool", "-debug=mempool"]
+ self.nodes = []
+ self.nodes.append(start_node(0, self.options.tmpdir, args))
+ self.is_network_split = False
+
+ def create_tx(self, from_txid, to_address, amount):
+ inputs = [{ "txid" : from_txid, "vout" : 0}]
+ outputs = { to_address : amount }
+ rawtx = self.nodes[0].createrawtransaction(inputs, outputs)
+ signresult = self.nodes[0].signrawtransaction(rawtx)
+ assert_equal(signresult["complete"], True)
+ return signresult["hex"]
+
+ def run_test(self):
+ node0_address = self.nodes[0].getnewaddress()
+ # Spend block 1/2/3's coinbase transactions
+ # Mine a block.
+ # Create three more transactions, spending the spends
+ # Mine another block.
+ # ... make sure all the transactions are confirmed
+ # Invalidate both blocks
+ # ... make sure all the transactions are put back in the mempool
+ # Mine a new block
+ # ... make sure all the transactions are confirmed again.
+
+ b = [ self.nodes[0].getblockhash(n) for n in range(1, 4) ]
+ coinbase_txids = [ self.nodes[0].getblock(h)['tx'][0] for h in b ]
+ spends1_raw = [ self.create_tx(txid, node0_address, 50) for txid in coinbase_txids ]
+ spends1_id = [ self.nodes[0].sendrawtransaction(tx) for tx in spends1_raw ]
+
+ blocks = []
+ blocks.extend(self.nodes[0].generate(1))
+
+ spends2_raw = [ self.create_tx(txid, node0_address, 49.99) for txid in spends1_id ]
+ spends2_id = [ self.nodes[0].sendrawtransaction(tx) for tx in spends2_raw ]
+
+ blocks.extend(self.nodes[0].generate(1))
+
+ # mempool should be empty, all txns confirmed
+ assert_equal(set(self.nodes[0].getrawmempool()), set())
+ for txid in spends1_id+spends2_id:
+ tx = self.nodes[0].gettransaction(txid)
+ assert(tx["confirmations"] > 0)
+
+ # Use invalidateblock to re-org back; all transactions should
+ # end up unconfirmed and back in the mempool
+ for node in self.nodes:
+ node.invalidateblock(blocks[0])
+
+ # mempool should be empty, all txns confirmed
+ assert_equal(set(self.nodes[0].getrawmempool()), set(spends1_id+spends2_id))
+ for txid in spends1_id+spends2_id:
+ tx = self.nodes[0].gettransaction(txid)
+ assert(tx["confirmations"] == 0)
+
+ # Generate another block, they should all get mined
+ self.nodes[0].generate(1)
+ # mempool should be empty, all txns confirmed
+ assert_equal(set(self.nodes[0].getrawmempool()), set())
+ for txid in spends1_id+spends2_id:
+ tx = self.nodes[0].gettransaction(txid)
+ assert(tx["confirmations"] > 0)
+
+
+if __name__ == '__main__':
+ MempoolCoinbaseTest().main()
diff --git a/qa/rpc-tests/mempool_spendcoinbase.py b/qa/rpc-tests/mempool_spendcoinbase.py
new file mode 100755
index 0000000000..fc17c50692
--- /dev/null
+++ b/qa/rpc-tests/mempool_spendcoinbase.py
@@ -0,0 +1,68 @@
+#!/usr/bin/env python2
+# Copyright (c) 2014 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#
+# Test spending coinbase transactions.
+# The coinbase transaction in block N can appear in block
+# N+100... so is valid in the mempool when the best block
+# height is N+99.
+# This test makes sure coinbase spends that will be mature
+# in the next block are accepted into the memory pool,
+# but less mature coinbase spends are NOT.
+#
+
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import *
+import os
+import shutil
+
+# Create one-input, one-output, no-fee transaction:
+class MempoolSpendCoinbaseTest(BitcoinTestFramework):
+
+ def setup_network(self):
+ # Just need one node for this test
+ args = ["-checkmempool", "-debug=mempool"]
+ self.nodes = []
+ self.nodes.append(start_node(0, self.options.tmpdir, args))
+ self.is_network_split = False
+
+ def create_tx(self, from_txid, to_address, amount):
+ inputs = [{ "txid" : from_txid, "vout" : 0}]
+ outputs = { to_address : amount }
+ rawtx = self.nodes[0].createrawtransaction(inputs, outputs)
+ signresult = self.nodes[0].signrawtransaction(rawtx)
+ assert_equal(signresult["complete"], True)
+ return signresult["hex"]
+
+ def run_test(self):
+ chain_height = self.nodes[0].getblockcount()
+ assert_equal(chain_height, 200)
+ node0_address = self.nodes[0].getnewaddress()
+
+ # Coinbase at height chain_height-100+1 ok in mempool, should
+ # get mined. Coinbase at height chain_height-100+2 is
+ # is too immature to spend.
+ b = [ self.nodes[0].getblockhash(n) for n in range(101, 103) ]
+ coinbase_txids = [ self.nodes[0].getblock(h)['tx'][0] for h in b ]
+ spends_raw = [ self.create_tx(txid, node0_address, 50) for txid in coinbase_txids ]
+
+ spend_101_id = self.nodes[0].sendrawtransaction(spends_raw[0])
+
+ # coinbase at height 102 should be too immature to spend
+ assert_raises(JSONRPCException, self.nodes[0].sendrawtransaction, spends_raw[1])
+
+ # mempool should have just spend_101:
+ assert_equal(self.nodes[0].getrawmempool(), [ spend_101_id ])
+
+ # mine a block, spend_101 should get confirmed
+ self.nodes[0].generate(1)
+ assert_equal(set(self.nodes[0].getrawmempool()), set())
+
+ # ... and now height 102 can be spent:
+ spend_102_id = self.nodes[0].sendrawtransaction(spends_raw[1])
+ assert_equal(self.nodes[0].getrawmempool(), [ spend_102_id ])
+
+if __name__ == '__main__':
+ MempoolSpendCoinbaseTest().main()
diff --git a/qa/rpc-tests/merkle_blocks.py b/qa/rpc-tests/merkle_blocks.py
new file mode 100755
index 0000000000..72a80ce6ca
--- /dev/null
+++ b/qa/rpc-tests/merkle_blocks.py
@@ -0,0 +1,89 @@
+#!/usr/bin/env python2
+# Copyright (c) 2014 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#
+# Test merkleblock fetch/validation
+#
+
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import *
+import os
+import shutil
+
+class MerkleBlockTest(BitcoinTestFramework):
+
+ def setup_chain(self):
+ print("Initializing test directory "+self.options.tmpdir)
+ initialize_chain_clean(self.options.tmpdir, 4)
+
+ def setup_network(self):
+ self.nodes = []
+ # Nodes 0/1 are "wallet" nodes
+ self.nodes.append(start_node(0, self.options.tmpdir, ["-debug"]))
+ self.nodes.append(start_node(1, self.options.tmpdir, ["-debug"]))
+ # Nodes 2/3 are used for testing
+ self.nodes.append(start_node(2, self.options.tmpdir, ["-debug"]))
+ self.nodes.append(start_node(3, self.options.tmpdir, ["-debug", "-txindex"]))
+ connect_nodes(self.nodes[0], 1)
+ connect_nodes(self.nodes[0], 2)
+ connect_nodes(self.nodes[0], 3)
+
+ self.is_network_split = False
+ self.sync_all()
+
+ def run_test(self):
+ print "Mining blocks..."
+ self.nodes[0].generate(105)
+ self.sync_all()
+
+ chain_height = self.nodes[1].getblockcount()
+ assert_equal(chain_height, 105)
+ assert_equal(self.nodes[1].getbalance(), 0)
+ assert_equal(self.nodes[2].getbalance(), 0)
+
+ node0utxos = self.nodes[0].listunspent(1)
+ tx1 = self.nodes[0].createrawtransaction([node0utxos.pop()], {self.nodes[1].getnewaddress(): 50})
+ txid1 = self.nodes[0].sendrawtransaction(self.nodes[0].signrawtransaction(tx1)["hex"])
+ tx2 = self.nodes[0].createrawtransaction([node0utxos.pop()], {self.nodes[1].getnewaddress(): 50})
+ txid2 = self.nodes[0].sendrawtransaction(self.nodes[0].signrawtransaction(tx2)["hex"])
+ assert_raises(JSONRPCException, self.nodes[0].gettxoutproof, [txid1])
+
+ self.nodes[0].generate(1)
+ blockhash = self.nodes[0].getblockhash(chain_height + 1)
+ self.sync_all()
+
+ txlist = []
+ blocktxn = self.nodes[0].getblock(blockhash, True)["tx"]
+ txlist.append(blocktxn[1])
+ txlist.append(blocktxn[2])
+
+ assert_equal(self.nodes[2].verifytxoutproof(self.nodes[2].gettxoutproof([txid1])), [txid1])
+ assert_equal(self.nodes[2].verifytxoutproof(self.nodes[2].gettxoutproof([txid1, txid2])), txlist)
+ assert_equal(self.nodes[2].verifytxoutproof(self.nodes[2].gettxoutproof([txid1, txid2], blockhash)), txlist)
+
+ txin_spent = self.nodes[1].listunspent(1).pop()
+ tx3 = self.nodes[1].createrawtransaction([txin_spent], {self.nodes[0].getnewaddress(): 50})
+ self.nodes[0].sendrawtransaction(self.nodes[1].signrawtransaction(tx3)["hex"])
+ self.nodes[0].generate(1)
+ self.sync_all()
+
+ txid_spent = txin_spent["txid"]
+ txid_unspent = txid1 if txin_spent["txid"] != txid1 else txid2
+
+ # We cant find the block from a fully-spent tx
+ assert_raises(JSONRPCException, self.nodes[2].gettxoutproof, [txid_spent])
+ # ...but we can if we specify the block
+ assert_equal(self.nodes[2].verifytxoutproof(self.nodes[2].gettxoutproof([txid_spent], blockhash)), [txid_spent])
+ # ...or if the first tx is not fully-spent
+ assert_equal(self.nodes[2].verifytxoutproof(self.nodes[2].gettxoutproof([txid_unspent])), [txid_unspent])
+ try:
+ assert_equal(self.nodes[2].verifytxoutproof(self.nodes[2].gettxoutproof([txid1, txid2])), txlist)
+ except JSONRPCException:
+ assert_equal(self.nodes[2].verifytxoutproof(self.nodes[2].gettxoutproof([txid2, txid1])), txlist)
+ # ...or if we have a -txindex
+ assert_equal(self.nodes[2].verifytxoutproof(self.nodes[3].gettxoutproof([txid_spent])), [txid_spent])
+
+if __name__ == '__main__':
+ MerkleBlockTest().main()
diff --git a/qa/rpc-tests/p2p-acceptblock.py b/qa/rpc-tests/p2p-acceptblock.py
new file mode 100755
index 0000000000..83c03eeb78
--- /dev/null
+++ b/qa/rpc-tests/p2p-acceptblock.py
@@ -0,0 +1,291 @@
+#!/usr/bin/env python2
+#
+# Distributed under the MIT/X11 software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#
+
+from test_framework.mininode import *
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import *
+import time
+from test_framework.blocktools import create_block, create_coinbase
+
+'''
+AcceptBlockTest -- test processing of unrequested blocks.
+
+Since behavior differs when receiving unrequested blocks from whitelisted peers
+versus non-whitelisted peers, this tests the behavior of both (effectively two
+separate tests running in parallel).
+
+Setup: two nodes, node0 and node1, not connected to each other. Node0 does not
+whitelist localhost, but node1 does. They will each be on their own chain for
+this test.
+
+We have one NodeConn connection to each, test_node and white_node respectively.
+
+The test:
+1. Generate one block on each node, to leave IBD.
+
+2. Mine a new block on each tip, and deliver to each node from node's peer.
+ The tip should advance.
+
+3. Mine a block that forks the previous block, and deliver to each node from
+ corresponding peer.
+ Node0 should not process this block (just accept the header), because it is
+ unrequested and doesn't have more work than the tip.
+ Node1 should process because this is coming from a whitelisted peer.
+
+4. Send another block that builds on the forking block.
+ Node0 should process this block but be stuck on the shorter chain, because
+ it's missing an intermediate block.
+ Node1 should reorg to this longer chain.
+
+4b.Send 288 more blocks on the longer chain.
+ Node0 should process all but the last block (too far ahead in height).
+ Send all headers to Node1, and then send the last block in that chain.
+ Node1 should accept the block because it's coming from a whitelisted peer.
+
+5. Send a duplicate of the block in #3 to Node0.
+ Node0 should not process the block because it is unrequested, and stay on
+ the shorter chain.
+
+6. Send Node0 an inv for the height 3 block produced in #4 above.
+ Node0 should figure out that Node0 has the missing height 2 block and send a
+ getdata.
+
+7. Send Node0 the missing block again.
+ Node0 should process and the tip should advance.
+'''
+
+# TestNode: bare-bones "peer". Used mostly as a conduit for a test to sending
+# p2p messages to a node, generating the messages in the main testing logic.
+class TestNode(NodeConnCB):
+ def __init__(self):
+ NodeConnCB.__init__(self)
+ self.create_callback_map()
+ self.connection = None
+ self.ping_counter = 1
+ self.last_pong = msg_pong()
+
+ def add_connection(self, conn):
+ self.connection = conn
+
+ # Track the last getdata message we receive (used in the test)
+ def on_getdata(self, conn, message):
+ self.last_getdata = message
+
+ # Spin until verack message is received from the node.
+ # We use this to signal that our test can begin. This
+ # is called from the testing thread, so it needs to acquire
+ # the global lock.
+ def wait_for_verack(self):
+ while True:
+ with mininode_lock:
+ if self.verack_received:
+ return
+ time.sleep(0.05)
+
+ # Wrapper for the NodeConn's send_message function
+ def send_message(self, message):
+ self.connection.send_message(message)
+
+ def on_pong(self, conn, message):
+ self.last_pong = message
+
+ # Sync up with the node after delivery of a block
+ def sync_with_ping(self, timeout=30):
+ self.connection.send_message(msg_ping(nonce=self.ping_counter))
+ received_pong = False
+ sleep_time = 0.05
+ while not received_pong and timeout > 0:
+ time.sleep(sleep_time)
+ timeout -= sleep_time
+ with mininode_lock:
+ if self.last_pong.nonce == self.ping_counter:
+ received_pong = True
+ self.ping_counter += 1
+ return received_pong
+
+
+class AcceptBlockTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ parser.add_option("--testbinary", dest="testbinary",
+ default=os.getenv("BITCOIND", "bitcoind"),
+ help="bitcoind binary to test")
+
+ def setup_chain(self):
+ initialize_chain_clean(self.options.tmpdir, 2)
+
+ def setup_network(self):
+ # Node0 will be used to test behavior of processing unrequested blocks
+ # from peers which are not whitelisted, while Node1 will be used for
+ # the whitelisted case.
+ self.nodes = []
+ self.nodes.append(start_node(0, self.options.tmpdir, ["-debug"],
+ binary=self.options.testbinary))
+ self.nodes.append(start_node(1, self.options.tmpdir,
+ ["-debug", "-whitelist=127.0.0.1"],
+ binary=self.options.testbinary))
+
+ def run_test(self):
+ # Setup the p2p connections and start up the network thread.
+ test_node = TestNode() # connects to node0 (not whitelisted)
+ white_node = TestNode() # connects to node1 (whitelisted)
+
+ connections = []
+ connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test_node))
+ connections.append(NodeConn('127.0.0.1', p2p_port(1), self.nodes[1], white_node))
+ test_node.add_connection(connections[0])
+ white_node.add_connection(connections[1])
+
+ NetworkThread().start() # Start up network handling in another thread
+
+ # Test logic begins here
+ test_node.wait_for_verack()
+ white_node.wait_for_verack()
+
+ # 1. Have both nodes mine a block (leave IBD)
+ [ n.generate(1) for n in self.nodes ]
+ tips = [ int ("0x" + n.getbestblockhash() + "L", 0) for n in self.nodes ]
+
+ # 2. Send one block that builds on each tip.
+ # This should be accepted.
+ blocks_h2 = [] # the height 2 blocks on each node's chain
+ block_time = time.time() + 1
+ for i in xrange(2):
+ blocks_h2.append(create_block(tips[i], create_coinbase(), block_time))
+ blocks_h2[i].solve()
+ block_time += 1
+ test_node.send_message(msg_block(blocks_h2[0]))
+ white_node.send_message(msg_block(blocks_h2[1]))
+
+ [ x.sync_with_ping() for x in [test_node, white_node] ]
+ assert_equal(self.nodes[0].getblockcount(), 2)
+ assert_equal(self.nodes[1].getblockcount(), 2)
+ print "First height 2 block accepted by both nodes"
+
+ # 3. Send another block that builds on the original tip.
+ blocks_h2f = [] # Blocks at height 2 that fork off the main chain
+ for i in xrange(2):
+ blocks_h2f.append(create_block(tips[i], create_coinbase(), blocks_h2[i].nTime+1))
+ blocks_h2f[i].solve()
+ test_node.send_message(msg_block(blocks_h2f[0]))
+ white_node.send_message(msg_block(blocks_h2f[1]))
+
+ [ x.sync_with_ping() for x in [test_node, white_node] ]
+ for x in self.nodes[0].getchaintips():
+ if x['hash'] == blocks_h2f[0].hash:
+ assert_equal(x['status'], "headers-only")
+
+ for x in self.nodes[1].getchaintips():
+ if x['hash'] == blocks_h2f[1].hash:
+ assert_equal(x['status'], "valid-headers")
+
+ print "Second height 2 block accepted only from whitelisted peer"
+
+ # 4. Now send another block that builds on the forking chain.
+ blocks_h3 = []
+ for i in xrange(2):
+ blocks_h3.append(create_block(blocks_h2f[i].sha256, create_coinbase(), blocks_h2f[i].nTime+1))
+ blocks_h3[i].solve()
+ test_node.send_message(msg_block(blocks_h3[0]))
+ white_node.send_message(msg_block(blocks_h3[1]))
+
+ [ x.sync_with_ping() for x in [test_node, white_node] ]
+ # Since the earlier block was not processed by node0, the new block
+ # can't be fully validated.
+ for x in self.nodes[0].getchaintips():
+ if x['hash'] == blocks_h3[0].hash:
+ assert_equal(x['status'], "headers-only")
+
+ # But this block should be accepted by node0 since it has more work.
+ try:
+ self.nodes[0].getblock(blocks_h3[0].hash)
+ print "Unrequested more-work block accepted from non-whitelisted peer"
+ except:
+ raise AssertionError("Unrequested more work block was not processed")
+
+ # Node1 should have accepted and reorged.
+ assert_equal(self.nodes[1].getblockcount(), 3)
+ print "Successfully reorged to length 3 chain from whitelisted peer"
+
+ # 4b. Now mine 288 more blocks and deliver; all should be processed but
+ # the last (height-too-high) on node0. Node1 should process the tip if
+ # we give it the headers chain leading to the tip.
+ tips = blocks_h3
+ headers_message = msg_headers()
+ all_blocks = [] # node0's blocks
+ for j in xrange(2):
+ for i in xrange(288):
+ next_block = create_block(tips[j].sha256, create_coinbase(), tips[j].nTime+1)
+ next_block.solve()
+ if j==0:
+ test_node.send_message(msg_block(next_block))
+ all_blocks.append(next_block)
+ else:
+ headers_message.headers.append(CBlockHeader(next_block))
+ tips[j] = next_block
+
+ time.sleep(2)
+ for x in all_blocks:
+ try:
+ self.nodes[0].getblock(x.hash)
+ if x == all_blocks[287]:
+ raise AssertionError("Unrequested block too far-ahead should have been ignored")
+ except:
+ if x == all_blocks[287]:
+ print "Unrequested block too far-ahead not processed"
+ else:
+ raise AssertionError("Unrequested block with more work should have been accepted")
+
+ headers_message.headers.pop() # Ensure the last block is unrequested
+ white_node.send_message(headers_message) # Send headers leading to tip
+ white_node.send_message(msg_block(tips[1])) # Now deliver the tip
+ try:
+ white_node.sync_with_ping()
+ self.nodes[1].getblock(tips[1].hash)
+ print "Unrequested block far ahead of tip accepted from whitelisted peer"
+ except:
+ raise AssertionError("Unrequested block from whitelisted peer not accepted")
+
+ # 5. Test handling of unrequested block on the node that didn't process
+ # Should still not be processed (even though it has a child that has more
+ # work).
+ test_node.send_message(msg_block(blocks_h2f[0]))
+
+ # Here, if the sleep is too short, the test could falsely succeed (if the
+ # node hasn't processed the block by the time the sleep returns, and then
+ # the node processes it and incorrectly advances the tip).
+ # But this would be caught later on, when we verify that an inv triggers
+ # a getdata request for this block.
+ test_node.sync_with_ping()
+ assert_equal(self.nodes[0].getblockcount(), 2)
+ print "Unrequested block that would complete more-work chain was ignored"
+
+ # 6. Try to get node to request the missing block.
+ # Poke the node with an inv for block at height 3 and see if that
+ # triggers a getdata on block 2 (it should if block 2 is missing).
+ with mininode_lock:
+ # Clear state so we can check the getdata request
+ test_node.last_getdata = None
+ test_node.send_message(msg_inv([CInv(2, blocks_h3[0].sha256)]))
+
+ test_node.sync_with_ping()
+ with mininode_lock:
+ getdata = test_node.last_getdata
+
+ # Check that the getdata includes the right block
+ assert_equal(getdata.inv[0].hash, blocks_h2f[0].sha256)
+ print "Inv at tip triggered getdata for unprocessed block"
+
+ # 7. Send the missing block for the third time (now it is requested)
+ test_node.send_message(msg_block(blocks_h2f[0]))
+
+ test_node.sync_with_ping()
+ assert_equal(self.nodes[0].getblockcount(), 290)
+ print "Successfully reorged to longer chain from non-whitelisted peer"
+
+ [ c.disconnect_node() for c in connections ]
+
+if __name__ == '__main__':
+ AcceptBlockTest().main()
diff --git a/qa/rpc-tests/proxy_test.py b/qa/rpc-tests/proxy_test.py
new file mode 100755
index 0000000000..9a9b2f5300
--- /dev/null
+++ b/qa/rpc-tests/proxy_test.py
@@ -0,0 +1,146 @@
+#!/usr/bin/env python2
+# Copyright (c) 2015 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+import socket
+import traceback, sys
+from binascii import hexlify
+import time, os
+
+from test_framework.socks5 import Socks5Configuration, Socks5Command, Socks5Server, AddressType
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import *
+'''
+Test plan:
+- Start bitcoind's with different proxy configurations
+- Use addnode to initiate connections
+- Verify that proxies are connected to, and the right connection command is given
+- Proxy configurations to test on bitcoind side:
+ - `-proxy` (proxy everything)
+ - `-onion` (proxy just onions)
+ - `-proxyrandomize` Circuit randomization
+- Proxy configurations to test on proxy side,
+ - support no authentication (other proxy)
+ - support no authentication + user/pass authentication (Tor)
+ - proxy on IPv6
+
+- Create various proxies (as threads)
+- Create bitcoinds that connect to them
+- Manipulate the bitcoinds using addnode (onetry) an observe effects
+
+addnode connect to IPv4
+addnode connect to IPv6
+addnode connect to onion
+addnode connect to generic DNS name
+'''
+
+class ProxyTest(BitcoinTestFramework):
+ def __init__(self):
+ # Create two proxies on different ports
+ # ... one unauthenticated
+ self.conf1 = Socks5Configuration()
+ self.conf1.addr = ('127.0.0.1', 13000 + (os.getpid() % 1000))
+ self.conf1.unauth = True
+ self.conf1.auth = False
+ # ... one supporting authenticated and unauthenticated (Tor)
+ self.conf2 = Socks5Configuration()
+ self.conf2.addr = ('127.0.0.1', 14000 + (os.getpid() % 1000))
+ self.conf2.unauth = True
+ self.conf2.auth = True
+ # ... one on IPv6 with similar configuration
+ self.conf3 = Socks5Configuration()
+ self.conf3.af = socket.AF_INET6
+ self.conf3.addr = ('::1', 15000 + (os.getpid() % 1000))
+ self.conf3.unauth = True
+ self.conf3.auth = True
+
+ self.serv1 = Socks5Server(self.conf1)
+ self.serv1.start()
+ self.serv2 = Socks5Server(self.conf2)
+ self.serv2.start()
+ self.serv3 = Socks5Server(self.conf3)
+ self.serv3.start()
+
+ def setup_nodes(self):
+ # Note: proxies are not used to connect to local nodes
+ # this is because the proxy to use is based on CService.GetNetwork(), which return NET_UNROUTABLE for localhost
+ return start_nodes(4, self.options.tmpdir, extra_args=[
+ ['-listen', '-debug=net', '-debug=proxy', '-proxy=%s:%i' % (self.conf1.addr),'-proxyrandomize=1'],
+ ['-listen', '-debug=net', '-debug=proxy', '-proxy=%s:%i' % (self.conf1.addr),'-onion=%s:%i' % (self.conf2.addr),'-proxyrandomize=0'],
+ ['-listen', '-debug=net', '-debug=proxy', '-proxy=%s:%i' % (self.conf2.addr),'-proxyrandomize=1'],
+ ['-listen', '-debug=net', '-debug=proxy', '-proxy=[%s]:%i' % (self.conf3.addr),'-proxyrandomize=0']
+ ])
+
+ def node_test(self, node, proxies, auth):
+ rv = []
+ # Test: outgoing IPv4 connection through node
+ node.addnode("15.61.23.23:1234", "onetry")
+ cmd = proxies[0].queue.get()
+ assert(isinstance(cmd, Socks5Command))
+ # Note: bitcoind's SOCKS5 implementation only sends atyp DOMAINNAME, even if connecting directly to IPv4/IPv6
+ assert_equal(cmd.atyp, AddressType.DOMAINNAME)
+ assert_equal(cmd.addr, "15.61.23.23")
+ assert_equal(cmd.port, 1234)
+ if not auth:
+ assert_equal(cmd.username, None)
+ assert_equal(cmd.password, None)
+ rv.append(cmd)
+
+ # Test: outgoing IPv6 connection through node
+ node.addnode("[1233:3432:2434:2343:3234:2345:6546:4534]:5443", "onetry")
+ cmd = proxies[1].queue.get()
+ assert(isinstance(cmd, Socks5Command))
+ # Note: bitcoind's SOCKS5 implementation only sends atyp DOMAINNAME, even if connecting directly to IPv4/IPv6
+ assert_equal(cmd.atyp, AddressType.DOMAINNAME)
+ assert_equal(cmd.addr, "1233:3432:2434:2343:3234:2345:6546:4534")
+ assert_equal(cmd.port, 5443)
+ if not auth:
+ assert_equal(cmd.username, None)
+ assert_equal(cmd.password, None)
+ rv.append(cmd)
+
+ # Test: outgoing onion connection through node
+ node.addnode("bitcoinostk4e4re.onion:8333", "onetry")
+ cmd = proxies[2].queue.get()
+ assert(isinstance(cmd, Socks5Command))
+ assert_equal(cmd.atyp, AddressType.DOMAINNAME)
+ assert_equal(cmd.addr, "bitcoinostk4e4re.onion")
+ assert_equal(cmd.port, 8333)
+ if not auth:
+ assert_equal(cmd.username, None)
+ assert_equal(cmd.password, None)
+ rv.append(cmd)
+
+ # Test: outgoing DNS name connection through node
+ node.addnode("node.noumenon:8333", "onetry")
+ cmd = proxies[3].queue.get()
+ assert(isinstance(cmd, Socks5Command))
+ assert_equal(cmd.atyp, AddressType.DOMAINNAME)
+ assert_equal(cmd.addr, "node.noumenon")
+ assert_equal(cmd.port, 8333)
+ if not auth:
+ assert_equal(cmd.username, None)
+ assert_equal(cmd.password, None)
+ rv.append(cmd)
+
+ return rv
+
+ def run_test(self):
+ # basic -proxy
+ self.node_test(self.nodes[0], [self.serv1, self.serv1, self.serv1, self.serv1], False)
+
+ # -proxy plus -onion
+ self.node_test(self.nodes[1], [self.serv1, self.serv1, self.serv2, self.serv1], False)
+
+ # -proxy plus -onion, -proxyrandomize
+ rv = self.node_test(self.nodes[2], [self.serv2, self.serv2, self.serv2, self.serv2], True)
+ # Check that credentials as used for -proxyrandomize connections are unique
+ credentials = set((x.username,x.password) for x in rv)
+ assert_equal(len(credentials), 4)
+
+ # proxy on IPv6 localhost
+ self.node_test(self.nodes[3], [self.serv3, self.serv3, self.serv3, self.serv3], False)
+
+if __name__ == '__main__':
+ ProxyTest().main()
+
diff --git a/qa/rpc-tests/pruning.py b/qa/rpc-tests/pruning.py
new file mode 100755
index 0000000000..21f8d69382
--- /dev/null
+++ b/qa/rpc-tests/pruning.py
@@ -0,0 +1,359 @@
+#!/usr/bin/env python2
+# Copyright (c) 2014 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#
+# Test pruning code
+# ********
+# WARNING:
+# This test uses 4GB of disk space.
+# This test takes 30 mins or more (up to 2 hours)
+# ********
+
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import *
+import os.path
+
+def calc_usage(blockdir):
+ return sum(os.path.getsize(blockdir+f) for f in os.listdir(blockdir) if os.path.isfile(blockdir+f))/(1024*1024)
+
+class PruneTest(BitcoinTestFramework):
+
+ def __init__(self):
+ self.utxo = []
+ self.address = ["",""]
+
+ # Some pre-processing to create a bunch of OP_RETURN txouts to insert into transactions we create
+ # So we have big transactions and full blocks to fill up our block files
+
+ # create one script_pubkey
+ script_pubkey = "6a4d0200" #OP_RETURN OP_PUSH2 512 bytes
+ for i in xrange (512):
+ script_pubkey = script_pubkey + "01"
+ # concatenate 128 txouts of above script_pubkey which we'll insert before the txout for change
+ self.txouts = "81"
+ for k in xrange(128):
+ # add txout value
+ self.txouts = self.txouts + "0000000000000000"
+ # add length of script_pubkey
+ self.txouts = self.txouts + "fd0402"
+ # add script_pubkey
+ self.txouts = self.txouts + script_pubkey
+
+
+ def setup_chain(self):
+ print("Initializing test directory "+self.options.tmpdir)
+ initialize_chain_clean(self.options.tmpdir, 3)
+
+ def setup_network(self):
+ self.nodes = []
+ self.is_network_split = False
+
+ # Create nodes 0 and 1 to mine
+ self.nodes.append(start_node(0, self.options.tmpdir, ["-debug","-maxreceivebuffer=20000","-blockmaxsize=999000", "-checkblocks=5"], timewait=900))
+ self.nodes.append(start_node(1, self.options.tmpdir, ["-debug","-maxreceivebuffer=20000","-blockmaxsize=999000", "-checkblocks=5"], timewait=900))
+
+ # Create node 2 to test pruning
+ self.nodes.append(start_node(2, self.options.tmpdir, ["-debug","-maxreceivebuffer=20000","-prune=550"], timewait=900))
+ self.prunedir = self.options.tmpdir+"/node2/regtest/blocks/"
+
+ self.address[0] = self.nodes[0].getnewaddress()
+ self.address[1] = self.nodes[1].getnewaddress()
+
+ # Determine default relay fee
+ self.relayfee = self.nodes[0].getnetworkinfo()["relayfee"]
+
+ connect_nodes(self.nodes[0], 1)
+ connect_nodes(self.nodes[1], 2)
+ connect_nodes(self.nodes[2], 0)
+ sync_blocks(self.nodes[0:3])
+
+ def create_big_chain(self):
+ # Start by creating some coinbases we can spend later
+ self.nodes[1].generate(200)
+ sync_blocks(self.nodes[0:2])
+ self.nodes[0].generate(150)
+ # Then mine enough full blocks to create more than 550MB of data
+ for i in xrange(645):
+ self.mine_full_block(self.nodes[0], self.address[0])
+
+ sync_blocks(self.nodes[0:3])
+
+ def test_height_min(self):
+ if not os.path.isfile(self.prunedir+"blk00000.dat"):
+ raise AssertionError("blk00000.dat is missing, pruning too early")
+ print "Success"
+ print "Though we're already using more than 550MB, current usage:", calc_usage(self.prunedir)
+ print "Mining 25 more blocks should cause the first block file to be pruned"
+ # Pruning doesn't run until we're allocating another chunk, 20 full blocks past the height cutoff will ensure this
+ for i in xrange(25):
+ self.mine_full_block(self.nodes[0],self.address[0])
+
+ waitstart = time.time()
+ while os.path.isfile(self.prunedir+"blk00000.dat"):
+ time.sleep(0.1)
+ if time.time() - waitstart > 10:
+ raise AssertionError("blk00000.dat not pruned when it should be")
+
+ print "Success"
+ usage = calc_usage(self.prunedir)
+ print "Usage should be below target:", usage
+ if (usage > 550):
+ raise AssertionError("Pruning target not being met")
+
+ def create_chain_with_staleblocks(self):
+ # Create stale blocks in manageable sized chunks
+ print "Mine 24 (stale) blocks on Node 1, followed by 25 (main chain) block reorg from Node 0, for 12 rounds"
+
+ for j in xrange(12):
+ # Disconnect node 0 so it can mine a longer reorg chain without knowing about node 1's soon-to-be-stale chain
+ # Node 2 stays connected, so it hears about the stale blocks and then reorg's when node0 reconnects
+ # Stopping node 0 also clears its mempool, so it doesn't have node1's transactions to accidentally mine
+ stop_node(self.nodes[0],0)
+ self.nodes[0]=start_node(0, self.options.tmpdir, ["-debug","-maxreceivebuffer=20000","-blockmaxsize=999000", "-checkblocks=5"], timewait=900)
+ # Mine 24 blocks in node 1
+ self.utxo = self.nodes[1].listunspent()
+ for i in xrange(24):
+ if j == 0:
+ self.mine_full_block(self.nodes[1],self.address[1])
+ else:
+ self.nodes[1].generate(1) #tx's already in mempool from previous disconnects
+
+ # Reorg back with 25 block chain from node 0
+ self.utxo = self.nodes[0].listunspent()
+ for i in xrange(25):
+ self.mine_full_block(self.nodes[0],self.address[0])
+
+ # Create connections in the order so both nodes can see the reorg at the same time
+ connect_nodes(self.nodes[1], 0)
+ connect_nodes(self.nodes[2], 0)
+ sync_blocks(self.nodes[0:3])
+
+ print "Usage can be over target because of high stale rate:", calc_usage(self.prunedir)
+
+ def reorg_test(self):
+ # Node 1 will mine a 300 block chain starting 287 blocks back from Node 0 and Node 2's tip
+ # This will cause Node 2 to do a reorg requiring 288 blocks of undo data to the reorg_test chain
+ # Reboot node 1 to clear its mempool (hopefully make the invalidate faster)
+ # Lower the block max size so we don't keep mining all our big mempool transactions (from disconnected blocks)
+ stop_node(self.nodes[1],1)
+ self.nodes[1]=start_node(1, self.options.tmpdir, ["-debug","-maxreceivebuffer=20000","-blockmaxsize=5000", "-checkblocks=5", "-disablesafemode"], timewait=900)
+
+ height = self.nodes[1].getblockcount()
+ print "Current block height:", height
+
+ invalidheight = height-287
+ badhash = self.nodes[1].getblockhash(invalidheight)
+ print "Invalidating block at height:",invalidheight,badhash
+ self.nodes[1].invalidateblock(badhash)
+
+ # We've now switched to our previously mined-24 block fork on node 1, but thats not what we want
+ # So invalidate that fork as well, until we're on the same chain as node 0/2 (but at an ancestor 288 blocks ago)
+ mainchainhash = self.nodes[0].getblockhash(invalidheight - 1)
+ curhash = self.nodes[1].getblockhash(invalidheight - 1)
+ while curhash != mainchainhash:
+ self.nodes[1].invalidateblock(curhash)
+ curhash = self.nodes[1].getblockhash(invalidheight - 1)
+
+ assert(self.nodes[1].getblockcount() == invalidheight - 1)
+ print "New best height", self.nodes[1].getblockcount()
+
+ # Reboot node1 to clear those giant tx's from mempool
+ stop_node(self.nodes[1],1)
+ self.nodes[1]=start_node(1, self.options.tmpdir, ["-debug","-maxreceivebuffer=20000","-blockmaxsize=5000", "-checkblocks=5", "-disablesafemode"], timewait=900)
+
+ print "Generating new longer chain of 300 more blocks"
+ self.nodes[1].generate(300)
+
+ print "Reconnect nodes"
+ connect_nodes(self.nodes[0], 1)
+ connect_nodes(self.nodes[2], 1)
+ sync_blocks(self.nodes[0:3])
+
+ print "Verify height on node 2:",self.nodes[2].getblockcount()
+ print "Usage possibly still high bc of stale blocks in block files:", calc_usage(self.prunedir)
+
+ print "Mine 220 more blocks so we have requisite history (some blocks will be big and cause pruning of previous chain)"
+ self.nodes[0].generate(220) #node 0 has many large tx's in its mempool from the disconnects
+ sync_blocks(self.nodes[0:3])
+
+ usage = calc_usage(self.prunedir)
+ print "Usage should be below target:", usage
+ if (usage > 550):
+ raise AssertionError("Pruning target not being met")
+
+ return invalidheight,badhash
+
+ def reorg_back(self):
+ # Verify that a block on the old main chain fork has been pruned away
+ try:
+ self.nodes[2].getblock(self.forkhash)
+ raise AssertionError("Old block wasn't pruned so can't test redownload")
+ except JSONRPCException as e:
+ print "Will need to redownload block",self.forkheight
+
+ # Verify that we have enough history to reorg back to the fork point
+ # Although this is more than 288 blocks, because this chain was written more recently
+ # and only its other 299 small and 220 large block are in the block files after it,
+ # its expected to still be retained
+ self.nodes[2].getblock(self.nodes[2].getblockhash(self.forkheight))
+
+ first_reorg_height = self.nodes[2].getblockcount()
+ curchainhash = self.nodes[2].getblockhash(self.mainchainheight)
+ self.nodes[2].invalidateblock(curchainhash)
+ goalbestheight = self.mainchainheight
+ goalbesthash = self.mainchainhash2
+
+ # As of 0.10 the current block download logic is not able to reorg to the original chain created in
+ # create_chain_with_stale_blocks because it doesn't know of any peer thats on that chain from which to
+ # redownload its missing blocks.
+ # Invalidate the reorg_test chain in node 0 as well, it can successfully switch to the original chain
+ # because it has all the block data.
+ # However it must mine enough blocks to have a more work chain than the reorg_test chain in order
+ # to trigger node 2's block download logic.
+ # At this point node 2 is within 288 blocks of the fork point so it will preserve its ability to reorg
+ if self.nodes[2].getblockcount() < self.mainchainheight:
+ blocks_to_mine = first_reorg_height + 1 - self.mainchainheight
+ print "Rewind node 0 to prev main chain to mine longer chain to trigger redownload. Blocks needed:", blocks_to_mine
+ self.nodes[0].invalidateblock(curchainhash)
+ assert(self.nodes[0].getblockcount() == self.mainchainheight)
+ assert(self.nodes[0].getbestblockhash() == self.mainchainhash2)
+ goalbesthash = self.nodes[0].generate(blocks_to_mine)[-1]
+ goalbestheight = first_reorg_height + 1
+
+ print "Verify node 2 reorged back to the main chain, some blocks of which it had to redownload"
+ waitstart = time.time()
+ while self.nodes[2].getblockcount() < goalbestheight:
+ time.sleep(0.1)
+ if time.time() - waitstart > 900:
+ raise AssertionError("Node 2 didn't reorg to proper height")
+ assert(self.nodes[2].getbestblockhash() == goalbesthash)
+ # Verify we can now have the data for a block previously pruned
+ assert(self.nodes[2].getblock(self.forkhash)["height"] == self.forkheight)
+
+ def mine_full_block(self, node, address):
+ # Want to create a full block
+ # We'll generate a 66k transaction below, and 14 of them is close to the 1MB block limit
+ for j in xrange(14):
+ if len(self.utxo) < 14:
+ self.utxo = node.listunspent()
+ inputs=[]
+ outputs = {}
+ t = self.utxo.pop()
+ inputs.append({ "txid" : t["txid"], "vout" : t["vout"]})
+ remchange = t["amount"] - 100*self.relayfee # Fee must be above min relay rate for 66kb tx
+ outputs[address]=remchange
+ # Create a basic transaction that will send change back to ourself after account for a fee
+ # And then insert the 128 generated transaction outs in the middle rawtx[92] is where the #
+ # of txouts is stored and is the only thing we overwrite from the original transaction
+ rawtx = node.createrawtransaction(inputs, outputs)
+ newtx = rawtx[0:92]
+ newtx = newtx + self.txouts
+ newtx = newtx + rawtx[94:]
+ # Appears to be ever so slightly faster to sign with SIGHASH_NONE
+ signresult = node.signrawtransaction(newtx,None,None,"NONE")
+ txid = node.sendrawtransaction(signresult["hex"], True)
+ # Mine a full sized block which will be these transactions we just created
+ node.generate(1)
+
+
+ def run_test(self):
+ print "Warning! This test requires 4GB of disk space and takes over 30 mins (up to 2 hours)"
+ print "Mining a big blockchain of 995 blocks"
+ self.create_big_chain()
+ # Chain diagram key:
+ # * blocks on main chain
+ # +,&,$,@ blocks on other forks
+ # X invalidated block
+ # N1 Node 1
+ #
+ # Start by mining a simple chain that all nodes have
+ # N0=N1=N2 **...*(995)
+
+ print "Check that we haven't started pruning yet because we're below PruneAfterHeight"
+ self.test_height_min()
+ # Extend this chain past the PruneAfterHeight
+ # N0=N1=N2 **...*(1020)
+
+ print "Check that we'll exceed disk space target if we have a very high stale block rate"
+ self.create_chain_with_staleblocks()
+ # Disconnect N0
+ # And mine a 24 block chain on N1 and a separate 25 block chain on N0
+ # N1=N2 **...*+...+(1044)
+ # N0 **...**...**(1045)
+ #
+ # reconnect nodes causing reorg on N1 and N2
+ # N1=N2 **...*(1020) *...**(1045)
+ # \
+ # +...+(1044)
+ #
+ # repeat this process until you have 12 stale forks hanging off the
+ # main chain on N1 and N2
+ # N0 *************************...***************************(1320)
+ #
+ # N1=N2 **...*(1020) *...**(1045) *.. ..**(1295) *...**(1320)
+ # \ \ \
+ # +...+(1044) &.. $...$(1319)
+
+ # Save some current chain state for later use
+ self.mainchainheight = self.nodes[2].getblockcount() #1320
+ self.mainchainhash2 = self.nodes[2].getblockhash(self.mainchainheight)
+
+ print "Check that we can survive a 288 block reorg still"
+ (self.forkheight,self.forkhash) = self.reorg_test() #(1033, )
+ # Now create a 288 block reorg by mining a longer chain on N1
+ # First disconnect N1
+ # Then invalidate 1033 on main chain and 1032 on fork so height is 1032 on main chain
+ # N1 **...*(1020) **...**(1032)X..
+ # \
+ # ++...+(1031)X..
+ #
+ # Now mine 300 more blocks on N1
+ # N1 **...*(1020) **...**(1032) @@...@(1332)
+ # \ \
+ # \ X...
+ # \ \
+ # ++...+(1031)X.. ..
+ #
+ # Reconnect nodes and mine 220 more blocks on N1
+ # N1 **...*(1020) **...**(1032) @@...@@@(1552)
+ # \ \
+ # \ X...
+ # \ \
+ # ++...+(1031)X.. ..
+ #
+ # N2 **...*(1020) **...**(1032) @@...@@@(1552)
+ # \ \
+ # \ *...**(1320)
+ # \ \
+ # ++...++(1044) ..
+ #
+ # N0 ********************(1032) @@...@@@(1552)
+ # \
+ # *...**(1320)
+
+ print "Test that we can rerequest a block we previously pruned if needed for a reorg"
+ self.reorg_back()
+ # Verify that N2 still has block 1033 on current chain (@), but not on main chain (*)
+ # Invalidate 1033 on current chain (@) on N2 and we should be able to reorg to
+ # original main chain (*), but will require redownload of some blocks
+ # In order to have a peer we think we can download from, must also perform this invalidation
+ # on N0 and mine a new longest chain to trigger.
+ # Final result:
+ # N0 ********************(1032) **...****(1553)
+ # \
+ # X@...@@@(1552)
+ #
+ # N2 **...*(1020) **...**(1032) **...****(1553)
+ # \ \
+ # \ X@...@@@(1552)
+ # \
+ # +..
+ #
+ # N1 doesn't change because 1033 on main chain (*) is invalid
+
+ print "Done"
+
+if __name__ == '__main__':
+ PruneTest().main()
diff --git a/qa/rpc-tests/rawtransactions.py b/qa/rpc-tests/rawtransactions.py
new file mode 100755
index 0000000000..1378514c84
--- /dev/null
+++ b/qa/rpc-tests/rawtransactions.py
@@ -0,0 +1,144 @@
+#!/usr/bin/env python2
+# Copyright (c) 2014 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#
+# Test re-org scenarios with a mempool that contains transactions
+# that spend (directly or indirectly) coinbase transactions.
+#
+
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import *
+from pprint import pprint
+from time import sleep
+
+# Create one-input, one-output, no-fee transaction:
+class RawTransactionsTest(BitcoinTestFramework):
+
+ def setup_chain(self):
+ print("Initializing test directory "+self.options.tmpdir)
+ initialize_chain_clean(self.options.tmpdir, 3)
+
+ def setup_network(self, split=False):
+ self.nodes = start_nodes(3, self.options.tmpdir)
+
+ #connect to a local machine for debugging
+ #url = "http://bitcoinrpc:DP6DvqZtqXarpeNWyN3LZTFchCCyCUuHwNF7E8pX99x1@%s:%d" % ('127.0.0.1', 18332)
+ #proxy = AuthServiceProxy(url)
+ #proxy.url = url # store URL on proxy for info
+ #self.nodes.append(proxy)
+
+ connect_nodes_bi(self.nodes,0,1)
+ connect_nodes_bi(self.nodes,1,2)
+ connect_nodes_bi(self.nodes,0,2)
+
+ self.is_network_split=False
+ self.sync_all()
+
+ def run_test(self):
+
+ #prepare some coins for multiple *rawtransaction commands
+ self.nodes[2].generate(1)
+ self.nodes[0].generate(101)
+ self.sync_all()
+ self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),1.5);
+ self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),1.0);
+ self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),5.0);
+ self.sync_all()
+ self.nodes[0].generate(5)
+ self.sync_all()
+
+ #########################################
+ # sendrawtransaction with missing input #
+ #########################################
+ inputs = [ {'txid' : "1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000", 'vout' : 1}] #won't exists
+ outputs = { self.nodes[0].getnewaddress() : 4.998 }
+ rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
+ rawtx = self.nodes[2].signrawtransaction(rawtx)
+
+ errorString = ""
+ try:
+ rawtx = self.nodes[2].sendrawtransaction(rawtx['hex'])
+ except JSONRPCException,e:
+ errorString = e.error['message']
+
+ assert_equal("Missing inputs" in errorString, True);
+
+ #########################
+ # RAW TX MULTISIG TESTS #
+ #########################
+ # 2of2 test
+ addr1 = self.nodes[2].getnewaddress()
+ addr2 = self.nodes[2].getnewaddress()
+
+ addr1Obj = self.nodes[2].validateaddress(addr1)
+ addr2Obj = self.nodes[2].validateaddress(addr2)
+
+ mSigObj = self.nodes[2].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey']])
+ mSigObjValid = self.nodes[2].validateaddress(mSigObj)
+
+ #use balance deltas instead of absolute values
+ bal = self.nodes[2].getbalance()
+
+ # send 1.2 BTC to msig adr
+ txId = self.nodes[0].sendtoaddress(mSigObj, 1.2);
+ self.sync_all()
+ self.nodes[0].generate(1)
+ self.sync_all()
+ assert_equal(self.nodes[2].getbalance(), bal+Decimal('1.20000000')) #node2 has both keys of the 2of2 ms addr., tx should affect the balance
+
+
+
+
+ # 2of3 test from different nodes
+ bal = self.nodes[2].getbalance()
+ addr1 = self.nodes[1].getnewaddress()
+ addr2 = self.nodes[2].getnewaddress()
+ addr3 = self.nodes[2].getnewaddress()
+
+ addr1Obj = self.nodes[1].validateaddress(addr1)
+ addr2Obj = self.nodes[2].validateaddress(addr2)
+ addr3Obj = self.nodes[2].validateaddress(addr3)
+
+ mSigObj = self.nodes[2].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey'], addr3Obj['pubkey']])
+ mSigObjValid = self.nodes[2].validateaddress(mSigObj)
+
+ txId = self.nodes[0].sendtoaddress(mSigObj, 2.2);
+ decTx = self.nodes[0].gettransaction(txId)
+ rawTx = self.nodes[0].decoderawtransaction(decTx['hex'])
+ sPK = rawTx['vout'][0]['scriptPubKey']['hex']
+ self.sync_all()
+ self.nodes[0].generate(1)
+ self.sync_all()
+
+ #THIS IS A INCOMPLETE FEATURE
+ #NODE2 HAS TWO OF THREE KEY AND THE FUNDS SHOULD BE SPENDABLE AND COUNT AT BALANCE CALCULATION
+ assert_equal(self.nodes[2].getbalance(), bal) #for now, assume the funds of a 2of3 multisig tx are not marked as spendable
+
+ txDetails = self.nodes[0].gettransaction(txId, True)
+ rawTx = self.nodes[0].decoderawtransaction(txDetails['hex'])
+ vout = False
+ for outpoint in rawTx['vout']:
+ if outpoint['value'] == Decimal('2.20000000'):
+ vout = outpoint
+ break;
+
+ bal = self.nodes[0].getbalance()
+ inputs = [{ "txid" : txId, "vout" : vout['n'], "scriptPubKey" : vout['scriptPubKey']['hex']}]
+ outputs = { self.nodes[0].getnewaddress() : 2.19 }
+ rawTx = self.nodes[2].createrawtransaction(inputs, outputs)
+ rawTxPartialSigned = self.nodes[1].signrawtransaction(rawTx, inputs)
+ assert_equal(rawTxPartialSigned['complete'], False) #node1 only has one key, can't comp. sign the tx
+
+ rawTxSigned = self.nodes[2].signrawtransaction(rawTx, inputs)
+ assert_equal(rawTxSigned['complete'], True) #node2 can sign the tx compl., own two of three keys
+ self.nodes[2].sendrawtransaction(rawTxSigned['hex'])
+ rawTx = self.nodes[0].decoderawtransaction(rawTxSigned['hex'])
+ self.sync_all()
+ self.nodes[0].generate(1)
+ self.sync_all()
+ assert_equal(self.nodes[0].getbalance(), bal+Decimal('50.00000000')+Decimal('2.19000000')) #block reward + tx
+
+if __name__ == '__main__':
+ RawTransactionsTest().main()
diff --git a/qa/rpc-tests/receivedby.py b/qa/rpc-tests/receivedby.py
new file mode 100755
index 0000000000..16d6bd4cf1
--- /dev/null
+++ b/qa/rpc-tests/receivedby.py
@@ -0,0 +1,166 @@
+#!/usr/bin/env python2
+# Copyright (c) 2014 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+# Exercise the listreceivedbyaddress API
+
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import *
+
+
+def get_sub_array_from_array(object_array, to_match):
+ '''
+ Finds and returns a sub array from an array of arrays.
+ to_match should be a unique idetifier of a sub array
+ '''
+ num_matched = 0
+ for item in object_array:
+ all_match = True
+ for key,value in to_match.items():
+ if item[key] != value:
+ all_match = False
+ if not all_match:
+ continue
+ return item
+ return []
+
+def check_array_result(object_array, to_match, expected, should_not_find = False):
+ """
+ Pass in array of JSON objects, a dictionary with key/value pairs
+ to match against, and another dictionary with expected key/value
+ pairs.
+ If the should_not_find flag is true, to_match should not be found in object_array
+ """
+ if should_not_find == True:
+ expected = { }
+ num_matched = 0
+ for item in object_array:
+ all_match = True
+ for key,value in to_match.items():
+ if item[key] != value:
+ all_match = False
+ if not all_match:
+ continue
+ for key,value in expected.items():
+ if item[key] != value:
+ raise AssertionError("%s : expected %s=%s"%(str(item), str(key), str(value)))
+ num_matched = num_matched+1
+ if num_matched == 0 and should_not_find != True:
+ raise AssertionError("No objects matched %s"%(str(to_match)))
+ if num_matched > 0 and should_not_find == True:
+ raise AssertionError("Objects was matched %s"%(str(to_match)))
+
+class ReceivedByTest(BitcoinTestFramework):
+
+ def run_test(self):
+ '''
+ listreceivedbyaddress Test
+ '''
+ # Send from node 0 to 1
+ addr = self.nodes[1].getnewaddress()
+ txid = self.nodes[0].sendtoaddress(addr, 0.1)
+ self.sync_all()
+
+ #Check not listed in listreceivedbyaddress because has 0 confirmations
+ check_array_result(self.nodes[1].listreceivedbyaddress(),
+ {"address":addr},
+ { },
+ True)
+ #Bury Tx under 10 block so it will be returned by listreceivedbyaddress
+ self.nodes[1].generate(10)
+ self.sync_all()
+ check_array_result(self.nodes[1].listreceivedbyaddress(),
+ {"address":addr},
+ {"address":addr, "account":"", "amount":Decimal("0.1"), "confirmations":10, "txids":[txid,]})
+ #With min confidence < 10
+ check_array_result(self.nodes[1].listreceivedbyaddress(5),
+ {"address":addr},
+ {"address":addr, "account":"", "amount":Decimal("0.1"), "confirmations":10, "txids":[txid,]})
+ #With min confidence > 10, should not find Tx
+ check_array_result(self.nodes[1].listreceivedbyaddress(11),{"address":addr},{ },True)
+
+ #Empty Tx
+ addr = self.nodes[1].getnewaddress()
+ check_array_result(self.nodes[1].listreceivedbyaddress(0,True),
+ {"address":addr},
+ {"address":addr, "account":"", "amount":0, "confirmations":0, "txids":[]})
+
+ '''
+ getreceivedbyaddress Test
+ '''
+ # Send from node 0 to 1
+ addr = self.nodes[1].getnewaddress()
+ txid = self.nodes[0].sendtoaddress(addr, 0.1)
+ self.sync_all()
+
+ #Check balance is 0 because of 0 confirmations
+ balance = self.nodes[1].getreceivedbyaddress(addr)
+ if balance != Decimal("0.0"):
+ raise AssertionError("Wrong balance returned by getreceivedbyaddress, %0.2f"%(balance))
+
+ #Check balance is 0.1
+ balance = self.nodes[1].getreceivedbyaddress(addr,0)
+ if balance != Decimal("0.1"):
+ raise AssertionError("Wrong balance returned by getreceivedbyaddress, %0.2f"%(balance))
+
+ #Bury Tx under 10 block so it will be returned by the default getreceivedbyaddress
+ self.nodes[1].generate(10)
+ self.sync_all()
+ balance = self.nodes[1].getreceivedbyaddress(addr)
+ if balance != Decimal("0.1"):
+ raise AssertionError("Wrong balance returned by getreceivedbyaddress, %0.2f"%(balance))
+
+ '''
+ listreceivedbyaccount + getreceivedbyaccount Test
+ '''
+ #set pre-state
+ addrArr = self.nodes[1].getnewaddress()
+ account = self.nodes[1].getaccount(addrArr)
+ received_by_account_json = get_sub_array_from_array(self.nodes[1].listreceivedbyaccount(),{"account":account})
+ if len(received_by_account_json) == 0:
+ raise AssertionError("No accounts found in node")
+ balance_by_account = rec_by_accountArr = self.nodes[1].getreceivedbyaccount(account)
+
+ txid = self.nodes[0].sendtoaddress(addr, 0.1)
+ self.sync_all()
+
+ # listreceivedbyaccount should return received_by_account_json because of 0 confirmations
+ check_array_result(self.nodes[1].listreceivedbyaccount(),
+ {"account":account},
+ received_by_account_json)
+
+ # getreceivedbyaddress should return same balance because of 0 confirmations
+ balance = self.nodes[1].getreceivedbyaccount(account)
+ if balance != balance_by_account:
+ raise AssertionError("Wrong balance returned by getreceivedbyaccount, %0.2f"%(balance))
+
+ self.nodes[1].generate(10)
+ self.sync_all()
+ # listreceivedbyaccount should return updated account balance
+ check_array_result(self.nodes[1].listreceivedbyaccount(),
+ {"account":account},
+ {"account":received_by_account_json["account"], "amount":(received_by_account_json["amount"] + Decimal("0.1"))})
+
+ # getreceivedbyaddress should return updates balance
+ balance = self.nodes[1].getreceivedbyaccount(account)
+ if balance != balance_by_account + Decimal("0.1"):
+ raise AssertionError("Wrong balance returned by getreceivedbyaccount, %0.2f"%(balance))
+
+ #Create a new account named "mynewaccount" that has a 0 balance
+ self.nodes[1].getaccountaddress("mynewaccount")
+ received_by_account_json = get_sub_array_from_array(self.nodes[1].listreceivedbyaccount(0,True),{"account":"mynewaccount"})
+ if len(received_by_account_json) == 0:
+ raise AssertionError("No accounts found in node")
+
+ # Test includeempty of listreceivedbyaccount
+ if received_by_account_json["amount"] != Decimal("0.0"):
+ raise AssertionError("Wrong balance returned by listreceivedbyaccount, %0.2f"%(received_by_account_json["amount"]))
+
+ # Test getreceivedbyaccount for 0 amount accounts
+ balance = self.nodes[1].getreceivedbyaccount("mynewaccount")
+ if balance != Decimal("0.0"):
+ raise AssertionError("Wrong balance returned by getreceivedbyaccount, %0.2f"%(balance))
+
+if __name__ == '__main__':
+ ReceivedByTest().main()
diff --git a/qa/rpc-tests/reindex.py b/qa/rpc-tests/reindex.py
new file mode 100755
index 0000000000..f2e3f248ea
--- /dev/null
+++ b/qa/rpc-tests/reindex.py
@@ -0,0 +1,33 @@
+#!/usr/bin/env python2
+# Copyright (c) 2014 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#
+# Test -reindex with CheckBlockIndex
+#
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import *
+import os.path
+
+class ReindexTest(BitcoinTestFramework):
+
+ def setup_chain(self):
+ print("Initializing test directory "+self.options.tmpdir)
+ initialize_chain_clean(self.options.tmpdir, 1)
+
+ def setup_network(self):
+ self.nodes = []
+ self.is_network_split = False
+ self.nodes.append(start_node(0, self.options.tmpdir))
+
+ def run_test(self):
+ self.nodes[0].generate(3)
+ stop_node(self.nodes[0], 0)
+ wait_bitcoinds()
+ self.nodes[0]=start_node(0, self.options.tmpdir, ["-debug", "-reindex", "-checkblockindex=1"])
+ assert_equal(self.nodes[0].getblockcount(), 3)
+ print "Success"
+
+if __name__ == '__main__':
+ ReindexTest().main()
diff --git a/qa/rpc-tests/rest.py b/qa/rpc-tests/rest.py
new file mode 100755
index 0000000000..15de037360
--- /dev/null
+++ b/qa/rpc-tests/rest.py
@@ -0,0 +1,288 @@
+#!/usr/bin/env python2
+# Copyright (c) 2014 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#
+# Test REST interface
+#
+
+
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import *
+from struct import *
+import binascii
+import json
+import StringIO
+
+try:
+ import http.client as httplib
+except ImportError:
+ import httplib
+try:
+ import urllib.parse as urlparse
+except ImportError:
+ import urlparse
+
+def deser_uint256(f):
+ r = 0
+ for i in range(8):
+ t = unpack(b"<I", f.read(4))[0]
+ r += t << (i * 32)
+ return r
+
+#allows simple http get calls with a request body
+def http_get_call(host, port, path, requestdata = '', response_object = 0):
+ conn = httplib.HTTPConnection(host, port)
+ conn.request('GET', path, requestdata)
+
+ if response_object:
+ return conn.getresponse()
+
+ return conn.getresponse().read()
+
+class RESTTest (BitcoinTestFramework):
+ FORMAT_SEPARATOR = "."
+
+ def setup_chain(self):
+ print("Initializing test directory "+self.options.tmpdir)
+ initialize_chain_clean(self.options.tmpdir, 3)
+
+ def setup_network(self, split=False):
+ self.nodes = start_nodes(3, self.options.tmpdir)
+ connect_nodes_bi(self.nodes,0,1)
+ connect_nodes_bi(self.nodes,1,2)
+ connect_nodes_bi(self.nodes,0,2)
+ self.is_network_split=False
+ self.sync_all()
+
+ def run_test(self):
+ url = urlparse.urlparse(self.nodes[0].url)
+ print "Mining blocks..."
+
+ self.nodes[0].generate(1)
+ self.sync_all()
+ self.nodes[2].generate(100)
+ self.sync_all()
+
+ assert_equal(self.nodes[0].getbalance(), 50)
+
+ txid = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.1)
+ self.sync_all()
+ self.nodes[2].generate(1)
+ self.sync_all()
+ bb_hash = self.nodes[0].getbestblockhash()
+
+ assert_equal(self.nodes[1].getbalance(), Decimal("0.1")) #balance now should be 0.1 on node 1
+
+ # load the latest 0.1 tx over the REST API
+ json_string = http_get_call(url.hostname, url.port, '/rest/tx/'+txid+self.FORMAT_SEPARATOR+"json")
+ json_obj = json.loads(json_string)
+ vintx = json_obj['vin'][0]['txid'] # get the vin to later check for utxo (should be spent by then)
+ # get n of 0.1 outpoint
+ n = 0
+ for vout in json_obj['vout']:
+ if vout['value'] == 0.1:
+ n = vout['n']
+
+
+ ######################################
+ # GETUTXOS: query a unspent outpoint #
+ ######################################
+ json_request = '/checkmempool/'+txid+'-'+str(n)
+ json_string = http_get_call(url.hostname, url.port, '/rest/getutxos'+json_request+self.FORMAT_SEPARATOR+'json')
+ json_obj = json.loads(json_string)
+
+ #check chainTip response
+ assert_equal(json_obj['chaintipHash'], bb_hash)
+
+ #make sure there is one utxo
+ assert_equal(len(json_obj['utxos']), 1)
+ assert_equal(json_obj['utxos'][0]['value'], 0.1)
+
+
+ ################################################
+ # GETUTXOS: now query a already spent outpoint #
+ ################################################
+ json_request = '/checkmempool/'+vintx+'-0'
+ json_string = http_get_call(url.hostname, url.port, '/rest/getutxos'+json_request+self.FORMAT_SEPARATOR+'json')
+ json_obj = json.loads(json_string)
+
+ #check chainTip response
+ assert_equal(json_obj['chaintipHash'], bb_hash)
+
+ #make sure there is no utox in the response because this oupoint has been spent
+ assert_equal(len(json_obj['utxos']), 0)
+
+ #check bitmap
+ assert_equal(json_obj['bitmap'], "0")
+
+
+ ##################################################
+ # GETUTXOS: now check both with the same request #
+ ##################################################
+ json_request = '/checkmempool/'+txid+'-'+str(n)+'/'+vintx+'-0'
+ json_string = http_get_call(url.hostname, url.port, '/rest/getutxos'+json_request+self.FORMAT_SEPARATOR+'json')
+ json_obj = json.loads(json_string)
+ assert_equal(len(json_obj['utxos']), 1)
+ assert_equal(json_obj['bitmap'], "10")
+
+ #test binary response
+ bb_hash = self.nodes[0].getbestblockhash()
+
+ binaryRequest = b'\x01\x02'
+ binaryRequest += binascii.unhexlify(txid)
+ binaryRequest += pack("i", n);
+ binaryRequest += binascii.unhexlify(vintx);
+ binaryRequest += pack("i", 0);
+
+ bin_response = http_get_call(url.hostname, url.port, '/rest/getutxos'+self.FORMAT_SEPARATOR+'bin', binaryRequest)
+ output = StringIO.StringIO()
+ output.write(bin_response)
+ output.seek(0)
+ chainHeight = unpack("i", output.read(4))[0]
+ hashFromBinResponse = hex(deser_uint256(output))[2:].zfill(65).rstrip("L")
+
+ assert_equal(bb_hash, hashFromBinResponse) #check if getutxo's chaintip during calculation was fine
+ assert_equal(chainHeight, 102) #chain height must be 102
+
+
+ ############################
+ # GETUTXOS: mempool checks #
+ ############################
+
+ # do a tx and don't sync
+ txid = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.1)
+ json_string = http_get_call(url.hostname, url.port, '/rest/tx/'+txid+self.FORMAT_SEPARATOR+"json")
+ json_obj = json.loads(json_string)
+ vintx = json_obj['vin'][0]['txid'] # get the vin to later check for utxo (should be spent by then)
+ # get n of 0.1 outpoint
+ n = 0
+ for vout in json_obj['vout']:
+ if vout['value'] == 0.1:
+ n = vout['n']
+
+ json_request = '/'+txid+'-'+str(n)
+ json_string = http_get_call(url.hostname, url.port, '/rest/getutxos'+json_request+self.FORMAT_SEPARATOR+'json')
+ json_obj = json.loads(json_string)
+ assert_equal(len(json_obj['utxos']), 0) #there should be a outpoint because it has just added to the mempool
+
+ json_request = '/checkmempool/'+txid+'-'+str(n)
+ json_string = http_get_call(url.hostname, url.port, '/rest/getutxos'+json_request+self.FORMAT_SEPARATOR+'json')
+ json_obj = json.loads(json_string)
+ assert_equal(len(json_obj['utxos']), 1) #there should be a outpoint because it has just added to the mempool
+
+ #do some invalid requests
+ json_request = '{"checkmempool'
+ response = http_get_call(url.hostname, url.port, '/rest/getutxos'+self.FORMAT_SEPARATOR+'json', json_request, True)
+ assert_equal(response.status, 500) #must be a 500 because we send a invalid json request
+
+ json_request = '{"checkmempool'
+ response = http_get_call(url.hostname, url.port, '/rest/getutxos'+self.FORMAT_SEPARATOR+'bin', json_request, True)
+ assert_equal(response.status, 500) #must be a 500 because we send a invalid bin request
+
+ response = http_get_call(url.hostname, url.port, '/rest/getutxos/checkmempool'+self.FORMAT_SEPARATOR+'bin', '', True)
+ assert_equal(response.status, 500) #must be a 500 because we send a invalid bin request
+
+ #test limits
+ json_request = '/checkmempool/'
+ for x in range(0, 20):
+ json_request += txid+'-'+str(n)+'/'
+ json_request = json_request.rstrip("/")
+ response = http_get_call(url.hostname, url.port, '/rest/getutxos'+json_request+self.FORMAT_SEPARATOR+'json', '', True)
+ assert_equal(response.status, 500) #must be a 500 because we exceeding the limits
+
+ json_request = '/checkmempool/'
+ for x in range(0, 15):
+ json_request += txid+'-'+str(n)+'/'
+ json_request = json_request.rstrip("/");
+ response = http_get_call(url.hostname, url.port, '/rest/getutxos'+json_request+self.FORMAT_SEPARATOR+'json', '', True)
+ assert_equal(response.status, 200) #must be a 500 because we exceeding the limits
+
+ self.nodes[0].generate(1) #generate block to not affect upcoming tests
+ self.sync_all()
+
+ ################
+ # /rest/block/ #
+ ################
+
+ # check binary format
+ response = http_get_call(url.hostname, url.port, '/rest/block/'+bb_hash+self.FORMAT_SEPARATOR+"bin", "", True)
+ assert_equal(response.status, 200)
+ assert_greater_than(int(response.getheader('content-length')), 80)
+ response_str = response.read()
+
+ # compare with block header
+ response_header = http_get_call(url.hostname, url.port, '/rest/headers/1/'+bb_hash+self.FORMAT_SEPARATOR+"bin", "", True)
+ assert_equal(response_header.status, 200)
+ assert_equal(int(response_header.getheader('content-length')), 80)
+ response_header_str = response_header.read()
+ assert_equal(response_str[0:80], response_header_str)
+
+ # check block hex format
+ response_hex = http_get_call(url.hostname, url.port, '/rest/block/'+bb_hash+self.FORMAT_SEPARATOR+"hex", "", True)
+ assert_equal(response_hex.status, 200)
+ assert_greater_than(int(response_hex.getheader('content-length')), 160)
+ response_hex_str = response_hex.read()
+ assert_equal(response_str.encode("hex")[0:160], response_hex_str[0:160])
+
+ # compare with hex block header
+ response_header_hex = http_get_call(url.hostname, url.port, '/rest/headers/1/'+bb_hash+self.FORMAT_SEPARATOR+"hex", "", True)
+ assert_equal(response_header_hex.status, 200)
+ assert_greater_than(int(response_header_hex.getheader('content-length')), 160)
+ response_header_hex_str = response_header_hex.read()
+ assert_equal(response_hex_str[0:160], response_header_hex_str[0:160])
+ assert_equal(response_header_str.encode("hex")[0:160], response_header_hex_str[0:160])
+
+ # check json format
+ json_string = http_get_call(url.hostname, url.port, '/rest/block/'+bb_hash+self.FORMAT_SEPARATOR+'json')
+ json_obj = json.loads(json_string)
+ assert_equal(json_obj['hash'], bb_hash)
+
+ # do tx test
+ tx_hash = json_obj['tx'][0]['txid'];
+ json_string = http_get_call(url.hostname, url.port, '/rest/tx/'+tx_hash+self.FORMAT_SEPARATOR+"json")
+ json_obj = json.loads(json_string)
+ assert_equal(json_obj['txid'], tx_hash)
+
+ # check hex format response
+ hex_string = http_get_call(url.hostname, url.port, '/rest/tx/'+tx_hash+self.FORMAT_SEPARATOR+"hex", "", True)
+ assert_equal(hex_string.status, 200)
+ assert_greater_than(int(response.getheader('content-length')), 10)
+
+
+
+ # check block tx details
+ # let's make 3 tx and mine them on node 1
+ txs = []
+ txs.append(self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11))
+ txs.append(self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11))
+ txs.append(self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11))
+ self.sync_all()
+
+ # now mine the transactions
+ newblockhash = self.nodes[1].generate(1)
+ self.sync_all()
+
+ #check if the 3 tx show up in the new block
+ json_string = http_get_call(url.hostname, url.port, '/rest/block/'+newblockhash[0]+self.FORMAT_SEPARATOR+'json')
+ json_obj = json.loads(json_string)
+ for tx in json_obj['tx']:
+ if not 'coinbase' in tx['vin'][0]: #exclude coinbase
+ assert_equal(tx['txid'] in txs, True)
+
+ #check the same but without tx details
+ json_string = http_get_call(url.hostname, url.port, '/rest/block/notxdetails/'+newblockhash[0]+self.FORMAT_SEPARATOR+'json')
+ json_obj = json.loads(json_string)
+ for tx in txs:
+ assert_equal(tx in json_obj['tx'], True)
+
+ #test rest bestblock
+ bb_hash = self.nodes[0].getbestblockhash()
+
+ json_string = http_get_call(url.hostname, url.port, '/rest/chaininfo.json')
+ json_obj = json.loads(json_string)
+ assert_equal(json_obj['bestblockhash'], bb_hash)
+
+if __name__ == '__main__':
+ RESTTest ().main ()
diff --git a/qa/rpc-tests/rpcbind_test.py b/qa/rpc-tests/rpcbind_test.py
new file mode 100755
index 0000000000..04110c2831
--- /dev/null
+++ b/qa/rpc-tests/rpcbind_test.py
@@ -0,0 +1,152 @@
+#!/usr/bin/env python2
+# Copyright (c) 2014 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+# Test for -rpcbind, as well as -rpcallowip and -rpcconnect
+
+# Add python-bitcoinrpc to module search path:
+import os
+import sys
+
+import json
+import shutil
+import subprocess
+import tempfile
+import traceback
+
+from test_framework.util import *
+from test_framework.netutil import *
+
+def run_bind_test(tmpdir, allow_ips, connect_to, addresses, expected):
+ '''
+ Start a node with requested rpcallowip and rpcbind parameters,
+ then try to connect, and check if the set of bound addresses
+ matches the expected set.
+ '''
+ expected = [(addr_to_hex(addr), port) for (addr, port) in expected]
+ base_args = ['-disablewallet', '-nolisten']
+ if allow_ips:
+ base_args += ['-rpcallowip=' + x for x in allow_ips]
+ binds = ['-rpcbind='+addr for addr in addresses]
+ nodes = start_nodes(1, tmpdir, [base_args + binds], connect_to)
+ try:
+ pid = bitcoind_processes[0].pid
+ assert_equal(set(get_bind_addrs(pid)), set(expected))
+ finally:
+ stop_nodes(nodes)
+ wait_bitcoinds()
+
+def run_allowip_test(tmpdir, allow_ips, rpchost, rpcport):
+ '''
+ Start a node with rpcwallow IP, and request getinfo
+ at a non-localhost IP.
+ '''
+ base_args = ['-disablewallet', '-nolisten'] + ['-rpcallowip='+x for x in allow_ips]
+ nodes = start_nodes(1, tmpdir, [base_args])
+ try:
+ # connect to node through non-loopback interface
+ url = "http://rt:rt@%s:%d" % (rpchost, rpcport,)
+ node = AuthServiceProxy(url)
+ node.getinfo()
+ finally:
+ node = None # make sure connection will be garbage collected and closed
+ stop_nodes(nodes)
+ wait_bitcoinds()
+
+
+def run_test(tmpdir):
+ assert(sys.platform == 'linux2') # due to OS-specific network stats queries, this test works only on Linux
+ # find the first non-loopback interface for testing
+ non_loopback_ip = None
+ for name,ip in all_interfaces():
+ if ip != '127.0.0.1':
+ non_loopback_ip = ip
+ break
+ if non_loopback_ip is None:
+ assert(not 'This test requires at least one non-loopback IPv4 interface')
+ print("Using interface %s for testing" % non_loopback_ip)
+
+ defaultport = rpc_port(0)
+
+ # check default without rpcallowip (IPv4 and IPv6 localhost)
+ run_bind_test(tmpdir, None, '127.0.0.1', [],
+ [('127.0.0.1', defaultport), ('::1', defaultport)])
+ # check default with rpcallowip (IPv6 any)
+ run_bind_test(tmpdir, ['127.0.0.1'], '127.0.0.1', [],
+ [('::0', defaultport)])
+ # check only IPv4 localhost (explicit)
+ run_bind_test(tmpdir, ['127.0.0.1'], '127.0.0.1', ['127.0.0.1'],
+ [('127.0.0.1', defaultport)])
+ # check only IPv4 localhost (explicit) with alternative port
+ run_bind_test(tmpdir, ['127.0.0.1'], '127.0.0.1:32171', ['127.0.0.1:32171'],
+ [('127.0.0.1', 32171)])
+ # check only IPv4 localhost (explicit) with multiple alternative ports on same host
+ run_bind_test(tmpdir, ['127.0.0.1'], '127.0.0.1:32171', ['127.0.0.1:32171', '127.0.0.1:32172'],
+ [('127.0.0.1', 32171), ('127.0.0.1', 32172)])
+ # check only IPv6 localhost (explicit)
+ run_bind_test(tmpdir, ['[::1]'], '[::1]', ['[::1]'],
+ [('::1', defaultport)])
+ # check both IPv4 and IPv6 localhost (explicit)
+ run_bind_test(tmpdir, ['127.0.0.1'], '127.0.0.1', ['127.0.0.1', '[::1]'],
+ [('127.0.0.1', defaultport), ('::1', defaultport)])
+ # check only non-loopback interface
+ run_bind_test(tmpdir, [non_loopback_ip], non_loopback_ip, [non_loopback_ip],
+ [(non_loopback_ip, defaultport)])
+
+ # Check that with invalid rpcallowip, we are denied
+ run_allowip_test(tmpdir, [non_loopback_ip], non_loopback_ip, defaultport)
+ try:
+ run_allowip_test(tmpdir, ['1.1.1.1'], non_loopback_ip, defaultport)
+ assert(not 'Connection not denied by rpcallowip as expected')
+ except ValueError:
+ pass
+
+def main():
+ import optparse
+
+ parser = optparse.OptionParser(usage="%prog [options]")
+ parser.add_option("--nocleanup", dest="nocleanup", default=False, action="store_true",
+ help="Leave bitcoinds and test.* datadir on exit or error")
+ parser.add_option("--srcdir", dest="srcdir", default="../../src",
+ help="Source directory containing bitcoind/bitcoin-cli (default: %default%)")
+ parser.add_option("--tmpdir", dest="tmpdir", default=tempfile.mkdtemp(prefix="test"),
+ help="Root directory for datadirs")
+ (options, args) = parser.parse_args()
+
+ os.environ['PATH'] = options.srcdir+":"+os.environ['PATH']
+
+ check_json_precision()
+
+ success = False
+ nodes = []
+ try:
+ print("Initializing test directory "+options.tmpdir)
+ if not os.path.isdir(options.tmpdir):
+ os.makedirs(options.tmpdir)
+ initialize_chain(options.tmpdir)
+
+ run_test(options.tmpdir)
+
+ success = True
+
+ except AssertionError as e:
+ print("Assertion failed: "+e.message)
+ except Exception as e:
+ print("Unexpected exception caught during testing: "+str(e))
+ traceback.print_tb(sys.exc_info()[2])
+
+ if not options.nocleanup:
+ print("Cleaning up")
+ wait_bitcoinds()
+ shutil.rmtree(options.tmpdir)
+
+ if success:
+ print("Tests successful")
+ sys.exit(0)
+ else:
+ print("Failed")
+ sys.exit(1)
+
+if __name__ == '__main__':
+ main()
diff --git a/qa/rpc-tests/script_test.py b/qa/rpc-tests/script_test.py
new file mode 100755
index 0000000000..860fa56b64
--- /dev/null
+++ b/qa/rpc-tests/script_test.py
@@ -0,0 +1,253 @@
+#!/usr/bin/env python2
+#
+# Distributed under the MIT/X11 software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#
+
+'''
+Test notes:
+This test uses the script_valid and script_invalid tests from the unittest
+framework to do end-to-end testing where we compare that two nodes agree on
+whether blocks containing a given test script are valid.
+
+We generally ignore the script flags associated with each test (since we lack
+the precision to test each script using those flags in this framework), but
+for tests with SCRIPT_VERIFY_P2SH, we can use a block time after the BIP16
+switchover date to try to test with that flag enabled (and for tests without
+that flag, we use a block time before the switchover date).
+
+NOTE: This test is very slow and may take more than 40 minutes to run.
+'''
+
+from test_framework.test_framework import ComparisonTestFramework
+from test_framework.util import *
+from test_framework.comptool import TestInstance, TestManager
+from test_framework.mininode import *
+from test_framework.blocktools import *
+from test_framework.script import *
+import logging
+import copy
+import json
+
+script_valid_file = "../../src/test/data/script_valid.json"
+script_invalid_file = "../../src/test/data/script_invalid.json"
+
+# Pass in a set of json files to open.
+class ScriptTestFile(object):
+
+ def __init__(self, files):
+ self.files = files
+ self.index = -1
+ self.data = []
+
+ def load_files(self):
+ for f in self.files:
+ self.data.extend(json.loads(open(os.path.dirname(os.path.abspath(__file__))+"/"+f).read()))
+
+ # Skip over records that are not long enough to be tests
+ def get_records(self):
+ while (self.index < len(self.data)):
+ if len(self.data[self.index]) >= 3:
+ yield self.data[self.index]
+ self.index += 1
+
+
+# Helper for parsing the flags specified in the .json files
+SCRIPT_VERIFY_NONE = 0
+SCRIPT_VERIFY_P2SH = 1
+SCRIPT_VERIFY_STRICTENC = 1 << 1
+SCRIPT_VERIFY_DERSIG = 1 << 2
+SCRIPT_VERIFY_LOW_S = 1 << 3
+SCRIPT_VERIFY_NULLDUMMY = 1 << 4
+SCRIPT_VERIFY_SIGPUSHONLY = 1 << 5
+SCRIPT_VERIFY_MINIMALDATA = 1 << 6
+SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS = 1 << 7
+SCRIPT_VERIFY_CLEANSTACK = 1 << 8
+
+flag_map = {
+ "": SCRIPT_VERIFY_NONE,
+ "NONE": SCRIPT_VERIFY_NONE,
+ "P2SH": SCRIPT_VERIFY_P2SH,
+ "STRICTENC": SCRIPT_VERIFY_STRICTENC,
+ "DERSIG": SCRIPT_VERIFY_DERSIG,
+ "LOW_S": SCRIPT_VERIFY_LOW_S,
+ "NULLDUMMY": SCRIPT_VERIFY_NULLDUMMY,
+ "SIGPUSHONLY": SCRIPT_VERIFY_SIGPUSHONLY,
+ "MINIMALDATA": SCRIPT_VERIFY_MINIMALDATA,
+ "DISCOURAGE_UPGRADABLE_NOPS": SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS,
+ "CLEANSTACK": SCRIPT_VERIFY_CLEANSTACK,
+}
+
+def ParseScriptFlags(flag_string):
+ flags = 0
+ for x in flag_string.split(","):
+ if x in flag_map:
+ flags |= flag_map[x]
+ else:
+ print "Error: unrecognized script flag: ", x
+ return flags
+
+'''
+Given a string that is a scriptsig or scriptpubkey from the .json files above,
+convert it to a CScript()
+'''
+# Replicates behavior from core_read.cpp
+def ParseScript(json_script):
+ script = json_script.split(" ")
+ parsed_script = CScript()
+ for x in script:
+ if len(x) == 0:
+ # Empty string, ignore.
+ pass
+ elif x.isdigit() or (len(x) >= 1 and x[0] == "-" and x[1:].isdigit()):
+ # Number
+ n = int(x, 0)
+ if (n == -1) or (n >= 1 and n <= 16):
+ parsed_script = CScript(bytes(parsed_script) + bytes(CScript([n])))
+ else:
+ parsed_script += CScriptNum(int(x, 0))
+ elif x.startswith("0x"):
+ # Raw hex data, inserted NOT pushed onto stack:
+ for i in xrange(2, len(x), 2):
+ parsed_script = CScript(bytes(parsed_script) + bytes(chr(int(x[i:i+2],16))))
+ elif x.startswith("'") and x.endswith("'") and len(x) >= 2:
+ # Single-quoted string, pushed as data.
+ parsed_script += CScript([x[1:-1]])
+ else:
+ # opcode, e.g. OP_ADD or ADD:
+ tryopname = "OP_" + x
+ if tryopname in OPCODES_BY_NAME:
+ parsed_script += CScriptOp(OPCODES_BY_NAME["OP_" + x])
+ else:
+ print "ParseScript: error parsing '%s'" % x
+ return ""
+ return parsed_script
+
+class TestBuilder(object):
+ def create_credit_tx(self, scriptPubKey):
+ # self.tx1 is a coinbase transaction, modeled after the one created by script_tests.cpp
+ # This allows us to reuse signatures created in the unit test framework.
+ self.tx1 = create_coinbase() # this has a bip34 scriptsig,
+ self.tx1.vin[0].scriptSig = CScript([0, 0]) # but this matches the unit tests
+ self.tx1.vout[0].nValue = 0
+ self.tx1.vout[0].scriptPubKey = scriptPubKey
+ self.tx1.rehash()
+ def create_spend_tx(self, scriptSig):
+ self.tx2 = create_transaction(self.tx1, 0, CScript(), 0)
+ self.tx2.vin[0].scriptSig = scriptSig
+ self.tx2.vout[0].scriptPubKey = CScript()
+ self.tx2.rehash()
+ def rehash(self):
+ self.tx1.rehash()
+ self.tx2.rehash()
+
+# This test uses the (default) two nodes provided by ComparisonTestFramework,
+# specified on the command line with --testbinary and --refbinary.
+# See comptool.py
+class ScriptTest(ComparisonTestFramework):
+
+ def run_test(self):
+ # Set up the comparison tool TestManager
+ test = TestManager(self, self.options.tmpdir)
+ test.add_all_connections(self.nodes)
+
+ # Load scripts
+ self.scripts = ScriptTestFile([script_valid_file, script_invalid_file])
+ self.scripts.load_files()
+
+ # Some variables we re-use between test instances (to build blocks)
+ self.tip = None
+ self.block_time = None
+
+ NetworkThread().start() # Start up network handling in another thread
+ test.run()
+
+ def generate_test_instance(self, pubkeystring, scriptsigstring):
+ scriptpubkey = ParseScript(pubkeystring)
+ scriptsig = ParseScript(scriptsigstring)
+
+ test = TestInstance(sync_every_block=False)
+ test_build = TestBuilder()
+ test_build.create_credit_tx(scriptpubkey)
+ test_build.create_spend_tx(scriptsig)
+ test_build.rehash()
+
+ block = create_block(self.tip, test_build.tx1, self.block_time)
+ self.block_time += 1
+ block.solve()
+ self.tip = block.sha256
+ test.blocks_and_transactions = [[block, True]]
+
+ for i in xrange(100):
+ block = create_block(self.tip, create_coinbase(), self.block_time)
+ self.block_time += 1
+ block.solve()
+ self.tip = block.sha256
+ test.blocks_and_transactions.append([block, True])
+
+ block = create_block(self.tip, create_coinbase(), self.block_time)
+ self.block_time += 1
+ block.vtx.append(test_build.tx2)
+ block.hashMerkleRoot = block.calc_merkle_root()
+ block.rehash()
+ block.solve()
+ test.blocks_and_transactions.append([block, None])
+ return test
+
+ # This generates the tests for TestManager.
+ def get_tests(self):
+ self.tip = int ("0x" + self.nodes[0].getbestblockhash() + "L", 0)
+ self.block_time = 1333230000 # before the BIP16 switchover
+
+ '''
+ Create a new block with an anyone-can-spend coinbase
+ '''
+ block = create_block(self.tip, create_coinbase(), self.block_time)
+ self.block_time += 1
+ block.solve()
+ self.tip = block.sha256
+ yield TestInstance(objects=[[block, True]])
+
+ '''
+ Build out to 100 blocks total, maturing the coinbase.
+ '''
+ test = TestInstance(objects=[], sync_every_block=False, sync_every_tx=False)
+ for i in xrange(100):
+ b = create_block(self.tip, create_coinbase(), self.block_time)
+ b.solve()
+ test.blocks_and_transactions.append([b, True])
+ self.tip = b.sha256
+ self.block_time += 1
+ yield test
+
+ ''' Iterate through script tests. '''
+ counter = 0
+ for script_test in self.scripts.get_records():
+ ''' Reset the blockchain to genesis block + 100 blocks. '''
+ if self.nodes[0].getblockcount() > 101:
+ self.nodes[0].invalidateblock(self.nodes[0].getblockhash(102))
+ self.nodes[1].invalidateblock(self.nodes[1].getblockhash(102))
+
+ self.tip = int ("0x" + self.nodes[0].getbestblockhash() + "L", 0)
+
+ [scriptsig, scriptpubkey, flags] = script_test[0:3]
+ flags = ParseScriptFlags(flags)
+
+ # We can use block time to determine whether the nodes should be
+ # enforcing BIP16.
+ #
+ # We intentionally let the block time grow by 1 each time.
+ # This forces the block hashes to differ between tests, so that
+ # a call to invalidateblock doesn't interfere with a later test.
+ if (flags & SCRIPT_VERIFY_P2SH):
+ self.block_time = 1333238400 + counter # Advance to enforcing BIP16
+ else:
+ self.block_time = 1333230000 + counter # Before the BIP16 switchover
+
+ print "Script test: [%s]" % script_test
+
+ yield self.generate_test_instance(scriptpubkey, scriptsig)
+ counter += 1
+
+if __name__ == '__main__':
+ ScriptTest().main()
diff --git a/qa/rpc-tests/signrawtransactions.py b/qa/rpc-tests/signrawtransactions.py
new file mode 100755
index 0000000000..d51d6ee610
--- /dev/null
+++ b/qa/rpc-tests/signrawtransactions.py
@@ -0,0 +1,109 @@
+#!/usr/bin/env python2
+# Copyright (c) 2015 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import *
+
+
+class SignRawTransactionsTest(BitcoinTestFramework):
+ """Tests transaction signing via RPC command "signrawtransaction"."""
+
+ def setup_chain(self):
+ print('Initializing test directory ' + self.options.tmpdir)
+ initialize_chain_clean(self.options.tmpdir, 1)
+
+ def setup_network(self, split=False):
+ self.nodes = start_nodes(1, self.options.tmpdir)
+ self.is_network_split = False
+
+ def successful_signing_test(self):
+ """Creates and signs a valid raw transaction with one input.
+
+ Expected results:
+
+ 1) The transaction has a complete set of signatures
+ 2) No script verification error occurred"""
+ privKeys = ['cUeKHd5orzT3mz8P9pxyREHfsWtVfgsfDjiZZBcjUBAaGk1BTj7N']
+
+ inputs = [
+ # Valid pay-to-pubkey script
+ {'txid': '9b907ef1e3c26fc71fe4a4b3580bc75264112f95050014157059c736f0202e71', 'vout': 0,
+ 'scriptPubKey': '76a91460baa0f494b38ce3c940dea67f3804dc52d1fb9488ac'}
+ ]
+
+ outputs = {'mpLQjfK79b7CCV4VMJWEWAj5Mpx8Up5zxB': 0.1}
+
+ rawTx = self.nodes[0].createrawtransaction(inputs, outputs)
+ rawTxSigned = self.nodes[0].signrawtransaction(rawTx, inputs, privKeys)
+
+ # 1) The transaction has a complete set of signatures
+ assert 'complete' in rawTxSigned
+ assert_equal(rawTxSigned['complete'], True)
+
+ # 2) No script verification error occurred
+ assert 'errors' not in rawTxSigned
+
+ def script_verification_error_test(self):
+ """Creates and signs a raw transaction with valid (vin 0), invalid (vin 1) and one missing (vin 2) input script.
+
+ Expected results:
+
+ 3) The transaction has no complete set of signatures
+ 4) Two script verification errors occurred
+ 5) Script verification errors have certain properties ("txid", "vout", "scriptSig", "sequence", "error")
+ 6) The verification errors refer to the invalid (vin 1) and missing input (vin 2)"""
+ privKeys = ['cUeKHd5orzT3mz8P9pxyREHfsWtVfgsfDjiZZBcjUBAaGk1BTj7N']
+
+ inputs = [
+ # Valid pay-to-pubkey script
+ {'txid': '9b907ef1e3c26fc71fe4a4b3580bc75264112f95050014157059c736f0202e71', 'vout': 0},
+ # Invalid script
+ {'txid': '5b8673686910442c644b1f4993d8f7753c7c8fcb5c87ee40d56eaeef25204547', 'vout': 7},
+ # Missing scriptPubKey
+ {'txid': '9b907ef1e3c26fc71fe4a4b3580bc75264112f95050014157059c736f0202e71', 'vout': 1},
+ ]
+
+ scripts = [
+ # Valid pay-to-pubkey script
+ {'txid': '9b907ef1e3c26fc71fe4a4b3580bc75264112f95050014157059c736f0202e71', 'vout': 0,
+ 'scriptPubKey': '76a91460baa0f494b38ce3c940dea67f3804dc52d1fb9488ac'},
+ # Invalid script
+ {'txid': '5b8673686910442c644b1f4993d8f7753c7c8fcb5c87ee40d56eaeef25204547', 'vout': 7,
+ 'scriptPubKey': 'badbadbadbad'}
+ ]
+
+ outputs = {'mpLQjfK79b7CCV4VMJWEWAj5Mpx8Up5zxB': 0.1}
+
+ rawTx = self.nodes[0].createrawtransaction(inputs, outputs)
+ rawTxSigned = self.nodes[0].signrawtransaction(rawTx, scripts, privKeys)
+
+ # 3) The transaction has no complete set of signatures
+ assert 'complete' in rawTxSigned
+ assert_equal(rawTxSigned['complete'], False)
+
+ # 4) Two script verification errors occurred
+ assert 'errors' in rawTxSigned
+ assert_equal(len(rawTxSigned['errors']), 2)
+
+ # 5) Script verification errors have certain properties
+ assert 'txid' in rawTxSigned['errors'][0]
+ assert 'vout' in rawTxSigned['errors'][0]
+ assert 'scriptSig' in rawTxSigned['errors'][0]
+ assert 'sequence' in rawTxSigned['errors'][0]
+ assert 'error' in rawTxSigned['errors'][0]
+
+ # 6) The verification errors refer to the invalid (vin 1) and missing input (vin 2)
+ assert_equal(rawTxSigned['errors'][0]['txid'], inputs[1]['txid'])
+ assert_equal(rawTxSigned['errors'][0]['vout'], inputs[1]['vout'])
+ assert_equal(rawTxSigned['errors'][1]['txid'], inputs[2]['txid'])
+ assert_equal(rawTxSigned['errors'][1]['vout'], inputs[2]['vout'])
+
+ def run_test(self):
+ self.successful_signing_test()
+ self.script_verification_error_test()
+
+
+if __name__ == '__main__':
+ SignRawTransactionsTest().main()
diff --git a/qa/rpc-tests/smartfees.py b/qa/rpc-tests/smartfees.py
new file mode 100755
index 0000000000..c15c5fda09
--- /dev/null
+++ b/qa/rpc-tests/smartfees.py
@@ -0,0 +1,258 @@
+#!/usr/bin/env python2
+# Copyright (c) 2014-2015 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#
+# Test fee estimation code
+#
+
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import *
+
+# Construct 2 trivial P2SH's and the ScriptSigs that spend them
+# So we can create many many transactions without needing to spend
+# time signing.
+P2SH_1 = "2MySexEGVzZpRgNQ1JdjdP5bRETznm3roQ2" # P2SH of "OP_1 OP_DROP"
+P2SH_2 = "2NBdpwq8Aoo1EEKEXPNrKvr5xQr3M9UfcZA" # P2SH of "OP_2 OP_DROP"
+# Associated ScriptSig's to spend satisfy P2SH_1 and P2SH_2
+# 4 bytes of OP_TRUE and push 2-byte redeem script of "OP_1 OP_DROP" or "OP_2 OP_DROP"
+SCRIPT_SIG = ["0451025175", "0451025275"]
+
+def satoshi_round(amount):
+ return Decimal(amount).quantize(Decimal('0.00000001'), rounding=ROUND_DOWN)
+
+def small_txpuzzle_randfee(from_node, conflist, unconflist, amount, min_fee, fee_increment):
+ '''
+ Create and send a transaction with a random fee.
+ The transaction pays to a trival P2SH script, and assumes that its inputs
+ are of the same form.
+ The function takes a list of confirmed outputs and unconfirmed outputs
+ and attempts to use the confirmed list first for its inputs.
+ It adds the newly created outputs to the unconfirmed list.
+ Returns (raw transaction, fee)
+ '''
+ # It's best to exponentially distribute our random fees
+ # because the buckets are exponentially spaced.
+ # Exponentially distributed from 1-128 * fee_increment
+ rand_fee = float(fee_increment)*(1.1892**random.randint(0,28))
+ # Total fee ranges from min_fee to min_fee + 127*fee_increment
+ fee = min_fee - fee_increment + satoshi_round(rand_fee)
+ inputs = []
+ total_in = Decimal("0.00000000")
+ while total_in <= (amount + fee) and len(conflist) > 0:
+ t = conflist.pop(0)
+ total_in += t["amount"]
+ inputs.append({ "txid" : t["txid"], "vout" : t["vout"]} )
+ if total_in <= amount + fee:
+ while total_in <= (amount + fee) and len(unconflist) > 0:
+ t = unconflist.pop(0)
+ total_in += t["amount"]
+ inputs.append({ "txid" : t["txid"], "vout" : t["vout"]} )
+ if total_in <= amount + fee:
+ raise RuntimeError("Insufficient funds: need %d, have %d"%(amount+fee, total_in))
+ outputs = {}
+ outputs[P2SH_1] = total_in - amount - fee
+ outputs[P2SH_2] = amount
+ rawtx = from_node.createrawtransaction(inputs, outputs)
+ # Createrawtransaction constructions a transaction that is ready to be signed
+ # These transactions don't need to be signed, but we still have to insert the ScriptSig
+ # that will satisfy the ScriptPubKey.
+ completetx = rawtx[0:10]
+ inputnum = 0
+ for inp in inputs:
+ completetx += rawtx[10+82*inputnum:82+82*inputnum]
+ completetx += SCRIPT_SIG[inp["vout"]]
+ completetx += rawtx[84+82*inputnum:92+82*inputnum]
+ inputnum += 1
+ completetx += rawtx[10+82*inputnum:]
+ txid = from_node.sendrawtransaction(completetx, True)
+ unconflist.append({ "txid" : txid, "vout" : 0 , "amount" : total_in - amount - fee})
+ unconflist.append({ "txid" : txid, "vout" : 1 , "amount" : amount})
+
+ return (completetx, fee)
+
+def split_inputs(from_node, txins, txouts, initial_split = False):
+ '''
+ We need to generate a lot of very small inputs so we can generate a ton of transactions
+ and they will have low priority.
+ This function takes an input from txins, and creates and sends a transaction
+ which splits the value into 2 outputs which are appended to txouts.
+ '''
+ prevtxout = txins.pop()
+ inputs = []
+ outputs = {}
+ inputs.append({ "txid" : prevtxout["txid"], "vout" : prevtxout["vout"] })
+ half_change = satoshi_round(prevtxout["amount"]/2)
+ rem_change = prevtxout["amount"] - half_change - Decimal("0.00001000")
+ outputs[P2SH_1] = half_change
+ outputs[P2SH_2] = rem_change
+ rawtx = from_node.createrawtransaction(inputs, outputs)
+ # If this is the initial split we actually need to sign the transaction
+ # Otherwise we just need to insert the property ScriptSig
+ if (initial_split) :
+ completetx = from_node.signrawtransaction(rawtx)["hex"]
+ else :
+ completetx = rawtx[0:82] + SCRIPT_SIG[prevtxout["vout"]] + rawtx[84:]
+ txid = from_node.sendrawtransaction(completetx, True)
+ txouts.append({ "txid" : txid, "vout" : 0 , "amount" : half_change})
+ txouts.append({ "txid" : txid, "vout" : 1 , "amount" : rem_change})
+
+def check_estimates(node, fees_seen, max_invalid, print_estimates = True):
+ '''
+ This function calls estimatefee and verifies that the estimates
+ meet certain invariants.
+ '''
+ all_estimates = [ node.estimatefee(i) for i in range(1,26) ]
+ if print_estimates:
+ print([str(all_estimates[e-1]) for e in [1,2,3,6,15,25]])
+ delta = 1.0e-6 # account for rounding error
+ last_e = max(fees_seen)
+ for e in filter(lambda x: x >= 0, all_estimates):
+ # Estimates should be within the bounds of what transactions fees actually were:
+ if float(e)+delta < min(fees_seen) or float(e)-delta > max(fees_seen):
+ raise AssertionError("Estimated fee (%f) out of range (%f,%f)"
+ %(float(e), min(fees_seen), max(fees_seen)))
+ # Estimates should be monotonically decreasing
+ if float(e)-delta > last_e:
+ raise AssertionError("Estimated fee (%f) larger than last fee (%f) for lower number of confirms"
+ %(float(e),float(last_e)))
+ last_e = e
+ valid_estimate = False
+ invalid_estimates = 0
+ for e in all_estimates:
+ if e >= 0:
+ valid_estimate = True
+ else:
+ invalid_estimates += 1
+ # Once we're at a high enough confirmation count that we can give an estimate
+ # We should have estimates for all higher confirmation counts
+ if valid_estimate and e < 0:
+ raise AssertionError("Invalid estimate appears at higher confirm count than valid estimate")
+ # Check on the expected number of different confirmation counts
+ # that we might not have valid estimates for
+ if invalid_estimates > max_invalid:
+ raise AssertionError("More than (%d) invalid estimates"%(max_invalid))
+ return all_estimates
+
+
+class EstimateFeeTest(BitcoinTestFramework):
+
+ def setup_network(self):
+ '''
+ We'll setup the network to have 3 nodes that all mine with different parameters.
+ But first we need to use one node to create a lot of small low priority outputs
+ which we will use to generate our transactions.
+ '''
+ self.nodes = []
+ # Use node0 to mine blocks for input splitting
+ self.nodes.append(start_node(0, self.options.tmpdir, ["-maxorphantx=1000",
+ "-relaypriority=0", "-whitelist=127.0.0.1"]))
+
+ print("This test is time consuming, please be patient")
+ print("Splitting inputs to small size so we can generate low priority tx's")
+ self.txouts = []
+ self.txouts2 = []
+ # Split a coinbase into two transaction puzzle outputs
+ split_inputs(self.nodes[0], self.nodes[0].listunspent(0), self.txouts, True)
+
+ # Mine
+ while (len(self.nodes[0].getrawmempool()) > 0):
+ self.nodes[0].generate(1)
+
+ # Repeatedly split those 2 outputs, doubling twice for each rep
+ # Use txouts to monitor the available utxo, since these won't be tracked in wallet
+ reps = 0
+ while (reps < 5):
+ #Double txouts to txouts2
+ while (len(self.txouts)>0):
+ split_inputs(self.nodes[0], self.txouts, self.txouts2)
+ while (len(self.nodes[0].getrawmempool()) > 0):
+ self.nodes[0].generate(1)
+ #Double txouts2 to txouts
+ while (len(self.txouts2)>0):
+ split_inputs(self.nodes[0], self.txouts2, self.txouts)
+ while (len(self.nodes[0].getrawmempool()) > 0):
+ self.nodes[0].generate(1)
+ reps += 1
+ print("Finished splitting")
+
+ # Now we can connect the other nodes, didn't want to connect them earlier
+ # so the estimates would not be affected by the splitting transactions
+ # Node1 mines small blocks but that are bigger than the expected transaction rate,
+ # and allows free transactions.
+ # NOTE: the CreateNewBlock code starts counting block size at 1,000 bytes,
+ # (17k is room enough for 110 or so transactions)
+ self.nodes.append(start_node(1, self.options.tmpdir,
+ ["-blockprioritysize=1500", "-blockmaxsize=18000",
+ "-maxorphantx=1000", "-relaypriority=0", "-debug=estimatefee"]))
+ connect_nodes(self.nodes[1], 0)
+
+ # Node2 is a stingy miner, that
+ # produces too small blocks (room for only 70 or so transactions)
+ node2args = ["-blockprioritysize=0", "-blockmaxsize=12000", "-maxorphantx=1000", "-relaypriority=0"]
+
+ self.nodes.append(start_node(2, self.options.tmpdir, node2args))
+ connect_nodes(self.nodes[0], 2)
+ connect_nodes(self.nodes[2], 1)
+
+ self.is_network_split = False
+ self.sync_all()
+
+ def transact_and_mine(self, numblocks, mining_node):
+ min_fee = Decimal("0.00001")
+ # We will now mine numblocks blocks generating on average 100 transactions between each block
+ # We shuffle our confirmed txout set before each set of transactions
+ # small_txpuzzle_randfee will use the transactions that have inputs already in the chain when possible
+ # resorting to tx's that depend on the mempool when those run out
+ for i in range(numblocks):
+ random.shuffle(self.confutxo)
+ for j in range(random.randrange(100-50,100+50)):
+ from_index = random.randint(1,2)
+ (txhex, fee) = small_txpuzzle_randfee(self.nodes[from_index], self.confutxo,
+ self.memutxo, Decimal("0.005"), min_fee, min_fee)
+ tx_kbytes = (len(txhex)/2)/1000.0
+ self.fees_per_kb.append(float(fee)/tx_kbytes)
+ sync_mempools(self.nodes[0:3],.1)
+ mined = mining_node.getblock(mining_node.generate(1)[0],True)["tx"]
+ sync_blocks(self.nodes[0:3],.1)
+ #update which txouts are confirmed
+ newmem = []
+ for utx in self.memutxo:
+ if utx["txid"] in mined:
+ self.confutxo.append(utx)
+ else:
+ newmem.append(utx)
+ self.memutxo = newmem
+
+ def run_test(self):
+ self.fees_per_kb = []
+ self.memutxo = []
+ self.confutxo = self.txouts # Start with the set of confirmed txouts after splitting
+ print("Checking estimates for 1/2/3/6/15/25 blocks")
+ print("Creating transactions and mining them with a huge block size")
+ # Create transactions and mine 20 big blocks with node 0 such that the mempool is always emptied
+ self.transact_and_mine(30, self.nodes[0])
+ check_estimates(self.nodes[1], self.fees_per_kb, 1)
+
+ print("Creating transactions and mining them with a block size that can't keep up")
+ # Create transactions and mine 30 small blocks with node 2, but create txs faster than we can mine
+ self.transact_and_mine(20, self.nodes[2])
+ check_estimates(self.nodes[1], self.fees_per_kb, 3)
+
+ print("Creating transactions and mining them at a block size that is just big enough")
+ # Generate transactions while mining 40 more blocks, this time with node1
+ # which mines blocks with capacity just above the rate that transactions are being created
+ self.transact_and_mine(40, self.nodes[1])
+ check_estimates(self.nodes[1], self.fees_per_kb, 2)
+
+ # Finish by mining a normal-sized block:
+ while len(self.nodes[1].getrawmempool()) > 0:
+ self.nodes[1].generate(1)
+
+ sync_blocks(self.nodes[0:3],.1)
+ print("Final estimates after emptying mempools")
+ check_estimates(self.nodes[1], self.fees_per_kb, 2)
+
+if __name__ == '__main__':
+ EstimateFeeTest().main()
diff --git a/qa/rpc-tests/test_framework/__init__.py b/qa/rpc-tests/test_framework/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/qa/rpc-tests/test_framework/__init__.py
diff --git a/qa/rpc-tests/test_framework/authproxy.py b/qa/rpc-tests/test_framework/authproxy.py
new file mode 100644
index 0000000000..bc7d655fdf
--- /dev/null
+++ b/qa/rpc-tests/test_framework/authproxy.py
@@ -0,0 +1,156 @@
+
+"""
+ Copyright 2011 Jeff Garzik
+
+ AuthServiceProxy has the following improvements over python-jsonrpc's
+ ServiceProxy class:
+
+ - HTTP connections persist for the life of the AuthServiceProxy object
+ (if server supports HTTP/1.1)
+ - sends protocol 'version', per JSON-RPC 1.1
+ - sends proper, incrementing 'id'
+ - sends Basic HTTP authentication headers
+ - parses all JSON numbers that look like floats as Decimal
+ - uses standard Python json lib
+
+ Previous copyright, from python-jsonrpc/jsonrpc/proxy.py:
+
+ Copyright (c) 2007 Jan-Klaas Kollhof
+
+ This file is part of jsonrpc.
+
+ jsonrpc is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ This software 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 Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this software; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+"""
+
+try:
+ import http.client as httplib
+except ImportError:
+ import httplib
+import base64
+import decimal
+import json
+import logging
+try:
+ import urllib.parse as urlparse
+except ImportError:
+ import urlparse
+
+USER_AGENT = "AuthServiceProxy/0.1"
+
+HTTP_TIMEOUT = 30
+
+log = logging.getLogger("BitcoinRPC")
+
+class JSONRPCException(Exception):
+ def __init__(self, rpc_error):
+ Exception.__init__(self)
+ self.error = rpc_error
+
+
+def EncodeDecimal(o):
+ if isinstance(o, decimal.Decimal):
+ return round(o, 8)
+ raise TypeError(repr(o) + " is not JSON serializable")
+
+class AuthServiceProxy(object):
+ __id_count = 0
+
+ def __init__(self, service_url, service_name=None, timeout=HTTP_TIMEOUT, connection=None):
+ self.__service_url = service_url
+ self.__service_name = service_name
+ self.__url = urlparse.urlparse(service_url)
+ if self.__url.port is None:
+ port = 80
+ else:
+ port = self.__url.port
+ (user, passwd) = (self.__url.username, self.__url.password)
+ try:
+ user = user.encode('utf8')
+ except AttributeError:
+ pass
+ try:
+ passwd = passwd.encode('utf8')
+ except AttributeError:
+ pass
+ authpair = user + b':' + passwd
+ self.__auth_header = b'Basic ' + base64.b64encode(authpair)
+
+ if connection:
+ # Callables re-use the connection of the original proxy
+ self.__conn = connection
+ elif self.__url.scheme == 'https':
+ self.__conn = httplib.HTTPSConnection(self.__url.hostname, port,
+ None, None, False,
+ timeout)
+ else:
+ self.__conn = httplib.HTTPConnection(self.__url.hostname, port,
+ False, timeout)
+
+ def __getattr__(self, name):
+ if name.startswith('__') and name.endswith('__'):
+ # Python internal stuff
+ raise AttributeError
+ if self.__service_name is not None:
+ name = "%s.%s" % (self.__service_name, name)
+ return AuthServiceProxy(self.__service_url, name, connection=self.__conn)
+
+ def __call__(self, *args):
+ AuthServiceProxy.__id_count += 1
+
+ log.debug("-%s-> %s %s"%(AuthServiceProxy.__id_count, self.__service_name,
+ json.dumps(args, default=EncodeDecimal)))
+ postdata = json.dumps({'version': '1.1',
+ 'method': self.__service_name,
+ 'params': args,
+ 'id': AuthServiceProxy.__id_count}, default=EncodeDecimal)
+ self.__conn.request('POST', self.__url.path, postdata,
+ {'Host': self.__url.hostname,
+ 'User-Agent': USER_AGENT,
+ 'Authorization': self.__auth_header,
+ 'Content-type': 'application/json'})
+
+ response = self._get_response()
+ if response['error'] is not None:
+ raise JSONRPCException(response['error'])
+ elif 'result' not in response:
+ raise JSONRPCException({
+ 'code': -343, 'message': 'missing JSON-RPC result'})
+ else:
+ return response['result']
+
+ def _batch(self, rpc_call_list):
+ postdata = json.dumps(list(rpc_call_list), default=EncodeDecimal)
+ log.debug("--> "+postdata)
+ self.__conn.request('POST', self.__url.path, postdata,
+ {'Host': self.__url.hostname,
+ 'User-Agent': USER_AGENT,
+ 'Authorization': self.__auth_header,
+ 'Content-type': 'application/json'})
+
+ return self._get_response()
+
+ def _get_response(self):
+ http_response = self.__conn.getresponse()
+ if http_response is None:
+ raise JSONRPCException({
+ 'code': -342, 'message': 'missing HTTP response from server'})
+
+ responsedata = http_response.read().decode('utf8')
+ response = json.loads(responsedata, parse_float=decimal.Decimal)
+ if "error" in response and response["error"] is None:
+ log.debug("<-%s- %s"%(response["id"], json.dumps(response["result"], default=EncodeDecimal)))
+ else:
+ log.debug("<-- "+responsedata)
+ return response
diff --git a/qa/rpc-tests/test_framework/bignum.py b/qa/rpc-tests/test_framework/bignum.py
new file mode 100644
index 0000000000..b0c58ccd47
--- /dev/null
+++ b/qa/rpc-tests/test_framework/bignum.py
@@ -0,0 +1,102 @@
+#
+#
+# bignum.py
+#
+# This file is copied from python-bitcoinlib.
+#
+# Distributed under the MIT/X11 software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#
+
+"""Bignum routines"""
+
+from __future__ import absolute_import, division, print_function, unicode_literals
+
+import struct
+
+
+# generic big endian MPI format
+
+def bn_bytes(v, have_ext=False):
+ ext = 0
+ if have_ext:
+ ext = 1
+ return ((v.bit_length()+7)//8) + ext
+
+def bn2bin(v):
+ s = bytearray()
+ i = bn_bytes(v)
+ while i > 0:
+ s.append((v >> ((i-1) * 8)) & 0xff)
+ i -= 1
+ return s
+
+def bin2bn(s):
+ l = 0
+ for ch in s:
+ l = (l << 8) | ch
+ return l
+
+def bn2mpi(v):
+ have_ext = False
+ if v.bit_length() > 0:
+ have_ext = (v.bit_length() & 0x07) == 0
+
+ neg = False
+ if v < 0:
+ neg = True
+ v = -v
+
+ s = struct.pack(b">I", bn_bytes(v, have_ext))
+ ext = bytearray()
+ if have_ext:
+ ext.append(0)
+ v_bin = bn2bin(v)
+ if neg:
+ if have_ext:
+ ext[0] |= 0x80
+ else:
+ v_bin[0] |= 0x80
+ return s + ext + v_bin
+
+def mpi2bn(s):
+ if len(s) < 4:
+ return None
+ s_size = bytes(s[:4])
+ v_len = struct.unpack(b">I", s_size)[0]
+ if len(s) != (v_len + 4):
+ return None
+ if v_len == 0:
+ return 0
+
+ v_str = bytearray(s[4:])
+ neg = False
+ i = v_str[0]
+ if i & 0x80:
+ neg = True
+ i &= ~0x80
+ v_str[0] = i
+
+ v = bin2bn(v_str)
+
+ if neg:
+ return -v
+ return v
+
+# bitcoin-specific little endian format, with implicit size
+def mpi2vch(s):
+ r = s[4:] # strip size
+ r = r[::-1] # reverse string, converting BE->LE
+ return r
+
+def bn2vch(v):
+ return bytes(mpi2vch(bn2mpi(v)))
+
+def vch2mpi(s):
+ r = struct.pack(b">I", len(s)) # size
+ r += s[::-1] # reverse string, converting LE->BE
+ return r
+
+def vch2bn(s):
+ return mpi2bn(vch2mpi(s))
+
diff --git a/qa/rpc-tests/test_framework/blockstore.py b/qa/rpc-tests/test_framework/blockstore.py
new file mode 100644
index 0000000000..c57b6df81b
--- /dev/null
+++ b/qa/rpc-tests/test_framework/blockstore.py
@@ -0,0 +1,127 @@
+# BlockStore: a helper class that keeps a map of blocks and implements
+# helper functions for responding to getheaders and getdata,
+# and for constructing a getheaders message
+#
+
+from mininode import *
+import dbm
+
+class BlockStore(object):
+ def __init__(self, datadir):
+ self.blockDB = dbm.open(datadir + "/blocks", 'c')
+ self.currentBlock = 0L
+
+ def close(self):
+ self.blockDB.close()
+
+ def get(self, blockhash):
+ serialized_block = None
+ try:
+ serialized_block = self.blockDB[repr(blockhash)]
+ except KeyError:
+ return None
+ f = cStringIO.StringIO(serialized_block)
+ ret = CBlock()
+ ret.deserialize(f)
+ ret.calc_sha256()
+ return ret
+
+ # Note: this pulls full blocks out of the database just to retrieve
+ # the headers -- perhaps we could keep a separate data structure
+ # to avoid this overhead.
+ def headers_for(self, locator, hash_stop, current_tip=None):
+ if current_tip is None:
+ current_tip = self.currentBlock
+ current_block = self.get(current_tip)
+ if current_block is None:
+ return None
+
+ response = msg_headers()
+ headersList = [ CBlockHeader(current_block) ]
+ maxheaders = 2000
+ while (headersList[0].sha256 not in locator.vHave):
+ prevBlockHash = headersList[0].hashPrevBlock
+ prevBlock = self.get(prevBlockHash)
+ if prevBlock is not None:
+ headersList.insert(0, CBlockHeader(prevBlock))
+ else:
+ break
+ headersList = headersList[:maxheaders] # truncate if we have too many
+ hashList = [x.sha256 for x in headersList]
+ index = len(headersList)
+ if (hash_stop in hashList):
+ index = hashList.index(hash_stop)+1
+ response.headers = headersList[:index]
+ return response
+
+ def add_block(self, block):
+ block.calc_sha256()
+ try:
+ self.blockDB[repr(block.sha256)] = bytes(block.serialize())
+ except TypeError as e:
+ print "Unexpected error: ", sys.exc_info()[0], e.args
+ self.currentBlock = block.sha256
+
+ def get_blocks(self, inv):
+ responses = []
+ for i in inv:
+ if (i.type == 2): # MSG_BLOCK
+ block = self.get(i.hash)
+ if block is not None:
+ responses.append(msg_block(block))
+ return responses
+
+ def get_locator(self, current_tip=None):
+ if current_tip is None:
+ current_tip = self.currentBlock
+ r = []
+ counter = 0
+ step = 1
+ lastBlock = self.get(current_tip)
+ while lastBlock is not None:
+ r.append(lastBlock.hashPrevBlock)
+ for i in range(step):
+ lastBlock = self.get(lastBlock.hashPrevBlock)
+ if lastBlock is None:
+ break
+ counter += 1
+ if counter > 10:
+ step *= 2
+ locator = CBlockLocator()
+ locator.vHave = r
+ return locator
+
+class TxStore(object):
+ def __init__(self, datadir):
+ self.txDB = dbm.open(datadir + "/transactions", 'c')
+
+ def close(self):
+ self.txDB.close()
+
+ def get(self, txhash):
+ serialized_tx = None
+ try:
+ serialized_tx = self.txDB[repr(txhash)]
+ except KeyError:
+ return None
+ f = cStringIO.StringIO(serialized_tx)
+ ret = CTransaction()
+ ret.deserialize(f)
+ ret.calc_sha256()
+ return ret
+
+ def add_transaction(self, tx):
+ tx.calc_sha256()
+ try:
+ self.txDB[repr(tx.sha256)] = bytes(tx.serialize())
+ except TypeError as e:
+ print "Unexpected error: ", sys.exc_info()[0], e.args
+
+ def get_transactions(self, inv):
+ responses = []
+ for i in inv:
+ if (i.type == 1): # MSG_TX
+ tx = self.get(i.hash)
+ if tx is not None:
+ responses.append(msg_tx(tx))
+ return responses
diff --git a/qa/rpc-tests/test_framework/blocktools.py b/qa/rpc-tests/test_framework/blocktools.py
new file mode 100644
index 0000000000..f397fe7cd6
--- /dev/null
+++ b/qa/rpc-tests/test_framework/blocktools.py
@@ -0,0 +1,65 @@
+# blocktools.py - utilities for manipulating blocks and transactions
+#
+# Distributed under the MIT/X11 software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#
+
+from mininode import *
+from script import CScript, CScriptOp
+
+# Create a block (with regtest difficulty)
+def create_block(hashprev, coinbase, nTime=None):
+ block = CBlock()
+ if nTime is None:
+ import time
+ block.nTime = int(time.time()+600)
+ else:
+ block.nTime = nTime
+ block.hashPrevBlock = hashprev
+ block.nBits = 0x207fffff # Will break after a difficulty adjustment...
+ block.vtx.append(coinbase)
+ block.hashMerkleRoot = block.calc_merkle_root()
+ block.calc_sha256()
+ return block
+
+def serialize_script_num(value):
+ r = bytearray(0)
+ if value == 0:
+ return r
+ neg = value < 0
+ absvalue = -value if neg else value
+ while (absvalue):
+ r.append(chr(absvalue & 0xff))
+ absvalue >>= 8
+ if r[-1] & 0x80:
+ r.append(0x80 if neg else 0)
+ elif neg:
+ r[-1] |= 0x80
+ return r
+
+counter=1
+# Create an anyone-can-spend coinbase transaction, assuming no miner fees
+def create_coinbase(heightAdjust = 0):
+ global counter
+ coinbase = CTransaction()
+ coinbase.vin.append(CTxIn(COutPoint(0, 0xffffffff),
+ ser_string(serialize_script_num(counter+heightAdjust)), 0xffffffff))
+ counter += 1
+ coinbaseoutput = CTxOut()
+ coinbaseoutput.nValue = 50*100000000
+ halvings = int((counter+heightAdjust)/150) # regtest
+ coinbaseoutput.nValue >>= halvings
+ coinbaseoutput.scriptPubKey = ""
+ coinbase.vout = [ coinbaseoutput ]
+ coinbase.calc_sha256()
+ return coinbase
+
+# Create a transaction with an anyone-can-spend output, that spends the
+# nth output of prevtx.
+def create_transaction(prevtx, n, sig, value):
+ tx = CTransaction()
+ assert(n < len(prevtx.vout))
+ tx.vin.append(CTxIn(COutPoint(prevtx.sha256, n), sig, 0xffffffff))
+ tx.vout.append(CTxOut(value, ""))
+ tx.calc_sha256()
+ return tx
diff --git a/qa/rpc-tests/test_framework/comptool.py b/qa/rpc-tests/test_framework/comptool.py
new file mode 100755
index 0000000000..24ae05807a
--- /dev/null
+++ b/qa/rpc-tests/test_framework/comptool.py
@@ -0,0 +1,343 @@
+#!/usr/bin/env python2
+#
+# Distributed under the MIT/X11 software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#
+
+from mininode import *
+from blockstore import BlockStore, TxStore
+from util import p2p_port
+
+'''
+This is a tool for comparing two or more bitcoinds to each other
+using a script provided.
+
+To use, create a class that implements get_tests(), and pass it in
+as the test generator to TestManager. get_tests() should be a python
+generator that returns TestInstance objects. See below for definition.
+'''
+
+# TestNode behaves as follows:
+# Configure with a BlockStore and TxStore
+# on_inv: log the message but don't request
+# on_headers: log the chain tip
+# on_pong: update ping response map (for synchronization)
+# on_getheaders: provide headers via BlockStore
+# on_getdata: provide blocks via BlockStore
+
+global mininode_lock
+
+def wait_until(predicate, attempts=float('inf'), timeout=float('inf')):
+ attempt = 0
+ elapsed = 0
+
+ while attempt < attempts and elapsed < timeout:
+ with mininode_lock:
+ if predicate():
+ return True
+ attempt += 1
+ elapsed += 0.05
+ time.sleep(0.05)
+
+ return False
+
+class TestNode(NodeConnCB):
+
+ def __init__(self, block_store, tx_store):
+ NodeConnCB.__init__(self)
+ self.create_callback_map()
+ self.conn = None
+ self.bestblockhash = None
+ self.block_store = block_store
+ self.block_request_map = {}
+ self.tx_store = tx_store
+ self.tx_request_map = {}
+
+ # When the pingmap is non-empty we're waiting for
+ # a response
+ self.pingMap = {}
+ self.lastInv = []
+ self.closed = False
+
+ def on_close(self, conn):
+ self.closed = True
+
+ def add_connection(self, conn):
+ self.conn = conn
+
+ def on_headers(self, conn, message):
+ if len(message.headers) > 0:
+ best_header = message.headers[-1]
+ best_header.calc_sha256()
+ self.bestblockhash = best_header.sha256
+
+ def on_getheaders(self, conn, message):
+ response = self.block_store.headers_for(message.locator, message.hashstop)
+ if response is not None:
+ conn.send_message(response)
+
+ def on_getdata(self, conn, message):
+ [conn.send_message(r) for r in self.block_store.get_blocks(message.inv)]
+ [conn.send_message(r) for r in self.tx_store.get_transactions(message.inv)]
+
+ for i in message.inv:
+ if i.type == 1:
+ self.tx_request_map[i.hash] = True
+ elif i.type == 2:
+ self.block_request_map[i.hash] = True
+
+ def on_inv(self, conn, message):
+ self.lastInv = [x.hash for x in message.inv]
+
+ def on_pong(self, conn, message):
+ try:
+ del self.pingMap[message.nonce]
+ except KeyError:
+ raise AssertionError("Got pong for unknown ping [%s]" % repr(message))
+
+ def send_inv(self, obj):
+ mtype = 2 if isinstance(obj, CBlock) else 1
+ self.conn.send_message(msg_inv([CInv(mtype, obj.sha256)]))
+
+ def send_getheaders(self):
+ # We ask for headers from their last tip.
+ m = msg_getheaders()
+ m.locator = self.block_store.get_locator(self.bestblockhash)
+ self.conn.send_message(m)
+
+ # This assumes BIP31
+ def send_ping(self, nonce):
+ self.pingMap[nonce] = True
+ self.conn.send_message(msg_ping(nonce))
+
+ def received_ping_response(self, nonce):
+ return nonce not in self.pingMap
+
+ def send_mempool(self):
+ self.lastInv = []
+ self.conn.send_message(msg_mempool())
+
+# TestInstance:
+#
+# Instances of these are generated by the test generator, and fed into the
+# comptool.
+#
+# "blocks_and_transactions" should be an array of [obj, True/False/None]:
+# - obj is either a CBlock or a CTransaction, and
+# - the second value indicates whether the object should be accepted
+# into the blockchain or mempool (for tests where we expect a certain
+# answer), or "None" if we don't expect a certain answer and are just
+# comparing the behavior of the nodes being tested.
+# sync_every_block: if True, then each block will be inv'ed, synced, and
+# nodes will be tested based on the outcome for the block. If False,
+# then inv's accumulate until all blocks are processed (or max inv size
+# is reached) and then sent out in one inv message. Then the final block
+# will be synced across all connections, and the outcome of the final
+# block will be tested.
+# sync_every_tx: analogous to behavior for sync_every_block, except if outcome
+# on the final tx is None, then contents of entire mempool are compared
+# across all connections. (If outcome of final tx is specified as true
+# or false, then only the last tx is tested against outcome.)
+
+class TestInstance(object):
+ def __init__(self, objects=[], sync_every_block=True, sync_every_tx=False):
+ self.blocks_and_transactions = objects
+ self.sync_every_block = sync_every_block
+ self.sync_every_tx = sync_every_tx
+
+class TestManager(object):
+
+ def __init__(self, testgen, datadir):
+ self.test_generator = testgen
+ self.connections = []
+ self.test_nodes = []
+ self.block_store = BlockStore(datadir)
+ self.tx_store = TxStore(datadir)
+ self.ping_counter = 1
+
+ def add_all_connections(self, nodes):
+ for i in range(len(nodes)):
+ # Create a p2p connection to each node
+ test_node = TestNode(self.block_store, self.tx_store)
+ self.test_nodes.append(test_node)
+ self.connections.append(NodeConn('127.0.0.1', p2p_port(i), nodes[i], test_node))
+ # Make sure the TestNode (callback class) has a reference to its
+ # associated NodeConn
+ test_node.add_connection(self.connections[-1])
+
+ def wait_for_disconnections(self):
+ def disconnected():
+ return all(node.closed for node in self.test_nodes)
+ return wait_until(disconnected, timeout=10)
+
+ def wait_for_verack(self):
+ def veracked():
+ return all(node.verack_received for node in self.test_nodes)
+ return wait_until(veracked, timeout=10)
+
+ def wait_for_pings(self, counter):
+ def received_pongs():
+ return all(node.received_ping_response(counter) for node in self.test_nodes)
+ return wait_until(received_pongs)
+
+ # sync_blocks: Wait for all connections to request the blockhash given
+ # then send get_headers to find out the tip of each node, and synchronize
+ # the response by using a ping (and waiting for pong with same nonce).
+ def sync_blocks(self, blockhash, num_blocks):
+ def blocks_requested():
+ return all(
+ blockhash in node.block_request_map and node.block_request_map[blockhash]
+ for node in self.test_nodes
+ )
+
+ # --> error if not requested
+ if not wait_until(blocks_requested, attempts=20*num_blocks):
+ # print [ c.cb.block_request_map for c in self.connections ]
+ raise AssertionError("Not all nodes requested block")
+ # --> Answer request (we did this inline!)
+
+ # Send getheaders message
+ [ c.cb.send_getheaders() for c in self.connections ]
+
+ # Send ping and wait for response -- synchronization hack
+ [ c.cb.send_ping(self.ping_counter) for c in self.connections ]
+ self.wait_for_pings(self.ping_counter)
+ self.ping_counter += 1
+
+ # Analogous to sync_block (see above)
+ def sync_transaction(self, txhash, num_events):
+ # Wait for nodes to request transaction (50ms sleep * 20 tries * num_events)
+ def transaction_requested():
+ return all(
+ txhash in node.tx_request_map and node.tx_request_map[txhash]
+ for node in self.test_nodes
+ )
+
+ # --> error if not requested
+ if not wait_until(transaction_requested, attempts=20*num_events):
+ # print [ c.cb.tx_request_map for c in self.connections ]
+ raise AssertionError("Not all nodes requested transaction")
+ # --> Answer request (we did this inline!)
+
+ # Get the mempool
+ [ c.cb.send_mempool() for c in self.connections ]
+
+ # Send ping and wait for response -- synchronization hack
+ [ c.cb.send_ping(self.ping_counter) for c in self.connections ]
+ self.wait_for_pings(self.ping_counter)
+ self.ping_counter += 1
+
+ # Sort inv responses from each node
+ with mininode_lock:
+ [ c.cb.lastInv.sort() for c in self.connections ]
+
+ # Verify that the tip of each connection all agree with each other, and
+ # with the expected outcome (if given)
+ def check_results(self, blockhash, outcome):
+ with mininode_lock:
+ for c in self.connections:
+ if outcome is None:
+ if c.cb.bestblockhash != self.connections[0].cb.bestblockhash:
+ return False
+ elif ((c.cb.bestblockhash == blockhash) != outcome):
+ # print c.cb.bestblockhash, blockhash, outcome
+ return False
+ return True
+
+ # Either check that the mempools all agree with each other, or that
+ # txhash's presence in the mempool matches the outcome specified.
+ # This is somewhat of a strange comparison, in that we're either comparing
+ # a particular tx to an outcome, or the entire mempools altogether;
+ # perhaps it would be useful to add the ability to check explicitly that
+ # a particular tx's existence in the mempool is the same across all nodes.
+ def check_mempool(self, txhash, outcome):
+ with mininode_lock:
+ for c in self.connections:
+ if outcome is None:
+ # Make sure the mempools agree with each other
+ if c.cb.lastInv != self.connections[0].cb.lastInv:
+ # print c.rpc.getrawmempool()
+ return False
+ elif ((txhash in c.cb.lastInv) != outcome):
+ # print c.rpc.getrawmempool(), c.cb.lastInv
+ return False
+ return True
+
+ def run(self):
+ # Wait until verack is received
+ self.wait_for_verack()
+
+ test_number = 1
+ for test_instance in self.test_generator.get_tests():
+ # We use these variables to keep track of the last block
+ # and last transaction in the tests, which are used
+ # if we're not syncing on every block or every tx.
+ [ block, block_outcome ] = [ None, None ]
+ [ tx, tx_outcome ] = [ None, None ]
+ invqueue = []
+
+ for b_or_t, outcome in test_instance.blocks_and_transactions:
+ # Determine if we're dealing with a block or tx
+ if isinstance(b_or_t, CBlock): # Block test runner
+ block = b_or_t
+ block_outcome = outcome
+ # Add to shared block_store, set as current block
+ with mininode_lock:
+ self.block_store.add_block(block)
+ for c in self.connections:
+ c.cb.block_request_map[block.sha256] = False
+ # Either send inv's to each node and sync, or add
+ # to invqueue for later inv'ing.
+ if (test_instance.sync_every_block):
+ [ c.cb.send_inv(block) for c in self.connections ]
+ self.sync_blocks(block.sha256, 1)
+ if (not self.check_results(block.sha256, outcome)):
+ raise AssertionError("Test failed at test %d" % test_number)
+ else:
+ invqueue.append(CInv(2, block.sha256))
+ else: # Tx test runner
+ assert(isinstance(b_or_t, CTransaction))
+ tx = b_or_t
+ tx_outcome = outcome
+ # Add to shared tx store and clear map entry
+ with mininode_lock:
+ self.tx_store.add_transaction(tx)
+ for c in self.connections:
+ c.cb.tx_request_map[tx.sha256] = False
+ # Again, either inv to all nodes or save for later
+ if (test_instance.sync_every_tx):
+ [ c.cb.send_inv(tx) for c in self.connections ]
+ self.sync_transaction(tx.sha256, 1)
+ if (not self.check_mempool(tx.sha256, outcome)):
+ raise AssertionError("Test failed at test %d" % test_number)
+ else:
+ invqueue.append(CInv(1, tx.sha256))
+ # Ensure we're not overflowing the inv queue
+ if len(invqueue) == MAX_INV_SZ:
+ [ c.send_message(msg_inv(invqueue)) for c in self.connections ]
+ invqueue = []
+
+ # Do final sync if we weren't syncing on every block or every tx.
+ if (not test_instance.sync_every_block and block is not None):
+ if len(invqueue) > 0:
+ [ c.send_message(msg_inv(invqueue)) for c in self.connections ]
+ invqueue = []
+ self.sync_blocks(block.sha256,
+ len(test_instance.blocks_and_transactions))
+ if (not self.check_results(block.sha256, block_outcome)):
+ raise AssertionError("Block test failed at test %d" % test_number)
+ if (not test_instance.sync_every_tx and tx is not None):
+ if len(invqueue) > 0:
+ [ c.send_message(msg_inv(invqueue)) for c in self.connections ]
+ invqueue = []
+ self.sync_transaction(tx.sha256, len(test_instance.blocks_and_transactions))
+ if (not self.check_mempool(tx.sha256, tx_outcome)):
+ raise AssertionError("Mempool test failed at test %d" % test_number)
+
+ print "Test %d: PASS" % test_number, [ c.rpc.getblockcount() for c in self.connections ]
+ test_number += 1
+
+ [ c.disconnect_node() for c in self.connections ]
+ self.wait_for_disconnections()
+ self.block_store.close()
+ self.tx_store.close()
diff --git a/qa/rpc-tests/test_framework/mininode.py b/qa/rpc-tests/test_framework/mininode.py
new file mode 100755
index 0000000000..b7d78e74fa
--- /dev/null
+++ b/qa/rpc-tests/test_framework/mininode.py
@@ -0,0 +1,1256 @@
+# mininode.py - Bitcoin P2P network half-a-node
+#
+# Distributed under the MIT/X11 software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#
+# This python code was modified from ArtForz' public domain half-a-node, as
+# found in the mini-node branch of http://github.com/jgarzik/pynode.
+#
+# NodeConn: an object which manages p2p connectivity to a bitcoin node
+# NodeConnCB: a base class that describes the interface for receiving
+# callbacks with network messages from a NodeConn
+# CBlock, CTransaction, CBlockHeader, CTxIn, CTxOut, etc....:
+# data structures that should map to corresponding structures in
+# bitcoin/primitives
+# msg_block, msg_tx, msg_headers, etc.:
+# data structures that represent network messages
+# ser_*, deser_*: functions that handle serialization/deserialization
+
+
+import struct
+import socket
+import asyncore
+import binascii
+import time
+import sys
+import random
+import cStringIO
+import hashlib
+from threading import RLock
+from threading import Thread
+import logging
+import copy
+
+BIP0031_VERSION = 60000
+MY_VERSION = 60001 # past bip-31 for ping/pong
+MY_SUBVERSION = "/python-mininode-tester:0.0.1/"
+
+MAX_INV_SZ = 50000
+
+# Keep our own socket map for asyncore, so that we can track disconnects
+# ourselves (to workaround an issue with closing an asyncore socket when
+# using select)
+mininode_socket_map = dict()
+
+# One lock for synchronizing all data access between the networking thread (see
+# NetworkThread below) and the thread running the test logic. For simplicity,
+# NodeConn acquires this lock whenever delivering a message to to a NodeConnCB,
+# and whenever adding anything to the send buffer (in send_message()). This
+# lock should be acquired in the thread running the test logic to synchronize
+# access to any data shared with the NodeConnCB or NodeConn.
+mininode_lock = RLock()
+
+# Serialization/deserialization tools
+def sha256(s):
+ return hashlib.new('sha256', s).digest()
+
+
+def hash256(s):
+ return sha256(sha256(s))
+
+
+def deser_string(f):
+ nit = struct.unpack("<B", f.read(1))[0]
+ if nit == 253:
+ nit = struct.unpack("<H", f.read(2))[0]
+ elif nit == 254:
+ nit = struct.unpack("<I", f.read(4))[0]
+ elif nit == 255:
+ nit = struct.unpack("<Q", f.read(8))[0]
+ return f.read(nit)
+
+
+def ser_string(s):
+ if len(s) < 253:
+ return chr(len(s)) + s
+ elif len(s) < 0x10000:
+ return chr(253) + struct.pack("<H", len(s)) + s
+ elif len(s) < 0x100000000L:
+ return chr(254) + struct.pack("<I", len(s)) + s
+ return chr(255) + struct.pack("<Q", len(s)) + s
+
+
+def deser_uint256(f):
+ r = 0L
+ for i in xrange(8):
+ t = struct.unpack("<I", f.read(4))[0]
+ r += t << (i * 32)
+ return r
+
+
+def ser_uint256(u):
+ rs = ""
+ for i in xrange(8):
+ rs += struct.pack("<I", u & 0xFFFFFFFFL)
+ u >>= 32
+ return rs
+
+
+def uint256_from_str(s):
+ r = 0L
+ t = struct.unpack("<IIIIIIII", s[:32])
+ for i in xrange(8):
+ r += t[i] << (i * 32)
+ return r
+
+
+def uint256_from_compact(c):
+ nbytes = (c >> 24) & 0xFF
+ v = (c & 0xFFFFFFL) << (8 * (nbytes - 3))
+ return v
+
+
+def deser_vector(f, c):
+ nit = struct.unpack("<B", f.read(1))[0]
+ if nit == 253:
+ nit = struct.unpack("<H", f.read(2))[0]
+ elif nit == 254:
+ nit = struct.unpack("<I", f.read(4))[0]
+ elif nit == 255:
+ nit = struct.unpack("<Q", f.read(8))[0]
+ r = []
+ for i in xrange(nit):
+ t = c()
+ t.deserialize(f)
+ r.append(t)
+ return r
+
+
+def ser_vector(l):
+ r = ""
+ if len(l) < 253:
+ r = chr(len(l))
+ elif len(l) < 0x10000:
+ r = chr(253) + struct.pack("<H", len(l))
+ elif len(l) < 0x100000000L:
+ r = chr(254) + struct.pack("<I", len(l))
+ else:
+ r = chr(255) + struct.pack("<Q", len(l))
+ for i in l:
+ r += i.serialize()
+ return r
+
+
+def deser_uint256_vector(f):
+ nit = struct.unpack("<B", f.read(1))[0]
+ if nit == 253:
+ nit = struct.unpack("<H", f.read(2))[0]
+ elif nit == 254:
+ nit = struct.unpack("<I", f.read(4))[0]
+ elif nit == 255:
+ nit = struct.unpack("<Q", f.read(8))[0]
+ r = []
+ for i in xrange(nit):
+ t = deser_uint256(f)
+ r.append(t)
+ return r
+
+
+def ser_uint256_vector(l):
+ r = ""
+ if len(l) < 253:
+ r = chr(len(l))
+ elif len(l) < 0x10000:
+ r = chr(253) + struct.pack("<H", len(l))
+ elif len(l) < 0x100000000L:
+ r = chr(254) + struct.pack("<I", len(l))
+ else:
+ r = chr(255) + struct.pack("<Q", len(l))
+ for i in l:
+ r += ser_uint256(i)
+ return r
+
+
+def deser_string_vector(f):
+ nit = struct.unpack("<B", f.read(1))[0]
+ if nit == 253:
+ nit = struct.unpack("<H", f.read(2))[0]
+ elif nit == 254:
+ nit = struct.unpack("<I", f.read(4))[0]
+ elif nit == 255:
+ nit = struct.unpack("<Q", f.read(8))[0]
+ r = []
+ for i in xrange(nit):
+ t = deser_string(f)
+ r.append(t)
+ return r
+
+
+def ser_string_vector(l):
+ r = ""
+ if len(l) < 253:
+ r = chr(len(l))
+ elif len(l) < 0x10000:
+ r = chr(253) + struct.pack("<H", len(l))
+ elif len(l) < 0x100000000L:
+ r = chr(254) + struct.pack("<I", len(l))
+ else:
+ r = chr(255) + struct.pack("<Q", len(l))
+ for sv in l:
+ r += ser_string(sv)
+ return r
+
+
+def deser_int_vector(f):
+ nit = struct.unpack("<B", f.read(1))[0]
+ if nit == 253:
+ nit = struct.unpack("<H", f.read(2))[0]
+ elif nit == 254:
+ nit = struct.unpack("<I", f.read(4))[0]
+ elif nit == 255:
+ nit = struct.unpack("<Q", f.read(8))[0]
+ r = []
+ for i in xrange(nit):
+ t = struct.unpack("<i", f.read(4))[0]
+ r.append(t)
+ return r
+
+
+def ser_int_vector(l):
+ r = ""
+ if len(l) < 253:
+ r = chr(len(l))
+ elif len(l) < 0x10000:
+ r = chr(253) + struct.pack("<H", len(l))
+ elif len(l) < 0x100000000L:
+ r = chr(254) + struct.pack("<I", len(l))
+ else:
+ r = chr(255) + struct.pack("<Q", len(l))
+ for i in l:
+ r += struct.pack("<i", i)
+ return r
+
+
+# Objects that map to bitcoind objects, which can be serialized/deserialized
+
+class CAddress(object):
+ def __init__(self):
+ self.nServices = 1
+ self.pchReserved = "\x00" * 10 + "\xff" * 2
+ self.ip = "0.0.0.0"
+ self.port = 0
+
+ def deserialize(self, f):
+ self.nServices = struct.unpack("<Q", f.read(8))[0]
+ self.pchReserved = f.read(12)
+ self.ip = socket.inet_ntoa(f.read(4))
+ self.port = struct.unpack(">H", f.read(2))[0]
+
+ def serialize(self):
+ r = ""
+ r += struct.pack("<Q", self.nServices)
+ r += self.pchReserved
+ r += socket.inet_aton(self.ip)
+ r += struct.pack(">H", self.port)
+ return r
+
+ def __repr__(self):
+ return "CAddress(nServices=%i ip=%s port=%i)" % (self.nServices,
+ self.ip, self.port)
+
+
+class CInv(object):
+ typemap = {
+ 0: "Error",
+ 1: "TX",
+ 2: "Block"}
+
+ def __init__(self, t=0, h=0L):
+ self.type = t
+ self.hash = h
+
+ def deserialize(self, f):
+ self.type = struct.unpack("<i", f.read(4))[0]
+ self.hash = deser_uint256(f)
+
+ def serialize(self):
+ r = ""
+ r += struct.pack("<i", self.type)
+ r += ser_uint256(self.hash)
+ return r
+
+ def __repr__(self):
+ return "CInv(type=%s hash=%064x)" \
+ % (self.typemap[self.type], self.hash)
+
+
+class CBlockLocator(object):
+ def __init__(self):
+ self.nVersion = MY_VERSION
+ self.vHave = []
+
+ def deserialize(self, f):
+ self.nVersion = struct.unpack("<i", f.read(4))[0]
+ self.vHave = deser_uint256_vector(f)
+
+ def serialize(self):
+ r = ""
+ r += struct.pack("<i", self.nVersion)
+ r += ser_uint256_vector(self.vHave)
+ return r
+
+ def __repr__(self):
+ return "CBlockLocator(nVersion=%i vHave=%s)" \
+ % (self.nVersion, repr(self.vHave))
+
+
+class COutPoint(object):
+ def __init__(self, hash=0, n=0):
+ self.hash = hash
+ self.n = n
+
+ def deserialize(self, f):
+ self.hash = deser_uint256(f)
+ self.n = struct.unpack("<I", f.read(4))[0]
+
+ def serialize(self):
+ r = ""
+ r += ser_uint256(self.hash)
+ r += struct.pack("<I", self.n)
+ return r
+
+ def __repr__(self):
+ return "COutPoint(hash=%064x n=%i)" % (self.hash, self.n)
+
+
+class CTxIn(object):
+ def __init__(self, outpoint=None, scriptSig="", nSequence=0):
+ if outpoint is None:
+ self.prevout = COutPoint()
+ else:
+ self.prevout = outpoint
+ self.scriptSig = scriptSig
+ self.nSequence = nSequence
+
+ def deserialize(self, f):
+ self.prevout = COutPoint()
+ self.prevout.deserialize(f)
+ self.scriptSig = deser_string(f)
+ self.nSequence = struct.unpack("<I", f.read(4))[0]
+
+ def serialize(self):
+ r = ""
+ r += self.prevout.serialize()
+ r += ser_string(self.scriptSig)
+ r += struct.pack("<I", self.nSequence)
+ return r
+
+ def __repr__(self):
+ return "CTxIn(prevout=%s scriptSig=%s nSequence=%i)" \
+ % (repr(self.prevout), binascii.hexlify(self.scriptSig),
+ self.nSequence)
+
+
+class CTxOut(object):
+ def __init__(self, nValue=0, scriptPubKey=""):
+ self.nValue = nValue
+ self.scriptPubKey = scriptPubKey
+
+ def deserialize(self, f):
+ self.nValue = struct.unpack("<q", f.read(8))[0]
+ self.scriptPubKey = deser_string(f)
+
+ def serialize(self):
+ r = ""
+ r += struct.pack("<q", self.nValue)
+ r += ser_string(self.scriptPubKey)
+ return r
+
+ def __repr__(self):
+ return "CTxOut(nValue=%i.%08i scriptPubKey=%s)" \
+ % (self.nValue // 100000000, self.nValue % 100000000,
+ binascii.hexlify(self.scriptPubKey))
+
+
+class CTransaction(object):
+ def __init__(self, tx=None):
+ if tx is None:
+ self.nVersion = 1
+ self.vin = []
+ self.vout = []
+ self.nLockTime = 0
+ self.sha256 = None
+ self.hash = None
+ else:
+ self.nVersion = tx.nVersion
+ self.vin = copy.deepcopy(tx.vin)
+ self.vout = copy.deepcopy(tx.vout)
+ self.nLockTime = tx.nLockTime
+ self.sha256 = None
+ self.hash = None
+
+ def deserialize(self, f):
+ self.nVersion = struct.unpack("<i", f.read(4))[0]
+ self.vin = deser_vector(f, CTxIn)
+ self.vout = deser_vector(f, CTxOut)
+ self.nLockTime = struct.unpack("<I", f.read(4))[0]
+ self.sha256 = None
+ self.hash = None
+
+ def serialize(self):
+ r = ""
+ r += struct.pack("<i", self.nVersion)
+ r += ser_vector(self.vin)
+ r += ser_vector(self.vout)
+ r += struct.pack("<I", self.nLockTime)
+ return r
+
+ def rehash(self):
+ self.sha256 = None
+ self.calc_sha256()
+
+ def calc_sha256(self):
+ if self.sha256 is None:
+ self.sha256 = uint256_from_str(hash256(self.serialize()))
+ self.hash = hash256(self.serialize())[::-1].encode('hex_codec')
+
+ def is_valid(self):
+ self.calc_sha256()
+ for tout in self.vout:
+ if tout.nValue < 0 or tout.nValue > 21000000L * 100000000L:
+ return False
+ return True
+
+ def __repr__(self):
+ return "CTransaction(nVersion=%i vin=%s vout=%s nLockTime=%i)" \
+ % (self.nVersion, repr(self.vin), repr(self.vout), self.nLockTime)
+
+
+class CBlockHeader(object):
+ def __init__(self, header=None):
+ if header is None:
+ self.set_null()
+ else:
+ self.nVersion = header.nVersion
+ self.hashPrevBlock = header.hashPrevBlock
+ self.hashMerkleRoot = header.hashMerkleRoot
+ self.nTime = header.nTime
+ self.nBits = header.nBits
+ self.nNonce = header.nNonce
+ self.sha256 = header.sha256
+ self.hash = header.hash
+ self.calc_sha256()
+
+ def set_null(self):
+ self.nVersion = 1
+ self.hashPrevBlock = 0
+ self.hashMerkleRoot = 0
+ self.nTime = 0
+ self.nBits = 0
+ self.nNonce = 0
+ self.sha256 = None
+ self.hash = None
+
+ def deserialize(self, f):
+ self.nVersion = struct.unpack("<i", f.read(4))[0]
+ self.hashPrevBlock = deser_uint256(f)
+ self.hashMerkleRoot = deser_uint256(f)
+ self.nTime = struct.unpack("<I", f.read(4))[0]
+ self.nBits = struct.unpack("<I", f.read(4))[0]
+ self.nNonce = struct.unpack("<I", f.read(4))[0]
+ self.sha256 = None
+ self.hash = None
+
+ def serialize(self):
+ r = ""
+ r += struct.pack("<i", self.nVersion)
+ r += ser_uint256(self.hashPrevBlock)
+ r += ser_uint256(self.hashMerkleRoot)
+ r += struct.pack("<I", self.nTime)
+ r += struct.pack("<I", self.nBits)
+ r += struct.pack("<I", self.nNonce)
+ return r
+
+ def calc_sha256(self):
+ if self.sha256 is None:
+ r = ""
+ r += struct.pack("<i", self.nVersion)
+ r += ser_uint256(self.hashPrevBlock)
+ r += ser_uint256(self.hashMerkleRoot)
+ r += struct.pack("<I", self.nTime)
+ r += struct.pack("<I", self.nBits)
+ r += struct.pack("<I", self.nNonce)
+ self.sha256 = uint256_from_str(hash256(r))
+ self.hash = hash256(r)[::-1].encode('hex_codec')
+
+ def rehash(self):
+ self.sha256 = None
+ self.calc_sha256()
+ return self.sha256
+
+ def __repr__(self):
+ return "CBlockHeader(nVersion=%i hashPrevBlock=%064x hashMerkleRoot=%064x nTime=%s nBits=%08x nNonce=%08x)" \
+ % (self.nVersion, self.hashPrevBlock, self.hashMerkleRoot,
+ time.ctime(self.nTime), self.nBits, self.nNonce)
+
+
+class CBlock(CBlockHeader):
+ def __init__(self, header=None):
+ super(CBlock, self).__init__(header)
+ self.vtx = []
+
+ def deserialize(self, f):
+ super(CBlock, self).deserialize(f)
+ self.vtx = deser_vector(f, CTransaction)
+
+ def serialize(self):
+ r = ""
+ r += super(CBlock, self).serialize()
+ r += ser_vector(self.vtx)
+ return r
+
+ def calc_merkle_root(self):
+ hashes = []
+ for tx in self.vtx:
+ tx.calc_sha256()
+ hashes.append(ser_uint256(tx.sha256))
+ while len(hashes) > 1:
+ newhashes = []
+ for i in xrange(0, len(hashes), 2):
+ i2 = min(i+1, len(hashes)-1)
+ newhashes.append(hash256(hashes[i] + hashes[i2]))
+ hashes = newhashes
+ return uint256_from_str(hashes[0])
+
+ def is_valid(self):
+ self.calc_sha256()
+ target = uint256_from_compact(self.nBits)
+ if self.sha256 > target:
+ return False
+ for tx in self.vtx:
+ if not tx.is_valid():
+ return False
+ if self.calc_merkle_root() != self.hashMerkleRoot:
+ return False
+ return True
+
+ def solve(self):
+ self.calc_sha256()
+ target = uint256_from_compact(self.nBits)
+ while self.sha256 > target:
+ self.nNonce += 1
+ self.rehash()
+
+ def __repr__(self):
+ return "CBlock(nVersion=%i hashPrevBlock=%064x hashMerkleRoot=%064x nTime=%s nBits=%08x nNonce=%08x vtx=%s)" \
+ % (self.nVersion, self.hashPrevBlock, self.hashMerkleRoot,
+ time.ctime(self.nTime), self.nBits, self.nNonce, repr(self.vtx))
+
+
+class CUnsignedAlert(object):
+ def __init__(self):
+ self.nVersion = 1
+ self.nRelayUntil = 0
+ self.nExpiration = 0
+ self.nID = 0
+ self.nCancel = 0
+ self.setCancel = []
+ self.nMinVer = 0
+ self.nMaxVer = 0
+ self.setSubVer = []
+ self.nPriority = 0
+ self.strComment = ""
+ self.strStatusBar = ""
+ self.strReserved = ""
+
+ def deserialize(self, f):
+ self.nVersion = struct.unpack("<i", f.read(4))[0]
+ self.nRelayUntil = struct.unpack("<q", f.read(8))[0]
+ self.nExpiration = struct.unpack("<q", f.read(8))[0]
+ self.nID = struct.unpack("<i", f.read(4))[0]
+ self.nCancel = struct.unpack("<i", f.read(4))[0]
+ self.setCancel = deser_int_vector(f)
+ self.nMinVer = struct.unpack("<i", f.read(4))[0]
+ self.nMaxVer = struct.unpack("<i", f.read(4))[0]
+ self.setSubVer = deser_string_vector(f)
+ self.nPriority = struct.unpack("<i", f.read(4))[0]
+ self.strComment = deser_string(f)
+ self.strStatusBar = deser_string(f)
+ self.strReserved = deser_string(f)
+
+ def serialize(self):
+ r = ""
+ r += struct.pack("<i", self.nVersion)
+ r += struct.pack("<q", self.nRelayUntil)
+ r += struct.pack("<q", self.nExpiration)
+ r += struct.pack("<i", self.nID)
+ r += struct.pack("<i", self.nCancel)
+ r += ser_int_vector(self.setCancel)
+ r += struct.pack("<i", self.nMinVer)
+ r += struct.pack("<i", self.nMaxVer)
+ r += ser_string_vector(self.setSubVer)
+ r += struct.pack("<i", self.nPriority)
+ r += ser_string(self.strComment)
+ r += ser_string(self.strStatusBar)
+ r += ser_string(self.strReserved)
+ return r
+
+ def __repr__(self):
+ return "CUnsignedAlert(nVersion %d, nRelayUntil %d, nExpiration %d, nID %d, nCancel %d, nMinVer %d, nMaxVer %d, nPriority %d, strComment %s, strStatusBar %s, strReserved %s)" \
+ % (self.nVersion, self.nRelayUntil, self.nExpiration, self.nID,
+ self.nCancel, self.nMinVer, self.nMaxVer, self.nPriority,
+ self.strComment, self.strStatusBar, self.strReserved)
+
+
+class CAlert(object):
+ def __init__(self):
+ self.vchMsg = ""
+ self.vchSig = ""
+
+ def deserialize(self, f):
+ self.vchMsg = deser_string(f)
+ self.vchSig = deser_string(f)
+
+ def serialize(self):
+ r = ""
+ r += ser_string(self.vchMsg)
+ r += ser_string(self.vchSig)
+ return r
+
+ def __repr__(self):
+ return "CAlert(vchMsg.sz %d, vchSig.sz %d)" \
+ % (len(self.vchMsg), len(self.vchSig))
+
+
+# Objects that correspond to messages on the wire
+class msg_version(object):
+ command = "version"
+
+ def __init__(self):
+ self.nVersion = MY_VERSION
+ self.nServices = 1
+ self.nTime = time.time()
+ self.addrTo = CAddress()
+ self.addrFrom = CAddress()
+ self.nNonce = random.getrandbits(64)
+ self.strSubVer = MY_SUBVERSION
+ self.nStartingHeight = -1
+
+ def deserialize(self, f):
+ self.nVersion = struct.unpack("<i", f.read(4))[0]
+ if self.nVersion == 10300:
+ self.nVersion = 300
+ self.nServices = struct.unpack("<Q", f.read(8))[0]
+ self.nTime = struct.unpack("<q", f.read(8))[0]
+ self.addrTo = CAddress()
+ self.addrTo.deserialize(f)
+ if self.nVersion >= 106:
+ self.addrFrom = CAddress()
+ self.addrFrom.deserialize(f)
+ self.nNonce = struct.unpack("<Q", f.read(8))[0]
+ self.strSubVer = deser_string(f)
+ if self.nVersion >= 209:
+ self.nStartingHeight = struct.unpack("<i", f.read(4))[0]
+ else:
+ self.nStartingHeight = None
+ else:
+ self.addrFrom = None
+ self.nNonce = None
+ self.strSubVer = None
+ self.nStartingHeight = None
+
+ def serialize(self):
+ r = ""
+ r += struct.pack("<i", self.nVersion)
+ r += struct.pack("<Q", self.nServices)
+ r += struct.pack("<q", self.nTime)
+ r += self.addrTo.serialize()
+ r += self.addrFrom.serialize()
+ r += struct.pack("<Q", self.nNonce)
+ r += ser_string(self.strSubVer)
+ r += struct.pack("<i", self.nStartingHeight)
+ return r
+
+ def __repr__(self):
+ return 'msg_version(nVersion=%i nServices=%i nTime=%s addrTo=%s addrFrom=%s nNonce=0x%016X strSubVer=%s nStartingHeight=%i)' \
+ % (self.nVersion, self.nServices, time.ctime(self.nTime),
+ repr(self.addrTo), repr(self.addrFrom), self.nNonce,
+ self.strSubVer, self.nStartingHeight)
+
+
+class msg_verack(object):
+ command = "verack"
+
+ def __init__(self):
+ pass
+
+ def deserialize(self, f):
+ pass
+
+ def serialize(self):
+ return ""
+
+ def __repr__(self):
+ return "msg_verack()"
+
+
+class msg_addr(object):
+ command = "addr"
+
+ def __init__(self):
+ self.addrs = []
+
+ def deserialize(self, f):
+ self.addrs = deser_vector(f, CAddress)
+
+ def serialize(self):
+ return ser_vector(self.addrs)
+
+ def __repr__(self):
+ return "msg_addr(addrs=%s)" % (repr(self.addrs))
+
+
+class msg_alert(object):
+ command = "alert"
+
+ def __init__(self):
+ self.alert = CAlert()
+
+ def deserialize(self, f):
+ self.alert = CAlert()
+ self.alert.deserialize(f)
+
+ def serialize(self):
+ r = ""
+ r += self.alert.serialize()
+ return r
+
+ def __repr__(self):
+ return "msg_alert(alert=%s)" % (repr(self.alert), )
+
+
+class msg_inv(object):
+ command = "inv"
+
+ def __init__(self, inv=None):
+ if inv is None:
+ self.inv = []
+ else:
+ self.inv = inv
+
+ def deserialize(self, f):
+ self.inv = deser_vector(f, CInv)
+
+ def serialize(self):
+ return ser_vector(self.inv)
+
+ def __repr__(self):
+ return "msg_inv(inv=%s)" % (repr(self.inv))
+
+
+class msg_getdata(object):
+ command = "getdata"
+
+ def __init__(self):
+ self.inv = []
+
+ def deserialize(self, f):
+ self.inv = deser_vector(f, CInv)
+
+ def serialize(self):
+ return ser_vector(self.inv)
+
+ def __repr__(self):
+ return "msg_getdata(inv=%s)" % (repr(self.inv))
+
+
+class msg_getblocks(object):
+ command = "getblocks"
+
+ def __init__(self):
+ self.locator = CBlockLocator()
+ self.hashstop = 0L
+
+ def deserialize(self, f):
+ self.locator = CBlockLocator()
+ self.locator.deserialize(f)
+ self.hashstop = deser_uint256(f)
+
+ def serialize(self):
+ r = ""
+ r += self.locator.serialize()
+ r += ser_uint256(self.hashstop)
+ return r
+
+ def __repr__(self):
+ return "msg_getblocks(locator=%s hashstop=%064x)" \
+ % (repr(self.locator), self.hashstop)
+
+
+class msg_tx(object):
+ command = "tx"
+
+ def __init__(self, tx=CTransaction()):
+ self.tx = tx
+
+ def deserialize(self, f):
+ self.tx.deserialize(f)
+
+ def serialize(self):
+ return self.tx.serialize()
+
+ def __repr__(self):
+ return "msg_tx(tx=%s)" % (repr(self.tx))
+
+
+class msg_block(object):
+ command = "block"
+
+ def __init__(self, block=None):
+ if block is None:
+ self.block = CBlock()
+ else:
+ self.block = block
+
+ def deserialize(self, f):
+ self.block.deserialize(f)
+
+ def serialize(self):
+ return self.block.serialize()
+
+ def __repr__(self):
+ return "msg_block(block=%s)" % (repr(self.block))
+
+
+class msg_getaddr(object):
+ command = "getaddr"
+
+ def __init__(self):
+ pass
+
+ def deserialize(self, f):
+ pass
+
+ def serialize(self):
+ return ""
+
+ def __repr__(self):
+ return "msg_getaddr()"
+
+
+class msg_ping_prebip31(object):
+ command = "ping"
+
+ def __init__(self):
+ pass
+
+ def deserialize(self, f):
+ pass
+
+ def serialize(self):
+ return ""
+
+ def __repr__(self):
+ return "msg_ping() (pre-bip31)"
+
+
+class msg_ping(object):
+ command = "ping"
+
+ def __init__(self, nonce=0L):
+ self.nonce = nonce
+
+ def deserialize(self, f):
+ self.nonce = struct.unpack("<Q", f.read(8))[0]
+
+ def serialize(self):
+ r = ""
+ r += struct.pack("<Q", self.nonce)
+ return r
+
+ def __repr__(self):
+ return "msg_ping(nonce=%08x)" % self.nonce
+
+
+class msg_pong(object):
+ command = "pong"
+
+ def __init__(self, nonce=0L):
+ self.nonce = nonce
+
+ def deserialize(self, f):
+ self.nonce = struct.unpack("<Q", f.read(8))[0]
+
+ def serialize(self):
+ r = ""
+ r += struct.pack("<Q", self.nonce)
+ return r
+
+ def __repr__(self):
+ return "msg_pong(nonce=%08x)" % self.nonce
+
+
+class msg_mempool(object):
+ command = "mempool"
+
+ def __init__(self):
+ pass
+
+ def deserialize(self, f):
+ pass
+
+ def serialize(self):
+ return ""
+
+ def __repr__(self):
+ return "msg_mempool()"
+
+
+# getheaders message has
+# number of entries
+# vector of hashes
+# hash_stop (hash of last desired block header, 0 to get as many as possible)
+class msg_getheaders(object):
+ command = "getheaders"
+
+ def __init__(self):
+ self.locator = CBlockLocator()
+ self.hashstop = 0L
+
+ def deserialize(self, f):
+ self.locator = CBlockLocator()
+ self.locator.deserialize(f)
+ self.hashstop = deser_uint256(f)
+
+ def serialize(self):
+ r = ""
+ r += self.locator.serialize()
+ r += ser_uint256(self.hashstop)
+ return r
+
+ def __repr__(self):
+ return "msg_getheaders(locator=%s, stop=%064x)" \
+ % (repr(self.locator), self.hashstop)
+
+
+# headers message has
+# <count> <vector of block headers>
+class msg_headers(object):
+ command = "headers"
+
+ def __init__(self):
+ self.headers = []
+
+ def deserialize(self, f):
+ # comment in bitcoind indicates these should be deserialized as blocks
+ blocks = deser_vector(f, CBlock)
+ for x in blocks:
+ self.headers.append(CBlockHeader(x))
+
+ def serialize(self):
+ blocks = [CBlock(x) for x in self.headers]
+ return ser_vector(blocks)
+
+ def __repr__(self):
+ return "msg_headers(headers=%s)" % repr(self.headers)
+
+
+class msg_reject(object):
+ command = "reject"
+
+ def __init__(self):
+ self.message = ""
+ self.code = ""
+ self.reason = ""
+ self.data = 0L
+
+ def deserialize(self, f):
+ self.message = deser_string(f)
+ self.code = struct.unpack("<B", f.read(1))[0]
+ self.reason = deser_string(f)
+ if (self.message == "block" or self.message == "tx"):
+ self.data = deser_uint256(f)
+
+ def serialize(self):
+ r = ser_string(self.message)
+ r += struct.pack("<B", self.code)
+ r += ser_string(self.reason)
+ if (self.message == "block" or self.message == "tx"):
+ r += ser_uint256(self.data)
+ return r
+
+ def __repr__(self):
+ return "msg_reject: %s %d %s [%064x]" \
+ % (self.message, self.code, self.reason, self.data)
+
+
+# This is what a callback should look like for NodeConn
+# Reimplement the on_* functions to provide handling for events
+class NodeConnCB(object):
+ def __init__(self):
+ self.verack_received = False
+
+ # Derived classes should call this function once to set the message map
+ # which associates the derived classes' functions to incoming messages
+ def create_callback_map(self):
+ self.cbmap = {
+ "version": self.on_version,
+ "verack": self.on_verack,
+ "addr": self.on_addr,
+ "alert": self.on_alert,
+ "inv": self.on_inv,
+ "getdata": self.on_getdata,
+ "getblocks": self.on_getblocks,
+ "tx": self.on_tx,
+ "block": self.on_block,
+ "getaddr": self.on_getaddr,
+ "ping": self.on_ping,
+ "pong": self.on_pong,
+ "headers": self.on_headers,
+ "getheaders": self.on_getheaders,
+ "reject": self.on_reject,
+ "mempool": self.on_mempool
+ }
+
+ def deliver(self, conn, message):
+ with mininode_lock:
+ try:
+ self.cbmap[message.command](conn, message)
+ except:
+ print "ERROR delivering %s (%s)" % (repr(message),
+ sys.exc_info()[0])
+
+ def on_version(self, conn, message):
+ if message.nVersion >= 209:
+ conn.send_message(msg_verack())
+ conn.ver_send = min(MY_VERSION, message.nVersion)
+ if message.nVersion < 209:
+ conn.ver_recv = conn.ver_send
+
+ def on_verack(self, conn, message):
+ conn.ver_recv = conn.ver_send
+ self.verack_received = True
+
+ def on_inv(self, conn, message):
+ want = msg_getdata()
+ for i in message.inv:
+ if i.type != 0:
+ want.inv.append(i)
+ if len(want.inv):
+ conn.send_message(want)
+
+ def on_addr(self, conn, message): pass
+ def on_alert(self, conn, message): pass
+ def on_getdata(self, conn, message): pass
+ def on_getblocks(self, conn, message): pass
+ def on_tx(self, conn, message): pass
+ def on_block(self, conn, message): pass
+ def on_getaddr(self, conn, message): pass
+ def on_headers(self, conn, message): pass
+ def on_getheaders(self, conn, message): pass
+ def on_ping(self, conn, message):
+ if conn.ver_send > BIP0031_VERSION:
+ conn.send_message(msg_pong(message.nonce))
+ def on_reject(self, conn, message): pass
+ def on_close(self, conn): pass
+ def on_mempool(self, conn): pass
+ def on_pong(self, conn, message): pass
+
+
+# The actual NodeConn class
+# This class provides an interface for a p2p connection to a specified node
+class NodeConn(asyncore.dispatcher):
+ messagemap = {
+ "version": msg_version,
+ "verack": msg_verack,
+ "addr": msg_addr,
+ "alert": msg_alert,
+ "inv": msg_inv,
+ "getdata": msg_getdata,
+ "getblocks": msg_getblocks,
+ "tx": msg_tx,
+ "block": msg_block,
+ "getaddr": msg_getaddr,
+ "ping": msg_ping,
+ "pong": msg_pong,
+ "headers": msg_headers,
+ "getheaders": msg_getheaders,
+ "reject": msg_reject,
+ "mempool": msg_mempool
+ }
+ MAGIC_BYTES = {
+ "mainnet": "\xf9\xbe\xb4\xd9", # mainnet
+ "testnet3": "\x0b\x11\x09\x07", # testnet3
+ "regtest": "\xfa\xbf\xb5\xda" # regtest
+ }
+
+ def __init__(self, dstaddr, dstport, rpc, callback, net="regtest"):
+ asyncore.dispatcher.__init__(self, map=mininode_socket_map)
+ self.log = logging.getLogger("NodeConn(%s:%d)" % (dstaddr, dstport))
+ self.dstaddr = dstaddr
+ self.dstport = dstport
+ self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
+ self.sendbuf = ""
+ self.recvbuf = ""
+ self.ver_send = 209
+ self.ver_recv = 209
+ self.last_sent = 0
+ self.state = "connecting"
+ self.network = net
+ self.cb = callback
+ self.disconnect = False
+
+ # stuff version msg into sendbuf
+ vt = msg_version()
+ vt.addrTo.ip = self.dstaddr
+ vt.addrTo.port = self.dstport
+ vt.addrFrom.ip = "0.0.0.0"
+ vt.addrFrom.port = 0
+ self.send_message(vt, True)
+ print 'MiniNode: Connecting to Bitcoin Node IP # ' + dstaddr + ':' \
+ + str(dstport)
+
+ try:
+ self.connect((dstaddr, dstport))
+ except:
+ self.handle_close()
+ self.rpc = rpc
+
+ def show_debug_msg(self, msg):
+ self.log.debug(msg)
+
+ def handle_connect(self):
+ self.show_debug_msg("MiniNode: Connected & Listening: \n")
+ self.state = "connected"
+
+ def handle_close(self):
+ self.show_debug_msg("MiniNode: Closing Connection to %s:%d... "
+ % (self.dstaddr, self.dstport))
+ self.state = "closed"
+ self.recvbuf = ""
+ self.sendbuf = ""
+ try:
+ self.close()
+ except:
+ pass
+ self.cb.on_close(self)
+
+ def handle_read(self):
+ try:
+ t = self.recv(8192)
+ if len(t) > 0:
+ self.recvbuf += t
+ self.got_data()
+ except:
+ pass
+
+ def readable(self):
+ return True
+
+ def writable(self):
+ with mininode_lock:
+ length = len(self.sendbuf)
+ return (length > 0)
+
+ def handle_write(self):
+ with mininode_lock:
+ try:
+ sent = self.send(self.sendbuf)
+ except:
+ self.handle_close()
+ return
+ self.sendbuf = self.sendbuf[sent:]
+
+ def got_data(self):
+ while True:
+ if len(self.recvbuf) < 4:
+ return
+ if self.recvbuf[:4] != self.MAGIC_BYTES[self.network]:
+ raise ValueError("got garbage %s" % repr(self.recvbuf))
+ if self.ver_recv < 209:
+ if len(self.recvbuf) < 4 + 12 + 4:
+ return
+ command = self.recvbuf[4:4+12].split("\x00", 1)[0]
+ msglen = struct.unpack("<i", self.recvbuf[4+12:4+12+4])[0]
+ checksum = None
+ if len(self.recvbuf) < 4 + 12 + 4 + msglen:
+ return
+ msg = self.recvbuf[4+12+4:4+12+4+msglen]
+ self.recvbuf = self.recvbuf[4+12+4+msglen:]
+ else:
+ if len(self.recvbuf) < 4 + 12 + 4 + 4:
+ return
+ command = self.recvbuf[4:4+12].split("\x00", 1)[0]
+ msglen = struct.unpack("<i", self.recvbuf[4+12:4+12+4])[0]
+ checksum = self.recvbuf[4+12+4:4+12+4+4]
+ if len(self.recvbuf) < 4 + 12 + 4 + 4 + msglen:
+ return
+ msg = self.recvbuf[4+12+4+4:4+12+4+4+msglen]
+ th = sha256(msg)
+ h = sha256(th)
+ if checksum != h[:4]:
+ raise ValueError("got bad checksum " + repr(self.recvbuf))
+ self.recvbuf = self.recvbuf[4+12+4+4+msglen:]
+ if command in self.messagemap:
+ f = cStringIO.StringIO(msg)
+ t = self.messagemap[command]()
+ t.deserialize(f)
+ self.got_message(t)
+ else:
+ self.show_debug_msg("Unknown command: '" + command + "' " +
+ repr(msg))
+
+ def send_message(self, message, pushbuf=False):
+ if self.state != "connected" and not pushbuf:
+ return
+ self.show_debug_msg("Send %s" % repr(message))
+ command = message.command
+ data = message.serialize()
+ tmsg = self.MAGIC_BYTES[self.network]
+ tmsg += command
+ tmsg += "\x00" * (12 - len(command))
+ tmsg += struct.pack("<I", len(data))
+ if self.ver_send >= 209:
+ th = sha256(data)
+ h = sha256(th)
+ tmsg += h[:4]
+ tmsg += data
+ with mininode_lock:
+ self.sendbuf += tmsg
+ self.last_sent = time.time()
+
+ def got_message(self, message):
+ if message.command == "version":
+ if message.nVersion <= BIP0031_VERSION:
+ self.messagemap['ping'] = msg_ping_prebip31
+ if self.last_sent + 30 * 60 < time.time():
+ self.send_message(self.messagemap['ping']())
+ self.show_debug_msg("Recv %s" % repr(message))
+ self.cb.deliver(self, message)
+
+ def disconnect_node(self):
+ self.disconnect = True
+
+
+class NetworkThread(Thread):
+ def run(self):
+ while mininode_socket_map:
+ # We check for whether to disconnect outside of the asyncore
+ # loop to workaround the behavior of asyncore when using
+ # select
+ disconnected = []
+ for fd, obj in mininode_socket_map.items():
+ if obj.disconnect:
+ disconnected.append(obj)
+ [ obj.handle_close() for obj in disconnected ]
+ asyncore.loop(0.1, use_poll=True, map=mininode_socket_map, count=1)
+
+
+# An exception we can raise if we detect a potential disconnect
+# (p2p or rpc) before the test is complete
+class EarlyDisconnectError(Exception):
+ def __init__(self, value):
+ self.value = value
+
+ def __str__(self):
+ return repr(self.value)
diff --git a/qa/rpc-tests/test_framework/netutil.py b/qa/rpc-tests/test_framework/netutil.py
new file mode 100644
index 0000000000..b30a88a4f7
--- /dev/null
+++ b/qa/rpc-tests/test_framework/netutil.py
@@ -0,0 +1,139 @@
+#!/usr/bin/env python2
+# Copyright (c) 2014 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+# Linux network utilities
+import sys
+import socket
+import fcntl
+import struct
+import array
+import os
+import binascii
+
+# Roughly based on http://voorloopnul.com/blog/a-python-netstat-in-less-than-100-lines-of-code/ by Ricardo Pascal
+STATE_ESTABLISHED = '01'
+STATE_SYN_SENT = '02'
+STATE_SYN_RECV = '03'
+STATE_FIN_WAIT1 = '04'
+STATE_FIN_WAIT2 = '05'
+STATE_TIME_WAIT = '06'
+STATE_CLOSE = '07'
+STATE_CLOSE_WAIT = '08'
+STATE_LAST_ACK = '09'
+STATE_LISTEN = '0A'
+STATE_CLOSING = '0B'
+
+def get_socket_inodes(pid):
+ '''
+ Get list of socket inodes for process pid.
+ '''
+ base = '/proc/%i/fd' % pid
+ inodes = []
+ for item in os.listdir(base):
+ target = os.readlink(os.path.join(base, item))
+ if target.startswith('socket:'):
+ inodes.append(int(target[8:-1]))
+ return inodes
+
+def _remove_empty(array):
+ return [x for x in array if x !='']
+
+def _convert_ip_port(array):
+ host,port = array.split(':')
+ # convert host from mangled-per-four-bytes form as used by kernel
+ host = binascii.unhexlify(host)
+ host_out = ''
+ for x in range(0, len(host)/4):
+ (val,) = struct.unpack('=I', host[x*4:(x+1)*4])
+ host_out += '%08x' % val
+
+ return host_out,int(port,16)
+
+def netstat(typ='tcp'):
+ '''
+ Function to return a list with status of tcp connections at linux systems
+ To get pid of all network process running on system, you must run this script
+ as superuser
+ '''
+ with open('/proc/net/'+typ,'r') as f:
+ content = f.readlines()
+ content.pop(0)
+ result = []
+ for line in content:
+ line_array = _remove_empty(line.split(' ')) # Split lines and remove empty spaces.
+ tcp_id = line_array[0]
+ l_addr = _convert_ip_port(line_array[1])
+ r_addr = _convert_ip_port(line_array[2])
+ state = line_array[3]
+ inode = int(line_array[9]) # Need the inode to match with process pid.
+ nline = [tcp_id, l_addr, r_addr, state, inode]
+ result.append(nline)
+ return result
+
+def get_bind_addrs(pid):
+ '''
+ Get bind addresses as (host,port) tuples for process pid.
+ '''
+ inodes = get_socket_inodes(pid)
+ bind_addrs = []
+ for conn in netstat('tcp') + netstat('tcp6'):
+ if conn[3] == STATE_LISTEN and conn[4] in inodes:
+ bind_addrs.append(conn[1])
+ return bind_addrs
+
+# from: http://code.activestate.com/recipes/439093/
+def all_interfaces():
+ '''
+ Return all interfaces that are up
+ '''
+ is_64bits = sys.maxsize > 2**32
+ struct_size = 40 if is_64bits else 32
+ s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+ max_possible = 8 # initial value
+ while True:
+ bytes = max_possible * struct_size
+ names = array.array('B', '\0' * bytes)
+ outbytes = struct.unpack('iL', fcntl.ioctl(
+ s.fileno(),
+ 0x8912, # SIOCGIFCONF
+ struct.pack('iL', bytes, names.buffer_info()[0])
+ ))[0]
+ if outbytes == bytes:
+ max_possible *= 2
+ else:
+ break
+ namestr = names.tostring()
+ return [(namestr[i:i+16].split('\0', 1)[0],
+ socket.inet_ntoa(namestr[i+20:i+24]))
+ for i in range(0, outbytes, struct_size)]
+
+def addr_to_hex(addr):
+ '''
+ Convert string IPv4 or IPv6 address to binary address as returned by
+ get_bind_addrs.
+ Very naive implementation that certainly doesn't work for all IPv6 variants.
+ '''
+ if '.' in addr: # IPv4
+ addr = [int(x) for x in addr.split('.')]
+ elif ':' in addr: # IPv6
+ sub = [[], []] # prefix, suffix
+ x = 0
+ addr = addr.split(':')
+ for i,comp in enumerate(addr):
+ if comp == '':
+ if i == 0 or i == (len(addr)-1): # skip empty component at beginning or end
+ continue
+ x += 1 # :: skips to suffix
+ assert(x < 2)
+ else: # two bytes per component
+ val = int(comp, 16)
+ sub[x].append(val >> 8)
+ sub[x].append(val & 0xff)
+ nullbytes = 16 - len(sub[0]) - len(sub[1])
+ assert((x == 0 and nullbytes == 0) or (x == 1 and nullbytes > 0))
+ addr = sub[0] + ([0] * nullbytes) + sub[1]
+ else:
+ raise ValueError('Could not parse address %s' % addr)
+ return binascii.hexlify(bytearray(addr))
diff --git a/qa/rpc-tests/test_framework/script.py b/qa/rpc-tests/test_framework/script.py
new file mode 100644
index 0000000000..e37ab5d45a
--- /dev/null
+++ b/qa/rpc-tests/test_framework/script.py
@@ -0,0 +1,896 @@
+#
+# script.py
+#
+# This file is modified from python-bitcoinlib.
+#
+# Distributed under the MIT/X11 software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#
+
+"""Scripts
+
+Functionality to build scripts, as well as SignatureHash().
+"""
+
+from __future__ import absolute_import, division, print_function, unicode_literals
+
+from test_framework.mininode import CTransaction, CTxOut, hash256
+
+import sys
+bchr = chr
+bord = ord
+if sys.version > '3':
+ long = int
+ bchr = lambda x: bytes([x])
+ bord = lambda x: x
+
+import copy
+import struct
+
+import test_framework.bignum
+
+MAX_SCRIPT_SIZE = 10000
+MAX_SCRIPT_ELEMENT_SIZE = 520
+MAX_SCRIPT_OPCODES = 201
+
+OPCODE_NAMES = {}
+
+_opcode_instances = []
+class CScriptOp(int):
+ """A single script opcode"""
+ __slots__ = []
+
+ @staticmethod
+ def encode_op_pushdata(d):
+ """Encode a PUSHDATA op, returning bytes"""
+ if len(d) < 0x4c:
+ return b'' + bchr(len(d)) + d # OP_PUSHDATA
+ elif len(d) <= 0xff:
+ return b'\x4c' + bchr(len(d)) + d # OP_PUSHDATA1
+ elif len(d) <= 0xffff:
+ return b'\x4d' + struct.pack(b'<H', len(d)) + d # OP_PUSHDATA2
+ elif len(d) <= 0xffffffff:
+ return b'\x4e' + struct.pack(b'<I', len(d)) + d # OP_PUSHDATA4
+ else:
+ raise ValueError("Data too long to encode in a PUSHDATA op")
+
+ @staticmethod
+ def encode_op_n(n):
+ """Encode a small integer op, returning an opcode"""
+ if not (0 <= n <= 16):
+ raise ValueError('Integer must be in range 0 <= n <= 16, got %d' % n)
+
+ if n == 0:
+ return OP_0
+ else:
+ return CScriptOp(OP_1 + n-1)
+
+ def decode_op_n(self):
+ """Decode a small integer opcode, returning an integer"""
+ if self == OP_0:
+ return 0
+
+ if not (self == OP_0 or OP_1 <= self <= OP_16):
+ raise ValueError('op %r is not an OP_N' % self)
+
+ return int(self - OP_1+1)
+
+ def is_small_int(self):
+ """Return true if the op pushes a small integer to the stack"""
+ if 0x51 <= self <= 0x60 or self == 0:
+ return True
+ else:
+ return False
+
+ def __str__(self):
+ return repr(self)
+
+ def __repr__(self):
+ if self in OPCODE_NAMES:
+ return OPCODE_NAMES[self]
+ else:
+ return 'CScriptOp(0x%x)' % self
+
+ def __new__(cls, n):
+ try:
+ return _opcode_instances[n]
+ except IndexError:
+ assert len(_opcode_instances) == n
+ _opcode_instances.append(super(CScriptOp, cls).__new__(cls, n))
+ return _opcode_instances[n]
+
+# Populate opcode instance table
+for n in range(0xff+1):
+ CScriptOp(n)
+
+
+# push value
+OP_0 = CScriptOp(0x00)
+OP_FALSE = OP_0
+OP_PUSHDATA1 = CScriptOp(0x4c)
+OP_PUSHDATA2 = CScriptOp(0x4d)
+OP_PUSHDATA4 = CScriptOp(0x4e)
+OP_1NEGATE = CScriptOp(0x4f)
+OP_RESERVED = CScriptOp(0x50)
+OP_1 = CScriptOp(0x51)
+OP_TRUE=OP_1
+OP_2 = CScriptOp(0x52)
+OP_3 = CScriptOp(0x53)
+OP_4 = CScriptOp(0x54)
+OP_5 = CScriptOp(0x55)
+OP_6 = CScriptOp(0x56)
+OP_7 = CScriptOp(0x57)
+OP_8 = CScriptOp(0x58)
+OP_9 = CScriptOp(0x59)
+OP_10 = CScriptOp(0x5a)
+OP_11 = CScriptOp(0x5b)
+OP_12 = CScriptOp(0x5c)
+OP_13 = CScriptOp(0x5d)
+OP_14 = CScriptOp(0x5e)
+OP_15 = CScriptOp(0x5f)
+OP_16 = CScriptOp(0x60)
+
+# control
+OP_NOP = CScriptOp(0x61)
+OP_VER = CScriptOp(0x62)
+OP_IF = CScriptOp(0x63)
+OP_NOTIF = CScriptOp(0x64)
+OP_VERIF = CScriptOp(0x65)
+OP_VERNOTIF = CScriptOp(0x66)
+OP_ELSE = CScriptOp(0x67)
+OP_ENDIF = CScriptOp(0x68)
+OP_VERIFY = CScriptOp(0x69)
+OP_RETURN = CScriptOp(0x6a)
+
+# stack ops
+OP_TOALTSTACK = CScriptOp(0x6b)
+OP_FROMALTSTACK = CScriptOp(0x6c)
+OP_2DROP = CScriptOp(0x6d)
+OP_2DUP = CScriptOp(0x6e)
+OP_3DUP = CScriptOp(0x6f)
+OP_2OVER = CScriptOp(0x70)
+OP_2ROT = CScriptOp(0x71)
+OP_2SWAP = CScriptOp(0x72)
+OP_IFDUP = CScriptOp(0x73)
+OP_DEPTH = CScriptOp(0x74)
+OP_DROP = CScriptOp(0x75)
+OP_DUP = CScriptOp(0x76)
+OP_NIP = CScriptOp(0x77)
+OP_OVER = CScriptOp(0x78)
+OP_PICK = CScriptOp(0x79)
+OP_ROLL = CScriptOp(0x7a)
+OP_ROT = CScriptOp(0x7b)
+OP_SWAP = CScriptOp(0x7c)
+OP_TUCK = CScriptOp(0x7d)
+
+# splice ops
+OP_CAT = CScriptOp(0x7e)
+OP_SUBSTR = CScriptOp(0x7f)
+OP_LEFT = CScriptOp(0x80)
+OP_RIGHT = CScriptOp(0x81)
+OP_SIZE = CScriptOp(0x82)
+
+# bit logic
+OP_INVERT = CScriptOp(0x83)
+OP_AND = CScriptOp(0x84)
+OP_OR = CScriptOp(0x85)
+OP_XOR = CScriptOp(0x86)
+OP_EQUAL = CScriptOp(0x87)
+OP_EQUALVERIFY = CScriptOp(0x88)
+OP_RESERVED1 = CScriptOp(0x89)
+OP_RESERVED2 = CScriptOp(0x8a)
+
+# numeric
+OP_1ADD = CScriptOp(0x8b)
+OP_1SUB = CScriptOp(0x8c)
+OP_2MUL = CScriptOp(0x8d)
+OP_2DIV = CScriptOp(0x8e)
+OP_NEGATE = CScriptOp(0x8f)
+OP_ABS = CScriptOp(0x90)
+OP_NOT = CScriptOp(0x91)
+OP_0NOTEQUAL = CScriptOp(0x92)
+
+OP_ADD = CScriptOp(0x93)
+OP_SUB = CScriptOp(0x94)
+OP_MUL = CScriptOp(0x95)
+OP_DIV = CScriptOp(0x96)
+OP_MOD = CScriptOp(0x97)
+OP_LSHIFT = CScriptOp(0x98)
+OP_RSHIFT = CScriptOp(0x99)
+
+OP_BOOLAND = CScriptOp(0x9a)
+OP_BOOLOR = CScriptOp(0x9b)
+OP_NUMEQUAL = CScriptOp(0x9c)
+OP_NUMEQUALVERIFY = CScriptOp(0x9d)
+OP_NUMNOTEQUAL = CScriptOp(0x9e)
+OP_LESSTHAN = CScriptOp(0x9f)
+OP_GREATERTHAN = CScriptOp(0xa0)
+OP_LESSTHANOREQUAL = CScriptOp(0xa1)
+OP_GREATERTHANOREQUAL = CScriptOp(0xa2)
+OP_MIN = CScriptOp(0xa3)
+OP_MAX = CScriptOp(0xa4)
+
+OP_WITHIN = CScriptOp(0xa5)
+
+# crypto
+OP_RIPEMD160 = CScriptOp(0xa6)
+OP_SHA1 = CScriptOp(0xa7)
+OP_SHA256 = CScriptOp(0xa8)
+OP_HASH160 = CScriptOp(0xa9)
+OP_HASH256 = CScriptOp(0xaa)
+OP_CODESEPARATOR = CScriptOp(0xab)
+OP_CHECKSIG = CScriptOp(0xac)
+OP_CHECKSIGVERIFY = CScriptOp(0xad)
+OP_CHECKMULTISIG = CScriptOp(0xae)
+OP_CHECKMULTISIGVERIFY = CScriptOp(0xaf)
+
+# expansion
+OP_NOP1 = CScriptOp(0xb0)
+OP_NOP2 = CScriptOp(0xb1)
+OP_NOP3 = CScriptOp(0xb2)
+OP_NOP4 = CScriptOp(0xb3)
+OP_NOP5 = CScriptOp(0xb4)
+OP_NOP6 = CScriptOp(0xb5)
+OP_NOP7 = CScriptOp(0xb6)
+OP_NOP8 = CScriptOp(0xb7)
+OP_NOP9 = CScriptOp(0xb8)
+OP_NOP10 = CScriptOp(0xb9)
+
+# template matching params
+OP_SMALLINTEGER = CScriptOp(0xfa)
+OP_PUBKEYS = CScriptOp(0xfb)
+OP_PUBKEYHASH = CScriptOp(0xfd)
+OP_PUBKEY = CScriptOp(0xfe)
+
+OP_INVALIDOPCODE = CScriptOp(0xff)
+
+VALID_OPCODES = {
+ OP_1NEGATE,
+ OP_RESERVED,
+ OP_1,
+ OP_2,
+ OP_3,
+ OP_4,
+ OP_5,
+ OP_6,
+ OP_7,
+ OP_8,
+ OP_9,
+ OP_10,
+ OP_11,
+ OP_12,
+ OP_13,
+ OP_14,
+ OP_15,
+ OP_16,
+
+ OP_NOP,
+ OP_VER,
+ OP_IF,
+ OP_NOTIF,
+ OP_VERIF,
+ OP_VERNOTIF,
+ OP_ELSE,
+ OP_ENDIF,
+ OP_VERIFY,
+ OP_RETURN,
+
+ OP_TOALTSTACK,
+ OP_FROMALTSTACK,
+ OP_2DROP,
+ OP_2DUP,
+ OP_3DUP,
+ OP_2OVER,
+ OP_2ROT,
+ OP_2SWAP,
+ OP_IFDUP,
+ OP_DEPTH,
+ OP_DROP,
+ OP_DUP,
+ OP_NIP,
+ OP_OVER,
+ OP_PICK,
+ OP_ROLL,
+ OP_ROT,
+ OP_SWAP,
+ OP_TUCK,
+
+ OP_CAT,
+ OP_SUBSTR,
+ OP_LEFT,
+ OP_RIGHT,
+ OP_SIZE,
+
+ OP_INVERT,
+ OP_AND,
+ OP_OR,
+ OP_XOR,
+ OP_EQUAL,
+ OP_EQUALVERIFY,
+ OP_RESERVED1,
+ OP_RESERVED2,
+
+ OP_1ADD,
+ OP_1SUB,
+ OP_2MUL,
+ OP_2DIV,
+ OP_NEGATE,
+ OP_ABS,
+ OP_NOT,
+ OP_0NOTEQUAL,
+
+ OP_ADD,
+ OP_SUB,
+ OP_MUL,
+ OP_DIV,
+ OP_MOD,
+ OP_LSHIFT,
+ OP_RSHIFT,
+
+ OP_BOOLAND,
+ OP_BOOLOR,
+ OP_NUMEQUAL,
+ OP_NUMEQUALVERIFY,
+ OP_NUMNOTEQUAL,
+ OP_LESSTHAN,
+ OP_GREATERTHAN,
+ OP_LESSTHANOREQUAL,
+ OP_GREATERTHANOREQUAL,
+ OP_MIN,
+ OP_MAX,
+
+ OP_WITHIN,
+
+ OP_RIPEMD160,
+ OP_SHA1,
+ OP_SHA256,
+ OP_HASH160,
+ OP_HASH256,
+ OP_CODESEPARATOR,
+ OP_CHECKSIG,
+ OP_CHECKSIGVERIFY,
+ OP_CHECKMULTISIG,
+ OP_CHECKMULTISIGVERIFY,
+
+ OP_NOP1,
+ OP_NOP2,
+ OP_NOP3,
+ OP_NOP4,
+ OP_NOP5,
+ OP_NOP6,
+ OP_NOP7,
+ OP_NOP8,
+ OP_NOP9,
+ OP_NOP10,
+
+ OP_SMALLINTEGER,
+ OP_PUBKEYS,
+ OP_PUBKEYHASH,
+ OP_PUBKEY,
+}
+
+OPCODE_NAMES.update({
+ OP_0 : 'OP_0',
+ OP_PUSHDATA1 : 'OP_PUSHDATA1',
+ OP_PUSHDATA2 : 'OP_PUSHDATA2',
+ OP_PUSHDATA4 : 'OP_PUSHDATA4',
+ OP_1NEGATE : 'OP_1NEGATE',
+ OP_RESERVED : 'OP_RESERVED',
+ OP_1 : 'OP_1',
+ OP_2 : 'OP_2',
+ OP_3 : 'OP_3',
+ OP_4 : 'OP_4',
+ OP_5 : 'OP_5',
+ OP_6 : 'OP_6',
+ OP_7 : 'OP_7',
+ OP_8 : 'OP_8',
+ OP_9 : 'OP_9',
+ OP_10 : 'OP_10',
+ OP_11 : 'OP_11',
+ OP_12 : 'OP_12',
+ OP_13 : 'OP_13',
+ OP_14 : 'OP_14',
+ OP_15 : 'OP_15',
+ OP_16 : 'OP_16',
+ OP_NOP : 'OP_NOP',
+ OP_VER : 'OP_VER',
+ OP_IF : 'OP_IF',
+ OP_NOTIF : 'OP_NOTIF',
+ OP_VERIF : 'OP_VERIF',
+ OP_VERNOTIF : 'OP_VERNOTIF',
+ OP_ELSE : 'OP_ELSE',
+ OP_ENDIF : 'OP_ENDIF',
+ OP_VERIFY : 'OP_VERIFY',
+ OP_RETURN : 'OP_RETURN',
+ OP_TOALTSTACK : 'OP_TOALTSTACK',
+ OP_FROMALTSTACK : 'OP_FROMALTSTACK',
+ OP_2DROP : 'OP_2DROP',
+ OP_2DUP : 'OP_2DUP',
+ OP_3DUP : 'OP_3DUP',
+ OP_2OVER : 'OP_2OVER',
+ OP_2ROT : 'OP_2ROT',
+ OP_2SWAP : 'OP_2SWAP',
+ OP_IFDUP : 'OP_IFDUP',
+ OP_DEPTH : 'OP_DEPTH',
+ OP_DROP : 'OP_DROP',
+ OP_DUP : 'OP_DUP',
+ OP_NIP : 'OP_NIP',
+ OP_OVER : 'OP_OVER',
+ OP_PICK : 'OP_PICK',
+ OP_ROLL : 'OP_ROLL',
+ OP_ROT : 'OP_ROT',
+ OP_SWAP : 'OP_SWAP',
+ OP_TUCK : 'OP_TUCK',
+ OP_CAT : 'OP_CAT',
+ OP_SUBSTR : 'OP_SUBSTR',
+ OP_LEFT : 'OP_LEFT',
+ OP_RIGHT : 'OP_RIGHT',
+ OP_SIZE : 'OP_SIZE',
+ OP_INVERT : 'OP_INVERT',
+ OP_AND : 'OP_AND',
+ OP_OR : 'OP_OR',
+ OP_XOR : 'OP_XOR',
+ OP_EQUAL : 'OP_EQUAL',
+ OP_EQUALVERIFY : 'OP_EQUALVERIFY',
+ OP_RESERVED1 : 'OP_RESERVED1',
+ OP_RESERVED2 : 'OP_RESERVED2',
+ OP_1ADD : 'OP_1ADD',
+ OP_1SUB : 'OP_1SUB',
+ OP_2MUL : 'OP_2MUL',
+ OP_2DIV : 'OP_2DIV',
+ OP_NEGATE : 'OP_NEGATE',
+ OP_ABS : 'OP_ABS',
+ OP_NOT : 'OP_NOT',
+ OP_0NOTEQUAL : 'OP_0NOTEQUAL',
+ OP_ADD : 'OP_ADD',
+ OP_SUB : 'OP_SUB',
+ OP_MUL : 'OP_MUL',
+ OP_DIV : 'OP_DIV',
+ OP_MOD : 'OP_MOD',
+ OP_LSHIFT : 'OP_LSHIFT',
+ OP_RSHIFT : 'OP_RSHIFT',
+ OP_BOOLAND : 'OP_BOOLAND',
+ OP_BOOLOR : 'OP_BOOLOR',
+ OP_NUMEQUAL : 'OP_NUMEQUAL',
+ OP_NUMEQUALVERIFY : 'OP_NUMEQUALVERIFY',
+ OP_NUMNOTEQUAL : 'OP_NUMNOTEQUAL',
+ OP_LESSTHAN : 'OP_LESSTHAN',
+ OP_GREATERTHAN : 'OP_GREATERTHAN',
+ OP_LESSTHANOREQUAL : 'OP_LESSTHANOREQUAL',
+ OP_GREATERTHANOREQUAL : 'OP_GREATERTHANOREQUAL',
+ OP_MIN : 'OP_MIN',
+ OP_MAX : 'OP_MAX',
+ OP_WITHIN : 'OP_WITHIN',
+ OP_RIPEMD160 : 'OP_RIPEMD160',
+ OP_SHA1 : 'OP_SHA1',
+ OP_SHA256 : 'OP_SHA256',
+ OP_HASH160 : 'OP_HASH160',
+ OP_HASH256 : 'OP_HASH256',
+ OP_CODESEPARATOR : 'OP_CODESEPARATOR',
+ OP_CHECKSIG : 'OP_CHECKSIG',
+ OP_CHECKSIGVERIFY : 'OP_CHECKSIGVERIFY',
+ OP_CHECKMULTISIG : 'OP_CHECKMULTISIG',
+ OP_CHECKMULTISIGVERIFY : 'OP_CHECKMULTISIGVERIFY',
+ OP_NOP1 : 'OP_NOP1',
+ OP_NOP2 : 'OP_NOP2',
+ OP_NOP3 : 'OP_NOP3',
+ OP_NOP4 : 'OP_NOP4',
+ OP_NOP5 : 'OP_NOP5',
+ OP_NOP6 : 'OP_NOP6',
+ OP_NOP7 : 'OP_NOP7',
+ OP_NOP8 : 'OP_NOP8',
+ OP_NOP9 : 'OP_NOP9',
+ OP_NOP10 : 'OP_NOP10',
+ OP_SMALLINTEGER : 'OP_SMALLINTEGER',
+ OP_PUBKEYS : 'OP_PUBKEYS',
+ OP_PUBKEYHASH : 'OP_PUBKEYHASH',
+ OP_PUBKEY : 'OP_PUBKEY',
+ OP_INVALIDOPCODE : 'OP_INVALIDOPCODE',
+})
+
+OPCODES_BY_NAME = {
+ 'OP_0' : OP_0,
+ 'OP_PUSHDATA1' : OP_PUSHDATA1,
+ 'OP_PUSHDATA2' : OP_PUSHDATA2,
+ 'OP_PUSHDATA4' : OP_PUSHDATA4,
+ 'OP_1NEGATE' : OP_1NEGATE,
+ 'OP_RESERVED' : OP_RESERVED,
+ 'OP_1' : OP_1,
+ 'OP_2' : OP_2,
+ 'OP_3' : OP_3,
+ 'OP_4' : OP_4,
+ 'OP_5' : OP_5,
+ 'OP_6' : OP_6,
+ 'OP_7' : OP_7,
+ 'OP_8' : OP_8,
+ 'OP_9' : OP_9,
+ 'OP_10' : OP_10,
+ 'OP_11' : OP_11,
+ 'OP_12' : OP_12,
+ 'OP_13' : OP_13,
+ 'OP_14' : OP_14,
+ 'OP_15' : OP_15,
+ 'OP_16' : OP_16,
+ 'OP_NOP' : OP_NOP,
+ 'OP_VER' : OP_VER,
+ 'OP_IF' : OP_IF,
+ 'OP_NOTIF' : OP_NOTIF,
+ 'OP_VERIF' : OP_VERIF,
+ 'OP_VERNOTIF' : OP_VERNOTIF,
+ 'OP_ELSE' : OP_ELSE,
+ 'OP_ENDIF' : OP_ENDIF,
+ 'OP_VERIFY' : OP_VERIFY,
+ 'OP_RETURN' : OP_RETURN,
+ 'OP_TOALTSTACK' : OP_TOALTSTACK,
+ 'OP_FROMALTSTACK' : OP_FROMALTSTACK,
+ 'OP_2DROP' : OP_2DROP,
+ 'OP_2DUP' : OP_2DUP,
+ 'OP_3DUP' : OP_3DUP,
+ 'OP_2OVER' : OP_2OVER,
+ 'OP_2ROT' : OP_2ROT,
+ 'OP_2SWAP' : OP_2SWAP,
+ 'OP_IFDUP' : OP_IFDUP,
+ 'OP_DEPTH' : OP_DEPTH,
+ 'OP_DROP' : OP_DROP,
+ 'OP_DUP' : OP_DUP,
+ 'OP_NIP' : OP_NIP,
+ 'OP_OVER' : OP_OVER,
+ 'OP_PICK' : OP_PICK,
+ 'OP_ROLL' : OP_ROLL,
+ 'OP_ROT' : OP_ROT,
+ 'OP_SWAP' : OP_SWAP,
+ 'OP_TUCK' : OP_TUCK,
+ 'OP_CAT' : OP_CAT,
+ 'OP_SUBSTR' : OP_SUBSTR,
+ 'OP_LEFT' : OP_LEFT,
+ 'OP_RIGHT' : OP_RIGHT,
+ 'OP_SIZE' : OP_SIZE,
+ 'OP_INVERT' : OP_INVERT,
+ 'OP_AND' : OP_AND,
+ 'OP_OR' : OP_OR,
+ 'OP_XOR' : OP_XOR,
+ 'OP_EQUAL' : OP_EQUAL,
+ 'OP_EQUALVERIFY' : OP_EQUALVERIFY,
+ 'OP_RESERVED1' : OP_RESERVED1,
+ 'OP_RESERVED2' : OP_RESERVED2,
+ 'OP_1ADD' : OP_1ADD,
+ 'OP_1SUB' : OP_1SUB,
+ 'OP_2MUL' : OP_2MUL,
+ 'OP_2DIV' : OP_2DIV,
+ 'OP_NEGATE' : OP_NEGATE,
+ 'OP_ABS' : OP_ABS,
+ 'OP_NOT' : OP_NOT,
+ 'OP_0NOTEQUAL' : OP_0NOTEQUAL,
+ 'OP_ADD' : OP_ADD,
+ 'OP_SUB' : OP_SUB,
+ 'OP_MUL' : OP_MUL,
+ 'OP_DIV' : OP_DIV,
+ 'OP_MOD' : OP_MOD,
+ 'OP_LSHIFT' : OP_LSHIFT,
+ 'OP_RSHIFT' : OP_RSHIFT,
+ 'OP_BOOLAND' : OP_BOOLAND,
+ 'OP_BOOLOR' : OP_BOOLOR,
+ 'OP_NUMEQUAL' : OP_NUMEQUAL,
+ 'OP_NUMEQUALVERIFY' : OP_NUMEQUALVERIFY,
+ 'OP_NUMNOTEQUAL' : OP_NUMNOTEQUAL,
+ 'OP_LESSTHAN' : OP_LESSTHAN,
+ 'OP_GREATERTHAN' : OP_GREATERTHAN,
+ 'OP_LESSTHANOREQUAL' : OP_LESSTHANOREQUAL,
+ 'OP_GREATERTHANOREQUAL' : OP_GREATERTHANOREQUAL,
+ 'OP_MIN' : OP_MIN,
+ 'OP_MAX' : OP_MAX,
+ 'OP_WITHIN' : OP_WITHIN,
+ 'OP_RIPEMD160' : OP_RIPEMD160,
+ 'OP_SHA1' : OP_SHA1,
+ 'OP_SHA256' : OP_SHA256,
+ 'OP_HASH160' : OP_HASH160,
+ 'OP_HASH256' : OP_HASH256,
+ 'OP_CODESEPARATOR' : OP_CODESEPARATOR,
+ 'OP_CHECKSIG' : OP_CHECKSIG,
+ 'OP_CHECKSIGVERIFY' : OP_CHECKSIGVERIFY,
+ 'OP_CHECKMULTISIG' : OP_CHECKMULTISIG,
+ 'OP_CHECKMULTISIGVERIFY' : OP_CHECKMULTISIGVERIFY,
+ 'OP_NOP1' : OP_NOP1,
+ 'OP_NOP2' : OP_NOP2,
+ 'OP_NOP3' : OP_NOP3,
+ 'OP_NOP4' : OP_NOP4,
+ 'OP_NOP5' : OP_NOP5,
+ 'OP_NOP6' : OP_NOP6,
+ 'OP_NOP7' : OP_NOP7,
+ 'OP_NOP8' : OP_NOP8,
+ 'OP_NOP9' : OP_NOP9,
+ 'OP_NOP10' : OP_NOP10,
+ 'OP_SMALLINTEGER' : OP_SMALLINTEGER,
+ 'OP_PUBKEYS' : OP_PUBKEYS,
+ 'OP_PUBKEYHASH' : OP_PUBKEYHASH,
+ 'OP_PUBKEY' : OP_PUBKEY,
+}
+
+class CScriptInvalidError(Exception):
+ """Base class for CScript exceptions"""
+ pass
+
+class CScriptTruncatedPushDataError(CScriptInvalidError):
+ """Invalid pushdata due to truncation"""
+ def __init__(self, msg, data):
+ self.data = data
+ super(CScriptTruncatedPushDataError, self).__init__(msg)
+
+# This is used, eg, for blockchain heights in coinbase scripts (bip34)
+class CScriptNum(object):
+ def __init__(self, d=0):
+ self.value = d
+
+ @staticmethod
+ def encode(obj):
+ r = bytearray(0)
+ if obj.value == 0:
+ return bytes(r)
+ neg = obj.value < 0
+ absvalue = -obj.value if neg else obj.value
+ while (absvalue):
+ r.append(chr(absvalue & 0xff))
+ absvalue >>= 8
+ if r[-1] & 0x80:
+ r.append(0x80 if neg else 0)
+ elif neg:
+ r[-1] |= 0x80
+ return bytes(bchr(len(r)) + r)
+
+
+class CScript(bytes):
+ """Serialized script
+
+ A bytes subclass, so you can use this directly whenever bytes are accepted.
+ Note that this means that indexing does *not* work - you'll get an index by
+ byte rather than opcode. This format was chosen for efficiency so that the
+ general case would not require creating a lot of little CScriptOP objects.
+
+ iter(script) however does iterate by opcode.
+ """
+ @classmethod
+ def __coerce_instance(cls, other):
+ # Coerce other into bytes
+ if isinstance(other, CScriptOp):
+ other = bchr(other)
+ elif isinstance(other, CScriptNum):
+ if (other.value == 0):
+ other = bchr(CScriptOp(OP_0))
+ else:
+ other = CScriptNum.encode(other)
+ elif isinstance(other, (int, long)):
+ if 0 <= other <= 16:
+ other = bytes(bchr(CScriptOp.encode_op_n(other)))
+ elif other == -1:
+ other = bytes(bchr(OP_1NEGATE))
+ else:
+ other = CScriptOp.encode_op_pushdata(bignum.bn2vch(other))
+ elif isinstance(other, (bytes, bytearray)):
+ other = CScriptOp.encode_op_pushdata(other)
+ return other
+
+ def __add__(self, other):
+ # Do the coercion outside of the try block so that errors in it are
+ # noticed.
+ other = self.__coerce_instance(other)
+
+ try:
+ # bytes.__add__ always returns bytes instances unfortunately
+ return CScript(super(CScript, self).__add__(other))
+ except TypeError:
+ raise TypeError('Can not add a %r instance to a CScript' % other.__class__)
+
+ def join(self, iterable):
+ # join makes no sense for a CScript()
+ raise NotImplementedError
+
+ def __new__(cls, value=b''):
+ if isinstance(value, bytes) or isinstance(value, bytearray):
+ return super(CScript, cls).__new__(cls, value)
+ else:
+ def coerce_iterable(iterable):
+ for instance in iterable:
+ yield cls.__coerce_instance(instance)
+ # Annoyingly on both python2 and python3 bytes.join() always
+ # returns a bytes instance even when subclassed.
+ return super(CScript, cls).__new__(cls, b''.join(coerce_iterable(value)))
+
+ def raw_iter(self):
+ """Raw iteration
+
+ Yields tuples of (opcode, data, sop_idx) so that the different possible
+ PUSHDATA encodings can be accurately distinguished, as well as
+ determining the exact opcode byte indexes. (sop_idx)
+ """
+ i = 0
+ while i < len(self):
+ sop_idx = i
+ opcode = bord(self[i])
+ i += 1
+
+ if opcode > OP_PUSHDATA4:
+ yield (opcode, None, sop_idx)
+ else:
+ datasize = None
+ pushdata_type = None
+ if opcode < OP_PUSHDATA1:
+ pushdata_type = 'PUSHDATA(%d)' % opcode
+ datasize = opcode
+
+ elif opcode == OP_PUSHDATA1:
+ pushdata_type = 'PUSHDATA1'
+ if i >= len(self):
+ raise CScriptInvalidError('PUSHDATA1: missing data length')
+ datasize = bord(self[i])
+ i += 1
+
+ elif opcode == OP_PUSHDATA2:
+ pushdata_type = 'PUSHDATA2'
+ if i + 1 >= len(self):
+ raise CScriptInvalidError('PUSHDATA2: missing data length')
+ datasize = bord(self[i]) + (bord(self[i+1]) << 8)
+ i += 2
+
+ elif opcode == OP_PUSHDATA4:
+ pushdata_type = 'PUSHDATA4'
+ if i + 3 >= len(self):
+ raise CScriptInvalidError('PUSHDATA4: missing data length')
+ datasize = bord(self[i]) + (bord(self[i+1]) << 8) + (bord(self[i+2]) << 16) + (bord(self[i+3]) << 24)
+ i += 4
+
+ else:
+ assert False # shouldn't happen
+
+
+ data = bytes(self[i:i+datasize])
+
+ # Check for truncation
+ if len(data) < datasize:
+ raise CScriptTruncatedPushDataError('%s: truncated data' % pushdata_type, data)
+
+ i += datasize
+
+ yield (opcode, data, sop_idx)
+
+ def __iter__(self):
+ """'Cooked' iteration
+
+ Returns either a CScriptOP instance, an integer, or bytes, as
+ appropriate.
+
+ See raw_iter() if you need to distinguish the different possible
+ PUSHDATA encodings.
+ """
+ for (opcode, data, sop_idx) in self.raw_iter():
+ if data is not None:
+ yield data
+ else:
+ opcode = CScriptOp(opcode)
+
+ if opcode.is_small_int():
+ yield opcode.decode_op_n()
+ else:
+ yield CScriptOp(opcode)
+
+ def __repr__(self):
+ # For Python3 compatibility add b before strings so testcases don't
+ # need to change
+ def _repr(o):
+ if isinstance(o, bytes):
+ return "x('%s')" % binascii.hexlify(o).decode('utf8')
+ else:
+ return repr(o)
+
+ ops = []
+ i = iter(self)
+ while True:
+ op = None
+ try:
+ op = _repr(next(i))
+ except CScriptTruncatedPushDataError as err:
+ op = '%s...<ERROR: %s>' % (_repr(err.data), err)
+ break
+ except CScriptInvalidError as err:
+ op = '<ERROR: %s>' % err
+ break
+ except StopIteration:
+ break
+ finally:
+ if op is not None:
+ ops.append(op)
+
+ return "CScript([%s])" % ', '.join(ops)
+
+ def GetSigOpCount(self, fAccurate):
+ """Get the SigOp count.
+
+ fAccurate - Accurately count CHECKMULTISIG, see BIP16 for details.
+
+ Note that this is consensus-critical.
+ """
+ n = 0
+ lastOpcode = OP_INVALIDOPCODE
+ for (opcode, data, sop_idx) in self.raw_iter():
+ if opcode in (OP_CHECKSIG, OP_CHECKSIGVERIFY):
+ n += 1
+ elif opcode in (OP_CHECKMULTISIG, OP_CHECKMULTISIGVERIFY):
+ if fAccurate and (OP_1 <= lastOpcode <= OP_16):
+ n += opcode.decode_op_n()
+ else:
+ n += 20
+ lastOpcode = opcode
+ return n
+
+
+SIGHASH_ALL = 1
+SIGHASH_NONE = 2
+SIGHASH_SINGLE = 3
+SIGHASH_ANYONECANPAY = 0x80
+
+def FindAndDelete(script, sig):
+ """Consensus critical, see FindAndDelete() in Satoshi codebase"""
+ r = b''
+ last_sop_idx = sop_idx = 0
+ skip = True
+ for (opcode, data, sop_idx) in script.raw_iter():
+ if not skip:
+ r += script[last_sop_idx:sop_idx]
+ last_sop_idx = sop_idx
+ if script[sop_idx:sop_idx + len(sig)] == sig:
+ skip = True
+ else:
+ skip = False
+ if not skip:
+ r += script[last_sop_idx:]
+ return CScript(r)
+
+
+def SignatureHash(script, txTo, inIdx, hashtype):
+ """Consensus-correct SignatureHash
+
+ Returns (hash, err) to precisely match the consensus-critical behavior of
+ the SIGHASH_SINGLE bug. (inIdx is *not* checked for validity)
+ """
+ HASH_ONE = b'\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+
+ if inIdx >= len(txTo.vin):
+ return (HASH_ONE, "inIdx %d out of range (%d)" % (inIdx, len(txTo.vin)))
+ txtmp = CTransaction(txTo)
+
+ for txin in txtmp.vin:
+ txin.scriptSig = b''
+ txtmp.vin[inIdx].scriptSig = FindAndDelete(script, CScript([OP_CODESEPARATOR]))
+
+ if (hashtype & 0x1f) == SIGHASH_NONE:
+ txtmp.vout = []
+
+ for i in range(len(txtmp.vin)):
+ if i != inIdx:
+ txtmp.vin[i].nSequence = 0
+
+ elif (hashtype & 0x1f) == SIGHASH_SINGLE:
+ outIdx = inIdx
+ if outIdx >= len(txtmp.vout):
+ return (HASH_ONE, "outIdx %d out of range (%d)" % (outIdx, len(txtmp.vout)))
+
+ tmp = txtmp.vout[outIdx]
+ txtmp.vout = []
+ for i in range(outIdx):
+ txtmp.vout.append(CTxOut())
+ txtmp.vout.append(tmp)
+
+ for i in range(len(txtmp.vin)):
+ if i != inIdx:
+ txtmp.vin[i].nSequence = 0
+
+ if hashtype & SIGHASH_ANYONECANPAY:
+ tmp = txtmp.vin[inIdx]
+ txtmp.vin = []
+ txtmp.vin.append(tmp)
+
+ s = txtmp.serialize()
+ s += struct.pack(b"<I", hashtype)
+
+ hash = hash256(s)
+
+ return (hash, None)
diff --git a/qa/rpc-tests/test_framework/socks5.py b/qa/rpc-tests/test_framework/socks5.py
new file mode 100644
index 0000000000..1dbfb98d5d
--- /dev/null
+++ b/qa/rpc-tests/test_framework/socks5.py
@@ -0,0 +1,160 @@
+# Copyright (c) 2015 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+'''
+Dummy Socks5 server for testing.
+'''
+from __future__ import print_function, division, unicode_literals
+import socket, threading, Queue
+import traceback, sys
+
+### Protocol constants
+class Command:
+ CONNECT = 0x01
+
+class AddressType:
+ IPV4 = 0x01
+ DOMAINNAME = 0x03
+ IPV6 = 0x04
+
+### Utility functions
+def recvall(s, n):
+ '''Receive n bytes from a socket, or fail'''
+ rv = bytearray()
+ while n > 0:
+ d = s.recv(n)
+ if not d:
+ raise IOError('Unexpected end of stream')
+ rv.extend(d)
+ n -= len(d)
+ return rv
+
+### Implementation classes
+class Socks5Configuration(object):
+ '''Proxy configuration'''
+ def __init__(self):
+ self.addr = None # Bind address (must be set)
+ self.af = socket.AF_INET # Bind address family
+ self.unauth = False # Support unauthenticated
+ self.auth = False # Support authentication
+
+class Socks5Command(object):
+ '''Information about an incoming socks5 command'''
+ def __init__(self, cmd, atyp, addr, port, username, password):
+ self.cmd = cmd # Command (one of Command.*)
+ self.atyp = atyp # Address type (one of AddressType.*)
+ self.addr = addr # Address
+ self.port = port # Port to connect to
+ self.username = username
+ self.password = password
+ def __repr__(self):
+ return 'Socks5Command(%s,%s,%s,%s,%s,%s)' % (self.cmd, self.atyp, self.addr, self.port, self.username, self.password)
+
+class Socks5Connection(object):
+ def __init__(self, serv, conn, peer):
+ self.serv = serv
+ self.conn = conn
+ self.peer = peer
+
+ def handle(self):
+ '''
+ Handle socks5 request according to RFC1928
+ '''
+ try:
+ # Verify socks version
+ ver = recvall(self.conn, 1)[0]
+ if ver != 0x05:
+ raise IOError('Invalid socks version %i' % ver)
+ # Choose authentication method
+ nmethods = recvall(self.conn, 1)[0]
+ methods = bytearray(recvall(self.conn, nmethods))
+ method = None
+ if 0x02 in methods and self.serv.conf.auth:
+ method = 0x02 # username/password
+ elif 0x00 in methods and self.serv.conf.unauth:
+ method = 0x00 # unauthenticated
+ if method is None:
+ raise IOError('No supported authentication method was offered')
+ # Send response
+ self.conn.sendall(bytearray([0x05, method]))
+ # Read authentication (optional)
+ username = None
+ password = None
+ if method == 0x02:
+ ver = recvall(self.conn, 1)[0]
+ if ver != 0x01:
+ raise IOError('Invalid auth packet version %i' % ver)
+ ulen = recvall(self.conn, 1)[0]
+ username = str(recvall(self.conn, ulen))
+ plen = recvall(self.conn, 1)[0]
+ password = str(recvall(self.conn, plen))
+ # Send authentication response
+ self.conn.sendall(bytearray([0x01, 0x00]))
+
+ # Read connect request
+ (ver,cmd,rsv,atyp) = recvall(self.conn, 4)
+ if ver != 0x05:
+ raise IOError('Invalid socks version %i in connect request' % ver)
+ if cmd != Command.CONNECT:
+ raise IOError('Unhandled command %i in connect request' % cmd)
+
+ if atyp == AddressType.IPV4:
+ addr = recvall(self.conn, 4)
+ elif atyp == AddressType.DOMAINNAME:
+ n = recvall(self.conn, 1)[0]
+ addr = str(recvall(self.conn, n))
+ elif atyp == AddressType.IPV6:
+ addr = recvall(self.conn, 16)
+ else:
+ raise IOError('Unknown address type %i' % atyp)
+ port_hi,port_lo = recvall(self.conn, 2)
+ port = (port_hi << 8) | port_lo
+
+ # Send dummy response
+ self.conn.sendall(bytearray([0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]))
+
+ cmdin = Socks5Command(cmd, atyp, addr, port, username, password)
+ self.serv.queue.put(cmdin)
+ print('Proxy: ', cmdin)
+ # Fall through to disconnect
+ except Exception,e:
+ traceback.print_exc(file=sys.stderr)
+ self.serv.queue.put(e)
+ finally:
+ self.conn.close()
+
+class Socks5Server(object):
+ def __init__(self, conf):
+ self.conf = conf
+ self.s = socket.socket(conf.af)
+ self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+ self.s.bind(conf.addr)
+ self.s.listen(5)
+ self.running = False
+ self.thread = None
+ self.queue = Queue.Queue() # report connections and exceptions to client
+
+ def run(self):
+ while self.running:
+ (sockconn, peer) = self.s.accept()
+ if self.running:
+ conn = Socks5Connection(self, sockconn, peer)
+ thread = threading.Thread(None, conn.handle)
+ thread.daemon = True
+ thread.start()
+
+ def start(self):
+ assert(not self.running)
+ self.running = True
+ self.thread = threading.Thread(None, self.run)
+ self.thread.daemon = True
+ self.thread.start()
+
+ def stop(self):
+ self.running = False
+ # connect to self to end run loop
+ s = socket.socket(self.conf.af)
+ s.connect(self.conf.addr)
+ s.close()
+ self.thread.join()
+
diff --git a/qa/rpc-tests/test_framework/test_framework.py b/qa/rpc-tests/test_framework/test_framework.py
new file mode 100755
index 0000000000..5671431f6e
--- /dev/null
+++ b/qa/rpc-tests/test_framework/test_framework.py
@@ -0,0 +1,179 @@
+#!/usr/bin/env python2
+# Copyright (c) 2014 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+# Base class for RPC testing
+
+# Add python-bitcoinrpc to module search path:
+import os
+import sys
+
+import shutil
+import tempfile
+import traceback
+
+from authproxy import AuthServiceProxy, JSONRPCException
+from util import *
+
+
+class BitcoinTestFramework(object):
+
+ # These may be over-ridden by subclasses:
+ def run_test(self):
+ for node in self.nodes:
+ assert_equal(node.getblockcount(), 200)
+ assert_equal(node.getbalance(), 25*50)
+
+ def add_options(self, parser):
+ pass
+
+ def setup_chain(self):
+ print("Initializing test directory "+self.options.tmpdir)
+ initialize_chain(self.options.tmpdir)
+
+ def setup_nodes(self):
+ return start_nodes(4, self.options.tmpdir)
+
+ def setup_network(self, split = False):
+ self.nodes = self.setup_nodes()
+
+ # Connect the nodes as a "chain". This allows us
+ # to split the network between nodes 1 and 2 to get
+ # two halves that can work on competing chains.
+
+ # If we joined network halves, connect the nodes from the joint
+ # on outward. This ensures that chains are properly reorganised.
+ if not split:
+ connect_nodes_bi(self.nodes, 1, 2)
+ sync_blocks(self.nodes[1:3])
+ sync_mempools(self.nodes[1:3])
+
+ connect_nodes_bi(self.nodes, 0, 1)
+ connect_nodes_bi(self.nodes, 2, 3)
+ self.is_network_split = split
+ self.sync_all()
+
+ def split_network(self):
+ """
+ Split the network of four nodes into nodes 0/1 and 2/3.
+ """
+ assert not self.is_network_split
+ stop_nodes(self.nodes)
+ wait_bitcoinds()
+ self.setup_network(True)
+
+ def sync_all(self):
+ if self.is_network_split:
+ sync_blocks(self.nodes[:2])
+ sync_blocks(self.nodes[2:])
+ sync_mempools(self.nodes[:2])
+ sync_mempools(self.nodes[2:])
+ else:
+ sync_blocks(self.nodes)
+ sync_mempools(self.nodes)
+
+ def join_network(self):
+ """
+ Join the (previously split) network halves together.
+ """
+ assert self.is_network_split
+ stop_nodes(self.nodes)
+ wait_bitcoinds()
+ self.setup_network(False)
+
+ def main(self):
+ import optparse
+
+ parser = optparse.OptionParser(usage="%prog [options]")
+ parser.add_option("--nocleanup", dest="nocleanup", default=False, action="store_true",
+ help="Leave bitcoinds and test.* datadir on exit or error")
+ parser.add_option("--noshutdown", dest="noshutdown", default=False, action="store_true",
+ help="Don't stop bitcoinds after the test execution")
+ parser.add_option("--srcdir", dest="srcdir", default="../../src",
+ help="Source directory containing bitcoind/bitcoin-cli (default: %default)")
+ parser.add_option("--tmpdir", dest="tmpdir", default=tempfile.mkdtemp(prefix="test"),
+ help="Root directory for datadirs")
+ parser.add_option("--tracerpc", dest="trace_rpc", default=False, action="store_true",
+ help="Print out all RPC calls as they are made")
+ self.add_options(parser)
+ (self.options, self.args) = parser.parse_args()
+
+ if self.options.trace_rpc:
+ import logging
+ logging.basicConfig(level=logging.DEBUG)
+
+ os.environ['PATH'] = self.options.srcdir+":"+os.environ['PATH']
+
+ check_json_precision()
+
+ success = False
+ try:
+ if not os.path.isdir(self.options.tmpdir):
+ os.makedirs(self.options.tmpdir)
+ self.setup_chain()
+
+ self.setup_network()
+
+ self.run_test()
+
+ success = True
+
+ except JSONRPCException as e:
+ print("JSONRPC error: "+e.error['message'])
+ traceback.print_tb(sys.exc_info()[2])
+ except AssertionError as e:
+ print("Assertion failed: "+e.message)
+ traceback.print_tb(sys.exc_info()[2])
+ except Exception as e:
+ print("Unexpected exception caught during testing: "+str(e))
+ traceback.print_tb(sys.exc_info()[2])
+
+ if not self.options.noshutdown:
+ print("Stopping nodes")
+ stop_nodes(self.nodes)
+ wait_bitcoinds()
+ else:
+ print("Note: bitcoinds were not stopped and may still be running")
+
+ if not self.options.nocleanup and not self.options.noshutdown:
+ print("Cleaning up")
+ shutil.rmtree(self.options.tmpdir)
+
+ if success:
+ print("Tests successful")
+ sys.exit(0)
+ else:
+ print("Failed")
+ sys.exit(1)
+
+
+# Test framework for doing p2p comparison testing, which sets up some bitcoind
+# binaries:
+# 1 binary: test binary
+# 2 binaries: 1 test binary, 1 ref binary
+# n>2 binaries: 1 test binary, n-1 ref binaries
+
+class ComparisonTestFramework(BitcoinTestFramework):
+
+ # Can override the num_nodes variable to indicate how many nodes to run.
+ def __init__(self):
+ self.num_nodes = 2
+
+ def add_options(self, parser):
+ parser.add_option("--testbinary", dest="testbinary",
+ default=os.getenv("BITCOIND", "bitcoind"),
+ help="bitcoind binary to test")
+ parser.add_option("--refbinary", dest="refbinary",
+ default=os.getenv("BITCOIND", "bitcoind"),
+ help="bitcoind binary to use for reference nodes (if any)")
+
+ def setup_chain(self):
+ print "Initializing test directory "+self.options.tmpdir
+ initialize_chain_clean(self.options.tmpdir, self.num_nodes)
+
+ def setup_network(self):
+ self.nodes = start_nodes(self.num_nodes, self.options.tmpdir,
+ extra_args=[['-debug', '-whitelist=127.0.0.1']] * self.num_nodes,
+ binary=[self.options.testbinary] +
+ [self.options.refbinary]*(self.num_nodes-1))
diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py
new file mode 100644
index 0000000000..c236ec2602
--- /dev/null
+++ b/qa/rpc-tests/test_framework/util.py
@@ -0,0 +1,356 @@
+# Copyright (c) 2014 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#
+# Helpful routines for regression testing
+#
+
+# Add python-bitcoinrpc to module search path:
+import os
+import sys
+
+from decimal import Decimal, ROUND_DOWN
+import json
+import random
+import shutil
+import subprocess
+import time
+import re
+
+from authproxy import AuthServiceProxy, JSONRPCException
+from util import *
+
+def p2p_port(n):
+ return 11000 + n + os.getpid()%999
+def rpc_port(n):
+ return 12000 + n + os.getpid()%999
+
+def check_json_precision():
+ """Make sure json library being used does not lose precision converting BTC values"""
+ n = Decimal("20000000.00000003")
+ satoshis = int(json.loads(json.dumps(float(n)))*1.0e8)
+ if satoshis != 2000000000000003:
+ raise RuntimeError("JSON encode/decode loses precision")
+
+def sync_blocks(rpc_connections, wait=1):
+ """
+ Wait until everybody has the same block count
+ """
+ while True:
+ counts = [ x.getblockcount() for x in rpc_connections ]
+ if counts == [ counts[0] ]*len(counts):
+ break
+ time.sleep(wait)
+
+def sync_mempools(rpc_connections, wait=1):
+ """
+ Wait until everybody has the same transactions in their memory
+ pools
+ """
+ while True:
+ pool = set(rpc_connections[0].getrawmempool())
+ num_match = 1
+ for i in range(1, len(rpc_connections)):
+ if set(rpc_connections[i].getrawmempool()) == pool:
+ num_match = num_match+1
+ if num_match == len(rpc_connections):
+ break
+ time.sleep(wait)
+
+bitcoind_processes = {}
+
+def initialize_datadir(dirname, n):
+ datadir = os.path.join(dirname, "node"+str(n))
+ if not os.path.isdir(datadir):
+ os.makedirs(datadir)
+ with open(os.path.join(datadir, "bitcoin.conf"), 'w') as f:
+ f.write("regtest=1\n");
+ f.write("rpcuser=rt\n");
+ f.write("rpcpassword=rt\n");
+ f.write("port="+str(p2p_port(n))+"\n");
+ f.write("rpcport="+str(rpc_port(n))+"\n");
+ return datadir
+
+def initialize_chain(test_dir):
+ """
+ Create (or copy from cache) a 200-block-long chain and
+ 4 wallets.
+ bitcoind and bitcoin-cli must be in search path.
+ """
+
+ if not os.path.isdir(os.path.join("cache", "node0")):
+ devnull = open("/dev/null", "w+")
+ # Create cache directories, run bitcoinds:
+ for i in range(4):
+ datadir=initialize_datadir("cache", i)
+ args = [ os.getenv("BITCOIND", "bitcoind"), "-keypool=1", "-datadir="+datadir, "-discover=0" ]
+ if i > 0:
+ args.append("-connect=127.0.0.1:"+str(p2p_port(0)))
+ bitcoind_processes[i] = subprocess.Popen(args)
+ if os.getenv("PYTHON_DEBUG", ""):
+ print "initialize_chain: bitcoind started, calling bitcoin-cli -rpcwait getblockcount"
+ subprocess.check_call([ os.getenv("BITCOINCLI", "bitcoin-cli"), "-datadir="+datadir,
+ "-rpcwait", "getblockcount"], stdout=devnull)
+ if os.getenv("PYTHON_DEBUG", ""):
+ print "initialize_chain: bitcoin-cli -rpcwait getblockcount completed"
+ devnull.close()
+ rpcs = []
+ for i in range(4):
+ try:
+ url = "http://rt:rt@127.0.0.1:%d"%(rpc_port(i),)
+ rpcs.append(AuthServiceProxy(url))
+ except:
+ sys.stderr.write("Error connecting to "+url+"\n")
+ sys.exit(1)
+
+ # Create a 200-block-long chain; each of the 4 nodes
+ # gets 25 mature blocks and 25 immature.
+ # blocks are created with timestamps 10 minutes apart, starting
+ # at 1 Jan 2014
+ block_time = 1388534400
+ for i in range(2):
+ for peer in range(4):
+ for j in range(25):
+ set_node_times(rpcs, block_time)
+ rpcs[peer].generate(1)
+ block_time += 10*60
+ # Must sync before next peer starts generating blocks
+ sync_blocks(rpcs)
+
+ # Shut them down, and clean up cache directories:
+ stop_nodes(rpcs)
+ wait_bitcoinds()
+ for i in range(4):
+ os.remove(log_filename("cache", i, "debug.log"))
+ os.remove(log_filename("cache", i, "db.log"))
+ os.remove(log_filename("cache", i, "peers.dat"))
+ os.remove(log_filename("cache", i, "fee_estimates.dat"))
+
+ for i in range(4):
+ from_dir = os.path.join("cache", "node"+str(i))
+ to_dir = os.path.join(test_dir, "node"+str(i))
+ shutil.copytree(from_dir, to_dir)
+ initialize_datadir(test_dir, i) # Overwrite port/rpcport in bitcoin.conf
+
+def initialize_chain_clean(test_dir, num_nodes):
+ """
+ Create an empty blockchain and num_nodes wallets.
+ Useful if a test case wants complete control over initialization.
+ """
+ for i in range(num_nodes):
+ datadir=initialize_datadir(test_dir, i)
+
+
+def _rpchost_to_args(rpchost):
+ '''Convert optional IP:port spec to rpcconnect/rpcport args'''
+ if rpchost is None:
+ return []
+
+ match = re.match('(\[[0-9a-fA-f:]+\]|[^:]+)(?::([0-9]+))?$', rpchost)
+ if not match:
+ raise ValueError('Invalid RPC host spec ' + rpchost)
+
+ rpcconnect = match.group(1)
+ rpcport = match.group(2)
+
+ if rpcconnect.startswith('['): # remove IPv6 [...] wrapping
+ rpcconnect = rpcconnect[1:-1]
+
+ rv = ['-rpcconnect=' + rpcconnect]
+ if rpcport:
+ rv += ['-rpcport=' + rpcport]
+ return rv
+
+def start_node(i, dirname, extra_args=None, rpchost=None, timewait=None, binary=None):
+ """
+ Start a bitcoind and return RPC connection to it
+ """
+ datadir = os.path.join(dirname, "node"+str(i))
+ if binary is None:
+ binary = os.getenv("BITCOIND", "bitcoind")
+ args = [ binary, "-datadir="+datadir, "-keypool=1", "-discover=0", "-rest" ]
+ if extra_args is not None: args.extend(extra_args)
+ bitcoind_processes[i] = subprocess.Popen(args)
+ devnull = open("/dev/null", "w+")
+ if os.getenv("PYTHON_DEBUG", ""):
+ print "start_node: bitcoind started, calling bitcoin-cli -rpcwait getblockcount"
+ subprocess.check_call([ os.getenv("BITCOINCLI", "bitcoin-cli"), "-datadir="+datadir] +
+ _rpchost_to_args(rpchost) +
+ ["-rpcwait", "getblockcount"], stdout=devnull)
+ if os.getenv("PYTHON_DEBUG", ""):
+ print "start_node: calling bitcoin-cli -rpcwait getblockcount returned"
+ devnull.close()
+ url = "http://rt:rt@%s:%d" % (rpchost or '127.0.0.1', rpc_port(i))
+ if timewait is not None:
+ proxy = AuthServiceProxy(url, timeout=timewait)
+ else:
+ proxy = AuthServiceProxy(url)
+ proxy.url = url # store URL on proxy for info
+ return proxy
+
+def start_nodes(num_nodes, dirname, extra_args=None, rpchost=None, binary=None):
+ """
+ Start multiple bitcoinds, return RPC connections to them
+ """
+ if extra_args is None: extra_args = [ None for i in range(num_nodes) ]
+ if binary is None: binary = [ None for i in range(num_nodes) ]
+ return [ start_node(i, dirname, extra_args[i], rpchost, binary=binary[i]) for i in range(num_nodes) ]
+
+def log_filename(dirname, n_node, logname):
+ return os.path.join(dirname, "node"+str(n_node), "regtest", logname)
+
+def stop_node(node, i):
+ node.stop()
+ bitcoind_processes[i].wait()
+ del bitcoind_processes[i]
+
+def stop_nodes(nodes):
+ for node in nodes:
+ node.stop()
+ del nodes[:] # Emptying array closes connections as a side effect
+
+def set_node_times(nodes, t):
+ for node in nodes:
+ node.setmocktime(t)
+
+def wait_bitcoinds():
+ # Wait for all bitcoinds to cleanly exit
+ for bitcoind in bitcoind_processes.values():
+ bitcoind.wait()
+ bitcoind_processes.clear()
+
+def connect_nodes(from_connection, node_num):
+ ip_port = "127.0.0.1:"+str(p2p_port(node_num))
+ from_connection.addnode(ip_port, "onetry")
+ # poll until version handshake complete to avoid race conditions
+ # with transaction relaying
+ while any(peer['version'] == 0 for peer in from_connection.getpeerinfo()):
+ time.sleep(0.1)
+
+def connect_nodes_bi(nodes, a, b):
+ connect_nodes(nodes[a], b)
+ connect_nodes(nodes[b], a)
+
+def find_output(node, txid, amount):
+ """
+ Return index to output of txid with value amount
+ Raises exception if there is none.
+ """
+ txdata = node.getrawtransaction(txid, 1)
+ for i in range(len(txdata["vout"])):
+ if txdata["vout"][i]["value"] == amount:
+ return i
+ raise RuntimeError("find_output txid %s : %s not found"%(txid,str(amount)))
+
+
+def gather_inputs(from_node, amount_needed, confirmations_required=1):
+ """
+ Return a random set of unspent txouts that are enough to pay amount_needed
+ """
+ assert(confirmations_required >=0)
+ utxo = from_node.listunspent(confirmations_required)
+ random.shuffle(utxo)
+ inputs = []
+ total_in = Decimal("0.00000000")
+ while total_in < amount_needed and len(utxo) > 0:
+ t = utxo.pop()
+ total_in += t["amount"]
+ inputs.append({ "txid" : t["txid"], "vout" : t["vout"], "address" : t["address"] } )
+ if total_in < amount_needed:
+ raise RuntimeError("Insufficient funds: need %d, have %d"%(amount_needed, total_in))
+ return (total_in, inputs)
+
+def make_change(from_node, amount_in, amount_out, fee):
+ """
+ Create change output(s), return them
+ """
+ outputs = {}
+ amount = amount_out+fee
+ change = amount_in - amount
+ if change > amount*2:
+ # Create an extra change output to break up big inputs
+ change_address = from_node.getnewaddress()
+ # Split change in two, being careful of rounding:
+ outputs[change_address] = Decimal(change/2).quantize(Decimal('0.00000001'), rounding=ROUND_DOWN)
+ change = amount_in - amount - outputs[change_address]
+ if change > 0:
+ outputs[from_node.getnewaddress()] = change
+ return outputs
+
+def send_zeropri_transaction(from_node, to_node, amount, fee):
+ """
+ Create&broadcast a zero-priority transaction.
+ Returns (txid, hex-encoded-txdata)
+ Ensures transaction is zero-priority by first creating a send-to-self,
+ then using its output
+ """
+
+ # Create a send-to-self with confirmed inputs:
+ self_address = from_node.getnewaddress()
+ (total_in, inputs) = gather_inputs(from_node, amount+fee*2)
+ outputs = make_change(from_node, total_in, amount+fee, fee)
+ outputs[self_address] = float(amount+fee)
+
+ self_rawtx = from_node.createrawtransaction(inputs, outputs)
+ self_signresult = from_node.signrawtransaction(self_rawtx)
+ self_txid = from_node.sendrawtransaction(self_signresult["hex"], True)
+
+ vout = find_output(from_node, self_txid, amount+fee)
+ # Now immediately spend the output to create a 1-input, 1-output
+ # zero-priority transaction:
+ inputs = [ { "txid" : self_txid, "vout" : vout } ]
+ outputs = { to_node.getnewaddress() : float(amount) }
+
+ rawtx = from_node.createrawtransaction(inputs, outputs)
+ signresult = from_node.signrawtransaction(rawtx)
+ txid = from_node.sendrawtransaction(signresult["hex"], True)
+
+ return (txid, signresult["hex"])
+
+def random_zeropri_transaction(nodes, amount, min_fee, fee_increment, fee_variants):
+ """
+ Create a random zero-priority transaction.
+ Returns (txid, hex-encoded-transaction-data, fee)
+ """
+ from_node = random.choice(nodes)
+ to_node = random.choice(nodes)
+ fee = min_fee + fee_increment*random.randint(0,fee_variants)
+ (txid, txhex) = send_zeropri_transaction(from_node, to_node, amount, fee)
+ return (txid, txhex, fee)
+
+def random_transaction(nodes, amount, min_fee, fee_increment, fee_variants):
+ """
+ Create a random transaction.
+ Returns (txid, hex-encoded-transaction-data, fee)
+ """
+ from_node = random.choice(nodes)
+ to_node = random.choice(nodes)
+ fee = min_fee + fee_increment*random.randint(0,fee_variants)
+
+ (total_in, inputs) = gather_inputs(from_node, amount+fee)
+ outputs = make_change(from_node, total_in, amount, fee)
+ outputs[to_node.getnewaddress()] = float(amount)
+
+ rawtx = from_node.createrawtransaction(inputs, outputs)
+ signresult = from_node.signrawtransaction(rawtx)
+ txid = from_node.sendrawtransaction(signresult["hex"], True)
+
+ return (txid, signresult["hex"], fee)
+
+def assert_equal(thing1, thing2):
+ if thing1 != thing2:
+ raise AssertionError("%s != %s"%(str(thing1),str(thing2)))
+
+def assert_greater_than(thing1, thing2):
+ if thing1 <= thing2:
+ raise AssertionError("%s <= %s"%(str(thing1),str(thing2)))
+
+def assert_raises(exc, fun, *args, **kwds):
+ try:
+ fun(*args, **kwds)
+ except exc:
+ pass
+ except Exception as e:
+ raise AssertionError("Unexpected exception raised: "+type(e).__name__)
+ else:
+ raise AssertionError("No exception raised")
diff --git a/qa/rpc-tests/txn_doublespend.py b/qa/rpc-tests/txn_doublespend.py
new file mode 100755
index 0000000000..99dcdae552
--- /dev/null
+++ b/qa/rpc-tests/txn_doublespend.py
@@ -0,0 +1,119 @@
+#!/usr/bin/env python2
+# Copyright (c) 2014 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#
+# Test proper accounting with malleable transactions
+#
+
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import *
+from decimal import Decimal
+import os
+import shutil
+
+class TxnMallTest(BitcoinTestFramework):
+
+ def add_options(self, parser):
+ parser.add_option("--mineblock", dest="mine_block", default=False, action="store_true",
+ help="Test double-spend of 1-confirmed transaction")
+
+ def setup_network(self):
+ # Start with split network:
+ return super(TxnMallTest, self).setup_network(True)
+
+ def run_test(self):
+ # All nodes should start with 1,250 BTC:
+ starting_balance = 1250
+ for i in range(4):
+ assert_equal(self.nodes[i].getbalance(), starting_balance)
+ self.nodes[i].getnewaddress("") # bug workaround, coins generated assigned to first getnewaddress!
+
+ # Assign coins to foo and bar accounts:
+ self.nodes[0].move("", "foo", 1220)
+ self.nodes[0].move("", "bar", 30)
+ assert_equal(self.nodes[0].getbalance(""), 0)
+
+ # Coins are sent to node1_address
+ node1_address = self.nodes[1].getnewaddress("from0")
+
+ # First: use raw transaction API to send 1210 BTC to node1_address,
+ # but don't broadcast:
+ (total_in, inputs) = gather_inputs(self.nodes[0], 1210)
+ change_address = self.nodes[0].getnewaddress("foo")
+ outputs = {}
+ outputs[change_address] = 40
+ outputs[node1_address] = 1210
+ rawtx = self.nodes[0].createrawtransaction(inputs, outputs)
+ doublespend = self.nodes[0].signrawtransaction(rawtx)
+ assert_equal(doublespend["complete"], True)
+
+ # Create two transaction from node[0] to node[1]; the
+ # second must spend change from the first because the first
+ # spends all mature inputs:
+ txid1 = self.nodes[0].sendfrom("foo", node1_address, 1210, 0)
+ txid2 = self.nodes[0].sendfrom("bar", node1_address, 20, 0)
+
+ # Have node0 mine a block:
+ if (self.options.mine_block):
+ self.nodes[0].generate(1)
+ sync_blocks(self.nodes[0:2])
+
+ tx1 = self.nodes[0].gettransaction(txid1)
+ tx2 = self.nodes[0].gettransaction(txid2)
+
+ # Node0's balance should be starting balance, plus 50BTC for another
+ # matured block, minus 1210, minus 20, and minus transaction fees:
+ expected = starting_balance
+ if self.options.mine_block: expected += 50
+ expected += tx1["amount"] + tx1["fee"]
+ expected += tx2["amount"] + tx2["fee"]
+ assert_equal(self.nodes[0].getbalance(), expected)
+
+ # foo and bar accounts should be debited:
+ assert_equal(self.nodes[0].getbalance("foo"), 1220+tx1["amount"]+tx1["fee"])
+ assert_equal(self.nodes[0].getbalance("bar"), 30+tx2["amount"]+tx2["fee"])
+
+ if self.options.mine_block:
+ assert_equal(tx1["confirmations"], 1)
+ assert_equal(tx2["confirmations"], 1)
+ # Node1's "from0" balance should be both transaction amounts:
+ assert_equal(self.nodes[1].getbalance("from0"), -(tx1["amount"]+tx2["amount"]))
+ else:
+ assert_equal(tx1["confirmations"], 0)
+ assert_equal(tx2["confirmations"], 0)
+
+ # Now give doublespend to miner:
+ mutated_txid = self.nodes[2].sendrawtransaction(doublespend["hex"])
+ # ... mine a block...
+ self.nodes[2].generate(1)
+
+ # Reconnect the split network, and sync chain:
+ connect_nodes(self.nodes[1], 2)
+ self.nodes[2].generate(1) # Mine another block to make sure we sync
+ sync_blocks(self.nodes)
+
+ # Re-fetch transaction info:
+ tx1 = self.nodes[0].gettransaction(txid1)
+ tx2 = self.nodes[0].gettransaction(txid2)
+
+ # Both transactions should be conflicted
+ assert_equal(tx1["confirmations"], -1)
+ assert_equal(tx2["confirmations"], -1)
+
+ # Node0's total balance should be starting balance, plus 100BTC for
+ # two more matured blocks, minus 1210 for the double-spend:
+ expected = starting_balance + 100 - 1210
+ assert_equal(self.nodes[0].getbalance(), expected)
+ assert_equal(self.nodes[0].getbalance("*"), expected)
+
+ # foo account should be debited, but bar account should not:
+ assert_equal(self.nodes[0].getbalance("foo"), 1220-1210)
+ assert_equal(self.nodes[0].getbalance("bar"), 30)
+
+ # Node1's "from" account balance should be just the mutated send:
+ assert_equal(self.nodes[1].getbalance("from0"), 1210)
+
+if __name__ == '__main__':
+ TxnMallTest().main()
diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py
new file mode 100755
index 0000000000..46dc7765b6
--- /dev/null
+++ b/qa/rpc-tests/wallet.py
@@ -0,0 +1,222 @@
+#!/usr/bin/env python2
+# Copyright (c) 2014 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#
+# Exercise the wallet. Ported from wallet.sh.
+# Does the following:
+# a) creates 3 nodes, with an empty chain (no blocks).
+# b) node0 mines a block
+# c) node1 mines 101 blocks, so now nodes 0 and 1 have 50btc, node2 has none.
+# d) node0 sends 21 btc to node2, in two transactions (11 btc, then 10 btc).
+# e) node0 mines a block, collects the fee on the second transaction
+# f) node1 mines 100 blocks, to mature node0's just-mined block
+# g) check that node0 has 100-21, node2 has 21
+# h) node0 should now have 2 unspent outputs; send these to node2 via raw tx broadcast by node1
+# i) have node1 mine a block
+# j) check balances - node0 should have 0, node2 should have 100
+# k) test ResendWalletTransactions - create transactions, startup fourth node, make sure it syncs
+#
+
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import *
+
+class WalletTest (BitcoinTestFramework):
+
+ def setup_chain(self):
+ print("Initializing test directory "+self.options.tmpdir)
+ initialize_chain_clean(self.options.tmpdir, 4)
+
+ def setup_network(self, split=False):
+ self.nodes = start_nodes(3, self.options.tmpdir)
+ connect_nodes_bi(self.nodes,0,1)
+ connect_nodes_bi(self.nodes,1,2)
+ connect_nodes_bi(self.nodes,0,2)
+ self.is_network_split=False
+ self.sync_all()
+
+ def run_test (self):
+ print "Mining blocks..."
+
+ self.nodes[0].generate(1)
+
+ walletinfo = self.nodes[0].getwalletinfo()
+ assert_equal(walletinfo['immature_balance'], 50)
+ assert_equal(walletinfo['balance'], 0)
+
+ self.sync_all()
+ self.nodes[1].generate(101)
+ self.sync_all()
+
+ assert_equal(self.nodes[0].getbalance(), 50)
+ assert_equal(self.nodes[1].getbalance(), 50)
+ assert_equal(self.nodes[2].getbalance(), 0)
+
+ # Send 21 BTC from 0 to 2 using sendtoaddress call.
+ # Second transaction will be child of first, and will require a fee
+ self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11)
+ self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 10)
+
+ walletinfo = self.nodes[0].getwalletinfo()
+ assert_equal(walletinfo['immature_balance'], 0)
+
+ # Have node0 mine a block, thus it will collect its own fee.
+ self.nodes[0].generate(1)
+ self.sync_all()
+
+ # Have node1 generate 100 blocks (so node0 can recover the fee)
+ self.nodes[1].generate(100)
+ self.sync_all()
+
+ # node0 should end up with 100 btc in block rewards plus fees, but
+ # minus the 21 plus fees sent to node2
+ assert_equal(self.nodes[0].getbalance(), 100-21)
+ assert_equal(self.nodes[2].getbalance(), 21)
+
+ # Node0 should have two unspent outputs.
+ # Create a couple of transactions to send them to node2, submit them through
+ # node1, and make sure both node0 and node2 pick them up properly:
+ node0utxos = self.nodes[0].listunspent(1)
+ assert_equal(len(node0utxos), 2)
+
+ # create both transactions
+ txns_to_send = []
+ for utxo in node0utxos:
+ inputs = []
+ outputs = {}
+ inputs.append({ "txid" : utxo["txid"], "vout" : utxo["vout"]})
+ outputs[self.nodes[2].getnewaddress("from1")] = utxo["amount"]
+ raw_tx = self.nodes[0].createrawtransaction(inputs, outputs)
+ txns_to_send.append(self.nodes[0].signrawtransaction(raw_tx))
+
+ # Have node 1 (miner) send the transactions
+ self.nodes[1].sendrawtransaction(txns_to_send[0]["hex"], True)
+ self.nodes[1].sendrawtransaction(txns_to_send[1]["hex"], True)
+
+ # Have node1 mine a block to confirm transactions:
+ self.nodes[1].generate(1)
+ self.sync_all()
+
+ assert_equal(self.nodes[0].getbalance(), 0)
+ assert_equal(self.nodes[2].getbalance(), 100)
+ assert_equal(self.nodes[2].getbalance("from1"), 100-21)
+
+ # Send 10 BTC normal
+ address = self.nodes[0].getnewaddress("test")
+ self.nodes[2].settxfee(Decimal('0.001'))
+ txid = self.nodes[2].sendtoaddress(address, 10, "", "", False)
+ self.nodes[2].generate(1)
+ self.sync_all()
+ assert_equal(self.nodes[2].getbalance(), Decimal('89.99900000'))
+ assert_equal(self.nodes[0].getbalance(), Decimal('10.00000000'))
+
+ # Send 10 BTC with subtract fee from amount
+ txid = self.nodes[2].sendtoaddress(address, 10, "", "", True)
+ self.nodes[2].generate(1)
+ self.sync_all()
+ assert_equal(self.nodes[2].getbalance(), Decimal('79.99900000'))
+ assert_equal(self.nodes[0].getbalance(), Decimal('19.99900000'))
+
+ # Sendmany 10 BTC
+ txid = self.nodes[2].sendmany('from1', {address: 10}, 0, "", [])
+ self.nodes[2].generate(1)
+ self.sync_all()
+ assert_equal(self.nodes[2].getbalance(), Decimal('69.99800000'))
+ assert_equal(self.nodes[0].getbalance(), Decimal('29.99900000'))
+
+ # Sendmany 10 BTC with subtract fee from amount
+ txid = self.nodes[2].sendmany('from1', {address: 10}, 0, "", [address])
+ self.nodes[2].generate(1)
+ self.sync_all()
+ assert_equal(self.nodes[2].getbalance(), Decimal('59.99800000'))
+ assert_equal(self.nodes[0].getbalance(), Decimal('39.99800000'))
+
+ # Test ResendWalletTransactions:
+ # Create a couple of transactions, then start up a fourth
+ # node (nodes[3]) and ask nodes[0] to rebroadcast.
+ # EXPECT: nodes[3] should have those transactions in its mempool.
+ txid1 = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 1)
+ txid2 = self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1)
+ sync_mempools(self.nodes)
+
+ self.nodes.append(start_node(3, self.options.tmpdir))
+ connect_nodes_bi(self.nodes, 0, 3)
+ sync_blocks(self.nodes)
+
+ relayed = self.nodes[0].resendwallettransactions()
+ assert_equal(set(relayed), set([txid1, txid2]))
+ sync_mempools(self.nodes)
+
+ assert(txid1 in self.nodes[3].getrawmempool())
+
+ #check if we can list zero value tx as available coins
+ #1. create rawtx
+ #2. hex-changed one output to 0.0
+ #3. sign and send
+ #4. check if recipient (node0) can list the zero value tx
+ usp = self.nodes[1].listunspent()
+ inputs = [{"txid":usp[0]['txid'], "vout":usp[0]['vout']}]
+ outputs = {self.nodes[1].getnewaddress(): 49.998, self.nodes[0].getnewaddress(): 11.11}
+
+ rawTx = self.nodes[1].createrawtransaction(inputs, outputs).replace("c0833842", "00000000") #replace 11.11 with 0.0 (int32)
+ decRawTx = self.nodes[1].decoderawtransaction(rawTx)
+ signedRawTx = self.nodes[1].signrawtransaction(rawTx)
+ decRawTx = self.nodes[1].decoderawtransaction(signedRawTx['hex'])
+ zeroValueTxid= decRawTx['txid']
+ sendResp = self.nodes[1].sendrawtransaction(signedRawTx['hex'])
+
+ self.sync_all()
+ self.nodes[1].generate(1) #mine a block
+ self.sync_all()
+
+ unspentTxs = self.nodes[0].listunspent() #zero value tx must be in listunspents output
+ found = False
+ for uTx in unspentTxs:
+ if uTx['txid'] == zeroValueTxid:
+ found = True
+ assert_equal(uTx['amount'], Decimal('0.00000000'));
+ assert(found)
+
+ #do some -walletbroadcast tests
+ stop_nodes(self.nodes)
+ wait_bitcoinds()
+ self.nodes = start_nodes(3, self.options.tmpdir, [["-walletbroadcast=0"],["-walletbroadcast=0"],["-walletbroadcast=0"]])
+ connect_nodes_bi(self.nodes,0,1)
+ connect_nodes_bi(self.nodes,1,2)
+ connect_nodes_bi(self.nodes,0,2)
+ self.sync_all()
+
+ txIdNotBroadcasted = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 2);
+ txObjNotBroadcasted = self.nodes[0].gettransaction(txIdNotBroadcasted)
+ self.nodes[1].generate(1) #mine a block, tx should not be in there
+ self.sync_all()
+ assert_equal(self.nodes[2].getbalance(), Decimal('59.99800000')); #should not be changed because tx was not broadcasted
+
+ #now broadcast from another node, mine a block, sync, and check the balance
+ self.nodes[1].sendrawtransaction(txObjNotBroadcasted['hex'])
+ self.nodes[1].generate(1)
+ self.sync_all()
+ txObjNotBroadcasted = self.nodes[0].gettransaction(txIdNotBroadcasted)
+ assert_equal(self.nodes[2].getbalance(), Decimal('61.99800000')); #should not be
+
+ #create another tx
+ txIdNotBroadcasted = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 2);
+
+ #restart the nodes with -walletbroadcast=1
+ stop_nodes(self.nodes)
+ wait_bitcoinds()
+ self.nodes = start_nodes(3, self.options.tmpdir)
+ connect_nodes_bi(self.nodes,0,1)
+ connect_nodes_bi(self.nodes,1,2)
+ connect_nodes_bi(self.nodes,0,2)
+ sync_blocks(self.nodes)
+
+ self.nodes[0].generate(1)
+ sync_blocks(self.nodes)
+
+ #tx should be added to balance because after restarting the nodes tx should be broadcastet
+ assert_equal(self.nodes[2].getbalance(), Decimal('63.99800000')); #should not be
+
+if __name__ == '__main__':
+ WalletTest ().main ()
diff --git a/qa/rpc-tests/walletbackup.py b/qa/rpc-tests/walletbackup.py
new file mode 100755
index 0000000000..da100d7fc0
--- /dev/null
+++ b/qa/rpc-tests/walletbackup.py
@@ -0,0 +1,200 @@
+#!/usr/bin/env python2
+# Copyright (c) 2014 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+"""
+Exercise the wallet backup code. Ported from walletbackup.sh.
+
+Test case is:
+4 nodes. 1 2 and 3 send transactions between each other,
+fourth node is a miner.
+1 2 3 each mine a block to start, then
+Miner creates 100 blocks so 1 2 3 each have 50 mature
+coins to spend.
+Then 5 iterations of 1/2/3 sending coins amongst
+themselves to get transactions in the wallets,
+and the miner mining one block.
+
+Wallets are backed up using dumpwallet/backupwallet.
+Then 5 more iterations of transactions and mining a block.
+
+Miner then generates 101 more blocks, so any
+transaction fees paid mature.
+
+Sanity check:
+ Sum(1,2,3,4 balances) == 114*50
+
+1/2/3 are shutdown, and their wallets erased.
+Then restore using wallet.dat backup. And
+confirm 1/2/3/4 balances are same as before.
+
+Shutdown again, restore using importwallet,
+and confirm again balances are correct.
+"""
+
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import *
+from random import randint
+import logging
+logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.INFO)
+
+class WalletBackupTest(BitcoinTestFramework):
+
+ def setup_chain(self):
+ logging.info("Initializing test directory "+self.options.tmpdir)
+ initialize_chain_clean(self.options.tmpdir, 4)
+
+ # This mirrors how the network was setup in the bash test
+ def setup_network(self, split=False):
+ # nodes 1, 2,3 are spenders, let's give them a keypool=100
+ extra_args = [["-keypool=100"], ["-keypool=100"], ["-keypool=100"], []]
+ self.nodes = start_nodes(4, self.options.tmpdir, extra_args)
+ connect_nodes(self.nodes[0], 3)
+ connect_nodes(self.nodes[1], 3)
+ connect_nodes(self.nodes[2], 3)
+ connect_nodes(self.nodes[2], 0)
+ self.is_network_split=False
+ self.sync_all()
+
+ def one_send(self, from_node, to_address):
+ if (randint(1,2) == 1):
+ amount = Decimal(randint(1,10)) / Decimal(10)
+ self.nodes[from_node].sendtoaddress(to_address, amount)
+
+ def do_one_round(self):
+ a0 = self.nodes[0].getnewaddress()
+ a1 = self.nodes[1].getnewaddress()
+ a2 = self.nodes[2].getnewaddress()
+
+ self.one_send(0, a1)
+ self.one_send(0, a2)
+ self.one_send(1, a0)
+ self.one_send(1, a2)
+ self.one_send(2, a0)
+ self.one_send(2, a1)
+
+ # Have the miner (node3) mine a block.
+ # Must sync mempools before mining.
+ sync_mempools(self.nodes)
+ self.nodes[3].generate(1)
+
+ # As above, this mirrors the original bash test.
+ def start_three(self):
+ self.nodes[0] = start_node(0, self.options.tmpdir)
+ self.nodes[1] = start_node(1, self.options.tmpdir)
+ self.nodes[2] = start_node(2, self.options.tmpdir)
+ connect_nodes(self.nodes[0], 3)
+ connect_nodes(self.nodes[1], 3)
+ connect_nodes(self.nodes[2], 3)
+ connect_nodes(self.nodes[2], 0)
+
+ def stop_three(self):
+ stop_node(self.nodes[0], 0)
+ stop_node(self.nodes[1], 1)
+ stop_node(self.nodes[2], 2)
+
+ def erase_three(self):
+ os.remove(self.options.tmpdir + "/node0/regtest/wallet.dat")
+ os.remove(self.options.tmpdir + "/node1/regtest/wallet.dat")
+ os.remove(self.options.tmpdir + "/node2/regtest/wallet.dat")
+
+ def run_test(self):
+ logging.info("Generating initial blockchain")
+ self.nodes[0].generate(1)
+ sync_blocks(self.nodes)
+ self.nodes[1].generate(1)
+ sync_blocks(self.nodes)
+ self.nodes[2].generate(1)
+ sync_blocks(self.nodes)
+ self.nodes[3].generate(100)
+ sync_blocks(self.nodes)
+
+ assert_equal(self.nodes[0].getbalance(), 50)
+ assert_equal(self.nodes[1].getbalance(), 50)
+ assert_equal(self.nodes[2].getbalance(), 50)
+ assert_equal(self.nodes[3].getbalance(), 0)
+
+ logging.info("Creating transactions")
+ # Five rounds of sending each other transactions.
+ for i in range(5):
+ self.do_one_round()
+
+ logging.info("Backing up")
+ tmpdir = self.options.tmpdir
+ self.nodes[0].backupwallet(tmpdir + "/node0/wallet.bak")
+ self.nodes[0].dumpwallet(tmpdir + "/node0/wallet.dump")
+ self.nodes[1].backupwallet(tmpdir + "/node1/wallet.bak")
+ self.nodes[1].dumpwallet(tmpdir + "/node1/wallet.dump")
+ self.nodes[2].backupwallet(tmpdir + "/node2/wallet.bak")
+ self.nodes[2].dumpwallet(tmpdir + "/node2/wallet.dump")
+
+ logging.info("More transactions")
+ for i in range(5):
+ self.do_one_round()
+
+ # Generate 101 more blocks, so any fees paid mature
+ self.nodes[3].generate(101)
+ self.sync_all()
+
+ balance0 = self.nodes[0].getbalance()
+ balance1 = self.nodes[1].getbalance()
+ balance2 = self.nodes[2].getbalance()
+ balance3 = self.nodes[3].getbalance()
+ total = balance0 + balance1 + balance2 + balance3
+
+ # At this point, there are 214 blocks (103 for setup, then 10 rounds, then 101.)
+ # 114 are mature, so the sum of all wallets should be 114 * 50 = 5700.
+ assert_equal(total, 5700)
+
+ ##
+ # Test restoring spender wallets from backups
+ ##
+ logging.info("Restoring using wallet.dat")
+ self.stop_three()
+ self.erase_three()
+
+ # Start node2 with no chain
+ shutil.rmtree(self.options.tmpdir + "/node2/regtest/blocks")
+ shutil.rmtree(self.options.tmpdir + "/node2/regtest/chainstate")
+
+ # Restore wallets from backup
+ shutil.copyfile(tmpdir + "/node0/wallet.bak", tmpdir + "/node0/regtest/wallet.dat")
+ shutil.copyfile(tmpdir + "/node1/wallet.bak", tmpdir + "/node1/regtest/wallet.dat")
+ shutil.copyfile(tmpdir + "/node2/wallet.bak", tmpdir + "/node2/regtest/wallet.dat")
+
+ logging.info("Re-starting nodes")
+ self.start_three()
+ sync_blocks(self.nodes)
+
+ assert_equal(self.nodes[0].getbalance(), balance0)
+ assert_equal(self.nodes[1].getbalance(), balance1)
+ assert_equal(self.nodes[2].getbalance(), balance2)
+
+ logging.info("Restoring using dumped wallet")
+ self.stop_three()
+ self.erase_three()
+
+ #start node2 with no chain
+ shutil.rmtree(self.options.tmpdir + "/node2/regtest/blocks")
+ shutil.rmtree(self.options.tmpdir + "/node2/regtest/chainstate")
+
+ self.start_three()
+
+ assert_equal(self.nodes[0].getbalance(), 0)
+ assert_equal(self.nodes[1].getbalance(), 0)
+ assert_equal(self.nodes[2].getbalance(), 0)
+
+ self.nodes[0].importwallet(tmpdir + "/node0/wallet.dump")
+ self.nodes[1].importwallet(tmpdir + "/node1/wallet.dump")
+ self.nodes[2].importwallet(tmpdir + "/node2/wallet.dump")
+
+ sync_blocks(self.nodes)
+
+ assert_equal(self.nodes[0].getbalance(), balance0)
+ assert_equal(self.nodes[1].getbalance(), balance1)
+ assert_equal(self.nodes[2].getbalance(), balance2)
+
+
+if __name__ == '__main__':
+ WalletBackupTest().main()
diff --git a/qa/rpc-tests/zapwallettxes.py b/qa/rpc-tests/zapwallettxes.py
new file mode 100755
index 0000000000..0ec8ec5364
--- /dev/null
+++ b/qa/rpc-tests/zapwallettxes.py
@@ -0,0 +1,82 @@
+#!/usr/bin/env python2
+# Copyright (c) 2014 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import *
+
+
+class ZapWalletTXesTest (BitcoinTestFramework):
+
+ def setup_chain(self):
+ print("Initializing test directory "+self.options.tmpdir)
+ initialize_chain_clean(self.options.tmpdir, 3)
+
+ def setup_network(self, split=False):
+ self.nodes = start_nodes(3, self.options.tmpdir)
+ connect_nodes_bi(self.nodes,0,1)
+ connect_nodes_bi(self.nodes,1,2)
+ connect_nodes_bi(self.nodes,0,2)
+ self.is_network_split=False
+ self.sync_all()
+
+ def run_test (self):
+ print "Mining blocks..."
+ self.nodes[0].generate(1)
+ self.sync_all()
+ self.nodes[1].generate(101)
+ self.sync_all()
+
+ assert_equal(self.nodes[0].getbalance(), 50)
+
+ txid0 = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11)
+ txid1 = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 10)
+ self.sync_all()
+ self.nodes[0].generate(1)
+ self.sync_all()
+
+ txid2 = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11)
+ txid3 = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 10)
+
+ tx0 = self.nodes[0].gettransaction(txid0)
+ assert_equal(tx0['txid'], txid0) #tx0 must be available (confirmed)
+
+ tx1 = self.nodes[0].gettransaction(txid1)
+ assert_equal(tx1['txid'], txid1) #tx1 must be available (confirmed)
+
+ tx2 = self.nodes[0].gettransaction(txid2)
+ assert_equal(tx2['txid'], txid2) #tx2 must be available (unconfirmed)
+
+ tx3 = self.nodes[0].gettransaction(txid3)
+ assert_equal(tx3['txid'], txid3) #tx3 must be available (unconfirmed)
+
+ #restart bitcoind
+ self.nodes[0].stop()
+ bitcoind_processes[0].wait()
+ self.nodes[0] = start_node(0,self.options.tmpdir)
+
+ tx3 = self.nodes[0].gettransaction(txid3)
+ assert_equal(tx3['txid'], txid3) #tx must be available (unconfirmed)
+
+ self.nodes[0].stop()
+ bitcoind_processes[0].wait()
+
+ #restart bitcoind with zapwallettxes
+ self.nodes[0] = start_node(0,self.options.tmpdir, ["-zapwallettxes=1"])
+
+ aException = False
+ try:
+ tx3 = self.nodes[0].gettransaction(txid3)
+ except JSONRPCException,e:
+ print e
+ aException = True
+
+ assert_equal(aException, True) #there must be a expection because the unconfirmed wallettx0 must be gone by now
+
+ tx0 = self.nodes[0].gettransaction(txid0)
+ assert_equal(tx0['txid'], txid0) #tx0 (confirmed) must still be available because it was confirmed
+
+
+if __name__ == '__main__':
+ ZapWalletTXesTest ().main ()
diff --git a/share/certs/BitcoinFoundation_Apple_Cert.pem b/share/certs/BitcoinFoundation_Apple_Cert.pem
new file mode 100644
index 0000000000..beb0d7073c
--- /dev/null
+++ b/share/certs/BitcoinFoundation_Apple_Cert.pem
@@ -0,0 +1,37 @@
+Bag Attributes
+ friendlyName: Developer ID Application: BITCOIN FOUNDATION, INC., THE
+ localKeyID: 6B 9C 6C A8 A5 73 70 70 E2 57 A3 49 D8 62 FB 97 C7 A5 5D 5E
+subject=/UID=PBV4GLS9J4/CN=Developer ID Application: BITCOIN FOUNDATION, INC., THE/OU=PBV4GLS9J4/O=BITCOIN FOUNDATION, INC., THE/C=US
+issuer=/CN=Developer ID Certification Authority/OU=Apple Certification Authority/O=Apple Inc./C=US
+-----BEGIN CERTIFICATE-----
+MIIFhzCCBG+gAwIBAgIIJ0r1rumyfZAwDQYJKoZIhvcNAQELBQAweTEtMCsGA1UE
+AwwkRGV2ZWxvcGVyIElEIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSYwJAYDVQQL
+DB1BcHBsZSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTETMBEGA1UECgwKQXBwbGUg
+SW5jLjELMAkGA1UEBhMCVVMwHhcNMTMwMTEwMjIzOTAxWhcNMTgwMTExMjIzOTAx
+WjCBqDEaMBgGCgmSJomT8ixkAQEMClBCVjRHTFM5SjQxQDA+BgNVBAMMN0RldmVs
+b3BlciBJRCBBcHBsaWNhdGlvbjogQklUQ09JTiBGT1VOREFUSU9OLCBJTkMuLCBU
+SEUxEzARBgNVBAsMClBCVjRHTFM5SjQxJjAkBgNVBAoMHUJJVENPSU4gRk9VTkRB
+VElPTiwgSU5DLiwgVEhFMQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQAD
+ggEPADCCAQoCggEBALTd5zURuZVoJviusr119aktXksenb9IN9vq6kBbq38vxEk7
+9wkKMES2XfBRh0HxcEizGzhMNy5OCXuTLMaNMihYdfwYSoBoR2foEU+6kjPUnyJ4
+dQBFLJZJr5/QeQmALmYHEgZ6lwXFD2lU8t92340zeJ4y5LZw5pcEHtH9IummYDut
+OGCkCGXDcjL+5nHhNScJiXHhswM+62o6XXsQiP6EWbM1CsgrGTNLtaa0U/UvVDwE
+79YKklSC5Bog2LD0jBcTuveI66mFzqu++L9X9u+ZArtebwCl7BPNQ+uboYy5uV2d
+zf8lpNNZLfXCFjoLe9bLICKfZ7ub9V5aC8+GhckCAwEAAaOCAeEwggHdMD4GCCsG
+AQUFBwEBBDIwMDAuBggrBgEFBQcwAYYiaHR0cDovL29jc3AuYXBwbGUuY29tL29j
+c3AtZGV2aWQwMTAdBgNVHQ4EFgQUa5xsqKVzcHDiV6NJ2GL7l8elXV4wDAYDVR0T
+AQH/BAIwADAfBgNVHSMEGDAWgBRXF+2iz9x8mKEQ4Py+hy0s8uMXVDCCAQ4GA1Ud
+IASCAQUwggEBMIH+BgkqhkiG92NkBQEwgfAwKAYIKwYBBQUHAgEWHGh0dHA6Ly93
+d3cuYXBwbGUuY29tL2FwcGxlY2EwgcMGCCsGAQUFBwICMIG2DIGzUmVsaWFuY2Ug
+b24gdGhpcyBjZXJ0aWZpY2F0ZSBieSBhbnkgcGFydHkgYXNzdW1lcyBhY2NlcHRh
+bmNlIG9mIHRoZSB0aGVuIGFwcGxpY2FibGUgc3RhbmRhcmQgdGVybXMgYW5kIGNv
+bmRpdGlvbnMgb2YgdXNlLCBjZXJ0aWZpY2F0ZSBwb2xpY3kgYW5kIGNlcnRpZmlj
+YXRpb24gcHJhY3RpY2Ugc3RhdGVtZW50cy4wDgYDVR0PAQH/BAQDAgeAMBYGA1Ud
+JQEB/wQMMAoGCCsGAQUFBwMDMBMGCiqGSIb3Y2QGAQ0BAf8EAgUAMA0GCSqGSIb3
+DQEBCwUAA4IBAQAfJ0BjID/1dS2aEeVyhAzPzCBjG8vm0gDf+/qfwRn3+yWeL9vS
+nMdbilwM48IyQWTagjGGcojbsAd/vE4N7NhQyHInoCllNoeor1I5xx+blTaGRBK+
+dDhJbbdlGCjsLnH/BczGZi5fyEJds9lUIrp1hJidRcUKO76qb/9gc6qNZpl1vH5k
+lDUuJYt7YhAs+L6rTXDyqcK9maeQr0gaOPsRRAQLLwiQCorPeMTUNsbVMdMwZYJs
+R+PxiAnk+nyi7rfiFvPoASAYUuI6OzYL/Fa6QU4/gYyPgic944QYVkaQBnc0vEP1
+nXq6LGKwgVGcqJnkr/E2kui5gJoV5C3qll3e
+-----END CERTIFICATE-----
diff --git a/share/certs/BitcoinFoundation_Comodo_Cert.pem b/share/certs/BitcoinFoundation_Comodo_Cert.pem
new file mode 100644
index 0000000000..dc752d455c
--- /dev/null
+++ b/share/certs/BitcoinFoundation_Comodo_Cert.pem
@@ -0,0 +1,37 @@
+Bag Attributes
+ friendlyName: The Bitcoin Foundation, Inc.'s COMODO CA Limited ID
+ localKeyID: 8C 94 64 E3 B5 B0 41 89 5B 89 B0 57 CC 74 B9 44 E5 B2 92 66
+subject=/C=US/postalCode=98104-1444/ST=WA/L=Seattle/street=Suite 300/street=71 Columbia St/O=The Bitcoin Foundation, Inc./CN=The Bitcoin Foundation, Inc.
+issuer=/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO Code Signing CA 2
+-----BEGIN CERTIFICATE-----
+MIIFeDCCBGCgAwIBAgIRAJVYMd+waOER7lUqtiz3M2IwDQYJKoZIhvcNAQEFBQAw
+ezELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
+A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxITAfBgNV
+BAMTGENPTU9ETyBDb2RlIFNpZ25pbmcgQ0EgMjAeFw0xMzAxMTYwMDAwMDBaFw0x
+NDAxMTYyMzU5NTlaMIG8MQswCQYDVQQGEwJVUzETMBEGA1UEEQwKOTgxMDQtMTQ0
+NDELMAkGA1UECAwCV0ExEDAOBgNVBAcMB1NlYXR0bGUxEjAQBgNVBAkMCVN1aXRl
+IDMwMDEXMBUGA1UECQwONzEgQ29sdW1iaWEgU3QxJTAjBgNVBAoMHFRoZSBCaXRj
+b2luIEZvdW5kYXRpb24sIEluYy4xJTAjBgNVBAMMHFRoZSBCaXRjb2luIEZvdW5k
+YXRpb24sIEluYy4wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQChUwLD
+u/hu5aFZ/n11B27awONaaDrmHm0pamiWHb01yL4JmTBtaLCrSftF8RhCscQ8jpI0
+UG1Cchmay0e3zH5o5XRs0H9C3x+SM5ozms0TWDmAYiB8aQEghsGovDk0D2nyTQeK
+Q0xqyCh0m8ZPOnMnYrakHEmF6WvhLdJvI6Od4KIwbKxgN17cPFIfLVsZ7GrzmmbU
+Gdi4wSQCHy5rxzvBxho8Qq/SfBl93uOMUrqOHjOUAPhNuTJG3t/MdhU8Zp24s29M
+abHtYkT9W86hMjIiI8RTAR+WHKVglx9SB0cjDabXN8SZ3gME0+H++LyzlySHT8sI
+ykepojZ7UBRgp9w3AgMBAAGjggGzMIIBrzAfBgNVHSMEGDAWgBQexbEsfYfaAmh8
+JbwMB4Q/ts/e8TAdBgNVHQ4EFgQUfPf+ZyDWl/4LH0Y5BuJTelkRd/EwDgYDVR0P
+AQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwMwEQYJ
+YIZIAYb4QgEBBAQDAgQQMEYGA1UdIAQ/MD0wOwYMKwYBBAGyMQECAQMCMCswKQYI
+KwYBBQUHAgEWHWh0dHBzOi8vc2VjdXJlLmNvbW9kby5uZXQvQ1BTMEEGA1UdHwQ6
+MDgwNqA0oDKGMGh0dHA6Ly9jcmwuY29tb2RvY2EuY29tL0NPTU9ET0NvZGVTaWdu
+aW5nQ0EyLmNybDByBggrBgEFBQcBAQRmMGQwPAYIKwYBBQUHMAKGMGh0dHA6Ly9j
+cnQuY29tb2RvY2EuY29tL0NPTU9ET0NvZGVTaWduaW5nQ0EyLmNydDAkBggrBgEF
+BQcwAYYYaHR0cDovL29jc3AuY29tb2RvY2EuY29tMCgGA1UdEQQhMB+BHWxpbmRz
+YXlAYml0Y29pbmZvdW5kYXRpb24ub3JnMA0GCSqGSIb3DQEBBQUAA4IBAQAqibjo
+D4HG5XSIIMCmYE5RgQBSEAJfI+EZERk1G9F83ZUWr0yNRZCw4O+RaM7xQhvJhEoD
+G2kpk/q2bNOc71/VyZ6SrE1JRVUON41/Flhz4M6cP0BclTicXvh+efVwqZhIz+ws
+UxF2hvC/1Xx6rqI7NYAlOYXk2MSUq3HREo+gWUPKM8em4MZZV/7XCH4QbsfxOl1J
+xS6EOQmV8hfUN4KRXI5WfGUmedBxq7dM0RSJOSQl8fq2f+JjRLfjQwQucy7LDY+y
+pRTsL2TdQV/DuDuI3s0NHRGznQNddoX5jqpXhSQFAAdgrhN1gGkWaaTPzr9IF2TG
+qgr6PEp9tIYC+MbM
+-----END CERTIFICATE-----
diff --git a/share/certs/PrivateKeyNotes.md b/share/certs/PrivateKeyNotes.md
new file mode 100644
index 0000000000..da299d168f
--- /dev/null
+++ b/share/certs/PrivateKeyNotes.md
@@ -0,0 +1,46 @@
+Code-signing private key notes
+==
+
+The private keys for these certificates were generated on Gavin's main work machine,
+following the certificate authoritys' recommendations for generating certificate
+signing requests.
+
+For OSX, the private key was generated by Keychain.app on Gavin's main work machine.
+The key and certificate is in a separate, passphrase-protected keychain file that is
+unlocked to sign the Bitcoin-Qt.app bundle.
+
+For Windows, the private key was generated by Firefox running on Gavin's main work machine.
+The key and certificate were exported into a separate, passphrase-protected PKCS#12 file, and
+then deleted from Firefox's keystore. The exported file is used to sign the Windows setup.exe.
+
+Threat analysis
+--
+
+Gavin is a single point of failure. He could be coerced to divulge the secret signing keys,
+allowing somebody to distribute a Bitcoin-Qt.app or bitcoin-qt-setup.exe with a valid
+signature but containing a malicious binary.
+
+Or the machine Gavin uses to sign the binaries could be compromised, either remotely or
+by breaking in to his office, allowing the attacker to get the private key files and then
+install a keylogger to get the passphrase that protects them.
+
+Threat Mitigation
+--
+
+"Air gapping" the machine used to do the signing will not work, because the signing
+process needs to access a timestamp server over the network. And it would not
+prevent the "rubber hose cryptography" threat (coercing Gavin to sign a bad binary
+or divulge the private keys).
+
+Windows binaries are reproducibly 'gitian-built', and the setup.exe file created
+by the NSIS installer system is a 7zip archive, so you could check to make sure
+that the bitcoin-qt.exe file inside the installer had not been tampered with.
+However, an attacker could modify the installer's code, so when the setup.exe
+was run it compromised users' systems. A volunteer to write an auditing tool
+that checks the setup.exe for tampering, and checks the files in it against
+the list of gitian signatures, is needed.
+
+The long-term solution is something like the 'gitian downloader' system, which
+uses signatures from multiple developers to determine whether or not a binary
+should be trusted. However, that just pushes the problem to "how will
+non-technical users securely get the gitian downloader code to start?"
diff --git a/share/genbuild.sh b/share/genbuild.sh
new file mode 100755
index 0000000000..a15cb34e47
--- /dev/null
+++ b/share/genbuild.sh
@@ -0,0 +1,51 @@
+#!/bin/sh
+if [ $# -gt 1 ]; then
+ cd "$2"
+fi
+if [ $# -gt 0 ]; then
+ FILE="$1"
+ shift
+ if [ -f "$FILE" ]; then
+ INFO="$(head -n 1 "$FILE")"
+ fi
+else
+ echo "Usage: $0 <filename> <srcroot>"
+ exit 1
+fi
+
+DESC=""
+SUFFIX=""
+LAST_COMMIT_DATE=""
+if [ -e "$(which git 2>/dev/null)" -a "$(git rev-parse --is-inside-work-tree 2>/dev/null)" = "true" ]; then
+ # clean 'dirty' status of touched files that haven't been modified
+ git diff >/dev/null 2>/dev/null
+
+ # if latest commit is tagged and not dirty, then override using the tag name
+ RAWDESC=$(git describe --abbrev=0 2>/dev/null)
+ if [ "$(git rev-parse HEAD)" = "$(git rev-list -1 $RAWDESC 2>/dev/null)" ]; then
+ git diff-index --quiet HEAD -- && DESC=$RAWDESC
+ fi
+
+ # otherwise generate suffix from git, i.e. string like "59887e8-dirty"
+ SUFFIX=$(git rev-parse --short HEAD)
+ git diff-index --quiet HEAD -- || SUFFIX="$SUFFIX-dirty"
+
+ # get a string like "2012-04-10 16:27:19 +0200"
+ LAST_COMMIT_DATE="$(git log -n 1 --format="%ci")"
+fi
+
+if [ -n "$DESC" ]; then
+ NEWINFO="#define BUILD_DESC \"$DESC\""
+elif [ -n "$SUFFIX" ]; then
+ NEWINFO="#define BUILD_SUFFIX $SUFFIX"
+else
+ NEWINFO="// No build information available"
+fi
+
+# only update build.h if necessary
+if [ "$INFO" != "$NEWINFO" ]; then
+ echo "$NEWINFO" >"$FILE"
+ if [ -n "$LAST_COMMIT_DATE" ]; then
+ echo "#define BUILD_DATE \"$LAST_COMMIT_DATE\"" >> "$FILE"
+ fi
+fi
diff --git a/share/pixmaps/addressbook16.bmp b/share/pixmaps/addressbook16.bmp
new file mode 100644
index 0000000000..c5576910b1
--- /dev/null
+++ b/share/pixmaps/addressbook16.bmp
Binary files differ
diff --git a/share/pixmaps/addressbook16mask.bmp b/share/pixmaps/addressbook16mask.bmp
new file mode 100644
index 0000000000..d3a478d1ad
--- /dev/null
+++ b/share/pixmaps/addressbook16mask.bmp
Binary files differ
diff --git a/share/pixmaps/addressbook20.bmp b/share/pixmaps/addressbook20.bmp
new file mode 100644
index 0000000000..2b33b228aa
--- /dev/null
+++ b/share/pixmaps/addressbook20.bmp
Binary files differ
diff --git a/share/pixmaps/addressbook20mask.bmp b/share/pixmaps/addressbook20mask.bmp
new file mode 100644
index 0000000000..56ce6125db
--- /dev/null
+++ b/share/pixmaps/addressbook20mask.bmp
Binary files differ
diff --git a/share/pixmaps/bitcoin-bc.ico b/share/pixmaps/bitcoin-bc.ico
new file mode 100644
index 0000000000..88cc240e2d
--- /dev/null
+++ b/share/pixmaps/bitcoin-bc.ico
Binary files differ
diff --git a/share/pixmaps/bitcoin.ico b/share/pixmaps/bitcoin.ico
new file mode 100644
index 0000000000..f5480f4161
--- /dev/null
+++ b/share/pixmaps/bitcoin.ico
Binary files differ
diff --git a/share/pixmaps/bitcoin128.png b/share/pixmaps/bitcoin128.png
new file mode 100644
index 0000000000..55039b1c92
--- /dev/null
+++ b/share/pixmaps/bitcoin128.png
Binary files differ
diff --git a/share/pixmaps/bitcoin128.xpm b/share/pixmaps/bitcoin128.xpm
new file mode 100644
index 0000000000..d8e41e9ea4
--- /dev/null
+++ b/share/pixmaps/bitcoin128.xpm
@@ -0,0 +1,384 @@
+/* XPM */
+static char *bitcoin___[] = {
+/* columns rows colors chars-per-pixel */
+"128 128 250 2",
+" c #845415",
+". c #895616",
+"X c #84581E",
+"o c #8D5C18",
+"O c #925A15",
+"+ c #925E1C",
+"@ c #98621C",
+"# c #9E711C",
+"$ c #A36E1A",
+"% c #A96F1B",
+"& c #A6711C",
+"* c #AC741C",
+"= c #B2741E",
+"- c #B37C1E",
+"; c #BB7C1E",
+": c #835B21",
+"> c #8F6125",
+", c #956727",
+"< c #916B2E",
+"1 c #996B2C",
+"2 c #B47B23",
+"3 c #BD7C20",
+"4 c #A17330",
+"5 c #AB7D3B",
+"6 c #C17F20",
+"7 c #B9831F",
+"8 c #BB842B",
+"9 c #BD8533",
+"0 c #B68F3D",
+"q c #BE8C3B",
+"w c #C4801F",
+"e c #FE8C03",
+"r c #F38A0F",
+"t c #FD8E0A",
+"y c #FF910C",
+"u c #F78F13",
+"i c #F98F10",
+"p c #F79016",
+"a c #FE9314",
+"s c #F6931E",
+"d c #FD961B",
+"f c #FE991E",
+"g c #C58421",
+"h c #CD8621",
+"j c #C78B21",
+"k c #CC8B23",
+"l c #C2852B",
+"z c #C08B2D",
+"x c #D28722",
+"c c #D38B25",
+"v c #DB8E22",
+"b c #D28E2C",
+"n c #D49323",
+"m c #DC9224",
+"M c #DC9B25",
+"N c #D4922D",
+"B c #DF972A",
+"V c #DF982E",
+"C c #C18D33",
+"Z c #C58E38",
+"A c #CB9332",
+"S c #C2933C",
+"D c #CD9339",
+"F c #CC9938",
+"G c #D19733",
+"H c #DA9230",
+"J c #D59935",
+"K c #DC9C33",
+"L c #DC9E3B",
+"P c #E49124",
+"I c #EA9426",
+"U c #E09D26",
+"Y c #EC972B",
+"T c #F79625",
+"R c #F99524",
+"E c #F69A26",
+"W c #F89825",
+"Q c #F2972B",
+"! c #F59A2C",
+"~ c #F89B2B",
+"^ c #E79D33",
+"/ c #EF9D31",
+"( c #E19F3A",
+") c #EF9D3A",
+"_ c #F49C33",
+"` c #F99E32",
+"' c #F49F39",
+"] c #D6A13E",
+"[ c #DAA33B",
+"{ c #E3A127",
+"} c #E7A328",
+"| c #EDA32C",
+" . c #EDA829",
+".. c #FFA325",
+"X. c #FFAB25",
+"o. c #F3A42B",
+"O. c #FFA429",
+"+. c #F4A929",
+"@. c #FFAC2A",
+"#. c #FFB227",
+"$. c #FFB32C",
+"%. c #FFBA2D",
+"&. c #EEA830",
+"*. c #F7A334",
+"=. c #FAA036",
+"-. c #FCAB34",
+";. c #F4A13C",
+":. c #F9A33B",
+">. c #F4A83B",
+",. c #FFA83F",
+"<. c #FDB432",
+"1. c #FFBB33",
+"2. c #FFB73A",
+"3. c #FDB93E",
+"4. c #FFC12F",
+"5. c #FFC432",
+"6. c #FFC338",
+"7. c #D2A043",
+"8. c #D8A140",
+"9. c #EEA144",
+"0. c #E2A840",
+"q. c #EDA34B",
+"w. c #F4A444",
+"e. c #F9A642",
+"r. c #FBA945",
+"t. c #F3A64B",
+"y. c #F4A84E",
+"u. c #FBAB4B",
+"i. c #EEB041",
+"p. c #FABA44",
+"a. c #ECA653",
+"s. c #EEAC5D",
+"d. c #F3AA53",
+"f. c #FAAE53",
+"g. c #F2AD5A",
+"h. c #FBB056",
+"j. c #F6B15E",
+"k. c #FBB25B",
+"l. c #DDAF79",
+"z. c #E3A962",
+"x. c #EBAE63",
+"c. c #E4AC68",
+"v. c #EAAF69",
+"b. c #EEB065",
+"n. c #E7B06C",
+"m. c #EEB36B",
+"M. c #F5B263",
+"N. c #FBB461",
+"B. c #E6B274",
+"V. c #ECB574",
+"C. c #E7B57B",
+"Z. c #EAB77C",
+"A. c #ECB97C",
+"S. c #F2B770",
+"D. c #F0BB7A",
+"F. c #DBB485",
+"G. c #DFB888",
+"H. c #E4B984",
+"J. c #EDBD82",
+"K. c #E5BC8B",
+"L. c #EABE8A",
+"P. c #F0BE82",
+"I. c #E0BF96",
+"U. c #EDC089",
+"Y. c #F0C28B",
+"T. c #E5C194",
+"R. c #E9C191",
+"E. c #E4C39C",
+"W. c #EBC699",
+"Q. c #EBC99F",
+"!. c #DFC3A0",
+"~. c #DDCAAF",
+"^. c #CFC7BD",
+"/. c #D2CBB6",
+"(. c #DBC8B1",
+"). c #DBCDBB",
+"_. c #E2C6A4",
+"`. c #E6C8A5",
+"'. c #EACBA5",
+"]. c #E1C7A8",
+"[. c #E3CBAD",
+"{. c #EACCAA",
+"}. c #EED1AC",
+"|. c #E1CDB3",
+" X c #E3CFB8",
+".X c #E6D1B6",
+"XX c #EBD2B3",
+"oX c #E3D1BB",
+"OX c #EAD6BB",
+"+X c #EBD8BF",
+"@X c #D3CDC2",
+"#X c #D8CDC2",
+"$X c #D0CECA",
+"%X c #DDD3C4",
+"&X c #D3D2CC",
+"*X c #DDD5CB",
+"=X c #CCD3D5",
+"-X c #C9D7DF",
+";X c #D2D4D6",
+":X c #DEDAD4",
+">X c #DDDCDB",
+",X c #E2D4C2",
+"<X c #ECDBC2",
+"1X c #E2D7CA",
+"2X c #E3D8CC",
+"3X c #E2DCD6",
+"4X c #E9DED2",
+"5X c #E1DEDA",
+"6X c #EEE0CE",
+"7X c #EEE3D4",
+"8X c #E7E2DA",
+"9X c #EEE4D8",
+"0X c #F3E6D1",
+"qX c #C5D7ED",
+"wX c #CDDBEB",
+"eX c #DBDEE2",
+"rX c #CBDCF1",
+"tX c #C4DFFF",
+"yX c #DEE1E4",
+"uX c #DDE4EC",
+"iX c #D3E1F2",
+"pX c #DDE6F1",
+"aX c #DEE9F4",
+"sX c #D8E5F8",
+"dX c #D6EEFF",
+"fX c #DEECFB",
+"gX c #D5F4FF",
+"hX c #DDF3FF",
+"jX c #DCF9FF",
+"kX c #E3E4E6",
+"lX c #EFEBE4",
+"zX c #E1E5EB",
+"xX c #E2E8ED",
+"cX c #F1F1ED",
+"vX c #E0E7F0",
+"bX c #E2E9F2",
+"nX c #EAEFF6",
+"mX c #E1EEFD",
+"MX c #E4F1F6",
+"NX c #E3F4FF",
+"BX c #EAF6FF",
+"VX c #E5F9FF",
+"CX c #EBFAFF",
+"ZX c #F5F5F5",
+"AX c #F9F7F5",
+"SX c #FAF8F6",
+"DX c #F3F7FB",
+"FX c #F4FAFE",
+"GX c #FEFEFE",
+"HX c None",
+/* pixels */
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX1 Z L >.N b b b b N >.( C > HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX4 L _ *.@.<.$.X.X...X.X.X.X.X.X...X.@.$.<.@.*./ G , HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX< L -.@.$.X...R R R T T T T W W W W W W T T T T R R W ..X.$.@.*.J HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXD -.%.X.W R T T W W W W W W W W W W W W W W W W W W W W W W T T R W X.%.+.A HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXS -.$.X.R T T W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W T T R X.$.-.C HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXF <.@.f R T W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W T R W #.<.A HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX[ <.X.f T W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W T R X.$.K HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX0.$...R T W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W E W W W W W W W T R ..%.G HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXS 1...R T W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W E ~ ~ E W W W W W W W W W T R X.1.A HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX3.X.d T W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W ~ ~ ~ ~ ~ E W W W W W W W W W W T R @.2.HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX7.5.f T W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W ~ ~ ~ ~ ~ ~ ~ E W W W W W W W W W W W W T W %.z HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX3.X.s T W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W ~ ~ ~ ~ ~ ~ ~ ~ ~ W W W W W W W W W W W W W T R $.<.HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX1...R W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W E ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ E E W W W W W W W W W W W W W R ..1.HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX0 5.f T W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W T W 5.8 HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX8.$.s W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W E ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ` ~ ~ ~ ~ ~ W W W W W W W W W W W W W W W W T R %.N HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXi.#.R W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W E ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ` ` ` ` ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W W W R $.&.HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXp.X.R W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W E ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ` ` ` ` ` ~ ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W W W R @.<.HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXp.X.R W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W E ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ` ` ` ` ` ` ` ~ ~ ~ ~ ~ ~ W W W W W W W W W W W W W W W W W R @.<.HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXi.X.R W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W E ~ E ~ W R ~ ~ ~ ~ ~ ~ ` ` ` ` ` ` ` ` ` ` ~ ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W W W W R @.| HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX] #.R W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W ~ ~ ~ ~ ~ ! s e t d ~ ` ` ` ` ` ` =.=.=.` ` ` ` ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W W W W W R %.N HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXq %.R W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W E W E ~ ~ ~ ~ y l.=XI.x.) p a =.` ` =.=.=.=.=.=.` ` ` ~ ~ ~ ~ ~ ~ W W W W W W W W W W W W W W W W W W W R %.2 HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX5 5.d W W W W W W W W W W W W W W W W W W W W W W W W W W W W W E ~ ~ ~ ~ ~ ~ ~ ~ t (.jXVXNXuX@XF.W ` =.:.` W =.:.=.=.` ` ` ~ ~ ~ ~ ~ W W W W W W W W W W W W W W W W W W W T R 5.HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX1.f T W W W W W W W W W W W W W W W W W W W W W W W W W W W W E ~ ~ ~ ~ ~ ~ ~ ~ R Q eXDXSXSXDXgX#Xa ` =.=.;.q.W a a R ` ` ` ~ ~ ~ ~ ~ ~ W W W W W W W W W W W W W W W W W W W T W %.HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX3...T W W W W W W W W W W W W W W W W W W W W W W W W W W W E ~ ~ ~ ~ ~ ~ ~ ~ ~ ` a a.NXSXGXGXAXNXV.a :.:.f c.tX*XE.n.9.R ~ ` ` ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W W W W W W T @.@.HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXD #.R W W W W W W W W W W W W W W W W W W W W W W W W W W W E ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ` t H.VXSXGXGXDXmXy.f :.:.a I.hXBXCXNXiX^.' W ` ~ ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W W W W W W R %.g HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX5.d W W W W W W W W W W W W W W W W W W W W W W W W W E ~ W ~ ~ ~ ~ ~ ~ ~ ~ ~ ` ` ` i |.CXGXGXGXCX3X~ ` :.:.R %XCXSXGXAXNX>XW ~ ` ` ~ ~ ~ ~ ~ ~ W W W W W W W W W W W W W W W W W W W W R 5.HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX2.W T W W W W W W W W W W W W W W W W W W W W W W W W ~ ~ ~ s t e a W ~ ` ` ` ` ` ` W ! eXFXGXGXSXVX[.d :.:.~ w.uXFXGXGXSXVXW.a ` ` ` ` ~ ~ ~ ~ ~ W W W W W W W W W W W W W W W W W W W W T ..@.HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHX9 $.R W W W W W W W W W W W W W W W W W W W W W W E W ~ ~ ~ y F./.B.9.T t t a ~ =.` =.a a.hXDXGXGXSXNXA.d :.e.R v.NXSXGXGXSXNXm.a =.` ` ` ~ ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W W W W W W R %.= HXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHX6.d W W W W W W W W W W W W W W W W W W W W W W E ~ ~ ~ ~ W i &XjXNXfX:X].B.q.T t a d e K.VXSXGXGXDXaXd.W e.e.d E.VXSXGXGXDXvXw.W =.` ` ` ` ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W W W W W W W W %.HXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXK X.T W W W W W W W W W W W W W W W W W W W W ~ ~ ~ ~ ~ ~ ~ a ) uXDXSXFXFXCXNXfX:X_.B.q.r .XFXGXGXGXCX3X=.=.e.,.~ %XCXGXGXGXCX1XW ` =.` ` ` ` ~ ~ ~ ~ ~ ~ W W W W W W W W W W W W W W W W W W W W T $.m HXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHX5.R W W W W W W W W W W W W W W W W W W W E ~ ~ ~ ~ ~ ~ ~ ~ t x.NXSXGXGXGXSXSXDXFXCXNXmX8XcXSXGXGXGXCXW.e :.e.=.t.uXFXGXGXSXVXE.d :.=.=.` ` ` ~ ~ ~ ~ ~ ~ W W W W W W W W W W W W W W W W W W W W W R %.HXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHX^ X.T W W W W W W W W W W W W W W W W W W ~ ~ ~ ~ ~ ~ ~ ~ ~ ` t T.VXSXGXGXGXGXGXGXGXSXSXFXGXGXGXGXGXGXFX}.9.' W e v.VXSXGXGXSXNXm.d :.=.=.=.` ` ` ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W W W W W W W T @.P HXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHX1.R W W W W W W W W W W W W W W W W E E ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ s ;XNXAXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXSXFXNX>X|.V.XXFXGXGXGXFXbXy.~ :.:.=.=.` ` ` ` ~ ~ ~ ~ ~ W W W W W W W W W W W W W W W W W W W W W R %.HXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXH X.T W W W W W W W W W W W W W W E E ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ` ` R ' $XsXNXVXFXSXSXGXGXGXGXGXGXGXGXGXGXGXGXGXGXSXFXCXCXFXSXGXGXGXCXOXa :.:.:.=.=.=.` ` ` ~ ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W W W W W W T $.c HXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHX1.R W W W W W W W W W W W W W W W ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ` ` ` ` ` ` ~ t.V.`.5XVXFXSXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXFX<X_ d d =.:.=.=.` ` ` ` ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W W W W W W W R $.HXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHX8 $.T W W W W W W W W W W W E E ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ` ` ` ` ` =.=.~ f a a W b.xXFXSXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXSXFXmX~.x.T a =.:.=.` ` ` ~ ~ ~ ~ ~ ~ W W W W W W W W W W W W W W W W W W W W T $.3 HXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHX-.W W W W W W W W W W W W ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ` ` ` ` ` ` =.=.=.=.=.:.:.:.` e y.MXFXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXSXFXCXhX*Xn.p a :.=.` ` ` ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W W W W W W W ~ O.HXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHX1.R W W W W W W W W W ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ` ` ` ` ` =.` =.=.=.:.:.:.:.:.:.:.a .XFXGXGXGXGXGXGXGXGXGXFXFXSXSXGXGXGXGXGXGXGXGXGXGXGXSXAXCXhX%Xq.t ~ =.` ` ` ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W W W W W W R %.HXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXb @.T W W W W W W W W E ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ` ` ` ` ` ` =.=.=.=.=.:.:.:.:.:.:.:.e.d [.CXGXGXGXGXGXGXGXGXSXZXnXNXNXBXDXSXSXGXGXGXGXGXGXGXGXGXSXAXCXhXH.t W :.` ` ~ ~ ~ ~ ~ ~ W W W W W W W W W W W W W W W W W W W T @.x HXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHX<.R W W W W W E E E ~ ~ ~ ~ ~ ~ ~ ~ ~ ` ~ ` ` ` ` ` =.=.=.=.=.:.:.:.:.:.:.:.:.e.=.' >XFXGXGXGXGXGXGXGXSXCX{.e.P.'.2XvXNXBXDXSXGXGXGXGXGXGXGXGXGXSXDXjX~.y W =.` ` ~ ~ ~ ~ ~ W W W W W W W W W W W W W W W W W W W W W @.HXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHX: 1.R W W W W E ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ` ` ` ` ` ` =.=.=.=.=.:.:.:.:.:.:.:.:.e.e.e.~ s.fXDXGXGXGXGXGXGXGXSXNXD.f =.=.,.M.L.oXaXVXDXSXGXGXGXGXGXGXGXGXGXAXVX(.t ~ ` ` ~ ~ ~ ~ ~ ~ W W W W W W W W W W W W W W W W W W W R %. HXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXl #.T W W W E ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ` ` ` ` ` ` =.=.=.=.:.:.:.:.:.:.:.:.:.e.e.e.e.r.W H.NXSXGXGXGXGXGXGXGXDXzXg.r.f.f.f.r.=.=.g.`.fXBXAXGXGXGXGXGXGXGXGXGXAXjXH.t =.` ` ~ ~ ~ ~ ~ W W W W W W W W W W W W W W W W W W W T $.6 HXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHX~ ..W W W W E ~ ~ ~ ~ ~ ~ ~ ~ ` ` ` ` ` ` =.=.=.=.=.:.:.:.:.:.:.:.e.e.e.e.e.e.e.r.W |.CXGXGXGXGXGXGXGXGXBX1X,.f.f.f.f.h.h.f.,.~ d.3XVXAXGXGXGXGXGXGXGXGXGXDXsX' f ` ` ~ ~ ~ ~ ~ ~ W W W W W W W W W W W W W W W W W W W ..~ HXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHX$.R W W W W W E ~ ~ ~ ~ ~ ` ` ` ` ` ` =.=.=.=.=.=.:.:.:.:.:.:.:.e.e.e.e.e.r.r.r.,.w.>XFXGXGXGXGXGXGXGXSXNX`.=.f.h.h.h.h.f.f.f.f.=.~ ,XVXSXGXGXGXGXGXGXGXGXSXVXT.y ` ` ` ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W W W W W R $.HXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXX %.T W W W W W E ~ ~ ~ ~ ~ ` ` ` ` =.=.=.=.=.:.:.:.:.:.:.:.:.e.e.e.e.e.e.r.r.r.u.=.x.fXDXGXGXGXGXGXGXGXSXmXA.,.h.h.h.k.k.h.f.f.f.f.:.~ 5XFXGXGXGXGXGXGXGXGXGXCX:XW ~ ` ` ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W W W W W T $.. HXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHX8 $.T W W W W W W E ~ ~ ~ ~ ~ ` ` ` =.=.=.:.:.:.:.:.:.:.:.e.e.e.e.e.r.r.r.r.r.u.u.~ K.NXSXGXGXGXGXGXGXGXDXzXj.r.k.k.k.k.k.h.f.f.f.f.f.W V.VXSXGXGXGXGXGXGXGXGXDXuXw.f ` ` ` ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W W W W T $.3 HXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXY ..W W W W W W W E ~ ~ ~ ~ ~ ~ ` ` ` =.=.=.:.:.:.:.:.e.e.e.e.e.e.r.r.r.r.u.u.u.u.~ |.CXGXGXGXGXGXGXGXGXBX2Xr.f.k.k.k.k.k.k.h.f.f.f.f.,.d.bXFXGXGXGXGXGXGXGXGXDXfXd.d =.` ` ~ ~ ~ ~ ~ ~ W W W W W W W W W W W W W W W W W W O.P HXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXO.W W W W W W W W W ~ ~ ~ ~ ~ ~ ` ` ` ` =.=.:.:.:.:.e.e.e.e.r.r.r.r.r.r.u.u.u.u.r.w.>XFXGXGXGXGXGXGXGXSXNX'.,.k.k.k.k.k.k.k.h.h.f.f.f.e.y.kXFXGXGXGXGXGXGXGXGXDXfXg.d =.` ` ` ~ ~ ~ ~ ~ W W W W W W W W W W W W W W W W W W W O.HXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHX$.R W W W W W W W W E ~ ~ ~ ~ ~ ` ` ` ` =.=.=.:.:.:.:.e.e.r.r.r.r.u.u.u.u.u.u.f.=.b.fXDXGXGXGXGXGXGXGXSXmXJ.r.k.k.k.k.k.k.k.h.h.f.f.f.:.s.mXFXGXGXGXGXGXGXGXGXDXpXy.R =.` ` ` ~ ~ ~ ~ ~ E E W W W W W W W W W W W W W W W W W $.HXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHX1.R W W W W W W W W W ~ ~ ~ ~ ~ ~ ` ` ` =.=.=.:.:.:.:.e.e.e.r.r.u.u.u.u.u.u.u.f.=.K.NXSXGXGXGXGXGXGXGXFXxXM.u.k.k.k.k.k.k.k.k.h.f.f.k.~ K.VXSXGXGXGXGXGXGXGXGXCX5X=.~ =.=.` ` ` ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W W W W $.HXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHX+ $.T W W W W W W W W W W ~ ~ ~ ~ ~ ~ ` ` ` =.=.=.:.:.:.:.e.e.e.r.r.u.u.u.u.f.f.f.=.|.CXGXGXGXGXGXGXGXGXFX<X~ u.k.N.N.N.k.k.k.k.k.k.k.=.;.uXFXGXGXGXGXGXGXGXGXSXBXoXR =.=.=.` ` ` ~ ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W W T $.O HXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXl @.T W W W W W W W W W W ~ ~ ~ ~ ~ ~ ` ` ` =.=.=.:.:.:.:.e.e.e.r.r.u.u.u.u.f.f.u.t.>XFXGXGXGXGXGXGXGXGXFX9XA.b.u.r.r.u.u.h.h.h.u.r.O.w.:XCXSXGXGXGXGXGXGXGXGXSXhXL.a :.=.=.=.` ` ` ~ ~ ~ ~ ~ ~ W W W W W W W W W W W W W W W T $.* HXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXV X.T W W W W W W W W W W E ~ ~ ~ ~ ~ ~ ` ` ` =.=.=.:.:.:.:.e.e.e.r.r.u.u.u.u.f.,.b.fXFXGXGXGXGXGXGXGXGXSXFXVXpX*X[.R.V.M.g.d.d.g.b.T.pXCXSXGXGXGXGXGXGXGXGXGXDXpXe.~ :.:.=.=.` ` ` ~ ~ ~ ~ ~ ~ W W W W W W W W W W W W W W W T $.; HXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHX| O.T W W W W W W W W W W W ~ ~ ~ ~ ~ ~ ` ` ` ` =.=.:.:.:.:.:.e.e.r.r.u.u.u.u.f.=.K.NXSXGXGXGXGXGXGXGXGXGXGXSXFXFXBXNXmXuX>X3X3XyXmXVXFXSXGXGXGXGXGXGXGXGXGXAXhXE.d :.:.:.=.=.` ` ` ` ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W T @.h HXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXc @.T W W W W W W W W W W W E ~ ~ ~ ~ ~ ~ ` ` ` ` =.:.:.:.:.:.e.e.e.r.r.u.u.u.u.=.|.BXGXGXGXGXGXGXGXGXGXGXGXGXGXGXSXSXSXFXFXFXFXFXSXSXGXGXGXGXGXGXGXGXGXGXAXNX>X~ =.e.:.:.:.=.` ` ` ` ~ ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W @.h HXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXk @.T W W W W W W W W W W W W W ~ ~ ~ ~ ~ ~ ` ` ` =.=.:.:.:.:.e.e.e.r.r.r.u.u.r.w.>XFXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXSXZXNXeXe.~ e.:.:.:.:.=.=.=.` ` ` ~ ~ ~ ~ ~ ~ W W W W W W W W W W W W W W @.h HXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXc @.T W W W W W W W W W W W W W ~ ~ ~ ~ ~ ~ ` ` ` =.=.=.:.:.:.:.e.e.e.r.r.u.u.=.x.fXFXGXGXGXGXGXGXGXGXGXFXFXSXSXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXFXCXfXoX:.~ r.e.:.:.:.:.:.=.` ` ` ` ~ ~ ~ ~ ~ ~ W W W W W W W W W W W W W W @.h HXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXc @.T W W W W W W W W W W W W W E ~ ~ ~ ~ ~ ` ` ` ` =.=.:.:.:.:.:.e.e.r.r.r.u.~ K.NXSXGXGXGXGXGXGXGXSXZX6XkXmXNXBXDXAXSXGXGXGXGXGXGXGXGXGXGXGXGXGXGX0X'.S.~ =.u.e.e.e.:.:.:.:.=.=.` ` ` ` ~ ~ ~ ~ ~ ~ W W W W W W W W W W W W W @.h HXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXk @.T W W W W W W W W W W W W W W ~ ~ ~ ~ ~ ~ ` ` ` ` =.=.:.:.:.:.e.e.e.r.r.u.~ |.CXGXGXGXGXGXGXGXGXFX4X,.k.D.Q.,XkXmXNXDXSXSXGXGXGXGXGXGXGXGXGXGXGX<X_ y r.u.r.r.e.e.e.:.:.:.:.=.=.` ` ` ~ ~ ~ ~ ~ ~ W W W W W W W W W W W W W @.h HXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXc @.T W W W W W W W W W W W W W W E ~ ~ ~ ~ ~ ` ` ` ` =.=.=.:.:.:.e.e.e.r.r.e.;.>XFXGXGXGXGXGXGXGXSXVX{.,.f.u.r.u.N.J.{.5XNXBXAXSXGXGXGXGXGXGXGXGXGXFXMXH.W r.u.r.e.e.e.:.:.:.:.=.=.` ` ` ` ~ ~ ~ ~ ~ ~ W W W W W W W W W W W T @.h HXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXo.O.T W W W W W W W W W W W W W W E ~ ~ ~ ~ ~ ~ ` ` ` =.=.=.:.:.:.:.e.e.e.r.O.s.fXFXGXGXGXGXGXGXGXSXmXJ.r.N.N.N.N.h.r.r.f.J.1XhXBXAXGXGXGXGXGXGXGXGXSXDXjX!.W e.u.r.e.e.e.:.:.:.:.=.=.` ` ` ` ~ ~ ~ ~ ~ E W W W W W W W W W W T @.g HXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXB X.T W W W W W W W W W W W W W W W W ~ ~ ~ ~ ~ ~ ` ` ` =.=.:.:.:.:.:.e.e.r.W H.NXSXGXGXGXGXGXGXGXDXuXM.u.k.k.N.N.N.N.N.h.,.e.D.>XNXSXGXGXGXGXGXGXGXGXSXZXjXE.W r.r.e.e.e.:.:.:.:.=.=.=.` ` ` ~ ~ ~ ~ ~ ~ W W W W W W W W W W T $.- HXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXl @.T W W W W W W W W W W W W W W W W E ~ ~ ~ ~ ~ ` ` ` =.=.=.:.:.:.:.e.e.r.W |.CXGXGXGXGXGXGXGXGXBX2Xr.h.k.k.k.k.k.k.k.k.k.h.,.,.|.NXZXGXGXGXGXGXGXGXGXGXZXgXV.~ u.e.e.e.:.:.:.:.:.=.=.` ` ` ` ~ ~ ~ ~ ~ ~ W W W W W W W W W T $.% HXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHX@ $.T W W W W W W W W W W W W W W W W E ~ ~ ~ ~ ~ ~ ` ` ` ` =.=.:.:.:.:.e.:.' >XFXGXGXGXGXGXGXGXSXNX{.,.k.k.k.k.k.k.k.k.k.k.k.k.u.~ `.NXSXGXGXGXGXGXGXGXGXSXCX>X=.e.r.r.e.e.:.:.:.:.:.=.=.` ` ` ~ ~ ~ ~ ~ ~ W W W W W W W W W T $.. HXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHX%.R W W W W W W W W W W W W W W W W W E ~ ~ ~ ~ ~ ` ` ` ` =.=.:.:.:.:.e.~ s.fXFXGXGXGXGXGXGXGXSXNXJ.,.k.k.k.k.k.k.k.k.k.k.h.h.k.u.O.2XCXGXGXGXGXGXGXGXGXGXAXhXV.~ u.r.e.e.e.:.:.:.:.=.=.=.` ` ` ~ ~ ~ ~ ~ W W W W W W W W W W $.HXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHX$.R W W W W W W W W W W W W W W W W W E ~ ~ ~ ~ ~ ~ ` ` ` ` ~ :.:.:.:.e.f Z.VXSXGXGXGXGXGXGXGXDXzXM.r.k.k.k.k.k.k.k.h.h.h.h.f.f.k.=.V.NXSXGXGXGXGXGXGXGXGXSXVX`.W r.e.e.e.e.:.:.:.:.=.=.=.` ` ` ~ ~ ~ ~ ~ ~ E W W W W W W W W $.HXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXO.W W W W W W W W W W W W W W W W W W W ~ ~ ~ ~ ~ ~ ` ` =.~ Q a a W =.=.t XCXGXGXGXGXGXGXGXGXBX2Xr.f.k.k.k.k.k.k.h.h.h.h.f.f.f.f.r.y.kXFXGXGXGXGXGXGXGXGXGXBX,X~ :.e.e.e.:.:.:.:.:.:.=.=.` ` ` ` ~ ~ ~ ~ ~ E W W W W W W W ~ ..HXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXI O.W W W W W W W W W W W W W W W W W W W ~ ~ ~ ~ ~ ~ ` a z.-X_.B.q.! u C.NXSXGXGXGXGXGXGXGXSXNX'.=.h.h.k.k.k.h.h.f.f.f.f.f.f.f.f.r.w.5XFXGXGXGXGXGXGXGXGXGXCX2X=.:.e.:.:.:.:.:.:.:.:.=.=.=.` ` ` ` ~ ~ ~ ~ ~ E W W W W W W O.P HXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXk @.T W W W W W W W W W W W W W W W W W W ~ ~ ~ ~ ~ ~ ~ t ).jXVXNXaX2X1XBXDXSXGXGXGXGXGXGXGXSXmXA.:.h.h.h.h.h.f.f.f.f.f.f.f.f.f.f.,.d.vXFXGXGXGXGXGXGXGXGXGXCX1X` =.:.:.:.:.:.:.=.=.=.=.=.=.` ` ` ` ~ ~ ~ ~ ~ ~ W W W W W T $.; HXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXo %.T W W W W W W W W W W W W W W W W W W W W ~ ~ ~ ` y q.fXZXSXSXFXFXFXSXSXGXGXGXGXGXGXGXGXFXxXj.r.f.h.h.h.f.f.f.f.f.f.f.f.u.u.f.W B.NXSXGXGXGXGXGXGXGXGXSXBXoXW :.:.:.:.:.:.=.=.=.=.=.` ` ` ` ` ` ~ ~ ~ ~ ~ ~ W W W W W W %. HXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHX$.R W W W W W W W W W W W W W W W W W W W E ~ ~ ~ ` e !.CXSXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXFX+Xd ,.f.h.h.h.f.f.f.f.f.f.u.u.u.f.,.T :XFXGXGXGXGXGXGXGXGXGXSXNXE.f :.:.:.:.:.=.=.=.=.` ` ` ` ` ` ~ ~ ~ ~ ~ ~ ~ ~ ~ W W W W R $.HXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHX~ ..W W W W W W W W W W W W W W W W W W W W E ~ ~ a _ aXFXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXFX7XV.s.:.=.:.,.u.f.f.f.f.u.u.u.r.~ s ~.VXSXGXGXGXGXGXGXGXGXGXAXhXV.d :.:.=.=.=.=.=.` ` ` ` ` ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W W W W O.E HXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXg $.T W W W W W W W W W W W W W W W W W W W E ~ ~ e G.hXAXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXSXFXVXpX*X_.Z.x.t.:.` ~ ~ ~ ~ ~ ' x.*XVXSXGXGXGXGXGXGXGXGXGXGXDXuXw.W :.=.=.=.=.` ` ` ` ` ` ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W W W W W W T $.; HXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHX %.R W W W W W W W W W W W W W W W W W W W W ~ d T qXgXBXFXSXSXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXSXFXFXBXNXaX>X,X[._.T.T.E.|.:XNXCXSXGXGXGXGXGXGXGXGXGXGXSXVX Xd =.=.=.=.` ` ` ` ` ` ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ E W W W W W W R %.HXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHX@.W W W W W W W W W W W W W W W W W W W W W ~ R ` s.H.oXkXNXNXCXFXSXSXGXGXGXGXGXGXGXGXGXGXGXGXGXGXSXSXDXFXCXCXBXVXVXBXCXFXSXSXGXGXGXGXGXGXGXGXGXGXGXAXhXm.a :.` =.` ` ` ` ` ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W W W W W W W W W W @.HXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXx @.T W W W W W W W W W W W W W W W W W W W W ~ ~ y t a _ g.L.oXkXhXVXCXFXSXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXSXGXSXSXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXSXBX:Xf ~ ` ` ` ` ` ` ` ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ E W W W W W W W W W T $.h HXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHX%.R W W W W W W W W W W W W W W W W W W W W W ~ ~ ~ ~ d a t a ' s.R.oXnXDXSXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXZXhXg.y =.` ` ` ` ` ~ ~ ~ ~ ~ ~ ~ ~ ~ E ~ E W W W W W W W W W W R %.HXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXO.~ W W W W W W W W W W W W W W W W W W W W W ~ ~ ~ ~ ~ ` ` ~ W a a d ! <XFXGXGXGXGXGXFXSXSXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXAXjX`.y ` ` ` ` ` ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ E E W W W W W W W W W W W W ..O.HXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHX; $.T W W W W W W W W W W W W W W W W W W W W W ~ ~ ~ ~ ~ ~ ` ` ` =.~ p 2XFXGXGXGXSXZXMXNXVXFXSXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXZXjX%Xa W =.` ` ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W W W W W W W W W W W W W W T %.= HXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHX%.R W W W W W W W W W W W W W W W W W W W W W ~ ~ ~ ~ ~ ~ ~ ` ` =.d a.mXSXGXGXSXCXY.:.U..XkXDXSXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXSXAXBXjX Xa d =.` ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W W W R $.HXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXv $.T W W W W W W W W W W W W W W W W W W W W E ~ ~ ~ ~ ~ ~ ` ` ` a C.NXSXGXGXDXNXg.a ~ ~ ~ '.FXGXGXGXGXFXFXFXDXDXSXSXSXSXSXSXSXSXDXBXhXuXZ.y d ` ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W W W T $.x HXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHX%.R W W W W W W W W W W W W W W W W W W W W W W ~ ~ ~ ~ ~ ` ` =.i ].CXGXGXGXCX5X:.:.r.r.d [.FXGXGXGXFXlXXX3XzXmXNXNXNXNXNXNXNXfXuX,XJ.~ t ~ ` ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W W W W W R %.HXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXP @.T W W W W W W W W W W W W W W W W W W W W W ~ ~ ~ ~ ~ ~ ` ~ E :XFXGXGXGXVX|.R e.r.:.w.yXFXGXGXSXCX'.e ` t.g.m.J.L.R.R.L.A.x.;.d t f ` ` ~ ~ ~ ~ ~ ~ ~ ~ ~ W W W W W W W W W W W W W W W W W W W W T @.m HXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHX%.R W W W W W W W W W W W W W W W W W W W W W E ~ ~ ~ ~ ~ ` a q.fXDXGXGXSXNXJ.f e.r.~ x.hXSXGXGXSXNXV.d ` W f d d a a a a a a d ~ ` ` ~ ~ ~ ~ ~ ~ ~ ~ E E W W W W W W W W W W W W W W W W W W W W W R %.HXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXP $.T W W W W W W W W W W W W W W W W W W W W W E ~ ~ ~ ~ ` t C.VXSXGXGXDXfXg.W e.r.f K.VXSXGXGXDXbXt.W :.:.:.=.=.=.` ` ` ` ` ` ~ ~ ~ ~ ~ ~ ~ ~ ~ E E W W W W W W W W W W W W W W W W W W W W W W T $.v HXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHX%.W W W W W W W W W W W W W W W W W W W W W W E ~ ~ ~ ~ ~ t ].CXSXGXGXFX3X` =.e.e.R ).CXGXGXGXCX2XW ` =.=.=.` ` ` ` ` ` ~ ` ~ ~ ~ ~ ~ ~ ~ ~ ~ E E W W W W W W W W W W W W W W W W W W W W W W W W %.HXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHX* %.R W W W W W W W W W W W W W W W W W W W W W ~ ~ ~ ~ R Q wXNXAXSXSXVX[.d :.e.=.;.yXFXGXGXSXVX`.a =.=.=.` ` ` ` ` ` ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W W W W W W W W W W W T %.* HXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX@.O.T W W W W W W W W W W W W W W W W W W W W E ~ ~ ~ d ' @XyXNXVXNXdXZ.d :.e.R s.NXSXGXGXSXNXV.a =.` ` ` ` ` ` ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W W W W W W W W W W W W W W W W W W W W W W W W W W W T O.@.HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX5.R W W W W W W W W W W W W W W W W W W W W W ~ ~ ~ ! ~ d ' b.W.%XrXd.R :.:.a K.NXSXGXGXFXbXw.f =.` ` ` ` ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ E E W W W W W W W W W W W W W W W W W W W W W W W W W W W R 5.HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXg %.R W W W W W W W W W W W W W W W W W W W W E ~ ~ ~ ~ ~ d a y R w.:.=.:.=.R =XgXDXSXAXBX1XR ~ ` ` ` ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W W W W W W W W W W W W W W W T %.w HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX+.@.T W W W W W W W W W W W W W W W W W W W W ~ ~ ~ ~ ~ ` ` ` ~ R ` :.:.=.` K.%XzXNXNXgXE.y ` ` ` ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W W W W W W W W W W W W W W W W W W W W W W W W W W W W W T @.o.HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX%.~ T W W W W W W W W W W W W W W W W W W W W ~ ~ ~ ~ ~ ` ` ` ` =.=.:.:.:.d d ;.b.R.&Xv.a ` ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W T ~ %.HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX4.R T W W W W W W W W W W W W W W W W W W W E ~ ~ ~ ~ ~ ` ` ` ` =.=.=.=.=.` R a y R ~ ` ~ ~ ~ ~ ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W T R 5.HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX& %.R W W W W W W W W W W W W W W W W W W W E ~ ~ ~ ~ ~ ~ ` ` ` =.=.` ` ` ` ` ` ` ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W R 4.$ HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXk %.R W W W W W W W W W W W W W W W W W W W W ~ ~ ~ ~ ~ ` ` ` ` ` ` ` ` ` ` ~ ~ ~ ~ ~ ~ ~ ~ ~ E E E W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W R %.g HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXM %.R W W W W W W W W W W W W W W W W W W W ~ ~ ~ ~ ~ ~ ` ` ` ` ` ` ` ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W R %.n HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX{ $.R W W W W W W W W W W W W W W W W W W ~ ~ ~ ~ ~ ~ ` ` ` ` ` ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W R $.U HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX{ $.R W W W W W W W W W W W W W W W W W W E ~ ~ ~ ~ ~ ` ` ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ E E W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W R %.M HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXM %.R W W W W W W W W W W W W W W W W W E ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W R %.n HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXk %.R T W W W W W W W W W W W W W W W W ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W T W %.g HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX* 4.~ T W W W W W W W W W W W W W W W ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W T ..4.# HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX%.@.T W W W W W W W W W W W W W W W ~ ~ ~ ~ ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W T @.%.HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX .%.R T W W W W W W W W W W W W W E ~ ~ ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W T R %.} HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX7 4.O.T W W W W W W W W W W W W W ~ ~ ~ ~ E E W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W T O.%.- HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX+.%.W T W W W W W W W W W W W E ~ E E W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W T W %. .HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX- %.@.R T W W W W W W W W W W ~ W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W T R $.%.* HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXk %.@.R T W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W T R @.%.j HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXn %.@.R T W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W T W @.%.n HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXk $.$.~ R T W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W T R ..$.$.j HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX- O.%.@.W T T W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W T T W @.%.O.* HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXk @.%.$.O.R T T W W W W W W W W W W W W W W W W W W W W W W T T R O.$.%.@.h HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX; E $.%.$.O.~ W W T T T T T T T T T T T T T T W W W O.$.$.$.E ; HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX ; P ..$.$.$.$.$.@.@.@.@.@.@.@.@.$.$.$.$.$.O.P ; . HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXO % ; g h h h h h h h ; % O HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX",
+"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX"
+};
diff --git a/share/pixmaps/bitcoin16.png b/share/pixmaps/bitcoin16.png
new file mode 100644
index 0000000000..5537479095
--- /dev/null
+++ b/share/pixmaps/bitcoin16.png
Binary files differ
diff --git a/share/pixmaps/bitcoin16.xpm b/share/pixmaps/bitcoin16.xpm
new file mode 100644
index 0000000000..40a0624ac7
--- /dev/null
+++ b/share/pixmaps/bitcoin16.xpm
@@ -0,0 +1,181 @@
+/* XPM */
+static char *bitcoin__[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 159 2",
+" c #CA7C1E",
+". c #CB7D1E",
+"X c #D1811E",
+"o c #D0801F",
+"O c #D1801F",
+"+ c #D3821F",
+"@ c #D7831F",
+"# c #EE8D18",
+"$ c #F4931F",
+"% c #D78625",
+"& c #D88520",
+"* c #D98521",
+"= c #D98620",
+"- c #D78B2D",
+"; c #DF8D2A",
+": c #DF8F2F",
+"> c #DF943B",
+", c #D8913C",
+"< c #D8923E",
+"1 c #DF953E",
+"2 c #E28B23",
+"3 c #E38B23",
+"4 c #EA9023",
+"5 c #EB9023",
+"6 c #ED9122",
+"7 c #ED9123",
+"8 c #EE9123",
+"9 c #EE9223",
+"0 c #F39421",
+"q c #F19423",
+"w c #F39523",
+"e c #F79521",
+"r c #F59422",
+"t c #F49623",
+"y c #F69622",
+"u c #F79623",
+"i c #F09324",
+"p c #F19424",
+"a c #F19525",
+"s c #F49624",
+"d c #F59625",
+"f c #F49725",
+"g c #F79624",
+"h c #F79724",
+"j c #F69725",
+"k c #F79725",
+"l c #F69726",
+"z c #F79726",
+"x c #F89621",
+"c c #F89722",
+"v c #F89723",
+"b c #F89724",
+"n c #F89824",
+"m c #F89825",
+"M c #F99825",
+"N c #F89925",
+"B c #F89926",
+"V c #F89927",
+"C c #F99927",
+"Z c #F0972E",
+"A c #F7992A",
+"S c #F79A2B",
+"D c #F79B2C",
+"F c #F69A2D",
+"G c #F79D2F",
+"H c #F89929",
+"J c #F89A28",
+"K c #F89A29",
+"L c #F99A29",
+"P c #F99B29",
+"I c #F89A2A",
+"U c #F89A2B",
+"Y c #F99B2B",
+"T c #F89B2C",
+"R c #F89C2C",
+"E c #F99C2D",
+"W c #F99C2E",
+"Q c #F89D2E",
+"! c #F99D2F",
+"~ c #E29335",
+"^ c #E49639",
+"/ c #E2983F",
+"( c #F79F35",
+") c #F99E31",
+"_ c #F89E32",
+"` c #F99E32",
+"' c #F9A033",
+"] c #F9A035",
+"[ c #F9A135",
+"{ c #F9A036",
+"} c #F9A136",
+"| c #F9A137",
+" . c #F3A03F",
+".. c #F7A43F",
+"X. c #F8A139",
+"o. c #F9A23A",
+"O. c #FAA33B",
+"+. c #FAA43E",
+"@. c #FAA43F",
+"#. c #EF9F41",
+"$. c #EEA244",
+"%. c #ECA34B",
+"&. c #F8A440",
+"*. c #F9A541",
+"=. c #F9A644",
+"-. c #F9A947",
+";. c #F0A349",
+":. c #F5A648",
+">. c #F1A74E",
+",. c #F7AA4F",
+"<. c #E4A458",
+"1. c #E4A55B",
+"2. c #E8A95E",
+"3. c #F2A950",
+"4. c #F4AA52",
+"5. c #FBAF55",
+"6. c #E4A860",
+"7. c #EAAC63",
+"8. c #EBAF68",
+"9. c #F2AF61",
+"0. c #EBB16C",
+"q. c #F6B568",
+"w. c #E3AF71",
+"e. c #EBBE89",
+"r. c #E0BC93",
+"t. c #E3C199",
+"y. c #E6C59D",
+"u. c #EAC89E",
+"i. c #E7C8A2",
+"p. c #EACBA6",
+"a. c #EBCFAF",
+"s. c #F1CCA0",
+"d. c #E7CEB1",
+"f. c #ECD1B0",
+"g. c #E5D2BB",
+"h. c #E8D2B8",
+"j. c #DFDFDF",
+"k. c #E7D5C1",
+"l. c #E7D7C4",
+"z. c #E5D7C7",
+"x. c #E7DACB",
+"c. c #EADAC8",
+"v. c #E9DCCC",
+"b. c #EDDFCE",
+"n. c #E5DDD3",
+"m. c #E4DFD9",
+"M. c #ECE0D1",
+"N. c #E4E1DD",
+"B. c #EDE3D8",
+"V. c #EAE4DD",
+"C. c #ECE5DC",
+"Z. c #E2E2E2",
+"A. c #E5E2E0",
+"S. c #E4E4E4",
+"D. c #E7E7E7",
+"F. c #EAEAE9",
+"G. c gray92",
+"H. c #EEEEEE",
+"J. c None",
+/* pixels */
+"J.J.J.J.J.J.J.1 > J.J.J.J.J.J.J.",
+"J.J.J.J.J./ ..| ' ( ~ J.J.J.J.J.",
+"J.J.J.< *.{ V $ r U W _ - J.J.J.",
+"J.J., o.J 0 # <.w.$.F N H % J.J.",
+"J.J.o.T e 1.r.k.x.t.S z B u J.J.",
+"J.^ [ Y ! #.z.H.M.n.0.d n m 2 J.",
+"J.X.) | =. .h.B.5.f.j.;.v B d J.",
+": Q M ` &.>.A.V.p.c.l.4.E n d = ",
+"; I b A Z 2.D.s.u.F.a.-.} C w & ",
+"J.l g y 6.m.G.q.3.b.Z.,.] D 8 J.",
+"J.3 k c %.d.C.v.N.S.y.@.L a * J.",
+"J.J.j z x 8.i.g.e.9.+.W t 6 J.J.",
+"J.J.+ s h G :.7.O.R B s 7 . J.J.",
+"J.J.J.O i f P L K d p 5 J.J.J.",
+"J.J.J.J.J.@ 9 q i 4 + J.J.J.J.J.",
+"J.J.J.J.J.J.J.X o J.J.J.J.J.J.J."
+};
diff --git a/share/pixmaps/bitcoin256.png b/share/pixmaps/bitcoin256.png
new file mode 100644
index 0000000000..1d42116ef1
--- /dev/null
+++ b/share/pixmaps/bitcoin256.png
Binary files differ
diff --git a/share/pixmaps/bitcoin256.xpm b/share/pixmaps/bitcoin256.xpm
new file mode 100644
index 0000000000..87bb35cdad
--- /dev/null
+++ b/share/pixmaps/bitcoin256.xpm
@@ -0,0 +1,465 @@
+/* XPM */
+static char *bitcoin___[] = {
+/* columns rows colors chars-per-pixel */
+"256 256 203 2",
+" c #BE741B",
+". c #C1761B",
+"X c #C6791C",
+"o c #CC7C1D",
+"O c #D07F1D",
+"+ c #C67B21",
+"@ c #CC7E21",
+"# c #D4821E",
+"$ c #D9841F",
+"% c #ED8E1D",
+"& c #EF911F",
+"* c #CF8022",
+"= c #D48323",
+"- c #DB8621",
+"; c #DD8922",
+": c #D58729",
+"> c #D6882B",
+", c #DE8C2A",
+"< c #CE8C3C",
+"1 c #D28934",
+"2 c #D98E32",
+"3 c #D28E3C",
+"4 c #DF9132",
+"5 c #D6903E",
+"6 c #DD933B",
+"7 c #E58C22",
+"8 c #E98F23",
+"9 c #E38F2B",
+"0 c #E88F28",
+"q c #ED9124",
+"w c #E6922D",
+"e c #EB942B",
+"r c #EF982F",
+"t c #F59624",
+"y c #F89723",
+"u c #F79826",
+"i c #F89825",
+"p c #F1972A",
+"a c #F59A2C",
+"s c #F89B2B",
+"d c #E59534",
+"f c #EA9632",
+"g c #EE9933",
+"h c #E3963B",
+"j c #E6993D",
+"k c #EC9C3B",
+"l c #F49C33",
+"z c #F99E32",
+"x c #F29E3A",
+"c c #F7A037",
+"v c #F9A036",
+"b c #F5A13C",
+"n c #F9A33B",
+"m c #CE9147",
+"M c #D29245",
+"N c #DC9641",
+"B c #DD9846",
+"V c #D2954B",
+"C c #DC9A4B",
+"Z c #E59C44",
+"A c #EA9E43",
+"S c #E39E4B",
+"D c #E89F49",
+"F c #F09F40",
+"G c #EDA145",
+"H c #E6A14D",
+"J c #EBA34B",
+"K c #F4A443",
+"L c #F9A642",
+"P c #F7A847",
+"I c #FAA846",
+"U c #F3A64A",
+"Y c #F8A748",
+"T c #F5A94D",
+"R c #FAAA4B",
+"E c #E6A454",
+"W c #EBA552",
+"Q c #EDA856",
+"! c #E4A55B",
+"~ c #E8A75B",
+"^ c #E7A95E",
+"/ c #EBA95B",
+"( c #F0A751",
+") c #F4AB53",
+"_ c #FAAE53",
+"` c #F4AE5A",
+"' c #F8AF59",
+"] c #FAB057",
+"[ c #F6B15E",
+"{ c #FAB25B",
+"} c #DFAD6F",
+"| c #DCAE77",
+" . c #DFB27D",
+".. c #E5AA64",
+"X. c #E8AB61",
+"o. c #E5AE6C",
+"O. c #E6B06F",
+"+. c #ECB16C",
+"@. c #F5B365",
+"#. c #FBB562",
+"$. c #FBB867",
+"%. c #F5B66B",
+"&. c #FAB768",
+"*. c #F4B86F",
+"=. c #FBB96A",
+"-. c #E1AE71",
+";. c #E5B174",
+":. c #EBB573",
+">. c #EFB977",
+",. c #E5B47A",
+"<. c #EEBA7B",
+"1. c #F3B770",
+"2. c #F3B974",
+"3. c #FBBC72",
+"4. c #F3BC7B",
+"5. c #F8BF7A",
+"6. c #FAC079",
+"7. c #DCB382",
+"8. c #DFBB8F",
+"9. c #DABB96",
+"0. c #DBBD99",
+"q. c #E2B682",
+"w. c #E4B985",
+"e. c #ECBD84",
+"r. c #E3BB8B",
+"t. c #EABF8C",
+"y. c #F1BE83",
+"u. c #E2BE92",
+"i. c #D3BDA2",
+"p. c #DEC09C",
+"a. c #EEC28D",
+"s. c #F4C286",
+"d. c #F8C282",
+"f. c #F3C48B",
+"g. c #E7C297",
+"h. c #ECC393",
+"j. c #E2C29D",
+"k. c #EAC69B",
+"l. c #ECC89F",
+"z. c #F1C694",
+"x. c #F2C897",
+"c. c #F1CA9B",
+"v. c #DBC2A3",
+"b. c #D6C2AB",
+"n. c #DDC7AD",
+"m. c #DEC9AF",
+"M. c #D3C4B3",
+"N. c #DDCAB3",
+"B. c #D2C7B9",
+"V. c #D6C9BA",
+"C. c #DDCEBB",
+"Z. c #DFD0BE",
+"A. c #E2C5A2",
+"S. c #E8C7A0",
+"D. c #E6C9A5",
+"F. c #EBCBA4",
+"G. c #E2C7A8",
+"H. c #E3CAAC",
+"J. c #EBCDA9",
+"K. c #EFD2AF",
+"L. c #F3D1A7",
+"P. c #F1D1A9",
+"I. c #E4CEB3",
+"U. c #E8CFB1",
+"Y. c #E1CFBA",
+"T. c #E6D0B6",
+"R. c #E9D1B4",
+"E. c #E4D2BC",
+"W. c #EAD4BA",
+"Q. c #F4D5B0",
+"!. c #F4D9B9",
+"~. c #CDCDCD",
+"^. c #D5CCC3",
+"/. c #D4CFCA",
+"(. c #DED2C3",
+"). c #D3D1CE",
+"_. c #DED6CC",
+"`. c #D5D5D5",
+"'. c #DBD7D1",
+"]. c #DEDAD4",
+"[. c #DDDDDC",
+"{. c #E3D5C3",
+"}. c #E9D7C1",
+"|. c #EBD9C4",
+" X c #E1D6CA",
+".X c #E3D9CD",
+"XX c #EADDCD",
+"oX c #E1DBD4",
+"OX c #E8DFD4",
+"+X c #E1DEDB",
+"@X c #EDE3D7",
+"#X c #E3E1DE",
+"$X c #E8E3DC",
+"%X c #F6E5D2",
+"&X c #F4EBDF",
+"*X c #E4E4E4",
+"=X c #ECE7E2",
+"-X c #EDE9E4",
+";X c #ECECEC",
+":X c #F0EBE7",
+">X c #F4F4F4",
+",X c #FEFEFE",
+"<X c None",
+/* pixels */
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XC C S H H J J J G J J J J J S S B M <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XV S J U T R Y I I L L n n n n n n n n n n n n n n n n L L I I U U J S M <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XC J T R Y L L n n v z z z z s s s s s s s s s s s s s s s s s s s z z z v v n n n L I U J B <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XV H T R I L n n v z z s s s u i i i i i i i i i i i i i i i i i i i i i i i i i i u u s s s z z v n n L I U Z <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XH T R I L n v z s s u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u s s s z v n n L K Z <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XV W R I L n v z s s u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u s s z v n n L A < <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XV W R I n n z s s u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u s s z z n L A <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XH R I n n z s u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u s s z z n L Z <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XC T Y L n z s u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u s s z v n K N <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XW R I n v s u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u s s z n n A <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XW R L n z s u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u i i i i i i i i i u s z z n k <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XV T Y n v s u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u i i i i i i i i i i i u s s z n b 5 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XV ) I n v s u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u i i i i i i i i i i i i i s s z v b 3 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XV ) I n v s u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u u i i i i i i i i i i i i i i u s z v b 3 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XT I n v s u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u i u u u u u u u u i i i i i i i i i i i i i i i i i u s z v x <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XW R L v s u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u u u u u u i i i i i i i i i i i i i i i i i i u s z v k <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XS R L n s u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u s s s s u u u u i i i i i i i i i i i i i i i i i i i s s z n h <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XT I n z u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u s u s s s s u u u u u i i i i i i i i i i i i i i i i i i i u s s z c <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XH R n z s i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i u s s z k <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XV T L n s u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i u s z c 3 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XH I n z s i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u i u u u u u u s s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i u s s z k <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XT L n s u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u s s s s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i u s s c <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XS R n z s i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u u s s s s s s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i u s s z d <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XJ I n s u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u s s s s s s s s s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i u s s l <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XT L v s i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u u s s s s s s s s s s s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i u s s z <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XC Y n z u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u u s s s s s s s s s s s s s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i u s s s 2 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XH I n s u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u s s s s s s s s s s s s s s s s s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u s s d <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XJ L n s i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u u s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u s s g <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XT L v s i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u s s l <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XR L z s i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u u s s s s s s s s s s s s s s s s s s s s z z s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u s s z <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XR n z u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u s s s s s s s s s s s s s s s s s s s s s s z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i s s s <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XY n s u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u u s s s s s s s s s s s s s s s s s s s z z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u s s <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xm I n s u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u s s s s s s s s s s s s s s s s s s s s s z z z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u s s <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XM I n s u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u u s s s s s s s s s s s s s s s s s s s s s z z z z z z z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u s s <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XI n s u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u u s s s s s s s s s s s s s s s s s s s s s s z z z z z z z z z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u s s <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XI n s u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u s s s s s s s s s s s s s s s s s s s s s s z z z z z z z z z z z z z z z s s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u s s <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XI n s u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u u s s s s s s s s s s s s s s s s s s s s s z z z z z z z z z z z z z z z z z z s s s s s s s s s s s s u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u s s <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XY n s u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u i u u u u u u s s s s s s s s s s s s s s s s s s s s s z z z z z z z z z z z z z z v z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u s s <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XR n s u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u u s s s s s s s a t t a a s s s s s s s s z z z z z z z z z z z z z z z v v z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XY n z u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u u s s s s s s s s s a e f w 8 q t p a a a s s z z z z z z z z z z z z z v v v v v v z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u i p <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XU L z u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u u s s s s s s s s s s p e M.B.9.o.Z e q q p p a l z z z z z z z z z z v v v v v v v v z z z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u i e <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XJ L v u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u s s s s s s s s s s s s t Z `.`.[.[.[.C.p.o.Z e q q a z z z z z z v v v v v v v v v v v v z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i s i w <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XB L v s i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u s s s s s s s s s s s s s a % ;.`.[.*X*X*X*X*X[.[.C.9.-.J z z z z z v v v v v v v v v v v v v z z z z z z z z s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u i : <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XI n s i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u s u s s s s s s s s s s s s s s a % v.[.*X-X;X;X;X;X*X*X[.`.`.v.s z z v v v v v c c c c n n v v v v v z z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u i <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XI n s i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u i u u u u u u s s s s s s s s s s s s s s s s s p e (.*X;X;X>X>X>X>X;X;X*X[.`.r.n n z v v v v c x l p l x x c c v v v v z z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u i u <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XU n z u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u s s s s s s s s s s s s s s s s s s s t D [.*X;X>X>X>X>X>X>X;X*X[.`.@.n n v v v v v c g E | S k f r l l l z z z z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u i e <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XS L z u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u u s s s s s s s s s s s s s s s s s s s s a q ;.*X;X>X>X,X,X,X,X>X>X;X*X_.R n v v v v v v x e 0.`.`.V.p.;.H f e e p l l z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u y , <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XI n s i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u u s s s s s s s s s s s s s s s s s s s s z a q A.*X;X>X>X,X,X,X,X>X>X;X*XI.L n v v v v n n x g V.`.[.[.[.[.[.(.p.;.S f r l z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u y <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XY n s i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u u s s s s s s s s s s s s s s s s s s s s s z z a e (.*X;X>X,X,X,X,X,X>X>X;X*Xa.n n v v v n n n l A `.[.*X*X-X-X*X*X*X[.`.V.9.K z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u i u <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XJ n z u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u u u u s s s s s s s s s s s s s s s s s s s s s z z z p D [.-X;X>X,X,X,X,X,X>X>X-X[.%.n n n n n n n b p o.[.*X;X;X;X>X;X;X*X*X[.`.~.T z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u y 0 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XM L v u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u u u s s s s s s s s s s s s s s s s s s s s z z z z z z q ;.*X;X>X>X,X,X,X,X,X>X;X*XoXR L n n n n n n b g u.*X-X;X>X>X>X>X>X;X*X*X[.N.L n z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u y <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XI n s i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u u u s s s s s s s s s s s s s s s s s s s s s z z z z z z l q A.*X;X>X>X,X,X,X,X>X>X;X*XI.L L n n n n n n b g C.*X;X>X>X,X,X,X>X>X;X*X[.g.L n z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u i u <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XG n z u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u u u s s s u u a s s s s s s s s s s s s s s s z z z z z z z z a e _.*X;X>X,X,X,X,X,X>X>X;X*Xh.L L n n n n n n l G [.*X;X>X,X,X,X,X>X>X;X*X[.2.n n z z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u y w <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XL v u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u u s s s s s a q q q & t p a a s s s s s s s s z z z z z z z z z z p D [.-X;X>X,X,X,X,X,X>X>X-X[.%.L n n n n n n b l o.*X;X>X>X,X,X,X,X,X>X;X*X]._ n v z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i y <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XP n s i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u u s s s s s s s t j i.7.! d q q q p a a a s s z z z z z z z z z z z z q ,.*X;X>X>X,X,X,X,X,X>X;X*XoXR L n n n n n n b g j.*X;X>X>X,X,X,X,X,X>X;X*XE.I n v z z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u y t <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XZ n z u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u u u s s s s s s s a % } `.`.`._.N.r.! d e q q p a a z z z z z z z z z z l e G.*X;X>X>X,X,X,X,X>X>X;X*XT.I L n n n n n n b k Z.*X;X>X,X,X,X,X,X>X>X;X*Xl.L n v v z z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u y ; <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XL v s i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u s s s s s s s s s a % 0.`.[.*X*X*X*X*X'.m.w.! d e q q p l l z z z z z v l f X*X;X>X,X,X,X,X,X>X>X;X*Xh.L L n n n n L L x G [.*X;X>X,X,X,X,X,X>X>X;X*X4.n n v v v z z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u i u <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XG n s i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u s s s s s s s s s s s p e C.[.*X*X;X;X;X;X*X*X*X*X'.N.r...j e e p a l l z z p H *X;X>X>X,X,X,X,X,X>X>X-X[.%.L L n n n L L L l ;.*X;X>X>X,X,X,X,X,X>X;X*X[._ L n v v v z z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u y q <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XL v u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u u u s s s s s s s s s s s s t A [.*X;X;X>X>X>X>X;X;X;X;X*X*X*X*X].N.q.! d e e r p q ,.-X;X>X>X,X,X,X,X,X>X;X*XoX_ I L n L L L L K g j.*X;X>X>X,X,X,X,X,X>X;X*XE.Y L n v v v z z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XK n s i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u u s s s s s s s s s s s s s s a q -.[.*X;X>X>X>X>X>X>X>X>X>X;X;X;X;X*X*X*X*X_.I.r.o.Z w D.;X>X>X,X,X,X,X,X,X>X;X*XW.R I L L L L L L K k Y.*X;X>X,X,X,X,X,X>X>X;X*Xl.L L n v v v v v z z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u y q <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X3 n z u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u u s s s s s s s s s s s s s s s s a q j.*X;X>X>X,X,X,X,X,X,X>X>X>X>X>X>X;X;X;X;X*X*X*X*X$X}.=X>X>X>X,X,X,X,X,X,X>X;X*Xx.I I L L L L L L x J [.*X;X>X,X,X,X,X,X>X>X;X*X4.L n n v v v v v z z z z z z s s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XL n s i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u u s s s s s s s s s s s s s s s s s s p e (.*X;X>X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X>X>X;X;X;X;X;X>X>X>X>X,X,X,X,X,X,X,X>X>X;X&.L L L L L L L L x ;.*X;X>X>X,X,X,X,X,X>X;X*X[.' L n n n v v v v z z z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u y t <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X3 n z u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u s s s s s s s s s s s s s s s s s s s a p A [.*X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X>X>X>X>X>X>X,X,X,X,X,X,X,X,X,X>X>X@Xb l x x K L L L L k j.*X;X>X>X,X,X,X,X,X>X;X*XE.R L n n n n v v v v z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XL n s i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u u s s s s s s s s s s s s s s s s s s s s z q o.[.*X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X:XW.g.;.H k k k b F k {.;X>X>X,X,X,X,X,X>X>X;X*XS.I L n n n n v v v v v z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i y t <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X5 n z u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u s s s s s s s s s s s s s s s s s s s s s z a q 0.[.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X;X*X+XE.j.,.~ j A =X;X>X>X,X,X,X,X,X>X>X;X*X4.I L n n n n v v v v v z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XL n s i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u u s u s s s s s s s s s s s s s s s s s s s z z z a e V.[.*X-X;X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X;X;X*X*X*X*XXX}.;X>X>X,X,X,X,X,X,X>X>X;X#X{ I n n n n n n v v v v z z z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i y t <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xn z u i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u s s s s s s s s s s s s s s s s s s s s s s z z z z u W ~.`.[.*X-X;X;X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X;X;X;X;X;X>X>X>X,X,X,X,X,X,X,X>X>X;X|.R I n n n n n n v v v v v z z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XK n s i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u u s s s s s s s s s s s s s s s s s s s s s s z z z z z z s ( v.^.`.[.*X*X-X;X;X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X>X>X>X>X>X,X,X,X,X,X,X,X,X>X>X;XF.L L n n n n n n n v v v v z z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i y q <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xn z u i i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u s s s s s s s s s s s s s s s s s s s s s z z z z z z z z z v c L _ %.t.D. X[.*X*X-X;X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X,X,X,X,X,X,X,X,X,X,X,X>X>X;X@.a x b b n n n n n v v v v z z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XG n s i i i i i i i i i i i i i i i i i i i i i i i u u u u u u u s s s s s s s s s s s s s s s s s s s s s s z z z z z z z z z z z v n n L L R _ %.a.U.oX*X-X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X|.e.G g l c b n n n n v v v v z z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t 0 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XL v u i i i i i i i i i i i i i i i i i i i i i i u u u u u u u s s s s s s s s s s s s s s s s s s s s s z z z z z z z z z z z z z v v v v n L L L L R ' f..X*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X-X+XG...k g l b n n n v v v v z z z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i y t <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X6 n s i i i i i i i i i i i i i i i i i i i i i u u u u u u u s s s s s s s s s s s s s s s s s s s s s z z z z z z z z z z z z z v v v v v v v v n n n L L L L J.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X;X*X*X(.w.A g l c c v v v v v z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t = <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XK v s i i i i i i i i i i i i i i i i i i i i u u u u u u s s s s s s s s s s s s s s s s s s s s z s z z z z z z z z z z z z v v v v v v v v v v n n n n n L n z W.-X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X;X-X*X*X'.u.A r l x c v v v z z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xn z u i i i i i i i i i i i i i i i i i u u u u u u s s s s s s s s s s s s s s s s s s s s s s z z z z z z z z z z z z v v v v v v v v v v n n n n n n n n n L z K *X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X;X;X*X*X].u.k r l c v v v z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XA n s i i i i i i i i i i i i i i i u u u u u u u s s s s s s s s s s s s s s s s s s s s s s z z z z z z z z z z z z z z v v v v v v v v n n n n n n n n n n n n n l U.;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X;X;X*X*X_.q.g p l z v z z z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t 7 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XL z u i i i i i i i i i i i i i u u u u u u u s s s s s s s s s s s s s s s s s s s s s s z z z z z z z z z z z z z v v v v v v v v v n n n n n n n n n n n n n n n l h.*X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X;X;X*X[.C.W p l c v z z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i y t <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xn s i i i i i i i i i i i i i u u u u u u u u s s s s s s s s s s s s s s s s s s s s z z z z z z z z z z z z z z v v v v v v v v v n n n n n n n n n n n n n n n b l e.*X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X;X;X;X;X>X>X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X;X*X*X[.w.r a l z z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xk v s i i i i i i i i i i i u u u u u u u u s s s s s s s s s s s s s s s s s s s s s z z z z z z z z z z z z z v v v v v v v v n n n n n n n n n n n n n n n n L L K g S.*X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X-X-X-X*X*X-X;X;X;X;X>X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X;X;X*X[.H.g a z z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t 0 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xn z u i i i i i i i i i u u u u u u u u s s s s s s s s s s s s s s s s s s s s s s z z z z z z z z z z z z z v v v v v v v n n n n n n n n n n n n n n n n L L L L b k {.*X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;Xf.3.x.R..X+X*X*X*X*X;X;X;X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X;X*X*X(.k p z z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i y t <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X< n s i i i i i i i u u i u u u u u u s s s s s s s s s s s s s s s s s s s s z z z z z z z z z z z z z z v v v v v v v v v n n n n n n n n n n n n n n L L L L L L L x H [.-X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X$.{ { { $.3.f.F.{.[.*X*X*X;X;X;X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X-X*X_.W p z z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t @ <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xk v s i i i i i i i u u u u u u u s s s s s s s s s s s s s s s s s s s s s z z z z z z z z z z z z z v v v v v v v v v n n n n n n n n n n n n n n n L L L L L L L L x ;.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X-X|.{ ] _ ] { { { { $.3.h.R..X*X*X*X;X;X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X-X*X'.k p z z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t 0 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xn z u i i i i u u u u u u u s s s s s s s s s s s s s s s s s s s s s s z z z z z z z z z z z z z z v v v v v v v v v n n n n n n n n n n n n n n L L L L L L L L L L k j.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*XJ._ ] _ _ _ _ ] { { { #.$.$.f.T.oX*X*X;X;X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X-X*X_.l a z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t t <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xn s i i i i i u u u u u u s s s s s s s s s s s s s s s s s s s s z z z z z z z z z z z z z z v z v v v v v v v v n n n n n n n n n n n n n n L L L L L L L L L L L K k (.*X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*Xs._ _ _ _ _ _ _ _ _ ] { { { { { =.l..X*X*X;X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X*XH.t z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xh v s i i i i i i u u u u s s s s s s s s s s s s s s s s s s s s s z z z z z z z z z z z z z v v v v v v v v n n n n n n n n n n n n n n n L L L L L L L L L L L I I b W [.*X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X+X&.] _ _ _ _ _ _ _ _ _ _ _ _ ] { { { #.k.oX*X-X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X[.:.t z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t ; <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xx z s i i i i i i i u u u s s s s s s s s s s s s s s s s s s z z z z z z z z z z z z z v v v v v v v v v n n n n n n n n n n n n n n n L L L L L L L L L L L I I I I x ,.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X{.{ { _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ] _ { J.*X*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X'.l s z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xn z u i i i i i i i u u u u s s s s s s s s s s s s s s s z z z z z z z z z z z z z v v v v v v v v v v n n n n n n n n n n n n n n n L L L L L L L L L L L I I I I P k A.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*XF.{ { _ _ _ _ _ _ _ _ ] _ _ _ _ _ _ _ _ _ _ _ y.oX*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X[.t.u z z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t t <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X1 n s i i i i i i i i u u u u u s s s s s s s s s s s s s s z z z z z z z z z z v z z v v v v v v v v n n n n n n n n n n n n n n n L L L L L L L L L L L I I I I I I K A (.*X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*Xs.{ ] _ _ _ _ _ ] ] ] ] ] _ _ _ _ _ _ _ _ _ _ _ ' .X*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X'.z z z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xh v s i i i i i i i i i i u u u s s s s s s s s s s s z z z z z z z z z z z z z z v v v v v v v v n n n n n n n n n n n n n n n L L L L L L L L L L L I I I I I I I Y K W [.*X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X].&.{ ] _ _ _ ] ] ] ] ] ] ] _ _ _ _ _ _ _ _ _ _ _ R R oX*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X[.:.u z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t ; <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xx z u i i i i i i i i i i u u u u s s s s s s s s s s s z z z z z z z z z v v v z v v v v v v n n n n n n n n n n n n n n n n L L L L L L L L L L L I I I I I I I Y P x ,.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X{.#.{ _ _ _ _ ] ] ] ] ] ] ] ] _ _ _ _ _ _ _ _ _ _ _ I @.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*XD.s z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xn z u i i i i i i i i i i u u u u s s s s s s s s s s s z z z z z z z z v v v v v v v v v n n n n n n n n n n n n n n n L L L L L L L L L L L I I I I I I I Y I R R Y k j.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*XF.{ { _ ' ] ] ] ] ] { { { ] ] ] _ _ _ _ _ _ _ _ R R _ n k.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X_.n z z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t t <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xn s i i i i i i i i i i i u u u u u s s s s s s s s s s s z z z z z z v v v v v v v v v n n n n n n n n n n n n n n n L L L L L L L L L L I I I I I I I I I R R R R U G (.*X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*Xs.{ { ] ] ] ] { { { { { { ] ] ] _ _ _ _ _ _ _ _ R R R I T +X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X[.T z z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X6 v s i i i i i i i i i i i i u u u u s s s s s s s s s s s z z z z z z z v v v v v v n n n n n n n n n n n n n n n L L L L L L L L L L I I I I I I I I I R Y R R R R K W [.*X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X[.=.{ { ] ] ] { { { { { { { ] ] ] _ _ _ _ _ _ _ _ _ R R R K D.*X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X[.%.z z z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t = <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xk z s i i i i i i i i i i i i i u u u u s s s s s s s s s s s z z z z z z z v v v v v n n n n n n n n n n n n n L L L L L L L L L L L I I I I I I I I I R R R R R R R K ,.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X{.#.{ ] ] { { { { { { { { { { ] ] ] _ _ _ _ _ _ _ _ R R R K e.*X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X-X[.<.v v z z z z z z z s s s s s s s s s s s s u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t 7 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xx z u i i i i i i i i i i i i i i u u u s s s s s s s s s s s s z z z z z z v v v v v n n n n n n n n n n L L L L L L L L L L L I I I I I I I I I I R R R R R R R R T G j.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*XJ.{ { { { { { { { { { { { { { { ] ] ] _ _ _ _ _ _ _ _ R R K +.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X<.n v v z z z z z z s s s s s s s s s s s s u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xn s i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s z z z z z z z z v v v v n n n n n n n n L L L L L L L L L L I I I I I I I I I I R R R R R R R R R R T G (.*X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*Xs.#.{ { { { { { { { { { { { { { ] ] ] ] _ _ _ _ _ _ _ _ R U / *X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*Xe.n n v v z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t t <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xv s i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s z z z z z z z z v v v v n n n n n n n n n L L L L L L L L I I I I I I I I I R R R R R R R R R R R R K Q [.*X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X[.=.#.{ { { { { { { { { { { { { { ] ] ] ' _ _ _ _ _ _ _ _ R K +.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X<.n n v v z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u t <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X1 z s i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s z z z z z z z v v v v v n n n n n n n n L L L L L L I I I I I I I I R R R R R R R R R R R R R R R K ,.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X{.$.#.{ { { { { { { { { { { { { { { ] ] ] ] _ _ _ _ _ _ _ T K ,.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X-X[.>.n n v z z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t @ <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xd z s i i i i i i i i i i i i i i i i u u u u u s s s s s s s s s s s z z z z z z v v v v v n n n n n n n n n L L L L L I I I I I I I R R R R R R R R R R R R R R R T G A.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*XJ.#.#.{ { { { { { { { { { { { { { { ] ] ] ] _ _ _ _ _ _ _ T G j.*X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X[.%.n n v v z z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t = <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xg z s i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s z z z z z z z v v v v v n n n n n n n n L L L L L L I I I I R R R R R R R R R R R R R R R _ _ T J (.*X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*Xf.#.{ { { { { { { { { { { { { { { { { ] ] ] _ _ _ _ _ _ _ T J X-X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X]._ L n v v v z z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t ; <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xx z u i i i i i i i i i i i i i i i i i u u u u u s s s s s s s s s s s z z z z z z z v v v v n n n n n n n n n L L L L L L I I I I R R R R R R R R R R R R _ _ _ _ U Q [.*X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X#X3.#.{ { { { { { { { { { { { { { { { { { ] ] ] _ _ _ _ _ ) G ..*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X{.R L n v v v v z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t 7 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xx z u i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s z z z z z z z v v v v v n n n n n n n n L L L L L L I I I I I R R R R R R R R _ R R _ _ _ _ U ,.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X|.=.#.{ { { { { { { { { { { { { { { { { { { ] ] ' _ _ _ _ T k E.*X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*XH.L L n v v v v z z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xv s i i i i i i i i i i i i i i i i i i i i u u u s s s s s s s s s s s s z z z z z z z v v v v n n n n n n n n n L L L L L I I I I I R R R R R R R R _ _ _ _ _ _ ) J j.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;Xc.] { { { { { { { { #.{ { { { { { { { { { { ] ] ] _ _ _ ( A w.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X-X[.a.L n n v v v v v z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xv s i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s z z z z z z z v v v v v n n n n n n n n L L L L L L I I I I I R R R R R R R R _ _ _ _ _ ) J Z.*X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;Xx.( Q ( ) ` [ [ { #.#.#.{ { { { { { { { { { { ] ] _ ) T D o.*X;X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X[.[ L n n n v v v v z z z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u q <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xz s i i i i i i i i i i i i i i i i i i i i u u u u u s s s s s s s s s s s z z z z z z z v v v v n n n n n n n n n L L L L L L I I I I R R R R R R R R _ _ _ _ _ T / [.*X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;XOXI.u.O./ Q Q ` ` [ [ [ { { { { { { { { { ] ' ) ( J H r.*X-X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*XE.R I n n n v v v v v z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u q <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xz s i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s z z z z z z z v v v v v n n n n n n n n n L L L L L I I I I I R R R R R R R R _ _ _ _ U ,.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X;X;X*X*X_.H.r.;.X./ Q Q ) ) ` ` ` ` ` ) ) ( J H W ,.{.*X;X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X[.y.I L n n n n v v v v z z z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u t <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X1 z s i i i i i i i i i i i i i i i i i i i i i u u u u u s s s s s s s s s s s z z z z z z z v v v v v n n n n n n n n L L L L L L I I I I R R R R R R R R _ _ _ ) J j.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X;X;X;X*X*X*X*X].(.H.u.q.;.^ ^ ~ ~ E E ~ o.r.G. X*X*X;X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X_._ Y L n n n n n v v v z z z z z z z s s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i u t @ <X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X2 z s i i i i i i i i i i i i i i i i i i i i i i i u u u s s s s s s s s s s s s z z z z z z z v v v v n n n n n n n n n L L L L L I I I I Y R R R R R R R R _ _ T J (.*X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X;X;X;X;X*X*X*X*X*X*X[.]..X X XoX+X*X*X*X-X;X;X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X[.f.R I n n n n n n v v v v z z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t = <X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X4 z s i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s z z z z z z z v v v v v n n n n n n n n L L L L L L I I I I R R R R R R R R _ _ U Q [.*X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X>X>X;X;X;X;X;X;X-X-X*X*X*X-X;X;X;X;X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X;X*X X_ R L n n n n n n v v v v z z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t = <X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<Xd z s i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s z z z z z z z v v v v v n n n n n n n n L L L L L L I I I I I R R R R R R R R R K ,.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X>X>X>X>X>X>X>X;X;X;X>X>X>X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X[.%.R I L n n n n n n n v v v v z z z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i t - <X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<Xf z u i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s z z z z z z z z v v v v n n n n n n n n L L L L L L I I I I R R R R R R R R T G j.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X>X>X>X>X>X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X;X*X[.k.R R L n n n n n n n n v v v v v z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i t ; <X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<Xf s u i i i i i i i i i i i i i i i i i i i i i i i i i u u u s s s s s s s s s s s z z z z z z z z v v v v n n n n n n n n L L L L L L I I I I I R R R R R R R T G (.*X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X;X;X*X[.l.] _ I L L n n n n n n n n v v v v v z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i t ; <X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<Xf s u i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s z z z z z z z v v v v v n n n n n n n n L L L L L L I I I I R Y R R R R R U W [.*X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X;X-X*X[.l.{ _ Y L L L n n n n n n n n v v v v v v z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i t ; <X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<Xf s u i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s s z z z z z z z v v v v n n n n n n n n n L L L L L I I I I I R R R R R R K ,.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X;X*X*X].h.{ _ R L L L L L n n n n n n n n v v v v v z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i t ; <X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<Xf s u i i i i i i i i i i i i i i i i i i i i i i i i i i u u u s s s s s s s s s s s s z z z z z z z v v v v v n n n n n n n n L L L L L L I I I Y I R R R R T G A.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X>X>X>X>X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X;X*X[.T.3.{ ] R I L L L L L n n n n n n n n n v v v z z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i t ; <X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<Xf s u i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s s z z z z z z z v v v v v n n n n n n n n L L L L L I I I I I Y R R R U G (.*X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X;X;X;X;X;X;X;X;X>X>X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X;X*XW.s.#.{ _ R I I L L L L L L n n n n n n n n v v v v z z z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i t ; <X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<Xf s u i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s z z z z z z z v v v v v n n n n n n n n L L L L L L I I I I R R R R K W [.*X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X-XQ.|.OX*X*X*X*X*X;X;X;X>X>X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X&X!.L.d.#.{ ] R R I I I L L L L L L n n n n n n n n n v v v v z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i t ; <X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<Xf s u i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s z z z z z z z z v v v v n n n n n n n n L L L L L I I I I I Y R R K ,.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;XXX3.3.3.s.c.R..X[.*X*X*X-X;X;X;X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X%X{ L R _ _ R R R I I I I L L L L L L n n n n n n n n v v v v v z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i t ; <X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<Xf s u i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s z z z z z z z z v v v v n n n n n n n n L L L L L L I I I I I R Y k j.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X-XK.&.=.=.&.=.3.3.d.c.R..X[.*X*X*X;X;X;X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;XJ.J K Y R R Y I I I I L L L L L L n n n n n n n n n v v v v z z z z z z z s s s s s s s s s s s s u u u i i i i i i i i i i i i i i i i i i i i i i i i t ; <X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<Xw s u i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u s s s s s s s s s s s z z z z z z z v v v v v n n n n n n n n L L L L L I I I I I R P A Z.*X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*Xf.$.#.#.#.#.&.&.=.=.3.3.f.F.}.+X*X*X*X;X;X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X;XOX:.K U R R I I I I I L L L L L L n n n n n n n n v v v v z z z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i t ; <X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<Xw s u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s z z z z z z z v v v v v n n n n n n n n L L L L L L I I I I Y K W [.*X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X-X+X3.$.#.{ { #.#.#.#.$.$.&.=.=.3.6.c.W.+X*X*X;X;X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X*Xj.K K R R I I I I I L L L L L n n n n n n n n v v v v v v z z z z z z s s s s s s s s s s s s u u u i i i i i i i i i i i i i i i i i i i i i i u t = <X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<Xw s u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s z z z z z z z v v v v v n n n n n n n n L L L L L L I I I P x ;.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X{.&.#.{ { { { #.#.#.#.#.#.#.#.$.$.=.=.5.J..X*X*X;X;X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X*XH.K K R R I I I I L L L L L L n n n n n n n n v v v v v z z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i u t = <X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X, s u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s s z z z z z z z v v v v n n n n n n n n L L L L L L I I I P k j.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*XJ.#.#.{ { { { #.#.#.#.#.#.#.#.{ #.#.$.$.$.=.z.{.*X*X;X;X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X;X*X*XC.U K R I I I I I L L L L L L n n n n n n n n v v v v v z z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i u q * <X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X> s u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s z z z z z z z v v v v v n n n n n n n n L L L L L L I I K A Z.*X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*Xf.#.#.{ { { { { #.#.#.#.{ { { { { { { #.#.#.#.$.z.{.*X*X;X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X*XC.b K Y I I I I L L L L L L n n n n n n n n n v v v v z z z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i u q + <X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xs s i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s z z z z z z z z v v v v v n n n n n n n n L L L L L I I b J [.*X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X[.3.#.{ { { { { { #.#.#.{ { { { { { { { { { { #.#.#.$.F.+X*X;X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X[.H.b P I I I I I L L L L L n n n n n n n n n v v v v v z z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i t q <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xs s i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s z z z z z z z v v v v v n n n n n n n n L L L L L I L x ;.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X{.$.#.{ { { { { { { { { { { { { { { { { { { { { { { #.{ 2.{.*X;X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X[.e.b Y I I I I L L L L L L n n n n n n n n v v v v z z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i t q <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xs s i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s s z z z z z z v v v v v n n n n n n n n L L L L L L K k j.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*XJ.#.#.{ { { { { { { { { { { { { { { { { { { { { { { { { { { U.*X;X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X].T L Y I I I I L L L L L L n n n n n n n n v v v v v z z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i t q <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xs s i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s z z z z z z z z v v v v n n n n n n n n L L L L L K k Z.*X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*Xf.#.{ { { { { { { { { { { { { { { { { { { { { { { { { ] { { _ R.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X-X*XD.L R I I I I L L L L L L n n n n n n n n v v v v v z z z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i t q <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xa u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s s z z z z z z z v v v v n n n n n n n n n L L L L x J [.*X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X[.=.#.{ { { { { { { { { { { { { { { { { { { { { { ] ] ] ] ] { ' R T.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X[.` L I I I I I L L L L L L n n n n n n n n v v v v v z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i t 8 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xp s i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s z z z z z z z v v v v v n n n n n n n n L L L L x ;.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X{.$.#.{ { { { { { { { { { { { { { { { { { { { ] ] ] ] ] ] ] _ ] _ R oX*X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X-X[.g.n I Y I I I I L L L L L n n n n n n n n n v v v v z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i t 7 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xe s i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u s s s s s s s s s s s z z z z z z v v v v v n n n n n n n n n L L K g j.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*XJ.{ { { { { { { { { { { { { { { { { { { { { ] ] ] ] ] _ _ _ _ _ ] Y <.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X(.I I I I I I L L L L L L L n n n n n n n n v v v v v z z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i u t ; <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X9 s u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s z z z z z z z v v v v v n n n n n n n n L L b k E.*X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*Xf.{ { { { { { { { { { { { { { { { { { { ] ] ] ] ] ] _ _ _ _ _ _ _ _ T .X-X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X[.[ L I I I L L L L L L L L n n n n n n n n n v v v v z z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i u q = <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X: s u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u s s s s s s s s s s s s z z z z z z z v v v v v n n n n n n n L L x G +X-X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X[.=.{ { ] { { { { { { { { { { { { { { ] ] ] ] ] ] _ _ _ _ _ _ _ _ _ _ P g.*X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X-X[.e.n I L L L L L L L L L L n n n n n n n n n v v v v v z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i t q <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xs u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s z z z z z z z l l l c c n n n n n n n n b g o.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X{.#.{ ] ] { { { { { { { { { { { ] ] ] ] ] ] ] ] _ _ _ _ _ _ _ _ _ _ _ Y +.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*Xg.L I L L L L L L L L L n n n n n n n n n n n v v v v z z z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i i i i i t q <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xs u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u s s s s s s s s s s s z z z z z l f j e r p l x n n n n n b b f H.-X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*XJ.{ { ] ] ] { { { { { { { { { ] ] ] ] ] ' _ _ _ _ _ _ _ _ _ _ _ _ _ _ T Q #X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*XD.I I L L L L L L L n n n n n n n n n n n n n v v v v v z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i t q <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xp u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s z z z z l q 7.^.v. .E d f g l l x x k w ..*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*Xf.{ { ] ] ] ] { { { { { { { ] ] ] ] ] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ Y W +X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*XI.I I L L L L L n n n n n n n n n n n n n n n v v v v v v z z z z z z z s s s s s s s s s s u u u u u i i i i i i i i i i i i t 7 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xe u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s z z z p e /.`.[.[.[._.v.q.! j f w d ;.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X[.=.{ ] ] ] ] ] { { { { { ] ] ] ] ] ' _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ R R T W +X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*XE.I L L L L n n n n n n n n n n n n n n v v v v v v v v v z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i u q ; <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X, s u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s z z l q -.[.[.*X*X*X*X*X*X*XoXE.E..X-X;X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X{.#.{ _ _ ] ] ] ] { ] ] ] ] ] ] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ R R R R K X.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*XE.I L n n n n n n n n n n n n n n n n v v v v v v v v v z z z z z z z z s s s s s s s s s s s s u u u i i i i i i i i i i i t q @ <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xs u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u s s s s s s s s s s s z p e (.[.*X;X;X;X;X;X;X;X;X;X;X;X;X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*XJ.{ { _ _ _ ] ] ] ] ] ] ] ] ' _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ R R R R R x q.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*XD.R L n n n n n n n n n n n n n n n v v v v v v v v v z z z z z z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i t q <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xu u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s a q ! [.*X;X>X>X>X>X>X>X>X>X>X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*Xs.{ ] _ _ _ ] ] ] ] ] ] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ R R R R R R R T k G.*X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*XS.I L n n n n n n n n n n n n n v v v v v v v v v z z z z z z z z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i t q <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xp u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u s s s s s s s s s a a 8 m.*X;X>X>X>X,X,X>X>X>X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X#X&.{ _ _ _ _ _ ] ] ] ] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ R R R R R R R R K A oX;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*Xh.L L n n n n n n n n n n v v v v v v v v v z z z z z z z z z z z z z s s s s s s s s s s s s s s s u u u i i i i i i i i i t 7 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X0 u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s a q j [.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X|.{ ] _ _ _ _ _ ] ] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ R R R R R R R R R U k u.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X-X[.2.L L n n n n n n n n n v v v v v v v v z z z z z z z z z z z z z s s s s s s s s s s s s s s s s s u u u u i i i i i i i u q = <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X= u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s a % u.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;Xc.R _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ R R R R R R R R R R T k D +X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X[.' L n n n n n n n n v v v v v v v z v v z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s u u u u i i i i i i i t q <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xu u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u s s s s s s s t w ].*X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;Xf.K G G U ) ) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ R R R R R R R R R R R U A j {.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X{.R L n n n n n n v v v v v v v v v z z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s s s u u u u i i i i i i t q <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xu i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s a % ;.[.-X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X-XXXH.w.X.J J J T ) ) ) _ _ _ _ _ _ _ _ R R R R R R R R R R R Y K k D Y.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*XJ.L L n n n n v v v v v v v v z z z z z z z z z z z z z s z s s s s s s s s s s s s s s s s s s s s u u u u u u u i i i i u t 7 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X7 u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s p q (.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X;X-X*X#X(.A.q...H J J U U T T T T R R R R R R R R R Y Y U K k A ;..X*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X-X[.4.L n n n v v v v v v v v z z z z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s u u u u u u u u u i i i i i t q * <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xu u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s a % ! `.*X*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X;X;X;X*X*X*X[.(.H.u.,.^ J D G A J K K U U U U K k k k A E w.Y.*X*X;X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X]._ L n v v v v v v v v v v z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s s s u u u u u u u u u i i i i i i t q <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xu i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u s s s s u q b.`.[.*X;X;X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X>X;X;X;X-X*X*X*X*X[._.N.A.u.;.;...E E E E ..;.q.j.I.+X*X*X;X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*XH.I L n v v v v v v v v z z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s s u u u u u u u u i i i i i i i i i t 8 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xq i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s t W ~.`.[.*X*X;X;X;X>X>X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X>X>X;X;X;X;X-X*X*X*X*X*X*X*X+X+X+X+X*X*X*X*X*X;X;X;X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X[.1.L n v v v v v v z z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s s s u u u u u u u u u i i i i i i i i i u q ; <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X= i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u s s u K ,.j.C.[.[.*X*X*X;X;X;X;X>X>X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X>X>X>X>X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X XR L n v v v v v z z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s s u u u u u u u u i i i i i i i i i i i i t q <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xi i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s z z L I [ e.J. X[.*X*X*X-X;X;X;X;X>X>X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X-X[.a.L n v v v z z z z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s u u u u u u u u u i i i i i i i i i i i i i t 8 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xq i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s z c n n n Y @.a.D.{.[.*X*X*X-X;X;X;X>X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X>X>X>X>X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X]._ L n v z z z z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s s u u u u u u u i i i i i i i i i i i i i i i u q ; <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X@ i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u s s s s s s z c c n n I R @.e.J.{.[.*X*X*X-X;X;X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X[.a.L n v z z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s s s s u u u u u u u i i i i i i i i i i i i i i i i t q <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xi i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s z z v n n L I R @.a.J. X*X*X*X;X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X_.R L n z z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s s s u u u u u u u i i i i i i i i i i i i i i i i i i t 8 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xq i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u s s s s s s s s s s s z z z v n n L L I _ %.a.R.OX;X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X[.2.L n z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s u s u u u u u u u u i i i i i i i i i i i i i i i i i i t q = <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xi i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s z z z z z v n n L L I R _ @.P.>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X[.D.L L v z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s u u u u u u u u u i i i i i i i i i i i i i i i i i i i i t q <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xt i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s s z z z z z z z v v n L n u e.;X>X>X,X,X,X,X,X,X,X,X>X>X>X>X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X-X*X XR L n z z z z z z z z s s s s s s s s s s s s s s s s s s s s s s u u u u u u u i i i i i i i i i i i i i i i i i i i i i i u q 7 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X- i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s z z z z z z z z v v v l g {.;X>X>X,X,X,X,X,X,X,X>X>X>X>X;X;X>X>X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X-X*X'._ I n z z z z z z z s s s s s s s s s s s s s s s s s s s s s s u u u u u u i u u i i i i i i i i i i i i i i i i i i i i i i t q o <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xi i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u s s s s s s s s s s s z z z z z z z v v c l A #X;X>X>X,X,X,X,X,X,X>X>X>X=X;X-X-X-X;X;X;X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X;X-X*X].%.L L z z z z z z s s s s s s s s s s s s s s s s s s s s s s u u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i t 8 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xq i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s z z z z z z z v v l p o.*X;X>X>X,X,X,X,X,X>X>X;X=X=.5.c.W.oX*X*X-X;X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X;X*X*X_.%.I L z z z z z z s s s s s s s s s s s s s s s s s s s s u u u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i t q - <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xu i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u s s s s s s s s s s s z z z z z z z v l e u.*X;X>X>X,X,X,X,X,X>X>X;X|._ _ _ { #.4.l.}.$X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X;X;X*X[.E.{ I L v z z z z s s s s s s s s s s s s s s s s s s s s u u u u u u u u i u i i i i i i i i i i i i i i i i i i i i i i i i i i i t 8 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xq i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s z z z z z z z z l r C.*X;X>X,X,X,X,X,X>X>X;X*XF.R R R R _ _ { { { 4.-X>X>X,X,X,X,X,X,X,X,X,X>X>X>X>X>X>X>X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X>X>X>X;X;X*X*X[.k._ I n z z z s s s s s s s s s s s s s s s s s s s s s s s u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q 7 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xu i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s z z z z z z z a k [.*X;X>X,X,X,X,X,X>X>X;X*X4.R I I I I R R R b U -X>X>X,X,X,X,X,X,X,X,X>X>X>X>X>X;X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X;X;X;X-X*X*X[.T.*.R L n z z z s s s s s s s s s s s s s s s s s s s s s u u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xt i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u s s s s s s s s s s z z z z z z z p ..*X;X>X>X,X,X,X,X,X>X;X*X+X] R I L I I I I P x t.;X>X>X,X,X,X,X,X,X,X>X>X;X;X;X;X-X-X-X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X*X*X*X[.].U.4.R I L v z z z s s s s s s s s s s s s s s s s s s s s u u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u q 7 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X@ u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u s s s s s s s s s s s z z z z z l q u.*X;X>X>X,X,X,X,X>X>X;X*XE.R Y L L I I I I K k I.-X;X>X,X,X,X,X,X,X>X>X;X|.f.J.W..X[.[.*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X[._.I.h.#.R L L n z z z s s s s s s s s s s s s s s s s s s s s u u u u u u u u i u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q . <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xt u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s z z z z z l e C.*X;X>X,X,X,X,X,X>X>X;X*Xl.I I L L L I I P K A oX-X>X>X,X,X,X,X,X>X>X;X;Xs.R _ _ { #.4.y.S.l.T.{.{. XoXoXoXoX].oX{.{.E.k.a.2.{ _ I L n v z z s s s s s s s s s s s s s s s s s s s s s s u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u q 7 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X@ u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s z z z z a k [.*X;X>X,X,X,X,X,X>X>X;X[.2.I I L L L L I L x ^ *X;X>X>X,X,X,X,X,X>X>X;X*X#.I I I I Y I R I _ R _ ] { { [ { { { { ] _ R R I I L n n v z z z s s s s s s s s s s s s s s s s s s s s u u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q . <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xt u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u s s s s s s s s s s s s z z z q ..*X;X>X>X,X,X,X,X,X>X;X*X]._ Y L L L L L I L k r.*X;X>X>X,X,X,X,X,X>X;X-X.XR L n n n n n n L L L L L L L n L n n n L n n n c v z z z z s s s s s s s s s s s s s s s s s s s s s u u u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u q 7 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xt i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u s s s s s s s s s s s s z z l q u.*X;X>X>X,X,X,X,X>X>X;X*XT.R I L L L L L L K k H.*X;X>X>X,X,X,X,X>X>X;X*XJ.L L n n n n n v v v v v v v v v z z z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s u u u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t 8 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xq u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s s z a e C.*X;X>X,X,X,X,X,X>X>X;X*Xk.I I n L L L L L b k ].*X;X>X,X,X,X,X,X>X>X;X*Xy.L n n n n v v v v v v v v v z z z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s u u u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q 7 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xt u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s a p k ].*X;X>X,X,X,X,X,X>X>X-X[.2.L L n L L L L L l ^ [.-X>X>X,X,X,X,X,X>X;X*X[.[ L n n n v v v v v v v z z v z z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s u u u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t 8 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xq t i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u s s s s s s s s s s a q ..[.*X;X>X,X,X,X,X,X>X;X*X]._ L L n L L L L K g r.*X;X>X>X,X,X,X,X,X>X;X*X{.R L n v v v v v v v z z z z z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s u u u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q - <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xt u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s a q 8.[.*X;X>X,X,X,X,X>X>X;X*XE.I L n n n L L L b g H.*X;X>X>X,X,X,X,X>X>X;X*XF.L L v v v v v v v z z z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s s u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u q 8 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X; t i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u s s s s s s s s s a q N.[.*X;X>X>X>X,X>X>X>X;X*Xk.L L n n n n L L x k _.*X;X>X,X,X,X,X,X>X>X;X*Xy.n n v v v v v v z z z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s s u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q # <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xt t i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s a t k ).[.*X-X;X>X>X>X>X>X;X*X[.2.L L n n n n n b l ~ [.-X>X>X,X,X,X,X,X>X;X*X[.' L n v v v z z z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s s s s u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q 7 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xt u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u s s s s s s s s t o.~.`.[.*X*X;X;X;X;X;X*X*X'.R L n n n n n n b g w.*X;X>X>X,X,X,X,X,X>X;X*X{.I n c v v z z z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s s u u u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t 8 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X7 t i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s U w.n._.[.[.*X*X*X*X*X*X[.Y.I L n n n n n n b g H.*X;X>X>X,X,X,X,X>X>X;X*XF.L n v z z z z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s u u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q - <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xt t i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u s s s s s s s z z v I R *.h.I..X[.[.[.`.`.u.L n n n n n n n x k _.*X;X>X>X,X,X,X,X>X>X;X*X4.n n z z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s s s u u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q 7 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xt u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s z v c n n L I _ 2.h.N./.~.>.L n n n n n n b l E [.*X;X>X>X,X,X,X>X>X;X*X[.' n v z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s s u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t 8 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X7 t i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s z z v n n n L R ' 2._ L n n n n n n b r 7.`.*X*X;X>X>X>X>X>X>X;X*X{.I n z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s s u u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q - <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xt t i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u s s s s s s s s s s s z z z v n n n n L n n n n n n n c l M.`.[.*X;X;X>X>X>X;X;X*X[.S.n n z z z z z z z z s s s s s s s s s s s s s s s s s s s s s u u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q 7 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xt t i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u s s s s s s s s s s s z z z z z z z v v v v v n n n n z b M.`.`.[.*X*X;X;X;X;X*X*X[.<.n c z z z z z z s s s s s s s s s s s s s s s s s s s s s u u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u q 8 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X; t u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s s z z z z z z z v v v v n n n n n n P %.a.H._.[.*X*X*X*X[.[.`._ n v z z z z s s s s s s s s s s s s s s s s s s s s u s u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t 8 # <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X8 t i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s z z z z z z z z v v v n n v v n n n L I R _ 1.a.I._.[.`.`.^.I n z z z s s s s s s s s s s s s s s s s s s s s u u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q 7 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xt t i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s z z z z z z z v v v v v v v v v v n n n n n L I R 1.t.n.u.I v z s s s s s s s s s s s s s s s s s s s s s u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q 7 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xt t i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s z z z z z z z v v v v v v v v v v v z z z z n n n n L I I n z s s s s s s s s s s s s s s s s s s s s u u u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q 7 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X# t t i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s s z z z z z z z v v v v v v v z z z z z z z z z z z v v z z z s s s s s s s s s s s s s s s s s s s u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u t 8 X <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X; t u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u s s s s s s s s s s s z z z z z z z v v v v z z z z z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s u s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t 8 - <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X8 t u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s z z z z z z z v v v z z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s s s u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q ; <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xq t u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s z z z z z z z z z z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s s s s u u u u u i u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q 7 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xt t i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s z z z z z z z z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s u u u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q 7 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xt t i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u s s s s s s s s s s s s z z z z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s s s u u u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q 7 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xt t i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s z z z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s s u u u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q 7 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xt t i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s s s u u u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q 7 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XX t t i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s s z z z z z z z z z s s s s s s s s s s s s s s s s s s s u u u u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q 7 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XX t t i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u s s s s s s s s s s s s z z z z z s s s s s s s s s s s s s s s s s s s s s u u u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q 7 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xt t i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s z z z s s s s s s s s s s s s s s s s s s s s s s u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q 7 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xq t u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u s s s s s s s s s s s z s s s s s s s s s s s s s s s s s s s s s u u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q 7 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xq t u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q 7 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xq t u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u s s s s s s s s s s s s s s s s s s s s s s s s s s s u s u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u t q 7 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X8 t t i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s s s s s s s s s s s s s s s s u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u t 8 7 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X7 t t i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u s s s s s s s s s s s s s s s s s s s s s s s s u u u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q 8 - <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X; q t i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s s s s s s s s s s s u u u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q 7 # <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X# q t u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s s s s s s s s u s u u u u u i u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q 7 X <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xq t t i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s s s s s s s u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u t 8 7 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X7 q t i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s s s s u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q 8 - <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X$ q t u i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s s s u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u t q 7 o <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xq t t i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u u s s s s s s s s s s u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q 8 7 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X; q t u i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s u u u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u t q 7 # <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XX q q t i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s u u u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q 8 7 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X- q t t i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s u u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u t q 7 # <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X8 q t u i i i i i i i i i i i i i i i i i i i i i i u u u u s u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q 8 7 <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X$ q q t u i i i i i i i i i i i i i i i i i i i i i u u u u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t t 8 7 o <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X- q t t i i i i i i i i i i i i i i i i i i i i i i u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t t q 7 $ <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X7 q t t i i i i i i i i i i i i i i i i i i i u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t t q 7 ; <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XX 7 q t t i i i i i i i i i i i i i i i i i i u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t t q 7 7 . <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XX 7 q t t u i i i i i i i i i i i i i i i u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t t q 7 7 . <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XX 7 q q t u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t t q 7 7 . <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X; q q t t i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u t q q 7 - <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X- 8 q t t u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t t q 8 7 $ <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xo 7 q q t t u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t t q q 7 7 o <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X$ 8 q q t t u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t t q q 8 7 # <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X $ 8 q q t t u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u t t q q 8 7 $ <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X. $ 7 8 q t t t u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u t t t q 8 7 7 $ . <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XO ; 8 q q t t t t u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u t t t q q 8 7 7 # <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X # ; 8 8 q q t t t t t u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u t t t t q q 8 7 7 7 # <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<Xo $ 7 7 8 q q q q t t t t t t t t u u u u u u u u u u u t t t t t t t t q q q q 8 7 7 7 $ o <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X. O $ ; 7 7 8 8 8 q q q q q q q q q q q q q q q q q 8 8 8 7 7 7 ; $ O X <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<XX o o # $ $ $ $ $ - - $ $ # # # o X <X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X",
+"<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X<X"
+};
diff --git a/share/pixmaps/bitcoin32.png b/share/pixmaps/bitcoin32.png
new file mode 100644
index 0000000000..367abfcc8e
--- /dev/null
+++ b/share/pixmaps/bitcoin32.png
Binary files differ
diff --git a/share/pixmaps/bitcoin32.xpm b/share/pixmaps/bitcoin32.xpm
new file mode 100644
index 0000000000..bffedd4c68
--- /dev/null
+++ b/share/pixmaps/bitcoin32.xpm
@@ -0,0 +1,140 @@
+/* XPM */
+static char *bitcoin__[] = {
+/* columns rows colors chars-per-pixel */
+"32 32 102 2",
+" c #CC7D1D",
+". c #D5831F",
+"X c #D48221",
+"o c #D98621",
+"O c #DC8820",
+"+ c #DC8D2C",
+"@ c #D98F36",
+"# c #D68F39",
+"$ c #DD943E",
+"% c #E28B23",
+"& c #E98F24",
+"* c #E18F2D",
+"= c #ED9124",
+"- c #EC942A",
+"; c #F59624",
+": c #F89724",
+"> c #F79827",
+", c #F89825",
+"< c #F0962B",
+"1 c #F59A2D",
+"2 c #F99B2B",
+"3 c #EC9732",
+"4 c #EC9A37",
+"5 c #E2963B",
+"6 c #E6983A",
+"7 c #EC9C3B",
+"8 c #F69D33",
+"9 c #F99E32",
+"0 c #F49E3A",
+"q c #F9A036",
+"w c #F6A13C",
+"e c #F9A33B",
+"r c #D79341",
+"t c #DC9641",
+"y c #E39A43",
+"u c #EA9D42",
+"i c #EFA041",
+"p c #EDA34B",
+"a c #F5A443",
+"s c #F9A643",
+"d c #FAA846",
+"f c #F2A64C",
+"g c #F9AA4B",
+"h c #E5A251",
+"j c #ECA756",
+"k c #EBA758",
+"l c #FAAF57",
+"z c #FBB057",
+"x c #FBB25B",
+"c c #DFB179",
+"v c #E4AA65",
+"b c #EBAE64",
+"n c #E9AF69",
+"m c #FBB665",
+"M c #F1B46A",
+"N c #F8B96D",
+"B c #E5B071",
+"V c #EBB777",
+"C c #EEB877",
+"Z c #E7B478",
+"A c #EBB97D",
+"S c #F0B671",
+"D c #F2B871",
+"F c #EFBC80",
+"G c #E6BD8D",
+"H c #EDBF88",
+"J c #E6BF90",
+"K c #F1C187",
+"L c #F1C288",
+"P c #E5C093",
+"I c #EEC493",
+"U c #E1C19B",
+"Y c #E9C69C",
+"T c #ECC89D",
+"R c #F1C897",
+"E c #DFC5A4",
+"W c #DBCBB8",
+"Q c #E2C7A7",
+"! c #EBCBA6",
+"~ c #E6CBAB",
+"^ c #E9D2B7",
+"/ c #E5D1B9",
+"( c #EBD6BD",
+") c #EFD9BE",
+"_ c #DDD0C2",
+"` c #DCD7D2",
+"' c #DEDEDE",
+"] c #ECDAC5",
+"[ c #EDDECB",
+"{ c #E9E0D5",
+"} c #E7E0D9",
+"| c #E9E2DB",
+" . c #EFE8DF",
+".. c #E5E5E5",
+"X. c #EBE7E2",
+"o. c #EFEAE6",
+"O. c #ECECEC",
+"+. c #F2ECE6",
+"@. c #F1F0EE",
+"#. c #F4F4F4",
+"$. c #FBFBFB",
+"%. c None",
+/* pixels */
+"%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.",
+"%.%.%.%.%.%.%.%.%.%.%.%.%.%.t 5 5 $ %.%.%.%.%.%.%.%.%.%.%.%.%.%.",
+"%.%.%.%.%.%.%.%.%.%.%.r u w q 9 9 9 8 4 # %.%.%.%.%.%.%.%.%.%.%.",
+"%.%.%.%.%.%.%.%.%.y s e 9 2 , , , : > 2 9 q 5 %.%.%.%.%.%.%.%.%.",
+"%.%.%.%.%.%.%.%.s q 2 , , , , : , > 2 2 > > 2 9 %.%.%.%.%.%.%.%.",
+"%.%.%.%.%.%.t e 1 , , , , : : ; > 2 9 9 2 , , > 2 + %.%.%.%.%.%.",
+"%.%.%.%.%.$ e 2 , , , , , , ; u u 8 1 1 2 > , , > > + %.%.%.%.%.",
+"%.%.%.%.%.e 2 , , : > ; ; > < ` ` 0 c n 1 2 , , , > , %.%.%.%.%.",
+"%.%.%.%.e 1 , , , , ; h v - 3 ..! w ' _ 9 2 > , , , > : %.%.%.%.",
+"%.%.%.6 q , : , > 2 > W ..| [ #.H V ..D 9 9 2 , , , , , % %.%.%.",
+"%.%.%.e 2 , > 2 2 2 9 b ! #.$.$.#.#.#.Y i 1 2 > , , , > ; %.%.%.",
+"%.%.@ q > 2 2 2 9 q e q 0 o.$.+.) { #.#.| b 2 2 , , , , : X %.%.",
+"%.%.4 9 2 2 9 q e e s w b O.#.( m x I @.$...f > > , , , : & %.%.",
+"%.%.8 > 2 2 9 e s d g a P #.#.L x l a [ $.#.A 2 2 , : , , ; %.%.",
+"%.+ 1 , , 2 2 q e d g f / $.#.T n k Z o.$.O.M 9 2 > , , , ; X %.",
+"%.* 2 , , , 2 9 q e s f X.$.#.O.O.O.#.$.+.Y g e 9 2 , , , ; o %.",
+"%.* 2 , , , 2 2 q e w n O.$.[ R ( O.$.$.[ d s e 9 2 2 , , ; o %.",
+"%.+ 2 , , , > 2 8 8 1 G #.#.T m m N ] #.#.~ s e e 9 2 > : ; X %.",
+"%.%.> , , , , 2 < v B [ $.O.m z z s b #.$...g e e q 9 2 ; = %.%.",
+"%.%.= : , , , : 7 ' O.#.$.@.C j p u ~ #.$.} g q 9 9 2 2 ; % %.%.",
+"%.%.o , , , , : 0 G ^ .$.#.O.X.{ X.#.$.#.Y e 9 2 2 > , ; %.%.",
+"%.%.%., : , , , 2 2 2 M O.) ] #.#.#.#.O./ d 9 2 > , , ; = %.%.%.",
+"%.%.%.& ; , , , , 2 ; Q ..g F O.K A H S s 9 2 > , : , ; o %.%.%.",
+"%.%.%.%.; ; , , , , 2 E _ d ' ..d q q 9 2 > , : , , ; = %.%.%.%.",
+"%.%.%.%.%.; : , , , 2 q d g U J e 2 2 > , , , , , ; = %.%.%.%.%.",
+"%.%.%.%.%.o ; : , , , 2 9 q 9 q 9 > , : , , , , ; = . %.%.%.%.%.",
+"%.%.%.%.%.%.. ; ; , , > 2 2 2 > , , , , , , , ; = %.%.%.%.%.%.",
+"%.%.%.%.%.%.%.%.= ; : > 2 2 , , : , , , , ; ; & %.%.%.%.%.%.%.%.",
+"%.%.%.%.%.%.%.%.%.. = ; > : , , , , ; ; = = X %.%.%.%.%.%.%.%.%.",
+"%.%.%.%.%.%.%.%.%.%.%. % = ; ; ; ; & O %.%.%.%.%.%.%.%.%.%.%.",
+"%.%.%.%.%.%.%.%.%.%.%.%.%.%. X X %.%.%.%.%.%.%.%.%.%.%.%.%.%.",
+"%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%."
+};
diff --git a/share/pixmaps/bitcoin64.png b/share/pixmaps/bitcoin64.png
new file mode 100644
index 0000000000..08c676ae4a
--- /dev/null
+++ b/share/pixmaps/bitcoin64.png
Binary files differ
diff --git a/share/pixmaps/bitcoin64.xpm b/share/pixmaps/bitcoin64.xpm
new file mode 100644
index 0000000000..851829d41c
--- /dev/null
+++ b/share/pixmaps/bitcoin64.xpm
@@ -0,0 +1,242 @@
+/* XPM */
+static char *bitcoin__[] = {
+/* columns rows colors chars-per-pixel */
+"64 64 172 2",
+" c #8F6319",
+". c #8F6A1A",
+"X c #90651A",
+"o c #916C1A",
+"O c #AF7C1E",
+"+ c #B1781E",
+"@ c #9A7026",
+"# c #AC801F",
+"$ c #B1811F",
+"% c #A9812B",
+"& c #B08320",
+"* c #BB8621",
+"= c #BD8E22",
+"- c #A58132",
+"; c #FC8400",
+": c #FD8A03",
+"> c #FD8E0C",
+", c #FF910E",
+"< c #F98F14",
+"1 c #F79117",
+"2 c #FD9314",
+"3 c #FC951B",
+"4 c #FE9A1D",
+"5 c #CA8E22",
+"6 c #CC8E2A",
+"7 c #D48D23",
+"8 c #C39223",
+"9 c #CE9925",
+"0 c #D19C25",
+"q c #D19329",
+"w c #D5992B",
+"e c #DD9D33",
+"r c #D69F3C",
+"t c #E29425",
+"y c #E79925",
+"u c #EA9926",
+"i c #E69A2C",
+"p c #F79625",
+"a c #F99524",
+"s c #F79825",
+"d c #F89825",
+"f c #F3962A",
+"g c #F69B2C",
+"h c #F89B2B",
+"j c #E19F30",
+"k c #EE9B34",
+"l c #F49D33",
+"z c #F99E32",
+"x c #F39F3B",
+"c c #DFA731",
+"v c #D7A43D",
+"b c #DCA63C",
+"n c #EEA328",
+"m c #FFA225",
+"M c #FFAB26",
+"N c #F3A529",
+"B c #FEA429",
+"V c #F4AB2A",
+"C c #FFAC2A",
+"Z c #FFB325",
+"A c #FFB42C",
+"S c #FFBB2D",
+"D c #E3A335",
+"F c #E5A438",
+"G c #EDA03D",
+"H c #F7A037",
+"J c #FAA135",
+"K c #F3AB31",
+"L c #FEAB31",
+"P c #F4A13C",
+"I c #F9A33B",
+"U c #FDB432",
+"Y c #FFBF37",
+"T c #FFC12F",
+"R c #FFC230",
+"E c #FFC03E",
+"W c #DFAF41",
+"Q c #ECA34D",
+"! c #EDA84E",
+"~ c #F2A343",
+"^ c #FAA642",
+"/ c #FAA846",
+"( c #F1A74C",
+") c #F6A94F",
+"_ c #FAAA4A",
+"` c #E7A451",
+"' c #ECA754",
+"] c #EFAA56",
+"[ c #ECAC5B",
+"{ c #F3AA52",
+"} c #FCAE52",
+"| c #FBB056",
+" . c #FBB25C",
+".. c #E7AB61",
+"X. c #ECB067",
+"o. c #E7B36D",
+"O. c #EBB36C",
+"+. c #F2B163",
+"@. c #FCB460",
+"#. c #F0B56B",
+"$. c #E3B274",
+"%. c #EDB672",
+"&. c #EDB877",
+"*. c #E2B57C",
+"=. c #ECB97B",
+"-. c #E4BA83",
+";. c #EBBD83",
+":. c #E7BF8D",
+">. c #EBBD88",
+",. c #E9C08C",
+"<. c #E7C496",
+"1. c #EBC393",
+"2. c #EBC997",
+"3. c #E7C49A",
+"4. c #E9C69A",
+"5. c #E3CA9D",
+"6. c #E9C89E",
+"7. c #DCC9AE",
+"8. c #DDCBB2",
+"9. c #E3C7A2",
+"0. c #E5CAA3",
+"q. c #E9CBA3",
+"w. c #E5CEAB",
+"e. c #E8CEAA",
+"r. c #E4D4AC",
+"t. c #EBD2AF",
+"y. c #E7CFB2",
+"u. c #E1D4B4",
+"i. c #E8D5B6",
+"p. c #E5D7BB",
+"a. c #E9D6BB",
+"s. c #E5D8B9",
+"d. c #EAD8BE",
+"f. c #F0D6B4",
+"g. c #DFDFC6",
+"h. c #E3D6C1",
+"j. c #E9D7C0",
+"k. c #E6DAC5",
+"l. c #EBDCC7",
+"z. c #E5DCCA",
+"x. c #EADEC9",
+"c. c #E8DFD0",
+"v. c #D7E2D9",
+"b. c #E3E0C9",
+"n. c #EEE2CB",
+"m. c #E6E1D4",
+"M. c #E9E2D3",
+"N. c #E4E4DC",
+"B. c #E9E5DE",
+"V. c #F4EDDE",
+"C. c #DFE8E6",
+"Z. c #DEEEE8",
+"A. c #DFF2F3",
+"S. c #DDFFFF",
+"D. c #E1E6E0",
+"F. c #E8E6E2",
+"G. c #E8E9E5",
+"H. c #E5EFEC",
+"J. c #E8E9EA",
+"K. c #EAF3EE",
+"L. c #F3F3EB",
+"P. c #E7EDF2",
+"I. c #E8EEF3",
+"U. c #E7F4F7",
+"Y. c #E9F0F7",
+"T. c #EBF5FD",
+"R. c #E4FEFF",
+"E. c #ECFCFF",
+"W. c #F4F5F4",
+"Q. c #F4FFFF",
+"!. c #FEFFFF",
+"~. c None",
+/* pixels */
+"~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.",
+"~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.",
+"~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.",
+"~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.",
+"~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.F L h C C A A A A C C h L e ~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.",
+"~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.D N C m d d a a p a a p a a d m m C N j ~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.",
+"~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.- K M m a p s d d d d d d d d d d d d s p d m M V % ~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.",
+"~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.Y M d a d d d d d d d d d d d d d d d d h h d s a d M U ~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.",
+"~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.E m 4 a d d d d d d d d d d d d d d d d d d h h h d d d a d M U ~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.",
+"~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.C 4 a d d d d d d d d d d d d d d d d d h h h h h h d d d d d a m C ~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.",
+"~.~.~.~.~.~.~.~.~.~.~.~.~.W S a p d d d d d d d d d d d d d d d d h h h h g g h h h d d d d d p a S c ~.~.~.~.~.~.~.~.~.~.~.~.~.",
+"~.~.~.~.~.~.~.~.~.~.~.~.v M a s d d d d d d d d d d d d d d d h h h h h g z z g h h d d d d d d s a C w ~.~.~.~.~.~.~.~.~.~.~.~.",
+"~.~.~.~.~.~.~.~.~.~.~.r Z a d d d d d d d d d d d d d d d g 4 : 2 h z z z z z h h h h d d d d d d d a S q ~.~.~.~.~.~.~.~.~.~.~.",
+"~.~.~.~.~.~.~.~.~.~.b Z a d d d d d d d d d d d d d d h h 4 x $.l a z H h h H z h h h d d d d d d d d a A w ~.~.~.~.~.~.~.~.~.~.",
+"~.~.~.~.~.~.~.~.~.~.T a s d d d d d d d d d d d d h h h g : $.R.T.7.a B x f > a H h h d d d d d d d d s a R ~.~.~.~.~.~.~.~.~.~.",
+"~.~.~.~.~.~.~.~.~.U a s d d d d d d d d d d d d h h h h z : e.!.!.p.2 3 8.D.5.' a h h h d d d d d d d d p d A ~.~.~.~.~.~.~.~.~.",
+"~.~.~.~.~.~.~.~.U M p d d d d d d d d d d h h 1 : : 2 h h p B.!.Q.%., l J.!.R.-.> z h h h d d d d d d d d p C N ~.~.~.~.~.~.~.~.",
+"~.~.~.~.~.~.~.~.S a d d d d d d d d d d h d 3 7.r.O.G p ; k E.!.T.( , [ E.!.T.~ 4 z h h h d d d d d d d d d a S ~.~.~.~.~.~.~.~.",
+"~.~.~.~.~.~.~.V d s d d d d d d d d h h h 2 l E.!.Q.T.m.:.q.!.!.l.: : -.Q.!.c.a z z z g h h d d d d d d d d s m A ~.~.~.~.~.~.~.",
+"~.~.~.~.~.~.@ S a d d d d d d d h h h h z : *.R.!.!.!.!.Q.!.!.!.V.,.Q d.!.Q.1.2 I z z h h h d d d d d d d d d a S X ~.~.~.~.~.~.",
+"~.~.~.~.~.~.U d s d d d d d h h h h h g z a [ 5.M.Q.!.!.!.!.!.!.!.Q.E.!.!.Q.&.; 3 J H z h h h d d d d d d d d s h C ~.~.~.~.~.~.",
+"~.~.~.~.~.~.S a d d d d h h h h h h z z z I d > < %.W.!.!.!.!.!.!.!.!.!.!.!.W.s.[ > 4 H g h h d d d d d d d d d a S ~.~.~.~.~.~.",
+"~.~.~.~.~.i M p d d d h h h h g z z z z J H I I J > x.!.!.!.!.Q.T.E.Q.!.!.!.!.!.E.u.f 2 H h h h d d d d d d d d p C 7 ~.~.~.~.~.",
+"~.~.~.~.~.C a d h h h h h g g z z z J J I I I I J P J.!.!.!.!.d.P =.e.G.E.!.!.!.!.Q.Z.f 2 z h h d d d d d d d d d d A ~.~.~.~.~.",
+"~.~.~.~.~.A a h h h h h g z z z J H I I I I ^ / d X.E.!.!.!.Q.1.4 I J I ;.U.!.!.!.!.!.N.1 h g h h d d d d d d d d a S ~.~.~.~.~.",
+"~.~.~.~.6 C p d h h h z z J J J I I I I ^ ^ ^ _ a 3.Q.!.!.!.E.#.I . ._ 3 ] K.!.!.!.!.E.O., z h h h d d d d d d d p A + ~.~.~.~.",
+"~.~.~.~.i B d d h h h g z J I I I I ^ ^ ^ / / _ h k.!.!.!.!.J.) } . .| .3 6.Q.!.!.!.Q.q.> z g h h d d d d d d d d B t ~.~.~.~.",
+"~.~.~.~.B d d d d h h h z z J I I ^ / / / _ _ ^ ( I.!.!.!.Q.d.I . . .| .d 1.Q.!.!.!.Q.q.2 z h h h d d d d d d d d d B ~.~.~.~.",
+"~.~.~.~.C a d d d d h h g z J H I ^ ^ / _ _ } J %.E.!.!.!.Q.;.4 _ } | } J f m.!.!.!.!.Q.;.2 J z g h h d d d d d d d a A ~.~.~.~.",
+"~.~.~.~.C a d d d d h h h z z J I I ^ ^ / _ } z 6.Q.!.!.!.!.n.<.&.+.{ ) ] h.Q.!.!.!.!.R.~ d H z z h h h d d d d d d a A ~.~.~.~.",
+"~.~.~.~.A a d d d d d h h g z z H I I ^ / _ _ z k.!.!.!.!.!.!.Q.E.I.F.F.T.Q.!.!.!.!.E.9.2 I J z z h h h d d d d d d d A ~.~.~.~.",
+"~.~.~.~.S a d d d d d h h h z z J I I ^ ^ / I ( P.!.!.!.!.Q.Q.!.!.!.!.!.!.!.!.!.!.E.w.d J I I J z h h h d d d d d d d A ~.~.~.~.",
+"~.~.~.~.A a d d d d d d h h h z J J I I ^ / h O.E.!.!.!.Q.f.1.z.Y.E.!.!.!.!.!.!.L.! , ^ / I I H z z h h h d d d d d d A ~.~.~.~.",
+"~.~.~.~.S p d d d d d d h h h z z J I I ^ / d <.Q.!.!.!.E.+.d _ +.>.k.E.!.!.!.!.Q.s.P J _ ^ I I J z z h h h d d d d d A ~.~.~.~.",
+"~.~.~.~.C a d d d d d d d h h g z z H I I ^ d k.!.!.!.!.J.{ | @.} I I O.H.!.!.!.!.Q.C.l I ^ I I H J z g h h d d d d a A ~.~.~.~.",
+"~.~.~.~.B a d d d d d d d h h h h z z J I J x P.!.!.!.Q.j.I . . . . .B { K.!.!.!.!.Q.0.a / ^ I I J z z h h h d d d a A ~.~.~.~.",
+"~.~.~.~.B d d d d d d d d d h h h J h f 2 ; [ E.!.!.!.Q.1.I . . .| | .d 4.Q.!.!.!.!.m.z I ^ I I I J z h h h h d d d B ~.~.~.~.",
+"~.~.~.~.u B d d d d d d d d h h z , ' v.q.X.M.!.!.!.!.E.#.^ . .| } } } d >.Q.!.!.!.!.F.x J I I I J J z z h h h d d C t ~.~.~.~.",
+"~.~.~.~.7 C p d d d d d d d d h h : y.Q.Q.Q.!.!.!.!.!.B.d B / _ } } } J 1 k.!.!.!.!.!.c.s J I H J J z z z h h h h s A + ~.~.~.~.",
+"~.~.~.~.~.A a d d d d d d d d h > ` R.!.!.!.!.!.!.!.!.L.q.=.[ ~ z h h l 0.Q.!.!.!.!.Q.q.2 I J J z z h h h h h h h a S ~.~.~.~.~.",
+"~.~.~.~.~.C d d d d d d d d d d > ..g.Y.E.Q.!.!.!.!.!.!.Q.E.T.B.k.a.d.P.Q.!.!.!.!.!.E.[ 2 J z z z g h h h h d d d d C ~.~.~.~.~.",
+"~.~.~.~.~.y C p d d d d d d d d g 3 > l [ <.x.W.!.!.!.!.!.!.!.!.!.!.!.!.!.!.!.!.!.Q.z.> z z z h h h h h d d d d p C 7 ~.~.~.~.~.",
+"~.~.~.~.~.~.S a d d d d d d d d d h h 3 , > ; =.Q.!.W.T.Q.!.!.!.!.!.!.!.!.!.!.!.Q.A.g 2 z h h h h h h d d d d d a S ~.~.~.~.~.~.",
+"~.~.~.~.~.~.C h s d d d d d d d d d h g z H : <.!.!.t.l &.V.!.!.Q.Q.Q.Q.!.Q.Q.E.b.l > H h h h h h d d d d d d s m C ~.~.~.~.~.~.",
+"~.~.~.~.~.~.X S a d d d d d d d d d h h h h p N.!.Q.=.: < c.!.Q.2.&.e.a.d.i.6.[ < 2 z h h h h d d d d d d d d a S ~.~.~.~.~.~.",
+"~.~.~.~.~.~.~.A h s d d d d d d d d d h g 2 ~ E.!.E.{ 2 [ E.!.T.l : 2 1 3 2 > > h z h h h h d d d d d d d d s m A ~.~.~.~.~.~.~.",
+"~.~.~.~.~.~.~.~.S a d d d d d d d d d h h : -.R.!.B.h 2 =.Q.!.M.p z z z h h z g h h h d d d d d d d d d d d a S ~.~.~.~.~.~.~.~.",
+"~.~.~.~.~.~.~.~.N C p d d d d d d d d d h 3 ' 2.N.9.2 3 z.!.!.q.> J z h h h h h h d d d d d d d d d d d d p C n ~.~.~.~.~.~.~.~.",
+"~.~.~.~.~.~.~.~.~.S h p d d d d d d d d d z 3 : p l J g 8.T.S.O.> z h h h h h d d d d d d d d d d d d d p h S ~.~.~.~.~.~.~.~.~.",
+"~.~.~.~.~.~.~.~.~.~.S a s d d d d d d d d h h z d h I J a P o.P d g h h h d d d d d d d d d d d d d d s a S ~.~.~.~.~.~.~.~.~.~.",
+"~.~.~.~.~.~.~.~.~.~.* S a s d d d d d d d d h h g z J J h 3 > d z h h h d d d d d d d d d d d d d d s a S * ~.~.~.~.~.~.~.~.~.~.",
+"~.~.~.~.~.~.~.~.~.~.~.$ T a s d d d d d d d h h h z z z h g g h h d d d d d d d d d d d d d d d d s a T O ~.~.~.~.~.~.~.~.~.~.~.",
+"~.~.~.~.~.~.~.~.~.~.~.~.& S a p d d d d d d h h h z g h h h h h d d d d d d d d d d d d d d d d p a S # ~.~.~.~.~.~.~.~.~.~.~.~.",
+"~.~.~.~.~.~.~.~.~.~.~.~.~.8 S d p d d d d d d h h g h h h h d d d d d d d d d d d d d d d d d p h S = ~.~.~.~.~.~.~.~.~.~.~.~.~.",
+"~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.S A a s d d d d h h h h h d d d d d d d d d d d d d d d d d s a A S ~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.",
+"~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.0 T m p d d d d h h h d d d d d d d d d d d d d d d d d p B S 9 ~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.",
+"~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.V S m a p d h d d d d d d d d d d d d d d d d p a m S V ~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.",
+"~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.o V S C d p p d d d d d d d d d d d d p p d C S N . ~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.",
+"~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.5 C S A B d d a a d d a a a d B A S C 5 ~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.",
+"~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.O t B A A A A A A A A B t O ~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.",
+"~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.",
+"~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.",
+"~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.",
+"~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~."
+};
diff --git a/share/pixmaps/check.ico b/share/pixmaps/check.ico
new file mode 100644
index 0000000000..0c4e6e8147
--- /dev/null
+++ b/share/pixmaps/check.ico
Binary files differ
diff --git a/share/pixmaps/favicon.ico b/share/pixmaps/favicon.ico
new file mode 100644
index 0000000000..754eebc488
--- /dev/null
+++ b/share/pixmaps/favicon.ico
Binary files differ
diff --git a/share/pixmaps/nsis-header.bmp b/share/pixmaps/nsis-header.bmp
new file mode 100644
index 0000000000..9ab0ce2591
--- /dev/null
+++ b/share/pixmaps/nsis-header.bmp
Binary files differ
diff --git a/share/pixmaps/nsis-wizard.bmp b/share/pixmaps/nsis-wizard.bmp
new file mode 100644
index 0000000000..71255c6850
--- /dev/null
+++ b/share/pixmaps/nsis-wizard.bmp
Binary files differ
diff --git a/share/pixmaps/send16.bmp b/share/pixmaps/send16.bmp
new file mode 100644
index 0000000000..676b5c4b49
--- /dev/null
+++ b/share/pixmaps/send16.bmp
Binary files differ
diff --git a/share/pixmaps/send16mask.bmp b/share/pixmaps/send16mask.bmp
new file mode 100644
index 0000000000..06c747f934
--- /dev/null
+++ b/share/pixmaps/send16mask.bmp
Binary files differ
diff --git a/share/pixmaps/send16masknoshadow.bmp b/share/pixmaps/send16masknoshadow.bmp
new file mode 100644
index 0000000000..faf24e0d8a
--- /dev/null
+++ b/share/pixmaps/send16masknoshadow.bmp
Binary files differ
diff --git a/share/pixmaps/send20.bmp b/share/pixmaps/send20.bmp
new file mode 100644
index 0000000000..2b90422b38
--- /dev/null
+++ b/share/pixmaps/send20.bmp
Binary files differ
diff --git a/share/pixmaps/send20mask.bmp b/share/pixmaps/send20mask.bmp
new file mode 100644
index 0000000000..f124d0da08
--- /dev/null
+++ b/share/pixmaps/send20mask.bmp
Binary files differ
diff --git a/share/qt/Info.plist.in b/share/qt/Info.plist.in
new file mode 100644
index 0000000000..a389332a52
--- /dev/null
+++ b/share/qt/Info.plist.in
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
+<plist version="0.9">
+<dict>
+ <key>LSMinimumSystemVersion</key>
+ <string>10.7.0</string>
+
+ <key>LSArchitecturePriority</key>
+ <array>
+ <string>x86_64</string>
+ </array>
+
+ <key>CFBundleIconFile</key>
+ <string>bitcoin.icns</string>
+
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+
+ <key>CFBundleGetInfoString</key>
+ <string>@CLIENT_VERSION_MAJOR@.@CLIENT_VERSION_MINOR@.@CLIENT_VERSION_REVISION@, Copyright © 2009-@COPYRIGHT_YEAR@ The Bitcoin Core developers</string>
+
+ <key>CFBundleShortVersionString</key>
+ <string>@CLIENT_VERSION_MAJOR@.@CLIENT_VERSION_MINOR@.@CLIENT_VERSION_REVISION@</string>
+
+ <key>CFBundleVersion</key>
+ <string>@CLIENT_VERSION_MAJOR@.@CLIENT_VERSION_MINOR@.@CLIENT_VERSION_REVISION@</string>
+
+ <key>CFBundleSignature</key>
+ <string>????</string>
+
+ <key>CFBundleExecutable</key>
+ <string>Bitcoin-Qt</string>
+
+ <key>CFBundleName</key>
+ <string>Bitcoin-Qt</string>
+
+ <key>LSHasLocalizedDisplayName</key>
+ <true/>
+
+ <key>CFBundleIdentifier</key>
+ <string>org.bitcoinfoundation.Bitcoin-Qt</string>
+
+ <key>CFBundleURLTypes</key>
+ <array>
+ <dict>
+ <key>CFBundleTypeRole</key>
+ <string>Editor</string>
+ <key>CFBundleURLName</key>
+ <string>org.bitcoin.BitcoinPayment</string>
+ <key>CFBundleURLSchemes</key>
+ <array>
+ <string>bitcoin</string>
+ </array>
+ </dict>
+ </array>
+
+ <key>UTExportedTypeDeclarations</key>
+ <array>
+ <dict>
+ <key>UTTypeIdentifier</key>
+ <string>org.bitcoin.paymentrequest</string>
+ <key>UTTypeDescription</key>
+ <string>Bitcoin payment request</string>
+ <key>UTTypeConformsTo</key>
+ <array>
+ <string>public.data</string>
+ </array>
+ <key>UTTypeTagSpecification</key>
+ <dict>
+ <key>public.mime-type</key>
+ <string>application/x-bitcoin-payment-request</string>
+ <key>public.filename-extension</key>
+ <array>
+ <string>bitcoinpaymentrequest</string>
+ </array>
+ </dict>
+ </dict>
+ </array>
+
+ <key>CFBundleDocumentTypes</key>
+ <array>
+ <dict>
+ <key>CFBundleTypeRole</key>
+ <string>Editor</string>
+ <key>LSItemContentTypes</key>
+ <array>
+ <string>org.bitcoin.paymentrequest</string>
+ </array>
+ <key>LSHandlerRank</key>
+ <string>Owner</string>
+ </dict>
+ </array>
+
+ <key>NSPrincipalClass</key>
+ <string>NSApplication</string>
+
+ <key>NSHighResolutionCapable</key>
+ <string>True</string>
+
+ <key>LSAppNapIsDisabled</key>
+ <string>True</string>
+
+ <key>LSApplicationCategoryType</key>
+ <string>public.app-category.finance</string>
+</dict>
+</plist>
diff --git a/share/qt/extract_strings_qt.py b/share/qt/extract_strings_qt.py
new file mode 100755
index 0000000000..d4bd585138
--- /dev/null
+++ b/share/qt/extract_strings_qt.py
@@ -0,0 +1,78 @@
+#!/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
+import os
+import sys
+
+OUT_CPP="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 = sys.argv[1:]
+
+# xgettext -n --keyword=_ $FILES
+XGETTEXT=os.getenv('XGETTEXT', 'xgettext')
+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 <QtGlobal>
+
+// 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('};\n')
+f.close()
diff --git a/share/qt/img/reload.png b/share/qt/img/reload.png
new file mode 100644
index 0000000000..9068db9a63
--- /dev/null
+++ b/share/qt/img/reload.png
Binary files differ
diff --git a/share/qt/img/reload.xcf b/share/qt/img/reload.xcf
new file mode 100644
index 0000000000..dc8be62831
--- /dev/null
+++ b/share/qt/img/reload.xcf
Binary files differ
diff --git a/share/qt/make_spinner.py b/share/qt/make_spinner.py
new file mode 100755
index 0000000000..bb19e91508
--- /dev/null
+++ b/share/qt/make_spinner.py
@@ -0,0 +1,38 @@
+#!/usr/bin/env python
+# W.J. van der Laan, 2011
+# Make spinning 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.png'
+TMPDIR='../../src/qt/res/movies/'
+TMPNAME='spinner-%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)
+
+
diff --git a/share/qt/make_windows_icon.sh b/share/qt/make_windows_icon.sh
new file mode 100755
index 0000000000..bf607b1c62
--- /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/qt/protobuf.pri b/share/qt/protobuf.pri
new file mode 100644
index 0000000000..865fe86555
--- /dev/null
+++ b/share/qt/protobuf.pri
@@ -0,0 +1,35 @@
+# Based on: http://code.google.com/p/ostinato/source/browse/protobuf.pri
+#
+# Qt qmake integration with Google Protocol Buffers compiler protoc
+#
+# To compile protocol buffers with qt qmake, specify PROTOS variable and
+# include this file
+#
+# Example:
+# PROTOS = a.proto b.proto
+# include(protobuf.pri)
+#
+# Set PROTO_PATH if you need to set the protoc --proto_path search path
+# Set PROTOC to the path to the protoc compiler if it is not in your $PATH
+#
+
+isEmpty(PROTO_DIR):PROTO_DIR = .
+isEmpty(PROTOC):PROTOC = protoc
+
+PROTOPATHS =
+for(p, PROTO_PATH):PROTOPATHS += --proto_path=$${p}
+
+protobuf_decl.name = protobuf header
+protobuf_decl.input = PROTOS
+protobuf_decl.output = $${PROTO_DIR}/${QMAKE_FILE_BASE}.pb.h
+protobuf_decl.commands = $${PROTOC} --cpp_out="$${PROTO_DIR}" $${PROTOPATHS} --proto_path=${QMAKE_FILE_IN_PATH} ${QMAKE_FILE_NAME}
+protobuf_decl.variable_out = GENERATED_FILES
+QMAKE_EXTRA_COMPILERS += protobuf_decl
+
+protobuf_impl.name = protobuf implementation
+protobuf_impl.input = PROTOS
+protobuf_impl.output = $${PROTO_DIR}/${QMAKE_FILE_BASE}.pb.cc
+protobuf_impl.depends = $${PROTO_DIR}/${QMAKE_FILE_BASE}.pb.h
+protobuf_impl.commands = $$escape_expand(\\n)
+protobuf_impl.variable_out = GENERATED_SOURCES
+QMAKE_EXTRA_COMPILERS += protobuf_impl
diff --git a/share/setup.nsi.in b/share/setup.nsi.in
new file mode 100644
index 0000000000..6c0e895bb1
--- /dev/null
+++ b/share/setup.nsi.in
@@ -0,0 +1,179 @@
+Name "@PACKAGE_NAME@ (@WINDOWS_BITS@-bit)"
+
+RequestExecutionLevel highest
+SetCompressor /SOLID lzma
+
+# General Symbol Definitions
+!define REGKEY "SOFTWARE\$(^Name)"
+!define VERSION @CLIENT_VERSION_MAJOR@.@CLIENT_VERSION_MINOR@.@CLIENT_VERSION_REVISION@
+!define COMPANY "Bitcoin Core project"
+!define URL http://www.bitcoin.org/
+
+# MUI Symbol Definitions
+!define MUI_ICON "@abs_top_srcdir@/share/pixmaps/bitcoin.ico"
+!define MUI_WELCOMEFINISHPAGE_BITMAP "@abs_top_srcdir@/share/pixmaps/nsis-wizard.bmp"
+!define MUI_HEADERIMAGE
+!define MUI_HEADERIMAGE_RIGHT
+!define MUI_HEADERIMAGE_BITMAP "@abs_top_srcdir@/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 "@PACKAGE_NAME@"
+!define MUI_FINISHPAGE_RUN $INSTDIR\bitcoin-qt.exe
+!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico"
+!define MUI_UNWELCOMEFINISHPAGE_BITMAP "@abs_top_srcdir@/share/pixmaps/nsis-wizard.bmp"
+!define MUI_UNFINISHPAGE_NOAUTOCLOSE
+
+# Included files
+!include Sections.nsh
+!include MUI2.nsh
+!if "@WINDOWS_BITS@" == "64"
+!include x64.nsh
+!endif
+
+# 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 @abs_top_srcdir@/bitcoin-${VERSION}-win@WINDOWS_BITS@-setup.exe
+!if "@WINDOWS_BITS@" == "64"
+InstallDir $PROGRAMFILES64\Bitcoin
+!else
+InstallDir $PROGRAMFILES\Bitcoin
+!endif
+CRCCheck on
+XPStyle on
+BrandingText " "
+ShowInstDetails show
+VIProductVersion ${VERSION}.@CLIENT_VERSION_BUILD@
+VIAddVersionKey ProductName "Bitcoin Core"
+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 @abs_top_srcdir@/release/bitcoin-qt.exe
+ File /oname=COPYING.txt @abs_top_srcdir@/COPYING
+ File /oname=readme.txt @abs_top_srcdir@/doc/README_windows.txt
+ SetOutPath $INSTDIR\daemon
+ File @abs_top_srcdir@/release/bitcoind.exe
+ File @abs_top_srcdir@/release/bitcoin-cli.exe
+ SetOutPath $INSTDIR\doc
+ File /r @abs_top_srcdir@/doc\*.*
+ SetOutPath $INSTDIR
+ WriteRegStr HKCU "${REGKEY}\Components" Main 1
+
+ # Remove old wxwidgets-based-bitcoin executable and locales:
+ Delete /REBOOTOK $INSTDIR\bitcoin.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\$(^Name).lnk" $INSTDIR\bitcoin-qt.exe
+ CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Uninstall $(^Name).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 "bitcoin" "URL Protocol" ""
+ WriteRegStr HKCR "bitcoin" "" "URL:Bitcoin"
+ WriteRegStr HKCR "bitcoin\DefaultIcon" "" $INSTDIR\bitcoin-qt.exe
+ WriteRegStr HKCR "bitcoin\shell\open\command" "" '"$INSTDIR\bitcoin-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\bitcoin-qt.exe
+ Delete /REBOOTOK $INSTDIR\COPYING.txt
+ Delete /REBOOTOK $INSTDIR\readme.txt
+ RMDir /r /REBOOTOK $INSTDIR\daemon
+ RMDir /r /REBOOTOK $INSTDIR\doc
+ DeleteRegValue HKCU "${REGKEY}\Components" Main
+SectionEnd
+
+Section -un.post UNSEC0001
+ DeleteRegKey HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)"
+ Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\Uninstall $(^Name).lnk"
+ Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\$(^Name).lnk"
+ Delete /REBOOTOK "$SMSTARTUP\Bitcoin.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 "bitcoin"
+ 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
+!if "@WINDOWS_BITS@" == "64"
+ ${If} ${RunningX64}
+ ; disable registry redirection (enable access to 64-bit portion of registry)
+ SetRegView 64
+ ${Else}
+ MessageBox MB_OK|MB_ICONSTOP "Cannot install 64-bit version on a 32-bit system."
+ Abort
+ ${EndIf}
+!endif
+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 0000000000..063641cba2
--- /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/.clang-format b/src/.clang-format
new file mode 100644
index 0000000000..226a15d185
--- /dev/null
+++ b/src/.clang-format
@@ -0,0 +1,51 @@
+AccessModifierOffset: -4
+AlignEscapedNewlinesLeft: true
+AlignTrailingComments: true
+AllowAllParametersOfDeclarationOnNextLine: false
+AllowShortBlocksOnASingleLine: false
+AllowShortFunctionsOnASingleLine: All
+AllowShortIfStatementsOnASingleLine: false
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakBeforeMultilineStrings: false
+AlwaysBreakTemplateDeclarations: true
+BinPackParameters: false
+BreakBeforeBinaryOperators: false
+BreakBeforeBraces: Linux
+BreakBeforeTernaryOperators: false
+BreakConstructorInitializersBeforeComma: false
+ColumnLimit: 0
+CommentPragmas: '^ IWYU pragma:'
+ConstructorInitializerAllOnOneLineOrOnePerLine: false
+ConstructorInitializerIndentWidth: 4
+ContinuationIndentWidth: 4
+Cpp11BracedListStyle: true
+DerivePointerAlignment: false
+DisableFormat: false
+ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH, BOOST_REVERSE_FOREACH ]
+IndentCaseLabels: false
+IndentFunctionDeclarationAfterType: false
+IndentWidth: 4
+KeepEmptyLinesAtTheStartOfBlocks: false
+Language: Cpp
+MaxEmptyLinesToKeep: 2
+NamespaceIndentation: None
+ObjCSpaceAfterProperty: false
+ObjCSpaceBeforeProtocolList: false
+PenaltyBreakBeforeFirstCallParameter: 1
+PenaltyBreakComment: 300
+PenaltyBreakFirstLessLess: 120
+PenaltyBreakString: 1000
+PenaltyExcessCharacter: 1000000
+PenaltyReturnTypeOnItsOwnLine: 200
+PointerAlignment: Left
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeParens: ControlStatements
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 1
+SpacesInAngles: false
+SpacesInContainerLiterals: true
+SpacesInCStyleCastParentheses: false
+SpacesInParentheses: false
+Standard: Cpp03
+TabWidth: 8
+UseTab: Never
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000000..8de216c176
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,436 @@
+DIST_SUBDIRS = secp256k1
+AM_LDFLAGS = $(PTHREAD_CFLAGS) $(LIBTOOL_LDFLAGS)
+
+
+if EMBEDDED_LEVELDB
+LEVELDB_CPPFLAGS += -I$(srcdir)/leveldb/include
+LEVELDB_CPPFLAGS += -I$(srcdir)/leveldb/helpers/memenv
+LIBLEVELDB += $(builddir)/leveldb/libleveldb.a
+LIBMEMENV += $(builddir)/leveldb/libmemenv.a
+
+# NOTE: This dependency is not strictly necessary, but without it make may try to build both in parallel, which breaks the LevelDB build system in a race
+$(LIBLEVELDB): $(LIBMEMENV)
+
+$(LIBLEVELDB) $(LIBMEMENV):
+ @echo "Building LevelDB ..." && $(MAKE) -C $(@D) $(@F) CXX="$(CXX)" \
+ CC="$(CC)" PLATFORM=$(TARGET_OS) AR="$(AR)" $(LEVELDB_TARGET_FLAGS) \
+ OPT="$(CXXFLAGS) $(CPPFLAGS) -D__STDC_LIMIT_MACROS"
+endif
+
+BITCOIN_CONFIG_INCLUDES=-I$(builddir)/config
+BITCOIN_INCLUDES=-I$(builddir) -I$(builddir)/obj $(BOOST_CPPFLAGS) $(LEVELDB_CPPFLAGS) $(CRYPTO_CFLAGS) $(SSL_CFLAGS)
+
+BITCOIN_INCLUDES += -I$(srcdir)/secp256k1/include
+
+LIBBITCOIN_SERVER=libbitcoin_server.a
+LIBBITCOIN_WALLET=libbitcoin_wallet.a
+LIBBITCOIN_COMMON=libbitcoin_common.a
+LIBBITCOIN_CLI=libbitcoin_cli.a
+LIBBITCOIN_UTIL=libbitcoin_util.a
+LIBBITCOIN_CRYPTO=crypto/libbitcoin_crypto.a
+LIBBITCOIN_UNIVALUE=univalue/libbitcoin_univalue.a
+LIBBITCOINQT=qt/libbitcoinqt.a
+LIBSECP256K1=secp256k1/libsecp256k1.la
+
+$(LIBSECP256K1): $(wildcard secp256k1/src/*) $(wildcard secp256k1/include/*)
+ $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F)
+
+# Make is not made aware of per-object dependencies to avoid limiting building parallelization
+# But to build the less dependent modules first, we manually select their order here:
+EXTRA_LIBRARIES = \
+ crypto/libbitcoin_crypto.a \
+ libbitcoin_util.a \
+ libbitcoin_common.a \
+ univalue/libbitcoin_univalue.a \
+ libbitcoin_server.a \
+ libbitcoin_cli.a
+if ENABLE_WALLET
+BITCOIN_INCLUDES += $(BDB_CPPFLAGS)
+EXTRA_LIBRARIES += libbitcoin_wallet.a
+endif
+
+if BUILD_BITCOIN_LIBS
+lib_LTLIBRARIES = libbitcoinconsensus.la
+LIBBITCOIN_CONSENSUS=libbitcoinconsensus.la
+else
+LIBBITCOIN_CONSENSUS=
+endif
+
+bin_PROGRAMS =
+TESTS =
+
+if BUILD_BITCOIND
+ bin_PROGRAMS += bitcoind
+endif
+
+if BUILD_BITCOIN_UTILS
+ bin_PROGRAMS += bitcoin-cli bitcoin-tx
+endif
+
+.PHONY: FORCE
+# bitcoin core #
+BITCOIN_CORE_H = \
+ addrman.h \
+ alert.h \
+ amount.h \
+ arith_uint256.h \
+ base58.h \
+ bloom.h \
+ chain.h \
+ chainparams.h \
+ chainparamsbase.h \
+ chainparamsseeds.h \
+ checkpoints.h \
+ checkqueue.h \
+ clientversion.h \
+ coincontrol.h \
+ coins.h \
+ compat.h \
+ compat/byteswap.h \
+ compat/endian.h \
+ compat/sanity.h \
+ compressor.h \
+ consensus/consensus.h \
+ consensus/params.h \
+ consensus/validation.h \
+ core_io.h \
+ eccryptoverify.h \
+ ecwrapper.h \
+ hash.h \
+ init.h \
+ key.h \
+ keystore.h \
+ leveldbwrapper.h \
+ limitedmap.h \
+ main.h \
+ memusage.h \
+ merkleblock.h \
+ miner.h \
+ mruset.h \
+ net.h \
+ netbase.h \
+ noui.h \
+ policy/fees.h \
+ pow.h \
+ primitives/block.h \
+ primitives/transaction.h \
+ protocol.h \
+ pubkey.h \
+ random.h \
+ reverselock.h \
+ rpcclient.h \
+ rpcprotocol.h \
+ rpcserver.h \
+ scheduler.h \
+ script/interpreter.h \
+ script/script.h \
+ script/script_error.h \
+ script/sigcache.h \
+ script/sign.h \
+ script/standard.h \
+ serialize.h \
+ streams.h \
+ support/allocators/secure.h \
+ support/allocators/zeroafterfree.h \
+ support/cleanse.h \
+ support/pagelocker.h \
+ sync.h \
+ threadsafety.h \
+ timedata.h \
+ tinyformat.h \
+ txdb.h \
+ txmempool.h \
+ ui_interface.h \
+ uint256.h \
+ undo.h \
+ util.h \
+ utilmoneystr.h \
+ utilstrencodings.h \
+ utiltime.h \
+ validationinterface.h \
+ version.h \
+ wallet/crypter.h \
+ wallet/db.h \
+ wallet/wallet.h \
+ wallet/wallet_ismine.h \
+ wallet/walletdb.h
+
+JSON_H = \
+ json/json_spirit.h \
+ json/json_spirit_error_position.h \
+ json/json_spirit_reader.h \
+ json/json_spirit_reader_template.h \
+ json/json_spirit_stream_reader.h \
+ json/json_spirit_utils.h \
+ json/json_spirit_value.h \
+ json/json_spirit_writer.h \
+ json/json_spirit_writer_template.h
+
+obj/build.h: FORCE
+ @$(MKDIR_P) $(builddir)/obj
+ @$(top_srcdir)/share/genbuild.sh $(abs_top_builddir)/src/obj/build.h \
+ $(abs_top_srcdir)
+libbitcoin_util_a-clientversion.$(OBJEXT): obj/build.h
+
+# server: shared between bitcoind and bitcoin-qt
+libbitcoin_server_a_CPPFLAGS = $(BITCOIN_INCLUDES) $(MINIUPNPC_CPPFLAGS)
+libbitcoin_server_a_SOURCES = \
+ addrman.cpp \
+ alert.cpp \
+ bloom.cpp \
+ chain.cpp \
+ checkpoints.cpp \
+ init.cpp \
+ leveldbwrapper.cpp \
+ main.cpp \
+ merkleblock.cpp \
+ miner.cpp \
+ net.cpp \
+ noui.cpp \
+ policy/fees.cpp \
+ pow.cpp \
+ rest.cpp \
+ rpcblockchain.cpp \
+ rpcmining.cpp \
+ rpcmisc.cpp \
+ rpcnet.cpp \
+ rpcrawtransaction.cpp \
+ rpcserver.cpp \
+ script/sigcache.cpp \
+ timedata.cpp \
+ txdb.cpp \
+ txmempool.cpp \
+ validationinterface.cpp \
+ $(JSON_H) \
+ $(BITCOIN_CORE_H)
+
+# wallet: shared between bitcoind and bitcoin-qt, but only linked
+# when wallet enabled
+libbitcoin_wallet_a_CPPFLAGS = $(BITCOIN_INCLUDES)
+libbitcoin_wallet_a_SOURCES = \
+ wallet/crypter.cpp \
+ wallet/db.cpp \
+ wallet/rpcdump.cpp \
+ wallet/rpcwallet.cpp \
+ wallet/wallet.cpp \
+ wallet/wallet_ismine.cpp \
+ wallet/walletdb.cpp \
+ $(BITCOIN_CORE_H)
+
+# crypto primitives library
+crypto_libbitcoin_crypto_a_CPPFLAGS = $(BITCOIN_CONFIG_INCLUDES)
+crypto_libbitcoin_crypto_a_SOURCES = \
+ crypto/common.h \
+ crypto/hmac_sha256.cpp \
+ crypto/hmac_sha256.h \
+ crypto/hmac_sha512.cpp \
+ crypto/hmac_sha512.h \
+ crypto/ripemd160.cpp \
+ crypto/ripemd160.h \
+ crypto/sha1.cpp \
+ crypto/sha1.h \
+ crypto/sha256.cpp \
+ crypto/sha256.h \
+ crypto/sha512.cpp \
+ crypto/sha512.h
+
+# univalue JSON library
+univalue_libbitcoin_univalue_a_SOURCES = \
+ univalue/univalue.cpp \
+ univalue/univalue.h \
+ univalue/univalue_escapes.h \
+ univalue/univalue_read.cpp \
+ univalue/univalue_write.cpp
+
+# common: shared between bitcoind, and bitcoin-qt and non-server tools
+libbitcoin_common_a_CPPFLAGS = $(BITCOIN_INCLUDES)
+libbitcoin_common_a_SOURCES = \
+ amount.cpp \
+ arith_uint256.cpp \
+ base58.cpp \
+ chainparams.cpp \
+ coins.cpp \
+ compressor.cpp \
+ core_read.cpp \
+ core_write.cpp \
+ eccryptoverify.cpp \
+ ecwrapper.cpp \
+ hash.cpp \
+ key.cpp \
+ keystore.cpp \
+ netbase.cpp \
+ primitives/block.cpp \
+ primitives/transaction.cpp \
+ protocol.cpp \
+ pubkey.cpp \
+ scheduler.cpp \
+ script/interpreter.cpp \
+ script/script.cpp \
+ script/script_error.cpp \
+ script/sign.cpp \
+ script/standard.cpp \
+ $(BITCOIN_CORE_H)
+
+# util: shared between all executables.
+# This library *must* be included to make sure that the glibc
+# backward-compatibility objects and their sanity checks are linked.
+libbitcoin_util_a_CPPFLAGS = $(BITCOIN_INCLUDES)
+libbitcoin_util_a_SOURCES = \
+ support/pagelocker.cpp \
+ chainparamsbase.cpp \
+ clientversion.cpp \
+ compat/glibc_sanity.cpp \
+ compat/glibcxx_sanity.cpp \
+ compat/strnlen.cpp \
+ random.cpp \
+ rpcprotocol.cpp \
+ support/cleanse.cpp \
+ sync.cpp \
+ uint256.cpp \
+ util.cpp \
+ utilmoneystr.cpp \
+ utilstrencodings.cpp \
+ utiltime.cpp \
+ $(BITCOIN_CORE_H)
+
+if GLIBC_BACK_COMPAT
+libbitcoin_util_a_SOURCES += compat/glibc_compat.cpp
+endif
+
+# cli: shared between bitcoin-cli and bitcoin-qt
+libbitcoin_cli_a_CPPFLAGS = $(BITCOIN_INCLUDES)
+libbitcoin_cli_a_SOURCES = \
+ rpcclient.cpp \
+ $(BITCOIN_CORE_H)
+
+nodist_libbitcoin_util_a_SOURCES = $(srcdir)/obj/build.h
+#
+
+# bitcoind binary #
+bitcoind_SOURCES = bitcoind.cpp
+bitcoind_CPPFLAGS = $(BITCOIN_INCLUDES)
+bitcoind_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
+
+if TARGET_WINDOWS
+bitcoind_SOURCES += bitcoind-res.rc
+endif
+
+bitcoind_LDADD = \
+ $(LIBBITCOIN_SERVER) \
+ $(LIBBITCOIN_COMMON) \
+ $(LIBBITCOIN_UNIVALUE) \
+ $(LIBBITCOIN_UTIL) \
+ $(LIBBITCOIN_CRYPTO) \
+ $(LIBLEVELDB) \
+ $(LIBMEMENV) \
+ $(LIBSECP256K1)
+
+if ENABLE_WALLET
+bitcoind_LDADD += libbitcoin_wallet.a
+endif
+
+bitcoind_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS)
+#
+
+# bitcoin-cli binary #
+bitcoin_cli_SOURCES = bitcoin-cli.cpp
+bitcoin_cli_CPPFLAGS = $(BITCOIN_INCLUDES)
+bitcoin_cli_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
+
+if TARGET_WINDOWS
+bitcoin_cli_SOURCES += bitcoin-cli-res.rc
+endif
+
+bitcoin_cli_LDADD = \
+ $(LIBBITCOIN_CLI) \
+ $(LIBBITCOIN_UTIL) \
+ $(LIBSECP256K1)
+
+bitcoin_cli_LDADD += $(BOOST_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS)
+#
+
+# bitcoin-tx binary #
+bitcoin_tx_SOURCES = bitcoin-tx.cpp
+bitcoin_tx_CPPFLAGS = $(BITCOIN_INCLUDES)
+bitcoin_tx_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
+
+if TARGET_WINDOWS
+bitcoin_tx_SOURCES += bitcoin-tx-res.rc
+endif
+
+bitcoin_tx_LDADD = \
+ $(LIBBITCOIN_UNIVALUE) \
+ $(LIBBITCOIN_COMMON) \
+ $(LIBBITCOIN_UTIL) \
+ $(LIBBITCOIN_CRYPTO) \
+ $(LIBSECP256K1)
+
+bitcoin_tx_LDADD += $(BOOST_LIBS) $(CRYPTO_LIBS)
+#
+
+# bitcoinconsensus library #
+if BUILD_BITCOIN_LIBS
+include_HEADERS = script/bitcoinconsensus.h
+libbitcoinconsensus_la_SOURCES = \
+ crypto/hmac_sha512.cpp \
+ crypto/ripemd160.cpp \
+ crypto/sha1.cpp \
+ crypto/sha256.cpp \
+ crypto/sha512.cpp \
+ eccryptoverify.cpp \
+ ecwrapper.cpp \
+ hash.cpp \
+ primitives/transaction.cpp \
+ pubkey.cpp \
+ script/bitcoinconsensus.cpp \
+ script/interpreter.cpp \
+ script/script.cpp \
+ uint256.cpp \
+ utilstrencodings.cpp
+
+if GLIBC_BACK_COMPAT
+ libbitcoinconsensus_la_SOURCES += compat/glibc_compat.cpp
+endif
+
+libbitcoinconsensus_la_LDFLAGS = -no-undefined $(RELDFLAGS)
+libbitcoinconsensus_la_LIBADD = $(CRYPTO_LIBS)
+libbitcoinconsensus_la_CPPFLAGS = $(CRYPTO_CFLAGS) -I$(builddir)/obj -DBUILD_BITCOIN_INTERNAL
+
+endif
+#
+
+CLEANFILES = leveldb/libleveldb.a leveldb/libmemenv.a *.gcda *.gcno
+
+DISTCLEANFILES = obj/build.h
+
+EXTRA_DIST = leveldb
+
+clean-local:
+ -$(MAKE) -C leveldb clean
+ -$(MAKE) -C secp256k1 clean
+ rm -f leveldb/*/*.gcno leveldb/helpers/memenv/*.gcno
+ -rm -f config.h
+
+.rc.o:
+ @test -f $(WINDRES)
+ $(AM_V_GEN) $(WINDRES) -DWINDRES_PREPROC -i $< -o $@
+
+.mm.o:
+ $(AM_V_CXX) $(OBJCXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CXXFLAGS) $(QT_INCLUDES) $(CXXFLAGS) -c -o $@ $<
+
+%.pb.cc %.pb.h: %.proto
+ @test -f $(PROTOC)
+ $(AM_V_GEN) $(PROTOC) --cpp_out=$(@D) --proto_path=$(abspath $(<D) $<)
+
+if ENABLE_TESTS
+include Makefile.test.include
+endif
+
+if ENABLE_QT
+include Makefile.qt.include
+endif
+
+if ENABLE_QT_TESTS
+include Makefile.qttest.include
+endif
diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include
new file mode 100644
index 0000000000..2ec3468e06
--- /dev/null
+++ b/src/Makefile.qt.include
@@ -0,0 +1,418 @@
+bin_PROGRAMS += qt/bitcoin-qt
+EXTRA_LIBRARIES += qt/libbitcoinqt.a
+
+# bitcoin qt core #
+QT_TS = \
+ qt/locale/bitcoin_ach.ts \
+ qt/locale/bitcoin_af_ZA.ts \
+ qt/locale/bitcoin_ar.ts \
+ qt/locale/bitcoin_be_BY.ts \
+ qt/locale/bitcoin_bg.ts \
+ qt/locale/bitcoin_bs.ts \
+ qt/locale/bitcoin_ca_ES.ts \
+ qt/locale/bitcoin_ca.ts \
+ qt/locale/bitcoin_ca@valencia.ts \
+ qt/locale/bitcoin_cmn.ts \
+ qt/locale/bitcoin_cs.ts \
+ qt/locale/bitcoin_cy.ts \
+ qt/locale/bitcoin_da.ts \
+ qt/locale/bitcoin_de.ts \
+ qt/locale/bitcoin_el_GR.ts \
+ qt/locale/bitcoin_en.ts \
+ qt/locale/bitcoin_eo.ts \
+ qt/locale/bitcoin_es_CL.ts \
+ qt/locale/bitcoin_es_DO.ts \
+ qt/locale/bitcoin_es_MX.ts \
+ qt/locale/bitcoin_es.ts \
+ qt/locale/bitcoin_es_UY.ts \
+ qt/locale/bitcoin_et.ts \
+ qt/locale/bitcoin_eu_ES.ts \
+ qt/locale/bitcoin_fa_IR.ts \
+ qt/locale/bitcoin_fa.ts \
+ qt/locale/bitcoin_fi.ts \
+ qt/locale/bitcoin_fr_CA.ts \
+ qt/locale/bitcoin_fr.ts \
+ qt/locale/bitcoin_gl.ts \
+ qt/locale/bitcoin_gu_IN.ts \
+ qt/locale/bitcoin_he.ts \
+ qt/locale/bitcoin_hi_IN.ts \
+ qt/locale/bitcoin_hr.ts \
+ qt/locale/bitcoin_hu.ts \
+ qt/locale/bitcoin_id_ID.ts \
+ qt/locale/bitcoin_it.ts \
+ qt/locale/bitcoin_ja.ts \
+ qt/locale/bitcoin_ka.ts \
+ qt/locale/bitcoin_kk_KZ.ts \
+ qt/locale/bitcoin_ko_KR.ts \
+ qt/locale/bitcoin_ky.ts \
+ qt/locale/bitcoin_la.ts \
+ qt/locale/bitcoin_lt.ts \
+ qt/locale/bitcoin_lv_LV.ts \
+ qt/locale/bitcoin_mn.ts \
+ qt/locale/bitcoin_ms_MY.ts \
+ qt/locale/bitcoin_nb.ts \
+ qt/locale/bitcoin_nl.ts \
+ qt/locale/bitcoin_pam.ts \
+ qt/locale/bitcoin_pl.ts \
+ qt/locale/bitcoin_pt_BR.ts \
+ qt/locale/bitcoin_pt_PT.ts \
+ qt/locale/bitcoin_ro_RO.ts \
+ qt/locale/bitcoin_ru.ts \
+ qt/locale/bitcoin_sah.ts \
+ qt/locale/bitcoin_sk.ts \
+ qt/locale/bitcoin_sl_SI.ts \
+ qt/locale/bitcoin_sq.ts \
+ qt/locale/bitcoin_sr.ts \
+ qt/locale/bitcoin_sv.ts \
+ qt/locale/bitcoin_th_TH.ts \
+ qt/locale/bitcoin_tr.ts \
+ qt/locale/bitcoin_uk.ts \
+ qt/locale/bitcoin_ur_PK.ts \
+ qt/locale/bitcoin_uz@Cyrl.ts \
+ qt/locale/bitcoin_vi.ts \
+ qt/locale/bitcoin_vi_VN.ts \
+ qt/locale/bitcoin_zh_CN.ts \
+ qt/locale/bitcoin_zh_HK.ts \
+ qt/locale/bitcoin_zh_TW.ts
+
+QT_FORMS_UI = \
+ qt/forms/addressbookpage.ui \
+ qt/forms/askpassphrasedialog.ui \
+ qt/forms/coincontroldialog.ui \
+ qt/forms/editaddressdialog.ui \
+ qt/forms/helpmessagedialog.ui \
+ qt/forms/intro.ui \
+ qt/forms/openuridialog.ui \
+ qt/forms/optionsdialog.ui \
+ qt/forms/overviewpage.ui \
+ qt/forms/receivecoinsdialog.ui \
+ qt/forms/receiverequestdialog.ui \
+ qt/forms/rpcconsole.ui \
+ qt/forms/sendcoinsdialog.ui \
+ qt/forms/sendcoinsentry.ui \
+ qt/forms/signverifymessagedialog.ui \
+ qt/forms/transactiondescdialog.ui
+
+QT_MOC_CPP = \
+ qt/moc_addressbookpage.cpp \
+ qt/moc_addresstablemodel.cpp \
+ qt/moc_askpassphrasedialog.cpp \
+ qt/moc_bitcoinaddressvalidator.cpp \
+ qt/moc_bitcoinamountfield.cpp \
+ qt/moc_bitcoingui.cpp \
+ qt/moc_bitcoinunits.cpp \
+ qt/moc_clientmodel.cpp \
+ qt/moc_coincontroldialog.cpp \
+ qt/moc_coincontroltreewidget.cpp \
+ qt/moc_csvmodelwriter.cpp \
+ qt/moc_editaddressdialog.cpp \
+ qt/moc_guiutil.cpp \
+ qt/moc_intro.cpp \
+ qt/moc_macdockiconhandler.cpp \
+ qt/moc_macnotificationhandler.cpp \
+ qt/moc_notificator.cpp \
+ qt/moc_openuridialog.cpp \
+ qt/moc_optionsdialog.cpp \
+ qt/moc_optionsmodel.cpp \
+ qt/moc_overviewpage.cpp \
+ qt/moc_peertablemodel.cpp \
+ qt/moc_paymentserver.cpp \
+ qt/moc_qvalidatedlineedit.cpp \
+ qt/moc_qvaluecombobox.cpp \
+ qt/moc_receivecoinsdialog.cpp \
+ qt/moc_receiverequestdialog.cpp \
+ qt/moc_recentrequeststablemodel.cpp \
+ qt/moc_rpcconsole.cpp \
+ qt/moc_sendcoinsdialog.cpp \
+ qt/moc_sendcoinsentry.cpp \
+ qt/moc_signverifymessagedialog.cpp \
+ qt/moc_splashscreen.cpp \
+ qt/moc_trafficgraphwidget.cpp \
+ qt/moc_transactiondesc.cpp \
+ qt/moc_transactiondescdialog.cpp \
+ qt/moc_transactionfilterproxy.cpp \
+ qt/moc_transactiontablemodel.cpp \
+ qt/moc_transactionview.cpp \
+ qt/moc_utilitydialog.cpp \
+ qt/moc_walletframe.cpp \
+ qt/moc_walletmodel.cpp \
+ qt/moc_walletview.cpp
+
+BITCOIN_MM = \
+ qt/macdockiconhandler.mm \
+ qt/macnotificationhandler.mm
+
+QT_MOC = \
+ qt/bitcoin.moc \
+ qt/bitcoinamountfield.moc \
+ qt/intro.moc \
+ qt/overviewpage.moc \
+ qt/rpcconsole.moc
+
+QT_QRC_CPP = qt/qrc_bitcoin.cpp
+QT_QRC = qt/bitcoin.qrc
+QT_QRC_LOCALE_CPP = qt/qrc_bitcoin_locale.cpp
+QT_QRC_LOCALE = qt/bitcoin_locale.qrc
+
+PROTOBUF_CC = qt/paymentrequest.pb.cc
+PROTOBUF_H = qt/paymentrequest.pb.h
+PROTOBUF_PROTO = qt/paymentrequest.proto
+
+BITCOIN_QT_H = \
+ qt/addressbookpage.h \
+ qt/addresstablemodel.h \
+ qt/askpassphrasedialog.h \
+ qt/bitcoinaddressvalidator.h \
+ qt/bitcoinamountfield.h \
+ qt/bitcoingui.h \
+ qt/bitcoinunits.h \
+ qt/clientmodel.h \
+ qt/coincontroldialog.h \
+ qt/coincontroltreewidget.h \
+ qt/csvmodelwriter.h \
+ qt/editaddressdialog.h \
+ qt/guiconstants.h \
+ qt/guiutil.h \
+ qt/intro.h \
+ qt/macdockiconhandler.h \
+ qt/macnotificationhandler.h \
+ qt/networkstyle.h \
+ qt/notificator.h \
+ qt/openuridialog.h \
+ qt/optionsdialog.h \
+ qt/optionsmodel.h \
+ qt/overviewpage.h \
+ qt/paymentrequestplus.h \
+ qt/paymentserver.h \
+ qt/peertablemodel.h \
+ qt/qvalidatedlineedit.h \
+ qt/qvaluecombobox.h \
+ qt/receivecoinsdialog.h \
+ qt/receiverequestdialog.h \
+ qt/recentrequeststablemodel.h \
+ qt/rpcconsole.h \
+ qt/scicon.h \
+ qt/sendcoinsdialog.h \
+ qt/sendcoinsentry.h \
+ qt/signverifymessagedialog.h \
+ qt/splashscreen.h \
+ qt/trafficgraphwidget.h \
+ qt/transactiondesc.h \
+ qt/transactiondescdialog.h \
+ qt/transactionfilterproxy.h \
+ qt/transactionrecord.h \
+ qt/transactiontablemodel.h \
+ qt/transactionview.h \
+ qt/utilitydialog.h \
+ qt/walletframe.h \
+ qt/walletmodel.h \
+ qt/walletmodeltransaction.h \
+ qt/walletview.h \
+ qt/winshutdownmonitor.h
+
+RES_ICONS = \
+ qt/res/icons/add.png \
+ qt/res/icons/address-book.png \
+ qt/res/icons/about.png \
+ qt/res/icons/about_qt.png \
+ qt/res/icons/bitcoin.ico \
+ qt/res/icons/bitcoin.png \
+ qt/res/icons/clock1.png \
+ qt/res/icons/clock2.png \
+ qt/res/icons/clock3.png \
+ qt/res/icons/clock4.png \
+ qt/res/icons/clock5.png \
+ qt/res/icons/configure.png \
+ qt/res/icons/connect0.png \
+ qt/res/icons/connect1.png \
+ qt/res/icons/connect2.png \
+ qt/res/icons/connect3.png \
+ qt/res/icons/connect4.png \
+ qt/res/icons/debugwindow.png \
+ qt/res/icons/edit.png \
+ qt/res/icons/editcopy.png \
+ qt/res/icons/editpaste.png \
+ qt/res/icons/export.png \
+ qt/res/icons/eye.png \
+ qt/res/icons/eye_minus.png \
+ qt/res/icons/eye_plus.png \
+ qt/res/icons/filesave.png \
+ qt/res/icons/history.png \
+ qt/res/icons/info.png \
+ qt/res/icons/key.png \
+ qt/res/icons/lock_closed.png \
+ qt/res/icons/lock_open.png \
+ qt/res/icons/open.png \
+ qt/res/icons/overview.png \
+ qt/res/icons/quit.png \
+ qt/res/icons/receive.png \
+ qt/res/icons/remove.png \
+ qt/res/icons/send.png \
+ qt/res/icons/synced.png \
+ qt/res/icons/transaction0.png \
+ qt/res/icons/transaction2.png \
+ qt/res/icons/transaction_conflicted.png \
+ qt/res/icons/tx_inout.png \
+ qt/res/icons/tx_input.png \
+ qt/res/icons/tx_output.png \
+ qt/res/icons/tx_mined.png \
+ qt/res/icons/warning.png \
+ qt/res/icons/verify.png
+
+BITCOIN_QT_CPP = \
+ qt/bitcoinaddressvalidator.cpp \
+ qt/bitcoinamountfield.cpp \
+ qt/bitcoingui.cpp \
+ qt/bitcoinunits.cpp \
+ qt/clientmodel.cpp \
+ qt/csvmodelwriter.cpp \
+ qt/guiutil.cpp \
+ qt/intro.cpp \
+ qt/networkstyle.cpp \
+ qt/notificator.cpp \
+ qt/optionsdialog.cpp \
+ qt/optionsmodel.cpp \
+ qt/peertablemodel.cpp \
+ qt/qvalidatedlineedit.cpp \
+ qt/qvaluecombobox.cpp \
+ qt/rpcconsole.cpp \
+ qt/scicon.cpp \
+ qt/splashscreen.cpp \
+ qt/trafficgraphwidget.cpp \
+ qt/utilitydialog.cpp
+
+if TARGET_WINDOWS
+BITCOIN_QT_CPP += qt/winshutdownmonitor.cpp
+endif
+
+if ENABLE_WALLET
+BITCOIN_QT_CPP += \
+ qt/addressbookpage.cpp \
+ qt/addresstablemodel.cpp \
+ qt/askpassphrasedialog.cpp \
+ qt/coincontroldialog.cpp \
+ qt/coincontroltreewidget.cpp \
+ qt/editaddressdialog.cpp \
+ qt/openuridialog.cpp \
+ qt/overviewpage.cpp \
+ qt/paymentrequestplus.cpp \
+ qt/paymentserver.cpp \
+ qt/receivecoinsdialog.cpp \
+ qt/receiverequestdialog.cpp \
+ qt/recentrequeststablemodel.cpp \
+ qt/sendcoinsdialog.cpp \
+ qt/sendcoinsentry.cpp \
+ qt/signverifymessagedialog.cpp \
+ qt/transactiondesc.cpp \
+ qt/transactiondescdialog.cpp \
+ qt/transactionfilterproxy.cpp \
+ qt/transactionrecord.cpp \
+ qt/transactiontablemodel.cpp \
+ qt/transactionview.cpp \
+ qt/walletframe.cpp \
+ qt/walletmodel.cpp \
+ qt/walletmodeltransaction.cpp \
+ qt/walletview.cpp
+endif
+
+RES_IMAGES =
+
+RES_MOVIES = $(wildcard qt/res/movies/spinner-*.png)
+
+BITCOIN_RC = qt/res/bitcoin-qt-res.rc
+
+BITCOIN_QT_INCLUDES = -I$(builddir)/qt -I$(srcdir)/qt -I$(srcdir)/qt/forms \
+ -I$(builddir)/qt/forms -DQT_NO_KEYWORDS
+
+qt_libbitcoinqt_a_CPPFLAGS = $(BITCOIN_INCLUDES) $(BITCOIN_QT_INCLUDES) \
+ $(QT_INCLUDES) $(QT_DBUS_INCLUDES) $(PROTOBUF_CFLAGS) $(QR_CFLAGS)
+
+qt_libbitcoinqt_a_SOURCES = $(BITCOIN_QT_CPP) $(BITCOIN_QT_H) $(QT_FORMS_UI) \
+ $(QT_QRC) $(QT_QRC_LOCALE) $(QT_TS) $(PROTOBUF_PROTO) $(RES_ICONS) $(RES_IMAGES) $(RES_MOVIES)
+
+nodist_qt_libbitcoinqt_a_SOURCES = $(QT_MOC_CPP) $(QT_MOC) $(PROTOBUF_CC) \
+ $(PROTOBUF_H) $(QT_QRC_CPP) $(QT_QRC_LOCALE_CPP)
+
+# forms/foo.h -> forms/ui_foo.h
+QT_FORMS_H=$(join $(dir $(QT_FORMS_UI)),$(addprefix ui_, $(notdir $(QT_FORMS_UI:.ui=.h))))
+
+# Most files will depend on the forms and moc files as includes. Generate them
+# before anything else.
+$(QT_MOC): $(QT_FORMS_H)
+$(qt_libbitcoinqt_a_OBJECTS) $(qt_bitcoin_qt_OBJECTS) : | $(QT_MOC)
+
+#Generating these with a half-written protobuf header leads to wacky results.
+#This makes sure it's done.
+$(QT_MOC): $(PROTOBUF_H)
+$(QT_MOC_CPP): $(PROTOBUF_H)
+
+# bitcoin-qt binary #
+qt_bitcoin_qt_CPPFLAGS = $(BITCOIN_INCLUDES) $(BITCOIN_QT_INCLUDES) \
+ $(QT_INCLUDES) $(PROTOBUF_CFLAGS) $(QR_CFLAGS)
+
+qt_bitcoin_qt_SOURCES = qt/bitcoin.cpp
+if TARGET_DARWIN
+ qt_bitcoin_qt_SOURCES += $(BITCOIN_MM)
+endif
+if TARGET_WINDOWS
+ qt_bitcoin_qt_SOURCES += $(BITCOIN_RC)
+endif
+qt_bitcoin_qt_LDADD = qt/libbitcoinqt.a $(LIBBITCOIN_SERVER)
+if ENABLE_WALLET
+qt_bitcoin_qt_LDADD += $(LIBBITCOIN_WALLET)
+endif
+qt_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBBITCOIN_UNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) \
+ $(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1)
+qt_bitcoin_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
+qt_bitcoin_qt_LIBTOOLFLAGS = --tag CXX
+
+#locale/foo.ts -> locale/foo.qm
+QT_QM=$(QT_TS:.ts=.qm)
+
+SECONDARY: $(QT_QM)
+
+qt/bitcoinstrings.cpp: $(libbitcoin_server_a_SOURCES) $(libbitcoin_wallet_a_SOURCES)
+ @test -n $(XGETTEXT) || echo "xgettext is required for updating translations"
+ $(AM_V_GEN) cd $(srcdir); XGETTEXT=$(XGETTEXT) ../share/qt/extract_strings_qt.py $^
+
+translate: qt/bitcoinstrings.cpp $(QT_FORMS_UI) $(QT_FORMS_UI) $(BITCOIN_QT_CPP) $(BITCOIN_QT_H) $(BITCOIN_MM)
+ @test -n $(LUPDATE) || echo "lupdate is required for updating translations"
+ $(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(LUPDATE) $^ -locations relative -no-obsolete -ts qt/locale/bitcoin_en.ts
+
+$(QT_QRC_LOCALE_CPP): $(QT_QRC_LOCALE) $(QT_QM)
+ @test -f $(RCC)
+ @test -f $(@D)/$(<F) || cp -f $< $(@D)
+ $(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(RCC) -name bitcoin_locale $(@D)/$(<F) | \
+ $(SED) -e '/^\*\*.*Created:/d' -e '/^\*\*.*by:/d' > $@
+
+$(QT_QRC_CPP): $(QT_QRC) $(QT_FORMS_H) $(RES_ICONS) $(RES_IMAGES) $(RES_MOVIES) $(PROTOBUF_H)
+ @test -f $(RCC)
+ $(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(RCC) -name bitcoin $< | \
+ $(SED) -e '/^\*\*.*Created:/d' -e '/^\*\*.*by:/d' > $@
+
+CLEAN_QT = $(nodist_qt_libbitcoinqt_a_SOURCES) $(QT_QM) $(QT_FORMS_H) qt/*.gcda qt/*.gcno
+
+CLEANFILES += $(CLEAN_QT)
+
+bitcoin_qt_clean: FORCE
+ rm -f $(CLEAN_QT) $(qt_libbitcoinqt_a_OBJECTS) $(qt_bitcoin_qt_OBJECTS) qt/bitcoin-qt$(EXEEXT) $(LIBBITCOINQT)
+
+bitcoin_qt : qt/bitcoin-qt$(EXEEXT)
+
+ui_%.h: %.ui
+ @test -f $(UIC)
+ @$(MKDIR_P) $(@D)
+ $(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(UIC) -o $@ $< || (echo "Error creating $@"; false)
+
+%.moc: %.cpp
+ $(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(MOC) $(QT_INCLUDES) $(MOC_DEFS) $< | \
+ $(SED) -e '/^\*\*.*Created:/d' -e '/^\*\*.*by:/d' > $@
+
+moc_%.cpp: %.h
+ $(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(MOC) $(QT_INCLUDES) $(MOC_DEFS) $< | \
+ $(SED) -e '/^\*\*.*Created:/d' -e '/^\*\*.*by:/d' > $@
+
+%.qm: %.ts
+ @test -f $(LRELEASE)
+ @$(MKDIR_P) $(@D)
+ $(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(LRELEASE) -silent $< -qm $@
diff --git a/src/Makefile.qttest.include b/src/Makefile.qttest.include
new file mode 100644
index 0000000000..c5392cf307
--- /dev/null
+++ b/src/Makefile.qttest.include
@@ -0,0 +1,48 @@
+bin_PROGRAMS += qt/test/test_bitcoin-qt
+TESTS += qt/test/test_bitcoin-qt
+
+TEST_QT_MOC_CPP = qt/test/moc_uritests.cpp
+
+if ENABLE_WALLET
+TEST_QT_MOC_CPP += qt/test/moc_paymentservertests.cpp
+endif
+
+TEST_QT_H = \
+ qt/test/uritests.h \
+ qt/test/paymentrequestdata.h \
+ qt/test/paymentservertests.h
+
+qt_test_test_bitcoin_qt_CPPFLAGS = $(BITCOIN_INCLUDES) $(BITCOIN_QT_INCLUDES) \
+ $(QT_INCLUDES) $(QT_TEST_INCLUDES) $(PROTOBUF_CFLAGS)
+
+qt_test_test_bitcoin_qt_SOURCES = \
+ qt/test/test_main.cpp \
+ qt/test/uritests.cpp \
+ $(TEST_QT_H)
+if ENABLE_WALLET
+qt_test_test_bitcoin_qt_SOURCES += \
+ qt/test/paymentservertests.cpp
+endif
+
+nodist_qt_test_test_bitcoin_qt_SOURCES = $(TEST_QT_MOC_CPP)
+
+qt_test_test_bitcoin_qt_LDADD = $(LIBBITCOINQT) $(LIBBITCOIN_SERVER)
+if ENABLE_WALLET
+qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_WALLET)
+endif
+qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBBITCOIN_UNIVALUE) $(LIBLEVELDB) \
+ $(LIBMEMENV) $(BOOST_LIBS) $(QT_DBUS_LIBS) $(QT_TEST_LIBS) $(QT_LIBS) \
+ $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1)
+qt_test_test_bitcoin_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
+
+CLEAN_BITCOIN_QT_TEST = $(TEST_QT_MOC_CPP) qt/test/*.gcda qt/test/*.gcno
+
+CLEANFILES += $(CLEAN_BITCOIN_QT_TEST)
+
+test_bitcoin_qt : qt/test/test_bitcoin-qt$(EXEEXT)
+
+test_bitcoin_qt_check : qt/test/test_bitcoin-qt$(EXEEXT) FORCE
+ $(MAKE) check-TESTS TESTS=$^
+
+test_bitcoin_qt_clean: FORCE
+ rm -f $(CLEAN_BITCOIN_QT_TEST) $(qt_test_test_bitcoin_qt_OBJECTS)
diff --git a/src/Makefile.test.include b/src/Makefile.test.include
new file mode 100644
index 0000000000..386911514e
--- /dev/null
+++ b/src/Makefile.test.include
@@ -0,0 +1,134 @@
+TESTS += test/test_bitcoin
+bin_PROGRAMS += test/test_bitcoin
+TEST_SRCDIR = test
+TEST_BINARY=test/test_bitcoin$(EXEEXT)
+
+
+EXTRA_DIST += \
+ test/bctest.py \
+ test/bitcoin-util-test.py \
+ test/data/bitcoin-util-test.json \
+ test/data/blanktx.hex \
+ test/data/tt-delin1-out.hex \
+ test/data/tt-delout1-out.hex \
+ test/data/tt-locktime317000-out.hex \
+ test/data/tx394b54bb.hex \
+ test/data/txcreate1.hex \
+ test/data/txcreate2.hex \
+ test/data/txcreatesign.hex
+
+JSON_TEST_FILES = \
+ test/data/script_valid.json \
+ test/data/base58_keys_valid.json \
+ test/data/base58_encode_decode.json \
+ test/data/base58_keys_invalid.json \
+ test/data/script_invalid.json \
+ test/data/tx_invalid.json \
+ test/data/tx_valid.json \
+ test/data/sighash.json
+
+RAW_TEST_FILES = test/data/alertTests.raw
+
+GENERATED_TEST_FILES = $(JSON_TEST_FILES:.json=.json.h) $(RAW_TEST_FILES:.raw=.raw.h)
+
+BITCOIN_TESTS =\
+ test/arith_uint256_tests.cpp \
+ test/bignum.h \
+ test/alert_tests.cpp \
+ test/allocator_tests.cpp \
+ test/base32_tests.cpp \
+ test/base58_tests.cpp \
+ test/base64_tests.cpp \
+ test/bip32_tests.cpp \
+ test/bloom_tests.cpp \
+ test/checkblock_tests.cpp \
+ test/Checkpoints_tests.cpp \
+ test/coins_tests.cpp \
+ test/compress_tests.cpp \
+ test/crypto_tests.cpp \
+ test/DoS_tests.cpp \
+ test/getarg_tests.cpp \
+ test/hash_tests.cpp \
+ test/key_tests.cpp \
+ test/main_tests.cpp \
+ test/mempool_tests.cpp \
+ test/miner_tests.cpp \
+ test/mruset_tests.cpp \
+ test/multisig_tests.cpp \
+ test/netbase_tests.cpp \
+ test/pmt_tests.cpp \
+ test/policyestimator_tests.cpp \
+ test/pow_tests.cpp \
+ test/reverselock_tests.cpp \
+ test/rpc_tests.cpp \
+ test/sanity_tests.cpp \
+ test/scheduler_tests.cpp \
+ test/script_P2SH_tests.cpp \
+ test/script_tests.cpp \
+ test/scriptnum_tests.cpp \
+ test/serialize_tests.cpp \
+ test/sighash_tests.cpp \
+ test/sigopcount_tests.cpp \
+ test/skiplist_tests.cpp \
+ test/test_bitcoin.cpp \
+ test/test_bitcoin.h \
+ test/timedata_tests.cpp \
+ test/transaction_tests.cpp \
+ test/uint256_tests.cpp \
+ test/univalue_tests.cpp \
+ test/util_tests.cpp
+
+if ENABLE_WALLET
+BITCOIN_TESTS += \
+ test/accounting_tests.cpp \
+ wallet/test/wallet_tests.cpp \
+ test/rpc_wallet_tests.cpp
+endif
+
+test_test_bitcoin_SOURCES = $(BITCOIN_TESTS) $(JSON_TEST_FILES) $(RAW_TEST_FILES)
+test_test_bitcoin_CPPFLAGS = $(BITCOIN_INCLUDES) -I$(builddir)/test/ $(TESTDEFS)
+test_test_bitcoin_LDADD = $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBBITCOIN_UNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) \
+ $(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(LIBSECP256K1)
+if ENABLE_WALLET
+test_test_bitcoin_LDADD += $(LIBBITCOIN_WALLET)
+endif
+
+test_test_bitcoin_LDADD += $(LIBBITCOIN_CONSENSUS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS)
+test_test_bitcoin_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) -static
+
+nodist_test_test_bitcoin_SOURCES = $(GENERATED_TEST_FILES)
+
+$(BITCOIN_TESTS): $(GENERATED_TEST_FILES)
+
+CLEAN_BITCOIN_TEST = test/*.gcda test/*.gcno $(GENERATED_TEST_FILES)
+
+CLEANFILES += $(CLEAN_BITCOIN_TEST)
+
+bitcoin_test: $(TEST_BINARY)
+
+bitcoin_test_check: $(TEST_BINARY) FORCE
+ $(MAKE) check-TESTS TESTS=$^
+
+bitcoin_test_clean : FORCE
+ rm -f $(CLEAN_BITCOIN_TEST) $(test_test_bitcoin_OBJECTS) $(TEST_BINARY)
+
+check-local:
+ @echo "Running test/bitcoin-util-test.py..."
+ $(AM_V_at)srcdir=$(srcdir) PYTHONPATH=$(builddir)/test $(srcdir)/test/bitcoin-util-test.py
+ $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C secp256k1 check
+
+%.json.h: %.json
+ @$(MKDIR_P) $(@D)
+ @echo "namespace json_tests{" > $@
+ @echo "static unsigned const char $(*F)[] = {" >> $@
+ @$(HEXDUMP) -v -e '8/1 "0x%02x, "' -e '"\n"' $< | $(SED) -e 's/0x ,//g' >> $@
+ @echo "};};" >> $@
+ @echo "Generated $@"
+
+%.raw.h: %.raw
+ @$(MKDIR_P) $(@D)
+ @echo "namespace alert_tests{" > $@
+ @echo "static unsigned const char $(*F)[] = {" >> $@
+ @$(HEXDUMP) -v -e '8/1 "0x%02x, "' -e '"\n"' $< | $(SED) -e 's/0x ,//g' >> $@
+ @echo "};};" >> $@
+ @echo "Generated $@"
diff --git a/src/addrman.cpp b/src/addrman.cpp
new file mode 100644
index 0000000000..c41ee3f9fc
--- /dev/null
+++ b/src/addrman.cpp
@@ -0,0 +1,490 @@
+// Copyright (c) 2012 Pieter Wuille
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "addrman.h"
+
+#include "hash.h"
+#include "serialize.h"
+#include "streams.h"
+
+using namespace std;
+
+int CAddrInfo::GetTriedBucket(const uint256& nKey) const
+{
+ uint64_t hash1 = (CHashWriter(SER_GETHASH, 0) << nKey << GetKey()).GetHash().GetCheapHash();
+ uint64_t hash2 = (CHashWriter(SER_GETHASH, 0) << nKey << GetGroup() << (hash1 % ADDRMAN_TRIED_BUCKETS_PER_GROUP)).GetHash().GetCheapHash();
+ return hash2 % ADDRMAN_TRIED_BUCKET_COUNT;
+}
+
+int CAddrInfo::GetNewBucket(const uint256& nKey, const CNetAddr& src) const
+{
+ std::vector<unsigned char> vchSourceGroupKey = src.GetGroup();
+ uint64_t hash1 = (CHashWriter(SER_GETHASH, 0) << nKey << GetGroup() << vchSourceGroupKey).GetHash().GetCheapHash();
+ uint64_t hash2 = (CHashWriter(SER_GETHASH, 0) << nKey << vchSourceGroupKey << (hash1 % ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP)).GetHash().GetCheapHash();
+ return hash2 % ADDRMAN_NEW_BUCKET_COUNT;
+}
+
+int CAddrInfo::GetBucketPosition(const uint256 &nKey, bool fNew, int nBucket) const
+{
+ uint64_t hash1 = (CHashWriter(SER_GETHASH, 0) << nKey << (fNew ? 'N' : 'K') << nBucket << GetKey()).GetHash().GetCheapHash();
+ return hash1 % ADDRMAN_BUCKET_SIZE;
+}
+
+bool CAddrInfo::IsTerrible(int64_t nNow) const
+{
+ if (nLastTry && nLastTry >= nNow - 60) // never remove things tried in 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 * 24 * 60 * 60) // not seen in recent history
+ return true;
+
+ if (nLastSuccess == 0 && nAttempts >= ADDRMAN_RETRIES) // tried N times and never a success
+ return true;
+
+ if (nNow - nLastSuccess > ADDRMAN_MIN_FAIL_DAYS * 24 * 60 * 60 && nAttempts >= ADDRMAN_MAX_FAILURES) // N successive failures in the last week
+ return true;
+
+ return false;
+}
+
+double CAddrInfo::GetChance(int64_t nNow) const
+{
+ double fChance = 1.0;
+
+ int64_t nSinceLastSeen = nNow - nTime;
+ int64_t nSinceLastTry = nNow - nLastTry;
+
+ if (nSinceLastSeen < 0)
+ nSinceLastSeen = 0;
+ if (nSinceLastTry < 0)
+ nSinceLastTry = 0;
+
+ // deprioritize very recent attempts away
+ if (nSinceLastTry < 60 * 10)
+ fChance *= 0.01;
+
+ // deprioritize 66% after each failed attempt, but at most 1/28th to avoid the search taking forever or overly penalizing outages.
+ fChance *= pow(0.66, min(nAttempts, 8));
+
+ return fChance;
+}
+
+CAddrInfo* CAddrMan::Find(const CNetAddr& addr, int* pnId)
+{
+ std::map<CNetAddr, int>::iterator it = mapAddr.find(addr);
+ if (it == mapAddr.end())
+ return NULL;
+ if (pnId)
+ *pnId = (*it).second;
+ std::map<int, CAddrInfo>::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;
+}
+
+void CAddrMan::Delete(int nId)
+{
+ assert(mapInfo.count(nId) != 0);
+ CAddrInfo& info = mapInfo[nId];
+ assert(!info.fInTried);
+ assert(info.nRefCount == 0);
+
+ SwapRandom(info.nRandomPos, vRandom.size() - 1);
+ vRandom.pop_back();
+ mapAddr.erase(info);
+ mapInfo.erase(nId);
+ nNew--;
+}
+
+void CAddrMan::ClearNew(int nUBucket, int nUBucketPos)
+{
+ // if there is an entry in the specified bucket, delete it.
+ if (vvNew[nUBucket][nUBucketPos] != -1) {
+ int nIdDelete = vvNew[nUBucket][nUBucketPos];
+ CAddrInfo& infoDelete = mapInfo[nIdDelete];
+ assert(infoDelete.nRefCount > 0);
+ infoDelete.nRefCount--;
+ vvNew[nUBucket][nUBucketPos] = -1;
+ if (infoDelete.nRefCount == 0) {
+ Delete(nIdDelete);
+ }
+ }
+}
+
+void CAddrMan::MakeTried(CAddrInfo& info, int nId)
+{
+ // remove the entry from all new buckets
+ for (int bucket = 0; bucket < ADDRMAN_NEW_BUCKET_COUNT; bucket++) {
+ int pos = info.GetBucketPosition(nKey, true, bucket);
+ if (vvNew[bucket][pos] == nId) {
+ vvNew[bucket][pos] = -1;
+ info.nRefCount--;
+ }
+ }
+ nNew--;
+
+ assert(info.nRefCount == 0);
+
+ // which tried bucket to move the entry to
+ int nKBucket = info.GetTriedBucket(nKey);
+ int nKBucketPos = info.GetBucketPosition(nKey, false, nKBucket);
+
+ // first make space to add it (the existing tried entry there is moved to new, deleting whatever is there).
+ if (vvTried[nKBucket][nKBucketPos] != -1) {
+ // find an item to evict
+ int nIdEvict = vvTried[nKBucket][nKBucketPos];
+ assert(mapInfo.count(nIdEvict) == 1);
+ CAddrInfo& infoOld = mapInfo[nIdEvict];
+
+ // Remove the to-be-evicted item from the tried set.
+ infoOld.fInTried = false;
+ vvTried[nKBucket][nKBucketPos] = -1;
+ nTried--;
+
+ // find which new bucket it belongs to
+ int nUBucket = infoOld.GetNewBucket(nKey);
+ int nUBucketPos = infoOld.GetBucketPosition(nKey, true, nUBucket);
+ ClearNew(nUBucket, nUBucketPos);
+ assert(vvNew[nUBucket][nUBucketPos] == -1);
+
+ // Enter it into the new set again.
+ infoOld.nRefCount = 1;
+ vvNew[nUBucket][nUBucketPos] = nIdEvict;
+ nNew++;
+ }
+ assert(vvTried[nKBucket][nKBucketPos] == -1);
+
+ vvTried[nKBucket][nKBucketPos] = nId;
+ nTried++;
+ info.fInTried = true;
+}
+
+void CAddrMan::Good_(const CService& addr, int64_t nTime)
+{
+ 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.nAttempts = 0;
+ // nTime is not updated here, to avoid leaking information about
+ // currently-connected peers.
+
+ // 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(ADDRMAN_NEW_BUCKET_COUNT);
+ int nUBucket = -1;
+ for (unsigned int n = 0; n < ADDRMAN_NEW_BUCKET_COUNT; n++) {
+ int nB = (n + nRnd) % ADDRMAN_NEW_BUCKET_COUNT;
+ int nBpos = info.GetBucketPosition(nKey, true, nB);
+ if (vvNew[nB][nBpos] == 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;
+
+ LogPrint("addrman", "Moving %s to tried\n", addr.ToString());
+
+ // move nId to the tried tables
+ MakeTried(info, nId);
+}
+
+bool CAddrMan::Add_(const CAddress& addr, const CNetAddr& source, int64_t 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_t nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60);
+ if (addr.nTime && (!pinfo->nTime || pinfo->nTime < addr.nTime - nUpdateInterval - nTimePenalty))
+ pinfo->nTime = max((int64_t)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; n < pinfo->nRefCount; n++)
+ nFactor *= 2;
+ if (nFactor > 1 && (GetRandInt(nFactor) != 0))
+ return false;
+ } else {
+ pinfo = Create(addr, source, &nId);
+ pinfo->nTime = max((int64_t)0, (int64_t)pinfo->nTime - nTimePenalty);
+ nNew++;
+ fNew = true;
+ }
+
+ int nUBucket = pinfo->GetNewBucket(nKey, source);
+ int nUBucketPos = pinfo->GetBucketPosition(nKey, true, nUBucket);
+ if (vvNew[nUBucket][nUBucketPos] != nId) {
+ bool fInsert = vvNew[nUBucket][nUBucketPos] == -1;
+ if (!fInsert) {
+ CAddrInfo& infoExisting = mapInfo[vvNew[nUBucket][nUBucketPos]];
+ if (infoExisting.IsTerrible() || (infoExisting.nRefCount > 1 && pinfo->nRefCount == 0)) {
+ // Overwrite the existing new table entry.
+ fInsert = true;
+ }
+ }
+ if (fInsert) {
+ ClearNew(nUBucket, nUBucketPos);
+ pinfo->nRefCount++;
+ vvNew[nUBucket][nUBucketPos] = nId;
+ } else {
+ if (pinfo->nRefCount == 0) {
+ Delete(nId);
+ }
+ }
+ }
+ return fNew;
+}
+
+void CAddrMan::Attempt_(const CService& addr, int64_t 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++;
+}
+
+CAddrInfo CAddrMan::Select_()
+{
+ if (size() == 0)
+ return CAddrInfo();
+
+ // Use a 50% chance for choosing between tried and new table entries.
+ if (nTried > 0 && (nNew == 0 || GetRandInt(2) == 0)) {
+ // use a tried node
+ double fChanceFactor = 1.0;
+ while (1) {
+ int nKBucket = GetRandInt(ADDRMAN_TRIED_BUCKET_COUNT);
+ int nKBucketPos = GetRandInt(ADDRMAN_BUCKET_SIZE);
+ if (vvTried[nKBucket][nKBucketPos] == -1)
+ continue;
+ int nId = vvTried[nKBucket][nKBucketPos];
+ assert(mapInfo.count(nId) == 1);
+ CAddrInfo& info = mapInfo[nId];
+ if (GetRandInt(1 << 30) < fChanceFactor * info.GetChance() * (1 << 30))
+ return info;
+ fChanceFactor *= 1.2;
+ }
+ } else {
+ // use a new node
+ double fChanceFactor = 1.0;
+ while (1) {
+ int nUBucket = GetRandInt(ADDRMAN_NEW_BUCKET_COUNT);
+ int nUBucketPos = GetRandInt(ADDRMAN_BUCKET_SIZE);
+ if (vvNew[nUBucket][nUBucketPos] == -1)
+ continue;
+ int nId = vvNew[nUBucket][nUBucketPos];
+ assert(mapInfo.count(nId) == 1);
+ CAddrInfo& info = mapInfo[nId];
+ if (GetRandInt(1 << 30) < fChanceFactor * info.GetChance() * (1 << 30))
+ return info;
+ fChanceFactor *= 1.2;
+ }
+ }
+}
+
+#ifdef DEBUG_ADDRMAN
+int CAddrMan::Check_()
+{
+ std::set<int> setTried;
+ std::map<int, int> mapNew;
+
+ if (vRandom.size() != nTried + nNew)
+ return -7;
+
+ for (std::map<int, CAddrInfo>::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 < ADDRMAN_TRIED_BUCKET_COUNT; n++) {
+ for (int i = 0; i < ADDRMAN_BUCKET_SIZE; i++) {
+ if (vvTried[n][i] != -1) {
+ if (!setTried.count(vvTried[n][i]))
+ return -11;
+ if (mapInfo[vvTried[n][i]].GetTriedBucket(nKey) != n)
+ return -17;
+ if (mapInfo[vvTried[n][i]].GetBucketPosition(nKey, false, n) != i)
+ return -18;
+ setTried.erase(vvTried[n][i]);
+ }
+ }
+ }
+
+ for (int n = 0; n < ADDRMAN_NEW_BUCKET_COUNT; n++) {
+ for (int i = 0; i < ADDRMAN_BUCKET_SIZE; i++) {
+ if (vvNew[n][i] != -1) {
+ if (!mapNew.count(vvNew[n][i]))
+ return -12;
+ if (mapInfo[vvNew[n][i]].GetBucketPosition(nKey, true, n) != i)
+ return -19;
+ if (--mapNew[vvNew[n][i]] == 0)
+ mapNew.erase(vvNew[n][i]);
+ }
+ }
+ }
+
+ if (setTried.size())
+ return -13;
+ if (mapNew.size())
+ return -15;
+ if (nKey.IsNull())
+ return -16;
+
+ return 0;
+}
+#endif
+
+void CAddrMan::GetAddr_(std::vector<CAddress>& vAddr)
+{
+ unsigned int nNodes = ADDRMAN_GETADDR_MAX_PCT * vRandom.size() / 100;
+ if (nNodes > ADDRMAN_GETADDR_MAX)
+ nNodes = ADDRMAN_GETADDR_MAX;
+
+ // gather a list of random nodes, skipping those of low quality
+ for (unsigned int n = 0; n < vRandom.size(); n++) {
+ if (vAddr.size() >= nNodes)
+ break;
+
+ int nRndPos = GetRandInt(vRandom.size() - n) + n;
+ SwapRandom(n, nRndPos);
+ assert(mapInfo.count(vRandom[n]) == 1);
+
+ const CAddrInfo& ai = mapInfo[vRandom[n]];
+ if (!ai.IsTerrible())
+ vAddr.push_back(ai);
+ }
+}
+
+void CAddrMan::Connected_(const CService& addr, int64_t 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
+ int64_t nUpdateInterval = 20 * 60;
+ if (nTime - info.nTime > nUpdateInterval)
+ info.nTime = nTime;
+}
diff --git a/src/addrman.h b/src/addrman.h
new file mode 100644
index 0000000000..2db1663997
--- /dev/null
+++ b/src/addrman.h
@@ -0,0 +1,572 @@
+// Copyright (c) 2012 Pieter Wuille
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_ADDRMAN_H
+#define BITCOIN_ADDRMAN_H
+
+#include "netbase.h"
+#include "protocol.h"
+#include "random.h"
+#include "sync.h"
+#include "timedata.h"
+#include "util.h"
+
+#include <map>
+#include <set>
+#include <stdint.h>
+#include <vector>
+
+/**
+ * Extended statistics about a CAddress
+ */
+class CAddrInfo : public CAddress
+{
+public:
+ //! last try whatsoever by us (memory only)
+ int64_t nLastTry;
+
+private:
+ //! where knowledge about this address first came from
+ CNetAddr source;
+
+ //! last successful connection by us
+ int64_t nLastSuccess;
+
+ //! 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:
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ READWRITE(*(CAddress*)this);
+ 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 uint256 &nKey) const;
+
+ //! Calculate in which "new" bucket this entry belongs, given a certain source
+ int GetNewBucket(const uint256 &nKey, const CNetAddr& src) const;
+
+ //! Calculate in which "new" bucket this entry belongs, using its default source
+ int GetNewBucket(const uint256 &nKey) const
+ {
+ return GetNewBucket(nKey, source);
+ }
+
+ //! Calculate in which position of a bucket to store this entry.
+ int GetBucketPosition(const uint256 &nKey, bool fNew, int nBucket) const;
+
+ //! Determine whether the statistics about this entry are bad enough so that it can just be deleted
+ bool IsTerrible(int64_t nNow = GetAdjustedTime()) const;
+
+ //! Calculate the relative chance this entry should be given when selecting nodes to connect to
+ double GetChance(int64_t nNow = GetAdjustedTime()) const;
+
+};
+
+/** Stochastic address manager
+ *
+ * Design goals:
+ * * Keep the address tables in-memory, and asynchronously dump the entire table to peers.dat.
+ * * Make sure no (localized) attacker can fill the entire table with his nodes/addresses.
+ *
+ * To that end:
+ * * Addresses are organized into buckets.
+ * * Addresses that have not yet been tried go into 1024 "new" buckets.
+ * * Based on the address range (/16 for IPv4) of the source of information, 64 buckets are selected at random.
+ * * The actual bucket is chosen from one of these, based on the range in which the address itself is located.
+ * * One single address can occur in up to 8 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 256 "tried" buckets.
+ * * Each address range selects at random 8 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 data structure.
+ */
+
+//! total number of buckets for tried addresses
+#define ADDRMAN_TRIED_BUCKET_COUNT 256
+
+//! total number of buckets for new addresses
+#define ADDRMAN_NEW_BUCKET_COUNT 1024
+
+//! maximum allowed number of entries in buckets for new and tried addresses
+#define ADDRMAN_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 8
+
+//! over how many buckets entries with new addresses originating from a single group are spread
+#define ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP 64
+
+//! in how many buckets for entries with new addresses a single address may occur
+#define ADDRMAN_NEW_BUCKETS_PER_ADDRESS 8
+
+//! 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
+ uint256 nKey;
+
+ //! last used nId
+ int nIdCount;
+
+ //! table with information about all nIds
+ std::map<int, CAddrInfo> mapInfo;
+
+ //! find an nId based on its network address
+ std::map<CNetAddr, int> mapAddr;
+
+ //! randomly-ordered vector of all nIds
+ std::vector<int> vRandom;
+
+ // number of "tried" entries
+ int nTried;
+
+ //! list of "tried" buckets
+ int vvTried[ADDRMAN_TRIED_BUCKET_COUNT][ADDRMAN_BUCKET_SIZE];
+
+ //! number of (unique) "new" entries
+ int nNew;
+
+ //! list of "new" buckets
+ int vvNew[ADDRMAN_NEW_BUCKET_COUNT][ADDRMAN_BUCKET_SIZE];
+
+protected:
+
+ //! Find an entry.
+ CAddrInfo* Find(const CNetAddr& addr, int *pnId = NULL);
+
+ //! find an entry, creating it if necessary.
+ //! nTime and nServices of the found node are 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);
+
+ //! Move an entry from the "new" table(s) to the "tried" table
+ void MakeTried(CAddrInfo& info, int nId);
+
+ //! Delete an entry. It must not be in tried, and have refcount 0.
+ void Delete(int nId);
+
+ //! Clear a position in a "new" table. This is the only place where entries are actually deleted.
+ void ClearNew(int nUBucket, int nUBucketPos);
+
+ //! Mark an entry "good", possibly moving it from "new" to "tried".
+ void Good_(const CService &addr, int64_t nTime);
+
+ //! Add an entry to the "new" table.
+ bool Add_(const CAddress &addr, const CNetAddr& source, int64_t nTimePenalty);
+
+ //! Mark an entry as attempted to connect.
+ void Attempt_(const CService &addr, int64_t nTime);
+
+ //! Select an address to connect to.
+ CAddrInfo Select_();
+
+#ifdef DEBUG_ADDRMAN
+ //! Perform consistency check. Returns an error code or zero.
+ int Check_();
+#endif
+
+ //! Select several addresses at once.
+ void GetAddr_(std::vector<CAddress> &vAddr);
+
+ //! Mark an entry as currently-connected-to.
+ void Connected_(const CService &addr, int64_t nTime);
+
+public:
+ /**
+ * serialized format:
+ * * version byte (currently 1)
+ * * 0x20 + nKey (serialized as if it were a vector, for backward compatibility)
+ * * nNew
+ * * nTried
+ * * number of "new" buckets XOR 2**30
+ * * all nNew addrinfos in vvNew
+ * * all nTried addrinfos in vvTried
+ * * for each bucket:
+ * * number of elements
+ * * for each element: index
+ *
+ * 2**30 is xorred with the number of buckets to make addrman deserializer v0 detect it
+ * as incompatible. This is necessary because it did not check the version number on
+ * deserialization.
+ *
+ * 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_UNKNOWN_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.
+ *
+ * We don't use ADD_SERIALIZE_METHODS since the serialization and deserialization code has
+ * very little in common.
+ */
+ template<typename Stream>
+ void Serialize(Stream &s, int nType, int nVersionDummy) const
+ {
+ LOCK(cs);
+
+ unsigned char nVersion = 1;
+ s << nVersion;
+ s << ((unsigned char)32);
+ s << nKey;
+ s << nNew;
+ s << nTried;
+
+ int nUBuckets = ADDRMAN_NEW_BUCKET_COUNT ^ (1 << 30);
+ s << nUBuckets;
+ std::map<int, int> mapUnkIds;
+ int nIds = 0;
+ for (std::map<int, CAddrInfo>::const_iterator it = mapInfo.begin(); it != mapInfo.end(); it++) {
+ mapUnkIds[(*it).first] = nIds;
+ const CAddrInfo &info = (*it).second;
+ if (info.nRefCount) {
+ assert(nIds != nNew); // this means nNew was wrong, oh ow
+ s << info;
+ nIds++;
+ }
+ }
+ nIds = 0;
+ for (std::map<int, CAddrInfo>::const_iterator it = mapInfo.begin(); it != mapInfo.end(); it++) {
+ const CAddrInfo &info = (*it).second;
+ if (info.fInTried) {
+ assert(nIds != nTried); // this means nTried was wrong, oh ow
+ s << info;
+ nIds++;
+ }
+ }
+ for (int bucket = 0; bucket < ADDRMAN_NEW_BUCKET_COUNT; bucket++) {
+ int nSize = 0;
+ for (int i = 0; i < ADDRMAN_BUCKET_SIZE; i++) {
+ if (vvNew[bucket][i] != -1)
+ nSize++;
+ }
+ s << nSize;
+ for (int i = 0; i < ADDRMAN_BUCKET_SIZE; i++) {
+ if (vvNew[bucket][i] != -1) {
+ int nIndex = mapUnkIds[vvNew[bucket][i]];
+ s << nIndex;
+ }
+ }
+ }
+ }
+
+ template<typename Stream>
+ void Unserialize(Stream& s, int nType, int nVersionDummy)
+ {
+ LOCK(cs);
+
+ Clear();
+
+ unsigned char nVersion;
+ s >> nVersion;
+ unsigned char nKeySize;
+ s >> nKeySize;
+ if (nKeySize != 32) throw std::ios_base::failure("Incorrect keysize in addrman deserialization");
+ s >> nKey;
+ s >> nNew;
+ s >> nTried;
+ int nUBuckets = 0;
+ s >> nUBuckets;
+ if (nVersion != 0) {
+ nUBuckets ^= (1 << 30);
+ }
+
+ // Deserialize entries from the new table.
+ for (int n = 0; n < nNew; n++) {
+ CAddrInfo &info = mapInfo[n];
+ s >> info;
+ mapAddr[info] = n;
+ info.nRandomPos = vRandom.size();
+ vRandom.push_back(n);
+ if (nVersion != 1 || nUBuckets != ADDRMAN_NEW_BUCKET_COUNT) {
+ // In case the new table data cannot be used (nVersion unknown, or bucket count wrong),
+ // immediately try to give them a reference based on their primary source address.
+ int nUBucket = info.GetNewBucket(nKey);
+ int nUBucketPos = info.GetBucketPosition(nKey, true, nUBucket);
+ if (vvNew[nUBucket][nUBucketPos] == -1) {
+ vvNew[nUBucket][nUBucketPos] = n;
+ info.nRefCount++;
+ }
+ }
+ }
+ nIdCount = nNew;
+
+ // Deserialize entries from the tried table.
+ int nLost = 0;
+ for (int n = 0; n < nTried; n++) {
+ CAddrInfo info;
+ s >> info;
+ int nKBucket = info.GetTriedBucket(nKey);
+ int nKBucketPos = info.GetBucketPosition(nKey, false, nKBucket);
+ if (vvTried[nKBucket][nKBucketPos] == -1) {
+ info.nRandomPos = vRandom.size();
+ info.fInTried = true;
+ vRandom.push_back(nIdCount);
+ mapInfo[nIdCount] = info;
+ mapAddr[info] = nIdCount;
+ vvTried[nKBucket][nKBucketPos] = nIdCount;
+ nIdCount++;
+ } else {
+ nLost++;
+ }
+ }
+ nTried -= nLost;
+
+ // Deserialize positions in the new table (if possible).
+ for (int bucket = 0; bucket < nUBuckets; bucket++) {
+ int nSize = 0;
+ s >> nSize;
+ for (int n = 0; n < nSize; n++) {
+ int nIndex = 0;
+ s >> nIndex;
+ if (nIndex >= 0 && nIndex < nNew) {
+ CAddrInfo &info = mapInfo[nIndex];
+ int nUBucketPos = info.GetBucketPosition(nKey, true, bucket);
+ if (nVersion == 1 && nUBuckets == ADDRMAN_NEW_BUCKET_COUNT && vvNew[bucket][nUBucketPos] == -1 && info.nRefCount < ADDRMAN_NEW_BUCKETS_PER_ADDRESS) {
+ info.nRefCount++;
+ vvNew[bucket][nUBucketPos] = nIndex;
+ }
+ }
+ }
+ }
+
+ // Prune new entries with refcount 0 (as a result of collisions).
+ int nLostUnk = 0;
+ for (std::map<int, CAddrInfo>::const_iterator it = mapInfo.begin(); it != mapInfo.end(); ) {
+ if (it->second.fInTried == false && it->second.nRefCount == 0) {
+ std::map<int, CAddrInfo>::const_iterator itCopy = it++;
+ Delete(itCopy->first);
+ nLostUnk++;
+ } else {
+ it++;
+ }
+ }
+ if (nLost + nLostUnk > 0) {
+ LogPrint("addrman", "addrman lost %i new and %i tried addresses due to collisions\n", nLostUnk, nLost);
+ }
+
+ Check();
+ }
+
+ unsigned int GetSerializeSize(int nType, int nVersion) const
+ {
+ return (CSizeComputer(nType, nVersion) << *this).size();
+ }
+
+ void Clear()
+ {
+ std::vector<int>().swap(vRandom);
+ nKey = GetRandHash();
+ for (size_t bucket = 0; bucket < ADDRMAN_NEW_BUCKET_COUNT; bucket++) {
+ for (size_t entry = 0; entry < ADDRMAN_BUCKET_SIZE; entry++) {
+ vvNew[bucket][entry] = -1;
+ }
+ }
+ for (size_t bucket = 0; bucket < ADDRMAN_TRIED_BUCKET_COUNT; bucket++) {
+ for (size_t entry = 0; entry < ADDRMAN_BUCKET_SIZE; entry++) {
+ vvTried[bucket][entry] = -1;
+ }
+ }
+
+ nIdCount = 0;
+ nTried = 0;
+ nNew = 0;
+ }
+
+ CAddrMan()
+ {
+ Clear();
+ }
+
+ ~CAddrMan()
+ {
+ nKey.SetNull();
+ }
+
+ //! 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_()))
+ LogPrintf("ADDRMAN CONSISTENCY CHECK FAILED!!! err=%i\n", err);
+ }
+#endif
+ }
+
+ //! Add a single address.
+ bool Add(const CAddress &addr, const CNetAddr& source, int64_t nTimePenalty = 0)
+ {
+ bool fRet = false;
+ {
+ LOCK(cs);
+ Check();
+ fRet |= Add_(addr, source, nTimePenalty);
+ Check();
+ }
+ if (fRet)
+ LogPrint("addrman", "Added %s from %s: %i tried, %i new\n", addr.ToStringIPPort(), source.ToString(), nTried, nNew);
+ return fRet;
+ }
+
+ //! Add multiple addresses.
+ bool Add(const std::vector<CAddress> &vAddr, const CNetAddr& source, int64_t nTimePenalty = 0)
+ {
+ int nAdd = 0;
+ {
+ LOCK(cs);
+ Check();
+ for (std::vector<CAddress>::const_iterator it = vAddr.begin(); it != vAddr.end(); it++)
+ nAdd += Add_(*it, source, nTimePenalty) ? 1 : 0;
+ Check();
+ }
+ if (nAdd)
+ LogPrint("addrman", "Added %i addresses from %s: %i tried, %i new\n", nAdd, source.ToString(), nTried, nNew);
+ return nAdd > 0;
+ }
+
+ //! Mark an entry as accessible.
+ void Good(const CService &addr, int64_t nTime = GetAdjustedTime())
+ {
+ {
+ LOCK(cs);
+ Check();
+ Good_(addr, nTime);
+ Check();
+ }
+ }
+
+ //! Mark an entry as connection attempted to.
+ void Attempt(const CService &addr, int64_t nTime = GetAdjustedTime())
+ {
+ {
+ LOCK(cs);
+ Check();
+ Attempt_(addr, nTime);
+ Check();
+ }
+ }
+
+ /**
+ * Choose an address to connect to.
+ */
+ CAddrInfo Select()
+ {
+ CAddrInfo addrRet;
+ {
+ LOCK(cs);
+ Check();
+ addrRet = Select_();
+ Check();
+ }
+ return addrRet;
+ }
+
+ //! Return a bunch of addresses, selected at random.
+ std::vector<CAddress> GetAddr()
+ {
+ Check();
+ std::vector<CAddress> vAddr;
+ {
+ LOCK(cs);
+ GetAddr_(vAddr);
+ }
+ Check();
+ return vAddr;
+ }
+
+ //! Mark an entry as currently-connected-to.
+ void Connected(const CService &addr, int64_t nTime = GetAdjustedTime())
+ {
+ {
+ LOCK(cs);
+ Check();
+ Connected_(addr, nTime);
+ Check();
+ }
+ }
+};
+
+#endif // BITCOIN_ADDRMAN_H
diff --git a/src/alert.cpp b/src/alert.cpp
new file mode 100644
index 0000000000..aa7ac748da
--- /dev/null
+++ b/src/alert.cpp
@@ -0,0 +1,265 @@
+// Copyright (c) 2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "alert.h"
+
+#include "clientversion.h"
+#include "net.h"
+#include "pubkey.h"
+#include "timedata.h"
+#include "ui_interface.h"
+#include "util.h"
+
+#include <stdint.h>
+#include <algorithm>
+#include <map>
+
+#include <boost/algorithm/string/classification.hpp>
+#include <boost/algorithm/string/replace.hpp>
+#include <boost/foreach.hpp>
+#include <boost/thread.hpp>
+
+using namespace std;
+
+map<uint256, CAlert> mapAlerts;
+CCriticalSection cs_mapAlerts;
+
+void CUnsignedAlert::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 CUnsignedAlert::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 = %d\n"
+ " nExpiration = %d\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,
+ nMinVer,
+ nMaxVer,
+ strSetSubVer,
+ nPriority,
+ strComment,
+ strStatusBar);
+}
+
+void CAlert::SetNull()
+{
+ CUnsignedAlert::SetNull();
+ vchMsg.clear();
+ vchSig.clear();
+}
+
+bool CAlert::IsNull() const
+{
+ return (nExpiration == 0);
+}
+
+uint256 CAlert::GetHash() const
+{
+ return Hash(this->vchMsg.begin(), this->vchMsg.end());
+}
+
+bool CAlert::IsInEffect() const
+{
+ return (GetAdjustedTime() < nExpiration);
+}
+
+bool CAlert::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 CAlert::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 CAlert::AppliesToMe() const
+{
+ return AppliesTo(PROTOCOL_VERSION, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<std::string>()));
+}
+
+bool CAlert::RelayTo(CNode* pnode) const
+{
+ if (!IsInEffect())
+ return false;
+ // don't relay to nodes which haven't sent their version message
+ if (pnode->nVersion == 0)
+ 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 CAlert::CheckSignature(const std::vector<unsigned char>& alertKey) const
+{
+ CPubKey key(alertKey);
+ 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;
+}
+
+CAlert CAlert::getAlertByHash(const uint256 &hash)
+{
+ CAlert retval;
+ {
+ LOCK(cs_mapAlerts);
+ map<uint256, CAlert>::iterator mi = mapAlerts.find(hash);
+ if(mi != mapAlerts.end())
+ retval = mi->second;
+ }
+ return retval;
+}
+
+bool CAlert::ProcessAlert(const std::vector<unsigned char>& alertKey, bool fThread)
+{
+ if (!CheckSignature(alertKey))
+ return false;
+ if (!IsInEffect())
+ return false;
+
+ // alert.nID=max is reserved for if the alert key is
+ // compromised. It must have a pre-defined message,
+ // must never expire, must apply to all versions,
+ // and must cancel all previous
+ // alerts or it will be ignored (so an attacker can't
+ // send an "everything is OK, don't panic" version that
+ // cannot be overridden):
+ int maxInt = std::numeric_limits<int>::max();
+ if (nID == maxInt)
+ {
+ if (!(
+ nExpiration == maxInt &&
+ nCancel == (maxInt-1) &&
+ nMinVer == 0 &&
+ nMaxVer == maxInt &&
+ setSubVer.empty() &&
+ nPriority == maxInt &&
+ strStatusBar == "URGENT: Alert key compromised, upgrade required"
+ ))
+ return false;
+ }
+
+ {
+ LOCK(cs_mapAlerts);
+ // Cancel previous alerts
+ for (map<uint256, CAlert>::iterator mi = mapAlerts.begin(); mi != mapAlerts.end();)
+ {
+ const CAlert& alert = (*mi).second;
+ if (Cancels(alert))
+ {
+ LogPrint("alert", "cancelling alert %d\n", alert.nID);
+ uiInterface.NotifyAlertChanged((*mi).first, CT_DELETED);
+ mapAlerts.erase(mi++);
+ }
+ else if (!alert.IsInEffect())
+ {
+ LogPrint("alert", "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))
+ {
+ LogPrint("alert", "alert already cancelled by %d\n", alert.nID);
+ return false;
+ }
+ }
+
+ // Add to mapAlerts
+ mapAlerts.insert(make_pair(GetHash(), *this));
+ // Notify UI and -alertnotify if it applies to me
+ if(AppliesToMe())
+ {
+ uiInterface.NotifyAlertChanged(GetHash(), CT_NEW);
+ Notify(strStatusBar, fThread);
+ }
+ }
+
+ LogPrint("alert", "accepted alert %d, AppliesToMe()=%d\n", nID, AppliesToMe());
+ return true;
+}
+
+void
+CAlert::Notify(const std::string& strMessage, bool fThread)
+{
+ std::string strCmd = GetArg("-alertnotify", "");
+ if (strCmd.empty()) return;
+
+ // Alert text should be plain ascii coming from a trusted source, but to
+ // be safe we first strip anything not in safeChars, then add single quotes around
+ // the whole string before passing it to the shell:
+ std::string singleQuote("'");
+ std::string safeStatus = SanitizeString(strMessage);
+ safeStatus = singleQuote+safeStatus+singleQuote;
+ boost::replace_all(strCmd, "%s", safeStatus);
+
+ if (fThread)
+ boost::thread t(runCommand, strCmd); // thread runs free
+ else
+ runCommand(strCmd);
+}
diff --git a/src/alert.h b/src/alert.h
new file mode 100644
index 0000000000..746967c4af
--- /dev/null
+++ b/src/alert.h
@@ -0,0 +1,113 @@
+// Copyright (c) 2010 Satoshi Nakamoto
+// Copyright (c) 2009-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_ALERT_H
+#define BITCOIN_ALERT_H
+
+#include "serialize.h"
+#include "sync.h"
+
+#include <map>
+#include <set>
+#include <stdint.h>
+#include <string>
+
+class CAlert;
+class CNode;
+class uint256;
+
+extern std::map<uint256, CAlert> mapAlerts;
+extern CCriticalSection cs_mapAlerts;
+
+/** 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_t nRelayUntil; // when newer nodes stop relaying to newer nodes
+ int64_t nExpiration;
+ int nID;
+ int nCancel;
+ std::set<int> setCancel;
+ int nMinVer; // lowest version inclusive
+ int nMaxVer; // highest version inclusive
+ std::set<std::string> setSubVer; // empty matches all
+ int nPriority;
+
+ // Actions
+ std::string strComment;
+ std::string strStatusBar;
+ std::string strReserved;
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ 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(LIMITED_STRING(strComment, 65536));
+ READWRITE(LIMITED_STRING(strStatusBar, 256));
+ READWRITE(LIMITED_STRING(strReserved, 256));
+ }
+
+ void SetNull();
+
+ std::string ToString() const;
+};
+
+/** An alert is a combination of a serialized CUnsignedAlert and a signature. */
+class CAlert : public CUnsignedAlert
+{
+public:
+ std::vector<unsigned char> vchMsg;
+ std::vector<unsigned char> vchSig;
+
+ CAlert()
+ {
+ SetNull();
+ }
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ READWRITE(vchMsg);
+ READWRITE(vchSig);
+ }
+
+ void SetNull();
+ bool IsNull() const;
+ uint256 GetHash() const;
+ bool IsInEffect() const;
+ bool Cancels(const CAlert& alert) const;
+ bool AppliesTo(int nVersion, std::string strSubVerIn) const;
+ bool AppliesToMe() const;
+ bool RelayTo(CNode* pnode) const;
+ bool CheckSignature(const std::vector<unsigned char>& alertKey) const;
+ bool ProcessAlert(const std::vector<unsigned char>& alertKey, bool fThread = true); // fThread means run -alertnotify in a free-running thread
+ static void Notify(const std::string& strMessage, bool fThread);
+
+ /*
+ * Get copy of (active) alert object by hash. Returns a null alert if it is not found.
+ */
+ static CAlert getAlertByHash(const uint256 &hash);
+};
+
+#endif // BITCOIN_ALERT_H
diff --git a/src/amount.cpp b/src/amount.cpp
new file mode 100644
index 0000000000..0a394c96fc
--- /dev/null
+++ b/src/amount.cpp
@@ -0,0 +1,31 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "amount.h"
+
+#include "tinyformat.h"
+
+CFeeRate::CFeeRate(const CAmount& nFeePaid, size_t nSize)
+{
+ if (nSize > 0)
+ nSatoshisPerK = nFeePaid*1000/nSize;
+ else
+ nSatoshisPerK = 0;
+}
+
+CAmount CFeeRate::GetFee(size_t nSize) const
+{
+ CAmount nFee = nSatoshisPerK*nSize / 1000;
+
+ if (nFee == 0 && nSatoshisPerK > 0)
+ nFee = nSatoshisPerK;
+
+ return nFee;
+}
+
+std::string CFeeRate::ToString() const
+{
+ return strprintf("%d.%08d BTC/kB", nSatoshisPerK / COIN, nSatoshisPerK % COIN);
+}
diff --git a/src/amount.h b/src/amount.h
new file mode 100644
index 0000000000..9212244a88
--- /dev/null
+++ b/src/amount.h
@@ -0,0 +1,54 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_AMOUNT_H
+#define BITCOIN_AMOUNT_H
+
+#include "serialize.h"
+
+#include <stdlib.h>
+#include <string>
+
+typedef int64_t CAmount;
+
+static const CAmount COIN = 100000000;
+static const CAmount CENT = 1000000;
+
+/** No amount larger than this (in satoshi) is valid */
+static const CAmount MAX_MONEY = 21000000 * COIN;
+inline bool MoneyRange(const CAmount& nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); }
+
+/** Type-safe wrapper class to for fee rates
+ * (how much to pay based on transaction size)
+ */
+class CFeeRate
+{
+private:
+ CAmount nSatoshisPerK; // unit is satoshis-per-1,000-bytes
+public:
+ CFeeRate() : nSatoshisPerK(0) { }
+ explicit CFeeRate(const CAmount& _nSatoshisPerK): nSatoshisPerK(_nSatoshisPerK) { }
+ CFeeRate(const CAmount& nFeePaid, size_t nSize);
+ CFeeRate(const CFeeRate& other) { nSatoshisPerK = other.nSatoshisPerK; }
+
+ CAmount GetFee(size_t size) const; // unit returned is satoshis
+ CAmount GetFeePerK() const { return GetFee(1000); } // satoshis-per-1000-bytes
+
+ friend bool operator<(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK < b.nSatoshisPerK; }
+ friend bool operator>(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK > b.nSatoshisPerK; }
+ friend bool operator==(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK == b.nSatoshisPerK; }
+ friend bool operator<=(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK <= b.nSatoshisPerK; }
+ friend bool operator>=(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK >= b.nSatoshisPerK; }
+ std::string ToString() const;
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ READWRITE(nSatoshisPerK);
+ }
+};
+
+#endif // BITCOIN_AMOUNT_H
diff --git a/src/arith_uint256.cpp b/src/arith_uint256.cpp
new file mode 100644
index 0000000000..2e61363576
--- /dev/null
+++ b/src/arith_uint256.cpp
@@ -0,0 +1,260 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "arith_uint256.h"
+
+#include "uint256.h"
+#include "utilstrencodings.h"
+#include "crypto/common.h"
+
+#include <stdio.h>
+#include <string.h>
+
+template <unsigned int BITS>
+base_uint<BITS>::base_uint(const std::string& str)
+{
+ SetHex(str);
+}
+
+template <unsigned int BITS>
+base_uint<BITS>& base_uint<BITS>::operator<<=(unsigned int shift)
+{
+ base_uint<BITS> 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;
+}
+
+template <unsigned int BITS>
+base_uint<BITS>& base_uint<BITS>::operator>>=(unsigned int shift)
+{
+ base_uint<BITS> 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;
+}
+
+template <unsigned int BITS>
+base_uint<BITS>& base_uint<BITS>::operator*=(uint32_t b32)
+{
+ uint64_t carry = 0;
+ for (int i = 0; i < WIDTH; i++) {
+ uint64_t n = carry + (uint64_t)b32 * pn[i];
+ pn[i] = n & 0xffffffff;
+ carry = n >> 32;
+ }
+ return *this;
+}
+
+template <unsigned int BITS>
+base_uint<BITS>& base_uint<BITS>::operator*=(const base_uint& b)
+{
+ base_uint<BITS> a = *this;
+ *this = 0;
+ for (int j = 0; j < WIDTH; j++) {
+ uint64_t carry = 0;
+ for (int i = 0; i + j < WIDTH; i++) {
+ uint64_t n = carry + pn[i + j] + (uint64_t)a.pn[j] * b.pn[i];
+ pn[i + j] = n & 0xffffffff;
+ carry = n >> 32;
+ }
+ }
+ return *this;
+}
+
+template <unsigned int BITS>
+base_uint<BITS>& base_uint<BITS>::operator/=(const base_uint& b)
+{
+ base_uint<BITS> div = b; // make a copy, so we can shift.
+ base_uint<BITS> num = *this; // make a copy, so we can subtract.
+ *this = 0; // the quotient.
+ int num_bits = num.bits();
+ int div_bits = div.bits();
+ if (div_bits == 0)
+ throw uint_error("Division by zero");
+ if (div_bits > num_bits) // the result is certainly 0.
+ return *this;
+ int shift = num_bits - div_bits;
+ div <<= shift; // shift so that div and num align.
+ while (shift >= 0) {
+ if (num >= div) {
+ num -= div;
+ pn[shift / 32] |= (1 << (shift & 31)); // set a bit of the result.
+ }
+ div >>= 1; // shift back.
+ shift--;
+ }
+ // num now contains the remainder of the division.
+ return *this;
+}
+
+template <unsigned int BITS>
+int base_uint<BITS>::CompareTo(const base_uint<BITS>& b) const
+{
+ for (int i = WIDTH - 1; i >= 0; i--) {
+ if (pn[i] < b.pn[i])
+ return -1;
+ if (pn[i] > b.pn[i])
+ return 1;
+ }
+ return 0;
+}
+
+template <unsigned int BITS>
+bool base_uint<BITS>::EqualTo(uint64_t b) const
+{
+ for (int i = WIDTH - 1; i >= 2; i--) {
+ if (pn[i])
+ return false;
+ }
+ if (pn[1] != (b >> 32))
+ return false;
+ if (pn[0] != (b & 0xfffffffful))
+ return false;
+ return true;
+}
+
+template <unsigned int BITS>
+double base_uint<BITS>::getdouble() const
+{
+ double ret = 0.0;
+ double fact = 1.0;
+ for (int i = 0; i < WIDTH; i++) {
+ ret += fact * pn[i];
+ fact *= 4294967296.0;
+ }
+ return ret;
+}
+
+template <unsigned int BITS>
+std::string base_uint<BITS>::GetHex() const
+{
+ return ArithToUint256(*this).GetHex();
+}
+
+template <unsigned int BITS>
+void base_uint<BITS>::SetHex(const char* psz)
+{
+ *this = UintToArith256(uint256S(psz));
+}
+
+template <unsigned int BITS>
+void base_uint<BITS>::SetHex(const std::string& str)
+{
+ SetHex(str.c_str());
+}
+
+template <unsigned int BITS>
+std::string base_uint<BITS>::ToString() const
+{
+ return (GetHex());
+}
+
+template <unsigned int BITS>
+unsigned int base_uint<BITS>::bits() const
+{
+ for (int pos = WIDTH - 1; pos >= 0; pos--) {
+ if (pn[pos]) {
+ for (int bits = 31; bits > 0; bits--) {
+ if (pn[pos] & 1 << bits)
+ return 32 * pos + bits + 1;
+ }
+ return 32 * pos + 1;
+ }
+ }
+ return 0;
+}
+
+// Explicit instantiations for base_uint<256>
+template base_uint<256>::base_uint(const std::string&);
+template base_uint<256>& base_uint<256>::operator<<=(unsigned int);
+template base_uint<256>& base_uint<256>::operator>>=(unsigned int);
+template base_uint<256>& base_uint<256>::operator*=(uint32_t b32);
+template base_uint<256>& base_uint<256>::operator*=(const base_uint<256>& b);
+template base_uint<256>& base_uint<256>::operator/=(const base_uint<256>& b);
+template int base_uint<256>::CompareTo(const base_uint<256>&) const;
+template bool base_uint<256>::EqualTo(uint64_t) const;
+template double base_uint<256>::getdouble() const;
+template std::string base_uint<256>::GetHex() const;
+template std::string base_uint<256>::ToString() const;
+template void base_uint<256>::SetHex(const char*);
+template void base_uint<256>::SetHex(const std::string&);
+template unsigned int base_uint<256>::bits() const;
+
+// This implementation directly uses shifts instead of going
+// through an intermediate MPI representation.
+arith_uint256& arith_uint256::SetCompact(uint32_t nCompact, bool* pfNegative, bool* pfOverflow)
+{
+ int nSize = nCompact >> 24;
+ uint32_t nWord = nCompact & 0x007fffff;
+ if (nSize <= 3) {
+ nWord >>= 8 * (3 - nSize);
+ *this = nWord;
+ } else {
+ *this = nWord;
+ *this <<= 8 * (nSize - 3);
+ }
+ if (pfNegative)
+ *pfNegative = nWord != 0 && (nCompact & 0x00800000) != 0;
+ if (pfOverflow)
+ *pfOverflow = nWord != 0 && ((nSize > 34) ||
+ (nWord > 0xff && nSize > 33) ||
+ (nWord > 0xffff && nSize > 32));
+ return *this;
+}
+
+uint32_t arith_uint256::GetCompact(bool fNegative) const
+{
+ int nSize = (bits() + 7) / 8;
+ uint32_t nCompact = 0;
+ if (nSize <= 3) {
+ nCompact = GetLow64() << 8 * (3 - nSize);
+ } else {
+ arith_uint256 bn = *this >> 8 * (nSize - 3);
+ nCompact = bn.GetLow64();
+ }
+ // The 0x00800000 bit denotes the sign.
+ // Thus, if it is already set, divide the mantissa by 256 and increase the exponent.
+ if (nCompact & 0x00800000) {
+ nCompact >>= 8;
+ nSize++;
+ }
+ assert((nCompact & ~0x007fffff) == 0);
+ assert(nSize < 256);
+ nCompact |= nSize << 24;
+ nCompact |= (fNegative && (nCompact & 0x007fffff) ? 0x00800000 : 0);
+ return nCompact;
+}
+
+uint256 ArithToUint256(const arith_uint256 &a)
+{
+ uint256 b;
+ for(int x=0; x<a.WIDTH; ++x)
+ WriteLE32(b.begin() + x*4, a.pn[x]);
+ return b;
+}
+arith_uint256 UintToArith256(const uint256 &a)
+{
+ arith_uint256 b;
+ for(int x=0; x<b.WIDTH; ++x)
+ b.pn[x] = ReadLE32(a.begin() + x*4);
+ return b;
+}
diff --git a/src/arith_uint256.h b/src/arith_uint256.h
new file mode 100644
index 0000000000..103c78bb8e
--- /dev/null
+++ b/src/arith_uint256.h
@@ -0,0 +1,290 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_ARITH_UINT256_H
+#define BITCOIN_ARITH_UINT256_H
+
+#include <assert.h>
+#include <cstring>
+#include <stdexcept>
+#include <stdint.h>
+#include <string>
+#include <vector>
+
+class uint256;
+
+class uint_error : public std::runtime_error {
+public:
+ explicit uint_error(const std::string& str) : std::runtime_error(str) {}
+};
+
+/** Template base class for unsigned big integers. */
+template<unsigned int BITS>
+class base_uint
+{
+protected:
+ enum { WIDTH=BITS/32 };
+ uint32_t pn[WIDTH];
+public:
+
+ base_uint()
+ {
+ for (int i = 0; i < WIDTH; i++)
+ pn[i] = 0;
+ }
+
+ base_uint(const base_uint& b)
+ {
+ for (int i = 0; i < WIDTH; i++)
+ pn[i] = b.pn[i];
+ }
+
+ base_uint& operator=(const base_uint& b)
+ {
+ for (int i = 0; i < WIDTH; i++)
+ pn[i] = b.pn[i];
+ return *this;
+ }
+
+ base_uint(uint64_t b)
+ {
+ pn[0] = (unsigned int)b;
+ pn[1] = (unsigned int)(b >> 32);
+ for (int i = 2; i < WIDTH; i++)
+ pn[i] = 0;
+ }
+
+ explicit base_uint(const std::string& str);
+
+ 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;
+ }
+
+ double getdouble() const;
+
+ base_uint& operator=(uint64_t 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_t b)
+ {
+ pn[0] ^= (unsigned int)b;
+ pn[1] ^= (unsigned int)(b >> 32);
+ return *this;
+ }
+
+ base_uint& operator|=(uint64_t b)
+ {
+ pn[0] |= (unsigned int)b;
+ pn[1] |= (unsigned int)(b >> 32);
+ return *this;
+ }
+
+ base_uint& operator<<=(unsigned int shift);
+ base_uint& operator>>=(unsigned int shift);
+
+ base_uint& operator+=(const base_uint& b)
+ {
+ uint64_t carry = 0;
+ for (int i = 0; i < WIDTH; i++)
+ {
+ uint64_t 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_t b64)
+ {
+ base_uint b;
+ b = b64;
+ *this += b;
+ return *this;
+ }
+
+ base_uint& operator-=(uint64_t b64)
+ {
+ base_uint b;
+ b = b64;
+ *this += -b;
+ return *this;
+ }
+
+ base_uint& operator*=(uint32_t b32);
+ base_uint& operator*=(const base_uint& b);
+ base_uint& operator/=(const base_uint& b);
+
+ 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] == (uint32_t)-1 && i < WIDTH-1)
+ i++;
+ return *this;
+ }
+
+ const base_uint operator--(int)
+ {
+ // postfix operator
+ const base_uint ret = *this;
+ --(*this);
+ return ret;
+ }
+
+ int CompareTo(const base_uint& b) const;
+ bool EqualTo(uint64_t b) const;
+
+ friend inline const base_uint operator+(const base_uint& a, const base_uint& b) { return base_uint(a) += b; }
+ friend inline const base_uint operator-(const base_uint& a, const base_uint& b) { return base_uint(a) -= b; }
+ friend inline const base_uint operator*(const base_uint& a, const base_uint& b) { return base_uint(a) *= b; }
+ friend inline const base_uint operator/(const base_uint& a, const base_uint& b) { return base_uint(a) /= b; }
+ friend inline const base_uint operator|(const base_uint& a, const base_uint& b) { return base_uint(a) |= b; }
+ friend inline const base_uint operator&(const base_uint& a, const base_uint& b) { return base_uint(a) &= b; }
+ friend inline const base_uint operator^(const base_uint& a, const base_uint& b) { return base_uint(a) ^= b; }
+ friend inline const base_uint operator>>(const base_uint& a, int shift) { return base_uint(a) >>= shift; }
+ friend inline const base_uint operator<<(const base_uint& a, int shift) { return base_uint(a) <<= shift; }
+ friend inline const base_uint operator*(const base_uint& a, uint32_t b) { return base_uint(a) *= b; }
+ friend inline bool operator==(const base_uint& a, const base_uint& b) { return memcmp(a.pn, b.pn, sizeof(a.pn)) == 0; }
+ friend inline bool operator!=(const base_uint& a, const base_uint& b) { return memcmp(a.pn, b.pn, sizeof(a.pn)) != 0; }
+ friend inline bool operator>(const base_uint& a, const base_uint& b) { return a.CompareTo(b) > 0; }
+ friend inline bool operator<(const base_uint& a, const base_uint& b) { return a.CompareTo(b) < 0; }
+ friend inline bool operator>=(const base_uint& a, const base_uint& b) { return a.CompareTo(b) >= 0; }
+ friend inline bool operator<=(const base_uint& a, const base_uint& b) { return a.CompareTo(b) <= 0; }
+ friend inline bool operator==(const base_uint& a, uint64_t b) { return a.EqualTo(b); }
+ friend inline bool operator!=(const base_uint& a, uint64_t b) { return !a.EqualTo(b); }
+
+ std::string GetHex() const;
+ void SetHex(const char* psz);
+ void SetHex(const std::string& str);
+ std::string ToString() const;
+
+ unsigned int size() const
+ {
+ return sizeof(pn);
+ }
+
+ /**
+ * Returns the position of the highest bit set plus one, or zero if the
+ * value is zero.
+ */
+ unsigned int bits() const;
+
+ uint64_t GetLow64() const
+ {
+ assert(WIDTH >= 2);
+ return pn[0] | (uint64_t)pn[1] << 32;
+ }
+};
+
+/** 256-bit unsigned big integer. */
+class arith_uint256 : public base_uint<256> {
+public:
+ arith_uint256() {}
+ arith_uint256(const base_uint<256>& b) : base_uint<256>(b) {}
+ arith_uint256(uint64_t b) : base_uint<256>(b) {}
+ explicit arith_uint256(const std::string& str) : base_uint<256>(str) {}
+
+ /**
+ * The "compact" format is a representation of a whole
+ * number N using an unsigned 32bit number similar to a
+ * floating point format.
+ * The most significant 8 bits are the unsigned exponent of base 256.
+ * This exponent can be thought of as "number of bytes of N".
+ * The lower 23 bits are the mantissa.
+ * Bit number 24 (0x800000) represents the sign of N.
+ * N = (-1^sign) * mantissa * 256^(exponent-3)
+ *
+ * Satoshi's original implementation used BN_bn2mpi() and BN_mpi2bn().
+ * MPI uses the most significant bit of the first byte as sign.
+ * Thus 0x1234560000 is compact (0x05123456)
+ * and 0xc0de000000 is compact (0x0600c0de)
+ *
+ * Bitcoin only uses this "compact" format for encoding difficulty
+ * targets, which are unsigned 256bit quantities. Thus, all the
+ * complexities of the sign bit and using base 256 are probably an
+ * implementation accident.
+ */
+ arith_uint256& SetCompact(uint32_t nCompact, bool *pfNegative = NULL, bool *pfOverflow = NULL);
+ uint32_t GetCompact(bool fNegative = false) const;
+
+ friend uint256 ArithToUint256(const arith_uint256 &);
+ friend arith_uint256 UintToArith256(const uint256 &);
+};
+
+uint256 ArithToUint256(const arith_uint256 &);
+arith_uint256 UintToArith256(const uint256 &);
+
+#endif // BITCOIN_ARITH_UINT256_H
diff --git a/src/base58.cpp b/src/base58.cpp
new file mode 100644
index 0000000000..c809185056
--- /dev/null
+++ b/src/base58.cpp
@@ -0,0 +1,311 @@
+// Copyright (c) 2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "base58.h"
+
+#include "hash.h"
+#include "uint256.h"
+
+#include <assert.h>
+#include <stdint.h>
+#include <string.h>
+#include <vector>
+#include <string>
+#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/static_visitor.hpp>
+
+/** All alphanumeric characters except for "0", "I", "O", and "l" */
+static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
+
+bool DecodeBase58(const char* psz, std::vector<unsigned char>& vch)
+{
+ // Skip leading spaces.
+ while (*psz && isspace(*psz))
+ psz++;
+ // Skip and count leading '1's.
+ int zeroes = 0;
+ while (*psz == '1') {
+ zeroes++;
+ psz++;
+ }
+ // Allocate enough space in big-endian base256 representation.
+ std::vector<unsigned char> b256(strlen(psz) * 733 / 1000 + 1); // log(58) / log(256), rounded up.
+ // Process the characters.
+ while (*psz && !isspace(*psz)) {
+ // Decode base58 character
+ const char* ch = strchr(pszBase58, *psz);
+ if (ch == NULL)
+ return false;
+ // Apply "b256 = b256 * 58 + ch".
+ int carry = ch - pszBase58;
+ for (std::vector<unsigned char>::reverse_iterator it = b256.rbegin(); it != b256.rend(); it++) {
+ carry += 58 * (*it);
+ *it = carry % 256;
+ carry /= 256;
+ }
+ assert(carry == 0);
+ psz++;
+ }
+ // Skip trailing spaces.
+ while (isspace(*psz))
+ psz++;
+ if (*psz != 0)
+ return false;
+ // Skip leading zeroes in b256.
+ std::vector<unsigned char>::iterator it = b256.begin();
+ while (it != b256.end() && *it == 0)
+ it++;
+ // Copy result into output vector.
+ vch.reserve(zeroes + (b256.end() - it));
+ vch.assign(zeroes, 0x00);
+ while (it != b256.end())
+ vch.push_back(*(it++));
+ return true;
+}
+
+std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend)
+{
+ // Skip & count leading zeroes.
+ int zeroes = 0;
+ while (pbegin != pend && *pbegin == 0) {
+ pbegin++;
+ zeroes++;
+ }
+ // Allocate enough space in big-endian base58 representation.
+ std::vector<unsigned char> b58((pend - pbegin) * 138 / 100 + 1); // log(256) / log(58), rounded up.
+ // Process the bytes.
+ while (pbegin != pend) {
+ int carry = *pbegin;
+ // Apply "b58 = b58 * 256 + ch".
+ for (std::vector<unsigned char>::reverse_iterator it = b58.rbegin(); it != b58.rend(); it++) {
+ carry += 256 * (*it);
+ *it = carry % 58;
+ carry /= 58;
+ }
+ assert(carry == 0);
+ pbegin++;
+ }
+ // Skip leading zeroes in base58 result.
+ std::vector<unsigned char>::iterator it = b58.begin();
+ while (it != b58.end() && *it == 0)
+ it++;
+ // Translate the result into a string.
+ std::string str;
+ str.reserve(zeroes + (b58.end() - it));
+ str.assign(zeroes, '1');
+ while (it != b58.end())
+ str += pszBase58[*(it++)];
+ return str;
+}
+
+std::string EncodeBase58(const std::vector<unsigned char>& vch)
+{
+ return EncodeBase58(&vch[0], &vch[0] + vch.size());
+}
+
+bool DecodeBase58(const std::string& str, std::vector<unsigned char>& vchRet)
+{
+ return DecodeBase58(str.c_str(), vchRet);
+}
+
+std::string EncodeBase58Check(const std::vector<unsigned char>& vchIn)
+{
+ // add 4-byte hash check to the end
+ std::vector<unsigned char> vch(vchIn);
+ uint256 hash = Hash(vch.begin(), vch.end());
+ vch.insert(vch.end(), (unsigned char*)&hash, (unsigned char*)&hash + 4);
+ return EncodeBase58(vch);
+}
+
+bool DecodeBase58Check(const char* psz, std::vector<unsigned char>& vchRet)
+{
+ if (!DecodeBase58(psz, vchRet) ||
+ (vchRet.size() < 4)) {
+ vchRet.clear();
+ return false;
+ }
+ // re-calculate the checksum, insure it matches the included 4-byte checksum
+ 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;
+}
+
+bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRet)
+{
+ return DecodeBase58Check(str.c_str(), vchRet);
+}
+
+CBase58Data::CBase58Data()
+{
+ vchVersion.clear();
+ vchData.clear();
+}
+
+void CBase58Data::SetData(const std::vector<unsigned char>& vchVersionIn, const void* pdata, size_t nSize)
+{
+ vchVersion = vchVersionIn;
+ vchData.resize(nSize);
+ if (!vchData.empty())
+ memcpy(&vchData[0], pdata, nSize);
+}
+
+void CBase58Data::SetData(const std::vector<unsigned char>& vchVersionIn, const unsigned char* pbegin, const unsigned char* pend)
+{
+ SetData(vchVersionIn, (void*)pbegin, pend - pbegin);
+}
+
+bool CBase58Data::SetString(const char* psz, unsigned int nVersionBytes)
+{
+ std::vector<unsigned char> vchTemp;
+ bool rc58 = DecodeBase58Check(psz, vchTemp);
+ if ((!rc58) || (vchTemp.size() < nVersionBytes)) {
+ vchData.clear();
+ vchVersion.clear();
+ return false;
+ }
+ vchVersion.assign(vchTemp.begin(), vchTemp.begin() + nVersionBytes);
+ vchData.resize(vchTemp.size() - nVersionBytes);
+ if (!vchData.empty())
+ memcpy(&vchData[0], &vchTemp[nVersionBytes], vchData.size());
+ memory_cleanse(&vchTemp[0], vchData.size());
+ return true;
+}
+
+bool CBase58Data::SetString(const std::string& str)
+{
+ return SetString(str.c_str());
+}
+
+std::string CBase58Data::ToString() const
+{
+ std::vector<unsigned char> vch = vchVersion;
+ vch.insert(vch.end(), vchData.begin(), vchData.end());
+ return EncodeBase58Check(vch);
+}
+
+int CBase58Data::CompareTo(const CBase58Data& b58) const
+{
+ if (vchVersion < b58.vchVersion)
+ return -1;
+ if (vchVersion > b58.vchVersion)
+ return 1;
+ if (vchData < b58.vchData)
+ return -1;
+ if (vchData > b58.vchData)
+ return 1;
+ return 0;
+}
+
+namespace
+{
+class CBitcoinAddressVisitor : public boost::static_visitor<bool>
+{
+private:
+ CBitcoinAddress* addr;
+
+public:
+ CBitcoinAddressVisitor(CBitcoinAddress* addrIn) : addr(addrIn) {}
+
+ bool operator()(const CKeyID& id) const { return addr->Set(id); }
+ bool operator()(const CScriptID& id) const { return addr->Set(id); }
+ bool operator()(const CNoDestination& no) const { return false; }
+};
+
+} // anon namespace
+
+bool CBitcoinAddress::Set(const CKeyID& id)
+{
+ SetData(Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS), &id, 20);
+ return true;
+}
+
+bool CBitcoinAddress::Set(const CScriptID& id)
+{
+ SetData(Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS), &id, 20);
+ return true;
+}
+
+bool CBitcoinAddress::Set(const CTxDestination& dest)
+{
+ return boost::apply_visitor(CBitcoinAddressVisitor(this), dest);
+}
+
+bool CBitcoinAddress::IsValid() const
+{
+ return IsValid(Params());
+}
+
+bool CBitcoinAddress::IsValid(const CChainParams& params) const
+{
+ bool fCorrectSize = vchData.size() == 20;
+ bool fKnownVersion = vchVersion == params.Base58Prefix(CChainParams::PUBKEY_ADDRESS) ||
+ vchVersion == params.Base58Prefix(CChainParams::SCRIPT_ADDRESS);
+ return fCorrectSize && fKnownVersion;
+}
+
+CTxDestination CBitcoinAddress::Get() const
+{
+ if (!IsValid())
+ return CNoDestination();
+ uint160 id;
+ memcpy(&id, &vchData[0], 20);
+ if (vchVersion == Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS))
+ return CKeyID(id);
+ else if (vchVersion == Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS))
+ return CScriptID(id);
+ else
+ return CNoDestination();
+}
+
+bool CBitcoinAddress::GetKeyID(CKeyID& keyID) const
+{
+ if (!IsValid() || vchVersion != Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS))
+ return false;
+ uint160 id;
+ memcpy(&id, &vchData[0], 20);
+ keyID = CKeyID(id);
+ return true;
+}
+
+bool CBitcoinAddress::IsScript() const
+{
+ return IsValid() && vchVersion == Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS);
+}
+
+void CBitcoinSecret::SetKey(const CKey& vchSecret)
+{
+ assert(vchSecret.IsValid());
+ SetData(Params().Base58Prefix(CChainParams::SECRET_KEY), vchSecret.begin(), vchSecret.size());
+ if (vchSecret.IsCompressed())
+ vchData.push_back(1);
+}
+
+CKey CBitcoinSecret::GetKey()
+{
+ CKey ret;
+ assert(vchData.size() >= 32);
+ ret.Set(vchData.begin(), vchData.begin() + 32, vchData.size() > 32 && vchData[32] == 1);
+ return ret;
+}
+
+bool CBitcoinSecret::IsValid() const
+{
+ bool fExpectedFormat = vchData.size() == 32 || (vchData.size() == 33 && vchData[32] == 1);
+ bool fCorrectVersion = vchVersion == Params().Base58Prefix(CChainParams::SECRET_KEY);
+ return fExpectedFormat && fCorrectVersion;
+}
+
+bool CBitcoinSecret::SetString(const char* pszSecret)
+{
+ return CBase58Data::SetString(pszSecret) && IsValid();
+}
+
+bool CBitcoinSecret::SetString(const std::string& strSecret)
+{
+ return SetString(strSecret.c_str());
+}
diff --git a/src/base58.h b/src/base58.h
new file mode 100644
index 0000000000..787979c827
--- /dev/null
+++ b/src/base58.h
@@ -0,0 +1,163 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT 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 data.
+ * - A string with non-alphanumeric characters is not as easily accepted as input.
+ * - E-mail usually won't line-break if there's no punctuation to break at.
+ * - Double-clicking selects the whole string as one word if it's all alphanumeric.
+ */
+#ifndef BITCOIN_BASE58_H
+#define BITCOIN_BASE58_H
+
+#include "chainparams.h"
+#include "key.h"
+#include "pubkey.h"
+#include "script/script.h"
+#include "script/standard.h"
+#include "support/allocators/zeroafterfree.h"
+
+#include <string>
+#include <vector>
+
+/**
+ * Encode a byte sequence as a base58-encoded string.
+ * pbegin and pend cannot be NULL, unless both are.
+ */
+std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend);
+
+/**
+ * Encode a byte vector as a base58-encoded string
+ */
+std::string EncodeBase58(const std::vector<unsigned char>& vch);
+
+/**
+ * Decode a base58-encoded string (psz) into a byte vector (vchRet).
+ * return true if decoding is successful.
+ * psz cannot be NULL.
+ */
+bool DecodeBase58(const char* psz, std::vector<unsigned char>& vchRet);
+
+/**
+ * Decode a base58-encoded string (str) into a byte vector (vchRet).
+ * return true if decoding is successful.
+ */
+bool DecodeBase58(const std::string& str, std::vector<unsigned char>& vchRet);
+
+/**
+ * Encode a byte vector into a base58-encoded string, including checksum
+ */
+std::string EncodeBase58Check(const std::vector<unsigned char>& vchIn);
+
+/**
+ * Decode a base58-encoded string (psz) that includes a checksum into a byte
+ * vector (vchRet), return true if decoding is successful
+ */
+inline bool DecodeBase58Check(const char* psz, std::vector<unsigned char>& vchRet);
+
+/**
+ * Decode a base58-encoded string (str) that includes a checksum into a byte
+ * vector (vchRet), return true if decoding is successful
+ */
+inline bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRet);
+
+/**
+ * Base class for all base58-encoded data
+ */
+class CBase58Data
+{
+protected:
+ //! the version byte(s)
+ std::vector<unsigned char> vchVersion;
+
+ //! the actually encoded data
+ typedef std::vector<unsigned char, zero_after_free_allocator<unsigned char> > vector_uchar;
+ vector_uchar vchData;
+
+ CBase58Data();
+ void SetData(const std::vector<unsigned char> &vchVersionIn, const void* pdata, size_t nSize);
+ void SetData(const std::vector<unsigned char> &vchVersionIn, const unsigned char *pbegin, const unsigned char *pend);
+
+public:
+ bool SetString(const char* psz, unsigned int nVersionBytes = 1);
+ bool SetString(const std::string& str);
+ std::string ToString() const;
+ int CompareTo(const CBase58Data& b58) const;
+
+ 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 : public CBase58Data {
+public:
+ bool Set(const CKeyID &id);
+ bool Set(const CScriptID &id);
+ bool Set(const CTxDestination &dest);
+ bool IsValid() const;
+ bool IsValid(const CChainParams &params) const;
+
+ CBitcoinAddress() {}
+ CBitcoinAddress(const CTxDestination &dest) { Set(dest); }
+ CBitcoinAddress(const std::string& strAddress) { SetString(strAddress); }
+ CBitcoinAddress(const char* pszAddress) { SetString(pszAddress); }
+
+ CTxDestination Get() const;
+ bool GetKeyID(CKeyID &keyID) const;
+ bool IsScript() const;
+};
+
+/**
+ * A base58-encoded secret key
+ */
+class CBitcoinSecret : public CBase58Data
+{
+public:
+ void SetKey(const CKey& vchSecret);
+ CKey GetKey();
+ bool IsValid() const;
+ bool SetString(const char* pszSecret);
+ bool SetString(const std::string& strSecret);
+
+ CBitcoinSecret(const CKey& vchSecret) { SetKey(vchSecret); }
+ CBitcoinSecret() {}
+};
+
+template<typename K, int Size, CChainParams::Base58Type Type> class CBitcoinExtKeyBase : public CBase58Data
+{
+public:
+ void SetKey(const K &key) {
+ unsigned char vch[Size];
+ key.Encode(vch);
+ SetData(Params().Base58Prefix(Type), vch, vch+Size);
+ }
+
+ K GetKey() {
+ K ret;
+ ret.Decode(&vchData[0], &vchData[Size]);
+ return ret;
+ }
+
+ CBitcoinExtKeyBase(const K &key) {
+ SetKey(key);
+ }
+
+ CBitcoinExtKeyBase() {}
+};
+
+typedef CBitcoinExtKeyBase<CExtKey, 74, CChainParams::EXT_SECRET_KEY> CBitcoinExtKey;
+typedef CBitcoinExtKeyBase<CExtPubKey, 74, CChainParams::EXT_PUBLIC_KEY> CBitcoinExtPubKey;
+
+#endif // BITCOIN_BASE58_H
diff --git a/src/bitcoin-cli-res.rc b/src/bitcoin-cli-res.rc
new file mode 100644
index 0000000000..1e4aa609bb
--- /dev/null
+++ b/src/bitcoin-cli-res.rc
@@ -0,0 +1,35 @@
+#include <windows.h> // needed for VERSIONINFO
+#include "clientversion.h" // holds the needed client version information
+
+#define VER_PRODUCTVERSION CLIENT_VERSION_MAJOR,CLIENT_VERSION_MINOR,CLIENT_VERSION_REVISION,CLIENT_VERSION_BUILD
+#define VER_PRODUCTVERSION_STR STRINGIZE(CLIENT_VERSION_MAJOR) "." STRINGIZE(CLIENT_VERSION_MINOR) "." STRINGIZE(CLIENT_VERSION_REVISION) "." STRINGIZE(CLIENT_VERSION_BUILD)
+#define VER_FILEVERSION VER_PRODUCTVERSION
+#define VER_FILEVERSION_STR VER_PRODUCTVERSION_STR
+
+VS_VERSION_INFO VERSIONINFO
+FILEVERSION VER_FILEVERSION
+PRODUCTVERSION VER_PRODUCTVERSION
+FILEOS VOS_NT_WINDOWS32
+FILETYPE VFT_APP
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904E4" // U.S. English - multilingual (hex)
+ BEGIN
+ VALUE "CompanyName", "Bitcoin"
+ VALUE "FileDescription", "bitcoin-cli (JSON-RPC client for Bitcoin Core)"
+ VALUE "FileVersion", VER_FILEVERSION_STR
+ VALUE "InternalName", "bitcoin-cli"
+ VALUE "LegalCopyright", COPYRIGHT_STR
+ VALUE "LegalTrademarks1", "Distributed under the MIT software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php."
+ VALUE "OriginalFilename", "bitcoin-cli.exe"
+ VALUE "ProductName", "bitcoin-cli"
+ VALUE "ProductVersion", VER_PRODUCTVERSION_STR
+ END
+ END
+
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0, 1252 // language neutral - multilingual (decimal)
+ END
+END
diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp
new file mode 100644
index 0000000000..1269d7a119
--- /dev/null
+++ b/src/bitcoin-cli.cpp
@@ -0,0 +1,257 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "chainparamsbase.h"
+#include "clientversion.h"
+#include "rpcclient.h"
+#include "rpcprotocol.h"
+#include "util.h"
+#include "utilstrencodings.h"
+
+#include <boost/filesystem/operations.hpp>
+
+using namespace std;
+using namespace json_spirit;
+
+std::string HelpMessageCli()
+{
+ string strUsage;
+ strUsage += HelpMessageGroup(_("Options:"));
+ strUsage += HelpMessageOpt("-?", _("This help message"));
+ strUsage += HelpMessageOpt("-conf=<file>", strprintf(_("Specify configuration file (default: %s)"), "bitcoin.conf"));
+ strUsage += HelpMessageOpt("-datadir=<dir>", _("Specify data directory"));
+ strUsage += HelpMessageOpt("-testnet", _("Use the test network"));
+ strUsage += HelpMessageOpt("-regtest", _("Enter regression test mode, which uses a special chain in which blocks can be "
+ "solved instantly. This is intended for regression testing tools and app development."));
+ strUsage += HelpMessageOpt("-rpcconnect=<ip>", strprintf(_("Send commands to node running on <ip> (default: %s)"), "127.0.0.1"));
+ strUsage += HelpMessageOpt("-rpcport=<port>", strprintf(_("Connect to JSON-RPC on <port> (default: %u or testnet: %u)"), 8332, 18332));
+ strUsage += HelpMessageOpt("-rpcwait", _("Wait for RPC server to start"));
+ strUsage += HelpMessageOpt("-rpcuser=<user>", _("Username for JSON-RPC connections"));
+ strUsage += HelpMessageOpt("-rpcpassword=<pw>", _("Password for JSON-RPC connections"));
+
+ strUsage += HelpMessageGroup(_("SSL options: (see the Bitcoin Wiki for SSL setup instructions)"));
+ strUsage += HelpMessageOpt("-rpcssl", _("Use OpenSSL (https) for JSON-RPC connections"));
+
+ return strUsage;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// Start
+//
+
+//
+// Exception thrown on connection error. This error is used to determine
+// when to wait if -rpcwait is given.
+//
+class CConnectionFailed : public std::runtime_error
+{
+public:
+
+ explicit inline CConnectionFailed(const std::string& msg) :
+ std::runtime_error(msg)
+ {}
+
+};
+
+static bool AppInitRPC(int argc, char* argv[])
+{
+ //
+ // Parameters
+ //
+ ParseParameters(argc, argv);
+ if (argc<2 || mapArgs.count("-?") || mapArgs.count("-help") || mapArgs.count("-version")) {
+ std::string strUsage = _("Bitcoin Core RPC client version") + " " + FormatFullVersion() + "\n";
+ if (!mapArgs.count("-version")) {
+ strUsage += "\n" + _("Usage:") + "\n" +
+ " bitcoin-cli [options] <command> [params] " + _("Send command to Bitcoin Core") + "\n" +
+ " bitcoin-cli [options] help " + _("List commands") + "\n" +
+ " bitcoin-cli [options] help <command> " + _("Get help for a command") + "\n";
+
+ strUsage += "\n" + HelpMessageCli();
+ }
+
+ fprintf(stdout, "%s", strUsage.c_str());
+ return false;
+ }
+ if (!boost::filesystem::is_directory(GetDataDir(false))) {
+ fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", mapArgs["-datadir"].c_str());
+ return false;
+ }
+ try {
+ ReadConfigFile(mapArgs, mapMultiArgs);
+ } catch (const std::exception& e) {
+ fprintf(stderr,"Error reading configuration file: %s\n", e.what());
+ return false;
+ }
+ // Check for -testnet or -regtest parameter (BaseParams() calls are only valid after this clause)
+ if (!SelectBaseParamsFromCommandLine()) {
+ fprintf(stderr, "Error: Invalid combination of -regtest and -testnet.\n");
+ return false;
+ }
+ return true;
+}
+
+Object CallRPC(const string& strMethod, const Array& params)
+{
+ if (mapArgs["-rpcuser"] == "" && mapArgs["-rpcpassword"] == "")
+ throw runtime_error(strprintf(
+ _("You must set rpcpassword=<password> in the configuration file:\n%s\n"
+ "If the file does not exist, create it with owner-readable-only file permissions."),
+ GetConfigFile().string().c_str()));
+
+ // Connect to localhost
+ bool fUseSSL = GetBoolArg("-rpcssl", false);
+ boost::asio::io_service io_service;
+ boost::asio::ssl::context context(io_service, boost::asio::ssl::context::sslv23);
+ context.set_options(boost::asio::ssl::context::no_sslv2 | boost::asio::ssl::context::no_sslv3);
+ boost::asio::ssl::stream<boost::asio::ip::tcp::socket> sslStream(io_service, context);
+ SSLIOStreamDevice<boost::asio::ip::tcp> d(sslStream, fUseSSL);
+ boost::iostreams::stream< SSLIOStreamDevice<boost::asio::ip::tcp> > stream(d);
+
+ const bool fConnected = d.connect(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", itostr(BaseParams().RPCPort())));
+ if (!fConnected)
+ throw CConnectionFailed("couldn't connect to server");
+
+ // HTTP basic authentication
+ string strUserPass64 = EncodeBase64(mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]);
+ map<string, string> mapRequestHeaders;
+ mapRequestHeaders["Authorization"] = string("Basic ") + strUserPass64;
+
+ // Send request
+ string strRequest = JSONRPCRequest(strMethod, params, 1);
+ string strPost = HTTPPost(strRequest, mapRequestHeaders);
+ stream << strPost << std::flush;
+
+ // Receive HTTP reply status
+ int nProto = 0;
+ int nStatus = ReadHTTPStatus(stream, nProto);
+
+ // Receive HTTP reply message headers and body
+ map<string, string> mapHeaders;
+ string strReply;
+ ReadHTTPMessage(stream, mapHeaders, strReply, nProto, std::numeric_limits<size_t>::max());
+
+ if (nStatus == HTTP_UNAUTHORIZED)
+ throw runtime_error("incorrect rpcuser or rpcpassword (authorization failed)");
+ else if (nStatus >= 400 && nStatus != HTTP_BAD_REQUEST && nStatus != HTTP_NOT_FOUND && nStatus != HTTP_INTERNAL_SERVER_ERROR)
+ 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;
+}
+
+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<std::string> strParams(&argv[2], &argv[argc]);
+ Array params = RPCConvertValues(strMethod, strParams);
+
+ // Execute and handle connection failures with -rpcwait
+ const bool fWait = GetBoolArg("-rpcwait", false);
+ do {
+ try {
+ const 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
+ const int code = find_value(error.get_obj(), "code").get_int();
+ if (fWait && code == RPC_IN_WARMUP)
+ throw CConnectionFailed("server in warmup");
+ strPrint = "error: " + write_string(error, false);
+ 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);
+ }
+
+ // Connection succeeded, no need to retry.
+ break;
+ }
+ catch (const CConnectionFailed&) {
+ if (fWait)
+ MilliSleep(1000);
+ else
+ throw;
+ }
+ } while (fWait);
+ }
+ catch (const boost::thread_interrupted&) {
+ throw;
+ }
+ catch (const std::exception& e) {
+ strPrint = string("error: ") + e.what();
+ nRet = EXIT_FAILURE;
+ }
+ catch (...) {
+ PrintExceptionContinue(NULL, "CommandLineRPC()");
+ throw;
+ }
+
+ if (strPrint != "") {
+ fprintf((nRet == 0 ? stdout : stderr), "%s\n", strPrint.c_str());
+ }
+ return nRet;
+}
+
+int main(int argc, char* argv[])
+{
+ SetupEnvironment();
+
+ try {
+ if(!AppInitRPC(argc, argv))
+ return EXIT_FAILURE;
+ }
+ catch (const std::exception& e) {
+ PrintExceptionContinue(&e, "AppInitRPC()");
+ return EXIT_FAILURE;
+ } catch (...) {
+ PrintExceptionContinue(NULL, "AppInitRPC()");
+ return EXIT_FAILURE;
+ }
+
+ int ret = EXIT_FAILURE;
+ try {
+ ret = CommandLineRPC(argc, argv);
+ }
+ catch (const std::exception& e) {
+ PrintExceptionContinue(&e, "CommandLineRPC()");
+ } catch (...) {
+ PrintExceptionContinue(NULL, "CommandLineRPC()");
+ }
+ return ret;
+}
diff --git a/src/bitcoin-tx-res.rc b/src/bitcoin-tx-res.rc
new file mode 100644
index 0000000000..3e49b820bc
--- /dev/null
+++ b/src/bitcoin-tx-res.rc
@@ -0,0 +1,35 @@
+#include <windows.h> // needed for VERSIONINFO
+#include "clientversion.h" // holds the needed client version information
+
+#define VER_PRODUCTVERSION CLIENT_VERSION_MAJOR,CLIENT_VERSION_MINOR,CLIENT_VERSION_REVISION,CLIENT_VERSION_BUILD
+#define VER_PRODUCTVERSION_STR STRINGIZE(CLIENT_VERSION_MAJOR) "." STRINGIZE(CLIENT_VERSION_MINOR) "." STRINGIZE(CLIENT_VERSION_REVISION) "." STRINGIZE(CLIENT_VERSION_BUILD)
+#define VER_FILEVERSION VER_PRODUCTVERSION
+#define VER_FILEVERSION_STR VER_PRODUCTVERSION_STR
+
+VS_VERSION_INFO VERSIONINFO
+FILEVERSION VER_FILEVERSION
+PRODUCTVERSION VER_PRODUCTVERSION
+FILEOS VOS_NT_WINDOWS32
+FILETYPE VFT_APP
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904E4" // U.S. English - multilingual (hex)
+ BEGIN
+ VALUE "CompanyName", "Bitcoin"
+ VALUE "FileDescription", "bitcoin-tx (CLI Bitcoin transaction editor utility)"
+ VALUE "FileVersion", VER_FILEVERSION_STR
+ VALUE "InternalName", "bitcoin-tx"
+ VALUE "LegalCopyright", COPYRIGHT_STR
+ VALUE "LegalTrademarks1", "Distributed under the MIT software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php."
+ VALUE "OriginalFilename", "bitcoin-tx.exe"
+ VALUE "ProductName", "bitcoin-tx"
+ VALUE "ProductVersion", VER_PRODUCTVERSION_STR
+ END
+ END
+
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0, 1252 // language neutral - multilingual (decimal)
+ END
+END
diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp
new file mode 100644
index 0000000000..40b4a38e41
--- /dev/null
+++ b/src/bitcoin-tx.cpp
@@ -0,0 +1,638 @@
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "base58.h"
+#include "clientversion.h"
+#include "coins.h"
+#include "consensus/consensus.h"
+#include "core_io.h"
+#include "keystore.h"
+#include "primitives/transaction.h"
+#include "script/script.h"
+#include "script/sign.h"
+#include "univalue/univalue.h"
+#include "util.h"
+#include "utilmoneystr.h"
+#include "utilstrencodings.h"
+
+#include <stdio.h>
+
+#include <boost/algorithm/string.hpp>
+#include <boost/assign/list_of.hpp>
+
+using namespace std;
+
+static bool fCreateBlank;
+static map<string,UniValue> registers;
+
+static bool AppInitRawTx(int argc, char* argv[])
+{
+ //
+ // Parameters
+ //
+ ParseParameters(argc, argv);
+
+ // Check for -testnet or -regtest parameter (Params() calls are only valid after this clause)
+ if (!SelectParamsFromCommandLine()) {
+ fprintf(stderr, "Error: Invalid combination of -regtest and -testnet.\n");
+ return false;
+ }
+
+ fCreateBlank = GetBoolArg("-create", false);
+
+ if (argc<2 || mapArgs.count("-?") || mapArgs.count("-help"))
+ {
+ // First part of help message is specific to this utility
+ std::string strUsage = _("Bitcoin Core bitcoin-tx utility version") + " " + FormatFullVersion() + "\n\n" +
+ _("Usage:") + "\n" +
+ " bitcoin-tx [options] <hex-tx> [commands] " + _("Update hex-encoded bitcoin transaction") + "\n" +
+ " bitcoin-tx [options] -create [commands] " + _("Create hex-encoded bitcoin transaction") + "\n" +
+ "\n";
+
+ fprintf(stdout, "%s", strUsage.c_str());
+
+ strUsage = HelpMessageGroup(_("Options:"));
+ strUsage += HelpMessageOpt("-?", _("This help message"));
+ strUsage += HelpMessageOpt("-create", _("Create new, empty TX."));
+ strUsage += HelpMessageOpt("-json", _("Select JSON output"));
+ strUsage += HelpMessageOpt("-txid", _("Output only the hex-encoded transaction id of the resultant transaction."));
+ strUsage += HelpMessageOpt("-regtest", _("Enter regression test mode, which uses a special chain in which blocks can be solved instantly."));
+ strUsage += HelpMessageOpt("-testnet", _("Use the test network"));
+
+ fprintf(stdout, "%s", strUsage.c_str());
+
+ strUsage = HelpMessageGroup(_("Commands:"));
+ strUsage += HelpMessageOpt("delin=N", _("Delete input N from TX"));
+ strUsage += HelpMessageOpt("delout=N", _("Delete output N from TX"));
+ strUsage += HelpMessageOpt("in=TXID:VOUT", _("Add input to TX"));
+ strUsage += HelpMessageOpt("locktime=N", _("Set TX lock time to N"));
+ strUsage += HelpMessageOpt("nversion=N", _("Set TX version to N"));
+ strUsage += HelpMessageOpt("outaddr=VALUE:ADDRESS", _("Add address-based output to TX"));
+ strUsage += HelpMessageOpt("outscript=VALUE:SCRIPT", _("Add raw script output to TX"));
+ strUsage += HelpMessageOpt("sign=SIGHASH-FLAGS", _("Add zero or more signatures to transaction") + ". " +
+ _("This command requires JSON registers:") +
+ _("prevtxs=JSON object") + ", " +
+ _("privatekeys=JSON object") + ". " +
+ _("See signrawtransaction docs for format of sighash flags, JSON objects."));
+ fprintf(stdout, "%s", strUsage.c_str());
+
+ strUsage = HelpMessageGroup(_("Register Commands:"));
+ strUsage += HelpMessageOpt("load=NAME:FILENAME", _("Load JSON file FILENAME into register NAME"));
+ strUsage += HelpMessageOpt("set=NAME:JSON-STRING", _("Set register NAME to given JSON-STRING"));
+ fprintf(stdout, "%s", strUsage.c_str());
+
+ return false;
+ }
+ return true;
+}
+
+static void RegisterSetJson(const string& key, const string& rawJson)
+{
+ UniValue val;
+ if (!val.read(rawJson)) {
+ string strErr = "Cannot parse JSON for key " + key;
+ throw runtime_error(strErr);
+ }
+
+ registers[key] = val;
+}
+
+static void RegisterSet(const string& strInput)
+{
+ // separate NAME:VALUE in string
+ size_t pos = strInput.find(':');
+ if ((pos == string::npos) ||
+ (pos == 0) ||
+ (pos == (strInput.size() - 1)))
+ throw runtime_error("Register input requires NAME:VALUE");
+
+ string key = strInput.substr(0, pos);
+ string valStr = strInput.substr(pos + 1, string::npos);
+
+ RegisterSetJson(key, valStr);
+}
+
+static void RegisterLoad(const string& strInput)
+{
+ // separate NAME:FILENAME in string
+ size_t pos = strInput.find(':');
+ if ((pos == string::npos) ||
+ (pos == 0) ||
+ (pos == (strInput.size() - 1)))
+ throw runtime_error("Register load requires NAME:FILENAME");
+
+ string key = strInput.substr(0, pos);
+ string filename = strInput.substr(pos + 1, string::npos);
+
+ FILE *f = fopen(filename.c_str(), "r");
+ if (!f) {
+ string strErr = "Cannot open file " + filename;
+ throw runtime_error(strErr);
+ }
+
+ // load file chunks into one big buffer
+ string valStr;
+ while ((!feof(f)) && (!ferror(f))) {
+ char buf[4096];
+ int bread = fread(buf, 1, sizeof(buf), f);
+ if (bread <= 0)
+ break;
+
+ valStr.insert(valStr.size(), buf, bread);
+ }
+
+ int error = ferror(f);
+ fclose(f);
+
+ if (error) {
+ string strErr = "Error reading file " + filename;
+ throw runtime_error(strErr);
+ }
+
+ // evaluate as JSON buffer register
+ RegisterSetJson(key, valStr);
+}
+
+static void MutateTxVersion(CMutableTransaction& tx, const string& cmdVal)
+{
+ int64_t newVersion = atoi64(cmdVal);
+ if (newVersion < 1 || newVersion > CTransaction::CURRENT_VERSION)
+ throw runtime_error("Invalid TX version requested");
+
+ tx.nVersion = (int) newVersion;
+}
+
+static void MutateTxLocktime(CMutableTransaction& tx, const string& cmdVal)
+{
+ int64_t newLocktime = atoi64(cmdVal);
+ if (newLocktime < 0LL || newLocktime > 0xffffffffLL)
+ throw runtime_error("Invalid TX locktime requested");
+
+ tx.nLockTime = (unsigned int) newLocktime;
+}
+
+static void MutateTxAddInput(CMutableTransaction& tx, const string& strInput)
+{
+ // separate TXID:VOUT in string
+ size_t pos = strInput.find(':');
+ if ((pos == string::npos) ||
+ (pos == 0) ||
+ (pos == (strInput.size() - 1)))
+ throw runtime_error("TX input missing separator");
+
+ // extract and validate TXID
+ string strTxid = strInput.substr(0, pos);
+ if ((strTxid.size() != 64) || !IsHex(strTxid))
+ throw runtime_error("invalid TX input txid");
+ uint256 txid(uint256S(strTxid));
+
+ static const unsigned int minTxOutSz = 9;
+ static const unsigned int maxVout = MAX_BLOCK_SIZE / minTxOutSz;
+
+ // extract and validate vout
+ string strVout = strInput.substr(pos + 1, string::npos);
+ int vout = atoi(strVout);
+ if ((vout < 0) || (vout > (int)maxVout))
+ throw runtime_error("invalid TX input vout");
+
+ // append to transaction input list
+ CTxIn txin(txid, vout);
+ tx.vin.push_back(txin);
+}
+
+static void MutateTxAddOutAddr(CMutableTransaction& tx, const string& strInput)
+{
+ // separate VALUE:ADDRESS in string
+ size_t pos = strInput.find(':');
+ if ((pos == string::npos) ||
+ (pos == 0) ||
+ (pos == (strInput.size() - 1)))
+ throw runtime_error("TX output missing separator");
+
+ // extract and validate VALUE
+ string strValue = strInput.substr(0, pos);
+ CAmount value;
+ if (!ParseMoney(strValue, value))
+ throw runtime_error("invalid TX output value");
+
+ // extract and validate ADDRESS
+ string strAddr = strInput.substr(pos + 1, string::npos);
+ CBitcoinAddress addr(strAddr);
+ if (!addr.IsValid())
+ throw runtime_error("invalid TX output address");
+
+ // build standard output script via GetScriptForDestination()
+ CScript scriptPubKey = GetScriptForDestination(addr.Get());
+
+ // construct TxOut, append to transaction output list
+ CTxOut txout(value, scriptPubKey);
+ tx.vout.push_back(txout);
+}
+
+static void MutateTxAddOutScript(CMutableTransaction& tx, const string& strInput)
+{
+ // separate VALUE:SCRIPT in string
+ size_t pos = strInput.find(':');
+ if ((pos == string::npos) ||
+ (pos == 0))
+ throw runtime_error("TX output missing separator");
+
+ // extract and validate VALUE
+ string strValue = strInput.substr(0, pos);
+ CAmount value;
+ if (!ParseMoney(strValue, value))
+ throw runtime_error("invalid TX output value");
+
+ // extract and validate script
+ string strScript = strInput.substr(pos + 1, string::npos);
+ CScript scriptPubKey = ParseScript(strScript); // throws on err
+
+ // construct TxOut, append to transaction output list
+ CTxOut txout(value, scriptPubKey);
+ tx.vout.push_back(txout);
+}
+
+static void MutateTxDelInput(CMutableTransaction& tx, const string& strInIdx)
+{
+ // parse requested deletion index
+ int inIdx = atoi(strInIdx);
+ if (inIdx < 0 || inIdx >= (int)tx.vin.size()) {
+ string strErr = "Invalid TX input index '" + strInIdx + "'";
+ throw runtime_error(strErr.c_str());
+ }
+
+ // delete input from transaction
+ tx.vin.erase(tx.vin.begin() + inIdx);
+}
+
+static void MutateTxDelOutput(CMutableTransaction& tx, const string& strOutIdx)
+{
+ // parse requested deletion index
+ int outIdx = atoi(strOutIdx);
+ if (outIdx < 0 || outIdx >= (int)tx.vout.size()) {
+ string strErr = "Invalid TX output index '" + strOutIdx + "'";
+ throw runtime_error(strErr.c_str());
+ }
+
+ // delete output from transaction
+ tx.vout.erase(tx.vout.begin() + outIdx);
+}
+
+static const unsigned int N_SIGHASH_OPTS = 6;
+static const struct {
+ const char *flagStr;
+ int flags;
+} sighashOptions[N_SIGHASH_OPTS] = {
+ {"ALL", SIGHASH_ALL},
+ {"NONE", SIGHASH_NONE},
+ {"SINGLE", SIGHASH_SINGLE},
+ {"ALL|ANYONECANPAY", SIGHASH_ALL|SIGHASH_ANYONECANPAY},
+ {"NONE|ANYONECANPAY", SIGHASH_NONE|SIGHASH_ANYONECANPAY},
+ {"SINGLE|ANYONECANPAY", SIGHASH_SINGLE|SIGHASH_ANYONECANPAY},
+};
+
+static bool findSighashFlags(int& flags, const string& flagStr)
+{
+ flags = 0;
+
+ for (unsigned int i = 0; i < N_SIGHASH_OPTS; i++) {
+ if (flagStr == sighashOptions[i].flagStr) {
+ flags = sighashOptions[i].flags;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+uint256 ParseHashUO(map<string,UniValue>& o, string strKey)
+{
+ if (!o.count(strKey))
+ return uint256();
+ return ParseHashUV(o[strKey], strKey);
+}
+
+vector<unsigned char> ParseHexUO(map<string,UniValue>& o, string strKey)
+{
+ if (!o.count(strKey)) {
+ vector<unsigned char> emptyVec;
+ return emptyVec;
+ }
+ return ParseHexUV(o[strKey], strKey);
+}
+
+static void MutateTxSign(CMutableTransaction& tx, const string& flagStr)
+{
+ int nHashType = SIGHASH_ALL;
+
+ if (flagStr.size() > 0)
+ if (!findSighashFlags(nHashType, flagStr))
+ throw runtime_error("unknown sighash flag/sign option");
+
+ vector<CTransaction> txVariants;
+ txVariants.push_back(tx);
+
+ // mergedTx will end up with all the signatures; it
+ // starts as a clone of the raw tx:
+ CMutableTransaction mergedTx(txVariants[0]);
+ bool fComplete = true;
+ CCoinsView viewDummy;
+ CCoinsViewCache view(&viewDummy);
+
+ if (!registers.count("privatekeys"))
+ throw runtime_error("privatekeys register variable must be set.");
+ bool fGivenKeys = false;
+ CBasicKeyStore tempKeystore;
+ UniValue keysObj = registers["privatekeys"];
+ fGivenKeys = true;
+
+ for (unsigned int kidx = 0; kidx < keysObj.count(); kidx++) {
+ if (!keysObj[kidx].isStr())
+ throw runtime_error("privatekey not a string");
+ CBitcoinSecret vchSecret;
+ bool fGood = vchSecret.SetString(keysObj[kidx].getValStr());
+ if (!fGood)
+ throw runtime_error("privatekey not valid");
+
+ CKey key = vchSecret.GetKey();
+ tempKeystore.AddKey(key);
+ }
+
+ // Add previous txouts given in the RPC call:
+ if (!registers.count("prevtxs"))
+ throw runtime_error("prevtxs register variable must be set.");
+ UniValue prevtxsObj = registers["prevtxs"];
+ {
+ for (unsigned int previdx = 0; previdx < prevtxsObj.count(); previdx++) {
+ UniValue prevOut = prevtxsObj[previdx];
+ if (!prevOut.isObject())
+ throw runtime_error("expected prevtxs internal object");
+
+ map<string,UniValue::VType> types = boost::assign::map_list_of("txid", UniValue::VSTR)("vout",UniValue::VNUM)("scriptPubKey",UniValue::VSTR);
+ if (!prevOut.checkObject(types))
+ throw runtime_error("prevtxs internal object typecheck fail");
+
+ uint256 txid = ParseHashUV(prevOut["txid"], "txid");
+
+ int nOut = atoi(prevOut["vout"].getValStr());
+ if (nOut < 0)
+ throw runtime_error("vout must be positive");
+
+ vector<unsigned char> pkData(ParseHexUV(prevOut["scriptPubKey"], "scriptPubKey"));
+ CScript scriptPubKey(pkData.begin(), pkData.end());
+
+ {
+ CCoinsModifier coins = view.ModifyCoins(txid);
+ if (coins->IsAvailable(nOut) && coins->vout[nOut].scriptPubKey != scriptPubKey) {
+ string err("Previous output scriptPubKey mismatch:\n");
+ err = err + coins->vout[nOut].scriptPubKey.ToString() + "\nvs:\n"+
+ scriptPubKey.ToString();
+ throw runtime_error(err);
+ }
+ if ((unsigned int)nOut >= coins->vout.size())
+ coins->vout.resize(nOut+1);
+ coins->vout[nOut].scriptPubKey = scriptPubKey;
+ coins->vout[nOut].nValue = 0; // we don't know the actual output value
+ }
+
+ // if redeemScript given and private keys given,
+ // add redeemScript to the tempKeystore so it can be signed:
+ if (fGivenKeys && scriptPubKey.IsPayToScriptHash() &&
+ prevOut.exists("redeemScript")) {
+ UniValue v = prevOut["redeemScript"];
+ vector<unsigned char> rsData(ParseHexUV(v, "redeemScript"));
+ CScript redeemScript(rsData.begin(), rsData.end());
+ tempKeystore.AddCScript(redeemScript);
+ }
+ }
+ }
+
+ const CKeyStore& keystore = tempKeystore;
+
+ bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE);
+
+ // Sign what we can:
+ for (unsigned int i = 0; i < mergedTx.vin.size(); i++) {
+ CTxIn& txin = mergedTx.vin[i];
+ const CCoins* coins = view.AccessCoins(txin.prevout.hash);
+ if (!coins || !coins->IsAvailable(txin.prevout.n)) {
+ fComplete = false;
+ continue;
+ }
+ const CScript& prevPubKey = coins->vout[txin.prevout.n].scriptPubKey;
+
+ txin.scriptSig.clear();
+ // Only sign SIGHASH_SINGLE if there's a corresponding output:
+ if (!fHashSingle || (i < mergedTx.vout.size()))
+ 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, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(&mergedTx, i)))
+ fComplete = false;
+ }
+
+ if (fComplete) {
+ // do nothing... for now
+ // perhaps store this for later optional JSON output
+ }
+
+ tx = mergedTx;
+}
+
+class Secp256k1Init
+{
+public:
+ Secp256k1Init() { ECC_Start(); }
+ ~Secp256k1Init() { ECC_Stop(); }
+};
+
+static void MutateTx(CMutableTransaction& tx, const string& command,
+ const string& commandVal)
+{
+ boost::scoped_ptr<Secp256k1Init> ecc;
+
+ if (command == "nversion")
+ MutateTxVersion(tx, commandVal);
+ else if (command == "locktime")
+ MutateTxLocktime(tx, commandVal);
+
+ else if (command == "delin")
+ MutateTxDelInput(tx, commandVal);
+ else if (command == "in")
+ MutateTxAddInput(tx, commandVal);
+
+ else if (command == "delout")
+ MutateTxDelOutput(tx, commandVal);
+ else if (command == "outaddr")
+ MutateTxAddOutAddr(tx, commandVal);
+ else if (command == "outscript")
+ MutateTxAddOutScript(tx, commandVal);
+
+ else if (command == "sign") {
+ if (!ecc) { ecc.reset(new Secp256k1Init()); }
+ MutateTxSign(tx, commandVal);
+ }
+
+ else if (command == "load")
+ RegisterLoad(commandVal);
+
+ else if (command == "set")
+ RegisterSet(commandVal);
+
+ else
+ throw runtime_error("unknown command");
+}
+
+static void OutputTxJSON(const CTransaction& tx)
+{
+ UniValue entry(UniValue::VOBJ);
+ TxToUniv(tx, uint256(), entry);
+
+ string jsonOutput = entry.write(4);
+ fprintf(stdout, "%s\n", jsonOutput.c_str());
+}
+
+static void OutputTxHash(const CTransaction& tx)
+{
+ string strHexHash = tx.GetHash().GetHex(); // the hex-encoded transaction hash (aka the transaction id)
+
+ fprintf(stdout, "%s\n", strHexHash.c_str());
+}
+
+static void OutputTxHex(const CTransaction& tx)
+{
+ string strHex = EncodeHexTx(tx);
+
+ fprintf(stdout, "%s\n", strHex.c_str());
+}
+
+static void OutputTx(const CTransaction& tx)
+{
+ if (GetBoolArg("-json", false))
+ OutputTxJSON(tx);
+ else if (GetBoolArg("-txid", false))
+ OutputTxHash(tx);
+ else
+ OutputTxHex(tx);
+}
+
+static string readStdin()
+{
+ char buf[4096];
+ string ret;
+
+ while (!feof(stdin)) {
+ size_t bread = fread(buf, 1, sizeof(buf), stdin);
+ ret.append(buf, bread);
+ if (bread < sizeof(buf))
+ break;
+ }
+
+ if (ferror(stdin))
+ throw runtime_error("error reading stdin");
+
+ boost::algorithm::trim_right(ret);
+
+ return ret;
+}
+
+static int CommandLineRawTx(int argc, char* argv[])
+{
+ string strPrint;
+ int nRet = 0;
+ try {
+ // Skip switches; Permit common stdin convention "-"
+ while (argc > 1 && IsSwitchChar(argv[1][0]) &&
+ (argv[1][1] != 0)) {
+ argc--;
+ argv++;
+ }
+
+ CTransaction txDecodeTmp;
+ int startArg;
+
+ if (!fCreateBlank) {
+ // require at least one param
+ if (argc < 2)
+ throw runtime_error("too few parameters");
+
+ // param: hex-encoded bitcoin transaction
+ string strHexTx(argv[1]);
+ if (strHexTx == "-") // "-" implies standard input
+ strHexTx = readStdin();
+
+ if (!DecodeHexTx(txDecodeTmp, strHexTx))
+ throw runtime_error("invalid transaction encoding");
+
+ startArg = 2;
+ } else
+ startArg = 1;
+
+ CMutableTransaction tx(txDecodeTmp);
+
+ for (int i = startArg; i < argc; i++) {
+ string arg = argv[i];
+ string key, value;
+ size_t eqpos = arg.find('=');
+ if (eqpos == string::npos)
+ key = arg;
+ else {
+ key = arg.substr(0, eqpos);
+ value = arg.substr(eqpos + 1);
+ }
+
+ MutateTx(tx, key, value);
+ }
+
+ OutputTx(tx);
+ }
+
+ catch (const boost::thread_interrupted&) {
+ throw;
+ }
+ catch (const std::exception& e) {
+ strPrint = string("error: ") + e.what();
+ nRet = EXIT_FAILURE;
+ }
+ catch (...) {
+ PrintExceptionContinue(NULL, "CommandLineRawTx()");
+ throw;
+ }
+
+ if (strPrint != "") {
+ fprintf((nRet == 0 ? stdout : stderr), "%s\n", strPrint.c_str());
+ }
+ return nRet;
+}
+
+int main(int argc, char* argv[])
+{
+ SetupEnvironment();
+
+ try {
+ if(!AppInitRawTx(argc, argv))
+ return EXIT_FAILURE;
+ }
+ catch (const std::exception& e) {
+ PrintExceptionContinue(&e, "AppInitRawTx()");
+ return EXIT_FAILURE;
+ } catch (...) {
+ PrintExceptionContinue(NULL, "AppInitRawTx()");
+ return EXIT_FAILURE;
+ }
+
+ int ret = EXIT_FAILURE;
+ try {
+ ret = CommandLineRawTx(argc, argv);
+ }
+ catch (const std::exception& e) {
+ PrintExceptionContinue(&e, "CommandLineRawTx()");
+ } catch (...) {
+ PrintExceptionContinue(NULL, "CommandLineRawTx()");
+ }
+ return ret;
+}
diff --git a/src/bitcoind-res.rc b/src/bitcoind-res.rc
new file mode 100644
index 0000000000..3a64acd5d1
--- /dev/null
+++ b/src/bitcoind-res.rc
@@ -0,0 +1,35 @@
+#include <windows.h> // needed for VERSIONINFO
+#include "clientversion.h" // holds the needed client version information
+
+#define VER_PRODUCTVERSION CLIENT_VERSION_MAJOR,CLIENT_VERSION_MINOR,CLIENT_VERSION_REVISION,CLIENT_VERSION_BUILD
+#define VER_PRODUCTVERSION_STR STRINGIZE(CLIENT_VERSION_MAJOR) "." STRINGIZE(CLIENT_VERSION_MINOR) "." STRINGIZE(CLIENT_VERSION_REVISION) "." STRINGIZE(CLIENT_VERSION_BUILD)
+#define VER_FILEVERSION VER_PRODUCTVERSION
+#define VER_FILEVERSION_STR VER_PRODUCTVERSION_STR
+
+VS_VERSION_INFO VERSIONINFO
+FILEVERSION VER_FILEVERSION
+PRODUCTVERSION VER_PRODUCTVERSION
+FILEOS VOS_NT_WINDOWS32
+FILETYPE VFT_APP
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904E4" // U.S. English - multilingual (hex)
+ BEGIN
+ VALUE "CompanyName", "Bitcoin"
+ VALUE "FileDescription", "bitcoind (Bitcoin node with a JSON-RPC server)"
+ VALUE "FileVersion", VER_FILEVERSION_STR
+ VALUE "InternalName", "bitcoind"
+ VALUE "LegalCopyright", COPYRIGHT_STR
+ VALUE "LegalTrademarks1", "Distributed under the MIT software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php."
+ VALUE "OriginalFilename", "bitcoind.exe"
+ VALUE "ProductName", "bitcoind"
+ VALUE "ProductVersion", VER_PRODUCTVERSION_STR
+ END
+ END
+
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0, 1252 // language neutral - multilingual (decimal)
+ END
+END
diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp
new file mode 100644
index 0000000000..cce687ac98
--- /dev/null
+++ b/src/bitcoind.cpp
@@ -0,0 +1,177 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "clientversion.h"
+#include "rpcserver.h"
+#include "init.h"
+#include "main.h"
+#include "noui.h"
+#include "scheduler.h"
+#include "util.h"
+
+#include <boost/algorithm/string/predicate.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/thread.hpp>
+
+/* Introduction text for doxygen: */
+
+/*! \mainpage Developer documentation
+ *
+ * \section intro_sec Introduction
+ *
+ * This is the developer documentation of the reference client for an experimental new digital currency called Bitcoin (https://www.bitcoin.org/),
+ * which enables instant payments to anyone, anywhere in the world. Bitcoin uses peer-to-peer technology to operate
+ * with no central authority: managing transactions and issuing money are carried out collectively by the network.
+ *
+ * The software is a community-driven open source project, released under the MIT license.
+ *
+ * \section Navigation
+ * Use the buttons <code>Namespaces</code>, <code>Classes</code> or <code>Files</code> at the top of the page to start navigating the code.
+ */
+
+static bool fDaemon;
+
+void WaitForShutdown(boost::thread_group* threadGroup)
+{
+ bool fShutdown = ShutdownRequested();
+ // Tell the main threads to shutdown.
+ while (!fShutdown)
+ {
+ MilliSleep(200);
+ fShutdown = ShutdownRequested();
+ }
+ if (threadGroup)
+ {
+ threadGroup->interrupt_all();
+ threadGroup->join_all();
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// Start
+//
+bool AppInit(int argc, char* argv[])
+{
+ boost::thread_group threadGroup;
+ CScheduler scheduler;
+
+ bool fRet = false;
+
+ //
+ // Parameters
+ //
+ // If Qt is used, parameters/bitcoin.conf are parsed in qt/bitcoin.cpp's main()
+ ParseParameters(argc, argv);
+
+ // Process help and version before taking care about datadir
+ if (mapArgs.count("-?") || mapArgs.count("-help") || mapArgs.count("-version"))
+ {
+ std::string strUsage = _("Bitcoin Core Daemon") + " " + _("version") + " " + FormatFullVersion() + "\n";
+
+ if (mapArgs.count("-version"))
+ {
+ strUsage += LicenseInfo();
+ }
+ else
+ {
+ strUsage += "\n" + _("Usage:") + "\n" +
+ " bitcoind [options] " + _("Start Bitcoin Core Daemon") + "\n";
+
+ strUsage += "\n" + HelpMessage(HMM_BITCOIND);
+ }
+
+ fprintf(stdout, "%s", strUsage.c_str());
+ return false;
+ }
+
+ try
+ {
+ if (!boost::filesystem::is_directory(GetDataDir(false)))
+ {
+ fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", mapArgs["-datadir"].c_str());
+ return false;
+ }
+ try
+ {
+ ReadConfigFile(mapArgs, mapMultiArgs);
+ } catch (const std::exception& e) {
+ fprintf(stderr,"Error reading configuration file: %s\n", e.what());
+ return false;
+ }
+ // Check for -testnet or -regtest parameter (Params() calls are only valid after this clause)
+ if (!SelectParamsFromCommandLine()) {
+ fprintf(stderr, "Error: Invalid combination of -regtest and -testnet.\n");
+ return false;
+ }
+
+ // Command-line RPC
+ bool fCommandLine = false;
+ for (int i = 1; i < argc; i++)
+ if (!IsSwitchChar(argv[i][0]) && !boost::algorithm::istarts_with(argv[i], "bitcoin:"))
+ fCommandLine = true;
+
+ if (fCommandLine)
+ {
+ fprintf(stderr, "Error: There is no RPC client functionality in bitcoind anymore. Use the bitcoin-cli utility instead.\n");
+ exit(1);
+ }
+#ifndef WIN32
+ fDaemon = GetBoolArg("-daemon", false);
+ if (fDaemon)
+ {
+ fprintf(stdout, "Bitcoin server starting\n");
+
+ // Daemonize
+ pid_t pid = fork();
+ if (pid < 0)
+ {
+ fprintf(stderr, "Error: fork() returned %d errno %d\n", pid, errno);
+ return false;
+ }
+ if (pid > 0) // Parent process, pid is child process id
+ {
+ return true;
+ }
+ // Child process falls through to rest of initialization
+
+ pid_t sid = setsid();
+ if (sid < 0)
+ fprintf(stderr, "Error: setsid() returned %d errno %d\n", sid, errno);
+ }
+#endif
+ SoftSetBoolArg("-server", true);
+
+ fRet = AppInit2(threadGroup, scheduler);
+ }
+ catch (const std::exception& e) {
+ PrintExceptionContinue(&e, "AppInit()");
+ } catch (...) {
+ PrintExceptionContinue(NULL, "AppInit()");
+ }
+
+ if (!fRet)
+ {
+ threadGroup.interrupt_all();
+ // threadGroup.join_all(); was left out intentionally here, because we didn't re-test all of
+ // the startup-failure cases to make sure they don't result in a hang due to some
+ // thread-blocking-waiting-for-another-thread-during-startup case
+ } else {
+ WaitForShutdown(&threadGroup);
+ }
+ Shutdown();
+
+ return fRet;
+}
+
+int main(int argc, char* argv[])
+{
+ SetupEnvironment();
+
+ // Connect bitcoind signal handlers
+ noui_connect();
+
+ return (AppInit(argc, argv) ? 0 : 1);
+}
diff --git a/src/bloom.cpp b/src/bloom.cpp
new file mode 100644
index 0000000000..de87206592
--- /dev/null
+++ b/src/bloom.cpp
@@ -0,0 +1,272 @@
+// Copyright (c) 2012-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "bloom.h"
+
+#include "primitives/transaction.h"
+#include "hash.h"
+#include "script/script.h"
+#include "script/standard.h"
+#include "random.h"
+#include "streams.h"
+
+#include <math.h>
+#include <stdlib.h>
+
+#include <boost/foreach.hpp>
+
+#define LN2SQUARED 0.4804530139182014246671025263266649717305529515945455
+#define LN2 0.6931471805599453094172321214581765680755001343602552
+
+using namespace std;
+
+CBloomFilter::CBloomFilter(unsigned int nElements, double nFPRate, unsigned int nTweakIn, unsigned char nFlagsIn) :
+ /**
+ * The ideal size for a bloom filter with a given number of elements and false positive rate is:
+ * - nElements * log(fp rate) / ln(2)^2
+ * We ignore filter parameters which will create a bloom filter larger than the protocol limits
+ */
+ vData(min((unsigned int)(-1 / LN2SQUARED * nElements * log(nFPRate)), MAX_BLOOM_FILTER_SIZE * 8) / 8),
+ /**
+ * The ideal number of hash functions is filter size * ln(2) / number of elements
+ * Again, we ignore filter parameters which will create a bloom filter with more hash functions than the protocol limits
+ * See https://en.wikipedia.org/wiki/Bloom_filter for an explanation of these formulas
+ */
+ isFull(false),
+ isEmpty(false),
+ nHashFuncs(min((unsigned int)(vData.size() * 8 / nElements * LN2), MAX_HASH_FUNCS)),
+ nTweak(nTweakIn),
+ nFlags(nFlagsIn)
+{
+}
+
+// Private constructor used by CRollingBloomFilter
+CBloomFilter::CBloomFilter(unsigned int nElements, double nFPRate, unsigned int nTweakIn) :
+ vData((unsigned int)(-1 / LN2SQUARED * nElements * log(nFPRate)) / 8),
+ isFull(false),
+ isEmpty(true),
+ nHashFuncs((unsigned int)(vData.size() * 8 / nElements * LN2)),
+ nTweak(nTweakIn),
+ nFlags(BLOOM_UPDATE_NONE)
+{
+}
+
+inline unsigned int CBloomFilter::Hash(unsigned int nHashNum, const std::vector<unsigned char>& vDataToHash) const
+{
+ // 0xFBA4C795 chosen as it guarantees a reasonable bit difference between nHashNum values.
+ return MurmurHash3(nHashNum * 0xFBA4C795 + nTweak, vDataToHash) % (vData.size() * 8);
+}
+
+void CBloomFilter::insert(const vector<unsigned char>& vKey)
+{
+ if (isFull)
+ return;
+ for (unsigned int i = 0; i < nHashFuncs; i++)
+ {
+ unsigned int nIndex = Hash(i, vKey);
+ // Sets bit nIndex of vData
+ vData[nIndex >> 3] |= (1 << (7 & nIndex));
+ }
+ isEmpty = false;
+}
+
+void CBloomFilter::insert(const COutPoint& outpoint)
+{
+ CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
+ stream << outpoint;
+ vector<unsigned char> data(stream.begin(), stream.end());
+ insert(data);
+}
+
+void CBloomFilter::insert(const uint256& hash)
+{
+ vector<unsigned char> data(hash.begin(), hash.end());
+ insert(data);
+}
+
+bool CBloomFilter::contains(const vector<unsigned char>& vKey) const
+{
+ if (isFull)
+ return true;
+ if (isEmpty)
+ return false;
+ for (unsigned int i = 0; i < nHashFuncs; i++)
+ {
+ unsigned int nIndex = Hash(i, vKey);
+ // Checks bit nIndex of vData
+ if (!(vData[nIndex >> 3] & (1 << (7 & nIndex))))
+ return false;
+ }
+ return true;
+}
+
+bool CBloomFilter::contains(const COutPoint& outpoint) const
+{
+ CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
+ stream << outpoint;
+ vector<unsigned char> data(stream.begin(), stream.end());
+ return contains(data);
+}
+
+bool CBloomFilter::contains(const uint256& hash) const
+{
+ vector<unsigned char> data(hash.begin(), hash.end());
+ return contains(data);
+}
+
+void CBloomFilter::clear()
+{
+ vData.assign(vData.size(),0);
+ isFull = false;
+ isEmpty = true;
+}
+
+void CBloomFilter::reset(unsigned int nNewTweak)
+{
+ clear();
+ nTweak = nNewTweak;
+}
+
+bool CBloomFilter::IsWithinSizeConstraints() const
+{
+ return vData.size() <= MAX_BLOOM_FILTER_SIZE && nHashFuncs <= MAX_HASH_FUNCS;
+}
+
+bool CBloomFilter::IsRelevantAndUpdate(const CTransaction& tx)
+{
+ bool fFound = false;
+ // Match if the filter contains the hash of tx
+ // for finding tx when they appear in a block
+ if (isFull)
+ return true;
+ if (isEmpty)
+ return false;
+ const uint256& hash = tx.GetHash();
+ if (contains(hash))
+ fFound = true;
+
+ for (unsigned int i = 0; i < tx.vout.size(); i++)
+ {
+ const CTxOut& txout = tx.vout[i];
+ // Match if the filter contains any arbitrary script data element in any scriptPubKey in tx
+ // If this matches, also add the specific output that was matched.
+ // This means clients don't have to update the filter themselves when a new relevant tx
+ // is discovered in order to find spending transactions, which avoids round-tripping and race conditions.
+ CScript::const_iterator pc = txout.scriptPubKey.begin();
+ vector<unsigned char> data;
+ while (pc < txout.scriptPubKey.end())
+ {
+ opcodetype opcode;
+ if (!txout.scriptPubKey.GetOp(pc, opcode, data))
+ break;
+ if (data.size() != 0 && contains(data))
+ {
+ fFound = true;
+ if ((nFlags & BLOOM_UPDATE_MASK) == BLOOM_UPDATE_ALL)
+ insert(COutPoint(hash, i));
+ else if ((nFlags & BLOOM_UPDATE_MASK) == BLOOM_UPDATE_P2PUBKEY_ONLY)
+ {
+ txnouttype type;
+ vector<vector<unsigned char> > vSolutions;
+ if (Solver(txout.scriptPubKey, type, vSolutions) &&
+ (type == TX_PUBKEY || type == TX_MULTISIG))
+ insert(COutPoint(hash, i));
+ }
+ break;
+ }
+ }
+ }
+
+ if (fFound)
+ return true;
+
+ BOOST_FOREACH(const CTxIn& txin, tx.vin)
+ {
+ // Match if the filter contains an outpoint tx spends
+ if (contains(txin.prevout))
+ return true;
+
+ // Match if the filter contains any arbitrary script data element in any scriptSig in tx
+ CScript::const_iterator pc = txin.scriptSig.begin();
+ vector<unsigned char> data;
+ while (pc < txin.scriptSig.end())
+ {
+ opcodetype opcode;
+ if (!txin.scriptSig.GetOp(pc, opcode, data))
+ break;
+ if (data.size() != 0 && contains(data))
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void CBloomFilter::UpdateEmptyFull()
+{
+ bool full = true;
+ bool empty = true;
+ for (unsigned int i = 0; i < vData.size(); i++)
+ {
+ full &= vData[i] == 0xff;
+ empty &= vData[i] == 0;
+ }
+ isFull = full;
+ isEmpty = empty;
+}
+
+CRollingBloomFilter::CRollingBloomFilter(unsigned int nElements, double fpRate) :
+ b1(nElements * 2, fpRate, 0), b2(nElements * 2, fpRate, 0)
+{
+ // Implemented using two bloom filters of 2 * nElements each.
+ // We fill them up, and clear them, staggered, every nElements
+ // inserted, so at least one always contains the last nElements
+ // inserted.
+ nInsertions = 0;
+ nBloomSize = nElements * 2;
+
+ reset();
+}
+
+void CRollingBloomFilter::insert(const std::vector<unsigned char>& vKey)
+{
+ if (nInsertions == 0) {
+ b1.clear();
+ } else if (nInsertions == nBloomSize / 2) {
+ b2.clear();
+ }
+ b1.insert(vKey);
+ b2.insert(vKey);
+ if (++nInsertions == nBloomSize) {
+ nInsertions = 0;
+ }
+}
+
+void CRollingBloomFilter::insert(const uint256& hash)
+{
+ vector<unsigned char> data(hash.begin(), hash.end());
+ insert(data);
+}
+
+bool CRollingBloomFilter::contains(const std::vector<unsigned char>& vKey) const
+{
+ if (nInsertions < nBloomSize / 2) {
+ return b2.contains(vKey);
+ }
+ return b1.contains(vKey);
+}
+
+bool CRollingBloomFilter::contains(const uint256& hash) const
+{
+ vector<unsigned char> data(hash.begin(), hash.end());
+ return contains(data);
+}
+
+void CRollingBloomFilter::reset()
+{
+ unsigned int nNewTweak = GetRand(std::numeric_limits<unsigned int>::max());
+ b1.reset(nNewTweak);
+ b2.reset(nNewTweak);
+ nInsertions = 0;
+}
diff --git a/src/bloom.h b/src/bloom.h
new file mode 100644
index 0000000000..a4dba8cb4f
--- /dev/null
+++ b/src/bloom.h
@@ -0,0 +1,138 @@
+// Copyright (c) 2012-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_BLOOM_H
+#define BITCOIN_BLOOM_H
+
+#include "serialize.h"
+
+#include <vector>
+
+class COutPoint;
+class CTransaction;
+class uint256;
+
+//! 20,000 items with fp rate < 0.1% or 10,000 items and <0.0001%
+static const unsigned int MAX_BLOOM_FILTER_SIZE = 36000; // bytes
+static const unsigned int MAX_HASH_FUNCS = 50;
+
+/**
+ * First two bits of nFlags control how much IsRelevantAndUpdate actually updates
+ * The remaining bits are reserved
+ */
+enum bloomflags
+{
+ BLOOM_UPDATE_NONE = 0,
+ BLOOM_UPDATE_ALL = 1,
+ // Only adds outpoints to the filter if the output is a pay-to-pubkey/pay-to-multisig script
+ BLOOM_UPDATE_P2PUBKEY_ONLY = 2,
+ BLOOM_UPDATE_MASK = 3,
+};
+
+/**
+ * BloomFilter is a probabilistic filter which SPV clients provide
+ * so that we can filter the transactions we send them.
+ *
+ * This allows for significantly more efficient transaction and block downloads.
+ *
+ * Because bloom filters are probabilistic, a SPV node can increase the false-
+ * positive rate, making us send it transactions which aren't actually its,
+ * allowing clients to trade more bandwidth for more privacy by obfuscating which
+ * keys are controlled by them.
+ */
+class CBloomFilter
+{
+private:
+ std::vector<unsigned char> vData;
+ bool isFull;
+ bool isEmpty;
+ unsigned int nHashFuncs;
+ unsigned int nTweak;
+ unsigned char nFlags;
+
+ unsigned int Hash(unsigned int nHashNum, const std::vector<unsigned char>& vDataToHash) const;
+
+ // Private constructor for CRollingBloomFilter, no restrictions on size
+ CBloomFilter(unsigned int nElements, double nFPRate, unsigned int nTweak);
+ friend class CRollingBloomFilter;
+
+public:
+ /**
+ * Creates a new bloom filter which will provide the given fp rate when filled with the given number of elements
+ * Note that if the given parameters will result in a filter outside the bounds of the protocol limits,
+ * the filter created will be as close to the given parameters as possible within the protocol limits.
+ * This will apply if nFPRate is very low or nElements is unreasonably high.
+ * nTweak is a constant which is added to the seed value passed to the hash function
+ * It should generally always be a random value (and is largely only exposed for unit testing)
+ * nFlags should be one of the BLOOM_UPDATE_* enums (not _MASK)
+ */
+ CBloomFilter(unsigned int nElements, double nFPRate, unsigned int nTweak, unsigned char nFlagsIn);
+ CBloomFilter() : isFull(true), isEmpty(false), nHashFuncs(0), nTweak(0), nFlags(0) {}
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ READWRITE(vData);
+ READWRITE(nHashFuncs);
+ READWRITE(nTweak);
+ READWRITE(nFlags);
+ }
+
+ void insert(const std::vector<unsigned char>& vKey);
+ void insert(const COutPoint& outpoint);
+ void insert(const uint256& hash);
+
+ bool contains(const std::vector<unsigned char>& vKey) const;
+ bool contains(const COutPoint& outpoint) const;
+ bool contains(const uint256& hash) const;
+
+ void clear();
+ void reset(unsigned int nNewTweak);
+
+ //! True if the size is <= MAX_BLOOM_FILTER_SIZE and the number of hash functions is <= MAX_HASH_FUNCS
+ //! (catch a filter which was just deserialized which was too big)
+ bool IsWithinSizeConstraints() const;
+
+ //! Also adds any outputs which match the filter to the filter (to match their spending txes)
+ bool IsRelevantAndUpdate(const CTransaction& tx);
+
+ //! Checks for empty and full filters to avoid wasting cpu
+ void UpdateEmptyFull();
+};
+
+/**
+ * RollingBloomFilter is a probabilistic "keep track of most recently inserted" set.
+ * Construct it with the number of items to keep track of, and a false-positive
+ * rate. Unlike CBloomFilter, by default nTweak is set to a cryptographically
+ * secure random value for you. Similarly rather than clear() the method
+ * reset() is provided, which also changes nTweak to decrease the impact of
+ * false-positives.
+ *
+ * contains(item) will always return true if item was one of the last N things
+ * insert()'ed ... but may also return true for items that were not inserted.
+ */
+class CRollingBloomFilter
+{
+public:
+ // A random bloom filter calls GetRand() at creation time.
+ // Don't create global CRollingBloomFilter objects, as they may be
+ // constructed before the randomizer is properly initialized.
+ CRollingBloomFilter(unsigned int nElements, double nFPRate);
+
+ void insert(const std::vector<unsigned char>& vKey);
+ void insert(const uint256& hash);
+ bool contains(const std::vector<unsigned char>& vKey) const;
+ bool contains(const uint256& hash) const;
+
+ void reset();
+
+private:
+ unsigned int nBloomSize;
+ unsigned int nInsertions;
+ CBloomFilter b1, b2;
+};
+
+
+#endif // BITCOIN_BLOOM_H
diff --git a/src/chain.cpp b/src/chain.cpp
new file mode 100644
index 0000000000..719256106e
--- /dev/null
+++ b/src/chain.cpp
@@ -0,0 +1,108 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "chain.h"
+
+using namespace std;
+
+/**
+ * CChain implementation
+ */
+void CChain::SetTip(CBlockIndex *pindex) {
+ if (pindex == NULL) {
+ vChain.clear();
+ return;
+ }
+ vChain.resize(pindex->nHeight + 1);
+ while (pindex && vChain[pindex->nHeight] != pindex) {
+ vChain[pindex->nHeight] = pindex;
+ pindex = pindex->pprev;
+ }
+}
+
+CBlockLocator CChain::GetLocator(const CBlockIndex *pindex) const {
+ int nStep = 1;
+ std::vector<uint256> vHave;
+ vHave.reserve(32);
+
+ if (!pindex)
+ pindex = Tip();
+ while (pindex) {
+ vHave.push_back(pindex->GetBlockHash());
+ // Stop when we have added the genesis block.
+ if (pindex->nHeight == 0)
+ break;
+ // Exponentially larger steps back, plus the genesis block.
+ int nHeight = std::max(pindex->nHeight - nStep, 0);
+ if (Contains(pindex)) {
+ // Use O(1) CChain index if possible.
+ pindex = (*this)[nHeight];
+ } else {
+ // Otherwise, use O(log n) skiplist.
+ pindex = pindex->GetAncestor(nHeight);
+ }
+ if (vHave.size() > 10)
+ nStep *= 2;
+ }
+
+ return CBlockLocator(vHave);
+}
+
+const CBlockIndex *CChain::FindFork(const CBlockIndex *pindex) const {
+ if (pindex->nHeight > Height())
+ pindex = pindex->GetAncestor(Height());
+ while (pindex && !Contains(pindex))
+ pindex = pindex->pprev;
+ return pindex;
+}
+
+/** Turn the lowest '1' bit in the binary representation of a number into a '0'. */
+int static inline InvertLowestOne(int n) { return n & (n - 1); }
+
+/** Compute what height to jump back to with the CBlockIndex::pskip pointer. */
+int static inline GetSkipHeight(int height) {
+ if (height < 2)
+ return 0;
+
+ // Determine which height to jump back to. Any number strictly lower than height is acceptable,
+ // but the following expression seems to perform well in simulations (max 110 steps to go back
+ // up to 2**18 blocks).
+ return (height & 1) ? InvertLowestOne(InvertLowestOne(height - 1)) + 1 : InvertLowestOne(height);
+}
+
+CBlockIndex* CBlockIndex::GetAncestor(int height)
+{
+ if (height > nHeight || height < 0)
+ return NULL;
+
+ CBlockIndex* pindexWalk = this;
+ int heightWalk = nHeight;
+ while (heightWalk > height) {
+ int heightSkip = GetSkipHeight(heightWalk);
+ int heightSkipPrev = GetSkipHeight(heightWalk - 1);
+ if (heightSkip == height ||
+ (heightSkip > height && !(heightSkipPrev < heightSkip - 2 &&
+ heightSkipPrev >= height))) {
+ // Only follow pskip if pprev->pskip isn't better than pskip->pprev.
+ pindexWalk = pindexWalk->pskip;
+ heightWalk = heightSkip;
+ } else {
+ pindexWalk = pindexWalk->pprev;
+ heightWalk--;
+ }
+ }
+ return pindexWalk;
+}
+
+const CBlockIndex* CBlockIndex::GetAncestor(int height) const
+{
+ return const_cast<CBlockIndex*>(this)->GetAncestor(height);
+}
+
+void CBlockIndex::BuildSkip()
+{
+ if (pprev)
+ pskip = pprev->GetAncestor(GetSkipHeight(nHeight));
+}
diff --git a/src/chain.h b/src/chain.h
new file mode 100644
index 0000000000..01be2d6e5c
--- /dev/null
+++ b/src/chain.h
@@ -0,0 +1,406 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_CHAIN_H
+#define BITCOIN_CHAIN_H
+
+#include "arith_uint256.h"
+#include "primitives/block.h"
+#include "pow.h"
+#include "tinyformat.h"
+#include "uint256.h"
+
+#include <vector>
+
+#include <boost/foreach.hpp>
+
+struct CDiskBlockPos
+{
+ int nFile;
+ unsigned int nPos;
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ READWRITE(VARINT(nFile));
+ READWRITE(VARINT(nPos));
+ }
+
+ CDiskBlockPos() {
+ SetNull();
+ }
+
+ CDiskBlockPos(int nFileIn, unsigned int nPosIn) {
+ nFile = nFileIn;
+ nPos = nPosIn;
+ }
+
+ friend bool operator==(const CDiskBlockPos &a, const CDiskBlockPos &b) {
+ return (a.nFile == b.nFile && a.nPos == b.nPos);
+ }
+
+ friend bool operator!=(const CDiskBlockPos &a, const CDiskBlockPos &b) {
+ return !(a == b);
+ }
+
+ void SetNull() { nFile = -1; nPos = 0; }
+ bool IsNull() const { return (nFile == -1); }
+
+ std::string ToString() const
+ {
+ return strprintf("CBlockDiskPos(nFile=%i, nPos=%i)", nFile, nPos);
+ }
+
+};
+
+enum BlockStatus {
+ //! Unused.
+ BLOCK_VALID_UNKNOWN = 0,
+
+ //! Parsed, version ok, hash satisfies claimed PoW, 1 <= vtx count <= max, timestamp not in future
+ BLOCK_VALID_HEADER = 1,
+
+ //! All parent headers found, difficulty matches, timestamp >= median previous, checkpoint. Implies all parents
+ //! are also at least TREE.
+ BLOCK_VALID_TREE = 2,
+
+ /**
+ * Only first tx is coinbase, 2 <= coinbase input script length <= 100, transactions valid, no duplicate txids,
+ * sigops, size, merkle root. Implies all parents are at least TREE but not necessarily TRANSACTIONS. When all
+ * parent blocks also have TRANSACTIONS, CBlockIndex::nChainTx will be set.
+ */
+ BLOCK_VALID_TRANSACTIONS = 3,
+
+ //! Outputs do not overspend inputs, no double spends, coinbase output ok, no immature coinbase spends, BIP30.
+ //! Implies all parents are also at least CHAIN.
+ BLOCK_VALID_CHAIN = 4,
+
+ //! Scripts & signatures ok. Implies all parents are also at least SCRIPTS.
+ BLOCK_VALID_SCRIPTS = 5,
+
+ //! All validity bits.
+ BLOCK_VALID_MASK = BLOCK_VALID_HEADER | BLOCK_VALID_TREE | BLOCK_VALID_TRANSACTIONS |
+ BLOCK_VALID_CHAIN | BLOCK_VALID_SCRIPTS,
+
+ BLOCK_HAVE_DATA = 8, //! full block available in blk*.dat
+ BLOCK_HAVE_UNDO = 16, //! undo data available in rev*.dat
+ BLOCK_HAVE_MASK = BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO,
+
+ BLOCK_FAILED_VALID = 32, //! stage after last reached validness failed
+ BLOCK_FAILED_CHILD = 64, //! descends from failed block
+ BLOCK_FAILED_MASK = BLOCK_FAILED_VALID | BLOCK_FAILED_CHILD,
+};
+
+/** 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. A blockindex may have multiple pprev pointing
+ * to it, but at most one of them can be part of the currently active branch.
+ */
+class CBlockIndex
+{
+public:
+ //! pointer to the hash of the block, if any. Memory is owned by this CBlockIndex
+ const uint256* phashBlock;
+
+ //! pointer to the index of the predecessor of this block
+ CBlockIndex* pprev;
+
+ //! pointer to the index of some further predecessor of this block
+ CBlockIndex* pskip;
+
+ //! height of the entry in the chain. The genesis block has height 0
+ int nHeight;
+
+ //! Which # file this block is stored in (blk?????.dat)
+ int nFile;
+
+ //! Byte offset within blk?????.dat where this block's data is stored
+ unsigned int nDataPos;
+
+ //! Byte offset within rev?????.dat where this block's undo data is stored
+ unsigned int nUndoPos;
+
+ //! (memory only) Total amount of work (expected number of hashes) in the chain up to and including this block
+ arith_uint256 nChainWork;
+
+ //! Number of transactions in this block.
+ //! Note: in a potential headers-first mode, this number cannot be relied upon
+ unsigned int nTx;
+
+ //! (memory only) Number of transactions in the chain up to and including this block.
+ //! This value will be non-zero only if and only if transactions for this block and all its parents are available.
+ //! Change to 64-bit type when necessary; won't happen before 2030
+ unsigned int nChainTx;
+
+ //! Verification status of this block. See enum BlockStatus
+ unsigned int nStatus;
+
+ //! block header
+ int nVersion;
+ uint256 hashMerkleRoot;
+ unsigned int nTime;
+ unsigned int nBits;
+ unsigned int nNonce;
+
+ //! (memory only) Sequential id assigned to distinguish order in which blocks are received.
+ uint32_t nSequenceId;
+
+ void SetNull()
+ {
+ phashBlock = NULL;
+ pprev = NULL;
+ pskip = NULL;
+ nHeight = 0;
+ nFile = 0;
+ nDataPos = 0;
+ nUndoPos = 0;
+ nChainWork = arith_uint256();
+ nTx = 0;
+ nChainTx = 0;
+ nStatus = 0;
+ nSequenceId = 0;
+
+ nVersion = 0;
+ hashMerkleRoot = uint256();
+ nTime = 0;
+ nBits = 0;
+ nNonce = 0;
+ }
+
+ CBlockIndex()
+ {
+ SetNull();
+ }
+
+ CBlockIndex(const CBlockHeader& block)
+ {
+ SetNull();
+
+ nVersion = block.nVersion;
+ hashMerkleRoot = block.hashMerkleRoot;
+ nTime = block.nTime;
+ nBits = block.nBits;
+ nNonce = block.nNonce;
+ }
+
+ CDiskBlockPos GetBlockPos() const {
+ CDiskBlockPos ret;
+ if (nStatus & BLOCK_HAVE_DATA) {
+ ret.nFile = nFile;
+ ret.nPos = nDataPos;
+ }
+ return ret;
+ }
+
+ CDiskBlockPos GetUndoPos() const {
+ CDiskBlockPos ret;
+ if (nStatus & BLOCK_HAVE_UNDO) {
+ ret.nFile = nFile;
+ ret.nPos = nUndoPos;
+ }
+ return ret;
+ }
+
+ CBlockHeader GetBlockHeader() const
+ {
+ CBlockHeader 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_t GetBlockTime() const
+ {
+ return (int64_t)nTime;
+ }
+
+ enum { nMedianTimeSpan=11 };
+
+ int64_t GetMedianTimePast() const
+ {
+ int64_t pmedian[nMedianTimeSpan];
+ int64_t* pbegin = &pmedian[nMedianTimeSpan];
+ int64_t* 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];
+ }
+
+ std::string ToString() const
+ {
+ return strprintf("CBlockIndex(pprev=%p, nHeight=%d, merkle=%s, hashBlock=%s)",
+ pprev, nHeight,
+ hashMerkleRoot.ToString(),
+ GetBlockHash().ToString());
+ }
+
+ //! Check whether this block index entry is valid up to the passed validity level.
+ bool IsValid(enum BlockStatus nUpTo = BLOCK_VALID_TRANSACTIONS) const
+ {
+ assert(!(nUpTo & ~BLOCK_VALID_MASK)); // Only validity flags allowed.
+ if (nStatus & BLOCK_FAILED_MASK)
+ return false;
+ return ((nStatus & BLOCK_VALID_MASK) >= nUpTo);
+ }
+
+ //! Raise the validity level of this block index entry.
+ //! Returns true if the validity was changed.
+ bool RaiseValidity(enum BlockStatus nUpTo)
+ {
+ assert(!(nUpTo & ~BLOCK_VALID_MASK)); // Only validity flags allowed.
+ if (nStatus & BLOCK_FAILED_MASK)
+ return false;
+ if ((nStatus & BLOCK_VALID_MASK) < nUpTo) {
+ nStatus = (nStatus & ~BLOCK_VALID_MASK) | nUpTo;
+ return true;
+ }
+ return false;
+ }
+
+ //! Build the skiplist pointer for this entry.
+ void BuildSkip();
+
+ //! Efficiently find an ancestor of this block.
+ CBlockIndex* GetAncestor(int height);
+ const CBlockIndex* GetAncestor(int height) const;
+};
+
+/** Used to marshal pointers into hashes for db storage. */
+class CDiskBlockIndex : public CBlockIndex
+{
+public:
+ uint256 hashPrev;
+
+ CDiskBlockIndex() {
+ hashPrev = uint256();
+ }
+
+ explicit CDiskBlockIndex(const CBlockIndex* pindex) : CBlockIndex(*pindex) {
+ hashPrev = (pprev ? pprev->GetBlockHash() : uint256());
+ }
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ if (!(nType & SER_GETHASH))
+ READWRITE(VARINT(nVersion));
+
+ READWRITE(VARINT(nHeight));
+ READWRITE(VARINT(nStatus));
+ READWRITE(VARINT(nTx));
+ if (nStatus & (BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO))
+ READWRITE(VARINT(nFile));
+ if (nStatus & BLOCK_HAVE_DATA)
+ READWRITE(VARINT(nDataPos));
+ if (nStatus & BLOCK_HAVE_UNDO)
+ READWRITE(VARINT(nUndoPos));
+
+ // block header
+ READWRITE(this->nVersion);
+ READWRITE(hashPrev);
+ READWRITE(hashMerkleRoot);
+ READWRITE(nTime);
+ READWRITE(nBits);
+ READWRITE(nNonce);
+ }
+
+ uint256 GetBlockHash() const
+ {
+ CBlockHeader 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)",
+ GetBlockHash().ToString(),
+ hashPrev.ToString());
+ return str;
+ }
+};
+
+/** An in-memory indexed chain of blocks. */
+class CChain {
+private:
+ std::vector<CBlockIndex*> vChain;
+
+public:
+ /** Returns the index entry for the genesis block of this chain, or NULL if none. */
+ CBlockIndex *Genesis() const {
+ return vChain.size() > 0 ? vChain[0] : NULL;
+ }
+
+ /** Returns the index entry for the tip of this chain, or NULL if none. */
+ CBlockIndex *Tip() const {
+ return vChain.size() > 0 ? vChain[vChain.size() - 1] : NULL;
+ }
+
+ /** Returns the index entry at a particular height in this chain, or NULL if no such height exists. */
+ CBlockIndex *operator[](int nHeight) const {
+ if (nHeight < 0 || nHeight >= (int)vChain.size())
+ return NULL;
+ return vChain[nHeight];
+ }
+
+ /** Compare two chains efficiently. */
+ friend bool operator==(const CChain &a, const CChain &b) {
+ return a.vChain.size() == b.vChain.size() &&
+ a.vChain[a.vChain.size() - 1] == b.vChain[b.vChain.size() - 1];
+ }
+
+ /** Efficiently check whether a block is present in this chain. */
+ bool Contains(const CBlockIndex *pindex) const {
+ return (*this)[pindex->nHeight] == pindex;
+ }
+
+ /** Find the successor of a block in this chain, or NULL if the given index is not found or is the tip. */
+ CBlockIndex *Next(const CBlockIndex *pindex) const {
+ if (Contains(pindex))
+ return (*this)[pindex->nHeight + 1];
+ else
+ return NULL;
+ }
+
+ /** Return the maximal height in the chain. Is equal to chain.Tip() ? chain.Tip()->nHeight : -1. */
+ int Height() const {
+ return vChain.size() - 1;
+ }
+
+ /** Set/initialize a chain with a given tip. */
+ void SetTip(CBlockIndex *pindex);
+
+ /** Return a CBlockLocator that refers to a block in this chain (by default the tip). */
+ CBlockLocator GetLocator(const CBlockIndex *pindex = NULL) const;
+
+ /** Find the last common block between this chain and a block index entry. */
+ const CBlockIndex *FindFork(const CBlockIndex *pindex) const;
+};
+
+#endif // BITCOIN_CHAIN_H
diff --git a/src/chainparams.cpp b/src/chainparams.cpp
new file mode 100644
index 0000000000..5f400b265c
--- /dev/null
+++ b/src/chainparams.cpp
@@ -0,0 +1,272 @@
+// Copyright (c) 2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "chainparams.h"
+
+#include "util.h"
+#include "utilstrencodings.h"
+
+#include <assert.h>
+
+#include <boost/assign/list_of.hpp>
+
+using namespace std;
+
+#include "chainparamsseeds.h"
+
+/**
+ * Main network
+ */
+/**
+ * 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
+ */
+
+class CMainParams : public CChainParams {
+public:
+ CMainParams() {
+ strNetworkID = "main";
+ consensus.nSubsidyHalvingInterval = 210000;
+ consensus.nMajorityEnforceBlockUpgrade = 750;
+ consensus.nMajorityRejectBlockOutdated = 950;
+ consensus.nMajorityWindow = 1000;
+ consensus.powLimit = uint256S("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
+ consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks
+ consensus.nPowTargetSpacing = 10 * 60;
+ consensus.fPowAllowMinDifficultyBlocks = false;
+ /**
+ * 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 32-bit integer with any alignment.
+ */
+ pchMessageStart[0] = 0xf9;
+ pchMessageStart[1] = 0xbe;
+ pchMessageStart[2] = 0xb4;
+ pchMessageStart[3] = 0xd9;
+ vAlertPubKey = ParseHex("04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284");
+ nDefaultPort = 8333;
+ nMinerThreads = 0;
+ nPruneAfterHeight = 100000;
+
+ /**
+ * Build the genesis block. Note that the output of its generation
+ * transaction cannot be spent since it did not originally exist in the
+ * database.
+ *
+ * CBlock(hash=000000000019d6, ver=1, hashPrevBlock=00000000000000, hashMerkleRoot=4a5e1e, nTime=1231006505, nBits=1d00ffff, nNonce=2083236893, vtx=1)
+ * CTransaction(hash=4a5e1e, ver=1, vin.size=1, vout.size=1, nLockTime=0)
+ * CTxIn(COutPoint(000000, -1), coinbase 04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73)
+ * CTxOut(nValue=50.00000000, scriptPubKey=0x5F1DF16B2B704C8A578D0B)
+ * vMerkleTree: 4a5e1e
+ */
+ const char* pszTimestamp = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks";
+ CMutableTransaction txNew;
+ txNew.vin.resize(1);
+ txNew.vout.resize(1);
+ txNew.vin[0].scriptSig = CScript() << 486604799 << CScriptNum(4) << vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp));
+ txNew.vout[0].nValue = 50 * COIN;
+ txNew.vout[0].scriptPubKey = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG;
+ genesis.vtx.push_back(txNew);
+ genesis.hashPrevBlock.SetNull();
+ genesis.hashMerkleRoot = genesis.BuildMerkleTree();
+ genesis.nVersion = 1;
+ genesis.nTime = 1231006505;
+ genesis.nBits = 0x1d00ffff;
+ genesis.nNonce = 2083236893;
+
+ consensus.hashGenesisBlock = genesis.GetHash();
+ assert(consensus.hashGenesisBlock == uint256S("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"));
+ assert(genesis.hashMerkleRoot == uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"));
+
+ vSeeds.push_back(CDNSSeedData("bitcoin.sipa.be", "seed.bitcoin.sipa.be")); // Pieter Wuille
+ vSeeds.push_back(CDNSSeedData("bluematt.me", "dnsseed.bluematt.me")); // Matt Corallo
+ vSeeds.push_back(CDNSSeedData("dashjr.org", "dnsseed.bitcoin.dashjr.org")); // Luke Dashjr
+ vSeeds.push_back(CDNSSeedData("bitcoinstats.com", "seed.bitcoinstats.com")); // Christian Decker
+ vSeeds.push_back(CDNSSeedData("xf2.org", "bitseed.xf2.org")); // Jeff Garzik
+ vSeeds.push_back(CDNSSeedData("bitcoin.jonasschnelli.ch", "seed.bitcoin.jonasschnelli.ch")); // Jonas Schnelli
+
+ base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,0);
+ base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,5);
+ base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,128);
+ base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x88)(0xB2)(0x1E).convert_to_container<std::vector<unsigned char> >();
+ base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x88)(0xAD)(0xE4).convert_to_container<std::vector<unsigned char> >();
+
+ vFixedSeeds = std::vector<SeedSpec6>(pnSeed6_main, pnSeed6_main + ARRAYLEN(pnSeed6_main));
+
+ fRequireRPCPassword = true;
+ fMiningRequiresPeers = true;
+ fDefaultConsistencyChecks = false;
+ fRequireStandard = true;
+ fMineBlocksOnDemand = false;
+ fTestnetToBeDeprecatedFieldRPC = false;
+
+ checkpointData = (Checkpoints::CCheckpointData) {
+ boost::assign::map_list_of
+ ( 11111, uint256S("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d"))
+ ( 33333, uint256S("0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6"))
+ ( 74000, uint256S("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20"))
+ (105000, uint256S("0x00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97"))
+ (134444, uint256S("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe"))
+ (168000, uint256S("0x000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763"))
+ (193000, uint256S("0x000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317"))
+ (210000, uint256S("0x000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e"))
+ (216116, uint256S("0x00000000000001b4f4b433e81ee46494af945cf96014816a4e2370f11b23df4e"))
+ (225430, uint256S("0x00000000000001c108384350f74090433e7fcf79a606b8e797f065b130575932"))
+ (250000, uint256S("0x000000000000003887df1f29024b06fc2200b55f8af8f35453d7be294df2d214"))
+ (279000, uint256S("0x0000000000000001ae8c72a0b0c301f67e3afca10e819efa9041e458e9bd7e40"))
+ (295000, uint256S("0x00000000000000004d9b4ef50f0f9d686fd69db2e03af35a100370c64632a983")),
+ 1397080064, // * UNIX timestamp of last checkpoint block
+ 36544669, // * total number of transactions between genesis and last checkpoint
+ // (the tx=... number in the SetBestChain debug.log lines)
+ 60000.0 // * estimated number of transactions per day after checkpoint
+ };
+ }
+};
+static CMainParams mainParams;
+
+/**
+ * Testnet (v3)
+ */
+class CTestNetParams : public CMainParams {
+public:
+ CTestNetParams() {
+ strNetworkID = "test";
+ consensus.nMajorityEnforceBlockUpgrade = 51;
+ consensus.nMajorityRejectBlockOutdated = 75;
+ consensus.nMajorityWindow = 100;
+ consensus.fPowAllowMinDifficultyBlocks = true;
+ pchMessageStart[0] = 0x0b;
+ pchMessageStart[1] = 0x11;
+ pchMessageStart[2] = 0x09;
+ pchMessageStart[3] = 0x07;
+ vAlertPubKey = ParseHex("04302390343f91cc401d56d68b123028bf52e5fca1939df127f63c6467cdf9c8e2c14b61104cf817d0b780da337893ecc4aaff1309e536162dabbdb45200ca2b0a");
+ nDefaultPort = 18333;
+ nMinerThreads = 0;
+ nPruneAfterHeight = 1000;
+
+ //! Modify the testnet genesis block so the timestamp is valid for a later start.
+ genesis.nTime = 1296688602;
+ genesis.nNonce = 414098458;
+ consensus.hashGenesisBlock = genesis.GetHash();
+ assert(consensus.hashGenesisBlock == uint256S("0x000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943"));
+
+ vFixedSeeds.clear();
+ vSeeds.clear();
+ vSeeds.push_back(CDNSSeedData("alexykot.me", "testnet-seed.alexykot.me"));
+ vSeeds.push_back(CDNSSeedData("bitcoin.petertodd.org", "testnet-seed.bitcoin.petertodd.org"));
+ vSeeds.push_back(CDNSSeedData("bluematt.me", "testnet-seed.bluematt.me"));
+ vSeeds.push_back(CDNSSeedData("bitcoin.schildbach.de", "testnet-seed.bitcoin.schildbach.de"));
+
+ base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,111);
+ base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,196);
+ base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,239);
+ base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x35)(0x87)(0xCF).convert_to_container<std::vector<unsigned char> >();
+ base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x35)(0x83)(0x94).convert_to_container<std::vector<unsigned char> >();
+
+ vFixedSeeds = std::vector<SeedSpec6>(pnSeed6_test, pnSeed6_test + ARRAYLEN(pnSeed6_test));
+
+ fRequireRPCPassword = true;
+ fMiningRequiresPeers = true;
+ fDefaultConsistencyChecks = false;
+ fRequireStandard = false;
+ fMineBlocksOnDemand = false;
+ fTestnetToBeDeprecatedFieldRPC = true;
+
+ checkpointData = (Checkpoints::CCheckpointData) {
+ boost::assign::map_list_of
+ ( 546, uint256S("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70")),
+ 1337966069,
+ 1488,
+ 300
+ };
+
+ }
+};
+static CTestNetParams testNetParams;
+
+/**
+ * Regression test
+ */
+class CRegTestParams : public CTestNetParams {
+public:
+ CRegTestParams() {
+ strNetworkID = "regtest";
+ consensus.nSubsidyHalvingInterval = 150;
+ consensus.nMajorityEnforceBlockUpgrade = 750;
+ consensus.nMajorityRejectBlockOutdated = 950;
+ consensus.nMajorityWindow = 1000;
+ consensus.powLimit = uint256S("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
+ pchMessageStart[0] = 0xfa;
+ pchMessageStart[1] = 0xbf;
+ pchMessageStart[2] = 0xb5;
+ pchMessageStart[3] = 0xda;
+ nMinerThreads = 1;
+ genesis.nTime = 1296688602;
+ genesis.nBits = 0x207fffff;
+ genesis.nNonce = 2;
+ consensus.hashGenesisBlock = genesis.GetHash();
+ nDefaultPort = 18444;
+ assert(consensus.hashGenesisBlock == uint256S("0x0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206"));
+ nPruneAfterHeight = 1000;
+
+ vFixedSeeds.clear(); //! Regtest mode doesn't have any fixed seeds.
+ vSeeds.clear(); //! Regtest mode doesn't have any DNS seeds.
+
+ fRequireRPCPassword = false;
+ fMiningRequiresPeers = false;
+ fDefaultConsistencyChecks = true;
+ fRequireStandard = false;
+ fMineBlocksOnDemand = true;
+ fTestnetToBeDeprecatedFieldRPC = false;
+
+ checkpointData = (Checkpoints::CCheckpointData){
+ boost::assign::map_list_of
+ ( 0, uint256S("0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206")),
+ 0,
+ 0,
+ 0
+ };
+ }
+};
+static CRegTestParams regTestParams;
+
+static CChainParams *pCurrentParams = 0;
+
+const CChainParams &Params() {
+ assert(pCurrentParams);
+ return *pCurrentParams;
+}
+
+CChainParams &Params(CBaseChainParams::Network network) {
+ switch (network) {
+ case CBaseChainParams::MAIN:
+ return mainParams;
+ case CBaseChainParams::TESTNET:
+ return testNetParams;
+ case CBaseChainParams::REGTEST:
+ return regTestParams;
+ default:
+ assert(false && "Unimplemented network");
+ return mainParams;
+ }
+}
+
+void SelectParams(CBaseChainParams::Network network) {
+ SelectBaseParams(network);
+ pCurrentParams = &Params(network);
+}
+
+bool SelectParamsFromCommandLine()
+{
+ CBaseChainParams::Network network = NetworkIdFromCommandLine();
+ if (network == CBaseChainParams::MAX_NETWORK_TYPES)
+ return false;
+
+ SelectParams(network);
+ return true;
+}
diff --git a/src/chainparams.h b/src/chainparams.h
new file mode 100644
index 0000000000..8044b553e1
--- /dev/null
+++ b/src/chainparams.h
@@ -0,0 +1,116 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_CHAINPARAMS_H
+#define BITCOIN_CHAINPARAMS_H
+
+#include "chainparamsbase.h"
+#include "checkpoints.h"
+#include "consensus/params.h"
+#include "primitives/block.h"
+#include "protocol.h"
+
+#include <vector>
+
+struct CDNSSeedData {
+ std::string name, host;
+ CDNSSeedData(const std::string &strName, const std::string &strHost) : name(strName), host(strHost) {}
+};
+
+struct SeedSpec6 {
+ uint8_t addr[16];
+ uint16_t port;
+};
+
+
+/**
+ * CChainParams defines various tweakable parameters of a given instance of the
+ * Bitcoin system. There are three: the main network on which people trade goods
+ * and services, the public test network which gets reset from time to time and
+ * a regression test mode which is intended for private networks only. It has
+ * minimal difficulty to ensure that blocks can be found instantly.
+ */
+class CChainParams
+{
+public:
+ enum Base58Type {
+ PUBKEY_ADDRESS,
+ SCRIPT_ADDRESS,
+ SECRET_KEY,
+ EXT_PUBLIC_KEY,
+ EXT_SECRET_KEY,
+
+ MAX_BASE58_TYPES
+ };
+
+ const Consensus::Params& GetConsensus() const { return consensus; }
+ const CMessageHeader::MessageStartChars& MessageStart() const { return pchMessageStart; }
+ const std::vector<unsigned char>& AlertKey() const { return vAlertPubKey; }
+ int GetDefaultPort() const { return nDefaultPort; }
+
+ /** Used if GenerateBitcoins is called with a negative number of threads */
+ int DefaultMinerThreads() const { return nMinerThreads; }
+ const CBlock& GenesisBlock() const { return genesis; }
+ bool RequireRPCPassword() const { return fRequireRPCPassword; }
+ /** Make miner wait to have peers to avoid wasting work */
+ bool MiningRequiresPeers() const { return fMiningRequiresPeers; }
+ /** Default value for -checkmempool and -checkblockindex argument */
+ bool DefaultConsistencyChecks() const { return fDefaultConsistencyChecks; }
+ /** Policy: Filter transactions that do not match well-defined patterns */
+ bool RequireStandard() const { return fRequireStandard; }
+ int64_t PruneAfterHeight() const { return nPruneAfterHeight; }
+ /** Make miner stop after a block is found. In RPC, don't return until nGenProcLimit blocks are generated */
+ bool MineBlocksOnDemand() const { return fMineBlocksOnDemand; }
+ /** In the future use NetworkIDString() for RPC fields */
+ bool TestnetToBeDeprecatedFieldRPC() const { return fTestnetToBeDeprecatedFieldRPC; }
+ /** Return the BIP70 network string (main, test or regtest) */
+ std::string NetworkIDString() const { return strNetworkID; }
+ const std::vector<CDNSSeedData>& DNSSeeds() const { return vSeeds; }
+ const std::vector<unsigned char>& Base58Prefix(Base58Type type) const { return base58Prefixes[type]; }
+ const std::vector<SeedSpec6>& FixedSeeds() const { return vFixedSeeds; }
+ const Checkpoints::CCheckpointData& Checkpoints() const { return checkpointData; }
+protected:
+ CChainParams() {}
+
+ Consensus::Params consensus;
+ CMessageHeader::MessageStartChars pchMessageStart;
+ //! Raw pub key bytes for the broadcast alert signing key.
+ std::vector<unsigned char> vAlertPubKey;
+ int nDefaultPort;
+ int nMinerThreads;
+ uint64_t nPruneAfterHeight;
+ std::vector<CDNSSeedData> vSeeds;
+ std::vector<unsigned char> base58Prefixes[MAX_BASE58_TYPES];
+ std::string strNetworkID;
+ CBlock genesis;
+ std::vector<SeedSpec6> vFixedSeeds;
+ bool fRequireRPCPassword;
+ bool fMiningRequiresPeers;
+ bool fDefaultConsistencyChecks;
+ bool fRequireStandard;
+ bool fMineBlocksOnDemand;
+ bool fTestnetToBeDeprecatedFieldRPC;
+ Checkpoints::CCheckpointData checkpointData;
+};
+
+/**
+ * Return the currently selected parameters. This won't change after app
+ * startup, except for unit tests.
+ */
+const CChainParams &Params();
+
+/** Return parameters for the given network. */
+CChainParams &Params(CBaseChainParams::Network network);
+
+/** Sets the params returned by Params() to those for the given network. */
+void SelectParams(CBaseChainParams::Network network);
+
+/**
+ * Looks for -regtest or -testnet and then calls SelectParams as appropriate.
+ * Returns false if an invalid combination is given.
+ */
+bool SelectParamsFromCommandLine();
+
+#endif // BITCOIN_CHAINPARAMS_H
diff --git a/src/chainparamsbase.cpp b/src/chainparamsbase.cpp
new file mode 100644
index 0000000000..7d82d689ec
--- /dev/null
+++ b/src/chainparamsbase.cpp
@@ -0,0 +1,118 @@
+// Copyright (c) 2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "chainparamsbase.h"
+
+#include "util.h"
+
+#include <assert.h>
+
+/**
+ * Main network
+ */
+class CBaseMainParams : public CBaseChainParams
+{
+public:
+ CBaseMainParams()
+ {
+ nRPCPort = 8332;
+ }
+};
+static CBaseMainParams mainParams;
+
+/**
+ * Testnet (v3)
+ */
+class CBaseTestNetParams : public CBaseMainParams
+{
+public:
+ CBaseTestNetParams()
+ {
+ nRPCPort = 18332;
+ strDataDir = "testnet3";
+ }
+};
+static CBaseTestNetParams testNetParams;
+
+/*
+ * Regression test
+ */
+class CBaseRegTestParams : public CBaseTestNetParams
+{
+public:
+ CBaseRegTestParams()
+ {
+ strDataDir = "regtest";
+ }
+};
+static CBaseRegTestParams regTestParams;
+
+/*
+ * Unit test
+ */
+class CBaseUnitTestParams : public CBaseMainParams
+{
+public:
+ CBaseUnitTestParams()
+ {
+ strDataDir = "unittest";
+ }
+};
+static CBaseUnitTestParams unitTestParams;
+
+static CBaseChainParams* pCurrentBaseParams = 0;
+
+const CBaseChainParams& BaseParams()
+{
+ assert(pCurrentBaseParams);
+ return *pCurrentBaseParams;
+}
+
+void SelectBaseParams(CBaseChainParams::Network network)
+{
+ switch (network) {
+ case CBaseChainParams::MAIN:
+ pCurrentBaseParams = &mainParams;
+ break;
+ case CBaseChainParams::TESTNET:
+ pCurrentBaseParams = &testNetParams;
+ break;
+ case CBaseChainParams::REGTEST:
+ pCurrentBaseParams = &regTestParams;
+ break;
+ default:
+ assert(false && "Unimplemented network");
+ return;
+ }
+}
+
+CBaseChainParams::Network NetworkIdFromCommandLine()
+{
+ bool fRegTest = GetBoolArg("-regtest", false);
+ bool fTestNet = GetBoolArg("-testnet", false);
+
+ if (fTestNet && fRegTest)
+ return CBaseChainParams::MAX_NETWORK_TYPES;
+ if (fRegTest)
+ return CBaseChainParams::REGTEST;
+ if (fTestNet)
+ return CBaseChainParams::TESTNET;
+ return CBaseChainParams::MAIN;
+}
+
+bool SelectBaseParamsFromCommandLine()
+{
+ CBaseChainParams::Network network = NetworkIdFromCommandLine();
+ if (network == CBaseChainParams::MAX_NETWORK_TYPES)
+ return false;
+
+ SelectBaseParams(network);
+ return true;
+}
+
+bool AreBaseParamsConfigured()
+{
+ return pCurrentBaseParams != NULL;
+}
diff --git a/src/chainparamsbase.h b/src/chainparamsbase.h
new file mode 100644
index 0000000000..4369d0aef7
--- /dev/null
+++ b/src/chainparamsbase.h
@@ -0,0 +1,63 @@
+// Copyright (c) 2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_CHAINPARAMSBASE_H
+#define BITCOIN_CHAINPARAMSBASE_H
+
+#include <string>
+#include <vector>
+
+/**
+ * CBaseChainParams defines the base parameters (shared between bitcoin-cli and bitcoind)
+ * of a given instance of the Bitcoin system.
+ */
+class CBaseChainParams
+{
+public:
+ enum Network {
+ MAIN,
+ TESTNET,
+ REGTEST,
+
+ MAX_NETWORK_TYPES
+ };
+
+ const std::string& DataDir() const { return strDataDir; }
+ int RPCPort() const { return nRPCPort; }
+
+protected:
+ CBaseChainParams() {}
+
+ int nRPCPort;
+ std::string strDataDir;
+};
+
+/**
+ * Return the currently selected parameters. This won't change after app
+ * startup, except for unit tests.
+ */
+const CBaseChainParams& BaseParams();
+
+/** Sets the params returned by Params() to those for the given network. */
+void SelectBaseParams(CBaseChainParams::Network network);
+
+/**
+ * Looks for -regtest or -testnet and returns the appropriate Network ID.
+ * Returns MAX_NETWORK_TYPES if an invalid combination is given.
+ */
+CBaseChainParams::Network NetworkIdFromCommandLine();
+
+/**
+ * Calls NetworkIdFromCommandLine() and then calls SelectParams as appropriate.
+ * Returns false if an invalid combination is given.
+ */
+bool SelectBaseParamsFromCommandLine();
+
+/**
+ * Return true if SelectBaseParamsFromCommandLine() has been called to select
+ * a network.
+ */
+bool AreBaseParamsConfigured();
+
+#endif // BITCOIN_CHAINPARAMSBASE_H
diff --git a/src/chainparamsseeds.h b/src/chainparamsseeds.h
new file mode 100644
index 0000000000..423362859f
--- /dev/null
+++ b/src/chainparamsseeds.h
@@ -0,0 +1,901 @@
+#ifndef BITCOIN_CHAINPARAMSSEEDS_H
+#define BITCOIN_CHAINPARAMSSEEDS_H
+/**
+ * List of fixed seed nodes for the bitcoin network
+ * AUTOGENERATED by contrib/seeds/generate-seeds.py
+ *
+ * Each line contains a 16-byte IPv6 address and a port.
+ * IPv4 as well as onion addresses are wrapped inside a IPv6 address accordingly.
+ */
+static SeedSpec6 pnSeed6_main[] = {
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x01,0x22,0xa8,0x80}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x01,0xca,0x80,0xda}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x02,0x1e,0x00,0xd2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x09,0x60,0xcb}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x2d,0x47,0x82}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x2d,0x62,0x8d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x66,0x91,0x44}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x87,0xa0,0x4d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xbd,0x86,0xf6}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xc7,0xa4,0x84}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xf9,0x87,0x66}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x08,0x13,0x2c,0x6e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x08,0x16,0xe6,0x08}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x0e,0xc8,0xc8,0x91}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x12,0xe4,0x00,0xbc}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x12,0xe4,0x00,0xc8}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0x18,0xa8,0x61}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0x1c,0x23,0xe3}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0x5c,0x4c,0xaa}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0x63,0x40,0x77}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0xe4,0xa6,0x80}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0xe5,0x2d,0x20}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x08,0x69,0x80}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x10,0x45,0x89}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x5e,0x62,0x60}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x66,0x76,0x07}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x76,0xa6,0xe4}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x7a,0x85,0x31}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0xa6,0x61,0xa2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0xd5,0xeb,0xf2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0xe2,0x6b,0x40}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0xe4,0xc0,0xab}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1b,0x8c,0x85,0x12}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0x29,0x28,0x19}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0x2b,0x65,0x3b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0xb8,0xc3,0xb5}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0xc1,0x8b,0x42}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xc8,0x46,0x66}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xcd,0x0a,0x97}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2a,0x03,0x6a,0xe3}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2a,0x3c,0x85,0x6a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x38,0x55,0xe7}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x38,0x66,0xe4}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x4f,0x82,0xeb}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x1c,0xcc,0x3d}, 11101},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x26,0xeb,0xe5}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x3b,0x02,0x4a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x65,0x84,0x25}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x65,0xa8,0x32}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xa3,0x4c,0xe6}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xa6,0xa1,0x67}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xb6,0x84,0x64}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xdf,0x24,0x5e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xe3,0x42,0x84}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xe3,0x42,0x8a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xef,0x6b,0x4a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xf9,0x27,0x64}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xfa,0x62,0x6c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x07,0x25,0x72}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x51,0x35,0x97}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x73,0x2b,0xfd}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x74,0x14,0x57}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x74,0x21,0x5c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x7d,0xa7,0xf5}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x8f,0x09,0x33}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0xbc,0xc0,0x85}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0x4d,0xa2,0x4c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0x99,0x61,0x6d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xa5,0xc0,0x7d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3a,0x60,0x69,0x55}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3b,0xa7,0xc4,0x87}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3c,0x1d,0xe3,0xa3}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3d,0x23,0xe1,0x13}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0x2b,0x82,0xb2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0x6d,0x31,0x1a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xca,0x00,0x61}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xd2,0x42,0xe3}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xd2,0xc0,0xa9}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0x4a,0x62,0xcd}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0x9c,0xc1,0x64}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0xcb,0x66,0x56}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0xe5,0x8e,0x30}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x41,0x60,0xc1,0xa5}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0x1e,0x03,0x07}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0x72,0x21,0x31}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0x76,0x85,0xc2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0x87,0x0a,0x7e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0xac,0x0a,0x04}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0xc2,0x26,0xfa}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0xc2,0x26,0xfd}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0xd7,0xc0,0x68}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0x3c,0x62,0x73}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xa4,0x23,0x24}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xbf,0xa2,0xf4}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xcf,0xc3,0x4d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xdb,0xe9,0x8c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xdd,0xc1,0x37}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xe4,0xa2,0xe4}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0x32,0x43,0xc7}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0x3e,0x03,0xcb}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0x41,0xcd,0xe2}, 9000},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0x6a,0x2a,0xbf}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0x96,0xb5,0xc6}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0xc4,0xc4,0x6a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0xe0,0xc2,0x51}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x2e,0x05,0xc2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x32,0xab,0xee}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x40,0x2b,0x98}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x41,0x29,0x0d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x5a,0x84,0xc8}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x8f,0x01,0xf3}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x92,0x62,0xd8}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0xa5,0xf6,0x26}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0xcf,0x06,0x87}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0xfb,0xd0,0x1a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0x26,0x01,0x65}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0x26,0x09,0x42}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0x5a,0x02,0x12}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0x3a,0xe4,0xe2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0xc7,0x0b,0xbd}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0xc7,0xc1,0xca}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0xcd,0xe8,0xb5}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0xec,0xc8,0xa2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x18,0x49,0xba}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x34,0x82,0x6e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x35,0x6f,0x25}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0xeb,0x26,0x46}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x49,0x1f,0xab,0x95}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x49,0x20,0x89,0x48}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x49,0x89,0x85,0xee}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x49,0xb5,0xc0,0x67}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x49,0xbe,0x02,0x3c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x49,0xc3,0xc0,0x89}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x49,0xde,0x23,0x75}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0x39,0xc7,0xb4}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0x52,0xe9,0xcd}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0x55,0x42,0x52}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0x65,0xe0,0x7f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0x71,0x45,0x10}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0x7a,0xeb,0x44}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0xc1,0x44,0x8d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0xd0,0xa4,0xdb}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0x64,0x25,0x7a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0x91,0x95,0xa9}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0xa8,0x22,0x14}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0x14,0x2c,0xf0}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0x64,0x46,0x11}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0xa8,0x03,0xef}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0xba,0x8c,0x67}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0x5c,0x44,0xdd}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0x6d,0x65,0x8e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0x6e,0x0b,0x56}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0xf2,0x6c,0x12}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x2e,0x60,0x96}, 9020},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x54,0x64,0x5f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0x84,0xe6,0x90}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0x85,0x2b,0x3f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0xa0,0x4c,0x99}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0xa9,0x22,0x18}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0xbc,0x07,0x4e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xd9,0xe2,0x19}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xdf,0x64,0xb3}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xf0,0x81,0xdd}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x01,0xad,0xf3}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x07,0x0b,0x32}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x07,0x10,0x11}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x42,0x6f,0x03}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x50,0x09,0x47}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x8c,0x2b,0x8a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xab,0x22,0x25}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xae,0xf7,0x32}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xb5,0x9b,0x35}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xb8,0x05,0xfd}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xbb,0x45,0x82}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xe6,0x03,0x54}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0x2a,0x80,0x33}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0x4a,0xe2,0x15}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0x8e,0x4b,0x32}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xc7,0x66,0x0a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xc8,0xcd,0x1e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xdd,0x6c,0x15}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xdd,0x80,0x23}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xee,0x7c,0x29}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xf2,0x00,0xf5}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x4c,0x7b,0x6e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x96,0x09,0xc4}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xa2,0xc4,0xc0}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xa2,0xea,0xe0}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xaa,0x68,0x5b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xff,0x42,0x76}, 8334},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0x02,0x22,0x68}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0x2d,0x62,0x5b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0x2f,0xa1,0x96}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xd4,0xc0,0x83}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xd7,0xa9,0x65}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xee,0x8c,0xb0}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xf5,0x47,0x1f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x11,0x04,0xd4}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x72,0x80,0x86}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x9f,0xed,0xbf}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xa6,0x82,0xbd}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xc7,0x04,0xe4}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xd6,0x42,0xa8}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xd6,0xc3,0xd2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xe5,0x00,0x49}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x56,0x15,0x60,0x2d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x30,0x2a,0xc7}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x51,0x8f,0x52}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x51,0xfb,0x48}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x68,0x18,0xb9}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x68,0xa8,0x68}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x75,0xea,0x47}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x76,0x60,0xc5}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x91,0x0c,0x39}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x9f,0xaa,0xbe}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0x96,0xa8,0xa0}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xd0,0x00,0x4f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xd0,0x00,0x95}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xd6,0xc2,0xe2}, 8343},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x01,0x0b,0x20}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x24,0xeb,0x6c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x43,0x60,0x02}, 15321},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x62,0x10,0x29}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x6c,0x48,0xc3}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x9c,0x23,0x9d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xa3,0xe3,0x1c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xd4,0x21,0xed}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xd4,0xa0,0xa5}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xe7,0x60,0x53}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xf8,0xa4,0x40}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5a,0x95,0xc1,0xc7}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x4d,0xef,0xf5}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x6a,0xc2,0x61}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x7e,0x4d,0x4d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x86,0x26,0xc3}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x9c,0x61,0xb5}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xcf,0x44,0x90}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xd1,0x4d,0x65}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xd6,0xc8,0xcd}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xdc,0x83,0xf2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xdc,0xa3,0x12}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xe9,0x17,0x23}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5c,0x0d,0x60,0x5d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5c,0x0e,0x4a,0x72}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5c,0x1b,0x07,0xd1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5c,0xdd,0xe4,0x0d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5c,0xff,0xcf,0x49}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0x48,0xa7,0x94}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0x4a,0xa3,0xea}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0x7b,0xae,0x42}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0x98,0xa6,0x1d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0xb5,0x2d,0xbc}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x13,0x0c,0xf4}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xbe,0xe3,0x70}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xc6,0x87,0x1d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xe0,0xa2,0x41}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xe2,0x6b,0x56}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xf2,0xc6,0xa1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x1f,0x0a,0xd1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x41,0x48,0xf4}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x54,0xa2,0x5f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x5a,0x8b,0x2e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xb7,0x31,0x1b}, 8005},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xd7,0x2f,0x85}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0x17,0x43,0x55}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0x2c,0xa6,0xbe}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x61,0x5d,0xe1,0x4a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0x1a,0x00,0x22}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0x1b,0xe1,0x66}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xe5,0x75,0xe5}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xf9,0x44,0x7d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xff,0x05,0x9b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x63,0x65,0xf0,0x72}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x65,0x64,0xae,0x8a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x65,0xfb,0xcb,0x06}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0x03,0x3c,0x3d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0x1e,0x2a,0xbd}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0xe0,0xa5,0x30}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x24,0x53,0xe9}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x25,0x81,0x16}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x36,0xc0,0xfb}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x80,0xe4,0xfc}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x80,0xe6,0xb9}, 8334},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x82,0xa1,0x2f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x83,0x21,0x3c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x8f,0x00,0x9c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x9c,0x6f,0x48}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xa7,0x6f,0x54}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xc1,0x28,0xf8}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xc5,0x07,0xae}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xc5,0x08,0xfa}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xdf,0x01,0x85}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xec,0x61,0x8c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xee,0x80,0xd6}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xee,0x82,0xb6}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6a,0x26,0xea,0x54}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6a,0xb9,0x24,0xcc}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0x06,0x04,0x91}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0x96,0x02,0x06}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0x96,0x28,0xea}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0x9b,0x6c,0x82}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0xa1,0xb6,0x73}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0xaa,0x42,0xe7}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0xbe,0x80,0xe2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0xbf,0x6a,0x73}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x10,0x02,0x3d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0x46,0x04,0xa8}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xa2,0x23,0xc4}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xa3,0xeb,0xef}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xbe,0xc4,0xdc}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xbf,0x27,0x3c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xea,0x6a,0xbf}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xee,0x51,0x52}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x72,0x4c,0x93,0x1b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x73,0x1c,0xe0,0x7f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x73,0x44,0x6e,0x52}, 18333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x76,0x61,0x4f,0xda}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x76,0xbd,0xcf,0xc5}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x77,0xe4,0x60,0xe9}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x78,0x93,0xb2,0x51}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x79,0x29,0x7b,0x05}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x79,0x43,0x05,0xe6}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7a,0x6b,0x8f,0x6e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7b,0x02,0xaa,0x62}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7b,0x6e,0x41,0x5e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7b,0xc1,0x8b,0x13}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7d,0xef,0xa0,0x29}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0x65,0xa2,0xc1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0x6f,0x49,0x0a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0x8c,0xe5,0x49}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0xaf,0xc3,0x1f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0xc7,0x6b,0x3f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0xc7,0xc0,0x99}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0xfd,0x03,0xc1}, 20020},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x81,0x7b,0x07,0x07}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x82,0x59,0xa0,0xea}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x83,0x48,0x8b,0xa4}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x83,0xbf,0x70,0x62}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x85,0x01,0x86,0xa2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x86,0x13,0x84,0x35}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x89,0xe2,0x22,0x2a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8d,0x29,0x02,0xac}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8d,0xff,0x80,0xcc}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8e,0xd9,0x0c,0x6a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8f,0xd7,0x81,0x7e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x92,0x00,0x20,0x65}, 8337},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x93,0xe5,0x0d,0xc7}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x95,0xd2,0x85,0xf4}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x95,0xd2,0xa2,0xbb}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x96,0x65,0xa3,0xf1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x97,0xec,0x0b,0xbd}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x99,0x79,0x42,0xd3}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9a,0x14,0x02,0x8b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9f,0xfd,0x17,0x84}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xd1,0x6a,0x7b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xd2,0xc6,0xb8}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xda,0x41,0x79}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xde,0xa1,0x31}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xf3,0x84,0x06}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xf3,0x84,0x3a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xf8,0x63,0xa4}, 53011},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xf8,0x66,0x75}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa3,0x9e,0x23,0x6e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa4,0x0f,0x0a,0xbd}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa4,0x28,0x86,0xab}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa6,0xe6,0x47,0x43}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa7,0xa0,0xa1,0xc7}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa8,0x67,0xc3,0xfa}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa8,0x90,0x1b,0x70}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa8,0x9e,0x81,0x1d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xaa,0x4b,0xa2,0x56}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xac,0x5a,0x63,0xae}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xac,0xf5,0x05,0x9c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0x17,0xa6,0x2f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0x20,0x0b,0xc2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0x22,0xcb,0x4c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xab,0x01,0x34}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xaf,0x88,0x0d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xe6,0xe4,0x8b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xf7,0xc1,0x46}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x31,0x84,0x1c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x34,0xca,0x48}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x35,0x4c,0x57}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x6d,0x21,0x1c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x1c,0x0c,0xa9}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x23,0xb6,0xd6}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x24,0x21,0x71}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x24,0x21,0x79}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x3a,0x60,0xad}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x79,0x4c,0x54}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x3e,0x46,0x10}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x3e,0x6f,0x1a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x4c,0xa9,0x3b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x4f,0x83,0x20}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xa2,0xc7,0xd8}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xaf,0x86,0x23}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xf8,0x6f,0x04}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xfe,0x01,0xaa}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xfe,0x22,0xa1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb3,0x2b,0x8f,0x78}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb3,0xd0,0x9c,0xc6}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb4,0xc8,0x80,0x3a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb7,0x4e,0xa9,0x6c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb7,0x60,0x60,0x98}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x44,0x02,0x2e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x49,0xa0,0xa0}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x5e,0xe3,0x3a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x98,0x44,0xa3}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x07,0x23,0x72}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x1c,0x4c,0xb3}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x1f,0xa0,0xca}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x2d,0xc0,0x81}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x42,0x8c,0x0f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xba,0x02,0xa7,0x17}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xba,0xdc,0x65,0x8e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x1a,0x05,0x21}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x4b,0x88,0x92}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x78,0xc2,0x8c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x79,0x05,0x96}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x8a,0x00,0x72}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x8a,0x21,0xef}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xa6,0x00,0x52}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xb6,0x6c,0x81}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xbf,0x61,0xd0}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xe2,0xc6,0x66}, 8001},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbe,0x0a,0x09,0xd9}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbe,0x4b,0x8f,0x90}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbe,0x8b,0x66,0x92}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbf,0xed,0x40,0x1c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x03,0x83,0x3d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x63,0xe1,0x03}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x6e,0xa0,0x7a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x92,0x89,0x01}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xb7,0xc6,0xcc}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xcb,0xe4,0x47}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x00,0x6d,0x03}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x0c,0xee,0xcc}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x5b,0xc8,0x55}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0xea,0xe1,0x9c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc2,0x06,0xe9,0x26}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc2,0x3f,0x8f,0x88}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc2,0x7e,0x64,0xf6}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x86,0x63,0xc3}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x9f,0x6f,0x62}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x9f,0xe2,0x8b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0xc5,0xaf,0xbe}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x30,0xc7,0x6c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x39,0xd0,0x86}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x39,0xd2,0x1b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x3e,0x6d,0xdf}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0xa7,0x8c,0x08}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0xa7,0x8c,0x12}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0x5b,0xad,0xea}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0x7f,0xe2,0xf5}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0xb4,0x86,0x74}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc8,0x07,0x60,0x63}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc9,0xa0,0x6a,0x56}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xca,0x37,0x57,0x2d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xca,0x3c,0x44,0xf2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xca,0x3c,0x45,0xe8}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xca,0x7c,0x6d,0x67}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcb,0x1e,0xc5,0x4d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcb,0x58,0xa0,0x2b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcb,0x97,0x8c,0x0e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcb,0xdb,0x0e,0xcc}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcd,0x93,0x28,0x3e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcf,0xeb,0x27,0xd6}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcf,0xf4,0x49,0x08}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd0,0x0c,0x40,0xe1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd0,0x4c,0xc8,0xc8}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0x28,0x60,0x79}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0x7e,0x6b,0xb0}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0x8d,0x28,0x95}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0xbe,0x4b,0x3b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0xd0,0x6f,0x8e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd2,0x36,0x22,0xa4}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd3,0x48,0x42,0xe5}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x33,0x90,0x2a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x70,0x21,0x9d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x74,0x48,0x3f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x7e,0x0e,0x7a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x42,0xcd,0xc2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x6f,0xc4,0x15}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x7a,0x6b,0x66}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x88,0x4b,0xaf}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x9b,0x07,0x18}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xa3,0x40,0x1f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xa3,0x40,0xd0}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xa5,0x56,0x88}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xb8,0x08,0x16}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0x0f,0x4e,0xb6}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0x37,0x8f,0x9a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0x73,0xeb,0x20}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0x7e,0xe2,0xa6}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0x91,0x43,0x57}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0xa9,0x8d,0xa9}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0xf9,0x5c,0xe6}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0xfa,0x8a,0xe6}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x14,0xab,0x2b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x17,0x02,0x47}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x17,0x02,0xf2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x19,0x09,0x4c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x28,0xe2,0xa9}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x7b,0x62,0x09}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x9b,0x24,0x3e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0xac,0x20,0x12}, 20993},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xda,0x3d,0xc4,0xca}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xda,0xe7,0xcd,0x29}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xdc,0xe9,0x4d,0xc8}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xdf,0x12,0xe2,0x55}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xdf,0xc5,0xcb,0x52}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xdf,0xff,0xa6,0x8e}, 8333},
+ {{0x20,0x01,0x12,0x91,0x02,0xbf,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00}, 8333},
+ {{0x20,0x01,0x14,0x18,0x01,0x00,0x05,0xc2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x20,0x01,0x16,0xd8,0xdd,0x24,0x00,0x00,0x86,0xc9,0x68,0x1e,0xf9,0x31,0x02,0x56}, 8333},
+ {{0x20,0x01,0x19,0xf0,0x16,0x24,0x00,0xe6,0x00,0x00,0x00,0x00,0x57,0x9d,0x94,0x28}, 8333},
+ {{0x20,0x01,0x19,0xf0,0x03,0x00,0x13,0x40,0x02,0x25,0x90,0xff,0xfe,0xc9,0x2b,0x6d}, 8333},
+ {{0x20,0x01,0x19,0xf0,0x40,0x09,0x14,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x64}, 8333},
+ {{0x20,0x01,0x1b,0x40,0x50,0x00,0x00,0x2e,0x00,0x00,0x00,0x00,0x3f,0xb0,0x65,0x71}, 8333},
+ {{0x20,0x01,0x04,0x10,0xa0,0x00,0x40,0x50,0x84,0x63,0x90,0xb0,0xff,0xfb,0x4e,0x58}, 8333},
+ {{0x20,0x01,0x04,0x10,0xa0,0x02,0xca,0xfe,0x84,0x63,0x90,0xb0,0xff,0xfb,0x4e,0x58}, 8333},
+ {{0x20,0x01,0x41,0xd0,0x00,0x01,0x54,0x1e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
+ {{0x20,0x01,0x41,0xd0,0x00,0x01,0x6a,0x34,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03}, 8333},
+ {{0x20,0x01,0x41,0xd0,0x00,0x01,0x6c,0xd3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333},
+ {{0x20,0x01,0x41,0xd0,0x00,0x01,0x8b,0x26,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
+ {{0x20,0x01,0x41,0xd0,0x00,0x01,0xa3,0x3d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
+ {{0x20,0x01,0x41,0xd0,0x00,0x01,0xb8,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
+ {{0x20,0x01,0x41,0xd0,0x00,0x01,0xc1,0x39,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
+ {{0x20,0x01,0x41,0xd0,0x00,0x01,0xc8,0xd7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
+ {{0x20,0x01,0x41,0xd0,0x00,0x01,0xdd,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
+ {{0x20,0x01,0x41,0xd0,0x00,0x01,0xe2,0x9d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
+ {{0x20,0x01,0x41,0xd0,0x00,0x01,0xf5,0x9f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33}, 8333},
+ {{0x20,0x01,0x41,0xd0,0x00,0x01,0xf7,0xcc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
+ {{0x20,0x01,0x41,0xd0,0x00,0x01,0xff,0x87,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
+ {{0x20,0x01,0x41,0xd0,0x00,0x02,0x2f,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
+ {{0x20,0x01,0x41,0xd0,0x00,0x02,0x37,0xc3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8200},
+ {{0x20,0x01,0x41,0xd0,0x00,0x02,0x3e,0x13,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
+ {{0x20,0x01,0x41,0xd0,0x00,0x02,0x86,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333},
+ {{0x20,0x01,0x41,0xd0,0x00,0x02,0x9c,0x94,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
+ {{0x20,0x01,0x41,0xd0,0x00,0x02,0xa2,0x4f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333},
+ {{0x20,0x01,0x41,0xd0,0x00,0x02,0xad,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333},
+ {{0x20,0x01,0x41,0xd0,0x00,0x02,0xb7,0x21,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
+ {{0x20,0x01,0x41,0xd0,0x00,0x02,0xee,0x52,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
+ {{0x20,0x01,0x41,0xd0,0x00,0x02,0xf1,0xa5,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333},
+ {{0x20,0x01,0x41,0xd0,0x00,0x02,0xfa,0x54,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
+ {{0x20,0x01,0x41,0xd0,0x00,0x51,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x36}, 8333},
+ {{0x20,0x01,0x41,0xd0,0x00,0x52,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xa1}, 8333},
+ {{0x20,0x01,0x41,0xd0,0x00,0x52,0x0c,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0xf5}, 8333},
+ {{0x20,0x01,0x41,0xd0,0x00,0x52,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0xc0}, 8333},
+ {{0x20,0x01,0x41,0xd0,0x00,0x52,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0xf2}, 8333},
+ {{0x20,0x01,0x41,0xd0,0x00,0x08,0x10,0x87,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
+ {{0x20,0x01,0x41,0xd0,0x00,0x08,0x4a,0x3c,0x00,0x00,0x00,0x00,0x00,0x00,0x0b,0x7c}, 8333},
+ {{0x20,0x01,0x41,0xd0,0x00,0x08,0x67,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333},
+ {{0x20,0x01,0x41,0xd0,0x00,0x08,0xb7,0x79,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
+ {{0x20,0x01,0x41,0xd0,0x00,0x08,0xc3,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
+ {{0x20,0x01,0x41,0xd0,0x00,0x08,0xd2,0xb2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
+ {{0x20,0x01,0x41,0xd0,0x00,0x08,0xd5,0xc3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
+ {{0x20,0x01,0x41,0xd0,0x00,0x08,0xeb,0x8b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333},
+ {{0x20,0x01,0x41,0xd0,0x00,0x0a,0x16,0xd0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
+ {{0x20,0x01,0x41,0xd0,0x00,0x0a,0x2b,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
+ {{0x20,0x01,0x41,0xd0,0x00,0x0a,0x3a,0x9c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
+ {{0x20,0x01,0x41,0xd0,0x00,0x0a,0x49,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333},
+ {{0x20,0x01,0x41,0xd0,0x00,0x0a,0x05,0x7b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
+ {{0x20,0x01,0x41,0xd0,0x00,0x0a,0x5c,0x7a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333},
+ {{0x20,0x01,0x41,0xd0,0x00,0x0a,0x6c,0x29,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
+ {{0x20,0x01,0x41,0xd0,0x00,0x0a,0xf4,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
+ {{0x20,0x01,0x41,0xd0,0x00,0x0b,0x08,0x54,0x0b,0x7c,0x0b,0x7c,0x0b,0x7c,0x0b,0x7c}, 8333},
+ {{0x20,0x01,0x41,0xd0,0x00,0x0d,0x11,0x1c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333},
+ {{0x20,0x01,0x44,0xb8,0x41,0x16,0x78,0x01,0x42,0x16,0x7e,0xff,0xfe,0x78,0x3f,0xe4}, 8333},
+ {{0x20,0x01,0x04,0x70,0x1f,0x08,0x08,0x37,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x20,0x01,0x04,0x70,0x1f,0x08,0x0c,0x33,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x20,0x01,0x04,0x70,0x1f,0x09,0x0b,0xca,0x02,0x18,0x7d,0xff,0xfe,0x10,0xbe,0x33}, 8333},
+ {{0x20,0x01,0x04,0x70,0x1f,0x0f,0x02,0x2d,0x00,0x00,0x00,0x00,0x02,0x12,0x00,0x26}, 8333},
+ {{0x20,0x01,0x04,0x70,0x1f,0x11,0x12,0xd5,0x00,0x00,0x00,0x00,0x0a,0xe1,0x56,0x11}, 8333},
+ {{0x20,0x01,0x04,0x70,0x1f,0x14,0x05,0x7a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x20,0x01,0x04,0x70,0x1f,0x14,0x00,0x7d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x20,0x01,0x04,0x70,0x1f,0x15,0x05,0x7c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
+ {{0x20,0x01,0x04,0x70,0x1f,0x15,0x0d,0xda,0x3d,0x9a,0x3f,0x11,0x9a,0x56,0xed,0x64}, 8333},
+ {{0x20,0x01,0x04,0x70,0x00,0x25,0x04,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x20,0x01,0x04,0x70,0x00,0x25,0x00,0xe4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x20,0x01,0x04,0x70,0x00,0x04,0x02,0x6b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x20,0x01,0x04,0x70,0x00,0x5f,0x00,0x5f,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x32}, 8333},
+ {{0x20,0x01,0x04,0x70,0x00,0x66,0x01,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x20,0x01,0x04,0x70,0x00,0x67,0x03,0x9d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x71}, 8333},
+ {{0x20,0x01,0x04,0x70,0x6c,0x4f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xca,0xfe}, 8333},
+ {{0x20,0x01,0x04,0x70,0x00,0x08,0x02,0xe1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x43}, 8333},
+ {{0x20,0x01,0x04,0x70,0x90,0xa7,0x00,0x96,0x00,0x00,0x00,0x00,0x0a,0xfe,0x60,0x21}, 8333},
+ {{0x20,0x01,0x04,0x70,0x95,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x20,0x01,0x04,0x70,0xb1,0xd0,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00}, 8333},
+ {{0x20,0x01,0x04,0x70,0xc1,0xf2,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x01}, 8333},
+ {{0x20,0x01,0x04,0x70,0xd0,0x0d,0x00,0x00,0x36,0x64,0xa9,0xff,0xfe,0x9a,0x51,0x50}, 8333},
+ {{0x20,0x01,0x04,0x70,0xe2,0x50,0x00,0x00,0x02,0x11,0x11,0xff,0xfe,0xb9,0x92,0x4c}, 8333},
+ {{0x20,0x01,0x48,0x00,0x78,0x17,0x01,0x01,0xbe,0x76,0x4e,0xff,0xfe,0x04,0xdc,0x52}, 8333},
+ {{0x20,0x01,0x48,0x00,0x78,0x19,0x01,0x04,0xbe,0x76,0x4e,0xff,0xfe,0x04,0x78,0x09}, 8333},
+ {{0x20,0x01,0x48,0x00,0x78,0x19,0x01,0x04,0xbe,0x76,0x4e,0xff,0xfe,0x05,0xc8,0x28}, 8333},
+ {{0x20,0x01,0x48,0x02,0x78,0x00,0x00,0x02,0x30,0xd7,0x17,0x75,0xff,0x20,0x18,0x58}, 8333},
+ {{0x20,0x01,0x48,0x02,0x78,0x02,0x01,0x01,0xbe,0x76,0x4e,0xff,0xfe,0x20,0x02,0x56}, 8333},
+ {{0x20,0x01,0x48,0x02,0x78,0x02,0x01,0x03,0xbe,0x76,0x4e,0xff,0xfe,0x20,0x2d,0xe8}, 8333},
+ {{0x20,0x01,0x48,0x30,0x11,0x00,0x02,0xe8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x20,0x01,0x4b,0xa0,0xff,0xf7,0x01,0x81,0xde,0xad,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
+ {{0x20,0x01,0x4b,0xa0,0xff,0xfa,0x00,0x5d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x93}, 8333},
+ {{0x20,0x01,0x4b,0xa0,0xff,0xff,0x01,0xbe,0x00,0x01,0x10,0x05,0x00,0x00,0x00,0x01}, 8335},
+ {{0x20,0x01,0x4c,0x48,0x01,0x10,0x01,0x01,0x02,0x16,0x3e,0xff,0xfe,0x24,0x11,0x62}, 8333},
+ {{0x20,0x01,0x4d,0xd0,0xf1,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x32}, 8333},
+ {{0x20,0x01,0x4d,0xd0,0xff,0x00,0x86,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03}, 8333},
+ {{0x20,0x01,0x4d,0xd0,0xff,0x00,0x9a,0x67,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09}, 8333},
+ {{0x20,0x01,0x4d,0xd0,0xff,0x00,0x9c,0x55,0xc2,0x3f,0xd5,0xff,0xfe,0x6c,0x7e,0xe9}, 8333},
+ {{0x20,0x01,0x05,0xc0,0x14,0x00,0x00,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0xc7}, 8333},
+ {{0x20,0x01,0x05,0xc0,0x14,0x00,0x00,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x3d,0x01}, 8333},
+ {{0x20,0x01,0x05,0xc0,0x14,0x00,0x00,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xdf}, 8333},
+ {{0x20,0x01,0x05,0xc0,0x15,0x01,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03}, 8333},
+ {{0x20,0x01,0x06,0x10,0x1b,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03}, 8333},
+ {{0x20,0x01,0x06,0x20,0x05,0x00,0xff,0xf0,0xf2,0x1f,0xaf,0xff,0xfe,0xcf,0x91,0xcc}, 8333},
+ {{0x20,0x01,0x06,0x7c,0x12,0x20,0x08,0x0c,0x00,0xad,0x8d,0xe2,0xf7,0xe2,0xc7,0x84}, 8333},
+ {{0x20,0x01,0x06,0x7c,0x21,0xec,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0b}, 8333},
+ {{0x20,0x01,0x06,0xf8,0x12,0x96,0x00,0x00,0x76,0xd4,0x35,0xff,0xfe,0xba,0x1d,0x26}, 8333},
+ {{0x20,0x01,0x08,0x40,0xf0,0x00,0x42,0x50,0x3e,0x4a,0x92,0xff,0xfe,0x6d,0x14,0x5f}, 8333},
+ {{0x20,0x01,0x08,0xd8,0x08,0x40,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x39,0x01,0xae}, 8333},
+ {{0x20,0x01,0x09,0x80,0xef,0xd8,0x00,0x00,0x00,0x21,0xde,0x4a,0x27,0x09,0x09,0x12}, 8333},
+ {{0x20,0x01,0x09,0x81,0x00,0x46,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03}, 8333},
+ {{0x20,0x01,0x09,0x81,0x93,0x19,0x00,0x02,0x00,0xc0,0x00,0xa8,0x00,0xc8,0x00,0x08}, 8333},
+ {{0x20,0x01,0x09,0xd8,0xca,0xfe,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x91}, 8333},
+ {{0x20,0x01,0x0a,0xd0,0x00,0x01,0x00,0x01,0x26,0xbe,0x05,0xff,0xfe,0x25,0x95,0x9d}, 8333},
+ {{0x20,0x01,0x0b,0xa8,0x01,0xf1,0xf3,0x4c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x20,0x01,0x0b,0xc8,0x38,0x1c,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
+ {{0x20,0x02,0x17,0x5c,0x4c,0xaa,0x00,0x00,0x00,0x00,0x00,0x00,0x17,0x5c,0x4c,0xaa}, 8333},
+ {{0x20,0x02,0x44,0x04,0x82,0xf1,0x00,0x00,0x8d,0x55,0x8f,0xbb,0x15,0xfa,0xf4,0xe0}, 8333},
+ {{0x20,0x02,0x44,0x75,0x22,0x33,0x00,0x00,0x02,0x1f,0x5b,0xff,0xfe,0x33,0x9f,0x70}, 8333},
+ {{0x20,0x02,0x59,0x6c,0x48,0xc3,0x00,0x00,0x00,0x00,0x00,0x00,0x59,0x6c,0x48,0xc3}, 8333},
+ {{0x20,0x02,0x8c,0x6d,0x65,0x21,0x96,0x17,0x12,0xbf,0x48,0xff,0xfe,0xd8,0x17,0x24}, 8333},
+ {{0x20,0x02,0xa6,0x46,0x5e,0x6a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x02}, 8333},
+ {{0x20,0x02,0xb0,0x09,0x20,0xc5,0x00,0x00,0x00,0x00,0x00,0x00,0xb0,0x09,0x20,0xc5}, 8333},
+ {{0x24,0x00,0x89,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x6e,0x82,0x3e}, 8333},
+ {{0x24,0x00,0x89,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x70,0xd1,0x64}, 8333},
+ {{0x24,0x00,0x89,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x37,0x97,0x61}, 8333},
+ {{0x24,0x03,0x42,0x00,0x04,0x03,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff}, 8333},
+ {{0x24,0x03,0xb8,0x00,0x10,0x00,0x00,0x64,0x04,0x0a,0xe9,0xff,0xfe,0x5f,0x94,0xc1}, 8333},
+ {{0x24,0x03,0xb8,0x00,0x10,0x00,0x00,0x64,0x98,0x79,0x17,0xff,0xfe,0x6a,0xa5,0x9f}, 8333},
+ {{0x26,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x18,0x59,0xb2}, 8333},
+ {{0x26,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x37,0xa4,0xb1}, 8333},
+ {{0x26,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x56,0x29,0x73}, 8333},
+ {{0x26,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x6e,0x72,0x97}, 8333},
+ {{0x26,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x84,0x8a,0x6e}, 8333},
+ {{0x26,0x00,0x3c,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x18,0x6a,0xdf}, 8333},
+ {{0x26,0x00,0x3c,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x18,0xe2,0x17}, 8333},
+ {{0x26,0x00,0x3c,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x33,0x1b,0x31}, 8333},
+ {{0x26,0x00,0x3c,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x33,0x2f,0xe1}, 8333},
+ {{0x26,0x00,0x3c,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x33,0xa0,0x3f}, 8333},
+ {{0x26,0x00,0x3c,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x50,0x5e,0x06}, 8333},
+ {{0x26,0x00,0x3c,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x56,0xd6,0x45}, 8333},
+ {{0x26,0x00,0x3c,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x6e,0xa3,0xdc}, 8333},
+ {{0x26,0x00,0x3c,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x89,0xa6,0x59}, 8333},
+ {{0x26,0x00,0x3c,0x02,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x6e,0x6f,0x0b}, 8333},
+ {{0x26,0x00,0x3c,0x03,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x33,0xf6,0xfb}, 8333},
+ {{0x26,0x00,0x3c,0x03,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x50,0x5f,0xa7}, 8333},
+ {{0x26,0x00,0x3c,0x03,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x6e,0x18,0x03}, 8333},
+ {{0x26,0x00,0x3c,0x03,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x6e,0x4a,0xc0}, 8333},
+ {{0x26,0x01,0x00,0x06,0x48,0x00,0x04,0x7f,0x1e,0x4e,0x1f,0x4d,0x33,0x2c,0x3b,0xf6}, 8333},
+ {{0x26,0x01,0x00,0x0d,0x54,0x00,0x0f,0xed,0x8d,0x54,0xc1,0xe8,0x7e,0xd7,0xd4,0x5e}, 8333},
+ {{0x26,0x02,0x01,0x00,0x4b,0x8f,0x6d,0x2a,0x02,0x0c,0x29,0xff,0xfe,0xaf,0xc4,0xc2}, 8333},
+ {{0x26,0x02,0xff,0xc5,0x00,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0x2d,0x61}, 8333},
+ {{0x26,0x02,0xff,0xc5,0x00,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0x92,0x11}, 8333},
+ {{0x26,0x02,0xff,0xc5,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xc5,0xb8,0x44}, 8333},
+ {{0x26,0x02,0xff,0xe8,0x01,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x04,0x57,0x93,0x6b}, 8333},
+ {{0x26,0x02,0xff,0xea,0x10,0x01,0x01,0x25,0x00,0x00,0x00,0x00,0x00,0x00,0x2a,0xd4}, 8333},
+ {{0x26,0x02,0xff,0xea,0x10,0x01,0x06,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x83,0x7d}, 8333},
+ {{0x26,0x02,0xff,0xea,0x10,0x01,0x07,0x2b,0x00,0x00,0x00,0x00,0x00,0x00,0x57,0x8b}, 8333},
+ {{0x26,0x02,0xff,0xea,0x10,0x01,0x07,0x7a,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0xae}, 8333},
+ {{0x26,0x02,0xff,0xea,0x00,0x01,0x02,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x6b,0xc8}, 8333},
+ {{0x26,0x02,0xff,0xea,0x00,0x01,0x07,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x79,0x68}, 8333},
+ {{0x26,0x02,0xff,0xea,0x00,0x01,0x07,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x82,0xec}, 8333},
+ {{0x26,0x02,0xff,0xea,0x00,0x01,0x09,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xe9,0x57}, 8333},
+ {{0x26,0x02,0xff,0xea,0x00,0x01,0x0a,0x5d,0x00,0x00,0x00,0x00,0x00,0x00,0x4a,0xcb}, 8333},
+ {{0x26,0x02,0xff,0xea,0x00,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x24,0xc4,0xd9,0xfd}, 8333},
+ {{0x26,0x02,0xff,0xea,0x00,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x06,0xae,0x32}, 8333},
+ {{0x26,0x04,0x00,0x00,0x00,0xc1,0x01,0x00,0x1e,0xc1,0xde,0xff,0xfe,0x54,0x22,0x35}, 8333},
+ {{0x26,0x04,0x01,0x80,0x00,0x01,0x01,0xaf,0x00,0x00,0x00,0x00,0x00,0x00,0x42,0xa9}, 8333},
+ {{0x26,0x04,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb2,0x08,0x03,0x98}, 8333},
+ {{0x26,0x04,0x28,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x72,0x0a,0xed}, 8333},
+ {{0x26,0x04,0x40,0x80,0x11,0x14,0x00,0x00,0x32,0x85,0xa9,0xff,0xfe,0x93,0x85,0x0c}, 8333},
+ {{0x26,0x04,0x7c,0x00,0x00,0x17,0x03,0xd0,0x00,0x00,0x00,0x00,0x00,0x00,0x5a,0x4d}, 8333},
+ {{0x26,0x04,0x9a,0x00,0x21,0x00,0xa0,0x09,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00}, 8333},
+ {{0x26,0x04,0xa8,0x80,0x00,0x01,0x00,0x20,0x00,0x00,0x00,0x00,0x02,0x2a,0x40,0x01}, 8333},
+ {{0x26,0x04,0xa8,0x80,0x08,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x07,0x52,0xf0,0x01}, 8333},
+ {{0x26,0x04,0x0c,0x00,0x00,0x88,0x00,0x32,0x02,0x16,0x3e,0xff,0xfe,0xe4,0xfc,0xca}, 8333},
+ {{0x26,0x04,0x0c,0x00,0x00,0x88,0x00,0x32,0x02,0x16,0x3e,0xff,0xfe,0xf5,0xbc,0x21}, 8333},
+ {{0x26,0x05,0x79,0x80,0x00,0x01,0x00,0x02,0x00,0x00,0x00,0x00,0x17,0x61,0x3d,0x4e}, 8333},
+ {{0x26,0x05,0xe0,0x00,0x14,0x17,0x40,0x68,0x02,0x23,0x32,0xff,0xfe,0x96,0x0e,0x2d}, 8333},
+ {{0x26,0x06,0x60,0x00,0xa4,0x41,0x99,0x03,0x50,0x54,0x00,0xff,0xfe,0x78,0x66,0xff}, 8333},
+ {{0x26,0x06,0xdf,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0xae,0x85,0x8f,0xc6}, 8333},
+ {{0x26,0x07,0x53,0x00,0x01,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0e,0x7f}, 8333},
+ {{0x26,0x07,0x53,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa1}, 8333},
+ {{0x26,0x07,0x53,0x00,0x00,0x60,0x11,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
+ {{0x26,0x07,0x53,0x00,0x00,0x60,0x15,0x35,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333},
+ {{0x26,0x07,0x53,0x00,0x00,0x60,0x1b,0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
+ {{0x26,0x07,0x53,0x00,0x00,0x60,0x23,0x37,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
+ {{0x26,0x07,0x53,0x00,0x00,0x60,0x2b,0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
+ {{0x26,0x07,0x53,0x00,0x00,0x60,0x2d,0x99,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
+ {{0x26,0x07,0x53,0x00,0x00,0x60,0x03,0xcb,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
+ {{0x26,0x07,0x53,0x00,0x00,0x60,0x4a,0x85,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333},
+ {{0x26,0x07,0x53,0x00,0x00,0x60,0x51,0x12,0x00,0x00,0x00,0x02,0x4a,0xf5,0x63,0xfe}, 8333},
+ {{0x26,0x07,0x53,0x00,0x00,0x60,0x6d,0xd5,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333},
+ {{0x26,0x07,0x53,0x00,0x00,0x60,0x0a,0x91,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
+ {{0x26,0x07,0xf1,0xc0,0x08,0x20,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x3f,0x44}, 8333},
+ {{0x26,0x07,0xf1,0xc0,0x08,0x48,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x94,0x3c}, 8333},
+ {{0x26,0x07,0xf9,0x48,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07}, 8333},
+ {{0x26,0x07,0xfc,0xd0,0x01,0x00,0x23,0x00,0x00,0x00,0x00,0x00,0x04,0xad,0xe5,0x94}, 8333},
+ {{0x26,0x07,0xfc,0xd0,0x01,0x00,0x23,0x00,0x00,0x00,0x00,0x00,0x65,0x9e,0x9c,0xb3}, 8333},
+ {{0x26,0x07,0xfc,0xd0,0x01,0x00,0x23,0x00,0x00,0x00,0x00,0x00,0xc7,0x4b,0xa8,0xae}, 8333},
+ {{0x26,0x07,0xfc,0xd0,0x01,0x00,0x23,0x00,0x00,0x00,0x00,0x00,0x0d,0x82,0xd8,0xc2}, 8333},
+ {{0x26,0x07,0xfc,0xd0,0x01,0x00,0x43,0x00,0x00,0x00,0x00,0x00,0x87,0x95,0x2f,0xa8}, 8333},
+ {{0x26,0x07,0xfc,0xd0,0xda,0xaa,0x09,0x01,0x00,0x00,0x00,0x00,0x95,0x61,0xe0,0x43}, 8333},
+ {{0x2a,0x00,0x11,0x78,0x00,0x02,0x00,0x43,0x50,0x54,0x00,0xff,0xfe,0xe7,0x2e,0xb6}, 8333},
+ {{0x2a,0x00,0x13,0x28,0xe1,0x00,0xcc,0x42,0x02,0x30,0x48,0xff,0xfe,0x92,0x05,0x5d}, 8333},
+ {{0x2a,0x00,0x14,0xf0,0xe0,0x00,0x80,0xd2,0xcd,0x1a,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
+ {{0x2a,0x00,0x16,0xd8,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x5b,0x6a,0xc2,0x61}, 8333},
+ {{0x2a,0x00,0x61,0xe0,0x40,0x83,0x6d,0x01,0x68,0x52,0x13,0x76,0xe9,0x72,0x20,0x91}, 8333},
+ {{0x2a,0x00,0x0c,0x98,0x20,0x30,0xa0,0x2f,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x01,0xb0,0x79,0x99,0x04,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x31}, 8333},
+ {{0x2a,0x01,0x01,0xe8,0xe1,0x00,0x81,0x1c,0x70,0x0f,0x65,0xf0,0xf7,0x2a,0x10,0x84}, 8333},
+ {{0x2a,0x01,0x02,0x38,0x42,0xda,0xc5,0x00,0x65,0x46,0x12,0x93,0x54,0x22,0xab,0x40}, 8333},
+ {{0x2a,0x01,0x03,0x48,0x00,0x06,0x04,0x73,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x03,0x68,0xe0,0x10,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0x30,0x00,0x17,0x00,0x01,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x49}, 8333},
+ {{0x2a,0x01,0x04,0x30,0x00,0x17,0x00,0x01,0x00,0x00,0x00,0x00,0xff,0xff,0x08,0x30}, 8333},
+ {{0x2a,0x01,0x04,0x88,0x00,0x66,0x10,0x00,0x53,0xa9,0x0d,0x04,0x00,0x00,0x00,0x01}, 8333},
+ {{0x2a,0x01,0x04,0x88,0x00,0x66,0x10,0x00,0x57,0xe6,0x57,0x8c,0x00,0x00,0x00,0x01}, 8333},
+ {{0x2a,0x01,0x04,0x88,0x00,0x66,0x10,0x00,0xb0,0x1c,0x17,0x8d,0x00,0x00,0x00,0x01}, 8333},
+ {{0x2a,0x01,0x04,0x88,0x00,0x67,0x10,0x00,0x05,0x23,0xfd,0xce,0x00,0x00,0x00,0x01}, 8333},
+ {{0x2a,0x01,0x04,0x88,0x00,0x67,0x10,0x00,0xb0,0x1c,0x30,0xab,0x00,0x00,0x00,0x01}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x00,0x24,0xaa,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x00,0x44,0xe7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x00,0x51,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x00,0x84,0xa7,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x01}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x10,0x51,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x10,0x53,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x20,0x62,0xe6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x20,0x70,0x2e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x20,0x80,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x20,0x82,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x20,0x84,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x21,0x11,0xeb,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x21,0x02,0x61,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x30,0x24,0x2b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x30,0x24,0x2b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x30,0x24,0x68,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x30,0x63,0x2c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x30,0x63,0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x30,0x64,0x26,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x30,0x93,0x4f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x31,0x20,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x31,0x54,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x40,0x80,0xad,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x41,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x50,0x21,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x50,0x22,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x50,0x23,0x49,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x50,0x61,0xee,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x50,0x70,0x88,0x50,0x54,0x00,0xff,0xfe,0x45,0xbf,0xf2}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x50,0x83,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 9001},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x51,0x01,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x51,0x51,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x51,0x63,0x47,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 9001},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x61,0x52,0x6d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x61,0x93,0x49,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x62,0x23,0xc6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x62,0x43,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x62,0x73,0x45,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x62,0x73,0x83,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x62,0x74,0xe3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x90,0x60,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x90,0x63,0x49,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x90,0x64,0xc9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x90,0x91,0xce,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x91,0x21,0x94,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x83}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x91,0x40,0xa1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x91,0x04,0xa7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x91,0x63,0xb4,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x91,0x71,0x21,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x91,0x83,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x91,0x93,0xc4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x92,0x60,0xa9,0x00,0x00,0x00,0x01,0x00,0x05,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x92,0x73,0xb2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x92,0x80,0x98,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x01,0x92,0x00,0xdb,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x02,0x00,0x10,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x02,0x00,0x22,0xe3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x02,0x00,0x41,0x4e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x02,0x00,0x63,0xaf,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x22}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x02,0x00,0x71,0xe3,0x78,0xb4,0xf3,0xff,0xfe,0xad,0xe8,0xcf}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x02,0x01,0x51,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x02,0x01,0x60,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x02,0x01,0x60,0xd5,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x02,0x02,0x53,0xc3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x02,0x10,0x24,0xaa,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x02,0x10,0x50,0x2f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x02,0x11,0x14,0xcf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x02,0x11,0x1a,0x59,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x02,0x11,0x2a,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x02,0x11,0x0c,0xca,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x00,0xa0,0x22,0xa5,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x00,0xa0,0x50,0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x00,0xa0,0x52,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x00,0xa0,0x74,0xc8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x00,0xa0,0x82,0x27,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x00,0xa0,0x82,0x2d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x04,0xf8,0x0d,0x13,0x21,0x83,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x01,0x06,0x08,0xff,0xff,0xa0,0x09,0x8b,0xf5,0x87,0x9d,0xe5,0x1a,0xf8,0x37}, 8333},
+ {{0x2a,0x01,0x07,0x9d,0x46,0x9e,0xed,0x94,0xc2,0x3f,0xd5,0xff,0xfe,0x65,0x20,0xc5}, 8333},
+ {{0x2a,0x01,0x07,0xc8,0xaa,0xb5,0x03,0xe6,0x50,0x54,0x00,0xff,0xfe,0xd7,0x4e,0x54}, 8333},
+ {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x18,0x30,0x1e}, 8333},
+ {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x18,0x77,0x49}, 8333},
+ {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x33,0x2d,0x67}, 8333},
+ {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x33,0x34,0x7c}, 8333},
+ {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x33,0xae,0x50}, 8333},
+ {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x56,0x6b,0x5c}, 8333},
+ {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x56,0xbe,0xe6}, 8333},
+ {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x69,0x48,0x95}, 8333},
+ {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x69,0x99,0x12}, 8333},
+ {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x6e,0x26,0xee}, 8333},
+ {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x73,0x42,0xf1}, 8333},
+ {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x84,0x43,0x4f}, 8333},
+ {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x84,0xb3,0x6b}, 8333},
+ {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x89,0x1f,0xaa}, 8333},
+ {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x98,0x08,0x16}, 8333},
+ {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0xdb,0x35,0x2e}, 8333},
+ {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0xdb,0x4a,0x1d}, 8333},
+ {{0x2a,0x01,0x0e,0x34,0xed,0xbb,0x67,0x50,0x02,0x24,0x1d,0xff,0xfe,0x89,0x38,0x97}, 8333},
+ {{0x2a,0x01,0x0e,0x35,0x2f,0x1d,0x3f,0xb0,0x71,0x87,0xc7,0xba,0xbc,0xfc,0x80,0xce}, 8333},
+ {{0x2a,0x01,0x0e,0x35,0x87,0x87,0x96,0xf0,0x90,0x32,0x92,0x97,0x39,0xae,0x49,0x6d}, 8333},
+ {{0x2a,0x01,0x0e,0x35,0x8a,0x3f,0x47,0xc0,0xc6,0x17,0xfe,0xff,0xfe,0x3c,0x9f,0xbd}, 8333},
+ {{0x2a,0x01,0x0e,0x35,0x8b,0x66,0x06,0xa0,0x49,0x00,0x9d,0xfd,0xd8,0x41,0xd0,0x25}, 8333},
+ {{0x2a,0x02,0x01,0x68,0x4a,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x39}, 8333},
+ {{0x2a,0x02,0x01,0x68,0x54,0x04,0x00,0x02,0xc2,0x3f,0xd5,0xff,0xfe,0x6a,0x51,0x2e}, 8333},
+ {{0x2a,0x02,0x01,0x80,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x5b,0x8f,0x53,0x8c}, 8333},
+ {{0x2a,0x02,0x20,0x28,0x10,0x16,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333},
+ {{0x2a,0x02,0x25,0x28,0x05,0x03,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14}, 8333},
+ {{0x2a,0x02,0x25,0x28,0x05,0x03,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x15}, 8333},
+ {{0x2a,0x02,0x25,0x28,0xff,0x00,0x81,0xa6,0x02,0x1e,0xc5,0xff,0xfe,0x8d,0xf9,0xa5}, 8333},
+ {{0x2a,0x02,0x27,0x70,0x00,0x05,0x00,0x00,0x02,0x1a,0x4a,0xff,0xfe,0xe4,0xc7,0xdb}, 8333},
+ {{0x2a,0x02,0x27,0x70,0x00,0x08,0x00,0x00,0x02,0x1a,0x4a,0xff,0xfe,0x7b,0x3d,0xcd}, 8333},
+ {{0x2a,0x02,0x03,0x48,0x00,0x5e,0x5a,0x29,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
+ {{0x2a,0x02,0x7a,0xa0,0x16,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x2f,0xc0,0x6a}, 8333},
+ {{0x2a,0x02,0x81,0x09,0x8e,0x40,0x35,0xfc,0xba,0x27,0xeb,0xff,0xfe,0xae,0xcf,0x16}, 8333},
+ {{0x2a,0x02,0x0a,0xf8,0x00,0x06,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x30}, 8333},
+ {{0x2a,0x02,0xc2,0x00,0x00,0x00,0x00,0x10,0x00,0x01,0x00,0x00,0x63,0x14,0x22,0x22}, 8333},
+ {{0x2a,0x02,0xc2,0x00,0x00,0x00,0x00,0x10,0x00,0x02,0x00,0x03,0x32,0x95,0x00,0x01}, 8332},
+ {{0x2a,0x02,0xc2,0x00,0x00,0x00,0x00,0x10,0x00,0x03,0x00,0x00,0x54,0x49,0x00,0x01}, 8333},
+ {{0x2a,0x02,0xc2,0x00,0x00,0x01,0x00,0x10,0x00,0x02,0x00,0x03,0x58,0x99,0x00,0x01}, 8333},
+ {{0x2a,0x02,0xc2,0x00,0x00,0x01,0x00,0x10,0x00,0x00,0x00,0x00,0x27,0x05,0x00,0x01}, 8333},
+ {{0x2a,0x02,0xce,0x80,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333},
+ {{0x2a,0x02,0x0f,0xe0,0xc3,0x21,0x27,0xe0,0x6e,0xf0,0x49,0xff,0xfe,0x11,0xa6,0x1d}, 8333},
+ {{0x2a,0x03,0x40,0x00,0x00,0x02,0x04,0x96,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08}, 8333},
+ {{0x2a,0x03,0xb0,0xc0,0x00,0x00,0x10,0x10,0x00,0x00,0x00,0x00,0x00,0x62,0xf0,0x01}, 8333},
+ {{0x2a,0x03,0x0f,0x80,0xed,0x16,0x0c,0xa7,0xea,0x75,0xb1,0x2d,0x02,0xaf,0x9e,0x2a}, 8333},
+ {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xd9,0x4a,0xaf,0xa2,0x8c,0x9d,0xf6,0x22,0x18,0x28}, 8333},
+ {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xd9,0xe4,0x70,0x01,0xb3,0xa7,0x9d,0x3e,0x51,0xf9}, 8333},
+ {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xe7,0x45,0xd5,0x8b,0xff,0x81,0x9e,0x85,0x00,0xb8}, 8333},
+ {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xff,0xd9,0x7d,0x26,0x57,0x03,0xb0,0x49,0x67,0x4f}, 8333},
+ {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xf9,0xbe,0x9e,0xf0,0x33,0x40,0x2e,0x79,0xc9,0x18}, 8333},
+ {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x0f,0x8b,0x1f,0x8d,0x61,0xa6,0x94,0xf4,0x62,0x45}, 8333},
+ {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x0a,0x26,0x27,0x21,0xa2,0x2c,0x05,0x29,0x20,0xdd}, 8333},
+ {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x0a,0x26,0x27,0x21,0xae,0x94,0xd5,0xc2,0x72,0x24}, 8333},
+ {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x0b,0x29,0x34,0x96,0x29,0xe8,0x67,0x22,0x0c,0x61}, 8333},
+ {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x1c,0x5f,0xc7,0xd4,0x89,0xc0,0x6f,0xa2,0x24,0x71}, 8333},
+ {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x32,0x2e,0xda,0xf7,0xc3,0xf6,0xc3,0x4c,0x3c,0x0d}, 8333},
+ {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x3e,0xaa,0xb7,0xd0,0x79,0x79,0xf3,0x0b,0xd2,0x63}, 8333},
+ {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x39,0xd1,0x5e,0xbd,0xb7,0x23,0x6a,0x12,0xf0,0x0c}, 8333},
+ {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x5e,0x6e,0xf5,0x37,0xcf,0x9b,0xf6,0xe3,0x9f,0xdb}, 8333},
+ {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x64,0x9e,0x79,0x18,0xa8,0x81,0x61,0xd9,0x4d,0xa4}, 8333},
+ {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x68,0xac,0xad,0xae,0x93,0x23,0x0a,0x51,0x3c,0x5c}, 8333},
+ {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x72,0x87,0x94,0x82,0x36,0x22,0x83,0x23,0xb5,0xc5}, 8333},
+ {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x92,0x46,0xe6,0x23,0x98,0x0e,0x87,0x65,0x24,0x22}, 8333},
+ {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xa5,0x6c,0xec,0xda,0xeb,0x41,0xdb,0x34,0x18,0x21}, 8333},
+ {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xaf,0xb0,0xbc,0xf3,0xa3,0x6f,0x70,0x17,0xab,0x83}, 8333},
+ {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xaa,0xb7,0x04,0x8c,0x87,0xc6,0x38,0x3b,0x0a,0xf6}, 8333},
+ {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xac,0x1f,0x82,0x69,0x5d,0x88,0xa1,0x54,0xf5,0x90}, 8333},
+ {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xbd,0x06,0xa7,0x66,0x63,0x2c,0x65,0x4c,0x61,0xd4}, 8333},
+ {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xcf,0x7b,0x5e,0x3a,0x53,0x21,0x5b,0x62,0xe3,0x7a}, 8333}
+};
+
+static SeedSpec6 pnSeed6_test[] = {
+ {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x99,0xcb,0x26,0x31,0xba,0x48,0x51,0x31,0x39,0x0d}, 18333},
+ {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x44,0xf4,0xf4,0xf0,0xbf,0xf7,0x7e,0x6d,0xc4,0xe8}, 18333},
+ {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x6a,0x8b,0xd2,0x78,0x3f,0x7a,0xf8,0x92,0x8f,0x80}, 18333},
+ {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xe6,0x4e,0xa4,0x47,0x4e,0x2a,0xfe,0xe8,0x95,0xcc}, 18333},
+ {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x9f,0xae,0x9f,0x59,0x0b,0x3f,0x31,0x3a,0x8a,0x5f}, 18333},
+ {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x47,0xb1,0xe4,0x55,0xd1,0xb0,0x14,0x3f,0xb6,0xdb}, 18333},
+ {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xa0,0x60,0x9e,0x46,0x54,0xdb,0x61,0x3b,0xb2,0x6f}, 18333}
+};
+#endif // BITCOIN_CHAINPARAMSSEEDS_H
diff --git a/src/checkpoints.cpp b/src/checkpoints.cpp
new file mode 100644
index 0000000000..2024486139
--- /dev/null
+++ b/src/checkpoints.cpp
@@ -0,0 +1,90 @@
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "checkpoints.h"
+
+#include "chainparams.h"
+#include "main.h"
+#include "uint256.h"
+
+#include <stdint.h>
+
+#include <boost/foreach.hpp>
+
+namespace Checkpoints {
+
+ /**
+ * How many times slower we expect checking transactions after the last
+ * checkpoint to be (from checking signatures, which is skipped up to the
+ * last checkpoint). This number is a compromise, as it can't be accurate
+ * for every system. When reindexing from a fast disk with a slow CPU, it
+ * can be up to 20, while when downloading from a slow network with a
+ * fast multicore CPU, it won't be much higher than 1.
+ */
+ static const double SIGCHECK_VERIFICATION_FACTOR = 5.0;
+
+ bool CheckBlock(const CCheckpointData& data, int nHeight, const uint256& hash)
+ {
+ const MapCheckpoints& checkpoints = data.mapCheckpoints;
+
+ MapCheckpoints::const_iterator i = checkpoints.find(nHeight);
+ if (i == checkpoints.end()) return true;
+ return hash == i->second;
+ }
+
+ //! Guess how far we are in the verification process at the given block index
+ double GuessVerificationProgress(const CCheckpointData& data, CBlockIndex *pindex, bool fSigchecks) {
+ if (pindex==NULL)
+ return 0.0;
+
+ int64_t nNow = time(NULL);
+
+ double fSigcheckVerificationFactor = fSigchecks ? SIGCHECK_VERIFICATION_FACTOR : 1.0;
+ double fWorkBefore = 0.0; // Amount of work done before pindex
+ double fWorkAfter = 0.0; // Amount of work left after pindex (estimated)
+ // Work is defined as: 1.0 per transaction before the last checkpoint, and
+ // fSigcheckVerificationFactor per transaction after.
+
+ if (pindex->nChainTx <= data.nTransactionsLastCheckpoint) {
+ double nCheapBefore = pindex->nChainTx;
+ double nCheapAfter = data.nTransactionsLastCheckpoint - pindex->nChainTx;
+ double nExpensiveAfter = (nNow - data.nTimeLastCheckpoint)/86400.0*data.fTransactionsPerDay;
+ fWorkBefore = nCheapBefore;
+ fWorkAfter = nCheapAfter + nExpensiveAfter*fSigcheckVerificationFactor;
+ } else {
+ double nCheapBefore = data.nTransactionsLastCheckpoint;
+ double nExpensiveBefore = pindex->nChainTx - data.nTransactionsLastCheckpoint;
+ double nExpensiveAfter = (nNow - pindex->GetBlockTime())/86400.0*data.fTransactionsPerDay;
+ fWorkBefore = nCheapBefore + nExpensiveBefore*fSigcheckVerificationFactor;
+ fWorkAfter = nExpensiveAfter*fSigcheckVerificationFactor;
+ }
+
+ return fWorkBefore / (fWorkBefore + fWorkAfter);
+ }
+
+ int GetTotalBlocksEstimate(const CCheckpointData& data)
+ {
+ const MapCheckpoints& checkpoints = data.mapCheckpoints;
+
+ if (checkpoints.empty())
+ return 0;
+
+ return checkpoints.rbegin()->first;
+ }
+
+ CBlockIndex* GetLastCheckpoint(const CCheckpointData& data)
+ {
+ const MapCheckpoints& checkpoints = data.mapCheckpoints;
+
+ BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, checkpoints)
+ {
+ const uint256& hash = i.second;
+ BlockMap::const_iterator t = mapBlockIndex.find(hash);
+ if (t != mapBlockIndex.end())
+ return t->second;
+ }
+ return NULL;
+ }
+
+} // namespace Checkpoints
diff --git a/src/checkpoints.h b/src/checkpoints.h
new file mode 100644
index 0000000000..a720f096c0
--- /dev/null
+++ b/src/checkpoints.h
@@ -0,0 +1,42 @@
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_CHECKPOINTS_H
+#define BITCOIN_CHECKPOINTS_H
+
+#include "uint256.h"
+
+#include <map>
+
+class CBlockIndex;
+
+/**
+ * Block-chain checkpoints are compiled-in sanity checks.
+ * They are updated every release or three.
+ */
+namespace Checkpoints
+{
+typedef std::map<int, uint256> MapCheckpoints;
+
+struct CCheckpointData {
+ MapCheckpoints mapCheckpoints;
+ int64_t nTimeLastCheckpoint;
+ int64_t nTransactionsLastCheckpoint;
+ double fTransactionsPerDay;
+};
+
+//! Returns true if block passes checkpoint checks
+bool CheckBlock(const CCheckpointData& data, int nHeight, const uint256& hash);
+
+//! Return conservative estimate of total number of blocks, 0 if unknown
+int GetTotalBlocksEstimate(const CCheckpointData& data);
+
+//! Returns last CBlockIndex* in mapBlockIndex that is a checkpoint
+CBlockIndex* GetLastCheckpoint(const CCheckpointData& data);
+
+double GuessVerificationProgress(const CCheckpointData& data, CBlockIndex* pindex, bool fSigchecks = true);
+
+} //namespace Checkpoints
+
+#endif // BITCOIN_CHECKPOINTS_H
diff --git a/src/checkqueue.h b/src/checkqueue.h
new file mode 100644
index 0000000000..20ba25bb41
--- /dev/null
+++ b/src/checkqueue.h
@@ -0,0 +1,215 @@
+// Copyright (c) 2012-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_CHECKQUEUE_H
+#define BITCOIN_CHECKQUEUE_H
+
+#include <algorithm>
+#include <vector>
+
+#include <boost/foreach.hpp>
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/thread/mutex.hpp>
+
+template <typename T>
+class CCheckQueueControl;
+
+/**
+ * Queue for verifications that have to be performed.
+ * The verifications are represented by a type T, which must provide an
+ * operator(), returning a bool.
+ *
+ * One thread (the master) is assumed to push batches of verifications
+ * onto the queue, where they are processed by N-1 worker threads. When
+ * the master is done adding work, it temporarily joins the worker pool
+ * as an N'th worker, until all jobs are done.
+ */
+template <typename T>
+class CCheckQueue
+{
+private:
+ //! Mutex to protect the inner state
+ boost::mutex mutex;
+
+ //! Worker threads block on this when out of work
+ boost::condition_variable condWorker;
+
+ //! Master thread blocks on this when out of work
+ boost::condition_variable condMaster;
+
+ //! The queue of elements to be processed.
+ //! As the order of booleans doesn't matter, it is used as a LIFO (stack)
+ std::vector<T> queue;
+
+ //! The number of workers (including the master) that are idle.
+ int nIdle;
+
+ //! The total number of workers (including the master).
+ int nTotal;
+
+ //! The temporary evaluation result.
+ bool fAllOk;
+
+ /**
+ * Number of verifications that haven't completed yet.
+ * This includes elements that are no longer queued, but still in the
+ * worker's own batches.
+ */
+ unsigned int nTodo;
+
+ //! Whether we're shutting down.
+ bool fQuit;
+
+ //! The maximum number of elements to be processed in one batch
+ unsigned int nBatchSize;
+
+ /** Internal function that does bulk of the verification work. */
+ bool Loop(bool fMaster = false)
+ {
+ boost::condition_variable& cond = fMaster ? condMaster : condWorker;
+ std::vector<T> vChecks;
+ vChecks.reserve(nBatchSize);
+ unsigned int nNow = 0;
+ bool fOk = true;
+ do {
+ {
+ boost::unique_lock<boost::mutex> lock(mutex);
+ // first do the clean-up of the previous loop run (allowing us to do it in the same critsect)
+ if (nNow) {
+ fAllOk &= fOk;
+ nTodo -= nNow;
+ if (nTodo == 0 && !fMaster)
+ // We processed the last element; inform the master it can exit and return the result
+ condMaster.notify_one();
+ } else {
+ // first iteration
+ nTotal++;
+ }
+ // logically, the do loop starts here
+ while (queue.empty()) {
+ if ((fMaster || fQuit) && nTodo == 0) {
+ nTotal--;
+ bool fRet = fAllOk;
+ // reset the status for new work later
+ if (fMaster)
+ fAllOk = true;
+ // return the current status
+ return fRet;
+ }
+ nIdle++;
+ cond.wait(lock); // wait
+ nIdle--;
+ }
+ // Decide how many work units to process now.
+ // * Do not try to do everything at once, but aim for increasingly smaller batches so
+ // all workers finish approximately simultaneously.
+ // * Try to account for idle jobs which will instantly start helping.
+ // * Don't do batches smaller than 1 (duh), or larger than nBatchSize.
+ nNow = std::max(1U, std::min(nBatchSize, (unsigned int)queue.size() / (nTotal + nIdle + 1)));
+ vChecks.resize(nNow);
+ for (unsigned int i = 0; i < nNow; i++) {
+ // We want the lock on the mutex to be as short as possible, so swap jobs from the global
+ // queue to the local batch vector instead of copying.
+ vChecks[i].swap(queue.back());
+ queue.pop_back();
+ }
+ // Check whether we need to do work at all
+ fOk = fAllOk;
+ }
+ // execute work
+ BOOST_FOREACH (T& check, vChecks)
+ if (fOk)
+ fOk = check();
+ vChecks.clear();
+ } while (true);
+ }
+
+public:
+ //! Create a new check queue
+ CCheckQueue(unsigned int nBatchSizeIn) : nIdle(0), nTotal(0), fAllOk(true), nTodo(0), fQuit(false), nBatchSize(nBatchSizeIn) {}
+
+ //! Worker thread
+ void Thread()
+ {
+ Loop();
+ }
+
+ //! Wait until execution finishes, and return whether all evaluations were successful.
+ bool Wait()
+ {
+ return Loop(true);
+ }
+
+ //! Add a batch of checks to the queue
+ void Add(std::vector<T>& vChecks)
+ {
+ boost::unique_lock<boost::mutex> lock(mutex);
+ BOOST_FOREACH (T& check, vChecks) {
+ queue.push_back(T());
+ check.swap(queue.back());
+ }
+ nTodo += vChecks.size();
+ if (vChecks.size() == 1)
+ condWorker.notify_one();
+ else if (vChecks.size() > 1)
+ condWorker.notify_all();
+ }
+
+ ~CCheckQueue()
+ {
+ }
+
+ bool IsIdle()
+ {
+ boost::unique_lock<boost::mutex> lock(mutex);
+ return (nTotal == nIdle && nTodo == 0 && fAllOk == true);
+ }
+
+};
+
+/**
+ * RAII-style controller object for a CCheckQueue that guarantees the passed
+ * queue is finished before continuing.
+ */
+template <typename T>
+class CCheckQueueControl
+{
+private:
+ CCheckQueue<T>* pqueue;
+ bool fDone;
+
+public:
+ CCheckQueueControl(CCheckQueue<T>* pqueueIn) : pqueue(pqueueIn), fDone(false)
+ {
+ // passed queue is supposed to be unused, or NULL
+ if (pqueue != NULL) {
+ bool isIdle = pqueue->IsIdle();
+ assert(isIdle);
+ }
+ }
+
+ bool Wait()
+ {
+ if (pqueue == NULL)
+ return true;
+ bool fRet = pqueue->Wait();
+ fDone = true;
+ return fRet;
+ }
+
+ void Add(std::vector<T>& vChecks)
+ {
+ if (pqueue != NULL)
+ pqueue->Add(vChecks);
+ }
+
+ ~CCheckQueueControl()
+ {
+ if (!fDone)
+ Wait();
+ }
+};
+
+#endif // BITCOIN_CHECKQUEUE_H
diff --git a/src/clientversion.cpp b/src/clientversion.cpp
new file mode 100644
index 0000000000..aae0569bba
--- /dev/null
+++ b/src/clientversion.cpp
@@ -0,0 +1,112 @@
+// Copyright (c) 2012-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "clientversion.h"
+
+#include "tinyformat.h"
+
+#include <string>
+
+/**
+ * Name of client reported in the 'version' message. Report the same name
+ * for both bitcoind and bitcoin-core, to make it harder for attackers to
+ * target servers or GUI users specifically.
+ */
+const std::string CLIENT_NAME("Satoshi");
+
+/**
+ * Client version number
+ */
+#define CLIENT_VERSION_SUFFIX ""
+
+
+/**
+ * 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. $Format:%n#define GIT_ARCHIVE 1$
+#ifdef GIT_ARCHIVE
+#define GIT_COMMIT_ID "$Format:%h$"
+#define GIT_COMMIT_DATE "$Format:%cD$"
+#endif
+
+#define BUILD_DESC_WITH_SUFFIX(maj, min, rev, build, suffix) \
+ "v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) "." DO_STRINGIZE(build) "-" DO_STRINGIZE(suffix)
+
+#define BUILD_DESC_FROM_COMMIT(maj, min, rev, build, commit) \
+ "v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) "." DO_STRINGIZE(build) "-g" commit
+
+#define BUILD_DESC_FROM_UNKNOWN(maj, min, rev, build) \
+ "v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) "." DO_STRINGIZE(build) "-unk"
+
+#ifndef BUILD_DESC
+#ifdef BUILD_SUFFIX
+#define BUILD_DESC BUILD_DESC_WITH_SUFFIX(CLIENT_VERSION_MAJOR, CLIENT_VERSION_MINOR, CLIENT_VERSION_REVISION, CLIENT_VERSION_BUILD, BUILD_SUFFIX)
+#elif defined(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);
+
+static std::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);
+}
+
+std::string FormatFullVersion()
+{
+ return CLIENT_BUILD;
+}
+
+/**
+ * Format the subversion field according to BIP 14 spec (https://github.com/bitcoin/bips/blob/master/bip-0014.mediawiki)
+ */
+std::string FormatSubVersion(const std::string& name, int nClientVersion, const std::vector<std::string>& comments)
+{
+ std::ostringstream ss;
+ ss << "/";
+ ss << name << ":" << FormatVersion(nClientVersion);
+ if (!comments.empty())
+ {
+ std::vector<std::string>::const_iterator it(comments.begin());
+ ss << "(" << *it;
+ for(++it; it != comments.end(); ++it)
+ ss << "; " << *it;
+ ss << ")";
+ }
+ ss << "/";
+ return ss.str();
+}
diff --git a/src/clientversion.h b/src/clientversion.h
new file mode 100644
index 0000000000..35ad13a474
--- /dev/null
+++ b/src/clientversion.h
@@ -0,0 +1,70 @@
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_CLIENTVERSION_H
+#define BITCOIN_CLIENTVERSION_H
+
+#if defined(HAVE_CONFIG_H)
+#include "config/bitcoin-config.h"
+#else
+
+/**
+ * client versioning and copyright year
+ */
+
+//! These need to be macros, as clientversion.cpp's and bitcoin*-res.rc's voodoo requires it
+#define CLIENT_VERSION_MAJOR 0
+#define CLIENT_VERSION_MINOR 11
+#define CLIENT_VERSION_REVISION 1
+#define CLIENT_VERSION_BUILD 0
+
+//! Set to true for release, false for prerelease or test build
+#define CLIENT_VERSION_IS_RELEASE true
+
+/**
+ * Copyright year (2009-this)
+ * Todo: update this when changing our copyright comments in the source
+ */
+#define COPYRIGHT_YEAR 2015
+
+#endif //HAVE_CONFIG_H
+
+/**
+ * Converts the parameter X to a string after macro replacement on X has been performed.
+ * Don't merge these into one macro!
+ */
+#define STRINGIZE(X) DO_STRINGIZE(X)
+#define DO_STRINGIZE(X) #X
+
+//! Copyright string used in Windows .rc files
+#define COPYRIGHT_STR "2009-" STRINGIZE(COPYRIGHT_YEAR) " The Bitcoin Core Developers"
+
+/**
+ * bitcoind-res.rc includes this file, but it cannot cope with real c++ code.
+ * WINDRES_PREPROC is defined to indicate that its pre-processor is running.
+ * Anything other than a define should be guarded below.
+ */
+
+#if !defined(WINDRES_PREPROC)
+
+#include <string>
+#include <vector>
+
+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;
+
+
+std::string FormatFullVersion();
+std::string FormatSubVersion(const std::string& name, int nClientVersion, const std::vector<std::string>& comments);
+
+#endif // WINDRES_PREPROC
+
+#endif // BITCOIN_CLIENTVERSION_H
diff --git a/src/coincontrol.h b/src/coincontrol.h
new file mode 100644
index 0000000000..92fae9847c
--- /dev/null
+++ b/src/coincontrol.h
@@ -0,0 +1,62 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_COINCONTROL_H
+#define BITCOIN_COINCONTROL_H
+
+#include "primitives/transaction.h"
+
+/** Coin Control Features. */
+class CCoinControl
+{
+public:
+ CTxDestination destChange;
+
+ CCoinControl()
+ {
+ SetNull();
+ }
+
+ void SetNull()
+ {
+ destChange = CNoDestination();
+ setSelected.clear();
+ }
+
+ bool HasSelected() const
+ {
+ return (setSelected.size() > 0);
+ }
+
+ bool IsSelected(const uint256& hash, unsigned int n) const
+ {
+ COutPoint outpt(hash, n);
+ return (setSelected.count(outpt) > 0);
+ }
+
+ void Select(const COutPoint& output)
+ {
+ setSelected.insert(output);
+ }
+
+ void UnSelect(const COutPoint& output)
+ {
+ setSelected.erase(output);
+ }
+
+ void UnSelectAll()
+ {
+ setSelected.clear();
+ }
+
+ void ListSelected(std::vector<COutPoint>& vOutpoints)
+ {
+ vOutpoints.assign(setSelected.begin(), setSelected.end());
+ }
+
+private:
+ std::set<COutPoint> setSelected;
+};
+
+#endif // BITCOIN_COINCONTROL_H
diff --git a/src/coins.cpp b/src/coins.cpp
new file mode 100644
index 0000000000..a41d5a310d
--- /dev/null
+++ b/src/coins.cpp
@@ -0,0 +1,266 @@
+// Copyright (c) 2012-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "coins.h"
+
+#include "memusage.h"
+#include "random.h"
+
+#include <assert.h>
+
+/**
+ * calculate number of bytes for the bitmask, and its number of non-zero bytes
+ * each bit in the bitmask represents the availability of one output, but the
+ * availabilities of the first two outputs are encoded separately
+ */
+void CCoins::CalcMaskSize(unsigned int &nBytes, unsigned int &nNonzeroBytes) const {
+ unsigned int nLastUsedByte = 0;
+ for (unsigned int b = 0; 2+b*8 < vout.size(); b++) {
+ bool fZero = true;
+ for (unsigned int i = 0; i < 8 && 2+b*8+i < vout.size(); i++) {
+ if (!vout[2+b*8+i].IsNull()) {
+ fZero = false;
+ continue;
+ }
+ }
+ if (!fZero) {
+ nLastUsedByte = b + 1;
+ nNonzeroBytes++;
+ }
+ }
+ nBytes += nLastUsedByte;
+}
+
+bool CCoins::Spend(uint32_t nPos)
+{
+ if (nPos >= vout.size() || vout[nPos].IsNull())
+ return false;
+ vout[nPos].SetNull();
+ Cleanup();
+ return true;
+}
+
+bool CCoinsView::GetCoins(const uint256 &txid, CCoins &coins) const { return false; }
+bool CCoinsView::HaveCoins(const uint256 &txid) const { return false; }
+uint256 CCoinsView::GetBestBlock() const { return uint256(); }
+bool CCoinsView::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return false; }
+bool CCoinsView::GetStats(CCoinsStats &stats) const { return false; }
+
+
+CCoinsViewBacked::CCoinsViewBacked(CCoinsView *viewIn) : base(viewIn) { }
+bool CCoinsViewBacked::GetCoins(const uint256 &txid, CCoins &coins) const { return base->GetCoins(txid, coins); }
+bool CCoinsViewBacked::HaveCoins(const uint256 &txid) const { return base->HaveCoins(txid); }
+uint256 CCoinsViewBacked::GetBestBlock() const { return base->GetBestBlock(); }
+void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; }
+bool CCoinsViewBacked::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return base->BatchWrite(mapCoins, hashBlock); }
+bool CCoinsViewBacked::GetStats(CCoinsStats &stats) const { return base->GetStats(stats); }
+
+CCoinsKeyHasher::CCoinsKeyHasher() : salt(GetRandHash()) {}
+
+CCoinsViewCache::CCoinsViewCache(CCoinsView *baseIn) : CCoinsViewBacked(baseIn), hasModifier(false), cachedCoinsUsage(0) { }
+
+CCoinsViewCache::~CCoinsViewCache()
+{
+ assert(!hasModifier);
+}
+
+size_t CCoinsViewCache::DynamicMemoryUsage() const {
+ return memusage::DynamicUsage(cacheCoins) + cachedCoinsUsage;
+}
+
+CCoinsMap::const_iterator CCoinsViewCache::FetchCoins(const uint256 &txid) const {
+ CCoinsMap::iterator it = cacheCoins.find(txid);
+ if (it != cacheCoins.end())
+ return it;
+ CCoins tmp;
+ if (!base->GetCoins(txid, tmp))
+ return cacheCoins.end();
+ CCoinsMap::iterator ret = cacheCoins.insert(std::make_pair(txid, CCoinsCacheEntry())).first;
+ tmp.swap(ret->second.coins);
+ if (ret->second.coins.IsPruned()) {
+ // The parent only has an empty entry for this txid; we can consider our
+ // version as fresh.
+ ret->second.flags = CCoinsCacheEntry::FRESH;
+ }
+ cachedCoinsUsage += memusage::DynamicUsage(ret->second.coins);
+ return ret;
+}
+
+bool CCoinsViewCache::GetCoins(const uint256 &txid, CCoins &coins) const {
+ CCoinsMap::const_iterator it = FetchCoins(txid);
+ if (it != cacheCoins.end()) {
+ coins = it->second.coins;
+ return true;
+ }
+ return false;
+}
+
+CCoinsModifier CCoinsViewCache::ModifyCoins(const uint256 &txid) {
+ assert(!hasModifier);
+ std::pair<CCoinsMap::iterator, bool> ret = cacheCoins.insert(std::make_pair(txid, CCoinsCacheEntry()));
+ size_t cachedCoinUsage = 0;
+ if (ret.second) {
+ if (!base->GetCoins(txid, ret.first->second.coins)) {
+ // The parent view does not have this entry; mark it as fresh.
+ ret.first->second.coins.Clear();
+ ret.first->second.flags = CCoinsCacheEntry::FRESH;
+ } else if (ret.first->second.coins.IsPruned()) {
+ // The parent view only has a pruned entry for this; mark it as fresh.
+ ret.first->second.flags = CCoinsCacheEntry::FRESH;
+ }
+ } else {
+ cachedCoinUsage = memusage::DynamicUsage(ret.first->second.coins);
+ }
+ // Assume that whenever ModifyCoins is called, the entry will be modified.
+ ret.first->second.flags |= CCoinsCacheEntry::DIRTY;
+ return CCoinsModifier(*this, ret.first, cachedCoinUsage);
+}
+
+const CCoins* CCoinsViewCache::AccessCoins(const uint256 &txid) const {
+ CCoinsMap::const_iterator it = FetchCoins(txid);
+ if (it == cacheCoins.end()) {
+ return NULL;
+ } else {
+ return &it->second.coins;
+ }
+}
+
+bool CCoinsViewCache::HaveCoins(const uint256 &txid) const {
+ CCoinsMap::const_iterator it = FetchCoins(txid);
+ // We're using vtx.empty() instead of IsPruned here for performance reasons,
+ // as we only care about the case where a transaction was replaced entirely
+ // in a reorganization (which wipes vout entirely, as opposed to spending
+ // which just cleans individual outputs).
+ return (it != cacheCoins.end() && !it->second.coins.vout.empty());
+}
+
+uint256 CCoinsViewCache::GetBestBlock() const {
+ if (hashBlock.IsNull())
+ hashBlock = base->GetBestBlock();
+ return hashBlock;
+}
+
+void CCoinsViewCache::SetBestBlock(const uint256 &hashBlockIn) {
+ hashBlock = hashBlockIn;
+}
+
+bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn) {
+ assert(!hasModifier);
+ for (CCoinsMap::iterator it = mapCoins.begin(); it != mapCoins.end();) {
+ if (it->second.flags & CCoinsCacheEntry::DIRTY) { // Ignore non-dirty entries (optimization).
+ CCoinsMap::iterator itUs = cacheCoins.find(it->first);
+ if (itUs == cacheCoins.end()) {
+ if (!it->second.coins.IsPruned()) {
+ // The parent cache does not have an entry, while the child
+ // cache does have (a non-pruned) one. Move the data up, and
+ // mark it as fresh (if the grandparent did have it, we
+ // would have pulled it in at first GetCoins).
+ assert(it->second.flags & CCoinsCacheEntry::FRESH);
+ CCoinsCacheEntry& entry = cacheCoins[it->first];
+ entry.coins.swap(it->second.coins);
+ cachedCoinsUsage += memusage::DynamicUsage(entry.coins);
+ entry.flags = CCoinsCacheEntry::DIRTY | CCoinsCacheEntry::FRESH;
+ }
+ } else {
+ if ((itUs->second.flags & CCoinsCacheEntry::FRESH) && it->second.coins.IsPruned()) {
+ // The grandparent does not have an entry, and the child is
+ // modified and being pruned. This means we can just delete
+ // it from the parent.
+ cachedCoinsUsage -= memusage::DynamicUsage(itUs->second.coins);
+ cacheCoins.erase(itUs);
+ } else {
+ // A normal modification.
+ cachedCoinsUsage -= memusage::DynamicUsage(itUs->second.coins);
+ itUs->second.coins.swap(it->second.coins);
+ cachedCoinsUsage += memusage::DynamicUsage(itUs->second.coins);
+ itUs->second.flags |= CCoinsCacheEntry::DIRTY;
+ }
+ }
+ }
+ CCoinsMap::iterator itOld = it++;
+ mapCoins.erase(itOld);
+ }
+ hashBlock = hashBlockIn;
+ return true;
+}
+
+bool CCoinsViewCache::Flush() {
+ bool fOk = base->BatchWrite(cacheCoins, hashBlock);
+ cacheCoins.clear();
+ cachedCoinsUsage = 0;
+ return fOk;
+}
+
+unsigned int CCoinsViewCache::GetCacheSize() const {
+ return cacheCoins.size();
+}
+
+const CTxOut &CCoinsViewCache::GetOutputFor(const CTxIn& input) const
+{
+ const CCoins* coins = AccessCoins(input.prevout.hash);
+ assert(coins && coins->IsAvailable(input.prevout.n));
+ return coins->vout[input.prevout.n];
+}
+
+CAmount CCoinsViewCache::GetValueIn(const CTransaction& tx) const
+{
+ if (tx.IsCoinBase())
+ return 0;
+
+ CAmount nResult = 0;
+ for (unsigned int i = 0; i < tx.vin.size(); i++)
+ nResult += GetOutputFor(tx.vin[i]).nValue;
+
+ return nResult;
+}
+
+bool CCoinsViewCache::HaveInputs(const CTransaction& tx) const
+{
+ if (!tx.IsCoinBase()) {
+ for (unsigned int i = 0; i < tx.vin.size(); i++) {
+ const COutPoint &prevout = tx.vin[i].prevout;
+ const CCoins* coins = AccessCoins(prevout.hash);
+ if (!coins || !coins->IsAvailable(prevout.n)) {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+double CCoinsViewCache::GetPriority(const CTransaction &tx, int nHeight) const
+{
+ if (tx.IsCoinBase())
+ return 0.0;
+ double dResult = 0.0;
+ BOOST_FOREACH(const CTxIn& txin, tx.vin)
+ {
+ const CCoins* coins = AccessCoins(txin.prevout.hash);
+ assert(coins);
+ if (!coins->IsAvailable(txin.prevout.n)) continue;
+ if (coins->nHeight < nHeight) {
+ dResult += coins->vout[txin.prevout.n].nValue * (nHeight-coins->nHeight);
+ }
+ }
+ return tx.ComputePriority(dResult);
+}
+
+CCoinsModifier::CCoinsModifier(CCoinsViewCache& cache_, CCoinsMap::iterator it_, size_t usage) : cache(cache_), it(it_), cachedCoinUsage(usage) {
+ assert(!cache.hasModifier);
+ cache.hasModifier = true;
+}
+
+CCoinsModifier::~CCoinsModifier()
+{
+ assert(cache.hasModifier);
+ cache.hasModifier = false;
+ it->second.coins.Cleanup();
+ cache.cachedCoinsUsage -= cachedCoinUsage; // Subtract the old usage
+ if ((it->second.flags & CCoinsCacheEntry::FRESH) && it->second.coins.IsPruned()) {
+ cache.cacheCoins.erase(it);
+ } else {
+ // If the coin still exists after the modification, add the new usage
+ cache.cachedCoinsUsage += memusage::DynamicUsage(it->second.coins);
+ }
+}
diff --git a/src/coins.h b/src/coins.h
new file mode 100644
index 0000000000..a4671645df
--- /dev/null
+++ b/src/coins.h
@@ -0,0 +1,465 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_COINS_H
+#define BITCOIN_COINS_H
+
+#include "compressor.h"
+#include "memusage.h"
+#include "serialize.h"
+#include "uint256.h"
+
+#include <assert.h>
+#include <stdint.h>
+
+#include <boost/foreach.hpp>
+#include <boost/unordered_map.hpp>
+
+/**
+ * Pruned version of CTransaction: only retains metadata and unspent transaction outputs
+ *
+ * Serialized format:
+ * - VARINT(nVersion)
+ * - VARINT(nCode)
+ * - unspentness bitvector, for vout[2] and further; least significant byte first
+ * - the non-spent CTxOuts (via CTxOutCompressor)
+ * - VARINT(nHeight)
+ *
+ * The nCode value consists of:
+ * - bit 1: IsCoinBase()
+ * - bit 2: vout[0] is not spent
+ * - bit 4: vout[1] is not spent
+ * - The higher bits encode N, the number of non-zero bytes in the following bitvector.
+ * - In case both bit 2 and bit 4 are unset, they encode N-1, as there must be at
+ * least one non-spent output).
+ *
+ * Example: 0104835800816115944e077fe7c803cfa57f29b36bf87c1d358bb85e
+ * <><><--------------------------------------------><---->
+ * | \ | /
+ * version code vout[1] height
+ *
+ * - version = 1
+ * - code = 4 (vout[1] is not spent, and 0 non-zero bytes of bitvector follow)
+ * - unspentness bitvector: as 0 non-zero bytes follow, it has length 0
+ * - vout[1]: 835800816115944e077fe7c803cfa57f29b36bf87c1d35
+ * * 8358: compact amount representation for 60000000000 (600 BTC)
+ * * 00: special txout type pay-to-pubkey-hash
+ * * 816115944e077fe7c803cfa57f29b36bf87c1d35: address uint160
+ * - height = 203998
+ *
+ *
+ * Example: 0109044086ef97d5790061b01caab50f1b8e9c50a5057eb43c2d9563a4eebbd123008c988f1a4a4de2161e0f50aac7f17e7f9555caa486af3b
+ * <><><--><--------------------------------------------------><----------------------------------------------><---->
+ * / \ \ | | /
+ * version code unspentness vout[4] vout[16] height
+ *
+ * - version = 1
+ * - code = 9 (coinbase, neither vout[0] or vout[1] are unspent,
+ * 2 (1, +1 because both bit 2 and bit 4 are unset) non-zero bitvector bytes follow)
+ * - unspentness bitvector: bits 2 (0x04) and 14 (0x4000) are set, so vout[2+2] and vout[14+2] are unspent
+ * - vout[4]: 86ef97d5790061b01caab50f1b8e9c50a5057eb43c2d9563a4ee
+ * * 86ef97d579: compact amount representation for 234925952 (2.35 BTC)
+ * * 00: special txout type pay-to-pubkey-hash
+ * * 61b01caab50f1b8e9c50a5057eb43c2d9563a4ee: address uint160
+ * - vout[16]: bbd123008c988f1a4a4de2161e0f50aac7f17e7f9555caa4
+ * * bbd123: compact amount representation for 110397 (0.001 BTC)
+ * * 00: special txout type pay-to-pubkey-hash
+ * * 8c988f1a4a4de2161e0f50aac7f17e7f9555caa4: address uint160
+ * - height = 120891
+ */
+class CCoins
+{
+public:
+ //! whether transaction is a coinbase
+ bool fCoinBase;
+
+ //! unspent transaction outputs; spent outputs are .IsNull(); spent outputs at the end of the array are dropped
+ std::vector<CTxOut> vout;
+
+ //! at which height this transaction was included in the active block chain
+ int nHeight;
+
+ //! version of the CTransaction; accesses to this value should probably check for nHeight as well,
+ //! as new tx version will probably only be introduced at certain heights
+ int nVersion;
+
+ void FromTx(const CTransaction &tx, int nHeightIn) {
+ fCoinBase = tx.IsCoinBase();
+ vout = tx.vout;
+ nHeight = nHeightIn;
+ nVersion = tx.nVersion;
+ ClearUnspendable();
+ }
+
+ //! construct a CCoins from a CTransaction, at a given height
+ CCoins(const CTransaction &tx, int nHeightIn) {
+ FromTx(tx, nHeightIn);
+ }
+
+ void Clear() {
+ fCoinBase = false;
+ std::vector<CTxOut>().swap(vout);
+ nHeight = 0;
+ nVersion = 0;
+ }
+
+ //! empty constructor
+ CCoins() : fCoinBase(false), vout(0), nHeight(0), nVersion(0) { }
+
+ //!remove spent outputs at the end of vout
+ void Cleanup() {
+ while (vout.size() > 0 && vout.back().IsNull())
+ vout.pop_back();
+ if (vout.empty())
+ std::vector<CTxOut>().swap(vout);
+ }
+
+ void ClearUnspendable() {
+ BOOST_FOREACH(CTxOut &txout, vout) {
+ if (txout.scriptPubKey.IsUnspendable())
+ txout.SetNull();
+ }
+ Cleanup();
+ }
+
+ void swap(CCoins &to) {
+ std::swap(to.fCoinBase, fCoinBase);
+ to.vout.swap(vout);
+ std::swap(to.nHeight, nHeight);
+ std::swap(to.nVersion, nVersion);
+ }
+
+ //! equality test
+ friend bool operator==(const CCoins &a, const CCoins &b) {
+ // Empty CCoins objects are always equal.
+ if (a.IsPruned() && b.IsPruned())
+ return true;
+ return a.fCoinBase == b.fCoinBase &&
+ a.nHeight == b.nHeight &&
+ a.nVersion == b.nVersion &&
+ a.vout == b.vout;
+ }
+ friend bool operator!=(const CCoins &a, const CCoins &b) {
+ return !(a == b);
+ }
+
+ void CalcMaskSize(unsigned int &nBytes, unsigned int &nNonzeroBytes) const;
+
+ bool IsCoinBase() const {
+ return fCoinBase;
+ }
+
+ unsigned int GetSerializeSize(int nType, int nVersion) const {
+ unsigned int nSize = 0;
+ unsigned int nMaskSize = 0, nMaskCode = 0;
+ CalcMaskSize(nMaskSize, nMaskCode);
+ bool fFirst = vout.size() > 0 && !vout[0].IsNull();
+ bool fSecond = vout.size() > 1 && !vout[1].IsNull();
+ assert(fFirst || fSecond || nMaskCode);
+ unsigned int nCode = 8*(nMaskCode - (fFirst || fSecond ? 0 : 1)) + (fCoinBase ? 1 : 0) + (fFirst ? 2 : 0) + (fSecond ? 4 : 0);
+ // version
+ nSize += ::GetSerializeSize(VARINT(this->nVersion), nType, nVersion);
+ // size of header code
+ nSize += ::GetSerializeSize(VARINT(nCode), nType, nVersion);
+ // spentness bitmask
+ nSize += nMaskSize;
+ // txouts themself
+ for (unsigned int i = 0; i < vout.size(); i++)
+ if (!vout[i].IsNull())
+ nSize += ::GetSerializeSize(CTxOutCompressor(REF(vout[i])), nType, nVersion);
+ // height
+ nSize += ::GetSerializeSize(VARINT(nHeight), nType, nVersion);
+ return nSize;
+ }
+
+ template<typename Stream>
+ void Serialize(Stream &s, int nType, int nVersion) const {
+ unsigned int nMaskSize = 0, nMaskCode = 0;
+ CalcMaskSize(nMaskSize, nMaskCode);
+ bool fFirst = vout.size() > 0 && !vout[0].IsNull();
+ bool fSecond = vout.size() > 1 && !vout[1].IsNull();
+ assert(fFirst || fSecond || nMaskCode);
+ unsigned int nCode = 8*(nMaskCode - (fFirst || fSecond ? 0 : 1)) + (fCoinBase ? 1 : 0) + (fFirst ? 2 : 0) + (fSecond ? 4 : 0);
+ // version
+ ::Serialize(s, VARINT(this->nVersion), nType, nVersion);
+ // header code
+ ::Serialize(s, VARINT(nCode), nType, nVersion);
+ // spentness bitmask
+ for (unsigned int b = 0; b<nMaskSize; b++) {
+ unsigned char chAvail = 0;
+ for (unsigned int i = 0; i < 8 && 2+b*8+i < vout.size(); i++)
+ if (!vout[2+b*8+i].IsNull())
+ chAvail |= (1 << i);
+ ::Serialize(s, chAvail, nType, nVersion);
+ }
+ // txouts themself
+ for (unsigned int i = 0; i < vout.size(); i++) {
+ if (!vout[i].IsNull())
+ ::Serialize(s, CTxOutCompressor(REF(vout[i])), nType, nVersion);
+ }
+ // coinbase height
+ ::Serialize(s, VARINT(nHeight), nType, nVersion);
+ }
+
+ template<typename Stream>
+ void Unserialize(Stream &s, int nType, int nVersion) {
+ unsigned int nCode = 0;
+ // version
+ ::Unserialize(s, VARINT(this->nVersion), nType, nVersion);
+ // header code
+ ::Unserialize(s, VARINT(nCode), nType, nVersion);
+ fCoinBase = nCode & 1;
+ std::vector<bool> vAvail(2, false);
+ vAvail[0] = (nCode & 2) != 0;
+ vAvail[1] = (nCode & 4) != 0;
+ unsigned int nMaskCode = (nCode / 8) + ((nCode & 6) != 0 ? 0 : 1);
+ // spentness bitmask
+ while (nMaskCode > 0) {
+ unsigned char chAvail = 0;
+ ::Unserialize(s, chAvail, nType, nVersion);
+ for (unsigned int p = 0; p < 8; p++) {
+ bool f = (chAvail & (1 << p)) != 0;
+ vAvail.push_back(f);
+ }
+ if (chAvail != 0)
+ nMaskCode--;
+ }
+ // txouts themself
+ vout.assign(vAvail.size(), CTxOut());
+ for (unsigned int i = 0; i < vAvail.size(); i++) {
+ if (vAvail[i])
+ ::Unserialize(s, REF(CTxOutCompressor(vout[i])), nType, nVersion);
+ }
+ // coinbase height
+ ::Unserialize(s, VARINT(nHeight), nType, nVersion);
+ Cleanup();
+ }
+
+ //! mark a vout spent
+ bool Spend(uint32_t nPos);
+
+ //! check whether a particular output is still available
+ bool IsAvailable(unsigned int nPos) const {
+ return (nPos < vout.size() && !vout[nPos].IsNull());
+ }
+
+ //! check whether the entire CCoins is spent
+ //! note that only !IsPruned() CCoins can be serialized
+ bool IsPruned() const {
+ BOOST_FOREACH(const CTxOut &out, vout)
+ if (!out.IsNull())
+ return false;
+ return true;
+ }
+
+ size_t DynamicMemoryUsage() const {
+ size_t ret = memusage::DynamicUsage(vout);
+ BOOST_FOREACH(const CTxOut &out, vout) {
+ const std::vector<unsigned char> *script = &out.scriptPubKey;
+ ret += memusage::DynamicUsage(*script);
+ }
+ return ret;
+ }
+};
+
+class CCoinsKeyHasher
+{
+private:
+ uint256 salt;
+
+public:
+ CCoinsKeyHasher();
+
+ /**
+ * This *must* return size_t. With Boost 1.46 on 32-bit systems the
+ * unordered_map will behave unpredictably if the custom hasher returns a
+ * uint64_t, resulting in failures when syncing the chain (#4634).
+ */
+ size_t operator()(const uint256& key) const {
+ return key.GetHash(salt);
+ }
+};
+
+struct CCoinsCacheEntry
+{
+ CCoins coins; // The actual cached data.
+ unsigned char flags;
+
+ enum Flags {
+ DIRTY = (1 << 0), // This cache entry is potentially different from the version in the parent view.
+ FRESH = (1 << 1), // The parent view does not have this entry (or it is pruned).
+ };
+
+ CCoinsCacheEntry() : coins(), flags(0) {}
+};
+
+typedef boost::unordered_map<uint256, CCoinsCacheEntry, CCoinsKeyHasher> CCoinsMap;
+
+struct CCoinsStats
+{
+ int nHeight;
+ uint256 hashBlock;
+ uint64_t nTransactions;
+ uint64_t nTransactionOutputs;
+ uint64_t nSerializedSize;
+ uint256 hashSerialized;
+ CAmount nTotalAmount;
+
+ CCoinsStats() : nHeight(0), nTransactions(0), nTransactionOutputs(0), nSerializedSize(0), nTotalAmount(0) {}
+};
+
+
+/** Abstract view on the open txout dataset. */
+class CCoinsView
+{
+public:
+ //! Retrieve the CCoins (unspent transaction outputs) for a given txid
+ virtual bool GetCoins(const uint256 &txid, CCoins &coins) const;
+
+ //! Just check whether we have data for a given txid.
+ //! This may (but cannot always) return true for fully spent transactions
+ virtual bool HaveCoins(const uint256 &txid) const;
+
+ //! Retrieve the block hash whose state this CCoinsView currently represents
+ virtual uint256 GetBestBlock() const;
+
+ //! Do a bulk modification (multiple CCoins changes + BestBlock change).
+ //! The passed mapCoins can be modified.
+ virtual bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock);
+
+ //! Calculate statistics about the unspent transaction output set
+ virtual bool GetStats(CCoinsStats &stats) const;
+
+ //! As we use CCoinsViews polymorphically, have a virtual destructor
+ virtual ~CCoinsView() {}
+};
+
+
+/** CCoinsView backed by another CCoinsView */
+class CCoinsViewBacked : public CCoinsView
+{
+protected:
+ CCoinsView *base;
+
+public:
+ CCoinsViewBacked(CCoinsView *viewIn);
+ bool GetCoins(const uint256 &txid, CCoins &coins) const;
+ bool HaveCoins(const uint256 &txid) const;
+ uint256 GetBestBlock() const;
+ void SetBackend(CCoinsView &viewIn);
+ bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock);
+ bool GetStats(CCoinsStats &stats) const;
+};
+
+
+class CCoinsViewCache;
+
+/**
+ * A reference to a mutable cache entry. Encapsulating it allows us to run
+ * cleanup code after the modification is finished, and keeping track of
+ * concurrent modifications.
+ */
+class CCoinsModifier
+{
+private:
+ CCoinsViewCache& cache;
+ CCoinsMap::iterator it;
+ size_t cachedCoinUsage; // Cached memory usage of the CCoins object before modification
+ CCoinsModifier(CCoinsViewCache& cache_, CCoinsMap::iterator it_, size_t usage);
+
+public:
+ CCoins* operator->() { return &it->second.coins; }
+ CCoins& operator*() { return it->second.coins; }
+ ~CCoinsModifier();
+ friend class CCoinsViewCache;
+};
+
+/** CCoinsView that adds a memory cache for transactions to another CCoinsView */
+class CCoinsViewCache : public CCoinsViewBacked
+{
+protected:
+ /* Whether this cache has an active modifier. */
+ bool hasModifier;
+
+
+ /**
+ * Make mutable so that we can "fill the cache" even from Get-methods
+ * declared as "const".
+ */
+ mutable uint256 hashBlock;
+ mutable CCoinsMap cacheCoins;
+
+ /* Cached dynamic memory usage for the inner CCoins objects. */
+ mutable size_t cachedCoinsUsage;
+
+public:
+ CCoinsViewCache(CCoinsView *baseIn);
+ ~CCoinsViewCache();
+
+ // Standard CCoinsView methods
+ bool GetCoins(const uint256 &txid, CCoins &coins) const;
+ bool HaveCoins(const uint256 &txid) const;
+ uint256 GetBestBlock() const;
+ void SetBestBlock(const uint256 &hashBlock);
+ bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock);
+
+ /**
+ * Return a pointer to CCoins in the cache, or NULL if not found. This is
+ * more efficient than GetCoins. Modifications to other cache entries are
+ * allowed while accessing the returned pointer.
+ */
+ const CCoins* AccessCoins(const uint256 &txid) const;
+
+ /**
+ * Return a modifiable reference to a CCoins. If no entry with the given
+ * txid exists, a new one is created. Simultaneous modifications are not
+ * allowed.
+ */
+ CCoinsModifier ModifyCoins(const uint256 &txid);
+
+ /**
+ * Push the modifications applied to this cache to its base.
+ * Failure to call this method before destruction will cause the changes to be forgotten.
+ * If false is returned, the state of this cache (and its backing view) will be undefined.
+ */
+ bool Flush();
+
+ //! Calculate the size of the cache (in number of transactions)
+ unsigned int GetCacheSize() const;
+
+ //! Calculate the size of the cache (in bytes)
+ size_t DynamicMemoryUsage() const;
+
+ /**
+ * Amount of bitcoins coming in to a 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] tx transaction for which we are checking input total
+ * @return Sum of value of all inputs (scriptSigs)
+ */
+ CAmount GetValueIn(const CTransaction& tx) const;
+
+ //! Check whether all prevouts of the transaction are present in the UTXO set represented by this view
+ bool HaveInputs(const CTransaction& tx) const;
+
+ //! Return priority of tx at height nHeight
+ double GetPriority(const CTransaction &tx, int nHeight) const;
+
+ const CTxOut &GetOutputFor(const CTxIn& input) const;
+
+ friend class CCoinsModifier;
+
+private:
+ CCoinsMap::iterator FetchCoins(const uint256 &txid);
+ CCoinsMap::const_iterator FetchCoins(const uint256 &txid) const;
+
+ /**
+ * By making the copy constructor private, we prevent accidentally using it when one intends to create a cache on top of a base cache.
+ */
+ CCoinsViewCache(const CCoinsViewCache &);
+};
+
+#endif // BITCOIN_COINS_H
diff --git a/src/compat.h b/src/compat.h
new file mode 100644
index 0000000000..20c2a25143
--- /dev/null
+++ b/src/compat.h
@@ -0,0 +1,104 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_COMPAT_H
+#define BITCOIN_COMPAT_H
+
+#if defined(HAVE_CONFIG_H)
+#include "config/bitcoin-config.h"
+#endif
+
+#ifdef WIN32
+#ifdef _WIN32_WINNT
+#undef _WIN32_WINNT
+#endif
+#define _WIN32_WINNT 0x0501
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN 1
+#endif
+#ifndef NOMINMAX
+#define NOMINMAX
+#endif
+#ifdef FD_SETSIZE
+#undef FD_SETSIZE // prevent redefinition compiler warning
+#endif
+#define FD_SETSIZE 1024 // max number of fds in fd_set
+
+#include <winsock2.h> // Must be included before mswsock.h and windows.h
+
+#include <mswsock.h>
+#include <windows.h>
+#include <ws2tcpip.h>
+#else
+#include <sys/fcntl.h>
+#include <sys/mman.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <arpa/inet.h>
+#include <ifaddrs.h>
+#include <limits.h>
+#include <netdb.h>
+#include <unistd.h>
+#endif
+
+#ifdef WIN32
+#define MSG_DONTWAIT 0
+#else
+typedef u_int SOCKET;
+#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
+
+#ifdef WIN32
+#ifndef S_IRUSR
+#define S_IRUSR 0400
+#define S_IWUSR 0200
+#endif
+#else
+#define MAX_PATH 1024
+#endif
+
+// As Solaris does not have the MSG_NOSIGNAL flag for send(2) syscall, it is defined as 0
+#if !defined(HAVE_MSG_NOSIGNAL) && !defined(MSG_NOSIGNAL)
+#define MSG_NOSIGNAL 0
+#endif
+
+#ifndef WIN32
+// PRIO_MAX is not defined on Solaris
+#ifndef PRIO_MAX
+#define PRIO_MAX 20
+#endif
+#define THREAD_PRIORITY_LOWEST PRIO_MAX
+#define THREAD_PRIORITY_BELOW_NORMAL 2
+#define THREAD_PRIORITY_NORMAL 0
+#define THREAD_PRIORITY_ABOVE_NORMAL (-2)
+#endif
+
+#if HAVE_DECL_STRNLEN == 0
+size_t strnlen( const char *start, size_t max_len);
+#endif // HAVE_DECL_STRNLEN
+
+bool static inline IsSelectableSocket(SOCKET s) {
+#ifdef WIN32
+ return true;
+#else
+ return (s < FD_SETSIZE);
+#endif
+}
+
+#endif // BITCOIN_COMPAT_H
diff --git a/src/compat/byteswap.h b/src/compat/byteswap.h
new file mode 100644
index 0000000000..899220bdc5
--- /dev/null
+++ b/src/compat/byteswap.h
@@ -0,0 +1,47 @@
+// Copyright (c) 2014 The Bitcoin developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_COMPAT_BYTESWAP_H
+#define BITCOIN_COMPAT_BYTESWAP_H
+
+#if defined(HAVE_CONFIG_H)
+#include "config/bitcoin-config.h"
+#endif
+
+#include <stdint.h>
+
+#if defined(HAVE_BYTESWAP_H)
+#include <byteswap.h>
+#endif
+
+#if HAVE_DECL_BSWAP_16 == 0
+inline uint16_t bswap_16(uint16_t x)
+{
+ return (x >> 8) | ((x & 0x00ff) << 8);
+}
+#endif // HAVE_DECL_BSWAP16
+
+#if HAVE_DECL_BSWAP_32 == 0
+inline uint32_t bswap_32(uint32_t x)
+{
+ return (((x & 0xff000000U) >> 24) | ((x & 0x00ff0000U) >> 8) |
+ ((x & 0x0000ff00U) << 8) | ((x & 0x000000ffU) << 24));
+}
+#endif // HAVE_DECL_BSWAP32
+
+#if HAVE_DECL_BSWAP_64 == 0
+inline uint64_t bswap_64(uint64_t x)
+{
+ return (((x & 0xff00000000000000ull) >> 56)
+ | ((x & 0x00ff000000000000ull) >> 40)
+ | ((x & 0x0000ff0000000000ull) >> 24)
+ | ((x & 0x000000ff00000000ull) >> 8)
+ | ((x & 0x00000000ff000000ull) << 8)
+ | ((x & 0x0000000000ff0000ull) << 24)
+ | ((x & 0x000000000000ff00ull) << 40)
+ | ((x & 0x00000000000000ffull) << 56));
+}
+#endif // HAVE_DECL_BSWAP64
+
+#endif // BITCOIN_COMPAT_BYTESWAP_H
diff --git a/src/compat/endian.h b/src/compat/endian.h
new file mode 100644
index 0000000000..9fec2a07fa
--- /dev/null
+++ b/src/compat/endian.h
@@ -0,0 +1,196 @@
+// Copyright (c) 2014 The Bitcoin developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_COMPAT_ENDIAN_H
+#define BITCOIN_COMPAT_ENDIAN_H
+
+#if defined(HAVE_CONFIG_H)
+#include "config/bitcoin-config.h"
+#endif
+
+#include <stdint.h>
+
+#include "compat/byteswap.h"
+
+#if defined(HAVE_ENDIAN_H)
+#include <endian.h>
+#elif defined(HAVE_SYS_ENDIAN_H)
+#include <sys/endian.h>
+#endif
+
+#if defined(WORDS_BIGENDIAN)
+
+#if HAVE_DECL_HTOBE16 == 0
+inline uint16_t htobe16(uint16_t host_16bits)
+{
+ return host_16bits;
+}
+#endif // HAVE_DECL_HTOBE16
+
+#if HAVE_DECL_HTOLE16 == 0
+inline uint16_t htole16(uint16_t host_16bits)
+{
+ return bswap_16(host_16bits);
+}
+#endif // HAVE_DECL_HTOLE16
+
+#if HAVE_DECL_BE16TOH == 0
+inline uint16_t be16toh(uint16_t big_endian_16bits)
+{
+ return big_endian_16bits;
+}
+#endif // HAVE_DECL_BE16TOH
+
+#if HAVE_DECL_LE16TOH == 0
+inline uint16_t le16toh(uint16_t little_endian_16bits)
+{
+ return bswap_16(little_endian_16bits);
+}
+#endif // HAVE_DECL_LE16TOH
+
+#if HAVE_DECL_HTOBE32 == 0
+inline uint32_t htobe32(uint32_t host_32bits)
+{
+ return host_32bits;
+}
+#endif // HAVE_DECL_HTOBE32
+
+#if HAVE_DECL_HTOLE32 == 0
+inline uint32_t htole32(uint32_t host_32bits)
+{
+ return bswap_32(host_32bits);
+}
+#endif // HAVE_DECL_HTOLE32
+
+#if HAVE_DECL_BE32TOH == 0
+inline uint32_t be32toh(uint32_t big_endian_32bits)
+{
+ return big_endian_32bits;
+}
+#endif // HAVE_DECL_BE32TOH
+
+#if HAVE_DECL_LE32TOH == 0
+inline uint32_t le32toh(uint32_t little_endian_32bits)
+{
+ return bswap_32(little_endian_32bits);
+}
+#endif // HAVE_DECL_LE32TOH
+
+#if HAVE_DECL_HTOBE64 == 0
+inline uint64_t htobe64(uint64_t host_64bits)
+{
+ return host_64bits;
+}
+#endif // HAVE_DECL_HTOBE64
+
+#if HAVE_DECL_HTOLE64 == 0
+inline uint64_t htole64(uint64_t host_64bits)
+{
+ return bswap_64(host_64bits);
+}
+#endif // HAVE_DECL_HTOLE64
+
+#if HAVE_DECL_BE64TOH == 0
+inline uint64_t be64toh(uint64_t big_endian_64bits)
+{
+ return big_endian_64bits;
+}
+#endif // HAVE_DECL_BE64TOH
+
+#if HAVE_DECL_LE64TOH == 0
+inline uint64_t le64toh(uint64_t little_endian_64bits)
+{
+ return bswap_64(little_endian_64bits);
+}
+#endif // HAVE_DECL_LE64TOH
+
+#else // WORDS_BIGENDIAN
+
+#if HAVE_DECL_HTOBE16 == 0
+inline uint16_t htobe16(uint16_t host_16bits)
+{
+ return bswap_16(host_16bits);
+}
+#endif // HAVE_DECL_HTOBE16
+
+#if HAVE_DECL_HTOLE16 == 0
+inline uint16_t htole16(uint16_t host_16bits)
+{
+ return host_16bits;
+}
+#endif // HAVE_DECL_HTOLE16
+
+#if HAVE_DECL_BE16TOH == 0
+inline uint16_t be16toh(uint16_t big_endian_16bits)
+{
+ return bswap_16(big_endian_16bits);
+}
+#endif // HAVE_DECL_BE16TOH
+
+#if HAVE_DECL_LE16TOH == 0
+inline uint16_t le16toh(uint16_t little_endian_16bits)
+{
+ return little_endian_16bits;
+}
+#endif // HAVE_DECL_LE16TOH
+
+#if HAVE_DECL_HTOBE32 == 0
+inline uint32_t htobe32(uint32_t host_32bits)
+{
+ return bswap_32(host_32bits);
+}
+#endif // HAVE_DECL_HTOBE32
+
+#if HAVE_DECL_HTOLE32 == 0
+inline uint32_t htole32(uint32_t host_32bits)
+{
+ return host_32bits;
+}
+#endif // HAVE_DECL_HTOLE32
+
+#if HAVE_DECL_BE32TOH == 0
+inline uint32_t be32toh(uint32_t big_endian_32bits)
+{
+ return bswap_32(big_endian_32bits);
+}
+#endif // HAVE_DECL_BE32TOH
+
+#if HAVE_DECL_LE32TOH == 0
+inline uint32_t le32toh(uint32_t little_endian_32bits)
+{
+ return little_endian_32bits;
+}
+#endif // HAVE_DECL_LE32TOH
+
+#if HAVE_DECL_HTOBE64 == 0
+inline uint64_t htobe64(uint64_t host_64bits)
+{
+ return bswap_64(host_64bits);
+}
+#endif // HAVE_DECL_HTOBE64
+
+#if HAVE_DECL_HTOLE64 == 0
+inline uint64_t htole64(uint64_t host_64bits)
+{
+ return host_64bits;
+}
+#endif // HAVE_DECL_HTOLE64
+
+#if HAVE_DECL_BE64TOH == 0
+inline uint64_t be64toh(uint64_t big_endian_64bits)
+{
+ return bswap_64(big_endian_64bits);
+}
+#endif // HAVE_DECL_BE64TOH
+
+#if HAVE_DECL_LE64TOH == 0
+inline uint64_t le64toh(uint64_t little_endian_64bits)
+{
+ return little_endian_64bits;
+}
+#endif // HAVE_DECL_LE64TOH
+
+#endif // WORDS_BIGENDIAN
+
+#endif // BITCOIN_COMPAT_ENDIAN_H
diff --git a/src/compat/glibc_compat.cpp b/src/compat/glibc_compat.cpp
new file mode 100644
index 0000000000..3b9c70df7f
--- /dev/null
+++ b/src/compat/glibc_compat.cpp
@@ -0,0 +1,29 @@
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#if defined(HAVE_CONFIG_H)
+#include "config/bitcoin-config.h"
+#endif
+
+#include <cstddef>
+
+#if defined(HAVE_SYS_SELECT_H)
+#include <sys/select.h>
+#endif
+
+// Prior to GLIBC_2.14, memcpy was aliased to memmove.
+extern "C" void* memmove(void* a, const void* b, size_t c);
+extern "C" void* memcpy(void* a, const void* b, size_t c)
+{
+ return memmove(a, b, c);
+}
+
+extern "C" void __chk_fail(void) __attribute__((__noreturn__));
+extern "C" FDELT_TYPE __fdelt_warn(FDELT_TYPE a)
+{
+ if (a >= FD_SETSIZE)
+ __chk_fail();
+ return a / __NFDBITS;
+}
+extern "C" FDELT_TYPE __fdelt_chk(FDELT_TYPE) __attribute__((weak, alias("__fdelt_warn")));
diff --git a/src/compat/glibc_sanity.cpp b/src/compat/glibc_sanity.cpp
new file mode 100644
index 0000000000..d62d74d462
--- /dev/null
+++ b/src/compat/glibc_sanity.cpp
@@ -0,0 +1,68 @@
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#if defined(HAVE_CONFIG_H)
+#include "config/bitcoin-config.h"
+#endif
+
+#include <cstddef>
+
+#if defined(HAVE_SYS_SELECT_H)
+#include <sys/select.h>
+#endif
+
+extern "C" void* memcpy(void* a, const void* b, size_t c);
+void* memcpy_int(void* a, const void* b, size_t c)
+{
+ return memcpy(a, b, c);
+}
+
+namespace
+{
+// trigger: Use the memcpy_int wrapper which calls our internal memcpy.
+// A direct call to memcpy may be optimized away by the compiler.
+// test: Fill an array with a sequence of integers. memcpy to a new empty array.
+// Verify that the arrays are equal. Use an odd size to decrease the odds of
+// the call being optimized away.
+template <unsigned int T>
+bool sanity_test_memcpy()
+{
+ unsigned int memcpy_test[T];
+ unsigned int memcpy_verify[T] = {};
+ for (unsigned int i = 0; i != T; ++i)
+ memcpy_test[i] = i;
+
+ memcpy_int(memcpy_verify, memcpy_test, sizeof(memcpy_test));
+
+ for (unsigned int i = 0; i != T; ++i) {
+ if (memcpy_verify[i] != i)
+ return false;
+ }
+ return true;
+}
+
+#if defined(HAVE_SYS_SELECT_H)
+// trigger: Call FD_SET to trigger __fdelt_chk. FORTIFY_SOURCE must be defined
+// as >0 and optimizations must be set to at least -O2.
+// test: Add a file descriptor to an empty fd_set. Verify that it has been
+// correctly added.
+bool sanity_test_fdelt()
+{
+ fd_set fds;
+ FD_ZERO(&fds);
+ FD_SET(0, &fds);
+ return FD_ISSET(0, &fds);
+}
+#endif
+
+} // anon namespace
+
+bool glibc_sanity_test()
+{
+#if defined(HAVE_SYS_SELECT_H)
+ if (!sanity_test_fdelt())
+ return false;
+#endif
+ return sanity_test_memcpy<1025>();
+}
diff --git a/src/compat/glibcxx_sanity.cpp b/src/compat/glibcxx_sanity.cpp
new file mode 100644
index 0000000000..cee8a98c7f
--- /dev/null
+++ b/src/compat/glibcxx_sanity.cpp
@@ -0,0 +1,61 @@
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include <list>
+#include <locale>
+#include <stdexcept>
+
+namespace
+{
+// trigger: use ctype<char>::widen to trigger ctype<char>::_M_widen_init().
+// test: convert a char from narrow to wide and back. Verify that the result
+// matches the original.
+bool sanity_test_widen(char testchar)
+{
+ const std::ctype<char>& test(std::use_facet<std::ctype<char> >(std::locale()));
+ return test.narrow(test.widen(testchar), 'b') == testchar;
+}
+
+// trigger: use list::push_back and list::pop_back to trigger _M_hook and
+// _M_unhook.
+// test: Push a sequence of integers into a list. Pop them off and verify that
+// they match the original sequence.
+bool sanity_test_list(unsigned int size)
+{
+ std::list<unsigned int> test;
+ for (unsigned int i = 0; i != size; ++i)
+ test.push_back(i + 1);
+
+ if (test.size() != size)
+ return false;
+
+ while (!test.empty()) {
+ if (test.back() != test.size())
+ return false;
+ test.pop_back();
+ }
+ return true;
+}
+
+} // anon namespace
+
+// trigger: string::at(x) on an empty string to trigger __throw_out_of_range_fmt.
+// test: force std::string to throw an out_of_range exception. Verify that
+// it's caught correctly.
+bool sanity_test_range_fmt()
+{
+ std::string test;
+ try {
+ test.at(1);
+ } catch (const std::out_of_range&) {
+ return true;
+ } catch (...) {
+ }
+ return false;
+}
+
+bool glibcxx_sanity_test()
+{
+ return sanity_test_widen('a') && sanity_test_list(100) && sanity_test_range_fmt();
+}
diff --git a/src/compat/sanity.h b/src/compat/sanity.h
new file mode 100644
index 0000000000..909c4f6da8
--- /dev/null
+++ b/src/compat/sanity.h
@@ -0,0 +1,11 @@
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_COMPAT_SANITY_H
+#define BITCOIN_COMPAT_SANITY_H
+
+bool glibc_sanity_test();
+bool glibcxx_sanity_test();
+
+#endif // BITCOIN_COMPAT_SANITY_H
diff --git a/src/compat/strnlen.cpp b/src/compat/strnlen.cpp
new file mode 100644
index 0000000000..1ac266c2d1
--- /dev/null
+++ b/src/compat/strnlen.cpp
@@ -0,0 +1,18 @@
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#if defined(HAVE_CONFIG_H)
+#include "config/bitcoin-config.h"
+#endif
+
+#include <cstring>
+
+#if HAVE_DECL_STRNLEN == 0
+size_t strnlen( const char *start, size_t max_len)
+{
+ const char *end = (const char *)memchr(start, '\0', max_len);
+
+ return end ? (size_t)(end - start) : max_len;
+}
+#endif // HAVE_DECL_STRNLEN
diff --git a/src/compressor.cpp b/src/compressor.cpp
new file mode 100644
index 0000000000..20c154fc1e
--- /dev/null
+++ b/src/compressor.cpp
@@ -0,0 +1,185 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "compressor.h"
+
+#include "hash.h"
+#include "pubkey.h"
+#include "script/standard.h"
+
+bool CScriptCompressor::IsToKeyID(CKeyID &hash) const
+{
+ if (script.size() == 25 && script[0] == OP_DUP && script[1] == OP_HASH160
+ && script[2] == 20 && script[23] == OP_EQUALVERIFY
+ && script[24] == OP_CHECKSIG) {
+ memcpy(&hash, &script[3], 20);
+ return true;
+ }
+ return false;
+}
+
+bool CScriptCompressor::IsToScriptID(CScriptID &hash) const
+{
+ if (script.size() == 23 && script[0] == OP_HASH160 && script[1] == 20
+ && script[22] == OP_EQUAL) {
+ memcpy(&hash, &script[2], 20);
+ return true;
+ }
+ return false;
+}
+
+bool CScriptCompressor::IsToPubKey(CPubKey &pubkey) const
+{
+ if (script.size() == 35 && script[0] == 33 && script[34] == OP_CHECKSIG
+ && (script[1] == 0x02 || script[1] == 0x03)) {
+ pubkey.Set(&script[1], &script[34]);
+ return true;
+ }
+ if (script.size() == 67 && script[0] == 65 && script[66] == OP_CHECKSIG
+ && script[1] == 0x04) {
+ pubkey.Set(&script[1], &script[66]);
+ return pubkey.IsFullyValid(); // if not fully valid, a case that would not be compressible
+ }
+ return false;
+}
+
+bool CScriptCompressor::Compress(std::vector<unsigned char> &out) const
+{
+ CKeyID keyID;
+ if (IsToKeyID(keyID)) {
+ out.resize(21);
+ out[0] = 0x00;
+ memcpy(&out[1], &keyID, 20);
+ return true;
+ }
+ CScriptID scriptID;
+ if (IsToScriptID(scriptID)) {
+ out.resize(21);
+ out[0] = 0x01;
+ memcpy(&out[1], &scriptID, 20);
+ return true;
+ }
+ CPubKey pubkey;
+ if (IsToPubKey(pubkey)) {
+ out.resize(33);
+ memcpy(&out[1], &pubkey[1], 32);
+ if (pubkey[0] == 0x02 || pubkey[0] == 0x03) {
+ out[0] = pubkey[0];
+ return true;
+ } else if (pubkey[0] == 0x04) {
+ out[0] = 0x04 | (pubkey[64] & 0x01);
+ return true;
+ }
+ }
+ return false;
+}
+
+unsigned int CScriptCompressor::GetSpecialSize(unsigned int nSize) const
+{
+ if (nSize == 0 || nSize == 1)
+ return 20;
+ if (nSize == 2 || nSize == 3 || nSize == 4 || nSize == 5)
+ return 32;
+ return 0;
+}
+
+bool CScriptCompressor::Decompress(unsigned int nSize, const std::vector<unsigned char> &in)
+{
+ switch(nSize) {
+ case 0x00:
+ script.resize(25);
+ script[0] = OP_DUP;
+ script[1] = OP_HASH160;
+ script[2] = 20;
+ memcpy(&script[3], &in[0], 20);
+ script[23] = OP_EQUALVERIFY;
+ script[24] = OP_CHECKSIG;
+ return true;
+ case 0x01:
+ script.resize(23);
+ script[0] = OP_HASH160;
+ script[1] = 20;
+ memcpy(&script[2], &in[0], 20);
+ script[22] = OP_EQUAL;
+ return true;
+ case 0x02:
+ case 0x03:
+ script.resize(35);
+ script[0] = 33;
+ script[1] = nSize;
+ memcpy(&script[2], &in[0], 32);
+ script[34] = OP_CHECKSIG;
+ return true;
+ case 0x04:
+ case 0x05:
+ unsigned char vch[33] = {};
+ vch[0] = nSize - 2;
+ memcpy(&vch[1], &in[0], 32);
+ CPubKey pubkey(&vch[0], &vch[33]);
+ if (!pubkey.Decompress())
+ return false;
+ assert(pubkey.size() == 65);
+ script.resize(67);
+ script[0] = 65;
+ memcpy(&script[1], pubkey.begin(), 65);
+ script[66] = OP_CHECKSIG;
+ return true;
+ }
+ return false;
+}
+
+// Amount compression:
+// * If the amount is 0, output 0
+// * first, divide the amount (in base units) by the largest power of 10 possible; call the exponent e (e is max 9)
+// * if e<9, the last digit of the resulting number cannot be 0; store it as d, and drop it (divide by 10)
+// * call the result n
+// * output 1 + 10*(9*n + d - 1) + e
+// * if e==9, we only know the resulting number is not zero, so output 1 + 10*(n - 1) + 9
+// (this is decodable, as d is in [1-9] and e is in [0-9])
+
+uint64_t CTxOutCompressor::CompressAmount(uint64_t n)
+{
+ if (n == 0)
+ return 0;
+ int e = 0;
+ while (((n % 10) == 0) && e < 9) {
+ n /= 10;
+ e++;
+ }
+ if (e < 9) {
+ int d = (n % 10);
+ assert(d >= 1 && d <= 9);
+ n /= 10;
+ return 1 + (n*9 + d - 1)*10 + e;
+ } else {
+ return 1 + (n - 1)*10 + 9;
+ }
+}
+
+uint64_t CTxOutCompressor::DecompressAmount(uint64_t x)
+{
+ // x = 0 OR x = 1+10*(9*n + d - 1) + e OR x = 1+10*(n - 1) + 9
+ if (x == 0)
+ return 0;
+ x--;
+ // x = 10*(9*n + d - 1) + e
+ int e = x % 10;
+ x /= 10;
+ uint64_t n = 0;
+ if (e < 9) {
+ // x = 9*n + d - 1
+ int d = (x % 9) + 1;
+ x /= 9;
+ // x = n
+ n = x*10 + d;
+ } else {
+ n = x+1;
+ }
+ while (e) {
+ n *= 10;
+ e--;
+ }
+ return n;
+}
diff --git a/src/compressor.h b/src/compressor.h
new file mode 100644
index 0000000000..4a72090830
--- /dev/null
+++ b/src/compressor.h
@@ -0,0 +1,123 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_COMPRESSOR_H
+#define BITCOIN_COMPRESSOR_H
+
+#include "primitives/transaction.h"
+#include "script/script.h"
+#include "serialize.h"
+
+class CKeyID;
+class CPubKey;
+class CScriptID;
+
+/** Compact serializer for scripts.
+ *
+ * It detects common cases and encodes them much more efficiently.
+ * 3 special cases are defined:
+ * * Pay to pubkey hash (encoded as 21 bytes)
+ * * Pay to script hash (encoded as 21 bytes)
+ * * Pay to pubkey starting with 0x02, 0x03 or 0x04 (encoded as 33 bytes)
+ *
+ * Other scripts up to 121 bytes require 1 byte + script length. Above
+ * that, scripts up to 16505 bytes require 2 bytes + script length.
+ */
+class CScriptCompressor
+{
+private:
+ /**
+ * make this static for now (there are only 6 special scripts defined)
+ * this can potentially be extended together with a new nVersion for
+ * transactions, in which case this value becomes dependent on nVersion
+ * and nHeight of the enclosing transaction.
+ */
+ static const unsigned int nSpecialScripts = 6;
+
+ CScript &script;
+protected:
+ /**
+ * These check for scripts for which a special case with a shorter encoding is defined.
+ * They are implemented separately from the CScript test, as these test for exact byte
+ * sequence correspondences, and are more strict. For example, IsToPubKey also verifies
+ * whether the public key is valid (as invalid ones cannot be represented in compressed
+ * form).
+ */
+ bool IsToKeyID(CKeyID &hash) const;
+ bool IsToScriptID(CScriptID &hash) const;
+ bool IsToPubKey(CPubKey &pubkey) const;
+
+ bool Compress(std::vector<unsigned char> &out) const;
+ unsigned int GetSpecialSize(unsigned int nSize) const;
+ bool Decompress(unsigned int nSize, const std::vector<unsigned char> &out);
+public:
+ CScriptCompressor(CScript &scriptIn) : script(scriptIn) { }
+
+ unsigned int GetSerializeSize(int nType, int nVersion) const {
+ std::vector<unsigned char> compr;
+ if (Compress(compr))
+ return compr.size();
+ unsigned int nSize = script.size() + nSpecialScripts;
+ return script.size() + VARINT(nSize).GetSerializeSize(nType, nVersion);
+ }
+
+ template<typename Stream>
+ void Serialize(Stream &s, int nType, int nVersion) const {
+ std::vector<unsigned char> compr;
+ if (Compress(compr)) {
+ s << CFlatData(compr);
+ return;
+ }
+ unsigned int nSize = script.size() + nSpecialScripts;
+ s << VARINT(nSize);
+ s << CFlatData(script);
+ }
+
+ template<typename Stream>
+ void Unserialize(Stream &s, int nType, int nVersion) {
+ unsigned int nSize = 0;
+ s >> VARINT(nSize);
+ if (nSize < nSpecialScripts) {
+ std::vector<unsigned char> vch(GetSpecialSize(nSize), 0x00);
+ s >> REF(CFlatData(vch));
+ Decompress(nSize, vch);
+ return;
+ }
+ nSize -= nSpecialScripts;
+ script.resize(nSize);
+ s >> REF(CFlatData(script));
+ }
+};
+
+/** wrapper for CTxOut that provides a more compact serialization */
+class CTxOutCompressor
+{
+private:
+ CTxOut &txout;
+
+public:
+ static uint64_t CompressAmount(uint64_t nAmount);
+ static uint64_t DecompressAmount(uint64_t nAmount);
+
+ CTxOutCompressor(CTxOut &txoutIn) : txout(txoutIn) { }
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ if (!ser_action.ForRead()) {
+ uint64_t nVal = CompressAmount(txout.nValue);
+ READWRITE(VARINT(nVal));
+ } else {
+ uint64_t nVal = 0;
+ READWRITE(VARINT(nVal));
+ txout.nValue = DecompressAmount(nVal);
+ }
+ CScriptCompressor cscript(REF(txout.scriptPubKey));
+ READWRITE(cscript);
+ }
+};
+
+#endif // BITCOIN_COMPRESSOR_H
diff --git a/src/config/.empty b/src/config/.empty
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/src/config/.empty
diff --git a/src/consensus/consensus.h b/src/consensus/consensus.h
new file mode 100644
index 0000000000..f937844e9f
--- /dev/null
+++ b/src/consensus/consensus.h
@@ -0,0 +1,16 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_CONSENSUS_CONSENSUS_H
+#define BITCOIN_CONSENSUS_CONSENSUS_H
+
+/** The maximum allowed size for a serialized block, in bytes (network rule) */
+static const unsigned int MAX_BLOCK_SIZE = 1000000;
+/** The maximum allowed number of signature check operations in a block (network rule) */
+static const unsigned int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50;
+/** Coinbase transaction outputs can only be spent after this number of new blocks (network rule) */
+static const int COINBASE_MATURITY = 100;
+
+#endif // BITCOIN_CONSENSUS_CONSENSUS_H
diff --git a/src/consensus/params.h b/src/consensus/params.h
new file mode 100644
index 0000000000..c480a1cce1
--- /dev/null
+++ b/src/consensus/params.h
@@ -0,0 +1,31 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_CONSENSUS_PARAMS_H
+#define BITCOIN_CONSENSUS_PARAMS_H
+
+#include "uint256.h"
+
+namespace Consensus {
+/**
+ * Parameters that influence chain consensus.
+ */
+struct Params {
+ uint256 hashGenesisBlock;
+ int nSubsidyHalvingInterval;
+ /** Used to check majorities for block version upgrade */
+ int nMajorityEnforceBlockUpgrade;
+ int nMajorityRejectBlockOutdated;
+ int nMajorityWindow;
+ /** Proof of work parameters */
+ uint256 powLimit;
+ bool fPowAllowMinDifficultyBlocks;
+ int64_t nPowTargetSpacing;
+ int64_t nPowTargetTimespan;
+ int64_t DifficultyAdjustmentInterval() const { return nPowTargetTimespan / nPowTargetSpacing; }
+};
+} // namespace Consensus
+
+#endif // BITCOIN_CONSENSUS_PARAMS_H
diff --git a/src/consensus/validation.h b/src/consensus/validation.h
new file mode 100644
index 0000000000..c92bec4fae
--- /dev/null
+++ b/src/consensus/validation.h
@@ -0,0 +1,80 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_CONSENSUS_VALIDATION_H
+#define BITCOIN_CONSENSUS_VALIDATION_H
+
+#include <string>
+
+/** "reject" message codes */
+static const unsigned char REJECT_MALFORMED = 0x01;
+static const unsigned char REJECT_INVALID = 0x10;
+static const unsigned char REJECT_OBSOLETE = 0x11;
+static const unsigned char REJECT_DUPLICATE = 0x12;
+static const unsigned char REJECT_NONSTANDARD = 0x40;
+static const unsigned char REJECT_DUST = 0x41;
+static const unsigned char REJECT_INSUFFICIENTFEE = 0x42;
+static const unsigned char REJECT_CHECKPOINT = 0x43;
+
+/** Capture information about block/transaction validation */
+class CValidationState {
+private:
+ enum mode_state {
+ MODE_VALID, //! everything ok
+ MODE_INVALID, //! network rule violation (DoS value may be set)
+ MODE_ERROR, //! run-time error
+ } mode;
+ int nDoS;
+ std::string strRejectReason;
+ unsigned char chRejectCode;
+ bool corruptionPossible;
+public:
+ CValidationState() : mode(MODE_VALID), nDoS(0), chRejectCode(0), corruptionPossible(false) {}
+ bool DoS(int level, bool ret = false,
+ unsigned char chRejectCodeIn=0, std::string strRejectReasonIn="",
+ bool corruptionIn=false) {
+ chRejectCode = chRejectCodeIn;
+ strRejectReason = strRejectReasonIn;
+ corruptionPossible = corruptionIn;
+ if (mode == MODE_ERROR)
+ return ret;
+ nDoS += level;
+ mode = MODE_INVALID;
+ return ret;
+ }
+ bool Invalid(bool ret = false,
+ unsigned char _chRejectCode=0, std::string _strRejectReason="") {
+ return DoS(0, ret, _chRejectCode, _strRejectReason);
+ }
+ bool Error(std::string strRejectReasonIn="") {
+ if (mode == MODE_VALID)
+ strRejectReason = strRejectReasonIn;
+ mode = MODE_ERROR;
+ return false;
+ }
+ bool IsValid() const {
+ return mode == MODE_VALID;
+ }
+ bool IsInvalid() const {
+ return mode == MODE_INVALID;
+ }
+ bool IsError() const {
+ return mode == MODE_ERROR;
+ }
+ bool IsInvalid(int &nDoSOut) const {
+ if (IsInvalid()) {
+ nDoSOut = nDoS;
+ return true;
+ }
+ return false;
+ }
+ bool CorruptionPossible() const {
+ return corruptionPossible;
+ }
+ unsigned char GetRejectCode() const { return chRejectCode; }
+ std::string GetRejectReason() const { return strRejectReason; }
+};
+
+#endif // BITCOIN_CONSENSUS_VALIDATION_H
diff --git a/src/core_io.h b/src/core_io.h
new file mode 100644
index 0000000000..0989cf7437
--- /dev/null
+++ b/src/core_io.h
@@ -0,0 +1,32 @@
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_CORE_IO_H
+#define BITCOIN_CORE_IO_H
+
+#include <string>
+#include <vector>
+
+class CBlock;
+class CScript;
+class CTransaction;
+class uint256;
+class UniValue;
+
+// core_read.cpp
+extern CScript ParseScript(std::string s);
+extern bool DecodeHexTx(CTransaction& tx, const std::string& strHexTx);
+extern bool DecodeHexBlk(CBlock&, const std::string& strHexBlk);
+extern uint256 ParseHashUV(const UniValue& v, const std::string& strName);
+extern uint256 ParseHashStr(const std::string&, const std::string& strName);
+extern std::vector<unsigned char> ParseHexUV(const UniValue& v, const std::string& strName);
+
+// core_write.cpp
+extern std::string FormatScript(const CScript& script);
+extern std::string EncodeHexTx(const CTransaction& tx);
+extern void ScriptPubKeyToUniv(const CScript& scriptPubKey,
+ UniValue& out, bool fIncludeHex);
+extern void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry);
+
+#endif // BITCOIN_CORE_IO_H
diff --git a/src/core_read.cpp b/src/core_read.cpp
new file mode 100644
index 0000000000..e064955ff0
--- /dev/null
+++ b/src/core_read.cpp
@@ -0,0 +1,153 @@
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "core_io.h"
+
+#include "primitives/block.h"
+#include "primitives/transaction.h"
+#include "script/script.h"
+#include "serialize.h"
+#include "streams.h"
+#include "univalue/univalue.h"
+#include "util.h"
+#include "utilstrencodings.h"
+#include "version.h"
+
+#include <boost/algorithm/string/classification.hpp>
+#include <boost/algorithm/string/predicate.hpp>
+#include <boost/algorithm/string/replace.hpp>
+#include <boost/algorithm/string/split.hpp>
+#include <boost/assign/list_of.hpp>
+
+using namespace std;
+
+CScript ParseScript(std::string s)
+{
+ CScript result;
+
+ static map<string, opcodetype> mapOpNames;
+
+ if (mapOpNames.empty())
+ {
+ for (int op = 0; op <= OP_NOP10; op++)
+ {
+ // Allow OP_RESERVED to get into mapOpNames
+ if (op < OP_NOP && op != OP_RESERVED)
+ continue;
+
+ 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:
+ boost::algorithm::replace_first(strName, "OP_", "");
+ mapOpNames[strName] = (opcodetype)op;
+ }
+ }
+
+ vector<string> words;
+ boost::algorithm::split(words, s, boost::algorithm::is_any_of(" \t\n"), boost::algorithm::token_compress_on);
+
+ for (std::vector<std::string>::const_iterator w = words.begin(); w != words.end(); ++w)
+ {
+ if (w->empty())
+ {
+ // Empty string, ignore. (boost::split given '' will return one word)
+ }
+ else if (all(*w, boost::algorithm::is_digit()) ||
+ (boost::algorithm::starts_with(*w, "-") && all(string(w->begin()+1, w->end()), boost::algorithm::is_digit())))
+ {
+ // Number
+ int64_t n = atoi64(*w);
+ result << n;
+ }
+ else if (boost::algorithm::starts_with(*w, "0x") && (w->begin()+2 != w->end()) && IsHex(string(w->begin()+2, w->end())))
+ {
+ // Raw hex data, inserted NOT pushed onto stack:
+ std::vector<unsigned char> raw = ParseHex(string(w->begin()+2, w->end()));
+ result.insert(result.end(), raw.begin(), raw.end());
+ }
+ else if (w->size() >= 2 && boost::algorithm::starts_with(*w, "'") && boost::algorithm::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<unsigned char> value(w->begin()+1, w->end()-1);
+ result << value;
+ }
+ else if (mapOpNames.count(*w))
+ {
+ // opcode, e.g. OP_ADD or ADD:
+ result << mapOpNames[*w];
+ }
+ else
+ {
+ throw runtime_error("script parse error");
+ }
+ }
+
+ return result;
+}
+
+bool DecodeHexTx(CTransaction& tx, const std::string& strHexTx)
+{
+ if (!IsHex(strHexTx))
+ return false;
+
+ vector<unsigned char> txData(ParseHex(strHexTx));
+ CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION);
+ try {
+ ssData >> tx;
+ }
+ catch (const std::exception&) {
+ return false;
+ }
+
+ return true;
+}
+
+bool DecodeHexBlk(CBlock& block, const std::string& strHexBlk)
+{
+ if (!IsHex(strHexBlk))
+ return false;
+
+ std::vector<unsigned char> blockData(ParseHex(strHexBlk));
+ CDataStream ssBlock(blockData, SER_NETWORK, PROTOCOL_VERSION);
+ try {
+ ssBlock >> block;
+ }
+ catch (const std::exception&) {
+ return false;
+ }
+
+ return true;
+}
+
+uint256 ParseHashUV(const UniValue& v, const string& strName)
+{
+ string strHex;
+ if (v.isStr())
+ strHex = v.getValStr();
+ return ParseHashStr(strHex, strName); // Note: ParseHashStr("") throws a runtime_error
+}
+
+uint256 ParseHashStr(const std::string& strHex, const std::string& strName)
+{
+ if (!IsHex(strHex)) // Note: IsHex("") is false
+ throw runtime_error(strName+" must be hexadecimal string (not '"+strHex+"')");
+
+ uint256 result;
+ result.SetHex(strHex);
+ return result;
+}
+
+vector<unsigned char> ParseHexUV(const UniValue& v, const string& strName)
+{
+ string strHex;
+ if (v.isStr())
+ strHex = v.getValStr();
+ if (!IsHex(strHex))
+ throw runtime_error(strName+" must be hexadecimal string (not '"+strHex+"')");
+ return ParseHex(strHex);
+}
diff --git a/src/core_write.cpp b/src/core_write.cpp
new file mode 100644
index 0000000000..c3babec2fc
--- /dev/null
+++ b/src/core_write.cpp
@@ -0,0 +1,134 @@
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "core_io.h"
+
+#include "base58.h"
+#include "primitives/transaction.h"
+#include "script/script.h"
+#include "script/standard.h"
+#include "serialize.h"
+#include "streams.h"
+#include "univalue/univalue.h"
+#include "util.h"
+#include "utilmoneystr.h"
+#include "utilstrencodings.h"
+
+#include <boost/foreach.hpp>
+
+using namespace std;
+
+string FormatScript(const CScript& script)
+{
+ string ret;
+ CScript::const_iterator it = script.begin();
+ opcodetype op;
+ while (it != script.end()) {
+ CScript::const_iterator it2 = it;
+ vector<unsigned char> vch;
+ if (script.GetOp2(it, op, &vch)) {
+ if (op == OP_0) {
+ ret += "0 ";
+ continue;
+ } else if ((op >= OP_1 && op <= OP_16) || op == OP_1NEGATE) {
+ ret += strprintf("%i ", op - OP_1NEGATE - 1);
+ continue;
+ } else if (op >= OP_NOP && op <= OP_CHECKMULTISIGVERIFY) {
+ string str(GetOpName(op));
+ if (str.substr(0, 3) == string("OP_")) {
+ ret += str.substr(3, string::npos) + " ";
+ continue;
+ }
+ }
+ if (vch.size() > 0) {
+ ret += strprintf("0x%x 0x%x ", HexStr(it2, it - vch.size()), HexStr(it - vch.size(), it));
+ } else {
+ ret += strprintf("0x%x", HexStr(it2, it));
+ }
+ continue;
+ }
+ ret += strprintf("0x%x ", HexStr(it2, script.end()));
+ break;
+ }
+ return ret.substr(0, ret.size() - 1);
+}
+
+string EncodeHexTx(const CTransaction& tx)
+{
+ CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
+ ssTx << tx;
+ return HexStr(ssTx.begin(), ssTx.end());
+}
+
+void ScriptPubKeyToUniv(const CScript& scriptPubKey,
+ UniValue& out, bool fIncludeHex)
+{
+ txnouttype type;
+ vector<CTxDestination> addresses;
+ int nRequired;
+
+ out.pushKV("asm", scriptPubKey.ToString());
+ if (fIncludeHex)
+ out.pushKV("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end()));
+
+ if (!ExtractDestinations(scriptPubKey, type, addresses, nRequired)) {
+ out.pushKV("type", GetTxnOutputType(type));
+ return;
+ }
+
+ out.pushKV("reqSigs", nRequired);
+ out.pushKV("type", GetTxnOutputType(type));
+
+ UniValue a(UniValue::VARR);
+ BOOST_FOREACH(const CTxDestination& addr, addresses)
+ a.push_back(CBitcoinAddress(addr).ToString());
+ out.pushKV("addresses", a);
+}
+
+void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry)
+{
+ entry.pushKV("txid", tx.GetHash().GetHex());
+ entry.pushKV("version", tx.nVersion);
+ entry.pushKV("locktime", (int64_t)tx.nLockTime);
+
+ UniValue vin(UniValue::VARR);
+ BOOST_FOREACH(const CTxIn& txin, tx.vin) {
+ UniValue in(UniValue::VOBJ);
+ if (tx.IsCoinBase())
+ in.pushKV("coinbase", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()));
+ else {
+ in.pushKV("txid", txin.prevout.hash.GetHex());
+ in.pushKV("vout", (int64_t)txin.prevout.n);
+ UniValue o(UniValue::VOBJ);
+ o.pushKV("asm", txin.scriptSig.ToString());
+ o.pushKV("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()));
+ in.pushKV("scriptSig", o);
+ }
+ in.pushKV("sequence", (int64_t)txin.nSequence);
+ vin.push_back(in);
+ }
+ entry.pushKV("vin", vin);
+
+ UniValue vout(UniValue::VARR);
+ for (unsigned int i = 0; i < tx.vout.size(); i++) {
+ const CTxOut& txout = tx.vout[i];
+
+ UniValue out(UniValue::VOBJ);
+
+ UniValue outValue(UniValue::VNUM, FormatMoney(txout.nValue));
+ out.pushKV("value", outValue);
+ out.pushKV("n", (int64_t)i);
+
+ UniValue o(UniValue::VOBJ);
+ ScriptPubKeyToUniv(txout.scriptPubKey, o, true);
+ out.pushKV("scriptPubKey", o);
+ vout.push_back(out);
+ }
+ entry.pushKV("vout", vout);
+
+ if (!hashBlock.IsNull())
+ entry.pushKV("blockhash", hashBlock.GetHex());
+
+ entry.pushKV("hex", EncodeHexTx(tx)); // the hex-encoded transaction. used the name "hex" to be consistent with the verbose output of "getrawtransaction".
+}
diff --git a/src/crypto/common.h b/src/crypto/common.h
new file mode 100644
index 0000000000..580c72f5a6
--- /dev/null
+++ b/src/crypto/common.h
@@ -0,0 +1,66 @@
+// Copyright (c) 2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_CRYPTO_COMMON_H
+#define BITCOIN_CRYPTO_COMMON_H
+
+#if defined(HAVE_CONFIG_H)
+#include "bitcoin-config.h"
+#endif
+
+#include <stdint.h>
+
+#include "compat/endian.h"
+
+uint16_t static inline ReadLE16(const unsigned char* ptr)
+{
+ return le16toh(*((uint16_t*)ptr));
+}
+
+uint32_t static inline ReadLE32(const unsigned char* ptr)
+{
+ return le32toh(*((uint32_t*)ptr));
+}
+
+uint64_t static inline ReadLE64(const unsigned char* ptr)
+{
+ return le64toh(*((uint64_t*)ptr));
+}
+
+void static inline WriteLE16(unsigned char* ptr, uint16_t x)
+{
+ *((uint16_t*)ptr) = htole16(x);
+}
+
+void static inline WriteLE32(unsigned char* ptr, uint32_t x)
+{
+ *((uint32_t*)ptr) = htole32(x);
+}
+
+void static inline WriteLE64(unsigned char* ptr, uint64_t x)
+{
+ *((uint64_t*)ptr) = htole64(x);
+}
+
+uint32_t static inline ReadBE32(const unsigned char* ptr)
+{
+ return be32toh(*((uint32_t*)ptr));
+}
+
+uint64_t static inline ReadBE64(const unsigned char* ptr)
+{
+ return be64toh(*((uint64_t*)ptr));
+}
+
+void static inline WriteBE32(unsigned char* ptr, uint32_t x)
+{
+ *((uint32_t*)ptr) = htobe32(x);
+}
+
+void static inline WriteBE64(unsigned char* ptr, uint64_t x)
+{
+ *((uint64_t*)ptr) = htobe64(x);
+}
+
+#endif // BITCOIN_CRYPTO_COMMON_H
diff --git a/src/crypto/hmac_sha256.cpp b/src/crypto/hmac_sha256.cpp
new file mode 100644
index 0000000000..3c791625d0
--- /dev/null
+++ b/src/crypto/hmac_sha256.cpp
@@ -0,0 +1,34 @@
+// Copyright (c) 2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "crypto/hmac_sha256.h"
+
+#include <string.h>
+
+CHMAC_SHA256::CHMAC_SHA256(const unsigned char* key, size_t keylen)
+{
+ unsigned char rkey[64];
+ if (keylen <= 64) {
+ memcpy(rkey, key, keylen);
+ memset(rkey + keylen, 0, 64 - keylen);
+ } else {
+ CSHA256().Write(key, keylen).Finalize(rkey);
+ memset(rkey + 32, 0, 32);
+ }
+
+ for (int n = 0; n < 64; n++)
+ rkey[n] ^= 0x5c;
+ outer.Write(rkey, 64);
+
+ for (int n = 0; n < 64; n++)
+ rkey[n] ^= 0x5c ^ 0x36;
+ inner.Write(rkey, 64);
+}
+
+void CHMAC_SHA256::Finalize(unsigned char hash[OUTPUT_SIZE])
+{
+ unsigned char temp[32];
+ inner.Finalize(temp);
+ outer.Write(temp, 32).Finalize(hash);
+}
diff --git a/src/crypto/hmac_sha256.h b/src/crypto/hmac_sha256.h
new file mode 100644
index 0000000000..1519c1457e
--- /dev/null
+++ b/src/crypto/hmac_sha256.h
@@ -0,0 +1,32 @@
+// Copyright (c) 2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_CRYPTO_HMAC_SHA256_H
+#define BITCOIN_CRYPTO_HMAC_SHA256_H
+
+#include "crypto/sha256.h"
+
+#include <stdint.h>
+#include <stdlib.h>
+
+/** A hasher class for HMAC-SHA-512. */
+class CHMAC_SHA256
+{
+private:
+ CSHA256 outer;
+ CSHA256 inner;
+
+public:
+ static const size_t OUTPUT_SIZE = 32;
+
+ CHMAC_SHA256(const unsigned char* key, size_t keylen);
+ CHMAC_SHA256& Write(const unsigned char* data, size_t len)
+ {
+ inner.Write(data, len);
+ return *this;
+ }
+ void Finalize(unsigned char hash[OUTPUT_SIZE]);
+};
+
+#endif // BITCOIN_CRYPTO_HMAC_SHA256_H
diff --git a/src/crypto/hmac_sha512.cpp b/src/crypto/hmac_sha512.cpp
new file mode 100644
index 0000000000..5939c6ec47
--- /dev/null
+++ b/src/crypto/hmac_sha512.cpp
@@ -0,0 +1,34 @@
+// Copyright (c) 2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "crypto/hmac_sha512.h"
+
+#include <string.h>
+
+CHMAC_SHA512::CHMAC_SHA512(const unsigned char* key, size_t keylen)
+{
+ unsigned char rkey[128];
+ if (keylen <= 128) {
+ memcpy(rkey, key, keylen);
+ memset(rkey + keylen, 0, 128 - keylen);
+ } else {
+ CSHA512().Write(key, keylen).Finalize(rkey);
+ memset(rkey + 64, 0, 64);
+ }
+
+ for (int n = 0; n < 128; n++)
+ rkey[n] ^= 0x5c;
+ outer.Write(rkey, 128);
+
+ for (int n = 0; n < 128; n++)
+ rkey[n] ^= 0x5c ^ 0x36;
+ inner.Write(rkey, 128);
+}
+
+void CHMAC_SHA512::Finalize(unsigned char hash[OUTPUT_SIZE])
+{
+ unsigned char temp[64];
+ inner.Finalize(temp);
+ outer.Write(temp, 64).Finalize(hash);
+}
diff --git a/src/crypto/hmac_sha512.h b/src/crypto/hmac_sha512.h
new file mode 100644
index 0000000000..17dee61ea8
--- /dev/null
+++ b/src/crypto/hmac_sha512.h
@@ -0,0 +1,32 @@
+// Copyright (c) 2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_CRYPTO_HMAC_SHA512_H
+#define BITCOIN_CRYPTO_HMAC_SHA512_H
+
+#include "crypto/sha512.h"
+
+#include <stdint.h>
+#include <stdlib.h>
+
+/** A hasher class for HMAC-SHA-512. */
+class CHMAC_SHA512
+{
+private:
+ CSHA512 outer;
+ CSHA512 inner;
+
+public:
+ static const size_t OUTPUT_SIZE = 64;
+
+ CHMAC_SHA512(const unsigned char* key, size_t keylen);
+ CHMAC_SHA512& Write(const unsigned char* data, size_t len)
+ {
+ inner.Write(data, len);
+ return *this;
+ }
+ void Finalize(unsigned char hash[OUTPUT_SIZE]);
+};
+
+#endif // BITCOIN_CRYPTO_HMAC_SHA512_H
diff --git a/src/crypto/ripemd160.cpp b/src/crypto/ripemd160.cpp
new file mode 100644
index 0000000000..77c9acfc26
--- /dev/null
+++ b/src/crypto/ripemd160.cpp
@@ -0,0 +1,292 @@
+// Copyright (c) 2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "crypto/ripemd160.h"
+
+#include "crypto/common.h"
+
+#include <string.h>
+
+// Internal implementation code.
+namespace
+{
+/// Internal RIPEMD-160 implementation.
+namespace ripemd160
+{
+uint32_t inline f1(uint32_t x, uint32_t y, uint32_t z) { return x ^ y ^ z; }
+uint32_t inline f2(uint32_t x, uint32_t y, uint32_t z) { return (x & y) | (~x & z); }
+uint32_t inline f3(uint32_t x, uint32_t y, uint32_t z) { return (x | ~y) ^ z; }
+uint32_t inline f4(uint32_t x, uint32_t y, uint32_t z) { return (x & z) | (y & ~z); }
+uint32_t inline f5(uint32_t x, uint32_t y, uint32_t z) { return x ^ (y | ~z); }
+
+/** Initialize RIPEMD-160 state. */
+void inline Initialize(uint32_t* s)
+{
+ s[0] = 0x67452301ul;
+ s[1] = 0xEFCDAB89ul;
+ s[2] = 0x98BADCFEul;
+ s[3] = 0x10325476ul;
+ s[4] = 0xC3D2E1F0ul;
+}
+
+uint32_t inline rol(uint32_t x, int i) { return (x << i) | (x >> (32 - i)); }
+
+void inline Round(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t f, uint32_t x, uint32_t k, int r)
+{
+ a = rol(a + f + x + k, r) + e;
+ c = rol(c, 10);
+}
+
+void inline R11(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f1(b, c, d), x, 0, r); }
+void inline R21(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f2(b, c, d), x, 0x5A827999ul, r); }
+void inline R31(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f3(b, c, d), x, 0x6ED9EBA1ul, r); }
+void inline R41(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f4(b, c, d), x, 0x8F1BBCDCul, r); }
+void inline R51(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f5(b, c, d), x, 0xA953FD4Eul, r); }
+
+void inline R12(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f5(b, c, d), x, 0x50A28BE6ul, r); }
+void inline R22(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f4(b, c, d), x, 0x5C4DD124ul, r); }
+void inline R32(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f3(b, c, d), x, 0x6D703EF3ul, r); }
+void inline R42(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f2(b, c, d), x, 0x7A6D76E9ul, r); }
+void inline R52(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f1(b, c, d), x, 0, r); }
+
+/** Perform a RIPEMD-160 transformation, processing a 64-byte chunk. */
+void Transform(uint32_t* s, const unsigned char* chunk)
+{
+ uint32_t a1 = s[0], b1 = s[1], c1 = s[2], d1 = s[3], e1 = s[4];
+ uint32_t a2 = a1, b2 = b1, c2 = c1, d2 = d1, e2 = e1;
+ uint32_t w0 = ReadLE32(chunk + 0), w1 = ReadLE32(chunk + 4), w2 = ReadLE32(chunk + 8), w3 = ReadLE32(chunk + 12);
+ uint32_t w4 = ReadLE32(chunk + 16), w5 = ReadLE32(chunk + 20), w6 = ReadLE32(chunk + 24), w7 = ReadLE32(chunk + 28);
+ uint32_t w8 = ReadLE32(chunk + 32), w9 = ReadLE32(chunk + 36), w10 = ReadLE32(chunk + 40), w11 = ReadLE32(chunk + 44);
+ uint32_t w12 = ReadLE32(chunk + 48), w13 = ReadLE32(chunk + 52), w14 = ReadLE32(chunk + 56), w15 = ReadLE32(chunk + 60);
+
+ R11(a1, b1, c1, d1, e1, w0, 11);
+ R12(a2, b2, c2, d2, e2, w5, 8);
+ R11(e1, a1, b1, c1, d1, w1, 14);
+ R12(e2, a2, b2, c2, d2, w14, 9);
+ R11(d1, e1, a1, b1, c1, w2, 15);
+ R12(d2, e2, a2, b2, c2, w7, 9);
+ R11(c1, d1, e1, a1, b1, w3, 12);
+ R12(c2, d2, e2, a2, b2, w0, 11);
+ R11(b1, c1, d1, e1, a1, w4, 5);
+ R12(b2, c2, d2, e2, a2, w9, 13);
+ R11(a1, b1, c1, d1, e1, w5, 8);
+ R12(a2, b2, c2, d2, e2, w2, 15);
+ R11(e1, a1, b1, c1, d1, w6, 7);
+ R12(e2, a2, b2, c2, d2, w11, 15);
+ R11(d1, e1, a1, b1, c1, w7, 9);
+ R12(d2, e2, a2, b2, c2, w4, 5);
+ R11(c1, d1, e1, a1, b1, w8, 11);
+ R12(c2, d2, e2, a2, b2, w13, 7);
+ R11(b1, c1, d1, e1, a1, w9, 13);
+ R12(b2, c2, d2, e2, a2, w6, 7);
+ R11(a1, b1, c1, d1, e1, w10, 14);
+ R12(a2, b2, c2, d2, e2, w15, 8);
+ R11(e1, a1, b1, c1, d1, w11, 15);
+ R12(e2, a2, b2, c2, d2, w8, 11);
+ R11(d1, e1, a1, b1, c1, w12, 6);
+ R12(d2, e2, a2, b2, c2, w1, 14);
+ R11(c1, d1, e1, a1, b1, w13, 7);
+ R12(c2, d2, e2, a2, b2, w10, 14);
+ R11(b1, c1, d1, e1, a1, w14, 9);
+ R12(b2, c2, d2, e2, a2, w3, 12);
+ R11(a1, b1, c1, d1, e1, w15, 8);
+ R12(a2, b2, c2, d2, e2, w12, 6);
+
+ R21(e1, a1, b1, c1, d1, w7, 7);
+ R22(e2, a2, b2, c2, d2, w6, 9);
+ R21(d1, e1, a1, b1, c1, w4, 6);
+ R22(d2, e2, a2, b2, c2, w11, 13);
+ R21(c1, d1, e1, a1, b1, w13, 8);
+ R22(c2, d2, e2, a2, b2, w3, 15);
+ R21(b1, c1, d1, e1, a1, w1, 13);
+ R22(b2, c2, d2, e2, a2, w7, 7);
+ R21(a1, b1, c1, d1, e1, w10, 11);
+ R22(a2, b2, c2, d2, e2, w0, 12);
+ R21(e1, a1, b1, c1, d1, w6, 9);
+ R22(e2, a2, b2, c2, d2, w13, 8);
+ R21(d1, e1, a1, b1, c1, w15, 7);
+ R22(d2, e2, a2, b2, c2, w5, 9);
+ R21(c1, d1, e1, a1, b1, w3, 15);
+ R22(c2, d2, e2, a2, b2, w10, 11);
+ R21(b1, c1, d1, e1, a1, w12, 7);
+ R22(b2, c2, d2, e2, a2, w14, 7);
+ R21(a1, b1, c1, d1, e1, w0, 12);
+ R22(a2, b2, c2, d2, e2, w15, 7);
+ R21(e1, a1, b1, c1, d1, w9, 15);
+ R22(e2, a2, b2, c2, d2, w8, 12);
+ R21(d1, e1, a1, b1, c1, w5, 9);
+ R22(d2, e2, a2, b2, c2, w12, 7);
+ R21(c1, d1, e1, a1, b1, w2, 11);
+ R22(c2, d2, e2, a2, b2, w4, 6);
+ R21(b1, c1, d1, e1, a1, w14, 7);
+ R22(b2, c2, d2, e2, a2, w9, 15);
+ R21(a1, b1, c1, d1, e1, w11, 13);
+ R22(a2, b2, c2, d2, e2, w1, 13);
+ R21(e1, a1, b1, c1, d1, w8, 12);
+ R22(e2, a2, b2, c2, d2, w2, 11);
+
+ R31(d1, e1, a1, b1, c1, w3, 11);
+ R32(d2, e2, a2, b2, c2, w15, 9);
+ R31(c1, d1, e1, a1, b1, w10, 13);
+ R32(c2, d2, e2, a2, b2, w5, 7);
+ R31(b1, c1, d1, e1, a1, w14, 6);
+ R32(b2, c2, d2, e2, a2, w1, 15);
+ R31(a1, b1, c1, d1, e1, w4, 7);
+ R32(a2, b2, c2, d2, e2, w3, 11);
+ R31(e1, a1, b1, c1, d1, w9, 14);
+ R32(e2, a2, b2, c2, d2, w7, 8);
+ R31(d1, e1, a1, b1, c1, w15, 9);
+ R32(d2, e2, a2, b2, c2, w14, 6);
+ R31(c1, d1, e1, a1, b1, w8, 13);
+ R32(c2, d2, e2, a2, b2, w6, 6);
+ R31(b1, c1, d1, e1, a1, w1, 15);
+ R32(b2, c2, d2, e2, a2, w9, 14);
+ R31(a1, b1, c1, d1, e1, w2, 14);
+ R32(a2, b2, c2, d2, e2, w11, 12);
+ R31(e1, a1, b1, c1, d1, w7, 8);
+ R32(e2, a2, b2, c2, d2, w8, 13);
+ R31(d1, e1, a1, b1, c1, w0, 13);
+ R32(d2, e2, a2, b2, c2, w12, 5);
+ R31(c1, d1, e1, a1, b1, w6, 6);
+ R32(c2, d2, e2, a2, b2, w2, 14);
+ R31(b1, c1, d1, e1, a1, w13, 5);
+ R32(b2, c2, d2, e2, a2, w10, 13);
+ R31(a1, b1, c1, d1, e1, w11, 12);
+ R32(a2, b2, c2, d2, e2, w0, 13);
+ R31(e1, a1, b1, c1, d1, w5, 7);
+ R32(e2, a2, b2, c2, d2, w4, 7);
+ R31(d1, e1, a1, b1, c1, w12, 5);
+ R32(d2, e2, a2, b2, c2, w13, 5);
+
+ R41(c1, d1, e1, a1, b1, w1, 11);
+ R42(c2, d2, e2, a2, b2, w8, 15);
+ R41(b1, c1, d1, e1, a1, w9, 12);
+ R42(b2, c2, d2, e2, a2, w6, 5);
+ R41(a1, b1, c1, d1, e1, w11, 14);
+ R42(a2, b2, c2, d2, e2, w4, 8);
+ R41(e1, a1, b1, c1, d1, w10, 15);
+ R42(e2, a2, b2, c2, d2, w1, 11);
+ R41(d1, e1, a1, b1, c1, w0, 14);
+ R42(d2, e2, a2, b2, c2, w3, 14);
+ R41(c1, d1, e1, a1, b1, w8, 15);
+ R42(c2, d2, e2, a2, b2, w11, 14);
+ R41(b1, c1, d1, e1, a1, w12, 9);
+ R42(b2, c2, d2, e2, a2, w15, 6);
+ R41(a1, b1, c1, d1, e1, w4, 8);
+ R42(a2, b2, c2, d2, e2, w0, 14);
+ R41(e1, a1, b1, c1, d1, w13, 9);
+ R42(e2, a2, b2, c2, d2, w5, 6);
+ R41(d1, e1, a1, b1, c1, w3, 14);
+ R42(d2, e2, a2, b2, c2, w12, 9);
+ R41(c1, d1, e1, a1, b1, w7, 5);
+ R42(c2, d2, e2, a2, b2, w2, 12);
+ R41(b1, c1, d1, e1, a1, w15, 6);
+ R42(b2, c2, d2, e2, a2, w13, 9);
+ R41(a1, b1, c1, d1, e1, w14, 8);
+ R42(a2, b2, c2, d2, e2, w9, 12);
+ R41(e1, a1, b1, c1, d1, w5, 6);
+ R42(e2, a2, b2, c2, d2, w7, 5);
+ R41(d1, e1, a1, b1, c1, w6, 5);
+ R42(d2, e2, a2, b2, c2, w10, 15);
+ R41(c1, d1, e1, a1, b1, w2, 12);
+ R42(c2, d2, e2, a2, b2, w14, 8);
+
+ R51(b1, c1, d1, e1, a1, w4, 9);
+ R52(b2, c2, d2, e2, a2, w12, 8);
+ R51(a1, b1, c1, d1, e1, w0, 15);
+ R52(a2, b2, c2, d2, e2, w15, 5);
+ R51(e1, a1, b1, c1, d1, w5, 5);
+ R52(e2, a2, b2, c2, d2, w10, 12);
+ R51(d1, e1, a1, b1, c1, w9, 11);
+ R52(d2, e2, a2, b2, c2, w4, 9);
+ R51(c1, d1, e1, a1, b1, w7, 6);
+ R52(c2, d2, e2, a2, b2, w1, 12);
+ R51(b1, c1, d1, e1, a1, w12, 8);
+ R52(b2, c2, d2, e2, a2, w5, 5);
+ R51(a1, b1, c1, d1, e1, w2, 13);
+ R52(a2, b2, c2, d2, e2, w8, 14);
+ R51(e1, a1, b1, c1, d1, w10, 12);
+ R52(e2, a2, b2, c2, d2, w7, 6);
+ R51(d1, e1, a1, b1, c1, w14, 5);
+ R52(d2, e2, a2, b2, c2, w6, 8);
+ R51(c1, d1, e1, a1, b1, w1, 12);
+ R52(c2, d2, e2, a2, b2, w2, 13);
+ R51(b1, c1, d1, e1, a1, w3, 13);
+ R52(b2, c2, d2, e2, a2, w13, 6);
+ R51(a1, b1, c1, d1, e1, w8, 14);
+ R52(a2, b2, c2, d2, e2, w14, 5);
+ R51(e1, a1, b1, c1, d1, w11, 11);
+ R52(e2, a2, b2, c2, d2, w0, 15);
+ R51(d1, e1, a1, b1, c1, w6, 8);
+ R52(d2, e2, a2, b2, c2, w3, 13);
+ R51(c1, d1, e1, a1, b1, w15, 5);
+ R52(c2, d2, e2, a2, b2, w9, 11);
+ R51(b1, c1, d1, e1, a1, w13, 6);
+ R52(b2, c2, d2, e2, a2, w11, 11);
+
+ uint32_t t = s[0];
+ s[0] = s[1] + c1 + d2;
+ s[1] = s[2] + d1 + e2;
+ s[2] = s[3] + e1 + a2;
+ s[3] = s[4] + a1 + b2;
+ s[4] = t + b1 + c2;
+}
+
+} // namespace ripemd160
+
+} // namespace
+
+////// RIPEMD160
+
+CRIPEMD160::CRIPEMD160() : bytes(0)
+{
+ ripemd160::Initialize(s);
+}
+
+CRIPEMD160& CRIPEMD160::Write(const unsigned char* data, size_t len)
+{
+ const unsigned char* end = data + len;
+ size_t bufsize = bytes % 64;
+ if (bufsize && bufsize + len >= 64) {
+ // Fill the buffer, and process it.
+ memcpy(buf + bufsize, data, 64 - bufsize);
+ bytes += 64 - bufsize;
+ data += 64 - bufsize;
+ ripemd160::Transform(s, buf);
+ bufsize = 0;
+ }
+ while (end >= data + 64) {
+ // Process full chunks directly from the source.
+ ripemd160::Transform(s, data);
+ bytes += 64;
+ data += 64;
+ }
+ if (end > data) {
+ // Fill the buffer with what remains.
+ memcpy(buf + bufsize, data, end - data);
+ bytes += end - data;
+ }
+ return *this;
+}
+
+void CRIPEMD160::Finalize(unsigned char hash[OUTPUT_SIZE])
+{
+ static const unsigned char pad[64] = {0x80};
+ unsigned char sizedesc[8];
+ WriteLE64(sizedesc, bytes << 3);
+ Write(pad, 1 + ((119 - (bytes % 64)) % 64));
+ Write(sizedesc, 8);
+ WriteLE32(hash, s[0]);
+ WriteLE32(hash + 4, s[1]);
+ WriteLE32(hash + 8, s[2]);
+ WriteLE32(hash + 12, s[3]);
+ WriteLE32(hash + 16, s[4]);
+}
+
+CRIPEMD160& CRIPEMD160::Reset()
+{
+ bytes = 0;
+ ripemd160::Initialize(s);
+ return *this;
+}
diff --git a/src/crypto/ripemd160.h b/src/crypto/ripemd160.h
new file mode 100644
index 0000000000..687204fdae
--- /dev/null
+++ b/src/crypto/ripemd160.h
@@ -0,0 +1,28 @@
+// Copyright (c) 2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_CRYPTO_RIPEMD160_H
+#define BITCOIN_CRYPTO_RIPEMD160_H
+
+#include <stdint.h>
+#include <stdlib.h>
+
+/** A hasher class for RIPEMD-160. */
+class CRIPEMD160
+{
+private:
+ uint32_t s[5];
+ unsigned char buf[64];
+ size_t bytes;
+
+public:
+ static const size_t OUTPUT_SIZE = 20;
+
+ CRIPEMD160();
+ CRIPEMD160& Write(const unsigned char* data, size_t len);
+ void Finalize(unsigned char hash[OUTPUT_SIZE]);
+ CRIPEMD160& Reset();
+};
+
+#endif // BITCOIN_CRYPTO_RIPEMD160_H
diff --git a/src/crypto/sha1.cpp b/src/crypto/sha1.cpp
new file mode 100644
index 0000000000..0b895b33a2
--- /dev/null
+++ b/src/crypto/sha1.cpp
@@ -0,0 +1,199 @@
+// Copyright (c) 2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "crypto/sha1.h"
+
+#include "crypto/common.h"
+
+#include <string.h>
+
+// Internal implementation code.
+namespace
+{
+/// Internal SHA-1 implementation.
+namespace sha1
+{
+/** One round of SHA-1. */
+void inline Round(uint32_t a, uint32_t& b, uint32_t c, uint32_t d, uint32_t& e, uint32_t f, uint32_t k, uint32_t w)
+{
+ e += ((a << 5) | (a >> 27)) + f + k + w;
+ b = (b << 30) | (b >> 2);
+}
+
+uint32_t inline f1(uint32_t b, uint32_t c, uint32_t d) { return d ^ (b & (c ^ d)); }
+uint32_t inline f2(uint32_t b, uint32_t c, uint32_t d) { return b ^ c ^ d; }
+uint32_t inline f3(uint32_t b, uint32_t c, uint32_t d) { return (b & c) | (d & (b | c)); }
+
+uint32_t inline left(uint32_t x) { return (x << 1) | (x >> 31); }
+
+/** Initialize SHA-1 state. */
+void inline Initialize(uint32_t* s)
+{
+ s[0] = 0x67452301ul;
+ s[1] = 0xEFCDAB89ul;
+ s[2] = 0x98BADCFEul;
+ s[3] = 0x10325476ul;
+ s[4] = 0xC3D2E1F0ul;
+}
+
+const uint32_t k1 = 0x5A827999ul;
+const uint32_t k2 = 0x6ED9EBA1ul;
+const uint32_t k3 = 0x8F1BBCDCul;
+const uint32_t k4 = 0xCA62C1D6ul;
+
+/** Perform a SHA-1 transformation, processing a 64-byte chunk. */
+void Transform(uint32_t* s, const unsigned char* chunk)
+{
+ uint32_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4];
+ uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
+
+ Round(a, b, c, d, e, f1(b, c, d), k1, w0 = ReadBE32(chunk + 0));
+ Round(e, a, b, c, d, f1(a, b, c), k1, w1 = ReadBE32(chunk + 4));
+ Round(d, e, a, b, c, f1(e, a, b), k1, w2 = ReadBE32(chunk + 8));
+ Round(c, d, e, a, b, f1(d, e, a), k1, w3 = ReadBE32(chunk + 12));
+ Round(b, c, d, e, a, f1(c, d, e), k1, w4 = ReadBE32(chunk + 16));
+ Round(a, b, c, d, e, f1(b, c, d), k1, w5 = ReadBE32(chunk + 20));
+ Round(e, a, b, c, d, f1(a, b, c), k1, w6 = ReadBE32(chunk + 24));
+ Round(d, e, a, b, c, f1(e, a, b), k1, w7 = ReadBE32(chunk + 28));
+ Round(c, d, e, a, b, f1(d, e, a), k1, w8 = ReadBE32(chunk + 32));
+ Round(b, c, d, e, a, f1(c, d, e), k1, w9 = ReadBE32(chunk + 36));
+ Round(a, b, c, d, e, f1(b, c, d), k1, w10 = ReadBE32(chunk + 40));
+ Round(e, a, b, c, d, f1(a, b, c), k1, w11 = ReadBE32(chunk + 44));
+ Round(d, e, a, b, c, f1(e, a, b), k1, w12 = ReadBE32(chunk + 48));
+ Round(c, d, e, a, b, f1(d, e, a), k1, w13 = ReadBE32(chunk + 52));
+ Round(b, c, d, e, a, f1(c, d, e), k1, w14 = ReadBE32(chunk + 56));
+ Round(a, b, c, d, e, f1(b, c, d), k1, w15 = ReadBE32(chunk + 60));
+
+ Round(e, a, b, c, d, f1(a, b, c), k1, w0 = left(w0 ^ w13 ^ w8 ^ w2));
+ Round(d, e, a, b, c, f1(e, a, b), k1, w1 = left(w1 ^ w14 ^ w9 ^ w3));
+ Round(c, d, e, a, b, f1(d, e, a), k1, w2 = left(w2 ^ w15 ^ w10 ^ w4));
+ Round(b, c, d, e, a, f1(c, d, e), k1, w3 = left(w3 ^ w0 ^ w11 ^ w5));
+ Round(a, b, c, d, e, f2(b, c, d), k2, w4 = left(w4 ^ w1 ^ w12 ^ w6));
+ Round(e, a, b, c, d, f2(a, b, c), k2, w5 = left(w5 ^ w2 ^ w13 ^ w7));
+ Round(d, e, a, b, c, f2(e, a, b), k2, w6 = left(w6 ^ w3 ^ w14 ^ w8));
+ Round(c, d, e, a, b, f2(d, e, a), k2, w7 = left(w7 ^ w4 ^ w15 ^ w9));
+ Round(b, c, d, e, a, f2(c, d, e), k2, w8 = left(w8 ^ w5 ^ w0 ^ w10));
+ Round(a, b, c, d, e, f2(b, c, d), k2, w9 = left(w9 ^ w6 ^ w1 ^ w11));
+ Round(e, a, b, c, d, f2(a, b, c), k2, w10 = left(w10 ^ w7 ^ w2 ^ w12));
+ Round(d, e, a, b, c, f2(e, a, b), k2, w11 = left(w11 ^ w8 ^ w3 ^ w13));
+ Round(c, d, e, a, b, f2(d, e, a), k2, w12 = left(w12 ^ w9 ^ w4 ^ w14));
+ Round(b, c, d, e, a, f2(c, d, e), k2, w13 = left(w13 ^ w10 ^ w5 ^ w15));
+ Round(a, b, c, d, e, f2(b, c, d), k2, w14 = left(w14 ^ w11 ^ w6 ^ w0));
+ Round(e, a, b, c, d, f2(a, b, c), k2, w15 = left(w15 ^ w12 ^ w7 ^ w1));
+
+ Round(d, e, a, b, c, f2(e, a, b), k2, w0 = left(w0 ^ w13 ^ w8 ^ w2));
+ Round(c, d, e, a, b, f2(d, e, a), k2, w1 = left(w1 ^ w14 ^ w9 ^ w3));
+ Round(b, c, d, e, a, f2(c, d, e), k2, w2 = left(w2 ^ w15 ^ w10 ^ w4));
+ Round(a, b, c, d, e, f2(b, c, d), k2, w3 = left(w3 ^ w0 ^ w11 ^ w5));
+ Round(e, a, b, c, d, f2(a, b, c), k2, w4 = left(w4 ^ w1 ^ w12 ^ w6));
+ Round(d, e, a, b, c, f2(e, a, b), k2, w5 = left(w5 ^ w2 ^ w13 ^ w7));
+ Round(c, d, e, a, b, f2(d, e, a), k2, w6 = left(w6 ^ w3 ^ w14 ^ w8));
+ Round(b, c, d, e, a, f2(c, d, e), k2, w7 = left(w7 ^ w4 ^ w15 ^ w9));
+ Round(a, b, c, d, e, f3(b, c, d), k3, w8 = left(w8 ^ w5 ^ w0 ^ w10));
+ Round(e, a, b, c, d, f3(a, b, c), k3, w9 = left(w9 ^ w6 ^ w1 ^ w11));
+ Round(d, e, a, b, c, f3(e, a, b), k3, w10 = left(w10 ^ w7 ^ w2 ^ w12));
+ Round(c, d, e, a, b, f3(d, e, a), k3, w11 = left(w11 ^ w8 ^ w3 ^ w13));
+ Round(b, c, d, e, a, f3(c, d, e), k3, w12 = left(w12 ^ w9 ^ w4 ^ w14));
+ Round(a, b, c, d, e, f3(b, c, d), k3, w13 = left(w13 ^ w10 ^ w5 ^ w15));
+ Round(e, a, b, c, d, f3(a, b, c), k3, w14 = left(w14 ^ w11 ^ w6 ^ w0));
+ Round(d, e, a, b, c, f3(e, a, b), k3, w15 = left(w15 ^ w12 ^ w7 ^ w1));
+
+ Round(c, d, e, a, b, f3(d, e, a), k3, w0 = left(w0 ^ w13 ^ w8 ^ w2));
+ Round(b, c, d, e, a, f3(c, d, e), k3, w1 = left(w1 ^ w14 ^ w9 ^ w3));
+ Round(a, b, c, d, e, f3(b, c, d), k3, w2 = left(w2 ^ w15 ^ w10 ^ w4));
+ Round(e, a, b, c, d, f3(a, b, c), k3, w3 = left(w3 ^ w0 ^ w11 ^ w5));
+ Round(d, e, a, b, c, f3(e, a, b), k3, w4 = left(w4 ^ w1 ^ w12 ^ w6));
+ Round(c, d, e, a, b, f3(d, e, a), k3, w5 = left(w5 ^ w2 ^ w13 ^ w7));
+ Round(b, c, d, e, a, f3(c, d, e), k3, w6 = left(w6 ^ w3 ^ w14 ^ w8));
+ Round(a, b, c, d, e, f3(b, c, d), k3, w7 = left(w7 ^ w4 ^ w15 ^ w9));
+ Round(e, a, b, c, d, f3(a, b, c), k3, w8 = left(w8 ^ w5 ^ w0 ^ w10));
+ Round(d, e, a, b, c, f3(e, a, b), k3, w9 = left(w9 ^ w6 ^ w1 ^ w11));
+ Round(c, d, e, a, b, f3(d, e, a), k3, w10 = left(w10 ^ w7 ^ w2 ^ w12));
+ Round(b, c, d, e, a, f3(c, d, e), k3, w11 = left(w11 ^ w8 ^ w3 ^ w13));
+ Round(a, b, c, d, e, f2(b, c, d), k4, w12 = left(w12 ^ w9 ^ w4 ^ w14));
+ Round(e, a, b, c, d, f2(a, b, c), k4, w13 = left(w13 ^ w10 ^ w5 ^ w15));
+ Round(d, e, a, b, c, f2(e, a, b), k4, w14 = left(w14 ^ w11 ^ w6 ^ w0));
+ Round(c, d, e, a, b, f2(d, e, a), k4, w15 = left(w15 ^ w12 ^ w7 ^ w1));
+
+ Round(b, c, d, e, a, f2(c, d, e), k4, w0 = left(w0 ^ w13 ^ w8 ^ w2));
+ Round(a, b, c, d, e, f2(b, c, d), k4, w1 = left(w1 ^ w14 ^ w9 ^ w3));
+ Round(e, a, b, c, d, f2(a, b, c), k4, w2 = left(w2 ^ w15 ^ w10 ^ w4));
+ Round(d, e, a, b, c, f2(e, a, b), k4, w3 = left(w3 ^ w0 ^ w11 ^ w5));
+ Round(c, d, e, a, b, f2(d, e, a), k4, w4 = left(w4 ^ w1 ^ w12 ^ w6));
+ Round(b, c, d, e, a, f2(c, d, e), k4, w5 = left(w5 ^ w2 ^ w13 ^ w7));
+ Round(a, b, c, d, e, f2(b, c, d), k4, w6 = left(w6 ^ w3 ^ w14 ^ w8));
+ Round(e, a, b, c, d, f2(a, b, c), k4, w7 = left(w7 ^ w4 ^ w15 ^ w9));
+ Round(d, e, a, b, c, f2(e, a, b), k4, w8 = left(w8 ^ w5 ^ w0 ^ w10));
+ Round(c, d, e, a, b, f2(d, e, a), k4, w9 = left(w9 ^ w6 ^ w1 ^ w11));
+ Round(b, c, d, e, a, f2(c, d, e), k4, w10 = left(w10 ^ w7 ^ w2 ^ w12));
+ Round(a, b, c, d, e, f2(b, c, d), k4, w11 = left(w11 ^ w8 ^ w3 ^ w13));
+ Round(e, a, b, c, d, f2(a, b, c), k4, w12 = left(w12 ^ w9 ^ w4 ^ w14));
+ Round(d, e, a, b, c, f2(e, a, b), k4, left(w13 ^ w10 ^ w5 ^ w15));
+ Round(c, d, e, a, b, f2(d, e, a), k4, left(w14 ^ w11 ^ w6 ^ w0));
+ Round(b, c, d, e, a, f2(c, d, e), k4, left(w15 ^ w12 ^ w7 ^ w1));
+
+ s[0] += a;
+ s[1] += b;
+ s[2] += c;
+ s[3] += d;
+ s[4] += e;
+}
+
+} // namespace sha1
+
+} // namespace
+
+////// SHA1
+
+CSHA1::CSHA1() : bytes(0)
+{
+ sha1::Initialize(s);
+}
+
+CSHA1& CSHA1::Write(const unsigned char* data, size_t len)
+{
+ const unsigned char* end = data + len;
+ size_t bufsize = bytes % 64;
+ if (bufsize && bufsize + len >= 64) {
+ // Fill the buffer, and process it.
+ memcpy(buf + bufsize, data, 64 - bufsize);
+ bytes += 64 - bufsize;
+ data += 64 - bufsize;
+ sha1::Transform(s, buf);
+ bufsize = 0;
+ }
+ while (end >= data + 64) {
+ // Process full chunks directly from the source.
+ sha1::Transform(s, data);
+ bytes += 64;
+ data += 64;
+ }
+ if (end > data) {
+ // Fill the buffer with what remains.
+ memcpy(buf + bufsize, data, end - data);
+ bytes += end - data;
+ }
+ return *this;
+}
+
+void CSHA1::Finalize(unsigned char hash[OUTPUT_SIZE])
+{
+ static const unsigned char pad[64] = {0x80};
+ unsigned char sizedesc[8];
+ WriteBE64(sizedesc, bytes << 3);
+ Write(pad, 1 + ((119 - (bytes % 64)) % 64));
+ Write(sizedesc, 8);
+ WriteBE32(hash, s[0]);
+ WriteBE32(hash + 4, s[1]);
+ WriteBE32(hash + 8, s[2]);
+ WriteBE32(hash + 12, s[3]);
+ WriteBE32(hash + 16, s[4]);
+}
+
+CSHA1& CSHA1::Reset()
+{
+ bytes = 0;
+ sha1::Initialize(s);
+ return *this;
+}
diff --git a/src/crypto/sha1.h b/src/crypto/sha1.h
new file mode 100644
index 0000000000..7b2a21bc6c
--- /dev/null
+++ b/src/crypto/sha1.h
@@ -0,0 +1,28 @@
+// Copyright (c) 2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_CRYPTO_SHA1_H
+#define BITCOIN_CRYPTO_SHA1_H
+
+#include <stdint.h>
+#include <stdlib.h>
+
+/** A hasher class for SHA1. */
+class CSHA1
+{
+private:
+ uint32_t s[5];
+ unsigned char buf[64];
+ size_t bytes;
+
+public:
+ static const size_t OUTPUT_SIZE = 20;
+
+ CSHA1();
+ CSHA1& Write(const unsigned char* data, size_t len);
+ void Finalize(unsigned char hash[OUTPUT_SIZE]);
+ CSHA1& Reset();
+};
+
+#endif // BITCOIN_CRYPTO_SHA1_H
diff --git a/src/crypto/sha256.cpp b/src/crypto/sha256.cpp
new file mode 100644
index 0000000000..5b9f00a0a2
--- /dev/null
+++ b/src/crypto/sha256.cpp
@@ -0,0 +1,189 @@
+// Copyright (c) 2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "crypto/sha256.h"
+
+#include "crypto/common.h"
+
+#include <string.h>
+
+// Internal implementation code.
+namespace
+{
+/// Internal SHA-256 implementation.
+namespace sha256
+{
+uint32_t inline Ch(uint32_t x, uint32_t y, uint32_t z) { return z ^ (x & (y ^ z)); }
+uint32_t inline Maj(uint32_t x, uint32_t y, uint32_t z) { return (x & y) | (z & (x | y)); }
+uint32_t inline Sigma0(uint32_t x) { return (x >> 2 | x << 30) ^ (x >> 13 | x << 19) ^ (x >> 22 | x << 10); }
+uint32_t inline Sigma1(uint32_t x) { return (x >> 6 | x << 26) ^ (x >> 11 | x << 21) ^ (x >> 25 | x << 7); }
+uint32_t inline sigma0(uint32_t x) { return (x >> 7 | x << 25) ^ (x >> 18 | x << 14) ^ (x >> 3); }
+uint32_t inline sigma1(uint32_t x) { return (x >> 17 | x << 15) ^ (x >> 19 | x << 13) ^ (x >> 10); }
+
+/** One round of SHA-256. */
+void inline Round(uint32_t a, uint32_t b, uint32_t c, uint32_t& d, uint32_t e, uint32_t f, uint32_t g, uint32_t& h, uint32_t k, uint32_t w)
+{
+ uint32_t t1 = h + Sigma1(e) + Ch(e, f, g) + k + w;
+ uint32_t t2 = Sigma0(a) + Maj(a, b, c);
+ d += t1;
+ h = t1 + t2;
+}
+
+/** Initialize SHA-256 state. */
+void inline Initialize(uint32_t* s)
+{
+ s[0] = 0x6a09e667ul;
+ s[1] = 0xbb67ae85ul;
+ s[2] = 0x3c6ef372ul;
+ s[3] = 0xa54ff53aul;
+ s[4] = 0x510e527ful;
+ s[5] = 0x9b05688cul;
+ s[6] = 0x1f83d9abul;
+ s[7] = 0x5be0cd19ul;
+}
+
+/** Perform one SHA-256 transformation, processing a 64-byte chunk. */
+void Transform(uint32_t* s, const unsigned char* chunk)
+{
+ uint32_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7];
+ uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
+
+ Round(a, b, c, d, e, f, g, h, 0x428a2f98, w0 = ReadBE32(chunk + 0));
+ Round(h, a, b, c, d, e, f, g, 0x71374491, w1 = ReadBE32(chunk + 4));
+ Round(g, h, a, b, c, d, e, f, 0xb5c0fbcf, w2 = ReadBE32(chunk + 8));
+ Round(f, g, h, a, b, c, d, e, 0xe9b5dba5, w3 = ReadBE32(chunk + 12));
+ Round(e, f, g, h, a, b, c, d, 0x3956c25b, w4 = ReadBE32(chunk + 16));
+ Round(d, e, f, g, h, a, b, c, 0x59f111f1, w5 = ReadBE32(chunk + 20));
+ Round(c, d, e, f, g, h, a, b, 0x923f82a4, w6 = ReadBE32(chunk + 24));
+ Round(b, c, d, e, f, g, h, a, 0xab1c5ed5, w7 = ReadBE32(chunk + 28));
+ Round(a, b, c, d, e, f, g, h, 0xd807aa98, w8 = ReadBE32(chunk + 32));
+ Round(h, a, b, c, d, e, f, g, 0x12835b01, w9 = ReadBE32(chunk + 36));
+ Round(g, h, a, b, c, d, e, f, 0x243185be, w10 = ReadBE32(chunk + 40));
+ Round(f, g, h, a, b, c, d, e, 0x550c7dc3, w11 = ReadBE32(chunk + 44));
+ Round(e, f, g, h, a, b, c, d, 0x72be5d74, w12 = ReadBE32(chunk + 48));
+ Round(d, e, f, g, h, a, b, c, 0x80deb1fe, w13 = ReadBE32(chunk + 52));
+ Round(c, d, e, f, g, h, a, b, 0x9bdc06a7, w14 = ReadBE32(chunk + 56));
+ Round(b, c, d, e, f, g, h, a, 0xc19bf174, w15 = ReadBE32(chunk + 60));
+
+ Round(a, b, c, d, e, f, g, h, 0xe49b69c1, w0 += sigma1(w14) + w9 + sigma0(w1));
+ Round(h, a, b, c, d, e, f, g, 0xefbe4786, w1 += sigma1(w15) + w10 + sigma0(w2));
+ Round(g, h, a, b, c, d, e, f, 0x0fc19dc6, w2 += sigma1(w0) + w11 + sigma0(w3));
+ Round(f, g, h, a, b, c, d, e, 0x240ca1cc, w3 += sigma1(w1) + w12 + sigma0(w4));
+ Round(e, f, g, h, a, b, c, d, 0x2de92c6f, w4 += sigma1(w2) + w13 + sigma0(w5));
+ Round(d, e, f, g, h, a, b, c, 0x4a7484aa, w5 += sigma1(w3) + w14 + sigma0(w6));
+ Round(c, d, e, f, g, h, a, b, 0x5cb0a9dc, w6 += sigma1(w4) + w15 + sigma0(w7));
+ Round(b, c, d, e, f, g, h, a, 0x76f988da, w7 += sigma1(w5) + w0 + sigma0(w8));
+ Round(a, b, c, d, e, f, g, h, 0x983e5152, w8 += sigma1(w6) + w1 + sigma0(w9));
+ Round(h, a, b, c, d, e, f, g, 0xa831c66d, w9 += sigma1(w7) + w2 + sigma0(w10));
+ Round(g, h, a, b, c, d, e, f, 0xb00327c8, w10 += sigma1(w8) + w3 + sigma0(w11));
+ Round(f, g, h, a, b, c, d, e, 0xbf597fc7, w11 += sigma1(w9) + w4 + sigma0(w12));
+ Round(e, f, g, h, a, b, c, d, 0xc6e00bf3, w12 += sigma1(w10) + w5 + sigma0(w13));
+ Round(d, e, f, g, h, a, b, c, 0xd5a79147, w13 += sigma1(w11) + w6 + sigma0(w14));
+ Round(c, d, e, f, g, h, a, b, 0x06ca6351, w14 += sigma1(w12) + w7 + sigma0(w15));
+ Round(b, c, d, e, f, g, h, a, 0x14292967, w15 += sigma1(w13) + w8 + sigma0(w0));
+
+ Round(a, b, c, d, e, f, g, h, 0x27b70a85, w0 += sigma1(w14) + w9 + sigma0(w1));
+ Round(h, a, b, c, d, e, f, g, 0x2e1b2138, w1 += sigma1(w15) + w10 + sigma0(w2));
+ Round(g, h, a, b, c, d, e, f, 0x4d2c6dfc, w2 += sigma1(w0) + w11 + sigma0(w3));
+ Round(f, g, h, a, b, c, d, e, 0x53380d13, w3 += sigma1(w1) + w12 + sigma0(w4));
+ Round(e, f, g, h, a, b, c, d, 0x650a7354, w4 += sigma1(w2) + w13 + sigma0(w5));
+ Round(d, e, f, g, h, a, b, c, 0x766a0abb, w5 += sigma1(w3) + w14 + sigma0(w6));
+ Round(c, d, e, f, g, h, a, b, 0x81c2c92e, w6 += sigma1(w4) + w15 + sigma0(w7));
+ Round(b, c, d, e, f, g, h, a, 0x92722c85, w7 += sigma1(w5) + w0 + sigma0(w8));
+ Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1, w8 += sigma1(w6) + w1 + sigma0(w9));
+ Round(h, a, b, c, d, e, f, g, 0xa81a664b, w9 += sigma1(w7) + w2 + sigma0(w10));
+ Round(g, h, a, b, c, d, e, f, 0xc24b8b70, w10 += sigma1(w8) + w3 + sigma0(w11));
+ Round(f, g, h, a, b, c, d, e, 0xc76c51a3, w11 += sigma1(w9) + w4 + sigma0(w12));
+ Round(e, f, g, h, a, b, c, d, 0xd192e819, w12 += sigma1(w10) + w5 + sigma0(w13));
+ Round(d, e, f, g, h, a, b, c, 0xd6990624, w13 += sigma1(w11) + w6 + sigma0(w14));
+ Round(c, d, e, f, g, h, a, b, 0xf40e3585, w14 += sigma1(w12) + w7 + sigma0(w15));
+ Round(b, c, d, e, f, g, h, a, 0x106aa070, w15 += sigma1(w13) + w8 + sigma0(w0));
+
+ Round(a, b, c, d, e, f, g, h, 0x19a4c116, w0 += sigma1(w14) + w9 + sigma0(w1));
+ Round(h, a, b, c, d, e, f, g, 0x1e376c08, w1 += sigma1(w15) + w10 + sigma0(w2));
+ Round(g, h, a, b, c, d, e, f, 0x2748774c, w2 += sigma1(w0) + w11 + sigma0(w3));
+ Round(f, g, h, a, b, c, d, e, 0x34b0bcb5, w3 += sigma1(w1) + w12 + sigma0(w4));
+ Round(e, f, g, h, a, b, c, d, 0x391c0cb3, w4 += sigma1(w2) + w13 + sigma0(w5));
+ Round(d, e, f, g, h, a, b, c, 0x4ed8aa4a, w5 += sigma1(w3) + w14 + sigma0(w6));
+ Round(c, d, e, f, g, h, a, b, 0x5b9cca4f, w6 += sigma1(w4) + w15 + sigma0(w7));
+ Round(b, c, d, e, f, g, h, a, 0x682e6ff3, w7 += sigma1(w5) + w0 + sigma0(w8));
+ Round(a, b, c, d, e, f, g, h, 0x748f82ee, w8 += sigma1(w6) + w1 + sigma0(w9));
+ Round(h, a, b, c, d, e, f, g, 0x78a5636f, w9 += sigma1(w7) + w2 + sigma0(w10));
+ Round(g, h, a, b, c, d, e, f, 0x84c87814, w10 += sigma1(w8) + w3 + sigma0(w11));
+ Round(f, g, h, a, b, c, d, e, 0x8cc70208, w11 += sigma1(w9) + w4 + sigma0(w12));
+ Round(e, f, g, h, a, b, c, d, 0x90befffa, w12 += sigma1(w10) + w5 + sigma0(w13));
+ Round(d, e, f, g, h, a, b, c, 0xa4506ceb, w13 += sigma1(w11) + w6 + sigma0(w14));
+ Round(c, d, e, f, g, h, a, b, 0xbef9a3f7, w14 + sigma1(w12) + w7 + sigma0(w15));
+ Round(b, c, d, e, f, g, h, a, 0xc67178f2, w15 + sigma1(w13) + w8 + sigma0(w0));
+
+ s[0] += a;
+ s[1] += b;
+ s[2] += c;
+ s[3] += d;
+ s[4] += e;
+ s[5] += f;
+ s[6] += g;
+ s[7] += h;
+}
+
+} // namespace sha256
+} // namespace
+
+
+////// SHA-256
+
+CSHA256::CSHA256() : bytes(0)
+{
+ sha256::Initialize(s);
+}
+
+CSHA256& CSHA256::Write(const unsigned char* data, size_t len)
+{
+ const unsigned char* end = data + len;
+ size_t bufsize = bytes % 64;
+ if (bufsize && bufsize + len >= 64) {
+ // Fill the buffer, and process it.
+ memcpy(buf + bufsize, data, 64 - bufsize);
+ bytes += 64 - bufsize;
+ data += 64 - bufsize;
+ sha256::Transform(s, buf);
+ bufsize = 0;
+ }
+ while (end >= data + 64) {
+ // Process full chunks directly from the source.
+ sha256::Transform(s, data);
+ bytes += 64;
+ data += 64;
+ }
+ if (end > data) {
+ // Fill the buffer with what remains.
+ memcpy(buf + bufsize, data, end - data);
+ bytes += end - data;
+ }
+ return *this;
+}
+
+void CSHA256::Finalize(unsigned char hash[OUTPUT_SIZE])
+{
+ static const unsigned char pad[64] = {0x80};
+ unsigned char sizedesc[8];
+ WriteBE64(sizedesc, bytes << 3);
+ Write(pad, 1 + ((119 - (bytes % 64)) % 64));
+ Write(sizedesc, 8);
+ WriteBE32(hash, s[0]);
+ WriteBE32(hash + 4, s[1]);
+ WriteBE32(hash + 8, s[2]);
+ WriteBE32(hash + 12, s[3]);
+ WriteBE32(hash + 16, s[4]);
+ WriteBE32(hash + 20, s[5]);
+ WriteBE32(hash + 24, s[6]);
+ WriteBE32(hash + 28, s[7]);
+}
+
+CSHA256& CSHA256::Reset()
+{
+ bytes = 0;
+ sha256::Initialize(s);
+ return *this;
+}
diff --git a/src/crypto/sha256.h b/src/crypto/sha256.h
new file mode 100644
index 0000000000..85cf33739a
--- /dev/null
+++ b/src/crypto/sha256.h
@@ -0,0 +1,28 @@
+// Copyright (c) 2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_CRYPTO_SHA256_H
+#define BITCOIN_CRYPTO_SHA256_H
+
+#include <stdint.h>
+#include <stdlib.h>
+
+/** A hasher class for SHA-256. */
+class CSHA256
+{
+private:
+ uint32_t s[8];
+ unsigned char buf[64];
+ size_t bytes;
+
+public:
+ static const size_t OUTPUT_SIZE = 32;
+
+ CSHA256();
+ CSHA256& Write(const unsigned char* data, size_t len);
+ void Finalize(unsigned char hash[OUTPUT_SIZE]);
+ CSHA256& Reset();
+};
+
+#endif // BITCOIN_CRYPTO_SHA256_H
diff --git a/src/crypto/sha512.cpp b/src/crypto/sha512.cpp
new file mode 100644
index 0000000000..564127cc31
--- /dev/null
+++ b/src/crypto/sha512.cpp
@@ -0,0 +1,207 @@
+// Copyright (c) 2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "crypto/sha512.h"
+
+#include "crypto/common.h"
+
+#include <string.h>
+
+// Internal implementation code.
+namespace
+{
+/// Internal SHA-512 implementation.
+namespace sha512
+{
+uint64_t inline Ch(uint64_t x, uint64_t y, uint64_t z) { return z ^ (x & (y ^ z)); }
+uint64_t inline Maj(uint64_t x, uint64_t y, uint64_t z) { return (x & y) | (z & (x | y)); }
+uint64_t inline Sigma0(uint64_t x) { return (x >> 28 | x << 36) ^ (x >> 34 | x << 30) ^ (x >> 39 | x << 25); }
+uint64_t inline Sigma1(uint64_t x) { return (x >> 14 | x << 50) ^ (x >> 18 | x << 46) ^ (x >> 41 | x << 23); }
+uint64_t inline sigma0(uint64_t x) { return (x >> 1 | x << 63) ^ (x >> 8 | x << 56) ^ (x >> 7); }
+uint64_t inline sigma1(uint64_t x) { return (x >> 19 | x << 45) ^ (x >> 61 | x << 3) ^ (x >> 6); }
+
+/** One round of SHA-512. */
+void inline Round(uint64_t a, uint64_t b, uint64_t c, uint64_t& d, uint64_t e, uint64_t f, uint64_t g, uint64_t& h, uint64_t k, uint64_t w)
+{
+ uint64_t t1 = h + Sigma1(e) + Ch(e, f, g) + k + w;
+ uint64_t t2 = Sigma0(a) + Maj(a, b, c);
+ d += t1;
+ h = t1 + t2;
+}
+
+/** Initialize SHA-256 state. */
+void inline Initialize(uint64_t* s)
+{
+ s[0] = 0x6a09e667f3bcc908ull;
+ s[1] = 0xbb67ae8584caa73bull;
+ s[2] = 0x3c6ef372fe94f82bull;
+ s[3] = 0xa54ff53a5f1d36f1ull;
+ s[4] = 0x510e527fade682d1ull;
+ s[5] = 0x9b05688c2b3e6c1full;
+ s[6] = 0x1f83d9abfb41bd6bull;
+ s[7] = 0x5be0cd19137e2179ull;
+}
+
+/** Perform one SHA-512 transformation, processing a 128-byte chunk. */
+void Transform(uint64_t* s, const unsigned char* chunk)
+{
+ uint64_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7];
+ uint64_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
+
+ Round(a, b, c, d, e, f, g, h, 0x428a2f98d728ae22ull, w0 = ReadBE64(chunk + 0));
+ Round(h, a, b, c, d, e, f, g, 0x7137449123ef65cdull, w1 = ReadBE64(chunk + 8));
+ Round(g, h, a, b, c, d, e, f, 0xb5c0fbcfec4d3b2full, w2 = ReadBE64(chunk + 16));
+ Round(f, g, h, a, b, c, d, e, 0xe9b5dba58189dbbcull, w3 = ReadBE64(chunk + 24));
+ Round(e, f, g, h, a, b, c, d, 0x3956c25bf348b538ull, w4 = ReadBE64(chunk + 32));
+ Round(d, e, f, g, h, a, b, c, 0x59f111f1b605d019ull, w5 = ReadBE64(chunk + 40));
+ Round(c, d, e, f, g, h, a, b, 0x923f82a4af194f9bull, w6 = ReadBE64(chunk + 48));
+ Round(b, c, d, e, f, g, h, a, 0xab1c5ed5da6d8118ull, w7 = ReadBE64(chunk + 56));
+ Round(a, b, c, d, e, f, g, h, 0xd807aa98a3030242ull, w8 = ReadBE64(chunk + 64));
+ Round(h, a, b, c, d, e, f, g, 0x12835b0145706fbeull, w9 = ReadBE64(chunk + 72));
+ Round(g, h, a, b, c, d, e, f, 0x243185be4ee4b28cull, w10 = ReadBE64(chunk + 80));
+ Round(f, g, h, a, b, c, d, e, 0x550c7dc3d5ffb4e2ull, w11 = ReadBE64(chunk + 88));
+ Round(e, f, g, h, a, b, c, d, 0x72be5d74f27b896full, w12 = ReadBE64(chunk + 96));
+ Round(d, e, f, g, h, a, b, c, 0x80deb1fe3b1696b1ull, w13 = ReadBE64(chunk + 104));
+ Round(c, d, e, f, g, h, a, b, 0x9bdc06a725c71235ull, w14 = ReadBE64(chunk + 112));
+ Round(b, c, d, e, f, g, h, a, 0xc19bf174cf692694ull, w15 = ReadBE64(chunk + 120));
+
+ Round(a, b, c, d, e, f, g, h, 0xe49b69c19ef14ad2ull, w0 += sigma1(w14) + w9 + sigma0(w1));
+ Round(h, a, b, c, d, e, f, g, 0xefbe4786384f25e3ull, w1 += sigma1(w15) + w10 + sigma0(w2));
+ Round(g, h, a, b, c, d, e, f, 0x0fc19dc68b8cd5b5ull, w2 += sigma1(w0) + w11 + sigma0(w3));
+ Round(f, g, h, a, b, c, d, e, 0x240ca1cc77ac9c65ull, w3 += sigma1(w1) + w12 + sigma0(w4));
+ Round(e, f, g, h, a, b, c, d, 0x2de92c6f592b0275ull, w4 += sigma1(w2) + w13 + sigma0(w5));
+ Round(d, e, f, g, h, a, b, c, 0x4a7484aa6ea6e483ull, w5 += sigma1(w3) + w14 + sigma0(w6));
+ Round(c, d, e, f, g, h, a, b, 0x5cb0a9dcbd41fbd4ull, w6 += sigma1(w4) + w15 + sigma0(w7));
+ Round(b, c, d, e, f, g, h, a, 0x76f988da831153b5ull, w7 += sigma1(w5) + w0 + sigma0(w8));
+ Round(a, b, c, d, e, f, g, h, 0x983e5152ee66dfabull, w8 += sigma1(w6) + w1 + sigma0(w9));
+ Round(h, a, b, c, d, e, f, g, 0xa831c66d2db43210ull, w9 += sigma1(w7) + w2 + sigma0(w10));
+ Round(g, h, a, b, c, d, e, f, 0xb00327c898fb213full, w10 += sigma1(w8) + w3 + sigma0(w11));
+ Round(f, g, h, a, b, c, d, e, 0xbf597fc7beef0ee4ull, w11 += sigma1(w9) + w4 + sigma0(w12));
+ Round(e, f, g, h, a, b, c, d, 0xc6e00bf33da88fc2ull, w12 += sigma1(w10) + w5 + sigma0(w13));
+ Round(d, e, f, g, h, a, b, c, 0xd5a79147930aa725ull, w13 += sigma1(w11) + w6 + sigma0(w14));
+ Round(c, d, e, f, g, h, a, b, 0x06ca6351e003826full, w14 += sigma1(w12) + w7 + sigma0(w15));
+ Round(b, c, d, e, f, g, h, a, 0x142929670a0e6e70ull, w15 += sigma1(w13) + w8 + sigma0(w0));
+
+ Round(a, b, c, d, e, f, g, h, 0x27b70a8546d22ffcull, w0 += sigma1(w14) + w9 + sigma0(w1));
+ Round(h, a, b, c, d, e, f, g, 0x2e1b21385c26c926ull, w1 += sigma1(w15) + w10 + sigma0(w2));
+ Round(g, h, a, b, c, d, e, f, 0x4d2c6dfc5ac42aedull, w2 += sigma1(w0) + w11 + sigma0(w3));
+ Round(f, g, h, a, b, c, d, e, 0x53380d139d95b3dfull, w3 += sigma1(w1) + w12 + sigma0(w4));
+ Round(e, f, g, h, a, b, c, d, 0x650a73548baf63deull, w4 += sigma1(w2) + w13 + sigma0(w5));
+ Round(d, e, f, g, h, a, b, c, 0x766a0abb3c77b2a8ull, w5 += sigma1(w3) + w14 + sigma0(w6));
+ Round(c, d, e, f, g, h, a, b, 0x81c2c92e47edaee6ull, w6 += sigma1(w4) + w15 + sigma0(w7));
+ Round(b, c, d, e, f, g, h, a, 0x92722c851482353bull, w7 += sigma1(w5) + w0 + sigma0(w8));
+ Round(a, b, c, d, e, f, g, h, 0xa2bfe8a14cf10364ull, w8 += sigma1(w6) + w1 + sigma0(w9));
+ Round(h, a, b, c, d, e, f, g, 0xa81a664bbc423001ull, w9 += sigma1(w7) + w2 + sigma0(w10));
+ Round(g, h, a, b, c, d, e, f, 0xc24b8b70d0f89791ull, w10 += sigma1(w8) + w3 + sigma0(w11));
+ Round(f, g, h, a, b, c, d, e, 0xc76c51a30654be30ull, w11 += sigma1(w9) + w4 + sigma0(w12));
+ Round(e, f, g, h, a, b, c, d, 0xd192e819d6ef5218ull, w12 += sigma1(w10) + w5 + sigma0(w13));
+ Round(d, e, f, g, h, a, b, c, 0xd69906245565a910ull, w13 += sigma1(w11) + w6 + sigma0(w14));
+ Round(c, d, e, f, g, h, a, b, 0xf40e35855771202aull, w14 += sigma1(w12) + w7 + sigma0(w15));
+ Round(b, c, d, e, f, g, h, a, 0x106aa07032bbd1b8ull, w15 += sigma1(w13) + w8 + sigma0(w0));
+
+ Round(a, b, c, d, e, f, g, h, 0x19a4c116b8d2d0c8ull, w0 += sigma1(w14) + w9 + sigma0(w1));
+ Round(h, a, b, c, d, e, f, g, 0x1e376c085141ab53ull, w1 += sigma1(w15) + w10 + sigma0(w2));
+ Round(g, h, a, b, c, d, e, f, 0x2748774cdf8eeb99ull, w2 += sigma1(w0) + w11 + sigma0(w3));
+ Round(f, g, h, a, b, c, d, e, 0x34b0bcb5e19b48a8ull, w3 += sigma1(w1) + w12 + sigma0(w4));
+ Round(e, f, g, h, a, b, c, d, 0x391c0cb3c5c95a63ull, w4 += sigma1(w2) + w13 + sigma0(w5));
+ Round(d, e, f, g, h, a, b, c, 0x4ed8aa4ae3418acbull, w5 += sigma1(w3) + w14 + sigma0(w6));
+ Round(c, d, e, f, g, h, a, b, 0x5b9cca4f7763e373ull, w6 += sigma1(w4) + w15 + sigma0(w7));
+ Round(b, c, d, e, f, g, h, a, 0x682e6ff3d6b2b8a3ull, w7 += sigma1(w5) + w0 + sigma0(w8));
+ Round(a, b, c, d, e, f, g, h, 0x748f82ee5defb2fcull, w8 += sigma1(w6) + w1 + sigma0(w9));
+ Round(h, a, b, c, d, e, f, g, 0x78a5636f43172f60ull, w9 += sigma1(w7) + w2 + sigma0(w10));
+ Round(g, h, a, b, c, d, e, f, 0x84c87814a1f0ab72ull, w10 += sigma1(w8) + w3 + sigma0(w11));
+ Round(f, g, h, a, b, c, d, e, 0x8cc702081a6439ecull, w11 += sigma1(w9) + w4 + sigma0(w12));
+ Round(e, f, g, h, a, b, c, d, 0x90befffa23631e28ull, w12 += sigma1(w10) + w5 + sigma0(w13));
+ Round(d, e, f, g, h, a, b, c, 0xa4506cebde82bde9ull, w13 += sigma1(w11) + w6 + sigma0(w14));
+ Round(c, d, e, f, g, h, a, b, 0xbef9a3f7b2c67915ull, w14 += sigma1(w12) + w7 + sigma0(w15));
+ Round(b, c, d, e, f, g, h, a, 0xc67178f2e372532bull, w15 += sigma1(w13) + w8 + sigma0(w0));
+
+ Round(a, b, c, d, e, f, g, h, 0xca273eceea26619cull, w0 += sigma1(w14) + w9 + sigma0(w1));
+ Round(h, a, b, c, d, e, f, g, 0xd186b8c721c0c207ull, w1 += sigma1(w15) + w10 + sigma0(w2));
+ Round(g, h, a, b, c, d, e, f, 0xeada7dd6cde0eb1eull, w2 += sigma1(w0) + w11 + sigma0(w3));
+ Round(f, g, h, a, b, c, d, e, 0xf57d4f7fee6ed178ull, w3 += sigma1(w1) + w12 + sigma0(w4));
+ Round(e, f, g, h, a, b, c, d, 0x06f067aa72176fbaull, w4 += sigma1(w2) + w13 + sigma0(w5));
+ Round(d, e, f, g, h, a, b, c, 0x0a637dc5a2c898a6ull, w5 += sigma1(w3) + w14 + sigma0(w6));
+ Round(c, d, e, f, g, h, a, b, 0x113f9804bef90daeull, w6 += sigma1(w4) + w15 + sigma0(w7));
+ Round(b, c, d, e, f, g, h, a, 0x1b710b35131c471bull, w7 += sigma1(w5) + w0 + sigma0(w8));
+ Round(a, b, c, d, e, f, g, h, 0x28db77f523047d84ull, w8 += sigma1(w6) + w1 + sigma0(w9));
+ Round(h, a, b, c, d, e, f, g, 0x32caab7b40c72493ull, w9 += sigma1(w7) + w2 + sigma0(w10));
+ Round(g, h, a, b, c, d, e, f, 0x3c9ebe0a15c9bebcull, w10 += sigma1(w8) + w3 + sigma0(w11));
+ Round(f, g, h, a, b, c, d, e, 0x431d67c49c100d4cull, w11 += sigma1(w9) + w4 + sigma0(w12));
+ Round(e, f, g, h, a, b, c, d, 0x4cc5d4becb3e42b6ull, w12 += sigma1(w10) + w5 + sigma0(w13));
+ Round(d, e, f, g, h, a, b, c, 0x597f299cfc657e2aull, w13 += sigma1(w11) + w6 + sigma0(w14));
+ Round(c, d, e, f, g, h, a, b, 0x5fcb6fab3ad6faecull, w14 + sigma1(w12) + w7 + sigma0(w15));
+ Round(b, c, d, e, f, g, h, a, 0x6c44198c4a475817ull, w15 + sigma1(w13) + w8 + sigma0(w0));
+
+ s[0] += a;
+ s[1] += b;
+ s[2] += c;
+ s[3] += d;
+ s[4] += e;
+ s[5] += f;
+ s[6] += g;
+ s[7] += h;
+}
+
+} // namespace sha512
+
+} // namespace
+
+
+////// SHA-512
+
+CSHA512::CSHA512() : bytes(0)
+{
+ sha512::Initialize(s);
+}
+
+CSHA512& CSHA512::Write(const unsigned char* data, size_t len)
+{
+ const unsigned char* end = data + len;
+ size_t bufsize = bytes % 128;
+ if (bufsize && bufsize + len >= 128) {
+ // Fill the buffer, and process it.
+ memcpy(buf + bufsize, data, 128 - bufsize);
+ bytes += 128 - bufsize;
+ data += 128 - bufsize;
+ sha512::Transform(s, buf);
+ bufsize = 0;
+ }
+ while (end >= data + 128) {
+ // Process full chunks directly from the source.
+ sha512::Transform(s, data);
+ data += 128;
+ bytes += 128;
+ }
+ if (end > data) {
+ // Fill the buffer with what remains.
+ memcpy(buf + bufsize, data, end - data);
+ bytes += end - data;
+ }
+ return *this;
+}
+
+void CSHA512::Finalize(unsigned char hash[OUTPUT_SIZE])
+{
+ static const unsigned char pad[128] = {0x80};
+ unsigned char sizedesc[16] = {0x00};
+ WriteBE64(sizedesc + 8, bytes << 3);
+ Write(pad, 1 + ((239 - (bytes % 128)) % 128));
+ Write(sizedesc, 16);
+ WriteBE64(hash, s[0]);
+ WriteBE64(hash + 8, s[1]);
+ WriteBE64(hash + 16, s[2]);
+ WriteBE64(hash + 24, s[3]);
+ WriteBE64(hash + 32, s[4]);
+ WriteBE64(hash + 40, s[5]);
+ WriteBE64(hash + 48, s[6]);
+ WriteBE64(hash + 56, s[7]);
+}
+
+CSHA512& CSHA512::Reset()
+{
+ bytes = 0;
+ sha512::Initialize(s);
+ return *this;
+}
diff --git a/src/crypto/sha512.h b/src/crypto/sha512.h
new file mode 100644
index 0000000000..f1f17caf90
--- /dev/null
+++ b/src/crypto/sha512.h
@@ -0,0 +1,28 @@
+// Copyright (c) 2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_CRYPTO_SHA512_H
+#define BITCOIN_CRYPTO_SHA512_H
+
+#include <stdint.h>
+#include <stdlib.h>
+
+/** A hasher class for SHA-512. */
+class CSHA512
+{
+private:
+ uint64_t s[8];
+ unsigned char buf[128];
+ size_t bytes;
+
+public:
+ static const size_t OUTPUT_SIZE = 64;
+
+ CSHA512();
+ CSHA512& Write(const unsigned char* data, size_t len);
+ void Finalize(unsigned char hash[OUTPUT_SIZE]);
+ CSHA512& Reset();
+};
+
+#endif // BITCOIN_CRYPTO_SHA512_H
diff --git a/src/eccryptoverify.cpp b/src/eccryptoverify.cpp
new file mode 100644
index 0000000000..e894e1122c
--- /dev/null
+++ b/src/eccryptoverify.cpp
@@ -0,0 +1,68 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "eccryptoverify.h"
+
+namespace {
+
+int CompareBigEndian(const unsigned char *c1, size_t c1len, const unsigned char *c2, size_t c2len) {
+ while (c1len > c2len) {
+ if (*c1)
+ return 1;
+ c1++;
+ c1len--;
+ }
+ while (c2len > c1len) {
+ if (*c2)
+ return -1;
+ c2++;
+ c2len--;
+ }
+ while (c1len > 0) {
+ if (*c1 > *c2)
+ return 1;
+ if (*c2 > *c1)
+ return -1;
+ c1++;
+ c2++;
+ c1len--;
+ }
+ return 0;
+}
+
+/** Order of secp256k1's generator minus 1. */
+const unsigned char vchMaxModOrder[32] = {
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,
+ 0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,
+ 0xBF,0xD2,0x5E,0x8C,0xD0,0x36,0x41,0x40
+};
+
+/** Half of the order of secp256k1's generator minus 1. */
+const unsigned char vchMaxModHalfOrder[32] = {
+ 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0x5D,0x57,0x6E,0x73,0x57,0xA4,0x50,0x1D,
+ 0xDF,0xE9,0x2F,0x46,0x68,0x1B,0x20,0xA0
+};
+
+const unsigned char vchZero[1] = {0};
+} // anon namespace
+
+namespace eccrypto {
+
+bool Check(const unsigned char *vch) {
+ return vch &&
+ CompareBigEndian(vch, 32, vchZero, 0) > 0 &&
+ CompareBigEndian(vch, 32, vchMaxModOrder, 32) <= 0;
+}
+
+bool CheckSignatureElement(const unsigned char *vch, int len, bool half) {
+ return vch &&
+ CompareBigEndian(vch, len, vchZero, 0) > 0 &&
+ CompareBigEndian(vch, len, half ? vchMaxModHalfOrder : vchMaxModOrder, 32) <= 0;
+}
+
+} // namespace eccrypto
diff --git a/src/eccryptoverify.h b/src/eccryptoverify.h
new file mode 100644
index 0000000000..c67c1e44fc
--- /dev/null
+++ b/src/eccryptoverify.h
@@ -0,0 +1,21 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_ECCRYPTOVERIFY_H
+#define BITCOIN_ECCRYPTOVERIFY_H
+
+#include <vector>
+#include <cstdlib>
+
+class uint256;
+
+namespace eccrypto {
+
+bool Check(const unsigned char *vch);
+bool CheckSignatureElement(const unsigned char *vch, int len, bool half);
+
+} // eccrypto namespace
+
+#endif // BITCOIN_ECCRYPTOVERIFY_H
diff --git a/src/ecwrapper.cpp b/src/ecwrapper.cpp
new file mode 100644
index 0000000000..f94bc954fd
--- /dev/null
+++ b/src/ecwrapper.cpp
@@ -0,0 +1,218 @@
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "ecwrapper.h"
+
+#include "serialize.h"
+#include "uint256.h"
+
+#include <openssl/bn.h>
+#include <openssl/ecdsa.h>
+#include <openssl/obj_mac.h>
+
+namespace {
+
+class ecgroup_order
+{
+public:
+ static const EC_GROUP* get()
+ {
+ static const ecgroup_order wrapper;
+ return wrapper.pgroup;
+ }
+
+private:
+ ecgroup_order()
+ : pgroup(EC_GROUP_new_by_curve_name(NID_secp256k1))
+ {
+ }
+
+ ~ecgroup_order()
+ {
+ EC_GROUP_free(pgroup);
+ }
+
+ EC_GROUP* pgroup;
+};
+
+/**
+ * Perform ECDSA key recovery (see SEC1 4.1.6) for curves over (mod p)-fields
+ * recid selects which key is recovered
+ * if check is non-zero, 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;
+}
+
+} // anon namespace
+
+CECKey::CECKey() {
+ pkey = EC_KEY_new();
+ assert(pkey != NULL);
+ int result = EC_KEY_set_group(pkey, ecgroup_order::get());
+ assert(result);
+}
+
+CECKey::~CECKey() {
+ EC_KEY_free(pkey);
+}
+
+void CECKey::GetPubKey(std::vector<unsigned char> &pubkey, bool fCompressed) {
+ EC_KEY_set_conv_form(pkey, fCompressed ? POINT_CONVERSION_COMPRESSED : POINT_CONVERSION_UNCOMPRESSED);
+ int nSize = i2o_ECPublicKey(pkey, NULL);
+ assert(nSize);
+ assert(nSize <= 65);
+ pubkey.clear();
+ pubkey.resize(nSize);
+ unsigned char *pbegin(begin_ptr(pubkey));
+ int nSize2 = i2o_ECPublicKey(pkey, &pbegin);
+ assert(nSize == nSize2);
+}
+
+bool CECKey::SetPubKey(const unsigned char* pubkey, size_t size) {
+ return o2i_ECPublicKey(&pkey, &pubkey, size) != NULL;
+}
+
+bool CECKey::Verify(const uint256 &hash, const std::vector<unsigned char>& vchSig) {
+ if (vchSig.empty())
+ return false;
+
+ // New versions of OpenSSL will reject non-canonical DER signatures. de/re-serialize first.
+ unsigned char *norm_der = NULL;
+ ECDSA_SIG *norm_sig = ECDSA_SIG_new();
+ const unsigned char* sigptr = &vchSig[0];
+ assert(norm_sig);
+ if (d2i_ECDSA_SIG(&norm_sig, &sigptr, vchSig.size()) == NULL)
+ {
+ /* As of OpenSSL 1.0.0p d2i_ECDSA_SIG frees and nulls the pointer on
+ * error. But OpenSSL's own use of this function redundantly frees the
+ * result. As ECDSA_SIG_free(NULL) is a no-op, and in the absence of a
+ * clear contract for the function behaving the same way is more
+ * conservative.
+ */
+ ECDSA_SIG_free(norm_sig);
+ return false;
+ }
+ int derlen = i2d_ECDSA_SIG(norm_sig, &norm_der);
+ ECDSA_SIG_free(norm_sig);
+ if (derlen <= 0)
+ return false;
+
+ // -1 = error, 0 = bad sig, 1 = good
+ bool ret = ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), norm_der, derlen, pkey) == 1;
+ OPENSSL_free(norm_der);
+ return ret;
+}
+
+bool CECKey::Recover(const uint256 &hash, const unsigned char *p64, int rec)
+{
+ if (rec<0 || rec>=3)
+ return false;
+ ECDSA_SIG *sig = ECDSA_SIG_new();
+ BN_bin2bn(&p64[0], 32, sig->r);
+ BN_bin2bn(&p64[32], 32, sig->s);
+ bool ret = ECDSA_SIG_recover_key_GFp(pkey, sig, (unsigned char*)&hash, sizeof(hash), rec, 0) == 1;
+ ECDSA_SIG_free(sig);
+ return ret;
+}
+
+bool CECKey::TweakPublic(const unsigned char vchTweak[32]) {
+ bool ret = true;
+ BN_CTX *ctx = BN_CTX_new();
+ BN_CTX_start(ctx);
+ BIGNUM *bnTweak = BN_CTX_get(ctx);
+ BIGNUM *bnOrder = BN_CTX_get(ctx);
+ BIGNUM *bnOne = BN_CTX_get(ctx);
+ const EC_GROUP *group = EC_KEY_get0_group(pkey);
+ EC_GROUP_get_order(group, bnOrder, ctx); // what a grossly inefficient way to get the (constant) group order...
+ BN_bin2bn(vchTweak, 32, bnTweak);
+ if (BN_cmp(bnTweak, bnOrder) >= 0)
+ ret = false; // extremely unlikely
+ EC_POINT *point = EC_POINT_dup(EC_KEY_get0_public_key(pkey), group);
+ BN_one(bnOne);
+ EC_POINT_mul(group, point, bnTweak, point, bnOne, ctx);
+ if (EC_POINT_is_at_infinity(group, point))
+ ret = false; // ridiculously unlikely
+ EC_KEY_set_public_key(pkey, point);
+ EC_POINT_free(point);
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ return ret;
+}
+
+bool CECKey::SanityCheck()
+{
+ const EC_GROUP *pgroup = ecgroup_order::get();
+ if(pgroup == NULL)
+ return false;
+ // TODO Is there more EC functionality that could be missing?
+ return true;
+}
diff --git a/src/ecwrapper.h b/src/ecwrapper.h
new file mode 100644
index 0000000000..efb6cd18a7
--- /dev/null
+++ b/src/ecwrapper.h
@@ -0,0 +1,40 @@
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_ECWRAPPER_H
+#define BITCOIN_ECWRAPPER_H
+
+#include <cstddef>
+#include <vector>
+
+#include <openssl/ec.h>
+
+class uint256;
+
+/** RAII Wrapper around OpenSSL's EC_KEY */
+class CECKey {
+private:
+ EC_KEY *pkey;
+
+public:
+ CECKey();
+ ~CECKey();
+
+ void GetPubKey(std::vector<unsigned char>& pubkey, bool fCompressed);
+ bool SetPubKey(const unsigned char* pubkey, size_t size);
+ bool Verify(const uint256 &hash, const std::vector<unsigned char>& 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 Recover(const uint256 &hash, const unsigned char *p64, int rec);
+
+ bool TweakPublic(const unsigned char vchTweak[32]);
+ static bool SanityCheck();
+};
+
+#endif // BITCOIN_ECWRAPPER_H
diff --git a/src/hash.cpp b/src/hash.cpp
new file mode 100644
index 0000000000..9711293e38
--- /dev/null
+++ b/src/hash.cpp
@@ -0,0 +1,83 @@
+// Copyright (c) 2013-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "hash.h"
+#include "crypto/common.h"
+#include "crypto/hmac_sha512.h"
+#include "pubkey.h"
+
+
+inline uint32_t ROTL32(uint32_t x, int8_t r)
+{
+ return (x << r) | (x >> (32 - r));
+}
+
+unsigned int MurmurHash3(unsigned int nHashSeed, const std::vector<unsigned char>& vDataToHash)
+{
+ // The following is MurmurHash3 (x86_32), see http://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp
+ uint32_t h1 = nHashSeed;
+ if (vDataToHash.size() > 0)
+ {
+ const uint32_t c1 = 0xcc9e2d51;
+ const uint32_t c2 = 0x1b873593;
+
+ const int nblocks = vDataToHash.size() / 4;
+
+ //----------
+ // body
+ const uint8_t* blocks = &vDataToHash[0] + nblocks * 4;
+
+ for (int i = -nblocks; i; i++) {
+ uint32_t k1 = ReadLE32(blocks + i*4);
+
+ k1 *= c1;
+ k1 = ROTL32(k1, 15);
+ k1 *= c2;
+
+ h1 ^= k1;
+ h1 = ROTL32(h1, 13);
+ h1 = h1 * 5 + 0xe6546b64;
+ }
+
+ //----------
+ // tail
+ const uint8_t* tail = (const uint8_t*)(&vDataToHash[0] + nblocks * 4);
+
+ uint32_t k1 = 0;
+
+ switch (vDataToHash.size() & 3) {
+ case 3:
+ k1 ^= tail[2] << 16;
+ case 2:
+ k1 ^= tail[1] << 8;
+ case 1:
+ k1 ^= tail[0];
+ k1 *= c1;
+ k1 = ROTL32(k1, 15);
+ k1 *= c2;
+ h1 ^= k1;
+ };
+ }
+
+ //----------
+ // finalization
+ h1 ^= vDataToHash.size();
+ h1 ^= h1 >> 16;
+ h1 *= 0x85ebca6b;
+ h1 ^= h1 >> 13;
+ h1 *= 0xc2b2ae35;
+ h1 ^= h1 >> 16;
+
+ return h1;
+}
+
+void BIP32Hash(const ChainCode &chainCode, unsigned int nChild, unsigned char header, const unsigned char data[32], unsigned char output[64])
+{
+ unsigned char num[4];
+ num[0] = (nChild >> 24) & 0xFF;
+ num[1] = (nChild >> 16) & 0xFF;
+ num[2] = (nChild >> 8) & 0xFF;
+ num[3] = (nChild >> 0) & 0xFF;
+ CHMAC_SHA512(chainCode.begin(), chainCode.size()).Write(&header, 1).Write(data, 32).Write(num, 4).Finalize(output);
+}
diff --git a/src/hash.h b/src/hash.h
new file mode 100644
index 0000000000..0771555623
--- /dev/null
+++ b/src/hash.h
@@ -0,0 +1,166 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_HASH_H
+#define BITCOIN_HASH_H
+
+#include "crypto/ripemd160.h"
+#include "crypto/sha256.h"
+#include "serialize.h"
+#include "uint256.h"
+#include "version.h"
+
+#include <vector>
+
+typedef uint256 ChainCode;
+
+/** A hasher class for Bitcoin's 256-bit hash (double SHA-256). */
+class CHash256 {
+private:
+ CSHA256 sha;
+public:
+ static const size_t OUTPUT_SIZE = CSHA256::OUTPUT_SIZE;
+
+ void Finalize(unsigned char hash[OUTPUT_SIZE]) {
+ unsigned char buf[sha.OUTPUT_SIZE];
+ sha.Finalize(buf);
+ sha.Reset().Write(buf, sha.OUTPUT_SIZE).Finalize(hash);
+ }
+
+ CHash256& Write(const unsigned char *data, size_t len) {
+ sha.Write(data, len);
+ return *this;
+ }
+
+ CHash256& Reset() {
+ sha.Reset();
+ return *this;
+ }
+};
+
+/** A hasher class for Bitcoin's 160-bit hash (SHA-256 + RIPEMD-160). */
+class CHash160 {
+private:
+ CSHA256 sha;
+public:
+ static const size_t OUTPUT_SIZE = CRIPEMD160::OUTPUT_SIZE;
+
+ void Finalize(unsigned char hash[OUTPUT_SIZE]) {
+ unsigned char buf[sha.OUTPUT_SIZE];
+ sha.Finalize(buf);
+ CRIPEMD160().Write(buf, sha.OUTPUT_SIZE).Finalize(hash);
+ }
+
+ CHash160& Write(const unsigned char *data, size_t len) {
+ sha.Write(data, len);
+ return *this;
+ }
+
+ CHash160& Reset() {
+ sha.Reset();
+ return *this;
+ }
+};
+
+/** Compute the 256-bit hash of an object. */
+template<typename T1>
+inline uint256 Hash(const T1 pbegin, const T1 pend)
+{
+ static const unsigned char pblank[1] = {};
+ uint256 result;
+ CHash256().Write(pbegin == pend ? pblank : (const unsigned char*)&pbegin[0], (pend - pbegin) * sizeof(pbegin[0]))
+ .Finalize((unsigned char*)&result);
+ return result;
+}
+
+/** Compute the 256-bit hash of the concatenation of two objects. */
+template<typename T1, typename T2>
+inline uint256 Hash(const T1 p1begin, const T1 p1end,
+ const T2 p2begin, const T2 p2end) {
+ static const unsigned char pblank[1] = {};
+ uint256 result;
+ CHash256().Write(p1begin == p1end ? pblank : (const unsigned char*)&p1begin[0], (p1end - p1begin) * sizeof(p1begin[0]))
+ .Write(p2begin == p2end ? pblank : (const unsigned char*)&p2begin[0], (p2end - p2begin) * sizeof(p2begin[0]))
+ .Finalize((unsigned char*)&result);
+ return result;
+}
+
+/** Compute the 256-bit hash of the concatenation of three objects. */
+template<typename T1, typename T2, typename T3>
+inline uint256 Hash(const T1 p1begin, const T1 p1end,
+ const T2 p2begin, const T2 p2end,
+ const T3 p3begin, const T3 p3end) {
+ static const unsigned char pblank[1] = {};
+ uint256 result;
+ CHash256().Write(p1begin == p1end ? pblank : (const unsigned char*)&p1begin[0], (p1end - p1begin) * sizeof(p1begin[0]))
+ .Write(p2begin == p2end ? pblank : (const unsigned char*)&p2begin[0], (p2end - p2begin) * sizeof(p2begin[0]))
+ .Write(p3begin == p3end ? pblank : (const unsigned char*)&p3begin[0], (p3end - p3begin) * sizeof(p3begin[0]))
+ .Finalize((unsigned char*)&result);
+ return result;
+}
+
+/** Compute the 160-bit hash an object. */
+template<typename T1>
+inline uint160 Hash160(const T1 pbegin, const T1 pend)
+{
+ static unsigned char pblank[1] = {};
+ uint160 result;
+ CHash160().Write(pbegin == pend ? pblank : (const unsigned char*)&pbegin[0], (pend - pbegin) * sizeof(pbegin[0]))
+ .Finalize((unsigned char*)&result);
+ return result;
+}
+
+/** Compute the 160-bit hash of a vector. */
+inline uint160 Hash160(const std::vector<unsigned char>& vch)
+{
+ return Hash160(vch.begin(), vch.end());
+}
+
+/** A writer stream (for serialization) that computes a 256-bit hash. */
+class CHashWriter
+{
+private:
+ CHash256 ctx;
+
+public:
+ int nType;
+ int nVersion;
+
+ CHashWriter(int nTypeIn, int nVersionIn) : nType(nTypeIn), nVersion(nVersionIn) {}
+
+ CHashWriter& write(const char *pch, size_t size) {
+ ctx.Write((const unsigned char*)pch, size);
+ return (*this);
+ }
+
+ // invalidates the object
+ uint256 GetHash() {
+ uint256 result;
+ ctx.Finalize((unsigned char*)&result);
+ return result;
+ }
+
+ template<typename T>
+ CHashWriter& operator<<(const T& obj) {
+ // Serialize to this stream
+ ::Serialize(*this, obj, nType, nVersion);
+ return (*this);
+ }
+};
+
+/** Compute the 256-bit hash of an object's serialization. */
+template<typename T>
+uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=PROTOCOL_VERSION)
+{
+ CHashWriter ss(nType, nVersion);
+ ss << obj;
+ return ss.GetHash();
+}
+
+unsigned int MurmurHash3(unsigned int nHashSeed, const std::vector<unsigned char>& vDataToHash);
+
+void BIP32Hash(const ChainCode &chainCode, unsigned int nChild, unsigned char header, const unsigned char data[32], unsigned char output[64]);
+
+#endif // BITCOIN_HASH_H
diff --git a/src/init.cpp b/src/init.cpp
new file mode 100644
index 0000000000..a04e4e0a94
--- /dev/null
+++ b/src/init.cpp
@@ -0,0 +1,1453 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#if defined(HAVE_CONFIG_H)
+#include "config/bitcoin-config.h"
+#endif
+
+#include "init.h"
+
+#include "addrman.h"
+#include "amount.h"
+#include "checkpoints.h"
+#include "compat/sanity.h"
+#include "consensus/validation.h"
+#include "key.h"
+#include "main.h"
+#include "miner.h"
+#include "net.h"
+#include "rpcserver.h"
+#include "script/standard.h"
+#include "scheduler.h"
+#include "txdb.h"
+#include "ui_interface.h"
+#include "util.h"
+#include "utilmoneystr.h"
+#include "validationinterface.h"
+#ifdef ENABLE_WALLET
+#include "wallet/wallet.h"
+#include "wallet/walletdb.h"
+#endif
+
+#include <stdint.h>
+#include <stdio.h>
+
+#ifndef WIN32
+#include <signal.h>
+#endif
+
+#include <boost/algorithm/string/predicate.hpp>
+#include <boost/algorithm/string/replace.hpp>
+#include <boost/bind.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/function.hpp>
+#include <boost/interprocess/sync/file_lock.hpp>
+#include <boost/thread.hpp>
+#include <openssl/crypto.h>
+
+using namespace std;
+
+#ifdef ENABLE_WALLET
+CWallet* pwalletMain = NULL;
+#endif
+bool fFeeEstimatesInitialized = false;
+
+#ifdef WIN32
+// Win32 LevelDB doesn't use filedescriptors, and the ones used for
+// accessing block files don't count towards the fd_set size limit
+// anyway.
+#define MIN_CORE_FILEDESCRIPTORS 0
+#else
+#define MIN_CORE_FILEDESCRIPTORS 150
+#endif
+
+/** Used to pass flags to the Bind() function */
+enum BindFlags {
+ BF_NONE = 0,
+ BF_EXPLICIT = (1U << 0),
+ BF_REPORT_ERROR = (1U << 1),
+ BF_WHITELIST = (1U << 2),
+};
+
+static const char* FEE_ESTIMATES_FILENAME="fee_estimates.dat";
+CClientUIInterface uiInterface; // Declared but not defined in ui_interface.h
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// Shutdown
+//
+
+//
+// Thread management and startup/shutdown:
+//
+// The network-processing threads are all part of a thread group
+// created by AppInit() or the Qt main() function.
+//
+// A clean exit happens when StartShutdown() or the SIGTERM
+// signal handler sets fRequestShutdown, which triggers
+// the DetectShutdownThread(), which interrupts the main thread group.
+// DetectShutdownThread() then exits, which causes AppInit() to
+// continue (it .joins the shutdown thread).
+// Shutdown() is then
+// called to clean up database connections, and stop other
+// threads that should only be stopped after the main network-processing
+// threads have exited.
+//
+// Note that if running -daemon the parent process returns from AppInit2
+// before adding any threads to the threadGroup, so .join_all() returns
+// immediately and the parent exits from main().
+//
+// Shutdown for Qt is very similar, only it uses a QTimer to detect
+// fRequestShutdown getting set, and then does the normal Qt
+// shutdown thing.
+//
+
+volatile bool fRequestShutdown = false;
+
+void StartShutdown()
+{
+ fRequestShutdown = true;
+}
+bool ShutdownRequested()
+{
+ return fRequestShutdown;
+}
+
+class CCoinsViewErrorCatcher : public CCoinsViewBacked
+{
+public:
+ CCoinsViewErrorCatcher(CCoinsView* view) : CCoinsViewBacked(view) {}
+ bool GetCoins(const uint256 &txid, CCoins &coins) const {
+ try {
+ return CCoinsViewBacked::GetCoins(txid, coins);
+ } catch(const std::runtime_error& e) {
+ uiInterface.ThreadSafeMessageBox(_("Error reading from database, shutting down."), "", CClientUIInterface::MSG_ERROR);
+ LogPrintf("Error reading from database: %s\n", e.what());
+ // Starting the shutdown sequence and returning false to the caller would be
+ // interpreted as 'entry not found' (as opposed to unable to read data), and
+ // could lead to invalid interpretation. Just exit immediately, as we can't
+ // continue anyway, and all writes should be atomic.
+ abort();
+ }
+ }
+ // Writes do not need similar protection, as failure to write is handled by the caller.
+};
+
+static CCoinsViewDB *pcoinsdbview = NULL;
+static CCoinsViewErrorCatcher *pcoinscatcher = NULL;
+
+void Shutdown()
+{
+ LogPrintf("%s: In progress...\n", __func__);
+ static CCriticalSection cs_Shutdown;
+ TRY_LOCK(cs_Shutdown, lockShutdown);
+ if (!lockShutdown)
+ return;
+
+ /// Note: Shutdown() must be able to handle cases in which AppInit2() failed part of the way,
+ /// for example if the data directory was found to be locked.
+ /// Be sure that anything that writes files or flushes caches only does this if the respective
+ /// module was initialized.
+ RenameThread("bitcoin-shutoff");
+ mempool.AddTransactionsUpdated(1);
+ StopRPCThreads();
+#ifdef ENABLE_WALLET
+ if (pwalletMain)
+ pwalletMain->Flush(false);
+ GenerateBitcoins(false, NULL, 0);
+#endif
+ StopNode();
+ UnregisterNodeSignals(GetNodeSignals());
+
+ if (fFeeEstimatesInitialized)
+ {
+ boost::filesystem::path est_path = GetDataDir() / FEE_ESTIMATES_FILENAME;
+ CAutoFile est_fileout(fopen(est_path.string().c_str(), "wb"), SER_DISK, CLIENT_VERSION);
+ if (!est_fileout.IsNull())
+ mempool.WriteFeeEstimates(est_fileout);
+ else
+ LogPrintf("%s: Failed to write fee estimates to %s\n", __func__, est_path.string());
+ fFeeEstimatesInitialized = false;
+ }
+
+ {
+ LOCK(cs_main);
+ if (pcoinsTip != NULL) {
+ FlushStateToDisk();
+ }
+ delete pcoinsTip;
+ pcoinsTip = NULL;
+ delete pcoinscatcher;
+ pcoinscatcher = NULL;
+ delete pcoinsdbview;
+ pcoinsdbview = NULL;
+ delete pblocktree;
+ pblocktree = NULL;
+ }
+#ifdef ENABLE_WALLET
+ if (pwalletMain)
+ pwalletMain->Flush(true);
+#endif
+#ifndef WIN32
+ try {
+ boost::filesystem::remove(GetPidFile());
+ } catch (const boost::filesystem::filesystem_error& e) {
+ LogPrintf("%s: Unable to remove pidfile: %s\n", __func__, e.what());
+ }
+#endif
+ UnregisterAllValidationInterfaces();
+#ifdef ENABLE_WALLET
+ delete pwalletMain;
+ pwalletMain = NULL;
+#endif
+ ECC_Stop();
+ LogPrintf("%s: done\n", __func__);
+}
+
+/**
+ * Signal handlers are very limited in what they are allowed to do, so:
+ */
+void HandleSIGTERM(int)
+{
+ fRequestShutdown = true;
+}
+
+void HandleSIGHUP(int)
+{
+ fReopenDebugLog = true;
+}
+
+bool static InitError(const std::string &str)
+{
+ uiInterface.ThreadSafeMessageBox(str, "", CClientUIInterface::MSG_ERROR);
+ return false;
+}
+
+bool static InitWarning(const std::string &str)
+{
+ uiInterface.ThreadSafeMessageBox(str, "", CClientUIInterface::MSG_WARNING);
+ return true;
+}
+
+bool static Bind(const CService &addr, unsigned int flags) {
+ if (!(flags & BF_EXPLICIT) && IsLimited(addr))
+ return false;
+ std::string strError;
+ if (!BindListenPort(addr, strError, (flags & BF_WHITELIST) != 0)) {
+ if (flags & BF_REPORT_ERROR)
+ return InitError(strError);
+ return false;
+ }
+ return true;
+}
+
+void OnRPCStopped()
+{
+ cvBlockChange.notify_all();
+ LogPrint("rpc", "RPC stopped.\n");
+}
+
+void OnRPCPreCommand(const CRPCCommand& cmd)
+{
+ // Observe safe mode
+ string strWarning = GetWarnings("rpc");
+ if (strWarning != "" && !GetBoolArg("-disablesafemode", false) &&
+ !cmd.okSafeMode)
+ throw JSONRPCError(RPC_FORBIDDEN_BY_SAFE_MODE, string("Safe mode: ") + strWarning);
+}
+
+std::string HelpMessage(HelpMessageMode mode)
+{
+ const bool showDebug = GetBoolArg("-help-debug", false);
+
+ // When adding new options to the categories, please keep and ensure alphabetical ordering.
+ // Do not translate _(...) -help-debug options, Many technical terms, and only a very small audience, so is unnecessary stress to translators
+
+ string strUsage = HelpMessageGroup(_("Options:"));
+ strUsage += HelpMessageOpt("-?", _("This help message"));
+ strUsage += HelpMessageOpt("-alerts", strprintf(_("Receive and display P2P network alerts (default: %u)"), DEFAULT_ALERTS));
+ strUsage += HelpMessageOpt("-alertnotify=<cmd>", _("Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)"));
+ strUsage += HelpMessageOpt("-blocknotify=<cmd>", _("Execute command when the best block changes (%s in cmd is replaced by block hash)"));
+ strUsage += HelpMessageOpt("-checkblocks=<n>", strprintf(_("How many blocks to check at startup (default: %u, 0 = all)"), 288));
+ strUsage += HelpMessageOpt("-checklevel=<n>", strprintf(_("How thorough the block verification of -checkblocks is (0-4, default: %u)"), 3));
+ strUsage += HelpMessageOpt("-conf=<file>", strprintf(_("Specify configuration file (default: %s)"), "bitcoin.conf"));
+ if (mode == HMM_BITCOIND)
+ {
+#if !defined(WIN32)
+ strUsage += HelpMessageOpt("-daemon", _("Run in the background as a daemon and accept commands"));
+#endif
+ }
+ strUsage += HelpMessageOpt("-datadir=<dir>", _("Specify data directory"));
+ strUsage += HelpMessageOpt("-dbcache=<n>", strprintf(_("Set database cache size in megabytes (%d to %d, default: %d)"), nMinDbCache, nMaxDbCache, nDefaultDbCache));
+ strUsage += HelpMessageOpt("-loadblock=<file>", _("Imports blocks from external blk000??.dat file") + " " + _("on startup"));
+ strUsage += HelpMessageOpt("-maxorphantx=<n>", strprintf(_("Keep at most <n> unconnectable transactions in memory (default: %u)"), DEFAULT_MAX_ORPHAN_TRANSACTIONS));
+ strUsage += HelpMessageOpt("-par=<n>", strprintf(_("Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)"),
+ -(int)boost::thread::hardware_concurrency(), MAX_SCRIPTCHECK_THREADS, DEFAULT_SCRIPTCHECK_THREADS));
+#ifndef WIN32
+ strUsage += HelpMessageOpt("-pid=<file>", strprintf(_("Specify pid file (default: %s)"), "bitcoind.pid"));
+#endif
+ strUsage += HelpMessageOpt("-prune=<n>", strprintf(_("Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. "
+ "Warning: Reverting this setting requires re-downloading the entire blockchain. "
+ "(default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)"), MIN_DISK_SPACE_FOR_BLOCK_FILES / 1024 / 1024));
+ strUsage += HelpMessageOpt("-reindex", _("Rebuild block chain index from current blk000??.dat files on startup"));
+#if !defined(WIN32)
+ strUsage += HelpMessageOpt("-sysperms", _("Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)"));
+#endif
+ strUsage += HelpMessageOpt("-txindex", strprintf(_("Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)"), 0));
+
+ strUsage += HelpMessageGroup(_("Connection options:"));
+ strUsage += HelpMessageOpt("-addnode=<ip>", _("Add a node to connect to and attempt to keep the connection open"));
+ strUsage += HelpMessageOpt("-banscore=<n>", strprintf(_("Threshold for disconnecting misbehaving peers (default: %u)"), 100));
+ strUsage += HelpMessageOpt("-bantime=<n>", strprintf(_("Number of seconds to keep misbehaving peers from reconnecting (default: %u)"), 86400));
+ strUsage += HelpMessageOpt("-bind=<addr>", _("Bind to given address and always listen on it. Use [host]:port notation for IPv6"));
+ strUsage += HelpMessageOpt("-connect=<ip>", _("Connect only to the specified node(s)"));
+ strUsage += HelpMessageOpt("-discover", _("Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)"));
+ strUsage += HelpMessageOpt("-dns", _("Allow DNS lookups for -addnode, -seednode and -connect") + " " + _("(default: 1)"));
+ strUsage += HelpMessageOpt("-dnsseed", _("Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)"));
+ strUsage += HelpMessageOpt("-externalip=<ip>", _("Specify your own public address"));
+ strUsage += HelpMessageOpt("-forcednsseed", strprintf(_("Always query for peer addresses via DNS lookup (default: %u)"), 0));
+ strUsage += HelpMessageOpt("-listen", _("Accept connections from outside (default: 1 if no -proxy or -connect)"));
+ strUsage += HelpMessageOpt("-maxconnections=<n>", strprintf(_("Maintain at most <n> connections to peers (default: %u)"), 125));
+ strUsage += HelpMessageOpt("-maxreceivebuffer=<n>", strprintf(_("Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)"), 5000));
+ strUsage += HelpMessageOpt("-maxsendbuffer=<n>", strprintf(_("Maximum per-connection send buffer, <n>*1000 bytes (default: %u)"), 1000));
+ strUsage += HelpMessageOpt("-onion=<ip:port>", strprintf(_("Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)"), "-proxy"));
+ strUsage += HelpMessageOpt("-onlynet=<net>", _("Only connect to nodes in network <net> (ipv4, ipv6 or onion)"));
+ strUsage += HelpMessageOpt("-permitbaremultisig", strprintf(_("Relay non-P2SH multisig (default: %u)"), 1));
+ strUsage += HelpMessageOpt("-port=<port>", strprintf(_("Listen for connections on <port> (default: %u or testnet: %u)"), 8333, 18333));
+ strUsage += HelpMessageOpt("-proxy=<ip:port>", _("Connect through SOCKS5 proxy"));
+ strUsage += HelpMessageOpt("-proxyrandomize", strprintf(_("Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)"), 1));
+ strUsage += HelpMessageOpt("-seednode=<ip>", _("Connect to a node to retrieve peer addresses, and disconnect"));
+ strUsage += HelpMessageOpt("-timeout=<n>", strprintf(_("Specify connection timeout in milliseconds (minimum: 1, default: %d)"), DEFAULT_CONNECT_TIMEOUT));
+#ifdef USE_UPNP
+#if USE_UPNP
+ strUsage += HelpMessageOpt("-upnp", _("Use UPnP to map the listening port (default: 1 when listening)"));
+#else
+ strUsage += HelpMessageOpt("-upnp", strprintf(_("Use UPnP to map the listening port (default: %u)"), 0));
+#endif
+#endif
+ strUsage += HelpMessageOpt("-whitebind=<addr>", _("Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6"));
+ strUsage += HelpMessageOpt("-whitelist=<netmask>", _("Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.") +
+ " " + _("Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway"));
+
+
+#ifdef ENABLE_WALLET
+ strUsage += HelpMessageGroup(_("Wallet options:"));
+ strUsage += HelpMessageOpt("-disablewallet", _("Do not load the wallet and disable wallet RPC calls"));
+ strUsage += HelpMessageOpt("-keypool=<n>", strprintf(_("Set key pool size to <n> (default: %u)"), 100));
+ if (showDebug)
+ strUsage += HelpMessageOpt("-mintxfee=<amt>", strprintf("Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)",
+ FormatMoney(CWallet::minTxFee.GetFeePerK())));
+ strUsage += HelpMessageOpt("-paytxfee=<amt>", strprintf(_("Fee (in BTC/kB) to add to transactions you send (default: %s)"), FormatMoney(payTxFee.GetFeePerK())));
+ strUsage += HelpMessageOpt("-rescan", _("Rescan the block chain for missing wallet transactions") + " " + _("on startup"));
+ strUsage += HelpMessageOpt("-salvagewallet", _("Attempt to recover private keys from a corrupt wallet.dat") + " " + _("on startup"));
+ strUsage += HelpMessageOpt("-sendfreetransactions", strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), 0));
+ strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), 1));
+ strUsage += HelpMessageOpt("-txconfirmtarget=<n>", strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), DEFAULT_TX_CONFIRM_TARGET));
+ strUsage += HelpMessageOpt("-maxtxfee=<amt>", strprintf(_("Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)"),
+ FormatMoney(maxTxFee)));
+ strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format") + " " + _("on startup"));
+ strUsage += HelpMessageOpt("-wallet=<file>", _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), "wallet.dat"));
+ strUsage += HelpMessageOpt("-walletbroadcast", _("Make the wallet broadcast transactions") + " " + strprintf(_("(default: %u)"), true));
+ strUsage += HelpMessageOpt("-walletnotify=<cmd>", _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)"));
+ strUsage += HelpMessageOpt("-zapwallettxes=<mode>", _("Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup") +
+ " " + _("(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)"));
+
+#endif
+
+ strUsage += HelpMessageGroup(_("Debugging/Testing options:"));
+ if (showDebug)
+ {
+ strUsage += HelpMessageOpt("-checkpoints", strprintf("Only accept block chain matching built-in checkpoints (default: %u)", 1));
+ strUsage += HelpMessageOpt("-dblogsize=<n>", strprintf("Flush database activity from memory pool to disk log every <n> megabytes (default: %u)", 100));
+ strUsage += HelpMessageOpt("-disablesafemode", strprintf("Disable safemode, override a real safe mode event (default: %u)", 0));
+ strUsage += HelpMessageOpt("-testsafemode", strprintf("Force safe mode (default: %u)", 0));
+ strUsage += HelpMessageOpt("-dropmessagestest=<n>", "Randomly drop 1 of every <n> network messages");
+ strUsage += HelpMessageOpt("-fuzzmessagestest=<n>", "Randomly fuzz 1 of every <n> network messages");
+ strUsage += HelpMessageOpt("-flushwallet", strprintf("Run a thread to flush wallet periodically (default: %u)", 1));
+ strUsage += HelpMessageOpt("-stopafterblockimport", strprintf("Stop running after importing blocks from disk (default: %u)", 0));
+ }
+ string debugCategories = "addrman, alert, bench, coindb, db, lock, rand, rpc, selectcoins, mempool, net, proxy, prune"; // Don't translate these and qt below
+ if (mode == HMM_BITCOIN_QT)
+ debugCategories += ", qt";
+ strUsage += HelpMessageOpt("-debug=<category>", strprintf(_("Output debugging information (default: %u, supplying <category> is optional)"), 0) + ". " +
+ _("If <category> is not supplied, output all debugging information.") + _("<category> can be:") + " " + debugCategories + ".");
+#ifdef ENABLE_WALLET
+ strUsage += HelpMessageOpt("-gen", strprintf(_("Generate coins (default: %u)"), 0));
+ strUsage += HelpMessageOpt("-genproclimit=<n>", strprintf(_("Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)"), 1));
+#endif
+ strUsage += HelpMessageOpt("-help-debug", _("Show all debugging options (usage: --help -help-debug)"));
+ strUsage += HelpMessageOpt("-logips", strprintf(_("Include IP addresses in debug output (default: %u)"), 0));
+ strUsage += HelpMessageOpt("-logtimestamps", strprintf(_("Prepend debug output with timestamp (default: %u)"), 1));
+ if (showDebug)
+ {
+ strUsage += HelpMessageOpt("-limitfreerelay=<n>", strprintf("Continuously rate-limit free transactions to <n>*1000 bytes per minute (default: %u)", 15));
+ strUsage += HelpMessageOpt("-relaypriority", strprintf("Require high priority for relaying free or low-fee transactions (default: %u)", 1));
+ strUsage += HelpMessageOpt("-maxsigcachesize=<n>", strprintf("Limit size of signature cache to <n> entries (default: %u)", 50000));
+ }
+ strUsage += HelpMessageOpt("-minrelaytxfee=<amt>", strprintf(_("Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)"), FormatMoney(::minRelayTxFee.GetFeePerK())));
+ strUsage += HelpMessageOpt("-printtoconsole", _("Send trace/debug info to console instead of debug.log file"));
+ if (showDebug)
+ {
+ strUsage += HelpMessageOpt("-printpriority", strprintf("Log transaction priority and fee per kB when mining blocks (default: %u)", 0));
+ strUsage += HelpMessageOpt("-privdb", strprintf("Sets the DB_PRIVATE flag in the wallet db environment (default: %u)", 1));
+ strUsage += HelpMessageOpt("-regtest", "Enter regression test mode, which uses a special chain in which blocks can be solved instantly. "
+ "This is intended for regression testing tools and app development.");
+ }
+ strUsage += HelpMessageOpt("-shrinkdebugfile", _("Shrink debug.log file on client startup (default: 1 when no -debug)"));
+ strUsage += HelpMessageOpt("-testnet", _("Use the test network"));
+
+ strUsage += HelpMessageGroup(_("Node relay options:"));
+ strUsage += HelpMessageOpt("-datacarrier", strprintf(_("Relay and mine data carrier transactions (default: %u)"), 1));
+ strUsage += HelpMessageOpt("-datacarriersize", strprintf(_("Maximum size of data in data carrier transactions we relay and mine (default: %u)"), MAX_OP_RETURN_RELAY));
+
+ strUsage += HelpMessageGroup(_("Block creation options:"));
+ strUsage += HelpMessageOpt("-blockminsize=<n>", strprintf(_("Set minimum block size in bytes (default: %u)"), 0));
+ strUsage += HelpMessageOpt("-blockmaxsize=<n>", strprintf(_("Set maximum block size in bytes (default: %d)"), DEFAULT_BLOCK_MAX_SIZE));
+ strUsage += HelpMessageOpt("-blockprioritysize=<n>", strprintf(_("Set maximum size of high-priority/low-fee transactions in bytes (default: %d)"), DEFAULT_BLOCK_PRIORITY_SIZE));
+
+ strUsage += HelpMessageGroup(_("RPC server options:"));
+ strUsage += HelpMessageOpt("-server", _("Accept command line and JSON-RPC commands"));
+ strUsage += HelpMessageOpt("-rest", strprintf(_("Accept public REST requests (default: %u)"), 0));
+ strUsage += HelpMessageOpt("-rpcbind=<addr>", _("Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)"));
+ strUsage += HelpMessageOpt("-rpcuser=<user>", _("Username for JSON-RPC connections"));
+ strUsage += HelpMessageOpt("-rpcpassword=<pw>", _("Password for JSON-RPC connections"));
+ strUsage += HelpMessageOpt("-rpcport=<port>", strprintf(_("Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)"), 8332, 18332));
+ strUsage += HelpMessageOpt("-rpcallowip=<ip>", _("Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times"));
+ strUsage += HelpMessageOpt("-rpcthreads=<n>", strprintf(_("Set the number of threads to service RPC calls (default: %d)"), 4));
+ strUsage += HelpMessageOpt("-rpckeepalive", strprintf(_("RPC support for HTTP persistent connections (default: %d)"), 1));
+
+ strUsage += HelpMessageGroup(_("RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)"));
+ strUsage += HelpMessageOpt("-rpcssl", _("Use OpenSSL (https) for JSON-RPC connections"));
+ strUsage += HelpMessageOpt("-rpcsslcertificatechainfile=<file.cert>", strprintf(_("Server certificate file (default: %s)"), "server.cert"));
+ strUsage += HelpMessageOpt("-rpcsslprivatekeyfile=<file.pem>", strprintf(_("Server private key (default: %s)"), "server.pem"));
+ strUsage += HelpMessageOpt("-rpcsslciphers=<ciphers>", strprintf(_("Acceptable ciphers (default: %s)"), "TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH"));
+
+ if (mode == HMM_BITCOIN_QT)
+ {
+ strUsage += HelpMessageGroup(_("UI Options:"));
+ if (showDebug) {
+ strUsage += HelpMessageOpt("-allowselfsignedrootcertificates", "Allow self signed root certificates (default: 0)");
+ }
+ strUsage += HelpMessageOpt("-choosedatadir", _("Choose data directory on startup (default: 0)"));
+ strUsage += HelpMessageOpt("-lang=<lang>", _("Set language, for example \"de_DE\" (default: system locale)"));
+ strUsage += HelpMessageOpt("-min", _("Start minimized"));
+ strUsage += HelpMessageOpt("-rootcertificates=<file>", _("Set SSL root certificates for payment request (default: -system-)"));
+ strUsage += HelpMessageOpt("-splash", _("Show splash screen on startup (default: 1)"));
+ }
+
+ return strUsage;
+}
+
+std::string LicenseInfo()
+{
+ return FormatParagraph(strprintf(_("Copyright (C) 2009-%i The Bitcoin Core Developers"), COPYRIGHT_YEAR)) + "\n" +
+ "\n" +
+ FormatParagraph(_("This is experimental software.")) + "\n" +
+ "\n" +
+ FormatParagraph(_("Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.")) + "\n" +
+ "\n" +
+ FormatParagraph(_("This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.")) +
+ "\n";
+}
+
+static void BlockNotifyCallback(const uint256& hashNewTip)
+{
+ std::string strCmd = GetArg("-blocknotify", "");
+
+ boost::replace_all(strCmd, "%s", hashNewTip.GetHex());
+ boost::thread t(runCommand, strCmd); // thread runs free
+}
+
+struct CImportingNow
+{
+ CImportingNow() {
+ assert(fImporting == false);
+ fImporting = true;
+ }
+
+ ~CImportingNow() {
+ assert(fImporting == true);
+ fImporting = false;
+ }
+};
+
+
+// If we're using -prune with -reindex, then delete block files that will be ignored by the
+// reindex. Since reindexing works by starting at block file 0 and looping until a blockfile
+// is missing, do the same here to delete any later block files after a gap. Also delete all
+// rev files since they'll be rewritten by the reindex anyway. This ensures that vinfoBlockFile
+// is in sync with what's actually on disk by the time we start downloading, so that pruning
+// works correctly.
+void CleanupBlockRevFiles()
+{
+ using namespace boost::filesystem;
+ map<string, path> mapBlockFiles;
+
+ // Glob all blk?????.dat and rev?????.dat files from the blocks directory.
+ // Remove the rev files immediately and insert the blk file paths into an
+ // ordered map keyed by block file index.
+ LogPrintf("Removing unusable blk?????.dat and rev?????.dat files for -reindex with -prune\n");
+ path blocksdir = GetDataDir() / "blocks";
+ for (directory_iterator it(blocksdir); it != directory_iterator(); it++) {
+ if (is_regular_file(*it) &&
+ it->path().filename().string().length() == 12 &&
+ it->path().filename().string().substr(8,4) == ".dat")
+ {
+ if (it->path().filename().string().substr(0,3) == "blk")
+ mapBlockFiles[it->path().filename().string().substr(3,5)] = it->path();
+ else if (it->path().filename().string().substr(0,3) == "rev")
+ remove(it->path());
+ }
+ }
+
+ // Remove all block files that aren't part of a contiguous set starting at
+ // zero by walking the ordered map (keys are block file indices) by
+ // keeping a separate counter. Once we hit a gap (or if 0 doesn't exist)
+ // start removing block files.
+ int nContigCounter = 0;
+ BOOST_FOREACH(const PAIRTYPE(string, path)& item, mapBlockFiles) {
+ if (atoi(item.first) == nContigCounter) {
+ nContigCounter++;
+ continue;
+ }
+ remove(item.second);
+ }
+}
+
+void ThreadImport(std::vector<boost::filesystem::path> vImportFiles)
+{
+ RenameThread("bitcoin-loadblk");
+ // -reindex
+ if (fReindex) {
+ CImportingNow imp;
+ int nFile = 0;
+ while (true) {
+ CDiskBlockPos pos(nFile, 0);
+ if (!boost::filesystem::exists(GetBlockPosFilename(pos, "blk")))
+ break; // No block files left to reindex
+ FILE *file = OpenBlockFile(pos, true);
+ if (!file)
+ break; // This error is logged in OpenBlockFile
+ LogPrintf("Reindexing block file blk%05u.dat...\n", (unsigned int)nFile);
+ LoadExternalBlockFile(file, &pos);
+ nFile++;
+ }
+ pblocktree->WriteReindexing(false);
+ fReindex = false;
+ LogPrintf("Reindexing finished\n");
+ // To avoid ending up in a situation without genesis block, re-try initializing (no-op if reindexing worked):
+ InitBlockIndex();
+ }
+
+ // hardcoded $DATADIR/bootstrap.dat
+ boost::filesystem::path pathBootstrap = GetDataDir() / "bootstrap.dat";
+ if (boost::filesystem::exists(pathBootstrap)) {
+ FILE *file = fopen(pathBootstrap.string().c_str(), "rb");
+ if (file) {
+ CImportingNow imp;
+ boost::filesystem::path pathBootstrapOld = GetDataDir() / "bootstrap.dat.old";
+ LogPrintf("Importing bootstrap.dat...\n");
+ LoadExternalBlockFile(file);
+ RenameOver(pathBootstrap, pathBootstrapOld);
+ } else {
+ LogPrintf("Warning: Could not open bootstrap file %s\n", pathBootstrap.string());
+ }
+ }
+
+ // -loadblock=
+ BOOST_FOREACH(boost::filesystem::path &path, vImportFiles) {
+ FILE *file = fopen(path.string().c_str(), "rb");
+ if (file) {
+ CImportingNow imp;
+ LogPrintf("Importing blocks file %s...\n", path.string());
+ LoadExternalBlockFile(file);
+ } else {
+ LogPrintf("Warning: Could not open blocks file %s\n", path.string());
+ }
+ }
+
+ if (GetBoolArg("-stopafterblockimport", false)) {
+ LogPrintf("Stopping after block import\n");
+ StartShutdown();
+ }
+}
+
+/** Sanity checks
+ * Ensure that Bitcoin is running in a usable environment with all
+ * necessary library support.
+ */
+bool InitSanityCheck(void)
+{
+ if(!ECC_InitSanityCheck()) {
+ InitError("OpenSSL appears to lack support for elliptic curve cryptography. For more "
+ "information, visit https://en.bitcoin.it/wiki/OpenSSL_and_EC_Libraries");
+ return false;
+ }
+ if (!glibc_sanity_test() || !glibcxx_sanity_test())
+ return false;
+
+ return true;
+}
+
+/** Initialize bitcoin.
+ * @pre Parameters should be parsed and config file should be read.
+ */
+bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
+{
+ // ********************************************************* 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
+#ifdef WIN32
+ // Enable Data Execution Prevention (DEP)
+ // Minimum supported OS versions: WinXP SP3, WinVista >= SP1, Win Server 2008
+ // A failure is non-critical and needs no further attention!
+#ifndef PROCESS_DEP_ENABLE
+ // We define this here, because GCCs winbase.h limits this to _WIN32_WINNT >= 0x0601 (Windows 7),
+ // which is not correct. Can be removed, when GCCs winbase.h is fixed!
+#define PROCESS_DEP_ENABLE 0x00000001
+#endif
+ typedef BOOL (WINAPI *PSETPROCDEPPOL)(DWORD);
+ PSETPROCDEPPOL setProcDEPPol = (PSETPROCDEPPOL)GetProcAddress(GetModuleHandleA("Kernel32.dll"), "SetProcessDEPPolicy");
+ if (setProcDEPPol != NULL) setProcDEPPol(PROCESS_DEP_ENABLE);
+
+ // Initialize Windows Sockets
+ WSADATA wsadata;
+ int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
+ if (ret != NO_ERROR || LOBYTE(wsadata.wVersion ) != 2 || HIBYTE(wsadata.wVersion) != 2)
+ {
+ return InitError(strprintf("Error: Winsock library failed to start (WSAStartup returned error %d)", ret));
+ }
+#endif
+#ifndef WIN32
+
+ if (GetBoolArg("-sysperms", false)) {
+#ifdef ENABLE_WALLET
+ if (!GetBoolArg("-disablewallet", false))
+ return InitError("Error: -sysperms is not allowed in combination with enabled wallet functionality");
+#endif
+ } else {
+ umask(077);
+ }
+
+ // 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);
+
+#if defined (__SVR4) && defined (__sun)
+ // ignore SIGPIPE on Solaris
+ signal(SIGPIPE, SIG_IGN);
+#endif
+#endif
+
+ // ********************************************************* Step 2: parameter interactions
+ const CChainParams& chainparams = Params();
+
+ // Set this early so that parameter interactions go to console
+ fPrintToConsole = GetBoolArg("-printtoconsole", false);
+ fLogTimestamps = GetBoolArg("-logtimestamps", true);
+ fLogIPs = GetBoolArg("-logips", false);
+
+ // when specifying an explicit binding address, you want to listen on it
+ // even when -connect or -proxy is specified
+ if (mapArgs.count("-bind")) {
+ if (SoftSetBoolArg("-listen", true))
+ LogPrintf("%s: parameter interaction: -bind set -> setting -listen=1\n", __func__);
+ }
+ if (mapArgs.count("-whitebind")) {
+ if (SoftSetBoolArg("-listen", true))
+ LogPrintf("%s: parameter interaction: -whitebind set -> setting -listen=1\n", __func__);
+ }
+
+ if (mapArgs.count("-connect") && mapMultiArgs["-connect"].size() > 0) {
+ // when only connecting to trusted nodes, do not seed via DNS, or listen by default
+ if (SoftSetBoolArg("-dnsseed", false))
+ LogPrintf("%s: parameter interaction: -connect set -> setting -dnsseed=0\n", __func__);
+ if (SoftSetBoolArg("-listen", false))
+ LogPrintf("%s: parameter interaction: -connect set -> setting -listen=0\n", __func__);
+ }
+
+ if (mapArgs.count("-proxy")) {
+ // to protect privacy, do not listen by default if a default proxy server is specified
+ if (SoftSetBoolArg("-listen", false))
+ LogPrintf("%s: parameter interaction: -proxy set -> setting -listen=0\n", __func__);
+ // to protect privacy, do not use UPNP when a proxy is set. The user may still specify -listen=1
+ // to listen locally, so don't rely on this happening through -listen below.
+ if (SoftSetBoolArg("-upnp", false))
+ LogPrintf("%s: parameter interaction: -proxy set -> setting -upnp=0\n", __func__);
+ // to protect privacy, do not discover addresses by default
+ if (SoftSetBoolArg("-discover", false))
+ LogPrintf("%s: parameter interaction: -proxy set -> setting -discover=0\n", __func__);
+ }
+
+ if (!GetBoolArg("-listen", DEFAULT_LISTEN)) {
+ // do not map ports or try to retrieve public IP when not listening (pointless)
+ if (SoftSetBoolArg("-upnp", false))
+ LogPrintf("%s: parameter interaction: -listen=0 -> setting -upnp=0\n", __func__);
+ if (SoftSetBoolArg("-discover", false))
+ LogPrintf("%s: parameter interaction: -listen=0 -> setting -discover=0\n", __func__);
+ }
+
+ if (mapArgs.count("-externalip")) {
+ // if an explicit public IP is specified, do not try to find others
+ if (SoftSetBoolArg("-discover", false))
+ LogPrintf("%s: parameter interaction: -externalip set -> setting -discover=0\n", __func__);
+ }
+
+ if (GetBoolArg("-salvagewallet", false)) {
+ // Rewrite just private keys: rescan to find transactions
+ if (SoftSetBoolArg("-rescan", true))
+ LogPrintf("%s: parameter interaction: -salvagewallet=1 -> setting -rescan=1\n", __func__);
+ }
+
+ // -zapwallettx implies a rescan
+ if (GetBoolArg("-zapwallettxes", false)) {
+ if (SoftSetBoolArg("-rescan", true))
+ LogPrintf("%s: parameter interaction: -zapwallettxes=<mode> -> setting -rescan=1\n", __func__);
+ }
+
+ // Make sure enough file descriptors are available
+ int nBind = std::max((int)mapArgs.count("-bind") + (int)mapArgs.count("-whitebind"), 1);
+ nMaxConnections = GetArg("-maxconnections", 125);
+ nMaxConnections = std::max(std::min(nMaxConnections, (int)(FD_SETSIZE - nBind - MIN_CORE_FILEDESCRIPTORS)), 0);
+ int nFD = RaiseFileDescriptorLimit(nMaxConnections + MIN_CORE_FILEDESCRIPTORS);
+ if (nFD < MIN_CORE_FILEDESCRIPTORS)
+ return InitError(_("Not enough file descriptors available."));
+ if (nFD - MIN_CORE_FILEDESCRIPTORS < nMaxConnections)
+ nMaxConnections = nFD - MIN_CORE_FILEDESCRIPTORS;
+
+ // if using block pruning, then disable txindex
+ // also disable the wallet (for now, until SPV support is implemented in wallet)
+ if (GetArg("-prune", 0)) {
+ if (GetBoolArg("-txindex", false))
+ return InitError(_("Prune mode is incompatible with -txindex."));
+#ifdef ENABLE_WALLET
+ if (!GetBoolArg("-disablewallet", false)) {
+ if (SoftSetBoolArg("-disablewallet", true))
+ LogPrintf("%s : parameter interaction: -prune -> setting -disablewallet=1\n", __func__);
+ else
+ return InitError(_("Can't run with a wallet in prune mode."));
+ }
+#endif
+ }
+
+ // ********************************************************* Step 3: parameter-to-internal-flags
+
+ fDebug = !mapMultiArgs["-debug"].empty();
+ // Special-case: if -debug=0/-nodebug is set, turn off debugging messages
+ const vector<string>& categories = mapMultiArgs["-debug"];
+ if (GetBoolArg("-nodebug", false) || find(categories.begin(), categories.end(), string("0")) != categories.end())
+ fDebug = false;
+
+ // Check for -debugnet
+ if (GetBoolArg("-debugnet", false))
+ InitWarning(_("Warning: Unsupported argument -debugnet ignored, use -debug=net."));
+ // Check for -socks - as this is a privacy risk to continue, exit here
+ if (mapArgs.count("-socks"))
+ return InitError(_("Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported."));
+ // Check for -tor - as this is a privacy risk to continue, exit here
+ if (GetBoolArg("-tor", false))
+ return InitError(_("Error: Unsupported argument -tor found, use -onion."));
+
+ if (GetBoolArg("-benchmark", false))
+ InitWarning(_("Warning: Unsupported argument -benchmark ignored, use -debug=bench."));
+
+ // Checkmempool and checkblockindex default to true in regtest mode
+ mempool.setSanityCheck(GetBoolArg("-checkmempool", chainparams.DefaultConsistencyChecks()));
+ fCheckBlockIndex = GetBoolArg("-checkblockindex", chainparams.DefaultConsistencyChecks());
+ fCheckpointsEnabled = GetBoolArg("-checkpoints", true);
+
+ // -par=0 means autodetect, but nScriptCheckThreads==0 means no concurrency
+ nScriptCheckThreads = GetArg("-par", DEFAULT_SCRIPTCHECK_THREADS);
+ if (nScriptCheckThreads <= 0)
+ nScriptCheckThreads += boost::thread::hardware_concurrency();
+ if (nScriptCheckThreads <= 1)
+ nScriptCheckThreads = 0;
+ else if (nScriptCheckThreads > MAX_SCRIPTCHECK_THREADS)
+ nScriptCheckThreads = MAX_SCRIPTCHECK_THREADS;
+
+ fServer = GetBoolArg("-server", false);
+
+ // block pruning; get the amount of disk space (in MB) to allot for block & undo files
+ int64_t nSignedPruneTarget = GetArg("-prune", 0) * 1024 * 1024;
+ if (nSignedPruneTarget < 0) {
+ return InitError(_("Prune cannot be configured with a negative value."));
+ }
+ nPruneTarget = (uint64_t) nSignedPruneTarget;
+ if (nPruneTarget) {
+ if (nPruneTarget < MIN_DISK_SPACE_FOR_BLOCK_FILES) {
+ return InitError(strprintf(_("Prune configured below the minimum of %d MB. Please use a higher number."), MIN_DISK_SPACE_FOR_BLOCK_FILES / 1024 / 1024));
+ }
+ LogPrintf("Prune configured to target %uMiB on disk for block and undo files.\n", nPruneTarget / 1024 / 1024);
+ fPruneMode = true;
+ }
+
+#ifdef ENABLE_WALLET
+ bool fDisableWallet = GetBoolArg("-disablewallet", false);
+#endif
+
+ nConnectTimeout = GetArg("-timeout", DEFAULT_CONNECT_TIMEOUT);
+ if (nConnectTimeout <= 0)
+ nConnectTimeout = DEFAULT_CONNECT_TIMEOUT;
+
+ // Fee-per-kilobyte amount considered the same as "free"
+ // If you are mining, be careful setting this:
+ // if you set it to zero then
+ // a transaction spammer can cheaply fill blocks using
+ // 1-satoshi-fee transactions. It should be set above the real
+ // cost to you of processing a transaction.
+ if (mapArgs.count("-minrelaytxfee"))
+ {
+ CAmount n = 0;
+ if (ParseMoney(mapArgs["-minrelaytxfee"], n) && n > 0)
+ ::minRelayTxFee = CFeeRate(n);
+ else
+ return InitError(strprintf(_("Invalid amount for -minrelaytxfee=<amount>: '%s'"), mapArgs["-minrelaytxfee"]));
+ }
+
+#ifdef ENABLE_WALLET
+ if (mapArgs.count("-mintxfee"))
+ {
+ CAmount n = 0;
+ if (ParseMoney(mapArgs["-mintxfee"], n) && n > 0)
+ CWallet::minTxFee = CFeeRate(n);
+ else
+ return InitError(strprintf(_("Invalid amount for -mintxfee=<amount>: '%s'"), mapArgs["-mintxfee"]));
+ }
+ if (mapArgs.count("-paytxfee"))
+ {
+ CAmount nFeePerK = 0;
+ if (!ParseMoney(mapArgs["-paytxfee"], nFeePerK))
+ return InitError(strprintf(_("Invalid amount for -paytxfee=<amount>: '%s'"), mapArgs["-paytxfee"]));
+ if (nFeePerK > nHighTransactionFeeWarning)
+ InitWarning(_("Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction."));
+ payTxFee = CFeeRate(nFeePerK, 1000);
+ if (payTxFee < ::minRelayTxFee)
+ {
+ return InitError(strprintf(_("Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)"),
+ mapArgs["-paytxfee"], ::minRelayTxFee.ToString()));
+ }
+ }
+ if (mapArgs.count("-maxtxfee"))
+ {
+ CAmount nMaxFee = 0;
+ if (!ParseMoney(mapArgs["-maxtxfee"], nMaxFee))
+ return InitError(strprintf(_("Invalid amount for -maxtxfee=<amount>: '%s'"), mapArgs["-maptxfee"]));
+ if (nMaxFee > nHighTransactionMaxFeeWarning)
+ InitWarning(_("Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction."));
+ maxTxFee = nMaxFee;
+ if (CFeeRate(maxTxFee, 1000) < ::minRelayTxFee)
+ {
+ return InitError(strprintf(_("Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)"),
+ mapArgs["-maxtxfee"], ::minRelayTxFee.ToString()));
+ }
+ }
+ nTxConfirmTarget = GetArg("-txconfirmtarget", DEFAULT_TX_CONFIRM_TARGET);
+ bSpendZeroConfChange = GetBoolArg("-spendzeroconfchange", true);
+ fSendFreeTransactions = GetBoolArg("-sendfreetransactions", false);
+
+ std::string strWalletFile = GetArg("-wallet", "wallet.dat");
+#endif // ENABLE_WALLET
+
+ fIsBareMultisigStd = GetBoolArg("-permitbaremultisig", true);
+ nMaxDatacarrierBytes = GetArg("-datacarriersize", nMaxDatacarrierBytes);
+
+ fAlerts = GetBoolArg("-alerts", DEFAULT_ALERTS);
+
+ // ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log
+
+ // Initialize elliptic curve code
+ ECC_Start();
+
+ // Sanity check
+ if (!InitSanityCheck())
+ return InitError(_("Initialization sanity check failed. Bitcoin Core is shutting down."));
+
+ std::string strDataDir = GetDataDir().string();
+#ifdef ENABLE_WALLET
+ // Wallet file must be a plain filename without a directory
+ if (strWalletFile != boost::filesystem::basename(strWalletFile) + boost::filesystem::extension(strWalletFile))
+ return InitError(strprintf(_("Wallet %s resides outside data directory %s"), strWalletFile, strDataDir));
+#endif
+ // Make sure only a single Bitcoin 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);
+
+ try {
+ 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. Bitcoin Core is probably already running."), strDataDir));
+ } catch(const boost::interprocess::interprocess_exception& e) {
+ return InitError(strprintf(_("Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.") + " %s.", strDataDir, e.what()));
+ }
+
+#ifndef WIN32
+ CreatePidFile(GetPidFile(), getpid());
+#endif
+ if (GetBoolArg("-shrinkdebugfile", !fDebug))
+ ShrinkDebugFile();
+ LogPrintf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
+ LogPrintf("Bitcoin version %s (%s)\n", FormatFullVersion(), CLIENT_DATE);
+ LogPrintf("Using OpenSSL version %s\n", SSLeay_version(SSLEAY_VERSION));
+#ifdef ENABLE_WALLET
+ LogPrintf("Using BerkeleyDB version %s\n", DbEnv::version(0, 0, 0));
+#endif
+ if (!fLogTimestamps)
+ LogPrintf("Startup time: %s\n", DateTimeStrFormat("%Y-%m-%d %H:%M:%S", GetTime()));
+ LogPrintf("Default data directory %s\n", GetDefaultDataDir().string());
+ LogPrintf("Using data directory %s\n", strDataDir);
+ LogPrintf("Using config file %s\n", GetConfigFile().string());
+ LogPrintf("Using at most %i connections (%i file descriptors available)\n", nMaxConnections, nFD);
+ std::ostringstream strErrors;
+
+ LogPrintf("Using %u threads for script verification\n", nScriptCheckThreads);
+ if (nScriptCheckThreads) {
+ for (int i=0; i<nScriptCheckThreads-1; i++)
+ threadGroup.create_thread(&ThreadScriptCheck);
+ }
+
+ // Start the lightweight task scheduler thread
+ CScheduler::Function serviceLoop = boost::bind(&CScheduler::serviceQueue, &scheduler);
+ threadGroup.create_thread(boost::bind(&TraceThread<CScheduler::Function>, "scheduler", serviceLoop));
+
+ /* Start the RPC server already. It will be started in "warmup" mode
+ * and not really process calls already (but it will signify connections
+ * that the server is there and will be ready later). Warmup mode will
+ * be disabled when initialisation is finished.
+ */
+ if (fServer)
+ {
+ uiInterface.InitMessage.connect(SetRPCWarmupStatus);
+ RPCServer::OnStopped(&OnRPCStopped);
+ RPCServer::OnPreCommand(&OnRPCPreCommand);
+ StartRPCThreads();
+ }
+
+ int64_t nStart;
+
+ // ********************************************************* Step 5: verify wallet database integrity
+#ifdef ENABLE_WALLET
+ if (!fDisableWallet) {
+ LogPrintf("Using wallet %s\n", strWalletFile);
+ uiInterface.InitMessage(_("Verifying wallet..."));
+
+ std::string warningString;
+ std::string errorString;
+
+ if (!CWallet::Verify(strWalletFile, warningString, errorString))
+ return false;
+
+ if (!warningString.empty())
+ InitWarning(warningString);
+ if (!errorString.empty())
+ return InitError(warningString);
+
+ } // (!fDisableWallet)
+#endif // ENABLE_WALLET
+ // ********************************************************* Step 6: network initialization
+
+ RegisterNodeSignals(GetNodeSignals());
+
+ if (mapArgs.count("-onlynet")) {
+ std::set<enum Network> 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));
+ nets.insert(net);
+ }
+ for (int n = 0; n < NET_MAX; n++) {
+ enum Network net = (enum Network)n;
+ if (!nets.count(net))
+ SetLimited(net);
+ }
+ }
+
+ if (mapArgs.count("-whitelist")) {
+ BOOST_FOREACH(const std::string& net, mapMultiArgs["-whitelist"]) {
+ CSubNet subnet(net);
+ if (!subnet.IsValid())
+ return InitError(strprintf(_("Invalid netmask specified in -whitelist: '%s'"), net));
+ CNode::AddWhitelistedRange(subnet);
+ }
+ }
+
+ proxyType addrProxy;
+ bool fProxy = false;
+ if (mapArgs.count("-proxy")) {
+ addrProxy = proxyType(CService(mapArgs["-proxy"], 9050), GetBoolArg("-proxyrandomize", true));
+ if (!addrProxy.IsValid())
+ return InitError(strprintf(_("Invalid -proxy address: '%s'"), mapArgs["-proxy"]));
+
+ SetProxy(NET_IPV4, addrProxy);
+ SetProxy(NET_IPV6, addrProxy);
+ SetNameProxy(addrProxy);
+ fProxy = true;
+ }
+
+ // -onion can override normal proxy, -noonion disables connecting to .onion entirely
+ if (!(mapArgs.count("-onion") && mapArgs["-onion"] == "0") &&
+ (fProxy || mapArgs.count("-onion"))) {
+ proxyType addrOnion;
+ if (!mapArgs.count("-onion"))
+ addrOnion = addrProxy;
+ else
+ addrOnion = proxyType(CService(mapArgs["-onion"], 9050), GetBoolArg("-proxyrandomize", true));
+ if (!addrOnion.IsValid())
+ return InitError(strprintf(_("Invalid -onion address: '%s'"), mapArgs["-onion"]));
+ SetProxy(NET_TOR, addrOnion);
+ SetReachable(NET_TOR);
+ }
+
+ // see Step 2: parameter interactions for more information about these
+ fListen = GetBoolArg("-listen", DEFAULT_LISTEN);
+ fDiscover = GetBoolArg("-discover", true);
+ fNameLookup = GetBoolArg("-dns", true);
+
+ bool fBound = false;
+ if (fListen) {
+ if (mapArgs.count("-bind") || mapArgs.count("-whitebind")) {
+ 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));
+ fBound |= Bind(addrBind, (BF_EXPLICIT | BF_REPORT_ERROR));
+ }
+ BOOST_FOREACH(std::string strBind, mapMultiArgs["-whitebind"]) {
+ CService addrBind;
+ if (!Lookup(strBind.c_str(), addrBind, 0, false))
+ return InitError(strprintf(_("Cannot resolve -whitebind address: '%s'"), strBind));
+ if (addrBind.GetPort() == 0)
+ return InitError(strprintf(_("Need to specify a port with -whitebind: '%s'"), strBind));
+ fBound |= Bind(addrBind, (BF_EXPLICIT | BF_REPORT_ERROR | BF_WHITELIST));
+ }
+ }
+ else {
+ struct in_addr inaddr_any;
+ inaddr_any.s_addr = INADDR_ANY;
+ fBound |= Bind(CService(in6addr_any, GetListenPort()), BF_NONE);
+ fBound |= Bind(CService(inaddr_any, GetListenPort()), !fBound ? BF_REPORT_ERROR : BF_NONE);
+ }
+ 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));
+ AddLocal(CService(strAddr, GetListenPort(), fNameLookup), LOCAL_MANUAL);
+ }
+ }
+
+ BOOST_FOREACH(string strDest, mapMultiArgs["-seednode"])
+ AddOneShot(strDest);
+
+ // ********************************************************* Step 7: load block chain
+
+ fReindex = GetBoolArg("-reindex", false);
+
+ // Upgrading to 0.8; hard-link the old blknnnn.dat files into /blocks/
+ boost::filesystem::path blocksDir = GetDataDir() / "blocks";
+ if (!boost::filesystem::exists(blocksDir))
+ {
+ boost::filesystem::create_directories(blocksDir);
+ bool linked = false;
+ for (unsigned int i = 1; i < 10000; i++) {
+ boost::filesystem::path source = GetDataDir() / strprintf("blk%04u.dat", i);
+ if (!boost::filesystem::exists(source)) break;
+ boost::filesystem::path dest = blocksDir / strprintf("blk%05u.dat", i-1);
+ try {
+ boost::filesystem::create_hard_link(source, dest);
+ LogPrintf("Hardlinked %s -> %s\n", source.string(), dest.string());
+ linked = true;
+ } catch (const boost::filesystem::filesystem_error& e) {
+ // Note: hardlink creation failing is not a disaster, it just means
+ // blocks will get re-downloaded from peers.
+ LogPrintf("Error hardlinking blk%04u.dat: %s\n", i, e.what());
+ break;
+ }
+ }
+ if (linked)
+ {
+ fReindex = true;
+ }
+ }
+
+ // cache size calculations
+ int64_t nTotalCache = (GetArg("-dbcache", nDefaultDbCache) << 20);
+ nTotalCache = std::max(nTotalCache, nMinDbCache << 20); // total cache cannot be less than nMinDbCache
+ nTotalCache = std::min(nTotalCache, nMaxDbCache << 20); // total cache cannot be greated than nMaxDbcache
+ int64_t nBlockTreeDBCache = nTotalCache / 8;
+ if (nBlockTreeDBCache > (1 << 21) && !GetBoolArg("-txindex", false))
+ nBlockTreeDBCache = (1 << 21); // block tree db cache shouldn't be larger than 2 MiB
+ nTotalCache -= nBlockTreeDBCache;
+ int64_t nCoinDBCache = std::min(nTotalCache / 2, (nTotalCache / 4) + (1 << 23)); // use 25%-50% of the remainder for disk cache
+ nTotalCache -= nCoinDBCache;
+ nCoinCacheUsage = nTotalCache; // the rest goes to in-memory cache
+ LogPrintf("Cache configuration:\n");
+ LogPrintf("* Using %.1fMiB for block index database\n", nBlockTreeDBCache * (1.0 / 1024 / 1024));
+ LogPrintf("* Using %.1fMiB for chain state database\n", nCoinDBCache * (1.0 / 1024 / 1024));
+ LogPrintf("* Using %.1fMiB for in-memory UTXO set\n", nCoinCacheUsage * (1.0 / 1024 / 1024));
+
+ bool fLoaded = false;
+ while (!fLoaded) {
+ bool fReset = fReindex;
+ std::string strLoadError;
+
+ uiInterface.InitMessage(_("Loading block index..."));
+
+ nStart = GetTimeMillis();
+ do {
+ try {
+ UnloadBlockIndex();
+ delete pcoinsTip;
+ delete pcoinsdbview;
+ delete pcoinscatcher;
+ delete pblocktree;
+
+ pblocktree = new CBlockTreeDB(nBlockTreeDBCache, false, fReindex);
+ pcoinsdbview = new CCoinsViewDB(nCoinDBCache, false, fReindex);
+ pcoinscatcher = new CCoinsViewErrorCatcher(pcoinsdbview);
+ pcoinsTip = new CCoinsViewCache(pcoinscatcher);
+
+ if (fReindex) {
+ pblocktree->WriteReindexing(true);
+ //If we're reindexing in prune mode, wipe away unusable block files and all undo data files
+ if (fPruneMode)
+ CleanupBlockRevFiles();
+ }
+
+ if (!LoadBlockIndex()) {
+ strLoadError = _("Error loading block database");
+ break;
+ }
+
+ // If the loaded chain has a wrong genesis, bail out immediately
+ // (we're likely using a testnet datadir, or the other way around).
+ if (!mapBlockIndex.empty() && mapBlockIndex.count(chainparams.GetConsensus().hashGenesisBlock) == 0)
+ return InitError(_("Incorrect or no genesis block found. Wrong datadir for network?"));
+
+ // Initialize the block index (no-op if non-empty database was already loaded)
+ if (!InitBlockIndex()) {
+ strLoadError = _("Error initializing block database");
+ break;
+ }
+
+ // Check for changed -txindex state
+ if (fTxIndex != GetBoolArg("-txindex", false)) {
+ strLoadError = _("You need to rebuild the database using -reindex to change -txindex");
+ break;
+ }
+
+ // Check for changed -prune state. What we are concerned about is a user who has pruned blocks
+ // in the past, but is now trying to run unpruned.
+ if (fHavePruned && !fPruneMode) {
+ strLoadError = _("You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain");
+ break;
+ }
+
+ uiInterface.InitMessage(_("Verifying blocks..."));
+ if (fHavePruned && GetArg("-checkblocks", 288) > MIN_BLOCKS_TO_KEEP) {
+ LogPrintf("Prune: pruned datadir may not have more than %d blocks; -checkblocks=%d may fail\n",
+ MIN_BLOCKS_TO_KEEP, GetArg("-checkblocks", 288));
+ }
+ if (!CVerifyDB().VerifyDB(pcoinsdbview, GetArg("-checklevel", 3),
+ GetArg("-checkblocks", 288))) {
+ strLoadError = _("Corrupted block database detected");
+ break;
+ }
+ } catch (const std::exception& e) {
+ if (fDebug) LogPrintf("%s\n", e.what());
+ strLoadError = _("Error opening block database");
+ break;
+ }
+
+ fLoaded = true;
+ } while(false);
+
+ if (!fLoaded) {
+ // first suggest a reindex
+ if (!fReset) {
+ bool fRet = uiInterface.ThreadSafeMessageBox(
+ strLoadError + ".\n\n" + _("Do you want to rebuild the block database now?"),
+ "", CClientUIInterface::MSG_ERROR | CClientUIInterface::BTN_ABORT);
+ if (fRet) {
+ fReindex = true;
+ fRequestShutdown = false;
+ } else {
+ LogPrintf("Aborted block database rebuild. Exiting.\n");
+ return false;
+ }
+ } else {
+ return InitError(strLoadError);
+ }
+ }
+ }
+
+ // As LoadBlockIndex can take several minutes, it's possible the user
+ // requested to kill the GUI during the last operation. If so, exit.
+ // As the program has not fully started yet, Shutdown() is possibly overkill.
+ if (fRequestShutdown)
+ {
+ LogPrintf("Shutdown requested. Exiting.\n");
+ return false;
+ }
+ LogPrintf(" block index %15dms\n", GetTimeMillis() - nStart);
+
+ boost::filesystem::path est_path = GetDataDir() / FEE_ESTIMATES_FILENAME;
+ CAutoFile est_filein(fopen(est_path.string().c_str(), "rb"), SER_DISK, CLIENT_VERSION);
+ // Allowed to fail as this file IS missing on first startup.
+ if (!est_filein.IsNull())
+ mempool.ReadFeeEstimates(est_filein);
+ fFeeEstimatesInitialized = true;
+
+ // ********************************************************* Step 8: load wallet
+#ifdef ENABLE_WALLET
+ if (fDisableWallet) {
+ pwalletMain = NULL;
+ LogPrintf("Wallet disabled!\n");
+ } else {
+
+ // needed to restore wallet transaction meta data after -zapwallettxes
+ std::vector<CWalletTx> vWtx;
+
+ if (GetBoolArg("-zapwallettxes", false)) {
+ uiInterface.InitMessage(_("Zapping all transactions from wallet..."));
+
+ pwalletMain = new CWallet(strWalletFile);
+ DBErrors nZapWalletRet = pwalletMain->ZapWalletTx(vWtx);
+ if (nZapWalletRet != DB_LOAD_OK) {
+ uiInterface.InitMessage(_("Error loading wallet.dat: Wallet corrupted"));
+ return false;
+ }
+
+ delete pwalletMain;
+ pwalletMain = NULL;
+ }
+
+ uiInterface.InitMessage(_("Loading wallet..."));
+
+ nStart = GetTimeMillis();
+ bool fFirstRun = true;
+ pwalletMain = new CWallet(strWalletFile);
+ DBErrors 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_NONCRITICAL_ERROR)
+ {
+ string msg(_("Warning: error reading wallet.dat! All keys read correctly, but transaction data"
+ " or address book entries might be missing or incorrect."));
+ InitWarning(msg);
+ }
+ else if (nLoadWalletRet == DB_TOO_NEW)
+ strErrors << _("Error loading wallet.dat: Wallet requires newer version of Bitcoin Core") << "\n";
+ else if (nLoadWalletRet == DB_NEED_REWRITE)
+ {
+ strErrors << _("Wallet needed to be rewritten: restart Bitcoin Core to complete") << "\n";
+ LogPrintf("%s", strErrors.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
+ {
+ LogPrintf("Performing wallet upgrade to %i\n", FEATURE_LATEST);
+ nMaxVersion = CLIENT_VERSION;
+ pwalletMain->SetMinVersion(FEATURE_LATEST); // permanently upgrade the wallet immediately
+ }
+ else
+ LogPrintf("Allowing wallet upgrade up to %i\n", nMaxVersion);
+ if (nMaxVersion < 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)) {
+ pwalletMain->SetDefaultKey(newDefaultKey);
+ if (!pwalletMain->SetAddressBook(pwalletMain->vchDefaultKey.GetID(), "", "receive"))
+ strErrors << _("Cannot write default address") << "\n";
+ }
+
+ pwalletMain->SetBestChain(chainActive.GetLocator());
+ }
+
+ LogPrintf("%s", strErrors.str());
+ LogPrintf(" wallet %15dms\n", GetTimeMillis() - nStart);
+
+ RegisterValidationInterface(pwalletMain);
+
+ CBlockIndex *pindexRescan = chainActive.Tip();
+ if (GetBoolArg("-rescan", false))
+ pindexRescan = chainActive.Genesis();
+ else
+ {
+ CWalletDB walletdb(strWalletFile);
+ CBlockLocator locator;
+ if (walletdb.ReadBestBlock(locator))
+ pindexRescan = FindForkInGlobalIndex(chainActive, locator);
+ else
+ pindexRescan = chainActive.Genesis();
+ }
+ if (chainActive.Tip() && chainActive.Tip() != pindexRescan)
+ {
+ uiInterface.InitMessage(_("Rescanning..."));
+ LogPrintf("Rescanning last %i blocks (from block %i)...\n", chainActive.Height() - pindexRescan->nHeight, pindexRescan->nHeight);
+ nStart = GetTimeMillis();
+ pwalletMain->ScanForWalletTransactions(pindexRescan, true);
+ LogPrintf(" rescan %15dms\n", GetTimeMillis() - nStart);
+ pwalletMain->SetBestChain(chainActive.GetLocator());
+ nWalletDBUpdated++;
+
+ // Restore wallet transaction metadata after -zapwallettxes=1
+ if (GetBoolArg("-zapwallettxes", false) && GetArg("-zapwallettxes", "1") != "2")
+ {
+ CWalletDB walletdb(strWalletFile);
+
+ BOOST_FOREACH(const CWalletTx& wtxOld, vWtx)
+ {
+ uint256 hash = wtxOld.GetHash();
+ std::map<uint256, CWalletTx>::iterator mi = pwalletMain->mapWallet.find(hash);
+ if (mi != pwalletMain->mapWallet.end())
+ {
+ const CWalletTx* copyFrom = &wtxOld;
+ CWalletTx* copyTo = &mi->second;
+ copyTo->mapValue = copyFrom->mapValue;
+ copyTo->vOrderForm = copyFrom->vOrderForm;
+ copyTo->nTimeReceived = copyFrom->nTimeReceived;
+ copyTo->nTimeSmart = copyFrom->nTimeSmart;
+ copyTo->fFromMe = copyFrom->fFromMe;
+ copyTo->strFromAccount = copyFrom->strFromAccount;
+ copyTo->nOrderPos = copyFrom->nOrderPos;
+ copyTo->WriteToDisk(&walletdb);
+ }
+ }
+ }
+ }
+ pwalletMain->SetBroadcastTransactions(GetBoolArg("-walletbroadcast", true));
+ } // (!fDisableWallet)
+#else // ENABLE_WALLET
+ LogPrintf("No wallet support compiled in!\n");
+#endif // !ENABLE_WALLET
+
+ // ********************************************************* Step 9: data directory maintenance
+
+ // if pruning, unset the service bit and perform the initial blockstore prune
+ // after any wallet rescanning has taken place.
+ if (fPruneMode) {
+ LogPrintf("Unsetting NODE_NETWORK on prune mode\n");
+ nLocalServices &= ~NODE_NETWORK;
+ if (!fReindex) {
+ uiInterface.InitMessage(_("Pruning blockstore..."));
+ PruneAndFlush();
+ }
+ }
+
+ // ********************************************************* Step 10: import blocks
+
+ if (mapArgs.count("-blocknotify"))
+ uiInterface.NotifyBlockTip.connect(BlockNotifyCallback);
+
+ uiInterface.InitMessage(_("Activating best chain..."));
+ // scan for better chains in the block chain database, that are not yet connected in the active best chain
+ CValidationState state;
+ if (!ActivateBestChain(state))
+ strErrors << "Failed to connect best block";
+
+ std::vector<boost::filesystem::path> vImportFiles;
+ if (mapArgs.count("-loadblock"))
+ {
+ BOOST_FOREACH(string strFile, mapMultiArgs["-loadblock"])
+ vImportFiles.push_back(strFile);
+ }
+ threadGroup.create_thread(boost::bind(&ThreadImport, vImportFiles));
+ if (chainActive.Tip() == NULL) {
+ LogPrintf("Waiting for genesis block to be imported...\n");
+ while (!fRequestShutdown && chainActive.Tip() == NULL)
+ MilliSleep(10);
+ }
+
+ // ********************************************************* Step 11: start node
+
+ if (!CheckDiskSpace())
+ return false;
+
+ if (!strErrors.str().empty())
+ return InitError(strErrors.str());
+
+ RandAddSeedPerfmon();
+
+ //// debug print
+ LogPrintf("mapBlockIndex.size() = %u\n", mapBlockIndex.size());
+ LogPrintf("nBestHeight = %d\n", chainActive.Height());
+#ifdef ENABLE_WALLET
+ LogPrintf("setKeyPool.size() = %u\n", pwalletMain ? pwalletMain->setKeyPool.size() : 0);
+ LogPrintf("mapWallet.size() = %u\n", pwalletMain ? pwalletMain->mapWallet.size() : 0);
+ LogPrintf("mapAddressBook.size() = %u\n", pwalletMain ? pwalletMain->mapAddressBook.size() : 0);
+#endif
+
+ StartNode(threadGroup, scheduler);
+
+ // Monitor the chain, and alert if we get blocks much quicker or slower than expected
+ int64_t nPowTargetSpacing = Params().GetConsensus().nPowTargetSpacing;
+ CScheduler::Function f = boost::bind(&PartitionCheck, &IsInitialBlockDownload,
+ boost::ref(cs_main), boost::cref(pindexBestHeader), nPowTargetSpacing);
+ scheduler.scheduleEvery(f, nPowTargetSpacing);
+
+#ifdef ENABLE_WALLET
+ // Generate coins in the background
+ if (pwalletMain)
+ GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain, GetArg("-genproclimit", 1));
+#endif
+
+ // ********************************************************* Step 11: finished
+
+ SetRPCWarmupFinished();
+ uiInterface.InitMessage(_("Done loading"));
+
+#ifdef ENABLE_WALLET
+ if (pwalletMain) {
+ // Add wallet transactions that aren't already in a block to mapTransactions
+ pwalletMain->ReacceptWalletTransactions();
+
+ // Run a thread to flush wallet periodically
+ threadGroup.create_thread(boost::bind(&ThreadFlushWalletDB, boost::ref(pwalletMain->strWalletFile)));
+ }
+#endif
+
+ return !fRequestShutdown;
+}
diff --git a/src/init.h b/src/init.h
new file mode 100644
index 0000000000..dcb2b29360
--- /dev/null
+++ b/src/init.h
@@ -0,0 +1,37 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT 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 <string>
+
+class CScheduler;
+class CWallet;
+
+namespace boost
+{
+class thread_group;
+} // namespace boost
+
+extern CWallet* pwalletMain;
+
+void StartShutdown();
+bool ShutdownRequested();
+void Shutdown();
+bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler);
+
+/** The help message mode determines what help message to show */
+enum HelpMessageMode {
+ HMM_BITCOIND,
+ HMM_BITCOIN_QT
+};
+
+/** Help for options shared between UI and daemon (for -help) */
+std::string HelpMessage(HelpMessageMode mode);
+/** Returns licensing information (for -version) */
+std::string LicenseInfo();
+
+#endif // BITCOIN_INIT_H
diff --git a/src/json/LICENSE.txt b/src/json/LICENSE.txt
new file mode 100644
index 0000000000..797d5363b3
--- /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 0000000000..ac1879d5b3
--- /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 0000000000..17208507df
--- /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 <string>
+
+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 0000000000..aa4f637226
--- /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 0000000000..96494a9789
--- /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 <iostream>
+
+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 0000000000..47e3c1ca84
--- /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 <boost/bind.hpp>
+#include <boost/function.hpp>
+#include <boost/version.hpp>
+
+#if BOOST_VERSION >= 103800
+ #include <boost/spirit/include/classic_core.hpp>
+ #include <boost/spirit/include/classic_confix.hpp>
+ #include <boost/spirit/include/classic_escape_char.hpp>
+ #include <boost/spirit/include/classic_multi_pass.hpp>
+ #include <boost/spirit/include/classic_position_iterator.hpp>
+ #define spirit_namespace boost::spirit::classic
+#else
+ #include <boost/spirit/core.hpp>
+ #include <boost/spirit/utility/confix.hpp>
+ #include <boost/spirit/utility/escape_char.hpp>
+ #include <boost/spirit/iterator/multi_pass.hpp>
+ #include <boost/spirit/iterator/position_iterator.hpp>
+ #define spirit_namespace boost::spirit
+#endif
+
+namespace json_spirit
+{
+ const spirit_namespace::int_parser < int64_t > int64_p = spirit_namespace::int_parser < int64_t >();
+ const spirit_namespace::uint_parser< uint64_t > uint64_p = spirit_namespace::uint_parser< 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( int64_t i )
+ {
+ add_to_current( i );
+ }
+
+ void new_uint64( 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 &current_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( int64_t ) > Int_action;
+ typedef boost::function< void( 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::end_p,
+ spirit_namespace::space_p );
+
+ if( !info.hit )
+ {
+ 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();
+
+ bool success = read_range( begin, s.end(), value );
+ return success && begin == s.end();
+ }
+
+ 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 0000000000..7e59c9adc2
--- /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 0000000000..553e3b96a4
--- /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 <map>
+
+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 0000000000..44d2f06a01
--- /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 0000000000..13cc89210c
--- /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 <vector>
+#include <map>
+#include <string>
+#include <cassert>
+#include <sstream>
+#include <stdexcept>
+#include <stdint.h>
+#include <boost/config.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/variant.hpp>
+
+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( int64_t value );
+ Value_impl( 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;
+ int64_t get_int64() const;
+ 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, 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< int64_t >( value ) )
+ , is_uint64_( false )
+ {
+ }
+
+ template< class Config >
+ Value_impl< Config >::Value_impl( int64_t value )
+ : type_( int_type )
+ , v_( value )
+ , is_uint64_( false )
+ {
+ }
+
+ template< class Config >
+ Value_impl< Config >::Value_impl( uint64_t value )
+ : type_( int_type )
+ , v_( static_cast< 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 >
+ int64_t Value_impl< Config >::get_int64() const
+ {
+ check_type( int_type );
+
+ return boost::get< int64_t >( v_ );
+ }
+
+ template< class Config >
+ uint64_t Value_impl< Config >::get_uint64() const
+ {
+ check_type( int_type );
+
+ return static_cast< 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 >
+ int64_t get_value( const Value& value, Type_to_type< int64_t > )
+ {
+ return value.get_int64();
+ }
+
+ template< class Value >
+ uint64_t get_value( const Value& value, Type_to_type< 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 0000000000..d24a632cf3
--- /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 0000000000..52e14068e7
--- /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 <iostream>
+
+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 0000000000..6b4978a1ff
--- /dev/null
+++ b/src/json/json_spirit_writer_template.h
@@ -0,0 +1,249 @@
+#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 <cassert>
+#include <sstream>
+#include <iomanip>
+
+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 )
+ {
+ // Silence the warning: typedef ‘Char_type’ locally defined but not used [-Wunused-local-typedefs]
+ // 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 0000000000..b772dff333
--- /dev/null
+++ b/src/key.cpp
@@ -0,0 +1,223 @@
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "key.h"
+
+#include "arith_uint256.h"
+#include "crypto/common.h"
+#include "crypto/hmac_sha512.h"
+#include "eccryptoverify.h"
+#include "pubkey.h"
+#include "random.h"
+
+#include <secp256k1.h>
+#include "ecwrapper.h"
+
+static secp256k1_context_t* secp256k1_context = NULL;
+
+bool CKey::Check(const unsigned char *vch) {
+ return eccrypto::Check(vch);
+}
+
+void CKey::MakeNewKey(bool fCompressedIn) {
+ RandAddSeedPerfmon();
+ do {
+ GetRandBytes(vch, sizeof(vch));
+ } while (!Check(vch));
+ fValid = true;
+ fCompressed = fCompressedIn;
+}
+
+bool CKey::SetPrivKey(const CPrivKey &privkey, bool fCompressedIn) {
+ if (!secp256k1_ec_privkey_import(secp256k1_context, (unsigned char*)begin(), &privkey[0], privkey.size()))
+ return false;
+ fCompressed = fCompressedIn;
+ fValid = true;
+ return true;
+}
+
+CPrivKey CKey::GetPrivKey() const {
+ assert(fValid);
+ CPrivKey privkey;
+ int privkeylen, ret;
+ privkey.resize(279);
+ privkeylen = 279;
+ ret = secp256k1_ec_privkey_export(secp256k1_context, begin(), (unsigned char*)&privkey[0], &privkeylen, fCompressed);
+ assert(ret);
+ privkey.resize(privkeylen);
+ return privkey;
+}
+
+CPubKey CKey::GetPubKey() const {
+ assert(fValid);
+ CPubKey result;
+ int clen = 65;
+ int ret = secp256k1_ec_pubkey_create(secp256k1_context, (unsigned char*)result.begin(), &clen, begin(), fCompressed);
+ assert((int)result.size() == clen);
+ assert(ret);
+ assert(result.IsValid());
+ return result;
+}
+
+bool CKey::Sign(const uint256 &hash, std::vector<unsigned char>& vchSig, uint32_t test_case) const {
+ if (!fValid)
+ return false;
+ vchSig.resize(72);
+ int nSigLen = 72;
+ unsigned char extra_entropy[32] = {0};
+ WriteLE32(extra_entropy, test_case);
+ int ret = secp256k1_ecdsa_sign(secp256k1_context, hash.begin(), (unsigned char*)&vchSig[0], &nSigLen, begin(), secp256k1_nonce_function_rfc6979, test_case ? extra_entropy : NULL);
+ assert(ret);
+ vchSig.resize(nSigLen);
+ return true;
+}
+
+bool CKey::VerifyPubKey(const CPubKey& pubkey) const {
+ if (pubkey.IsCompressed() != fCompressed) {
+ return false;
+ }
+ unsigned char rnd[8];
+ std::string str = "Bitcoin key verification\n";
+ GetRandBytes(rnd, sizeof(rnd));
+ uint256 hash;
+ CHash256().Write((unsigned char*)str.data(), str.size()).Write(rnd, sizeof(rnd)).Finalize(hash.begin());
+ std::vector<unsigned char> vchSig;
+ Sign(hash, vchSig);
+ return pubkey.Verify(hash, vchSig);
+}
+
+bool CKey::SignCompact(const uint256 &hash, std::vector<unsigned char>& vchSig) const {
+ if (!fValid)
+ return false;
+ vchSig.resize(65);
+ int rec = -1;
+ int ret = secp256k1_ecdsa_sign_compact(secp256k1_context, hash.begin(), &vchSig[1], begin(), secp256k1_nonce_function_rfc6979, NULL, &rec);
+ assert(ret);
+ assert(rec != -1);
+ vchSig[0] = 27 + rec + (fCompressed ? 4 : 0);
+ return true;
+}
+
+bool CKey::Load(CPrivKey &privkey, CPubKey &vchPubKey, bool fSkipCheck=false) {
+ if (!secp256k1_ec_privkey_import(secp256k1_context, (unsigned char*)begin(), &privkey[0], privkey.size()))
+ return false;
+ fCompressed = vchPubKey.IsCompressed();
+ fValid = true;
+
+ if (fSkipCheck)
+ return true;
+
+ return VerifyPubKey(vchPubKey);
+}
+
+bool CKey::Derive(CKey& keyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const {
+ assert(IsValid());
+ assert(IsCompressed());
+ unsigned char out[64];
+ LockObject(out);
+ if ((nChild >> 31) == 0) {
+ CPubKey pubkey = GetPubKey();
+ assert(pubkey.begin() + 33 == pubkey.end());
+ BIP32Hash(cc, nChild, *pubkey.begin(), pubkey.begin()+1, out);
+ } else {
+ assert(begin() + 32 == end());
+ BIP32Hash(cc, nChild, 0, begin(), out);
+ }
+ memcpy(ccChild.begin(), out+32, 32);
+ memcpy((unsigned char*)keyChild.begin(), begin(), 32);
+ bool ret = secp256k1_ec_privkey_tweak_add(secp256k1_context, (unsigned char*)keyChild.begin(), out);
+ UnlockObject(out);
+ keyChild.fCompressed = true;
+ keyChild.fValid = ret;
+ return ret;
+}
+
+bool CExtKey::Derive(CExtKey &out, unsigned int nChild) const {
+ out.nDepth = nDepth + 1;
+ CKeyID id = key.GetPubKey().GetID();
+ memcpy(&out.vchFingerprint[0], &id, 4);
+ out.nChild = nChild;
+ return key.Derive(out.key, out.chaincode, nChild, chaincode);
+}
+
+void CExtKey::SetMaster(const unsigned char *seed, unsigned int nSeedLen) {
+ static const unsigned char hashkey[] = {'B','i','t','c','o','i','n',' ','s','e','e','d'};
+ unsigned char out[64];
+ LockObject(out);
+ CHMAC_SHA512(hashkey, sizeof(hashkey)).Write(seed, nSeedLen).Finalize(out);
+ key.Set(&out[0], &out[32], true);
+ memcpy(chaincode.begin(), &out[32], 32);
+ UnlockObject(out);
+ nDepth = 0;
+ nChild = 0;
+ memset(vchFingerprint, 0, sizeof(vchFingerprint));
+}
+
+CExtPubKey CExtKey::Neuter() const {
+ CExtPubKey ret;
+ ret.nDepth = nDepth;
+ memcpy(&ret.vchFingerprint[0], &vchFingerprint[0], 4);
+ ret.nChild = nChild;
+ ret.pubkey = key.GetPubKey();
+ ret.chaincode = chaincode;
+ return ret;
+}
+
+void CExtKey::Encode(unsigned char code[74]) const {
+ code[0] = nDepth;
+ memcpy(code+1, vchFingerprint, 4);
+ code[5] = (nChild >> 24) & 0xFF; code[6] = (nChild >> 16) & 0xFF;
+ code[7] = (nChild >> 8) & 0xFF; code[8] = (nChild >> 0) & 0xFF;
+ memcpy(code+9, chaincode.begin(), 32);
+ code[41] = 0;
+ assert(key.size() == 32);
+ memcpy(code+42, key.begin(), 32);
+}
+
+void CExtKey::Decode(const unsigned char code[74]) {
+ nDepth = code[0];
+ memcpy(vchFingerprint, code+1, 4);
+ nChild = (code[5] << 24) | (code[6] << 16) | (code[7] << 8) | code[8];
+ memcpy(chaincode.begin(), code+9, 32);
+ key.Set(code+42, code+74, true);
+}
+
+bool ECC_InitSanityCheck() {
+ if (!CECKey::SanityCheck()) {
+ return false;
+ }
+ CKey key;
+ key.MakeNewKey(true);
+ CPubKey pubkey = key.GetPubKey();
+ return key.VerifyPubKey(pubkey);
+}
+
+
+void ECC_Start() {
+ assert(secp256k1_context == NULL);
+
+ secp256k1_context_t *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN);
+ assert(ctx != NULL);
+
+ {
+ // Pass in a random blinding seed to the secp256k1 context.
+ unsigned char seed[32];
+ LockObject(seed);
+ GetRandBytes(seed, 32);
+ bool ret = secp256k1_context_randomize(ctx, seed);
+ assert(ret);
+ UnlockObject(seed);
+ }
+
+ secp256k1_context = ctx;
+}
+
+void ECC_Stop() {
+ secp256k1_context_t *ctx = secp256k1_context;
+ secp256k1_context = NULL;
+
+ if (ctx) {
+ secp256k1_context_destroy(ctx);
+ }
+}
diff --git a/src/key.h b/src/key.h
new file mode 100644
index 0000000000..021eac2a8d
--- /dev/null
+++ b/src/key.h
@@ -0,0 +1,183 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT 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 "pubkey.h"
+#include "serialize.h"
+#include "support/allocators/secure.h"
+#include "uint256.h"
+
+#include <stdexcept>
+#include <vector>
+
+
+/**
+ * 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
+ */
+
+/**
+ * secure_allocator is defined in allocators.h
+ * CPrivKey is a serialized private key, with all parameters included (279 bytes)
+ */
+typedef std::vector<unsigned char, secure_allocator<unsigned char> > CPrivKey;
+
+/** An encapsulated private key. */
+class CKey
+{
+private:
+ //! Whether this private key is valid. We check for correctness when modifying the key
+ //! data, so fValid should always correspond to the actual state.
+ bool fValid;
+
+ //! Whether the public key corresponding to this private key is (to be) compressed.
+ bool fCompressed;
+
+ //! The actual byte data
+ unsigned char vch[32];
+
+ //! Check whether the 32-byte array pointed to be vch is valid keydata.
+ bool static Check(const unsigned char* vch);
+
+public:
+ //! Construct an invalid private key.
+ CKey() : fValid(false), fCompressed(false)
+ {
+ LockObject(vch);
+ }
+
+ //! Copy constructor. This is necessary because of memlocking.
+ CKey(const CKey& secret) : fValid(secret.fValid), fCompressed(secret.fCompressed)
+ {
+ LockObject(vch);
+ memcpy(vch, secret.vch, sizeof(vch));
+ }
+
+ //! Destructor (again necessary because of memlocking).
+ ~CKey()
+ {
+ UnlockObject(vch);
+ }
+
+ friend bool operator==(const CKey& a, const CKey& b)
+ {
+ return a.fCompressed == b.fCompressed && a.size() == b.size() &&
+ memcmp(&a.vch[0], &b.vch[0], a.size()) == 0;
+ }
+
+ //! Initialize using begin and end iterators to byte data.
+ template <typename T>
+ void Set(const T pbegin, const T pend, bool fCompressedIn)
+ {
+ if (pend - pbegin != 32) {
+ fValid = false;
+ return;
+ }
+ if (Check(&pbegin[0])) {
+ memcpy(vch, (unsigned char*)&pbegin[0], 32);
+ fValid = true;
+ fCompressed = fCompressedIn;
+ } else {
+ fValid = false;
+ }
+ }
+
+ //! Simple read-only vector-like interface.
+ unsigned int size() const { return (fValid ? 32 : 0); }
+ const unsigned char* begin() const { return vch; }
+ const unsigned char* end() const { return vch + size(); }
+
+ //! Check whether this private key is valid.
+ bool IsValid() const { return fValid; }
+
+ //! Check whether the public key corresponding to this private key is (to be) compressed.
+ bool IsCompressed() const { return fCompressed; }
+
+ //! Initialize from a CPrivKey (serialized OpenSSL private key data).
+ bool SetPrivKey(const CPrivKey& vchPrivKey, bool fCompressed);
+
+ //! Generate a new private key using a cryptographic PRNG.
+ void MakeNewKey(bool fCompressed);
+
+ /**
+ * Convert the private key to a CPrivKey (serialized OpenSSL private key data).
+ * This is expensive.
+ */
+ CPrivKey GetPrivKey() const;
+
+ /**
+ * Compute the public key from a private key.
+ * This is expensive.
+ */
+ CPubKey GetPubKey() const;
+
+ /**
+ * Create a DER-serialized signature.
+ * The test_case parameter tweaks the deterministic nonce.
+ */
+ bool Sign(const uint256& hash, std::vector<unsigned char>& vchSig, uint32_t test_case = 0) const;
+
+ /**
+ * 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,
+ * add 0x04 for compressed keys.
+ */
+ bool SignCompact(const uint256& hash, std::vector<unsigned char>& vchSig) const;
+
+ //! Derive BIP32 child key.
+ bool Derive(CKey& keyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const;
+
+ /**
+ * Verify thoroughly whether a private key and a public key match.
+ * This is done using a different mechanism than just regenerating it.
+ */
+ bool VerifyPubKey(const CPubKey& vchPubKey) const;
+
+ //! Load private key and check that public key matches.
+ bool Load(CPrivKey& privkey, CPubKey& vchPubKey, bool fSkipCheck);
+
+ //! Check whether an element of a signature (r or s) is valid.
+ static bool CheckSignatureElement(const unsigned char* vch, int len, bool half);
+};
+
+struct CExtKey {
+ unsigned char nDepth;
+ unsigned char vchFingerprint[4];
+ unsigned int nChild;
+ ChainCode chaincode;
+ CKey key;
+
+ friend bool operator==(const CExtKey& a, const CExtKey& b)
+ {
+ return a.nDepth == b.nDepth && memcmp(&a.vchFingerprint[0], &b.vchFingerprint[0], 4) == 0 && a.nChild == b.nChild &&
+ a.chaincode == b.chaincode && a.key == b.key;
+ }
+
+ void Encode(unsigned char code[74]) const;
+ void Decode(const unsigned char code[74]);
+ bool Derive(CExtKey& out, unsigned int nChild) const;
+ CExtPubKey Neuter() const;
+ void SetMaster(const unsigned char* seed, unsigned int nSeedLen);
+};
+
+/** Initialize the elliptic curve support. May not be called twice without calling ECC_Stop first. */
+void ECC_Start(void);
+
+/** Deinitialize the elliptic curve support. No-op if ECC_Start wasn't called first. */
+void ECC_Stop(void);
+
+/** Check that required EC support is available at runtime. */
+bool ECC_InitSanityCheck(void);
+
+#endif // BITCOIN_KEY_H
diff --git a/src/keystore.cpp b/src/keystore.cpp
new file mode 100644
index 0000000000..3bae24b7b9
--- /dev/null
+++ b/src/keystore.cpp
@@ -0,0 +1,85 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "keystore.h"
+
+#include "key.h"
+#include "util.h"
+
+#include <boost/foreach.hpp>
+
+bool CKeyStore::GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const
+{
+ CKey key;
+ if (!GetKey(address, key))
+ return false;
+ vchPubKeyOut = key.GetPubKey();
+ return true;
+}
+
+bool CKeyStore::AddKey(const CKey &key) {
+ return AddKeyPubKey(key, key.GetPubKey());
+}
+
+bool CBasicKeyStore::AddKeyPubKey(const CKey& key, const CPubKey &pubkey)
+{
+ LOCK(cs_KeyStore);
+ mapKeys[pubkey.GetID()] = key;
+ return true;
+}
+
+bool CBasicKeyStore::AddCScript(const CScript& redeemScript)
+{
+ if (redeemScript.size() > MAX_SCRIPT_ELEMENT_SIZE)
+ return error("CBasicKeyStore::AddCScript(): redeemScripts > %i bytes are invalid", MAX_SCRIPT_ELEMENT_SIZE);
+
+ LOCK(cs_KeyStore);
+ mapScripts[CScriptID(redeemScript)] = redeemScript;
+ return true;
+}
+
+bool CBasicKeyStore::HaveCScript(const CScriptID& hash) const
+{
+ LOCK(cs_KeyStore);
+ return mapScripts.count(hash) > 0;
+}
+
+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 CBasicKeyStore::AddWatchOnly(const CScript &dest)
+{
+ LOCK(cs_KeyStore);
+ setWatchOnly.insert(dest);
+ return true;
+}
+
+bool CBasicKeyStore::RemoveWatchOnly(const CScript &dest)
+{
+ LOCK(cs_KeyStore);
+ setWatchOnly.erase(dest);
+ return true;
+}
+
+bool CBasicKeyStore::HaveWatchOnly(const CScript &dest) const
+{
+ LOCK(cs_KeyStore);
+ return setWatchOnly.count(dest) > 0;
+}
+
+bool CBasicKeyStore::HaveWatchOnly() const
+{
+ LOCK(cs_KeyStore);
+ return (!setWatchOnly.empty());
+}
diff --git a/src/keystore.h b/src/keystore.h
new file mode 100644
index 0000000000..4a4b6d20af
--- /dev/null
+++ b/src/keystore.h
@@ -0,0 +1,111 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT 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 "key.h"
+#include "pubkey.h"
+#include "script/script.h"
+#include "script/standard.h"
+#include "sync.h"
+
+#include <boost/signals2/signal.hpp>
+#include <boost/variant.hpp>
+
+/** 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 AddKeyPubKey(const CKey &key, const CPubKey &pubkey) =0;
+ virtual bool AddKey(const CKey &key);
+
+ //! 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<CKeyID> &setAddress) const =0;
+ virtual bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const;
+
+ //! Support for BIP 0013 : see https://github.com/bitcoin/bips/blob/master/bip-0013.mediawiki
+ 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;
+
+ //! Support for Watch-only addresses
+ virtual bool AddWatchOnly(const CScript &dest) =0;
+ virtual bool RemoveWatchOnly(const CScript &dest) =0;
+ virtual bool HaveWatchOnly(const CScript &dest) const =0;
+ virtual bool HaveWatchOnly() const =0;
+};
+
+typedef std::map<CKeyID, CKey> KeyMap;
+typedef std::map<CScriptID, CScript > ScriptMap;
+typedef std::set<CScript> WatchOnlySet;
+
+/** Basic key store, that keeps keys in an address->secret map */
+class CBasicKeyStore : public CKeyStore
+{
+protected:
+ KeyMap mapKeys;
+ ScriptMap mapScripts;
+ WatchOnlySet setWatchOnly;
+
+public:
+ bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey);
+ bool HaveKey(const CKeyID &address) const
+ {
+ bool result;
+ {
+ LOCK(cs_KeyStore);
+ result = (mapKeys.count(address) > 0);
+ }
+ return result;
+ }
+ void GetKeys(std::set<CKeyID> &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 = mi->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;
+
+ virtual bool AddWatchOnly(const CScript &dest);
+ virtual bool RemoveWatchOnly(const CScript &dest);
+ virtual bool HaveWatchOnly(const CScript &dest) const;
+ virtual bool HaveWatchOnly() const;
+};
+
+typedef std::vector<unsigned char, secure_allocator<unsigned char> > CKeyingMaterial;
+typedef std::map<CKeyID, std::pair<CPubKey, std::vector<unsigned char> > > CryptedKeyMap;
+
+#endif // BITCOIN_KEYSTORE_H
diff --git a/src/leveldb/.gitignore b/src/leveldb/.gitignore
new file mode 100644
index 0000000000..71d87a4eeb
--- /dev/null
+++ b/src/leveldb/.gitignore
@@ -0,0 +1,13 @@
+build_config.mk
+*.a
+*.o
+*.dylib*
+*.so
+*.so.*
+*_test
+db_bench
+leveldbutil
+Release
+Debug
+Benchmark
+vs2010.*
diff --git a/AUTHORS b/src/leveldb/AUTHORS
index 2439d7a452..2439d7a452 100644
--- a/AUTHORS
+++ b/src/leveldb/AUTHORS
diff --git a/CONTRIBUTING.md b/src/leveldb/CONTRIBUTING.md
index cd600ff46b..cd600ff46b 100644
--- a/CONTRIBUTING.md
+++ b/src/leveldb/CONTRIBUTING.md
diff --git a/LICENSE b/src/leveldb/LICENSE
index 8e80208cd7..8e80208cd7 100644
--- a/LICENSE
+++ b/src/leveldb/LICENSE
diff --git a/Makefile b/src/leveldb/Makefile
index 2bd2cadcdd..2bd2cadcdd 100644
--- a/Makefile
+++ b/src/leveldb/Makefile
diff --git a/NEWS b/src/leveldb/NEWS
index 3fd99242d7..3fd99242d7 100644
--- a/NEWS
+++ b/src/leveldb/NEWS
diff --git a/README b/src/leveldb/README
index 3618adeeed..3618adeeed 100644
--- a/README
+++ b/src/leveldb/README
diff --git a/src/leveldb/README.md b/src/leveldb/README.md
new file mode 100644
index 0000000000..480affb5ca
--- /dev/null
+++ b/src/leveldb/README.md
@@ -0,0 +1,138 @@
+**LevelDB is a fast key-value storage library written at Google that provides an ordered mapping from string keys to string values.**
+
+Authors: Sanjay Ghemawat (sanjay@google.com) and Jeff Dean (jeff@google.com)
+
+# Features
+ * Keys and values are arbitrary byte arrays.
+ * Data is stored sorted by key.
+ * Callers can provide a custom comparison function to override the sort order.
+ * The basic operations are `Put(key,value)`, `Get(key)`, `Delete(key)`.
+ * Multiple changes can be made in one atomic batch.
+ * Users can create a transient snapshot to get a consistent view of data.
+ * Forward and backward iteration is supported over the data.
+ * Data is automatically compressed using the [Snappy compression library](http://code.google.com/p/snappy).
+ * External activity (file system operations etc.) is relayed through a virtual interface so users can customize the operating system interactions.
+ * [Detailed documentation](http://htmlpreview.github.io/?https://github.com/google/leveldb/blob/master/doc/index.html) about how to use the library is included with the source code.
+
+
+# Limitations
+ * This is not a SQL database. It does not have a relational data model, it does not support SQL queries, and it has no support for indexes.
+ * Only a single process (possibly multi-threaded) can access a particular database at a time.
+ * There is no client-server support builtin to the library. An application that needs such support will have to wrap their own server around the library.
+
+# Performance
+
+Here is a performance report (with explanations) from the run of the
+included db_bench program. The results are somewhat noisy, but should
+be enough to get a ballpark performance estimate.
+
+## Setup
+
+We use a database with a million entries. Each entry has a 16 byte
+key, and a 100 byte value. Values used by the benchmark compress to
+about half their original size.
+
+ LevelDB: version 1.1
+ Date: Sun May 1 12:11:26 2011
+ CPU: 4 x Intel(R) Core(TM)2 Quad CPU Q6600 @ 2.40GHz
+ CPUCache: 4096 KB
+ Keys: 16 bytes each
+ Values: 100 bytes each (50 bytes after compression)
+ Entries: 1000000
+ Raw Size: 110.6 MB (estimated)
+ File Size: 62.9 MB (estimated)
+
+## Write performance
+
+The "fill" benchmarks create a brand new database, in either
+sequential, or random order. The "fillsync" benchmark flushes data
+from the operating system to the disk after every operation; the other
+write operations leave the data sitting in the operating system buffer
+cache for a while. The "overwrite" benchmark does random writes that
+update existing keys in the database.
+
+ fillseq : 1.765 micros/op; 62.7 MB/s
+ fillsync : 268.409 micros/op; 0.4 MB/s (10000 ops)
+ fillrandom : 2.460 micros/op; 45.0 MB/s
+ overwrite : 2.380 micros/op; 46.5 MB/s
+
+Each "op" above corresponds to a write of a single key/value pair.
+I.e., a random write benchmark goes at approximately 400,000 writes per second.
+
+Each "fillsync" operation costs much less (0.3 millisecond)
+than a disk seek (typically 10 milliseconds). We suspect that this is
+because the hard disk itself is buffering the update in its memory and
+responding before the data has been written to the platter. This may
+or may not be safe based on whether or not the hard disk has enough
+power to save its memory in the event of a power failure.
+
+## Read performance
+
+We list the performance of reading sequentially in both the forward
+and reverse direction, and also the performance of a random lookup.
+Note that the database created by the benchmark is quite small.
+Therefore the report characterizes the performance of leveldb when the
+working set fits in memory. The cost of reading a piece of data that
+is not present in the operating system buffer cache will be dominated
+by the one or two disk seeks needed to fetch the data from disk.
+Write performance will be mostly unaffected by whether or not the
+working set fits in memory.
+
+ readrandom : 16.677 micros/op; (approximately 60,000 reads per second)
+ readseq : 0.476 micros/op; 232.3 MB/s
+ readreverse : 0.724 micros/op; 152.9 MB/s
+
+LevelDB compacts its underlying storage data in the background to
+improve read performance. The results listed above were done
+immediately after a lot of random writes. The results after
+compactions (which are usually triggered automatically) are better.
+
+ readrandom : 11.602 micros/op; (approximately 85,000 reads per second)
+ readseq : 0.423 micros/op; 261.8 MB/s
+ readreverse : 0.663 micros/op; 166.9 MB/s
+
+Some of the high cost of reads comes from repeated decompression of blocks
+read from disk. If we supply enough cache to the leveldb so it can hold the
+uncompressed blocks in memory, the read performance improves again:
+
+ readrandom : 9.775 micros/op; (approximately 100,000 reads per second before compaction)
+ readrandom : 5.215 micros/op; (approximately 190,000 reads per second after compaction)
+
+## Repository contents
+
+See doc/index.html for more explanation. See doc/impl.html for a brief overview of the implementation.
+
+The public interface is in include/*.h. Callers should not include or
+rely on the details of any other header files in this package. Those
+internal APIs may be changed without warning.
+
+Guide to header files:
+
+* **include/db.h**: Main interface to the DB: Start here
+
+* **include/options.h**: Control over the behavior of an entire database,
+and also control over the behavior of individual reads and writes.
+
+* **include/comparator.h**: Abstraction for user-specified comparison function.
+If you want just bytewise comparison of keys, you can use the default
+comparator, but clients can write their own comparator implementations if they
+want custom ordering (e.g. to handle different character encodings, etc.)
+
+* **include/iterator.h**: Interface for iterating over data. You can get
+an iterator from a DB object.
+
+* **include/write_batch.h**: Interface for atomically applying multiple
+updates to a database.
+
+* **include/slice.h**: A simple module for maintaining a pointer and a
+length into some other byte array.
+
+* **include/status.h**: Status is returned from many of the public interfaces
+and is used to report success and various kinds of errors.
+
+* **include/env.h**:
+Abstraction of the OS environment. A posix implementation of this interface is
+in util/env_posix.cc
+
+* **include/table.h, include/table_builder.h**: Lower-level modules that most
+clients probably won't use directly
diff --git a/TODO b/src/leveldb/TODO
index e603c07137..e603c07137 100644
--- a/TODO
+++ b/src/leveldb/TODO
diff --git a/WINDOWS.md b/src/leveldb/WINDOWS.md
index 5b76c2448f..5b76c2448f 100644
--- a/WINDOWS.md
+++ b/src/leveldb/WINDOWS.md
diff --git a/build_detect_platform b/src/leveldb/build_detect_platform
index a1101c1bda..a1101c1bda 100755
--- a/build_detect_platform
+++ b/src/leveldb/build_detect_platform
diff --git a/db/autocompact_test.cc b/src/leveldb/db/autocompact_test.cc
index d20a2362c3..d20a2362c3 100644
--- a/db/autocompact_test.cc
+++ b/src/leveldb/db/autocompact_test.cc
diff --git a/db/builder.cc b/src/leveldb/db/builder.cc
index f419882197..f419882197 100644
--- a/db/builder.cc
+++ b/src/leveldb/db/builder.cc
diff --git a/db/builder.h b/src/leveldb/db/builder.h
index 62431fcf44..62431fcf44 100644
--- a/db/builder.h
+++ b/src/leveldb/db/builder.h
diff --git a/db/c.cc b/src/leveldb/db/c.cc
index 08ff0ad90a..08ff0ad90a 100644
--- a/db/c.cc
+++ b/src/leveldb/db/c.cc
diff --git a/db/c_test.c b/src/leveldb/db/c_test.c
index 7cd5ee0207..7cd5ee0207 100644
--- a/db/c_test.c
+++ b/src/leveldb/db/c_test.c
diff --git a/db/corruption_test.cc b/src/leveldb/db/corruption_test.cc
index 96afc68913..96afc68913 100644
--- a/db/corruption_test.cc
+++ b/src/leveldb/db/corruption_test.cc
diff --git a/db/db_bench.cc b/src/leveldb/db/db_bench.cc
index 705a170aae..705a170aae 100644
--- a/db/db_bench.cc
+++ b/src/leveldb/db/db_bench.cc
diff --git a/db/db_impl.cc b/src/leveldb/db/db_impl.cc
index 49b95953b4..49b95953b4 100644
--- a/db/db_impl.cc
+++ b/src/leveldb/db/db_impl.cc
diff --git a/db/db_impl.h b/src/leveldb/db/db_impl.h
index cfc998164a..cfc998164a 100644
--- a/db/db_impl.h
+++ b/src/leveldb/db/db_impl.h
diff --git a/db/db_iter.cc b/src/leveldb/db/db_iter.cc
index 3b2035e9e3..3b2035e9e3 100644
--- a/db/db_iter.cc
+++ b/src/leveldb/db/db_iter.cc
diff --git a/db/db_iter.h b/src/leveldb/db/db_iter.h
index 04927e937b..04927e937b 100644
--- a/db/db_iter.h
+++ b/src/leveldb/db/db_iter.h
diff --git a/db/db_test.cc b/src/leveldb/db/db_test.cc
index 0fed9137d5..0fed9137d5 100644
--- a/db/db_test.cc
+++ b/src/leveldb/db/db_test.cc
diff --git a/db/dbformat.cc b/src/leveldb/db/dbformat.cc
index 20a7ca4462..20a7ca4462 100644
--- a/db/dbformat.cc
+++ b/src/leveldb/db/dbformat.cc
diff --git a/db/dbformat.h b/src/leveldb/db/dbformat.h
index ea897b13c0..ea897b13c0 100644
--- a/db/dbformat.h
+++ b/src/leveldb/db/dbformat.h
diff --git a/db/dbformat_test.cc b/src/leveldb/db/dbformat_test.cc
index 5d82f5d313..5d82f5d313 100644
--- a/db/dbformat_test.cc
+++ b/src/leveldb/db/dbformat_test.cc
diff --git a/db/dumpfile.cc b/src/leveldb/db/dumpfile.cc
index 61c47c2ff9..61c47c2ff9 100644
--- a/db/dumpfile.cc
+++ b/src/leveldb/db/dumpfile.cc
diff --git a/db/filename.cc b/src/leveldb/db/filename.cc
index da32946d99..da32946d99 100644
--- a/db/filename.cc
+++ b/src/leveldb/db/filename.cc
diff --git a/db/filename.h b/src/leveldb/db/filename.h
index 87a752605d..87a752605d 100644
--- a/db/filename.h
+++ b/src/leveldb/db/filename.h
diff --git a/db/filename_test.cc b/src/leveldb/db/filename_test.cc
index a32556deaf..a32556deaf 100644
--- a/db/filename_test.cc
+++ b/src/leveldb/db/filename_test.cc
diff --git a/db/leveldb_main.cc b/src/leveldb/db/leveldb_main.cc
index 9f4b7dd70c..9f4b7dd70c 100644
--- a/db/leveldb_main.cc
+++ b/src/leveldb/db/leveldb_main.cc
diff --git a/db/log_format.h b/src/leveldb/db/log_format.h
index a8c06efe18..a8c06efe18 100644
--- a/db/log_format.h
+++ b/src/leveldb/db/log_format.h
diff --git a/db/log_reader.cc b/src/leveldb/db/log_reader.cc
index e44b66c85b..e44b66c85b 100644
--- a/db/log_reader.cc
+++ b/src/leveldb/db/log_reader.cc
diff --git a/db/log_reader.h b/src/leveldb/db/log_reader.h
index 6aff791716..6aff791716 100644
--- a/db/log_reader.h
+++ b/src/leveldb/db/log_reader.h
diff --git a/db/log_test.cc b/src/leveldb/db/log_test.cc
index dcf0562652..dcf0562652 100644
--- a/db/log_test.cc
+++ b/src/leveldb/db/log_test.cc
diff --git a/db/log_writer.cc b/src/leveldb/db/log_writer.cc
index 2da99ac088..2da99ac088 100644
--- a/db/log_writer.cc
+++ b/src/leveldb/db/log_writer.cc
diff --git a/db/log_writer.h b/src/leveldb/db/log_writer.h
index a3a954d967..a3a954d967 100644
--- a/db/log_writer.h
+++ b/src/leveldb/db/log_writer.h
diff --git a/db/memtable.cc b/src/leveldb/db/memtable.cc
index bfec0a7e7a..bfec0a7e7a 100644
--- a/db/memtable.cc
+++ b/src/leveldb/db/memtable.cc
diff --git a/db/memtable.h b/src/leveldb/db/memtable.h
index 92e90bb099..92e90bb099 100644
--- a/db/memtable.h
+++ b/src/leveldb/db/memtable.h
diff --git a/db/repair.cc b/src/leveldb/db/repair.cc
index 4cd4bb047f..4cd4bb047f 100644
--- a/db/repair.cc
+++ b/src/leveldb/db/repair.cc
diff --git a/db/skiplist.h b/src/leveldb/db/skiplist.h
index ed8b092203..ed8b092203 100644
--- a/db/skiplist.h
+++ b/src/leveldb/db/skiplist.h
diff --git a/db/skiplist_test.cc b/src/leveldb/db/skiplist_test.cc
index c78f4b4fb1..c78f4b4fb1 100644
--- a/db/skiplist_test.cc
+++ b/src/leveldb/db/skiplist_test.cc
diff --git a/db/snapshot.h b/src/leveldb/db/snapshot.h
index e7f8fd2c37..e7f8fd2c37 100644
--- a/db/snapshot.h
+++ b/src/leveldb/db/snapshot.h
diff --git a/db/table_cache.cc b/src/leveldb/db/table_cache.cc
index e3d82cd3ea..e3d82cd3ea 100644
--- a/db/table_cache.cc
+++ b/src/leveldb/db/table_cache.cc
diff --git a/db/table_cache.h b/src/leveldb/db/table_cache.h
index 8cf4aaf12d..8cf4aaf12d 100644
--- a/db/table_cache.h
+++ b/src/leveldb/db/table_cache.h
diff --git a/db/version_edit.cc b/src/leveldb/db/version_edit.cc
index f10a2d58b2..f10a2d58b2 100644
--- a/db/version_edit.cc
+++ b/src/leveldb/db/version_edit.cc
diff --git a/db/version_edit.h b/src/leveldb/db/version_edit.h
index eaef77b327..eaef77b327 100644
--- a/db/version_edit.h
+++ b/src/leveldb/db/version_edit.h
diff --git a/db/version_edit_test.cc b/src/leveldb/db/version_edit_test.cc
index 280310b49d..280310b49d 100644
--- a/db/version_edit_test.cc
+++ b/src/leveldb/db/version_edit_test.cc
diff --git a/db/version_set.cc b/src/leveldb/db/version_set.cc
index aa83df55e4..aa83df55e4 100644
--- a/db/version_set.cc
+++ b/src/leveldb/db/version_set.cc
diff --git a/db/version_set.h b/src/leveldb/db/version_set.h
index 8dc14b8e01..8dc14b8e01 100644
--- a/db/version_set.h
+++ b/src/leveldb/db/version_set.h
diff --git a/db/version_set_test.cc b/src/leveldb/db/version_set_test.cc
index 501e34d133..501e34d133 100644
--- a/db/version_set_test.cc
+++ b/src/leveldb/db/version_set_test.cc
diff --git a/db/write_batch.cc b/src/leveldb/db/write_batch.cc
index 33f4a4257e..33f4a4257e 100644
--- a/db/write_batch.cc
+++ b/src/leveldb/db/write_batch.cc
diff --git a/db/write_batch_internal.h b/src/leveldb/db/write_batch_internal.h
index 310a3c8912..310a3c8912 100644
--- a/db/write_batch_internal.h
+++ b/src/leveldb/db/write_batch_internal.h
diff --git a/db/write_batch_test.cc b/src/leveldb/db/write_batch_test.cc
index 9064e3d85e..9064e3d85e 100644
--- a/db/write_batch_test.cc
+++ b/src/leveldb/db/write_batch_test.cc
diff --git a/doc/bench/db_bench_sqlite3.cc b/src/leveldb/doc/bench/db_bench_sqlite3.cc
index e63aaa8dcc..e63aaa8dcc 100644
--- a/doc/bench/db_bench_sqlite3.cc
+++ b/src/leveldb/doc/bench/db_bench_sqlite3.cc
diff --git a/doc/bench/db_bench_tree_db.cc b/src/leveldb/doc/bench/db_bench_tree_db.cc
index 4ca381f11f..4ca381f11f 100644
--- a/doc/bench/db_bench_tree_db.cc
+++ b/src/leveldb/doc/bench/db_bench_tree_db.cc
diff --git a/doc/benchmark.html b/src/leveldb/doc/benchmark.html
index c4639772c1..c4639772c1 100644
--- a/doc/benchmark.html
+++ b/src/leveldb/doc/benchmark.html
diff --git a/doc/doc.css b/src/leveldb/doc/doc.css
index 700c564e43..700c564e43 100644
--- a/doc/doc.css
+++ b/src/leveldb/doc/doc.css
diff --git a/doc/impl.html b/src/leveldb/doc/impl.html
index 6a468be095..6a468be095 100644
--- a/doc/impl.html
+++ b/src/leveldb/doc/impl.html
diff --git a/doc/index.html b/src/leveldb/doc/index.html
index 3ed0ed9d9e..3ed0ed9d9e 100644
--- a/doc/index.html
+++ b/src/leveldb/doc/index.html
diff --git a/doc/log_format.txt b/src/leveldb/doc/log_format.txt
index 4cca5ef6ea..4cca5ef6ea 100644
--- a/doc/log_format.txt
+++ b/src/leveldb/doc/log_format.txt
diff --git a/doc/table_format.txt b/src/leveldb/doc/table_format.txt
index ca8f9b4460..ca8f9b4460 100644
--- a/doc/table_format.txt
+++ b/src/leveldb/doc/table_format.txt
diff --git a/helpers/memenv/memenv.cc b/src/leveldb/helpers/memenv/memenv.cc
index 43ef2e0729..43ef2e0729 100644
--- a/helpers/memenv/memenv.cc
+++ b/src/leveldb/helpers/memenv/memenv.cc
diff --git a/helpers/memenv/memenv.h b/src/leveldb/helpers/memenv/memenv.h
index 03b88de761..03b88de761 100644
--- a/helpers/memenv/memenv.h
+++ b/src/leveldb/helpers/memenv/memenv.h
diff --git a/helpers/memenv/memenv_test.cc b/src/leveldb/helpers/memenv/memenv_test.cc
index a44310fed8..a44310fed8 100644
--- a/helpers/memenv/memenv_test.cc
+++ b/src/leveldb/helpers/memenv/memenv_test.cc
diff --git a/include/leveldb/c.h b/src/leveldb/include/leveldb/c.h
index 1048fe3b86..1048fe3b86 100644
--- a/include/leveldb/c.h
+++ b/src/leveldb/include/leveldb/c.h
diff --git a/include/leveldb/cache.h b/src/leveldb/include/leveldb/cache.h
index 1a201e5e0a..1a201e5e0a 100644
--- a/include/leveldb/cache.h
+++ b/src/leveldb/include/leveldb/cache.h
diff --git a/include/leveldb/comparator.h b/src/leveldb/include/leveldb/comparator.h
index 556b984c76..556b984c76 100644
--- a/include/leveldb/comparator.h
+++ b/src/leveldb/include/leveldb/comparator.h
diff --git a/include/leveldb/db.h b/src/leveldb/include/leveldb/db.h
index 4c169bf22e..4c169bf22e 100644
--- a/include/leveldb/db.h
+++ b/src/leveldb/include/leveldb/db.h
diff --git a/include/leveldb/dumpfile.h b/src/leveldb/include/leveldb/dumpfile.h
index 3f97fda16b..3f97fda16b 100644
--- a/include/leveldb/dumpfile.h
+++ b/src/leveldb/include/leveldb/dumpfile.h
diff --git a/include/leveldb/env.h b/src/leveldb/include/leveldb/env.h
index f709514da6..f709514da6 100644
--- a/include/leveldb/env.h
+++ b/src/leveldb/include/leveldb/env.h
diff --git a/include/leveldb/filter_policy.h b/src/leveldb/include/leveldb/filter_policy.h
index 1fba08001f..1fba08001f 100644
--- a/include/leveldb/filter_policy.h
+++ b/src/leveldb/include/leveldb/filter_policy.h
diff --git a/include/leveldb/iterator.h b/src/leveldb/include/leveldb/iterator.h
index 76aced04bd..76aced04bd 100644
--- a/include/leveldb/iterator.h
+++ b/src/leveldb/include/leveldb/iterator.h
diff --git a/include/leveldb/options.h b/src/leveldb/include/leveldb/options.h
index 7c9b973454..7c9b973454 100644
--- a/include/leveldb/options.h
+++ b/src/leveldb/include/leveldb/options.h
diff --git a/include/leveldb/slice.h b/src/leveldb/include/leveldb/slice.h
index bc367986f7..bc367986f7 100644
--- a/include/leveldb/slice.h
+++ b/src/leveldb/include/leveldb/slice.h
diff --git a/include/leveldb/status.h b/src/leveldb/include/leveldb/status.h
index 11dbd4b47e..11dbd4b47e 100644
--- a/include/leveldb/status.h
+++ b/src/leveldb/include/leveldb/status.h
diff --git a/include/leveldb/table.h b/src/leveldb/include/leveldb/table.h
index a9746c3f5e..a9746c3f5e 100644
--- a/include/leveldb/table.h
+++ b/src/leveldb/include/leveldb/table.h
diff --git a/include/leveldb/table_builder.h b/src/leveldb/include/leveldb/table_builder.h
index 5fd1dc71f1..5fd1dc71f1 100644
--- a/include/leveldb/table_builder.h
+++ b/src/leveldb/include/leveldb/table_builder.h
diff --git a/include/leveldb/write_batch.h b/src/leveldb/include/leveldb/write_batch.h
index ee9aab68e0..ee9aab68e0 100644
--- a/include/leveldb/write_batch.h
+++ b/src/leveldb/include/leveldb/write_batch.h
diff --git a/issues/issue178_test.cc b/src/leveldb/issues/issue178_test.cc
index 1b1cf8bb28..1b1cf8bb28 100644
--- a/issues/issue178_test.cc
+++ b/src/leveldb/issues/issue178_test.cc
diff --git a/issues/issue200_test.cc b/src/leveldb/issues/issue200_test.cc
index 1cec79f443..1cec79f443 100644
--- a/issues/issue200_test.cc
+++ b/src/leveldb/issues/issue200_test.cc
diff --git a/port/README b/src/leveldb/port/README
index 422563e25c..422563e25c 100644
--- a/port/README
+++ b/src/leveldb/port/README
diff --git a/port/atomic_pointer.h b/src/leveldb/port/atomic_pointer.h
index 9bf091f757..9bf091f757 100644
--- a/port/atomic_pointer.h
+++ b/src/leveldb/port/atomic_pointer.h
diff --git a/port/port.h b/src/leveldb/port/port.h
index 4baafa8e22..4baafa8e22 100644
--- a/port/port.h
+++ b/src/leveldb/port/port.h
diff --git a/port/port_example.h b/src/leveldb/port/port_example.h
index ab9e489b32..ab9e489b32 100644
--- a/port/port_example.h
+++ b/src/leveldb/port/port_example.h
diff --git a/port/port_posix.cc b/src/leveldb/port/port_posix.cc
index 5ba127a5b9..5ba127a5b9 100644
--- a/port/port_posix.cc
+++ b/src/leveldb/port/port_posix.cc
diff --git a/port/port_posix.h b/src/leveldb/port/port_posix.h
index ccca9939d3..ccca9939d3 100644
--- a/port/port_posix.h
+++ b/src/leveldb/port/port_posix.h
diff --git a/port/port_win.cc b/src/leveldb/port/port_win.cc
index 1b0f060a19..1b0f060a19 100644
--- a/port/port_win.cc
+++ b/src/leveldb/port/port_win.cc
diff --git a/port/port_win.h b/src/leveldb/port/port_win.h
index 45bf2f0ea7..45bf2f0ea7 100644
--- a/port/port_win.h
+++ b/src/leveldb/port/port_win.h
diff --git a/port/thread_annotations.h b/src/leveldb/port/thread_annotations.h
index 9470ef587c..9470ef587c 100644
--- a/port/thread_annotations.h
+++ b/src/leveldb/port/thread_annotations.h
diff --git a/port/win/stdint.h b/src/leveldb/port/win/stdint.h
index 39edd0db13..39edd0db13 100644
--- a/port/win/stdint.h
+++ b/src/leveldb/port/win/stdint.h
diff --git a/table/block.cc b/src/leveldb/table/block.cc
index 43e402c9c0..43e402c9c0 100644
--- a/table/block.cc
+++ b/src/leveldb/table/block.cc
diff --git a/table/block.h b/src/leveldb/table/block.h
index 2493eb9f9f..2493eb9f9f 100644
--- a/table/block.h
+++ b/src/leveldb/table/block.h
diff --git a/table/block_builder.cc b/src/leveldb/table/block_builder.cc
index db660cd07c..db660cd07c 100644
--- a/table/block_builder.cc
+++ b/src/leveldb/table/block_builder.cc
diff --git a/table/block_builder.h b/src/leveldb/table/block_builder.h
index 4fbcb33972..4fbcb33972 100644
--- a/table/block_builder.h
+++ b/src/leveldb/table/block_builder.h
diff --git a/table/filter_block.cc b/src/leveldb/table/filter_block.cc
index 203e15c8bc..203e15c8bc 100644
--- a/table/filter_block.cc
+++ b/src/leveldb/table/filter_block.cc
diff --git a/table/filter_block.h b/src/leveldb/table/filter_block.h
index c67d010bd1..c67d010bd1 100644
--- a/table/filter_block.h
+++ b/src/leveldb/table/filter_block.h
diff --git a/table/filter_block_test.cc b/src/leveldb/table/filter_block_test.cc
index 8c4a4741f2..8c4a4741f2 100644
--- a/table/filter_block_test.cc
+++ b/src/leveldb/table/filter_block_test.cc
diff --git a/table/format.cc b/src/leveldb/table/format.cc
index aa63144c9e..aa63144c9e 100644
--- a/table/format.cc
+++ b/src/leveldb/table/format.cc
diff --git a/table/format.h b/src/leveldb/table/format.h
index 6c0b80c017..6c0b80c017 100644
--- a/table/format.h
+++ b/src/leveldb/table/format.h
diff --git a/table/iterator.cc b/src/leveldb/table/iterator.cc
index 3d1c87fdec..3d1c87fdec 100644
--- a/table/iterator.cc
+++ b/src/leveldb/table/iterator.cc
diff --git a/table/iterator_wrapper.h b/src/leveldb/table/iterator_wrapper.h
index 9e16b3dbed..9e16b3dbed 100644
--- a/table/iterator_wrapper.h
+++ b/src/leveldb/table/iterator_wrapper.h
diff --git a/table/merger.cc b/src/leveldb/table/merger.cc
index 2dde4dc21f..2dde4dc21f 100644
--- a/table/merger.cc
+++ b/src/leveldb/table/merger.cc
diff --git a/table/merger.h b/src/leveldb/table/merger.h
index 91ddd80faa..91ddd80faa 100644
--- a/table/merger.h
+++ b/src/leveldb/table/merger.h
diff --git a/table/table.cc b/src/leveldb/table/table.cc
index dff8a82590..dff8a82590 100644
--- a/table/table.cc
+++ b/src/leveldb/table/table.cc
diff --git a/table/table_builder.cc b/src/leveldb/table/table_builder.cc
index 62002c84f2..62002c84f2 100644
--- a/table/table_builder.cc
+++ b/src/leveldb/table/table_builder.cc
diff --git a/table/table_test.cc b/src/leveldb/table/table_test.cc
index c723bf84cf..c723bf84cf 100644
--- a/table/table_test.cc
+++ b/src/leveldb/table/table_test.cc
diff --git a/table/two_level_iterator.cc b/src/leveldb/table/two_level_iterator.cc
index 7822ebab9c..7822ebab9c 100644
--- a/table/two_level_iterator.cc
+++ b/src/leveldb/table/two_level_iterator.cc
diff --git a/table/two_level_iterator.h b/src/leveldb/table/two_level_iterator.h
index 629ca34525..629ca34525 100644
--- a/table/two_level_iterator.h
+++ b/src/leveldb/table/two_level_iterator.h
diff --git a/util/arena.cc b/src/leveldb/util/arena.cc
index 9367f71492..9367f71492 100644
--- a/util/arena.cc
+++ b/src/leveldb/util/arena.cc
diff --git a/util/arena.h b/src/leveldb/util/arena.h
index 73bbf1cb9b..73bbf1cb9b 100644
--- a/util/arena.h
+++ b/src/leveldb/util/arena.h
diff --git a/util/arena_test.cc b/src/leveldb/util/arena_test.cc
index 58e870ec44..58e870ec44 100644
--- a/util/arena_test.cc
+++ b/src/leveldb/util/arena_test.cc
diff --git a/util/bloom.cc b/src/leveldb/util/bloom.cc
index a27a2ace28..a27a2ace28 100644
--- a/util/bloom.cc
+++ b/src/leveldb/util/bloom.cc
diff --git a/util/bloom_test.cc b/src/leveldb/util/bloom_test.cc
index 77fb1b3159..77fb1b3159 100644
--- a/util/bloom_test.cc
+++ b/src/leveldb/util/bloom_test.cc
diff --git a/util/cache.cc b/src/leveldb/util/cache.cc
index 8b197bc02a..8b197bc02a 100644
--- a/util/cache.cc
+++ b/src/leveldb/util/cache.cc
diff --git a/util/cache_test.cc b/src/leveldb/util/cache_test.cc
index 43716715a8..43716715a8 100644
--- a/util/cache_test.cc
+++ b/src/leveldb/util/cache_test.cc
diff --git a/util/coding.cc b/src/leveldb/util/coding.cc
index 21e3186d5d..21e3186d5d 100644
--- a/util/coding.cc
+++ b/src/leveldb/util/coding.cc
diff --git a/util/coding.h b/src/leveldb/util/coding.h
index 3993c4a755..3993c4a755 100644
--- a/util/coding.h
+++ b/src/leveldb/util/coding.h
diff --git a/util/coding_test.cc b/src/leveldb/util/coding_test.cc
index 521541ea61..521541ea61 100644
--- a/util/coding_test.cc
+++ b/src/leveldb/util/coding_test.cc
diff --git a/util/comparator.cc b/src/leveldb/util/comparator.cc
index 4b7b5724ef..4b7b5724ef 100644
--- a/util/comparator.cc
+++ b/src/leveldb/util/comparator.cc
diff --git a/util/crc32c.cc b/src/leveldb/util/crc32c.cc
index 6db9e77077..6db9e77077 100644
--- a/util/crc32c.cc
+++ b/src/leveldb/util/crc32c.cc
diff --git a/util/crc32c.h b/src/leveldb/util/crc32c.h
index 1d7e5c075d..1d7e5c075d 100644
--- a/util/crc32c.h
+++ b/src/leveldb/util/crc32c.h
diff --git a/util/crc32c_test.cc b/src/leveldb/util/crc32c_test.cc
index 4b957ee120..4b957ee120 100644
--- a/util/crc32c_test.cc
+++ b/src/leveldb/util/crc32c_test.cc
diff --git a/util/env.cc b/src/leveldb/util/env.cc
index c2600e964a..c2600e964a 100644
--- a/util/env.cc
+++ b/src/leveldb/util/env.cc
diff --git a/util/env_posix.cc b/src/leveldb/util/env_posix.cc
index ba2667864a..ba2667864a 100644
--- a/util/env_posix.cc
+++ b/src/leveldb/util/env_posix.cc
diff --git a/util/env_test.cc b/src/leveldb/util/env_test.cc
index b72cb44384..b72cb44384 100644
--- a/util/env_test.cc
+++ b/src/leveldb/util/env_test.cc
diff --git a/util/env_win.cc b/src/leveldb/util/env_win.cc
index e11a96b791..e11a96b791 100644
--- a/util/env_win.cc
+++ b/src/leveldb/util/env_win.cc
diff --git a/util/filter_policy.cc b/src/leveldb/util/filter_policy.cc
index 7b045c8c91..7b045c8c91 100644
--- a/util/filter_policy.cc
+++ b/src/leveldb/util/filter_policy.cc
diff --git a/util/hash.cc b/src/leveldb/util/hash.cc
index ed439ce7a2..ed439ce7a2 100644
--- a/util/hash.cc
+++ b/src/leveldb/util/hash.cc
diff --git a/util/hash.h b/src/leveldb/util/hash.h
index 8889d56be8..8889d56be8 100644
--- a/util/hash.h
+++ b/src/leveldb/util/hash.h
diff --git a/util/hash_test.cc b/src/leveldb/util/hash_test.cc
index eaa1c92c23..eaa1c92c23 100644
--- a/util/hash_test.cc
+++ b/src/leveldb/util/hash_test.cc
diff --git a/util/histogram.cc b/src/leveldb/util/histogram.cc
index bb95f583ea..bb95f583ea 100644
--- a/util/histogram.cc
+++ b/src/leveldb/util/histogram.cc
diff --git a/util/histogram.h b/src/leveldb/util/histogram.h
index 1ef9f3c8ab..1ef9f3c8ab 100644
--- a/util/histogram.h
+++ b/src/leveldb/util/histogram.h
diff --git a/util/logging.cc b/src/leveldb/util/logging.cc
index ca6b324403..ca6b324403 100644
--- a/util/logging.cc
+++ b/src/leveldb/util/logging.cc
diff --git a/util/logging.h b/src/leveldb/util/logging.h
index 1b450d2480..1b450d2480 100644
--- a/util/logging.h
+++ b/src/leveldb/util/logging.h
diff --git a/util/mutexlock.h b/src/leveldb/util/mutexlock.h
index 1ff5a9efa1..1ff5a9efa1 100644
--- a/util/mutexlock.h
+++ b/src/leveldb/util/mutexlock.h
diff --git a/util/options.cc b/src/leveldb/util/options.cc
index 76af5b9302..76af5b9302 100644
--- a/util/options.cc
+++ b/src/leveldb/util/options.cc
diff --git a/util/posix_logger.h b/src/leveldb/util/posix_logger.h
index c063c2b7cb..c063c2b7cb 100644
--- a/util/posix_logger.h
+++ b/src/leveldb/util/posix_logger.h
diff --git a/util/random.h b/src/leveldb/util/random.h
index ddd51b1c7b..ddd51b1c7b 100644
--- a/util/random.h
+++ b/src/leveldb/util/random.h
diff --git a/util/status.cc b/src/leveldb/util/status.cc
index a44f35b314..a44f35b314 100644
--- a/util/status.cc
+++ b/src/leveldb/util/status.cc
diff --git a/util/testharness.cc b/src/leveldb/util/testharness.cc
index 402fab34d7..402fab34d7 100644
--- a/util/testharness.cc
+++ b/src/leveldb/util/testharness.cc
diff --git a/util/testharness.h b/src/leveldb/util/testharness.h
index da4fe68bb4..da4fe68bb4 100644
--- a/util/testharness.h
+++ b/src/leveldb/util/testharness.h
diff --git a/util/testutil.cc b/src/leveldb/util/testutil.cc
index bee56bf75f..bee56bf75f 100644
--- a/util/testutil.cc
+++ b/src/leveldb/util/testutil.cc
diff --git a/util/testutil.h b/src/leveldb/util/testutil.h
index adad3fc1ea..adad3fc1ea 100644
--- a/util/testutil.h
+++ b/src/leveldb/util/testutil.h
diff --git a/src/leveldbwrapper.cpp b/src/leveldbwrapper.cpp
new file mode 100644
index 0000000000..26cacf95ae
--- /dev/null
+++ b/src/leveldbwrapper.cpp
@@ -0,0 +1,89 @@
+// Copyright (c) 2012-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "leveldbwrapper.h"
+
+#include "util.h"
+
+#include <boost/filesystem.hpp>
+
+#include <leveldb/cache.h>
+#include <leveldb/env.h>
+#include <leveldb/filter_policy.h>
+#include <memenv.h>
+
+void HandleError(const leveldb::Status& status) throw(leveldb_error)
+{
+ if (status.ok())
+ return;
+ LogPrintf("%s\n", status.ToString());
+ if (status.IsCorruption())
+ throw leveldb_error("Database corrupted");
+ if (status.IsIOError())
+ throw leveldb_error("Database I/O error");
+ if (status.IsNotFound())
+ throw leveldb_error("Database entry missing");
+ throw leveldb_error("Unknown database error");
+}
+
+static leveldb::Options GetOptions(size_t nCacheSize)
+{
+ leveldb::Options options;
+ options.block_cache = leveldb::NewLRUCache(nCacheSize / 2);
+ options.write_buffer_size = nCacheSize / 4; // up to two write buffers may be held in memory simultaneously
+ options.filter_policy = leveldb::NewBloomFilterPolicy(10);
+ options.compression = leveldb::kNoCompression;
+ options.max_open_files = 64;
+ if (leveldb::kMajorVersion > 1 || (leveldb::kMajorVersion == 1 && leveldb::kMinorVersion >= 16)) {
+ // LevelDB versions before 1.16 consider short writes to be corruption. Only trigger error
+ // on corruption in later versions.
+ options.paranoid_checks = true;
+ }
+ return options;
+}
+
+CLevelDBWrapper::CLevelDBWrapper(const boost::filesystem::path& path, size_t nCacheSize, bool fMemory, bool fWipe)
+{
+ penv = NULL;
+ readoptions.verify_checksums = true;
+ iteroptions.verify_checksums = true;
+ iteroptions.fill_cache = false;
+ syncoptions.sync = true;
+ options = GetOptions(nCacheSize);
+ options.create_if_missing = true;
+ if (fMemory) {
+ penv = leveldb::NewMemEnv(leveldb::Env::Default());
+ options.env = penv;
+ } else {
+ if (fWipe) {
+ LogPrintf("Wiping LevelDB in %s\n", path.string());
+ leveldb::Status result = leveldb::DestroyDB(path.string(), options);
+ HandleError(result);
+ }
+ TryCreateDirectory(path);
+ LogPrintf("Opening LevelDB in %s\n", path.string());
+ }
+ leveldb::Status status = leveldb::DB::Open(options, path.string(), &pdb);
+ HandleError(status);
+ LogPrintf("Opened LevelDB successfully\n");
+}
+
+CLevelDBWrapper::~CLevelDBWrapper()
+{
+ delete pdb;
+ pdb = NULL;
+ delete options.filter_policy;
+ options.filter_policy = NULL;
+ delete options.block_cache;
+ options.block_cache = NULL;
+ delete penv;
+ options.env = NULL;
+}
+
+bool CLevelDBWrapper::WriteBatch(CLevelDBBatch& batch, bool fSync) throw(leveldb_error)
+{
+ leveldb::Status status = pdb->Write(fSync ? syncoptions : writeoptions, &batch.batch);
+ HandleError(status);
+ return true;
+}
diff --git a/src/leveldbwrapper.h b/src/leveldbwrapper.h
new file mode 100644
index 0000000000..c65e842704
--- /dev/null
+++ b/src/leveldbwrapper.h
@@ -0,0 +1,173 @@
+// Copyright (c) 2012-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_LEVELDBWRAPPER_H
+#define BITCOIN_LEVELDBWRAPPER_H
+
+#include "clientversion.h"
+#include "serialize.h"
+#include "streams.h"
+#include "util.h"
+#include "version.h"
+
+#include <boost/filesystem/path.hpp>
+
+#include <leveldb/db.h>
+#include <leveldb/write_batch.h>
+
+class leveldb_error : public std::runtime_error
+{
+public:
+ leveldb_error(const std::string& msg) : std::runtime_error(msg) {}
+};
+
+void HandleError(const leveldb::Status& status) throw(leveldb_error);
+
+/** Batch of changes queued to be written to a CLevelDBWrapper */
+class CLevelDBBatch
+{
+ friend class CLevelDBWrapper;
+
+private:
+ leveldb::WriteBatch batch;
+
+public:
+ template <typename K, typename V>
+ void Write(const K& key, const V& value)
+ {
+ CDataStream ssKey(SER_DISK, CLIENT_VERSION);
+ ssKey.reserve(ssKey.GetSerializeSize(key));
+ ssKey << key;
+ leveldb::Slice slKey(&ssKey[0], ssKey.size());
+
+ CDataStream ssValue(SER_DISK, CLIENT_VERSION);
+ ssValue.reserve(ssValue.GetSerializeSize(value));
+ ssValue << value;
+ leveldb::Slice slValue(&ssValue[0], ssValue.size());
+
+ batch.Put(slKey, slValue);
+ }
+
+ template <typename K>
+ void Erase(const K& key)
+ {
+ CDataStream ssKey(SER_DISK, CLIENT_VERSION);
+ ssKey.reserve(ssKey.GetSerializeSize(key));
+ ssKey << key;
+ leveldb::Slice slKey(&ssKey[0], ssKey.size());
+
+ batch.Delete(slKey);
+ }
+};
+
+class CLevelDBWrapper
+{
+private:
+ //! custom environment this database is using (may be NULL in case of default environment)
+ leveldb::Env* penv;
+
+ //! database options used
+ leveldb::Options options;
+
+ //! options used when reading from the database
+ leveldb::ReadOptions readoptions;
+
+ //! options used when iterating over values of the database
+ leveldb::ReadOptions iteroptions;
+
+ //! options used when writing to the database
+ leveldb::WriteOptions writeoptions;
+
+ //! options used when sync writing to the database
+ leveldb::WriteOptions syncoptions;
+
+ //! the database itself
+ leveldb::DB* pdb;
+
+public:
+ CLevelDBWrapper(const boost::filesystem::path& path, size_t nCacheSize, bool fMemory = false, bool fWipe = false);
+ ~CLevelDBWrapper();
+
+ template <typename K, typename V>
+ bool Read(const K& key, V& value) const throw(leveldb_error)
+ {
+ CDataStream ssKey(SER_DISK, CLIENT_VERSION);
+ ssKey.reserve(ssKey.GetSerializeSize(key));
+ ssKey << key;
+ leveldb::Slice slKey(&ssKey[0], ssKey.size());
+
+ std::string strValue;
+ leveldb::Status status = pdb->Get(readoptions, slKey, &strValue);
+ if (!status.ok()) {
+ if (status.IsNotFound())
+ return false;
+ LogPrintf("LevelDB read failure: %s\n", status.ToString());
+ HandleError(status);
+ }
+ try {
+ CDataStream ssValue(strValue.data(), strValue.data() + strValue.size(), SER_DISK, CLIENT_VERSION);
+ ssValue >> value;
+ } catch (const std::exception&) {
+ return false;
+ }
+ return true;
+ }
+
+ template <typename K, typename V>
+ bool Write(const K& key, const V& value, bool fSync = false) throw(leveldb_error)
+ {
+ CLevelDBBatch batch;
+ batch.Write(key, value);
+ return WriteBatch(batch, fSync);
+ }
+
+ template <typename K>
+ bool Exists(const K& key) const throw(leveldb_error)
+ {
+ CDataStream ssKey(SER_DISK, CLIENT_VERSION);
+ ssKey.reserve(ssKey.GetSerializeSize(key));
+ ssKey << key;
+ leveldb::Slice slKey(&ssKey[0], ssKey.size());
+
+ std::string strValue;
+ leveldb::Status status = pdb->Get(readoptions, slKey, &strValue);
+ if (!status.ok()) {
+ if (status.IsNotFound())
+ return false;
+ LogPrintf("LevelDB read failure: %s\n", status.ToString());
+ HandleError(status);
+ }
+ return true;
+ }
+
+ template <typename K>
+ bool Erase(const K& key, bool fSync = false) throw(leveldb_error)
+ {
+ CLevelDBBatch batch;
+ batch.Erase(key);
+ return WriteBatch(batch, fSync);
+ }
+
+ bool WriteBatch(CLevelDBBatch& batch, bool fSync = false) throw(leveldb_error);
+
+ // not available for LevelDB; provide for compatibility with BDB
+ bool Flush()
+ {
+ return true;
+ }
+
+ bool Sync() throw(leveldb_error)
+ {
+ CLevelDBBatch batch;
+ return WriteBatch(batch, true);
+ }
+
+ // not exactly clean encapsulation, but it's easiest for now
+ leveldb::Iterator* NewIterator()
+ {
+ return pdb->NewIterator(iteroptions);
+ }
+};
+
+#endif // BITCOIN_LEVELDBWRAPPER_H
diff --git a/src/limitedmap.h b/src/limitedmap.h
new file mode 100644
index 0000000000..e8ea549653
--- /dev/null
+++ b/src/limitedmap.h
@@ -0,0 +1,94 @@
+// Copyright (c) 2012-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_LIMITEDMAP_H
+#define BITCOIN_LIMITEDMAP_H
+
+#include <assert.h>
+#include <map>
+
+/** STL-like map container that only keeps the N elements with the highest value. */
+template <typename K, typename V>
+class limitedmap
+{
+public:
+ typedef K key_type;
+ typedef V mapped_type;
+ typedef std::pair<const key_type, mapped_type> value_type;
+ typedef typename std::map<K, V>::const_iterator const_iterator;
+ typedef typename std::map<K, V>::size_type size_type;
+
+protected:
+ std::map<K, V> map;
+ typedef typename std::map<K, V>::iterator iterator;
+ std::multimap<V, iterator> rmap;
+ typedef typename std::multimap<V, iterator>::iterator rmap_iterator;
+ size_type nMaxSize;
+
+public:
+ limitedmap(size_type nMaxSizeIn = 0) { nMaxSize = nMaxSizeIn; }
+ const_iterator begin() const { return map.begin(); }
+ const_iterator end() const { return map.end(); }
+ size_type size() const { return map.size(); }
+ bool empty() const { return map.empty(); }
+ const_iterator find(const key_type& k) const { return map.find(k); }
+ size_type count(const key_type& k) const { return map.count(k); }
+ void insert(const value_type& x)
+ {
+ std::pair<iterator, bool> ret = map.insert(x);
+ if (ret.second) {
+ if (nMaxSize && map.size() == nMaxSize) {
+ map.erase(rmap.begin()->second);
+ rmap.erase(rmap.begin());
+ }
+ rmap.insert(make_pair(x.second, ret.first));
+ }
+ return;
+ }
+ void erase(const key_type& k)
+ {
+ iterator itTarget = map.find(k);
+ if (itTarget == map.end())
+ return;
+ std::pair<rmap_iterator, rmap_iterator> itPair = rmap.equal_range(itTarget->second);
+ for (rmap_iterator it = itPair.first; it != itPair.second; ++it)
+ if (it->second == itTarget) {
+ rmap.erase(it);
+ map.erase(itTarget);
+ return;
+ }
+ // Shouldn't ever get here
+ assert(0);
+ }
+ void update(const_iterator itIn, const mapped_type& v)
+ {
+ // TODO: When we switch to C++11, use map.erase(itIn, itIn) to get the non-const iterator.
+ iterator itTarget = map.find(itIn->first);
+ if (itTarget == map.end())
+ return;
+ std::pair<rmap_iterator, rmap_iterator> itPair = rmap.equal_range(itTarget->second);
+ for (rmap_iterator it = itPair.first; it != itPair.second; ++it)
+ if (it->second == itTarget) {
+ rmap.erase(it);
+ itTarget->second = v;
+ rmap.insert(make_pair(v, itTarget));
+ return;
+ }
+ // Shouldn't ever get here
+ assert(0);
+ }
+ size_type max_size() const { return nMaxSize; }
+ size_type max_size(size_type s)
+ {
+ if (s)
+ while (map.size() > s) {
+ map.erase(rmap.begin()->second);
+ rmap.erase(rmap.begin());
+ }
+ nMaxSize = s;
+ return nMaxSize;
+ }
+};
+
+#endif // BITCOIN_LIMITEDMAP_H
diff --git a/src/main.cpp b/src/main.cpp
new file mode 100644
index 0000000000..621fd720e6
--- /dev/null
+++ b/src/main.cpp
@@ -0,0 +1,5205 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "main.h"
+
+#include "addrman.h"
+#include "alert.h"
+#include "arith_uint256.h"
+#include "chainparams.h"
+#include "checkpoints.h"
+#include "checkqueue.h"
+#include "consensus/validation.h"
+#include "init.h"
+#include "merkleblock.h"
+#include "net.h"
+#include "pow.h"
+#include "txdb.h"
+#include "txmempool.h"
+#include "ui_interface.h"
+#include "undo.h"
+#include "util.h"
+#include "utilmoneystr.h"
+#include "validationinterface.h"
+
+#include <sstream>
+
+#include <boost/algorithm/string/replace.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/filesystem/fstream.hpp>
+#include <boost/math/distributions/poisson.hpp>
+#include <boost/thread.hpp>
+
+using namespace std;
+
+#if defined(NDEBUG)
+# error "Bitcoin cannot be compiled without assertions."
+#endif
+
+/**
+ * Global state
+ */
+
+CCriticalSection cs_main;
+
+BlockMap mapBlockIndex;
+CChain chainActive;
+CBlockIndex *pindexBestHeader = NULL;
+int64_t nTimeBestReceived = 0;
+CWaitableCriticalSection csBestBlock;
+CConditionVariable cvBlockChange;
+int nScriptCheckThreads = 0;
+bool fImporting = false;
+bool fReindex = false;
+bool fTxIndex = false;
+bool fHavePruned = false;
+bool fPruneMode = false;
+bool fIsBareMultisigStd = true;
+bool fCheckBlockIndex = false;
+bool fCheckpointsEnabled = true;
+size_t nCoinCacheUsage = 5000 * 300;
+uint64_t nPruneTarget = 0;
+bool fAlerts = DEFAULT_ALERTS;
+
+/** Fees smaller than this (in satoshi) are considered zero fee (for relaying and mining) */
+CFeeRate minRelayTxFee = CFeeRate(5000);
+
+CTxMemPool mempool(::minRelayTxFee);
+
+struct COrphanTx {
+ CTransaction tx;
+ NodeId fromPeer;
+};
+map<uint256, COrphanTx> mapOrphanTransactions;
+map<uint256, set<uint256> > mapOrphanTransactionsByPrev;
+void EraseOrphansFor(NodeId peer);
+
+/**
+ * Returns true if there are nRequired or more blocks of minVersion or above
+ * in the last Consensus::Params::nMajorityWindow blocks, starting at pstart and going backwards.
+ */
+static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned nRequired, const Consensus::Params& consensusParams);
+static void CheckBlockIndex();
+
+/** Constant stuff for coinbase transactions we create: */
+CScript COINBASE_FLAGS;
+
+const string strMessageMagic = "Bitcoin Signed Message:\n";
+
+// Internal stuff
+namespace {
+
+ struct CBlockIndexWorkComparator
+ {
+ bool operator()(CBlockIndex *pa, CBlockIndex *pb) const {
+ // First sort by most total work, ...
+ if (pa->nChainWork > pb->nChainWork) return false;
+ if (pa->nChainWork < pb->nChainWork) return true;
+
+ // ... then by earliest time received, ...
+ if (pa->nSequenceId < pb->nSequenceId) return false;
+ if (pa->nSequenceId > pb->nSequenceId) return true;
+
+ // Use pointer address as tie breaker (should only happen with blocks
+ // loaded from disk, as those all have id 0).
+ if (pa < pb) return false;
+ if (pa > pb) return true;
+
+ // Identical blocks.
+ return false;
+ }
+ };
+
+ CBlockIndex *pindexBestInvalid;
+
+ /**
+ * The set of all CBlockIndex entries with BLOCK_VALID_TRANSACTIONS (for itself and all ancestors) and
+ * as good as our current tip or better. Entries may be failed, though, and pruning nodes may be
+ * missing the data for the block.
+ */
+ set<CBlockIndex*, CBlockIndexWorkComparator> setBlockIndexCandidates;
+ /** Number of nodes with fSyncStarted. */
+ int nSyncStarted = 0;
+ /** All pairs A->B, where A (or one if its ancestors) misses transactions, but B has transactions.
+ * Pruned nodes may have entries where B is missing data.
+ */
+ multimap<CBlockIndex*, CBlockIndex*> mapBlocksUnlinked;
+
+ CCriticalSection cs_LastBlockFile;
+ std::vector<CBlockFileInfo> vinfoBlockFile;
+ int nLastBlockFile = 0;
+ /** Global flag to indicate we should check to see if there are
+ * block/undo files that should be deleted. Set on startup
+ * or if we allocate more file space when we're in prune mode
+ */
+ bool fCheckForPruning = false;
+
+ /**
+ * Every received block is assigned a unique and increasing identifier, so we
+ * know which one to give priority in case of a fork.
+ */
+ CCriticalSection cs_nBlockSequenceId;
+ /** Blocks loaded from disk are assigned id 0, so start the counter at 1. */
+ uint32_t nBlockSequenceId = 1;
+
+ /**
+ * Sources of received blocks, saved to be able to send them reject
+ * messages or ban them when processing happens afterwards. Protected by
+ * cs_main.
+ */
+ map<uint256, NodeId> mapBlockSource;
+
+ /**
+ * Filter for transactions that were recently rejected by
+ * AcceptToMemoryPool. These are not rerequested until the chain tip
+ * changes, at which point the entire filter is reset. Protected by
+ * cs_main.
+ *
+ * Without this filter we'd be re-requesting txs from each of our peers,
+ * increasing bandwidth consumption considerably. For instance, with 100
+ * peers, half of which relay a tx we don't accept, that might be a 50x
+ * bandwidth increase. A flooding attacker attempting to roll-over the
+ * filter using minimum-sized, 60byte, transactions might manage to send
+ * 1000/sec if we have fast peers, so we pick 120,000 to give our peers a
+ * two minute window to send invs to us.
+ *
+ * Decreasing the false positive rate is fairly cheap, so we pick one in a
+ * million to make it highly unlikely for users to have issues with this
+ * filter.
+ *
+ * Memory used: 1.7MB
+ */
+ boost::scoped_ptr<CRollingBloomFilter> recentRejects;
+ uint256 hashRecentRejectsChainTip;
+
+ /** Blocks that are in flight, and that are in the queue to be downloaded. Protected by cs_main. */
+ struct QueuedBlock {
+ uint256 hash;
+ CBlockIndex *pindex; //! Optional.
+ int64_t nTime; //! Time of "getdata" request in microseconds.
+ bool fValidatedHeaders; //! Whether this block has validated headers at the time of request.
+ int64_t nTimeDisconnect; //! The timeout for this block request (for disconnecting a slow peer)
+ };
+ map<uint256, pair<NodeId, list<QueuedBlock>::iterator> > mapBlocksInFlight;
+
+ /** Number of blocks in flight with validated headers. */
+ int nQueuedValidatedHeaders = 0;
+
+ /** Number of preferable block download peers. */
+ int nPreferredDownload = 0;
+
+ /** Dirty block index entries. */
+ set<CBlockIndex*> setDirtyBlockIndex;
+
+ /** Dirty block file entries. */
+ set<int> setDirtyFileInfo;
+} // anon namespace
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// Registration of network node signals.
+//
+
+namespace {
+
+struct CBlockReject {
+ unsigned char chRejectCode;
+ string strRejectReason;
+ uint256 hashBlock;
+};
+
+/**
+ * Maintain validation-specific state about nodes, protected by cs_main, instead
+ * by CNode's own locks. This simplifies asynchronous operation, where
+ * processing of incoming data is done after the ProcessMessage call returns,
+ * and we're no longer holding the node's locks.
+ */
+struct CNodeState {
+ //! The peer's address
+ CService address;
+ //! Whether we have a fully established connection.
+ bool fCurrentlyConnected;
+ //! Accumulated misbehaviour score for this peer.
+ int nMisbehavior;
+ //! Whether this peer should be disconnected and banned (unless whitelisted).
+ bool fShouldBan;
+ //! String name of this peer (debugging/logging purposes).
+ std::string name;
+ //! List of asynchronously-determined block rejections to notify this peer about.
+ std::vector<CBlockReject> rejects;
+ //! The best known block we know this peer has announced.
+ CBlockIndex *pindexBestKnownBlock;
+ //! The hash of the last unknown block this peer has announced.
+ uint256 hashLastUnknownBlock;
+ //! The last full block we both have.
+ CBlockIndex *pindexLastCommonBlock;
+ //! Whether we've started headers synchronization with this peer.
+ bool fSyncStarted;
+ //! Since when we're stalling block download progress (in microseconds), or 0.
+ int64_t nStallingSince;
+ list<QueuedBlock> vBlocksInFlight;
+ int nBlocksInFlight;
+ int nBlocksInFlightValidHeaders;
+ //! Whether we consider this a preferred download peer.
+ bool fPreferredDownload;
+
+ CNodeState() {
+ fCurrentlyConnected = false;
+ nMisbehavior = 0;
+ fShouldBan = false;
+ pindexBestKnownBlock = NULL;
+ hashLastUnknownBlock.SetNull();
+ pindexLastCommonBlock = NULL;
+ fSyncStarted = false;
+ nStallingSince = 0;
+ nBlocksInFlight = 0;
+ nBlocksInFlightValidHeaders = 0;
+ fPreferredDownload = false;
+ }
+};
+
+/** Map maintaining per-node state. Requires cs_main. */
+map<NodeId, CNodeState> mapNodeState;
+
+// Requires cs_main.
+CNodeState *State(NodeId pnode) {
+ map<NodeId, CNodeState>::iterator it = mapNodeState.find(pnode);
+ if (it == mapNodeState.end())
+ return NULL;
+ return &it->second;
+}
+
+int GetHeight()
+{
+ LOCK(cs_main);
+ return chainActive.Height();
+}
+
+void UpdatePreferredDownload(CNode* node, CNodeState* state)
+{
+ nPreferredDownload -= state->fPreferredDownload;
+
+ // Whether this node should be marked as a preferred download node.
+ state->fPreferredDownload = (!node->fInbound || node->fWhitelisted) && !node->fOneShot && !node->fClient;
+
+ nPreferredDownload += state->fPreferredDownload;
+}
+
+// Returns time at which to timeout block request (nTime in microseconds)
+int64_t GetBlockTimeout(int64_t nTime, int nValidatedQueuedBefore, const Consensus::Params &consensusParams)
+{
+ return nTime + 500000 * consensusParams.nPowTargetSpacing * (4 + nValidatedQueuedBefore);
+}
+
+void InitializeNode(NodeId nodeid, const CNode *pnode) {
+ LOCK(cs_main);
+ CNodeState &state = mapNodeState.insert(std::make_pair(nodeid, CNodeState())).first->second;
+ state.name = pnode->addrName;
+ state.address = pnode->addr;
+}
+
+void FinalizeNode(NodeId nodeid) {
+ LOCK(cs_main);
+ CNodeState *state = State(nodeid);
+
+ if (state->fSyncStarted)
+ nSyncStarted--;
+
+ if (state->nMisbehavior == 0 && state->fCurrentlyConnected) {
+ AddressCurrentlyConnected(state->address);
+ }
+
+ BOOST_FOREACH(const QueuedBlock& entry, state->vBlocksInFlight)
+ mapBlocksInFlight.erase(entry.hash);
+ EraseOrphansFor(nodeid);
+ nPreferredDownload -= state->fPreferredDownload;
+
+ mapNodeState.erase(nodeid);
+}
+
+// Requires cs_main.
+// Returns a bool indicating whether we requested this block.
+bool MarkBlockAsReceived(const uint256& hash) {
+ map<uint256, pair<NodeId, list<QueuedBlock>::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash);
+ if (itInFlight != mapBlocksInFlight.end()) {
+ CNodeState *state = State(itInFlight->second.first);
+ nQueuedValidatedHeaders -= itInFlight->second.second->fValidatedHeaders;
+ state->nBlocksInFlightValidHeaders -= itInFlight->second.second->fValidatedHeaders;
+ state->vBlocksInFlight.erase(itInFlight->second.second);
+ state->nBlocksInFlight--;
+ state->nStallingSince = 0;
+ mapBlocksInFlight.erase(itInFlight);
+ return true;
+ }
+ return false;
+}
+
+// Requires cs_main.
+void MarkBlockAsInFlight(NodeId nodeid, const uint256& hash, const Consensus::Params& consensusParams, CBlockIndex *pindex = NULL) {
+ CNodeState *state = State(nodeid);
+ assert(state != NULL);
+
+ // Make sure it's not listed somewhere already.
+ MarkBlockAsReceived(hash);
+
+ int64_t nNow = GetTimeMicros();
+ QueuedBlock newentry = {hash, pindex, nNow, pindex != NULL, GetBlockTimeout(nNow, nQueuedValidatedHeaders, consensusParams)};
+ nQueuedValidatedHeaders += newentry.fValidatedHeaders;
+ list<QueuedBlock>::iterator it = state->vBlocksInFlight.insert(state->vBlocksInFlight.end(), newentry);
+ state->nBlocksInFlight++;
+ state->nBlocksInFlightValidHeaders += newentry.fValidatedHeaders;
+ mapBlocksInFlight[hash] = std::make_pair(nodeid, it);
+}
+
+/** Check whether the last unknown block a peer advertized is not yet known. */
+void ProcessBlockAvailability(NodeId nodeid) {
+ CNodeState *state = State(nodeid);
+ assert(state != NULL);
+
+ if (!state->hashLastUnknownBlock.IsNull()) {
+ BlockMap::iterator itOld = mapBlockIndex.find(state->hashLastUnknownBlock);
+ if (itOld != mapBlockIndex.end() && itOld->second->nChainWork > 0) {
+ if (state->pindexBestKnownBlock == NULL || itOld->second->nChainWork >= state->pindexBestKnownBlock->nChainWork)
+ state->pindexBestKnownBlock = itOld->second;
+ state->hashLastUnknownBlock.SetNull();
+ }
+ }
+}
+
+/** Update tracking information about which blocks a peer is assumed to have. */
+void UpdateBlockAvailability(NodeId nodeid, const uint256 &hash) {
+ CNodeState *state = State(nodeid);
+ assert(state != NULL);
+
+ ProcessBlockAvailability(nodeid);
+
+ BlockMap::iterator it = mapBlockIndex.find(hash);
+ if (it != mapBlockIndex.end() && it->second->nChainWork > 0) {
+ // An actually better block was announced.
+ if (state->pindexBestKnownBlock == NULL || it->second->nChainWork >= state->pindexBestKnownBlock->nChainWork)
+ state->pindexBestKnownBlock = it->second;
+ } else {
+ // An unknown block was announced; just assume that the latest one is the best one.
+ state->hashLastUnknownBlock = hash;
+ }
+}
+
+/** Find the last common ancestor two blocks have.
+ * Both pa and pb must be non-NULL. */
+CBlockIndex* LastCommonAncestor(CBlockIndex* pa, CBlockIndex* pb) {
+ if (pa->nHeight > pb->nHeight) {
+ pa = pa->GetAncestor(pb->nHeight);
+ } else if (pb->nHeight > pa->nHeight) {
+ pb = pb->GetAncestor(pa->nHeight);
+ }
+
+ while (pa != pb && pa && pb) {
+ pa = pa->pprev;
+ pb = pb->pprev;
+ }
+
+ // Eventually all chain branches meet at the genesis block.
+ assert(pa == pb);
+ return pa;
+}
+
+/** Update pindexLastCommonBlock and add not-in-flight missing successors to vBlocks, until it has
+ * at most count entries. */
+void FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vector<CBlockIndex*>& vBlocks, NodeId& nodeStaller) {
+ if (count == 0)
+ return;
+
+ vBlocks.reserve(vBlocks.size() + count);
+ CNodeState *state = State(nodeid);
+ assert(state != NULL);
+
+ // Make sure pindexBestKnownBlock is up to date, we'll need it.
+ ProcessBlockAvailability(nodeid);
+
+ if (state->pindexBestKnownBlock == NULL || state->pindexBestKnownBlock->nChainWork < chainActive.Tip()->nChainWork) {
+ // This peer has nothing interesting.
+ return;
+ }
+
+ if (state->pindexLastCommonBlock == NULL) {
+ // Bootstrap quickly by guessing a parent of our best tip is the forking point.
+ // Guessing wrong in either direction is not a problem.
+ state->pindexLastCommonBlock = chainActive[std::min(state->pindexBestKnownBlock->nHeight, chainActive.Height())];
+ }
+
+ // If the peer reorganized, our previous pindexLastCommonBlock may not be an ancestor
+ // of its current tip anymore. Go back enough to fix that.
+ state->pindexLastCommonBlock = LastCommonAncestor(state->pindexLastCommonBlock, state->pindexBestKnownBlock);
+ if (state->pindexLastCommonBlock == state->pindexBestKnownBlock)
+ return;
+
+ std::vector<CBlockIndex*> vToFetch;
+ CBlockIndex *pindexWalk = state->pindexLastCommonBlock;
+ // Never fetch further than the best block we know the peer has, or more than BLOCK_DOWNLOAD_WINDOW + 1 beyond the last
+ // linked block we have in common with this peer. The +1 is so we can detect stalling, namely if we would be able to
+ // download that next block if the window were 1 larger.
+ int nWindowEnd = state->pindexLastCommonBlock->nHeight + BLOCK_DOWNLOAD_WINDOW;
+ int nMaxHeight = std::min<int>(state->pindexBestKnownBlock->nHeight, nWindowEnd + 1);
+ NodeId waitingfor = -1;
+ while (pindexWalk->nHeight < nMaxHeight) {
+ // Read up to 128 (or more, if more blocks than that are needed) successors of pindexWalk (towards
+ // pindexBestKnownBlock) into vToFetch. We fetch 128, because CBlockIndex::GetAncestor may be as expensive
+ // as iterating over ~100 CBlockIndex* entries anyway.
+ int nToFetch = std::min(nMaxHeight - pindexWalk->nHeight, std::max<int>(count - vBlocks.size(), 128));
+ vToFetch.resize(nToFetch);
+ pindexWalk = state->pindexBestKnownBlock->GetAncestor(pindexWalk->nHeight + nToFetch);
+ vToFetch[nToFetch - 1] = pindexWalk;
+ for (unsigned int i = nToFetch - 1; i > 0; i--) {
+ vToFetch[i - 1] = vToFetch[i]->pprev;
+ }
+
+ // Iterate over those blocks in vToFetch (in forward direction), adding the ones that
+ // are not yet downloaded and not in flight to vBlocks. In the mean time, update
+ // pindexLastCommonBlock as long as all ancestors are already downloaded, or if it's
+ // already part of our chain (and therefore don't need it even if pruned).
+ BOOST_FOREACH(CBlockIndex* pindex, vToFetch) {
+ if (!pindex->IsValid(BLOCK_VALID_TREE)) {
+ // We consider the chain that this peer is on invalid.
+ return;
+ }
+ if (pindex->nStatus & BLOCK_HAVE_DATA || chainActive.Contains(pindex)) {
+ if (pindex->nChainTx)
+ state->pindexLastCommonBlock = pindex;
+ } else if (mapBlocksInFlight.count(pindex->GetBlockHash()) == 0) {
+ // The block is not already downloaded, and not yet in flight.
+ if (pindex->nHeight > nWindowEnd) {
+ // We reached the end of the window.
+ if (vBlocks.size() == 0 && waitingfor != nodeid) {
+ // We aren't able to fetch anything, but we would be if the download window was one larger.
+ nodeStaller = waitingfor;
+ }
+ return;
+ }
+ vBlocks.push_back(pindex);
+ if (vBlocks.size() == count) {
+ return;
+ }
+ } else if (waitingfor == -1) {
+ // This is the first already-in-flight block.
+ waitingfor = mapBlocksInFlight[pindex->GetBlockHash()].first;
+ }
+ }
+ }
+}
+
+} // anon namespace
+
+bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats) {
+ LOCK(cs_main);
+ CNodeState *state = State(nodeid);
+ if (state == NULL)
+ return false;
+ stats.nMisbehavior = state->nMisbehavior;
+ stats.nSyncHeight = state->pindexBestKnownBlock ? state->pindexBestKnownBlock->nHeight : -1;
+ stats.nCommonHeight = state->pindexLastCommonBlock ? state->pindexLastCommonBlock->nHeight : -1;
+ BOOST_FOREACH(const QueuedBlock& queue, state->vBlocksInFlight) {
+ if (queue.pindex)
+ stats.vHeightInFlight.push_back(queue.pindex->nHeight);
+ }
+ return true;
+}
+
+void RegisterNodeSignals(CNodeSignals& nodeSignals)
+{
+ nodeSignals.GetHeight.connect(&GetHeight);
+ nodeSignals.ProcessMessages.connect(&ProcessMessages);
+ nodeSignals.SendMessages.connect(&SendMessages);
+ nodeSignals.InitializeNode.connect(&InitializeNode);
+ nodeSignals.FinalizeNode.connect(&FinalizeNode);
+}
+
+void UnregisterNodeSignals(CNodeSignals& nodeSignals)
+{
+ nodeSignals.GetHeight.disconnect(&GetHeight);
+ nodeSignals.ProcessMessages.disconnect(&ProcessMessages);
+ nodeSignals.SendMessages.disconnect(&SendMessages);
+ nodeSignals.InitializeNode.disconnect(&InitializeNode);
+ nodeSignals.FinalizeNode.disconnect(&FinalizeNode);
+}
+
+CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& locator)
+{
+ // Find the first block the caller has in the main chain
+ BOOST_FOREACH(const uint256& hash, locator.vHave) {
+ BlockMap::iterator mi = mapBlockIndex.find(hash);
+ if (mi != mapBlockIndex.end())
+ {
+ CBlockIndex* pindex = (*mi).second;
+ if (chain.Contains(pindex))
+ return pindex;
+ }
+ }
+ return chain.Genesis();
+}
+
+CCoinsViewCache *pcoinsTip = NULL;
+CBlockTreeDB *pblocktree = NULL;
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// mapOrphanTransactions
+//
+
+bool AddOrphanTx(const CTransaction& tx, NodeId peer)
+{
+ uint256 hash = tx.GetHash();
+ if (mapOrphanTransactions.count(hash))
+ return false;
+
+ // 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:
+ unsigned int sz = tx.GetSerializeSize(SER_NETWORK, CTransaction::CURRENT_VERSION);
+ if (sz > 5000)
+ {
+ LogPrint("mempool", "ignoring large orphan tx (size: %u, hash: %s)\n", sz, hash.ToString());
+ return false;
+ }
+
+ mapOrphanTransactions[hash].tx = tx;
+ mapOrphanTransactions[hash].fromPeer = peer;
+ BOOST_FOREACH(const CTxIn& txin, tx.vin)
+ mapOrphanTransactionsByPrev[txin.prevout.hash].insert(hash);
+
+ LogPrint("mempool", "stored orphan tx %s (mapsz %u prevsz %u)\n", hash.ToString(),
+ mapOrphanTransactions.size(), mapOrphanTransactionsByPrev.size());
+ return true;
+}
+
+void static EraseOrphanTx(uint256 hash)
+{
+ map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.find(hash);
+ if (it == mapOrphanTransactions.end())
+ return;
+ BOOST_FOREACH(const CTxIn& txin, it->second.tx.vin)
+ {
+ map<uint256, set<uint256> >::iterator itPrev = mapOrphanTransactionsByPrev.find(txin.prevout.hash);
+ if (itPrev == mapOrphanTransactionsByPrev.end())
+ continue;
+ itPrev->second.erase(hash);
+ if (itPrev->second.empty())
+ mapOrphanTransactionsByPrev.erase(itPrev);
+ }
+ mapOrphanTransactions.erase(it);
+}
+
+void EraseOrphansFor(NodeId peer)
+{
+ int nErased = 0;
+ map<uint256, COrphanTx>::iterator iter = mapOrphanTransactions.begin();
+ while (iter != mapOrphanTransactions.end())
+ {
+ map<uint256, COrphanTx>::iterator maybeErase = iter++; // increment to avoid iterator becoming invalid
+ if (maybeErase->second.fromPeer == peer)
+ {
+ EraseOrphanTx(maybeErase->second.tx.GetHash());
+ ++nErased;
+ }
+ }
+ if (nErased > 0) LogPrint("mempool", "Erased %d orphan tx from peer %d\n", nErased, peer);
+}
+
+
+unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans)
+{
+ unsigned int nEvicted = 0;
+ while (mapOrphanTransactions.size() > nMaxOrphans)
+ {
+ // Evict a random orphan:
+ uint256 randomhash = GetRandHash();
+ map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.lower_bound(randomhash);
+ if (it == mapOrphanTransactions.end())
+ it = mapOrphanTransactions.begin();
+ EraseOrphanTx(it->first);
+ ++nEvicted;
+ }
+ return nEvicted;
+}
+
+
+
+
+
+
+
+bool IsStandardTx(const CTransaction& tx, string& reason)
+{
+ if (tx.nVersion > CTransaction::CURRENT_VERSION || tx.nVersion < 1) {
+ reason = "version";
+ return false;
+ }
+
+ // Extremely large transactions with lots of inputs can cost the network
+ // almost as much to process as they cost the sender in fees, because
+ // computing signature hashes is O(ninputs*txsize). Limiting transactions
+ // to MAX_STANDARD_TX_SIZE mitigates CPU exhaustion attacks.
+ unsigned int sz = tx.GetSerializeSize(SER_NETWORK, CTransaction::CURRENT_VERSION);
+ if (sz >= MAX_STANDARD_TX_SIZE) {
+ reason = "tx-size";
+ return false;
+ }
+
+ BOOST_FOREACH(const CTxIn& txin, tx.vin)
+ {
+ // Biggest 'standard' txin is a 15-of-15 P2SH multisig with compressed
+ // keys. (remember the 520 byte limit on redeemScript size) That works
+ // out to a (15*(33+1))+3=513 byte redeemScript, 513+1+15*(73+1)+3=1627
+ // bytes of scriptSig, which we round off to 1650 bytes for some minor
+ // future-proofing. That's also enough to spend a 20-of-20
+ // CHECKMULTISIG scriptPubKey, though such a scriptPubKey is not
+ // considered standard)
+ if (txin.scriptSig.size() > 1650) {
+ reason = "scriptsig-size";
+ return false;
+ }
+ if (!txin.scriptSig.IsPushOnly()) {
+ reason = "scriptsig-not-pushonly";
+ return false;
+ }
+ }
+
+ unsigned int nDataOut = 0;
+ txnouttype whichType;
+ BOOST_FOREACH(const CTxOut& txout, tx.vout) {
+ if (!::IsStandard(txout.scriptPubKey, whichType)) {
+ reason = "scriptpubkey";
+ return false;
+ }
+
+ if (whichType == TX_NULL_DATA)
+ nDataOut++;
+ else if ((whichType == TX_MULTISIG) && (!fIsBareMultisigStd)) {
+ reason = "bare-multisig";
+ return false;
+ } else if (txout.IsDust(::minRelayTxFee)) {
+ reason = "dust";
+ return false;
+ }
+ }
+
+ // only one OP_RETURN txout is permitted
+ if (nDataOut > 1) {
+ reason = "multi-op-return";
+ return false;
+ }
+
+ return true;
+}
+
+bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
+{
+ if (tx.nLockTime == 0)
+ return true;
+ if ((int64_t)tx.nLockTime < ((int64_t)tx.nLockTime < LOCKTIME_THRESHOLD ? (int64_t)nBlockHeight : nBlockTime))
+ return true;
+ BOOST_FOREACH(const CTxIn& txin, tx.vin)
+ if (!txin.IsFinal())
+ return false;
+ return true;
+}
+
+bool CheckFinalTx(const CTransaction &tx)
+{
+ AssertLockHeld(cs_main);
+ return IsFinalTx(tx, chainActive.Height() + 1, GetAdjustedTime());
+}
+
+/**
+ * Check transaction inputs to mitigate two
+ * potential denial-of-service attacks:
+ *
+ * 1. scriptSigs with extra data stuffed into them,
+ * not consumed by scriptPubKey (or P2SH script)
+ * 2. P2SH scripts with a crazy number of expensive
+ * CHECKSIG/CHECKMULTISIG operations
+ */
+bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
+{
+ if (tx.IsCoinBase())
+ return true; // Coinbases don't use vin normally
+
+ for (unsigned int i = 0; i < tx.vin.size(); i++)
+ {
+ const CTxOut& prev = mapInputs.GetOutputFor(tx.vin[i]);
+
+ vector<vector<unsigned char> > 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
+ // IsStandardTx() will have already returned false
+ // and this method isn't called.
+ vector<vector<unsigned char> > stack;
+ if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker()))
+ return false;
+
+ if (whichType == TX_SCRIPTHASH)
+ {
+ if (stack.empty())
+ return false;
+ CScript subscript(stack.back().begin(), stack.back().end());
+ vector<vector<unsigned char> > vSolutions2;
+ txnouttype whichType2;
+ if (Solver(subscript, whichType2, vSolutions2))
+ {
+ int tmpExpected = ScriptSigArgsExpected(whichType2, vSolutions2);
+ if (tmpExpected < 0)
+ return false;
+ nArgsExpected += tmpExpected;
+ }
+ else
+ {
+ // Any other Script with less than 15 sigops OK:
+ unsigned int sigops = subscript.GetSigOpCount(true);
+ // ... extra data left on the stack after execution is OK, too:
+ return (sigops <= MAX_P2SH_SIGOPS);
+ }
+ }
+
+ if (stack.size() != (unsigned int)nArgsExpected)
+ return false;
+ }
+
+ return true;
+}
+
+unsigned int GetLegacySigOpCount(const CTransaction& tx)
+{
+ unsigned int nSigOps = 0;
+ BOOST_FOREACH(const CTxIn& txin, tx.vin)
+ {
+ nSigOps += txin.scriptSig.GetSigOpCount(false);
+ }
+ BOOST_FOREACH(const CTxOut& txout, tx.vout)
+ {
+ nSigOps += txout.scriptPubKey.GetSigOpCount(false);
+ }
+ return nSigOps;
+}
+
+unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& inputs)
+{
+ if (tx.IsCoinBase())
+ return 0;
+
+ unsigned int nSigOps = 0;
+ for (unsigned int i = 0; i < tx.vin.size(); i++)
+ {
+ const CTxOut &prevout = inputs.GetOutputFor(tx.vin[i]);
+ if (prevout.scriptPubKey.IsPayToScriptHash())
+ nSigOps += prevout.scriptPubKey.GetSigOpCount(tx.vin[i].scriptSig);
+ }
+ return nSigOps;
+}
+
+
+
+
+
+
+
+
+bool CheckTransaction(const CTransaction& tx, CValidationState &state)
+{
+ // Basic checks that don't depend on any context
+ if (tx.vin.empty())
+ return state.DoS(10, error("CheckTransaction(): vin empty"),
+ REJECT_INVALID, "bad-txns-vin-empty");
+ if (tx.vout.empty())
+ return state.DoS(10, error("CheckTransaction(): vout empty"),
+ REJECT_INVALID, "bad-txns-vout-empty");
+ // Size limits
+ if (::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE)
+ return state.DoS(100, error("CheckTransaction(): size limits failed"),
+ REJECT_INVALID, "bad-txns-oversize");
+
+ // Check for negative or overflow output values
+ CAmount nValueOut = 0;
+ BOOST_FOREACH(const CTxOut& txout, tx.vout)
+ {
+ if (txout.nValue < 0)
+ return state.DoS(100, error("CheckTransaction(): txout.nValue negative"),
+ REJECT_INVALID, "bad-txns-vout-negative");
+ if (txout.nValue > MAX_MONEY)
+ return state.DoS(100, error("CheckTransaction(): txout.nValue too high"),
+ REJECT_INVALID, "bad-txns-vout-toolarge");
+ nValueOut += txout.nValue;
+ if (!MoneyRange(nValueOut))
+ return state.DoS(100, error("CheckTransaction(): txout total out of range"),
+ REJECT_INVALID, "bad-txns-txouttotal-toolarge");
+ }
+
+ // Check for duplicate inputs
+ set<COutPoint> vInOutPoints;
+ BOOST_FOREACH(const CTxIn& txin, tx.vin)
+ {
+ if (vInOutPoints.count(txin.prevout))
+ return state.DoS(100, error("CheckTransaction(): duplicate inputs"),
+ REJECT_INVALID, "bad-txns-inputs-duplicate");
+ vInOutPoints.insert(txin.prevout);
+ }
+
+ if (tx.IsCoinBase())
+ {
+ if (tx.vin[0].scriptSig.size() < 2 || tx.vin[0].scriptSig.size() > 100)
+ return state.DoS(100, error("CheckTransaction(): coinbase script size"),
+ REJECT_INVALID, "bad-cb-length");
+ }
+ else
+ {
+ BOOST_FOREACH(const CTxIn& txin, tx.vin)
+ if (txin.prevout.IsNull())
+ return state.DoS(10, error("CheckTransaction(): prevout is null"),
+ REJECT_INVALID, "bad-txns-prevout-null");
+ }
+
+ return true;
+}
+
+CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree)
+{
+ {
+ LOCK(mempool.cs);
+ uint256 hash = tx.GetHash();
+ double dPriorityDelta = 0;
+ CAmount nFeeDelta = 0;
+ mempool.ApplyDeltas(hash, dPriorityDelta, nFeeDelta);
+ if (dPriorityDelta > 0 || nFeeDelta > 0)
+ return 0;
+ }
+
+ CAmount nMinFee = ::minRelayTxFee.GetFee(nBytes);
+
+ if (fAllowFree)
+ {
+ // There is a free transaction area in blocks created by most miners,
+ // * If we are relaying we allow transactions up to DEFAULT_BLOCK_PRIORITY_SIZE - 1000
+ // to be considered to fall into this category. We don't want to encourage sending
+ // multiple transactions instead of one big transaction to avoid fees.
+ if (nBytes < (DEFAULT_BLOCK_PRIORITY_SIZE - 1000))
+ nMinFee = 0;
+ }
+
+ if (!MoneyRange(nMinFee))
+ nMinFee = MAX_MONEY;
+ return nMinFee;
+}
+
+
+bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree,
+ bool* pfMissingInputs, bool fRejectAbsurdFee)
+{
+ AssertLockHeld(cs_main);
+ if (pfMissingInputs)
+ *pfMissingInputs = false;
+
+ if (!CheckTransaction(tx, state))
+ return error("AcceptToMemoryPool: CheckTransaction failed");
+
+ // Coinbase is only valid in a block, not as a loose transaction
+ if (tx.IsCoinBase())
+ return state.DoS(100, error("AcceptToMemoryPool: coinbase as individual tx"),
+ REJECT_INVALID, "coinbase");
+
+ // Rather not work on nonstandard transactions (unless -testnet/-regtest)
+ string reason;
+ if (Params().RequireStandard() && !IsStandardTx(tx, reason))
+ return state.DoS(0,
+ error("AcceptToMemoryPool: nonstandard transaction: %s", reason),
+ REJECT_NONSTANDARD, reason);
+
+ // Only accept nLockTime-using transactions that can be mined in the next
+ // block; we don't want our mempool filled up with transactions that can't
+ // be mined yet.
+ if (!CheckFinalTx(tx))
+ return state.DoS(0, error("AcceptToMemoryPool: non-final"),
+ REJECT_NONSTANDARD, "non-final");
+
+ // is it already in the memory pool?
+ uint256 hash = tx.GetHash();
+ if (pool.exists(hash))
+ return false;
+
+ // Check for conflicts with in-memory transactions
+ {
+ LOCK(pool.cs); // protect pool.mapNextTx
+ for (unsigned int i = 0; i < tx.vin.size(); i++)
+ {
+ COutPoint outpoint = tx.vin[i].prevout;
+ if (pool.mapNextTx.count(outpoint))
+ {
+ // Disable replacement feature for now
+ return false;
+ }
+ }
+ }
+
+ {
+ CCoinsView dummy;
+ CCoinsViewCache view(&dummy);
+
+ CAmount nValueIn = 0;
+ {
+ LOCK(pool.cs);
+ CCoinsViewMemPool viewMemPool(pcoinsTip, pool);
+ view.SetBackend(viewMemPool);
+
+ // do we already have it?
+ if (view.HaveCoins(hash))
+ return false;
+
+ // do all inputs exist?
+ // Note that this does not check for the presence of actual outputs (see the next check for that),
+ // and only helps with filling in pfMissingInputs (to determine missing vs spent).
+ BOOST_FOREACH(const CTxIn txin, tx.vin) {
+ if (!view.HaveCoins(txin.prevout.hash)) {
+ if (pfMissingInputs)
+ *pfMissingInputs = true;
+ return false;
+ }
+ }
+
+ // are the actual inputs available?
+ if (!view.HaveInputs(tx))
+ return state.Invalid(error("AcceptToMemoryPool: inputs already spent"),
+ REJECT_DUPLICATE, "bad-txns-inputs-spent");
+
+ // Bring the best block into scope
+ view.GetBestBlock();
+
+ nValueIn = view.GetValueIn(tx);
+
+ // we have all inputs cached now, so switch back to dummy, so we don't need to keep lock on mempool
+ view.SetBackend(dummy);
+ }
+
+ // Check for non-standard pay-to-script-hash in inputs
+ if (Params().RequireStandard() && !AreInputsStandard(tx, view))
+ return error("AcceptToMemoryPool: nonstandard transaction input");
+
+ // Check that the transaction doesn't have an excessive number of
+ // sigops, making it impossible to mine. Since the coinbase transaction
+ // itself can contain sigops MAX_STANDARD_TX_SIGOPS is less than
+ // MAX_BLOCK_SIGOPS; we still consider this an invalid rather than
+ // merely non-standard transaction.
+ unsigned int nSigOps = GetLegacySigOpCount(tx);
+ nSigOps += GetP2SHSigOpCount(tx, view);
+ if (nSigOps > MAX_STANDARD_TX_SIGOPS)
+ return state.DoS(0,
+ error("AcceptToMemoryPool: too many sigops %s, %d > %d",
+ hash.ToString(), nSigOps, MAX_STANDARD_TX_SIGOPS),
+ REJECT_NONSTANDARD, "bad-txns-too-many-sigops");
+
+ CAmount nValueOut = tx.GetValueOut();
+ CAmount nFees = nValueIn-nValueOut;
+ double dPriority = view.GetPriority(tx, chainActive.Height());
+
+ CTxMemPoolEntry entry(tx, nFees, GetTime(), dPriority, chainActive.Height(), mempool.HasNoInputsOf(tx));
+ unsigned int nSize = entry.GetTxSize();
+
+ // Don't accept it if it can't get into a block
+ CAmount txMinFee = GetMinRelayFee(tx, nSize, true);
+ if (fLimitFree && nFees < txMinFee)
+ return state.DoS(0, error("AcceptToMemoryPool: not enough fees %s, %d < %d",
+ hash.ToString(), nFees, txMinFee),
+ REJECT_INSUFFICIENTFEE, "insufficient fee");
+
+ // Require that free transactions have sufficient priority to be mined in the next block.
+ if (GetBoolArg("-relaypriority", true) && nFees < ::minRelayTxFee.GetFee(nSize) && !AllowFree(view.GetPriority(tx, chainActive.Height() + 1))) {
+ return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "insufficient priority");
+ }
+
+ // Continuously rate-limit free (really, very-low-fee) transactions
+ // This mitigates 'penny-flooding' -- sending thousands of free transactions just to
+ // be annoying or make others' transactions take longer to confirm.
+ if (fLimitFree && nFees < ::minRelayTxFee.GetFee(nSize))
+ {
+ static CCriticalSection csFreeLimiter;
+ static double dFreeCount;
+ static int64_t nLastTime;
+ int64_t nNow = GetTime();
+
+ LOCK(csFreeLimiter);
+
+ // 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)
+ return state.DoS(0, error("AcceptToMemoryPool: free transaction rejected by rate limiter"),
+ REJECT_INSUFFICIENTFEE, "rate limited free transaction");
+ LogPrint("mempool", "Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize);
+ dFreeCount += nSize;
+ }
+
+ if (fRejectAbsurdFee && nFees > ::minRelayTxFee.GetFee(nSize) * 10000)
+ return error("AcceptToMemoryPool: absurdly high fees %s, %d > %d",
+ hash.ToString(),
+ nFees, ::minRelayTxFee.GetFee(nSize) * 10000);
+
+ // Check against previous transactions
+ // This is done last to help prevent CPU exhaustion denial-of-service attacks.
+ if (!CheckInputs(tx, state, view, true, STANDARD_SCRIPT_VERIFY_FLAGS, true))
+ {
+ return error("AcceptToMemoryPool: ConnectInputs failed %s", hash.ToString());
+ }
+
+ // Check again against just the consensus-critical mandatory script
+ // verification flags, in case of bugs in the standard flags that cause
+ // transactions to pass as valid when they're actually invalid. For
+ // instance the STRICTENC flag was incorrectly allowing certain
+ // CHECKSIG NOT scripts to pass, even though they were invalid.
+ //
+ // There is a similar check in CreateNewBlock() to prevent creating
+ // invalid blocks, however allowing such transactions into the mempool
+ // can be exploited as a DoS attack.
+ if (!CheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true))
+ {
+ return error("AcceptToMemoryPool: BUG! PLEASE REPORT THIS! ConnectInputs failed against MANDATORY but not STANDARD flags %s", hash.ToString());
+ }
+
+ // Store transaction in memory
+ pool.addUnchecked(hash, entry, !IsInitialBlockDownload());
+ }
+
+ SyncWithWallets(tx, NULL);
+
+ return true;
+}
+
+/** Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock */
+bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock, bool fAllowSlow)
+{
+ CBlockIndex *pindexSlow = NULL;
+ {
+ LOCK(cs_main);
+ {
+ if (mempool.lookup(hash, txOut))
+ {
+ return true;
+ }
+ }
+
+ if (fTxIndex) {
+ CDiskTxPos postx;
+ if (pblocktree->ReadTxIndex(hash, postx)) {
+ CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION);
+ if (file.IsNull())
+ return error("%s: OpenBlockFile failed", __func__);
+ CBlockHeader header;
+ try {
+ file >> header;
+ fseek(file.Get(), postx.nTxOffset, SEEK_CUR);
+ file >> txOut;
+ } catch (const std::exception& e) {
+ return error("%s: Deserialize or I/O error - %s", __func__, e.what());
+ }
+ hashBlock = header.GetHash();
+ if (txOut.GetHash() != hash)
+ return error("%s: txid mismatch", __func__);
+ return true;
+ }
+ }
+
+ if (fAllowSlow) { // use coin database to locate block that contains transaction, and scan it
+ int nHeight = -1;
+ {
+ CCoinsViewCache &view = *pcoinsTip;
+ const CCoins* coins = view.AccessCoins(hash);
+ if (coins)
+ nHeight = coins->nHeight;
+ }
+ if (nHeight > 0)
+ pindexSlow = chainActive[nHeight];
+ }
+ }
+
+ if (pindexSlow) {
+ CBlock block;
+ if (ReadBlockFromDisk(block, pindexSlow)) {
+ BOOST_FOREACH(const CTransaction &tx, block.vtx) {
+ if (tx.GetHash() == hash) {
+ txOut = tx;
+ hashBlock = pindexSlow->GetBlockHash();
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+
+
+
+
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// CBlock and CBlockIndex
+//
+
+bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart)
+{
+ // Open history file to append
+ CAutoFile fileout(OpenBlockFile(pos), SER_DISK, CLIENT_VERSION);
+ if (fileout.IsNull())
+ return error("WriteBlockToDisk: OpenBlockFile failed");
+
+ // Write index header
+ unsigned int nSize = fileout.GetSerializeSize(block);
+ fileout << FLATDATA(messageStart) << nSize;
+
+ // Write block
+ long fileOutPos = ftell(fileout.Get());
+ if (fileOutPos < 0)
+ return error("WriteBlockToDisk: ftell failed");
+ pos.nPos = (unsigned int)fileOutPos;
+ fileout << block;
+
+ return true;
+}
+
+bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos)
+{
+ block.SetNull();
+
+ // Open history file to read
+ CAutoFile filein(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION);
+ if (filein.IsNull())
+ return error("ReadBlockFromDisk: OpenBlockFile failed for %s", pos.ToString());
+
+ // Read block
+ try {
+ filein >> block;
+ }
+ catch (const std::exception& e) {
+ return error("%s: Deserialize or I/O error - %s at %s", __func__, e.what(), pos.ToString());
+ }
+
+ // Check the header
+ if (!CheckProofOfWork(block.GetHash(), block.nBits, Params().GetConsensus()))
+ return error("ReadBlockFromDisk: Errors in block header at %s", pos.ToString());
+
+ return true;
+}
+
+bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex)
+{
+ if (!ReadBlockFromDisk(block, pindex->GetBlockPos()))
+ return false;
+ if (block.GetHash() != pindex->GetBlockHash())
+ return error("ReadBlockFromDisk(CBlock&, CBlockIndex*): GetHash() doesn't match index for %s at %s",
+ pindex->ToString(), pindex->GetBlockPos().ToString());
+ return true;
+}
+
+CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams)
+{
+ int halvings = nHeight / consensusParams.nSubsidyHalvingInterval;
+ // Force block reward to zero when right shift is undefined.
+ if (halvings >= 64)
+ return 0;
+
+ CAmount nSubsidy = 50 * COIN;
+ // Subsidy is cut in half every 210,000 blocks which will occur approximately every 4 years.
+ nSubsidy >>= halvings;
+ return nSubsidy;
+}
+
+bool IsInitialBlockDownload()
+{
+ const CChainParams& chainParams = Params();
+ LOCK(cs_main);
+ if (fImporting || fReindex)
+ return true;
+ if (fCheckpointsEnabled && chainActive.Height() < Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints()))
+ return true;
+ static bool lockIBDState = false;
+ if (lockIBDState)
+ return false;
+ bool state = (chainActive.Height() < pindexBestHeader->nHeight - 24 * 6 ||
+ pindexBestHeader->GetBlockTime() < GetTime() - 24 * 60 * 60);
+ if (!state)
+ lockIBDState = true;
+ return state;
+}
+
+bool fLargeWorkForkFound = false;
+bool fLargeWorkInvalidChainFound = false;
+CBlockIndex *pindexBestForkTip = NULL, *pindexBestForkBase = NULL;
+
+void CheckForkWarningConditions()
+{
+ AssertLockHeld(cs_main);
+ // Before we get past initial download, we cannot reliably alert about forks
+ // (we assume we don't get stuck on a fork before the last checkpoint)
+ if (IsInitialBlockDownload())
+ return;
+
+ // If our best fork is no longer within 72 blocks (+/- 12 hours if no one mines it)
+ // of our head, drop it
+ if (pindexBestForkTip && chainActive.Height() - pindexBestForkTip->nHeight >= 72)
+ pindexBestForkTip = NULL;
+
+ if (pindexBestForkTip || (pindexBestInvalid && pindexBestInvalid->nChainWork > chainActive.Tip()->nChainWork + (GetBlockProof(*chainActive.Tip()) * 6)))
+ {
+ if (!fLargeWorkForkFound && pindexBestForkBase)
+ {
+ std::string warning = std::string("'Warning: Large-work fork detected, forking after block ") +
+ pindexBestForkBase->phashBlock->ToString() + std::string("'");
+ CAlert::Notify(warning, true);
+ }
+ if (pindexBestForkTip && pindexBestForkBase)
+ {
+ LogPrintf("%s: Warning: Large valid fork found\n forking the chain at height %d (%s)\n lasting to height %d (%s).\nChain state database corruption likely.\n", __func__,
+ pindexBestForkBase->nHeight, pindexBestForkBase->phashBlock->ToString(),
+ pindexBestForkTip->nHeight, pindexBestForkTip->phashBlock->ToString());
+ fLargeWorkForkFound = true;
+ }
+ else
+ {
+ LogPrintf("%s: Warning: Found invalid chain at least ~6 blocks longer than our best chain.\nChain state database corruption likely.\n", __func__);
+ fLargeWorkInvalidChainFound = true;
+ }
+ }
+ else
+ {
+ fLargeWorkForkFound = false;
+ fLargeWorkInvalidChainFound = false;
+ }
+}
+
+void CheckForkWarningConditionsOnNewFork(CBlockIndex* pindexNewForkTip)
+{
+ AssertLockHeld(cs_main);
+ // If we are on a fork that is sufficiently large, set a warning flag
+ CBlockIndex* pfork = pindexNewForkTip;
+ CBlockIndex* plonger = chainActive.Tip();
+ while (pfork && pfork != plonger)
+ {
+ while (plonger && plonger->nHeight > pfork->nHeight)
+ plonger = plonger->pprev;
+ if (pfork == plonger)
+ break;
+ pfork = pfork->pprev;
+ }
+
+ // We define a condition where we should warn the user about as a fork of at least 7 blocks
+ // with a tip within 72 blocks (+/- 12 hours if no one mines it) of ours
+ // We use 7 blocks rather arbitrarily as it represents just under 10% of sustained network
+ // hash rate operating on the fork.
+ // or a chain that is entirely longer than ours and invalid (note that this should be detected by both)
+ // We define it this way because it allows us to only store the highest fork tip (+ base) which meets
+ // the 7-block condition and from this always have the most-likely-to-cause-warning fork
+ if (pfork && (!pindexBestForkTip || (pindexBestForkTip && pindexNewForkTip->nHeight > pindexBestForkTip->nHeight)) &&
+ pindexNewForkTip->nChainWork - pfork->nChainWork > (GetBlockProof(*pfork) * 7) &&
+ chainActive.Height() - pindexNewForkTip->nHeight < 72)
+ {
+ pindexBestForkTip = pindexNewForkTip;
+ pindexBestForkBase = pfork;
+ }
+
+ CheckForkWarningConditions();
+}
+
+// Requires cs_main.
+void Misbehaving(NodeId pnode, int howmuch)
+{
+ if (howmuch == 0)
+ return;
+
+ CNodeState *state = State(pnode);
+ if (state == NULL)
+ return;
+
+ state->nMisbehavior += howmuch;
+ int banscore = GetArg("-banscore", 100);
+ if (state->nMisbehavior >= banscore && state->nMisbehavior - howmuch < banscore)
+ {
+ LogPrintf("%s: %s (%d -> %d) BAN THRESHOLD EXCEEDED\n", __func__, state->name, state->nMisbehavior-howmuch, state->nMisbehavior);
+ state->fShouldBan = true;
+ } else
+ LogPrintf("%s: %s (%d -> %d)\n", __func__, state->name, state->nMisbehavior-howmuch, state->nMisbehavior);
+}
+
+void static InvalidChainFound(CBlockIndex* pindexNew)
+{
+ if (!pindexBestInvalid || pindexNew->nChainWork > pindexBestInvalid->nChainWork)
+ pindexBestInvalid = pindexNew;
+
+ LogPrintf("%s: invalid block=%s height=%d log2_work=%.8g date=%s\n", __func__,
+ pindexNew->GetBlockHash().ToString(), pindexNew->nHeight,
+ log(pindexNew->nChainWork.getdouble())/log(2.0), DateTimeStrFormat("%Y-%m-%d %H:%M:%S",
+ pindexNew->GetBlockTime()));
+ CBlockIndex *tip = chainActive.Tip();
+ assert (tip);
+ LogPrintf("%s: current best=%s height=%d log2_work=%.8g date=%s\n", __func__,
+ tip->GetBlockHash().ToString(), chainActive.Height(), log(tip->nChainWork.getdouble())/log(2.0),
+ DateTimeStrFormat("%Y-%m-%d %H:%M:%S", tip->GetBlockTime()));
+ CheckForkWarningConditions();
+}
+
+void static InvalidBlockFound(CBlockIndex *pindex, const CValidationState &state) {
+ int nDoS = 0;
+ if (state.IsInvalid(nDoS)) {
+ std::map<uint256, NodeId>::iterator it = mapBlockSource.find(pindex->GetBlockHash());
+ if (it != mapBlockSource.end() && State(it->second)) {
+ CBlockReject reject = {state.GetRejectCode(), state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), pindex->GetBlockHash()};
+ State(it->second)->rejects.push_back(reject);
+ if (nDoS > 0)
+ Misbehaving(it->second, nDoS);
+ }
+ }
+ if (!state.CorruptionPossible()) {
+ pindex->nStatus |= BLOCK_FAILED_VALID;
+ setDirtyBlockIndex.insert(pindex);
+ setBlockIndexCandidates.erase(pindex);
+ InvalidChainFound(pindex);
+ }
+}
+
+void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, CTxUndo &txundo, int nHeight)
+{
+ // mark inputs spent
+ if (!tx.IsCoinBase()) {
+ txundo.vprevout.reserve(tx.vin.size());
+ BOOST_FOREACH(const CTxIn &txin, tx.vin) {
+ CCoinsModifier coins = inputs.ModifyCoins(txin.prevout.hash);
+ unsigned nPos = txin.prevout.n;
+
+ if (nPos >= coins->vout.size() || coins->vout[nPos].IsNull())
+ assert(false);
+ // mark an outpoint spent, and construct undo information
+ txundo.vprevout.push_back(CTxInUndo(coins->vout[nPos]));
+ coins->Spend(nPos);
+ if (coins->vout.size() == 0) {
+ CTxInUndo& undo = txundo.vprevout.back();
+ undo.nHeight = coins->nHeight;
+ undo.fCoinBase = coins->fCoinBase;
+ undo.nVersion = coins->nVersion;
+ }
+ }
+ }
+
+ // add outputs
+ inputs.ModifyCoins(tx.GetHash())->FromTx(tx, nHeight);
+}
+
+void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, int nHeight)
+{
+ CTxUndo txundo;
+ UpdateCoins(tx, state, inputs, txundo, nHeight);
+}
+
+bool CScriptCheck::operator()() {
+ const CScript &scriptSig = ptxTo->vin[nIn].scriptSig;
+ if (!VerifyScript(scriptSig, scriptPubKey, nFlags, CachingTransactionSignatureChecker(ptxTo, nIn, cacheStore), &error)) {
+ return ::error("CScriptCheck(): %s:%d VerifySignature failed: %s", ptxTo->GetHash().ToString(), nIn, ScriptErrorString(error));
+ }
+ return true;
+}
+
+bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, bool cacheStore, std::vector<CScriptCheck> *pvChecks)
+{
+ if (!tx.IsCoinBase())
+ {
+ if (pvChecks)
+ pvChecks->reserve(tx.vin.size());
+
+ // 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 (!inputs.HaveInputs(tx))
+ return state.Invalid(error("CheckInputs(): %s inputs unavailable", tx.GetHash().ToString()));
+
+ // While checking, GetBestBlock() refers to the parent block.
+ // This is also true for mempool checks.
+ CBlockIndex *pindexPrev = mapBlockIndex.find(inputs.GetBestBlock())->second;
+ int nSpendHeight = pindexPrev->nHeight + 1;
+ CAmount nValueIn = 0;
+ CAmount nFees = 0;
+ for (unsigned int i = 0; i < tx.vin.size(); i++)
+ {
+ const COutPoint &prevout = tx.vin[i].prevout;
+ const CCoins *coins = inputs.AccessCoins(prevout.hash);
+ assert(coins);
+
+ // If prev is coinbase, check that it's matured
+ if (coins->IsCoinBase()) {
+ if (nSpendHeight - coins->nHeight < COINBASE_MATURITY)
+ return state.Invalid(
+ error("CheckInputs(): tried to spend coinbase at depth %d", nSpendHeight - coins->nHeight),
+ REJECT_INVALID, "bad-txns-premature-spend-of-coinbase");
+ }
+
+ // Check for negative or overflow input values
+ nValueIn += coins->vout[prevout.n].nValue;
+ if (!MoneyRange(coins->vout[prevout.n].nValue) || !MoneyRange(nValueIn))
+ return state.DoS(100, error("CheckInputs(): txin values out of range"),
+ REJECT_INVALID, "bad-txns-inputvalues-outofrange");
+
+ }
+
+ if (nValueIn < tx.GetValueOut())
+ return state.DoS(100, error("CheckInputs(): %s value in (%s) < value out (%s)",
+ tx.GetHash().ToString(), FormatMoney(nValueIn), FormatMoney(tx.GetValueOut())),
+ REJECT_INVALID, "bad-txns-in-belowout");
+
+ // Tally transaction fees
+ CAmount nTxFee = nValueIn - tx.GetValueOut();
+ if (nTxFee < 0)
+ return state.DoS(100, error("CheckInputs(): %s nTxFee < 0", tx.GetHash().ToString()),
+ REJECT_INVALID, "bad-txns-fee-negative");
+ nFees += nTxFee;
+ if (!MoneyRange(nFees))
+ return state.DoS(100, error("CheckInputs(): nFees out of range"),
+ REJECT_INVALID, "bad-txns-fee-outofrange");
+
+ // 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.
+
+ // Skip ECDSA signature verification when connecting blocks
+ // before the last block chain checkpoint. This is safe because block merkle hashes are
+ // still computed and checked, and any change will be caught at the next checkpoint.
+ if (fScriptChecks) {
+ for (unsigned int i = 0; i < tx.vin.size(); i++) {
+ const COutPoint &prevout = tx.vin[i].prevout;
+ const CCoins* coins = inputs.AccessCoins(prevout.hash);
+ assert(coins);
+
+ // Verify signature
+ CScriptCheck check(*coins, tx, i, flags, cacheStore);
+ if (pvChecks) {
+ pvChecks->push_back(CScriptCheck());
+ check.swap(pvChecks->back());
+ } else if (!check()) {
+ if (flags & STANDARD_NOT_MANDATORY_VERIFY_FLAGS) {
+ // Check whether the failure was caused by a
+ // non-mandatory script verification check, such as
+ // non-standard DER encodings or non-null dummy
+ // arguments; if so, don't trigger DoS protection to
+ // avoid splitting the network between upgraded and
+ // non-upgraded nodes.
+ CScriptCheck check(*coins, tx, i,
+ flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheStore);
+ if (check())
+ return state.Invalid(false, REJECT_NONSTANDARD, strprintf("non-mandatory-script-verify-flag (%s)", ScriptErrorString(check.GetScriptError())));
+ }
+ // Failures of other flags indicate a transaction that is
+ // invalid in new blocks, e.g. a invalid P2SH. We DoS ban
+ // such nodes as they are not following the protocol. That
+ // said during an upgrade careful thought should be taken
+ // as to the correct behavior - we may want to continue
+ // peering with non-upgraded nodes even after a soft-fork
+ // super-majority vote has passed.
+ return state.DoS(100,false, REJECT_INVALID, strprintf("mandatory-script-verify-flag-failed (%s)", ScriptErrorString(check.GetScriptError())));
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+namespace {
+
+bool UndoWriteToDisk(const CBlockUndo& blockundo, CDiskBlockPos& pos, const uint256& hashBlock, const CMessageHeader::MessageStartChars& messageStart)
+{
+ // Open history file to append
+ CAutoFile fileout(OpenUndoFile(pos), SER_DISK, CLIENT_VERSION);
+ if (fileout.IsNull())
+ return error("%s: OpenUndoFile failed", __func__);
+
+ // Write index header
+ unsigned int nSize = fileout.GetSerializeSize(blockundo);
+ fileout << FLATDATA(messageStart) << nSize;
+
+ // Write undo data
+ long fileOutPos = ftell(fileout.Get());
+ if (fileOutPos < 0)
+ return error("%s: ftell failed", __func__);
+ pos.nPos = (unsigned int)fileOutPos;
+ fileout << blockundo;
+
+ // calculate & write checksum
+ CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
+ hasher << hashBlock;
+ hasher << blockundo;
+ fileout << hasher.GetHash();
+
+ return true;
+}
+
+bool UndoReadFromDisk(CBlockUndo& blockundo, const CDiskBlockPos& pos, const uint256& hashBlock)
+{
+ // Open history file to read
+ CAutoFile filein(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION);
+ if (filein.IsNull())
+ return error("%s: OpenBlockFile failed", __func__);
+
+ // Read block
+ uint256 hashChecksum;
+ try {
+ filein >> blockundo;
+ filein >> hashChecksum;
+ }
+ catch (const std::exception& e) {
+ return error("%s: Deserialize or I/O error - %s", __func__, e.what());
+ }
+
+ // Verify checksum
+ CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
+ hasher << hashBlock;
+ hasher << blockundo;
+ if (hashChecksum != hasher.GetHash())
+ return error("%s: Checksum mismatch", __func__);
+
+ return true;
+}
+
+/** Abort with a message */
+bool AbortNode(const std::string& strMessage, const std::string& userMessage="")
+{
+ strMiscWarning = strMessage;
+ LogPrintf("*** %s\n", strMessage);
+ uiInterface.ThreadSafeMessageBox(
+ userMessage.empty() ? _("Error: A fatal internal error occurred, see debug.log for details") : userMessage,
+ "", CClientUIInterface::MSG_ERROR);
+ StartShutdown();
+ return false;
+}
+
+bool AbortNode(CValidationState& state, const std::string& strMessage, const std::string& userMessage="")
+{
+ AbortNode(strMessage, userMessage);
+ return state.Error(strMessage);
+}
+
+} // anon namespace
+
+/**
+ * Apply the undo operation of a CTxInUndo to the given chain state.
+ * @param undo The undo object.
+ * @param view The coins view to which to apply the changes.
+ * @param out The out point that corresponds to the tx input.
+ * @return True on success.
+ */
+static bool ApplyTxInUndo(const CTxInUndo& undo, CCoinsViewCache& view, const COutPoint& out)
+{
+ bool fClean = true;
+
+ CCoinsModifier coins = view.ModifyCoins(out.hash);
+ if (undo.nHeight != 0) {
+ // undo data contains height: this is the last output of the prevout tx being spent
+ if (!coins->IsPruned())
+ fClean = fClean && error("%s: undo data overwriting existing transaction", __func__);
+ coins->Clear();
+ coins->fCoinBase = undo.fCoinBase;
+ coins->nHeight = undo.nHeight;
+ coins->nVersion = undo.nVersion;
+ } else {
+ if (coins->IsPruned())
+ fClean = fClean && error("%s: undo data adding output to missing transaction", __func__);
+ }
+ if (coins->IsAvailable(out.n))
+ fClean = fClean && error("%s: undo data overwriting existing output", __func__);
+ if (coins->vout.size() < out.n+1)
+ coins->vout.resize(out.n+1);
+ coins->vout[out.n] = undo.txout;
+
+ return fClean;
+}
+
+bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool* pfClean)
+{
+ assert(pindex->GetBlockHash() == view.GetBestBlock());
+
+ if (pfClean)
+ *pfClean = false;
+
+ bool fClean = true;
+
+ CBlockUndo blockUndo;
+ CDiskBlockPos pos = pindex->GetUndoPos();
+ if (pos.IsNull())
+ return error("DisconnectBlock(): no undo data available");
+ if (!UndoReadFromDisk(blockUndo, pos, pindex->pprev->GetBlockHash()))
+ return error("DisconnectBlock(): failure reading undo data");
+
+ if (blockUndo.vtxundo.size() + 1 != block.vtx.size())
+ return error("DisconnectBlock(): block and undo data inconsistent");
+
+ // undo transactions in reverse order
+ for (int i = block.vtx.size() - 1; i >= 0; i--) {
+ const CTransaction &tx = block.vtx[i];
+ uint256 hash = tx.GetHash();
+
+ // Check that all outputs are available and match the outputs in the block itself
+ // exactly.
+ {
+ CCoinsModifier outs = view.ModifyCoins(hash);
+ outs->ClearUnspendable();
+
+ CCoins outsBlock(tx, pindex->nHeight);
+ // The CCoins serialization does not serialize negative numbers.
+ // No network rules currently depend on the version here, so an inconsistency is harmless
+ // but it must be corrected before txout nversion ever influences a network rule.
+ if (outsBlock.nVersion < 0)
+ outs->nVersion = outsBlock.nVersion;
+ if (*outs != outsBlock)
+ fClean = fClean && error("DisconnectBlock(): added transaction mismatch? database corrupted");
+
+ // remove outputs
+ outs->Clear();
+ }
+
+ // restore inputs
+ if (i > 0) { // not coinbases
+ const CTxUndo &txundo = blockUndo.vtxundo[i-1];
+ if (txundo.vprevout.size() != tx.vin.size())
+ return error("DisconnectBlock(): transaction and undo data inconsistent");
+ for (unsigned int j = tx.vin.size(); j-- > 0;) {
+ const COutPoint &out = tx.vin[j].prevout;
+ const CTxInUndo &undo = txundo.vprevout[j];
+ if (!ApplyTxInUndo(undo, view, out))
+ fClean = false;
+ }
+ }
+ }
+
+ // move best block pointer to prevout block
+ view.SetBestBlock(pindex->pprev->GetBlockHash());
+
+ if (pfClean) {
+ *pfClean = fClean;
+ return true;
+ }
+
+ return fClean;
+}
+
+void static FlushBlockFile(bool fFinalize = false)
+{
+ LOCK(cs_LastBlockFile);
+
+ CDiskBlockPos posOld(nLastBlockFile, 0);
+
+ FILE *fileOld = OpenBlockFile(posOld);
+ if (fileOld) {
+ if (fFinalize)
+ TruncateFile(fileOld, vinfoBlockFile[nLastBlockFile].nSize);
+ FileCommit(fileOld);
+ fclose(fileOld);
+ }
+
+ fileOld = OpenUndoFile(posOld);
+ if (fileOld) {
+ if (fFinalize)
+ TruncateFile(fileOld, vinfoBlockFile[nLastBlockFile].nUndoSize);
+ FileCommit(fileOld);
+ fclose(fileOld);
+ }
+}
+
+bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigned int nAddSize);
+
+static CCheckQueue<CScriptCheck> scriptcheckqueue(128);
+
+void ThreadScriptCheck() {
+ RenameThread("bitcoin-scriptch");
+ scriptcheckqueue.Thread();
+}
+
+//
+// Called periodically asynchronously; alerts if it smells like
+// we're being fed a bad chain (blocks being generated much
+// too slowly or too quickly).
+//
+void PartitionCheck(bool (*initialDownloadCheck)(), CCriticalSection& cs, const CBlockIndex *const &bestHeader,
+ int64_t nPowTargetSpacing)
+{
+ if (bestHeader == NULL || initialDownloadCheck()) return;
+
+ static int64_t lastAlertTime = 0;
+ int64_t now = GetAdjustedTime();
+ if (lastAlertTime > now-60*60*24) return; // Alert at most once per day
+
+ const int SPAN_HOURS=4;
+ const int SPAN_SECONDS=SPAN_HOURS*60*60;
+ int BLOCKS_EXPECTED = SPAN_SECONDS / nPowTargetSpacing;
+
+ boost::math::poisson_distribution<double> poisson(BLOCKS_EXPECTED);
+
+ std::string strWarning;
+ int64_t startTime = GetAdjustedTime()-SPAN_SECONDS;
+
+ LOCK(cs);
+ const CBlockIndex* i = bestHeader;
+ int nBlocks = 0;
+ while (i->GetBlockTime() >= startTime) {
+ ++nBlocks;
+ i = i->pprev;
+ if (i == NULL) return; // Ran out of chain, we must not be fully sync'ed
+ }
+
+ // How likely is it to find that many by chance?
+ double p = boost::math::pdf(poisson, nBlocks);
+
+ LogPrint("partitioncheck", "%s : Found %d blocks in the last %d hours\n", __func__, nBlocks, SPAN_HOURS);
+ LogPrint("partitioncheck", "%s : likelihood: %g\n", __func__, p);
+
+ // Aim for one false-positive about every fifty years of normal running:
+ const int FIFTY_YEARS = 50*365*24*60*60;
+ double alertThreshold = 1.0 / (FIFTY_YEARS / SPAN_SECONDS);
+
+ if (p <= alertThreshold && nBlocks < BLOCKS_EXPECTED)
+ {
+ // Many fewer blocks than expected: alert!
+ strWarning = strprintf(_("WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)"),
+ nBlocks, SPAN_HOURS, BLOCKS_EXPECTED);
+ }
+ else if (p <= alertThreshold && nBlocks > BLOCKS_EXPECTED)
+ {
+ // Many more blocks than expected: alert!
+ strWarning = strprintf(_("WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)"),
+ nBlocks, SPAN_HOURS, BLOCKS_EXPECTED);
+ }
+ if (!strWarning.empty())
+ {
+ strMiscWarning = strWarning;
+ CAlert::Notify(strWarning, true);
+ lastAlertTime = now;
+ }
+}
+
+static int64_t nTimeVerify = 0;
+static int64_t nTimeConnect = 0;
+static int64_t nTimeIndex = 0;
+static int64_t nTimeCallbacks = 0;
+static int64_t nTimeTotal = 0;
+
+bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool fJustCheck)
+{
+ const CChainParams& chainparams = Params();
+ AssertLockHeld(cs_main);
+ // Check it again in case a previous version let a bad block in
+ if (!CheckBlock(block, state, !fJustCheck, !fJustCheck))
+ return false;
+
+ // verify that the view's current state corresponds to the previous block
+ uint256 hashPrevBlock = pindex->pprev == NULL ? uint256() : pindex->pprev->GetBlockHash();
+ assert(hashPrevBlock == view.GetBestBlock());
+
+ // Special case for the genesis block, skipping connection of its transactions
+ // (its coinbase is unspendable)
+ if (block.GetHash() == chainparams.GetConsensus().hashGenesisBlock) {
+ if (!fJustCheck)
+ view.SetBestBlock(pindex->GetBlockHash());
+ return true;
+ }
+
+ bool fScriptChecks = (!fCheckpointsEnabled || pindex->nHeight >= Checkpoints::GetTotalBlocksEstimate(chainparams.Checkpoints()));
+
+ // 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 ids entirely.
+ // This rule was originally applied to all blocks with a timestamp after March 15, 2012, 0:00 UTC.
+ // Now that the whole chain is irreversibly beyond that time it is applied to all blocks except the
+ // two in the chain that violate it. This prevents exploiting the issue against nodes during their
+ // initial block download.
+ bool fEnforceBIP30 = (!pindex->phashBlock) || // Enforce on CreateNewBlock invocations which don't have a hash.
+ !((pindex->nHeight==91842 && pindex->GetBlockHash() == uint256S("0x00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec")) ||
+ (pindex->nHeight==91880 && pindex->GetBlockHash() == uint256S("0x00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721")));
+ if (fEnforceBIP30) {
+ BOOST_FOREACH(const CTransaction& tx, block.vtx) {
+ const CCoins* coins = view.AccessCoins(tx.GetHash());
+ if (coins && !coins->IsPruned())
+ return state.DoS(100, error("ConnectBlock(): tried to overwrite transaction"),
+ REJECT_INVALID, "bad-txns-BIP30");
+ }
+ }
+
+ // BIP16 didn't become active until Apr 1 2012
+ int64_t nBIP16SwitchTime = 1333238400;
+ bool fStrictPayToScriptHash = (pindex->GetBlockTime() >= nBIP16SwitchTime);
+
+ unsigned int flags = fStrictPayToScriptHash ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE;
+
+ // Start enforcing the DERSIG (BIP66) rules, for block.nVersion=3 blocks,
+ // when 75% of the network has upgraded:
+ if (block.nVersion >= 3 && IsSuperMajority(3, pindex->pprev, chainparams.GetConsensus().nMajorityEnforceBlockUpgrade, chainparams.GetConsensus())) {
+ flags |= SCRIPT_VERIFY_DERSIG;
+ }
+
+ // Start enforcing CHECKLOCKTIMEVERIFY, (BIP65) for block.nVersion=4
+ // blocks, when 75% of the network has upgraded:
+ if (block.nVersion >= 4 && IsSuperMajority(4, pindex->pprev, chainparams.GetConsensus().nMajorityEnforceBlockUpgrade, chainparams.GetConsensus())) {
+ flags |= SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY;
+ }
+
+ CBlockUndo blockundo;
+
+ CCheckQueueControl<CScriptCheck> control(fScriptChecks && nScriptCheckThreads ? &scriptcheckqueue : NULL);
+
+ int64_t nTimeStart = GetTimeMicros();
+ CAmount nFees = 0;
+ int nInputs = 0;
+ unsigned int nSigOps = 0;
+ CDiskTxPos pos(pindex->GetBlockPos(), GetSizeOfCompactSize(block.vtx.size()));
+ std::vector<std::pair<uint256, CDiskTxPos> > vPos;
+ vPos.reserve(block.vtx.size());
+ blockundo.vtxundo.reserve(block.vtx.size() - 1);
+ for (unsigned int i = 0; i < block.vtx.size(); i++)
+ {
+ const CTransaction &tx = block.vtx[i];
+
+ nInputs += tx.vin.size();
+ nSigOps += GetLegacySigOpCount(tx);
+ if (nSigOps > MAX_BLOCK_SIGOPS)
+ return state.DoS(100, error("ConnectBlock(): too many sigops"),
+ REJECT_INVALID, "bad-blk-sigops");
+
+ if (!tx.IsCoinBase())
+ {
+ if (!view.HaveInputs(tx))
+ return state.DoS(100, error("ConnectBlock(): inputs missing/spent"),
+ REJECT_INVALID, "bad-txns-inputs-missingorspent");
+
+ 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 += GetP2SHSigOpCount(tx, view);
+ if (nSigOps > MAX_BLOCK_SIGOPS)
+ return state.DoS(100, error("ConnectBlock(): too many sigops"),
+ REJECT_INVALID, "bad-blk-sigops");
+ }
+
+ nFees += view.GetValueIn(tx)-tx.GetValueOut();
+
+ std::vector<CScriptCheck> vChecks;
+ if (!CheckInputs(tx, state, view, fScriptChecks, flags, false, nScriptCheckThreads ? &vChecks : NULL))
+ return false;
+ control.Add(vChecks);
+ }
+
+ CTxUndo undoDummy;
+ if (i > 0) {
+ blockundo.vtxundo.push_back(CTxUndo());
+ }
+ UpdateCoins(tx, state, view, i == 0 ? undoDummy : blockundo.vtxundo.back(), pindex->nHeight);
+
+ vPos.push_back(std::make_pair(tx.GetHash(), pos));
+ pos.nTxOffset += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION);
+ }
+ int64_t nTime1 = GetTimeMicros(); nTimeConnect += nTime1 - nTimeStart;
+ LogPrint("bench", " - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) [%.2fs]\n", (unsigned)block.vtx.size(), 0.001 * (nTime1 - nTimeStart), 0.001 * (nTime1 - nTimeStart) / block.vtx.size(), nInputs <= 1 ? 0 : 0.001 * (nTime1 - nTimeStart) / (nInputs-1), nTimeConnect * 0.000001);
+
+ CAmount blockReward = nFees + GetBlockSubsidy(pindex->nHeight, chainparams.GetConsensus());
+ if (block.vtx[0].GetValueOut() > blockReward)
+ return state.DoS(100,
+ error("ConnectBlock(): coinbase pays too much (actual=%d vs limit=%d)",
+ block.vtx[0].GetValueOut(), blockReward),
+ REJECT_INVALID, "bad-cb-amount");
+
+ if (!control.Wait())
+ return state.DoS(100, false);
+ int64_t nTime2 = GetTimeMicros(); nTimeVerify += nTime2 - nTimeStart;
+ LogPrint("bench", " - Verify %u txins: %.2fms (%.3fms/txin) [%.2fs]\n", nInputs - 1, 0.001 * (nTime2 - nTimeStart), nInputs <= 1 ? 0 : 0.001 * (nTime2 - nTimeStart) / (nInputs-1), nTimeVerify * 0.000001);
+
+ if (fJustCheck)
+ return true;
+
+ // Write undo information to disk
+ if (pindex->GetUndoPos().IsNull() || !pindex->IsValid(BLOCK_VALID_SCRIPTS))
+ {
+ if (pindex->GetUndoPos().IsNull()) {
+ CDiskBlockPos pos;
+ if (!FindUndoPos(state, pindex->nFile, pos, ::GetSerializeSize(blockundo, SER_DISK, CLIENT_VERSION) + 40))
+ return error("ConnectBlock(): FindUndoPos failed");
+ if (!UndoWriteToDisk(blockundo, pos, pindex->pprev->GetBlockHash(), chainparams.MessageStart()))
+ return AbortNode(state, "Failed to write undo data");
+
+ // update nUndoPos in block index
+ pindex->nUndoPos = pos.nPos;
+ pindex->nStatus |= BLOCK_HAVE_UNDO;
+ }
+
+ pindex->RaiseValidity(BLOCK_VALID_SCRIPTS);
+ setDirtyBlockIndex.insert(pindex);
+ }
+
+ if (fTxIndex)
+ if (!pblocktree->WriteTxIndex(vPos))
+ return AbortNode(state, "Failed to write transaction index");
+
+ // add this block to the view's block chain
+ view.SetBestBlock(pindex->GetBlockHash());
+
+ int64_t nTime3 = GetTimeMicros(); nTimeIndex += nTime3 - nTime2;
+ LogPrint("bench", " - Index writing: %.2fms [%.2fs]\n", 0.001 * (nTime3 - nTime2), nTimeIndex * 0.000001);
+
+ // Watch for changes to the previous coinbase transaction.
+ static uint256 hashPrevBestCoinBase;
+ GetMainSignals().UpdatedTransaction(hashPrevBestCoinBase);
+ hashPrevBestCoinBase = block.vtx[0].GetHash();
+
+ int64_t nTime4 = GetTimeMicros(); nTimeCallbacks += nTime4 - nTime3;
+ LogPrint("bench", " - Callbacks: %.2fms [%.2fs]\n", 0.001 * (nTime4 - nTime3), nTimeCallbacks * 0.000001);
+
+ return true;
+}
+
+enum FlushStateMode {
+ FLUSH_STATE_NONE,
+ FLUSH_STATE_IF_NEEDED,
+ FLUSH_STATE_PERIODIC,
+ FLUSH_STATE_ALWAYS
+};
+
+/**
+ * Update the on-disk chain state.
+ * The caches and indexes are flushed depending on the mode we're called with
+ * if they're too large, if it's been a while since the last write,
+ * or always and in all cases if we're in prune mode and are deleting files.
+ */
+bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) {
+ LOCK2(cs_main, cs_LastBlockFile);
+ static int64_t nLastWrite = 0;
+ static int64_t nLastFlush = 0;
+ static int64_t nLastSetChain = 0;
+ std::set<int> setFilesToPrune;
+ bool fFlushForPrune = false;
+ try {
+ if (fPruneMode && fCheckForPruning && !fReindex) {
+ FindFilesToPrune(setFilesToPrune);
+ fCheckForPruning = false;
+ if (!setFilesToPrune.empty()) {
+ fFlushForPrune = true;
+ if (!fHavePruned) {
+ pblocktree->WriteFlag("prunedblockfiles", true);
+ fHavePruned = true;
+ }
+ }
+ }
+ int64_t nNow = GetTimeMicros();
+ // Avoid writing/flushing immediately after startup.
+ if (nLastWrite == 0) {
+ nLastWrite = nNow;
+ }
+ if (nLastFlush == 0) {
+ nLastFlush = nNow;
+ }
+ if (nLastSetChain == 0) {
+ nLastSetChain = nNow;
+ }
+ size_t cacheSize = pcoinsTip->DynamicMemoryUsage();
+ // The cache is large and close to the limit, but we have time now (not in the middle of a block processing).
+ bool fCacheLarge = mode == FLUSH_STATE_PERIODIC && cacheSize * (10.0/9) > nCoinCacheUsage;
+ // The cache is over the limit, we have to write now.
+ bool fCacheCritical = mode == FLUSH_STATE_IF_NEEDED && cacheSize > nCoinCacheUsage;
+ // It's been a while since we wrote the block index to disk. Do this frequently, so we don't need to redownload after a crash.
+ bool fPeriodicWrite = mode == FLUSH_STATE_PERIODIC && nNow > nLastWrite + (int64_t)DATABASE_WRITE_INTERVAL * 1000000;
+ // It's been very long since we flushed the cache. Do this infrequently, to optimize cache usage.
+ bool fPeriodicFlush = mode == FLUSH_STATE_PERIODIC && nNow > nLastFlush + (int64_t)DATABASE_FLUSH_INTERVAL * 1000000;
+ // Combine all conditions that result in a full cache flush.
+ bool fDoFullFlush = (mode == FLUSH_STATE_ALWAYS) || fCacheLarge || fCacheCritical || fPeriodicFlush || fFlushForPrune;
+ // Write blocks and block index to disk.
+ if (fDoFullFlush || fPeriodicWrite) {
+ // Depend on nMinDiskSpace to ensure we can write block index
+ if (!CheckDiskSpace(0))
+ return state.Error("out of disk space");
+ // First make sure all block and undo data is flushed to disk.
+ FlushBlockFile();
+ // Then update all block file information (which may refer to block and undo files).
+ {
+ std::vector<std::pair<int, const CBlockFileInfo*> > vFiles;
+ vFiles.reserve(setDirtyFileInfo.size());
+ for (set<int>::iterator it = setDirtyFileInfo.begin(); it != setDirtyFileInfo.end(); ) {
+ vFiles.push_back(make_pair(*it, &vinfoBlockFile[*it]));
+ setDirtyFileInfo.erase(it++);
+ }
+ std::vector<const CBlockIndex*> vBlocks;
+ vBlocks.reserve(setDirtyBlockIndex.size());
+ for (set<CBlockIndex*>::iterator it = setDirtyBlockIndex.begin(); it != setDirtyBlockIndex.end(); ) {
+ vBlocks.push_back(*it);
+ setDirtyBlockIndex.erase(it++);
+ }
+ if (!pblocktree->WriteBatchSync(vFiles, nLastBlockFile, vBlocks)) {
+ return AbortNode(state, "Files to write to block index database");
+ }
+ }
+ // Finally remove any pruned files
+ if (fFlushForPrune)
+ UnlinkPrunedFiles(setFilesToPrune);
+ nLastWrite = nNow;
+ }
+ // Flush best chain related state. This can only be done if the blocks / block index write was also done.
+ if (fDoFullFlush) {
+ // Typical CCoins structures on disk are around 128 bytes in size.
+ // Pushing a new one to the database can cause it to be written
+ // twice (once in the log, and once in the tables). This is already
+ // an overestimation, as most will delete an existing entry or
+ // overwrite one. Still, use a conservative safety factor of 2.
+ if (!CheckDiskSpace(128 * 2 * 2 * pcoinsTip->GetCacheSize()))
+ return state.Error("out of disk space");
+ // Flush the chainstate (which may refer to block index entries).
+ if (!pcoinsTip->Flush())
+ return AbortNode(state, "Failed to write to coin database");
+ nLastFlush = nNow;
+ }
+ if ((mode == FLUSH_STATE_ALWAYS || mode == FLUSH_STATE_PERIODIC) && nNow > nLastSetChain + (int64_t)DATABASE_WRITE_INTERVAL * 1000000) {
+ // Update best block in wallet (so we can detect restored wallets).
+ GetMainSignals().SetBestChain(chainActive.GetLocator());
+ nLastSetChain = nNow;
+ }
+ } catch (const std::runtime_error& e) {
+ return AbortNode(state, std::string("System error while flushing: ") + e.what());
+ }
+ return true;
+}
+
+void FlushStateToDisk() {
+ CValidationState state;
+ FlushStateToDisk(state, FLUSH_STATE_ALWAYS);
+}
+
+void PruneAndFlush() {
+ CValidationState state;
+ fCheckForPruning = true;
+ FlushStateToDisk(state, FLUSH_STATE_NONE);
+}
+
+/** Update chainActive and related internal data structures. */
+void static UpdateTip(CBlockIndex *pindexNew) {
+ const CChainParams& chainParams = Params();
+ chainActive.SetTip(pindexNew);
+
+ // New best block
+ nTimeBestReceived = GetTime();
+ mempool.AddTransactionsUpdated(1);
+
+ LogPrintf("%s: new best=%s height=%d log2_work=%.8g tx=%lu date=%s progress=%f cache=%.1fMiB(%utx)\n", __func__,
+ chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(), log(chainActive.Tip()->nChainWork.getdouble())/log(2.0), (unsigned long)chainActive.Tip()->nChainTx,
+ DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()),
+ Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), chainActive.Tip()), pcoinsTip->DynamicMemoryUsage() * (1.0 / (1<<20)), pcoinsTip->GetCacheSize());
+
+ cvBlockChange.notify_all();
+
+ // Check the version of the last 100 blocks to see if we need to upgrade:
+ static bool fWarned = false;
+ if (!IsInitialBlockDownload() && !fWarned)
+ {
+ int nUpgraded = 0;
+ const CBlockIndex* pindex = chainActive.Tip();
+ for (int i = 0; i < 100 && pindex != NULL; i++)
+ {
+ if (pindex->nVersion > CBlock::CURRENT_VERSION)
+ ++nUpgraded;
+ pindex = pindex->pprev;
+ }
+ if (nUpgraded > 0)
+ LogPrintf("%s: %d of last 100 blocks above version %d\n", __func__, nUpgraded, (int)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!");
+ CAlert::Notify(strMiscWarning, true);
+ fWarned = true;
+ }
+ }
+}
+
+/** Disconnect chainActive's tip. */
+bool static DisconnectTip(CValidationState &state) {
+ CBlockIndex *pindexDelete = chainActive.Tip();
+ assert(pindexDelete);
+ mempool.check(pcoinsTip);
+ // Read block from disk.
+ CBlock block;
+ if (!ReadBlockFromDisk(block, pindexDelete))
+ return AbortNode(state, "Failed to read block");
+ // Apply the block atomically to the chain state.
+ int64_t nStart = GetTimeMicros();
+ {
+ CCoinsViewCache view(pcoinsTip);
+ if (!DisconnectBlock(block, state, pindexDelete, view))
+ return error("DisconnectTip(): DisconnectBlock %s failed", pindexDelete->GetBlockHash().ToString());
+ assert(view.Flush());
+ }
+ LogPrint("bench", "- Disconnect block: %.2fms\n", (GetTimeMicros() - nStart) * 0.001);
+ // Write the chain state to disk, if necessary.
+ if (!FlushStateToDisk(state, FLUSH_STATE_IF_NEEDED))
+ return false;
+ // Resurrect mempool transactions from the disconnected block.
+ BOOST_FOREACH(const CTransaction &tx, block.vtx) {
+ // ignore validation errors in resurrected transactions
+ list<CTransaction> removed;
+ CValidationState stateDummy;
+ if (tx.IsCoinBase() || !AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL))
+ mempool.remove(tx, removed, true);
+ }
+ mempool.removeCoinbaseSpends(pcoinsTip, pindexDelete->nHeight);
+ mempool.check(pcoinsTip);
+ // Update chainActive and related variables.
+ UpdateTip(pindexDelete->pprev);
+ // Let wallets know transactions went from 1-confirmed to
+ // 0-confirmed or conflicted:
+ BOOST_FOREACH(const CTransaction &tx, block.vtx) {
+ SyncWithWallets(tx, NULL);
+ }
+ return true;
+}
+
+static int64_t nTimeReadFromDisk = 0;
+static int64_t nTimeConnectTotal = 0;
+static int64_t nTimeFlush = 0;
+static int64_t nTimeChainState = 0;
+static int64_t nTimePostConnect = 0;
+
+/**
+ * Connect a new block to chainActive. pblock is either NULL or a pointer to a CBlock
+ * corresponding to pindexNew, to bypass loading it again from disk.
+ */
+bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *pblock) {
+ assert(pindexNew->pprev == chainActive.Tip());
+ mempool.check(pcoinsTip);
+ // Read block from disk.
+ int64_t nTime1 = GetTimeMicros();
+ CBlock block;
+ if (!pblock) {
+ if (!ReadBlockFromDisk(block, pindexNew))
+ return AbortNode(state, "Failed to read block");
+ pblock = &block;
+ }
+ // Apply the block atomically to the chain state.
+ int64_t nTime2 = GetTimeMicros(); nTimeReadFromDisk += nTime2 - nTime1;
+ int64_t nTime3;
+ LogPrint("bench", " - Load block from disk: %.2fms [%.2fs]\n", (nTime2 - nTime1) * 0.001, nTimeReadFromDisk * 0.000001);
+ {
+ CCoinsViewCache view(pcoinsTip);
+ CInv inv(MSG_BLOCK, pindexNew->GetBlockHash());
+ bool rv = ConnectBlock(*pblock, state, pindexNew, view);
+ GetMainSignals().BlockChecked(*pblock, state);
+ if (!rv) {
+ if (state.IsInvalid())
+ InvalidBlockFound(pindexNew, state);
+ return error("ConnectTip(): ConnectBlock %s failed", pindexNew->GetBlockHash().ToString());
+ }
+ mapBlockSource.erase(inv.hash);
+ nTime3 = GetTimeMicros(); nTimeConnectTotal += nTime3 - nTime2;
+ LogPrint("bench", " - Connect total: %.2fms [%.2fs]\n", (nTime3 - nTime2) * 0.001, nTimeConnectTotal * 0.000001);
+ assert(view.Flush());
+ }
+ int64_t nTime4 = GetTimeMicros(); nTimeFlush += nTime4 - nTime3;
+ LogPrint("bench", " - Flush: %.2fms [%.2fs]\n", (nTime4 - nTime3) * 0.001, nTimeFlush * 0.000001);
+ // Write the chain state to disk, if necessary.
+ if (!FlushStateToDisk(state, FLUSH_STATE_IF_NEEDED))
+ return false;
+ int64_t nTime5 = GetTimeMicros(); nTimeChainState += nTime5 - nTime4;
+ LogPrint("bench", " - Writing chainstate: %.2fms [%.2fs]\n", (nTime5 - nTime4) * 0.001, nTimeChainState * 0.000001);
+ // Remove conflicting transactions from the mempool.
+ list<CTransaction> txConflicted;
+ mempool.removeForBlock(pblock->vtx, pindexNew->nHeight, txConflicted, !IsInitialBlockDownload());
+ mempool.check(pcoinsTip);
+ // Update chainActive & related variables.
+ UpdateTip(pindexNew);
+ // Tell wallet about transactions that went from mempool
+ // to conflicted:
+ BOOST_FOREACH(const CTransaction &tx, txConflicted) {
+ SyncWithWallets(tx, NULL);
+ }
+ // ... and about transactions that got confirmed:
+ BOOST_FOREACH(const CTransaction &tx, pblock->vtx) {
+ SyncWithWallets(tx, pblock);
+ }
+
+ int64_t nTime6 = GetTimeMicros(); nTimePostConnect += nTime6 - nTime5; nTimeTotal += nTime6 - nTime1;
+ LogPrint("bench", " - Connect postprocess: %.2fms [%.2fs]\n", (nTime6 - nTime5) * 0.001, nTimePostConnect * 0.000001);
+ LogPrint("bench", "- Connect block: %.2fms [%.2fs]\n", (nTime6 - nTime1) * 0.001, nTimeTotal * 0.000001);
+ return true;
+}
+
+/**
+ * Return the tip of the chain with the most work in it, that isn't
+ * known to be invalid (it's however far from certain to be valid).
+ */
+static CBlockIndex* FindMostWorkChain() {
+ do {
+ CBlockIndex *pindexNew = NULL;
+
+ // Find the best candidate header.
+ {
+ std::set<CBlockIndex*, CBlockIndexWorkComparator>::reverse_iterator it = setBlockIndexCandidates.rbegin();
+ if (it == setBlockIndexCandidates.rend())
+ return NULL;
+ pindexNew = *it;
+ }
+
+ // Check whether all blocks on the path between the currently active chain and the candidate are valid.
+ // Just going until the active chain is an optimization, as we know all blocks in it are valid already.
+ CBlockIndex *pindexTest = pindexNew;
+ bool fInvalidAncestor = false;
+ while (pindexTest && !chainActive.Contains(pindexTest)) {
+ assert(pindexTest->nChainTx || pindexTest->nHeight == 0);
+
+ // Pruned nodes may have entries in setBlockIndexCandidates for
+ // which block files have been deleted. Remove those as candidates
+ // for the most work chain if we come across them; we can't switch
+ // to a chain unless we have all the non-active-chain parent blocks.
+ bool fFailedChain = pindexTest->nStatus & BLOCK_FAILED_MASK;
+ bool fMissingData = !(pindexTest->nStatus & BLOCK_HAVE_DATA);
+ if (fFailedChain || fMissingData) {
+ // Candidate chain is not usable (either invalid or missing data)
+ if (fFailedChain && (pindexBestInvalid == NULL || pindexNew->nChainWork > pindexBestInvalid->nChainWork))
+ pindexBestInvalid = pindexNew;
+ CBlockIndex *pindexFailed = pindexNew;
+ // Remove the entire chain from the set.
+ while (pindexTest != pindexFailed) {
+ if (fFailedChain) {
+ pindexFailed->nStatus |= BLOCK_FAILED_CHILD;
+ } else if (fMissingData) {
+ // If we're missing data, then add back to mapBlocksUnlinked,
+ // so that if the block arrives in the future we can try adding
+ // to setBlockIndexCandidates again.
+ mapBlocksUnlinked.insert(std::make_pair(pindexFailed->pprev, pindexFailed));
+ }
+ setBlockIndexCandidates.erase(pindexFailed);
+ pindexFailed = pindexFailed->pprev;
+ }
+ setBlockIndexCandidates.erase(pindexTest);
+ fInvalidAncestor = true;
+ break;
+ }
+ pindexTest = pindexTest->pprev;
+ }
+ if (!fInvalidAncestor)
+ return pindexNew;
+ } while(true);
+}
+
+/** Delete all entries in setBlockIndexCandidates that are worse than the current tip. */
+static void PruneBlockIndexCandidates() {
+ // Note that we can't delete the current block itself, as we may need to return to it later in case a
+ // reorganization to a better block fails.
+ std::set<CBlockIndex*, CBlockIndexWorkComparator>::iterator it = setBlockIndexCandidates.begin();
+ while (it != setBlockIndexCandidates.end() && setBlockIndexCandidates.value_comp()(*it, chainActive.Tip())) {
+ setBlockIndexCandidates.erase(it++);
+ }
+ // Either the current tip or a successor of it we're working towards is left in setBlockIndexCandidates.
+ assert(!setBlockIndexCandidates.empty());
+}
+
+/**
+ * Try to make some progress towards making pindexMostWork the active block.
+ * pblock is either NULL or a pointer to a CBlock corresponding to pindexMostWork.
+ */
+static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMostWork, CBlock *pblock) {
+ AssertLockHeld(cs_main);
+ bool fInvalidFound = false;
+ const CBlockIndex *pindexOldTip = chainActive.Tip();
+ const CBlockIndex *pindexFork = chainActive.FindFork(pindexMostWork);
+
+ // Disconnect active blocks which are no longer in the best chain.
+ while (chainActive.Tip() && chainActive.Tip() != pindexFork) {
+ if (!DisconnectTip(state))
+ return false;
+ }
+
+ // Build list of new blocks to connect.
+ std::vector<CBlockIndex*> vpindexToConnect;
+ bool fContinue = true;
+ int nHeight = pindexFork ? pindexFork->nHeight : -1;
+ while (fContinue && nHeight != pindexMostWork->nHeight) {
+ // Don't iterate the entire list of potential improvements toward the best tip, as we likely only need
+ // a few blocks along the way.
+ int nTargetHeight = std::min(nHeight + 32, pindexMostWork->nHeight);
+ vpindexToConnect.clear();
+ vpindexToConnect.reserve(nTargetHeight - nHeight);
+ CBlockIndex *pindexIter = pindexMostWork->GetAncestor(nTargetHeight);
+ while (pindexIter && pindexIter->nHeight != nHeight) {
+ vpindexToConnect.push_back(pindexIter);
+ pindexIter = pindexIter->pprev;
+ }
+ nHeight = nTargetHeight;
+
+ // Connect new blocks.
+ BOOST_REVERSE_FOREACH(CBlockIndex *pindexConnect, vpindexToConnect) {
+ if (!ConnectTip(state, pindexConnect, pindexConnect == pindexMostWork ? pblock : NULL)) {
+ if (state.IsInvalid()) {
+ // The block violates a consensus rule.
+ if (!state.CorruptionPossible())
+ InvalidChainFound(vpindexToConnect.back());
+ state = CValidationState();
+ fInvalidFound = true;
+ fContinue = false;
+ break;
+ } else {
+ // A system error occurred (disk space, database error, ...).
+ return false;
+ }
+ } else {
+ PruneBlockIndexCandidates();
+ if (!pindexOldTip || chainActive.Tip()->nChainWork > pindexOldTip->nChainWork) {
+ // We're in a better position than we were. Return temporarily to release the lock.
+ fContinue = false;
+ break;
+ }
+ }
+ }
+ }
+
+ // Callbacks/notifications for a new best chain.
+ if (fInvalidFound)
+ CheckForkWarningConditionsOnNewFork(vpindexToConnect.back());
+ else
+ CheckForkWarningConditions();
+
+ return true;
+}
+
+/**
+ * Make the best chain active, in multiple steps. The result is either failure
+ * or an activated best chain. pblock is either NULL or a pointer to a block
+ * that is already loaded (to avoid loading it again from disk).
+ */
+bool ActivateBestChain(CValidationState &state, CBlock *pblock) {
+ CBlockIndex *pindexNewTip = NULL;
+ CBlockIndex *pindexMostWork = NULL;
+ const CChainParams& chainParams = Params();
+ do {
+ boost::this_thread::interruption_point();
+
+ bool fInitialDownload;
+ {
+ LOCK(cs_main);
+ pindexMostWork = FindMostWorkChain();
+
+ // Whether we have anything to do at all.
+ if (pindexMostWork == NULL || pindexMostWork == chainActive.Tip())
+ return true;
+
+ if (!ActivateBestChainStep(state, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->GetBlockHash() ? pblock : NULL))
+ return false;
+
+ pindexNewTip = chainActive.Tip();
+ fInitialDownload = IsInitialBlockDownload();
+ }
+ // When we reach this point, we switched to a new tip (stored in pindexNewTip).
+
+ // Notifications/callbacks that can run without cs_main
+ if (!fInitialDownload) {
+ uint256 hashNewTip = pindexNewTip->GetBlockHash();
+ // Relay inventory, but don't relay old inventory during initial block download.
+ int nBlockEstimate = 0;
+ if (fCheckpointsEnabled)
+ nBlockEstimate = Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints());
+ // Don't relay blocks if pruning -- could cause a peer to try to download, resulting
+ // in a stalled download if the block file is pruned before the request.
+ if (nLocalServices & NODE_NETWORK) {
+ LOCK(cs_vNodes);
+ BOOST_FOREACH(CNode* pnode, vNodes)
+ if (chainActive.Height() > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate))
+ pnode->PushInventory(CInv(MSG_BLOCK, hashNewTip));
+ }
+ // Notify external listeners about the new tip.
+ uiInterface.NotifyBlockTip(hashNewTip);
+ }
+ } while(pindexMostWork != chainActive.Tip());
+ CheckBlockIndex();
+
+ // Write changes periodically to disk, after relay.
+ if (!FlushStateToDisk(state, FLUSH_STATE_PERIODIC)) {
+ return false;
+ }
+
+ return true;
+}
+
+bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex) {
+ AssertLockHeld(cs_main);
+
+ // Mark the block itself as invalid.
+ pindex->nStatus |= BLOCK_FAILED_VALID;
+ setDirtyBlockIndex.insert(pindex);
+ setBlockIndexCandidates.erase(pindex);
+
+ while (chainActive.Contains(pindex)) {
+ CBlockIndex *pindexWalk = chainActive.Tip();
+ pindexWalk->nStatus |= BLOCK_FAILED_CHILD;
+ setDirtyBlockIndex.insert(pindexWalk);
+ setBlockIndexCandidates.erase(pindexWalk);
+ // ActivateBestChain considers blocks already in chainActive
+ // unconditionally valid already, so force disconnect away from it.
+ if (!DisconnectTip(state)) {
+ return false;
+ }
+ }
+
+ // The resulting new best tip may not be in setBlockIndexCandidates anymore, so
+ // add it again.
+ BlockMap::iterator it = mapBlockIndex.begin();
+ while (it != mapBlockIndex.end()) {
+ if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && !setBlockIndexCandidates.value_comp()(it->second, chainActive.Tip())) {
+ setBlockIndexCandidates.insert(it->second);
+ }
+ it++;
+ }
+
+ InvalidChainFound(pindex);
+ return true;
+}
+
+bool ReconsiderBlock(CValidationState& state, CBlockIndex *pindex) {
+ AssertLockHeld(cs_main);
+
+ int nHeight = pindex->nHeight;
+
+ // Remove the invalidity flag from this block and all its descendants.
+ BlockMap::iterator it = mapBlockIndex.begin();
+ while (it != mapBlockIndex.end()) {
+ if (!it->second->IsValid() && it->second->GetAncestor(nHeight) == pindex) {
+ it->second->nStatus &= ~BLOCK_FAILED_MASK;
+ setDirtyBlockIndex.insert(it->second);
+ if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && setBlockIndexCandidates.value_comp()(chainActive.Tip(), it->second)) {
+ setBlockIndexCandidates.insert(it->second);
+ }
+ if (it->second == pindexBestInvalid) {
+ // Reset invalid block marker if it was pointing to one of those.
+ pindexBestInvalid = NULL;
+ }
+ }
+ it++;
+ }
+
+ // Remove the invalidity flag from all ancestors too.
+ while (pindex != NULL) {
+ if (pindex->nStatus & BLOCK_FAILED_MASK) {
+ pindex->nStatus &= ~BLOCK_FAILED_MASK;
+ setDirtyBlockIndex.insert(pindex);
+ }
+ pindex = pindex->pprev;
+ }
+ return true;
+}
+
+CBlockIndex* AddToBlockIndex(const CBlockHeader& block)
+{
+ // Check for duplicate
+ uint256 hash = block.GetHash();
+ BlockMap::iterator it = mapBlockIndex.find(hash);
+ if (it != mapBlockIndex.end())
+ return it->second;
+
+ // Construct new block index object
+ CBlockIndex* pindexNew = new CBlockIndex(block);
+ assert(pindexNew);
+ // We assign the sequence id to blocks only when the full data is available,
+ // to avoid miners withholding blocks but broadcasting headers, to get a
+ // competitive advantage.
+ pindexNew->nSequenceId = 0;
+ BlockMap::iterator mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
+ pindexNew->phashBlock = &((*mi).first);
+ BlockMap::iterator miPrev = mapBlockIndex.find(block.hashPrevBlock);
+ if (miPrev != mapBlockIndex.end())
+ {
+ pindexNew->pprev = (*miPrev).second;
+ pindexNew->nHeight = pindexNew->pprev->nHeight + 1;
+ pindexNew->BuildSkip();
+ }
+ pindexNew->nChainWork = (pindexNew->pprev ? pindexNew->pprev->nChainWork : 0) + GetBlockProof(*pindexNew);
+ pindexNew->RaiseValidity(BLOCK_VALID_TREE);
+ if (pindexBestHeader == NULL || pindexBestHeader->nChainWork < pindexNew->nChainWork)
+ pindexBestHeader = pindexNew;
+
+ setDirtyBlockIndex.insert(pindexNew);
+
+ return pindexNew;
+}
+
+/** Mark a block as having its data received and checked (up to BLOCK_VALID_TRANSACTIONS). */
+bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBlockIndex *pindexNew, const CDiskBlockPos& pos)
+{
+ pindexNew->nTx = block.vtx.size();
+ pindexNew->nChainTx = 0;
+ pindexNew->nFile = pos.nFile;
+ pindexNew->nDataPos = pos.nPos;
+ pindexNew->nUndoPos = 0;
+ pindexNew->nStatus |= BLOCK_HAVE_DATA;
+ pindexNew->RaiseValidity(BLOCK_VALID_TRANSACTIONS);
+ setDirtyBlockIndex.insert(pindexNew);
+
+ if (pindexNew->pprev == NULL || pindexNew->pprev->nChainTx) {
+ // If pindexNew is the genesis block or all parents are BLOCK_VALID_TRANSACTIONS.
+ deque<CBlockIndex*> queue;
+ queue.push_back(pindexNew);
+
+ // Recursively process any descendant blocks that now may be eligible to be connected.
+ while (!queue.empty()) {
+ CBlockIndex *pindex = queue.front();
+ queue.pop_front();
+ pindex->nChainTx = (pindex->pprev ? pindex->pprev->nChainTx : 0) + pindex->nTx;
+ {
+ LOCK(cs_nBlockSequenceId);
+ pindex->nSequenceId = nBlockSequenceId++;
+ }
+ if (chainActive.Tip() == NULL || !setBlockIndexCandidates.value_comp()(pindex, chainActive.Tip())) {
+ setBlockIndexCandidates.insert(pindex);
+ }
+ std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range = mapBlocksUnlinked.equal_range(pindex);
+ while (range.first != range.second) {
+ std::multimap<CBlockIndex*, CBlockIndex*>::iterator it = range.first;
+ queue.push_back(it->second);
+ range.first++;
+ mapBlocksUnlinked.erase(it);
+ }
+ }
+ } else {
+ if (pindexNew->pprev && pindexNew->pprev->IsValid(BLOCK_VALID_TREE)) {
+ mapBlocksUnlinked.insert(std::make_pair(pindexNew->pprev, pindexNew));
+ }
+ }
+
+ return true;
+}
+
+bool FindBlockPos(CValidationState &state, CDiskBlockPos &pos, unsigned int nAddSize, unsigned int nHeight, uint64_t nTime, bool fKnown = false)
+{
+ LOCK(cs_LastBlockFile);
+
+ unsigned int nFile = fKnown ? pos.nFile : nLastBlockFile;
+ if (vinfoBlockFile.size() <= nFile) {
+ vinfoBlockFile.resize(nFile + 1);
+ }
+
+ if (!fKnown) {
+ while (vinfoBlockFile[nFile].nSize + nAddSize >= MAX_BLOCKFILE_SIZE) {
+ LogPrintf("Leaving block file %i: %s\n", nFile, vinfoBlockFile[nFile].ToString());
+ FlushBlockFile(true);
+ nFile++;
+ if (vinfoBlockFile.size() <= nFile) {
+ vinfoBlockFile.resize(nFile + 1);
+ }
+ }
+ pos.nFile = nFile;
+ pos.nPos = vinfoBlockFile[nFile].nSize;
+ }
+
+ nLastBlockFile = nFile;
+ vinfoBlockFile[nFile].AddBlock(nHeight, nTime);
+ if (fKnown)
+ vinfoBlockFile[nFile].nSize = std::max(pos.nPos + nAddSize, vinfoBlockFile[nFile].nSize);
+ else
+ vinfoBlockFile[nFile].nSize += nAddSize;
+
+ if (!fKnown) {
+ unsigned int nOldChunks = (pos.nPos + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
+ unsigned int nNewChunks = (vinfoBlockFile[nFile].nSize + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
+ if (nNewChunks > nOldChunks) {
+ if (fPruneMode)
+ fCheckForPruning = true;
+ if (CheckDiskSpace(nNewChunks * BLOCKFILE_CHUNK_SIZE - pos.nPos)) {
+ FILE *file = OpenBlockFile(pos);
+ if (file) {
+ LogPrintf("Pre-allocating up to position 0x%x in blk%05u.dat\n", nNewChunks * BLOCKFILE_CHUNK_SIZE, pos.nFile);
+ AllocateFileRange(file, pos.nPos, nNewChunks * BLOCKFILE_CHUNK_SIZE - pos.nPos);
+ fclose(file);
+ }
+ }
+ else
+ return state.Error("out of disk space");
+ }
+ }
+
+ setDirtyFileInfo.insert(nFile);
+ return true;
+}
+
+bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigned int nAddSize)
+{
+ pos.nFile = nFile;
+
+ LOCK(cs_LastBlockFile);
+
+ unsigned int nNewSize;
+ pos.nPos = vinfoBlockFile[nFile].nUndoSize;
+ nNewSize = vinfoBlockFile[nFile].nUndoSize += nAddSize;
+ setDirtyFileInfo.insert(nFile);
+
+ unsigned int nOldChunks = (pos.nPos + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE;
+ unsigned int nNewChunks = (nNewSize + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE;
+ if (nNewChunks > nOldChunks) {
+ if (fPruneMode)
+ fCheckForPruning = true;
+ if (CheckDiskSpace(nNewChunks * UNDOFILE_CHUNK_SIZE - pos.nPos)) {
+ FILE *file = OpenUndoFile(pos);
+ if (file) {
+ LogPrintf("Pre-allocating up to position 0x%x in rev%05u.dat\n", nNewChunks * UNDOFILE_CHUNK_SIZE, pos.nFile);
+ AllocateFileRange(file, pos.nPos, nNewChunks * UNDOFILE_CHUNK_SIZE - pos.nPos);
+ fclose(file);
+ }
+ }
+ else
+ return state.Error("out of disk space");
+ }
+
+ return true;
+}
+
+bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, bool fCheckPOW)
+{
+ // Check proof of work matches claimed amount
+ if (fCheckPOW && !CheckProofOfWork(block.GetHash(), block.nBits, Params().GetConsensus()))
+ return state.DoS(50, error("CheckBlockHeader(): proof of work failed"),
+ REJECT_INVALID, "high-hash");
+
+ // Check timestamp
+ if (block.GetBlockTime() > GetAdjustedTime() + 2 * 60 * 60)
+ return state.Invalid(error("CheckBlockHeader(): block timestamp too far in the future"),
+ REJECT_INVALID, "time-too-new");
+
+ return true;
+}
+
+bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bool fCheckMerkleRoot)
+{
+ // These are checks that are independent of context.
+
+ // Check that the header is valid (particularly PoW). This is mostly
+ // redundant with the call in AcceptBlockHeader.
+ if (!CheckBlockHeader(block, state, fCheckPOW))
+ return false;
+
+ // Check the merkle root.
+ if (fCheckMerkleRoot) {
+ bool mutated;
+ uint256 hashMerkleRoot2 = block.BuildMerkleTree(&mutated);
+ if (block.hashMerkleRoot != hashMerkleRoot2)
+ return state.DoS(100, error("CheckBlock(): hashMerkleRoot mismatch"),
+ REJECT_INVALID, "bad-txnmrklroot", true);
+
+ // Check for merkle tree malleability (CVE-2012-2459): repeating sequences
+ // of transactions in a block without affecting the merkle root of a block,
+ // while still invalidating it.
+ if (mutated)
+ return state.DoS(100, error("CheckBlock(): duplicate transaction"),
+ REJECT_INVALID, "bad-txns-duplicate", true);
+ }
+
+ // All potential-corruption validation must be done before we do any
+ // transaction validation, as otherwise we may mark the header as invalid
+ // because we receive the wrong transactions for it.
+
+ // Size limits
+ if (block.vtx.empty() || block.vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE)
+ return state.DoS(100, error("CheckBlock(): size limits failed"),
+ REJECT_INVALID, "bad-blk-length");
+
+ // First transaction must be coinbase, the rest must not be
+ if (block.vtx.empty() || !block.vtx[0].IsCoinBase())
+ return state.DoS(100, error("CheckBlock(): first tx is not coinbase"),
+ REJECT_INVALID, "bad-cb-missing");
+ for (unsigned int i = 1; i < block.vtx.size(); i++)
+ if (block.vtx[i].IsCoinBase())
+ return state.DoS(100, error("CheckBlock(): more than one coinbase"),
+ REJECT_INVALID, "bad-cb-multiple");
+
+ // Check transactions
+ BOOST_FOREACH(const CTransaction& tx, block.vtx)
+ if (!CheckTransaction(tx, state))
+ return error("CheckBlock(): CheckTransaction failed");
+
+ unsigned int nSigOps = 0;
+ BOOST_FOREACH(const CTransaction& tx, block.vtx)
+ {
+ nSigOps += GetLegacySigOpCount(tx);
+ }
+ if (nSigOps > MAX_BLOCK_SIGOPS)
+ return state.DoS(100, error("CheckBlock(): out-of-bounds SigOpCount"),
+ REJECT_INVALID, "bad-blk-sigops", true);
+
+ return true;
+}
+
+bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex * const pindexPrev)
+{
+ const CChainParams& chainParams = Params();
+ const Consensus::Params& consensusParams = chainParams.GetConsensus();
+ uint256 hash = block.GetHash();
+ if (hash == consensusParams.hashGenesisBlock)
+ return true;
+
+ assert(pindexPrev);
+
+ int nHeight = pindexPrev->nHeight+1;
+
+ // Check proof of work
+ if (block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams))
+ return state.DoS(100, error("%s: incorrect proof of work", __func__),
+ REJECT_INVALID, "bad-diffbits");
+
+ // Check timestamp against prev
+ if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast())
+ return state.Invalid(error("%s: block's timestamp is too early", __func__),
+ REJECT_INVALID, "time-too-old");
+
+ if(fCheckpointsEnabled)
+ {
+ // Check that the block chain matches the known block chain up to a checkpoint
+ if (!Checkpoints::CheckBlock(chainParams.Checkpoints(), nHeight, hash))
+ return state.DoS(100, error("%s: rejected by checkpoint lock-in at %d", __func__, nHeight),
+ REJECT_CHECKPOINT, "checkpoint mismatch");
+
+ // Don't accept any forks from the main chain prior to last checkpoint
+ CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(chainParams.Checkpoints());
+ if (pcheckpoint && nHeight < pcheckpoint->nHeight)
+ return state.DoS(100, error("%s: forked chain older than last checkpoint (height %d)", __func__, nHeight));
+ }
+
+ // Reject block.nVersion=1 blocks when 95% (75% on testnet) of the network has upgraded:
+ if (block.nVersion < 2 && IsSuperMajority(2, pindexPrev, consensusParams.nMajorityRejectBlockOutdated, consensusParams))
+ return state.Invalid(error("%s: rejected nVersion=1 block", __func__),
+ REJECT_OBSOLETE, "bad-version");
+
+ // Reject block.nVersion=2 blocks when 95% (75% on testnet) of the network has upgraded:
+ if (block.nVersion < 3 && IsSuperMajority(3, pindexPrev, consensusParams.nMajorityRejectBlockOutdated, consensusParams))
+ return state.Invalid(error("%s : rejected nVersion=2 block", __func__),
+ REJECT_OBSOLETE, "bad-version");
+
+ // Reject block.nVersion=3 blocks when 95% (75% on testnet) of the network has upgraded:
+ if (block.nVersion < 4 && IsSuperMajority(4, pindexPrev, consensusParams.nMajorityRejectBlockOutdated, consensusParams))
+ return state.Invalid(error("%s : rejected nVersion=3 block", __func__),
+ REJECT_OBSOLETE, "bad-version");
+
+ return true;
+}
+
+bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIndex * const pindexPrev)
+{
+ const int nHeight = pindexPrev == NULL ? 0 : pindexPrev->nHeight + 1;
+ const Consensus::Params& consensusParams = Params().GetConsensus();
+
+ // Check that all transactions are finalized
+ BOOST_FOREACH(const CTransaction& tx, block.vtx)
+ if (!IsFinalTx(tx, nHeight, block.GetBlockTime())) {
+ return state.DoS(10, error("%s: contains a non-final transaction", __func__), REJECT_INVALID, "bad-txns-nonfinal");
+ }
+
+ // Enforce block.nVersion=2 rule that the coinbase starts with serialized block height
+ // if 750 of the last 1,000 blocks are version 2 or greater (51/100 if testnet):
+ if (block.nVersion >= 2 && IsSuperMajority(2, pindexPrev, consensusParams.nMajorityEnforceBlockUpgrade, consensusParams))
+ {
+ CScript expect = CScript() << nHeight;
+ if (block.vtx[0].vin[0].scriptSig.size() < expect.size() ||
+ !std::equal(expect.begin(), expect.end(), block.vtx[0].vin[0].scriptSig.begin())) {
+ return state.DoS(100, error("%s: block height mismatch in coinbase", __func__), REJECT_INVALID, "bad-cb-height");
+ }
+ }
+
+ return true;
+}
+
+bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex** ppindex)
+{
+ const CChainParams& chainparams = Params();
+ AssertLockHeld(cs_main);
+ // Check for duplicate
+ uint256 hash = block.GetHash();
+ BlockMap::iterator miSelf = mapBlockIndex.find(hash);
+ CBlockIndex *pindex = NULL;
+ if (miSelf != mapBlockIndex.end()) {
+ // Block header is already known.
+ pindex = miSelf->second;
+ if (ppindex)
+ *ppindex = pindex;
+ if (pindex->nStatus & BLOCK_FAILED_MASK)
+ return state.Invalid(error("%s: block is marked invalid", __func__), 0, "duplicate");
+ return true;
+ }
+
+ if (!CheckBlockHeader(block, state))
+ return false;
+
+ // Get prev block index
+ CBlockIndex* pindexPrev = NULL;
+ if (hash != chainparams.GetConsensus().hashGenesisBlock) {
+ BlockMap::iterator mi = mapBlockIndex.find(block.hashPrevBlock);
+ if (mi == mapBlockIndex.end())
+ return state.DoS(10, error("%s: prev block not found", __func__), 0, "bad-prevblk");
+ pindexPrev = (*mi).second;
+ if (pindexPrev->nStatus & BLOCK_FAILED_MASK)
+ return state.DoS(100, error("%s: prev block invalid", __func__), REJECT_INVALID, "bad-prevblk");
+ }
+
+ if (!ContextualCheckBlockHeader(block, state, pindexPrev))
+ return false;
+
+ if (pindex == NULL)
+ pindex = AddToBlockIndex(block);
+
+ if (ppindex)
+ *ppindex = pindex;
+
+ return true;
+}
+
+bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex, bool fRequested, CDiskBlockPos* dbp)
+{
+ const CChainParams& chainparams = Params();
+ AssertLockHeld(cs_main);
+
+ CBlockIndex *&pindex = *ppindex;
+
+ if (!AcceptBlockHeader(block, state, &pindex))
+ return false;
+
+ // Try to process all requested blocks that we don't have, but only
+ // process an unrequested block if it's new and has enough work to
+ // advance our tip, and isn't too many blocks ahead.
+ bool fAlreadyHave = pindex->nStatus & BLOCK_HAVE_DATA;
+ bool fHasMoreWork = (chainActive.Tip() ? pindex->nChainWork > chainActive.Tip()->nChainWork : true);
+ // Blocks that are too out-of-order needlessly limit the effectiveness of
+ // pruning, because pruning will not delete block files that contain any
+ // blocks which are too close in height to the tip. Apply this test
+ // regardless of whether pruning is enabled; it should generally be safe to
+ // not process unrequested blocks.
+ bool fTooFarAhead = (pindex->nHeight > int(chainActive.Height() + MIN_BLOCKS_TO_KEEP));
+
+ // TODO: deal better with return value and error conditions for duplicate
+ // and unrequested blocks.
+ if (fAlreadyHave) return true;
+ if (!fRequested) { // If we didn't ask for it:
+ if (pindex->nTx != 0) return true; // This is a previously-processed block that was pruned
+ if (!fHasMoreWork) return true; // Don't process less-work chains
+ if (fTooFarAhead) return true; // Block height is too high
+ }
+
+ if ((!CheckBlock(block, state)) || !ContextualCheckBlock(block, state, pindex->pprev)) {
+ if (state.IsInvalid() && !state.CorruptionPossible()) {
+ pindex->nStatus |= BLOCK_FAILED_VALID;
+ setDirtyBlockIndex.insert(pindex);
+ }
+ return false;
+ }
+
+ int nHeight = pindex->nHeight;
+
+ // Write block to history file
+ try {
+ unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION);
+ CDiskBlockPos blockPos;
+ if (dbp != NULL)
+ blockPos = *dbp;
+ if (!FindBlockPos(state, blockPos, nBlockSize+8, nHeight, block.GetBlockTime(), dbp != NULL))
+ return error("AcceptBlock(): FindBlockPos failed");
+ if (dbp == NULL)
+ if (!WriteBlockToDisk(block, blockPos, chainparams.MessageStart()))
+ AbortNode(state, "Failed to write block");
+ if (!ReceivedBlockTransactions(block, state, pindex, blockPos))
+ return error("AcceptBlock(): ReceivedBlockTransactions failed");
+ } catch (const std::runtime_error& e) {
+ return AbortNode(state, std::string("System error: ") + e.what());
+ }
+
+ if (fCheckForPruning)
+ FlushStateToDisk(state, FLUSH_STATE_NONE); // we just allocated more disk space for block files
+
+ return true;
+}
+
+static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned nRequired, const Consensus::Params& consensusParams)
+{
+ unsigned int nFound = 0;
+ for (int i = 0; i < consensusParams.nMajorityWindow && nFound < nRequired && pstart != NULL; i++)
+ {
+ if (pstart->nVersion >= minVersion)
+ ++nFound;
+ pstart = pstart->pprev;
+ }
+ return (nFound >= nRequired);
+}
+
+
+bool ProcessNewBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, bool fForceProcessing, CDiskBlockPos *dbp)
+{
+ // Preliminary checks
+ bool checked = CheckBlock(*pblock, state);
+
+ {
+ LOCK(cs_main);
+ bool fRequested = MarkBlockAsReceived(pblock->GetHash());
+ fRequested |= fForceProcessing;
+ if (!checked) {
+ return error("%s: CheckBlock FAILED", __func__);
+ }
+
+ // Store to disk
+ CBlockIndex *pindex = NULL;
+ bool ret = AcceptBlock(*pblock, state, &pindex, fRequested, dbp);
+ if (pindex && pfrom) {
+ mapBlockSource[pindex->GetBlockHash()] = pfrom->GetId();
+ }
+ CheckBlockIndex();
+ if (!ret)
+ return error("%s: AcceptBlock FAILED", __func__);
+ }
+
+ if (!ActivateBestChain(state, pblock))
+ return error("%s: ActivateBestChain failed", __func__);
+
+ return true;
+}
+
+bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex * const pindexPrev, bool fCheckPOW, bool fCheckMerkleRoot)
+{
+ AssertLockHeld(cs_main);
+ assert(pindexPrev == chainActive.Tip());
+
+ CCoinsViewCache viewNew(pcoinsTip);
+ CBlockIndex indexDummy(block);
+ indexDummy.pprev = pindexPrev;
+ indexDummy.nHeight = pindexPrev->nHeight + 1;
+
+ // NOTE: CheckBlockHeader is called by CheckBlock
+ if (!ContextualCheckBlockHeader(block, state, pindexPrev))
+ return false;
+ if (!CheckBlock(block, state, fCheckPOW, fCheckMerkleRoot))
+ return false;
+ if (!ContextualCheckBlock(block, state, pindexPrev))
+ return false;
+ if (!ConnectBlock(block, state, &indexDummy, viewNew, true))
+ return false;
+ assert(state.IsValid());
+
+ return true;
+}
+
+/**
+ * BLOCK PRUNING CODE
+ */
+
+/* Calculate the amount of disk space the block & undo files currently use */
+uint64_t CalculateCurrentUsage()
+{
+ uint64_t retval = 0;
+ BOOST_FOREACH(const CBlockFileInfo &file, vinfoBlockFile) {
+ retval += file.nSize + file.nUndoSize;
+ }
+ return retval;
+}
+
+/* Prune a block file (modify associated database entries)*/
+void PruneOneBlockFile(const int fileNumber)
+{
+ for (BlockMap::iterator it = mapBlockIndex.begin(); it != mapBlockIndex.end(); ++it) {
+ CBlockIndex* pindex = it->second;
+ if (pindex->nFile == fileNumber) {
+ pindex->nStatus &= ~BLOCK_HAVE_DATA;
+ pindex->nStatus &= ~BLOCK_HAVE_UNDO;
+ pindex->nFile = 0;
+ pindex->nDataPos = 0;
+ pindex->nUndoPos = 0;
+ setDirtyBlockIndex.insert(pindex);
+
+ // Prune from mapBlocksUnlinked -- any block we prune would have
+ // to be downloaded again in order to consider its chain, at which
+ // point it would be considered as a candidate for
+ // mapBlocksUnlinked or setBlockIndexCandidates.
+ std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range = mapBlocksUnlinked.equal_range(pindex->pprev);
+ while (range.first != range.second) {
+ std::multimap<CBlockIndex *, CBlockIndex *>::iterator it = range.first;
+ range.first++;
+ if (it->second == pindex) {
+ mapBlocksUnlinked.erase(it);
+ }
+ }
+ }
+ }
+
+ vinfoBlockFile[fileNumber].SetNull();
+ setDirtyFileInfo.insert(fileNumber);
+}
+
+
+void UnlinkPrunedFiles(std::set<int>& setFilesToPrune)
+{
+ for (set<int>::iterator it = setFilesToPrune.begin(); it != setFilesToPrune.end(); ++it) {
+ CDiskBlockPos pos(*it, 0);
+ boost::filesystem::remove(GetBlockPosFilename(pos, "blk"));
+ boost::filesystem::remove(GetBlockPosFilename(pos, "rev"));
+ LogPrintf("Prune: %s deleted blk/rev (%05u)\n", __func__, *it);
+ }
+}
+
+/* Calculate the block/rev files that should be deleted to remain under target*/
+void FindFilesToPrune(std::set<int>& setFilesToPrune)
+{
+ LOCK2(cs_main, cs_LastBlockFile);
+ if (chainActive.Tip() == NULL || nPruneTarget == 0) {
+ return;
+ }
+ if (chainActive.Tip()->nHeight <= Params().PruneAfterHeight()) {
+ return;
+ }
+
+ unsigned int nLastBlockWeCanPrune = chainActive.Tip()->nHeight - MIN_BLOCKS_TO_KEEP;
+ uint64_t nCurrentUsage = CalculateCurrentUsage();
+ // We don't check to prune until after we've allocated new space for files
+ // So we should leave a buffer under our target to account for another allocation
+ // before the next pruning.
+ uint64_t nBuffer = BLOCKFILE_CHUNK_SIZE + UNDOFILE_CHUNK_SIZE;
+ uint64_t nBytesToPrune;
+ int count=0;
+
+ if (nCurrentUsage + nBuffer >= nPruneTarget) {
+ for (int fileNumber = 0; fileNumber < nLastBlockFile; fileNumber++) {
+ nBytesToPrune = vinfoBlockFile[fileNumber].nSize + vinfoBlockFile[fileNumber].nUndoSize;
+
+ if (vinfoBlockFile[fileNumber].nSize == 0)
+ continue;
+
+ if (nCurrentUsage + nBuffer < nPruneTarget) // are we below our target?
+ break;
+
+ // don't prune files that could have a block within MIN_BLOCKS_TO_KEEP of the main chain's tip but keep scanning
+ if (vinfoBlockFile[fileNumber].nHeightLast > nLastBlockWeCanPrune)
+ continue;
+
+ PruneOneBlockFile(fileNumber);
+ // Queue up the files for removal
+ setFilesToPrune.insert(fileNumber);
+ nCurrentUsage -= nBytesToPrune;
+ count++;
+ }
+ }
+
+ LogPrint("prune", "Prune: target=%dMiB actual=%dMiB diff=%dMiB max_prune_height=%d removed %d blk/rev pairs\n",
+ nPruneTarget/1024/1024, nCurrentUsage/1024/1024,
+ ((int64_t)nPruneTarget - (int64_t)nCurrentUsage)/1024/1024,
+ nLastBlockWeCanPrune, count);
+}
+
+bool CheckDiskSpace(uint64_t nAdditionalBytes)
+{
+ uint64_t nFreeBytesAvailable = boost::filesystem::space(GetDataDir()).available;
+
+ // Check for nMinDiskSpace bytes (currently 50MB)
+ if (nFreeBytesAvailable < nMinDiskSpace + nAdditionalBytes)
+ return AbortNode("Disk space is low!", _("Error: Disk space is low!"));
+
+ return true;
+}
+
+FILE* OpenDiskFile(const CDiskBlockPos &pos, const char *prefix, bool fReadOnly)
+{
+ if (pos.IsNull())
+ return NULL;
+ boost::filesystem::path path = GetBlockPosFilename(pos, prefix);
+ boost::filesystem::create_directories(path.parent_path());
+ FILE* file = fopen(path.string().c_str(), "rb+");
+ if (!file && !fReadOnly)
+ file = fopen(path.string().c_str(), "wb+");
+ if (!file) {
+ LogPrintf("Unable to open file %s\n", path.string());
+ return NULL;
+ }
+ if (pos.nPos) {
+ if (fseek(file, pos.nPos, SEEK_SET)) {
+ LogPrintf("Unable to seek to position %u of %s\n", pos.nPos, path.string());
+ fclose(file);
+ return NULL;
+ }
+ }
+ return file;
+}
+
+FILE* OpenBlockFile(const CDiskBlockPos &pos, bool fReadOnly) {
+ return OpenDiskFile(pos, "blk", fReadOnly);
+}
+
+FILE* OpenUndoFile(const CDiskBlockPos &pos, bool fReadOnly) {
+ return OpenDiskFile(pos, "rev", fReadOnly);
+}
+
+boost::filesystem::path GetBlockPosFilename(const CDiskBlockPos &pos, const char *prefix)
+{
+ return GetDataDir() / "blocks" / strprintf("%s%05u.dat", prefix, pos.nFile);
+}
+
+CBlockIndex * InsertBlockIndex(uint256 hash)
+{
+ if (hash.IsNull())
+ return NULL;
+
+ // Return existing
+ BlockMap::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 static LoadBlockIndexDB()
+{
+ const CChainParams& chainparams = Params();
+ if (!pblocktree->LoadBlockIndexGuts())
+ return false;
+
+ boost::this_thread::interruption_point();
+
+ // Calculate nChainWork
+ vector<pair<int, CBlockIndex*> > 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->nChainWork = (pindex->pprev ? pindex->pprev->nChainWork : 0) + GetBlockProof(*pindex);
+ // We can link the chain of blocks for which we've received transactions at some point.
+ // Pruned nodes may have deleted the block.
+ if (pindex->nTx > 0) {
+ if (pindex->pprev) {
+ if (pindex->pprev->nChainTx) {
+ pindex->nChainTx = pindex->pprev->nChainTx + pindex->nTx;
+ } else {
+ pindex->nChainTx = 0;
+ mapBlocksUnlinked.insert(std::make_pair(pindex->pprev, pindex));
+ }
+ } else {
+ pindex->nChainTx = pindex->nTx;
+ }
+ }
+ if (pindex->IsValid(BLOCK_VALID_TRANSACTIONS) && (pindex->nChainTx || pindex->pprev == NULL))
+ setBlockIndexCandidates.insert(pindex);
+ if (pindex->nStatus & BLOCK_FAILED_MASK && (!pindexBestInvalid || pindex->nChainWork > pindexBestInvalid->nChainWork))
+ pindexBestInvalid = pindex;
+ if (pindex->pprev)
+ pindex->BuildSkip();
+ if (pindex->IsValid(BLOCK_VALID_TREE) && (pindexBestHeader == NULL || CBlockIndexWorkComparator()(pindexBestHeader, pindex)))
+ pindexBestHeader = pindex;
+ }
+
+ // Load block file info
+ pblocktree->ReadLastBlockFile(nLastBlockFile);
+ vinfoBlockFile.resize(nLastBlockFile + 1);
+ LogPrintf("%s: last block file = %i\n", __func__, nLastBlockFile);
+ for (int nFile = 0; nFile <= nLastBlockFile; nFile++) {
+ pblocktree->ReadBlockFileInfo(nFile, vinfoBlockFile[nFile]);
+ }
+ LogPrintf("%s: last block file info: %s\n", __func__, vinfoBlockFile[nLastBlockFile].ToString());
+ for (int nFile = nLastBlockFile + 1; true; nFile++) {
+ CBlockFileInfo info;
+ if (pblocktree->ReadBlockFileInfo(nFile, info)) {
+ vinfoBlockFile.push_back(info);
+ } else {
+ break;
+ }
+ }
+
+ // Check presence of blk files
+ LogPrintf("Checking all blk files are present...\n");
+ set<int> setBlkDataFiles;
+ BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex)
+ {
+ CBlockIndex* pindex = item.second;
+ if (pindex->nStatus & BLOCK_HAVE_DATA) {
+ setBlkDataFiles.insert(pindex->nFile);
+ }
+ }
+ for (std::set<int>::iterator it = setBlkDataFiles.begin(); it != setBlkDataFiles.end(); it++)
+ {
+ CDiskBlockPos pos(*it, 0);
+ if (CAutoFile(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION).IsNull()) {
+ return false;
+ }
+ }
+
+ // Check whether we have ever pruned block & undo files
+ pblocktree->ReadFlag("prunedblockfiles", fHavePruned);
+ if (fHavePruned)
+ LogPrintf("LoadBlockIndexDB(): Block files have previously been pruned\n");
+
+ // Check whether we need to continue reindexing
+ bool fReindexing = false;
+ pblocktree->ReadReindexing(fReindexing);
+ fReindex |= fReindexing;
+
+ // Check whether we have a transaction index
+ pblocktree->ReadFlag("txindex", fTxIndex);
+ LogPrintf("%s: transaction index %s\n", __func__, fTxIndex ? "enabled" : "disabled");
+
+ // Load pointer to end of best chain
+ BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
+ if (it == mapBlockIndex.end())
+ return true;
+ chainActive.SetTip(it->second);
+
+ PruneBlockIndexCandidates();
+
+ LogPrintf("%s: hashBestChain=%s height=%d date=%s progress=%f\n", __func__,
+ chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(),
+ DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()),
+ Checkpoints::GuessVerificationProgress(chainparams.Checkpoints(), chainActive.Tip()));
+
+ return true;
+}
+
+CVerifyDB::CVerifyDB()
+{
+ uiInterface.ShowProgress(_("Verifying blocks..."), 0);
+}
+
+CVerifyDB::~CVerifyDB()
+{
+ uiInterface.ShowProgress("", 100);
+}
+
+bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth)
+{
+ LOCK(cs_main);
+ if (chainActive.Tip() == NULL || chainActive.Tip()->pprev == NULL)
+ return true;
+
+ // Verify blocks in the best chain
+ if (nCheckDepth <= 0)
+ nCheckDepth = 1000000000; // suffices until the year 19000
+ if (nCheckDepth > chainActive.Height())
+ nCheckDepth = chainActive.Height();
+ nCheckLevel = std::max(0, std::min(4, nCheckLevel));
+ LogPrintf("Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel);
+ CCoinsViewCache coins(coinsview);
+ CBlockIndex* pindexState = chainActive.Tip();
+ CBlockIndex* pindexFailure = NULL;
+ int nGoodTransactions = 0;
+ CValidationState state;
+ for (CBlockIndex* pindex = chainActive.Tip(); pindex && pindex->pprev; pindex = pindex->pprev)
+ {
+ boost::this_thread::interruption_point();
+ uiInterface.ShowProgress(_("Verifying blocks..."), std::max(1, std::min(99, (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * (nCheckLevel >= 4 ? 50 : 100)))));
+ if (pindex->nHeight < chainActive.Height()-nCheckDepth)
+ break;
+ CBlock block;
+ // check level 0: read from disk
+ if (!ReadBlockFromDisk(block, pindex))
+ return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
+ // check level 1: verify block validity
+ if (nCheckLevel >= 1 && !CheckBlock(block, state))
+ return error("VerifyDB(): *** found bad block at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
+ // check level 2: verify undo validity
+ if (nCheckLevel >= 2 && pindex) {
+ CBlockUndo undo;
+ CDiskBlockPos pos = pindex->GetUndoPos();
+ if (!pos.IsNull()) {
+ if (!UndoReadFromDisk(undo, pos, pindex->pprev->GetBlockHash()))
+ return error("VerifyDB(): *** found bad undo data at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
+ }
+ }
+ // check level 3: check for inconsistencies during memory-only disconnect of tip blocks
+ if (nCheckLevel >= 3 && pindex == pindexState && (coins.DynamicMemoryUsage() + pcoinsTip->DynamicMemoryUsage()) <= nCoinCacheUsage) {
+ bool fClean = true;
+ if (!DisconnectBlock(block, state, pindex, coins, &fClean))
+ return error("VerifyDB(): *** irrecoverable inconsistency in block data at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
+ pindexState = pindex->pprev;
+ if (!fClean) {
+ nGoodTransactions = 0;
+ pindexFailure = pindex;
+ } else
+ nGoodTransactions += block.vtx.size();
+ }
+ if (ShutdownRequested())
+ return true;
+ }
+ if (pindexFailure)
+ return error("VerifyDB(): *** coin database inconsistencies found (last %i blocks, %i good transactions before that)\n", chainActive.Height() - pindexFailure->nHeight + 1, nGoodTransactions);
+
+ // check level 4: try reconnecting blocks
+ if (nCheckLevel >= 4) {
+ CBlockIndex *pindex = pindexState;
+ while (pindex != chainActive.Tip()) {
+ boost::this_thread::interruption_point();
+ uiInterface.ShowProgress(_("Verifying blocks..."), std::max(1, std::min(99, 100 - (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * 50))));
+ pindex = chainActive.Next(pindex);
+ CBlock block;
+ if (!ReadBlockFromDisk(block, pindex))
+ return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
+ if (!ConnectBlock(block, state, pindex, coins))
+ return error("VerifyDB(): *** found unconnectable block at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
+ }
+ }
+
+ LogPrintf("No coin database inconsistencies in last %i blocks (%i transactions)\n", chainActive.Height() - pindexState->nHeight, nGoodTransactions);
+
+ return true;
+}
+
+void UnloadBlockIndex()
+{
+ LOCK(cs_main);
+ setBlockIndexCandidates.clear();
+ chainActive.SetTip(NULL);
+ pindexBestInvalid = NULL;
+ pindexBestHeader = NULL;
+ mempool.clear();
+ mapOrphanTransactions.clear();
+ mapOrphanTransactionsByPrev.clear();
+ nSyncStarted = 0;
+ mapBlocksUnlinked.clear();
+ vinfoBlockFile.clear();
+ nLastBlockFile = 0;
+ nBlockSequenceId = 1;
+ mapBlockSource.clear();
+ mapBlocksInFlight.clear();
+ nQueuedValidatedHeaders = 0;
+ nPreferredDownload = 0;
+ setDirtyBlockIndex.clear();
+ setDirtyFileInfo.clear();
+ mapNodeState.clear();
+ recentRejects.reset(NULL);
+
+ BOOST_FOREACH(BlockMap::value_type& entry, mapBlockIndex) {
+ delete entry.second;
+ }
+ mapBlockIndex.clear();
+ fHavePruned = false;
+}
+
+bool LoadBlockIndex()
+{
+ // Load block index from databases
+ if (!fReindex && !LoadBlockIndexDB())
+ return false;
+ return true;
+}
+
+
+bool InitBlockIndex() {
+ const CChainParams& chainparams = Params();
+ LOCK(cs_main);
+
+ // Initialize global variables that cannot be constructed at startup.
+ recentRejects.reset(new CRollingBloomFilter(120000, 0.000001));
+
+ // Check whether we're already initialized
+ if (chainActive.Genesis() != NULL)
+ return true;
+
+ // Use the provided setting for -txindex in the new database
+ fTxIndex = GetBoolArg("-txindex", false);
+ pblocktree->WriteFlag("txindex", fTxIndex);
+ LogPrintf("Initializing databases...\n");
+
+ // Only add the genesis block if not reindexing (in which case we reuse the one already on disk)
+ if (!fReindex) {
+ try {
+ CBlock &block = const_cast<CBlock&>(Params().GenesisBlock());
+ // Start new block file
+ unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION);
+ CDiskBlockPos blockPos;
+ CValidationState state;
+ if (!FindBlockPos(state, blockPos, nBlockSize+8, 0, block.GetBlockTime()))
+ return error("LoadBlockIndex(): FindBlockPos failed");
+ if (!WriteBlockToDisk(block, blockPos, chainparams.MessageStart()))
+ return error("LoadBlockIndex(): writing genesis block to disk failed");
+ CBlockIndex *pindex = AddToBlockIndex(block);
+ if (!ReceivedBlockTransactions(block, state, pindex, blockPos))
+ return error("LoadBlockIndex(): genesis block not accepted");
+ if (!ActivateBestChain(state, &block))
+ return error("LoadBlockIndex(): genesis block cannot be activated");
+ // Force a chainstate write so that when we VerifyDB in a moment, it doesn't check stale data
+ return FlushStateToDisk(state, FLUSH_STATE_ALWAYS);
+ } catch (const std::runtime_error& e) {
+ return error("LoadBlockIndex(): failed to initialize block database: %s", e.what());
+ }
+ }
+
+ return true;
+}
+
+
+
+bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
+{
+ const CChainParams& chainparams = Params();
+ // Map of disk positions for blocks with unknown parent (only used for reindex)
+ static std::multimap<uint256, CDiskBlockPos> mapBlocksUnknownParent;
+ int64_t nStart = GetTimeMillis();
+
+ int nLoaded = 0;
+ try {
+ // This takes over fileIn and calls fclose() on it in the CBufferedFile destructor
+ CBufferedFile blkdat(fileIn, 2*MAX_BLOCK_SIZE, MAX_BLOCK_SIZE+8, SER_DISK, CLIENT_VERSION);
+ uint64_t nRewind = blkdat.GetPos();
+ while (!blkdat.eof()) {
+ boost::this_thread::interruption_point();
+
+ blkdat.SetPos(nRewind);
+ nRewind++; // start one byte further next time, in case of failure
+ blkdat.SetLimit(); // remove former limit
+ unsigned int nSize = 0;
+ try {
+ // locate a header
+ unsigned char buf[MESSAGE_START_SIZE];
+ blkdat.FindByte(Params().MessageStart()[0]);
+ nRewind = blkdat.GetPos()+1;
+ blkdat >> FLATDATA(buf);
+ if (memcmp(buf, Params().MessageStart(), MESSAGE_START_SIZE))
+ continue;
+ // read size
+ blkdat >> nSize;
+ if (nSize < 80 || nSize > MAX_BLOCK_SIZE)
+ continue;
+ } catch (const std::exception&) {
+ // no valid block header found; don't complain
+ break;
+ }
+ try {
+ // read block
+ uint64_t nBlockPos = blkdat.GetPos();
+ if (dbp)
+ dbp->nPos = nBlockPos;
+ blkdat.SetLimit(nBlockPos + nSize);
+ blkdat.SetPos(nBlockPos);
+ CBlock block;
+ blkdat >> block;
+ nRewind = blkdat.GetPos();
+
+ // detect out of order blocks, and store them for later
+ uint256 hash = block.GetHash();
+ if (hash != chainparams.GetConsensus().hashGenesisBlock && mapBlockIndex.find(block.hashPrevBlock) == mapBlockIndex.end()) {
+ LogPrint("reindex", "%s: Out of order block %s, parent %s not known\n", __func__, hash.ToString(),
+ block.hashPrevBlock.ToString());
+ if (dbp)
+ mapBlocksUnknownParent.insert(std::make_pair(block.hashPrevBlock, *dbp));
+ continue;
+ }
+
+ // process in case the block isn't known yet
+ if (mapBlockIndex.count(hash) == 0 || (mapBlockIndex[hash]->nStatus & BLOCK_HAVE_DATA) == 0) {
+ CValidationState state;
+ if (ProcessNewBlock(state, NULL, &block, true, dbp))
+ nLoaded++;
+ if (state.IsError())
+ break;
+ } else if (hash != chainparams.GetConsensus().hashGenesisBlock && mapBlockIndex[hash]->nHeight % 1000 == 0) {
+ LogPrintf("Block Import: already had block %s at height %d\n", hash.ToString(), mapBlockIndex[hash]->nHeight);
+ }
+
+ // Recursively process earlier encountered successors of this block
+ deque<uint256> queue;
+ queue.push_back(hash);
+ while (!queue.empty()) {
+ uint256 head = queue.front();
+ queue.pop_front();
+ std::pair<std::multimap<uint256, CDiskBlockPos>::iterator, std::multimap<uint256, CDiskBlockPos>::iterator> range = mapBlocksUnknownParent.equal_range(head);
+ while (range.first != range.second) {
+ std::multimap<uint256, CDiskBlockPos>::iterator it = range.first;
+ if (ReadBlockFromDisk(block, it->second))
+ {
+ LogPrintf("%s: Processing out of order child %s of %s\n", __func__, block.GetHash().ToString(),
+ head.ToString());
+ CValidationState dummy;
+ if (ProcessNewBlock(dummy, NULL, &block, true, &it->second))
+ {
+ nLoaded++;
+ queue.push_back(block.GetHash());
+ }
+ }
+ range.first++;
+ mapBlocksUnknownParent.erase(it);
+ }
+ }
+ } catch (const std::exception& e) {
+ LogPrintf("%s: Deserialize or I/O error - %s\n", __func__, e.what());
+ }
+ }
+ } catch (const std::runtime_error& e) {
+ AbortNode(std::string("System error: ") + e.what());
+ }
+ if (nLoaded > 0)
+ LogPrintf("Loaded %i blocks from external file in %dms\n", nLoaded, GetTimeMillis() - nStart);
+ return nLoaded > 0;
+}
+
+void static CheckBlockIndex()
+{
+ const Consensus::Params& consensusParams = Params().GetConsensus();
+ if (!fCheckBlockIndex) {
+ return;
+ }
+
+ LOCK(cs_main);
+
+ // During a reindex, we read the genesis block and call CheckBlockIndex before ActivateBestChain,
+ // so we have the genesis block in mapBlockIndex but no active chain. (A few of the tests when
+ // iterating the block tree require that chainActive has been initialized.)
+ if (chainActive.Height() < 0) {
+ assert(mapBlockIndex.size() <= 1);
+ return;
+ }
+
+ // Build forward-pointing map of the entire block tree.
+ std::multimap<CBlockIndex*,CBlockIndex*> forward;
+ for (BlockMap::iterator it = mapBlockIndex.begin(); it != mapBlockIndex.end(); it++) {
+ forward.insert(std::make_pair(it->second->pprev, it->second));
+ }
+
+ assert(forward.size() == mapBlockIndex.size());
+
+ std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeGenesis = forward.equal_range(NULL);
+ CBlockIndex *pindex = rangeGenesis.first->second;
+ rangeGenesis.first++;
+ assert(rangeGenesis.first == rangeGenesis.second); // There is only one index entry with parent NULL.
+
+ // Iterate over the entire block tree, using depth-first search.
+ // Along the way, remember whether there are blocks on the path from genesis
+ // block being explored which are the first to have certain properties.
+ size_t nNodes = 0;
+ int nHeight = 0;
+ CBlockIndex* pindexFirstInvalid = NULL; // Oldest ancestor of pindex which is invalid.
+ CBlockIndex* pindexFirstMissing = NULL; // Oldest ancestor of pindex which does not have BLOCK_HAVE_DATA.
+ CBlockIndex* pindexFirstNeverProcessed = NULL; // Oldest ancestor of pindex for which nTx == 0.
+ CBlockIndex* pindexFirstNotTreeValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_TREE (regardless of being valid or not).
+ CBlockIndex* pindexFirstNotTransactionsValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_TRANSACTIONS (regardless of being valid or not).
+ CBlockIndex* pindexFirstNotChainValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_CHAIN (regardless of being valid or not).
+ CBlockIndex* pindexFirstNotScriptsValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_SCRIPTS (regardless of being valid or not).
+ while (pindex != NULL) {
+ nNodes++;
+ if (pindexFirstInvalid == NULL && pindex->nStatus & BLOCK_FAILED_VALID) pindexFirstInvalid = pindex;
+ if (pindexFirstMissing == NULL && !(pindex->nStatus & BLOCK_HAVE_DATA)) pindexFirstMissing = pindex;
+ if (pindexFirstNeverProcessed == NULL && pindex->nTx == 0) pindexFirstNeverProcessed = pindex;
+ if (pindex->pprev != NULL && pindexFirstNotTreeValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_TREE) pindexFirstNotTreeValid = pindex;
+ if (pindex->pprev != NULL && pindexFirstNotTransactionsValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_TRANSACTIONS) pindexFirstNotTransactionsValid = pindex;
+ if (pindex->pprev != NULL && pindexFirstNotChainValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_CHAIN) pindexFirstNotChainValid = pindex;
+ if (pindex->pprev != NULL && pindexFirstNotScriptsValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_SCRIPTS) pindexFirstNotScriptsValid = pindex;
+
+ // Begin: actual consistency checks.
+ if (pindex->pprev == NULL) {
+ // Genesis block checks.
+ assert(pindex->GetBlockHash() == consensusParams.hashGenesisBlock); // Genesis block's hash must match.
+ assert(pindex == chainActive.Genesis()); // The current active chain's genesis block must be this block.
+ }
+ if (pindex->nChainTx == 0) assert(pindex->nSequenceId == 0); // nSequenceId can't be set for blocks that aren't linked
+ // VALID_TRANSACTIONS is equivalent to nTx > 0 for all nodes (whether or not pruning has occurred).
+ // HAVE_DATA is only equivalent to nTx > 0 (or VALID_TRANSACTIONS) if no pruning has occurred.
+ if (!fHavePruned) {
+ // If we've never pruned, then HAVE_DATA should be equivalent to nTx > 0
+ assert(!(pindex->nStatus & BLOCK_HAVE_DATA) == (pindex->nTx == 0));
+ assert(pindexFirstMissing == pindexFirstNeverProcessed);
+ } else {
+ // If we have pruned, then we can only say that HAVE_DATA implies nTx > 0
+ if (pindex->nStatus & BLOCK_HAVE_DATA) assert(pindex->nTx > 0);
+ }
+ if (pindex->nStatus & BLOCK_HAVE_UNDO) assert(pindex->nStatus & BLOCK_HAVE_DATA);
+ assert(((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TRANSACTIONS) == (pindex->nTx > 0)); // This is pruning-independent.
+ // All parents having had data (at some point) is equivalent to all parents being VALID_TRANSACTIONS, which is equivalent to nChainTx being set.
+ assert((pindexFirstNeverProcessed != NULL) == (pindex->nChainTx == 0)); // nChainTx != 0 is used to signal that all parent blocks have been processed (but may have been pruned).
+ assert((pindexFirstNotTransactionsValid != NULL) == (pindex->nChainTx == 0));
+ assert(pindex->nHeight == nHeight); // nHeight must be consistent.
+ assert(pindex->pprev == NULL || pindex->nChainWork >= pindex->pprev->nChainWork); // For every block except the genesis block, the chainwork must be larger than the parent's.
+ assert(nHeight < 2 || (pindex->pskip && (pindex->pskip->nHeight < nHeight))); // The pskip pointer must point back for all but the first 2 blocks.
+ assert(pindexFirstNotTreeValid == NULL); // All mapBlockIndex entries must at least be TREE valid
+ if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TREE) assert(pindexFirstNotTreeValid == NULL); // TREE valid implies all parents are TREE valid
+ if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_CHAIN) assert(pindexFirstNotChainValid == NULL); // CHAIN valid implies all parents are CHAIN valid
+ if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_SCRIPTS) assert(pindexFirstNotScriptsValid == NULL); // SCRIPTS valid implies all parents are SCRIPTS valid
+ if (pindexFirstInvalid == NULL) {
+ // Checks for not-invalid blocks.
+ assert((pindex->nStatus & BLOCK_FAILED_MASK) == 0); // The failed mask cannot be set for blocks without invalid parents.
+ }
+ if (!CBlockIndexWorkComparator()(pindex, chainActive.Tip()) && pindexFirstNeverProcessed == NULL) {
+ if (pindexFirstInvalid == NULL) {
+ // If this block sorts at least as good as the current tip and
+ // is valid and we have all data for its parents, it must be in
+ // setBlockIndexCandidates. chainActive.Tip() must also be there
+ // even if some data has been pruned.
+ if (pindexFirstMissing == NULL || pindex == chainActive.Tip()) {
+ assert(setBlockIndexCandidates.count(pindex));
+ }
+ // If some parent is missing, then it could be that this block was in
+ // setBlockIndexCandidates but had to be removed because of the missing data.
+ // In this case it must be in mapBlocksUnlinked -- see test below.
+ }
+ } else { // If this block sorts worse than the current tip or some ancestor's block has never been seen, it cannot be in setBlockIndexCandidates.
+ assert(setBlockIndexCandidates.count(pindex) == 0);
+ }
+ // Check whether this block is in mapBlocksUnlinked.
+ std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeUnlinked = mapBlocksUnlinked.equal_range(pindex->pprev);
+ bool foundInUnlinked = false;
+ while (rangeUnlinked.first != rangeUnlinked.second) {
+ assert(rangeUnlinked.first->first == pindex->pprev);
+ if (rangeUnlinked.first->second == pindex) {
+ foundInUnlinked = true;
+ break;
+ }
+ rangeUnlinked.first++;
+ }
+ if (pindex->pprev && (pindex->nStatus & BLOCK_HAVE_DATA) && pindexFirstNeverProcessed != NULL && pindexFirstInvalid == NULL) {
+ // If this block has block data available, some parent was never received, and has no invalid parents, it must be in mapBlocksUnlinked.
+ assert(foundInUnlinked);
+ }
+ if (!(pindex->nStatus & BLOCK_HAVE_DATA)) assert(!foundInUnlinked); // Can't be in mapBlocksUnlinked if we don't HAVE_DATA
+ if (pindexFirstMissing == NULL) assert(!foundInUnlinked); // We aren't missing data for any parent -- cannot be in mapBlocksUnlinked.
+ if (pindex->pprev && (pindex->nStatus & BLOCK_HAVE_DATA) && pindexFirstNeverProcessed == NULL && pindexFirstMissing != NULL) {
+ // We HAVE_DATA for this block, have received data for all parents at some point, but we're currently missing data for some parent.
+ assert(fHavePruned); // We must have pruned.
+ // This block may have entered mapBlocksUnlinked if:
+ // - it has a descendant that at some point had more work than the
+ // tip, and
+ // - we tried switching to that descendant but were missing
+ // data for some intermediate block between chainActive and the
+ // tip.
+ // So if this block is itself better than chainActive.Tip() and it wasn't in
+ // setBlockIndexCandidates, then it must be in mapBlocksUnlinked.
+ if (!CBlockIndexWorkComparator()(pindex, chainActive.Tip()) && setBlockIndexCandidates.count(pindex) == 0) {
+ if (pindexFirstInvalid == NULL) {
+ assert(foundInUnlinked);
+ }
+ }
+ }
+ // assert(pindex->GetBlockHash() == pindex->GetBlockHeader().GetHash()); // Perhaps too slow
+ // End: actual consistency checks.
+
+ // Try descending into the first subnode.
+ std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> range = forward.equal_range(pindex);
+ if (range.first != range.second) {
+ // A subnode was found.
+ pindex = range.first->second;
+ nHeight++;
+ continue;
+ }
+ // This is a leaf node.
+ // Move upwards until we reach a node of which we have not yet visited the last child.
+ while (pindex) {
+ // We are going to either move to a parent or a sibling of pindex.
+ // If pindex was the first with a certain property, unset the corresponding variable.
+ if (pindex == pindexFirstInvalid) pindexFirstInvalid = NULL;
+ if (pindex == pindexFirstMissing) pindexFirstMissing = NULL;
+ if (pindex == pindexFirstNeverProcessed) pindexFirstNeverProcessed = NULL;
+ if (pindex == pindexFirstNotTreeValid) pindexFirstNotTreeValid = NULL;
+ if (pindex == pindexFirstNotTransactionsValid) pindexFirstNotTransactionsValid = NULL;
+ if (pindex == pindexFirstNotChainValid) pindexFirstNotChainValid = NULL;
+ if (pindex == pindexFirstNotScriptsValid) pindexFirstNotScriptsValid = NULL;
+ // Find our parent.
+ CBlockIndex* pindexPar = pindex->pprev;
+ // Find which child we just visited.
+ std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangePar = forward.equal_range(pindexPar);
+ while (rangePar.first->second != pindex) {
+ assert(rangePar.first != rangePar.second); // Our parent must have at least the node we're coming from as child.
+ rangePar.first++;
+ }
+ // Proceed to the next one.
+ rangePar.first++;
+ if (rangePar.first != rangePar.second) {
+ // Move to the sibling.
+ pindex = rangePar.first->second;
+ break;
+ } else {
+ // Move up further.
+ pindex = pindexPar;
+ nHeight--;
+ continue;
+ }
+ }
+ }
+
+ // Check that we actually traversed the entire map.
+ assert(nNodes == forward.size());
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// CAlert
+//
+
+string GetWarnings(string strFor)
+{
+ int nPriority = 0;
+ string strStatusBar;
+ string strRPC;
+
+ if (!CLIENT_VERSION_IS_RELEASE)
+ strStatusBar = _("This is a pre-release test build - use at your own risk - do not use for mining or merchant applications");
+
+ if (GetBoolArg("-testsafemode", false))
+ strStatusBar = strRPC = "testsafemode enabled";
+
+ // Misc warnings like out of disk space and clock is wrong
+ if (strMiscWarning != "")
+ {
+ nPriority = 1000;
+ strStatusBar = strMiscWarning;
+ }
+
+ if (fLargeWorkForkFound)
+ {
+ nPriority = 2000;
+ strStatusBar = strRPC = _("Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.");
+ }
+ else if (fLargeWorkInvalidChainFound)
+ {
+ nPriority = 2000;
+ strStatusBar = strRPC = _("Warning: We do not appear to fully agree with our peers! 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";
+}
+
+
+
+
+
+
+
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// Messages
+//
+
+
+bool static AlreadyHave(const CInv& inv)
+{
+ switch (inv.type)
+ {
+ case MSG_TX:
+ {
+ assert(recentRejects);
+ if (chainActive.Tip()->GetBlockHash() != hashRecentRejectsChainTip)
+ {
+ // If the chain tip has changed previously rejected transactions
+ // might be now valid, e.g. due to a nLockTime'd tx becoming valid,
+ // or a double-spend. Reset the rejects filter and give those
+ // txs a second chance.
+ hashRecentRejectsChainTip = chainActive.Tip()->GetBlockHash();
+ recentRejects->reset();
+ }
+
+ return recentRejects->contains(inv.hash) ||
+ mempool.exists(inv.hash) ||
+ mapOrphanTransactions.count(inv.hash) ||
+ pcoinsTip->HaveCoins(inv.hash);
+ }
+ case MSG_BLOCK:
+ return mapBlockIndex.count(inv.hash);
+ }
+ // Don't know what it is, just say we already got one
+ return true;
+}
+
+void static ProcessGetData(CNode* pfrom)
+{
+ std::deque<CInv>::iterator it = pfrom->vRecvGetData.begin();
+
+ vector<CInv> vNotFound;
+
+ LOCK(cs_main);
+
+ while (it != pfrom->vRecvGetData.end()) {
+ // Don't bother if send buffer is too full to respond anyway
+ if (pfrom->nSendSize >= SendBufferSize())
+ break;
+
+ const CInv &inv = *it;
+ {
+ boost::this_thread::interruption_point();
+ it++;
+
+ if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK)
+ {
+ bool send = false;
+ BlockMap::iterator mi = mapBlockIndex.find(inv.hash);
+ if (mi != mapBlockIndex.end())
+ {
+ if (chainActive.Contains(mi->second)) {
+ send = true;
+ } else {
+ static const int nOneMonth = 30 * 24 * 60 * 60;
+ // To prevent fingerprinting attacks, only send blocks outside of the active
+ // chain if they are valid, and no more than a month older (both in time, and in
+ // best equivalent proof of work) than the best header chain we know about.
+ send = mi->second->IsValid(BLOCK_VALID_SCRIPTS) && (pindexBestHeader != NULL) &&
+ (pindexBestHeader->GetBlockTime() - mi->second->GetBlockTime() < nOneMonth) &&
+ (GetBlockProofEquivalentTime(*pindexBestHeader, *mi->second, *pindexBestHeader, Params().GetConsensus()) < nOneMonth);
+ if (!send) {
+ LogPrintf("%s: ignoring request from peer=%i for old block that isn't in the main chain\n", __func__, pfrom->GetId());
+ }
+ }
+ }
+ // Pruned nodes may have deleted the block, so check whether
+ // it's available before trying to send.
+ if (send && (mi->second->nStatus & BLOCK_HAVE_DATA))
+ {
+ // Send block from disk
+ CBlock block;
+ if (!ReadBlockFromDisk(block, (*mi).second))
+ assert(!"cannot load block from disk");
+ if (inv.type == MSG_BLOCK)
+ pfrom->PushMessage("block", block);
+ else // MSG_FILTERED_BLOCK)
+ {
+ LOCK(pfrom->cs_filter);
+ if (pfrom->pfilter)
+ {
+ CMerkleBlock merkleBlock(block, *pfrom->pfilter);
+ pfrom->PushMessage("merkleblock", merkleBlock);
+ // CMerkleBlock just contains hashes, so also push any transactions in the block the client did not see
+ // This avoids hurting performance by pointlessly requiring a round-trip
+ // Note that there is currently no way for a node to request any single transactions we didn't send here -
+ // they must either disconnect and retry or request the full block.
+ // Thus, the protocol spec specified allows for us to provide duplicate txn here,
+ // however we MUST always provide at least what the remote peer needs
+ typedef std::pair<unsigned int, uint256> PairType;
+ BOOST_FOREACH(PairType& pair, merkleBlock.vMatchedTxn)
+ if (!pfrom->setInventoryKnown.count(CInv(MSG_TX, pair.second)))
+ pfrom->PushMessage("tx", block.vtx[pair.first]);
+ }
+ // else
+ // no response
+ }
+
+ // Trigger the peer node 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<CInv> vInv;
+ vInv.push_back(CInv(MSG_BLOCK, chainActive.Tip()->GetBlockHash()));
+ pfrom->PushMessage("inv", vInv);
+ pfrom->hashContinue.SetNull();
+ }
+ }
+ }
+ else if (inv.IsKnownType())
+ {
+ // Send stream from relay memory
+ bool pushed = false;
+ {
+ LOCK(cs_mapRelay);
+ map<CInv, CDataStream>::iterator mi = mapRelay.find(inv);
+ if (mi != mapRelay.end()) {
+ pfrom->PushMessage(inv.GetCommand(), (*mi).second);
+ pushed = true;
+ }
+ }
+ if (!pushed && inv.type == MSG_TX) {
+ CTransaction tx;
+ if (mempool.lookup(inv.hash, tx)) {
+ CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
+ ss.reserve(1000);
+ ss << tx;
+ pfrom->PushMessage("tx", ss);
+ pushed = true;
+ }
+ }
+ if (!pushed) {
+ vNotFound.push_back(inv);
+ }
+ }
+
+ // Track requests for our stuff.
+ GetMainSignals().Inventory(inv.hash);
+
+ if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK)
+ break;
+ }
+ }
+
+ pfrom->vRecvGetData.erase(pfrom->vRecvGetData.begin(), it);
+
+ if (!vNotFound.empty()) {
+ // Let the peer know that we didn't find what it asked for, so it doesn't
+ // have to wait around forever. Currently only SPV clients actually care
+ // about this message: it's needed when they are recursively walking the
+ // dependencies of relevant unconfirmed transactions. SPV clients want to
+ // do that because they want to know about (and store and rebroadcast and
+ // risk analyze) the dependencies of transactions relevant to them, without
+ // having to download the entire memory pool.
+ pfrom->PushMessage("notfound", vNotFound);
+ }
+}
+
+bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t nTimeReceived)
+{
+ const CChainParams& chainparams = Params();
+ RandAddSeedPerfmon();
+ LogPrint("net", "received: %s (%u bytes) peer=%d\n", SanitizeString(strCommand), vRecv.size(), pfrom->id);
+ if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
+ {
+ LogPrintf("dropmessagestest DROPPING RECV MESSAGE\n");
+ return true;
+ }
+
+
+
+
+ if (strCommand == "version")
+ {
+ // Each connection can only send one version message
+ if (pfrom->nVersion != 0)
+ {
+ pfrom->PushMessage("reject", strCommand, REJECT_DUPLICATE, string("Duplicate version message"));
+ Misbehaving(pfrom->GetId(), 1);
+ return false;
+ }
+
+ int64_t nTime;
+ CAddress addrMe;
+ CAddress addrFrom;
+ uint64_t nNonce = 1;
+ vRecv >> pfrom->nVersion >> pfrom->nServices >> nTime >> addrMe;
+ if (pfrom->nVersion < MIN_PEER_PROTO_VERSION)
+ {
+ // disconnect from peers older than this proto version
+ LogPrintf("peer=%d using obsolete version %i; disconnecting\n", pfrom->id, pfrom->nVersion);
+ pfrom->PushMessage("reject", strCommand, REJECT_OBSOLETE,
+ strprintf("Version must be %d or greater", MIN_PEER_PROTO_VERSION));
+ pfrom->fDisconnect = true;
+ return false;
+ }
+
+ if (pfrom->nVersion == 10300)
+ pfrom->nVersion = 300;
+ if (!vRecv.empty())
+ vRecv >> addrFrom >> nNonce;
+ if (!vRecv.empty()) {
+ vRecv >> LIMITED_STRING(pfrom->strSubVer, 256);
+ pfrom->cleanSubVer = SanitizeString(pfrom->strSubVer);
+ }
+ if (!vRecv.empty())
+ vRecv >> pfrom->nStartingHeight;
+ if (!vRecv.empty())
+ vRecv >> pfrom->fRelayTxes; // set to true after we get the first filter* message
+ else
+ pfrom->fRelayTxes = true;
+
+ // Disconnect if we connected to ourself
+ if (nNonce == nLocalHostNonce && nNonce > 1)
+ {
+ LogPrintf("connected to self at %s, disconnecting\n", pfrom->addr.ToString());
+ pfrom->fDisconnect = true;
+ return true;
+ }
+
+ pfrom->addrLocal = addrMe;
+ if (pfrom->fInbound && addrMe.IsRoutable())
+ {
+ SeenLocal(addrMe);
+ }
+
+ // Be shy and don't send version until we hear
+ if (pfrom->fInbound)
+ pfrom->PushVersion();
+
+ pfrom->fClient = !(pfrom->nServices & NODE_NETWORK);
+
+ // Potentially mark this peer as a preferred download peer.
+ UpdatePreferredDownload(pfrom, State(pfrom->GetId()));
+
+ // Change version
+ pfrom->PushMessage("verack");
+ pfrom->ssSend.SetVersion(min(pfrom->nVersion, PROTOCOL_VERSION));
+
+ if (!pfrom->fInbound)
+ {
+ // Advertise our address
+ if (fListen && !IsInitialBlockDownload())
+ {
+ CAddress addr = GetLocalAddress(&pfrom->addr);
+ if (addr.IsRoutable())
+ {
+ pfrom->PushAddress(addr);
+ } else if (IsPeerAddrLocalGood(pfrom)) {
+ addr.SetIP(pfrom->addrLocal);
+ 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);
+ }
+ }
+
+ // Relay alerts
+ {
+ LOCK(cs_mapAlerts);
+ BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
+ item.second.RelayTo(pfrom);
+ }
+
+ pfrom->fSuccessfullyConnected = true;
+
+ string remoteAddr;
+ if (fLogIPs)
+ remoteAddr = ", peeraddr=" + pfrom->addr.ToString();
+
+ LogPrintf("receive version message: %s: version %d, blocks=%d, us=%s, peer=%d%s\n",
+ pfrom->cleanSubVer, pfrom->nVersion,
+ pfrom->nStartingHeight, addrMe.ToString(), pfrom->id,
+ remoteAddr);
+
+ int64_t nTimeOffset = nTime - GetTime();
+ pfrom->nTimeOffset = nTimeOffset;
+ AddTimeData(pfrom->addr, nTimeOffset);
+ }
+
+
+ else if (pfrom->nVersion == 0)
+ {
+ // Must have a version message before anything else
+ Misbehaving(pfrom->GetId(), 1);
+ return false;
+ }
+
+
+ else if (strCommand == "verack")
+ {
+ pfrom->SetRecvVersion(min(pfrom->nVersion, PROTOCOL_VERSION));
+
+ // Mark this node as currently connected, so we update its timestamp later.
+ if (pfrom->fNetworkNode) {
+ LOCK(cs_main);
+ State(pfrom->GetId())->fCurrentlyConnected = true;
+ }
+ }
+
+
+ else if (strCommand == "addr")
+ {
+ vector<CAddress> 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)
+ {
+ Misbehaving(pfrom->GetId(), 20);
+ return error("message addr size() = %u", vAddr.size());
+ }
+
+ // Store the new addresses
+ vector<CAddress> vAddrOk;
+ int64_t nNow = GetAdjustedTime();
+ int64_t nSince = nNow - 10 * 60;
+ BOOST_FOREACH(CAddress& addr, vAddr)
+ {
+ boost::this_thread::interruption_point();
+
+ 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 addrKnowns of the chosen nodes prevent repeats
+ static uint256 hashSalt;
+ if (hashSalt.IsNull())
+ hashSalt = GetRandHash();
+ uint64_t hashAddr = addr.GetHash();
+ uint256 hashRand = ArithToUint256(UintToArith256(hashSalt) ^ (hashAddr<<32) ^ ((GetTime()+hashAddr)/(24*60*60)));
+ hashRand = Hash(BEGIN(hashRand), END(hashRand));
+ multimap<uint256, CNode*> mapMix;
+ BOOST_FOREACH(CNode* pnode, vNodes)
+ {
+ if (pnode->nVersion < CADDR_TIME_VERSION)
+ continue;
+ unsigned int nPointer;
+ memcpy(&nPointer, &pnode, sizeof(nPointer));
+ uint256 hashKey = ArithToUint256(UintToArith256(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<uint256, CNode*>::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<CInv> vInv;
+ vRecv >> vInv;
+ if (vInv.size() > MAX_INV_SZ)
+ {
+ Misbehaving(pfrom->GetId(), 20);
+ return error("message inv size() = %u", vInv.size());
+ }
+
+ LOCK(cs_main);
+
+ std::vector<CInv> vToFetch;
+
+ for (unsigned int nInv = 0; nInv < vInv.size(); nInv++)
+ {
+ const CInv &inv = vInv[nInv];
+
+ boost::this_thread::interruption_point();
+ pfrom->AddInventoryKnown(inv);
+
+ bool fAlreadyHave = AlreadyHave(inv);
+ LogPrint("net", "got inv: %s %s peer=%d\n", inv.ToString(), fAlreadyHave ? "have" : "new", pfrom->id);
+
+ if (!fAlreadyHave && !fImporting && !fReindex && inv.type != MSG_BLOCK)
+ pfrom->AskFor(inv);
+
+ if (inv.type == MSG_BLOCK) {
+ UpdateBlockAvailability(pfrom->GetId(), inv.hash);
+ if (!fAlreadyHave && !fImporting && !fReindex && !mapBlocksInFlight.count(inv.hash)) {
+ // First request the headers preceding the announced block. In the normal fully-synced
+ // case where a new block is announced that succeeds the current tip (no reorganization),
+ // there are no such headers.
+ // Secondly, and only when we are close to being synced, we request the announced block directly,
+ // to avoid an extra round-trip. Note that we must *first* ask for the headers, so by the
+ // time the block arrives, the header chain leading up to it is already validated. Not
+ // doing this will result in the received block being rejected as an orphan in case it is
+ // not a direct successor.
+ pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexBestHeader), inv.hash);
+ CNodeState *nodestate = State(pfrom->GetId());
+ if (chainActive.Tip()->GetBlockTime() > GetAdjustedTime() - chainparams.GetConsensus().nPowTargetSpacing * 20 &&
+ nodestate->nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
+ vToFetch.push_back(inv);
+ // Mark block as in flight already, even though the actual "getdata" message only goes out
+ // later (within the same cs_main lock, though).
+ MarkBlockAsInFlight(pfrom->GetId(), inv.hash, chainparams.GetConsensus());
+ }
+ LogPrint("net", "getheaders (%d) %s to peer=%d\n", pindexBestHeader->nHeight, inv.hash.ToString(), pfrom->id);
+ }
+ }
+
+ // Track requests for our stuff
+ GetMainSignals().Inventory(inv.hash);
+
+ if (pfrom->nSendSize > (SendBufferSize() * 2)) {
+ Misbehaving(pfrom->GetId(), 50);
+ return error("send buffer size() = %u", pfrom->nSendSize);
+ }
+ }
+
+ if (!vToFetch.empty())
+ pfrom->PushMessage("getdata", vToFetch);
+ }
+
+
+ else if (strCommand == "getdata")
+ {
+ vector<CInv> vInv;
+ vRecv >> vInv;
+ if (vInv.size() > MAX_INV_SZ)
+ {
+ Misbehaving(pfrom->GetId(), 20);
+ return error("message getdata size() = %u", vInv.size());
+ }
+
+ if (fDebug || (vInv.size() != 1))
+ LogPrint("net", "received getdata (%u invsz) peer=%d\n", vInv.size(), pfrom->id);
+
+ if ((fDebug && vInv.size() > 0) || (vInv.size() == 1))
+ LogPrint("net", "received getdata for: %s peer=%d\n", vInv[0].ToString(), pfrom->id);
+
+ pfrom->vRecvGetData.insert(pfrom->vRecvGetData.end(), vInv.begin(), vInv.end());
+ ProcessGetData(pfrom);
+ }
+
+
+ else if (strCommand == "getblocks")
+ {
+ CBlockLocator locator;
+ uint256 hashStop;
+ vRecv >> locator >> hashStop;
+
+ LOCK(cs_main);
+
+ // Find the last block the caller has in the main chain
+ CBlockIndex* pindex = FindForkInGlobalIndex(chainActive, locator);
+
+ // Send the rest of the chain
+ if (pindex)
+ pindex = chainActive.Next(pindex);
+ int nLimit = 500;
+ LogPrint("net", "getblocks %d to %s limit %d from peer=%d\n", (pindex ? pindex->nHeight : -1), hashStop.IsNull() ? "end" : hashStop.ToString(), nLimit, pfrom->id);
+ for (; pindex; pindex = chainActive.Next(pindex))
+ {
+ if (pindex->GetBlockHash() == hashStop)
+ {
+ LogPrint("net", " getblocks stopping at %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
+ break;
+ }
+ pfrom->PushInventory(CInv(MSG_BLOCK, pindex->GetBlockHash()));
+ if (--nLimit <= 0)
+ {
+ // When this block is requested, we'll send an inv that'll
+ // trigger the peer to getblocks the next batch of inventory.
+ LogPrint("net", " getblocks stopping at limit %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
+ pfrom->hashContinue = pindex->GetBlockHash();
+ break;
+ }
+ }
+ }
+
+
+ else if (strCommand == "getheaders")
+ {
+ CBlockLocator locator;
+ uint256 hashStop;
+ vRecv >> locator >> hashStop;
+
+ LOCK(cs_main);
+
+ if (IsInitialBlockDownload())
+ return true;
+
+ CBlockIndex* pindex = NULL;
+ if (locator.IsNull())
+ {
+ // If locator is null, return the hashStop block
+ BlockMap::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 = FindForkInGlobalIndex(chainActive, locator);
+ if (pindex)
+ pindex = chainActive.Next(pindex);
+ }
+
+ // we must use CBlocks, as CBlockHeaders won't include the 0x00 nTx count at the end
+ vector<CBlock> vHeaders;
+ int nLimit = MAX_HEADERS_RESULTS;
+ LogPrint("net", "getheaders %d to %s from peer=%d\n", (pindex ? pindex->nHeight : -1), hashStop.ToString(), pfrom->id);
+ for (; pindex; pindex = chainActive.Next(pindex))
+ {
+ vHeaders.push_back(pindex->GetBlockHeader());
+ if (--nLimit <= 0 || pindex->GetBlockHash() == hashStop)
+ break;
+ }
+ pfrom->PushMessage("headers", vHeaders);
+ }
+
+
+ else if (strCommand == "tx")
+ {
+ vector<uint256> vWorkQueue;
+ vector<uint256> vEraseQueue;
+ CTransaction tx;
+ vRecv >> tx;
+
+ CInv inv(MSG_TX, tx.GetHash());
+ pfrom->AddInventoryKnown(inv);
+
+ LOCK(cs_main);
+
+ bool fMissingInputs = false;
+ CValidationState state;
+
+ mapAlreadyAskedFor.erase(inv);
+
+ // Check for recently rejected (and do other quick existence checks)
+ if (AlreadyHave(inv))
+ return true;
+
+ if (AcceptToMemoryPool(mempool, state, tx, true, &fMissingInputs))
+ {
+ mempool.check(pcoinsTip);
+ RelayTransaction(tx);
+ vWorkQueue.push_back(inv.hash);
+
+ LogPrint("mempool", "AcceptToMemoryPool: peer=%d %s: accepted %s (poolsz %u)\n",
+ pfrom->id, pfrom->cleanSubVer,
+ tx.GetHash().ToString(),
+ mempool.mapTx.size());
+
+ // Recursively process any orphan transactions that depended on this one
+ set<NodeId> setMisbehaving;
+ for (unsigned int i = 0; i < vWorkQueue.size(); i++)
+ {
+ map<uint256, set<uint256> >::iterator itByPrev = mapOrphanTransactionsByPrev.find(vWorkQueue[i]);
+ if (itByPrev == mapOrphanTransactionsByPrev.end())
+ continue;
+ for (set<uint256>::iterator mi = itByPrev->second.begin();
+ mi != itByPrev->second.end();
+ ++mi)
+ {
+ const uint256& orphanHash = *mi;
+ const CTransaction& orphanTx = mapOrphanTransactions[orphanHash].tx;
+ NodeId fromPeer = mapOrphanTransactions[orphanHash].fromPeer;
+ bool fMissingInputs2 = false;
+ // Use a dummy CValidationState so someone can't setup nodes to counter-DoS based on orphan
+ // resolution (that is, feeding people an invalid transaction based on LegitTxX in order to get
+ // anyone relaying LegitTxX banned)
+ CValidationState stateDummy;
+
+
+ if (setMisbehaving.count(fromPeer))
+ continue;
+ if (AcceptToMemoryPool(mempool, stateDummy, orphanTx, true, &fMissingInputs2))
+ {
+ LogPrint("mempool", " accepted orphan tx %s\n", orphanHash.ToString());
+ RelayTransaction(orphanTx);
+ vWorkQueue.push_back(orphanHash);
+ vEraseQueue.push_back(orphanHash);
+ }
+ else if (!fMissingInputs2)
+ {
+ int nDos = 0;
+ if (stateDummy.IsInvalid(nDos) && nDos > 0)
+ {
+ // Punish peer that gave us an invalid orphan tx
+ Misbehaving(fromPeer, nDos);
+ setMisbehaving.insert(fromPeer);
+ LogPrint("mempool", " invalid orphan tx %s\n", orphanHash.ToString());
+ }
+ // Has inputs but not accepted to mempool
+ // Probably non-standard or insufficient fee/priority
+ LogPrint("mempool", " removed orphan tx %s\n", orphanHash.ToString());
+ vEraseQueue.push_back(orphanHash);
+ assert(recentRejects);
+ recentRejects->insert(orphanHash);
+ }
+ mempool.check(pcoinsTip);
+ }
+ }
+
+ BOOST_FOREACH(uint256 hash, vEraseQueue)
+ EraseOrphanTx(hash);
+ }
+ else if (fMissingInputs)
+ {
+ AddOrphanTx(tx, pfrom->GetId());
+
+ // DoS prevention: do not allow mapOrphanTransactions to grow unbounded
+ unsigned int nMaxOrphanTx = (unsigned int)std::max((int64_t)0, GetArg("-maxorphantx", DEFAULT_MAX_ORPHAN_TRANSACTIONS));
+ unsigned int nEvicted = LimitOrphanTxSize(nMaxOrphanTx);
+ if (nEvicted > 0)
+ LogPrint("mempool", "mapOrphan overflow, removed %u tx\n", nEvicted);
+ } else {
+ assert(recentRejects);
+ recentRejects->insert(tx.GetHash());
+
+ if (pfrom->fWhitelisted) {
+ // Always relay transactions received from whitelisted peers, even
+ // if they were rejected from the mempool, allowing the node to
+ // function as a gateway for nodes hidden behind it.
+ //
+ // FIXME: This includes invalid transactions, which means a
+ // whitelisted peer could get us banned! We may want to change
+ // that.
+ RelayTransaction(tx);
+ }
+ }
+ int nDoS = 0;
+ if (state.IsInvalid(nDoS))
+ {
+ LogPrint("mempool", "%s from peer=%d %s was not accepted into the memory pool: %s\n", tx.GetHash().ToString(),
+ pfrom->id, pfrom->cleanSubVer,
+ state.GetRejectReason());
+ pfrom->PushMessage("reject", strCommand, state.GetRejectCode(),
+ state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash);
+ if (nDoS > 0)
+ Misbehaving(pfrom->GetId(), nDoS);
+ }
+ }
+
+
+ else if (strCommand == "headers" && !fImporting && !fReindex) // Ignore headers received while importing
+ {
+ std::vector<CBlockHeader> headers;
+
+ // Bypass the normal CBlock deserialization, as we don't want to risk deserializing 2000 full blocks.
+ unsigned int nCount = ReadCompactSize(vRecv);
+ if (nCount > MAX_HEADERS_RESULTS) {
+ Misbehaving(pfrom->GetId(), 20);
+ return error("headers message size = %u", nCount);
+ }
+ headers.resize(nCount);
+ for (unsigned int n = 0; n < nCount; n++) {
+ vRecv >> headers[n];
+ ReadCompactSize(vRecv); // ignore tx count; assume it is 0.
+ }
+
+ LOCK(cs_main);
+
+ if (nCount == 0) {
+ // Nothing interesting. Stop asking this peers for more headers.
+ return true;
+ }
+
+ CBlockIndex *pindexLast = NULL;
+ BOOST_FOREACH(const CBlockHeader& header, headers) {
+ CValidationState state;
+ if (pindexLast != NULL && header.hashPrevBlock != pindexLast->GetBlockHash()) {
+ Misbehaving(pfrom->GetId(), 20);
+ return error("non-continuous headers sequence");
+ }
+ if (!AcceptBlockHeader(header, state, &pindexLast)) {
+ int nDoS;
+ if (state.IsInvalid(nDoS)) {
+ if (nDoS > 0)
+ Misbehaving(pfrom->GetId(), nDoS);
+ return error("invalid header received");
+ }
+ }
+ }
+
+ if (pindexLast)
+ UpdateBlockAvailability(pfrom->GetId(), pindexLast->GetBlockHash());
+
+ if (nCount == MAX_HEADERS_RESULTS && pindexLast) {
+ // Headers message had its maximum size; the peer may have more headers.
+ // TODO: optimize: if pindexLast is an ancestor of chainActive.Tip or pindexBestHeader, continue
+ // from there instead.
+ LogPrint("net", "more getheaders (%d) to end to peer=%d (startheight:%d)\n", pindexLast->nHeight, pfrom->id, pfrom->nStartingHeight);
+ pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexLast), uint256());
+ }
+
+ CheckBlockIndex();
+ }
+
+ else if (strCommand == "block" && !fImporting && !fReindex) // Ignore blocks received while importing
+ {
+ CBlock block;
+ vRecv >> block;
+
+ CInv inv(MSG_BLOCK, block.GetHash());
+ LogPrint("net", "received block %s peer=%d\n", inv.hash.ToString(), pfrom->id);
+
+ pfrom->AddInventoryKnown(inv);
+
+ CValidationState state;
+ // Process all blocks from whitelisted peers, even if not requested,
+ // unless we're still syncing with the network.
+ // Such an unrequested block may still be processed, subject to the
+ // conditions in AcceptBlock().
+ bool forceProcessing = pfrom->fWhitelisted && !IsInitialBlockDownload();
+ ProcessNewBlock(state, pfrom, &block, forceProcessing, NULL);
+ int nDoS;
+ if (state.IsInvalid(nDoS)) {
+ pfrom->PushMessage("reject", strCommand, state.GetRejectCode(),
+ state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash);
+ if (nDoS > 0) {
+ LOCK(cs_main);
+ Misbehaving(pfrom->GetId(), nDoS);
+ }
+ }
+
+ }
+
+
+ // This asymmetric behavior for inbound and outbound connections was introduced
+ // to prevent a fingerprinting attack: an attacker can send specific fake addresses
+ // to users' AddrMan and later request them by sending getaddr messages.
+ // Making nodes which are behind NAT and can only make outgoing connections ignore
+ // the getaddr message mitigates the attack.
+ else if ((strCommand == "getaddr") && (pfrom->fInbound))
+ {
+ pfrom->vAddrToSend.clear();
+ vector<CAddress> vAddr = addrman.GetAddr();
+ BOOST_FOREACH(const CAddress &addr, vAddr)
+ pfrom->PushAddress(addr);
+ }
+
+
+ else if (strCommand == "mempool")
+ {
+ LOCK2(cs_main, pfrom->cs_filter);
+
+ std::vector<uint256> vtxid;
+ mempool.queryHashes(vtxid);
+ vector<CInv> vInv;
+ BOOST_FOREACH(uint256& hash, vtxid) {
+ CInv inv(MSG_TX, hash);
+ CTransaction tx;
+ bool fInMemPool = mempool.lookup(hash, tx);
+ if (!fInMemPool) continue; // another thread removed since queryHashes, maybe...
+ if ((pfrom->pfilter && pfrom->pfilter->IsRelevantAndUpdate(tx)) ||
+ (!pfrom->pfilter))
+ vInv.push_back(inv);
+ if (vInv.size() == MAX_INV_SZ) {
+ pfrom->PushMessage("inv", vInv);
+ vInv.clear();
+ }
+ }
+ if (vInv.size() > 0)
+ pfrom->PushMessage("inv", vInv);
+ }
+
+
+ else if (strCommand == "ping")
+ {
+ if (pfrom->nVersion > BIP0031_VERSION)
+ {
+ uint64_t 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 == "pong")
+ {
+ int64_t pingUsecEnd = nTimeReceived;
+ uint64_t nonce = 0;
+ size_t nAvail = vRecv.in_avail();
+ bool bPingFinished = false;
+ std::string sProblem;
+
+ if (nAvail >= sizeof(nonce)) {
+ vRecv >> nonce;
+
+ // Only process pong message if there is an outstanding ping (old ping without nonce should never pong)
+ if (pfrom->nPingNonceSent != 0) {
+ if (nonce == pfrom->nPingNonceSent) {
+ // Matching pong received, this ping is no longer outstanding
+ bPingFinished = true;
+ int64_t pingUsecTime = pingUsecEnd - pfrom->nPingUsecStart;
+ if (pingUsecTime > 0) {
+ // Successful ping time measurement, replace previous
+ pfrom->nPingUsecTime = pingUsecTime;
+ } else {
+ // This should never happen
+ sProblem = "Timing mishap";
+ }
+ } else {
+ // Nonce mismatches are normal when pings are overlapping
+ sProblem = "Nonce mismatch";
+ if (nonce == 0) {
+ // This is most likely a bug in another implementation somewhere; cancel this ping
+ bPingFinished = true;
+ sProblem = "Nonce zero";
+ }
+ }
+ } else {
+ sProblem = "Unsolicited pong without ping";
+ }
+ } else {
+ // This is most likely a bug in another implementation somewhere; cancel this ping
+ bPingFinished = true;
+ sProblem = "Short payload";
+ }
+
+ if (!(sProblem.empty())) {
+ LogPrint("net", "pong peer=%d %s: %s, %x expected, %x received, %u bytes\n",
+ pfrom->id,
+ pfrom->cleanSubVer,
+ sProblem,
+ pfrom->nPingNonceSent,
+ nonce,
+ nAvail);
+ }
+ if (bPingFinished) {
+ pfrom->nPingNonceSent = 0;
+ }
+ }
+
+
+ else if (fAlerts && strCommand == "alert")
+ {
+ CAlert alert;
+ vRecv >> alert;
+
+ uint256 alertHash = alert.GetHash();
+ if (pfrom->setKnown.count(alertHash) == 0)
+ {
+ if (alert.ProcessAlert(Params().AlertKey()))
+ {
+ // Relay
+ pfrom->setKnown.insert(alertHash);
+ {
+ LOCK(cs_vNodes);
+ BOOST_FOREACH(CNode* pnode, vNodes)
+ alert.RelayTo(pnode);
+ }
+ }
+ else {
+ // Small DoS penalty so peers that send us lots of
+ // duplicate/expired/invalid-signature/whatever alerts
+ // eventually get banned.
+ // This isn't a Misbehaving(100) (immediate ban) because the
+ // peer might be an older or different implementation with
+ // a different signature key, etc.
+ Misbehaving(pfrom->GetId(), 10);
+ }
+ }
+ }
+
+
+ else if (strCommand == "filterload")
+ {
+ CBloomFilter filter;
+ vRecv >> filter;
+
+ if (!filter.IsWithinSizeConstraints())
+ // There is no excuse for sending a too-large filter
+ Misbehaving(pfrom->GetId(), 100);
+ else
+ {
+ LOCK(pfrom->cs_filter);
+ delete pfrom->pfilter;
+ pfrom->pfilter = new CBloomFilter(filter);
+ pfrom->pfilter->UpdateEmptyFull();
+ }
+ pfrom->fRelayTxes = true;
+ }
+
+
+ else if (strCommand == "filteradd")
+ {
+ vector<unsigned char> vData;
+ vRecv >> vData;
+
+ // Nodes must NEVER send a data item > 520 bytes (the max size for a script data object,
+ // and thus, the maximum size any matched object can have) in a filteradd message
+ if (vData.size() > MAX_SCRIPT_ELEMENT_SIZE)
+ {
+ Misbehaving(pfrom->GetId(), 100);
+ } else {
+ LOCK(pfrom->cs_filter);
+ if (pfrom->pfilter)
+ pfrom->pfilter->insert(vData);
+ else
+ Misbehaving(pfrom->GetId(), 100);
+ }
+ }
+
+
+ else if (strCommand == "filterclear")
+ {
+ LOCK(pfrom->cs_filter);
+ delete pfrom->pfilter;
+ pfrom->pfilter = new CBloomFilter();
+ pfrom->fRelayTxes = true;
+ }
+
+
+ else if (strCommand == "reject")
+ {
+ if (fDebug) {
+ try {
+ string strMsg; unsigned char ccode; string strReason;
+ vRecv >> LIMITED_STRING(strMsg, CMessageHeader::COMMAND_SIZE) >> ccode >> LIMITED_STRING(strReason, MAX_REJECT_MESSAGE_LENGTH);
+
+ ostringstream ss;
+ ss << strMsg << " code " << itostr(ccode) << ": " << strReason;
+
+ if (strMsg == "block" || strMsg == "tx")
+ {
+ uint256 hash;
+ vRecv >> hash;
+ ss << ": hash " << hash.ToString();
+ }
+ LogPrint("net", "Reject %s\n", SanitizeString(ss.str()));
+ } catch (const std::ios_base::failure&) {
+ // Avoid feedback loops by preventing reject messages from triggering a new reject message.
+ LogPrint("net", "Unparseable reject message received\n");
+ }
+ }
+ }
+
+ else
+ {
+ // Ignore unknown commands for extensibility
+ LogPrint("net", "Unknown command \"%s\" from peer=%d\n", SanitizeString(strCommand), pfrom->id);
+ }
+
+
+
+ return true;
+}
+
+// requires LOCK(cs_vRecvMsg)
+bool ProcessMessages(CNode* pfrom)
+{
+ //if (fDebug)
+ // LogPrintf("%s(%u messages)\n", __func__, pfrom->vRecvMsg.size());
+
+ //
+ // Message format
+ // (4) message start
+ // (12) command
+ // (4) size
+ // (4) checksum
+ // (x) data
+ //
+ bool fOk = true;
+
+ if (!pfrom->vRecvGetData.empty())
+ ProcessGetData(pfrom);
+
+ // this maintains the order of responses
+ if (!pfrom->vRecvGetData.empty()) return fOk;
+
+ std::deque<CNetMessage>::iterator it = pfrom->vRecvMsg.begin();
+ while (!pfrom->fDisconnect && it != pfrom->vRecvMsg.end()) {
+ // Don't bother if send buffer is too full to respond anyway
+ if (pfrom->nSendSize >= SendBufferSize())
+ break;
+
+ // get next message
+ CNetMessage& msg = *it;
+
+ //if (fDebug)
+ // LogPrintf("%s(message %u msgsz, %u bytes, complete:%s)\n", __func__,
+ // msg.hdr.nMessageSize, msg.vRecv.size(),
+ // msg.complete() ? "Y" : "N");
+
+ // end, if an incomplete message is found
+ if (!msg.complete())
+ break;
+
+ // at this point, any failure means we can delete the current message
+ it++;
+
+ // Scan for message start
+ if (memcmp(msg.hdr.pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE) != 0) {
+ LogPrintf("PROCESSMESSAGE: INVALID MESSAGESTART %s peer=%d\n", SanitizeString(msg.hdr.GetCommand()), pfrom->id);
+ fOk = false;
+ break;
+ }
+
+ // Read header
+ CMessageHeader& hdr = msg.hdr;
+ if (!hdr.IsValid(Params().MessageStart()))
+ {
+ LogPrintf("PROCESSMESSAGE: ERRORS IN HEADER %s peer=%d\n", SanitizeString(hdr.GetCommand()), pfrom->id);
+ continue;
+ }
+ string strCommand = hdr.GetCommand();
+
+ // Message size
+ unsigned int nMessageSize = hdr.nMessageSize;
+
+ // Checksum
+ CDataStream& vRecv = msg.vRecv;
+ uint256 hash = Hash(vRecv.begin(), vRecv.begin() + nMessageSize);
+ unsigned int nChecksum = ReadLE32((unsigned char*)&hash);
+ if (nChecksum != hdr.nChecksum)
+ {
+ LogPrintf("%s(%s, %u bytes): CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n", __func__,
+ SanitizeString(strCommand), nMessageSize, nChecksum, hdr.nChecksum);
+ continue;
+ }
+
+ // Process message
+ bool fRet = false;
+ try
+ {
+ fRet = ProcessMessage(pfrom, strCommand, vRecv, msg.nTime);
+ boost::this_thread::interruption_point();
+ }
+ catch (const std::ios_base::failure& e)
+ {
+ pfrom->PushMessage("reject", strCommand, REJECT_MALFORMED, string("error parsing message"));
+ if (strstr(e.what(), "end of data"))
+ {
+ // Allow exceptions from under-length message on vRecv
+ LogPrintf("%s(%s, %u bytes): Exception '%s' caught, normally caused by a message being shorter than its stated length\n", __func__, SanitizeString(strCommand), nMessageSize, e.what());
+ }
+ else if (strstr(e.what(), "size too large"))
+ {
+ // Allow exceptions from over-long size
+ LogPrintf("%s(%s, %u bytes): Exception '%s' caught\n", __func__, SanitizeString(strCommand), nMessageSize, e.what());
+ }
+ else
+ {
+ PrintExceptionContinue(&e, "ProcessMessages()");
+ }
+ }
+ catch (const boost::thread_interrupted&) {
+ throw;
+ }
+ catch (const std::exception& e) {
+ PrintExceptionContinue(&e, "ProcessMessages()");
+ } catch (...) {
+ PrintExceptionContinue(NULL, "ProcessMessages()");
+ }
+
+ if (!fRet)
+ LogPrintf("%s(%s, %u bytes) FAILED peer=%d\n", __func__, SanitizeString(strCommand), nMessageSize, pfrom->id);
+
+ break;
+ }
+
+ // In case the connection got shut down, its receive buffer was wiped
+ if (!pfrom->fDisconnect)
+ pfrom->vRecvMsg.erase(pfrom->vRecvMsg.begin(), it);
+
+ return fOk;
+}
+
+
+bool SendMessages(CNode* pto, bool fSendTrickle)
+{
+ const Consensus::Params& consensusParams = Params().GetConsensus();
+ {
+ // Don't send anything until we get its version message
+ if (pto->nVersion == 0)
+ return true;
+
+ //
+ // Message: ping
+ //
+ bool pingSend = false;
+ if (pto->fPingQueued) {
+ // RPC ping request by user
+ pingSend = true;
+ }
+ if (pto->nPingNonceSent == 0 && pto->nPingUsecStart + PING_INTERVAL * 1000000 < GetTimeMicros()) {
+ // Ping automatically sent as a latency probe & keepalive.
+ pingSend = true;
+ }
+ if (pingSend) {
+ uint64_t nonce = 0;
+ while (nonce == 0) {
+ GetRandBytes((unsigned char*)&nonce, sizeof(nonce));
+ }
+ pto->fPingQueued = false;
+ pto->nPingUsecStart = GetTimeMicros();
+ if (pto->nVersion > BIP0031_VERSION) {
+ pto->nPingNonceSent = nonce;
+ pto->PushMessage("ping", nonce);
+ } else {
+ // Peer is too old to support ping command with nonce, pong will never arrive.
+ pto->nPingNonceSent = 0;
+ pto->PushMessage("ping");
+ }
+ }
+
+ TRY_LOCK(cs_main, lockMain); // Acquire cs_main for IsInitialBlockDownload() and CNodeState()
+ if (!lockMain)
+ return true;
+
+ // Address refresh broadcast
+ static int64_t nLastRebroadcast;
+ if (!IsInitialBlockDownload() && (GetTime() - nLastRebroadcast > 24 * 60 * 60))
+ {
+ LOCK(cs_vNodes);
+ BOOST_FOREACH(CNode* pnode, vNodes)
+ {
+ // Periodically clear addrKnown to allow refresh broadcasts
+ if (nLastRebroadcast)
+ pnode->addrKnown.reset();
+
+ // Rebroadcast our address
+ AdvertizeLocal(pnode);
+ }
+ if (!vNodes.empty())
+ nLastRebroadcast = GetTime();
+ }
+
+ //
+ // Message: addr
+ //
+ if (fSendTrickle)
+ {
+ vector<CAddress> vAddr;
+ vAddr.reserve(pto->vAddrToSend.size());
+ BOOST_FOREACH(const CAddress& addr, pto->vAddrToSend)
+ {
+ if (!pto->addrKnown.contains(addr.GetKey()))
+ {
+ pto->addrKnown.insert(addr.GetKey());
+ 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);
+ }
+
+ CNodeState &state = *State(pto->GetId());
+ if (state.fShouldBan) {
+ if (pto->fWhitelisted)
+ LogPrintf("Warning: not punishing whitelisted peer %s!\n", pto->addr.ToString());
+ else {
+ pto->fDisconnect = true;
+ if (pto->addr.IsLocal())
+ LogPrintf("Warning: not banning local peer %s!\n", pto->addr.ToString());
+ else
+ {
+ CNode::Ban(pto->addr);
+ }
+ }
+ state.fShouldBan = false;
+ }
+
+ BOOST_FOREACH(const CBlockReject& reject, state.rejects)
+ pto->PushMessage("reject", (string)"block", reject.chRejectCode, reject.strRejectReason, reject.hashBlock);
+ state.rejects.clear();
+
+ // Start block sync
+ if (pindexBestHeader == NULL)
+ pindexBestHeader = chainActive.Tip();
+ bool fFetch = state.fPreferredDownload || (nPreferredDownload == 0 && !pto->fClient && !pto->fOneShot); // Download if this is a nice peer, or we have no nice peers and this one might do.
+ if (!state.fSyncStarted && !pto->fClient && !fImporting && !fReindex) {
+ // Only actively request headers from a single peer, unless we're close to today.
+ if ((nSyncStarted == 0 && fFetch) || pindexBestHeader->GetBlockTime() > GetAdjustedTime() - 24 * 60 * 60) {
+ state.fSyncStarted = true;
+ nSyncStarted++;
+ CBlockIndex *pindexStart = pindexBestHeader->pprev ? pindexBestHeader->pprev : pindexBestHeader;
+ LogPrint("net", "initial getheaders (%d) to peer=%d (startheight:%d)\n", pindexStart->nHeight, pto->id, pto->nStartingHeight);
+ pto->PushMessage("getheaders", chainActive.GetLocator(pindexStart), uint256());
+ }
+ }
+
+ // Resend wallet transactions that haven't gotten in a block yet
+ // Except during reindex, importing and IBD, when old wallet
+ // transactions become unconfirmed and spams other nodes.
+ if (!fReindex && !fImporting && !IsInitialBlockDownload())
+ {
+ GetMainSignals().Broadcast(nTimeBestReceived);
+ }
+
+ //
+ // Message: inventory
+ //
+ vector<CInv> vInv;
+ vector<CInv> 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.IsNull())
+ hashSalt = GetRandHash();
+ uint256 hashRand = ArithToUint256(UintToArith256(inv.hash) ^ UintToArith256(hashSalt));
+ hashRand = Hash(BEGIN(hashRand), END(hashRand));
+ bool fTrickleWait = ((UintToArith256(hashRand) & 3) != 0);
+
+ 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);
+
+ // Detect whether we're stalling
+ int64_t nNow = GetTimeMicros();
+ if (!pto->fDisconnect && state.nStallingSince && state.nStallingSince < nNow - 1000000 * BLOCK_STALLING_TIMEOUT) {
+ // Stalling only triggers when the block download window cannot move. During normal steady state,
+ // the download window should be much larger than the to-be-downloaded set of blocks, so disconnection
+ // should only happen during initial block download.
+ LogPrintf("Peer=%d is stalling block download, disconnecting\n", pto->id);
+ pto->fDisconnect = true;
+ }
+ // In case there is a block that has been in flight from this peer for (2 + 0.5 * N) times the block interval
+ // (with N the number of validated blocks that were in flight at the time it was requested), disconnect due to
+ // timeout. We compensate for in-flight blocks to prevent killing off peers due to our own downstream link
+ // being saturated. We only count validated in-flight blocks so peers can't advertise non-existing block hashes
+ // to unreasonably increase our timeout.
+ // We also compare the block download timeout originally calculated against the time at which we'd disconnect
+ // if we assumed the block were being requested now (ignoring blocks we've requested from this peer, since we're
+ // only looking at this peer's oldest request). This way a large queue in the past doesn't result in a
+ // permanently large window for this block to be delivered (ie if the number of blocks in flight is decreasing
+ // more quickly than once every 5 minutes, then we'll shorten the download window for this block).
+ if (!pto->fDisconnect && state.vBlocksInFlight.size() > 0) {
+ QueuedBlock &queuedBlock = state.vBlocksInFlight.front();
+ int64_t nTimeoutIfRequestedNow = GetBlockTimeout(nNow, nQueuedValidatedHeaders - state.nBlocksInFlightValidHeaders, consensusParams);
+ if (queuedBlock.nTimeDisconnect > nTimeoutIfRequestedNow) {
+ LogPrint("net", "Reducing block download timeout for peer=%d block=%s, orig=%d new=%d\n", pto->id, queuedBlock.hash.ToString(), queuedBlock.nTimeDisconnect, nTimeoutIfRequestedNow);
+ queuedBlock.nTimeDisconnect = nTimeoutIfRequestedNow;
+ }
+ if (queuedBlock.nTimeDisconnect < nNow) {
+ LogPrintf("Timeout downloading block %s from peer=%d, disconnecting\n", queuedBlock.hash.ToString(), pto->id);
+ pto->fDisconnect = true;
+ }
+ }
+
+ //
+ // Message: getdata (blocks)
+ //
+ vector<CInv> vGetData;
+ if (!pto->fDisconnect && !pto->fClient && (fFetch || !IsInitialBlockDownload()) && state.nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
+ vector<CBlockIndex*> vToDownload;
+ NodeId staller = -1;
+ FindNextBlocksToDownload(pto->GetId(), MAX_BLOCKS_IN_TRANSIT_PER_PEER - state.nBlocksInFlight, vToDownload, staller);
+ BOOST_FOREACH(CBlockIndex *pindex, vToDownload) {
+ vGetData.push_back(CInv(MSG_BLOCK, pindex->GetBlockHash()));
+ MarkBlockAsInFlight(pto->GetId(), pindex->GetBlockHash(), consensusParams, pindex);
+ LogPrint("net", "Requesting block %s (%d) peer=%d\n", pindex->GetBlockHash().ToString(),
+ pindex->nHeight, pto->id);
+ }
+ if (state.nBlocksInFlight == 0 && staller != -1) {
+ if (State(staller)->nStallingSince == 0) {
+ State(staller)->nStallingSince = nNow;
+ LogPrint("net", "Stall started peer=%d\n", staller);
+ }
+ }
+ }
+
+ //
+ // Message: getdata (non-blocks)
+ //
+ while (!pto->fDisconnect && !pto->mapAskFor.empty() && (*pto->mapAskFor.begin()).first <= nNow)
+ {
+ const CInv& inv = (*pto->mapAskFor.begin()).second;
+ if (!AlreadyHave(inv))
+ {
+ if (fDebug)
+ LogPrint("net", "Requesting %s peer=%d\n", inv.ToString(), pto->id);
+ vGetData.push_back(inv);
+ if (vGetData.size() >= 1000)
+ {
+ pto->PushMessage("getdata", vGetData);
+ vGetData.clear();
+ }
+ }
+ pto->mapAskFor.erase(pto->mapAskFor.begin());
+ }
+ if (!vGetData.empty())
+ pto->PushMessage("getdata", vGetData);
+
+ }
+ return true;
+}
+
+ std::string CBlockFileInfo::ToString() const {
+ return strprintf("CBlockFileInfo(blocks=%u, size=%u, heights=%u...%u, time=%s...%s)", nBlocks, nSize, nHeightFirst, nHeightLast, DateTimeStrFormat("%Y-%m-%d", nTimeFirst), DateTimeStrFormat("%Y-%m-%d", nTimeLast));
+ }
+
+
+
+class CMainCleanup
+{
+public:
+ CMainCleanup() {}
+ ~CMainCleanup() {
+ // block headers
+ BlockMap::iterator it1 = mapBlockIndex.begin();
+ for (; it1 != mapBlockIndex.end(); it1++)
+ delete (*it1).second;
+ mapBlockIndex.clear();
+
+ // orphan transactions
+ mapOrphanTransactions.clear();
+ mapOrphanTransactionsByPrev.clear();
+ }
+} instance_of_cmaincleanup;
diff --git a/src/main.h b/src/main.h
new file mode 100644
index 0000000000..58c717c277
--- /dev/null
+++ b/src/main.h
@@ -0,0 +1,493 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_MAIN_H
+#define BITCOIN_MAIN_H
+
+#if defined(HAVE_CONFIG_H)
+#include "config/bitcoin-config.h"
+#endif
+
+#include "amount.h"
+#include "chain.h"
+#include "chainparams.h"
+#include "coins.h"
+#include "consensus/consensus.h"
+#include "net.h"
+#include "primitives/block.h"
+#include "primitives/transaction.h"
+#include "script/script.h"
+#include "script/sigcache.h"
+#include "script/standard.h"
+#include "sync.h"
+#include "tinyformat.h"
+#include "txmempool.h"
+#include "uint256.h"
+
+#include <algorithm>
+#include <exception>
+#include <map>
+#include <set>
+#include <stdint.h>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include <boost/unordered_map.hpp>
+
+class CBlockIndex;
+class CBlockTreeDB;
+class CBloomFilter;
+class CInv;
+class CScriptCheck;
+class CValidationInterface;
+class CValidationState;
+
+struct CNodeStateStats;
+
+/** Default for -blockmaxsize and -blockminsize, which control the range of sizes the mining code will create **/
+static const unsigned int DEFAULT_BLOCK_MAX_SIZE = 750000;
+static const unsigned int DEFAULT_BLOCK_MIN_SIZE = 0;
+/** Default for -blockprioritysize, maximum space for zero/low-fee transactions **/
+static const unsigned int DEFAULT_BLOCK_PRIORITY_SIZE = 50000;
+/** Default for accepting alerts from the P2P network. */
+static const bool DEFAULT_ALERTS = true;
+/** The maximum size for transactions we're willing to relay/mine */
+static const unsigned int MAX_STANDARD_TX_SIZE = 100000;
+/** Maximum number of signature check operations in an IsStandard() P2SH script */
+static const unsigned int MAX_P2SH_SIGOPS = 15;
+/** The maximum number of sigops we're willing to relay/mine in a single tx */
+static const unsigned int MAX_STANDARD_TX_SIGOPS = MAX_BLOCK_SIGOPS/5;
+/** Default for -maxorphantx, maximum number of orphan transactions kept in memory */
+static const unsigned int DEFAULT_MAX_ORPHAN_TRANSACTIONS = 100;
+/** The maximum size of a blk?????.dat file (since 0.8) */
+static const unsigned int MAX_BLOCKFILE_SIZE = 0x8000000; // 128 MiB
+/** The pre-allocation chunk size for blk?????.dat files (since 0.8) */
+static const unsigned int BLOCKFILE_CHUNK_SIZE = 0x1000000; // 16 MiB
+/** The pre-allocation chunk size for rev?????.dat files (since 0.8) */
+static const unsigned int UNDOFILE_CHUNK_SIZE = 0x100000; // 1 MiB
+/** Maximum number of script-checking threads allowed */
+static const int MAX_SCRIPTCHECK_THREADS = 16;
+/** -par default (number of script-checking threads, 0 = auto) */
+static const int DEFAULT_SCRIPTCHECK_THREADS = 0;
+/** Number of blocks that can be requested at any given time from a single peer. */
+static const int MAX_BLOCKS_IN_TRANSIT_PER_PEER = 16;
+/** Timeout in seconds during which a peer must stall block download progress before being disconnected. */
+static const unsigned int BLOCK_STALLING_TIMEOUT = 2;
+/** Number of headers sent in one getheaders result. We rely on the assumption that if a peer sends
+ * less than this number, we reached its tip. Changing this value is a protocol upgrade. */
+static const unsigned int MAX_HEADERS_RESULTS = 2000;
+/** Size of the "block download window": how far ahead of our current height do we fetch?
+ * Larger windows tolerate larger download speed differences between peer, but increase the potential
+ * degree of disordering of blocks on disk (which make reindexing and in the future perhaps pruning
+ * harder). We'll probably want to make this a per-peer adaptive value at some point. */
+static const unsigned int BLOCK_DOWNLOAD_WINDOW = 1024;
+/** Time to wait (in seconds) between writing blocks/block index to disk. */
+static const unsigned int DATABASE_WRITE_INTERVAL = 60 * 60;
+/** Time to wait (in seconds) between flushing chainstate to disk. */
+static const unsigned int DATABASE_FLUSH_INTERVAL = 24 * 60 * 60;
+/** Maximum length of reject messages. */
+static const unsigned int MAX_REJECT_MESSAGE_LENGTH = 111;
+
+struct BlockHasher
+{
+ size_t operator()(const uint256& hash) const { return hash.GetCheapHash(); }
+};
+
+extern CScript COINBASE_FLAGS;
+extern CCriticalSection cs_main;
+extern CTxMemPool mempool;
+typedef boost::unordered_map<uint256, CBlockIndex*, BlockHasher> BlockMap;
+extern BlockMap mapBlockIndex;
+extern uint64_t nLastBlockTx;
+extern uint64_t nLastBlockSize;
+extern const std::string strMessageMagic;
+extern CWaitableCriticalSection csBestBlock;
+extern CConditionVariable cvBlockChange;
+extern bool fImporting;
+extern bool fReindex;
+extern int nScriptCheckThreads;
+extern bool fTxIndex;
+extern bool fIsBareMultisigStd;
+extern bool fCheckBlockIndex;
+extern bool fCheckpointsEnabled;
+extern size_t nCoinCacheUsage;
+extern CFeeRate minRelayTxFee;
+extern bool fAlerts;
+
+/** Best header we've seen so far (used for getheaders queries' starting points). */
+extern CBlockIndex *pindexBestHeader;
+
+/** Minimum disk space required - used in CheckDiskSpace() */
+static const uint64_t nMinDiskSpace = 52428800;
+
+/** Pruning-related variables and constants */
+/** True if any block files have ever been pruned. */
+extern bool fHavePruned;
+/** True if we're running in -prune mode. */
+extern bool fPruneMode;
+/** Number of MiB of block files that we're trying to stay below. */
+extern uint64_t nPruneTarget;
+/** Block files containing a block-height within MIN_BLOCKS_TO_KEEP of chainActive.Tip() will not be pruned. */
+static const signed int MIN_BLOCKS_TO_KEEP = 288;
+
+// Require that user allocate at least 550MB for block & undo files (blk???.dat and rev???.dat)
+// At 1MB per block, 288 blocks = 288MB.
+// Add 15% for Undo data = 331MB
+// Add 20% for Orphan block rate = 397MB
+// We want the low water mark after pruning to be at least 397 MB and since we prune in
+// full block file chunks, we need the high water mark which triggers the prune to be
+// one 128MB block file + added 15% undo data = 147MB greater for a total of 545MB
+// Setting the target to > than 550MB will make it likely we can respect the target.
+static const signed int MIN_DISK_SPACE_FOR_BLOCK_FILES = 550 * 1024 * 1024;
+
+/** Register with a network node to receive its signals */
+void RegisterNodeSignals(CNodeSignals& nodeSignals);
+/** Unregister a network node */
+void UnregisterNodeSignals(CNodeSignals& nodeSignals);
+
+/**
+ * Process an incoming block. This only returns after the best known valid
+ * block is made active. Note that it does not, however, guarantee that the
+ * specific block passed to it has been checked for validity!
+ *
+ * @param[out] state This may be set to an Error state if any error occurred processing it, including during validation/connection/etc of otherwise unrelated blocks during reorganisation; or it may be set to an Invalid state if pblock is itself invalid (but this is not guaranteed even when the block is checked). If you want to *possibly* get feedback on whether pblock is valid, you must also install a CValidationInterface (see validationinterface.h) - this will have its BlockChecked method called whenever *any* block completes validation.
+ * @param[in] pfrom The node which we are receiving the block from; it is added to mapBlockSource and may be penalised if the block is invalid.
+ * @param[in] pblock The block we want to process.
+ * @param[in] fForceProcessing Process this block even if unrequested; used for non-network block sources and whitelisted peers.
+ * @param[out] dbp If pblock is stored to disk (or already there), this will be set to its location.
+ * @return True if state.IsValid()
+ */
+bool ProcessNewBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, bool fForceProcessing, CDiskBlockPos *dbp);
+/** Check whether enough disk space is available for an incoming block */
+bool CheckDiskSpace(uint64_t nAdditionalBytes = 0);
+/** Open a block file (blk?????.dat) */
+FILE* OpenBlockFile(const CDiskBlockPos &pos, bool fReadOnly = false);
+/** Open an undo file (rev?????.dat) */
+FILE* OpenUndoFile(const CDiskBlockPos &pos, bool fReadOnly = false);
+/** Translation to a filesystem path */
+boost::filesystem::path GetBlockPosFilename(const CDiskBlockPos &pos, const char *prefix);
+/** Import blocks from an external file */
+bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp = NULL);
+/** Initialize a new block tree database + block data on disk */
+bool InitBlockIndex();
+/** Load the block tree and coins database from disk */
+bool LoadBlockIndex();
+/** Unload database information */
+void UnloadBlockIndex();
+/** Process protocol messages received from a given node */
+bool ProcessMessages(CNode* pfrom);
+/**
+ * Send queued protocol messages to be sent to a give node.
+ *
+ * @param[in] pto The node which we are sending messages to.
+ * @param[in] fSendTrickle When true send the trickled data, otherwise trickle the data until true.
+ */
+bool SendMessages(CNode* pto, bool fSendTrickle);
+/** Run an instance of the script checking thread */
+void ThreadScriptCheck();
+/** Try to detect Partition (network isolation) attacks against us */
+void PartitionCheck(bool (*initialDownloadCheck)(), CCriticalSection& cs, const CBlockIndex *const &bestHeader, int64_t nPowTargetSpacing);
+/** Check whether we are doing an initial block download (synchronizing from disk or network) */
+bool IsInitialBlockDownload();
+/** Format a string that describes several potential problems detected by the core */
+std::string GetWarnings(std::string strFor);
+/** Retrieve a transaction (from memory pool, or from disk, if possible) */
+bool GetTransaction(const uint256 &hash, CTransaction &tx, uint256 &hashBlock, bool fAllowSlow = false);
+/** Find the best known block, and make it the tip of the block chain */
+bool ActivateBestChain(CValidationState &state, CBlock *pblock = NULL);
+CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams);
+
+/**
+ * Prune block and undo files (blk???.dat and undo???.dat) so that the disk space used is less than a user-defined target.
+ * The user sets the target (in MB) on the command line or in config file. This will be run on startup and whenever new
+ * space is allocated in a block or undo file, staying below the target. Changing back to unpruned requires a reindex
+ * (which in this case means the blockchain must be re-downloaded.)
+ *
+ * Pruning functions are called from FlushStateToDisk when the global fCheckForPruning flag has been set.
+ * Block and undo files are deleted in lock-step (when blk00003.dat is deleted, so is rev00003.dat.)
+ * Pruning cannot take place until the longest chain is at least a certain length (100000 on mainnet, 1000 on testnet, 10 on regtest).
+ * Pruning will never delete a block within a defined distance (currently 288) from the active chain's tip.
+ * The block index is updated by unsetting HAVE_DATA and HAVE_UNDO for any blocks that were stored in the deleted files.
+ * A db flag records the fact that at least some block files have been pruned.
+ *
+ * @param[out] setFilesToPrune The set of file indices that can be unlinked will be returned
+ */
+void FindFilesToPrune(std::set<int>& setFilesToPrune);
+
+/**
+ * Actually unlink the specified files
+ */
+void UnlinkPrunedFiles(std::set<int>& setFilesToPrune);
+
+/** Create a new block index entry for a given block hash */
+CBlockIndex * InsertBlockIndex(uint256 hash);
+/** Get statistics from node state */
+bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats);
+/** Increase a node's misbehavior score. */
+void Misbehaving(NodeId nodeid, int howmuch);
+/** Flush all state, indexes and buffers to disk. */
+void FlushStateToDisk();
+/** Prune block files and flush state to disk. */
+void PruneAndFlush();
+
+/** (try to) add transaction to memory pool **/
+bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree,
+ bool* pfMissingInputs, bool fRejectAbsurdFee=false);
+
+
+struct CNodeStateStats {
+ int nMisbehavior;
+ int nSyncHeight;
+ int nCommonHeight;
+ std::vector<int> vHeightInFlight;
+};
+
+struct CDiskTxPos : public CDiskBlockPos
+{
+ unsigned int nTxOffset; // after header
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ READWRITE(*(CDiskBlockPos*)this);
+ READWRITE(VARINT(nTxOffset));
+ }
+
+ CDiskTxPos(const CDiskBlockPos &blockIn, unsigned int nTxOffsetIn) : CDiskBlockPos(blockIn.nFile, blockIn.nPos), nTxOffset(nTxOffsetIn) {
+ }
+
+ CDiskTxPos() {
+ SetNull();
+ }
+
+ void SetNull() {
+ CDiskBlockPos::SetNull();
+ nTxOffset = 0;
+ }
+};
+
+
+CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree);
+
+/**
+ * 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
+ */
+
+/**
+ * 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
+ */
+bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs);
+
+/**
+ * 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 CTransaction& tx);
+
+/**
+ * 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 CTransaction& tx, const CCoinsViewCache& mapInputs);
+
+
+/**
+ * Check whether all inputs of this transaction are valid (no double spends, scripts & sigs, amounts)
+ * This does not modify the UTXO set. If pvChecks is not NULL, script checks are pushed onto it
+ * instead of being performed inline.
+ */
+bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &view, bool fScriptChecks,
+ unsigned int flags, bool cacheStore, std::vector<CScriptCheck> *pvChecks = NULL);
+
+/** Apply the effects of this transaction on the UTXO set represented by view */
+void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, int nHeight);
+
+/** Context-independent validity checks */
+bool CheckTransaction(const CTransaction& tx, CValidationState& state);
+
+/** Check for standard transaction types
+ * @return True if all outputs (scriptPubKeys) use only standard transaction forms
+ */
+bool IsStandardTx(const CTransaction& tx, std::string& reason);
+
+/**
+ * Check if transaction is final and can be included in a block with the
+ * specified height and time. Consensus critical.
+ */
+bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime);
+
+/**
+ * Check if transaction will be final in the next block to be created.
+ *
+ * Calls IsFinalTx() with current block height and appropriate block time.
+ */
+bool CheckFinalTx(const CTransaction &tx);
+
+/**
+ * Closure representing one script verification
+ * Note that this stores references to the spending transaction
+ */
+class CScriptCheck
+{
+private:
+ CScript scriptPubKey;
+ const CTransaction *ptxTo;
+ unsigned int nIn;
+ unsigned int nFlags;
+ bool cacheStore;
+ ScriptError error;
+
+public:
+ CScriptCheck(): ptxTo(0), nIn(0), nFlags(0), cacheStore(false), error(SCRIPT_ERR_UNKNOWN_ERROR) {}
+ CScriptCheck(const CCoins& txFromIn, const CTransaction& txToIn, unsigned int nInIn, unsigned int nFlagsIn, bool cacheIn) :
+ scriptPubKey(txFromIn.vout[txToIn.vin[nInIn].prevout.n].scriptPubKey),
+ ptxTo(&txToIn), nIn(nInIn), nFlags(nFlagsIn), cacheStore(cacheIn), error(SCRIPT_ERR_UNKNOWN_ERROR) { }
+
+ bool operator()();
+
+ void swap(CScriptCheck &check) {
+ scriptPubKey.swap(check.scriptPubKey);
+ std::swap(ptxTo, check.ptxTo);
+ std::swap(nIn, check.nIn);
+ std::swap(nFlags, check.nFlags);
+ std::swap(cacheStore, check.cacheStore);
+ std::swap(error, check.error);
+ }
+
+ ScriptError GetScriptError() const { return error; }
+};
+
+
+/** Functions for disk access for blocks */
+bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart);
+bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos);
+bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex);
+
+
+/** Functions for validating blocks and updating the block tree */
+
+/** Undo the effects of this block (with given index) on the UTXO set represented by coins.
+ * In case pfClean is provided, operation will try to be tolerant about errors, and *pfClean
+ * will be true if no problems were found. Otherwise, the return value will be false in case
+ * of problems. Note that in any case, coins may be modified. */
+bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& coins, bool* pfClean = NULL);
+
+/** Apply the effects of this block (with given index) on the UTXO set represented by coins */
+bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& coins, bool fJustCheck = false);
+
+/** Context-independent validity checks */
+bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, bool fCheckPOW = true);
+bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW = true, bool fCheckMerkleRoot = true);
+
+/** Context-dependent validity checks */
+bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex *pindexPrev);
+bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIndex *pindexPrev);
+
+/** Check a block is completely valid from start to finish (only works on top of our current best block, with cs_main held) */
+bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex *pindexPrev, bool fCheckPOW = true, bool fCheckMerkleRoot = true);
+
+/** Store block on disk. If dbp is non-NULL, the file is known to already reside on disk */
+bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex **pindex, bool fRequested, CDiskBlockPos* dbp);
+bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex **ppindex= NULL);
+
+
+
+class CBlockFileInfo
+{
+public:
+ unsigned int nBlocks; //! number of blocks stored in file
+ unsigned int nSize; //! number of used bytes of block file
+ unsigned int nUndoSize; //! number of used bytes in the undo file
+ unsigned int nHeightFirst; //! lowest height of block in file
+ unsigned int nHeightLast; //! highest height of block in file
+ uint64_t nTimeFirst; //! earliest time of block in file
+ uint64_t nTimeLast; //! latest time of block in file
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ READWRITE(VARINT(nBlocks));
+ READWRITE(VARINT(nSize));
+ READWRITE(VARINT(nUndoSize));
+ READWRITE(VARINT(nHeightFirst));
+ READWRITE(VARINT(nHeightLast));
+ READWRITE(VARINT(nTimeFirst));
+ READWRITE(VARINT(nTimeLast));
+ }
+
+ void SetNull() {
+ nBlocks = 0;
+ nSize = 0;
+ nUndoSize = 0;
+ nHeightFirst = 0;
+ nHeightLast = 0;
+ nTimeFirst = 0;
+ nTimeLast = 0;
+ }
+
+ CBlockFileInfo() {
+ SetNull();
+ }
+
+ std::string ToString() const;
+
+ /** update statistics (does not update nSize) */
+ void AddBlock(unsigned int nHeightIn, uint64_t nTimeIn) {
+ if (nBlocks==0 || nHeightFirst > nHeightIn)
+ nHeightFirst = nHeightIn;
+ if (nBlocks==0 || nTimeFirst > nTimeIn)
+ nTimeFirst = nTimeIn;
+ nBlocks++;
+ if (nHeightIn > nHeightLast)
+ nHeightLast = nHeightIn;
+ if (nTimeIn > nTimeLast)
+ nTimeLast = nTimeIn;
+ }
+};
+
+/** RAII wrapper for VerifyDB: Verify consistency of the block and coin databases */
+class CVerifyDB {
+public:
+ CVerifyDB();
+ ~CVerifyDB();
+ bool VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth);
+};
+
+/** Find the last common block between the parameter chain and a locator. */
+CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& locator);
+
+/** Mark a block as invalid. */
+bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex);
+
+/** Remove invalidity status from a block and its descendants. */
+bool ReconsiderBlock(CValidationState& state, CBlockIndex *pindex);
+
+/** The currently-connected chain of blocks. */
+extern CChain chainActive;
+
+/** Global variable that points to the active CCoinsView (protected by cs_main) */
+extern CCoinsViewCache *pcoinsTip;
+
+/** Global variable that points to the active block tree (protected by cs_main) */
+extern CBlockTreeDB *pblocktree;
+
+#endif // BITCOIN_MAIN_H
diff --git a/src/memusage.h b/src/memusage.h
new file mode 100644
index 0000000000..9f7de9e2e1
--- /dev/null
+++ b/src/memusage.h
@@ -0,0 +1,111 @@
+// Copyright (c) 2015 The Bitcoin developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_MEMUSAGE_H
+#define BITCOIN_MEMUSAGE_H
+
+#include <stdlib.h>
+
+#include <map>
+#include <set>
+#include <vector>
+
+#include <boost/unordered_set.hpp>
+#include <boost/unordered_map.hpp>
+
+namespace memusage
+{
+
+/** Compute the total memory used by allocating alloc bytes. */
+static size_t MallocUsage(size_t alloc);
+
+/** Compute the memory used for dynamically allocated but owned data structures.
+ * For generic data types, this is *not* recursive. DynamicUsage(vector<vector<int> >)
+ * will compute the memory used for the vector<int>'s, but not for the ints inside.
+ * This is for efficiency reasons, as these functions are intended to be fast. If
+ * application data structures require more accurate inner accounting, they should
+ * do the recursion themselves, or use more efficient caching + updating on modification.
+ */
+template<typename X> static size_t DynamicUsage(const std::vector<X>& v);
+template<typename X> static size_t DynamicUsage(const std::set<X>& s);
+template<typename X, typename Y> static size_t DynamicUsage(const std::map<X, Y>& m);
+template<typename X, typename Y> static size_t DynamicUsage(const boost::unordered_set<X, Y>& s);
+template<typename X, typename Y, typename Z> static size_t DynamicUsage(const boost::unordered_map<X, Y, Z>& s);
+template<typename X> static size_t DynamicUsage(const X& x);
+
+static inline size_t MallocUsage(size_t alloc)
+{
+ // Measured on libc6 2.19 on Linux.
+ if (sizeof(void*) == 8) {
+ return ((alloc + 31) >> 4) << 4;
+ } else if (sizeof(void*) == 4) {
+ return ((alloc + 15) >> 3) << 3;
+ } else {
+ assert(0);
+ }
+}
+
+// STL data structures
+
+template<typename X>
+struct stl_tree_node
+{
+private:
+ int color;
+ void* parent;
+ void* left;
+ void* right;
+ X x;
+};
+
+template<typename X>
+static inline size_t DynamicUsage(const std::vector<X>& v)
+{
+ return MallocUsage(v.capacity() * sizeof(X));
+}
+
+template<typename X>
+static inline size_t DynamicUsage(const std::set<X>& s)
+{
+ return MallocUsage(sizeof(stl_tree_node<X>)) * s.size();
+}
+
+template<typename X, typename Y>
+static inline size_t DynamicUsage(const std::map<X, Y>& m)
+{
+ return MallocUsage(sizeof(stl_tree_node<std::pair<const X, Y> >)) * m.size();
+}
+
+// Boost data structures
+
+template<typename X>
+struct boost_unordered_node : private X
+{
+private:
+ void* ptr;
+};
+
+template<typename X, typename Y>
+static inline size_t DynamicUsage(const boost::unordered_set<X, Y>& s)
+{
+ return MallocUsage(sizeof(boost_unordered_node<X>)) * s.size() + MallocUsage(sizeof(void*) * s.bucket_count());
+}
+
+template<typename X, typename Y, typename Z>
+static inline size_t DynamicUsage(const boost::unordered_map<X, Y, Z>& m)
+{
+ return MallocUsage(sizeof(boost_unordered_node<std::pair<const X, Y> >)) * m.size() + MallocUsage(sizeof(void*) * m.bucket_count());
+}
+
+// Dispatch to class method as fallback
+
+template<typename X>
+static inline size_t DynamicUsage(const X& x)
+{
+ return x.DynamicMemoryUsage();
+}
+
+}
+
+#endif
diff --git a/src/merkleblock.cpp b/src/merkleblock.cpp
new file mode 100644
index 0000000000..f8e877df25
--- /dev/null
+++ b/src/merkleblock.cpp
@@ -0,0 +1,181 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "merkleblock.h"
+
+#include "hash.h"
+#include "consensus/consensus.h"
+#include "utilstrencodings.h"
+
+using namespace std;
+
+CMerkleBlock::CMerkleBlock(const CBlock& block, CBloomFilter& filter)
+{
+ header = block.GetBlockHeader();
+
+ vector<bool> vMatch;
+ vector<uint256> vHashes;
+
+ vMatch.reserve(block.vtx.size());
+ vHashes.reserve(block.vtx.size());
+
+ for (unsigned int i = 0; i < block.vtx.size(); i++)
+ {
+ const uint256& hash = block.vtx[i].GetHash();
+ if (filter.IsRelevantAndUpdate(block.vtx[i]))
+ {
+ vMatch.push_back(true);
+ vMatchedTxn.push_back(make_pair(i, hash));
+ }
+ else
+ vMatch.push_back(false);
+ vHashes.push_back(hash);
+ }
+
+ txn = CPartialMerkleTree(vHashes, vMatch);
+}
+
+CMerkleBlock::CMerkleBlock(const CBlock& block, const std::set<uint256>& txids)
+{
+ header = block.GetBlockHeader();
+
+ vector<bool> vMatch;
+ vector<uint256> vHashes;
+
+ vMatch.reserve(block.vtx.size());
+ vHashes.reserve(block.vtx.size());
+
+ for (unsigned int i = 0; i < block.vtx.size(); i++)
+ {
+ const uint256& hash = block.vtx[i].GetHash();
+ if (txids.count(hash))
+ vMatch.push_back(true);
+ else
+ vMatch.push_back(false);
+ vHashes.push_back(hash);
+ }
+
+ txn = CPartialMerkleTree(vHashes, vMatch);
+}
+
+uint256 CPartialMerkleTree::CalcHash(int height, unsigned int pos, const std::vector<uint256> &vTxid) {
+ if (height == 0) {
+ // hash at height 0 is the txids themself
+ return vTxid[pos];
+ } else {
+ // calculate left hash
+ uint256 left = CalcHash(height-1, pos*2, vTxid), right;
+ // calculate right hash if not beyond the end of the array - copy left hash otherwise1
+ if (pos*2+1 < CalcTreeWidth(height-1))
+ right = CalcHash(height-1, pos*2+1, vTxid);
+ else
+ right = left;
+ // combine subhashes
+ return Hash(BEGIN(left), END(left), BEGIN(right), END(right));
+ }
+}
+
+void CPartialMerkleTree::TraverseAndBuild(int height, unsigned int pos, const std::vector<uint256> &vTxid, const std::vector<bool> &vMatch) {
+ // determine whether this node is the parent of at least one matched txid
+ bool fParentOfMatch = false;
+ for (unsigned int p = pos << height; p < (pos+1) << height && p < nTransactions; p++)
+ fParentOfMatch |= vMatch[p];
+ // store as flag bit
+ vBits.push_back(fParentOfMatch);
+ if (height==0 || !fParentOfMatch) {
+ // if at height 0, or nothing interesting below, store hash and stop
+ vHash.push_back(CalcHash(height, pos, vTxid));
+ } else {
+ // otherwise, don't store any hash, but descend into the subtrees
+ TraverseAndBuild(height-1, pos*2, vTxid, vMatch);
+ if (pos*2+1 < CalcTreeWidth(height-1))
+ TraverseAndBuild(height-1, pos*2+1, vTxid, vMatch);
+ }
+}
+
+uint256 CPartialMerkleTree::TraverseAndExtract(int height, unsigned int pos, unsigned int &nBitsUsed, unsigned int &nHashUsed, std::vector<uint256> &vMatch) {
+ if (nBitsUsed >= vBits.size()) {
+ // overflowed the bits array - failure
+ fBad = true;
+ return uint256();
+ }
+ bool fParentOfMatch = vBits[nBitsUsed++];
+ if (height==0 || !fParentOfMatch) {
+ // if at height 0, or nothing interesting below, use stored hash and do not descend
+ if (nHashUsed >= vHash.size()) {
+ // overflowed the hash array - failure
+ fBad = true;
+ return uint256();
+ }
+ const uint256 &hash = vHash[nHashUsed++];
+ if (height==0 && fParentOfMatch) // in case of height 0, we have a matched txid
+ vMatch.push_back(hash);
+ return hash;
+ } else {
+ // otherwise, descend into the subtrees to extract matched txids and hashes
+ uint256 left = TraverseAndExtract(height-1, pos*2, nBitsUsed, nHashUsed, vMatch), right;
+ if (pos*2+1 < CalcTreeWidth(height-1)) {
+ right = TraverseAndExtract(height-1, pos*2+1, nBitsUsed, nHashUsed, vMatch);
+ if (right == left) {
+ // The left and right branches should never be identical, as the transaction
+ // hashes covered by them must each be unique.
+ fBad = true;
+ }
+ } else {
+ right = left;
+ }
+ // and combine them before returning
+ return Hash(BEGIN(left), END(left), BEGIN(right), END(right));
+ }
+}
+
+CPartialMerkleTree::CPartialMerkleTree(const std::vector<uint256> &vTxid, const std::vector<bool> &vMatch) : nTransactions(vTxid.size()), fBad(false) {
+ // reset state
+ vBits.clear();
+ vHash.clear();
+
+ // calculate height of tree
+ int nHeight = 0;
+ while (CalcTreeWidth(nHeight) > 1)
+ nHeight++;
+
+ // traverse the partial tree
+ TraverseAndBuild(nHeight, 0, vTxid, vMatch);
+}
+
+CPartialMerkleTree::CPartialMerkleTree() : nTransactions(0), fBad(true) {}
+
+uint256 CPartialMerkleTree::ExtractMatches(std::vector<uint256> &vMatch) {
+ vMatch.clear();
+ // An empty set will not work
+ if (nTransactions == 0)
+ return uint256();
+ // check for excessively high numbers of transactions
+ if (nTransactions > MAX_BLOCK_SIZE / 60) // 60 is the lower bound for the size of a serialized CTransaction
+ return uint256();
+ // there can never be more hashes provided than one for every txid
+ if (vHash.size() > nTransactions)
+ return uint256();
+ // there must be at least one bit per node in the partial tree, and at least one node per hash
+ if (vBits.size() < vHash.size())
+ return uint256();
+ // calculate height of tree
+ int nHeight = 0;
+ while (CalcTreeWidth(nHeight) > 1)
+ nHeight++;
+ // traverse the partial tree
+ unsigned int nBitsUsed = 0, nHashUsed = 0;
+ uint256 hashMerkleRoot = TraverseAndExtract(nHeight, 0, nBitsUsed, nHashUsed, vMatch);
+ // verify that no problems occurred during the tree traversal
+ if (fBad)
+ return uint256();
+ // verify that all bits were consumed (except for the padding caused by serializing it as a byte sequence)
+ if ((nBitsUsed+7)/8 != (vBits.size()+7)/8)
+ return uint256();
+ // verify that all hashes were consumed
+ if (nHashUsed != vHash.size())
+ return uint256();
+ return hashMerkleRoot;
+}
diff --git a/src/merkleblock.h b/src/merkleblock.h
new file mode 100644
index 0000000000..904c22abc2
--- /dev/null
+++ b/src/merkleblock.h
@@ -0,0 +1,156 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_MERKLEBLOCK_H
+#define BITCOIN_MERKLEBLOCK_H
+
+#include "serialize.h"
+#include "uint256.h"
+#include "primitives/block.h"
+#include "bloom.h"
+
+#include <vector>
+
+/** Data structure that represents a partial merkle tree.
+ *
+ * It represents a subset of the txid's of a known block, in a way that
+ * allows recovery of the list of txid's and the merkle root, in an
+ * authenticated way.
+ *
+ * The encoding works as follows: we traverse the tree in depth-first order,
+ * storing a bit for each traversed node, signifying whether the node is the
+ * parent of at least one matched leaf txid (or a matched txid itself). In
+ * case we are at the leaf level, or this bit is 0, its merkle node hash is
+ * stored, and its children are not explorer further. Otherwise, no hash is
+ * stored, but we recurse into both (or the only) child branch. During
+ * decoding, the same depth-first traversal is performed, consuming bits and
+ * hashes as they written during encoding.
+ *
+ * The serialization is fixed and provides a hard guarantee about the
+ * encoded size:
+ *
+ * SIZE <= 10 + ceil(32.25*N)
+ *
+ * Where N represents the number of leaf nodes of the partial tree. N itself
+ * is bounded by:
+ *
+ * N <= total_transactions
+ * N <= 1 + matched_transactions*tree_height
+ *
+ * The serialization format:
+ * - uint32 total_transactions (4 bytes)
+ * - varint number of hashes (1-3 bytes)
+ * - uint256[] hashes in depth-first order (<= 32*N bytes)
+ * - varint number of bytes of flag bits (1-3 bytes)
+ * - byte[] flag bits, packed per 8 in a byte, least significant bit first (<= 2*N-1 bits)
+ * The size constraints follow from this.
+ */
+class CPartialMerkleTree
+{
+protected:
+ /** the total number of transactions in the block */
+ unsigned int nTransactions;
+
+ /** node-is-parent-of-matched-txid bits */
+ std::vector<bool> vBits;
+
+ /** txids and internal hashes */
+ std::vector<uint256> vHash;
+
+ /** flag set when encountering invalid data */
+ bool fBad;
+
+ /** helper function to efficiently calculate the number of nodes at given height in the merkle tree */
+ unsigned int CalcTreeWidth(int height) {
+ return (nTransactions+(1 << height)-1) >> height;
+ }
+
+ /** calculate the hash of a node in the merkle tree (at leaf level: the txid's themselves) */
+ uint256 CalcHash(int height, unsigned int pos, const std::vector<uint256> &vTxid);
+
+ /** recursive function that traverses tree nodes, storing the data as bits and hashes */
+ void TraverseAndBuild(int height, unsigned int pos, const std::vector<uint256> &vTxid, const std::vector<bool> &vMatch);
+
+ /**
+ * recursive function that traverses tree nodes, consuming the bits and hashes produced by TraverseAndBuild.
+ * it returns the hash of the respective node.
+ */
+ uint256 TraverseAndExtract(int height, unsigned int pos, unsigned int &nBitsUsed, unsigned int &nHashUsed, std::vector<uint256> &vMatch);
+
+public:
+
+ /** serialization implementation */
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ READWRITE(nTransactions);
+ READWRITE(vHash);
+ std::vector<unsigned char> vBytes;
+ if (ser_action.ForRead()) {
+ READWRITE(vBytes);
+ CPartialMerkleTree &us = *(const_cast<CPartialMerkleTree*>(this));
+ us.vBits.resize(vBytes.size() * 8);
+ for (unsigned int p = 0; p < us.vBits.size(); p++)
+ us.vBits[p] = (vBytes[p / 8] & (1 << (p % 8))) != 0;
+ us.fBad = false;
+ } else {
+ vBytes.resize((vBits.size()+7)/8);
+ for (unsigned int p = 0; p < vBits.size(); p++)
+ vBytes[p / 8] |= vBits[p] << (p % 8);
+ READWRITE(vBytes);
+ }
+ }
+
+ /** Construct a partial merkle tree from a list of transaction ids, and a mask that selects a subset of them */
+ CPartialMerkleTree(const std::vector<uint256> &vTxid, const std::vector<bool> &vMatch);
+
+ CPartialMerkleTree();
+
+ /**
+ * extract the matching txid's represented by this partial merkle tree.
+ * returns the merkle root, or 0 in case of failure
+ */
+ uint256 ExtractMatches(std::vector<uint256> &vMatch);
+};
+
+
+/**
+ * Used to relay blocks as header + vector<merkle branch>
+ * to filtered nodes.
+ */
+class CMerkleBlock
+{
+public:
+ /** Public only for unit testing */
+ CBlockHeader header;
+ CPartialMerkleTree txn;
+
+public:
+ /** Public only for unit testing and relay testing (not relayed) */
+ std::vector<std::pair<unsigned int, uint256> > vMatchedTxn;
+
+ /**
+ * Create from a CBlock, filtering transactions according to filter
+ * Note that this will call IsRelevantAndUpdate on the filter for each transaction,
+ * thus the filter will likely be modified.
+ */
+ CMerkleBlock(const CBlock& block, CBloomFilter& filter);
+
+ // Create from a CBlock, matching the txids in the set
+ CMerkleBlock(const CBlock& block, const std::set<uint256>& txids);
+
+ CMerkleBlock() {}
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ READWRITE(header);
+ READWRITE(txn);
+ }
+};
+
+#endif // BITCOIN_MERKLEBLOCK_H
diff --git a/src/miner.cpp b/src/miner.cpp
new file mode 100644
index 0000000000..f5919ca3af
--- /dev/null
+++ b/src/miner.cpp
@@ -0,0 +1,581 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "miner.h"
+
+#include "amount.h"
+#include "chainparams.h"
+#include "consensus/consensus.h"
+#include "consensus/validation.h"
+#include "hash.h"
+#include "main.h"
+#include "net.h"
+#include "pow.h"
+#include "primitives/transaction.h"
+#include "timedata.h"
+#include "util.h"
+#include "utilmoneystr.h"
+#ifdef ENABLE_WALLET
+#include "wallet/wallet.h"
+#endif
+
+#include <boost/thread.hpp>
+#include <boost/tuple/tuple.hpp>
+
+using namespace std;
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// BitcoinMiner
+//
+
+//
+// Unconfirmed transactions in the memory pool often depend on other
+// transactions in the memory pool. When we select transactions from the
+// pool, we select by highest priority or fee rate, so we might consider
+// transactions that depend on transactions that aren't yet in the block.
+// The COrphan class keeps track of these 'temporary orphans' while
+// CreateBlock is figuring out which transactions to include.
+//
+class COrphan
+{
+public:
+ const CTransaction* ptx;
+ set<uint256> setDependsOn;
+ CFeeRate feeRate;
+ double dPriority;
+
+ COrphan(const CTransaction* ptxIn) : ptx(ptxIn), feeRate(0), dPriority(0)
+ {
+ }
+};
+
+uint64_t nLastBlockTx = 0;
+uint64_t nLastBlockSize = 0;
+
+// We want to sort transactions by priority and fee rate, so:
+typedef boost::tuple<double, CFeeRate, const CTransaction*> TxPriority;
+class TxPriorityCompare
+{
+ bool byFee;
+
+public:
+ TxPriorityCompare(bool _byFee) : byFee(_byFee) { }
+
+ bool operator()(const TxPriority& a, const TxPriority& b)
+ {
+ if (byFee)
+ {
+ if (a.get<1>() == b.get<1>())
+ return a.get<0>() < b.get<0>();
+ return a.get<1>() < b.get<1>();
+ }
+ else
+ {
+ if (a.get<0>() == b.get<0>())
+ return a.get<1>() < b.get<1>();
+ return a.get<0>() < b.get<0>();
+ }
+ }
+};
+
+void UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev)
+{
+ pblock->nTime = std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
+
+ // Updating time can change work required on testnet:
+ if (consensusParams.fPowAllowMinDifficultyBlocks)
+ pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, consensusParams);
+}
+
+CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
+{
+ const CChainParams& chainparams = Params();
+ // Create new block
+ auto_ptr<CBlockTemplate> pblocktemplate(new CBlockTemplate());
+ if(!pblocktemplate.get())
+ return NULL;
+ CBlock *pblock = &pblocktemplate->block; // pointer for convenience
+
+ // -regtest only: allow overriding block.nVersion with
+ // -blockversion=N to test forking scenarios
+ if (Params().MineBlocksOnDemand())
+ pblock->nVersion = GetArg("-blockversion", pblock->nVersion);
+
+ // Create coinbase tx
+ CMutableTransaction txNew;
+ txNew.vin.resize(1);
+ txNew.vin[0].prevout.SetNull();
+ txNew.vout.resize(1);
+ txNew.vout[0].scriptPubKey = scriptPubKeyIn;
+
+ // Add dummy coinbase tx as first transaction
+ pblock->vtx.push_back(CTransaction());
+ pblocktemplate->vTxFees.push_back(-1); // updated at end
+ pblocktemplate->vTxSigOps.push_back(-1); // updated at end
+
+ // Largest block you're willing to create:
+ unsigned int nBlockMaxSize = GetArg("-blockmaxsize", DEFAULT_BLOCK_MAX_SIZE);
+ // Limit to betweeen 1K and MAX_BLOCK_SIZE-1K for sanity:
+ nBlockMaxSize = std::max((unsigned int)1000, std::min((unsigned int)(MAX_BLOCK_SIZE-1000), nBlockMaxSize));
+
+ // How much of the block should be dedicated to high-priority transactions,
+ // included regardless of the fees they pay
+ unsigned int nBlockPrioritySize = GetArg("-blockprioritysize", DEFAULT_BLOCK_PRIORITY_SIZE);
+ nBlockPrioritySize = std::min(nBlockMaxSize, nBlockPrioritySize);
+
+ // Minimum block size you want to create; block will be filled with free transactions
+ // until there are no more or the block reaches this size:
+ unsigned int nBlockMinSize = GetArg("-blockminsize", DEFAULT_BLOCK_MIN_SIZE);
+ nBlockMinSize = std::min(nBlockMaxSize, nBlockMinSize);
+
+ // Collect memory pool transactions into the block
+ CAmount nFees = 0;
+
+ {
+ LOCK2(cs_main, mempool.cs);
+ CBlockIndex* pindexPrev = chainActive.Tip();
+ const int nHeight = pindexPrev->nHeight + 1;
+ pblock->nTime = GetAdjustedTime();
+ CCoinsViewCache view(pcoinsTip);
+
+ // Priority order to process transactions
+ list<COrphan> vOrphan; // list memory doesn't move
+ map<uint256, vector<COrphan*> > mapDependers;
+ bool fPrintPriority = GetBoolArg("-printpriority", false);
+
+ // This vector will be sorted into a priority queue:
+ vector<TxPriority> vecPriority;
+ vecPriority.reserve(mempool.mapTx.size());
+ for (map<uint256, CTxMemPoolEntry>::iterator mi = mempool.mapTx.begin();
+ mi != mempool.mapTx.end(); ++mi)
+ {
+ const CTransaction& tx = mi->second.GetTx();
+ if (tx.IsCoinBase() || !IsFinalTx(tx, nHeight, pblock->nTime))
+ continue;
+
+ COrphan* porphan = NULL;
+ double dPriority = 0;
+ CAmount nTotalIn = 0;
+ bool fMissingInputs = false;
+ BOOST_FOREACH(const CTxIn& txin, tx.vin)
+ {
+ // Read prev transaction
+ if (!view.HaveCoins(txin.prevout.hash))
+ {
+ // This should never happen; all transactions in the memory
+ // pool should connect to either transactions in the chain
+ // or other transactions in the memory pool.
+ if (!mempool.mapTx.count(txin.prevout.hash))
+ {
+ LogPrintf("ERROR: mempool transaction missing input\n");
+ if (fDebug) assert("mempool transaction missing input" == 0);
+ fMissingInputs = true;
+ if (porphan)
+ vOrphan.pop_back();
+ break;
+ }
+
+ // 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);
+ nTotalIn += mempool.mapTx[txin.prevout.hash].GetTx().vout[txin.prevout.n].nValue;
+ continue;
+ }
+ const CCoins* coins = view.AccessCoins(txin.prevout.hash);
+ assert(coins);
+
+ CAmount nValueIn = coins->vout[txin.prevout.n].nValue;
+ nTotalIn += nValueIn;
+
+ int nConf = nHeight - coins->nHeight;
+
+ dPriority += (double)nValueIn * nConf;
+ }
+ if (fMissingInputs) continue;
+
+ // Priority is sum(valuein * age) / modified_txsize
+ unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
+ dPriority = tx.ComputePriority(dPriority, nTxSize);
+
+ uint256 hash = tx.GetHash();
+ mempool.ApplyDeltas(hash, dPriority, nTotalIn);
+
+ CFeeRate feeRate(nTotalIn-tx.GetValueOut(), nTxSize);
+
+ if (porphan)
+ {
+ porphan->dPriority = dPriority;
+ porphan->feeRate = feeRate;
+ }
+ else
+ vecPriority.push_back(TxPriority(dPriority, feeRate, &mi->second.GetTx()));
+ }
+
+ // Collect transactions into block
+ uint64_t nBlockSize = 1000;
+ uint64_t nBlockTx = 0;
+ int nBlockSigOps = 100;
+ bool fSortedByFee = (nBlockPrioritySize <= 0);
+
+ TxPriorityCompare comparer(fSortedByFee);
+ std::make_heap(vecPriority.begin(), vecPriority.end(), comparer);
+
+ while (!vecPriority.empty())
+ {
+ // Take highest priority transaction off the priority queue:
+ double dPriority = vecPriority.front().get<0>();
+ CFeeRate feeRate = vecPriority.front().get<1>();
+ const CTransaction& tx = *(vecPriority.front().get<2>());
+
+ std::pop_heap(vecPriority.begin(), vecPriority.end(), comparer);
+ vecPriority.pop_back();
+
+ // Size limits
+ unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
+ if (nBlockSize + nTxSize >= nBlockMaxSize)
+ continue;
+
+ // Legacy limits on sigOps:
+ unsigned int nTxSigOps = GetLegacySigOpCount(tx);
+ if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS)
+ continue;
+
+ // Skip free transactions if we're past the minimum block size:
+ const uint256& hash = tx.GetHash();
+ double dPriorityDelta = 0;
+ CAmount nFeeDelta = 0;
+ mempool.ApplyDeltas(hash, dPriorityDelta, nFeeDelta);
+ if (fSortedByFee && (dPriorityDelta <= 0) && (nFeeDelta <= 0) && (feeRate < ::minRelayTxFee) && (nBlockSize + nTxSize >= nBlockMinSize))
+ continue;
+
+ // Prioritise by fee once past the priority size or we run out of high-priority
+ // transactions:
+ if (!fSortedByFee &&
+ ((nBlockSize + nTxSize >= nBlockPrioritySize) || !AllowFree(dPriority)))
+ {
+ fSortedByFee = true;
+ comparer = TxPriorityCompare(fSortedByFee);
+ std::make_heap(vecPriority.begin(), vecPriority.end(), comparer);
+ }
+
+ if (!view.HaveInputs(tx))
+ continue;
+
+ CAmount nTxFees = view.GetValueIn(tx)-tx.GetValueOut();
+
+ nTxSigOps += GetP2SHSigOpCount(tx, view);
+ if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS)
+ continue;
+
+ // Note that flags: we don't want to set mempool/IsStandard()
+ // policy here, but we still have to ensure that the block we
+ // create only contains transactions that are valid in new blocks.
+ CValidationState state;
+ if (!CheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true))
+ continue;
+
+ UpdateCoins(tx, state, view, nHeight);
+
+ // Added
+ pblock->vtx.push_back(tx);
+ pblocktemplate->vTxFees.push_back(nTxFees);
+ pblocktemplate->vTxSigOps.push_back(nTxSigOps);
+ nBlockSize += nTxSize;
+ ++nBlockTx;
+ nBlockSigOps += nTxSigOps;
+ nFees += nTxFees;
+
+ if (fPrintPriority)
+ {
+ LogPrintf("priority %.1f fee %s txid %s\n",
+ dPriority, feeRate.ToString(), tx.GetHash().ToString());
+ }
+
+ // Add transactions that depend on this one to the priority queue
+ if (mapDependers.count(hash))
+ {
+ BOOST_FOREACH(COrphan* porphan, mapDependers[hash])
+ {
+ if (!porphan->setDependsOn.empty())
+ {
+ porphan->setDependsOn.erase(hash);
+ if (porphan->setDependsOn.empty())
+ {
+ vecPriority.push_back(TxPriority(porphan->dPriority, porphan->feeRate, porphan->ptx));
+ std::push_heap(vecPriority.begin(), vecPriority.end(), comparer);
+ }
+ }
+ }
+ }
+ }
+
+ nLastBlockTx = nBlockTx;
+ nLastBlockSize = nBlockSize;
+ LogPrintf("CreateNewBlock(): total size %u\n", nBlockSize);
+
+ // Compute final coinbase transaction.
+ txNew.vout[0].nValue = nFees + GetBlockSubsidy(nHeight, chainparams.GetConsensus());
+ txNew.vin[0].scriptSig = CScript() << nHeight << OP_0;
+ pblock->vtx[0] = txNew;
+ pblocktemplate->vTxFees[0] = -nFees;
+
+ // Fill in header
+ pblock->hashPrevBlock = pindexPrev->GetBlockHash();
+ UpdateTime(pblock, Params().GetConsensus(), pindexPrev);
+ pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus());
+ pblock->nNonce = 0;
+ pblocktemplate->vTxSigOps[0] = GetLegacySigOpCount(pblock->vtx[0]);
+
+ CValidationState state;
+ if (!TestBlockValidity(state, *pblock, pindexPrev, false, false))
+ throw std::runtime_error("CreateNewBlock(): TestBlockValidity failed");
+ }
+
+ return pblocktemplate.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;
+ unsigned int nHeight = pindexPrev->nHeight+1; // Height first in coinbase required for block.version=2
+ CMutableTransaction txCoinbase(pblock->vtx[0]);
+ txCoinbase.vin[0].scriptSig = (CScript() << nHeight << CScriptNum(nExtraNonce)) + COINBASE_FLAGS;
+ assert(txCoinbase.vin[0].scriptSig.size() <= 100);
+
+ pblock->vtx[0] = txCoinbase;
+ pblock->hashMerkleRoot = pblock->BuildMerkleTree();
+}
+
+#ifdef ENABLE_WALLET
+//////////////////////////////////////////////////////////////////////////////
+//
+// Internal miner
+//
+
+//
+// ScanHash scans nonces looking for a hash with at least some zero bits.
+// The nonce is usually preserved between calls, but periodically or if the
+// nonce is 0xffff0000 or above, the block is rebuilt and nNonce starts over at
+// zero.
+//
+bool static ScanHash(const CBlockHeader *pblock, uint32_t& nNonce, uint256 *phash)
+{
+ // Write the first 76 bytes of the block header to a double-SHA256 state.
+ CHash256 hasher;
+ CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
+ ss << *pblock;
+ assert(ss.size() == 80);
+ hasher.Write((unsigned char*)&ss[0], 76);
+
+ while (true) {
+ nNonce++;
+
+ // Write the last 4 bytes of the block header (the nonce) to a copy of
+ // the double-SHA256 state, and compute the result.
+ CHash256(hasher).Write((unsigned char*)&nNonce, 4).Finalize((unsigned char*)phash);
+
+ // Return the nonce if the hash has at least some zero bits,
+ // caller will check if it has enough to reach the target
+ if (((uint16_t*)phash)[15] == 0)
+ return true;
+
+ // If nothing found after trying for a while, return -1
+ if ((nNonce & 0xfff) == 0)
+ return false;
+ }
+}
+
+CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey)
+{
+ CPubKey pubkey;
+ if (!reservekey.GetReservedKey(pubkey))
+ return NULL;
+
+ CScript scriptPubKey = CScript() << ToByteVector(pubkey) << OP_CHECKSIG;
+ return CreateNewBlock(scriptPubKey);
+}
+
+static bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey)
+{
+ LogPrintf("%s\n", pblock->ToString());
+ LogPrintf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue));
+
+ // Found a solution
+ {
+ LOCK(cs_main);
+ if (pblock->hashPrevBlock != chainActive.Tip()->GetBlockHash())
+ 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
+ CValidationState state;
+ if (!ProcessNewBlock(state, NULL, pblock, true, NULL))
+ return error("BitcoinMiner: ProcessNewBlock, block not accepted");
+
+ return true;
+}
+
+void static BitcoinMiner(CWallet *pwallet)
+{
+ LogPrintf("BitcoinMiner started\n");
+ SetThreadPriority(THREAD_PRIORITY_LOWEST);
+ RenameThread("bitcoin-miner");
+ const CChainParams& chainparams = Params();
+
+ // Each thread has its own key and counter
+ CReserveKey reservekey(pwallet);
+ unsigned int nExtraNonce = 0;
+
+ try {
+ while (true) {
+ if (chainparams.MiningRequiresPeers()) {
+ // Busy-wait for the network to come online so we don't waste time mining
+ // on an obsolete chain. In regtest mode we expect to fly solo.
+ do {
+ bool fvNodesEmpty;
+ {
+ LOCK(cs_vNodes);
+ fvNodesEmpty = vNodes.empty();
+ }
+ if (!fvNodesEmpty && !IsInitialBlockDownload())
+ break;
+ MilliSleep(1000);
+ } while (true);
+ }
+
+ //
+ // Create new block
+ //
+ unsigned int nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
+ CBlockIndex* pindexPrev = chainActive.Tip();
+
+ auto_ptr<CBlockTemplate> pblocktemplate(CreateNewBlockWithKey(reservekey));
+ if (!pblocktemplate.get())
+ {
+ LogPrintf("Error in BitcoinMiner: Keypool ran out, please call keypoolrefill before restarting the mining thread\n");
+ return;
+ }
+ CBlock *pblock = &pblocktemplate->block;
+ IncrementExtraNonce(pblock, pindexPrev, nExtraNonce);
+
+ LogPrintf("Running BitcoinMiner with %u transactions in block (%u bytes)\n", pblock->vtx.size(),
+ ::GetSerializeSize(*pblock, SER_NETWORK, PROTOCOL_VERSION));
+
+ //
+ // Search
+ //
+ int64_t nStart = GetTime();
+ arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits);
+ uint256 hash;
+ uint32_t nNonce = 0;
+ while (true) {
+ // Check if something found
+ if (ScanHash(pblock, nNonce, &hash))
+ {
+ if (UintToArith256(hash) <= hashTarget)
+ {
+ // Found a solution
+ pblock->nNonce = nNonce;
+ assert(hash == pblock->GetHash());
+
+ SetThreadPriority(THREAD_PRIORITY_NORMAL);
+ LogPrintf("BitcoinMiner:\n");
+ LogPrintf("proof-of-work found \n hash: %s \ntarget: %s\n", hash.GetHex(), hashTarget.GetHex());
+ ProcessBlockFound(pblock, *pwallet, reservekey);
+ SetThreadPriority(THREAD_PRIORITY_LOWEST);
+
+ // In regression test mode, stop mining after a block is found.
+ if (chainparams.MineBlocksOnDemand())
+ throw boost::thread_interrupted();
+
+ break;
+ }
+ }
+
+ // Check for stop or if block needs to be rebuilt
+ boost::this_thread::interruption_point();
+ // Regtest mode doesn't require peers
+ if (vNodes.empty() && chainparams.MiningRequiresPeers())
+ break;
+ if (nNonce >= 0xffff0000)
+ break;
+ if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 60)
+ break;
+ if (pindexPrev != chainActive.Tip())
+ break;
+
+ // Update nTime every few seconds
+ UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev);
+ if (chainparams.GetConsensus().fPowAllowMinDifficultyBlocks)
+ {
+ // Changing pblock->nTime can change work required on testnet:
+ hashTarget.SetCompact(pblock->nBits);
+ }
+ }
+ }
+ }
+ catch (const boost::thread_interrupted&)
+ {
+ LogPrintf("BitcoinMiner terminated\n");
+ throw;
+ }
+ catch (const std::runtime_error &e)
+ {
+ LogPrintf("BitcoinMiner runtime error: %s\n", e.what());
+ return;
+ }
+}
+
+void GenerateBitcoins(bool fGenerate, CWallet* pwallet, int nThreads)
+{
+ static boost::thread_group* minerThreads = NULL;
+
+ if (nThreads < 0) {
+ // In regtest threads defaults to 1
+ if (Params().DefaultMinerThreads())
+ nThreads = Params().DefaultMinerThreads();
+ else
+ nThreads = boost::thread::hardware_concurrency();
+ }
+
+ if (minerThreads != NULL)
+ {
+ minerThreads->interrupt_all();
+ delete minerThreads;
+ minerThreads = NULL;
+ }
+
+ if (nThreads == 0 || !fGenerate)
+ return;
+
+ minerThreads = new boost::thread_group();
+ for (int i = 0; i < nThreads; i++)
+ minerThreads->create_thread(boost::bind(&BitcoinMiner, pwallet));
+}
+
+#endif // ENABLE_WALLET
diff --git a/src/miner.h b/src/miner.h
new file mode 100644
index 0000000000..96a6b70ecd
--- /dev/null
+++ b/src/miner.h
@@ -0,0 +1,35 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_MINER_H
+#define BITCOIN_MINER_H
+
+#include "primitives/block.h"
+
+#include <stdint.h>
+
+class CBlockIndex;
+class CReserveKey;
+class CScript;
+class CWallet;
+namespace Consensus { struct Params; };
+
+struct CBlockTemplate
+{
+ CBlock block;
+ std::vector<CAmount> vTxFees;
+ std::vector<int64_t> vTxSigOps;
+};
+
+/** Run the miner threads */
+void GenerateBitcoins(bool fGenerate, CWallet* pwallet, int nThreads);
+/** Generate a new block, without valid proof-of-work */
+CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn);
+CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey);
+/** Modify the extranonce in a block */
+void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce);
+void UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev);
+
+#endif // BITCOIN_MINER_H
diff --git a/src/mruset.h b/src/mruset.h
new file mode 100644
index 0000000000..398aa173bf
--- /dev/null
+++ b/src/mruset.h
@@ -0,0 +1,65 @@
+// Copyright (c) 2012-2015 The Bitcoin Core developers
+// Distributed under the MIT 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 <set>
+#include <vector>
+#include <utility>
+
+/** STL-like set container that only keeps the most recent N elements. */
+template <typename T>
+class mruset
+{
+public:
+ typedef T key_type;
+ typedef T value_type;
+ typedef typename std::set<T>::iterator iterator;
+ typedef typename std::set<T>::const_iterator const_iterator;
+ typedef typename std::set<T>::size_type size_type;
+
+protected:
+ std::set<T> set;
+ std::vector<iterator> order;
+ size_type first_used;
+ size_type first_unused;
+ const size_type nMaxSize;
+
+public:
+ mruset(size_type nMaxSizeIn = 1) : nMaxSize(nMaxSizeIn) { clear(); }
+ 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); }
+ void clear()
+ {
+ set.clear();
+ order.assign(nMaxSize, set.end());
+ first_used = 0;
+ first_unused = 0;
+ }
+ bool inline friend operator==(const mruset<T>& a, const mruset<T>& b) { return a.set == b.set; }
+ bool inline friend operator==(const mruset<T>& a, const std::set<T>& b) { return a.set == b; }
+ bool inline friend operator<(const mruset<T>& a, const mruset<T>& b) { return a.set < b.set; }
+ std::pair<iterator, bool> insert(const key_type& x)
+ {
+ std::pair<iterator, bool> ret = set.insert(x);
+ if (ret.second) {
+ if (set.size() == nMaxSize + 1) {
+ set.erase(order[first_used]);
+ order[first_used] = set.end();
+ if (++first_used == nMaxSize) first_used = 0;
+ }
+ order[first_unused] = ret.first;
+ if (++first_unused == nMaxSize) first_unused = 0;
+ }
+ return ret;
+ }
+ size_type max_size() const { return nMaxSize; }
+};
+
+#endif // BITCOIN_MRUSET_H
diff --git a/src/net.cpp b/src/net.cpp
new file mode 100644
index 0000000000..e4b22f9ccc
--- /dev/null
+++ b/src/net.cpp
@@ -0,0 +1,2099 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#if defined(HAVE_CONFIG_H)
+#include "config/bitcoin-config.h"
+#endif
+
+#include "net.h"
+
+#include "addrman.h"
+#include "chainparams.h"
+#include "clientversion.h"
+#include "primitives/transaction.h"
+#include "scheduler.h"
+#include "ui_interface.h"
+#include "crypto/common.h"
+
+#ifdef WIN32
+#include <string.h>
+#else
+#include <fcntl.h>
+#endif
+
+#ifdef USE_UPNP
+#include <miniupnpc/miniupnpc.h>
+#include <miniupnpc/miniwget.h>
+#include <miniupnpc/upnpcommands.h>
+#include <miniupnpc/upnperrors.h>
+#endif
+
+#include <boost/filesystem.hpp>
+#include <boost/thread.hpp>
+
+// Dump addresses to peers.dat every 15 minutes (900s)
+#define DUMP_ADDRESSES_INTERVAL 900
+
+#if !defined(HAVE_MSG_NOSIGNAL) && !defined(MSG_NOSIGNAL)
+#define MSG_NOSIGNAL 0
+#endif
+
+// Fix for ancient MinGW versions, that don't have defined these in ws2tcpip.h.
+// Todo: Can be removed when our pull-tester is upgraded to a modern MinGW version.
+#ifdef WIN32
+#ifndef PROTECTION_LEVEL_UNRESTRICTED
+#define PROTECTION_LEVEL_UNRESTRICTED 10
+#endif
+#ifndef IPV6_PROTECTION_LEVEL
+#define IPV6_PROTECTION_LEVEL 23
+#endif
+#endif
+
+using namespace std;
+
+namespace {
+ const int MAX_OUTBOUND_CONNECTIONS = 8;
+
+ struct ListenSocket {
+ SOCKET socket;
+ bool whitelisted;
+
+ ListenSocket(SOCKET socket, bool whitelisted) : socket(socket), whitelisted(whitelisted) {}
+ };
+}
+
+//
+// Global state variables
+//
+bool fDiscover = true;
+bool fListen = true;
+uint64_t nLocalServices = NODE_NETWORK;
+CCriticalSection cs_mapLocalHost;
+map<CNetAddr, LocalServiceInfo> mapLocalHost;
+static bool vfReachable[NET_MAX] = {};
+static bool vfLimited[NET_MAX] = {};
+static CNode* pnodeLocalHost = NULL;
+uint64_t nLocalHostNonce = 0;
+static std::vector<ListenSocket> vhListenSocket;
+CAddrMan addrman;
+int nMaxConnections = 125;
+bool fAddressesInitialized = false;
+
+vector<CNode*> vNodes;
+CCriticalSection cs_vNodes;
+map<CInv, CDataStream> mapRelay;
+deque<pair<int64_t, CInv> > vRelayExpiration;
+CCriticalSection cs_mapRelay;
+limitedmap<CInv, int64_t> mapAlreadyAskedFor(MAX_INV_SZ);
+
+static deque<string> vOneShots;
+CCriticalSection cs_vOneShots;
+
+set<CNetAddr> setservAddNodeAddresses;
+CCriticalSection cs_setservAddNodeAddresses;
+
+vector<std::string> vAddedNodes;
+CCriticalSection cs_vAddedNodes;
+
+NodeId nLastNodeId = 0;
+CCriticalSection cs_nLastNodeId;
+
+static CSemaphore *semOutbound = NULL;
+boost::condition_variable messageHandlerCondition;
+
+// Signals for message handling
+static CNodeSignals g_signals;
+CNodeSignals& GetNodeSignals() { return g_signals; }
+
+void AddOneShot(string strDest)
+{
+ LOCK(cs_vOneShots);
+ vOneShots.push_back(strDest);
+}
+
+unsigned short GetListenPort()
+{
+ return (unsigned short)(GetArg("-port", Params().GetDefaultPort()));
+}
+
+// find 'best' local address for a particular peer
+bool GetLocal(CService& addr, const CNetAddr *paddrPeer)
+{
+ if (!fListen)
+ return false;
+
+ int nBestScore = -1;
+ int nBestReachability = -1;
+ {
+ LOCK(cs_mapLocalHost);
+ for (map<CNetAddr, LocalServiceInfo>::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;
+}
+
+//! Convert the pnSeeds6 array into usable address objects.
+static std::vector<CAddress> convertSeed6(const std::vector<SeedSpec6> &vSeedsIn)
+{
+ // 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_t nOneWeek = 7*24*60*60;
+ std::vector<CAddress> vSeedsOut;
+ vSeedsOut.reserve(vSeedsIn.size());
+ for (std::vector<SeedSpec6>::const_iterator i(vSeedsIn.begin()); i != vSeedsIn.end(); ++i)
+ {
+ struct in6_addr ip;
+ memcpy(&ip, i->addr, sizeof(ip));
+ CAddress addr(CService(ip, i->port));
+ addr.nTime = GetTime() - GetRand(nOneWeek) - nOneWeek;
+ vSeedsOut.push_back(addr);
+ }
+ return vSeedsOut;
+}
+
+// get best local address for a particular peer as a CAddress
+// Otherwise, return the unroutable 0.0.0.0 but filled in with
+// the normal parameters, since the IP may be changed to a useful
+// one by discovery.
+CAddress GetLocalAddress(const CNetAddr *paddrPeer)
+{
+ CAddress ret(CService("0.0.0.0",GetListenPort()),0);
+ CService addr;
+ if (GetLocal(addr, paddrPeer))
+ {
+ ret = CAddress(addr);
+ }
+ ret.nServices = nLocalServices;
+ ret.nTime = GetAdjustedTime();
+ return ret;
+}
+
+int GetnScore(const CService& addr)
+{
+ LOCK(cs_mapLocalHost);
+ if (mapLocalHost.count(addr) == LOCAL_NONE)
+ return 0;
+ return mapLocalHost[addr].nScore;
+}
+
+// Is our peer's addrLocal potentially useful as an external IP source?
+bool IsPeerAddrLocalGood(CNode *pnode)
+{
+ return fDiscover && pnode->addr.IsRoutable() && pnode->addrLocal.IsRoutable() &&
+ !IsLimited(pnode->addrLocal.GetNetwork());
+}
+
+// pushes our own address to a peer
+void AdvertizeLocal(CNode *pnode)
+{
+ if (fListen && pnode->fSuccessfullyConnected)
+ {
+ CAddress addrLocal = GetLocalAddress(&pnode->addr);
+ // If discovery is enabled, sometimes give our peer the address it
+ // tells us that it sees us as in case it has a better idea of our
+ // address than we do.
+ if (IsPeerAddrLocalGood(pnode) && (!addrLocal.IsRoutable() ||
+ GetRand((GetnScore(addrLocal) > LOCAL_MANUAL) ? 8:2) == 0))
+ {
+ addrLocal.SetIP(pnode->addrLocal);
+ }
+ if (addrLocal.IsRoutable())
+ {
+ pnode->PushAddress(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;
+
+ LogPrintf("AddLocal(%s,%i)\n", addr.ToString(), nScore);
+
+ {
+ LOCK(cs_mapLocalHost);
+ bool fAlready = mapLocalHost.count(addr) > 0;
+ LocalServiceInfo &info = mapLocalHost[addr];
+ if (!fAlready || nScore >= info.nScore) {
+ info.nScore = nScore + (fAlready ? 1 : 0);
+ info.nPort = addr.GetPort();
+ }
+ SetReachable(addr.GetNetwork());
+ }
+
+ 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++;
+ }
+ 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 network is one we can probably connect to */
+bool IsReachable(enum Network net)
+{
+ LOCK(cs_mapLocalHost);
+ return vfReachable[net] && !vfLimited[net];
+}
+
+/** check whether a given address is in a network we can probably connect to */
+bool IsReachable(const CNetAddr& addr)
+{
+ enum Network net = addr.GetNetwork();
+ return IsReachable(net);
+}
+
+void AddressCurrentlyConnected(const CService& addr)
+{
+ addrman.Connected(addr);
+}
+
+
+uint64_t CNode::nTotalBytesRecv = 0;
+uint64_t CNode::nTotalBytesSent = 0;
+CCriticalSection CNode::cs_totalBytesRecv;
+CCriticalSection CNode::cs_totalBytesSent;
+
+CNode* FindNode(const CNetAddr& ip)
+{
+ LOCK(cs_vNodes);
+ BOOST_FOREACH(CNode* pnode, vNodes)
+ if ((CNetAddr)pnode->addr == ip)
+ return (pnode);
+ return NULL;
+}
+
+CNode* FindNode(const 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)
+{
+ if (pszDest == NULL) {
+ if (IsLocal(addrConnect))
+ return NULL;
+
+ // Look for an existing connection
+ CNode* pnode = FindNode((CService)addrConnect);
+ if (pnode)
+ {
+ pnode->AddRef();
+ return pnode;
+ }
+ }
+
+ /// debug print
+ LogPrint("net", "trying connection %s lastseen=%.1fhrs\n",
+ pszDest ? pszDest : addrConnect.ToString(),
+ pszDest ? 0.0 : (double)(GetAdjustedTime() - addrConnect.nTime)/3600.0);
+
+ // Connect
+ SOCKET hSocket;
+ bool proxyConnectionFailed = false;
+ if (pszDest ? ConnectSocketByName(addrConnect, hSocket, pszDest, Params().GetDefaultPort(), nConnectTimeout, &proxyConnectionFailed) :
+ ConnectSocket(addrConnect, hSocket, nConnectTimeout, &proxyConnectionFailed))
+ {
+ if (!IsSelectableSocket(hSocket)) {
+ LogPrintf("Cannot create connection: non-selectable socket created (fd >= FD_SETSIZE ?)\n");
+ CloseSocket(hSocket);
+ return NULL;
+ }
+
+ addrman.Attempt(addrConnect);
+
+ // Add node
+ CNode* pnode = new CNode(hSocket, addrConnect, pszDest ? pszDest : "", false);
+ pnode->AddRef();
+
+ {
+ LOCK(cs_vNodes);
+ vNodes.push_back(pnode);
+ }
+
+ pnode->nTimeConnected = GetTime();
+
+ return pnode;
+ } else if (!proxyConnectionFailed) {
+ // If connecting to the node failed, and failure is not caused by a problem connecting to
+ // the proxy, mark this as an attempt.
+ addrman.Attempt(addrConnect);
+ }
+
+ return NULL;
+}
+
+void CNode::CloseSocketDisconnect()
+{
+ fDisconnect = true;
+ if (hSocket != INVALID_SOCKET)
+ {
+ LogPrint("net", "disconnecting peer=%d\n", id);
+ CloseSocket(hSocket);
+ }
+
+ // in case this fails, we'll empty the recv buffer when the CNode is deleted
+ TRY_LOCK(cs_vRecvMsg, lockRecv);
+ if (lockRecv)
+ vRecvMsg.clear();
+}
+
+void CNode::PushVersion()
+{
+ int nBestHeight = g_signals.GetHeight().get_value_or(0);
+
+ int64_t nTime = (fInbound ? GetAdjustedTime() : GetTime());
+ CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService("0.0.0.0",0)));
+ CAddress addrMe = GetLocalAddress(&addr);
+ GetRandBytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
+ if (fLogIPs)
+ LogPrint("net", "send version message: version %d, blocks=%d, us=%s, them=%s, peer=%d\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString(), addrYou.ToString(), id);
+ else
+ LogPrint("net", "send version message: version %d, blocks=%d, us=%s, peer=%d\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString(), id);
+ PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe,
+ nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>()), nBestHeight, true);
+}
+
+
+
+
+
+std::map<CNetAddr, int64_t> CNode::setBanned;
+CCriticalSection CNode::cs_setBanned;
+
+void CNode::ClearBanned()
+{
+ setBanned.clear();
+}
+
+bool CNode::IsBanned(CNetAddr ip)
+{
+ bool fResult = false;
+ {
+ LOCK(cs_setBanned);
+ std::map<CNetAddr, int64_t>::iterator i = setBanned.find(ip);
+ if (i != setBanned.end())
+ {
+ int64_t t = (*i).second;
+ if (GetTime() < t)
+ fResult = true;
+ }
+ }
+ return fResult;
+}
+
+bool CNode::Ban(const CNetAddr &addr) {
+ int64_t banTime = GetTime()+GetArg("-bantime", 60*60*24); // Default 24-hour ban
+ {
+ LOCK(cs_setBanned);
+ if (setBanned[addr] < banTime)
+ setBanned[addr] = banTime;
+ }
+ return true;
+}
+
+
+std::vector<CSubNet> CNode::vWhitelistedRange;
+CCriticalSection CNode::cs_vWhitelistedRange;
+
+bool CNode::IsWhitelistedRange(const CNetAddr &addr) {
+ LOCK(cs_vWhitelistedRange);
+ BOOST_FOREACH(const CSubNet& subnet, vWhitelistedRange) {
+ if (subnet.Match(addr))
+ return true;
+ }
+ return false;
+}
+
+void CNode::AddWhitelistedRange(const CSubNet &subnet) {
+ LOCK(cs_vWhitelistedRange);
+ vWhitelistedRange.push_back(subnet);
+}
+
+#undef X
+#define X(name) stats.name = name
+void CNode::copyStats(CNodeStats &stats)
+{
+ stats.nodeid = this->GetId();
+ X(nServices);
+ X(nLastSend);
+ X(nLastRecv);
+ X(nTimeConnected);
+ X(nTimeOffset);
+ X(addrName);
+ X(nVersion);
+ X(cleanSubVer);
+ X(fInbound);
+ X(nStartingHeight);
+ X(nSendBytes);
+ X(nRecvBytes);
+ X(fWhitelisted);
+
+ // It is common for nodes with good ping times to suddenly become lagged,
+ // due to a new block arriving or other large transfer.
+ // Merely reporting pingtime might fool the caller into thinking the node was still responsive,
+ // since pingtime does not update until the ping is complete, which might take a while.
+ // So, if a ping is taking an unusually long time in flight,
+ // the caller can immediately detect that this is happening.
+ int64_t nPingUsecWait = 0;
+ if ((0 != nPingNonceSent) && (0 != nPingUsecStart)) {
+ nPingUsecWait = GetTimeMicros() - nPingUsecStart;
+ }
+
+ // Raw ping time is in microseconds, but show it to user as whole seconds (Bitcoin users should be well used to small numbers with many decimal places by now :)
+ stats.dPingTime = (((double)nPingUsecTime) / 1e6);
+ stats.dPingWait = (((double)nPingUsecWait) / 1e6);
+
+ // Leave string empty if addrLocal invalid (not filled in yet)
+ stats.addrLocal = addrLocal.IsValid() ? addrLocal.ToString() : "";
+}
+#undef X
+
+// requires LOCK(cs_vRecvMsg)
+bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes)
+{
+ while (nBytes > 0) {
+
+ // get current incomplete message, or create a new one
+ if (vRecvMsg.empty() ||
+ vRecvMsg.back().complete())
+ vRecvMsg.push_back(CNetMessage(Params().MessageStart(), SER_NETWORK, nRecvVersion));
+
+ CNetMessage& msg = vRecvMsg.back();
+
+ // absorb network data
+ int handled;
+ if (!msg.in_data)
+ handled = msg.readHeader(pch, nBytes);
+ else
+ handled = msg.readData(pch, nBytes);
+
+ if (handled < 0)
+ return false;
+
+ if (msg.in_data && msg.hdr.nMessageSize > MAX_PROTOCOL_MESSAGE_LENGTH) {
+ LogPrint("net", "Oversized message from peer=%i, disconnecting\n", GetId());
+ return false;
+ }
+
+ pch += handled;
+ nBytes -= handled;
+
+ if (msg.complete()) {
+ msg.nTime = GetTimeMicros();
+ messageHandlerCondition.notify_one();
+ }
+ }
+
+ return true;
+}
+
+int CNetMessage::readHeader(const char *pch, unsigned int nBytes)
+{
+ // copy data to temporary parsing buffer
+ unsigned int nRemaining = 24 - nHdrPos;
+ unsigned int nCopy = std::min(nRemaining, nBytes);
+
+ memcpy(&hdrbuf[nHdrPos], pch, nCopy);
+ nHdrPos += nCopy;
+
+ // if header incomplete, exit
+ if (nHdrPos < 24)
+ return nCopy;
+
+ // deserialize to CMessageHeader
+ try {
+ hdrbuf >> hdr;
+ }
+ catch (const std::exception&) {
+ return -1;
+ }
+
+ // reject messages larger than MAX_SIZE
+ if (hdr.nMessageSize > MAX_SIZE)
+ return -1;
+
+ // switch state to reading message data
+ in_data = true;
+
+ return nCopy;
+}
+
+int CNetMessage::readData(const char *pch, unsigned int nBytes)
+{
+ unsigned int nRemaining = hdr.nMessageSize - nDataPos;
+ unsigned int nCopy = std::min(nRemaining, nBytes);
+
+ if (vRecv.size() < nDataPos + nCopy) {
+ // Allocate up to 256 KiB ahead, but never more than the total message size.
+ vRecv.resize(std::min(hdr.nMessageSize, nDataPos + nCopy + 256 * 1024));
+ }
+
+ memcpy(&vRecv[nDataPos], pch, nCopy);
+ nDataPos += nCopy;
+
+ return nCopy;
+}
+
+
+
+
+
+
+
+
+
+// requires LOCK(cs_vSend)
+void SocketSendData(CNode *pnode)
+{
+ std::deque<CSerializeData>::iterator it = pnode->vSendMsg.begin();
+
+ while (it != pnode->vSendMsg.end()) {
+ const CSerializeData &data = *it;
+ assert(data.size() > pnode->nSendOffset);
+ int nBytes = send(pnode->hSocket, &data[pnode->nSendOffset], data.size() - pnode->nSendOffset, MSG_NOSIGNAL | MSG_DONTWAIT);
+ if (nBytes > 0) {
+ pnode->nLastSend = GetTime();
+ pnode->nSendBytes += nBytes;
+ pnode->nSendOffset += nBytes;
+ pnode->RecordBytesSent(nBytes);
+ if (pnode->nSendOffset == data.size()) {
+ pnode->nSendOffset = 0;
+ pnode->nSendSize -= data.size();
+ it++;
+ } else {
+ // could not send full message; stop sending more
+ break;
+ }
+ } else {
+ if (nBytes < 0) {
+ // error
+ int nErr = WSAGetLastError();
+ if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
+ {
+ LogPrintf("socket send error %s\n", NetworkErrorString(nErr));
+ pnode->CloseSocketDisconnect();
+ }
+ }
+ // couldn't send anything at all
+ break;
+ }
+ }
+
+ if (it == pnode->vSendMsg.end()) {
+ assert(pnode->nSendOffset == 0);
+ assert(pnode->nSendSize == 0);
+ }
+ pnode->vSendMsg.erase(pnode->vSendMsg.begin(), it);
+}
+
+static list<CNode*> vNodesDisconnected;
+
+void ThreadSocketHandler()
+{
+ unsigned int nPrevNodeCount = 0;
+ while (true)
+ {
+ //
+ // Disconnect nodes
+ //
+ {
+ LOCK(cs_vNodes);
+ // Disconnect unused nodes
+ vector<CNode*> vNodesCopy = vNodes;
+ BOOST_FOREACH(CNode* pnode, vNodesCopy)
+ {
+ if (pnode->fDisconnect ||
+ (pnode->GetRefCount() <= 0 && pnode->vRecvMsg.empty() && pnode->nSendSize == 0 && pnode->ssSend.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();
+
+ // hold in disconnected pool until all refs are released
+ if (pnode->fNetworkNode || pnode->fInbound)
+ pnode->Release();
+ vNodesDisconnected.push_back(pnode);
+ }
+ }
+ }
+ {
+ // Delete disconnected nodes
+ list<CNode*> 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_vRecvMsg, lockRecv);
+ if (lockRecv)
+ {
+ 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(nPrevNodeCount);
+ }
+
+ //
+ // 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;
+ bool have_fds = false;
+
+ BOOST_FOREACH(const ListenSocket& hListenSocket, vhListenSocket) {
+ FD_SET(hListenSocket.socket, &fdsetRecv);
+ hSocketMax = max(hSocketMax, hListenSocket.socket);
+ have_fds = true;
+ }
+
+ {
+ LOCK(cs_vNodes);
+ BOOST_FOREACH(CNode* pnode, vNodes)
+ {
+ if (pnode->hSocket == INVALID_SOCKET)
+ continue;
+ FD_SET(pnode->hSocket, &fdsetError);
+ hSocketMax = max(hSocketMax, pnode->hSocket);
+ have_fds = true;
+
+ // Implement the following logic:
+ // * If there is data to send, select() for sending data. As this only
+ // happens when optimistic write failed, we choose to first drain the
+ // write buffer in this case before receiving more. This avoids
+ // needlessly queueing received data, if the remote peer is not themselves
+ // receiving data. This means properly utilizing TCP flow control signalling.
+ // * Otherwise, if there is no (complete) message in the receive buffer,
+ // or there is space left in the buffer, select() for receiving data.
+ // * (if neither of the above applies, there is certainly one message
+ // in the receiver buffer ready to be processed).
+ // Together, that means that at least one of the following is always possible,
+ // so we don't deadlock:
+ // * We send some data.
+ // * We wait for data to be received (and disconnect after timeout).
+ // * We process a message in the buffer (message handler thread).
+ {
+ TRY_LOCK(pnode->cs_vSend, lockSend);
+ if (lockSend && !pnode->vSendMsg.empty()) {
+ FD_SET(pnode->hSocket, &fdsetSend);
+ continue;
+ }
+ }
+ {
+ TRY_LOCK(pnode->cs_vRecvMsg, lockRecv);
+ if (lockRecv && (
+ pnode->vRecvMsg.empty() || !pnode->vRecvMsg.front().complete() ||
+ pnode->GetTotalRecvSize() <= ReceiveFloodSize()))
+ FD_SET(pnode->hSocket, &fdsetRecv);
+ }
+ }
+ }
+
+ int nSelect = select(have_fds ? hSocketMax + 1 : 0,
+ &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
+ boost::this_thread::interruption_point();
+
+ if (nSelect == SOCKET_ERROR)
+ {
+ if (have_fds)
+ {
+ int nErr = WSAGetLastError();
+ LogPrintf("socket select error %s\n", NetworkErrorString(nErr));
+ for (unsigned int i = 0; i <= hSocketMax; i++)
+ FD_SET(i, &fdsetRecv);
+ }
+ FD_ZERO(&fdsetSend);
+ FD_ZERO(&fdsetError);
+ MilliSleep(timeout.tv_usec/1000);
+ }
+
+ //
+ // Accept new connections
+ //
+ BOOST_FOREACH(const ListenSocket& hListenSocket, vhListenSocket)
+ {
+ if (hListenSocket.socket != INVALID_SOCKET && FD_ISSET(hListenSocket.socket, &fdsetRecv))
+ {
+ struct sockaddr_storage sockaddr;
+ socklen_t len = sizeof(sockaddr);
+ SOCKET hSocket = accept(hListenSocket.socket, (struct sockaddr*)&sockaddr, &len);
+ CAddress addr;
+ int nInbound = 0;
+
+ if (hSocket != INVALID_SOCKET)
+ if (!addr.SetSockAddr((const struct sockaddr*)&sockaddr))
+ LogPrintf("Warning: Unknown socket family\n");
+
+ bool whitelisted = hListenSocket.whitelisted || CNode::IsWhitelistedRange(addr);
+ {
+ LOCK(cs_vNodes);
+ BOOST_FOREACH(CNode* pnode, vNodes)
+ if (pnode->fInbound)
+ nInbound++;
+ }
+
+ if (hSocket == INVALID_SOCKET)
+ {
+ int nErr = WSAGetLastError();
+ if (nErr != WSAEWOULDBLOCK)
+ LogPrintf("socket error accept failed: %s\n", NetworkErrorString(nErr));
+ }
+ else if (!IsSelectableSocket(hSocket))
+ {
+ LogPrintf("connection from %s dropped: non-selectable socket\n", addr.ToString());
+ CloseSocket(hSocket);
+ }
+ else if (nInbound >= nMaxConnections - MAX_OUTBOUND_CONNECTIONS)
+ {
+ LogPrint("net", "connection from %s dropped (full)\n", addr.ToString());
+ CloseSocket(hSocket);
+ }
+ else if (CNode::IsBanned(addr) && !whitelisted)
+ {
+ LogPrintf("connection from %s dropped (banned)\n", addr.ToString());
+ CloseSocket(hSocket);
+ }
+ else
+ {
+ // According to the internet TCP_NODELAY is not carried into accepted sockets
+ // on all platforms. Set it again here just to be sure.
+ int set = 1;
+#ifdef WIN32
+ setsockopt(hSocket, IPPROTO_TCP, TCP_NODELAY, (const char*)&set, sizeof(int));
+#else
+ setsockopt(hSocket, IPPROTO_TCP, TCP_NODELAY, (void*)&set, sizeof(int));
+#endif
+
+ CNode* pnode = new CNode(hSocket, addr, "", true);
+ pnode->AddRef();
+ pnode->fWhitelisted = whitelisted;
+
+ {
+ LOCK(cs_vNodes);
+ vNodes.push_back(pnode);
+ }
+ }
+ }
+ }
+
+ //
+ // Service each socket
+ //
+ vector<CNode*> vNodesCopy;
+ {
+ LOCK(cs_vNodes);
+ vNodesCopy = vNodes;
+ BOOST_FOREACH(CNode* pnode, vNodesCopy)
+ pnode->AddRef();
+ }
+ BOOST_FOREACH(CNode* pnode, vNodesCopy)
+ {
+ boost::this_thread::interruption_point();
+
+ //
+ // Receive
+ //
+ if (pnode->hSocket == INVALID_SOCKET)
+ continue;
+ if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
+ {
+ TRY_LOCK(pnode->cs_vRecvMsg, lockRecv);
+ if (lockRecv)
+ {
+ {
+ // typical socket buffer is 8K-64K
+ char pchBuf[0x10000];
+ int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
+ if (nBytes > 0)
+ {
+ if (!pnode->ReceiveMsgBytes(pchBuf, nBytes))
+ pnode->CloseSocketDisconnect();
+ pnode->nLastRecv = GetTime();
+ pnode->nRecvBytes += nBytes;
+ pnode->RecordBytesRecv(nBytes);
+ }
+ else if (nBytes == 0)
+ {
+ // socket closed gracefully
+ if (!pnode->fDisconnect)
+ LogPrint("net", "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)
+ LogPrintf("socket recv error %s\n", NetworkErrorString(nErr));
+ pnode->CloseSocketDisconnect();
+ }
+ }
+ }
+ }
+ }
+
+ //
+ // Send
+ //
+ if (pnode->hSocket == INVALID_SOCKET)
+ continue;
+ if (FD_ISSET(pnode->hSocket, &fdsetSend))
+ {
+ TRY_LOCK(pnode->cs_vSend, lockSend);
+ if (lockSend)
+ SocketSendData(pnode);
+ }
+
+ //
+ // Inactivity checking
+ //
+ int64_t nTime = GetTime();
+ if (nTime - pnode->nTimeConnected > 60)
+ {
+ if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
+ {
+ LogPrint("net", "socket no message in first 60 seconds, %d %d from %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0, pnode->id);
+ pnode->fDisconnect = true;
+ }
+ else if (nTime - pnode->nLastSend > TIMEOUT_INTERVAL)
+ {
+ LogPrintf("socket sending timeout: %is\n", nTime - pnode->nLastSend);
+ pnode->fDisconnect = true;
+ }
+ else if (nTime - pnode->nLastRecv > (pnode->nVersion > BIP0031_VERSION ? TIMEOUT_INTERVAL : 90*60))
+ {
+ LogPrintf("socket receive timeout: %is\n", nTime - pnode->nLastRecv);
+ pnode->fDisconnect = true;
+ }
+ else if (pnode->nPingNonceSent && pnode->nPingUsecStart + TIMEOUT_INTERVAL * 1000000 < GetTimeMicros())
+ {
+ LogPrintf("ping timeout: %fs\n", 0.000001 * (GetTimeMicros() - pnode->nPingUsecStart));
+ pnode->fDisconnect = true;
+ }
+ }
+ }
+ {
+ LOCK(cs_vNodes);
+ BOOST_FOREACH(CNode* pnode, vNodesCopy)
+ pnode->Release();
+ }
+ }
+}
+
+
+
+
+
+
+
+
+
+#ifdef USE_UPNP
+void ThreadMapPort()
+{
+ std::string port = strprintf("%u", 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);
+#elif MINIUPNPC_API_VERSION < 14
+ /* miniupnpc 1.6 */
+ int error = 0;
+ devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
+#else
+ /* miniupnpc 1.9.20150730 */
+ int error = 0;
+ devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, 2, &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)
+ LogPrintf("UPnP: GetExternalIPAddress() returned %d\n", r);
+ else
+ {
+ if(externalIPAddress[0])
+ {
+ LogPrintf("UPnP: ExternalIPAddress = %s\n", externalIPAddress);
+ AddLocal(CNetAddr(externalIPAddress), LOCAL_UPNP);
+ }
+ else
+ LogPrintf("UPnP: GetExternalIPAddress failed.\n");
+ }
+ }
+
+ string strDesc = "Bitcoin " + FormatFullVersion();
+
+ try {
+ while (true) {
+#ifndef UPNPDISCOVER_SUCCESS
+ /* miniupnpc 1.5 */
+ r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
+ port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0);
+#else
+ /* miniupnpc 1.6 */
+ r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
+ port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0, "0");
+#endif
+
+ if(r!=UPNPCOMMAND_SUCCESS)
+ LogPrintf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
+ port, port, lanaddr, r, strupnperror(r));
+ else
+ LogPrintf("UPnP Port Mapping successful.\n");;
+
+ MilliSleep(20*60*1000); // Refresh every 20 minutes
+ }
+ }
+ catch (const boost::thread_interrupted&)
+ {
+ r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(), "TCP", 0);
+ LogPrintf("UPNP_DeletePortMapping() returned: %d\n", r);
+ freeUPNPDevlist(devlist); devlist = 0;
+ FreeUPNPUrls(&urls);
+ throw;
+ }
+ } else {
+ LogPrintf("No valid UPnP IGDs found\n");
+ freeUPNPDevlist(devlist); devlist = 0;
+ if (r != 0)
+ FreeUPNPUrls(&urls);
+ }
+}
+
+void MapPort(bool fUseUPnP)
+{
+ static boost::thread* upnp_thread = NULL;
+
+ if (fUseUPnP)
+ {
+ if (upnp_thread) {
+ upnp_thread->interrupt();
+ upnp_thread->join();
+ delete upnp_thread;
+ }
+ upnp_thread = new boost::thread(boost::bind(&TraceThread<void (*)()>, "upnp", &ThreadMapPort));
+ }
+ else if (upnp_thread) {
+ upnp_thread->interrupt();
+ upnp_thread->join();
+ delete upnp_thread;
+ upnp_thread = NULL;
+ }
+}
+
+#else
+void MapPort(bool)
+{
+ // Intentionally left blank.
+}
+#endif
+
+
+
+
+
+
+void ThreadDNSAddressSeed()
+{
+ // goal: only query DNS seeds if address need is acute
+ if ((addrman.size() > 0) &&
+ (!GetBoolArg("-forcednsseed", false))) {
+ MilliSleep(11 * 1000);
+
+ LOCK(cs_vNodes);
+ if (vNodes.size() >= 2) {
+ LogPrintf("P2P peers available. Skipped DNS seeding.\n");
+ return;
+ }
+ }
+
+ const vector<CDNSSeedData> &vSeeds = Params().DNSSeeds();
+ int found = 0;
+
+ LogPrintf("Loading addresses from DNS seeds (could take a while)\n");
+
+ BOOST_FOREACH(const CDNSSeedData &seed, vSeeds) {
+ if (HaveNameProxy()) {
+ AddOneShot(seed.host);
+ } else {
+ vector<CNetAddr> vIPs;
+ vector<CAddress> vAdd;
+ if (LookupHost(seed.host.c_str(), vIPs))
+ {
+ BOOST_FOREACH(CNetAddr& ip, vIPs)
+ {
+ int nOneDay = 24*3600;
+ CAddress addr = CAddress(CService(ip, Params().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(seed.name, true));
+ }
+ }
+
+ LogPrintf("%d addresses found from DNS seeds\n", found);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+void DumpAddresses()
+{
+ int64_t nStart = GetTimeMillis();
+
+ CAddrDB adb;
+ adb.Write(addrman);
+
+ LogPrint("net", "Flushed %d addresses to peers.dat %dms\n",
+ addrman.size(), GetTimeMillis() - nStart);
+}
+
+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 ThreadOpenConnections()
+{
+ // Connect to specific addresses
+ if (mapArgs.count("-connect") && mapMultiArgs["-connect"].size() > 0)
+ {
+ for (int64_t 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++)
+ {
+ MilliSleep(500);
+ }
+ }
+ MilliSleep(500);
+ }
+ }
+
+ // Initiate network connections
+ int64_t nStart = GetTime();
+ while (true)
+ {
+ ProcessOneShot();
+
+ MilliSleep(500);
+
+ CSemaphoreGrant grant(*semOutbound);
+ boost::this_thread::interruption_point();
+
+ // Add seed nodes if DNS seeds are all down (an infrastructure attack?).
+ if (addrman.size() == 0 && (GetTime() - nStart > 60)) {
+ static bool done = false;
+ if (!done) {
+ LogPrintf("Adding fixed seed nodes as DNS doesn't seem to be available.\n");
+ addrman.Add(convertSeed6(Params().FixedSeeds()), CNetAddr("127.0.0.1"));
+ done = true;
+ }
+ }
+
+ //
+ // 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<vector<unsigned char> > setConnected;
+ {
+ LOCK(cs_vNodes);
+ BOOST_FOREACH(CNode* pnode, vNodes) {
+ if (!pnode->fInbound) {
+ setConnected.insert(pnode->addr.GetGroup());
+ nOutbound++;
+ }
+ }
+ }
+
+ int64_t nANow = GetAdjustedTime();
+
+ int nTries = 0;
+ while (true)
+ {
+ CAddrInfo addr = addrman.Select();
+
+ // if we selected an invalid address, restart
+ if (!addr.IsValid() || setConnected.count(addr.GetGroup()) || IsLocal(addr))
+ break;
+
+ // If we didn't find an appropriate destination after trying 100 addresses fetched from addrman,
+ // stop this loop, and let the outer loop run again (which sleeps, adds seed nodes, recalculates
+ // already-connected network ranges, ...) before trying new addrman addresses.
+ nTries++;
+ if (nTries > 100)
+ break;
+
+ 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() != Params().GetDefaultPort() && nTries < 50)
+ continue;
+
+ addrConnect = addr;
+ break;
+ }
+
+ if (addrConnect.IsValid())
+ OpenNetworkConnection(addrConnect, &grant);
+ }
+}
+
+void ThreadOpenAddedConnections()
+{
+ {
+ LOCK(cs_vAddedNodes);
+ vAddedNodes = mapMultiArgs["-addnode"];
+ }
+
+ if (HaveNameProxy()) {
+ while(true) {
+ list<string> lAddresses(0);
+ {
+ LOCK(cs_vAddedNodes);
+ BOOST_FOREACH(string& strAddNode, vAddedNodes)
+ lAddresses.push_back(strAddNode);
+ }
+ BOOST_FOREACH(string& strAddNode, lAddresses) {
+ CAddress addr;
+ CSemaphoreGrant grant(*semOutbound);
+ OpenNetworkConnection(addr, &grant, strAddNode.c_str());
+ MilliSleep(500);
+ }
+ MilliSleep(120000); // Retry every 2 minutes
+ }
+ }
+
+ for (unsigned int i = 0; true; i++)
+ {
+ list<string> lAddresses(0);
+ {
+ LOCK(cs_vAddedNodes);
+ BOOST_FOREACH(string& strAddNode, vAddedNodes)
+ lAddresses.push_back(strAddNode);
+ }
+
+ list<vector<CService> > lservAddressesToAdd(0);
+ BOOST_FOREACH(string& strAddNode, lAddresses)
+ {
+ vector<CService> vservNode(0);
+ if(Lookup(strAddNode.c_str(), vservNode, Params().GetDefaultPort(), fNameLookup, 0))
+ {
+ lservAddressesToAdd.push_back(vservNode);
+ {
+ LOCK(cs_setservAddNodeAddresses);
+ BOOST_FOREACH(CService& serv, vservNode)
+ setservAddNodeAddresses.insert(serv);
+ }
+ }
+ }
+ // 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 (list<vector<CService> >::iterator it = lservAddressesToAdd.begin(); it != lservAddressesToAdd.end(); it++)
+ BOOST_FOREACH(CService& addrNode, *(it))
+ if (pnode->addr == addrNode)
+ {
+ it = lservAddressesToAdd.erase(it);
+ it--;
+ break;
+ }
+ }
+ BOOST_FOREACH(vector<CService>& vserv, lservAddressesToAdd)
+ {
+ CSemaphoreGrant grant(*semOutbound);
+ OpenNetworkConnection(CAddress(vserv[i % vserv.size()]), &grant);
+ MilliSleep(500);
+ }
+ MilliSleep(120000); // Retry every 2 minutes
+ }
+}
+
+// if successful, this moves the passed grant to the constructed node
+bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound, const char *pszDest, bool fOneShot)
+{
+ //
+ // Initiate outbound network connection
+ //
+ boost::this_thread::interruption_point();
+ if (!pszDest) {
+ if (IsLocal(addrConnect) ||
+ FindNode((CNetAddr)addrConnect) || CNode::IsBanned(addrConnect) ||
+ FindNode(addrConnect.ToStringIPPort()))
+ return false;
+ } else if (FindNode(std::string(pszDest)))
+ return false;
+
+ CNode* pnode = ConnectNode(addrConnect, pszDest);
+ boost::this_thread::interruption_point();
+
+ if (!pnode)
+ return false;
+ if (grantOutbound)
+ grantOutbound->MoveTo(pnode->grantOutbound);
+ pnode->fNetworkNode = true;
+ if (fOneShot)
+ pnode->fOneShot = true;
+
+ return true;
+}
+
+
+void ThreadMessageHandler()
+{
+ boost::mutex condition_mutex;
+ boost::unique_lock<boost::mutex> lock(condition_mutex);
+
+ SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
+ while (true)
+ {
+ vector<CNode*> 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())];
+
+ bool fSleep = true;
+
+ BOOST_FOREACH(CNode* pnode, vNodesCopy)
+ {
+ if (pnode->fDisconnect)
+ continue;
+
+ // Receive messages
+ {
+ TRY_LOCK(pnode->cs_vRecvMsg, lockRecv);
+ if (lockRecv)
+ {
+ if (!g_signals.ProcessMessages(pnode))
+ pnode->CloseSocketDisconnect();
+
+ if (pnode->nSendSize < SendBufferSize())
+ {
+ if (!pnode->vRecvGetData.empty() || (!pnode->vRecvMsg.empty() && pnode->vRecvMsg[0].complete()))
+ {
+ fSleep = false;
+ }
+ }
+ }
+ }
+ boost::this_thread::interruption_point();
+
+ // Send messages
+ {
+ TRY_LOCK(pnode->cs_vSend, lockSend);
+ if (lockSend)
+ g_signals.SendMessages(pnode, pnode == pnodeTrickle || pnode->fWhitelisted);
+ }
+ boost::this_thread::interruption_point();
+ }
+
+ {
+ LOCK(cs_vNodes);
+ BOOST_FOREACH(CNode* pnode, vNodesCopy)
+ pnode->Release();
+ }
+
+ if (fSleep)
+ messageHandlerCondition.timed_wait(lock, boost::posix_time::microsec_clock::universal_time() + boost::posix_time::milliseconds(100));
+ }
+}
+
+
+
+
+
+
+bool BindListenPort(const CService &addrBind, string& strError, bool fWhitelisted)
+{
+ strError = "";
+ int nOne = 1;
+
+ // Create socket for listening for incoming connections
+ struct sockaddr_storage sockaddr;
+ socklen_t len = sizeof(sockaddr);
+ if (!addrBind.GetSockAddr((struct sockaddr*)&sockaddr, &len))
+ {
+ strError = strprintf("Error: Bind address family for %s not supported", addrBind.ToString());
+ LogPrintf("%s\n", strError);
+ 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 %s)", NetworkErrorString(WSAGetLastError()));
+ LogPrintf("%s\n", strError);
+ return false;
+ }
+ if (!IsSelectableSocket(hListenSocket))
+ {
+ strError = "Error: Couldn't create a listenable socket for incoming connections";
+ LogPrintf("%s\n", strError);
+ return false;
+ }
+
+
+#ifndef WIN32
+#ifdef SO_NOSIGPIPE
+ // Different way of disabling SIGPIPE on BSD
+ setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
+#endif
+ // Allow binding if the port is still in TIME_WAIT state after
+ // the program was closed and restarted.
+ setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
+ // Disable Nagle's algorithm
+ setsockopt(hListenSocket, IPPROTO_TCP, TCP_NODELAY, (void*)&nOne, sizeof(int));
+#else
+ setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&nOne, sizeof(int));
+ setsockopt(hListenSocket, IPPROTO_TCP, TCP_NODELAY, (const char*)&nOne, sizeof(int));
+#endif
+
+ // Set to non-blocking, incoming connections will also inherit this
+ if (!SetSocketNonBlocking(hListenSocket, true)) {
+ strError = strprintf("BindListenPort: Setting listening socket to non-blocking failed, error %s\n", NetworkErrorString(WSAGetLastError()));
+ LogPrintf("%s\n", strError);
+ return false;
+ }
+
+ // 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
+#ifdef WIN32
+ setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&nOne, sizeof(int));
+#else
+ setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&nOne, sizeof(int));
+#endif
+#endif
+#ifdef WIN32
+ int nProtLevel = PROTECTION_LEVEL_UNRESTRICTED;
+ setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_PROTECTION_LEVEL, (const char*)&nProtLevel, sizeof(int));
+#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. Bitcoin Core is probably already running."), addrBind.ToString());
+ else
+ strError = strprintf(_("Unable to bind to %s on this computer (bind returned error %s)"), addrBind.ToString(), NetworkErrorString(nErr));
+ LogPrintf("%s\n", strError);
+ CloseSocket(hListenSocket);
+ return false;
+ }
+ LogPrintf("Bound to %s\n", addrBind.ToString());
+
+ // Listen for incoming connections
+ if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
+ {
+ strError = strprintf(_("Error: Listening for incoming connections failed (listen returned error %s)"), NetworkErrorString(WSAGetLastError()));
+ LogPrintf("%s\n", strError);
+ CloseSocket(hListenSocket);
+ return false;
+ }
+
+ vhListenSocket.push_back(ListenSocket(hListenSocket, fWhitelisted));
+
+ if (addrBind.IsRoutable() && fDiscover && !fWhitelisted)
+ AddLocal(addrBind, LOCAL_BIND);
+
+ return true;
+}
+
+void static Discover(boost::thread_group& threadGroup)
+{
+ if (!fDiscover)
+ return;
+
+#ifdef WIN32
+ // Get local host IP
+ char pszHostName[256] = "";
+ if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
+ {
+ vector<CNetAddr> vaddr;
+ if (LookupHost(pszHostName, vaddr))
+ {
+ BOOST_FOREACH (const CNetAddr &addr, vaddr)
+ {
+ if (AddLocal(addr, LOCAL_IF))
+ LogPrintf("%s: %s - %s\n", __func__, pszHostName, addr.ToString());
+ }
+ }
+ }
+#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))
+ LogPrintf("%s: IPv4 %s: %s\n", __func__, ifa->ifa_name, addr.ToString());
+ }
+ 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))
+ LogPrintf("%s: IPv6 %s: %s\n", __func__, ifa->ifa_name, addr.ToString());
+ }
+ }
+ freeifaddrs(myaddrs);
+ }
+#endif
+}
+
+void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler)
+{
+ uiInterface.InitMessage(_("Loading addresses..."));
+ // Load addresses for peers.dat
+ int64_t nStart = GetTimeMillis();
+ {
+ CAddrDB adb;
+ if (!adb.Read(addrman))
+ LogPrintf("Invalid or missing peers.dat; recreating\n");
+ }
+ LogPrintf("Loaded %i addresses from peers.dat %dms\n",
+ addrman.size(), GetTimeMillis() - nStart);
+ fAddressesInitialized = true;
+
+ if (semOutbound == NULL) {
+ // initialize semaphore
+ int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, nMaxConnections);
+ semOutbound = new CSemaphore(nMaxOutbound);
+ }
+
+ if (pnodeLocalHost == NULL)
+ pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", 0), nLocalServices));
+
+ Discover(threadGroup);
+
+ //
+ // Start threads
+ //
+
+ if (!GetBoolArg("-dnsseed", true))
+ LogPrintf("DNS seeding disabled\n");
+ else
+ threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "dnsseed", &ThreadDNSAddressSeed));
+
+ // Map ports with UPnP
+ MapPort(GetBoolArg("-upnp", DEFAULT_UPNP));
+
+ // Send and receive from sockets, accept connections
+ threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "net", &ThreadSocketHandler));
+
+ // Initiate outbound connections from -addnode
+ threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "addcon", &ThreadOpenAddedConnections));
+
+ // Initiate outbound connections
+ threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "opencon", &ThreadOpenConnections));
+
+ // Process messages
+ threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "msghand", &ThreadMessageHandler));
+
+ // Dump network addresses
+ scheduler.scheduleEvery(&DumpAddresses, DUMP_ADDRESSES_INTERVAL);
+}
+
+bool StopNode()
+{
+ LogPrintf("StopNode()\n");
+ MapPort(false);
+ if (semOutbound)
+ for (int i=0; i<MAX_OUTBOUND_CONNECTIONS; i++)
+ semOutbound->post();
+
+ if (fAddressesInitialized)
+ {
+ DumpAddresses();
+ fAddressesInitialized = false;
+ }
+
+ return true;
+}
+
+class CNetCleanup
+{
+public:
+ CNetCleanup() {}
+
+ ~CNetCleanup()
+ {
+ // Close sockets
+ BOOST_FOREACH(CNode* pnode, vNodes)
+ if (pnode->hSocket != INVALID_SOCKET)
+ CloseSocket(pnode->hSocket);
+ BOOST_FOREACH(ListenSocket& hListenSocket, vhListenSocket)
+ if (hListenSocket.socket != INVALID_SOCKET)
+ if (!CloseSocket(hListenSocket.socket))
+ LogPrintf("CloseSocket(hListenSocket) failed with error %s\n", NetworkErrorString(WSAGetLastError()));
+
+ // clean up some globals (to help leak detection)
+ BOOST_FOREACH(CNode *pnode, vNodes)
+ delete pnode;
+ BOOST_FOREACH(CNode *pnode, vNodesDisconnected)
+ delete pnode;
+ vNodes.clear();
+ vNodesDisconnected.clear();
+ vhListenSocket.clear();
+ delete semOutbound;
+ semOutbound = NULL;
+ delete pnodeLocalHost;
+ pnodeLocalHost = NULL;
+
+#ifdef WIN32
+ // Shutdown Windows Sockets
+ WSACleanup();
+#endif
+ }
+}
+instance_of_cnetcleanup;
+
+
+
+
+
+
+
+void RelayTransaction(const CTransaction& tx)
+{
+ CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
+ ss.reserve(10000);
+ ss << tx;
+ RelayTransaction(tx, ss);
+}
+
+void RelayTransaction(const CTransaction& tx, const CDataStream& ss)
+{
+ CInv inv(MSG_TX, tx.GetHash());
+ {
+ 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));
+ }
+ LOCK(cs_vNodes);
+ BOOST_FOREACH(CNode* pnode, vNodes)
+ {
+ if(!pnode->fRelayTxes)
+ continue;
+ LOCK(pnode->cs_filter);
+ if (pnode->pfilter)
+ {
+ if (pnode->pfilter->IsRelevantAndUpdate(tx))
+ pnode->PushInventory(inv);
+ } else
+ pnode->PushInventory(inv);
+ }
+}
+
+void CNode::RecordBytesRecv(uint64_t bytes)
+{
+ LOCK(cs_totalBytesRecv);
+ nTotalBytesRecv += bytes;
+}
+
+void CNode::RecordBytesSent(uint64_t bytes)
+{
+ LOCK(cs_totalBytesSent);
+ nTotalBytesSent += bytes;
+}
+
+uint64_t CNode::GetTotalBytesRecv()
+{
+ LOCK(cs_totalBytesRecv);
+ return nTotalBytesRecv;
+}
+
+uint64_t CNode::GetTotalBytesSent()
+{
+ LOCK(cs_totalBytesSent);
+ return nTotalBytesSent;
+}
+
+void CNode::Fuzz(int nChance)
+{
+ if (!fSuccessfullyConnected) return; // Don't fuzz initial handshake
+ if (GetRand(nChance) != 0) return; // Fuzz 1 of every nChance messages
+
+ switch (GetRand(3))
+ {
+ case 0:
+ // xor a random byte with a random value:
+ if (!ssSend.empty()) {
+ CDataStream::size_type pos = GetRand(ssSend.size());
+ ssSend[pos] ^= (unsigned char)(GetRand(256));
+ }
+ break;
+ case 1:
+ // delete a random byte:
+ if (!ssSend.empty()) {
+ CDataStream::size_type pos = GetRand(ssSend.size());
+ ssSend.erase(ssSend.begin()+pos);
+ }
+ break;
+ case 2:
+ // insert a random byte at a random position
+ {
+ CDataStream::size_type pos = GetRand(ssSend.size());
+ char ch = (char)GetRand(256);
+ ssSend.insert(ssSend.begin()+pos, ch);
+ }
+ break;
+ }
+ // Chance of more than one change half the time:
+ // (more changes exponentially less likely):
+ Fuzz(2);
+}
+
+//
+// CAddrDB
+//
+
+CAddrDB::CAddrDB()
+{
+ pathAddr = GetDataDir() / "peers.dat";
+}
+
+bool CAddrDB::Write(const CAddrMan& addr)
+{
+ // Generate random temporary filename
+ unsigned short randv = 0;
+ GetRandBytes((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(Params().MessageStart());
+ 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(file, SER_DISK, CLIENT_VERSION);
+ if (fileout.IsNull())
+ return error("%s: Failed to open file %s", __func__, pathTmp.string());
+
+ // Write and commit header, data
+ try {
+ fileout << ssPeers;
+ }
+ catch (const std::exception& e) {
+ return error("%s: Serialize or I/O error - %s", __func__, e.what());
+ }
+ FileCommit(fileout.Get());
+ fileout.fclose();
+
+ // replace existing peers.dat, if any, with new peers.dat.XXXX
+ if (!RenameOver(pathTmp, pathAddr))
+ return error("%s: Rename-into-place failed", __func__);
+
+ return true;
+}
+
+bool CAddrDB::Read(CAddrMan& addr)
+{
+ // open input file, and associate with CAutoFile
+ FILE *file = fopen(pathAddr.string().c_str(), "rb");
+ CAutoFile filein(file, SER_DISK, CLIENT_VERSION);
+ if (filein.IsNull())
+ return error("%s: Failed to open file %s", __func__, pathAddr.string());
+
+ // use file size to size memory buffer
+ int fileSize = boost::filesystem::file_size(pathAddr);
+ int dataSize = fileSize - sizeof(uint256);
+ // Don't try to resize to a negative number if file is small
+ if (dataSize < 0)
+ dataSize = 0;
+ vector<unsigned char> vchData;
+ vchData.resize(dataSize);
+ uint256 hashIn;
+
+ // read data and checksum from file
+ try {
+ filein.read((char *)&vchData[0], dataSize);
+ filein >> hashIn;
+ }
+ catch (const std::exception& e) {
+ return error("%s: Deserialize or I/O error - %s", __func__, e.what());
+ }
+ 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("%s: Checksum mismatch, data corrupted", __func__);
+
+ unsigned char pchMsgTmp[4];
+ try {
+ // de-serialize file header (network specific magic number) and ..
+ ssPeers >> FLATDATA(pchMsgTmp);
+
+ // ... verify the network matches ours
+ if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp)))
+ return error("%s: Invalid network magic number", __func__);
+
+ // de-serialize address data into one CAddrMan object
+ ssPeers >> addr;
+ }
+ catch (const std::exception& e) {
+ return error("%s: Deserialize or I/O error - %s", __func__, e.what());
+ }
+
+ return true;
+}
+
+unsigned int ReceiveFloodSize() { return 1000*GetArg("-maxreceivebuffer", 5*1000); }
+unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", 1*1000); }
+
+CNode::CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn, bool fInboundIn) :
+ ssSend(SER_NETWORK, INIT_PROTO_VERSION),
+ addrKnown(5000, 0.001),
+ setInventoryKnown(SendBufferSize() / 1000)
+{
+ nServices = 0;
+ hSocket = hSocketIn;
+ nRecvVersion = INIT_PROTO_VERSION;
+ nLastSend = 0;
+ nLastRecv = 0;
+ nSendBytes = 0;
+ nRecvBytes = 0;
+ nTimeConnected = GetTime();
+ nTimeOffset = 0;
+ addr = addrIn;
+ addrName = addrNameIn == "" ? addr.ToStringIPPort() : addrNameIn;
+ nVersion = 0;
+ strSubVer = "";
+ fWhitelisted = false;
+ fOneShot = false;
+ fClient = false; // set by version message
+ fInbound = fInboundIn;
+ fNetworkNode = false;
+ fSuccessfullyConnected = false;
+ fDisconnect = false;
+ nRefCount = 0;
+ nSendSize = 0;
+ nSendOffset = 0;
+ hashContinue = uint256();
+ nStartingHeight = -1;
+ fGetAddr = false;
+ fRelayTxes = false;
+ pfilter = new CBloomFilter();
+ nPingNonceSent = 0;
+ nPingUsecStart = 0;
+ nPingUsecTime = 0;
+ fPingQueued = false;
+
+ {
+ LOCK(cs_nLastNodeId);
+ id = nLastNodeId++;
+ }
+
+ if (fLogIPs)
+ LogPrint("net", "Added connection to %s peer=%d\n", addrName, id);
+ else
+ LogPrint("net", "Added connection peer=%d\n", id);
+
+ // Be shy and don't send version until we hear
+ if (hSocket != INVALID_SOCKET && !fInbound)
+ PushVersion();
+
+ GetNodeSignals().InitializeNode(GetId(), this);
+}
+
+CNode::~CNode()
+{
+ CloseSocket(hSocket);
+
+ if (pfilter)
+ delete pfilter;
+
+ GetNodeSignals().FinalizeNode(GetId());
+}
+
+void CNode::AskFor(const CInv& inv)
+{
+ if (mapAskFor.size() > MAPASKFOR_MAX_SZ)
+ return;
+ // We're using mapAskFor as a priority queue,
+ // the key is the earliest time the request can be sent
+ int64_t nRequestTime;
+ limitedmap<CInv, int64_t>::const_iterator it = mapAlreadyAskedFor.find(inv);
+ if (it != mapAlreadyAskedFor.end())
+ nRequestTime = it->second;
+ else
+ nRequestTime = 0;
+ LogPrint("net", "askfor %s %d (%s) peer=%d\n", inv.ToString(), nRequestTime, DateTimeStrFormat("%H:%M:%S", nRequestTime/1000000), id);
+
+ // Make sure not to reuse time indexes to keep things in the same order
+ int64_t nNow = GetTimeMicros() - 1000000;
+ static int64_t 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);
+ if (it != mapAlreadyAskedFor.end())
+ mapAlreadyAskedFor.update(it, nRequestTime);
+ else
+ mapAlreadyAskedFor.insert(std::make_pair(inv, nRequestTime));
+ mapAskFor.insert(std::make_pair(nRequestTime, inv));
+}
+
+void CNode::BeginMessage(const char* pszCommand) EXCLUSIVE_LOCK_FUNCTION(cs_vSend)
+{
+ ENTER_CRITICAL_SECTION(cs_vSend);
+ assert(ssSend.size() == 0);
+ ssSend << CMessageHeader(Params().MessageStart(), pszCommand, 0);
+ LogPrint("net", "sending: %s ", SanitizeString(pszCommand));
+}
+
+void CNode::AbortMessage() UNLOCK_FUNCTION(cs_vSend)
+{
+ ssSend.clear();
+
+ LEAVE_CRITICAL_SECTION(cs_vSend);
+
+ LogPrint("net", "(aborted)\n");
+}
+
+void CNode::EndMessage() UNLOCK_FUNCTION(cs_vSend)
+{
+ // The -*messagestest options are intentionally not documented in the help message,
+ // since they are only used during development to debug the networking code and are
+ // not intended for end-users.
+ if (mapArgs.count("-dropmessagestest") && GetRand(GetArg("-dropmessagestest", 2)) == 0)
+ {
+ LogPrint("net", "dropmessages DROPPING SEND MESSAGE\n");
+ AbortMessage();
+ return;
+ }
+ if (mapArgs.count("-fuzzmessagestest"))
+ Fuzz(GetArg("-fuzzmessagestest", 10));
+
+ if (ssSend.size() == 0)
+ {
+ LEAVE_CRITICAL_SECTION(cs_vSend);
+ return;
+ }
+ // Set the size
+ unsigned int nSize = ssSend.size() - CMessageHeader::HEADER_SIZE;
+ WriteLE32((uint8_t*)&ssSend[CMessageHeader::MESSAGE_SIZE_OFFSET], nSize);
+
+ // Set the checksum
+ uint256 hash = Hash(ssSend.begin() + CMessageHeader::HEADER_SIZE, ssSend.end());
+ unsigned int nChecksum = 0;
+ memcpy(&nChecksum, &hash, sizeof(nChecksum));
+ assert(ssSend.size () >= CMessageHeader::CHECKSUM_OFFSET + sizeof(nChecksum));
+ memcpy((char*)&ssSend[CMessageHeader::CHECKSUM_OFFSET], &nChecksum, sizeof(nChecksum));
+
+ LogPrint("net", "(%d bytes) peer=%d\n", nSize, id);
+
+ std::deque<CSerializeData>::iterator it = vSendMsg.insert(vSendMsg.end(), CSerializeData());
+ ssSend.GetAndClear(*it);
+ nSendSize += (*it).size();
+
+ // If write queue empty, attempt "optimistic write"
+ if (it == vSendMsg.begin())
+ SocketSendData(this);
+
+ LEAVE_CRITICAL_SECTION(cs_vSend);
+}
diff --git a/src/net.h b/src/net.h
new file mode 100644
index 0000000000..17502b97eb
--- /dev/null
+++ b/src/net.h
@@ -0,0 +1,640 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT 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 "bloom.h"
+#include "compat.h"
+#include "hash.h"
+#include "limitedmap.h"
+#include "mruset.h"
+#include "netbase.h"
+#include "protocol.h"
+#include "random.h"
+#include "streams.h"
+#include "sync.h"
+#include "uint256.h"
+#include "utilstrencodings.h"
+
+#include <deque>
+#include <stdint.h>
+
+#ifndef WIN32
+#include <arpa/inet.h>
+#endif
+
+#include <boost/filesystem/path.hpp>
+#include <boost/foreach.hpp>
+#include <boost/signals2/signal.hpp>
+
+class CAddrMan;
+class CBlockIndex;
+class CScheduler;
+class CNode;
+
+namespace boost {
+ class thread_group;
+} // namespace boost
+
+/** Time between pings automatically sent out for latency probing and keepalive (in seconds). */
+static const int PING_INTERVAL = 2 * 60;
+/** Time after which to disconnect, after waiting for a ping response (or inactivity). */
+static const int TIMEOUT_INTERVAL = 20 * 60;
+/** The maximum number of entries in an 'inv' protocol message */
+static const unsigned int MAX_INV_SZ = 50000;
+/** The maximum number of new addresses to accumulate before announcing. */
+static const unsigned int MAX_ADDR_TO_SEND = 1000;
+/** Maximum length of incoming protocol messages (no message over 2 MiB is currently acceptable). */
+static const unsigned int MAX_PROTOCOL_MESSAGE_LENGTH = 2 * 1024 * 1024;
+/** -listen default */
+static const bool DEFAULT_LISTEN = true;
+/** -upnp default */
+#ifdef USE_UPNP
+static const bool DEFAULT_UPNP = USE_UPNP;
+#else
+static const bool DEFAULT_UPNP = false;
+#endif
+/** The maximum number of entries in mapAskFor */
+static const size_t MAPASKFOR_MAX_SZ = MAX_INV_SZ;
+
+unsigned int ReceiveFloodSize();
+unsigned int SendBufferSize();
+
+void AddOneShot(std::string strDest);
+void AddressCurrentlyConnected(const CService& addr);
+CNode* FindNode(const CNetAddr& ip);
+CNode* FindNode(const std::string& addrName);
+CNode* FindNode(const CService& ip);
+CNode* ConnectNode(CAddress addrConnect, const char *pszDest = NULL);
+bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false);
+void MapPort(bool fUseUPnP);
+unsigned short GetListenPort();
+bool BindListenPort(const CService &bindAddr, std::string& strError, bool fWhitelisted = false);
+void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler);
+bool StopNode();
+void SocketSendData(CNode *pnode);
+
+typedef int NodeId;
+
+struct CombinerAll
+{
+ typedef bool result_type;
+
+ template<typename I>
+ bool operator()(I first, I last) const
+ {
+ while (first != last) {
+ if (!(*first)) return false;
+ ++first;
+ }
+ return true;
+ }
+};
+
+// Signals for message handling
+struct CNodeSignals
+{
+ boost::signals2::signal<int ()> GetHeight;
+ boost::signals2::signal<bool (CNode*), CombinerAll> ProcessMessages;
+ boost::signals2::signal<bool (CNode*, bool), CombinerAll> SendMessages;
+ boost::signals2::signal<void (NodeId, const CNode*)> InitializeNode;
+ boost::signals2::signal<void (NodeId)> FinalizeNode;
+};
+
+
+CNodeSignals& GetNodeSignals();
+
+
+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_MANUAL, // address explicitly specified (-externalip=)
+
+ LOCAL_MAX
+};
+
+bool IsPeerAddrLocalGood(CNode *pnode);
+void AdvertizeLocal(CNode *pnode);
+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(enum Network net);
+bool IsReachable(const CNetAddr &addr);
+void SetReachable(enum Network net, bool fFlag = true);
+CAddress GetLocalAddress(const CNetAddr *paddrPeer = NULL);
+
+
+extern bool fDiscover;
+extern bool fListen;
+extern uint64_t nLocalServices;
+extern uint64_t nLocalHostNonce;
+extern CAddrMan addrman;
+extern int nMaxConnections;
+
+extern std::vector<CNode*> vNodes;
+extern CCriticalSection cs_vNodes;
+extern std::map<CInv, CDataStream> mapRelay;
+extern std::deque<std::pair<int64_t, CInv> > vRelayExpiration;
+extern CCriticalSection cs_mapRelay;
+extern limitedmap<CInv, int64_t> mapAlreadyAskedFor;
+
+extern std::vector<std::string> vAddedNodes;
+extern CCriticalSection cs_vAddedNodes;
+
+extern NodeId nLastNodeId;
+extern CCriticalSection cs_nLastNodeId;
+
+struct LocalServiceInfo {
+ int nScore;
+ int nPort;
+};
+
+extern CCriticalSection cs_mapLocalHost;
+extern std::map<CNetAddr, LocalServiceInfo> mapLocalHost;
+
+class CNodeStats
+{
+public:
+ NodeId nodeid;
+ uint64_t nServices;
+ int64_t nLastSend;
+ int64_t nLastRecv;
+ int64_t nTimeConnected;
+ int64_t nTimeOffset;
+ std::string addrName;
+ int nVersion;
+ std::string cleanSubVer;
+ bool fInbound;
+ int nStartingHeight;
+ uint64_t nSendBytes;
+ uint64_t nRecvBytes;
+ bool fWhitelisted;
+ double dPingTime;
+ double dPingWait;
+ std::string addrLocal;
+};
+
+
+
+
+class CNetMessage {
+public:
+ bool in_data; // parsing header (false) or data (true)
+
+ CDataStream hdrbuf; // partially received header
+ CMessageHeader hdr; // complete header
+ unsigned int nHdrPos;
+
+ CDataStream vRecv; // received message data
+ unsigned int nDataPos;
+
+ int64_t nTime; // time (in microseconds) of message receipt.
+
+ CNetMessage(const CMessageHeader::MessageStartChars& pchMessageStartIn, int nTypeIn, int nVersionIn) : hdrbuf(nTypeIn, nVersionIn), hdr(pchMessageStartIn), vRecv(nTypeIn, nVersionIn) {
+ hdrbuf.resize(24);
+ in_data = false;
+ nHdrPos = 0;
+ nDataPos = 0;
+ nTime = 0;
+ }
+
+ bool complete() const
+ {
+ if (!in_data)
+ return false;
+ return (hdr.nMessageSize == nDataPos);
+ }
+
+ void SetVersion(int nVersionIn)
+ {
+ hdrbuf.SetVersion(nVersionIn);
+ vRecv.SetVersion(nVersionIn);
+ }
+
+ int readHeader(const char *pch, unsigned int nBytes);
+ int readData(const char *pch, unsigned int nBytes);
+};
+
+
+
+
+
+/** Information about a peer */
+class CNode
+{
+public:
+ // socket
+ uint64_t nServices;
+ SOCKET hSocket;
+ CDataStream ssSend;
+ size_t nSendSize; // total size of all vSendMsg entries
+ size_t nSendOffset; // offset inside the first vSendMsg already sent
+ uint64_t nSendBytes;
+ std::deque<CSerializeData> vSendMsg;
+ CCriticalSection cs_vSend;
+
+ std::deque<CInv> vRecvGetData;
+ std::deque<CNetMessage> vRecvMsg;
+ CCriticalSection cs_vRecvMsg;
+ uint64_t nRecvBytes;
+ int nRecvVersion;
+
+ int64_t nLastSend;
+ int64_t nLastRecv;
+ int64_t nTimeConnected;
+ int64_t nTimeOffset;
+ CAddress addr;
+ std::string addrName;
+ CService addrLocal;
+ int nVersion;
+ // strSubVer is whatever byte array we read from the wire. However, this field is intended
+ // to be printed out, displayed to humans in various forms and so on. So we sanitize it and
+ // store the sanitized version in cleanSubVer. The original should be used when dealing with
+ // the network or wire types and the cleaned string used when displayed or logged.
+ std::string strSubVer, cleanSubVer;
+ bool fWhitelisted; // This peer can bypass DoS banning.
+ bool fOneShot;
+ bool fClient;
+ bool fInbound;
+ bool fNetworkNode;
+ bool fSuccessfullyConnected;
+ bool fDisconnect;
+ // We use fRelayTxes for two purposes -
+ // a) it allows us to not relay tx invs before receiving the peer's version message
+ // b) the peer may tell us in its version message that we should not relay tx invs
+ // until it has initialized its bloom filter.
+ bool fRelayTxes;
+ CSemaphoreGrant grantOutbound;
+ CCriticalSection cs_filter;
+ CBloomFilter* pfilter;
+ int nRefCount;
+ NodeId id;
+protected:
+
+ // Denial-of-service detection/prevention
+ // Key is IP address, value is banned-until-time
+ static std::map<CNetAddr, int64_t> setBanned;
+ static CCriticalSection cs_setBanned;
+
+ // Whitelisted ranges. Any node connecting from these is automatically
+ // whitelisted (as well as those connecting to whitelisted binds).
+ static std::vector<CSubNet> vWhitelistedRange;
+ static CCriticalSection cs_vWhitelistedRange;
+
+ // Basic fuzz-testing
+ void Fuzz(int nChance); // modifies ssSend
+
+public:
+ uint256 hashContinue;
+ int nStartingHeight;
+
+ // flood relay
+ std::vector<CAddress> vAddrToSend;
+ CRollingBloomFilter addrKnown;
+ bool fGetAddr;
+ std::set<uint256> setKnown;
+
+ // inventory based relay
+ mruset<CInv> setInventoryKnown;
+ std::vector<CInv> vInventoryToSend;
+ CCriticalSection cs_inventory;
+ std::multimap<int64_t, CInv> mapAskFor;
+
+ // Ping time measurement:
+ // The pong reply we're expecting, or 0 if no pong expected.
+ uint64_t nPingNonceSent;
+ // Time (in usec) the last ping was sent, or 0 if no ping was ever sent.
+ int64_t nPingUsecStart;
+ // Last measured round-trip time.
+ int64_t nPingUsecTime;
+ // Whether a ping is requested.
+ bool fPingQueued;
+
+ CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn = "", bool fInboundIn=false);
+ ~CNode();
+
+private:
+ // Network usage totals
+ static CCriticalSection cs_totalBytesRecv;
+ static CCriticalSection cs_totalBytesSent;
+ static uint64_t nTotalBytesRecv;
+ static uint64_t nTotalBytesSent;
+
+ CNode(const CNode&);
+ void operator=(const CNode&);
+
+public:
+
+ NodeId GetId() const {
+ return id;
+ }
+
+ int GetRefCount()
+ {
+ assert(nRefCount >= 0);
+ return nRefCount;
+ }
+
+ // requires LOCK(cs_vRecvMsg)
+ unsigned int GetTotalRecvSize()
+ {
+ unsigned int total = 0;
+ BOOST_FOREACH(const CNetMessage &msg, vRecvMsg)
+ total += msg.vRecv.size() + 24;
+ return total;
+ }
+
+ // requires LOCK(cs_vRecvMsg)
+ bool ReceiveMsgBytes(const char *pch, unsigned int nBytes);
+
+ // requires LOCK(cs_vRecvMsg)
+ void SetRecvVersion(int nVersionIn)
+ {
+ nRecvVersion = nVersionIn;
+ BOOST_FOREACH(CNetMessage &msg, vRecvMsg)
+ msg.SetVersion(nVersionIn);
+ }
+
+ CNode* AddRef()
+ {
+ nRefCount++;
+ return this;
+ }
+
+ void Release()
+ {
+ nRefCount--;
+ }
+
+
+
+ void AddAddressKnown(const CAddress& addr)
+ {
+ addrKnown.insert(addr.GetKey());
+ }
+
+ 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() && !addrKnown.contains(addr.GetKey())) {
+ if (vAddrToSend.size() >= MAX_ADDR_TO_SEND) {
+ vAddrToSend[insecure_rand() % vAddrToSend.size()] = addr;
+ } else {
+ 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);
+
+ // TODO: Document the postcondition of this function. Is cs_vSend locked?
+ void BeginMessage(const char* pszCommand) EXCLUSIVE_LOCK_FUNCTION(cs_vSend);
+
+ // TODO: Document the precondition of this function. Is cs_vSend locked?
+ void AbortMessage() UNLOCK_FUNCTION(cs_vSend);
+
+ // TODO: Document the precondition of this function. Is cs_vSend locked?
+ void EndMessage() UNLOCK_FUNCTION(cs_vSend);
+
+ void PushVersion();
+
+
+ void PushMessage(const char* pszCommand)
+ {
+ try
+ {
+ BeginMessage(pszCommand);
+ EndMessage();
+ }
+ catch (...)
+ {
+ AbortMessage();
+ throw;
+ }
+ }
+
+ template<typename T1>
+ void PushMessage(const char* pszCommand, const T1& a1)
+ {
+ try
+ {
+ BeginMessage(pszCommand);
+ ssSend << a1;
+ EndMessage();
+ }
+ catch (...)
+ {
+ AbortMessage();
+ throw;
+ }
+ }
+
+ template<typename T1, typename T2>
+ void PushMessage(const char* pszCommand, const T1& a1, const T2& a2)
+ {
+ try
+ {
+ BeginMessage(pszCommand);
+ ssSend << a1 << a2;
+ EndMessage();
+ }
+ catch (...)
+ {
+ AbortMessage();
+ throw;
+ }
+ }
+
+ template<typename T1, typename T2, typename T3>
+ void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3)
+ {
+ try
+ {
+ BeginMessage(pszCommand);
+ ssSend << a1 << a2 << a3;
+ EndMessage();
+ }
+ catch (...)
+ {
+ AbortMessage();
+ throw;
+ }
+ }
+
+ template<typename T1, typename T2, typename T3, typename T4>
+ void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4)
+ {
+ try
+ {
+ BeginMessage(pszCommand);
+ ssSend << a1 << a2 << a3 << a4;
+ EndMessage();
+ }
+ catch (...)
+ {
+ AbortMessage();
+ throw;
+ }
+ }
+
+ template<typename T1, typename T2, typename T3, typename T4, typename T5>
+ void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5)
+ {
+ try
+ {
+ BeginMessage(pszCommand);
+ ssSend << a1 << a2 << a3 << a4 << a5;
+ EndMessage();
+ }
+ catch (...)
+ {
+ AbortMessage();
+ throw;
+ }
+ }
+
+ template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
+ 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);
+ ssSend << a1 << a2 << a3 << a4 << a5 << a6;
+ EndMessage();
+ }
+ catch (...)
+ {
+ AbortMessage();
+ throw;
+ }
+ }
+
+ template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
+ 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);
+ ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7;
+ EndMessage();
+ }
+ catch (...)
+ {
+ AbortMessage();
+ throw;
+ }
+ }
+
+ template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
+ 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);
+ ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8;
+ EndMessage();
+ }
+ catch (...)
+ {
+ AbortMessage();
+ throw;
+ }
+ }
+
+ template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
+ 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);
+ ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9;
+ EndMessage();
+ }
+ catch (...)
+ {
+ AbortMessage();
+ throw;
+ }
+ }
+
+ void CloseSocketDisconnect();
+
+ // 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);
+ static bool Ban(const CNetAddr &ip);
+ void copyStats(CNodeStats &stats);
+
+ static bool IsWhitelistedRange(const CNetAddr &ip);
+ static void AddWhitelistedRange(const CSubNet &subnet);
+
+ // Network stats
+ static void RecordBytesRecv(uint64_t bytes);
+ static void RecordBytesSent(uint64_t bytes);
+
+ static uint64_t GetTotalBytesRecv();
+ static uint64_t GetTotalBytesSent();
+};
+
+
+
+class CTransaction;
+void RelayTransaction(const CTransaction& tx);
+void RelayTransaction(const CTransaction& tx, const CDataStream& ss);
+
+/** 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_NET_H
diff --git a/src/netbase.cpp b/src/netbase.cpp
new file mode 100644
index 0000000000..54d2bef7c4
--- /dev/null
+++ b/src/netbase.cpp
@@ -0,0 +1,1417 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifdef HAVE_CONFIG_H
+#include "config/bitcoin-config.h"
+#endif
+
+#include "netbase.h"
+
+#include "hash.h"
+#include "sync.h"
+#include "uint256.h"
+#include "random.h"
+#include "util.h"
+#include "utilstrencodings.h"
+
+#ifdef HAVE_GETADDRINFO_A
+#include <netdb.h>
+#endif
+
+#ifndef WIN32
+#if HAVE_INET_PTON
+#include <arpa/inet.h>
+#endif
+#include <fcntl.h>
+#endif
+
+#include <boost/algorithm/string/case_conv.hpp> // for to_lower()
+#include <boost/algorithm/string/predicate.hpp> // for startswith() and endswith()
+#include <boost/thread.hpp>
+
+#if !defined(HAVE_MSG_NOSIGNAL) && !defined(MSG_NOSIGNAL)
+#define MSG_NOSIGNAL 0
+#endif
+
+// Settings
+static proxyType proxyInfo[NET_MAX];
+static proxyType nameProxy;
+static CCriticalSection cs_proxyInfos;
+int nConnectTimeout = DEFAULT_CONNECT_TIMEOUT;
+bool fNameLookup = false;
+
+static const unsigned char pchIPv4[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff };
+
+// Need ample time for negotiation for very slow proxies such as Tor (milliseconds)
+static const int SOCKS5_RECV_TIMEOUT = 20 * 1000;
+
+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" || net == "onion") return NET_TOR;
+ return NET_UNROUTABLE;
+}
+
+std::string GetNetworkName(enum Network net) {
+ switch(net)
+ {
+ case NET_IPV4: return "ipv4";
+ case NET_IPV6: return "ipv6";
+ case NET_TOR: return "onion";
+ default: return "";
+ }
+}
+
+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)) {
+ int32_t n;
+ if (ParseInt32(in.substr(colon + 1), &n) && n > 0 && n < 0x10000) {
+ in = in.substr(0, colon);
+ 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<CNetAddr>& vIP, unsigned int nMaxSolutions, bool fAllowLookup)
+{
+ vIP.clear();
+
+ {
+ CNetAddr addr;
+ if (addr.SetSpecial(std::string(pszName))) {
+ vIP.push_back(addr);
+ return true;
+ }
+ }
+
+#ifdef HAVE_GETADDRINFO_A
+ struct in_addr ipv4_addr;
+#ifdef HAVE_INET_PTON
+ if (inet_pton(AF_INET, pszName, &ipv4_addr) > 0) {
+ vIP.push_back(CNetAddr(ipv4_addr));
+ return true;
+ }
+
+ struct in6_addr ipv6_addr;
+ if (inet_pton(AF_INET6, pszName, &ipv6_addr) > 0) {
+ vIP.push_back(CNetAddr(ipv6_addr));
+ return true;
+ }
+#else
+ ipv4_addr.s_addr = inet_addr(pszName);
+ if (ipv4_addr.s_addr != INADDR_NONE) {
+ vIP.push_back(CNetAddr(ipv4_addr));
+ return true;
+ }
+#endif
+#endif
+
+ struct addrinfo aiHint;
+ memset(&aiHint, 0, sizeof(struct addrinfo));
+ aiHint.ai_socktype = SOCK_STREAM;
+ aiHint.ai_protocol = IPPROTO_TCP;
+ aiHint.ai_family = AF_UNSPEC;
+#ifdef WIN32
+ aiHint.ai_flags = fAllowLookup ? 0 : AI_NUMERICHOST;
+#else
+ aiHint.ai_flags = fAllowLookup ? AI_ADDRCONFIG : AI_NUMERICHOST;
+#endif
+
+ struct addrinfo *aiRes = NULL;
+#ifdef HAVE_GETADDRINFO_A
+ struct gaicb gcb, *query = &gcb;
+ memset(query, 0, sizeof(struct gaicb));
+ gcb.ar_name = pszName;
+ gcb.ar_request = &aiHint;
+ int nErr = getaddrinfo_a(GAI_NOWAIT, &query, 1, NULL);
+ if (nErr)
+ return false;
+
+ do {
+ // Should set the timeout limit to a resonable value to avoid
+ // generating unnecessary checking call during the polling loop,
+ // while it can still response to stop request quick enough.
+ // 2 seconds looks fine in our situation.
+ struct timespec ts = { 2, 0 };
+ gai_suspend(&query, 1, &ts);
+ boost::this_thread::interruption_point();
+
+ nErr = gai_error(query);
+ if (0 == nErr)
+ aiRes = query->ar_result;
+ } while (nErr == EAI_INPROGRESS);
+#else
+ int nErr = getaddrinfo(pszName, NULL, &aiHint, &aiRes);
+#endif
+ 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));
+ }
+
+ 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));
+ }
+
+ aiTrav = aiTrav->ai_next;
+ }
+
+ freeaddrinfo(aiRes);
+
+ return (vIP.size() > 0);
+}
+
+bool LookupHost(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions, bool fAllowLookup)
+{
+ std::string strHost(pszName);
+ if (strHost.empty())
+ return false;
+ if (boost::algorithm::starts_with(strHost, "[") && boost::algorithm::ends_with(strHost, "]"))
+ {
+ strHost = strHost.substr(1, strHost.size() - 2);
+ }
+
+ return LookupIntern(strHost.c_str(), vIP, nMaxSolutions, fAllowLookup);
+}
+
+bool Lookup(const char *pszName, std::vector<CService>& 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<CNetAddr> 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<CService> 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);
+}
+
+/**
+ * Convert milliseconds to a struct timeval for select.
+ */
+struct timeval static MillisToTimeval(int64_t nTimeout)
+{
+ struct timeval timeout;
+ timeout.tv_sec = nTimeout / 1000;
+ timeout.tv_usec = (nTimeout % 1000) * 1000;
+ return timeout;
+}
+
+/**
+ * Read bytes from socket. This will either read the full number of bytes requested
+ * or return False on error or timeout.
+ * This function can be interrupted by boost thread interrupt.
+ *
+ * @param data Buffer to receive into
+ * @param len Length of data to receive
+ * @param timeout Timeout in milliseconds for receive operation
+ *
+ * @note This function requires that hSocket is in non-blocking mode.
+ */
+bool static InterruptibleRecv(char* data, size_t len, int timeout, SOCKET& hSocket)
+{
+ int64_t curTime = GetTimeMillis();
+ int64_t endTime = curTime + timeout;
+ // Maximum time to wait in one select call. It will take up until this time (in millis)
+ // to break off in case of an interruption.
+ const int64_t maxWait = 1000;
+ while (len > 0 && curTime < endTime) {
+ ssize_t ret = recv(hSocket, data, len, 0); // Optimistically try the recv first
+ if (ret > 0) {
+ len -= ret;
+ data += ret;
+ } else if (ret == 0) { // Unexpected disconnection
+ return false;
+ } else { // Other error or blocking
+ int nErr = WSAGetLastError();
+ if (nErr == WSAEINPROGRESS || nErr == WSAEWOULDBLOCK || nErr == WSAEINVAL) {
+ if (!IsSelectableSocket(hSocket)) {
+ return false;
+ }
+ struct timeval tval = MillisToTimeval(std::min(endTime - curTime, maxWait));
+ fd_set fdset;
+ FD_ZERO(&fdset);
+ FD_SET(hSocket, &fdset);
+ int nRet = select(hSocket + 1, &fdset, NULL, NULL, &tval);
+ if (nRet == SOCKET_ERROR) {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+ boost::this_thread::interruption_point();
+ curTime = GetTimeMillis();
+ }
+ return len == 0;
+}
+
+struct ProxyCredentials
+{
+ std::string username;
+ std::string password;
+};
+
+/** Connect using SOCKS5 (as described in RFC1928) */
+static bool Socks5(const std::string& strDest, int port, const ProxyCredentials *auth, SOCKET& hSocket)
+{
+ LogPrintf("SOCKS5 connecting %s\n", strDest);
+ if (strDest.size() > 255) {
+ CloseSocket(hSocket);
+ return error("Hostname too long");
+ }
+ // Accepted authentication methods
+ std::vector<uint8_t> vSocks5Init;
+ vSocks5Init.push_back(0x05);
+ if (auth) {
+ vSocks5Init.push_back(0x02); // # METHODS
+ vSocks5Init.push_back(0x00); // X'00' NO AUTHENTICATION REQUIRED
+ vSocks5Init.push_back(0x02); // X'02' USERNAME/PASSWORD (RFC1929)
+ } else {
+ vSocks5Init.push_back(0x01); // # METHODS
+ vSocks5Init.push_back(0x00); // X'00' NO AUTHENTICATION REQUIRED
+ }
+ ssize_t ret = send(hSocket, (const char*)begin_ptr(vSocks5Init), vSocks5Init.size(), MSG_NOSIGNAL);
+ if (ret != (ssize_t)vSocks5Init.size()) {
+ CloseSocket(hSocket);
+ return error("Error sending to proxy");
+ }
+ char pchRet1[2];
+ if (!InterruptibleRecv(pchRet1, 2, SOCKS5_RECV_TIMEOUT, hSocket)) {
+ CloseSocket(hSocket);
+ return error("Error reading proxy response");
+ }
+ if (pchRet1[0] != 0x05) {
+ CloseSocket(hSocket);
+ return error("Proxy failed to initialize");
+ }
+ if (pchRet1[1] == 0x02 && auth) {
+ // Perform username/password authentication (as described in RFC1929)
+ std::vector<uint8_t> vAuth;
+ vAuth.push_back(0x01);
+ if (auth->username.size() > 255 || auth->password.size() > 255)
+ return error("Proxy username or password too long");
+ vAuth.push_back(auth->username.size());
+ vAuth.insert(vAuth.end(), auth->username.begin(), auth->username.end());
+ vAuth.push_back(auth->password.size());
+ vAuth.insert(vAuth.end(), auth->password.begin(), auth->password.end());
+ ret = send(hSocket, (const char*)begin_ptr(vAuth), vAuth.size(), MSG_NOSIGNAL);
+ if (ret != (ssize_t)vAuth.size()) {
+ CloseSocket(hSocket);
+ return error("Error sending authentication to proxy");
+ }
+ LogPrint("proxy", "SOCKS5 sending proxy authentication %s:%s\n", auth->username, auth->password);
+ char pchRetA[2];
+ if (!InterruptibleRecv(pchRetA, 2, SOCKS5_RECV_TIMEOUT, hSocket)) {
+ CloseSocket(hSocket);
+ return error("Error reading proxy authentication response");
+ }
+ if (pchRetA[0] != 0x01 || pchRetA[1] != 0x00) {
+ CloseSocket(hSocket);
+ return error("Proxy authentication unsuccessful");
+ }
+ } else if (pchRet1[1] == 0x00) {
+ // Perform no authentication
+ } else {
+ CloseSocket(hSocket);
+ return error("Proxy requested wrong authentication method %02x", pchRet1[1]);
+ }
+ std::vector<uint8_t> vSocks5;
+ vSocks5.push_back(0x05); // VER protocol version
+ vSocks5.push_back(0x01); // CMD CONNECT
+ vSocks5.push_back(0x00); // RSV Reserved
+ vSocks5.push_back(0x03); // ATYP DOMAINNAME
+ vSocks5.push_back(strDest.size()); // Length<=255 is checked at beginning of function
+ vSocks5.insert(vSocks5.end(), strDest.begin(), strDest.end());
+ vSocks5.push_back((port >> 8) & 0xFF);
+ vSocks5.push_back((port >> 0) & 0xFF);
+ ret = send(hSocket, (const char*)begin_ptr(vSocks5), vSocks5.size(), MSG_NOSIGNAL);
+ if (ret != (ssize_t)vSocks5.size()) {
+ CloseSocket(hSocket);
+ return error("Error sending to proxy");
+ }
+ char pchRet2[4];
+ if (!InterruptibleRecv(pchRet2, 4, SOCKS5_RECV_TIMEOUT, hSocket)) {
+ 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 = InterruptibleRecv(pchRet3, 4, SOCKS5_RECV_TIMEOUT, hSocket); break;
+ case 0x04: ret = InterruptibleRecv(pchRet3, 16, SOCKS5_RECV_TIMEOUT, hSocket); break;
+ case 0x03:
+ {
+ ret = InterruptibleRecv(pchRet3, 1, SOCKS5_RECV_TIMEOUT, hSocket);
+ if (!ret) {
+ CloseSocket(hSocket);
+ return error("Error reading from proxy");
+ }
+ int nRecv = pchRet3[0];
+ ret = InterruptibleRecv(pchRet3, nRecv, SOCKS5_RECV_TIMEOUT, hSocket);
+ break;
+ }
+ default: CloseSocket(hSocket); return error("Error: malformed proxy response");
+ }
+ if (!ret) {
+ CloseSocket(hSocket);
+ return error("Error reading from proxy");
+ }
+ if (!InterruptibleRecv(pchRet3, 2, SOCKS5_RECV_TIMEOUT, hSocket)) {
+ CloseSocket(hSocket);
+ return error("Error reading from proxy");
+ }
+ LogPrintf("SOCKS5 connected %s\n", strDest);
+ return true;
+}
+
+bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRet, int nTimeout)
+{
+ hSocketRet = INVALID_SOCKET;
+
+ struct sockaddr_storage sockaddr;
+ socklen_t len = sizeof(sockaddr);
+ if (!addrConnect.GetSockAddr((struct sockaddr*)&sockaddr, &len)) {
+ LogPrintf("Cannot connect to %s: unsupported network\n", addrConnect.ToString());
+ return false;
+ }
+
+ SOCKET hSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP);
+ if (hSocket == INVALID_SOCKET)
+ return false;
+
+ int set = 1;
+#ifdef SO_NOSIGPIPE
+ // Different way of disabling SIGPIPE on BSD
+ setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int));
+#endif
+
+ //Disable Nagle's algorithm
+#ifdef WIN32
+ setsockopt(hSocket, IPPROTO_TCP, TCP_NODELAY, (const char*)&set, sizeof(int));
+#else
+ setsockopt(hSocket, IPPROTO_TCP, TCP_NODELAY, (void*)&set, sizeof(int));
+#endif
+
+ // Set to non-blocking
+ if (!SetSocketNonBlocking(hSocket, true))
+ return error("ConnectSocketDirectly: Setting socket to non-blocking failed, error %s\n", NetworkErrorString(WSAGetLastError()));
+
+ if (connect(hSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR)
+ {
+ int nErr = WSAGetLastError();
+ // WSAEINVAL is here because some legacy version of winsock uses it
+ if (nErr == WSAEINPROGRESS || nErr == WSAEWOULDBLOCK || nErr == WSAEINVAL)
+ {
+ struct timeval timeout = MillisToTimeval(nTimeout);
+ fd_set fdset;
+ FD_ZERO(&fdset);
+ FD_SET(hSocket, &fdset);
+ int nRet = select(hSocket + 1, NULL, &fdset, NULL, &timeout);
+ if (nRet == 0)
+ {
+ LogPrint("net", "connection to %s timeout\n", addrConnect.ToString());
+ CloseSocket(hSocket);
+ return false;
+ }
+ if (nRet == SOCKET_ERROR)
+ {
+ LogPrintf("select() for %s failed: %s\n", addrConnect.ToString(), NetworkErrorString(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
+ {
+ LogPrintf("getsockopt() for %s failed: %s\n", addrConnect.ToString(), NetworkErrorString(WSAGetLastError()));
+ CloseSocket(hSocket);
+ return false;
+ }
+ if (nRet != 0)
+ {
+ LogPrintf("connect() to %s failed after select(): %s\n", addrConnect.ToString(), NetworkErrorString(nRet));
+ CloseSocket(hSocket);
+ return false;
+ }
+ }
+#ifdef WIN32
+ else if (WSAGetLastError() != WSAEISCONN)
+#else
+ else
+#endif
+ {
+ LogPrintf("connect() to %s failed: %s\n", addrConnect.ToString(), NetworkErrorString(WSAGetLastError()));
+ CloseSocket(hSocket);
+ return false;
+ }
+ }
+
+ hSocketRet = hSocket;
+ return true;
+}
+
+bool SetProxy(enum Network net, const proxyType &addrProxy) {
+ assert(net >= 0 && net < NET_MAX);
+ if (!addrProxy.IsValid())
+ return false;
+ LOCK(cs_proxyInfos);
+ proxyInfo[net] = addrProxy;
+ return true;
+}
+
+bool GetProxy(enum Network net, proxyType &proxyInfoOut) {
+ assert(net >= 0 && net < NET_MAX);
+ LOCK(cs_proxyInfos);
+ if (!proxyInfo[net].IsValid())
+ return false;
+ proxyInfoOut = proxyInfo[net];
+ return true;
+}
+
+bool SetNameProxy(const proxyType &addrProxy) {
+ if (!addrProxy.IsValid())
+ return false;
+ LOCK(cs_proxyInfos);
+ nameProxy = addrProxy;
+ return true;
+}
+
+bool GetNameProxy(proxyType &nameProxyOut) {
+ LOCK(cs_proxyInfos);
+ if(!nameProxy.IsValid())
+ return false;
+ nameProxyOut = nameProxy;
+ return true;
+}
+
+bool HaveNameProxy() {
+ LOCK(cs_proxyInfos);
+ return nameProxy.IsValid();
+}
+
+bool IsProxy(const CNetAddr &addr) {
+ LOCK(cs_proxyInfos);
+ for (int i = 0; i < NET_MAX; i++) {
+ if (addr == (CNetAddr)proxyInfo[i].proxy)
+ return true;
+ }
+ return false;
+}
+
+static bool ConnectThroughProxy(const proxyType &proxy, const std::string& strDest, int port, SOCKET& hSocketRet, int nTimeout, bool *outProxyConnectionFailed)
+{
+ SOCKET hSocket = INVALID_SOCKET;
+ // first connect to proxy server
+ if (!ConnectSocketDirectly(proxy.proxy, hSocket, nTimeout)) {
+ if (outProxyConnectionFailed)
+ *outProxyConnectionFailed = true;
+ return false;
+ }
+ // do socks negotiation
+ if (proxy.randomize_credentials) {
+ ProxyCredentials random_auth;
+ random_auth.username = strprintf("%i", insecure_rand());
+ random_auth.password = strprintf("%i", insecure_rand());
+ if (!Socks5(strDest, (unsigned short)port, &random_auth, hSocket))
+ return false;
+ } else {
+ if (!Socks5(strDest, (unsigned short)port, 0, hSocket))
+ return false;
+ }
+
+ hSocketRet = hSocket;
+ return true;
+}
+
+bool ConnectSocket(const CService &addrDest, SOCKET& hSocketRet, int nTimeout, bool *outProxyConnectionFailed)
+{
+ proxyType proxy;
+ if (outProxyConnectionFailed)
+ *outProxyConnectionFailed = false;
+
+ if (GetProxy(addrDest.GetNetwork(), proxy))
+ return ConnectThroughProxy(proxy, addrDest.ToStringIP(), addrDest.GetPort(), hSocketRet, nTimeout, outProxyConnectionFailed);
+ else // no proxy needed (none set for target network)
+ return ConnectSocketDirectly(addrDest, hSocketRet, nTimeout);
+}
+
+bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest, int portDefault, int nTimeout, bool *outProxyConnectionFailed)
+{
+ std::string strDest;
+ int port = portDefault;
+
+ if (outProxyConnectionFailed)
+ *outProxyConnectionFailed = false;
+
+ SplitHostPort(std::string(pszDest), port, strDest);
+
+ proxyType nameProxy;
+ GetNameProxy(nameProxy);
+
+ CService addrResolved(CNetAddr(strDest, fNameLookup && !HaveNameProxy()), port);
+ if (addrResolved.IsValid()) {
+ addr = addrResolved;
+ return ConnectSocket(addr, hSocketRet, nTimeout);
+ }
+
+ addr = CService("0.0.0.0:0");
+
+ if (!HaveNameProxy())
+ return false;
+ return ConnectThroughProxy(nameProxy, strDest, port, hSocketRet, nTimeout, outProxyConnectionFailed);
+}
+
+void CNetAddr::Init()
+{
+ memset(ip, 0, sizeof(ip));
+}
+
+void CNetAddr::SetIP(const CNetAddr& ipIn)
+{
+ memcpy(ip, ipIn.ip, sizeof(ip));
+}
+
+void CNetAddr::SetRaw(Network network, const uint8_t *ip_in)
+{
+ switch(network)
+ {
+ case NET_IPV4:
+ memcpy(ip, pchIPv4, 12);
+ memcpy(ip+12, ip_in, 4);
+ break;
+ case NET_IPV6:
+ memcpy(ip, ip_in, 16);
+ break;
+ default:
+ assert(!"invalid network");
+ }
+}
+
+static const unsigned char pchOnionCat[] = {0xFD,0x87,0xD8,0x7E,0xEB,0x43};
+
+bool CNetAddr::SetSpecial(const std::string &strName)
+{
+ if (strName.size()>6 && strName.substr(strName.size() - 6, 6) == ".onion") {
+ std::vector<unsigned char> 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;
+ }
+ return false;
+}
+
+CNetAddr::CNetAddr()
+{
+ Init();
+}
+
+CNetAddr::CNetAddr(const struct in_addr& ipv4Addr)
+{
+ SetRaw(NET_IPV4, (const uint8_t*)&ipv4Addr);
+}
+
+CNetAddr::CNetAddr(const struct in6_addr& ipv6Addr)
+{
+ SetRaw(NET_IPV6, (const uint8_t*)&ipv6Addr);
+}
+
+CNetAddr::CNetAddr(const char *pszIp, bool fAllowLookup)
+{
+ Init();
+ std::vector<CNetAddr> vIP;
+ if (LookupHost(pszIp, vIP, 1, fAllowLookup))
+ *this = vIP[0];
+}
+
+CNetAddr::CNetAddr(const std::string &strIp, bool fAllowLookup)
+{
+ Init();
+ std::vector<CNetAddr> vIP;
+ if (LookupHost(strIp.c_str(), vIP, 1, fAllowLookup))
+ *this = vIP[0];
+}
+
+unsigned 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());
+}
+
+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::IsRFC2544() const
+{
+ return IsIPv4() && GetByte(3) == 198 && (GetByte(2) == 18 || GetByte(2) == 19);
+}
+
+bool CNetAddr::IsRFC3927() const
+{
+ return IsIPv4() && (GetByte(3) == 169 && GetByte(2) == 254);
+}
+
+bool CNetAddr::IsRFC6598() const
+{
+ return IsIPv4() && GetByte(3) == 100 && GetByte(2) >= 64 && GetByte(2) <= 127;
+}
+
+bool CNetAddr::IsRFC5737() const
+{
+ return IsIPv4() && ((GetByte(3) == 192 && GetByte(2) == 0 && GetByte(1) == 2) ||
+ (GetByte(3) == 198 && GetByte(2) == 51 && GetByte(1) == 100) ||
+ (GetByte(3) == 203 && GetByte(2) == 0 && GetByte(1) == 113));
+}
+
+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::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
+{
+ // Cleanup 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() || IsRFC2544() || IsRFC3927() || IsRFC4862() || IsRFC6598() || IsRFC5737() || (IsRFC4193() && !IsTor()) || IsRFC4843() || IsLocal());
+}
+
+enum Network CNetAddr::GetNetwork() const
+{
+ if (!IsRoutable())
+ return NET_UNROUTABLE;
+
+ if (IsIPv4())
+ return NET_IPV4;
+
+ if (IsTor())
+ return NET_TOR;
+
+ return NET_IPV6;
+}
+
+std::string CNetAddr::ToStringIP() const
+{
+ if (IsTor())
+ return EncodeBase32(&ip[6], 10) + ".onion";
+ CService serv(*this, 0);
+ struct sockaddr_storage sockaddr;
+ 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;
+}
+
+bool CNetAddr::GetIn6Addr(struct in6_addr* pipv6Addr) const
+{
+ memcpy(pipv6Addr, ip, 16);
+ return true;
+}
+
+// get canonical identifier of an address' group
+// no two connections will be attempted to addresses with the same group
+std::vector<unsigned char> CNetAddr::GetGroup() const
+{
+ std::vector<unsigned char> 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 tunnelled addresses, use the encapsulated IPv4 address
+ else if (IsRFC3964())
+ {
+ nClass = NET_IPV4;
+ nStartByte = 2;
+ }
+ // for Teredo-tunnelled 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;
+ }
+ // for he.net, use /36 groups
+ else if (GetByte(15) == 0x20 && GetByte(14) == 0x01 && 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 << (8 - nBits)) - 1));
+
+ return vchRet;
+}
+
+uint64_t CNetAddr::GetHash() const
+{
+ uint256 hash = Hash(&ip[0], &ip[16]);
+ uint64_t nRet;
+ memcpy(&nRet, &hash, sizeof(nRet));
+ return nRet;
+}
+
+// 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 tunnelled
+ }
+ 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_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_TOR: return REACH_PRIVATE; // either from Tor, 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)
+{
+}
+
+CService::CService(const struct in6_addr& ipv6Addr, unsigned short portIn) : CNetAddr(ipv6Addr), port(portIn)
+{
+}
+
+CService::CService(const struct sockaddr_in& addr) : CNetAddr(addr.sin_addr), port(ntohs(addr.sin_port))
+{
+ assert(addr.sin_family == AF_INET);
+}
+
+CService::CService(const struct sockaddr_in6 &addr) : CNetAddr(addr.sin6_addr), port(ntohs(addr.sin6_port))
+{
+ assert(addr.sin6_family == AF_INET6);
+}
+
+bool CService::SetSockAddr(const struct sockaddr *paddr)
+{
+ switch (paddr->sa_family) {
+ case AF_INET:
+ *this = CService(*(const struct sockaddr_in*)paddr);
+ return true;
+ case AF_INET6:
+ *this = CService(*(const struct sockaddr_in6*)paddr);
+ return true;
+ 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;
+ }
+ 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;
+ }
+ return false;
+}
+
+std::vector<unsigned char> CService::GetKey() const
+{
+ std::vector<unsigned char> 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("%u", port);
+}
+
+std::string CService::ToStringIPPort() const
+{
+ if (IsIPv4() || IsTor()) {
+ return ToStringIP() + ":" + ToStringPort();
+ } else {
+ return "[" + ToStringIP() + "]:" + ToStringPort();
+ }
+}
+
+std::string CService::ToString() const
+{
+ return ToStringIPPort();
+}
+
+void CService::SetPort(unsigned short portIn)
+{
+ port = portIn;
+}
+
+CSubNet::CSubNet():
+ valid(false)
+{
+ memset(netmask, 0, sizeof(netmask));
+}
+
+CSubNet::CSubNet(const std::string &strSubnet, bool fAllowLookup)
+{
+ size_t slash = strSubnet.find_last_of('/');
+ std::vector<CNetAddr> vIP;
+
+ valid = true;
+ // Default to /32 (IPv4) or /128 (IPv6), i.e. match single address
+ memset(netmask, 255, sizeof(netmask));
+
+ std::string strAddress = strSubnet.substr(0, slash);
+ if (LookupHost(strAddress.c_str(), vIP, 1, fAllowLookup))
+ {
+ network = vIP[0];
+ if (slash != strSubnet.npos)
+ {
+ std::string strNetmask = strSubnet.substr(slash + 1);
+ int32_t n;
+ // IPv4 addresses start at offset 12, and first 12 bytes must match, so just offset n
+ const int astartofs = network.IsIPv4() ? 12 : 0;
+ if (ParseInt32(strNetmask, &n)) // If valid number, assume /24 symtex
+ {
+ if(n >= 0 && n <= (128 - astartofs*8)) // Only valid if in range of bits of address
+ {
+ n += astartofs*8;
+ // Clear bits [n..127]
+ for (; n < 128; ++n)
+ netmask[n>>3] &= ~(1<<(7-(n&7)));
+ }
+ else
+ {
+ valid = false;
+ }
+ }
+ else // If not a valid number, try full netmask syntax
+ {
+ if (LookupHost(strNetmask.c_str(), vIP, 1, false)) // Never allow lookup for netmask
+ {
+ // Copy only the *last* four bytes in case of IPv4, the rest of the mask should stay 1's as
+ // we don't want pchIPv4 to be part of the mask.
+ for(int x=astartofs; x<16; ++x)
+ netmask[x] = vIP[0].ip[x];
+ }
+ else
+ {
+ valid = false;
+ }
+ }
+ }
+ }
+ else
+ {
+ valid = false;
+ }
+
+ // Normalize network according to netmask
+ for(int x=0; x<16; ++x)
+ network.ip[x] &= netmask[x];
+}
+
+bool CSubNet::Match(const CNetAddr &addr) const
+{
+ if (!valid || !addr.IsValid())
+ return false;
+ for(int x=0; x<16; ++x)
+ if ((addr.ip[x] & netmask[x]) != network.ip[x])
+ return false;
+ return true;
+}
+
+std::string CSubNet::ToString() const
+{
+ std::string strNetmask;
+ if (network.IsIPv4())
+ strNetmask = strprintf("%u.%u.%u.%u", netmask[12], netmask[13], netmask[14], netmask[15]);
+ else
+ strNetmask = strprintf("%x:%x:%x:%x:%x:%x:%x:%x",
+ netmask[0] << 8 | netmask[1], netmask[2] << 8 | netmask[3],
+ netmask[4] << 8 | netmask[5], netmask[6] << 8 | netmask[7],
+ netmask[8] << 8 | netmask[9], netmask[10] << 8 | netmask[11],
+ netmask[12] << 8 | netmask[13], netmask[14] << 8 | netmask[15]);
+ return network.ToString() + "/" + strNetmask;
+}
+
+bool CSubNet::IsValid() const
+{
+ return valid;
+}
+
+bool operator==(const CSubNet& a, const CSubNet& b)
+{
+ return a.valid == b.valid && a.network == b.network && !memcmp(a.netmask, b.netmask, 16);
+}
+
+bool operator!=(const CSubNet& a, const CSubNet& b)
+{
+ return !(a==b);
+}
+
+#ifdef WIN32
+std::string NetworkErrorString(int err)
+{
+ char buf[256];
+ buf[0] = 0;
+ if(FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK,
+ NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ buf, sizeof(buf), NULL))
+ {
+ return strprintf("%s (%d)", buf, err);
+ }
+ else
+ {
+ return strprintf("Unknown error (%d)", err);
+ }
+}
+#else
+std::string NetworkErrorString(int err)
+{
+ char buf[256];
+ const char *s = buf;
+ buf[0] = 0;
+ /* Too bad there are two incompatible implementations of the
+ * thread-safe strerror. */
+#ifdef STRERROR_R_CHAR_P /* GNU variant can return a pointer outside the passed buffer */
+ s = strerror_r(err, buf, sizeof(buf));
+#else /* POSIX variant always returns message in buffer */
+ if (strerror_r(err, buf, sizeof(buf)))
+ buf[0] = 0;
+#endif
+ return strprintf("%s (%d)", s, err);
+}
+#endif
+
+bool CloseSocket(SOCKET& hSocket)
+{
+ if (hSocket == INVALID_SOCKET)
+ return false;
+#ifdef WIN32
+ int ret = closesocket(hSocket);
+#else
+ int ret = close(hSocket);
+#endif
+ hSocket = INVALID_SOCKET;
+ return ret != SOCKET_ERROR;
+}
+
+bool SetSocketNonBlocking(SOCKET& hSocket, bool fNonBlocking)
+{
+ if (fNonBlocking) {
+#ifdef WIN32
+ u_long nOne = 1;
+ if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR) {
+#else
+ int fFlags = fcntl(hSocket, F_GETFL, 0);
+ if (fcntl(hSocket, F_SETFL, fFlags | O_NONBLOCK) == SOCKET_ERROR) {
+#endif
+ CloseSocket(hSocket);
+ return false;
+ }
+ } else {
+#ifdef WIN32
+ u_long nZero = 0;
+ if (ioctlsocket(hSocket, FIONBIO, &nZero) == SOCKET_ERROR) {
+#else
+ int fFlags = fcntl(hSocket, F_GETFL, 0);
+ if (fcntl(hSocket, F_SETFL, fFlags & ~O_NONBLOCK) == SOCKET_ERROR) {
+#endif
+ CloseSocket(hSocket);
+ return false;
+ }
+ }
+
+ return true;
+}
diff --git a/src/netbase.h b/src/netbase.h
new file mode 100644
index 0000000000..1f2957116e
--- /dev/null
+++ b/src/netbase.h
@@ -0,0 +1,206 @@
+// Copyright (c) 2009-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_NETBASE_H
+#define BITCOIN_NETBASE_H
+
+#if defined(HAVE_CONFIG_H)
+#include "config/bitcoin-config.h"
+#endif
+
+#include "compat.h"
+#include "serialize.h"
+
+#include <stdint.h>
+#include <string>
+#include <vector>
+
+extern int nConnectTimeout;
+extern bool fNameLookup;
+
+/** -timeout default */
+static const int DEFAULT_CONNECT_TIMEOUT = 5000;
+
+#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 = 0,
+ NET_IPV4,
+ NET_IPV6,
+ NET_TOR,
+
+ NET_MAX,
+};
+
+/** 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);
+
+ /**
+ * Set raw IPv4 or IPv6 address (in network byte order)
+ * @note Only NET_IPV4 and NET_IPV6 are allowed for network.
+ */
+ void SetRaw(Network network, const uint8_t *data);
+
+ bool SetSpecial(const std::string &strName); // for Tor 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)
+ bool IsRFC1918() const; // IPv4 private networks (10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12)
+ bool IsRFC2544() const; // IPv4 inter-network communcations (192.18.0.0/15)
+ bool IsRFC6598() const; // IPv4 ISP-level NAT (100.64.0.0/10)
+ bool IsRFC5737() const; // IPv4 documentation addresses (192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24)
+ bool IsRFC3849() const; // IPv6 documentation address (2001:0DB8::/32)
+ bool IsRFC3927() const; // IPv4 autoconfig (169.254.0.0/16)
+ bool IsRFC3964() const; // IPv6 6to4 tunnelling (2002::/16)
+ bool IsRFC4193() const; // IPv6 unique local (FC00::/7)
+ bool IsRFC4380() const; // IPv6 Teredo tunnelling (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 IsLocal() const;
+ bool IsRoutable() const;
+ bool IsValid() const;
+ bool IsMulticast() const;
+ enum Network GetNetwork() const;
+ std::string ToString() const;
+ std::string ToStringIP() const;
+ unsigned int GetByte(int n) const;
+ uint64_t GetHash() const;
+ bool GetInAddr(struct in_addr* pipv4Addr) const;
+ std::vector<unsigned char> GetGroup() const;
+ int GetReachabilityFrom(const CNetAddr *paddrPartner = NULL) const;
+
+ CNetAddr(const struct in6_addr& pipv6Addr);
+ bool GetIn6Addr(struct in6_addr* pipv6Addr) const;
+
+ 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);
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ READWRITE(FLATDATA(ip));
+ }
+
+ friend class CSubNet;
+};
+
+class CSubNet
+{
+ protected:
+ /// Network (base) address
+ CNetAddr network;
+ /// Netmask, in network byte order
+ uint8_t netmask[16];
+ /// Is this value valid? (only used to signal parse errors)
+ bool valid;
+
+ public:
+ CSubNet();
+ explicit CSubNet(const std::string &strSubnet, bool fAllowLookup = false);
+
+ bool Match(const CNetAddr &addr) const;
+
+ std::string ToString() const;
+ bool IsValid() const;
+
+ friend bool operator==(const CSubNet& a, const CSubNet& b);
+ friend bool operator!=(const CSubNet& a, const CSubNet& b);
+};
+
+/** 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<unsigned char> GetKey() const;
+ std::string ToString() const;
+ std::string ToStringPort() const;
+ std::string ToStringIPPort() const;
+
+ CService(const struct in6_addr& ipv6Addr, unsigned short port);
+ CService(const struct sockaddr_in6& addr);
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ READWRITE(FLATDATA(ip));
+ unsigned short portN = htons(port);
+ READWRITE(FLATDATA(portN));
+ if (ser_action.ForRead())
+ port = ntohs(portN);
+ }
+};
+
+class proxyType
+{
+public:
+ proxyType(): randomize_credentials(false) {}
+ proxyType(const CService &proxy, bool randomize_credentials=false): proxy(proxy), randomize_credentials(randomize_credentials) {}
+
+ bool IsValid() const { return proxy.IsValid(); }
+
+ CService proxy;
+ bool randomize_credentials;
+};
+
+enum Network ParseNetwork(std::string net);
+std::string GetNetworkName(enum Network net);
+void SplitHostPort(std::string in, int &portOut, std::string &hostOut);
+bool SetProxy(enum Network net, const proxyType &addrProxy);
+bool GetProxy(enum Network net, proxyType &proxyInfoOut);
+bool IsProxy(const CNetAddr &addr);
+bool SetNameProxy(const proxyType &addrProxy);
+bool HaveNameProxy();
+bool LookupHost(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions = 0, bool fAllowLookup = true);
+bool Lookup(const char *pszName, CService& addr, int portDefault = 0, bool fAllowLookup = true);
+bool Lookup(const char *pszName, std::vector<CService>& 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, bool *outProxyConnectionFailed = 0);
+bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest, int portDefault, int nTimeout, bool *outProxyConnectionFailed = 0);
+/** Return readable error string for a network error code */
+std::string NetworkErrorString(int err);
+/** Close socket and set hSocket to INVALID_SOCKET */
+bool CloseSocket(SOCKET& hSocket);
+/** Disable or enable blocking-mode for a socket */
+bool SetSocketNonBlocking(SOCKET& hSocket, bool fNonBlocking);
+
+#endif // BITCOIN_NETBASE_H
diff --git a/src/noui.cpp b/src/noui.cpp
new file mode 100644
index 0000000000..3a77361919
--- /dev/null
+++ b/src/noui.cpp
@@ -0,0 +1,52 @@
+// Copyright (c) 2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "noui.h"
+
+#include "ui_interface.h"
+#include "util.h"
+
+#include <cstdio>
+#include <stdint.h>
+#include <string>
+
+static bool noui_ThreadSafeMessageBox(const std::string& message, const std::string& caption, unsigned int style)
+{
+ bool fSecure = style & CClientUIInterface::SECURE;
+ style &= ~CClientUIInterface::SECURE;
+
+ std::string strCaption;
+ // Check for usage of predefined caption
+ switch (style) {
+ case CClientUIInterface::MSG_ERROR:
+ strCaption += _("Error");
+ break;
+ case CClientUIInterface::MSG_WARNING:
+ strCaption += _("Warning");
+ break;
+ case CClientUIInterface::MSG_INFORMATION:
+ strCaption += _("Information");
+ break;
+ default:
+ strCaption += caption; // Use supplied caption (can be empty)
+ }
+
+ if (!fSecure)
+ LogPrintf("%s: %s\n", strCaption, message);
+ fprintf(stderr, "%s: %s\n", strCaption.c_str(), message.c_str());
+ return false;
+}
+
+static void noui_InitMessage(const std::string& message)
+{
+ LogPrintf("init message: %s\n", message);
+}
+
+void noui_connect()
+{
+ // Connect bitcoind signal handlers
+ uiInterface.ThreadSafeMessageBox.connect(noui_ThreadSafeMessageBox);
+ uiInterface.InitMessage.connect(noui_InitMessage);
+}
diff --git a/src/noui.h b/src/noui.h
new file mode 100644
index 0000000000..15cd30a639
--- /dev/null
+++ b/src/noui.h
@@ -0,0 +1,10 @@
+// Copyright (c) 2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_NOUI_H
+#define BITCOIN_NOUI_H
+
+extern void noui_connect();
+
+#endif // BITCOIN_NOUI_H
diff --git a/src/obj-test/.gitignore b/src/obj-test/.gitignore
new file mode 100644
index 0000000000..d6b7ef32c8
--- /dev/null
+++ b/src/obj-test/.gitignore
@@ -0,0 +1,2 @@
+*
+!.gitignore
diff --git a/src/obj/.gitignore b/src/obj/.gitignore
new file mode 100644
index 0000000000..d6b7ef32c8
--- /dev/null
+++ b/src/obj/.gitignore
@@ -0,0 +1,2 @@
+*
+!.gitignore
diff --git a/src/policy/fees.cpp b/src/policy/fees.cpp
new file mode 100644
index 0000000000..ffe31d1942
--- /dev/null
+++ b/src/policy/fees.cpp
@@ -0,0 +1,530 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2015 The Bitcoin developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "policy/fees.h"
+
+#include "amount.h"
+#include "primitives/transaction.h"
+#include "streams.h"
+#include "txmempool.h"
+#include "util.h"
+
+void TxConfirmStats::Initialize(std::vector<double>& defaultBuckets,
+ unsigned int maxConfirms, double _decay, std::string _dataTypeString)
+{
+ decay = _decay;
+ dataTypeString = _dataTypeString;
+ for (unsigned int i = 0; i < defaultBuckets.size(); i++) {
+ buckets.push_back(defaultBuckets[i]);
+ bucketMap[defaultBuckets[i]] = i;
+ }
+ confAvg.resize(maxConfirms);
+ curBlockConf.resize(maxConfirms);
+ unconfTxs.resize(maxConfirms);
+ for (unsigned int i = 0; i < maxConfirms; i++) {
+ confAvg[i].resize(buckets.size());
+ curBlockConf[i].resize(buckets.size());
+ unconfTxs[i].resize(buckets.size());
+ }
+
+ oldUnconfTxs.resize(buckets.size());
+ curBlockTxCt.resize(buckets.size());
+ txCtAvg.resize(buckets.size());
+ curBlockVal.resize(buckets.size());
+ avg.resize(buckets.size());
+}
+
+// Zero out the data for the current block
+void TxConfirmStats::ClearCurrent(unsigned int nBlockHeight)
+{
+ for (unsigned int j = 0; j < buckets.size(); j++) {
+ oldUnconfTxs[j] += unconfTxs[nBlockHeight%unconfTxs.size()][j];
+ unconfTxs[nBlockHeight%unconfTxs.size()][j] = 0;
+ for (unsigned int i = 0; i < curBlockConf.size(); i++)
+ curBlockConf[i][j] = 0;
+ curBlockTxCt[j] = 0;
+ curBlockVal[j] = 0;
+ }
+}
+
+
+void TxConfirmStats::Record(int blocksToConfirm, double val)
+{
+ // blocksToConfirm is 1-based
+ if (blocksToConfirm < 1)
+ return;
+ unsigned int bucketindex = bucketMap.lower_bound(val)->second;
+ for (size_t i = blocksToConfirm; i <= curBlockConf.size(); i++) {
+ curBlockConf[i - 1][bucketindex]++;
+ }
+ curBlockTxCt[bucketindex]++;
+ curBlockVal[bucketindex] += val;
+}
+
+void TxConfirmStats::UpdateMovingAverages()
+{
+ for (unsigned int j = 0; j < buckets.size(); j++) {
+ for (unsigned int i = 0; i < confAvg.size(); i++)
+ confAvg[i][j] = confAvg[i][j] * decay + curBlockConf[i][j];
+ avg[j] = avg[j] * decay + curBlockVal[j];
+ txCtAvg[j] = txCtAvg[j] * decay + curBlockTxCt[j];
+ }
+}
+
+// returns -1 on error conditions
+double TxConfirmStats::EstimateMedianVal(int confTarget, double sufficientTxVal,
+ double successBreakPoint, bool requireGreater,
+ unsigned int nBlockHeight)
+{
+ // Counters for a bucket (or range of buckets)
+ double nConf = 0; // Number of tx's confirmed within the confTarget
+ double totalNum = 0; // Total number of tx's that were ever confirmed
+ int extraNum = 0; // Number of tx's still in mempool for confTarget or longer
+
+ int maxbucketindex = buckets.size() - 1;
+
+ // requireGreater means we are looking for the lowest fee/priority such that all higher
+ // values pass, so we start at maxbucketindex (highest fee) and look at succesively
+ // smaller buckets until we reach failure. Otherwise, we are looking for the highest
+ // fee/priority such that all lower values fail, and we go in the opposite direction.
+ unsigned int startbucket = requireGreater ? maxbucketindex : 0;
+ int step = requireGreater ? -1 : 1;
+
+ // We'll combine buckets until we have enough samples.
+ // The near and far variables will define the range we've combined
+ // The best variables are the last range we saw which still had a high
+ // enough confirmation rate to count as success.
+ // The cur variables are the current range we're counting.
+ unsigned int curNearBucket = startbucket;
+ unsigned int bestNearBucket = startbucket;
+ unsigned int curFarBucket = startbucket;
+ unsigned int bestFarBucket = startbucket;
+
+ bool foundAnswer = false;
+ unsigned int bins = unconfTxs.size();
+
+ // Start counting from highest(default) or lowest fee/pri transactions
+ for (int bucket = startbucket; bucket >= 0 && bucket <= maxbucketindex; bucket += step) {
+ curFarBucket = bucket;
+ nConf += confAvg[confTarget - 1][bucket];
+ totalNum += txCtAvg[bucket];
+ for (unsigned int confct = confTarget; confct < GetMaxConfirms(); confct++)
+ extraNum += unconfTxs[(nBlockHeight - confct)%bins][bucket];
+ extraNum += oldUnconfTxs[bucket];
+ // If we have enough transaction data points in this range of buckets,
+ // we can test for success
+ // (Only count the confirmed data points, so that each confirmation count
+ // will be looking at the same amount of data and same bucket breaks)
+ if (totalNum >= sufficientTxVal / (1 - decay)) {
+ double curPct = nConf / (totalNum + extraNum);
+
+ // Check to see if we are no longer getting confirmed at the success rate
+ if (requireGreater && curPct < successBreakPoint)
+ break;
+ if (!requireGreater && curPct > successBreakPoint)
+ break;
+
+ // Otherwise update the cumulative stats, and the bucket variables
+ // and reset the counters
+ else {
+ foundAnswer = true;
+ nConf = 0;
+ totalNum = 0;
+ extraNum = 0;
+ bestNearBucket = curNearBucket;
+ bestFarBucket = curFarBucket;
+ curNearBucket = bucket + step;
+ }
+ }
+ }
+
+ double median = -1;
+ double txSum = 0;
+
+ // Calculate the "average" fee of the best bucket range that met success conditions
+ // Find the bucket with the median transaction and then report the average fee from that bucket
+ // This is a compromise between finding the median which we can't since we don't save all tx's
+ // and reporting the average which is less accurate
+ unsigned int minBucket = bestNearBucket < bestFarBucket ? bestNearBucket : bestFarBucket;
+ unsigned int maxBucket = bestNearBucket > bestFarBucket ? bestNearBucket : bestFarBucket;
+ for (unsigned int j = minBucket; j <= maxBucket; j++) {
+ txSum += txCtAvg[j];
+ }
+ if (foundAnswer && txSum != 0) {
+ txSum = txSum / 2;
+ for (unsigned int j = minBucket; j <= maxBucket; j++) {
+ if (txCtAvg[j] < txSum)
+ txSum -= txCtAvg[j];
+ else { // we're in the right bucket
+ median = avg[j] / txCtAvg[j];
+ break;
+ }
+ }
+ }
+
+ LogPrint("estimatefee", "%3d: For conf success %s %4.2f need %s %s: %12.5g from buckets %8g - %8g Cur Bucket stats %6.2f%% %8.1f/(%.1f+%d mempool)\n",
+ confTarget, requireGreater ? ">" : "<", successBreakPoint, dataTypeString,
+ requireGreater ? ">" : "<", median, buckets[minBucket], buckets[maxBucket],
+ 100 * nConf / (totalNum + extraNum), nConf, totalNum, extraNum);
+
+ return median;
+}
+
+void TxConfirmStats::Write(CAutoFile& fileout)
+{
+ fileout << decay;
+ fileout << buckets;
+ fileout << avg;
+ fileout << txCtAvg;
+ fileout << confAvg;
+}
+
+void TxConfirmStats::Read(CAutoFile& filein)
+{
+ // Read data file into temporary variables and do some very basic sanity checking
+ std::vector<double> fileBuckets;
+ std::vector<double> fileAvg;
+ std::vector<std::vector<double> > fileConfAvg;
+ std::vector<double> fileTxCtAvg;
+ double fileDecay;
+ size_t maxConfirms;
+ size_t numBuckets;
+
+ filein >> fileDecay;
+ if (fileDecay <= 0 || fileDecay >= 1)
+ throw std::runtime_error("Corrupt estimates file. Decay must be between 0 and 1 (non-inclusive)");
+ filein >> fileBuckets;
+ numBuckets = fileBuckets.size();
+ if (numBuckets <= 1 || numBuckets > 1000)
+ throw std::runtime_error("Corrupt estimates file. Must have between 2 and 1000 fee/pri buckets");
+ filein >> fileAvg;
+ if (fileAvg.size() != numBuckets)
+ throw std::runtime_error("Corrupt estimates file. Mismatch in fee/pri average bucket count");
+ filein >> fileTxCtAvg;
+ if (fileTxCtAvg.size() != numBuckets)
+ throw std::runtime_error("Corrupt estimates file. Mismatch in tx count bucket count");
+ filein >> fileConfAvg;
+ maxConfirms = fileConfAvg.size();
+ if (maxConfirms <= 0 || maxConfirms > 6 * 24 * 7) // one week
+ throw std::runtime_error("Corrupt estimates file. Must maintain estimates for between 1 and 1008 (one week) confirms");
+ for (unsigned int i = 0; i < maxConfirms; i++) {
+ if (fileConfAvg[i].size() != numBuckets)
+ throw std::runtime_error("Corrupt estimates file. Mismatch in fee/pri conf average bucket count");
+ }
+ // Now that we've processed the entire fee estimate data file and not
+ // thrown any errors, we can copy it to our data structures
+ decay = fileDecay;
+ buckets = fileBuckets;
+ avg = fileAvg;
+ confAvg = fileConfAvg;
+ txCtAvg = fileTxCtAvg;
+ bucketMap.clear();
+
+ // Resize the current block variables which aren't stored in the data file
+ // to match the number of confirms and buckets
+ curBlockConf.resize(maxConfirms);
+ for (unsigned int i = 0; i < maxConfirms; i++) {
+ curBlockConf[i].resize(buckets.size());
+ }
+ curBlockTxCt.resize(buckets.size());
+ curBlockVal.resize(buckets.size());
+
+ unconfTxs.resize(maxConfirms);
+ for (unsigned int i = 0; i < maxConfirms; i++) {
+ unconfTxs[i].resize(buckets.size());
+ }
+ oldUnconfTxs.resize(buckets.size());
+
+ for (unsigned int i = 0; i < buckets.size(); i++)
+ bucketMap[buckets[i]] = i;
+
+ LogPrint("estimatefee", "Reading estimates: %u %s buckets counting confirms up to %u blocks\n",
+ numBuckets, dataTypeString, maxConfirms);
+}
+
+unsigned int TxConfirmStats::NewTx(unsigned int nBlockHeight, double val)
+{
+ unsigned int bucketindex = bucketMap.lower_bound(val)->second;
+ unsigned int blockIndex = nBlockHeight % unconfTxs.size();
+ unconfTxs[blockIndex][bucketindex]++;
+ LogPrint("estimatefee", "adding to %s", dataTypeString);
+ return bucketindex;
+}
+
+void TxConfirmStats::removeTx(unsigned int entryHeight, unsigned int nBestSeenHeight, unsigned int bucketindex)
+{
+ //nBestSeenHeight is not updated yet for the new block
+ int blocksAgo = nBestSeenHeight - entryHeight;
+ if (nBestSeenHeight == 0) // the BlockPolicyEstimator hasn't seen any blocks yet
+ blocksAgo = 0;
+ if (blocksAgo < 0) {
+ LogPrint("estimatefee", "Blockpolicy error, blocks ago is negative for mempool tx\n");
+ return; //This can't happen because we call this with our best seen height, no entries can have higher
+ }
+
+ if (blocksAgo >= (int)unconfTxs.size()) {
+ if (oldUnconfTxs[bucketindex] > 0)
+ oldUnconfTxs[bucketindex]--;
+ else
+ LogPrint("estimatefee", "Blockpolicy error, mempool tx removed from >25 blocks,bucketIndex=%u already\n",
+ bucketindex);
+ }
+ else {
+ unsigned int blockIndex = entryHeight % unconfTxs.size();
+ if (unconfTxs[blockIndex][bucketindex] > 0)
+ unconfTxs[blockIndex][bucketindex]--;
+ else
+ LogPrint("estimatefee", "Blockpolicy error, mempool tx removed from blockIndex=%u,bucketIndex=%u already\n",
+ blockIndex, bucketindex);
+ }
+}
+
+void CBlockPolicyEstimator::removeTx(uint256 hash)
+{
+ std::map<uint256, TxStatsInfo>::iterator pos = mapMemPoolTxs.find(hash);
+ if (pos == mapMemPoolTxs.end()) {
+ LogPrint("estimatefee", "Blockpolicy error mempool tx %s not found for removeTx\n",
+ hash.ToString().c_str());
+ return;
+ }
+ TxConfirmStats *stats = pos->second.stats;
+ unsigned int entryHeight = pos->second.blockHeight;
+ unsigned int bucketIndex = pos->second.bucketIndex;
+
+ if (stats != NULL)
+ stats->removeTx(entryHeight, nBestSeenHeight, bucketIndex);
+ mapMemPoolTxs.erase(hash);
+}
+
+CBlockPolicyEstimator::CBlockPolicyEstimator(const CFeeRate& _minRelayFee)
+ : nBestSeenHeight(0)
+{
+ minTrackedFee = _minRelayFee < CFeeRate(MIN_FEERATE) ? CFeeRate(MIN_FEERATE) : _minRelayFee;
+ std::vector<double> vfeelist;
+ for (double bucketBoundary = minTrackedFee.GetFeePerK(); bucketBoundary <= MAX_FEERATE; bucketBoundary *= FEE_SPACING) {
+ vfeelist.push_back(bucketBoundary);
+ }
+ vfeelist.push_back(INF_FEERATE);
+ feeStats.Initialize(vfeelist, MAX_BLOCK_CONFIRMS, DEFAULT_DECAY, "FeeRate");
+
+ minTrackedPriority = AllowFreeThreshold() < MIN_PRIORITY ? MIN_PRIORITY : AllowFreeThreshold();
+ std::vector<double> vprilist;
+ for (double bucketBoundary = minTrackedPriority; bucketBoundary <= MAX_PRIORITY; bucketBoundary *= PRI_SPACING) {
+ vprilist.push_back(bucketBoundary);
+ }
+ vprilist.push_back(INF_PRIORITY);
+ priStats.Initialize(vprilist, MAX_BLOCK_CONFIRMS, DEFAULT_DECAY, "Priority");
+
+ feeUnlikely = CFeeRate(0);
+ feeLikely = CFeeRate(INF_FEERATE);
+ priUnlikely = 0;
+ priLikely = INF_PRIORITY;
+}
+
+bool CBlockPolicyEstimator::isFeeDataPoint(const CFeeRate &fee, double pri)
+{
+ if ((pri < minTrackedPriority && fee >= minTrackedFee) ||
+ (pri < priUnlikely && fee > feeLikely)) {
+ return true;
+ }
+ return false;
+}
+
+bool CBlockPolicyEstimator::isPriDataPoint(const CFeeRate &fee, double pri)
+{
+ if ((fee < minTrackedFee && pri >= minTrackedPriority) ||
+ (fee < feeUnlikely && pri > priLikely)) {
+ return true;
+ }
+ return false;
+}
+
+void CBlockPolicyEstimator::processTransaction(const CTxMemPoolEntry& entry, bool fCurrentEstimate)
+{
+ unsigned int txHeight = entry.GetHeight();
+ uint256 hash = entry.GetTx().GetHash();
+ if (mapMemPoolTxs[hash].stats != NULL) {
+ LogPrint("estimatefee", "Blockpolicy error mempool tx %s already being tracked\n",
+ hash.ToString().c_str());
+ return;
+ }
+
+ if (txHeight < nBestSeenHeight) {
+ // Ignore side chains and re-orgs; assuming they are random they don't
+ // affect the estimate. We'll potentially double count transactions in 1-block reorgs.
+ return;
+ }
+
+ // Only want to be updating estimates when our blockchain is synced,
+ // otherwise we'll miscalculate how many blocks its taking to get included.
+ if (!fCurrentEstimate)
+ return;
+
+ if (!entry.WasClearAtEntry()) {
+ // This transaction depends on other transactions in the mempool to
+ // be included in a block before it will be able to be included, so
+ // we shouldn't include it in our calculations
+ return;
+ }
+
+ // Fees are stored and reported as BTC-per-kb:
+ CFeeRate feeRate(entry.GetFee(), entry.GetTxSize());
+
+ // Want the priority of the tx at confirmation. However we don't know
+ // what that will be and its too hard to continue updating it
+ // so use starting priority as a proxy
+ double curPri = entry.GetPriority(txHeight);
+ mapMemPoolTxs[hash].blockHeight = txHeight;
+
+ LogPrint("estimatefee", "Blockpolicy mempool tx %s ", hash.ToString().substr(0,10));
+ // Record this as a priority estimate
+ if (entry.GetFee() == 0 || isPriDataPoint(feeRate, curPri)) {
+ mapMemPoolTxs[hash].stats = &priStats;
+ mapMemPoolTxs[hash].bucketIndex = priStats.NewTx(txHeight, curPri);
+ }
+ // Record this as a fee estimate
+ else if (isFeeDataPoint(feeRate, curPri)) {
+ mapMemPoolTxs[hash].stats = &feeStats;
+ mapMemPoolTxs[hash].bucketIndex = feeStats.NewTx(txHeight, (double)feeRate.GetFeePerK());
+ }
+ else {
+ LogPrint("estimatefee", "not adding");
+ }
+ LogPrint("estimatefee", "\n");
+}
+
+void CBlockPolicyEstimator::processBlockTx(unsigned int nBlockHeight, const CTxMemPoolEntry& entry)
+{
+ if (!entry.WasClearAtEntry()) {
+ // This transaction depended on other transactions in the mempool to
+ // be included in a block before it was able to be included, so
+ // we shouldn't include it in our calculations
+ return;
+ }
+
+ // How many blocks did it take for miners to include this transaction?
+ // blocksToConfirm is 1-based, so a transaction included in the earliest
+ // possible block has confirmation count of 1
+ int blocksToConfirm = nBlockHeight - entry.GetHeight();
+ if (blocksToConfirm <= 0) {
+ // This can't happen because we don't process transactions from a block with a height
+ // lower than our greatest seen height
+ LogPrint("estimatefee", "Blockpolicy error Transaction had negative blocksToConfirm\n");
+ return;
+ }
+
+ // Fees are stored and reported as BTC-per-kb:
+ CFeeRate feeRate(entry.GetFee(), entry.GetTxSize());
+
+ // Want the priority of the tx at confirmation. The priority when it
+ // entered the mempool could easily be very small and change quickly
+ double curPri = entry.GetPriority(nBlockHeight);
+
+ // Record this as a priority estimate
+ if (entry.GetFee() == 0 || isPriDataPoint(feeRate, curPri)) {
+ priStats.Record(blocksToConfirm, curPri);
+ }
+ // Record this as a fee estimate
+ else if (isFeeDataPoint(feeRate, curPri)) {
+ feeStats.Record(blocksToConfirm, (double)feeRate.GetFeePerK());
+ }
+}
+
+void CBlockPolicyEstimator::processBlock(unsigned int nBlockHeight,
+ std::vector<CTxMemPoolEntry>& entries, bool fCurrentEstimate)
+{
+ if (nBlockHeight <= nBestSeenHeight) {
+ // Ignore side chains and re-orgs; assuming they are random
+ // they don't affect the estimate.
+ // And if an attacker can re-org the chain at will, then
+ // you've got much bigger problems than "attacker can influence
+ // transaction fees."
+ return;
+ }
+ nBestSeenHeight = nBlockHeight;
+
+ // Only want to be updating estimates when our blockchain is synced,
+ // otherwise we'll miscalculate how many blocks its taking to get included.
+ if (!fCurrentEstimate)
+ return;
+
+ // Update the dynamic cutoffs
+ // a fee/priority is "likely" the reason your tx was included in a block if >85% of such tx's
+ // were confirmed in 2 blocks and is "unlikely" if <50% were confirmed in 10 blocks
+ LogPrint("estimatefee", "Blockpolicy recalculating dynamic cutoffs:\n");
+ priLikely = priStats.EstimateMedianVal(2, SUFFICIENT_PRITXS, MIN_SUCCESS_PCT, true, nBlockHeight);
+ if (priLikely == -1)
+ priLikely = INF_PRIORITY;
+
+ double feeLikelyEst = feeStats.EstimateMedianVal(2, SUFFICIENT_FEETXS, MIN_SUCCESS_PCT, true, nBlockHeight);
+ if (feeLikelyEst == -1)
+ feeLikely = CFeeRate(INF_FEERATE);
+ else
+ feeLikely = CFeeRate(feeLikelyEst);
+
+ priUnlikely = priStats.EstimateMedianVal(10, SUFFICIENT_PRITXS, UNLIKELY_PCT, false, nBlockHeight);
+ if (priUnlikely == -1)
+ priUnlikely = 0;
+
+ double feeUnlikelyEst = feeStats.EstimateMedianVal(10, SUFFICIENT_FEETXS, UNLIKELY_PCT, false, nBlockHeight);
+ if (feeUnlikelyEst == -1)
+ feeUnlikely = CFeeRate(0);
+ else
+ feeUnlikely = CFeeRate(feeUnlikelyEst);
+
+ // Clear the current block states
+ feeStats.ClearCurrent(nBlockHeight);
+ priStats.ClearCurrent(nBlockHeight);
+
+ // Repopulate the current block states
+ for (unsigned int i = 0; i < entries.size(); i++)
+ processBlockTx(nBlockHeight, entries[i]);
+
+ // Update all exponential averages with the current block states
+ feeStats.UpdateMovingAverages();
+ priStats.UpdateMovingAverages();
+
+ LogPrint("estimatefee", "Blockpolicy after updating estimates for %u confirmed entries, new mempool map size %u\n",
+ entries.size(), mapMemPoolTxs.size());
+}
+
+CFeeRate CBlockPolicyEstimator::estimateFee(int confTarget)
+{
+ // Return failure if trying to analyze a target we're not tracking
+ if (confTarget <= 0 || (unsigned int)confTarget > feeStats.GetMaxConfirms())
+ return CFeeRate(0);
+
+ double median = feeStats.EstimateMedianVal(confTarget, SUFFICIENT_FEETXS, MIN_SUCCESS_PCT, true, nBestSeenHeight);
+
+ if (median < 0)
+ return CFeeRate(0);
+
+ return CFeeRate(median);
+}
+
+double CBlockPolicyEstimator::estimatePriority(int confTarget)
+{
+ // Return failure if trying to analyze a target we're not tracking
+ if (confTarget <= 0 || (unsigned int)confTarget > priStats.GetMaxConfirms())
+ return -1;
+
+ return priStats.EstimateMedianVal(confTarget, SUFFICIENT_PRITXS, MIN_SUCCESS_PCT, true, nBestSeenHeight);
+}
+
+void CBlockPolicyEstimator::Write(CAutoFile& fileout)
+{
+ fileout << nBestSeenHeight;
+ feeStats.Write(fileout);
+ priStats.Write(fileout);
+}
+
+void CBlockPolicyEstimator::Read(CAutoFile& filein)
+{
+ int nFileBestSeenHeight;
+ filein >> nFileBestSeenHeight;
+ feeStats.Read(filein);
+ priStats.Read(filein);
+ nBestSeenHeight = nFileBestSeenHeight;
+}
diff --git a/src/policy/fees.h b/src/policy/fees.h
new file mode 100644
index 0000000000..15577d128a
--- /dev/null
+++ b/src/policy/fees.h
@@ -0,0 +1,276 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2015 The Bitcoin developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#ifndef BITCOIN_POLICYESTIMATOR_H
+#define BITCOIN_POLICYESTIMATOR_H
+
+#include "amount.h"
+#include "uint256.h"
+
+#include <map>
+#include <string>
+#include <vector>
+
+class CAutoFile;
+class CFeeRate;
+class CTxMemPoolEntry;
+
+/** \class CBlockPolicyEstimator
+ * The BlockPolicyEstimator is used for estimating the fee or priority needed
+ * for a transaction to be included in a block within a certain number of
+ * blocks.
+ *
+ * At a high level the algorithm works by grouping transactions into buckets
+ * based on having similar priorities or fees and then tracking how long it
+ * takes transactions in the various buckets to be mined. It operates under
+ * the assumption that in general transactions of higher fee/priority will be
+ * included in blocks before transactions of lower fee/priority. So for
+ * example if you wanted to know what fee you should put on a transaction to
+ * be included in a block within the next 5 blocks, you would start by looking
+ * at the bucket with with the highest fee transactions and verifying that a
+ * sufficiently high percentage of them were confirmed within 5 blocks and
+ * then you would look at the next highest fee bucket, and so on, stopping at
+ * the last bucket to pass the test. The average fee of transactions in this
+ * bucket will give you an indication of the lowest fee you can put on a
+ * transaction and still have a sufficiently high chance of being confirmed
+ * within your desired 5 blocks.
+ *
+ * When a transaction enters the mempool or is included within a block we
+ * decide whether it can be used as a data point for fee estimation, priority
+ * estimation or neither. If the value of exactly one of those properties was
+ * below the required minimum it can be used to estimate the other. In
+ * addition, if a priori our estimation code would indicate that the
+ * transaction would be much more quickly included in a block because of one
+ * of the properties compared to the other, we can also decide to use it as
+ * an estimate for that property.
+ *
+ * Here is a brief description of the implementation for fee estimation.
+ * When a transaction that counts for fee estimation enters the mempool, we
+ * track the height of the block chain at entry. Whenever a block comes in,
+ * we count the number of transactions in each bucket and the total amount of fee
+ * paid in each bucket. Then we calculate how many blocks Y it took each
+ * transaction to be mined and we track an array of counters in each bucket
+ * for how long it to took transactions to get confirmed from 1 to a max of 25
+ * and we increment all the counters from Y up to 25. This is because for any
+ * number Z>=Y the transaction was successfully mined within Z blocks. We
+ * want to save a history of this information, so at any time we have a
+ * counter of the total number of transactions that happened in a given fee
+ * bucket and the total number that were confirmed in each number 1-25 blocks
+ * or less for any bucket. We save this history by keeping an exponentially
+ * decaying moving average of each one of these stats. Furthermore we also
+ * keep track of the number unmined (in mempool) transactions in each bucket
+ * and for how many blocks they have been outstanding and use that to increase
+ * the number of transactions we've seen in that fee bucket when calculating
+ * an estimate for any number of confirmations below the number of blocks
+ * they've been outstanding.
+ */
+
+/**
+ * We will instantiate two instances of this class, one to track transactions
+ * that were included in a block due to fee, and one for tx's included due to
+ * priority. We will lump transactions into a bucket according to their approximate
+ * fee or priority and then track how long it took for those txs to be included in a block
+ *
+ * The tracking of unconfirmed (mempool) transactions is completely independent of the
+ * historical tracking of transactions that have been confirmed in a block.
+ */
+class TxConfirmStats
+{
+private:
+ //Define the buckets we will group transactions into (both fee buckets and priority buckets)
+ std::vector<double> buckets; // The upper-bound of the range for the bucket (inclusive)
+ std::map<double, unsigned int> bucketMap; // Map of bucket upper-bound to index into all vectors by bucket
+
+ // For each bucket X:
+ // Count the total # of txs in each bucket
+ // Track the historical moving average of this total over blocks
+ std::vector<double> txCtAvg;
+ // and calcuate the total for the current block to update the moving average
+ std::vector<int> curBlockTxCt;
+
+ // Count the total # of txs confirmed within Y blocks in each bucket
+ // Track the historical moving average of theses totals over blocks
+ std::vector<std::vector<double> > confAvg; // confAvg[Y][X]
+ // and calcuate the totals for the current block to update the moving averages
+ std::vector<std::vector<int> > curBlockConf; // curBlockConf[Y][X]
+
+ // Sum the total priority/fee of all tx's in each bucket
+ // Track the historical moving average of this total over blocks
+ std::vector<double> avg;
+ // and calculate the total for the current block to update the moving average
+ std::vector<double> curBlockVal;
+
+ // Combine the conf counts with tx counts to calculate the confirmation % for each Y,X
+ // Combine the total value with the tx counts to calculate the avg fee/priority per bucket
+
+ std::string dataTypeString;
+ double decay;
+
+ // Mempool counts of outstanding transactions
+ // For each bucket X, track the number of transactions in the mempool
+ // that are unconfirmed for each possible confirmation value Y
+ std::vector<std::vector<int> > unconfTxs; //unconfTxs[Y][X]
+ // transactions still unconfirmed after MAX_CONFIRMS for each bucket
+ std::vector<int> oldUnconfTxs;
+
+public:
+ /**
+ * Initialize the data structures. This is called by BlockPolicyEstimator's
+ * constructor with default values.
+ * @param defaultBuckets contains the upper limits for the bucket boundaries
+ * @param maxConfirms max number of confirms to track
+ * @param decay how much to decay the historical moving average per block
+ * @param dataTypeString for logging purposes
+ */
+ void Initialize(std::vector<double>& defaultBuckets, unsigned int maxConfirms, double decay, std::string dataTypeString);
+
+ /** Clear the state of the curBlock variables to start counting for the new block */
+ void ClearCurrent(unsigned int nBlockHeight);
+
+ /**
+ * Record a new transaction data point in the current block stats
+ * @param blocksToConfirm the number of blocks it took this transaction to confirm
+ * @param val either the fee or the priority when entered of the transaction
+ * @warning blocksToConfirm is 1-based and has to be >= 1
+ */
+ void Record(int blocksToConfirm, double val);
+
+ /** Record a new transaction entering the mempool*/
+ unsigned int NewTx(unsigned int nBlockHeight, double val);
+
+ /** Remove a transaction from mempool tracking stats*/
+ void removeTx(unsigned int entryHeight, unsigned int nBestSeenHeight,
+ unsigned int bucketIndex);
+
+ /** Update our estimates by decaying our historical moving average and updating
+ with the data gathered from the current block */
+ void UpdateMovingAverages();
+
+ /**
+ * Calculate a fee or priority estimate. Find the lowest value bucket (or range of buckets
+ * to make sure we have enough data points) whose transactions still have sufficient likelihood
+ * of being confirmed within the target number of confirmations
+ * @param confTarget target number of confirmations
+ * @param sufficientTxVal required average number of transactions per block in a bucket range
+ * @param minSuccess the success probability we require
+ * @param requireGreater return the lowest fee/pri such that all higher values pass minSuccess OR
+ * return the highest fee/pri such that all lower values fail minSuccess
+ * @param nBlockHeight the current block height
+ */
+ double EstimateMedianVal(int confTarget, double sufficientTxVal,
+ double minSuccess, bool requireGreater, unsigned int nBlockHeight);
+
+ /** Return the max number of confirms we're tracking */
+ unsigned int GetMaxConfirms() { return confAvg.size(); }
+
+ /** Write state of estimation data to a file*/
+ void Write(CAutoFile& fileout);
+
+ /**
+ * Read saved state of estimation data from a file and replace all internal data structures and
+ * variables with this state.
+ */
+ void Read(CAutoFile& filein);
+};
+
+
+
+/** Track confirm delays up to 25 blocks, can't estimate beyond that */
+static const unsigned int MAX_BLOCK_CONFIRMS = 25;
+
+/** Decay of .998 is a half-life of 346 blocks or about 2.4 days */
+static const double DEFAULT_DECAY = .998;
+
+/** Require greater than 85% of X fee transactions to be confirmed within Y blocks for X to be big enough */
+static const double MIN_SUCCESS_PCT = .85;
+static const double UNLIKELY_PCT = .5;
+
+/** Require an avg of 1 tx in the combined fee bucket per block to have stat significance */
+static const double SUFFICIENT_FEETXS = 1;
+
+/** Require only an avg of 1 tx every 5 blocks in the combined pri bucket (way less pri txs) */
+static const double SUFFICIENT_PRITXS = .2;
+
+// Minimum and Maximum values for tracking fees and priorities
+static const double MIN_FEERATE = 10;
+static const double MAX_FEERATE = 1e7;
+static const double INF_FEERATE = MAX_MONEY;
+static const double MIN_PRIORITY = 10;
+static const double MAX_PRIORITY = 1e16;
+static const double INF_PRIORITY = 1e9 * MAX_MONEY;
+
+// We have to lump transactions into buckets based on fee or priority, but we want to be able
+// to give accurate estimates over a large range of potential fees and priorities
+// Therefore it makes sense to exponentially space the buckets
+/** Spacing of FeeRate buckets */
+static const double FEE_SPACING = 1.1;
+
+/** Spacing of Priority buckets */
+static const double PRI_SPACING = 2;
+
+/**
+ * We want to be able to estimate fees or priorities that are needed on tx's to be included in
+ * a certain number of blocks. Every time a block is added to the best chain, this class records
+ * stats on the transactions included in that block
+ */
+class CBlockPolicyEstimator
+{
+public:
+ /** Create new BlockPolicyEstimator and initialize stats tracking classes with default values */
+ CBlockPolicyEstimator(const CFeeRate& minRelayFee);
+
+ /** Process all the transactions that have been included in a block */
+ void processBlock(unsigned int nBlockHeight,
+ std::vector<CTxMemPoolEntry>& entries, bool fCurrentEstimate);
+
+ /** Process a transaction confirmed in a block*/
+ void processBlockTx(unsigned int nBlockHeight, const CTxMemPoolEntry& entry);
+
+ /** Process a transaction accepted to the mempool*/
+ void processTransaction(const CTxMemPoolEntry& entry, bool fCurrentEstimate);
+
+ /** Remove a transaction from the mempool tracking stats*/
+ void removeTx(uint256 hash);
+
+ /** Is this transaction likely included in a block because of its fee?*/
+ bool isFeeDataPoint(const CFeeRate &fee, double pri);
+
+ /** Is this transaction likely included in a block because of its priority?*/
+ bool isPriDataPoint(const CFeeRate &fee, double pri);
+
+ /** Return a fee estimate */
+ CFeeRate estimateFee(int confTarget);
+
+ /** Return a priority estimate */
+ double estimatePriority(int confTarget);
+
+ /** Write estimation data to a file */
+ void Write(CAutoFile& fileout);
+
+ /** Read estimation data from a file */
+ void Read(CAutoFile& filein);
+
+private:
+ CFeeRate minTrackedFee; //! Passed to constructor to avoid dependency on main
+ double minTrackedPriority; //! Set to AllowFreeThreshold
+ unsigned int nBestSeenHeight;
+ struct TxStatsInfo
+ {
+ TxConfirmStats *stats;
+ unsigned int blockHeight;
+ unsigned int bucketIndex;
+ TxStatsInfo() : stats(NULL), blockHeight(0), bucketIndex(0) {}
+ };
+
+ // map of txids to information about that transaction
+ std::map<uint256, TxStatsInfo> mapMemPoolTxs;
+
+ /** Classes to track historical data on transaction confirmations */
+ TxConfirmStats feeStats, priStats;
+
+ /** Breakpoints to help determine whether a transaction was confirmed by priority or Fee */
+ CFeeRate feeLikely, feeUnlikely;
+ double priLikely, priUnlikely;
+};
+#endif /*BITCOIN_POLICYESTIMATOR_H */
diff --git a/src/pow.cpp b/src/pow.cpp
new file mode 100644
index 0000000000..bb53ad204b
--- /dev/null
+++ b/src/pow.cpp
@@ -0,0 +1,133 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "pow.h"
+
+#include "arith_uint256.h"
+#include "chain.h"
+#include "primitives/block.h"
+#include "uint256.h"
+#include "util.h"
+
+unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params)
+{
+ unsigned int nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact();
+
+ // Genesis block
+ if (pindexLast == NULL)
+ return nProofOfWorkLimit;
+
+ // Only change once per difficulty adjustment interval
+ if ((pindexLast->nHeight+1) % params.DifficultyAdjustmentInterval() != 0)
+ {
+ if (params.fPowAllowMinDifficultyBlocks)
+ {
+ // Special difficulty rule for testnet:
+ // If the new block's timestamp is more than 2* 10 minutes
+ // then allow mining of a min-difficulty block.
+ if (pblock->GetBlockTime() > pindexLast->GetBlockTime() + params.nPowTargetSpacing*2)
+ return nProofOfWorkLimit;
+ else
+ {
+ // Return the last non-special-min-difficulty-rules-block
+ const CBlockIndex* pindex = pindexLast;
+ while (pindex->pprev && pindex->nHeight % params.DifficultyAdjustmentInterval() != 0 && pindex->nBits == nProofOfWorkLimit)
+ pindex = pindex->pprev;
+ return pindex->nBits;
+ }
+ }
+ return pindexLast->nBits;
+ }
+
+ // Go back by what we want to be 14 days worth of blocks
+ int nHeightFirst = pindexLast->nHeight - (params.DifficultyAdjustmentInterval()-1);
+ assert(nHeightFirst >= 0);
+ const CBlockIndex* pindexFirst = pindexLast->GetAncestor(nHeightFirst);
+ assert(pindexFirst);
+
+ return CalculateNextWorkRequired(pindexLast, pindexFirst->GetBlockTime(), params);
+}
+
+unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params& params)
+{
+ // Limit adjustment step
+ int64_t nActualTimespan = pindexLast->GetBlockTime() - nFirstBlockTime;
+ LogPrintf(" nActualTimespan = %d before bounds\n", nActualTimespan);
+ if (nActualTimespan < params.nPowTargetTimespan/4)
+ nActualTimespan = params.nPowTargetTimespan/4;
+ if (nActualTimespan > params.nPowTargetTimespan*4)
+ nActualTimespan = params.nPowTargetTimespan*4;
+
+ // Retarget
+ const arith_uint256 bnPowLimit = UintToArith256(params.powLimit);
+ arith_uint256 bnNew;
+ arith_uint256 bnOld;
+ bnNew.SetCompact(pindexLast->nBits);
+ bnOld = bnNew;
+ bnNew *= nActualTimespan;
+ bnNew /= params.nPowTargetTimespan;
+
+ if (bnNew > bnPowLimit)
+ bnNew = bnPowLimit;
+
+ /// debug print
+ LogPrintf("GetNextWorkRequired RETARGET\n");
+ LogPrintf("params.nPowTargetTimespan = %d nActualTimespan = %d\n", params.nPowTargetTimespan, nActualTimespan);
+ LogPrintf("Before: %08x %s\n", pindexLast->nBits, bnOld.ToString());
+ LogPrintf("After: %08x %s\n", bnNew.GetCompact(), bnNew.ToString());
+
+ return bnNew.GetCompact();
+}
+
+bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params& params)
+{
+ bool fNegative;
+ bool fOverflow;
+ arith_uint256 bnTarget;
+
+ bnTarget.SetCompact(nBits, &fNegative, &fOverflow);
+
+ // Check range
+ if (fNegative || bnTarget == 0 || fOverflow || bnTarget > UintToArith256(params.powLimit))
+ return error("CheckProofOfWork(): nBits below minimum work");
+
+ // Check proof of work matches claimed amount
+ if (UintToArith256(hash) > bnTarget)
+ return error("CheckProofOfWork(): hash doesn't match nBits");
+
+ return true;
+}
+
+arith_uint256 GetBlockProof(const CBlockIndex& block)
+{
+ arith_uint256 bnTarget;
+ bool fNegative;
+ bool fOverflow;
+ bnTarget.SetCompact(block.nBits, &fNegative, &fOverflow);
+ if (fNegative || fOverflow || bnTarget == 0)
+ return 0;
+ // We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256
+ // as it's too large for a arith_uint256. However, as 2**256 is at least as large
+ // as bnTarget+1, it is equal to ((2**256 - bnTarget - 1) / (bnTarget+1)) + 1,
+ // or ~bnTarget / (nTarget+1) + 1.
+ return (~bnTarget / (bnTarget + 1)) + 1;
+}
+
+int64_t GetBlockProofEquivalentTime(const CBlockIndex& to, const CBlockIndex& from, const CBlockIndex& tip, const Consensus::Params& params)
+{
+ arith_uint256 r;
+ int sign = 1;
+ if (to.nChainWork > from.nChainWork) {
+ r = to.nChainWork - from.nChainWork;
+ } else {
+ r = from.nChainWork - to.nChainWork;
+ sign = -1;
+ }
+ r = r * arith_uint256(params.nPowTargetSpacing) / GetBlockProof(tip);
+ if (r.bits() > 63) {
+ return sign * std::numeric_limits<int64_t>::max();
+ }
+ return sign * r.GetLow64();
+}
diff --git a/src/pow.h b/src/pow.h
new file mode 100644
index 0000000000..e864a474cc
--- /dev/null
+++ b/src/pow.h
@@ -0,0 +1,28 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_POW_H
+#define BITCOIN_POW_H
+
+#include "consensus/params.h"
+
+#include <stdint.h>
+
+class CBlockHeader;
+class CBlockIndex;
+class uint256;
+class arith_uint256;
+
+unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params&);
+unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params&);
+
+/** Check whether a block hash satisfies the proof-of-work requirement specified by nBits */
+bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params&);
+arith_uint256 GetBlockProof(const CBlockIndex& block);
+
+/** Return the time it would take to redo the work difference between from and to, assuming the current hashrate corresponds to the difficulty at tip, in seconds. */
+int64_t GetBlockProofEquivalentTime(const CBlockIndex& to, const CBlockIndex& from, const CBlockIndex& tip, const Consensus::Params&);
+
+#endif // BITCOIN_POW_H
diff --git a/src/primitives/block.cpp b/src/primitives/block.cpp
new file mode 100644
index 0000000000..5b9c13d870
--- /dev/null
+++ b/src/primitives/block.cpp
@@ -0,0 +1,131 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "primitives/block.h"
+
+#include "hash.h"
+#include "tinyformat.h"
+#include "utilstrencodings.h"
+#include "crypto/common.h"
+
+uint256 CBlockHeader::GetHash() const
+{
+ return SerializeHash(*this);
+}
+
+uint256 CBlock::BuildMerkleTree(bool* fMutated) const
+{
+ /* WARNING! If you're reading this because you're learning about crypto
+ and/or designing a new system that will use merkle trees, keep in mind
+ that the following merkle tree algorithm has a serious flaw related to
+ duplicate txids, resulting in a vulnerability (CVE-2012-2459).
+
+ The reason is that if the number of hashes in the list at a given time
+ is odd, the last one is duplicated before computing the next level (which
+ is unusual in Merkle trees). This results in certain sequences of
+ transactions leading to the same merkle root. For example, these two
+ trees:
+
+ A A
+ / \ / \
+ B C B C
+ / \ | / \ / \
+ D E F D E F F
+ / \ / \ / \ / \ / \ / \ / \
+ 1 2 3 4 5 6 1 2 3 4 5 6 5 6
+
+ for transaction lists [1,2,3,4,5,6] and [1,2,3,4,5,6,5,6] (where 5 and
+ 6 are repeated) result in the same root hash A (because the hash of both
+ of (F) and (F,F) is C).
+
+ The vulnerability results from being able to send a block with such a
+ transaction list, with the same merkle root, and the same block hash as
+ the original without duplication, resulting in failed validation. If the
+ receiving node proceeds to mark that block as permanently invalid
+ however, it will fail to accept further unmodified (and thus potentially
+ valid) versions of the same block. We defend against this by detecting
+ the case where we would hash two identical hashes at the end of the list
+ together, and treating that identically to the block having an invalid
+ merkle root. Assuming no double-SHA256 collisions, this will detect all
+ known ways of changing the transactions without affecting the merkle
+ root.
+ */
+ vMerkleTree.clear();
+ vMerkleTree.reserve(vtx.size() * 2 + 16); // Safe upper bound for the number of total nodes.
+ for (std::vector<CTransaction>::const_iterator it(vtx.begin()); it != vtx.end(); ++it)
+ vMerkleTree.push_back(it->GetHash());
+ int j = 0;
+ bool mutated = false;
+ 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);
+ if (i2 == i + 1 && i2 + 1 == nSize && vMerkleTree[j+i] == vMerkleTree[j+i2]) {
+ // Two identical hashes at the end of the list at a particular level.
+ mutated = true;
+ }
+ vMerkleTree.push_back(Hash(BEGIN(vMerkleTree[j+i]), END(vMerkleTree[j+i]),
+ BEGIN(vMerkleTree[j+i2]), END(vMerkleTree[j+i2])));
+ }
+ j += nSize;
+ }
+ if (fMutated) {
+ *fMutated = mutated;
+ }
+ return (vMerkleTree.empty() ? uint256() : vMerkleTree.back());
+}
+
+std::vector<uint256> CBlock::GetMerkleBranch(int nIndex) const
+{
+ if (vMerkleTree.empty())
+ BuildMerkleTree();
+ std::vector<uint256> 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;
+}
+
+uint256 CBlock::CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex)
+{
+ if (nIndex == -1)
+ return uint256();
+ for (std::vector<uint256>::const_iterator it(vMerkleBranch.begin()); it != vMerkleBranch.end(); ++it)
+ {
+ if (nIndex & 1)
+ hash = Hash(BEGIN(*it), END(*it), BEGIN(hash), END(hash));
+ else
+ hash = Hash(BEGIN(hash), END(hash), BEGIN(*it), END(*it));
+ nIndex >>= 1;
+ }
+ return hash;
+}
+
+std::string CBlock::ToString() const
+{
+ std::stringstream s;
+ s << strprintf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%u)\n",
+ GetHash().ToString(),
+ nVersion,
+ hashPrevBlock.ToString(),
+ hashMerkleRoot.ToString(),
+ nTime, nBits, nNonce,
+ vtx.size());
+ for (unsigned int i = 0; i < vtx.size(); i++)
+ {
+ s << " " << vtx[i].ToString() << "\n";
+ }
+ s << " vMerkleTree: ";
+ for (unsigned int i = 0; i < vMerkleTree.size(); i++)
+ s << " " << vMerkleTree[i].ToString();
+ s << "\n";
+ return s.str();
+}
diff --git a/src/primitives/block.h b/src/primitives/block.h
new file mode 100644
index 0000000000..90b8904ab8
--- /dev/null
+++ b/src/primitives/block.h
@@ -0,0 +1,168 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_PRIMITIVES_BLOCK_H
+#define BITCOIN_PRIMITIVES_BLOCK_H
+
+#include "primitives/transaction.h"
+#include "serialize.h"
+#include "uint256.h"
+
+/** 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.
+ */
+class CBlockHeader
+{
+public:
+ // header
+ static const int32_t CURRENT_VERSION=4;
+ int32_t nVersion;
+ uint256 hashPrevBlock;
+ uint256 hashMerkleRoot;
+ uint32_t nTime;
+ uint32_t nBits;
+ uint32_t nNonce;
+
+ CBlockHeader()
+ {
+ SetNull();
+ }
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ READWRITE(this->nVersion);
+ nVersion = this->nVersion;
+ READWRITE(hashPrevBlock);
+ READWRITE(hashMerkleRoot);
+ READWRITE(nTime);
+ READWRITE(nBits);
+ READWRITE(nNonce);
+ }
+
+ void SetNull()
+ {
+ nVersion = CBlockHeader::CURRENT_VERSION;
+ hashPrevBlock.SetNull();
+ hashMerkleRoot.SetNull();
+ nTime = 0;
+ nBits = 0;
+ nNonce = 0;
+ }
+
+ bool IsNull() const
+ {
+ return (nBits == 0);
+ }
+
+ uint256 GetHash() const;
+
+ int64_t GetBlockTime() const
+ {
+ return (int64_t)nTime;
+ }
+};
+
+
+class CBlock : public CBlockHeader
+{
+public:
+ // network and disk
+ std::vector<CTransaction> vtx;
+
+ // memory only
+ mutable std::vector<uint256> vMerkleTree;
+
+ CBlock()
+ {
+ SetNull();
+ }
+
+ CBlock(const CBlockHeader &header)
+ {
+ SetNull();
+ *((CBlockHeader*)this) = header;
+ }
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ READWRITE(*(CBlockHeader*)this);
+ READWRITE(vtx);
+ }
+
+ void SetNull()
+ {
+ CBlockHeader::SetNull();
+ vtx.clear();
+ vMerkleTree.clear();
+ }
+
+ CBlockHeader GetBlockHeader() const
+ {
+ CBlockHeader block;
+ block.nVersion = nVersion;
+ block.hashPrevBlock = hashPrevBlock;
+ block.hashMerkleRoot = hashMerkleRoot;
+ block.nTime = nTime;
+ block.nBits = nBits;
+ block.nNonce = nNonce;
+ return block;
+ }
+
+ // Build the in-memory merkle tree for this block and return the merkle root.
+ // If non-NULL, *mutated is set to whether mutation was detected in the merkle
+ // tree (a duplication of transactions in the block leading to an identical
+ // merkle root).
+ uint256 BuildMerkleTree(bool* mutated = NULL) const;
+
+ std::vector<uint256> GetMerkleBranch(int nIndex) const;
+ static uint256 CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex);
+ std::string ToString() const;
+};
+
+
+/** 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.
+ */
+struct CBlockLocator
+{
+ std::vector<uint256> vHave;
+
+ CBlockLocator() {}
+
+ CBlockLocator(const std::vector<uint256>& vHaveIn)
+ {
+ vHave = vHaveIn;
+ }
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ if (!(nType & SER_GETHASH))
+ READWRITE(nVersion);
+ READWRITE(vHave);
+ }
+
+ void SetNull()
+ {
+ vHave.clear();
+ }
+
+ bool IsNull() const
+ {
+ return vHave.empty();
+ }
+};
+
+#endif // BITCOIN_PRIMITIVES_BLOCK_H
diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp
new file mode 100644
index 0000000000..606dbea798
--- /dev/null
+++ b/src/primitives/transaction.cpp
@@ -0,0 +1,142 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "primitives/transaction.h"
+
+#include "hash.h"
+#include "tinyformat.h"
+#include "utilstrencodings.h"
+
+std::string COutPoint::ToString() const
+{
+ return strprintf("COutPoint(%s, %u)", hash.ToString().substr(0,10), n);
+}
+
+CTxIn::CTxIn(COutPoint prevoutIn, CScript scriptSigIn, uint32_t nSequenceIn)
+{
+ prevout = prevoutIn;
+ scriptSig = scriptSigIn;
+ nSequence = nSequenceIn;
+}
+
+CTxIn::CTxIn(uint256 hashPrevTx, uint32_t nOut, CScript scriptSigIn, uint32_t nSequenceIn)
+{
+ prevout = COutPoint(hashPrevTx, nOut);
+ scriptSig = scriptSigIn;
+ nSequence = nSequenceIn;
+}
+
+std::string CTxIn::ToString() const
+{
+ std::string str;
+ str += "CTxIn(";
+ str += prevout.ToString();
+ if (prevout.IsNull())
+ str += strprintf(", coinbase %s", HexStr(scriptSig));
+ else
+ str += strprintf(", scriptSig=%s", scriptSig.ToString().substr(0,24));
+ if (nSequence != std::numeric_limits<unsigned int>::max())
+ str += strprintf(", nSequence=%u", nSequence);
+ str += ")";
+ return str;
+}
+
+CTxOut::CTxOut(const CAmount& nValueIn, CScript scriptPubKeyIn)
+{
+ nValue = nValueIn;
+ scriptPubKey = scriptPubKeyIn;
+}
+
+uint256 CTxOut::GetHash() const
+{
+ return SerializeHash(*this);
+}
+
+std::string CTxOut::ToString() const
+{
+ return strprintf("CTxOut(nValue=%d.%08d, scriptPubKey=%s)", nValue / COIN, nValue % COIN, scriptPubKey.ToString().substr(0,30));
+}
+
+CMutableTransaction::CMutableTransaction() : nVersion(CTransaction::CURRENT_VERSION), nLockTime(0) {}
+CMutableTransaction::CMutableTransaction(const CTransaction& tx) : nVersion(tx.nVersion), vin(tx.vin), vout(tx.vout), nLockTime(tx.nLockTime) {}
+
+uint256 CMutableTransaction::GetHash() const
+{
+ return SerializeHash(*this);
+}
+
+void CTransaction::UpdateHash() const
+{
+ *const_cast<uint256*>(&hash) = SerializeHash(*this);
+}
+
+CTransaction::CTransaction() : nVersion(CTransaction::CURRENT_VERSION), vin(), vout(), nLockTime(0) { }
+
+CTransaction::CTransaction(const CMutableTransaction &tx) : nVersion(tx.nVersion), vin(tx.vin), vout(tx.vout), nLockTime(tx.nLockTime) {
+ UpdateHash();
+}
+
+CTransaction& CTransaction::operator=(const CTransaction &tx) {
+ *const_cast<int*>(&nVersion) = tx.nVersion;
+ *const_cast<std::vector<CTxIn>*>(&vin) = tx.vin;
+ *const_cast<std::vector<CTxOut>*>(&vout) = tx.vout;
+ *const_cast<unsigned int*>(&nLockTime) = tx.nLockTime;
+ *const_cast<uint256*>(&hash) = tx.hash;
+ return *this;
+}
+
+CAmount CTransaction::GetValueOut() const
+{
+ CAmount nValueOut = 0;
+ for (std::vector<CTxOut>::const_iterator it(vout.begin()); it != vout.end(); ++it)
+ {
+ nValueOut += it->nValue;
+ if (!MoneyRange(it->nValue) || !MoneyRange(nValueOut))
+ throw std::runtime_error("CTransaction::GetValueOut(): value out of range");
+ }
+ return nValueOut;
+}
+
+double CTransaction::ComputePriority(double dPriorityInputs, unsigned int nTxSize) const
+{
+ nTxSize = CalculateModifiedSize(nTxSize);
+ if (nTxSize == 0) return 0.0;
+
+ return dPriorityInputs / nTxSize;
+}
+
+unsigned int CTransaction::CalculateModifiedSize(unsigned int nTxSize) const
+{
+ // In order to avoid disincentivizing cleaning up the UTXO set we don't count
+ // the constant overhead for each txin and up to 110 bytes of scriptSig (which
+ // is enough to cover a compressed pubkey p2sh redemption) for priority.
+ // Providing any more cleanup incentive than making additional inputs free would
+ // risk encouraging people to create junk outputs to redeem later.
+ if (nTxSize == 0)
+ nTxSize = ::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION);
+ for (std::vector<CTxIn>::const_iterator it(vin.begin()); it != vin.end(); ++it)
+ {
+ unsigned int offset = 41U + std::min(110U, (unsigned int)it->scriptSig.size());
+ if (nTxSize > offset)
+ nTxSize -= offset;
+ }
+ return nTxSize;
+}
+
+std::string CTransaction::ToString() const
+{
+ std::string str;
+ str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%u, vout.size=%u, nLockTime=%u)\n",
+ GetHash().ToString().substr(0,10),
+ 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;
+}
diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h
new file mode 100644
index 0000000000..6cfd93a9a1
--- /dev/null
+++ b/src/primitives/transaction.h
@@ -0,0 +1,282 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_PRIMITIVES_TRANSACTION_H
+#define BITCOIN_PRIMITIVES_TRANSACTION_H
+
+#include "amount.h"
+#include "script/script.h"
+#include "serialize.h"
+#include "uint256.h"
+
+/** An outpoint - a combination of a transaction hash and an index n into its vout */
+class COutPoint
+{
+public:
+ uint256 hash;
+ uint32_t n;
+
+ COutPoint() { SetNull(); }
+ COutPoint(uint256 hashIn, uint32_t nIn) { hash = hashIn; n = nIn; }
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ READWRITE(hash);
+ READWRITE(n);
+ }
+
+ void SetNull() { hash.SetNull(); n = (uint32_t) -1; }
+ bool IsNull() const { return (hash.IsNull() && n == (uint32_t) -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;
+};
+
+/** 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;
+ uint32_t nSequence;
+
+ CTxIn()
+ {
+ nSequence = std::numeric_limits<unsigned int>::max();
+ }
+
+ explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), uint32_t nSequenceIn=std::numeric_limits<unsigned int>::max());
+ CTxIn(uint256 hashPrevTx, uint32_t nOut, CScript scriptSigIn=CScript(), uint32_t nSequenceIn=std::numeric_limits<uint32_t>::max());
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ READWRITE(prevout);
+ READWRITE(scriptSig);
+ READWRITE(nSequence);
+ }
+
+ bool IsFinal() const
+ {
+ return (nSequence == std::numeric_limits<uint32_t>::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;
+};
+
+/** 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:
+ CAmount nValue;
+ CScript scriptPubKey;
+
+ CTxOut()
+ {
+ SetNull();
+ }
+
+ CTxOut(const CAmount& nValueIn, CScript scriptPubKeyIn);
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ READWRITE(nValue);
+ READWRITE(scriptPubKey);
+ }
+
+ void SetNull()
+ {
+ nValue = -1;
+ scriptPubKey.clear();
+ }
+
+ bool IsNull() const
+ {
+ return (nValue == -1);
+ }
+
+ uint256 GetHash() const;
+
+ CAmount GetDustThreshold(const CFeeRate &minRelayTxFee) const
+ {
+ // "Dust" is defined in terms of CTransaction::minRelayTxFee,
+ // which has units satoshis-per-kilobyte.
+ // If you'd pay more than 1/3 in fees
+ // to spend something, then we consider it dust.
+ // A typical txout is 34 bytes big, and will
+ // need a CTxIn of at least 148 bytes to spend:
+ // so dust is a txout less than 546 satoshis
+ // with default minRelayTxFee.
+ size_t nSize = GetSerializeSize(SER_DISK,0)+148u;
+ return 3*minRelayTxFee.GetFee(nSize);
+ }
+
+ bool IsDust(const CFeeRate &minRelayTxFee) const
+ {
+ return (nValue < GetDustThreshold(minRelayTxFee));
+ }
+
+ 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;
+};
+
+struct CMutableTransaction;
+
+/** The basic transaction that is broadcasted on the network and contained in
+ * blocks. A transaction can contain multiple inputs and outputs.
+ */
+class CTransaction
+{
+private:
+ /** Memory only. */
+ const uint256 hash;
+ void UpdateHash() const;
+
+public:
+ static const int32_t CURRENT_VERSION=1;
+
+ // The local variables are made const to prevent unintended modification
+ // without updating the cached hash value. However, CTransaction is not
+ // actually immutable; deserialization and assignment are implemented,
+ // and bypass the constness. This is safe, as they update the entire
+ // structure, including the hash.
+ const int32_t nVersion;
+ const std::vector<CTxIn> vin;
+ const std::vector<CTxOut> vout;
+ const uint32_t nLockTime;
+
+ /** Construct a CTransaction that qualifies as IsNull() */
+ CTransaction();
+
+ /** Convert a CMutableTransaction into a CTransaction. */
+ CTransaction(const CMutableTransaction &tx);
+
+ CTransaction& operator=(const CTransaction& tx);
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ READWRITE(*const_cast<int32_t*>(&this->nVersion));
+ nVersion = this->nVersion;
+ READWRITE(*const_cast<std::vector<CTxIn>*>(&vin));
+ READWRITE(*const_cast<std::vector<CTxOut>*>(&vout));
+ READWRITE(*const_cast<uint32_t*>(&nLockTime));
+ if (ser_action.ForRead())
+ UpdateHash();
+ }
+
+ bool IsNull() const {
+ return vin.empty() && vout.empty();
+ }
+
+ const uint256& GetHash() const {
+ return hash;
+ }
+
+ // Return sum of txouts.
+ CAmount GetValueOut() const;
+ // GetValueIn() is a method on CCoinsViewCache, because
+ // inputs must be known to compute value in.
+
+ // Compute priority, given priority of inputs and (optionally) tx size
+ double ComputePriority(double dPriorityInputs, unsigned int nTxSize=0) const;
+
+ // Compute modified tx size for priority calculation (optionally given tx size)
+ unsigned int CalculateModifiedSize(unsigned int nTxSize=0) const;
+
+ bool IsCoinBase() const
+ {
+ return (vin.size() == 1 && vin[0].prevout.IsNull());
+ }
+
+ friend bool operator==(const CTransaction& a, const CTransaction& b)
+ {
+ return a.hash == b.hash;
+ }
+
+ friend bool operator!=(const CTransaction& a, const CTransaction& b)
+ {
+ return a.hash != b.hash;
+ }
+
+ std::string ToString() const;
+};
+
+/** A mutable version of CTransaction. */
+struct CMutableTransaction
+{
+ int32_t nVersion;
+ std::vector<CTxIn> vin;
+ std::vector<CTxOut> vout;
+ uint32_t nLockTime;
+
+ CMutableTransaction();
+ CMutableTransaction(const CTransaction& tx);
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ READWRITE(this->nVersion);
+ nVersion = this->nVersion;
+ READWRITE(vin);
+ READWRITE(vout);
+ READWRITE(nLockTime);
+ }
+
+ /** Compute the hash of this CMutableTransaction. This is computed on the
+ * fly, as opposed to GetHash() in CTransaction, which uses a cached result.
+ */
+ uint256 GetHash() const;
+};
+
+#endif // BITCOIN_PRIMITIVES_TRANSACTION_H
diff --git a/src/protocol.cpp b/src/protocol.cpp
new file mode 100644
index 0000000000..dd855aa33a
--- /dev/null
+++ b/src/protocol.cpp
@@ -0,0 +1,142 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "protocol.h"
+
+#include "util.h"
+#include "utilstrencodings.h"
+
+#ifndef WIN32
+# include <arpa/inet.h>
+#endif
+
+static const char* ppszTypeName[] =
+{
+ "ERROR",
+ "tx",
+ "block",
+ "filtered block"
+};
+
+CMessageHeader::CMessageHeader(const MessageStartChars& pchMessageStartIn)
+{
+ memcpy(pchMessageStart, pchMessageStartIn, MESSAGE_START_SIZE);
+ memset(pchCommand, 0, sizeof(pchCommand));
+ nMessageSize = -1;
+ nChecksum = 0;
+}
+
+CMessageHeader::CMessageHeader(const MessageStartChars& pchMessageStartIn, const char* pszCommand, unsigned int nMessageSizeIn)
+{
+ memcpy(pchMessageStart, pchMessageStartIn, MESSAGE_START_SIZE);
+ memset(pchCommand, 0, sizeof(pchCommand));
+ strncpy(pchCommand, pszCommand, COMMAND_SIZE);
+ nMessageSize = nMessageSizeIn;
+ nChecksum = 0;
+}
+
+std::string CMessageHeader::GetCommand() const
+{
+ return std::string(pchCommand, pchCommand + strnlen(pchCommand, COMMAND_SIZE));
+}
+
+bool CMessageHeader::IsValid(const MessageStartChars& pchMessageStartIn) const
+{
+ // Check start string
+ if (memcmp(pchMessageStart, pchMessageStartIn, MESSAGE_START_SIZE) != 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)
+ {
+ LogPrintf("CMessageHeader::IsValid(): (%s, %u bytes) nMessageSize > MAX_SIZE\n", GetCommand(), nMessageSize);
+ return false;
+ }
+
+ return true;
+}
+
+
+
+CAddress::CAddress() : CService()
+{
+ Init();
+}
+
+CAddress::CAddress(CService ipIn, uint64_t nServicesIn) : CService(ipIn)
+{
+ Init();
+ nServices = nServicesIn;
+}
+
+void CAddress::Init()
+{
+ nServices = NODE_NETWORK;
+ nTime = 100000000;
+}
+
+CInv::CInv()
+{
+ type = 0;
+ hash.SetNull();
+}
+
+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));
+ 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());
+}
diff --git a/src/protocol.h b/src/protocol.h
new file mode 100644
index 0000000000..b5e65032a2
--- /dev/null
+++ b/src/protocol.h
@@ -0,0 +1,158 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2013 The Bitcoin Core developers
+// Distributed under the MIT 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 BITCOIN_PROTOCOL_H
+#define BITCOIN_PROTOCOL_H
+
+#include "netbase.h"
+#include "serialize.h"
+#include "uint256.h"
+#include "version.h"
+
+#include <stdint.h>
+#include <string>
+
+#define MESSAGE_START_SIZE 4
+
+/** Message header.
+ * (4) message start.
+ * (12) command.
+ * (4) size.
+ * (4) checksum.
+ */
+class CMessageHeader
+{
+public:
+ typedef unsigned char MessageStartChars[MESSAGE_START_SIZE];
+
+ CMessageHeader(const MessageStartChars& pchMessageStartIn);
+ CMessageHeader(const MessageStartChars& pchMessageStartIn, const char* pszCommand, unsigned int nMessageSizeIn);
+
+ std::string GetCommand() const;
+ bool IsValid(const MessageStartChars& messageStart) const;
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion)
+ {
+ READWRITE(FLATDATA(pchMessageStart));
+ READWRITE(FLATDATA(pchCommand));
+ READWRITE(nMessageSize);
+ READWRITE(nChecksum);
+ }
+
+ // TODO: make private (improves encapsulation)
+public:
+ enum {
+ 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,
+ HEADER_SIZE = MESSAGE_START_SIZE + COMMAND_SIZE + MESSAGE_SIZE_SIZE + CHECKSUM_SIZE
+ };
+ char pchMessageStart[MESSAGE_START_SIZE];
+ char pchCommand[COMMAND_SIZE];
+ unsigned int nMessageSize;
+ unsigned int nChecksum;
+};
+
+/** nServices flags */
+enum {
+ // NODE_NETWORK means that the node is capable of serving the block chain. It is currently
+ // set by all Bitcoin Core nodes, and is unset by SPV clients or other peers that just want
+ // network services but don't provide them.
+ NODE_NETWORK = (1 << 0),
+ // NODE_GETUTXO means the node is capable of responding to the getutxo protocol request.
+ // Bitcoin Core does not support this but a patch set called Bitcoin XT does.
+ // See BIP 64 for details on how this is implemented.
+ NODE_GETUTXO = (1 << 1),
+
+ // Bits 24-31 are reserved for temporary experiments. Just pick a bit that
+ // isn't getting used, or one not being used much, and notify the
+ // bitcoin-development mailing list. Remember that service bits are just
+ // unauthenticated advertisements, so your code must be robust against
+ // collisions and other cases where nodes may be advertising a service they
+ // do not actually support. Other service bits should be allocated via the
+ // BIP process.
+};
+
+/** A CService with information about it as peer */
+class CAddress : public CService
+{
+public:
+ CAddress();
+ explicit CAddress(CService ipIn, uint64_t nServicesIn = NODE_NETWORK);
+
+ void Init();
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion)
+ {
+ if (ser_action.ForRead())
+ Init();
+ if (nType & SER_DISK)
+ READWRITE(nVersion);
+ if ((nType & SER_DISK) ||
+ (nVersion >= CADDR_TIME_VERSION && !(nType & SER_GETHASH)))
+ READWRITE(nTime);
+ READWRITE(nServices);
+ READWRITE(*(CService*)this);
+ }
+
+ // TODO: make private (improves encapsulation)
+public:
+ uint64_t nServices;
+
+ // disk and network only
+ unsigned int nTime;
+};
+
+/** inv message data */
+class CInv
+{
+public:
+ CInv();
+ CInv(int typeIn, const uint256& hashIn);
+ CInv(const std::string& strType, const uint256& hashIn);
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion)
+ {
+ READWRITE(type);
+ READWRITE(hash);
+ }
+
+ friend bool operator<(const CInv& a, const CInv& b);
+
+ bool IsKnownType() const;
+ const char* GetCommand() const;
+ std::string ToString() const;
+
+ // TODO: make private (improves encapsulation)
+public:
+ int type;
+ uint256 hash;
+};
+
+enum {
+ MSG_TX = 1,
+ MSG_BLOCK,
+ // Nodes may always request a MSG_FILTERED_BLOCK in a getdata, however,
+ // MSG_FILTERED_BLOCK should not appear in any invs except as a part of getdata.
+ MSG_FILTERED_BLOCK,
+};
+
+#endif // BITCOIN_PROTOCOL_H
diff --git a/src/pubkey.cpp b/src/pubkey.cpp
new file mode 100644
index 0000000000..bdab137600
--- /dev/null
+++ b/src/pubkey.cpp
@@ -0,0 +1,97 @@
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "pubkey.h"
+
+#include "eccryptoverify.h"
+
+#include "ecwrapper.h"
+
+bool CPubKey::Verify(const uint256 &hash, const std::vector<unsigned char>& vchSig) const {
+ if (!IsValid())
+ return false;
+ CECKey key;
+ if (!key.SetPubKey(begin(), size()))
+ return false;
+ if (!key.Verify(hash, vchSig))
+ return false;
+ return true;
+}
+
+bool CPubKey::RecoverCompact(const uint256 &hash, const std::vector<unsigned char>& vchSig) {
+ if (vchSig.size() != 65)
+ return false;
+ int recid = (vchSig[0] - 27) & 3;
+ bool fComp = ((vchSig[0] - 27) & 4) != 0;
+ CECKey key;
+ if (!key.Recover(hash, &vchSig[1], recid))
+ return false;
+ std::vector<unsigned char> pubkey;
+ key.GetPubKey(pubkey, fComp);
+ Set(pubkey.begin(), pubkey.end());
+ return true;
+}
+
+bool CPubKey::IsFullyValid() const {
+ if (!IsValid())
+ return false;
+ CECKey key;
+ if (!key.SetPubKey(begin(), size()))
+ return false;
+ return true;
+}
+
+bool CPubKey::Decompress() {
+ if (!IsValid())
+ return false;
+ CECKey key;
+ if (!key.SetPubKey(begin(), size()))
+ return false;
+ std::vector<unsigned char> pubkey;
+ key.GetPubKey(pubkey, false);
+ Set(pubkey.begin(), pubkey.end());
+ return true;
+}
+
+bool CPubKey::Derive(CPubKey& pubkeyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const {
+ assert(IsValid());
+ assert((nChild >> 31) == 0);
+ assert(begin() + 33 == end());
+ unsigned char out[64];
+ BIP32Hash(cc, nChild, *begin(), begin()+1, out);
+ memcpy(ccChild.begin(), out+32, 32);
+ CECKey key;
+ bool ret = key.SetPubKey(begin(), size());
+ ret &= key.TweakPublic(out);
+ std::vector<unsigned char> pubkey;
+ key.GetPubKey(pubkey, true);
+ pubkeyChild.Set(pubkey.begin(), pubkey.end());
+ return ret;
+}
+
+void CExtPubKey::Encode(unsigned char code[74]) const {
+ code[0] = nDepth;
+ memcpy(code+1, vchFingerprint, 4);
+ code[5] = (nChild >> 24) & 0xFF; code[6] = (nChild >> 16) & 0xFF;
+ code[7] = (nChild >> 8) & 0xFF; code[8] = (nChild >> 0) & 0xFF;
+ memcpy(code+9, chaincode.begin(), 32);
+ assert(pubkey.size() == 33);
+ memcpy(code+41, pubkey.begin(), 33);
+}
+
+void CExtPubKey::Decode(const unsigned char code[74]) {
+ nDepth = code[0];
+ memcpy(vchFingerprint, code+1, 4);
+ nChild = (code[5] << 24) | (code[6] << 16) | (code[7] << 8) | code[8];
+ memcpy(chaincode.begin(), code+9, 32);
+ pubkey.Set(code+41, code+74);
+}
+
+bool CExtPubKey::Derive(CExtPubKey &out, unsigned int nChild) const {
+ out.nDepth = nDepth + 1;
+ CKeyID id = pubkey.GetID();
+ memcpy(&out.vchFingerprint[0], &id, 4);
+ out.nChild = nChild;
+ return pubkey.Derive(out.pubkey, out.chaincode, nChild, chaincode);
+}
diff --git a/src/pubkey.h b/src/pubkey.h
new file mode 100644
index 0000000000..cce9c826e5
--- /dev/null
+++ b/src/pubkey.h
@@ -0,0 +1,208 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_PUBKEY_H
+#define BITCOIN_PUBKEY_H
+
+#include "hash.h"
+#include "serialize.h"
+#include "uint256.h"
+
+#include <stdexcept>
+#include <vector>
+
+/**
+ * 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
+ */
+
+/** A reference to a CKey: the Hash160 of its serialized public key */
+class CKeyID : public uint160
+{
+public:
+ CKeyID() : uint160() {}
+ CKeyID(const uint160& in) : uint160(in) {}
+};
+
+typedef uint256 ChainCode;
+
+/** An encapsulated public key. */
+class CPubKey
+{
+private:
+
+ /**
+ * Just store the serialized data.
+ * Its length can very cheaply be computed from the first byte.
+ */
+ unsigned char vch[65];
+
+ //! Compute the length of a pubkey with a given first byte.
+ unsigned int static GetLen(unsigned char chHeader)
+ {
+ if (chHeader == 2 || chHeader == 3)
+ return 33;
+ if (chHeader == 4 || chHeader == 6 || chHeader == 7)
+ return 65;
+ return 0;
+ }
+
+ //! Set this key data to be invalid
+ void Invalidate()
+ {
+ vch[0] = 0xFF;
+ }
+
+public:
+ //! Construct an invalid public key.
+ CPubKey()
+ {
+ Invalidate();
+ }
+
+ //! Initialize a public key using begin/end iterators to byte data.
+ template <typename T>
+ void Set(const T pbegin, const T pend)
+ {
+ int len = pend == pbegin ? 0 : GetLen(pbegin[0]);
+ if (len && len == (pend - pbegin))
+ memcpy(vch, (unsigned char*)&pbegin[0], len);
+ else
+ Invalidate();
+ }
+
+ //! Construct a public key using begin/end iterators to byte data.
+ template <typename T>
+ CPubKey(const T pbegin, const T pend)
+ {
+ Set(pbegin, pend);
+ }
+
+ //! Construct a public key from a byte vector.
+ CPubKey(const std::vector<unsigned char>& vch)
+ {
+ Set(vch.begin(), vch.end());
+ }
+
+ //! Simple read-only vector-like interface to the pubkey data.
+ unsigned int size() const { return GetLen(vch[0]); }
+ const unsigned char* begin() const { return vch; }
+ const unsigned char* end() const { return vch + size(); }
+ const unsigned char& operator[](unsigned int pos) const { return vch[pos]; }
+
+ //! Comparator implementation.
+ friend bool operator==(const CPubKey& a, const CPubKey& b)
+ {
+ return a.vch[0] == b.vch[0] &&
+ memcmp(a.vch, b.vch, a.size()) == 0;
+ }
+ friend bool operator!=(const CPubKey& a, const CPubKey& b)
+ {
+ return !(a == b);
+ }
+ friend bool operator<(const CPubKey& a, const CPubKey& b)
+ {
+ return a.vch[0] < b.vch[0] ||
+ (a.vch[0] == b.vch[0] && memcmp(a.vch, b.vch, a.size()) < 0);
+ }
+
+ //! Implement serialization, as if this was a byte vector.
+ unsigned int GetSerializeSize(int nType, int nVersion) const
+ {
+ return size() + 1;
+ }
+ template <typename Stream>
+ void Serialize(Stream& s, int nType, int nVersion) const
+ {
+ unsigned int len = size();
+ ::WriteCompactSize(s, len);
+ s.write((char*)vch, len);
+ }
+ template <typename Stream>
+ void Unserialize(Stream& s, int nType, int nVersion)
+ {
+ unsigned int len = ::ReadCompactSize(s);
+ if (len <= 65) {
+ s.read((char*)vch, len);
+ } else {
+ // invalid pubkey, skip available data
+ char dummy;
+ while (len--)
+ s.read(&dummy, 1);
+ Invalidate();
+ }
+ }
+
+ //! Get the KeyID of this public key (hash of its serialization)
+ CKeyID GetID() const
+ {
+ return CKeyID(Hash160(vch, vch + size()));
+ }
+
+ //! Get the 256-bit hash of this public key.
+ uint256 GetHash() const
+ {
+ return Hash(vch, vch + size());
+ }
+
+ /*
+ * Check syntactic correctness.
+ *
+ * Note that this is consensus critical as CheckSig() calls it!
+ */
+ bool IsValid() const
+ {
+ return size() > 0;
+ }
+
+ //! fully validate whether this is a valid public key (more expensive than IsValid())
+ bool IsFullyValid() const;
+
+ //! Check whether this is a compressed public key.
+ bool IsCompressed() const
+ {
+ return size() == 33;
+ }
+
+ /**
+ * Verify a DER signature (~72 bytes).
+ * If this public key is not fully valid, the return value will be false.
+ */
+ bool Verify(const uint256& hash, const std::vector<unsigned char>& vchSig) const;
+
+ //! Recover a public key from a compact signature.
+ bool RecoverCompact(const uint256& hash, const std::vector<unsigned char>& vchSig);
+
+ //! Turn this public key into an uncompressed public key.
+ bool Decompress();
+
+ //! Derive BIP32 child pubkey.
+ bool Derive(CPubKey& pubkeyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const;
+};
+
+struct CExtPubKey {
+ unsigned char nDepth;
+ unsigned char vchFingerprint[4];
+ unsigned int nChild;
+ ChainCode chaincode;
+ CPubKey pubkey;
+
+ friend bool operator==(const CExtPubKey &a, const CExtPubKey &b)
+ {
+ return a.nDepth == b.nDepth && memcmp(&a.vchFingerprint[0], &b.vchFingerprint[0], 4) == 0 && a.nChild == b.nChild &&
+ a.chaincode == b.chaincode && a.pubkey == b.pubkey;
+ }
+
+ void Encode(unsigned char code[74]) const;
+ void Decode(const unsigned char code[74]);
+ bool Derive(CExtPubKey& out, unsigned int nChild) const;
+};
+
+#endif // BITCOIN_PUBKEY_H
diff --git a/src/qt/Makefile b/src/qt/Makefile
new file mode 100644
index 0000000000..b9dcf0c599
--- /dev/null
+++ b/src/qt/Makefile
@@ -0,0 +1,9 @@
+.PHONY: FORCE
+all: FORCE
+ $(MAKE) -C .. bitcoin_qt test_bitcoin_qt
+clean: FORCE
+ $(MAKE) -C .. bitcoin_qt_clean test_bitcoin_qt_clean
+check: FORCE
+ $(MAKE) -C .. test_bitcoin_qt_check
+bitcoin-qt bitcoin-qt.exe: FORCE
+ $(MAKE) -C .. bitcoin_qt
diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp
new file mode 100644
index 0000000000..af6801919c
--- /dev/null
+++ b/src/qt/addressbookpage.cpp
@@ -0,0 +1,313 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#if defined(HAVE_CONFIG_H)
+#include "config/bitcoin-config.h"
+#endif
+
+#include "addressbookpage.h"
+#include "ui_addressbookpage.h"
+
+#include "addresstablemodel.h"
+#include "bitcoingui.h"
+#include "csvmodelwriter.h"
+#include "editaddressdialog.h"
+#include "guiutil.h"
+#include "scicon.h"
+
+#include <QIcon>
+#include <QMenu>
+#include <QMessageBox>
+#include <QSortFilterProxyModel>
+
+AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::AddressBookPage),
+ model(0),
+ mode(mode),
+ tab(tab)
+{
+ ui->setupUi(this);
+
+#ifdef Q_OS_MAC // Icons on push buttons are very uncommon on Mac
+ ui->newAddress->setIcon(QIcon());
+ ui->copyAddress->setIcon(QIcon());
+ ui->deleteAddress->setIcon(QIcon());
+ ui->exportButton->setIcon(QIcon());
+#else
+ ui->newAddress->setIcon(SingleColorIcon(":/icons/add"));
+ ui->copyAddress->setIcon(SingleColorIcon(":/icons/editcopy"));
+ ui->deleteAddress->setIcon(SingleColorIcon(":/icons/remove"));
+ ui->exportButton->setIcon(SingleColorIcon(":/icons/export"));
+#endif
+
+ switch(mode)
+ {
+ case ForSelection:
+ switch(tab)
+ {
+ case SendingTab: setWindowTitle(tr("Choose the address to send coins to")); break;
+ case ReceivingTab: setWindowTitle(tr("Choose the address to receive coins with")); break;
+ }
+ connect(ui->tableView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(accept()));
+ ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
+ ui->tableView->setFocus();
+ ui->closeButton->setText(tr("C&hoose"));
+ ui->exportButton->hide();
+ break;
+ case ForEditing:
+ switch(tab)
+ {
+ case SendingTab: setWindowTitle(tr("Sending addresses")); break;
+ case ReceivingTab: setWindowTitle(tr("Receiving addresses")); break;
+ }
+ break;
+ }
+ switch(tab)
+ {
+ case SendingTab:
+ ui->labelExplanation->setText(tr("These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins."));
+ ui->deleteAddress->setVisible(true);
+ break;
+ case ReceivingTab:
+ ui->labelExplanation->setText(tr("These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction."));
+ ui->deleteAddress->setVisible(false);
+ break;
+ }
+
+ // Context menu actions
+ QAction *copyAddressAction = new QAction(tr("&Copy Address"), this);
+ QAction *copyLabelAction = new QAction(tr("Copy &Label"), this);
+ QAction *editAction = new QAction(tr("&Edit"), this);
+ deleteAction = new QAction(ui->deleteAddress->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();
+
+ // Connect signals for context menu actions
+ connect(copyAddressAction, SIGNAL(triggered()), this, SLOT(on_copyAddress_clicked()));
+ connect(copyLabelAction, SIGNAL(triggered()), this, SLOT(onCopyLabelAction()));
+ connect(editAction, SIGNAL(triggered()), this, SLOT(onEditAction()));
+ connect(deleteAction, SIGNAL(triggered()), this, SLOT(on_deleteAddress_clicked()));
+
+ connect(ui->tableView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextualMenu(QPoint)));
+
+ connect(ui->closeButton, SIGNAL(clicked()), 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
+#if QT_VERSION < 0x050000
+ ui->tableView->horizontalHeader()->setResizeMode(AddressTableModel::Label, QHeaderView::Stretch);
+ ui->tableView->horizontalHeader()->setResizeMode(AddressTableModel::Address, QHeaderView::ResizeToContents);
+#else
+ ui->tableView->horizontalHeader()->setSectionResizeMode(AddressTableModel::Label, QHeaderView::Stretch);
+ ui->tableView->horizontalHeader()->setSectionResizeMode(AddressTableModel::Address, QHeaderView::ResizeToContents);
+#endif
+
+ 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::on_copyAddress_clicked()
+{
+ GUIUtil::copyEntryData(ui->tableView, AddressTableModel::Address);
+}
+
+void AddressBookPage::onCopyLabelAction()
+{
+ GUIUtil::copyEntryData(ui->tableView, AddressTableModel::Label);
+}
+
+void AddressBookPage::onEditAction()
+{
+ if(!model)
+ return;
+
+ if(!ui->tableView->selectionModel())
+ return;
+ QModelIndexList indexes = ui->tableView->selectionModel()->selectedRows();
+ if(indexes.isEmpty())
+ return;
+
+ EditAddressDialog dlg(
+ tab == SendingTab ?
+ EditAddressDialog::EditSendingAddress :
+ EditAddressDialog::EditReceivingAddress, this);
+ dlg.setModel(model);
+ QModelIndex origIndex = proxyModel->mapToSource(indexes.at(0));
+ dlg.loadRow(origIndex.row());
+ dlg.exec();
+}
+
+void AddressBookPage::on_newAddress_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_deleteAddress_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->deleteAddress->setEnabled(true);
+ ui->deleteAddress->setVisible(true);
+ deleteAction->setEnabled(true);
+ break;
+ case ReceivingTab:
+ // Deleting receiving addresses, however, is not allowed
+ ui->deleteAddress->setEnabled(false);
+ ui->deleteAddress->setVisible(false);
+ deleteAction->setEnabled(false);
+ break;
+ }
+ ui->copyAddress->setEnabled(true);
+ }
+ else
+ {
+ ui->deleteAddress->setEnabled(false);
+ ui->copyAddress->setEnabled(false);
+ }
+}
+
+void AddressBookPage::done(int retval)
+{
+ QTableView *table = ui->tableView;
+ if(!table->selectionModel() || !table->model())
+ return;
+
+ // Figure out which address was selected, and return it
+ QModelIndexList indexes = table->selectionModel()->selectedRows(AddressTableModel::Address);
+
+ Q_FOREACH (const 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::on_exportButton_clicked()
+{
+ // CSV is currently the only supported format
+ QString filename = GUIUtil::getSaveFileName(this,
+ tr("Export Address List"), QString(),
+ tr("Comma separated file (*.csv)"), NULL);
+
+ 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("Exporting Failed"),
+ tr("There was an error trying to save the address list to %1. Please try again.").arg(filename));
+ }
+}
+
+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 0000000000..09634ce336
--- /dev/null
+++ b/src/qt/addressbookpage.h
@@ -0,0 +1,87 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_ADDRESSBOOKPAGE_H
+#define BITCOIN_QT_ADDRESSBOOKPAGE_H
+
+#include <QDialog>
+
+class AddressTableModel;
+class OptionsModel;
+
+namespace Ui {
+ class AddressBookPage;
+}
+
+QT_BEGIN_NAMESPACE
+class QItemSelection;
+class QMenu;
+class QModelIndex;
+class QSortFilterProxyModel;
+class QTableView;
+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 {
+ ForSelection, /**< Open address book to pick address */
+ ForEditing /**< Open address book for editing */
+ };
+
+ explicit AddressBookPage(Mode mode, Tabs tab, QWidget *parent);
+ ~AddressBookPage();
+
+ void setModel(AddressTableModel *model);
+ const QString &getReturnValue() const { return returnValue; }
+
+public Q_SLOTS:
+ void done(int retval);
+
+private:
+ Ui::AddressBookPage *ui;
+ AddressTableModel *model;
+ Mode mode;
+ Tabs tab;
+ QString returnValue;
+ QSortFilterProxyModel *proxyModel;
+ QMenu *contextMenu;
+ QAction *deleteAction; // to be able to explicitly disable it
+ QString newAddressToSelect;
+
+private Q_SLOTS:
+ /** Delete currently selected address entry */
+ void on_deleteAddress_clicked();
+ /** Create a new address for receiving coins and / or add a new address book entry */
+ void on_newAddress_clicked();
+ /** Copy address of currently selected address entry to clipboard */
+ void on_copyAddress_clicked();
+ /** Copy label of currently selected address entry to clipboard (no button) */
+ void onCopyLabelAction();
+ /** Edit currently selected address entry (no button) */
+ void onEditAction();
+ /** Export button clicked */
+ void on_exportButton_clicked();
+
+ /** Set button states based on selected tab and selection */
+ void selectionChanged();
+ /** Spawn contextual menu (right mouse menu) for address book entry */
+ void contextualMenu(const QPoint &point);
+ /** New entry/entries were added to address table */
+ void selectNewAddress(const QModelIndex &parent, int begin, int /*end*/);
+
+Q_SIGNALS:
+ void sendCoins(QString addr);
+};
+
+#endif // BITCOIN_QT_ADDRESSBOOKPAGE_H
diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp
new file mode 100644
index 0000000000..c5ac07cfc2
--- /dev/null
+++ b/src/qt/addresstablemodel.cpp
@@ -0,0 +1,454 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "addresstablemodel.h"
+
+#include "guiutil.h"
+#include "walletmodel.h"
+
+#include "base58.h"
+#include "wallet/wallet.h"
+
+#include <boost/foreach.hpp>
+
+#include <QFont>
+#include <QDebug>
+
+const QString AddressTableModel::Send = "S";
+const QString AddressTableModel::Receive = "R";
+
+struct AddressTableEntry
+{
+ enum Type {
+ Sending,
+ Receiving,
+ Hidden /* QSortFilterProxyModel will filter these out */
+ };
+
+ 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;
+ }
+};
+
+/* Determine address type from address purpose */
+static AddressTableEntry::Type translateTransactionType(const QString &strPurpose, bool isMine)
+{
+ AddressTableEntry::Type addressType = AddressTableEntry::Hidden;
+ // "refund" addresses aren't shown, and change addresses aren't in mapAddressBook at all.
+ if (strPurpose == "send")
+ addressType = AddressTableEntry::Sending;
+ else if (strPurpose == "receive")
+ addressType = AddressTableEntry::Receiving;
+ else if (strPurpose == "unknown" || strPurpose == "") // if purpose not set, guess
+ addressType = (isMine ? AddressTableEntry::Receiving : AddressTableEntry::Sending);
+ return addressType;
+}
+
+// Private implementation
+class AddressTablePriv
+{
+public:
+ CWallet *wallet;
+ QList<AddressTableEntry> 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, CAddressBookData)& item, wallet->mapAddressBook)
+ {
+ const CBitcoinAddress& address = item.first;
+ bool fMine = IsMine(*wallet, address.Get());
+ AddressTableEntry::Type addressType = translateTransactionType(
+ QString::fromStdString(item.second.purpose), fMine);
+ const std::string& strName = item.second.name;
+ cachedAddressTable.append(AddressTableEntry(addressType,
+ QString::fromStdString(strName),
+ QString::fromStdString(address.ToString())));
+ }
+ }
+ // qLowerBound() and qUpperBound() require our cachedAddressTable list to be sorted in asc order
+ // Even though the map is already sorted this re-sorting step is needed because the originating map
+ // is sorted by binary address, not by base58() address.
+ qSort(cachedAddressTable.begin(), cachedAddressTable.end(), AddressTableEntryLessThan());
+ }
+
+ void updateEntry(const QString &address, const QString &label, bool isMine, const QString &purpose, int status)
+ {
+ // Find address / label in model
+ QList<AddressTableEntry>::iterator lower = qLowerBound(
+ cachedAddressTable.begin(), cachedAddressTable.end(), address, AddressTableEntryLessThan());
+ QList<AddressTableEntry>::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 = translateTransactionType(purpose, isMine);
+
+ switch(status)
+ {
+ case CT_NEW:
+ if(inModel)
+ {
+ qWarning() << "AddressTablePriv::updateEntry: Warning: Got CT_NEW, but entry is already in model";
+ break;
+ }
+ parent->beginInsertRows(QModelIndex(), lowerIndex, lowerIndex);
+ cachedAddressTable.insert(lowerIndex, AddressTableEntry(newEntryType, label, address));
+ parent->endInsertRows();
+ break;
+ case CT_UPDATED:
+ if(!inModel)
+ {
+ qWarning() << "AddressTablePriv::updateEntry: Warning: Got CT_UPDATED, but entry is not in model";
+ break;
+ }
+ lower->type = newEntryType;
+ lower->label = label;
+ parent->emitDataChanged(lowerIndex);
+ break;
+ case CT_DELETED:
+ if(!inModel)
+ {
+ qWarning() << "AddressTablePriv::updateEntry: Warning: Got CT_DELETED, but entry is not in model";
+ 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<AddressTableEntry*>(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<AddressTableEntry*>(index.internalPointer());
+ std::string strPurpose = (rec->type == AddressTableEntry::Sending ? "send" : "receive");
+ editStatus = OK;
+
+ if(role == Qt::EditRole)
+ {
+ LOCK(wallet->cs_wallet); /* For SetAddressBook / DelAddressBook */
+ CTxDestination curAddress = CBitcoinAddress(rec->address.toStdString()).Get();
+ if(index.column() == Label)
+ {
+ // Do nothing, if old label == new label
+ if(rec->label == value.toString())
+ {
+ editStatus = NO_CHANGES;
+ return false;
+ }
+ wallet->SetAddressBook(curAddress, value.toString().toStdString(), strPurpose);
+ } else if(index.column() == Address) {
+ CTxDestination newAddress = CBitcoinAddress(value.toString().toStdString()).Get();
+ // Refuse to set invalid address, set error status and return false
+ if(boost::get<CNoDestination>(&newAddress))
+ {
+ editStatus = INVALID_ADDRESS;
+ return false;
+ }
+ // Do nothing, if old address == new address
+ else if(newAddress == curAddress)
+ {
+ editStatus = NO_CHANGES;
+ return false;
+ }
+ // Check for duplicate addresses to prevent accidental deletion of addresses, if you try
+ // to paste an existing address over another address (with a different label)
+ else if(wallet->mapAddressBook.count(newAddress))
+ {
+ editStatus = DUPLICATE_ADDRESS;
+ return false;
+ }
+ // Double-check that we're not overwriting a receiving address
+ else if(rec->type == AddressTableEntry::Sending)
+ {
+ // Remove old entry
+ wallet->DelAddressBook(curAddress);
+ // Add new entry with new address
+ wallet->SetAddressBook(newAddress, rec->label.toStdString(), strPurpose);
+ }
+ }
+ return true;
+ }
+ return false;
+}
+
+QVariant AddressTableModel::headerData(int section, Qt::Orientation orientation, int role) const
+{
+ if(orientation == Qt::Horizontal)
+ {
+ if(role == Qt::DisplayRole && section < columns.size())
+ {
+ return columns[section];
+ }
+ }
+ return QVariant();
+}
+
+Qt::ItemFlags AddressTableModel::flags(const QModelIndex &index) const
+{
+ if(!index.isValid())
+ return 0;
+ AddressTableEntry *rec = static_cast<AddressTableEntry*>(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, const QString &purpose, int status)
+{
+ // Update address book model from Bitcoin core
+ priv->updateEntry(address, label, isMine, purpose, 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
+ CPubKey newKey;
+ if(!wallet->GetKeyFromPool(newKey))
+ {
+ WalletModel::UnlockContext ctx(walletModel->requestUnlock());
+ if(!ctx.isValid())
+ {
+ // Unlock wallet failed or was cancelled
+ editStatus = WALLET_UNLOCK_FAILURE;
+ return QString();
+ }
+ if(!wallet->GetKeyFromPool(newKey))
+ {
+ editStatus = KEY_GENERATION_FAILURE;
+ return QString();
+ }
+ }
+ strAddress = CBitcoinAddress(newKey.GetID()).ToString();
+ }
+ else
+ {
+ return QString();
+ }
+
+ // Add entry
+ {
+ LOCK(wallet->cs_wallet);
+ wallet->SetAddressBook(CBitcoinAddress(strAddress).Get(), strLabel,
+ (type == Send ? "send" : "receive"));
+ }
+ 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->DelAddressBook(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<CTxDestination, CAddressBookData>::iterator mi = wallet->mapAddressBook.find(address_parsed.Get());
+ if (mi != wallet->mapAddressBook.end())
+ {
+ return QString::fromStdString(mi->second.name);
+ }
+ }
+ 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)
+{
+ Q_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 0000000000..2b7475c4e2
--- /dev/null
+++ b/src/qt/addresstablemodel.h
@@ -0,0 +1,95 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_ADDRESSTABLEMODEL_H
+#define BITCOIN_QT_ADDRESSTABLEMODEL_H
+
+#include <QAbstractTableModel>
+#include <QStringList>
+
+class AddressTablePriv;
+class WalletModel;
+
+class CWallet;
+
+/**
+ 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, /**< Everything ok */
+ NO_CHANGES, /**< No changes were made during edit operation */
+ 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);
+
+public Q_SLOTS:
+ /* Update address list from core.
+ */
+ void updateEntry(const QString &address, const QString &label, bool isMine, const QString &purpose, int status);
+
+ friend class AddressTablePriv;
+};
+
+#endif // BITCOIN_QT_ADDRESSTABLEMODEL_H
diff --git a/src/qt/askpassphrasedialog.cpp b/src/qt/askpassphrasedialog.cpp
new file mode 100644
index 0000000000..441814ff07
--- /dev/null
+++ b/src/qt/askpassphrasedialog.cpp
@@ -0,0 +1,258 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "askpassphrasedialog.h"
+#include "ui_askpassphrasedialog.h"
+
+#include "guiconstants.h"
+#include "walletmodel.h"
+
+#include "support/allocators/secure.h"
+
+#include <QKeyEvent>
+#include <QMessageBox>
+#include <QPushButton>
+
+AskPassphraseDialog::AskPassphraseDialog(Mode mode, QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::AskPassphraseDialog),
+ mode(mode),
+ model(0),
+ fCapsLock(false)
+{
+ ui->setupUi(this);
+
+ ui->passEdit1->setMinimumSize(ui->passEdit1->sizeHint());
+ ui->passEdit2->setMinimumSize(ui->passEdit2->sizeHint());
+ ui->passEdit3->setMinimumSize(ui->passEdit3->sizeHint());
+
+ 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->warningLabel->setText(tr("Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>."));
+ ui->passLabel1->hide();
+ ui->passEdit1->hide();
+ 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 passphrase 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 <b>LOSE ALL OF YOUR BITCOINS</b>!") + "<br><br>" + tr("Are 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"),
+ "<qt>" +
+ tr("Bitcoin Core 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.") +
+ "<br><br><b>" +
+ tr("IMPORTANT: Any previous backups you have made of your wallet file "
+ "should be replaced with the newly generated, encrypted wallet file. "
+ "For security reasons, previous backups of the unencrypted wallet file "
+ "will become useless as soon as you start using the new, encrypted wallet.") +
+ "</b></qt>");
+ 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 acceptable
+ 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<QKeyEvent *>(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 *object, 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<QKeyEvent *>(event);
+ QString str = ke->text();
+ if (str.length() != 0) {
+ const QChar *psz = str.unicode();
+ bool fShift = (ke->modifiers() & Qt::ShiftModifier) != 0;
+ if ((fShift && *psz >= 'a' && *psz <= 'z') || (!fShift && *psz >= 'A' && *psz <= 'Z')) {
+ fCapsLock = true;
+ ui->capsLabel->setText(tr("Warning: The Caps Lock key is on!"));
+ } else if (psz->isLetter()) {
+ fCapsLock = false;
+ ui->capsLabel->clear();
+ }
+ }
+ }
+ return QDialog::eventFilter(object, event);
+}
diff --git a/src/qt/askpassphrasedialog.h b/src/qt/askpassphrasedialog.h
new file mode 100644
index 0000000000..d4d832825a
--- /dev/null
+++ b/src/qt/askpassphrasedialog.h
@@ -0,0 +1,51 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_ASKPASSPHRASEDIALOG_H
+#define BITCOIN_QT_ASKPASSPHRASEDIALOG_H
+
+#include <QDialog>
+
+class WalletModel;
+
+namespace Ui {
+ class AskPassphraseDialog;
+}
+
+/** 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);
+ ~AskPassphraseDialog();
+
+ void accept();
+
+ void setModel(WalletModel *model);
+
+private:
+ Ui::AskPassphraseDialog *ui;
+ Mode mode;
+ WalletModel *model;
+ bool fCapsLock;
+
+private Q_SLOTS:
+ void textChanged();
+
+protected:
+ bool event(QEvent *event);
+ bool eventFilter(QObject *object, QEvent *event);
+};
+
+#endif // BITCOIN_QT_ASKPASSPHRASEDIALOG_H
diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp
new file mode 100644
index 0000000000..8a78533420
--- /dev/null
+++ b/src/qt/bitcoin.cpp
@@ -0,0 +1,658 @@
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#if defined(HAVE_CONFIG_H)
+#include "config/bitcoin-config.h"
+#endif
+
+#include "bitcoingui.h"
+
+#include "clientmodel.h"
+#include "guiconstants.h"
+#include "guiutil.h"
+#include "intro.h"
+#include "networkstyle.h"
+#include "optionsmodel.h"
+#include "splashscreen.h"
+#include "utilitydialog.h"
+#include "winshutdownmonitor.h"
+
+#ifdef ENABLE_WALLET
+#include "paymentserver.h"
+#include "walletmodel.h"
+#endif
+
+#include "init.h"
+#include "main.h"
+#include "rpcserver.h"
+#include "scheduler.h"
+#include "ui_interface.h"
+#include "util.h"
+
+#ifdef ENABLE_WALLET
+#include "wallet/wallet.h"
+#endif
+
+#include <stdint.h>
+
+#include <boost/filesystem/operations.hpp>
+#include <boost/thread.hpp>
+
+#include <QApplication>
+#include <QDebug>
+#include <QLibraryInfo>
+#include <QLocale>
+#include <QMessageBox>
+#include <QSettings>
+#include <QThread>
+#include <QTimer>
+#include <QTranslator>
+#include <QSslConfiguration>
+
+#if defined(QT_STATICPLUGIN)
+#include <QtPlugin>
+#if QT_VERSION < 0x050000
+Q_IMPORT_PLUGIN(qcncodecs)
+Q_IMPORT_PLUGIN(qjpcodecs)
+Q_IMPORT_PLUGIN(qtwcodecs)
+Q_IMPORT_PLUGIN(qkrcodecs)
+Q_IMPORT_PLUGIN(qtaccessiblewidgets)
+#else
+#if QT_VERSION < 0x050400
+Q_IMPORT_PLUGIN(AccessibleFactory)
+#endif
+#if defined(QT_QPA_PLATFORM_XCB)
+Q_IMPORT_PLUGIN(QXcbIntegrationPlugin);
+#elif defined(QT_QPA_PLATFORM_WINDOWS)
+Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin);
+#elif defined(QT_QPA_PLATFORM_COCOA)
+Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin);
+#endif
+#endif
+#endif
+
+#if QT_VERSION < 0x050000
+#include <QTextCodec>
+#endif
+
+// Declare meta types used for QMetaObject::invokeMethod
+Q_DECLARE_METATYPE(bool*)
+Q_DECLARE_METATYPE(CAmount)
+
+static void InitMessage(const std::string &message)
+{
+ LogPrintf("init message: %s\n", message);
+}
+
+/*
+ Translate string to current locale using Qt.
+ */
+static std::string Translate(const char* psz)
+{
+ return QCoreApplication::translate("bitcoin-core", psz).toStdString();
+}
+
+static QString GetLangTerritory()
+{
+ QSettings settings;
+ // Get desired locale (e.g. "de_DE")
+ // 1) System default language
+ QString lang_territory = QLocale::system().name();
+ // 2) Language from QSettings
+ QString lang_territory_qsettings = settings.value("language", "").toString();
+ if(!lang_territory_qsettings.isEmpty())
+ lang_territory = lang_territory_qsettings;
+ // 3) -lang command line argument
+ lang_territory = QString::fromStdString(GetArg("-lang", lang_territory.toStdString()));
+ return lang_territory;
+}
+
+/** Set up translations */
+static void initTranslations(QTranslator &qtTranslatorBase, QTranslator &qtTranslator, QTranslator &translatorBase, QTranslator &translator)
+{
+ // Remove old translators
+ QApplication::removeTranslator(&qtTranslatorBase);
+ QApplication::removeTranslator(&qtTranslator);
+ QApplication::removeTranslator(&translatorBase);
+ QApplication::removeTranslator(&translator);
+
+ // Get desired locale (e.g. "de_DE")
+ // 1) System default language
+ QString lang_territory = GetLangTerritory();
+
+ // Convert to "de" only by truncating "_DE"
+ QString lang = lang_territory;
+ lang.truncate(lang_territory.lastIndexOf('_'));
+
+ // 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)))
+ QApplication::installTranslator(&qtTranslatorBase);
+
+ // Load e.g. qt_de_DE.qm
+ if (qtTranslator.load("qt_" + lang_territory, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
+ QApplication::installTranslator(&qtTranslator);
+
+ // Load e.g. bitcoin_de.qm (shortcut "de" needs to be defined in bitcoin.qrc)
+ if (translatorBase.load(lang, ":/translations/"))
+ QApplication::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/"))
+ QApplication::installTranslator(&translator);
+}
+
+/* qDebug() message handler --> debug.log */
+#if QT_VERSION < 0x050000
+void DebugMessageHandler(QtMsgType type, const char *msg)
+{
+ const char *category = (type == QtDebugMsg) ? "qt" : NULL;
+ LogPrint(category, "GUI: %s\n", msg);
+}
+#else
+void DebugMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString &msg)
+{
+ Q_UNUSED(context);
+ const char *category = (type == QtDebugMsg) ? "qt" : NULL;
+ LogPrint(category, "GUI: %s\n", msg.toStdString());
+}
+#endif
+
+/** Class encapsulating Bitcoin Core startup and shutdown.
+ * Allows running startup and shutdown in a different thread from the UI thread.
+ */
+class BitcoinCore: public QObject
+{
+ Q_OBJECT
+public:
+ explicit BitcoinCore();
+
+public Q_SLOTS:
+ void initialize();
+ void shutdown();
+
+Q_SIGNALS:
+ void initializeResult(int retval);
+ void shutdownResult(int retval);
+ void runawayException(const QString &message);
+
+private:
+ boost::thread_group threadGroup;
+ CScheduler scheduler;
+
+ /// Pass fatal exception message to UI thread
+ void handleRunawayException(const std::exception *e);
+};
+
+/** Main Bitcoin application object */
+class BitcoinApplication: public QApplication
+{
+ Q_OBJECT
+public:
+ explicit BitcoinApplication(int &argc, char **argv);
+ ~BitcoinApplication();
+
+#ifdef ENABLE_WALLET
+ /// Create payment server
+ void createPaymentServer();
+#endif
+ /// Create options model
+ void createOptionsModel();
+ /// Create main window
+ void createWindow(const NetworkStyle *networkStyle);
+ /// Create splash screen
+ void createSplashScreen(const NetworkStyle *networkStyle);
+
+ /// Request core initialization
+ void requestInitialize();
+ /// Request core shutdown
+ void requestShutdown();
+
+ /// Get process return value
+ int getReturnValue() { return returnValue; }
+
+ /// Get window identifier of QMainWindow (BitcoinGUI)
+ WId getMainWinId() const;
+
+public Q_SLOTS:
+ void initializeResult(int retval);
+ void shutdownResult(int retval);
+ /// Handle runaway exceptions. Shows a message box with the problem and quits the program.
+ void handleRunawayException(const QString &message);
+
+Q_SIGNALS:
+ void requestedInitialize();
+ void requestedShutdown();
+ void stopThread();
+ void splashFinished(QWidget *window);
+
+private:
+ QThread *coreThread;
+ OptionsModel *optionsModel;
+ ClientModel *clientModel;
+ BitcoinGUI *window;
+ QTimer *pollShutdownTimer;
+#ifdef ENABLE_WALLET
+ PaymentServer* paymentServer;
+ WalletModel *walletModel;
+#endif
+ int returnValue;
+
+ void startThread();
+};
+
+#include "bitcoin.moc"
+
+BitcoinCore::BitcoinCore():
+ QObject()
+{
+}
+
+void BitcoinCore::handleRunawayException(const std::exception *e)
+{
+ PrintExceptionContinue(e, "Runaway exception");
+ Q_EMIT runawayException(QString::fromStdString(strMiscWarning));
+}
+
+void BitcoinCore::initialize()
+{
+ try
+ {
+ qDebug() << __func__ << ": Running AppInit2 in thread";
+ int rv = AppInit2(threadGroup, scheduler);
+ if(rv)
+ {
+ /* Start a dummy RPC thread if no RPC thread is active yet
+ * to handle timeouts.
+ */
+ StartDummyRPCThread();
+ }
+ Q_EMIT initializeResult(rv);
+ } catch (const std::exception& e) {
+ handleRunawayException(&e);
+ } catch (...) {
+ handleRunawayException(NULL);
+ }
+}
+
+void BitcoinCore::shutdown()
+{
+ try
+ {
+ qDebug() << __func__ << ": Running Shutdown in thread";
+ threadGroup.interrupt_all();
+ threadGroup.join_all();
+ Shutdown();
+ qDebug() << __func__ << ": Shutdown finished";
+ Q_EMIT shutdownResult(1);
+ } catch (const std::exception& e) {
+ handleRunawayException(&e);
+ } catch (...) {
+ handleRunawayException(NULL);
+ }
+}
+
+BitcoinApplication::BitcoinApplication(int &argc, char **argv):
+ QApplication(argc, argv),
+ coreThread(0),
+ optionsModel(0),
+ clientModel(0),
+ window(0),
+ pollShutdownTimer(0),
+#ifdef ENABLE_WALLET
+ paymentServer(0),
+ walletModel(0),
+#endif
+ returnValue(0)
+{
+ setQuitOnLastWindowClosed(false);
+}
+
+BitcoinApplication::~BitcoinApplication()
+{
+ if(coreThread)
+ {
+ qDebug() << __func__ << ": Stopping thread";
+ Q_EMIT stopThread();
+ coreThread->wait();
+ qDebug() << __func__ << ": Stopped thread";
+ }
+
+ delete window;
+ window = 0;
+#ifdef ENABLE_WALLET
+ delete paymentServer;
+ paymentServer = 0;
+#endif
+ delete optionsModel;
+ optionsModel = 0;
+}
+
+#ifdef ENABLE_WALLET
+void BitcoinApplication::createPaymentServer()
+{
+ paymentServer = new PaymentServer(this);
+}
+#endif
+
+void BitcoinApplication::createOptionsModel()
+{
+ optionsModel = new OptionsModel();
+}
+
+void BitcoinApplication::createWindow(const NetworkStyle *networkStyle)
+{
+ window = new BitcoinGUI(networkStyle, 0);
+
+ pollShutdownTimer = new QTimer(window);
+ connect(pollShutdownTimer, SIGNAL(timeout()), window, SLOT(detectShutdown()));
+ pollShutdownTimer->start(200);
+}
+
+void BitcoinApplication::createSplashScreen(const NetworkStyle *networkStyle)
+{
+ SplashScreen *splash = new SplashScreen(0, networkStyle);
+ // We don't hold a direct pointer to the splash screen after creation, so use
+ // Qt::WA_DeleteOnClose to make sure that the window will be deleted eventually.
+ splash->setAttribute(Qt::WA_DeleteOnClose);
+ splash->show();
+ connect(this, SIGNAL(splashFinished(QWidget*)), splash, SLOT(slotFinish(QWidget*)));
+}
+
+void BitcoinApplication::startThread()
+{
+ if(coreThread)
+ return;
+ coreThread = new QThread(this);
+ BitcoinCore *executor = new BitcoinCore();
+ executor->moveToThread(coreThread);
+
+ /* communication to and from thread */
+ connect(executor, SIGNAL(initializeResult(int)), this, SLOT(initializeResult(int)));
+ connect(executor, SIGNAL(shutdownResult(int)), this, SLOT(shutdownResult(int)));
+ connect(executor, SIGNAL(runawayException(QString)), this, SLOT(handleRunawayException(QString)));
+ connect(this, SIGNAL(requestedInitialize()), executor, SLOT(initialize()));
+ connect(this, SIGNAL(requestedShutdown()), executor, SLOT(shutdown()));
+ /* make sure executor object is deleted in its own thread */
+ connect(this, SIGNAL(stopThread()), executor, SLOT(deleteLater()));
+ connect(this, SIGNAL(stopThread()), coreThread, SLOT(quit()));
+
+ coreThread->start();
+}
+
+void BitcoinApplication::requestInitialize()
+{
+ qDebug() << __func__ << ": Requesting initialize";
+ startThread();
+ Q_EMIT requestedInitialize();
+}
+
+void BitcoinApplication::requestShutdown()
+{
+ qDebug() << __func__ << ": Requesting shutdown";
+ startThread();
+ window->hide();
+ window->setClientModel(0);
+ pollShutdownTimer->stop();
+
+#ifdef ENABLE_WALLET
+ window->removeAllWallets();
+ delete walletModel;
+ walletModel = 0;
+#endif
+ delete clientModel;
+ clientModel = 0;
+
+ // Show a simple window indicating shutdown status
+ ShutdownWindow::showShutdownWindow(window);
+
+ // Request shutdown from core thread
+ Q_EMIT requestedShutdown();
+}
+
+void BitcoinApplication::initializeResult(int retval)
+{
+ qDebug() << __func__ << ": Initialization result: " << retval;
+ // Set exit result: 0 if successful, 1 if failure
+ returnValue = retval ? 0 : 1;
+ if(retval)
+ {
+#ifdef ENABLE_WALLET
+ PaymentServer::LoadRootCAs();
+ paymentServer->setOptionsModel(optionsModel);
+#endif
+
+ clientModel = new ClientModel(optionsModel);
+ window->setClientModel(clientModel);
+
+#ifdef ENABLE_WALLET
+ if(pwalletMain)
+ {
+ walletModel = new WalletModel(pwalletMain, optionsModel);
+
+ window->addWallet(BitcoinGUI::DEFAULT_WALLET, walletModel);
+ window->setCurrentWallet(BitcoinGUI::DEFAULT_WALLET);
+
+ connect(walletModel, SIGNAL(coinsSent(CWallet*,SendCoinsRecipient,QByteArray)),
+ paymentServer, SLOT(fetchPaymentACK(CWallet*,const SendCoinsRecipient&,QByteArray)));
+ }
+#endif
+
+ // If -min option passed, start window minimized.
+ if(GetBoolArg("-min", false))
+ {
+ window->showMinimized();
+ }
+ else
+ {
+ window->show();
+ }
+ Q_EMIT splashFinished(window);
+
+#ifdef ENABLE_WALLET
+ // Now that initialization/startup is done, process any command-line
+ // bitcoin: URIs or payment requests:
+ connect(paymentServer, SIGNAL(receivedPaymentRequest(SendCoinsRecipient)),
+ window, SLOT(handlePaymentRequest(SendCoinsRecipient)));
+ connect(window, SIGNAL(receivedURI(QString)),
+ paymentServer, SLOT(handleURIOrFile(QString)));
+ connect(paymentServer, SIGNAL(message(QString,QString,unsigned int)),
+ window, SLOT(message(QString,QString,unsigned int)));
+ QTimer::singleShot(100, paymentServer, SLOT(uiReady()));
+#endif
+ } else {
+ quit(); // Exit main loop
+ }
+}
+
+void BitcoinApplication::shutdownResult(int retval)
+{
+ qDebug() << __func__ << ": Shutdown result: " << retval;
+ quit(); // Exit main loop after shutdown finished
+}
+
+void BitcoinApplication::handleRunawayException(const QString &message)
+{
+ QMessageBox::critical(0, "Runaway exception", BitcoinGUI::tr("A fatal error occurred. Bitcoin can no longer continue safely and will quit.") + QString("\n\n") + message);
+ ::exit(1);
+}
+
+WId BitcoinApplication::getMainWinId() const
+{
+ if (!window)
+ return 0;
+
+ return window->winId();
+}
+
+#ifndef BITCOIN_QT_TEST
+int main(int argc, char *argv[])
+{
+ SetupEnvironment();
+
+ /// 1. Parse command-line options. These take precedence over anything else.
+ // Command-line options take precedence:
+ ParseParameters(argc, argv);
+
+ // Do not refer to data directory yet, this can be overridden by Intro::pickDataDirectory
+
+ /// 2. Basic Qt initialization (not dependent on parameters or configuration)
+#if QT_VERSION < 0x050000
+ // Internal string conversion is all UTF-8
+ QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
+ QTextCodec::setCodecForCStrings(QTextCodec::codecForTr());
+#endif
+
+ Q_INIT_RESOURCE(bitcoin);
+ Q_INIT_RESOURCE(bitcoin_locale);
+
+ BitcoinApplication app(argc, argv);
+#if QT_VERSION > 0x050100
+ // Generate high-dpi pixmaps
+ QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
+#endif
+#ifdef Q_OS_MAC
+ QApplication::setAttribute(Qt::AA_DontShowIconsInMenus);
+#endif
+#if QT_VERSION >= 0x050500
+ // Because of the POODLE attack it is recommended to disable SSLv3 (https://disablessl3.com/),
+ // so set SSL protocols to TLS1.0+.
+ QSslConfiguration sslconf = QSslConfiguration::defaultConfiguration();
+ sslconf.setProtocol(QSsl::TlsV1_0OrLater);
+ QSslConfiguration::setDefaultConfiguration(sslconf);
+#endif
+
+ // Register meta types used for QMetaObject::invokeMethod
+ qRegisterMetaType< bool* >();
+ // Need to pass name here as CAmount is a typedef (see http://qt-project.org/doc/qt-5/qmetatype.html#qRegisterMetaType)
+ // IMPORTANT if it is no longer a typedef use the normal variant above
+ qRegisterMetaType< CAmount >("CAmount");
+
+ /// 3. Application identification
+ // must be set before OptionsModel is initialized or translations are loaded,
+ // as it is used to locate QSettings
+ QApplication::setOrganizationName(QAPP_ORG_NAME);
+ QApplication::setOrganizationDomain(QAPP_ORG_DOMAIN);
+ QApplication::setApplicationName(QAPP_APP_NAME_DEFAULT);
+ GUIUtil::SubstituteFonts(GetLangTerritory());
+
+ /// 4. Initialization of translations, so that intro dialog is in user's language
+ // Now that QSettings are accessible, initialize translations
+ QTranslator qtTranslatorBase, qtTranslator, translatorBase, translator;
+ initTranslations(qtTranslatorBase, qtTranslator, translatorBase, translator);
+ translationInterface.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") || mapArgs.count("-version"))
+ {
+ HelpMessageDialog help(NULL, mapArgs.count("-version"));
+ help.showOrPrint();
+ return 1;
+ }
+
+ /// 5. Now that settings and translations are available, ask user for data directory
+ // User language is set up: pick a data directory
+ Intro::pickDataDirectory();
+
+ /// 6. Determine availability of data directory and parse bitcoin.conf
+ /// - Do not call GetDataDir(true) before this step finishes
+ if (!boost::filesystem::is_directory(GetDataDir(false)))
+ {
+ QMessageBox::critical(0, QObject::tr("Bitcoin Core"),
+ QObject::tr("Error: Specified data directory \"%1\" does not exist.").arg(QString::fromStdString(mapArgs["-datadir"])));
+ return 1;
+ }
+ try {
+ ReadConfigFile(mapArgs, mapMultiArgs);
+ } catch (const std::exception& e) {
+ QMessageBox::critical(0, QObject::tr("Bitcoin Core"),
+ QObject::tr("Error: Cannot parse configuration file: %1. Only use key=value syntax.").arg(e.what()));
+ return false;
+ }
+
+ /// 7. Determine network (and switch to network specific options)
+ // - Do not call Params() before this step
+ // - Do this after parsing the configuration file, as the network can be switched there
+ // - QSettings() will use the new application name after this, resulting in network-specific settings
+ // - Needs to be done before createOptionsModel
+
+ // Check for -testnet or -regtest parameter (Params() calls are only valid after this clause)
+ if (!SelectParamsFromCommandLine()) {
+ QMessageBox::critical(0, QObject::tr("Bitcoin Core"), QObject::tr("Error: Invalid combination of -regtest and -testnet."));
+ return 1;
+ }
+#ifdef ENABLE_WALLET
+ // Parse URIs on command line -- this can affect Params()
+ PaymentServer::ipcParseCommandLine(argc, argv);
+#endif
+
+ QScopedPointer<const NetworkStyle> networkStyle(NetworkStyle::instantiate(QString::fromStdString(Params().NetworkIDString())));
+ assert(!networkStyle.isNull());
+ // Allow for separate UI settings for testnets
+ QApplication::setApplicationName(networkStyle->getAppName());
+ // Re-initialize translations after changing application name (language in network-specific settings can be different)
+ initTranslations(qtTranslatorBase, qtTranslator, translatorBase, translator);
+
+#ifdef ENABLE_WALLET
+ /// 8. URI IPC sending
+ // - Do this early as we don't want to bother initializing if we are just calling IPC
+ // - Do this *after* setting up the data directory, as the data directory hash is used in the name
+ // of the server.
+ // - Do this after creating app and setting up translations, so errors are
+ // translated properly.
+ if (PaymentServer::ipcSendCommandLine())
+ exit(0);
+
+ // Start up the payment server early, too, so impatient users that click on
+ // bitcoin: links repeatedly have their payment requests routed to this process:
+ app.createPaymentServer();
+#endif
+
+ /// 9. Main GUI initialization
+ // Install global event filter that makes sure that long tooltips can be word-wrapped
+ app.installEventFilter(new GUIUtil::ToolTipToRichTextFilter(TOOLTIP_WRAP_THRESHOLD, &app));
+#if QT_VERSION < 0x050000
+ // Install qDebug() message handler to route to debug.log
+ qInstallMsgHandler(DebugMessageHandler);
+#else
+#if defined(Q_OS_WIN)
+ // Install global event filter for processing Windows session related Windows messages (WM_QUERYENDSESSION and WM_ENDSESSION)
+ qApp->installNativeEventFilter(new WinShutdownMonitor());
+#endif
+ // Install qDebug() message handler to route to debug.log
+ qInstallMessageHandler(DebugMessageHandler);
+#endif
+ // Load GUI settings from QSettings
+ app.createOptionsModel();
+
+ // Subscribe to global signals from core
+ uiInterface.InitMessage.connect(InitMessage);
+
+ if (GetBoolArg("-splash", true) && !GetBoolArg("-min", false))
+ app.createSplashScreen(networkStyle.data());
+
+ try
+ {
+ app.createWindow(networkStyle.data());
+ app.requestInitialize();
+#if defined(Q_OS_WIN) && QT_VERSION >= 0x050000
+ WinShutdownMonitor::registerShutdownBlockReason(QObject::tr("Bitcoin Core didn't yet exit safely..."), (HWND)app.getMainWinId());
+#endif
+ app.exec();
+ app.requestShutdown();
+ app.exec();
+ } catch (const std::exception& e) {
+ PrintExceptionContinue(&e, "Runaway exception");
+ app.handleRunawayException(QString::fromStdString(strMiscWarning));
+ } catch (...) {
+ PrintExceptionContinue(NULL, "Runaway exception");
+ app.handleRunawayException(QString::fromStdString(strMiscWarning));
+ }
+ return app.getReturnValue();
+}
+#endif // BITCOIN_QT_TEST
diff --git a/src/qt/bitcoin.qrc b/src/qt/bitcoin.qrc
new file mode 100644
index 0000000000..c899e95506
--- /dev/null
+++ b/src/qt/bitcoin.qrc
@@ -0,0 +1,88 @@
+<!DOCTYPE RCC><RCC version="1.0">
+ <qresource prefix="/icons">
+ <file alias="bitcoin">res/icons/bitcoin.png</file>
+ <file alias="address-book">res/icons/address-book.png</file>
+ <file alias="quit">res/icons/quit.png</file>
+ <file alias="send">res/icons/send.png</file>
+ <file alias="connect_0">res/icons/connect0.png</file>
+ <file alias="connect_1">res/icons/connect1.png</file>
+ <file alias="connect_2">res/icons/connect2.png</file>
+ <file alias="connect_3">res/icons/connect3.png</file>
+ <file alias="connect_4">res/icons/connect4.png</file>
+ <file alias="transaction_0">res/icons/transaction0.png</file>
+ <file alias="transaction_confirmed">res/icons/transaction2.png</file>
+ <file alias="transaction_conflicted">res/icons/transaction_conflicted.png</file>
+ <file alias="transaction_1">res/icons/clock1.png</file>
+ <file alias="transaction_2">res/icons/clock2.png</file>
+ <file alias="transaction_3">res/icons/clock3.png</file>
+ <file alias="transaction_4">res/icons/clock4.png</file>
+ <file alias="transaction_5">res/icons/clock5.png</file>
+ <file alias="eye">res/icons/eye.png</file>
+ <file alias="eye_minus">res/icons/eye_minus.png</file>
+ <file alias="eye_plus">res/icons/eye_plus.png</file>
+ <file alias="options">res/icons/configure.png</file>
+ <file alias="receiving_addresses">res/icons/receive.png</file>
+ <file alias="editpaste">res/icons/editpaste.png</file>
+ <file alias="editcopy">res/icons/editcopy.png</file>
+ <file alias="add">res/icons/add.png</file>
+ <file alias="edit">res/icons/edit.png</file>
+ <file alias="history">res/icons/history.png</file>
+ <file alias="overview">res/icons/overview.png</file>
+ <file alias="export">res/icons/export.png</file>
+ <file alias="synced">res/icons/synced.png</file>
+ <file alias="remove">res/icons/remove.png</file>
+ <file alias="tx_mined">res/icons/tx_mined.png</file>
+ <file alias="tx_input">res/icons/tx_input.png</file>
+ <file alias="tx_output">res/icons/tx_output.png</file>
+ <file alias="tx_inout">res/icons/tx_inout.png</file>
+ <file alias="lock_closed">res/icons/lock_closed.png</file>
+ <file alias="lock_open">res/icons/lock_open.png</file>
+ <file alias="key">res/icons/key.png</file>
+ <file alias="filesave">res/icons/filesave.png</file>
+ <file alias="debugwindow">res/icons/debugwindow.png</file>
+ <file alias="open">res/icons/open.png</file>
+ <file alias="info">res/icons/info.png</file>
+ <file alias="about">res/icons/about.png</file>
+ <file alias="about_qt">res/icons/about_qt.png</file>
+ <file alias="verify">res/icons/verify.png</file>
+ <file alias="warning">res/icons/warning.png</file>
+ </qresource>
+ <qresource prefix="/movies">
+ <file alias="spinner-000">res/movies/spinner-000.png</file>
+ <file alias="spinner-001">res/movies/spinner-001.png</file>
+ <file alias="spinner-002">res/movies/spinner-002.png</file>
+ <file alias="spinner-003">res/movies/spinner-003.png</file>
+ <file alias="spinner-004">res/movies/spinner-004.png</file>
+ <file alias="spinner-005">res/movies/spinner-005.png</file>
+ <file alias="spinner-006">res/movies/spinner-006.png</file>
+ <file alias="spinner-007">res/movies/spinner-007.png</file>
+ <file alias="spinner-008">res/movies/spinner-008.png</file>
+ <file alias="spinner-009">res/movies/spinner-009.png</file>
+ <file alias="spinner-010">res/movies/spinner-010.png</file>
+ <file alias="spinner-011">res/movies/spinner-011.png</file>
+ <file alias="spinner-012">res/movies/spinner-012.png</file>
+ <file alias="spinner-013">res/movies/spinner-013.png</file>
+ <file alias="spinner-014">res/movies/spinner-014.png</file>
+ <file alias="spinner-015">res/movies/spinner-015.png</file>
+ <file alias="spinner-016">res/movies/spinner-016.png</file>
+ <file alias="spinner-017">res/movies/spinner-017.png</file>
+ <file alias="spinner-018">res/movies/spinner-018.png</file>
+ <file alias="spinner-019">res/movies/spinner-019.png</file>
+ <file alias="spinner-020">res/movies/spinner-020.png</file>
+ <file alias="spinner-021">res/movies/spinner-021.png</file>
+ <file alias="spinner-022">res/movies/spinner-022.png</file>
+ <file alias="spinner-023">res/movies/spinner-023.png</file>
+ <file alias="spinner-024">res/movies/spinner-024.png</file>
+ <file alias="spinner-025">res/movies/spinner-025.png</file>
+ <file alias="spinner-026">res/movies/spinner-026.png</file>
+ <file alias="spinner-027">res/movies/spinner-027.png</file>
+ <file alias="spinner-028">res/movies/spinner-028.png</file>
+ <file alias="spinner-029">res/movies/spinner-029.png</file>
+ <file alias="spinner-030">res/movies/spinner-030.png</file>
+ <file alias="spinner-031">res/movies/spinner-031.png</file>
+ <file alias="spinner-032">res/movies/spinner-032.png</file>
+ <file alias="spinner-033">res/movies/spinner-033.png</file>
+ <file alias="spinner-034">res/movies/spinner-034.png</file>
+ <file alias="spinner-035">res/movies/spinner-035.png</file>
+ </qresource>
+</RCC>
diff --git a/src/qt/bitcoin_locale.qrc b/src/qt/bitcoin_locale.qrc
new file mode 100644
index 0000000000..b70a107397
--- /dev/null
+++ b/src/qt/bitcoin_locale.qrc
@@ -0,0 +1,75 @@
+<!DOCTYPE RCC><RCC version="1.0">
+ <qresource prefix="/translations">
+ <file alias="ach">locale/bitcoin_ach.qm</file>
+ <file alias="af_ZA">locale/bitcoin_af_ZA.qm</file>
+ <file alias="ar">locale/bitcoin_ar.qm</file>
+ <file alias="be_BY">locale/bitcoin_be_BY.qm</file>
+ <file alias="bg">locale/bitcoin_bg.qm</file>
+ <file alias="bs">locale/bitcoin_bs.qm</file>
+ <file alias="ca_ES">locale/bitcoin_ca_ES.qm</file>
+ <file alias="ca">locale/bitcoin_ca.qm</file>
+ <file alias="ca@valencia">locale/bitcoin_ca@valencia.qm</file>
+ <file alias="cmn">locale/bitcoin_cmn.qm</file>
+ <file alias="cs">locale/bitcoin_cs.qm</file>
+ <file alias="cy">locale/bitcoin_cy.qm</file>
+ <file alias="da">locale/bitcoin_da.qm</file>
+ <file alias="de">locale/bitcoin_de.qm</file>
+ <file alias="el_GR">locale/bitcoin_el_GR.qm</file>
+ <file alias="en">locale/bitcoin_en.qm</file>
+ <file alias="eo">locale/bitcoin_eo.qm</file>
+ <file alias="es_CL">locale/bitcoin_es_CL.qm</file>
+ <file alias="es_DO">locale/bitcoin_es_DO.qm</file>
+ <file alias="es_MX">locale/bitcoin_es_MX.qm</file>
+ <file alias="es">locale/bitcoin_es.qm</file>
+ <file alias="es_UY">locale/bitcoin_es_UY.qm</file>
+ <file alias="et">locale/bitcoin_et.qm</file>
+ <file alias="eu_ES">locale/bitcoin_eu_ES.qm</file>
+ <file alias="fa_IR">locale/bitcoin_fa_IR.qm</file>
+ <file alias="fa">locale/bitcoin_fa.qm</file>
+ <file alias="fi">locale/bitcoin_fi.qm</file>
+ <file alias="fr_CA">locale/bitcoin_fr_CA.qm</file>
+ <file alias="fr">locale/bitcoin_fr.qm</file>
+ <file alias="gl">locale/bitcoin_gl.qm</file>
+ <file alias="gu_IN">locale/bitcoin_gu_IN.qm</file>
+ <file alias="he">locale/bitcoin_he.qm</file>
+ <file alias="hi_IN">locale/bitcoin_hi_IN.qm</file>
+ <file alias="hr">locale/bitcoin_hr.qm</file>
+ <file alias="hu">locale/bitcoin_hu.qm</file>
+ <file alias="id_ID">locale/bitcoin_id_ID.qm</file>
+ <file alias="it">locale/bitcoin_it.qm</file>
+ <file alias="ja">locale/bitcoin_ja.qm</file>
+ <file alias="ka">locale/bitcoin_ka.qm</file>
+ <file alias="kk_KZ">locale/bitcoin_kk_KZ.qm</file>
+ <file alias="ko_KR">locale/bitcoin_ko_KR.qm</file>
+ <file alias="ky">locale/bitcoin_ky.qm</file>
+ <file alias="la">locale/bitcoin_la.qm</file>
+ <file alias="lt">locale/bitcoin_lt.qm</file>
+ <file alias="lv_LV">locale/bitcoin_lv_LV.qm</file>
+ <file alias="mn">locale/bitcoin_mn.qm</file>
+ <file alias="ms_MY">locale/bitcoin_ms_MY.qm</file>
+ <file alias="nb">locale/bitcoin_nb.qm</file>
+ <file alias="nl">locale/bitcoin_nl.qm</file>
+ <file alias="pam">locale/bitcoin_pam.qm</file>
+ <file alias="pl">locale/bitcoin_pl.qm</file>
+ <file alias="pt_BR">locale/bitcoin_pt_BR.qm</file>
+ <file alias="pt_PT">locale/bitcoin_pt_PT.qm</file>
+ <file alias="ro_RO">locale/bitcoin_ro_RO.qm</file>
+ <file alias="ru">locale/bitcoin_ru.qm</file>
+ <file alias="sah">locale/bitcoin_sah.qm</file>
+ <file alias="sk">locale/bitcoin_sk.qm</file>
+ <file alias="sl_SI">locale/bitcoin_sl_SI.qm</file>
+ <file alias="sq">locale/bitcoin_sq.qm</file>
+ <file alias="sr">locale/bitcoin_sr.qm</file>
+ <file alias="sv">locale/bitcoin_sv.qm</file>
+ <file alias="th_TH">locale/bitcoin_th_TH.qm</file>
+ <file alias="tr">locale/bitcoin_tr.qm</file>
+ <file alias="uk">locale/bitcoin_uk.qm</file>
+ <file alias="ur_PK">locale/bitcoin_ur_PK.qm</file>
+ <file alias="uz@Cyrl">locale/bitcoin_uz@Cyrl.qm</file>
+ <file alias="vi">locale/bitcoin_vi.qm</file>
+ <file alias="vi_VN">locale/bitcoin_vi_VN.qm</file>
+ <file alias="zh_CN">locale/bitcoin_zh_CN.qm</file>
+ <file alias="zh_HK">locale/bitcoin_zh_HK.qm</file>
+ <file alias="zh_TW">locale/bitcoin_zh_TW.qm</file>
+ </qresource>
+</RCC>
diff --git a/src/qt/bitcoinaddressvalidator.cpp b/src/qt/bitcoinaddressvalidator.cpp
new file mode 100644
index 0000000000..d712705c43
--- /dev/null
+++ b/src/qt/bitcoinaddressvalidator.cpp
@@ -0,0 +1,97 @@
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "bitcoinaddressvalidator.h"
+
+#include "base58.h"
+
+/* Base58 characters are:
+ "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
+
+ This is:
+ - All numbers except for '0'
+ - All upper-case letters except for 'I' and 'O'
+ - All lower-case letters except for 'l'
+*/
+
+BitcoinAddressEntryValidator::BitcoinAddressEntryValidator(QObject *parent) :
+ QValidator(parent)
+{
+}
+
+QValidator::State BitcoinAddressEntryValidator::validate(QString &input, int &pos) const
+{
+ Q_UNUSED(pos);
+
+ // Empty address is "intermediate" input
+ if (input.isEmpty())
+ return QValidator::Intermediate;
+
+ // Correction
+ for (int idx = 0; idx < input.size();)
+ {
+ bool removeChar = false;
+ QChar ch = input.at(idx);
+ // Corrections made are very conservative on purpose, to avoid
+ // users unexpectedly getting away with typos that would normally
+ // be detected, and thus sending to the wrong address.
+ switch(ch.unicode())
+ {
+ // Qt categorizes these as "Other_Format" not "Separator_Space"
+ case 0x200B: // ZERO WIDTH SPACE
+ case 0xFEFF: // ZERO WIDTH NO-BREAK SPACE
+ removeChar = true;
+ break;
+ default:
+ break;
+ }
+
+ // Remove whitespace
+ if (ch.isSpace())
+ removeChar = true;
+
+ // To next character
+ if (removeChar)
+ input.remove(idx, 1);
+ else
+ ++idx;
+ }
+
+ // Validation
+ QValidator::State state = QValidator::Acceptable;
+ for (int idx = 0; idx < input.size(); ++idx)
+ {
+ int ch = input.at(idx).unicode();
+
+ if (((ch >= '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;
+ }
+ }
+
+ return state;
+}
+
+BitcoinAddressCheckValidator::BitcoinAddressCheckValidator(QObject *parent) :
+ QValidator(parent)
+{
+}
+
+QValidator::State BitcoinAddressCheckValidator::validate(QString &input, int &pos) const
+{
+ Q_UNUSED(pos);
+ // Validate the passed Bitcoin address
+ CBitcoinAddress addr(input.toStdString());
+ if (addr.IsValid())
+ return QValidator::Acceptable;
+
+ return QValidator::Invalid;
+}
diff --git a/src/qt/bitcoinaddressvalidator.h b/src/qt/bitcoinaddressvalidator.h
new file mode 100644
index 0000000000..30d4a26d0e
--- /dev/null
+++ b/src/qt/bitcoinaddressvalidator.h
@@ -0,0 +1,35 @@
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_BITCOINADDRESSVALIDATOR_H
+#define BITCOIN_QT_BITCOINADDRESSVALIDATOR_H
+
+#include <QValidator>
+
+/** Base58 entry widget validator, checks for valid characters and
+ * removes some whitespace.
+ */
+class BitcoinAddressEntryValidator : public QValidator
+{
+ Q_OBJECT
+
+public:
+ explicit BitcoinAddressEntryValidator(QObject *parent);
+
+ State validate(QString &input, int &pos) const;
+};
+
+/** Bitcoin address widget validator, checks for a valid bitcoin address.
+ */
+class BitcoinAddressCheckValidator : public QValidator
+{
+ Q_OBJECT
+
+public:
+ explicit BitcoinAddressCheckValidator(QObject *parent);
+
+ State validate(QString &input, int &pos) const;
+};
+
+#endif // BITCOIN_QT_BITCOINADDRESSVALIDATOR_H
diff --git a/src/qt/bitcoinamountfield.cpp b/src/qt/bitcoinamountfield.cpp
new file mode 100644
index 0000000000..d19b9fd4af
--- /dev/null
+++ b/src/qt/bitcoinamountfield.cpp
@@ -0,0 +1,302 @@
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "bitcoinamountfield.h"
+
+#include "bitcoinunits.h"
+#include "guiconstants.h"
+#include "qvaluecombobox.h"
+
+#include <QApplication>
+#include <QAbstractSpinBox>
+#include <QHBoxLayout>
+#include <QKeyEvent>
+#include <QLineEdit>
+
+/** QSpinBox that uses fixed-point numbers internally and uses our own
+ * formatting/parsing functions.
+ */
+class AmountSpinBox: public QAbstractSpinBox
+{
+ Q_OBJECT
+
+public:
+ explicit AmountSpinBox(QWidget *parent):
+ QAbstractSpinBox(parent),
+ currentUnit(BitcoinUnits::BTC),
+ singleStep(100000) // satoshis
+ {
+ setAlignment(Qt::AlignRight);
+
+ connect(lineEdit(), SIGNAL(textEdited(QString)), this, SIGNAL(valueChanged()));
+ }
+
+ QValidator::State validate(QString &text, int &pos) const
+ {
+ if(text.isEmpty())
+ return QValidator::Intermediate;
+ bool valid = false;
+ parse(text, &valid);
+ /* Make sure we return Intermediate so that fixup() is called on defocus */
+ return valid ? QValidator::Intermediate : QValidator::Invalid;
+ }
+
+ void fixup(QString &input) const
+ {
+ bool valid = false;
+ CAmount val = parse(input, &valid);
+ if(valid)
+ {
+ input = BitcoinUnits::format(currentUnit, val, false, BitcoinUnits::separatorAlways);
+ lineEdit()->setText(input);
+ }
+ }
+
+ CAmount value(bool *valid_out=0) const
+ {
+ return parse(text(), valid_out);
+ }
+
+ void setValue(const CAmount& value)
+ {
+ lineEdit()->setText(BitcoinUnits::format(currentUnit, value, false, BitcoinUnits::separatorAlways));
+ Q_EMIT valueChanged();
+ }
+
+ void stepBy(int steps)
+ {
+ bool valid = false;
+ CAmount val = value(&valid);
+ val = val + steps * singleStep;
+ val = qMin(qMax(val, CAmount(0)), BitcoinUnits::maxMoney());
+ setValue(val);
+ }
+
+ void setDisplayUnit(int unit)
+ {
+ bool valid = false;
+ CAmount val = value(&valid);
+
+ currentUnit = unit;
+
+ if(valid)
+ setValue(val);
+ else
+ clear();
+ }
+
+ void setSingleStep(const CAmount& step)
+ {
+ singleStep = step;
+ }
+
+ QSize minimumSizeHint() const
+ {
+ if(cachedMinimumSizeHint.isEmpty())
+ {
+ ensurePolished();
+
+ const QFontMetrics fm(fontMetrics());
+ int h = lineEdit()->minimumSizeHint().height();
+ int w = fm.width(BitcoinUnits::format(BitcoinUnits::BTC, BitcoinUnits::maxMoney(), false, BitcoinUnits::separatorAlways));
+ w += 2; // cursor blinking space
+
+ QStyleOptionSpinBox opt;
+ initStyleOption(&opt);
+ QSize hint(w, h);
+ QSize extra(35, 6);
+ opt.rect.setSize(hint + extra);
+ extra += hint - style()->subControlRect(QStyle::CC_SpinBox, &opt,
+ QStyle::SC_SpinBoxEditField, this).size();
+ // get closer to final result by repeating the calculation
+ opt.rect.setSize(hint + extra);
+ extra += hint - style()->subControlRect(QStyle::CC_SpinBox, &opt,
+ QStyle::SC_SpinBoxEditField, this).size();
+ hint += extra;
+ hint.setHeight(h);
+
+ opt.rect = rect();
+
+ cachedMinimumSizeHint = style()->sizeFromContents(QStyle::CT_SpinBox, &opt, hint, this)
+ .expandedTo(QApplication::globalStrut());
+ }
+ return cachedMinimumSizeHint;
+ }
+
+private:
+ int currentUnit;
+ CAmount singleStep;
+ mutable QSize cachedMinimumSizeHint;
+
+ /**
+ * Parse a string into a number of base monetary units and
+ * return validity.
+ * @note Must return 0 if !valid.
+ */
+ CAmount parse(const QString &text, bool *valid_out=0) const
+ {
+ CAmount val = 0;
+ bool valid = BitcoinUnits::parse(currentUnit, text, &val);
+ if(valid)
+ {
+ if(val < 0 || val > BitcoinUnits::maxMoney())
+ valid = false;
+ }
+ if(valid_out)
+ *valid_out = valid;
+ return valid ? val : 0;
+ }
+
+protected:
+ bool event(QEvent *event)
+ {
+ if (event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease)
+ {
+ QKeyEvent *keyEvent = static_cast<QKeyEvent *>(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());
+ return QAbstractSpinBox::event(&periodKeyEvent);
+ }
+ }
+ return QAbstractSpinBox::event(event);
+ }
+
+ StepEnabled stepEnabled() const
+ {
+ if (isReadOnly()) // Disable steps when AmountSpinBox is read-only
+ return StepNone;
+ if (text().isEmpty()) // Allow step-up with empty field
+ return StepUpEnabled;
+
+ StepEnabled rv = 0;
+ bool valid = false;
+ CAmount val = value(&valid);
+ if(valid)
+ {
+ if(val > 0)
+ rv |= StepDownEnabled;
+ if(val < BitcoinUnits::maxMoney())
+ rv |= StepUpEnabled;
+ }
+ return rv;
+ }
+
+Q_SIGNALS:
+ void valueChanged();
+};
+
+#include "bitcoinamountfield.moc"
+
+BitcoinAmountField::BitcoinAmountField(QWidget *parent) :
+ QWidget(parent),
+ amount(0)
+{
+ amount = new AmountSpinBox(this);
+ amount->setLocale(QLocale::c());
+ amount->installEventFilter(this);
+ amount->setMaximumWidth(170);
+
+ 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()), this, SIGNAL(valueChanged()));
+ connect(unit, SIGNAL(currentIndexChanged(int)), this, SLOT(unitChanged(int)));
+
+ // Set default based on configuration
+ unitChanged(unit->currentIndex());
+}
+
+void BitcoinAmountField::clear()
+{
+ amount->clear();
+ unit->setCurrentIndex(0);
+}
+
+void BitcoinAmountField::setEnabled(bool fEnabled)
+{
+ amount->setEnabled(fEnabled);
+ unit->setEnabled(fEnabled);
+}
+
+bool BitcoinAmountField::validate()
+{
+ bool valid = false;
+ value(&valid);
+ setValid(valid);
+ return valid;
+}
+
+void BitcoinAmountField::setValid(bool valid)
+{
+ if (valid)
+ amount->setStyleSheet("");
+ else
+ amount->setStyleSheet(STYLE_INVALID);
+}
+
+bool BitcoinAmountField::eventFilter(QObject *object, QEvent *event)
+{
+ if (event->type() == QEvent::FocusIn)
+ {
+ // Clear invalid flag on focus
+ setValid(true);
+ }
+ return QWidget::eventFilter(object, event);
+}
+
+QWidget *BitcoinAmountField::setupTabChain(QWidget *prev)
+{
+ QWidget::setTabOrder(prev, amount);
+ QWidget::setTabOrder(amount, unit);
+ return unit;
+}
+
+CAmount BitcoinAmountField::value(bool *valid_out) const
+{
+ return amount->value(valid_out);
+}
+
+void BitcoinAmountField::setValue(const CAmount& value)
+{
+ amount->setValue(value);
+}
+
+void BitcoinAmountField::setReadOnly(bool fReadOnly)
+{
+ amount->setReadOnly(fReadOnly);
+}
+
+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();
+
+ amount->setDisplayUnit(newUnit);
+}
+
+void BitcoinAmountField::setDisplayUnit(int newUnit)
+{
+ unit->setValue(newUnit);
+}
+
+void BitcoinAmountField::setSingleStep(const CAmount& step)
+{
+ amount->setSingleStep(step);
+}
diff --git a/src/qt/bitcoinamountfield.h b/src/qt/bitcoinamountfield.h
new file mode 100644
index 0000000000..3703b1f8d7
--- /dev/null
+++ b/src/qt/bitcoinamountfield.h
@@ -0,0 +1,75 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_BITCOINAMOUNTFIELD_H
+#define BITCOIN_QT_BITCOINAMOUNTFIELD_H
+
+#include "amount.h"
+
+#include <QWidget>
+
+class AmountSpinBox;
+
+QT_BEGIN_NAMESPACE
+class QValueComboBox;
+QT_END_NAMESPACE
+
+/** Widget for entering bitcoin amounts.
+ */
+class BitcoinAmountField: public QWidget
+{
+ Q_OBJECT
+
+ // ugly hack: for some unknown reason CAmount (instead of qint64) does not work here as expected
+ // discussion: https://github.com/bitcoin/bitcoin/pull/5117
+ Q_PROPERTY(qint64 value READ value WRITE setValue NOTIFY valueChanged USER true)
+
+public:
+ explicit BitcoinAmountField(QWidget *parent = 0);
+
+ CAmount value(bool *value=0) const;
+ void setValue(const CAmount& value);
+
+ /** Set single step in satoshis **/
+ void setSingleStep(const CAmount& step);
+
+ /** Make read-only **/
+ void setReadOnly(bool fReadOnly);
+
+ /** 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();
+
+ /** Enable/Disable. */
+ void setEnabled(bool fEnabled);
+
+ /** Qt messes up the tab chain by default in some cases (issue https://bugreports.qt-project.org/browse/QTBUG-10907),
+ in these cases we have to set it up manually.
+ */
+ QWidget *setupTabChain(QWidget *prev);
+
+Q_SIGNALS:
+ void valueChanged();
+
+protected:
+ /** Intercept focus-in event and ',' key presses */
+ bool eventFilter(QObject *object, QEvent *event);
+
+private:
+ AmountSpinBox *amount;
+ QValueComboBox *unit;
+
+private Q_SLOTS:
+ void unitChanged(int idx);
+
+};
+
+#endif // BITCOIN_QT_BITCOINAMOUNTFIELD_H
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
new file mode 100644
index 0000000000..396435f12b
--- /dev/null
+++ b/src/qt/bitcoingui.cpp
@@ -0,0 +1,1116 @@
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "bitcoingui.h"
+
+#include "bitcoinunits.h"
+#include "clientmodel.h"
+#include "guiconstants.h"
+#include "guiutil.h"
+#include "networkstyle.h"
+#include "notificator.h"
+#include "openuridialog.h"
+#include "optionsdialog.h"
+#include "optionsmodel.h"
+#include "rpcconsole.h"
+#include "scicon.h"
+#include "utilitydialog.h"
+
+#ifdef ENABLE_WALLET
+#include "walletframe.h"
+#include "walletmodel.h"
+#endif // ENABLE_WALLET
+
+#ifdef Q_OS_MAC
+#include "macdockiconhandler.h"
+#endif
+
+#include "init.h"
+#include "ui_interface.h"
+#include "util.h"
+
+#include <iostream>
+
+#include <QAction>
+#include <QApplication>
+#include <QDateTime>
+#include <QDesktopWidget>
+#include <QDragEnterEvent>
+#include <QListWidget>
+#include <QMenuBar>
+#include <QMessageBox>
+#include <QMimeData>
+#include <QProgressBar>
+#include <QProgressDialog>
+#include <QSettings>
+#include <QStackedWidget>
+#include <QStatusBar>
+#include <QStyle>
+#include <QTimer>
+#include <QToolBar>
+#include <QVBoxLayout>
+
+#if QT_VERSION < 0x050000
+#include <QTextDocument>
+#include <QUrl>
+#else
+#include <QUrlQuery>
+#endif
+
+const QString BitcoinGUI::DEFAULT_WALLET = "~Default";
+
+BitcoinGUI::BitcoinGUI(const NetworkStyle *networkStyle, QWidget *parent) :
+ QMainWindow(parent),
+ clientModel(0),
+ walletFrame(0),
+ unitDisplayControl(0),
+ labelEncryptionIcon(0),
+ labelConnectionsIcon(0),
+ labelBlocksIcon(0),
+ progressBarLabel(0),
+ progressBar(0),
+ progressDialog(0),
+ appMenuBar(0),
+ overviewAction(0),
+ historyAction(0),
+ quitAction(0),
+ sendCoinsAction(0),
+ sendCoinsMenuAction(0),
+ usedSendingAddressesAction(0),
+ usedReceivingAddressesAction(0),
+ signMessageAction(0),
+ verifyMessageAction(0),
+ aboutAction(0),
+ receiveCoinsAction(0),
+ receiveCoinsMenuAction(0),
+ optionsAction(0),
+ toggleHideAction(0),
+ encryptWalletAction(0),
+ backupWalletAction(0),
+ changePassphraseAction(0),
+ aboutQtAction(0),
+ openRPCConsoleAction(0),
+ openAction(0),
+ showHelpMessageAction(0),
+ trayIcon(0),
+ trayIconMenu(0),
+ notificator(0),
+ rpcConsole(0),
+ prevBlocks(0),
+ spinnerFrame(0)
+{
+ GUIUtil::restoreWindowGeometry("nWindow", QSize(850, 550), this);
+
+ QString windowTitle = tr("Bitcoin Core") + " - ";
+#ifdef ENABLE_WALLET
+ /* if compiled with wallet support, -disablewallet can still disable the wallet */
+ enableWallet = !GetBoolArg("-disablewallet", false);
+#else
+ enableWallet = false;
+#endif // ENABLE_WALLET
+ if(enableWallet)
+ {
+ windowTitle += tr("Wallet");
+ } else {
+ windowTitle += tr("Node");
+ }
+ windowTitle += " " + networkStyle->getTitleAddText();
+#ifndef Q_OS_MAC
+ QApplication::setWindowIcon(networkStyle->getTrayAndWindowIcon());
+ setWindowIcon(networkStyle->getTrayAndWindowIcon());
+#else
+ MacDockIconHandler::instance()->setIcon(networkStyle->getAppIcon());
+#endif
+ setWindowTitle(windowTitle);
+
+#if defined(Q_OS_MAC) && QT_VERSION < 0x050000
+ // This property is not implemented in Qt 5. Setting it has no effect.
+ // A replacement API (QtMacUnifiedToolBar) is available in QtMacExtras.
+ setUnifiedTitleAndToolBarOnMac(true);
+#endif
+
+ rpcConsole = new RPCConsole(0);
+#ifdef ENABLE_WALLET
+ if(enableWallet)
+ {
+ /** Create wallet frame and make it the central widget */
+ walletFrame = new WalletFrame(this);
+ setCentralWidget(walletFrame);
+ } else
+#endif // ENABLE_WALLET
+ {
+ /* When compiled without wallet or -disablewallet is provided,
+ * the central widget is the rpc console.
+ */
+ setCentralWidget(rpcConsole);
+ }
+
+ // Accept D&D of URIs
+ setAcceptDrops(true);
+
+ // Create actions for the toolbar, menu bar and tray/dock icon
+ // Needs walletFrame to be initialized
+ createActions();
+
+ // Create application menu bar
+ createMenuBar();
+
+ // Create the toolbars
+ createToolBars();
+
+ // Create system tray icon and notification
+ createTrayIcon(networkStyle);
+
+ // Create status bar
+ statusBar();
+
+ // Disable size grip because it looks ugly and nobody needs it
+ statusBar()->setSizeGripEnabled(false);
+
+ // Status bar notification icons
+ QFrame *frameBlocks = new QFrame();
+ frameBlocks->setContentsMargins(0,0,0,0);
+ frameBlocks->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
+ QHBoxLayout *frameBlocksLayout = new QHBoxLayout(frameBlocks);
+ frameBlocksLayout->setContentsMargins(3,0,3,0);
+ frameBlocksLayout->setSpacing(3);
+ unitDisplayControl = new UnitDisplayStatusBarControl();
+ labelEncryptionIcon = new QLabel();
+ labelConnectionsIcon = new QLabel();
+ labelBlocksIcon = new QLabel();
+ if(enableWallet)
+ {
+ frameBlocksLayout->addStretch();
+ frameBlocksLayout->addWidget(unitDisplayControl);
+ 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 GUIUtil::ProgressBar();
+ progressBar->setAlignment(Qt::AlignCenter);
+ progressBar->setVisible(false);
+
+ // Override style sheet for progress bar for styles that have a segmented progress bar,
+ // as they make the text unreadable (workaround for issue #1071)
+ // See https://qt-project.org/doc/qt-4.8/gallery.html
+ QString curStyle = QApplication::style()->metaObject()->className();
+ if(curStyle == "QWindowsStyle" || curStyle == "QWindowsXPStyle")
+ {
+ progressBar->setStyleSheet("QProgressBar { background-color: #e8e8e8; border: 1px solid grey; border-radius: 7px; padding: 1px; text-align: center; } QProgressBar::chunk { background: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #FF8000, stop: 1 orange); border-radius: 7px; margin: 0px; }");
+ }
+
+ statusBar()->addWidget(progressBarLabel);
+ statusBar()->addWidget(progressBar);
+ statusBar()->addPermanentWidget(frameBlocks);
+
+ connect(openRPCConsoleAction, SIGNAL(triggered()), rpcConsole, SLOT(show()));
+
+ // prevents an open debug window from becoming stuck/unusable on client shutdown
+ connect(quitAction, SIGNAL(triggered()), rpcConsole, SLOT(hide()));
+
+ // Install event filter to be able to catch status tip events (QEvent::StatusTip)
+ this->installEventFilter(this);
+
+ // Initially wallet actions should be disabled
+ setWalletActionsEnabled(false);
+
+ // Subscribe to notifications from core
+ subscribeToCoreSignals();
+}
+
+BitcoinGUI::~BitcoinGUI()
+{
+ // Unsubscribe from notifications from core
+ unsubscribeFromCoreSignals();
+
+ GUIUtil::saveWindowGeometry("nWindow", this);
+ if(trayIcon) // Hide tray icon, as deleting will let it linger until quit (on Ubuntu)
+ trayIcon->hide();
+#ifdef Q_OS_MAC
+ delete appMenuBar;
+ MacDockIconHandler::cleanup();
+#endif
+
+ delete rpcConsole;
+}
+
+void BitcoinGUI::createActions()
+{
+ QActionGroup *tabGroup = new QActionGroup(this);
+
+ overviewAction = new QAction(SingleColorIcon(":/icons/overview"), tr("&Overview"), this);
+ overviewAction->setStatusTip(tr("Show general overview of wallet"));
+ overviewAction->setToolTip(overviewAction->statusTip());
+ overviewAction->setCheckable(true);
+ overviewAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_1));
+ tabGroup->addAction(overviewAction);
+
+ sendCoinsAction = new QAction(SingleColorIcon(":/icons/send"), tr("&Send"), this);
+ sendCoinsAction->setStatusTip(tr("Send coins to a Bitcoin address"));
+ sendCoinsAction->setToolTip(sendCoinsAction->statusTip());
+ sendCoinsAction->setCheckable(true);
+ sendCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_2));
+ tabGroup->addAction(sendCoinsAction);
+
+ sendCoinsMenuAction = new QAction(TextColorIcon(":/icons/send"), sendCoinsAction->text(), this);
+ sendCoinsMenuAction->setStatusTip(sendCoinsAction->statusTip());
+ sendCoinsMenuAction->setToolTip(sendCoinsMenuAction->statusTip());
+
+ receiveCoinsAction = new QAction(SingleColorIcon(":/icons/receiving_addresses"), tr("&Receive"), this);
+ receiveCoinsAction->setStatusTip(tr("Request payments (generates QR codes and bitcoin: URIs)"));
+ receiveCoinsAction->setToolTip(receiveCoinsAction->statusTip());
+ receiveCoinsAction->setCheckable(true);
+ receiveCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_3));
+ tabGroup->addAction(receiveCoinsAction);
+
+ receiveCoinsMenuAction = new QAction(TextColorIcon(":/icons/receiving_addresses"), receiveCoinsAction->text(), this);
+ receiveCoinsMenuAction->setStatusTip(receiveCoinsAction->statusTip());
+ receiveCoinsMenuAction->setToolTip(receiveCoinsMenuAction->statusTip());
+
+ historyAction = new QAction(SingleColorIcon(":/icons/history"), tr("&Transactions"), this);
+ historyAction->setStatusTip(tr("Browse transaction history"));
+ historyAction->setToolTip(historyAction->statusTip());
+ historyAction->setCheckable(true);
+ historyAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_4));
+ tabGroup->addAction(historyAction);
+
+#ifdef ENABLE_WALLET
+ // These showNormalIfMinimized are needed because Send Coins and Receive Coins
+ // can be triggered from the tray menu, and need to show the GUI to be useful.
+ connect(overviewAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
+ connect(overviewAction, SIGNAL(triggered()), this, SLOT(gotoOverviewPage()));
+ connect(sendCoinsAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
+ connect(sendCoinsAction, SIGNAL(triggered()), this, SLOT(gotoSendCoinsPage()));
+ connect(sendCoinsMenuAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
+ connect(sendCoinsMenuAction, SIGNAL(triggered()), this, SLOT(gotoSendCoinsPage()));
+ connect(receiveCoinsAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
+ connect(receiveCoinsAction, SIGNAL(triggered()), this, SLOT(gotoReceiveCoinsPage()));
+ connect(receiveCoinsMenuAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
+ connect(receiveCoinsMenuAction, SIGNAL(triggered()), this, SLOT(gotoReceiveCoinsPage()));
+ connect(historyAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
+ connect(historyAction, SIGNAL(triggered()), this, SLOT(gotoHistoryPage()));
+#endif // ENABLE_WALLET
+
+ quitAction = new QAction(TextColorIcon(":/icons/quit"), tr("E&xit"), this);
+ quitAction->setStatusTip(tr("Quit application"));
+ quitAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q));
+ quitAction->setMenuRole(QAction::QuitRole);
+ aboutAction = new QAction(TextColorIcon(":/icons/about"), tr("&About Bitcoin Core"), this);
+ aboutAction->setStatusTip(tr("Show information about Bitcoin Core"));
+ aboutAction->setMenuRole(QAction::AboutRole);
+ aboutQtAction = new QAction(TextColorIcon(":/icons/about_qt"), tr("About &Qt"), this);
+ aboutQtAction->setStatusTip(tr("Show information about Qt"));
+ aboutQtAction->setMenuRole(QAction::AboutQtRole);
+ optionsAction = new QAction(TextColorIcon(":/icons/options"), tr("&Options..."), this);
+ optionsAction->setStatusTip(tr("Modify configuration options for Bitcoin Core"));
+ optionsAction->setMenuRole(QAction::PreferencesRole);
+ toggleHideAction = new QAction(TextColorIcon(":/icons/about"), tr("&Show / Hide"), this);
+ toggleHideAction->setStatusTip(tr("Show or hide the main Window"));
+
+ encryptWalletAction = new QAction(TextColorIcon(":/icons/lock_closed"), tr("&Encrypt Wallet..."), this);
+ encryptWalletAction->setStatusTip(tr("Encrypt the private keys that belong to your wallet"));
+ encryptWalletAction->setCheckable(true);
+ backupWalletAction = new QAction(TextColorIcon(":/icons/filesave"), tr("&Backup Wallet..."), this);
+ backupWalletAction->setStatusTip(tr("Backup wallet to another location"));
+ changePassphraseAction = new QAction(TextColorIcon(":/icons/key"), tr("&Change Passphrase..."), this);
+ changePassphraseAction->setStatusTip(tr("Change the passphrase used for wallet encryption"));
+ signMessageAction = new QAction(TextColorIcon(":/icons/edit"), tr("Sign &message..."), this);
+ signMessageAction->setStatusTip(tr("Sign messages with your Bitcoin addresses to prove you own them"));
+ verifyMessageAction = new QAction(TextColorIcon(":/icons/verify"), tr("&Verify message..."), this);
+ verifyMessageAction->setStatusTip(tr("Verify messages to ensure they were signed with specified Bitcoin addresses"));
+
+ openRPCConsoleAction = new QAction(TextColorIcon(":/icons/debugwindow"), tr("&Debug window"), this);
+ openRPCConsoleAction->setStatusTip(tr("Open debugging and diagnostic console"));
+
+ usedSendingAddressesAction = new QAction(TextColorIcon(":/icons/address-book"), tr("&Sending addresses..."), this);
+ usedSendingAddressesAction->setStatusTip(tr("Show the list of used sending addresses and labels"));
+ usedReceivingAddressesAction = new QAction(TextColorIcon(":/icons/address-book"), tr("&Receiving addresses..."), this);
+ usedReceivingAddressesAction->setStatusTip(tr("Show the list of used receiving addresses and labels"));
+
+ openAction = new QAction(TextColorIcon(":/icons/open"), tr("Open &URI..."), this);
+ openAction->setStatusTip(tr("Open a bitcoin: URI or payment request"));
+
+ showHelpMessageAction = new QAction(TextColorIcon(":/icons/info"), tr("&Command-line options"), this);
+ showHelpMessageAction->setMenuRole(QAction::NoRole);
+ showHelpMessageAction->setStatusTip(tr("Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options"));
+
+ connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
+ connect(aboutAction, SIGNAL(triggered()), this, SLOT(aboutClicked()));
+ connect(aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
+ connect(optionsAction, SIGNAL(triggered()), this, SLOT(optionsClicked()));
+ connect(toggleHideAction, SIGNAL(triggered()), this, SLOT(toggleHidden()));
+ connect(showHelpMessageAction, SIGNAL(triggered()), this, SLOT(showHelpMessageClicked()));
+#ifdef ENABLE_WALLET
+ if(walletFrame)
+ {
+ connect(encryptWalletAction, SIGNAL(triggered(bool)), walletFrame, SLOT(encryptWallet(bool)));
+ connect(backupWalletAction, SIGNAL(triggered()), walletFrame, SLOT(backupWallet()));
+ connect(changePassphraseAction, SIGNAL(triggered()), walletFrame, SLOT(changePassphrase()));
+ connect(signMessageAction, SIGNAL(triggered()), this, SLOT(gotoSignMessageTab()));
+ connect(verifyMessageAction, SIGNAL(triggered()), this, SLOT(gotoVerifyMessageTab()));
+ connect(usedSendingAddressesAction, SIGNAL(triggered()), walletFrame, SLOT(usedSendingAddresses()));
+ connect(usedReceivingAddressesAction, SIGNAL(triggered()), walletFrame, SLOT(usedReceivingAddresses()));
+ connect(openAction, SIGNAL(triggered()), this, SLOT(openClicked()));
+ }
+#endif // ENABLE_WALLET
+}
+
+void BitcoinGUI::createMenuBar()
+{
+#ifdef Q_OS_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"));
+ if(walletFrame)
+ {
+ file->addAction(openAction);
+ file->addAction(backupWalletAction);
+ file->addAction(signMessageAction);
+ file->addAction(verifyMessageAction);
+ file->addSeparator();
+ file->addAction(usedSendingAddressesAction);
+ file->addAction(usedReceivingAddressesAction);
+ file->addSeparator();
+ }
+ file->addAction(quitAction);
+
+ QMenu *settings = appMenuBar->addMenu(tr("&Settings"));
+ if(walletFrame)
+ {
+ settings->addAction(encryptWalletAction);
+ settings->addAction(changePassphraseAction);
+ settings->addSeparator();
+ }
+ settings->addAction(optionsAction);
+
+ QMenu *help = appMenuBar->addMenu(tr("&Help"));
+ if(walletFrame)
+ {
+ help->addAction(openRPCConsoleAction);
+ }
+ help->addAction(showHelpMessageAction);
+ help->addSeparator();
+ help->addAction(aboutAction);
+ help->addAction(aboutQtAction);
+}
+
+void BitcoinGUI::createToolBars()
+{
+ if(walletFrame)
+ {
+ QToolBar *toolbar = addToolBar(tr("Tabs toolbar"));
+ toolbar->setMovable(false);
+ toolbar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+ toolbar->addAction(overviewAction);
+ toolbar->addAction(sendCoinsAction);
+ toolbar->addAction(receiveCoinsAction);
+ toolbar->addAction(historyAction);
+ overviewAction->setChecked(true);
+ }
+}
+
+void BitcoinGUI::setClientModel(ClientModel *clientModel)
+{
+ this->clientModel = clientModel;
+ if(clientModel)
+ {
+ // Create system tray menu (or setup the dock menu) that late to prevent users from calling actions,
+ // while the client has not yet fully loaded
+ createTrayIconMenu();
+
+ // Keep up to date with client
+ setNumConnections(clientModel->getNumConnections());
+ connect(clientModel, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int)));
+
+ setNumBlocks(clientModel->getNumBlocks(), clientModel->getLastBlockDate());
+ connect(clientModel, SIGNAL(numBlocksChanged(int,QDateTime)), this, SLOT(setNumBlocks(int,QDateTime)));
+
+ // Receive and report messages from client model
+ connect(clientModel, SIGNAL(message(QString,QString,unsigned int)), this, SLOT(message(QString,QString,unsigned int)));
+
+ // Show progress dialog
+ connect(clientModel, SIGNAL(showProgress(QString,int)), this, SLOT(showProgress(QString,int)));
+
+ rpcConsole->setClientModel(clientModel);
+#ifdef ENABLE_WALLET
+ if(walletFrame)
+ {
+ walletFrame->setClientModel(clientModel);
+ }
+#endif // ENABLE_WALLET
+ unitDisplayControl->setOptionsModel(clientModel->getOptionsModel());
+ } else {
+ // Disable possibility to show main window via action
+ toggleHideAction->setEnabled(false);
+ if(trayIconMenu)
+ {
+ // Disable context menu on tray icon
+ trayIconMenu->clear();
+ }
+ }
+}
+
+#ifdef ENABLE_WALLET
+bool BitcoinGUI::addWallet(const QString& name, WalletModel *walletModel)
+{
+ if(!walletFrame)
+ return false;
+ setWalletActionsEnabled(true);
+ return walletFrame->addWallet(name, walletModel);
+}
+
+bool BitcoinGUI::setCurrentWallet(const QString& name)
+{
+ if(!walletFrame)
+ return false;
+ return walletFrame->setCurrentWallet(name);
+}
+
+void BitcoinGUI::removeAllWallets()
+{
+ if(!walletFrame)
+ return;
+ setWalletActionsEnabled(false);
+ walletFrame->removeAllWallets();
+}
+#endif // ENABLE_WALLET
+
+void BitcoinGUI::setWalletActionsEnabled(bool enabled)
+{
+ overviewAction->setEnabled(enabled);
+ sendCoinsAction->setEnabled(enabled);
+ sendCoinsMenuAction->setEnabled(enabled);
+ receiveCoinsAction->setEnabled(enabled);
+ receiveCoinsMenuAction->setEnabled(enabled);
+ historyAction->setEnabled(enabled);
+ encryptWalletAction->setEnabled(enabled);
+ backupWalletAction->setEnabled(enabled);
+ changePassphraseAction->setEnabled(enabled);
+ signMessageAction->setEnabled(enabled);
+ verifyMessageAction->setEnabled(enabled);
+ usedSendingAddressesAction->setEnabled(enabled);
+ usedReceivingAddressesAction->setEnabled(enabled);
+ openAction->setEnabled(enabled);
+}
+
+void BitcoinGUI::createTrayIcon(const NetworkStyle *networkStyle)
+{
+#ifndef Q_OS_MAC
+ trayIcon = new QSystemTrayIcon(this);
+ QString toolTip = tr("Bitcoin Core client") + " " + networkStyle->getTitleAddText();
+ trayIcon->setToolTip(toolTip);
+ trayIcon->setIcon(networkStyle->getTrayAndWindowIcon());
+ trayIcon->show();
+#endif
+
+ notificator = new Notificator(QApplication::applicationName(), trayIcon, this);
+}
+
+void BitcoinGUI::createTrayIconMenu()
+{
+#ifndef Q_OS_MAC
+ // return if trayIcon is unset (only on non-Mac OSes)
+ if (!trayIcon)
+ return;
+
+ trayIconMenu = new QMenu(this);
+ trayIcon->setContextMenu(trayIconMenu);
+
+ connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
+ this, SLOT(trayIconActivated(QSystemTrayIcon::ActivationReason)));
+#else
+ // Note: On Mac, the dock icon is used to provide the tray's functionality.
+ MacDockIconHandler *dockIconHandler = MacDockIconHandler::instance();
+ dockIconHandler->setMainWindow((QMainWindow *)this);
+ trayIconMenu = dockIconHandler->dockMenu();
+#endif
+
+ // Configuration of the tray icon (or dock icon) icon menu
+ trayIconMenu->addAction(toggleHideAction);
+ trayIconMenu->addSeparator();
+ trayIconMenu->addAction(sendCoinsMenuAction);
+ trayIconMenu->addAction(receiveCoinsMenuAction);
+ trayIconMenu->addSeparator();
+ trayIconMenu->addAction(signMessageAction);
+ trayIconMenu->addAction(verifyMessageAction);
+ trayIconMenu->addSeparator();
+ trayIconMenu->addAction(optionsAction);
+ trayIconMenu->addAction(openRPCConsoleAction);
+#ifndef Q_OS_MAC // This is built-in on Mac
+ trayIconMenu->addSeparator();
+ trayIconMenu->addAction(quitAction);
+#endif
+}
+
+#ifndef Q_OS_MAC
+void BitcoinGUI::trayIconActivated(QSystemTrayIcon::ActivationReason reason)
+{
+ if(reason == QSystemTrayIcon::Trigger)
+ {
+ // Click on system tray icon triggers show/hide of the main window
+ toggleHidden();
+ }
+}
+#endif
+
+void BitcoinGUI::optionsClicked()
+{
+ if(!clientModel || !clientModel->getOptionsModel())
+ return;
+
+ OptionsDialog dlg(this, enableWallet);
+ dlg.setModel(clientModel->getOptionsModel());
+ dlg.exec();
+}
+
+void BitcoinGUI::aboutClicked()
+{
+ if(!clientModel)
+ return;
+
+ HelpMessageDialog dlg(this, true);
+ dlg.exec();
+}
+
+void BitcoinGUI::showHelpMessageClicked()
+{
+ HelpMessageDialog *help = new HelpMessageDialog(this, false);
+ help->setAttribute(Qt::WA_DeleteOnClose);
+ help->show();
+}
+
+#ifdef ENABLE_WALLET
+void BitcoinGUI::openClicked()
+{
+ OpenURIDialog dlg(this);
+ if(dlg.exec())
+ {
+ Q_EMIT receivedURI(dlg.getURI());
+ }
+}
+
+void BitcoinGUI::gotoOverviewPage()
+{
+ overviewAction->setChecked(true);
+ if (walletFrame) walletFrame->gotoOverviewPage();
+}
+
+void BitcoinGUI::gotoHistoryPage()
+{
+ historyAction->setChecked(true);
+ if (walletFrame) walletFrame->gotoHistoryPage();
+}
+
+void BitcoinGUI::gotoReceiveCoinsPage()
+{
+ receiveCoinsAction->setChecked(true);
+ if (walletFrame) walletFrame->gotoReceiveCoinsPage();
+}
+
+void BitcoinGUI::gotoSendCoinsPage(QString addr)
+{
+ sendCoinsAction->setChecked(true);
+ if (walletFrame) walletFrame->gotoSendCoinsPage(addr);
+}
+
+void BitcoinGUI::gotoSignMessageTab(QString addr)
+{
+ if (walletFrame) walletFrame->gotoSignMessageTab(addr);
+}
+
+void BitcoinGUI::gotoVerifyMessageTab(QString addr)
+{
+ if (walletFrame) walletFrame->gotoVerifyMessageTab(addr);
+}
+#endif // ENABLE_WALLET
+
+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(SingleColorIcon(icon).pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
+ labelConnectionsIcon->setToolTip(tr("%n active connection(s) to Bitcoin network", "", count));
+}
+
+void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate)
+{
+ if(!clientModel)
+ return;
+
+ // Prevent orphan statusbar messages (e.g. hover Quit in main menu, wait until chain-sync starts -> garbelled text)
+ statusBar()->clearMessage();
+
+ // Acquire current block source
+ enum BlockSource blockSource = clientModel->getBlockSource();
+ switch (blockSource) {
+ case BLOCK_SOURCE_NETWORK:
+ progressBarLabel->setText(tr("Synchronizing with network..."));
+ break;
+ case BLOCK_SOURCE_DISK:
+ progressBarLabel->setText(tr("Importing blocks from disk..."));
+ break;
+ case BLOCK_SOURCE_REINDEX:
+ progressBarLabel->setText(tr("Reindexing blocks on disk..."));
+ break;
+ case BLOCK_SOURCE_NONE:
+ // Case: not Importing, not Reindexing and no network connection
+ progressBarLabel->setText(tr("No block source available..."));
+ break;
+ }
+
+ QString tooltip;
+
+ QDateTime currentDate = QDateTime::currentDateTime();
+ qint64 secs = blockDate.secsTo(currentDate);
+
+ tooltip = tr("Processed %n block(s) of transaction history.", "", count);
+
+ // Set icon state: spinning if catching up, tick otherwise
+ if(secs < 90*60)
+ {
+ tooltip = tr("Up to date") + QString(".<br>") + tooltip;
+ labelBlocksIcon->setPixmap(SingleColorIcon(":/icons/synced").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
+
+#ifdef ENABLE_WALLET
+ if(walletFrame)
+ walletFrame->showOutOfSyncWarning(false);
+#endif // ENABLE_WALLET
+
+ progressBarLabel->setVisible(false);
+ progressBar->setVisible(false);
+ }
+ else
+ {
+ // Represent time from last generated block in human readable text
+ QString timeBehindText;
+ const int HOUR_IN_SECONDS = 60*60;
+ const int DAY_IN_SECONDS = 24*60*60;
+ const int WEEK_IN_SECONDS = 7*24*60*60;
+ const int YEAR_IN_SECONDS = 31556952; // Average length of year in Gregorian calendar
+ if(secs < 2*DAY_IN_SECONDS)
+ {
+ timeBehindText = tr("%n hour(s)","",secs/HOUR_IN_SECONDS);
+ }
+ else if(secs < 2*WEEK_IN_SECONDS)
+ {
+ timeBehindText = tr("%n day(s)","",secs/DAY_IN_SECONDS);
+ }
+ else if(secs < YEAR_IN_SECONDS)
+ {
+ timeBehindText = tr("%n week(s)","",secs/WEEK_IN_SECONDS);
+ }
+ else
+ {
+ qint64 years = secs / YEAR_IN_SECONDS;
+ qint64 remainder = secs % YEAR_IN_SECONDS;
+ timeBehindText = tr("%1 and %2").arg(tr("%n year(s)", "", years)).arg(tr("%n week(s)","", remainder/WEEK_IN_SECONDS));
+ }
+
+ progressBarLabel->setVisible(true);
+ progressBar->setFormat(tr("%1 behind").arg(timeBehindText));
+ progressBar->setMaximum(1000000000);
+ progressBar->setValue(clientModel->getVerificationProgress() * 1000000000.0 + 0.5);
+ progressBar->setVisible(true);
+
+ tooltip = tr("Catching up...") + QString("<br>") + tooltip;
+ if(count != prevBlocks)
+ {
+ labelBlocksIcon->setPixmap(SingleColorIcon(QString(
+ ":/movies/spinner-%1").arg(spinnerFrame, 3, 10, QChar('0')))
+ .pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
+ spinnerFrame = (spinnerFrame + 1) % SPINNER_FRAMES;
+ }
+ prevBlocks = count;
+
+#ifdef ENABLE_WALLET
+ if(walletFrame)
+ walletFrame->showOutOfSyncWarning(true);
+#endif // ENABLE_WALLET
+
+ tooltip += QString("<br>");
+ tooltip += tr("Last received block was generated %1 ago.").arg(timeBehindText);
+ tooltip += QString("<br>");
+ tooltip += tr("Transactions after this will not yet be visible.");
+ }
+
+ // Don't word-wrap this (fixed-width) tooltip
+ tooltip = QString("<nobr>") + tooltip + QString("</nobr>");
+
+ labelBlocksIcon->setToolTip(tooltip);
+ progressBarLabel->setToolTip(tooltip);
+ progressBar->setToolTip(tooltip);
+}
+
+void BitcoinGUI::message(const QString &title, const QString &message, unsigned int style, bool *ret)
+{
+ QString strTitle = tr("Bitcoin"); // default title
+ // Default to information icon
+ int nMBoxIcon = QMessageBox::Information;
+ int nNotifyIcon = Notificator::Information;
+
+ QString msgType;
+
+ // Prefer supplied title over style based title
+ if (!title.isEmpty()) {
+ msgType = title;
+ }
+ else {
+ switch (style) {
+ case CClientUIInterface::MSG_ERROR:
+ msgType = tr("Error");
+ break;
+ case CClientUIInterface::MSG_WARNING:
+ msgType = tr("Warning");
+ break;
+ case CClientUIInterface::MSG_INFORMATION:
+ msgType = tr("Information");
+ break;
+ default:
+ break;
+ }
+ }
+ // Append title to "Bitcoin - "
+ if (!msgType.isEmpty())
+ strTitle += " - " + msgType;
+
+ // Check for error/warning icon
+ if (style & CClientUIInterface::ICON_ERROR) {
+ nMBoxIcon = QMessageBox::Critical;
+ nNotifyIcon = Notificator::Critical;
+ }
+ else if (style & CClientUIInterface::ICON_WARNING) {
+ nMBoxIcon = QMessageBox::Warning;
+ nNotifyIcon = Notificator::Warning;
+ }
+
+ // Display message
+ if (style & CClientUIInterface::MODAL) {
+ // Check for buttons, use OK as default, if none was supplied
+ QMessageBox::StandardButton buttons;
+ if (!(buttons = (QMessageBox::StandardButton)(style & CClientUIInterface::BTN_MASK)))
+ buttons = QMessageBox::Ok;
+
+ showNormalIfMinimized();
+ QMessageBox mBox((QMessageBox::Icon)nMBoxIcon, strTitle, message, buttons, this);
+ int r = mBox.exec();
+ if (ret != NULL)
+ *ret = r == QMessageBox::Ok;
+ }
+ else
+ notificator->notify((Notificator::Class)nNotifyIcon, strTitle, message);
+}
+
+void BitcoinGUI::changeEvent(QEvent *e)
+{
+ QMainWindow::changeEvent(e);
+#ifndef Q_OS_MAC // Ignored on Mac
+ if(e->type() == QEvent::WindowStateChange)
+ {
+ if(clientModel && clientModel->getOptionsModel() && clientModel->getOptionsModel()->getMinimizeToTray())
+ {
+ QWindowStateChangeEvent *wsevt = static_cast<QWindowStateChangeEvent*>(e);
+ if(!(wsevt->oldState() & Qt::WindowMinimized) && isMinimized())
+ {
+ QTimer::singleShot(0, this, SLOT(hide()));
+ e->ignore();
+ }
+ }
+ }
+#endif
+}
+
+void BitcoinGUI::closeEvent(QCloseEvent *event)
+{
+#ifndef Q_OS_MAC // Ignored on Mac
+ if(clientModel && clientModel->getOptionsModel())
+ {
+ if(!clientModel->getOptionsModel()->getMinimizeToTray() &&
+ !clientModel->getOptionsModel()->getMinimizeOnClose())
+ {
+ // close rpcConsole in case it was open to make some space for the shutdown window
+ rpcConsole->close();
+
+ QApplication::quit();
+ }
+ }
+#endif
+ QMainWindow::closeEvent(event);
+}
+
+#ifdef ENABLE_WALLET
+void BitcoinGUI::incomingTransaction(const QString& date, int unit, const CAmount& amount, const QString& type, const QString& address, const QString& label)
+{
+ // On new transaction, make an info balloon
+ QString msg = tr("Date: %1\n").arg(date) +
+ tr("Amount: %1\n").arg(BitcoinUnits::formatWithUnit(unit, amount, true)) +
+ tr("Type: %1\n").arg(type);
+ if (!label.isEmpty())
+ msg += tr("Label: %1\n").arg(label);
+ else if (!address.isEmpty())
+ msg += tr("Address: %1\n").arg(address);
+ message((amount)<0 ? tr("Sent transaction") : tr("Incoming transaction"),
+ msg, CClientUIInterface::MSG_INFORMATION);
+}
+#endif // ENABLE_WALLET
+
+void BitcoinGUI::dragEnterEvent(QDragEnterEvent *event)
+{
+ // Accept only URIs
+ if(event->mimeData()->hasUrls())
+ event->acceptProposedAction();
+}
+
+void BitcoinGUI::dropEvent(QDropEvent *event)
+{
+ if(event->mimeData()->hasUrls())
+ {
+ Q_FOREACH(const QUrl &uri, event->mimeData()->urls())
+ {
+ Q_EMIT receivedURI(uri.toString());
+ }
+ }
+ event->acceptProposedAction();
+}
+
+bool BitcoinGUI::eventFilter(QObject *object, QEvent *event)
+{
+ // Catch status tip events
+ if (event->type() == QEvent::StatusTip)
+ {
+ // Prevent adding text from setStatusTip(), if we currently use the status bar for displaying other stuff
+ if (progressBarLabel->isVisible() || progressBar->isVisible())
+ return true;
+ }
+ return QMainWindow::eventFilter(object, event);
+}
+
+#ifdef ENABLE_WALLET
+bool BitcoinGUI::handlePaymentRequest(const SendCoinsRecipient& recipient)
+{
+ // URI has to be valid
+ if (walletFrame && walletFrame->handlePaymentRequest(recipient))
+ {
+ showNormalIfMinimized();
+ gotoSendCoinsPage();
+ return true;
+ }
+ return false;
+}
+
+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(SingleColorIcon(":/icons/lock_open").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
+ labelEncryptionIcon->setToolTip(tr("Wallet is <b>encrypted</b> and currently <b>unlocked</b>"));
+ encryptWalletAction->setChecked(true);
+ changePassphraseAction->setEnabled(true);
+ encryptWalletAction->setEnabled(false); // TODO: decrypt currently not supported
+ break;
+ case WalletModel::Locked:
+ labelEncryptionIcon->show();
+ labelEncryptionIcon->setPixmap(SingleColorIcon(":/icons/lock_closed").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
+ labelEncryptionIcon->setToolTip(tr("Wallet is <b>encrypted</b> and currently <b>locked</b>"));
+ encryptWalletAction->setChecked(true);
+ changePassphraseAction->setEnabled(true);
+ encryptWalletAction->setEnabled(false); // TODO: decrypt currently not supported
+ break;
+ }
+}
+#endif // ENABLE_WALLET
+
+void BitcoinGUI::showNormalIfMinimized(bool fToggleHidden)
+{
+ if(!clientModel)
+ return;
+
+ // 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);
+}
+
+void BitcoinGUI::detectShutdown()
+{
+ if (ShutdownRequested())
+ {
+ if(rpcConsole)
+ rpcConsole->hide();
+ qApp->quit();
+ }
+}
+
+void BitcoinGUI::showProgress(const QString &title, int nProgress)
+{
+ if (nProgress == 0)
+ {
+ progressDialog = new QProgressDialog(title, "", 0, 100);
+ progressDialog->setWindowModality(Qt::ApplicationModal);
+ progressDialog->setMinimumDuration(0);
+ progressDialog->setCancelButton(0);
+ progressDialog->setAutoClose(false);
+ progressDialog->setValue(0);
+ }
+ else if (nProgress == 100)
+ {
+ if (progressDialog)
+ {
+ progressDialog->close();
+ progressDialog->deleteLater();
+ }
+ }
+ else if (progressDialog)
+ progressDialog->setValue(nProgress);
+}
+
+static bool ThreadSafeMessageBox(BitcoinGUI *gui, const std::string& message, const std::string& caption, unsigned int style)
+{
+ bool modal = (style & CClientUIInterface::MODAL);
+ // The SECURE flag has no effect in the Qt GUI.
+ // bool secure = (style & CClientUIInterface::SECURE);
+ style &= ~CClientUIInterface::SECURE;
+ bool ret = false;
+ // In case of modal message, use blocking connection to wait for user to click a button
+ QMetaObject::invokeMethod(gui, "message",
+ modal ? GUIUtil::blockingGUIThreadConnection() : Qt::QueuedConnection,
+ Q_ARG(QString, QString::fromStdString(caption)),
+ Q_ARG(QString, QString::fromStdString(message)),
+ Q_ARG(unsigned int, style),
+ Q_ARG(bool*, &ret));
+ return ret;
+}
+
+void BitcoinGUI::subscribeToCoreSignals()
+{
+ // Connect signals to client
+ uiInterface.ThreadSafeMessageBox.connect(boost::bind(ThreadSafeMessageBox, this, _1, _2, _3));
+}
+
+void BitcoinGUI::unsubscribeFromCoreSignals()
+{
+ // Disconnect signals from client
+ uiInterface.ThreadSafeMessageBox.disconnect(boost::bind(ThreadSafeMessageBox, this, _1, _2, _3));
+}
+
+UnitDisplayStatusBarControl::UnitDisplayStatusBarControl() :
+ optionsModel(0),
+ menu(0)
+{
+ createContextMenu();
+ setToolTip(tr("Unit to show amounts in. Click to select another unit."));
+ QList<BitcoinUnits::Unit> units = BitcoinUnits::availableUnits();
+ int max_width = 0;
+ const QFontMetrics fm(font());
+ Q_FOREACH (const BitcoinUnits::Unit unit, units)
+ {
+ max_width = qMax(max_width, fm.width(BitcoinUnits::name(unit)));
+ }
+ setMinimumSize(max_width, 0);
+ setAlignment(Qt::AlignRight | Qt::AlignVCenter);
+ setStyleSheet(QString("QLabel { color : %1 }").arg(SingleColor().name()));
+}
+
+/** So that it responds to button clicks */
+void UnitDisplayStatusBarControl::mousePressEvent(QMouseEvent *event)
+{
+ onDisplayUnitsClicked(event->pos());
+}
+
+/** Creates context menu, its actions, and wires up all the relevant signals for mouse events. */
+void UnitDisplayStatusBarControl::createContextMenu()
+{
+ menu = new QMenu();
+ Q_FOREACH(BitcoinUnits::Unit u, BitcoinUnits::availableUnits())
+ {
+ QAction *menuAction = new QAction(QString(BitcoinUnits::name(u)), this);
+ menuAction->setData(QVariant(u));
+ menu->addAction(menuAction);
+ }
+ connect(menu,SIGNAL(triggered(QAction*)),this,SLOT(onMenuSelection(QAction*)));
+}
+
+/** Lets the control know about the Options Model (and its signals) */
+void UnitDisplayStatusBarControl::setOptionsModel(OptionsModel *optionsModel)
+{
+ if (optionsModel)
+ {
+ this->optionsModel = optionsModel;
+
+ // be aware of a display unit change reported by the OptionsModel object.
+ connect(optionsModel,SIGNAL(displayUnitChanged(int)),this,SLOT(updateDisplayUnit(int)));
+
+ // initialize the display units label with the current value in the model.
+ updateDisplayUnit(optionsModel->getDisplayUnit());
+ }
+}
+
+/** When Display Units are changed on OptionsModel it will refresh the display text of the control on the status bar */
+void UnitDisplayStatusBarControl::updateDisplayUnit(int newUnits)
+{
+ setText(BitcoinUnits::name(newUnits));
+}
+
+/** Shows context menu with Display Unit options by the mouse coordinates */
+void UnitDisplayStatusBarControl::onDisplayUnitsClicked(const QPoint& point)
+{
+ QPoint globalPos = mapToGlobal(point);
+ menu->exec(globalPos);
+}
+
+/** Tells underlying optionsModel to update its current display unit. */
+void UnitDisplayStatusBarControl::onMenuSelection(QAction* action)
+{
+ if (action)
+ {
+ optionsModel->setDisplayUnit(action->data());
+ }
+}
diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h
new file mode 100644
index 0000000000..4e50b1712a
--- /dev/null
+++ b/src/qt/bitcoingui.h
@@ -0,0 +1,242 @@
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_BITCOINGUI_H
+#define BITCOIN_QT_BITCOINGUI_H
+
+#if defined(HAVE_CONFIG_H)
+#include "config/bitcoin-config.h"
+#endif
+
+#include "amount.h"
+
+#include <QLabel>
+#include <QMainWindow>
+#include <QMap>
+#include <QMenu>
+#include <QPoint>
+#include <QSystemTrayIcon>
+
+class ClientModel;
+class NetworkStyle;
+class Notificator;
+class OptionsModel;
+class RPCConsole;
+class SendCoinsRecipient;
+class UnitDisplayStatusBarControl;
+class WalletFrame;
+class WalletModel;
+
+class CWallet;
+
+QT_BEGIN_NAMESPACE
+class QAction;
+class QProgressBar;
+class QProgressDialog;
+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:
+ static const QString DEFAULT_WALLET;
+
+ explicit BitcoinGUI(const NetworkStyle *networkStyle, 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);
+
+#ifdef ENABLE_WALLET
+ /** Set the wallet model.
+ The wallet model represents a bitcoin wallet, and offers access to the list of transactions, address book and sending
+ functionality.
+ */
+ bool addWallet(const QString& name, WalletModel *walletModel);
+ bool setCurrentWallet(const QString& name);
+ void removeAllWallets();
+#endif // ENABLE_WALLET
+ bool enableWallet;
+
+protected:
+ void changeEvent(QEvent *e);
+ void closeEvent(QCloseEvent *event);
+ void dragEnterEvent(QDragEnterEvent *event);
+ void dropEvent(QDropEvent *event);
+ bool eventFilter(QObject *object, QEvent *event);
+
+private:
+ ClientModel *clientModel;
+ WalletFrame *walletFrame;
+
+ UnitDisplayStatusBarControl *unitDisplayControl;
+ QLabel *labelEncryptionIcon;
+ QLabel *labelConnectionsIcon;
+ QLabel *labelBlocksIcon;
+ QLabel *progressBarLabel;
+ QProgressBar *progressBar;
+ QProgressDialog *progressDialog;
+
+ QMenuBar *appMenuBar;
+ QAction *overviewAction;
+ QAction *historyAction;
+ QAction *quitAction;
+ QAction *sendCoinsAction;
+ QAction *sendCoinsMenuAction;
+ QAction *usedSendingAddressesAction;
+ QAction *usedReceivingAddressesAction;
+ QAction *signMessageAction;
+ QAction *verifyMessageAction;
+ QAction *aboutAction;
+ QAction *receiveCoinsAction;
+ QAction *receiveCoinsMenuAction;
+ QAction *optionsAction;
+ QAction *toggleHideAction;
+ QAction *encryptWalletAction;
+ QAction *backupWalletAction;
+ QAction *changePassphraseAction;
+ QAction *aboutQtAction;
+ QAction *openRPCConsoleAction;
+ QAction *openAction;
+ QAction *showHelpMessageAction;
+
+ QSystemTrayIcon *trayIcon;
+ QMenu *trayIconMenu;
+ Notificator *notificator;
+ RPCConsole *rpcConsole;
+
+ /** Keep track of previous number of blocks, to detect progress */
+ int prevBlocks;
+ int spinnerFrame;
+
+ /** Create the main UI actions. */
+ void createActions();
+ /** Create the menu bar and sub-menus. */
+ void createMenuBar();
+ /** Create the toolbars */
+ void createToolBars();
+ /** Create system tray icon and notification */
+ void createTrayIcon(const NetworkStyle *networkStyle);
+ /** Create system tray menu (or setup the dock menu) */
+ void createTrayIconMenu();
+
+ /** Enable or disable all wallet-related actions */
+ void setWalletActionsEnabled(bool enabled);
+
+ /** Connect core signals to GUI client */
+ void subscribeToCoreSignals();
+ /** Disconnect core signals from GUI client */
+ void unsubscribeFromCoreSignals();
+
+Q_SIGNALS:
+ /** Signal raised when a URI was entered or dragged to the GUI */
+ void receivedURI(const QString &uri);
+
+public Q_SLOTS:
+ /** Set number of connections shown in the UI */
+ void setNumConnections(int count);
+ /** Set number of blocks and last block date shown in the UI */
+ void setNumBlocks(int count, const QDateTime& blockDate);
+
+ /** Notify the user of an event from the core network or transaction handling code.
+ @param[in] title the message box / notification title
+ @param[in] message the displayed text
+ @param[in] style modality and style definitions (icon and used buttons - buttons only for message boxes)
+ @see CClientUIInterface::MessageBoxFlags
+ @param[in] ret pointer to a bool that will be modified to whether Ok was clicked (modal only)
+ */
+ void message(const QString &title, const QString &message, unsigned int style, bool *ret = NULL);
+
+#ifdef ENABLE_WALLET
+ /** Set the encryption status as shown in the UI.
+ @param[in] status current encryption status
+ @see WalletModel::EncryptionStatus
+ */
+ void setEncryptionStatus(int status);
+
+ bool handlePaymentRequest(const SendCoinsRecipient& recipient);
+
+ /** Show incoming transaction notification for new transactions. */
+ void incomingTransaction(const QString& date, int unit, const CAmount& amount, const QString& type, const QString& address, const QString& label);
+#endif // ENABLE_WALLET
+
+private Q_SLOTS:
+#ifdef ENABLE_WALLET
+ /** Switch to overview (home) page */
+ void gotoOverviewPage();
+ /** Switch to history (transactions) page */
+ void gotoHistoryPage();
+ /** Switch to receive coins page */
+ void gotoReceiveCoinsPage();
+ /** Switch to send coins page */
+ void gotoSendCoinsPage(QString addr = "");
+
+ /** 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 open dialog */
+ void openClicked();
+#endif // ENABLE_WALLET
+ /** Show configuration dialog */
+ void optionsClicked();
+ /** Show about dialog */
+ void aboutClicked();
+ /** Show help message dialog */
+ void showHelpMessageClicked();
+#ifndef Q_OS_MAC
+ /** Handle tray icon clicked */
+ void trayIconActivated(QSystemTrayIcon::ActivationReason reason);
+#endif
+
+ /** 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();
+
+ /** called by a timer to check if fRequestShutdown has been set **/
+ void detectShutdown();
+
+ /** Show progress dialog e.g. for verifychain */
+ void showProgress(const QString &title, int nProgress);
+};
+
+class UnitDisplayStatusBarControl : public QLabel
+{
+ Q_OBJECT
+
+public:
+ explicit UnitDisplayStatusBarControl();
+ /** Lets the control know about the Options Model (and its signals) */
+ void setOptionsModel(OptionsModel *optionsModel);
+
+protected:
+ /** So that it responds to left-button clicks */
+ void mousePressEvent(QMouseEvent *event);
+
+private:
+ OptionsModel *optionsModel;
+ QMenu* menu;
+
+ /** Shows context menu with Display Unit options by the mouse coordinates */
+ void onDisplayUnitsClicked(const QPoint& point);
+ /** Creates context menu, its actions, and wires up all the relevant signals for mouse events. */
+ void createContextMenu();
+
+private Q_SLOTS:
+ /** When Display Units are changed on OptionsModel it will refresh the display text of the control on the status bar */
+ void updateDisplayUnit(int newUnits);
+ /** Tells underlying optionsModel to update its current display unit. */
+ void onMenuSelection(QAction* action);
+};
+
+#endif // BITCOIN_QT_BITCOINGUI_H
diff --git a/src/qt/bitcoinstrings.cpp b/src/qt/bitcoinstrings.cpp
new file mode 100644
index 0000000000..b3e7f4849e
--- /dev/null
+++ b/src/qt/bitcoinstrings.cpp
@@ -0,0 +1,319 @@
+
+
+#include <QtGlobal>
+
+// 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", ""
+"(1 = keep tx meta data e.g. account owner and payment request information, 2 "
+"= drop tx meta data)"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Allow JSON-RPC connections from specified source. Valid for <ip> are a "
+"single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or "
+"a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"An error occurred while setting up the RPC address %s port %u for listening: "
+"%s"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Bind to given address and always listen on it. Use [host]:port notation for "
+"IPv6"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Bind to given address and whitelist peers connecting to it. Use [host]:port "
+"notation for IPv6"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Bind to given address to listen for JSON-RPC connections. Use [host]:port "
+"notation for IPv6. This option can be specified multiple times (default: "
+"bind to all interfaces)"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Cannot obtain a lock on data directory %s. Bitcoin Core is probably already "
+"running."),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Create new files with system default permissions, instead of umask 077 (only "
+"effective with disabled wallet functionality)"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Delete all wallet transactions and only recover those parts of the "
+"blockchain through -rescan on startup"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Discover own IP addresses (default: 1 when listening and no -externalip or -"
+"proxy)"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Distributed under the MIT software license, see the accompanying file "
+"COPYING or <http://www.opensource.org/licenses/mit-license.php>."),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Error: Listening for incoming connections failed (listen returned error %s)"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Error: Unsupported argument -socks found. Setting SOCKS version isn't "
+"possible anymore, only SOCKS5 proxies are supported."),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Execute command when a relevant alert is received or we see a really long "
+"fork (%s in cmd is replaced by message)"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Execute command when a wallet transaction changes (%s in cmd is replaced by "
+"TxID)"),
+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", ""
+"Fees (in BTC/Kb) smaller than this are considered zero fee for relaying "
+"(default: %s)"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"How thorough the block verification of -checkblocks is (0-4, default: %u)"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"If paytxfee is not set, include enough fee so transactions begin "
+"confirmation on average within n blocks (default: %u)"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay "
+"fee of %s to prevent stuck transactions)"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Maintain a full transaction index, used by the getrawtransaction rpc call "
+"(default: %u)"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Maximum size of data in data carrier transactions we relay and mine "
+"(default: %u)"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Maximum total fees to use in a single wallet transaction; setting this too "
+"low may abort large transactions (default: %s)"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Number of seconds to keep misbehaving peers from reconnecting (default: %u)"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Output debugging information (default: %u, supplying <category> is optional)"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Prune configured below the minimum of %d MB. Please use a higher number."),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Query for peer addresses via DNS lookup, if low on addresses (default: 1 "
+"unless -connect)"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Randomize credentials for every proxy connection. This enables Tor stream "
+"isolation (default: %u)"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Reduce storage requirements by pruning (deleting) old blocks. This mode "
+"disables wallet support and is incompatible with -txindex. Warning: "
+"Reverting this setting requires re-downloading the entire blockchain. "
+"(default: 0 = disable pruning blocks, >%u = target size in MiB to use for "
+"block files)"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Set maximum size of high-priority/low-fee transactions in bytes (default: %d)"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Set the number of script verification threads (%u to %d, 0 = auto, <0 = "
+"leave that many cores free, default: %d)"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Set the number of threads for coin generation if enabled (-1 = all cores, "
+"default: %d)"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"The transaction amount is too small to send after the fee has been deducted"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"This is a pre-release test build - use at your own risk - do not use for "
+"mining or merchant applications"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"This product includes software developed by the OpenSSL Project for use in "
+"the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software "
+"written by Eric Young and UPnP software written by Thomas Bernard."),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"To use bitcoind, or the -server option to bitcoin-qt, you must set an "
+"rpcpassword in the configuration file:\n"
+"%s\n"
+"It is recommended you use the following random password:\n"
+"rpcuser=bitcoinrpc\n"
+"rpcpassword=%s\n"
+"(you do not need to remember this password)\n"
+"The username and password MUST NOT be the same.\n"
+"If the file does not exist, create it with owner-readable-only file "
+"permissions.\n"
+"It is also recommended to set alertnotify so you are notified of problems;\n"
+"for example: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com\n"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Unable to bind to %s on this computer. Bitcoin Core is probably already "
+"running."),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: "
+"%s)"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"WARNING: abnormally high number of blocks generated, %d blocks received in "
+"the last %d hours (%d expected)"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"WARNING: check your network connection, %d blocks received in the last %d "
+"hours (%d expected)"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Warning: -maxtxfee is set very high! Fees this large could be paid on a "
+"single transaction."),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Warning: -paytxfee is set very high! This is the transaction fee you will "
+"pay if you send a transaction."),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Warning: Please check that your computer's date and time are correct! If "
+"your clock is wrong Bitcoin Core will not work properly."),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Warning: The network does not appear to fully agree! Some miners appear to "
+"be experiencing issues."),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Warning: We do not appear to fully agree with our peers! You may need to "
+"upgrade, or other nodes may need to upgrade."),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Warning: error reading wallet.dat! All keys read correctly, but transaction "
+"data or address book entries might be missing or incorrect."),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as "
+"wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect "
+"you should restore from a backup."),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Whitelist peers connecting from the given netmask or IP address. Can be "
+"specified multiple times."),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Whitelisted peers cannot be DoS banned and their transactions are always "
+"relayed, even if they are already in the mempool, useful e.g. for a gateway"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"You need to rebuild the database using -reindex to go back to unpruned "
+"mode. This will redownload the entire blockchain"),
+QT_TRANSLATE_NOOP("bitcoin-core", "(default: %s)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "(default: %u)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "(default: 1)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "<category> can be:"),
+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", "Accept public REST requests (default: %u)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Acceptable ciphers (default: %s)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Activating best chain..."),
+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", "Always query for peer addresses via DNS lookup (default: %u)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Attempt to recover private keys from a corrupt wallet.dat"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Block creation options:"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Can't run with a wallet in prune mode."),
+QT_TRANSLATE_NOOP("bitcoin-core", "Cannot downgrade wallet"),
+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 resolve -whitebind address: '%s'"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Cannot write default address"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Choose data directory on startup (default: 0)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Connect only to the specified node(s)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Connect through SOCKS5 proxy"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Connect to a node to retrieve peer addresses, and disconnect"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Connection options:"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Copyright (C) 2009-%i The Bitcoin Core Developers"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Corrupted block database detected"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Could not parse -rpcbind value %s as network address"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Debugging/Testing options:"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Do not load the wallet and disable wallet RPC calls"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Do you want to rebuild the block database now?"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Done loading"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Error initializing block database"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Error initializing wallet database environment %s!"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Error loading block database"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat: Wallet corrupted"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat: Wallet requires newer version of Bitcoin Core"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Error opening block database"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Error reading from database, shutting down."),
+QT_TRANSLATE_NOOP("bitcoin-core", "Error"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Error: A fatal internal error occurred, see debug.log for details"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Error: Disk space is low!"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Error: Unsupported argument -tor found, use -onion."),
+QT_TRANSLATE_NOOP("bitcoin-core", "Failed to listen on any port. Use -listen=0 if you want this."),
+QT_TRANSLATE_NOOP("bitcoin-core", "Fee (in BTC/kB) to add to transactions you send (default: %s)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Generate coins (default: %u)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "How many blocks to check at startup (default: %u, 0 = all)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "If <category> is not supplied, output all debugging information."),
+QT_TRANSLATE_NOOP("bitcoin-core", "Importing..."),
+QT_TRANSLATE_NOOP("bitcoin-core", "Imports blocks from external blk000??.dat file"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Include IP addresses in debug output (default: %u)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Incorrect or no genesis block found. Wrong datadir for network?"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Information"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Initialization sanity check failed. Bitcoin Core is shutting down."),
+QT_TRANSLATE_NOOP("bitcoin-core", "Insufficient funds"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Invalid -onion address: '%s'"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Invalid -proxy address: '%s'"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -maxtxfee=<amount>: '%s'"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -minrelaytxfee=<amount>: '%s'"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -mintxfee=<amount>: '%s'"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -paytxfee=<amount>: '%s'"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Invalid netmask specified in -whitelist: '%s'"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Keep at most <n> unconnectable transactions in memory (default: %u)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Listen for connections on <port> (default: %u or testnet: %u)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Loading addresses..."),
+QT_TRANSLATE_NOOP("bitcoin-core", "Loading block index..."),
+QT_TRANSLATE_NOOP("bitcoin-core", "Loading wallet..."),
+QT_TRANSLATE_NOOP("bitcoin-core", "Maintain at most <n> connections to peers (default: %u)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Make the wallet broadcast transactions"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Maximum per-connection send buffer, <n>*1000 bytes (default: %u)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Need to specify a port with -whitebind: '%s'"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Node relay options:"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Not enough file descriptors available."),
+QT_TRANSLATE_NOOP("bitcoin-core", "Only connect to nodes in network <net> (ipv4, ipv6 or onion)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Options:"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Password for JSON-RPC connections"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Prepend debug output with timestamp (default: %u)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Prune cannot be configured with a negative value."),
+QT_TRANSLATE_NOOP("bitcoin-core", "Prune mode is incompatible with -txindex."),
+QT_TRANSLATE_NOOP("bitcoin-core", "Pruning blockstore..."),
+QT_TRANSLATE_NOOP("bitcoin-core", "RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "RPC server options:"),
+QT_TRANSLATE_NOOP("bitcoin-core", "RPC support for HTTP persistent connections (default: %d)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Rebuild block chain index from current blk000??.dat files on startup"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Receive and display P2P network alerts (default: %u)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Relay and mine data carrier transactions (default: %u)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Relay non-P2SH multisig (default: %u)"),
+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", "Send trace/debug info to console instead of debug.log file"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Send transactions as zero-fee transactions if possible (default: %u)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Server certificate file (default: %s)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Server private key (default: %s)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Set SSL root certificates for payment request (default: -system-)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Set database cache size in megabytes (%d to %d, default: %d)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Set key pool size to <n> (default: %u)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Set language, for example \"de_DE\" (default: system locale)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Set maximum block size in bytes (default: %d)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Set minimum block size in bytes (default: %u)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Set the number of threads to service RPC calls (default: %d)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Show all debugging options (usage: --help -help-debug)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Show splash screen on startup (default: 1)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Shrink debug.log file on client startup (default: 1 when no -debug)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Signing transaction failed"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Specify configuration file (default: %s)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Specify connection timeout in milliseconds (minimum: 1, default: %d)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Specify data directory"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Specify pid file (default: %s)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Specify wallet file (within data directory)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Specify your own public address"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Spend unconfirmed change when sending transactions (default: %u)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Start minimized"),
+QT_TRANSLATE_NOOP("bitcoin-core", "The transaction amount is too small to pay the fee"),
+QT_TRANSLATE_NOOP("bitcoin-core", "This help message"),
+QT_TRANSLATE_NOOP("bitcoin-core", "This is experimental software."),
+QT_TRANSLATE_NOOP("bitcoin-core", "Threshold for disconnecting misbehaving peers (default: %u)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Transaction amount too small"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Transaction amounts must be positive"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Transaction too large for fee policy"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Transaction too large"),
+QT_TRANSLATE_NOOP("bitcoin-core", "UI Options:"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Unable to bind to %s on this computer (bind returned error %s)"),
+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", "Use OpenSSL (https) for JSON-RPC connections"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Use UPnP to map the listening port (default: %u)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Use UPnP to map the listening port (default: 1 when listening)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Use the test network"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Username for JSON-RPC connections"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Verifying blocks..."),
+QT_TRANSLATE_NOOP("bitcoin-core", "Verifying wallet..."),
+QT_TRANSLATE_NOOP("bitcoin-core", "Wallet %s resides outside data directory %s"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Wallet needed to be rewritten: restart Bitcoin Core to complete"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Wallet options:"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Warning"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Warning: This version is obsolete; upgrade required!"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Warning: Unsupported argument -benchmark ignored, use -debug=bench."),
+QT_TRANSLATE_NOOP("bitcoin-core", "Warning: Unsupported argument -debugnet ignored, use -debug=net."),
+QT_TRANSLATE_NOOP("bitcoin-core", "You need to rebuild the database using -reindex to change -txindex"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Zapping all transactions from wallet..."),
+QT_TRANSLATE_NOOP("bitcoin-core", "on startup"),
+QT_TRANSLATE_NOOP("bitcoin-core", "wallet.dat corrupt, salvage failed"),
+};
diff --git a/src/qt/bitcoinunits.cpp b/src/qt/bitcoinunits.cpp
new file mode 100644
index 0000000000..425b45d918
--- /dev/null
+++ b/src/qt/bitcoinunits.cpp
@@ -0,0 +1,220 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "bitcoinunits.h"
+
+#include "primitives/transaction.h"
+
+#include <QStringList>
+
+BitcoinUnits::BitcoinUnits(QObject *parent):
+ QAbstractListModel(parent),
+ unitlist(availableUnits())
+{
+}
+
+QList<BitcoinUnits::Unit> BitcoinUnits::availableUnits()
+{
+ QList<BitcoinUnits::Unit> 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("BTC");
+ case mBTC: return QString("mBTC");
+ case uBTC: return QString::fromUtf8("μBTC");
+ default: return QString("???");
+ }
+}
+
+QString BitcoinUnits::description(int unit)
+{
+ switch(unit)
+ {
+ case BTC: return QString("Bitcoins");
+ case mBTC: return QString("Milli-Bitcoins (1 / 1" THIN_SP_UTF8 "000)");
+ case uBTC: return QString("Micro-Bitcoins (1 / 1" THIN_SP_UTF8 "000" THIN_SP_UTF8 "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::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, const CAmount& nIn, bool fPlus, SeparatorStyle separators)
+{
+ // 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 n = (qint64)nIn;
+ 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');
+
+ // Use SI-style thin space separators as these are locale independent and can't be
+ // confused with the decimal marker.
+ QChar thin_sp(THIN_SP_CP);
+ int q_size = quotient_str.size();
+ if (separators == separatorAlways || (separators == separatorStandard && q_size > 4))
+ for (int i = 3; i < q_size; i += 3)
+ quotient_str.insert(q_size - i, thin_sp);
+
+ if (n < 0)
+ quotient_str.insert(0, '-');
+ else if (fPlus && n > 0)
+ quotient_str.insert(0, '+');
+ return quotient_str + QString(".") + remainder_str;
+}
+
+
+// TODO: Review all remaining calls to BitcoinUnits::formatWithUnit to
+// TODO: determine whether the output is used in a plain text context
+// TODO: or an HTML context (and replace with
+// TODO: BtcoinUnits::formatHtmlWithUnit in the latter case). Hopefully
+// TODO: there aren't instances where the result could be used in
+// TODO: either context.
+
+// NOTE: Using formatWithUnit in an HTML context risks wrapping
+// quantities at the thousands separator. More subtly, it also results
+// in a standard space rather than a thin space, due to a bug in Qt's
+// XML whitespace canonicalisation
+//
+// Please take care to use formatHtmlWithUnit instead, when
+// appropriate.
+
+QString BitcoinUnits::formatWithUnit(int unit, const CAmount& amount, bool plussign, SeparatorStyle separators)
+{
+ return format(unit, amount, plussign, separators) + QString(" ") + name(unit);
+}
+
+QString BitcoinUnits::formatHtmlWithUnit(int unit, const CAmount& amount, bool plussign, SeparatorStyle separators)
+{
+ QString str(formatWithUnit(unit, amount, plussign, separators));
+ str.replace(QChar(THIN_SP_CP), QString(THIN_SP_HTML));
+ return QString("<span style='white-space: nowrap;'>%1</span>").arg(str);
+}
+
+
+bool BitcoinUnits::parse(int unit, const QString &value, CAmount *val_out)
+{
+ if(!valid(unit) || value.isEmpty())
+ return false; // Refuse to parse invalid unit or empty string
+ int num_decimals = decimals(unit);
+
+ // Ignore spaces and thin spaces when parsing
+ QStringList parts = removeSpaces(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
+ }
+ CAmount retvalue(str.toLongLong(&ok));
+ if(val_out)
+ {
+ *val_out = retvalue;
+ }
+ return ok;
+}
+
+QString BitcoinUnits::getAmountColumnTitle(int unit)
+{
+ QString amountTitle = QObject::tr("Amount");
+ if (BitcoinUnits::valid(unit))
+ {
+ amountTitle += " ("+BitcoinUnits::name(unit) + ")";
+ }
+ return amountTitle;
+}
+
+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<int>(unit));
+ }
+ }
+ return QVariant();
+}
+
+CAmount BitcoinUnits::maxMoney()
+{
+ return MAX_MONEY;
+}
diff --git a/src/qt/bitcoinunits.h b/src/qt/bitcoinunits.h
new file mode 100644
index 0000000000..1871c33a78
--- /dev/null
+++ b/src/qt/bitcoinunits.h
@@ -0,0 +1,127 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_BITCOINUNITS_H
+#define BITCOIN_QT_BITCOINUNITS_H
+
+#include "amount.h"
+
+#include <QAbstractListModel>
+#include <QString>
+
+// U+2009 THIN SPACE = UTF-8 E2 80 89
+#define REAL_THIN_SP_CP 0x2009
+#define REAL_THIN_SP_UTF8 "\xE2\x80\x89"
+#define REAL_THIN_SP_HTML "&thinsp;"
+
+// U+200A HAIR SPACE = UTF-8 E2 80 8A
+#define HAIR_SP_CP 0x200A
+#define HAIR_SP_UTF8 "\xE2\x80\x8A"
+#define HAIR_SP_HTML "&#8202;"
+
+// U+2006 SIX-PER-EM SPACE = UTF-8 E2 80 86
+#define SIXPEREM_SP_CP 0x2006
+#define SIXPEREM_SP_UTF8 "\xE2\x80\x86"
+#define SIXPEREM_SP_HTML "&#8198;"
+
+// U+2007 FIGURE SPACE = UTF-8 E2 80 87
+#define FIGURE_SP_CP 0x2007
+#define FIGURE_SP_UTF8 "\xE2\x80\x87"
+#define FIGURE_SP_HTML "&#8199;"
+
+// QMessageBox seems to have a bug whereby it doesn't display thin/hair spaces
+// correctly. Workaround is to display a space in a small font. If you
+// change this, please test that it doesn't cause the parent span to start
+// wrapping.
+#define HTML_HACK_SP "<span style='white-space: nowrap; font-size: 6pt'> </span>"
+
+// Define THIN_SP_* variables to be our preferred type of thin space
+#define THIN_SP_CP REAL_THIN_SP_CP
+#define THIN_SP_UTF8 REAL_THIN_SP_UTF8
+#define THIN_SP_HTML HTML_HACK_SP
+
+/** Bitcoin unit definitions. Encapsulates parsing and formatting
+ and serves as list model for drop-down selection boxes.
+*/
+class BitcoinUnits: public QAbstractListModel
+{
+ Q_OBJECT
+
+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
+ };
+
+ enum SeparatorStyle
+ {
+ separatorNever,
+ separatorStandard,
+ separatorAlways
+ };
+
+ //! @name Static API
+ //! Unit conversion and formatting
+ ///@{
+
+ //! Get list of units, for drop-down box
+ static QList<Unit> 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 decimals left
+ static int decimals(int unit);
+ //! Format as string
+ static QString format(int unit, const CAmount& amount, bool plussign=false, SeparatorStyle separators=separatorStandard);
+ //! Format as string (with unit)
+ static QString formatWithUnit(int unit, const CAmount& amount, bool plussign=false, SeparatorStyle separators=separatorStandard);
+ static QString formatHtmlWithUnit(int unit, const CAmount& amount, bool plussign=false, SeparatorStyle separators=separatorStandard);
+ //! Parse string to coin amount
+ static bool parse(int unit, const QString &value, CAmount *val_out);
+ //! Gets title for amount column including current display unit if optionsModel reference available */
+ static QString getAmountColumnTitle(int unit);
+ ///@}
+
+ //! @name AbstractListModel implementation
+ //! List model for unit drop-down selection box.
+ ///@{
+ enum RoleIndex {
+ /** Unit identifier */
+ UnitRole = Qt::UserRole
+ };
+ int rowCount(const QModelIndex &parent) const;
+ QVariant data(const QModelIndex &index, int role) const;
+ ///@}
+
+ static QString removeSpaces(QString text)
+ {
+ text.remove(' ');
+ text.remove(QChar(THIN_SP_CP));
+#if (THIN_SP_CP != REAL_THIN_SP_CP)
+ text.remove(QChar(REAL_THIN_SP_CP));
+#endif
+ return text;
+ }
+
+ //! Return maximum number of base units (Satoshis)
+ static CAmount maxMoney();
+
+private:
+ QList<BitcoinUnits::Unit> unitlist;
+};
+typedef BitcoinUnits::Unit BitcoinUnit;
+
+#endif // BITCOIN_QT_BITCOINUNITS_H
diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp
new file mode 100644
index 0000000000..51fd443dd0
--- /dev/null
+++ b/src/qt/clientmodel.cpp
@@ -0,0 +1,243 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "clientmodel.h"
+
+#include "guiconstants.h"
+#include "peertablemodel.h"
+
+#include "alert.h"
+#include "chainparams.h"
+#include "checkpoints.h"
+#include "clientversion.h"
+#include "main.h"
+#include "net.h"
+#include "ui_interface.h"
+#include "util.h"
+
+#include <stdint.h>
+
+#include <QDebug>
+#include <QTimer>
+
+static const int64_t nClientStartupTime = GetTime();
+
+ClientModel::ClientModel(OptionsModel *optionsModel, QObject *parent) :
+ QObject(parent),
+ optionsModel(optionsModel),
+ peerTableModel(0),
+ cachedNumBlocks(0),
+ cachedBlockDate(QDateTime()),
+ cachedReindexing(0),
+ cachedImporting(0),
+ pollTimer(0)
+{
+ peerTableModel = new PeerTableModel(this);
+ pollTimer = new QTimer(this);
+ connect(pollTimer, SIGNAL(timeout()), this, SLOT(updateTimer()));
+ pollTimer->start(MODEL_UPDATE_DELAY);
+
+ subscribeToCoreSignals();
+}
+
+ClientModel::~ClientModel()
+{
+ unsubscribeFromCoreSignals();
+}
+
+int ClientModel::getNumConnections(unsigned int flags) const
+{
+ LOCK(cs_vNodes);
+ if (flags == CONNECTIONS_ALL) // Shortcut if we want total
+ return vNodes.size();
+
+ int nNum = 0;
+ BOOST_FOREACH(CNode* pnode, vNodes)
+ if (flags & (pnode->fInbound ? CONNECTIONS_IN : CONNECTIONS_OUT))
+ nNum++;
+
+ return nNum;
+}
+
+int ClientModel::getNumBlocks() const
+{
+ LOCK(cs_main);
+ return chainActive.Height();
+}
+
+quint64 ClientModel::getTotalBytesRecv() const
+{
+ return CNode::GetTotalBytesRecv();
+}
+
+quint64 ClientModel::getTotalBytesSent() const
+{
+ return CNode::GetTotalBytesSent();
+}
+
+QDateTime ClientModel::getLastBlockDate() const
+{
+ LOCK(cs_main);
+
+ if (chainActive.Tip())
+ return QDateTime::fromTime_t(chainActive.Tip()->GetBlockTime());
+
+ return QDateTime::fromTime_t(Params().GenesisBlock().GetBlockTime()); // Genesis block's time of current network
+}
+
+double ClientModel::getVerificationProgress() const
+{
+ LOCK(cs_main);
+ return Checkpoints::GuessVerificationProgress(Params().Checkpoints(), chainActive.Tip());
+}
+
+void ClientModel::updateTimer()
+{
+ // Get required lock upfront. This avoids the GUI from getting stuck on
+ // periodical polls if the core is holding the locks for a longer time -
+ // for example, during a wallet rescan.
+ TRY_LOCK(cs_main, lockMain);
+ if (!lockMain)
+ return;
+
+ // 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();
+ QDateTime newBlockDate = getLastBlockDate();
+
+ // check for changed number of blocks we have, number of blocks peers claim to have, reindexing state and importing state
+ if (cachedNumBlocks != newNumBlocks ||
+ cachedBlockDate != newBlockDate ||
+ cachedReindexing != fReindex ||
+ cachedImporting != fImporting)
+ {
+ cachedNumBlocks = newNumBlocks;
+ cachedBlockDate = newBlockDate;
+ cachedReindexing = fReindex;
+ cachedImporting = fImporting;
+
+ Q_EMIT numBlocksChanged(newNumBlocks, newBlockDate);
+ }
+
+ Q_EMIT bytesChanged(getTotalBytesRecv(), getTotalBytesSent());
+}
+
+void ClientModel::updateNumConnections(int numConnections)
+{
+ Q_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())
+ {
+ Q_EMIT message(tr("Network Alert"), QString::fromStdString(alert.strStatusBar), CClientUIInterface::ICON_ERROR);
+ }
+ }
+
+ Q_EMIT alertsChanged(getStatusBarWarnings());
+}
+
+bool ClientModel::inInitialBlockDownload() const
+{
+ return IsInitialBlockDownload();
+}
+
+enum BlockSource ClientModel::getBlockSource() const
+{
+ if (fReindex)
+ return BLOCK_SOURCE_REINDEX;
+ else if (fImporting)
+ return BLOCK_SOURCE_DISK;
+ else if (getNumConnections() > 0)
+ return BLOCK_SOURCE_NETWORK;
+
+ return BLOCK_SOURCE_NONE;
+}
+
+QString ClientModel::getStatusBarWarnings() const
+{
+ return QString::fromStdString(GetWarnings("statusbar"));
+}
+
+OptionsModel *ClientModel::getOptionsModel()
+{
+ return optionsModel;
+}
+
+PeerTableModel *ClientModel::getPeerTableModel()
+{
+ return peerTableModel;
+}
+
+QString ClientModel::formatFullVersion() const
+{
+ return QString::fromStdString(FormatFullVersion());
+}
+
+QString ClientModel::formatBuildDate() const
+{
+ return QString::fromStdString(CLIENT_DATE);
+}
+
+bool ClientModel::isReleaseVersion() const
+{
+ return CLIENT_VERSION_IS_RELEASE;
+}
+
+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 ShowProgress(ClientModel *clientmodel, const std::string &title, int nProgress)
+{
+ // emits signal "showProgress"
+ QMetaObject::invokeMethod(clientmodel, "showProgress", Qt::QueuedConnection,
+ Q_ARG(QString, QString::fromStdString(title)),
+ Q_ARG(int, nProgress));
+}
+
+static void NotifyNumConnectionsChanged(ClientModel *clientmodel, int newNumConnections)
+{
+ // Too noisy: qDebug() << "NotifyNumConnectionsChanged: " + QString::number(newNumConnections);
+ QMetaObject::invokeMethod(clientmodel, "updateNumConnections", Qt::QueuedConnection,
+ Q_ARG(int, newNumConnections));
+}
+
+static void NotifyAlertChanged(ClientModel *clientmodel, const uint256 &hash, ChangeType status)
+{
+ qDebug() << "NotifyAlertChanged: " + QString::fromStdString(hash.GetHex()) + " status=" + QString::number(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.ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2));
+ 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.ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2));
+ 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 0000000000..68434f404c
--- /dev/null
+++ b/src/qt/clientmodel.h
@@ -0,0 +1,103 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_CLIENTMODEL_H
+#define BITCOIN_QT_CLIENTMODEL_H
+
+#include <QObject>
+#include <QDateTime>
+
+class AddressTableModel;
+class OptionsModel;
+class PeerTableModel;
+class TransactionTableModel;
+
+class CWallet;
+
+QT_BEGIN_NAMESPACE
+class QTimer;
+QT_END_NAMESPACE
+
+enum BlockSource {
+ BLOCK_SOURCE_NONE,
+ BLOCK_SOURCE_REINDEX,
+ BLOCK_SOURCE_DISK,
+ BLOCK_SOURCE_NETWORK
+};
+
+enum NumConnections {
+ CONNECTIONS_NONE = 0,
+ CONNECTIONS_IN = (1U << 0),
+ CONNECTIONS_OUT = (1U << 1),
+ CONNECTIONS_ALL = (CONNECTIONS_IN | CONNECTIONS_OUT),
+};
+
+/** Model for Bitcoin network client. */
+class ClientModel : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit ClientModel(OptionsModel *optionsModel, QObject *parent = 0);
+ ~ClientModel();
+
+ OptionsModel *getOptionsModel();
+ PeerTableModel *getPeerTableModel();
+
+ //! Return number of connections, default is in- and outbound (total)
+ int getNumConnections(unsigned int flags = CONNECTIONS_ALL) const;
+ int getNumBlocks() const;
+
+ quint64 getTotalBytesRecv() const;
+ quint64 getTotalBytesSent() const;
+
+ double getVerificationProgress() const;
+ QDateTime getLastBlockDate() const;
+
+ //! Return true if core is doing initial block download
+ bool inInitialBlockDownload() const;
+ //! Return true if core is importing blocks
+ enum BlockSource getBlockSource() const;
+ //! Return warnings to be displayed in status bar
+ QString getStatusBarWarnings() const;
+
+ QString formatFullVersion() const;
+ QString formatBuildDate() const;
+ bool isReleaseVersion() const;
+ QString clientName() const;
+ QString formatClientStartupTime() const;
+
+private:
+ OptionsModel *optionsModel;
+ PeerTableModel *peerTableModel;
+
+ int cachedNumBlocks;
+ QDateTime cachedBlockDate;
+ bool cachedReindexing;
+ bool cachedImporting;
+
+ QTimer *pollTimer;
+
+ void subscribeToCoreSignals();
+ void unsubscribeFromCoreSignals();
+
+Q_SIGNALS:
+ void numConnectionsChanged(int count);
+ void numBlocksChanged(int count, const QDateTime& blockDate);
+ void alertsChanged(const QString &warnings);
+ void bytesChanged(quint64 totalBytesIn, quint64 totalBytesOut);
+
+ //! Fired when a message should be reported to the user
+ void message(const QString &title, const QString &message, unsigned int style);
+
+ // Show progress dialog e.g. for verifychain
+ void showProgress(const QString &title, int nProgress);
+
+public Q_SLOTS:
+ void updateTimer();
+ void updateNumConnections(int numConnections);
+ void updateAlert(const QString &hash, int status);
+};
+
+#endif // BITCOIN_QT_CLIENTMODEL_H
diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp
new file mode 100644
index 0000000000..6a527429e3
--- /dev/null
+++ b/src/qt/coincontroldialog.cpp
@@ -0,0 +1,828 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "coincontroldialog.h"
+#include "ui_coincontroldialog.h"
+
+#include "addresstablemodel.h"
+#include "bitcoinunits.h"
+#include "guiutil.h"
+#include "optionsmodel.h"
+#include "scicon.h"
+#include "walletmodel.h"
+
+#include "coincontrol.h"
+#include "init.h"
+#include "main.h"
+#include "wallet/wallet.h"
+
+#include <boost/assign/list_of.hpp> // for 'map_list_of()'
+
+#include <QApplication>
+#include <QCheckBox>
+#include <QCursor>
+#include <QDialogButtonBox>
+#include <QFlags>
+#include <QIcon>
+#include <QSettings>
+#include <QString>
+#include <QTreeWidget>
+#include <QTreeWidgetItem>
+
+using namespace std;
+QList<CAmount> CoinControlDialog::payAmounts;
+CCoinControl* CoinControlDialog::coinControl = new CCoinControl();
+bool CoinControlDialog::fSubtractFeeFromAmount = false;
+
+CoinControlDialog::CoinControlDialog(QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::CoinControlDialog),
+ model(0)
+{
+ ui->setupUi(this);
+
+ // context menu 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);
+ copyTransactionHashAction = new QAction(tr("Copy transaction ID"), this); // we need to enable/disable this
+ lockAction = new QAction(tr("Lock unspent"), this); // we need to enable/disable this
+ unlockAction = new QAction(tr("Unlock unspent"), this); // we need to enable/disable this
+
+ // context menu
+ contextMenu = new QMenu();
+ contextMenu->addAction(copyAddressAction);
+ contextMenu->addAction(copyLabelAction);
+ contextMenu->addAction(copyAmountAction);
+ contextMenu->addAction(copyTransactionHashAction);
+ contextMenu->addSeparator();
+ contextMenu->addAction(lockAction);
+ contextMenu->addAction(unlockAction);
+
+ // context menu signals
+ connect(ui->treeWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showMenu(QPoint)));
+ connect(copyAddressAction, SIGNAL(triggered()), this, SLOT(copyAddress()));
+ connect(copyLabelAction, SIGNAL(triggered()), this, SLOT(copyLabel()));
+ connect(copyAmountAction, SIGNAL(triggered()), this, SLOT(copyAmount()));
+ connect(copyTransactionHashAction, SIGNAL(triggered()), this, SLOT(copyTransactionHash()));
+ connect(lockAction, SIGNAL(triggered()), this, SLOT(lockCoin()));
+ connect(unlockAction, SIGNAL(triggered()), this, SLOT(unlockCoin()));
+
+ // clipboard actions
+ QAction *clipboardQuantityAction = new QAction(tr("Copy quantity"), this);
+ QAction *clipboardAmountAction = new QAction(tr("Copy amount"), this);
+ QAction *clipboardFeeAction = new QAction(tr("Copy fee"), this);
+ QAction *clipboardAfterFeeAction = new QAction(tr("Copy after fee"), this);
+ QAction *clipboardBytesAction = new QAction(tr("Copy bytes"), this);
+ QAction *clipboardPriorityAction = new QAction(tr("Copy priority"), this);
+ QAction *clipboardLowOutputAction = new QAction(tr("Copy dust"), this);
+ QAction *clipboardChangeAction = new QAction(tr("Copy change"), this);
+
+ connect(clipboardQuantityAction, SIGNAL(triggered()), this, SLOT(clipboardQuantity()));
+ connect(clipboardAmountAction, SIGNAL(triggered()), this, SLOT(clipboardAmount()));
+ connect(clipboardFeeAction, SIGNAL(triggered()), this, SLOT(clipboardFee()));
+ connect(clipboardAfterFeeAction, SIGNAL(triggered()), this, SLOT(clipboardAfterFee()));
+ connect(clipboardBytesAction, SIGNAL(triggered()), this, SLOT(clipboardBytes()));
+ connect(clipboardPriorityAction, SIGNAL(triggered()), this, SLOT(clipboardPriority()));
+ connect(clipboardLowOutputAction, SIGNAL(triggered()), this, SLOT(clipboardLowOutput()));
+ connect(clipboardChangeAction, SIGNAL(triggered()), this, SLOT(clipboardChange()));
+
+ ui->labelCoinControlQuantity->addAction(clipboardQuantityAction);
+ ui->labelCoinControlAmount->addAction(clipboardAmountAction);
+ ui->labelCoinControlFee->addAction(clipboardFeeAction);
+ ui->labelCoinControlAfterFee->addAction(clipboardAfterFeeAction);
+ ui->labelCoinControlBytes->addAction(clipboardBytesAction);
+ ui->labelCoinControlPriority->addAction(clipboardPriorityAction);
+ ui->labelCoinControlLowOutput->addAction(clipboardLowOutputAction);
+ ui->labelCoinControlChange->addAction(clipboardChangeAction);
+
+ // toggle tree/list mode
+ connect(ui->radioTreeMode, SIGNAL(toggled(bool)), this, SLOT(radioTreeMode(bool)));
+ connect(ui->radioListMode, SIGNAL(toggled(bool)), this, SLOT(radioListMode(bool)));
+
+ // click on checkbox
+ connect(ui->treeWidget, SIGNAL(itemChanged(QTreeWidgetItem*, int)), this, SLOT(viewItemChanged(QTreeWidgetItem*, int)));
+
+ // click on header
+#if QT_VERSION < 0x050000
+ ui->treeWidget->header()->setClickable(true);
+#else
+ ui->treeWidget->header()->setSectionsClickable(true);
+#endif
+ connect(ui->treeWidget->header(), SIGNAL(sectionClicked(int)), this, SLOT(headerSectionClicked(int)));
+
+ // ok button
+ connect(ui->buttonBox, SIGNAL(clicked( QAbstractButton*)), this, SLOT(buttonBoxClicked(QAbstractButton*)));
+
+ // (un)select all
+ connect(ui->pushButtonSelectAll, SIGNAL(clicked()), this, SLOT(buttonSelectAllClicked()));
+
+ // change coin control first column label due Qt4 bug.
+ // see https://github.com/bitcoin/bitcoin/issues/5716
+ ui->treeWidget->headerItem()->setText(COLUMN_CHECKBOX, QString());
+
+ ui->treeWidget->setColumnWidth(COLUMN_CHECKBOX, 84);
+ ui->treeWidget->setColumnWidth(COLUMN_AMOUNT, 100);
+ ui->treeWidget->setColumnWidth(COLUMN_LABEL, 170);
+ ui->treeWidget->setColumnWidth(COLUMN_ADDRESS, 290);
+ ui->treeWidget->setColumnWidth(COLUMN_DATE, 110);
+ ui->treeWidget->setColumnWidth(COLUMN_CONFIRMATIONS, 100);
+ ui->treeWidget->setColumnWidth(COLUMN_PRIORITY, 100);
+ ui->treeWidget->setColumnHidden(COLUMN_TXHASH, true); // store transacton hash in this column, but don't show it
+ ui->treeWidget->setColumnHidden(COLUMN_VOUT_INDEX, true); // store vout index in this column, but don't show it
+ ui->treeWidget->setColumnHidden(COLUMN_AMOUNT_INT64, true); // store amount int64 in this column, but don't show it
+ ui->treeWidget->setColumnHidden(COLUMN_PRIORITY_INT64, true); // store priority int64 in this column, but don't show it
+ ui->treeWidget->setColumnHidden(COLUMN_DATE_INT64, true); // store date int64 in this column, but don't show it
+
+ // default view is sorted by amount desc
+ sortView(COLUMN_AMOUNT_INT64, Qt::DescendingOrder);
+
+ // restore list mode and sortorder as a convenience feature
+ QSettings settings;
+ if (settings.contains("nCoinControlMode") && !settings.value("nCoinControlMode").toBool())
+ ui->radioTreeMode->click();
+ if (settings.contains("nCoinControlSortColumn") && settings.contains("nCoinControlSortOrder"))
+ sortView(settings.value("nCoinControlSortColumn").toInt(), ((Qt::SortOrder)settings.value("nCoinControlSortOrder").toInt()));
+}
+
+CoinControlDialog::~CoinControlDialog()
+{
+ QSettings settings;
+ settings.setValue("nCoinControlMode", ui->radioListMode->isChecked());
+ settings.setValue("nCoinControlSortColumn", sortColumn);
+ settings.setValue("nCoinControlSortOrder", (int)sortOrder);
+
+ delete ui;
+}
+
+void CoinControlDialog::setModel(WalletModel *model)
+{
+ this->model = model;
+
+ if(model && model->getOptionsModel() && model->getAddressTableModel())
+ {
+ updateView();
+ updateLabelLocked();
+ CoinControlDialog::updateLabels(model, this);
+ }
+}
+
+// helper function str_pad
+QString CoinControlDialog::strPad(QString s, int nPadLength, QString sPadding)
+{
+ while (s.length() < nPadLength)
+ s = sPadding + s;
+
+ return s;
+}
+
+// ok button
+void CoinControlDialog::buttonBoxClicked(QAbstractButton* button)
+{
+ if (ui->buttonBox->buttonRole(button) == QDialogButtonBox::AcceptRole)
+ done(QDialog::Accepted); // closes the dialog
+}
+
+// (un)select all
+void CoinControlDialog::buttonSelectAllClicked()
+{
+ Qt::CheckState state = Qt::Checked;
+ for (int i = 0; i < ui->treeWidget->topLevelItemCount(); i++)
+ {
+ if (ui->treeWidget->topLevelItem(i)->checkState(COLUMN_CHECKBOX) != Qt::Unchecked)
+ {
+ state = Qt::Unchecked;
+ break;
+ }
+ }
+ ui->treeWidget->setEnabled(false);
+ for (int i = 0; i < ui->treeWidget->topLevelItemCount(); i++)
+ if (ui->treeWidget->topLevelItem(i)->checkState(COLUMN_CHECKBOX) != state)
+ ui->treeWidget->topLevelItem(i)->setCheckState(COLUMN_CHECKBOX, state);
+ ui->treeWidget->setEnabled(true);
+ if (state == Qt::Unchecked)
+ coinControl->UnSelectAll(); // just to be sure
+ CoinControlDialog::updateLabels(model, this);
+}
+
+// context menu
+void CoinControlDialog::showMenu(const QPoint &point)
+{
+ QTreeWidgetItem *item = ui->treeWidget->itemAt(point);
+ if(item)
+ {
+ contextMenuItem = item;
+
+ // disable some items (like Copy Transaction ID, lock, unlock) for tree roots in context menu
+ if (item->text(COLUMN_TXHASH).length() == 64) // transaction hash is 64 characters (this means its a child node, so its not a parent node in tree mode)
+ {
+ copyTransactionHashAction->setEnabled(true);
+ if (model->isLockedCoin(uint256S(item->text(COLUMN_TXHASH).toStdString()), item->text(COLUMN_VOUT_INDEX).toUInt()))
+ {
+ lockAction->setEnabled(false);
+ unlockAction->setEnabled(true);
+ }
+ else
+ {
+ lockAction->setEnabled(true);
+ unlockAction->setEnabled(false);
+ }
+ }
+ else // this means click on parent node in tree mode -> disable all
+ {
+ copyTransactionHashAction->setEnabled(false);
+ lockAction->setEnabled(false);
+ unlockAction->setEnabled(false);
+ }
+
+ // show context menu
+ contextMenu->exec(QCursor::pos());
+ }
+}
+
+// context menu action: copy amount
+void CoinControlDialog::copyAmount()
+{
+ GUIUtil::setClipboard(BitcoinUnits::removeSpaces(contextMenuItem->text(COLUMN_AMOUNT)));
+}
+
+// context menu action: copy label
+void CoinControlDialog::copyLabel()
+{
+ if (ui->radioTreeMode->isChecked() && contextMenuItem->text(COLUMN_LABEL).length() == 0 && contextMenuItem->parent())
+ GUIUtil::setClipboard(contextMenuItem->parent()->text(COLUMN_LABEL));
+ else
+ GUIUtil::setClipboard(contextMenuItem->text(COLUMN_LABEL));
+}
+
+// context menu action: copy address
+void CoinControlDialog::copyAddress()
+{
+ if (ui->radioTreeMode->isChecked() && contextMenuItem->text(COLUMN_ADDRESS).length() == 0 && contextMenuItem->parent())
+ GUIUtil::setClipboard(contextMenuItem->parent()->text(COLUMN_ADDRESS));
+ else
+ GUIUtil::setClipboard(contextMenuItem->text(COLUMN_ADDRESS));
+}
+
+// context menu action: copy transaction id
+void CoinControlDialog::copyTransactionHash()
+{
+ GUIUtil::setClipboard(contextMenuItem->text(COLUMN_TXHASH));
+}
+
+// context menu action: lock coin
+void CoinControlDialog::lockCoin()
+{
+ if (contextMenuItem->checkState(COLUMN_CHECKBOX) == Qt::Checked)
+ contextMenuItem->setCheckState(COLUMN_CHECKBOX, Qt::Unchecked);
+
+ COutPoint outpt(uint256S(contextMenuItem->text(COLUMN_TXHASH).toStdString()), contextMenuItem->text(COLUMN_VOUT_INDEX).toUInt());
+ model->lockCoin(outpt);
+ contextMenuItem->setDisabled(true);
+ contextMenuItem->setIcon(COLUMN_CHECKBOX, SingleColorIcon(":/icons/lock_closed"));
+ updateLabelLocked();
+}
+
+// context menu action: unlock coin
+void CoinControlDialog::unlockCoin()
+{
+ COutPoint outpt(uint256S(contextMenuItem->text(COLUMN_TXHASH).toStdString()), contextMenuItem->text(COLUMN_VOUT_INDEX).toUInt());
+ model->unlockCoin(outpt);
+ contextMenuItem->setDisabled(false);
+ contextMenuItem->setIcon(COLUMN_CHECKBOX, QIcon());
+ updateLabelLocked();
+}
+
+// copy label "Quantity" to clipboard
+void CoinControlDialog::clipboardQuantity()
+{
+ GUIUtil::setClipboard(ui->labelCoinControlQuantity->text());
+}
+
+// copy label "Amount" to clipboard
+void CoinControlDialog::clipboardAmount()
+{
+ GUIUtil::setClipboard(ui->labelCoinControlAmount->text().left(ui->labelCoinControlAmount->text().indexOf(" ")));
+}
+
+// copy label "Fee" to clipboard
+void CoinControlDialog::clipboardFee()
+{
+ GUIUtil::setClipboard(ui->labelCoinControlFee->text().left(ui->labelCoinControlFee->text().indexOf(" ")).replace(ASYMP_UTF8, ""));
+}
+
+// copy label "After fee" to clipboard
+void CoinControlDialog::clipboardAfterFee()
+{
+ GUIUtil::setClipboard(ui->labelCoinControlAfterFee->text().left(ui->labelCoinControlAfterFee->text().indexOf(" ")).replace(ASYMP_UTF8, ""));
+}
+
+// copy label "Bytes" to clipboard
+void CoinControlDialog::clipboardBytes()
+{
+ GUIUtil::setClipboard(ui->labelCoinControlBytes->text().replace(ASYMP_UTF8, ""));
+}
+
+// copy label "Priority" to clipboard
+void CoinControlDialog::clipboardPriority()
+{
+ GUIUtil::setClipboard(ui->labelCoinControlPriority->text());
+}
+
+// copy label "Dust" to clipboard
+void CoinControlDialog::clipboardLowOutput()
+{
+ GUIUtil::setClipboard(ui->labelCoinControlLowOutput->text());
+}
+
+// copy label "Change" to clipboard
+void CoinControlDialog::clipboardChange()
+{
+ GUIUtil::setClipboard(ui->labelCoinControlChange->text().left(ui->labelCoinControlChange->text().indexOf(" ")).replace(ASYMP_UTF8, ""));
+}
+
+// treeview: sort
+void CoinControlDialog::sortView(int column, Qt::SortOrder order)
+{
+ sortColumn = column;
+ sortOrder = order;
+ ui->treeWidget->sortItems(column, order);
+ ui->treeWidget->header()->setSortIndicator(getMappedColumn(sortColumn), sortOrder);
+}
+
+// treeview: clicked on header
+void CoinControlDialog::headerSectionClicked(int logicalIndex)
+{
+ if (logicalIndex == COLUMN_CHECKBOX) // click on most left column -> do nothing
+ {
+ ui->treeWidget->header()->setSortIndicator(getMappedColumn(sortColumn), sortOrder);
+ }
+ else
+ {
+ logicalIndex = getMappedColumn(logicalIndex, false);
+
+ if (sortColumn == logicalIndex)
+ sortOrder = ((sortOrder == Qt::AscendingOrder) ? Qt::DescendingOrder : Qt::AscendingOrder);
+ else
+ {
+ sortColumn = logicalIndex;
+ sortOrder = ((sortColumn == COLUMN_LABEL || sortColumn == COLUMN_ADDRESS) ? Qt::AscendingOrder : Qt::DescendingOrder); // if label or address then default => asc, else default => desc
+ }
+
+ sortView(sortColumn, sortOrder);
+ }
+}
+
+// toggle tree mode
+void CoinControlDialog::radioTreeMode(bool checked)
+{
+ if (checked && model)
+ updateView();
+}
+
+// toggle list mode
+void CoinControlDialog::radioListMode(bool checked)
+{
+ if (checked && model)
+ updateView();
+}
+
+// checkbox clicked by user
+void CoinControlDialog::viewItemChanged(QTreeWidgetItem* item, int column)
+{
+ if (column == COLUMN_CHECKBOX && item->text(COLUMN_TXHASH).length() == 64) // transaction hash is 64 characters (this means its a child node, so its not a parent node in tree mode)
+ {
+ COutPoint outpt(uint256S(item->text(COLUMN_TXHASH).toStdString()), item->text(COLUMN_VOUT_INDEX).toUInt());
+
+ if (item->checkState(COLUMN_CHECKBOX) == Qt::Unchecked)
+ coinControl->UnSelect(outpt);
+ else if (item->isDisabled()) // locked (this happens if "check all" through parent node)
+ item->setCheckState(COLUMN_CHECKBOX, Qt::Unchecked);
+ else
+ coinControl->Select(outpt);
+
+ // selection changed -> update labels
+ if (ui->treeWidget->isEnabled()) // do not update on every click for (un)select all
+ CoinControlDialog::updateLabels(model, this);
+ }
+
+ // todo: this is a temporary qt5 fix: when clicking a parent node in tree mode, the parent node
+ // including all children are partially selected. But the parent node should be fully selected
+ // as well as the children. Children should never be partially selected in the first place.
+ // Please remove this ugly fix, once the bug is solved upstream.
+#if QT_VERSION >= 0x050000
+ else if (column == COLUMN_CHECKBOX && item->childCount() > 0)
+ {
+ if (item->checkState(COLUMN_CHECKBOX) == Qt::PartiallyChecked && item->child(0)->checkState(COLUMN_CHECKBOX) == Qt::PartiallyChecked)
+ item->setCheckState(COLUMN_CHECKBOX, Qt::Checked);
+ }
+#endif
+}
+
+// return human readable label for priority number
+QString CoinControlDialog::getPriorityLabel(double dPriority, double mempoolEstimatePriority)
+{
+ double dPriorityMedium = mempoolEstimatePriority;
+
+ if (dPriorityMedium <= 0)
+ dPriorityMedium = AllowFreeThreshold(); // not enough data, back to hard-coded
+
+ if (dPriority / 1000000 > dPriorityMedium) return tr("highest");
+ else if (dPriority / 100000 > dPriorityMedium) return tr("higher");
+ else if (dPriority / 10000 > dPriorityMedium) return tr("high");
+ else if (dPriority / 1000 > dPriorityMedium) return tr("medium-high");
+ else if (dPriority > dPriorityMedium) return tr("medium");
+ else if (dPriority * 10 > dPriorityMedium) return tr("low-medium");
+ else if (dPriority * 100 > dPriorityMedium) return tr("low");
+ else if (dPriority * 1000 > dPriorityMedium) return tr("lower");
+ else return tr("lowest");
+}
+
+// shows count of locked unspent outputs
+void CoinControlDialog::updateLabelLocked()
+{
+ vector<COutPoint> vOutpts;
+ model->listLockedCoins(vOutpts);
+ if (vOutpts.size() > 0)
+ {
+ ui->labelLocked->setText(tr("(%1 locked)").arg(vOutpts.size()));
+ ui->labelLocked->setVisible(true);
+ }
+ else ui->labelLocked->setVisible(false);
+}
+
+void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
+{
+ if (!model)
+ return;
+
+ // nPayAmount
+ CAmount nPayAmount = 0;
+ bool fDust = false;
+ CMutableTransaction txDummy;
+ Q_FOREACH(const CAmount &amount, CoinControlDialog::payAmounts)
+ {
+ nPayAmount += amount;
+
+ if (amount > 0)
+ {
+ CTxOut txout(amount, (CScript)vector<unsigned char>(24, 0));
+ txDummy.vout.push_back(txout);
+ if (txout.IsDust(::minRelayTxFee))
+ fDust = true;
+ }
+ }
+
+ QString sPriorityLabel = tr("none");
+ CAmount nAmount = 0;
+ CAmount nPayFee = 0;
+ CAmount nAfterFee = 0;
+ CAmount nChange = 0;
+ unsigned int nBytes = 0;
+ unsigned int nBytesInputs = 0;
+ double dPriority = 0;
+ double dPriorityInputs = 0;
+ unsigned int nQuantity = 0;
+ int nQuantityUncompressed = 0;
+ bool fAllowFree = false;
+
+ vector<COutPoint> vCoinControl;
+ vector<COutput> vOutputs;
+ coinControl->ListSelected(vCoinControl);
+ model->getOutputs(vCoinControl, vOutputs);
+
+ BOOST_FOREACH(const COutput& out, vOutputs)
+ {
+ // unselect already spent, very unlikely scenario, this could happen
+ // when selected are spent elsewhere, like rpc or another computer
+ uint256 txhash = out.tx->GetHash();
+ COutPoint outpt(txhash, out.i);
+ if (model->isSpent(outpt))
+ {
+ coinControl->UnSelect(outpt);
+ continue;
+ }
+
+ // Quantity
+ nQuantity++;
+
+ // Amount
+ nAmount += out.tx->vout[out.i].nValue;
+
+ // Priority
+ dPriorityInputs += (double)out.tx->vout[out.i].nValue * (out.nDepth+1);
+
+ // Bytes
+ CTxDestination address;
+ if(ExtractDestination(out.tx->vout[out.i].scriptPubKey, address))
+ {
+ CPubKey pubkey;
+ CKeyID *keyid = boost::get<CKeyID>(&address);
+ if (keyid && model->getPubKey(*keyid, pubkey))
+ {
+ nBytesInputs += (pubkey.IsCompressed() ? 148 : 180);
+ if (!pubkey.IsCompressed())
+ nQuantityUncompressed++;
+ }
+ else
+ nBytesInputs += 148; // in all error cases, simply assume 148 here
+ }
+ else nBytesInputs += 148;
+ }
+
+ // calculation
+ if (nQuantity > 0)
+ {
+ // Bytes
+ nBytes = nBytesInputs + ((CoinControlDialog::payAmounts.size() > 0 ? CoinControlDialog::payAmounts.size() + 1 : 2) * 34) + 10; // always assume +1 output for change here
+
+ // Priority
+ double mempoolEstimatePriority = mempool.estimatePriority(nTxConfirmTarget);
+ dPriority = dPriorityInputs / (nBytes - nBytesInputs + (nQuantityUncompressed * 29)); // 29 = 180 - 151 (uncompressed public keys are over the limit. max 151 bytes of the input are ignored for priority)
+ sPriorityLabel = CoinControlDialog::getPriorityLabel(dPriority, mempoolEstimatePriority);
+
+ // in the subtract fee from amount case, we can tell if zero change already and subtract the bytes, so that fee calculation afterwards is accurate
+ if (CoinControlDialog::fSubtractFeeFromAmount)
+ if (nAmount - nPayAmount == 0)
+ nBytes -= 34;
+
+ // Fee
+ nPayFee = CWallet::GetMinimumFee(nBytes, nTxConfirmTarget, mempool);
+
+ // Allow free?
+ double dPriorityNeeded = mempoolEstimatePriority;
+ if (dPriorityNeeded <= 0)
+ dPriorityNeeded = AllowFreeThreshold(); // not enough data, back to hard-coded
+ fAllowFree = (dPriority >= dPriorityNeeded);
+
+ if (fSendFreeTransactions)
+ if (fAllowFree && nBytes <= MAX_FREE_TRANSACTION_CREATE_SIZE)
+ nPayFee = 0;
+
+ if (nPayAmount > 0)
+ {
+ nChange = nAmount - nPayAmount;
+ if (!CoinControlDialog::fSubtractFeeFromAmount)
+ nChange -= nPayFee;
+
+ // Never create dust outputs; if we would, just add the dust to the fee.
+ if (nChange > 0 && nChange < CENT)
+ {
+ CTxOut txout(nChange, (CScript)vector<unsigned char>(24, 0));
+ if (txout.IsDust(::minRelayTxFee))
+ {
+ if (CoinControlDialog::fSubtractFeeFromAmount) // dust-change will be raised until no dust
+ nChange = txout.GetDustThreshold(::minRelayTxFee);
+ else
+ {
+ nPayFee += nChange;
+ nChange = 0;
+ }
+ }
+ }
+
+ if (nChange == 0 && !CoinControlDialog::fSubtractFeeFromAmount)
+ nBytes -= 34;
+ }
+
+ // after fee
+ nAfterFee = nAmount - nPayFee;
+ if (nAfterFee < 0)
+ nAfterFee = 0;
+ }
+
+ // actually update labels
+ int nDisplayUnit = BitcoinUnits::BTC;
+ if (model && model->getOptionsModel())
+ nDisplayUnit = model->getOptionsModel()->getDisplayUnit();
+
+ QLabel *l1 = dialog->findChild<QLabel *>("labelCoinControlQuantity");
+ QLabel *l2 = dialog->findChild<QLabel *>("labelCoinControlAmount");
+ QLabel *l3 = dialog->findChild<QLabel *>("labelCoinControlFee");
+ QLabel *l4 = dialog->findChild<QLabel *>("labelCoinControlAfterFee");
+ QLabel *l5 = dialog->findChild<QLabel *>("labelCoinControlBytes");
+ QLabel *l6 = dialog->findChild<QLabel *>("labelCoinControlPriority");
+ QLabel *l7 = dialog->findChild<QLabel *>("labelCoinControlLowOutput");
+ QLabel *l8 = dialog->findChild<QLabel *>("labelCoinControlChange");
+
+ // enable/disable "dust" and "change"
+ dialog->findChild<QLabel *>("labelCoinControlLowOutputText")->setEnabled(nPayAmount > 0);
+ dialog->findChild<QLabel *>("labelCoinControlLowOutput") ->setEnabled(nPayAmount > 0);
+ dialog->findChild<QLabel *>("labelCoinControlChangeText") ->setEnabled(nPayAmount > 0);
+ dialog->findChild<QLabel *>("labelCoinControlChange") ->setEnabled(nPayAmount > 0);
+
+ // stats
+ l1->setText(QString::number(nQuantity)); // Quantity
+ l2->setText(BitcoinUnits::formatWithUnit(nDisplayUnit, nAmount)); // Amount
+ l3->setText(BitcoinUnits::formatWithUnit(nDisplayUnit, nPayFee)); // Fee
+ l4->setText(BitcoinUnits::formatWithUnit(nDisplayUnit, nAfterFee)); // After Fee
+ l5->setText(((nBytes > 0) ? ASYMP_UTF8 : "") + QString::number(nBytes)); // Bytes
+ l6->setText(sPriorityLabel); // Priority
+ l7->setText(fDust ? tr("yes") : tr("no")); // Dust
+ l8->setText(BitcoinUnits::formatWithUnit(nDisplayUnit, nChange)); // Change
+ if (nPayFee > 0 && !(payTxFee.GetFeePerK() > 0 && fPayAtLeastCustomFee && nBytes < 1000))
+ {
+ l3->setText(ASYMP_UTF8 + l3->text());
+ l4->setText(ASYMP_UTF8 + l4->text());
+ if (nChange > 0 && !CoinControlDialog::fSubtractFeeFromAmount)
+ l8->setText(ASYMP_UTF8 + l8->text());
+ }
+
+ // turn labels "red"
+ l5->setStyleSheet((nBytes >= MAX_FREE_TRANSACTION_CREATE_SIZE) ? "color:red;" : "");// Bytes >= 1000
+ l6->setStyleSheet((dPriority > 0 && !fAllowFree) ? "color:red;" : ""); // Priority < "medium"
+ l7->setStyleSheet((fDust) ? "color:red;" : ""); // Dust = "yes"
+
+ // tool tips
+ QString toolTip1 = tr("This label turns red if the transaction size is greater than 1000 bytes.") + "<br /><br />";
+ toolTip1 += tr("This means a fee of at least %1 per kB is required.").arg(BitcoinUnits::formatWithUnit(nDisplayUnit, CWallet::minTxFee.GetFeePerK())) + "<br /><br />";
+ toolTip1 += tr("Can vary +/- 1 byte per input.");
+
+ QString toolTip2 = tr("Transactions with higher priority are more likely to get included into a block.") + "<br /><br />";
+ toolTip2 += tr("This label turns red if the priority is smaller than \"medium\".") + "<br /><br />";
+ toolTip2 += tr("This means a fee of at least %1 per kB is required.").arg(BitcoinUnits::formatWithUnit(nDisplayUnit, CWallet::minTxFee.GetFeePerK()));
+
+ QString toolTip3 = tr("This label turns red if any recipient receives an amount smaller than %1.").arg(BitcoinUnits::formatWithUnit(nDisplayUnit, ::minRelayTxFee.GetFee(546)));
+
+ // how many satoshis the estimated fee can vary per byte we guess wrong
+ double dFeeVary;
+ if (payTxFee.GetFeePerK() > 0)
+ dFeeVary = (double)std::max(CWallet::minTxFee.GetFeePerK(), payTxFee.GetFeePerK()) / 1000;
+ else
+ dFeeVary = (double)std::max(CWallet::minTxFee.GetFeePerK(), mempool.estimateFee(nTxConfirmTarget).GetFeePerK()) / 1000;
+ QString toolTip4 = tr("Can vary +/- %1 satoshi(s) per input.").arg(dFeeVary);
+
+ l3->setToolTip(toolTip4);
+ l4->setToolTip(toolTip4);
+ l5->setToolTip(toolTip1);
+ l6->setToolTip(toolTip2);
+ l7->setToolTip(toolTip3);
+ l8->setToolTip(toolTip4);
+ dialog->findChild<QLabel *>("labelCoinControlFeeText") ->setToolTip(l3->toolTip());
+ dialog->findChild<QLabel *>("labelCoinControlAfterFeeText") ->setToolTip(l4->toolTip());
+ dialog->findChild<QLabel *>("labelCoinControlBytesText") ->setToolTip(l5->toolTip());
+ dialog->findChild<QLabel *>("labelCoinControlPriorityText") ->setToolTip(l6->toolTip());
+ dialog->findChild<QLabel *>("labelCoinControlLowOutputText")->setToolTip(l7->toolTip());
+ dialog->findChild<QLabel *>("labelCoinControlChangeText") ->setToolTip(l8->toolTip());
+
+ // Insufficient funds
+ QLabel *label = dialog->findChild<QLabel *>("labelCoinControlInsuffFunds");
+ if (label)
+ label->setVisible(nChange < 0);
+}
+
+void CoinControlDialog::updateView()
+{
+ if (!model || !model->getOptionsModel() || !model->getAddressTableModel())
+ return;
+
+ bool treeMode = ui->radioTreeMode->isChecked();
+
+ ui->treeWidget->clear();
+ ui->treeWidget->setEnabled(false); // performance, otherwise updateLabels would be called for every checked checkbox
+ ui->treeWidget->setAlternatingRowColors(!treeMode);
+ QFlags<Qt::ItemFlag> flgCheckbox = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable;
+ QFlags<Qt::ItemFlag> flgTristate = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsTristate;
+
+ int nDisplayUnit = model->getOptionsModel()->getDisplayUnit();
+ double mempoolEstimatePriority = mempool.estimatePriority(nTxConfirmTarget);
+
+ map<QString, vector<COutput> > mapCoins;
+ model->listCoins(mapCoins);
+
+ BOOST_FOREACH(PAIRTYPE(QString, vector<COutput>) coins, mapCoins)
+ {
+ QTreeWidgetItem *itemWalletAddress = new QTreeWidgetItem();
+ itemWalletAddress->setCheckState(COLUMN_CHECKBOX, Qt::Unchecked);
+ QString sWalletAddress = coins.first;
+ QString sWalletLabel = model->getAddressTableModel()->labelForAddress(sWalletAddress);
+ if (sWalletLabel.isEmpty())
+ sWalletLabel = tr("(no label)");
+
+ if (treeMode)
+ {
+ // wallet address
+ ui->treeWidget->addTopLevelItem(itemWalletAddress);
+
+ itemWalletAddress->setFlags(flgTristate);
+ itemWalletAddress->setCheckState(COLUMN_CHECKBOX, Qt::Unchecked);
+
+ // label
+ itemWalletAddress->setText(COLUMN_LABEL, sWalletLabel);
+
+ // address
+ itemWalletAddress->setText(COLUMN_ADDRESS, sWalletAddress);
+ }
+
+ CAmount nSum = 0;
+ double dPrioritySum = 0;
+ int nChildren = 0;
+ int nInputSum = 0;
+ BOOST_FOREACH(const COutput& out, coins.second)
+ {
+ int nInputSize = 0;
+ nSum += out.tx->vout[out.i].nValue;
+ nChildren++;
+
+ QTreeWidgetItem *itemOutput;
+ if (treeMode) itemOutput = new QTreeWidgetItem(itemWalletAddress);
+ else itemOutput = new QTreeWidgetItem(ui->treeWidget);
+ itemOutput->setFlags(flgCheckbox);
+ itemOutput->setCheckState(COLUMN_CHECKBOX,Qt::Unchecked);
+
+ // address
+ CTxDestination outputAddress;
+ QString sAddress = "";
+ if(ExtractDestination(out.tx->vout[out.i].scriptPubKey, outputAddress))
+ {
+ sAddress = QString::fromStdString(CBitcoinAddress(outputAddress).ToString());
+
+ // if listMode or change => show bitcoin address. In tree mode, address is not shown again for direct wallet address outputs
+ if (!treeMode || (!(sAddress == sWalletAddress)))
+ itemOutput->setText(COLUMN_ADDRESS, sAddress);
+
+ CPubKey pubkey;
+ CKeyID *keyid = boost::get<CKeyID>(&outputAddress);
+ if (keyid && model->getPubKey(*keyid, pubkey) && !pubkey.IsCompressed())
+ nInputSize = 29; // 29 = 180 - 151 (public key is 180 bytes, priority free area is 151 bytes)
+ }
+
+ // label
+ if (!(sAddress == sWalletAddress)) // change
+ {
+ // tooltip from where the change comes from
+ itemOutput->setToolTip(COLUMN_LABEL, tr("change from %1 (%2)").arg(sWalletLabel).arg(sWalletAddress));
+ itemOutput->setText(COLUMN_LABEL, tr("(change)"));
+ }
+ else if (!treeMode)
+ {
+ QString sLabel = model->getAddressTableModel()->labelForAddress(sAddress);
+ if (sLabel.isEmpty())
+ sLabel = tr("(no label)");
+ itemOutput->setText(COLUMN_LABEL, sLabel);
+ }
+
+ // amount
+ itemOutput->setText(COLUMN_AMOUNT, BitcoinUnits::format(nDisplayUnit, out.tx->vout[out.i].nValue));
+ itemOutput->setText(COLUMN_AMOUNT_INT64, strPad(QString::number(out.tx->vout[out.i].nValue), 15, " ")); // padding so that sorting works correctly
+
+ // date
+ itemOutput->setText(COLUMN_DATE, GUIUtil::dateTimeStr(out.tx->GetTxTime()));
+ itemOutput->setText(COLUMN_DATE_INT64, strPad(QString::number(out.tx->GetTxTime()), 20, " "));
+
+ // confirmations
+ itemOutput->setText(COLUMN_CONFIRMATIONS, strPad(QString::number(out.nDepth), 8, " "));
+
+ // priority
+ double dPriority = ((double)out.tx->vout[out.i].nValue / (nInputSize + 78)) * (out.nDepth+1); // 78 = 2 * 34 + 10
+ itemOutput->setText(COLUMN_PRIORITY, CoinControlDialog::getPriorityLabel(dPriority, mempoolEstimatePriority));
+ itemOutput->setText(COLUMN_PRIORITY_INT64, strPad(QString::number((int64_t)dPriority), 20, " "));
+ dPrioritySum += (double)out.tx->vout[out.i].nValue * (out.nDepth+1);
+ nInputSum += nInputSize;
+
+ // transaction hash
+ uint256 txhash = out.tx->GetHash();
+ itemOutput->setText(COLUMN_TXHASH, QString::fromStdString(txhash.GetHex()));
+
+ // vout index
+ itemOutput->setText(COLUMN_VOUT_INDEX, QString::number(out.i));
+
+ // disable locked coins
+ if (model->isLockedCoin(txhash, out.i))
+ {
+ COutPoint outpt(txhash, out.i);
+ coinControl->UnSelect(outpt); // just to be sure
+ itemOutput->setDisabled(true);
+ itemOutput->setIcon(COLUMN_CHECKBOX, SingleColorIcon(":/icons/lock_closed"));
+ }
+
+ // set checkbox
+ if (coinControl->IsSelected(txhash, out.i))
+ itemOutput->setCheckState(COLUMN_CHECKBOX, Qt::Checked);
+ }
+
+ // amount
+ if (treeMode)
+ {
+ dPrioritySum = dPrioritySum / (nInputSum + 78);
+ itemWalletAddress->setText(COLUMN_CHECKBOX, "(" + QString::number(nChildren) + ")");
+ itemWalletAddress->setText(COLUMN_AMOUNT, BitcoinUnits::format(nDisplayUnit, nSum));
+ itemWalletAddress->setText(COLUMN_AMOUNT_INT64, strPad(QString::number(nSum), 15, " "));
+ itemWalletAddress->setText(COLUMN_PRIORITY, CoinControlDialog::getPriorityLabel(dPrioritySum, mempoolEstimatePriority));
+ itemWalletAddress->setText(COLUMN_PRIORITY_INT64, strPad(QString::number((int64_t)dPrioritySum), 20, " "));
+ }
+ }
+
+ // expand all partially selected
+ if (treeMode)
+ {
+ for (int i = 0; i < ui->treeWidget->topLevelItemCount(); i++)
+ if (ui->treeWidget->topLevelItem(i)->checkState(COLUMN_CHECKBOX) == Qt::PartiallyChecked)
+ ui->treeWidget->topLevelItem(i)->setExpanded(true);
+ }
+
+ // sort view
+ sortView(sortColumn, sortOrder);
+ ui->treeWidget->setEnabled(true);
+}
diff --git a/src/qt/coincontroldialog.h b/src/qt/coincontroldialog.h
new file mode 100644
index 0000000000..0566b02c96
--- /dev/null
+++ b/src/qt/coincontroldialog.h
@@ -0,0 +1,130 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_COINCONTROLDIALOG_H
+#define BITCOIN_QT_COINCONTROLDIALOG_H
+
+#include "amount.h"
+
+#include <QAbstractButton>
+#include <QAction>
+#include <QDialog>
+#include <QList>
+#include <QMenu>
+#include <QPoint>
+#include <QString>
+#include <QTreeWidgetItem>
+
+class WalletModel;
+
+class CCoinControl;
+class CTxMemPool;
+
+namespace Ui {
+ class CoinControlDialog;
+}
+
+#define ASYMP_UTF8 "\xE2\x89\x88"
+
+class CoinControlDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit CoinControlDialog(QWidget *parent = 0);
+ ~CoinControlDialog();
+
+ void setModel(WalletModel *model);
+
+ // static because also called from sendcoinsdialog
+ static void updateLabels(WalletModel*, QDialog*);
+ static QString getPriorityLabel(double dPriority, double mempoolEstimatePriority);
+
+ static QList<CAmount> payAmounts;
+ static CCoinControl *coinControl;
+ static bool fSubtractFeeFromAmount;
+
+private:
+ Ui::CoinControlDialog *ui;
+ WalletModel *model;
+ int sortColumn;
+ Qt::SortOrder sortOrder;
+
+ QMenu *contextMenu;
+ QTreeWidgetItem *contextMenuItem;
+ QAction *copyTransactionHashAction;
+ QAction *lockAction;
+ QAction *unlockAction;
+
+ QString strPad(QString, int, QString);
+ void sortView(int, Qt::SortOrder);
+ void updateView();
+
+ enum
+ {
+ COLUMN_CHECKBOX,
+ COLUMN_AMOUNT,
+ COLUMN_LABEL,
+ COLUMN_ADDRESS,
+ COLUMN_DATE,
+ COLUMN_CONFIRMATIONS,
+ COLUMN_PRIORITY,
+ COLUMN_TXHASH,
+ COLUMN_VOUT_INDEX,
+ COLUMN_AMOUNT_INT64,
+ COLUMN_PRIORITY_INT64,
+ COLUMN_DATE_INT64
+ };
+
+ // some columns have a hidden column containing the value used for sorting
+ int getMappedColumn(int column, bool fVisibleColumn = true)
+ {
+ if (fVisibleColumn)
+ {
+ if (column == COLUMN_AMOUNT_INT64)
+ return COLUMN_AMOUNT;
+ else if (column == COLUMN_PRIORITY_INT64)
+ return COLUMN_PRIORITY;
+ else if (column == COLUMN_DATE_INT64)
+ return COLUMN_DATE;
+ }
+ else
+ {
+ if (column == COLUMN_AMOUNT)
+ return COLUMN_AMOUNT_INT64;
+ else if (column == COLUMN_PRIORITY)
+ return COLUMN_PRIORITY_INT64;
+ else if (column == COLUMN_DATE)
+ return COLUMN_DATE_INT64;
+ }
+
+ return column;
+ }
+
+private Q_SLOTS:
+ void showMenu(const QPoint &);
+ void copyAmount();
+ void copyLabel();
+ void copyAddress();
+ void copyTransactionHash();
+ void lockCoin();
+ void unlockCoin();
+ void clipboardQuantity();
+ void clipboardAmount();
+ void clipboardFee();
+ void clipboardAfterFee();
+ void clipboardBytes();
+ void clipboardPriority();
+ void clipboardLowOutput();
+ void clipboardChange();
+ void radioTreeMode(bool);
+ void radioListMode(bool);
+ void viewItemChanged(QTreeWidgetItem*, int);
+ void headerSectionClicked(int);
+ void buttonBoxClicked(QAbstractButton*);
+ void buttonSelectAllClicked();
+ void updateLabelLocked();
+};
+
+#endif // BITCOIN_QT_COINCONTROLDIALOG_H
diff --git a/src/qt/coincontroltreewidget.cpp b/src/qt/coincontroltreewidget.cpp
new file mode 100644
index 0000000000..5dcbf0c3f1
--- /dev/null
+++ b/src/qt/coincontroltreewidget.cpp
@@ -0,0 +1,33 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "coincontroltreewidget.h"
+#include "coincontroldialog.h"
+
+CoinControlTreeWidget::CoinControlTreeWidget(QWidget *parent) :
+ QTreeWidget(parent)
+{
+
+}
+
+void CoinControlTreeWidget::keyPressEvent(QKeyEvent *event)
+{
+ if (event->key() == Qt::Key_Space) // press spacebar -> select checkbox
+ {
+ event->ignore();
+ int COLUMN_CHECKBOX = 0;
+ if(this->currentItem())
+ this->currentItem()->setCheckState(COLUMN_CHECKBOX, ((this->currentItem()->checkState(COLUMN_CHECKBOX) == Qt::Checked) ? Qt::Unchecked : Qt::Checked));
+ }
+ else if (event->key() == Qt::Key_Escape) // press esc -> close dialog
+ {
+ event->ignore();
+ CoinControlDialog *coinControlDialog = (CoinControlDialog*)this->parentWidget();
+ coinControlDialog->done(QDialog::Accepted);
+ }
+ else
+ {
+ this->QTreeWidget::keyPressEvent(event);
+ }
+}
diff --git a/src/qt/coincontroltreewidget.h b/src/qt/coincontroltreewidget.h
new file mode 100644
index 0000000000..98a7d32f05
--- /dev/null
+++ b/src/qt/coincontroltreewidget.h
@@ -0,0 +1,22 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_COINCONTROLTREEWIDGET_H
+#define BITCOIN_QT_COINCONTROLTREEWIDGET_H
+
+#include <QKeyEvent>
+#include <QTreeWidget>
+
+class CoinControlTreeWidget : public QTreeWidget
+{
+ Q_OBJECT
+
+public:
+ explicit CoinControlTreeWidget(QWidget *parent = 0);
+
+protected:
+ virtual void keyPressEvent(QKeyEvent *event);
+};
+
+#endif // BITCOIN_QT_COINCONTROLTREEWIDGET_H
diff --git a/src/qt/csvmodelwriter.cpp b/src/qt/csvmodelwriter.cpp
new file mode 100644
index 0000000000..55c5957088
--- /dev/null
+++ b/src/qt/csvmodelwriter.cpp
@@ -0,0 +1,91 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "csvmodelwriter.h"
+
+#include <QAbstractItemModel>
+#include <QFile>
+#include <QTextStream>
+
+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; i<columns.size(); ++i)
+ {
+ if(i!=0)
+ {
+ writeSep(out);
+ }
+ writeValue(out, columns[i].title);
+ }
+ writeNewline(out);
+
+ // Data rows
+ for(int j=0; j<numRows; ++j)
+ {
+ for(int i=0; i<columns.size(); ++i)
+ {
+ if(i!=0)
+ {
+ writeSep(out);
+ }
+ QVariant data = model->index(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 0000000000..a2bf379f4e
--- /dev/null
+++ b/src/qt/csvmodelwriter.h
@@ -0,0 +1,46 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_CSVMODELWRITER_H
+#define BITCOIN_QT_CSVMODELWRITER_H
+
+#include <QList>
+#include <QObject>
+
+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<Column> columns;
+};
+
+#endif // BITCOIN_QT_CSVMODELWRITER_H
diff --git a/src/qt/editaddressdialog.cpp b/src/qt/editaddressdialog.cpp
new file mode 100644
index 0000000000..1c22594cd7
--- /dev/null
+++ b/src/qt/editaddressdialog.cpp
@@ -0,0 +1,144 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "editaddressdialog.h"
+#include "ui_editaddressdialog.h"
+
+#include "addresstablemodel.h"
+#include "guiutil.h"
+
+#include <QDataWidgetMapper>
+#include <QMessageBox>
+
+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->setEnabled(false);
+ 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;
+ if(!model)
+ return;
+
+ 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::OK:
+ // Failed with unknown reason. Just reject.
+ break;
+ case AddressTableModel::NO_CHANGES:
+ // No changes were made during edit operation. Just reject.
+ break;
+ case AddressTableModel::INVALID_ADDRESS:
+ QMessageBox::warning(this, windowTitle(),
+ tr("The entered address \"%1\" is not a valid Bitcoin address.").arg(ui->addressEdit->text()),
+ QMessageBox::Ok, QMessageBox::Ok);
+ break;
+ 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::WALLET_UNLOCK_FAILURE:
+ QMessageBox::critical(this, windowTitle(),
+ tr("Could not unlock wallet."),
+ QMessageBox::Ok, QMessageBox::Ok);
+ break;
+ case AddressTableModel::KEY_GENERATION_FAILURE:
+ QMessageBox::critical(this, windowTitle(),
+ tr("New key generation failed."),
+ QMessageBox::Ok, QMessageBox::Ok);
+ 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 0000000000..d59fce2d41
--- /dev/null
+++ b/src/qt/editaddressdialog.h
@@ -0,0 +1,57 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_EDITADDRESSDIALOG_H
+#define BITCOIN_QT_EDITADDRESSDIALOG_H
+
+#include <QDialog>
+
+class AddressTableModel;
+
+namespace Ui {
+ class EditAddressDialog;
+}
+
+QT_BEGIN_NAMESPACE
+class QDataWidgetMapper;
+QT_END_NAMESPACE
+
+/** 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);
+ ~EditAddressDialog();
+
+ void setModel(AddressTableModel *model);
+ void loadRow(int row);
+
+ QString getAddress() const;
+ void setAddress(const QString &address);
+
+public Q_SLOTS:
+ void accept();
+
+private:
+ bool saveCurrentRow();
+
+ Ui::EditAddressDialog *ui;
+ QDataWidgetMapper *mapper;
+ Mode mode;
+ AddressTableModel *model;
+
+ QString address;
+};
+
+#endif // BITCOIN_QT_EDITADDRESSDIALOG_H
diff --git a/src/qt/forms/addressbookpage.ui b/src/qt/forms/addressbookpage.ui
new file mode 100644
index 0000000000..264edeb720
--- /dev/null
+++ b/src/qt/forms/addressbookpage.ui
@@ -0,0 +1,159 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>AddressBookPage</class>
+ <widget class="QWidget" name="AddressBookPage">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>760</width>
+ <height>380</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="labelExplanation">
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QTableView" name="tableView">
+ <property name="contextMenuPolicy">
+ <enum>Qt::CustomContextMenu</enum>
+ </property>
+ <property name="toolTip">
+ <string>Right-click to edit address or label</string>
+ </property>
+ <property name="tabKeyNavigation">
+ <bool>false</bool>
+ </property>
+ <property name="alternatingRowColors">
+ <bool>true</bool>
+ </property>
+ <property name="selectionMode">
+ <enum>QAbstractItemView::SingleSelection</enum>
+ </property>
+ <property name="selectionBehavior">
+ <enum>QAbstractItemView::SelectRows</enum>
+ </property>
+ <property name="sortingEnabled">
+ <bool>true</bool>
+ </property>
+ <attribute name="verticalHeaderVisible">
+ <bool>false</bool>
+ </attribute>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QPushButton" name="newAddress">
+ <property name="toolTip">
+ <string>Create a new address</string>
+ </property>
+ <property name="text">
+ <string>&amp;New</string>
+ </property>
+ <property name="icon">
+ <iconset resource="../bitcoin.qrc">
+ <normaloff>:/icons/add</normaloff>:/icons/add</iconset>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="copyAddress">
+ <property name="toolTip">
+ <string>Copy the currently selected address to the system clipboard</string>
+ </property>
+ <property name="text">
+ <string>&amp;Copy</string>
+ </property>
+ <property name="icon">
+ <iconset resource="../bitcoin.qrc">
+ <normaloff>:/icons/editcopy</normaloff>:/icons/editcopy</iconset>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="deleteAddress">
+ <property name="toolTip">
+ <string>Delete the currently selected address from the list</string>
+ </property>
+ <property name="text">
+ <string>&amp;Delete</string>
+ </property>
+ <property name="icon">
+ <iconset resource="../bitcoin.qrc">
+ <normaloff>:/icons/remove</normaloff>:/icons/remove</iconset>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="exportButton">
+ <property name="toolTip">
+ <string>Export the data in the current tab to a file</string>
+ </property>
+ <property name="text">
+ <string>&amp;Export</string>
+ </property>
+ <property name="icon">
+ <iconset resource="../bitcoin.qrc">
+ <normaloff>:/icons/export</normaloff>:/icons/export</iconset>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="closeButton">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>C&amp;lose</string>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources>
+ <include location="../bitcoin.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/src/qt/forms/askpassphrasedialog.ui b/src/qt/forms/askpassphrasedialog.ui
new file mode 100644
index 0000000000..a2105ecd0a
--- /dev/null
+++ b/src/qt/forms/askpassphrasedialog.ui
@@ -0,0 +1,160 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>AskPassphraseDialog</class>
+ <widget class="QDialog" name="AskPassphraseDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>598</width>
+ <height>222</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>550</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="windowTitle">
+ <string>Passphrase Dialog</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <property name="sizeConstraint">
+ <enum>QLayout::SetMinimumSize</enum>
+ </property>
+ <item>
+ <widget class="QLabel" name="warningLabel">
+ <property name="text">
+ <string notr="true">Placeholder text</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::RichText</enum>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QFormLayout" name="formLayout">
+ <property name="sizeConstraint">
+ <enum>QLayout::SetMinimumSize</enum>
+ </property>
+ <property name="fieldGrowthPolicy">
+ <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
+ </property>
+ <item row="0" column="0">
+ <widget class="QLabel" name="passLabel1">
+ <property name="text">
+ <string>Enter passphrase</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="passEdit1">
+ <property name="echoMode">
+ <enum>QLineEdit::Password</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="passLabel2">
+ <property name="text">
+ <string>New passphrase</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="passEdit2">
+ <property name="echoMode">
+ <enum>QLineEdit::Password</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="passLabel3">
+ <property name="text">
+ <string>Repeat new passphrase</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLineEdit" name="passEdit3">
+ <property name="echoMode">
+ <enum>QLineEdit::Password</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QLabel" name="capsLabel">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>AskPassphraseDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>20</x>
+ <y>20</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>20</x>
+ <y>20</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>AskPassphraseDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>20</x>
+ <y>20</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>20</x>
+ <y>20</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/qt/forms/coincontroldialog.ui b/src/qt/forms/coincontroldialog.ui
new file mode 100644
index 0000000000..c1fef6b9b1
--- /dev/null
+++ b/src/qt/forms/coincontroldialog.ui
@@ -0,0 +1,534 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>CoinControlDialog</class>
+ <widget class="QDialog" name="CoinControlDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>1000</width>
+ <height>500</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Coin Selection</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayoutTop" stretch="0,0,0,0">
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>10</number>
+ </property>
+ <item>
+ <layout class="QFormLayout" name="formLayoutCoinControl1">
+ <property name="horizontalSpacing">
+ <number>10</number>
+ </property>
+ <property name="verticalSpacing">
+ <number>10</number>
+ </property>
+ <property name="leftMargin">
+ <number>6</number>
+ </property>
+ <property name="rightMargin">
+ <number>6</number>
+ </property>
+ <item row="0" column="0">
+ <widget class="QLabel" name="labelCoinControlQuantityText">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Quantity:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLabel" name="labelCoinControlQuantity">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="contextMenuPolicy">
+ <enum>Qt::ActionsContextMenu</enum>
+ </property>
+ <property name="text">
+ <string notr="true">0</string>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="labelCoinControlBytesText">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Bytes:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLabel" name="labelCoinControlBytes">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="contextMenuPolicy">
+ <enum>Qt::ActionsContextMenu</enum>
+ </property>
+ <property name="text">
+ <string notr="true">0</string>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QFormLayout" name="formLayoutCoinControl2">
+ <property name="horizontalSpacing">
+ <number>10</number>
+ </property>
+ <property name="verticalSpacing">
+ <number>10</number>
+ </property>
+ <property name="leftMargin">
+ <number>6</number>
+ </property>
+ <property name="rightMargin">
+ <number>6</number>
+ </property>
+ <item row="0" column="0">
+ <widget class="QLabel" name="labelCoinControlAmountText">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Amount:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLabel" name="labelCoinControlAmount">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="contextMenuPolicy">
+ <enum>Qt::ActionsContextMenu</enum>
+ </property>
+ <property name="text">
+ <string notr="true">0.00 BTC</string>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="labelCoinControlPriorityText">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Priority:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLabel" name="labelCoinControlPriority">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="contextMenuPolicy">
+ <enum>Qt::ActionsContextMenu</enum>
+ </property>
+ <property name="text">
+ <string notr="true">medium</string>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QFormLayout" name="formLayoutCoinControl3">
+ <property name="horizontalSpacing">
+ <number>10</number>
+ </property>
+ <property name="verticalSpacing">
+ <number>10</number>
+ </property>
+ <property name="leftMargin">
+ <number>6</number>
+ </property>
+ <property name="rightMargin">
+ <number>6</number>
+ </property>
+ <item row="0" column="0">
+ <widget class="QLabel" name="labelCoinControlFeeText">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Fee:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLabel" name="labelCoinControlFee">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="contextMenuPolicy">
+ <enum>Qt::ActionsContextMenu</enum>
+ </property>
+ <property name="text">
+ <string notr="true">0.00 BTC</string>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="labelCoinControlLowOutputText">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Dust:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLabel" name="labelCoinControlLowOutput">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="contextMenuPolicy">
+ <enum>Qt::ActionsContextMenu</enum>
+ </property>
+ <property name="text">
+ <string notr="true">no</string>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QFormLayout" name="formLayoutCoinControl4">
+ <property name="horizontalSpacing">
+ <number>10</number>
+ </property>
+ <property name="verticalSpacing">
+ <number>10</number>
+ </property>
+ <property name="leftMargin">
+ <number>6</number>
+ </property>
+ <property name="rightMargin">
+ <number>6</number>
+ </property>
+ <item row="0" column="0">
+ <widget class="QLabel" name="labelCoinControlAfterFeeText">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>After Fee:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLabel" name="labelCoinControlAfterFee">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="contextMenuPolicy">
+ <enum>Qt::ActionsContextMenu</enum>
+ </property>
+ <property name="text">
+ <string notr="true">0.00 BTC</string>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="labelCoinControlChangeText">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Change:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLabel" name="labelCoinControlChange">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="contextMenuPolicy">
+ <enum>Qt::ActionsContextMenu</enum>
+ </property>
+ <property name="text">
+ <string notr="true">0.00 BTC</string>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QFrame" name="frame">
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>40</height>
+ </size>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Sunken</enum>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayoutPanel" stretch="0,0,0,0,0">
+ <property name="spacing">
+ <number>14</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="pushButtonSelectAll">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>(un)select all</string>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="radioTreeMode">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Tree mode</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="radioListMode">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>List mode</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="labelLocked">
+ <property name="text">
+ <string notr="true">(1 locked)</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="CoinControlTreeWidget" name="treeWidget">
+ <property name="contextMenuPolicy">
+ <enum>Qt::CustomContextMenu</enum>
+ </property>
+ <property name="sortingEnabled">
+ <bool>false</bool>
+ </property>
+ <property name="columnCount">
+ <number>12</number>
+ </property>
+ <attribute name="headerShowSortIndicator" stdset="0">
+ <bool>true</bool>
+ </attribute>
+ <attribute name="headerStretchLastSection">
+ <bool>false</bool>
+ </attribute>
+ <column>
+ <property name="text">
+ <string/>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Amount</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Received with label</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Received with address</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Date</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Confirmations</string>
+ </property>
+ <property name="toolTip">
+ <string>Confirmed</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Priority</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string/>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string/>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string/>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string/>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string/>
+ </property>
+ </column>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>CoinControlTreeWidget</class>
+ <extends>QTreeWidget</extends>
+ <header>coincontroltreewidget.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/qt/forms/editaddressdialog.ui b/src/qt/forms/editaddressdialog.ui
new file mode 100644
index 0000000000..c1aea36338
--- /dev/null
+++ b/src/qt/forms/editaddressdialog.ui
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>EditAddressDialog</class>
+ <widget class="QDialog" name="EditAddressDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>457</width>
+ <height>126</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Edit Address</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QFormLayout" name="formLayout">
+ <property name="fieldGrowthPolicy">
+ <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
+ </property>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>&amp;Label</string>
+ </property>
+ <property name="buddy">
+ <cstring>labelEdit</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="labelEdit">
+ <property name="toolTip">
+ <string>The label associated with this address list entry</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>&amp;Address</string>
+ </property>
+ <property name="buddy">
+ <cstring>addressEdit</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QValidatedLineEdit" name="addressEdit">
+ <property name="toolTip">
+ <string>The address associated with this address list entry. This can only be modified for sending addresses.</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>QValidatedLineEdit</class>
+ <extends>QLineEdit</extends>
+ <header>qvalidatedlineedit.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>EditAddressDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>20</x>
+ <y>20</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>20</x>
+ <y>20</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>EditAddressDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>20</x>
+ <y>20</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>20</x>
+ <y>20</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/qt/forms/helpmessagedialog.ui b/src/qt/forms/helpmessagedialog.ui
new file mode 100644
index 0000000000..dc7df9d6c8
--- /dev/null
+++ b/src/qt/forms/helpmessagedialog.ui
@@ -0,0 +1,192 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>HelpMessageDialog</class>
+ <widget class="QDialog" name="HelpMessageDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>780</width>
+ <height>400</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string notr="true">Bitcoin Core - Command-line options</string>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>12</number>
+ </property>
+ <property name="topMargin">
+ <number>12</number>
+ </property>
+ <property name="rightMargin">
+ <number>12</number>
+ </property>
+ <property name="bottomMargin">
+ <number>12</number>
+ </property>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayoutLogo" stretch="0,0">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>4</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="aboutLogo">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Ignored">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>100</width>
+ <height>100</height>
+ </size>
+ </property>
+ <property name="pixmap">
+ <pixmap resource="../bitcoin.qrc">:/icons/bitcoin</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QFrame" name="frame">
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QTextEdit" name="helpMessage">
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QScrollArea" name="scrollArea">
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="verticalScrollBarPolicy">
+ <enum>Qt::ScrollBarAlwaysOn</enum>
+ </property>
+ <property name="widgetResizable">
+ <bool>true</bool>
+ </property>
+ <widget class="QWidget" name="scrollAreaWidgetContents">
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QLabel" name="aboutMessage">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+ </property>
+ <property name="openExternalLinks">
+ <bool>true</bool>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>4</width>
+ <height>4</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="okButton">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources>
+ <include location="../bitcoin.qrc"/>
+ </resources>
+ <connections>
+ <connection>
+ <sender>okButton</sender>
+ <signal>accepted()</signal>
+ <receiver>HelpMessageDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>20</x>
+ <y>20</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>20</x>
+ <y>20</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>okButton</sender>
+ <signal>rejected()</signal>
+ <receiver>HelpMessageDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>20</x>
+ <y>20</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>20</x>
+ <y>20</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/qt/forms/intro.ui b/src/qt/forms/intro.ui
new file mode 100644
index 0000000000..09e7bdb024
--- /dev/null
+++ b/src/qt/forms/intro.ui
@@ -0,0 +1,266 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Intro</class>
+ <widget class="QDialog" name="Intro">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>674</width>
+ <height>363</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Welcome</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="label_2">
+ <property name="styleSheet">
+ <string notr="true">QLabel { font-style:italic; }</string>
+ </property>
+ <property name="text">
+ <string>Welcome to Bitcoin Core.</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_4">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Minimum</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>15</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="sizeWarningLabel">
+ <property name="text">
+ <string>Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory.</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="dataDirDefault">
+ <property name="text">
+ <string>Use the default data directory</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="dataDirCustom">
+ <property name="text">
+ <string>Use a custom data directory:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="sizeConstraint">
+ <enum>QLayout::SetDefaultConstraint</enum>
+ </property>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>60</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <property name="sizeConstraint">
+ <enum>QLayout::SetDefaultConstraint</enum>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QLineEdit" name="dataDirectory"/>
+ </item>
+ <item>
+ <widget class="QPushButton" name="ellipsisButton">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>30</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string notr="true">…</string>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>5</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="freeSpace">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
+ <horstretch>1</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>5</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="errorMessage">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::RichText</enum>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>Intro</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>20</x>
+ <y>20</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>20</x>
+ <y>20</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>Intro</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>20</x>
+ <y>20</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>20</x>
+ <y>20</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/qt/forms/openuridialog.ui b/src/qt/forms/openuridialog.ui
new file mode 100644
index 0000000000..7fce858bd2
--- /dev/null
+++ b/src/qt/forms/openuridialog.ui
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>OpenURIDialog</class>
+ <widget class="QDialog" name="OpenURIDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>564</width>
+ <height>109</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Open URI</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Open payment request from URI or file</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>URI:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QValidatedLineEdit" name="uriEdit"/>
+ </item>
+ <item>
+ <widget class="QPushButton" name="selectFileButton">
+ <property name="toolTip">
+ <string>Select payment request file</string>
+ </property>
+ <property name="text">
+ <string notr="true">…</string>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>QValidatedLineEdit</class>
+ <extends>QLineEdit</extends>
+ <header>qvalidatedlineedit.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>OpenURIDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>OpenURIDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/qt/forms/optionsdialog.ui b/src/qt/forms/optionsdialog.ui
new file mode 100644
index 0000000000..55c4f5ac58
--- /dev/null
+++ b/src/qt/forms/optionsdialog.ui
@@ -0,0 +1,602 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>OptionsDialog</class>
+ <widget class="QDialog" name="OptionsDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>560</width>
+ <height>400</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Options</string>
+ </property>
+ <property name="modal">
+ <bool>true</bool>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QTabWidget" name="tabWidget">
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="tabMain">
+ <attribute name="title">
+ <string>&amp;Main</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_Main">
+ <item>
+ <widget class="QCheckBox" name="bitcoinAtStartup">
+ <property name="toolTip">
+ <string>Automatically start Bitcoin Core after logging in to the system.</string>
+ </property>
+ <property name="text">
+ <string>&amp;Start Bitcoin Core on system login</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2_Main">
+ <item>
+ <widget class="QLabel" name="databaseCacheLabel">
+ <property name="text">
+ <string>Size of &amp;database cache</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="buddy">
+ <cstring>databaseCache</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="databaseCache"/>
+ </item>
+ <item>
+ <widget class="QLabel" name="databaseCacheUnitLabel">
+ <property name="text">
+ <string>MB</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2_Main">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_3_Main">
+ <item>
+ <widget class="QLabel" name="threadsScriptVerifLabel">
+ <property name="text">
+ <string>Number of script &amp;verification threads</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="buddy">
+ <cstring>threadsScriptVerif</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="threadsScriptVerif">
+ <property name="toolTip">
+ <string>(0 = auto, &lt;0 = leave that many cores free)</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_3_Main">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_Main">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tabWallet">
+ <attribute name="title">
+ <string>W&amp;allet</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_Wallet">
+ <item>
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string>Expert</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QCheckBox" name="coinControlFeatures">
+ <property name="toolTip">
+ <string>Whether to show coin control features or not.</string>
+ </property>
+ <property name="text">
+ <string>Enable coin &amp;control features</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="spendZeroConfChange">
+ <property name="toolTip">
+ <string>If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.</string>
+ </property>
+ <property name="text">
+ <string>&amp;Spend unconfirmed change</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_Wallet">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tabNetwork">
+ <attribute name="title">
+ <string>&amp;Network</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_Network">
+ <item>
+ <widget class="QCheckBox" name="mapPortUpnp">
+ <property name="toolTip">
+ <string>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</string>
+ </property>
+ <property name="text">
+ <string>Map port using &amp;UPnP</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="allowIncoming">
+ <property name="toolTip">
+ <string>Accept connections from outside</string>
+ </property>
+ <property name="text">
+ <string>Allow incoming connections</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="connectSocks">
+ <property name="toolTip">
+ <string>Connect to the Bitcoin network through a SOCKS5 proxy.</string>
+ </property>
+ <property name="text">
+ <string>&amp;Connect through SOCKS5 proxy (default proxy):</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_1_Network">
+ <item>
+ <widget class="QLabel" name="proxyIpLabel">
+ <property name="text">
+ <string>Proxy &amp;IP:</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="buddy">
+ <cstring>proxyIp</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QValidatedLineEdit" name="proxyIp">
+ <property name="minimumSize">
+ <size>
+ <width>140</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>140</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="proxyPortLabel">
+ <property name="text">
+ <string>&amp;Port:</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="buddy">
+ <cstring>proxyPort</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="proxyPort">
+ <property name="minimumSize">
+ <size>
+ <width>55</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>55</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>Port of the proxy (e.g. 9050)</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_1_Network">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_Network">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tabWindow">
+ <attribute name="title">
+ <string>&amp;Window</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_Window">
+ <item>
+ <widget class="QCheckBox" name="minimizeToTray">
+ <property name="toolTip">
+ <string>Show only a tray icon after minimizing the window.</string>
+ </property>
+ <property name="text">
+ <string>&amp;Minimize to the tray instead of the taskbar</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="minimizeOnClose">
+ <property name="toolTip">
+ <string>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</string>
+ </property>
+ <property name="text">
+ <string>M&amp;inimize on close</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_Window">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tabDisplay">
+ <attribute name="title">
+ <string>&amp;Display</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_Display">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_1_Display">
+ <item>
+ <widget class="QLabel" name="langLabel">
+ <property name="text">
+ <string>User Interface &amp;language:</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="buddy">
+ <cstring>lang</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QValueComboBox" name="lang">
+ <property name="toolTip">
+ <string>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2_Display">
+ <item>
+ <widget class="QLabel" name="unitLabel">
+ <property name="text">
+ <string>&amp;Unit to show amounts in:</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="buddy">
+ <cstring>unit</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QValueComboBox" name="unit">
+ <property name="toolTip">
+ <string>Choose the default subdivision unit to show in the interface and when sending coins.</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_3_Display">
+ <item>
+ <widget class="QLabel" name="thirdPartyTxUrlsLabel">
+ <property name="toolTip">
+ <string>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</string>
+ </property>
+ <property name="text">
+ <string>Third party transaction URLs</string>
+ </property>
+ <property name="buddy">
+ <cstring>thirdPartyTxUrls</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="thirdPartyTxUrls">
+ <property name="toolTip">
+ <string>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_Display">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ <item>
+ <widget class="QFrame" name="frame">
+ <layout class="QVBoxLayout" name="verticalLayout_Bottom">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_Bottom">
+ <item>
+ <widget class="QLabel" name="overriddenByCommandLineInfoLabel">
+ <property name="text">
+ <string>Active command-line options that override above options:</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_Bottom">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QLabel" name="overriddenByCommandLineLabel">
+ <property name="text">
+ <string/>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_Buttons">
+ <item>
+ <widget class="QPushButton" name="resetButton">
+ <property name="toolTip">
+ <string>Reset all client options to default.</string>
+ </property>
+ <property name="text">
+ <string>&amp;Reset Options</string>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_1">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>48</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="statusLabel">
+ <property name="minimumSize">
+ <size>
+ <width>200</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>48</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="okButton">
+ <property name="text">
+ <string>&amp;OK</string>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ <property name="default">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="cancelButton">
+ <property name="text">
+ <string>&amp;Cancel</string>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>QValidatedLineEdit</class>
+ <extends>QLineEdit</extends>
+ <header>qvalidatedlineedit.h</header>
+ </customwidget>
+ <customwidget>
+ <class>QValueComboBox</class>
+ <extends>QComboBox</extends>
+ <header>qvaluecombobox.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/qt/forms/overviewpage.ui b/src/qt/forms/overviewpage.ui
new file mode 100644
index 0000000000..6d792d1475
--- /dev/null
+++ b/src/qt/forms/overviewpage.ui
@@ -0,0 +1,538 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>OverviewPage</class>
+ <widget class="QWidget" name="OverviewPage">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>596</width>
+ <height>342</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QVBoxLayout" name="topLayout">
+ <item>
+ <widget class="QLabel" name="labelAlerts">
+ <property name="visible">
+ <bool>false</bool>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop:0 #F0D0A0, stop:1 #F8D488); color:#000000;</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ <property name="margin">
+ <number>3</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout" stretch="1,1">
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QFrame" name="frame">
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_4">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_4">
+ <item>
+ <widget class="QLabel" name="label_5">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Balances</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="labelWalletStatus">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>30</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>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.</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="../bitcoin.qrc">
+ <normaloff>:/icons/warning</normaloff>
+ <disabledoff>:/icons/warning</disabledoff>:/icons/warning</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>24</width>
+ <height>24</height>
+ </size>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QGridLayout" name="gridLayout">
+ <property name="spacing">
+ <number>12</number>
+ </property>
+ <item row="2" column="2">
+ <widget class="QLabel" name="labelWatchPending">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="toolTip">
+ <string>Unconfirmed transactions to watch-only addresses</string>
+ </property>
+ <property name="text">
+ <string notr="true">0.000 000 00 BTC</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLabel" name="labelUnconfirmed">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="toolTip">
+ <string>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</string>
+ </property>
+ <property name="text">
+ <string notr="true">0.000 000 00 BTC</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="2">
+ <widget class="QLabel" name="labelWatchImmature">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="toolTip">
+ <string>Mined balance in watch-only addresses that has not yet matured</string>
+ </property>
+ <property name="text">
+ <string notr="true">0.000 000 00 BTC</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0" colspan="2">
+ <widget class="Line" name="line">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="2">
+ <widget class="Line" name="lineWatchBalance">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>140</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0">
+ <widget class="QLabel" name="labelTotalText">
+ <property name="text">
+ <string>Total:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QLabel" name="labelImmature">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="toolTip">
+ <string>Mined balance that has not yet matured</string>
+ </property>
+ <property name="text">
+ <string notr="true">0.000 000 00 BTC</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="3">
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="labelImmatureText">
+ <property name="text">
+ <string>Immature:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="1">
+ <widget class="QLabel" name="labelTotal">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="toolTip">
+ <string>Your current total balance</string>
+ </property>
+ <property name="text">
+ <string notr="true">0.000 000 00 BTC</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="2">
+ <widget class="QLabel" name="labelWatchTotal">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="toolTip">
+ <string>Current total balance in watch-only addresses</string>
+ </property>
+ <property name="text">
+ <string notr="true">0.000 000 00 BTC</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QLabel" name="labelWatchonly">
+ <property name="text">
+ <string>Watch-only:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="labelBalanceText">
+ <property name="text">
+ <string>Available:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLabel" name="labelBalance">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="toolTip">
+ <string>Your current spendable balance</string>
+ </property>
+ <property name="text">
+ <string notr="true">0.000 000 00 BTC</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QLabel" name="labelWatchAvailable">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="toolTip">
+ <string>Your current balance in watch-only addresses</string>
+ </property>
+ <property name="text">
+ <string notr="true">0.000 000 00 BTC</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="labelPendingText">
+ <property name="text">
+ <string>Pending:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLabel" name="labelSpendable">
+ <property name="text">
+ <string>Spendable:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <widget class="QFrame" name="frame_2">
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QLabel" name="label_4">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Recent transactions</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="labelTransactionsStatus">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>30</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>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.</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="../bitcoin.qrc">
+ <normaloff>:/icons/warning</normaloff>
+ <disabledoff>:/icons/warning</disabledoff>:/icons/warning</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>24</width>
+ <height>24</height>
+ </size>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QListView" name="listTransactions">
+ <property name="styleSheet">
+ <string notr="true">QListView { background: transparent; }</string>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="verticalScrollBarPolicy">
+ <enum>Qt::ScrollBarAlwaysOff</enum>
+ </property>
+ <property name="horizontalScrollBarPolicy">
+ <enum>Qt::ScrollBarAlwaysOff</enum>
+ </property>
+ <property name="selectionMode">
+ <enum>QAbstractItemView::NoSelection</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/qt/forms/receivecoinsdialog.ui b/src/qt/forms/receivecoinsdialog.ui
new file mode 100644
index 0000000000..03fcb2fb50
--- /dev/null
+++ b/src/qt/forms/receivecoinsdialog.ui
@@ -0,0 +1,338 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ReceiveCoinsDialog</class>
+ <widget class="QWidget" name="ReceiveCoinsDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>776</width>
+ <height>364</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout" stretch="0,0,1">
+ <item>
+ <widget class="QFrame" name="frame2">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Sunken</enum>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="7" column="2">
+ <widget class="QCheckBox" name="reuseAddress">
+ <property name="toolTip">
+ <string>Reuse one of the previously used receiving addresses. Reusing addresses has security and privacy issues. Do not use this unless re-generating a payment request made before.</string>
+ </property>
+ <property name="text">
+ <string>R&amp;euse an existing receiving address (not recommended)</string>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="0">
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="0">
+ <widget class="QLabel" name="label_3">
+ <property name="toolTip">
+ <string>An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network.</string>
+ </property>
+ <property name="text">
+ <string>&amp;Message:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ <property name="buddy">
+ <cstring>reqMessage</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="2">
+ <widget class="QLineEdit" name="reqLabel">
+ <property name="toolTip">
+ <string>An optional label to associate with the new receiving address.</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="2">
+ <widget class="QLineEdit" name="reqMessage">
+ <property name="toolTip">
+ <string>An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network.</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2">
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>Use this form to request payments. All fields are &lt;b&gt;optional&lt;/b&gt;.</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="toolTip">
+ <string>An optional label to associate with the new receiving address.</string>
+ </property>
+ <property name="text">
+ <string>&amp;Label:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ <property name="buddy">
+ <cstring>reqLabel</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0">
+ <widget class="QLabel" name="label">
+ <property name="toolTip">
+ <string>An optional amount to request. Leave this empty or zero to not request a specific amount.</string>
+ </property>
+ <property name="text">
+ <string>&amp;Amount:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ <property name="buddy">
+ <cstring>reqAmount</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="2">
+ <widget class="BitcoinAmountField" name="reqAmount">
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>An optional amount to request. Leave this empty or zero to not request a specific amount.</string>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="2">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QPushButton" name="receiveButton">
+ <property name="minimumSize">
+ <size>
+ <width>150</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>&amp;Request payment</string>
+ </property>
+ <property name="icon">
+ <iconset resource="../bitcoin.qrc">
+ <normaloff>:/icons/receiving_addresses</normaloff>:/icons/receiving_addresses</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="clearButton">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Clear all fields of the form.</string>
+ </property>
+ <property name="text">
+ <string>Clear</string>
+ </property>
+ <property name="icon">
+ <iconset resource="../bitcoin.qrc">
+ <normaloff>:/icons/remove</normaloff>:/icons/remove</iconset>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item row="8" column="0">
+ <widget class="QLabel" name="label_7">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>10</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QFrame" name="frame">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QLabel" name="label_6">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Requested payments history</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QTableView" name="recentRequestsView">
+ <property name="contextMenuPolicy">
+ <enum>Qt::CustomContextMenu</enum>
+ </property>
+ <property name="tabKeyNavigation">
+ <bool>false</bool>
+ </property>
+ <property name="sortingEnabled">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QPushButton" name="showRequestButton">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="toolTip">
+ <string>Show the selected request (does the same as double clicking an entry)</string>
+ </property>
+ <property name="text">
+ <string>Show</string>
+ </property>
+ <property name="icon">
+ <iconset resource="../bitcoin.qrc">
+ <normaloff>:/icons/edit</normaloff>:/icons/edit</iconset>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="removeRequestButton">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="toolTip">
+ <string>Remove the selected entries from the list</string>
+ </property>
+ <property name="text">
+ <string>Remove</string>
+ </property>
+ <property name="icon">
+ <iconset resource="../bitcoin.qrc">
+ <normaloff>:/icons/remove</normaloff>:/icons/remove</iconset>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>BitcoinAmountField</class>
+ <extends>QLineEdit</extends>
+ <header>bitcoinamountfield.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <tabstops>
+ <tabstop>reqLabel</tabstop>
+ <tabstop>reqAmount</tabstop>
+ <tabstop>reqMessage</tabstop>
+ <tabstop>reuseAddress</tabstop>
+ <tabstop>receiveButton</tabstop>
+ <tabstop>clearButton</tabstop>
+ <tabstop>recentRequestsView</tabstop>
+ <tabstop>showRequestButton</tabstop>
+ <tabstop>removeRequestButton</tabstop>
+ </tabstops>
+ <resources>
+ <include location="../bitcoin.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/src/qt/forms/receiverequestdialog.ui b/src/qt/forms/receiverequestdialog.ui
new file mode 100644
index 0000000000..1e484dd9a0
--- /dev/null
+++ b/src/qt/forms/receiverequestdialog.ui
@@ -0,0 +1,168 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ReceiveRequestDialog</class>
+ <widget class="QDialog" name="ReceiveRequestDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>487</width>
+ <height>597</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <widget class="QRImageWidget" name="lblQRCode">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>300</width>
+ <height>300</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>QR Code</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QTextEdit" name="outUri">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>50</height>
+ </size>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Plain</enum>
+ </property>
+ <property name="tabChangesFocus">
+ <bool>true</bool>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QPushButton" name="btnCopyURI">
+ <property name="text">
+ <string>Copy &amp;URI</string>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnCopyAddress">
+ <property name="text">
+ <string>Copy &amp;Address</string>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnSaveAs">
+ <property name="text">
+ <string>&amp;Save Image...</string>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Close</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>QRImageWidget</class>
+ <extends>QLabel</extends>
+ <header>receiverequestdialog.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>ReceiveRequestDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>452</x>
+ <y>573</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>243</x>
+ <y>298</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>ReceiveRequestDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>452</x>
+ <y>573</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>243</x>
+ <y>298</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/qt/forms/rpcconsole.ui b/src/qt/forms/rpcconsole.ui
new file mode 100644
index 0000000000..c1eb185501
--- /dev/null
+++ b/src/qt/forms/rpcconsole.ui
@@ -0,0 +1,1106 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>RPCConsole</class>
+ <widget class="QWidget" name="RPCConsole">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>740</width>
+ <height>450</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Debug window</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QTabWidget" name="tabWidget">
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="tab_info">
+ <attribute name="title">
+ <string>&amp;Information</string>
+ </attribute>
+ <layout class="QGridLayout" name="gridLayout" columnstretch="0,1">
+ <property name="horizontalSpacing">
+ <number>12</number>
+ </property>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_9">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>General</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>Client name</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLabel" name="clientName">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_6">
+ <property name="text">
+ <string>Client version</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLabel" name="clientVersion">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="label_14">
+ <property name="text">
+ <string>Using OpenSSL version</string>
+ </property>
+ <property name="indent">
+ <number>10</number>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QLabel" name="openSSLVersion">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="label_berkeleyDBVersion">
+ <property name="text">
+ <string>Using BerkeleyDB version</string>
+ </property>
+ <property name="indent">
+ <number>10</number>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="QLabel" name="berkeleyDBVersion">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0">
+ <widget class="QLabel" name="label_12">
+ <property name="text">
+ <string>Build date</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="1">
+ <widget class="QLabel" name="buildDate">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="0">
+ <widget class="QLabel" name="label_13">
+ <property name="text">
+ <string>Startup time</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="1">
+ <widget class="QLabel" name="startupTime">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="0">
+ <widget class="QLabel" name="label_11">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Network</string>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="0">
+ <widget class="QLabel" name="label_8">
+ <property name="text">
+ <string>Name</string>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="1">
+ <widget class="QLabel" name="networkName">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="9" column="0">
+ <widget class="QLabel" name="label_7">
+ <property name="text">
+ <string>Number of connections</string>
+ </property>
+ </widget>
+ </item>
+ <item row="9" column="1">
+ <widget class="QLabel" name="numberOfConnections">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="10" column="0">
+ <widget class="QLabel" name="label_10">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Block chain</string>
+ </property>
+ </widget>
+ </item>
+ <item row="11" column="0">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Current number of blocks</string>
+ </property>
+ </widget>
+ </item>
+ <item row="11" column="1">
+ <widget class="QLabel" name="numberOfBlocks">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="12" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Last block time</string>
+ </property>
+ </widget>
+ </item>
+ <item row="12" column="1">
+ <widget class="QLabel" name="lastBlockTime">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="13" column="0">
+ <spacer name="verticalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="14" column="0">
+ <widget class="QLabel" name="labelDebugLogfile">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Debug log file</string>
+ </property>
+ </widget>
+ </item>
+ <item row="15" column="0">
+ <widget class="QPushButton" name="openDebugLogfileButton">
+ <property name="toolTip">
+ <string>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</string>
+ </property>
+ <property name="text">
+ <string>&amp;Open</string>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="16" column="0">
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab_console">
+ <attribute name="title">
+ <string>&amp;Console</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <property name="spacing">
+ <number>3</number>
+ </property>
+ <item>
+ <widget class="QTextEdit" name="messagesWidget">
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>100</height>
+ </size>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ <property name="tabKeyNavigation" stdset="0">
+ <bool>false</bool>
+ </property>
+ <property name="columnCount" stdset="0">
+ <number>2</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="spacing">
+ <number>3</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string notr="true">&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="lineEdit"/>
+ </item>
+ <item>
+ <widget class="QPushButton" name="clearButton">
+ <property name="maximumSize">
+ <size>
+ <width>24</width>
+ <height>24</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>Clear console</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="../bitcoin.qrc">
+ <normaloff>:/icons/remove</normaloff>:/icons/remove</iconset>
+ </property>
+ <property name="shortcut">
+ <string notr="true">Ctrl+L</string>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab_nettraffic">
+ <attribute name="title">
+ <string>&amp;Network Traffic</string>
+ </attribute>
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_4">
+ <item>
+ <widget class="TrafficGraphWidget" name="trafficGraph" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QSlider" name="sldGraphRange">
+ <property name="minimum">
+ <number>1</number>
+ </property>
+ <property name="maximum">
+ <number>288</number>
+ </property>
+ <property name="pageStep">
+ <number>12</number>
+ </property>
+ <property name="value">
+ <number>6</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="lblGraphRange">
+ <property name="minimumSize">
+ <size>
+ <width>100</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnClearTrafficGraph">
+ <property name="text">
+ <string>&amp;Clear</string>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string>Totals</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_5">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_4">
+ <item>
+ <widget class="Line" name="line">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>10</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="palette">
+ <palette>
+ <active>
+ <colorrole role="Light">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>255</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </active>
+ <inactive>
+ <colorrole role="Light">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>255</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </inactive>
+ <disabled>
+ <colorrole role="Light">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>255</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </disabled>
+ </palette>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_16">
+ <property name="text">
+ <string>Received</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="lblBytesIn">
+ <property name="minimumSize">
+ <size>
+ <width>50</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_5">
+ <item>
+ <widget class="Line" name="line_2">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>10</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="palette">
+ <palette>
+ <active>
+ <colorrole role="Light">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </active>
+ <inactive>
+ <colorrole role="Light">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </inactive>
+ <disabled>
+ <colorrole role="Light">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </disabled>
+ </palette>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_17">
+ <property name="text">
+ <string>Sent</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="lblBytesOut">
+ <property name="minimumSize">
+ <size>
+ <width>50</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_4">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>407</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab_peers">
+ <attribute name="title">
+ <string>&amp;Peers</string>
+ </attribute>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0" rowspan="2">
+ <widget class="QTableView" name="peerWidget">
+ <property name="horizontalScrollBarPolicy">
+ <enum>Qt::ScrollBarAsNeeded</enum>
+ </property>
+ <property name="sortingEnabled">
+ <bool>true</bool>
+ </property>
+ <attribute name="horizontalHeaderHighlightSections">
+ <bool>false</bool>
+ </attribute>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLabel" name="peerHeading">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>300</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="font">
+ <font>
+ <pointsize>10</pointsize>
+ </font>
+ </property>
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>Select a peer to view detailed information.</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignHCenter|Qt::AlignTop</set>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QWidget" name="detailWidget" native="true">
+ <property name="minimumSize">
+ <size>
+ <width>300</width>
+ <height>0</height>
+ </size>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_3">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_23">
+ <property name="text">
+ <string>Direction</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QLabel" name="peerDirection">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_21">
+ <property name="text">
+ <string>Version</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QLabel" name="peerVersion">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_28">
+ <property name="text">
+ <string>User Agent</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2">
+ <widget class="QLabel" name="peerSubversion">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>Services</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="2">
+ <widget class="QLabel" name="peerServices">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0">
+ <widget class="QLabel" name="label_29">
+ <property name="text">
+ <string>Starting Height</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="2">
+ <widget class="QLabel" name="peerHeight">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="0">
+ <widget class="QLabel" name="label_27">
+ <property name="text">
+ <string>Sync Height</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="2">
+ <widget class="QLabel" name="peerSyncHeight">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="0">
+ <widget class="QLabel" name="label_24">
+ <property name="text">
+ <string>Ban Score</string>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="2">
+ <widget class="QLabel" name="peerBanScore">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="0">
+ <widget class="QLabel" name="label_22">
+ <property name="text">
+ <string>Connection Time</string>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="2">
+ <widget class="QLabel" name="peerConnTime">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="9" column="0">
+ <widget class="QLabel" name="label_15">
+ <property name="text">
+ <string>Last Send</string>
+ </property>
+ </widget>
+ </item>
+ <item row="9" column="2">
+ <widget class="QLabel" name="peerLastSend">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="10" column="0">
+ <widget class="QLabel" name="label_19">
+ <property name="text">
+ <string>Last Receive</string>
+ </property>
+ </widget>
+ </item>
+ <item row="10" column="2">
+ <widget class="QLabel" name="peerLastRecv">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="11" column="0">
+ <widget class="QLabel" name="label_18">
+ <property name="text">
+ <string>Bytes Sent</string>
+ </property>
+ </widget>
+ </item>
+ <item row="11" column="2">
+ <widget class="QLabel" name="peerBytesSent">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="12" column="0">
+ <widget class="QLabel" name="label_20">
+ <property name="text">
+ <string>Bytes Received</string>
+ </property>
+ </widget>
+ </item>
+ <item row="12" column="2">
+ <widget class="QLabel" name="peerBytesRecv">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="13" column="0">
+ <widget class="QLabel" name="label_26">
+ <property name="text">
+ <string>Ping Time</string>
+ </property>
+ </widget>
+ </item>
+ <item row="13" column="2">
+ <widget class="QLabel" name="peerPingTime">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="14" column="0">
+ <widget class="QLabel" name="label_timeoffset">
+ <property name="text">
+ <string>Time Offset</string>
+ </property>
+ </widget>
+ </item>
+ <item row="14" column="2">
+ <widget class="QLabel" name="timeoffset">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="15" column="1">
+ <spacer name="verticalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>TrafficGraphWidget</class>
+ <extends>QWidget</extends>
+ <header>trafficgraphwidget.h</header>
+ <container>1</container>
+ <slots>
+ <slot>clear()</slot>
+ </slots>
+ </customwidget>
+ </customwidgets>
+ <resources>
+ <include location="../bitcoin.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/src/qt/forms/sendcoinsdialog.ui b/src/qt/forms/sendcoinsdialog.ui
new file mode 100644
index 0000000000..8911b41cbf
--- /dev/null
+++ b/src/qt/forms/sendcoinsdialog.ui
@@ -0,0 +1,1389 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>SendCoinsDialog</class>
+ <widget class="QDialog" name="SendCoinsDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>850</width>
+ <height>526</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Send Coins</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout" stretch="0,1,0,0">
+ <property name="bottomMargin">
+ <number>8</number>
+ </property>
+ <item>
+ <widget class="QFrame" name="frameCoinControl">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Sunken</enum>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayoutCoinControl2">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>6</number>
+ </property>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayoutCoinControl" stretch="0,0,0,0,1">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>10</number>
+ </property>
+ <property name="topMargin">
+ <number>10</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayoutCoinControl1">
+ <property name="bottomMargin">
+ <number>15</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="labelCoinControlFeatures">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">font-weight:bold;</string>
+ </property>
+ <property name="text">
+ <string>Coin Control Features</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayoutCoinControl2" stretch="0,0,0,0">
+ <property name="spacing">
+ <number>8</number>
+ </property>
+ <property name="bottomMargin">
+ <number>10</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="pushButtonCoinControl">
+ <property name="styleSheet">
+ <string notr="true"/>
+ </property>
+ <property name="text">
+ <string>Inputs...</string>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="labelCoinControlAutomaticallySelected">
+ <property name="text">
+ <string>automatically selected</string>
+ </property>
+ <property name="margin">
+ <number>5</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="labelCoinControlInsuffFunds">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">color:red;font-weight:bold;</string>
+ </property>
+ <property name="text">
+ <string>Insufficient funds!</string>
+ </property>
+ <property name="margin">
+ <number>5</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacerCoinControl">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>1</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QWidget" name="widgetCoinControl" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="styleSheet">
+ <string notr="true"/>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayoutCoinControl5">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayoutCoinControl3" stretch="0,0,0,1">
+ <property name="spacing">
+ <number>20</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>10</number>
+ </property>
+ <item>
+ <layout class="QFormLayout" name="formLayoutCoinControl1">
+ <property name="horizontalSpacing">
+ <number>10</number>
+ </property>
+ <property name="verticalSpacing">
+ <number>14</number>
+ </property>
+ <property name="leftMargin">
+ <number>10</number>
+ </property>
+ <property name="topMargin">
+ <number>4</number>
+ </property>
+ <property name="rightMargin">
+ <number>6</number>
+ </property>
+ <item row="0" column="0">
+ <widget class="QLabel" name="labelCoinControlQuantityText">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Quantity:</string>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLabel" name="labelCoinControlQuantity">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="contextMenuPolicy">
+ <enum>Qt::ActionsContextMenu</enum>
+ </property>
+ <property name="text">
+ <string notr="true">0</string>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="labelCoinControlBytesText">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Bytes:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLabel" name="labelCoinControlBytes">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="contextMenuPolicy">
+ <enum>Qt::ActionsContextMenu</enum>
+ </property>
+ <property name="text">
+ <string notr="true">0</string>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QFormLayout" name="formLayoutCoinControl2">
+ <property name="horizontalSpacing">
+ <number>10</number>
+ </property>
+ <property name="verticalSpacing">
+ <number>14</number>
+ </property>
+ <property name="leftMargin">
+ <number>6</number>
+ </property>
+ <property name="topMargin">
+ <number>4</number>
+ </property>
+ <property name="rightMargin">
+ <number>6</number>
+ </property>
+ <item row="0" column="0">
+ <widget class="QLabel" name="labelCoinControlAmountText">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Amount:</string>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLabel" name="labelCoinControlAmount">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="contextMenuPolicy">
+ <enum>Qt::ActionsContextMenu</enum>
+ </property>
+ <property name="text">
+ <string notr="true">0.00 BTC</string>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="labelCoinControlPriorityText">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Priority:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLabel" name="labelCoinControlPriority">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="contextMenuPolicy">
+ <enum>Qt::ActionsContextMenu</enum>
+ </property>
+ <property name="text">
+ <string notr="true">medium</string>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QFormLayout" name="formLayoutCoinControl3">
+ <property name="horizontalSpacing">
+ <number>10</number>
+ </property>
+ <property name="verticalSpacing">
+ <number>14</number>
+ </property>
+ <property name="leftMargin">
+ <number>6</number>
+ </property>
+ <property name="topMargin">
+ <number>4</number>
+ </property>
+ <property name="rightMargin">
+ <number>6</number>
+ </property>
+ <item row="0" column="0">
+ <widget class="QLabel" name="labelCoinControlFeeText">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Fee:</string>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLabel" name="labelCoinControlFee">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="contextMenuPolicy">
+ <enum>Qt::ActionsContextMenu</enum>
+ </property>
+ <property name="text">
+ <string notr="true">0.00 BTC</string>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="labelCoinControlLowOutputText">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Dust:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLabel" name="labelCoinControlLowOutput">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="contextMenuPolicy">
+ <enum>Qt::ActionsContextMenu</enum>
+ </property>
+ <property name="text">
+ <string notr="true">no</string>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QFormLayout" name="formLayoutCoinControl4">
+ <property name="horizontalSpacing">
+ <number>10</number>
+ </property>
+ <property name="verticalSpacing">
+ <number>14</number>
+ </property>
+ <property name="leftMargin">
+ <number>6</number>
+ </property>
+ <property name="topMargin">
+ <number>4</number>
+ </property>
+ <property name="rightMargin">
+ <number>6</number>
+ </property>
+ <item row="0" column="0">
+ <widget class="QLabel" name="labelCoinControlAfterFeeText">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>After Fee:</string>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLabel" name="labelCoinControlAfterFee">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="contextMenuPolicy">
+ <enum>Qt::ActionsContextMenu</enum>
+ </property>
+ <property name="text">
+ <string notr="true">0.00 BTC</string>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="labelCoinControlChangeText">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Change:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLabel" name="labelCoinControlChange">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="contextMenuPolicy">
+ <enum>Qt::ActionsContextMenu</enum>
+ </property>
+ <property name="text">
+ <string notr="true">0.00 BTC</string>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayoutCoinControl4" stretch="0,0,0">
+ <property name="spacing">
+ <number>12</number>
+ </property>
+ <property name="sizeConstraint">
+ <enum>QLayout::SetDefaultConstraint</enum>
+ </property>
+ <property name="topMargin">
+ <number>5</number>
+ </property>
+ <property name="rightMargin">
+ <number>5</number>
+ </property>
+ <item>
+ <widget class="QCheckBox" name="checkBoxCoinControlChange">
+ <property name="toolTip">
+ <string>If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address.</string>
+ </property>
+ <property name="text">
+ <string>Custom change address</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QValidatedLineEdit" name="lineEditCoinControlChange">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="labelCoinControlChangeLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="margin">
+ <number>3</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacerCoinControl">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>800</width>
+ <height>1</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QScrollArea" name="scrollArea">
+ <property name="widgetResizable">
+ <bool>true</bool>
+ </property>
+ <widget class="QWidget" name="scrollAreaWidgetContents">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>830</width>
+ <height>68</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2" stretch="0,1">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <layout class="QVBoxLayout" name="entries">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ <item>
+ <widget class="QFrame" name="frameFee">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Sunken</enum>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayoutFee1">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayoutFee2" stretch="0,0,0">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>10</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayoutFee1">
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayoutFee7">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <item>
+ <spacer name="verticalSpacerSmartFee">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>1</width>
+ <height>4</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayoutSmartFee">
+ <property name="spacing">
+ <number>10</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="labelFeeHeadline">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">font-weight:bold;</string>
+ </property>
+ <property name="text">
+ <string>Transaction Fee:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="labelFeeMinimized">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonChooseFee">
+ <property name="text">
+ <string>Choose...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_5">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>1</width>
+ <height>1</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_4">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="buttonMinimizeFee">
+ <property name="toolTip">
+ <string>collapse fee-settings</string>
+ </property>
+ <property name="text">
+ <string>Hide</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QFrame" name="frameFeeSelection">
+ <layout class="QVBoxLayout" name="verticalLayoutFee12">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <layout class="QGridLayout" name="gridLayoutFee">
+ <property name="topMargin">
+ <number>10</number>
+ </property>
+ <property name="bottomMargin">
+ <number>4</number>
+ </property>
+ <property name="horizontalSpacing">
+ <number>10</number>
+ </property>
+ <property name="verticalSpacing">
+ <number>4</number>
+ </property>
+ <item row="1" column="1">
+ <layout class="QVBoxLayout" name="verticalLayoutFee8">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayoutFee13">
+ <item>
+ <widget class="QRadioButton" name="radioCustomPerKilobyte">
+ <property name="toolTip">
+ <string>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then &quot;per kilobyte&quot; only pays 250 satoshis in fee, while &quot;total at least&quot; pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</string>
+ </property>
+ <property name="text">
+ <string>per kilobyte</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <attribute name="buttonGroup">
+ <string notr="true">groupCustomFee</string>
+ </attribute>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="radioCustomAtLeast">
+ <property name="toolTip">
+ <string>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then &quot;per kilobyte&quot; only pays 250 satoshis in fee, while &quot;total at least&quot; pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</string>
+ </property>
+ <property name="text">
+ <string>total at least</string>
+ </property>
+ <attribute name="buttonGroup">
+ <string notr="true">groupCustomFee</string>
+ </attribute>
+ </widget>
+ </item>
+ <item>
+ <widget class="BitcoinAmountField" name="customFee"/>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_6">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>1</width>
+ <height>1</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayoutFee8">
+ <item>
+ <widget class="QCheckBox" name="checkBoxMinimumFee">
+ <property name="toolTip">
+ <string>Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process.</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="labelMinFeeWarning">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="toolTip">
+ <string>Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process.</string>
+ </property>
+ <property name="text">
+ <string>(read the tooltip)</string>
+ </property>
+ <property name="margin">
+ <number>5</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>1</width>
+ <height>1</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item row="0" column="0">
+ <layout class="QVBoxLayout" name="verticalLayoutFee4" stretch="0,1">
+ <item>
+ <widget class="QRadioButton" name="radioSmartFee">
+ <property name="text">
+ <string>Recommended:</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <attribute name="buttonGroup">
+ <string notr="true">groupFee</string>
+ </attribute>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>1</width>
+ <height>1</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="0">
+ <layout class="QVBoxLayout" name="verticalLayoutFee9" stretch="0,1">
+ <item>
+ <widget class="QRadioButton" name="radioCustomFee">
+ <property name="text">
+ <string>Custom:</string>
+ </property>
+ <attribute name="buttonGroup">
+ <string notr="true">groupFee</string>
+ </attribute>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_6">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>1</width>
+ <height>1</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item row="0" column="1">
+ <layout class="QVBoxLayout" name="verticalLayoutFee3" stretch="0,0,1">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="topMargin">
+ <number>2</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayoutFee12">
+ <item>
+ <widget class="QLabel" name="labelSmartFee">
+ <property name="text">
+ <string/>
+ </property>
+ <property name="margin">
+ <number>2</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="labelFeeEstimation">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="labelSmartFee2">
+ <property name="text">
+ <string>(Smart fee not initialized yet. This usually takes a few blocks...)</string>
+ </property>
+ <property name="margin">
+ <number>2</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_5">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>1</width>
+ <height>1</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayoutFee9">
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayoutFee6">
+ <item>
+ <widget class="QLabel" name="labelSmartFee3">
+ <property name="text">
+ <string>Confirmation time:</string>
+ </property>
+ <property name="margin">
+ <number>2</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>1</width>
+ <height>1</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayoutFee5">
+ <property name="rightMargin">
+ <number>30</number>
+ </property>
+ <item>
+ <widget class="QSlider" name="sliderSmartFee">
+ <property name="minimum">
+ <number>0</number>
+ </property>
+ <property name="maximum">
+ <number>24</number>
+ </property>
+ <property name="pageStep">
+ <number>1</number>
+ </property>
+ <property name="value">
+ <number>0</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="invertedAppearance">
+ <bool>false</bool>
+ </property>
+ <property name="invertedControls">
+ <bool>false</bool>
+ </property>
+ <property name="tickPosition">
+ <enum>QSlider::NoTicks</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayoutFee10">
+ <item>
+ <widget class="QLabel" name="labelSmartFeeNormal">
+ <property name="text">
+ <string>normal</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="labelSmartFeeFast">
+ <property name="text">
+ <string>fast</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_4">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>1</width>
+ <height>1</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayoutFee5" stretch="0,0,0">
+ <property name="spacing">
+ <number>8</number>
+ </property>
+ <property name="bottomMargin">
+ <number>4</number>
+ </property>
+ <item>
+ <widget class="QCheckBox" name="checkBoxFreeTx">
+ <property name="text">
+ <string>Send as zero-fee transaction if possible</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="labelFreeTx">
+ <property name="text">
+ <string>(confirmation may take longer)</string>
+ </property>
+ <property name="margin">
+ <number>5</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacerFee5">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>1</width>
+ <height>1</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacerFee2">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>1</width>
+ <height>1</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacerFee">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>800</width>
+ <height>1</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QPushButton" name="sendButton">
+ <property name="minimumSize">
+ <size>
+ <width>150</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>Confirm the send action</string>
+ </property>
+ <property name="text">
+ <string>S&amp;end</string>
+ </property>
+ <property name="icon">
+ <iconset resource="../bitcoin.qrc">
+ <normaloff>:/icons/send</normaloff>:/icons/send</iconset>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ <property name="default">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="clearButton">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Clear all fields of the form.</string>
+ </property>
+ <property name="text">
+ <string>Clear &amp;All</string>
+ </property>
+ <property name="icon">
+ <iconset resource="../bitcoin.qrc">
+ <normaloff>:/icons/remove</normaloff>:/icons/remove</iconset>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="addButton">
+ <property name="toolTip">
+ <string>Send to multiple recipients at once</string>
+ </property>
+ <property name="text">
+ <string>Add &amp;Recipient</string>
+ </property>
+ <property name="icon">
+ <iconset resource="../bitcoin.qrc">
+ <normaloff>:/icons/add</normaloff>:/icons/add</iconset>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <property name="spacing">
+ <number>3</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Balance:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="labelBalance">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string notr="true">123.456 BTC</string>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>QValidatedLineEdit</class>
+ <extends>QLineEdit</extends>
+ <header>qvalidatedlineedit.h</header>
+ </customwidget>
+ <customwidget>
+ <class>BitcoinAmountField</class>
+ <extends>QLineEdit</extends>
+ <header>bitcoinamountfield.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources>
+ <include location="../bitcoin.qrc"/>
+ </resources>
+ <connections/>
+ <buttongroups>
+ <buttongroup name="groupFee"/>
+ <buttongroup name="groupCustomFee"/>
+ </buttongroups>
+</ui>
diff --git a/src/qt/forms/sendcoinsentry.ui b/src/qt/forms/sendcoinsentry.ui
new file mode 100644
index 0000000000..df06f36833
--- /dev/null
+++ b/src/qt/forms/sendcoinsentry.ui
@@ -0,0 +1,1275 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>SendCoinsEntry</class>
+ <widget class="QStackedWidget" name="SendCoinsEntry">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>729</width>
+ <height>150</height>
+ </rect>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::TabFocus</enum>
+ </property>
+ <property name="autoFillBackground">
+ <bool>false</bool>
+ </property>
+ <widget class="QFrame" name="SendCoins">
+ <property name="toolTip">
+ <string>This is a normal payment.</string>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <property name="topMargin">
+ <number>8</number>
+ </property>
+ <property name="bottomMargin">
+ <number>4</number>
+ </property>
+ <property name="horizontalSpacing">
+ <number>12</number>
+ </property>
+ <property name="verticalSpacing">
+ <number>8</number>
+ </property>
+ <item row="0" column="0">
+ <widget class="QLabel" name="payToLabel">
+ <property name="text">
+ <string>Pay &amp;To:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ <property name="buddy">
+ <cstring>payTo</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <layout class="QHBoxLayout" name="payToLayout">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QValidatedLineEdit" name="payTo">
+ <property name="toolTip">
+ <string>The Bitcoin address to send the payment to</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="addressBookButton">
+ <property name="toolTip">
+ <string>Choose previously used address</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="../bitcoin.qrc">
+ <normaloff>:/icons/address-book</normaloff>:/icons/address-book</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>22</width>
+ <height>22</height>
+ </size>
+ </property>
+ <property name="shortcut">
+ <string>Alt+A</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="pasteButton">
+ <property name="toolTip">
+ <string>Paste address from clipboard</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="../bitcoin.qrc">
+ <normaloff>:/icons/editpaste</normaloff>:/icons/editpaste</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>22</width>
+ <height>22</height>
+ </size>
+ </property>
+ <property name="shortcut">
+ <string>Alt+P</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="deleteButton">
+ <property name="toolTip">
+ <string>Remove this entry</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="../bitcoin.qrc">
+ <normaloff>:/icons/remove</normaloff>:/icons/remove</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>22</width>
+ <height>22</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="labellLabel">
+ <property name="text">
+ <string>&amp;Label:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ <property name="buddy">
+ <cstring>addAsLabel</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="addAsLabel">
+ <property name="toolTip">
+ <string>Enter a label for this address to add it to the list of used addresses</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="amountLabel">
+ <property name="text">
+ <string>A&amp;mount:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ <property name="buddy">
+ <cstring>payAmount</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <layout class="QHBoxLayout" name="horizontalLayoutAmount" stretch="0,1">
+ <item>
+ <widget class="BitcoinAmountField" name="payAmount"/>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="checkboxSubtractFeeFromAmount">
+ <property name="toolTip">
+ <string>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</string>
+ </property>
+ <property name="text">
+ <string>S&amp;ubtract fee from amount</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="messageLabel">
+ <property name="text">
+ <string>Message:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QLabel" name="messageTextLabel">
+ <property name="toolTip">
+ <string>A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network.</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0" colspan="2">
+ <widget class="Line" name="line">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QFrame" name="SendCoins_UnauthenticatedPaymentRequest">
+ <property name="palette">
+ <palette>
+ <active>
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Button">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Light">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Midlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>191</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>127</red>
+ <green>127</green>
+ <blue>63</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>170</red>
+ <green>170</green>
+ <blue>84</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="BrightText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ButtonText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Base">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Shadow">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="AlternateBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>191</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ToolTipBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>220</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ToolTipText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </active>
+ <inactive>
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Button">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Light">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Midlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>191</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>127</red>
+ <green>127</green>
+ <blue>63</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>170</red>
+ <green>170</green>
+ <blue>84</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="BrightText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ButtonText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Base">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Shadow">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="AlternateBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>191</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ToolTipBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>220</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ToolTipText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </inactive>
+ <disabled>
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>127</red>
+ <green>127</green>
+ <blue>63</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Button">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Light">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Midlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>191</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>127</red>
+ <green>127</green>
+ <blue>63</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>170</red>
+ <green>170</green>
+ <blue>84</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>127</red>
+ <green>127</green>
+ <blue>63</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="BrightText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ButtonText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>127</red>
+ <green>127</green>
+ <blue>63</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Base">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Shadow">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="AlternateBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ToolTipBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>220</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ToolTipText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </disabled>
+ </palette>
+ </property>
+ <property name="toolTip">
+ <string>This is an unauthenticated payment request.</string>
+ </property>
+ <property name="autoFillBackground">
+ <bool>true</bool>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_is">
+ <property name="spacing">
+ <number>12</number>
+ </property>
+ <item row="0" column="0">
+ <widget class="QLabel" name="payToLabel_is">
+ <property name="text">
+ <string>Pay To:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <layout class="QHBoxLayout" name="payToLayout_is">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="payTo_is"/>
+ </item>
+ <item>
+ <widget class="QToolButton" name="deleteButton_is">
+ <property name="toolTip">
+ <string>Remove this entry</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="../bitcoin.qrc">
+ <normaloff>:/icons/remove</normaloff>:/icons/remove</iconset>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="memoLabel_is">
+ <property name="text">
+ <string>Memo:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLabel" name="memoTextLabel_is">
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="amountLabel_is">
+ <property name="text">
+ <string>A&amp;mount:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ <property name="buddy">
+ <cstring>payAmount_is</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="BitcoinAmountField" name="payAmount_is">
+ <property name="acceptDrops">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QFrame" name="SendCoins_AuthenticatedPaymentRequest">
+ <property name="palette">
+ <palette>
+ <active>
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Button">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>140</red>
+ <green>232</green>
+ <blue>119</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Light">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>230</red>
+ <green>255</green>
+ <blue>224</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Midlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>185</red>
+ <green>243</green>
+ <blue>171</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>70</red>
+ <green>116</green>
+ <blue>59</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>93</red>
+ <green>155</green>
+ <blue>79</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="BrightText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>155</red>
+ <green>255</green>
+ <blue>147</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ButtonText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Base">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>119</red>
+ <green>255</green>
+ <blue>233</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>140</red>
+ <green>232</green>
+ <blue>119</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Shadow">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="AlternateBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>197</red>
+ <green>243</green>
+ <blue>187</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="NoRole">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>125</red>
+ <green>194</green>
+ <blue>122</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ToolTipBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>220</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ToolTipText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </active>
+ <inactive>
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Button">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>140</red>
+ <green>232</green>
+ <blue>119</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Light">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>230</red>
+ <green>255</green>
+ <blue>224</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Midlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>185</red>
+ <green>243</green>
+ <blue>171</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>70</red>
+ <green>116</green>
+ <blue>59</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>93</red>
+ <green>155</green>
+ <blue>79</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="BrightText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>155</red>
+ <green>255</green>
+ <blue>147</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ButtonText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Base">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>119</red>
+ <green>255</green>
+ <blue>233</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>140</red>
+ <green>232</green>
+ <blue>119</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Shadow">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="AlternateBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>197</red>
+ <green>243</green>
+ <blue>187</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="NoRole">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>125</red>
+ <green>194</green>
+ <blue>122</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ToolTipBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>220</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ToolTipText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </inactive>
+ <disabled>
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>70</red>
+ <green>116</green>
+ <blue>59</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Button">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>140</red>
+ <green>232</green>
+ <blue>119</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Light">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>230</red>
+ <green>255</green>
+ <blue>224</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Midlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>185</red>
+ <green>243</green>
+ <blue>171</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>70</red>
+ <green>116</green>
+ <blue>59</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>93</red>
+ <green>155</green>
+ <blue>79</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>70</red>
+ <green>116</green>
+ <blue>59</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="BrightText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>155</red>
+ <green>255</green>
+ <blue>147</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ButtonText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>70</red>
+ <green>116</green>
+ <blue>59</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Base">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>140</red>
+ <green>232</green>
+ <blue>119</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>140</red>
+ <green>232</green>
+ <blue>119</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Shadow">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="AlternateBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>140</red>
+ <green>232</green>
+ <blue>119</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="NoRole">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>125</red>
+ <green>194</green>
+ <blue>122</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ToolTipBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>220</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ToolTipText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </disabled>
+ </palette>
+ </property>
+ <property name="toolTip">
+ <string>This is an authenticated payment request.</string>
+ </property>
+ <property name="autoFillBackground">
+ <bool>true</bool>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_s">
+ <property name="spacing">
+ <number>12</number>
+ </property>
+ <item row="0" column="0">
+ <widget class="QLabel" name="payToLabel_s">
+ <property name="text">
+ <string>Pay To:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <layout class="QHBoxLayout" name="payToLayout_s">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="payTo_s">
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="deleteButton_s">
+ <property name="toolTip">
+ <string>Remove this entry</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="../bitcoin.qrc">
+ <normaloff>:/icons/remove</normaloff>:/icons/remove</iconset>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="memoLabel_s">
+ <property name="text">
+ <string>Memo:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLabel" name="memoTextLabel_s">
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="amountLabel_s">
+ <property name="text">
+ <string>A&amp;mount:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ <property name="buddy">
+ <cstring>payAmount_s</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="BitcoinAmountField" name="payAmount_s">
+ <property name="acceptDrops">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>QValidatedLineEdit</class>
+ <extends>QLineEdit</extends>
+ <header>qvalidatedlineedit.h</header>
+ </customwidget>
+ <customwidget>
+ <class>BitcoinAmountField</class>
+ <extends>QLineEdit</extends>
+ <header>bitcoinamountfield.h</header>
+ </customwidget>
+ </customwidgets>
+ <tabstops>
+ <tabstop>payTo</tabstop>
+ <tabstop>addressBookButton</tabstop>
+ <tabstop>pasteButton</tabstop>
+ <tabstop>deleteButton</tabstop>
+ <tabstop>addAsLabel</tabstop>
+ <tabstop>payAmount</tabstop>
+ <tabstop>payAmount_is</tabstop>
+ <tabstop>deleteButton_is</tabstop>
+ <tabstop>payAmount_s</tabstop>
+ <tabstop>deleteButton_s</tabstop>
+ </tabstops>
+ <resources>
+ <include location="../bitcoin.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/src/qt/forms/signverifymessagedialog.ui b/src/qt/forms/signverifymessagedialog.ui
new file mode 100644
index 0000000000..92f6430c51
--- /dev/null
+++ b/src/qt/forms/signverifymessagedialog.ui
@@ -0,0 +1,390 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>SignVerifyMessageDialog</class>
+ <widget class="QDialog" name="SignVerifyMessageDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>700</width>
+ <height>380</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Signatures - Sign / Verify a Message</string>
+ </property>
+ <property name="modal">
+ <bool>true</bool>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QTabWidget" name="tabWidget">
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="tabSignMessage">
+ <attribute name="title">
+ <string>&amp;Sign Message</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_SM">
+ <item>
+ <widget class="QLabel" name="infoLabel_SM">
+ <property name="text">
+ <string>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_1_SM">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QValidatedLineEdit" name="addressIn_SM">
+ <property name="toolTip">
+ <string>The Bitcoin address to sign the message with</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="addressBookButton_SM">
+ <property name="toolTip">
+ <string>Choose previously used address</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="../bitcoin.qrc">
+ <normaloff>:/icons/address-book</normaloff>:/icons/address-book</iconset>
+ </property>
+ <property name="shortcut">
+ <string>Alt+A</string>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="pasteButton_SM">
+ <property name="toolTip">
+ <string>Paste address from clipboard</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="../bitcoin.qrc">
+ <normaloff>:/icons/editpaste</normaloff>:/icons/editpaste</iconset>
+ </property>
+ <property name="shortcut">
+ <string>Alt+P</string>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QPlainTextEdit" name="messageIn_SM">
+ <property name="toolTip">
+ <string>Enter the message you want to sign here</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="signatureLabel_SM">
+ <property name="text">
+ <string>Signature</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2_SM">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLineEdit" name="signatureOut_SM">
+ <property name="font">
+ <font>
+ <italic>true</italic>
+ </font>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="copySignatureButton_SM">
+ <property name="toolTip">
+ <string>Copy the current signature to the system clipboard</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="../bitcoin.qrc">
+ <normaloff>:/icons/editcopy</normaloff>:/icons/editcopy</iconset>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_3_SM">
+ <item>
+ <widget class="QPushButton" name="signMessageButton_SM">
+ <property name="toolTip">
+ <string>Sign the message to prove you own this Bitcoin address</string>
+ </property>
+ <property name="text">
+ <string>Sign &amp;Message</string>
+ </property>
+ <property name="icon">
+ <iconset resource="../bitcoin.qrc">
+ <normaloff>:/icons/edit</normaloff>:/icons/edit</iconset>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="clearButton_SM">
+ <property name="toolTip">
+ <string>Reset all sign message fields</string>
+ </property>
+ <property name="text">
+ <string>Clear &amp;All</string>
+ </property>
+ <property name="icon">
+ <iconset resource="../bitcoin.qrc">
+ <normaloff>:/icons/remove</normaloff>:/icons/remove</iconset>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_1_SM">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>48</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="statusLabel_SM">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2_SM">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>48</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tabVerifyMessage">
+ <attribute name="title">
+ <string>&amp;Verify Message</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_VM">
+ <item>
+ <widget class="QLabel" name="infoLabel_VM">
+ <property name="text">
+ <string>Enter the receiver's 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. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_1_VM">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QValidatedLineEdit" name="addressIn_VM">
+ <property name="toolTip">
+ <string>The Bitcoin address the message was signed with</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="addressBookButton_VM">
+ <property name="toolTip">
+ <string>Choose previously used address</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="../bitcoin.qrc">
+ <normaloff>:/icons/address-book</normaloff>:/icons/address-book</iconset>
+ </property>
+ <property name="shortcut">
+ <string>Alt+A</string>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QPlainTextEdit" name="messageIn_VM"/>
+ </item>
+ <item>
+ <widget class="QValidatedLineEdit" name="signatureIn_VM"/>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2_VM">
+ <item>
+ <widget class="QPushButton" name="verifyMessageButton_VM">
+ <property name="toolTip">
+ <string>Verify the message to ensure it was signed with the specified Bitcoin address</string>
+ </property>
+ <property name="text">
+ <string>Verify &amp;Message</string>
+ </property>
+ <property name="icon">
+ <iconset resource="../bitcoin.qrc">
+ <normaloff>:/icons/transaction_0</normaloff>:/icons/transaction_0</iconset>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="clearButton_VM">
+ <property name="toolTip">
+ <string>Reset all verify message fields</string>
+ </property>
+ <property name="text">
+ <string>Clear &amp;All</string>
+ </property>
+ <property name="icon">
+ <iconset resource="../bitcoin.qrc">
+ <normaloff>:/icons/remove</normaloff>:/icons/remove</iconset>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_1_VM">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>48</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="statusLabel_VM">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2_VM">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>48</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>QValidatedLineEdit</class>
+ <extends>QLineEdit</extends>
+ <header>qvalidatedlineedit.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources>
+ <include location="../bitcoin.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/src/qt/forms/transactiondescdialog.ui b/src/qt/forms/transactiondescdialog.ui
new file mode 100644
index 0000000000..5ae1e12856
--- /dev/null
+++ b/src/qt/forms/transactiondescdialog.ui
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>TransactionDescDialog</class>
+ <widget class="QDialog" name="TransactionDescDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>620</width>
+ <height>250</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Transaction details</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QTextEdit" name="detailText">
+ <property name="toolTip">
+ <string>This pane shows a detailed description of the transaction</string>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Close</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>TransactionDescDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>20</x>
+ <y>20</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>20</x>
+ <y>20</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>TransactionDescDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>20</x>
+ <y>20</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>20</x>
+ <y>20</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/qt/guiconstants.h b/src/qt/guiconstants.h
new file mode 100644
index 0000000000..a0a2993ea3
--- /dev/null
+++ b/src/qt/guiconstants.h
@@ -0,0 +1,52 @@
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_GUICONSTANTS_H
+#define BITCOIN_QT_GUICONSTANTS_H
+
+/* Milliseconds between model updates */
+static const int MODEL_UPDATE_DELAY = 250;
+
+/* 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)
+/* Transaction list -- TX status decoration - open until date */
+#define COLOR_TX_STATUS_OPENUNTILDATE QColor(64, 64, 255)
+/* Transaction list -- TX status decoration - offline */
+#define COLOR_TX_STATUS_OFFLINE QColor(192, 192, 192)
+/* Transaction list -- TX status decoration - default color */
+#define COLOR_BLACK QColor(0, 0, 0)
+
+/* 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
+
+/* Number of frames in spinner animation */
+#define SPINNER_FRAMES 35
+
+#define QAPP_ORG_NAME "Bitcoin"
+#define QAPP_ORG_DOMAIN "bitcoin.org"
+#define QAPP_APP_NAME_DEFAULT "Bitcoin-Qt"
+#define QAPP_APP_NAME_TESTNET "Bitcoin-Qt-testnet"
+
+#endif // BITCOIN_QT_GUICONSTANTS_H
diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp
new file mode 100644
index 0000000000..4a1f728e18
--- /dev/null
+++ b/src/qt/guiutil.cpp
@@ -0,0 +1,908 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "guiutil.h"
+
+#include "bitcoinaddressvalidator.h"
+#include "bitcoinunits.h"
+#include "qvalidatedlineedit.h"
+#include "walletmodel.h"
+
+#include "primitives/transaction.h"
+#include "init.h"
+#include "main.h"
+#include "protocol.h"
+#include "script/script.h"
+#include "script/standard.h"
+#include "util.h"
+
+#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 "shellapi.h"
+#include "shlobj.h"
+#include "shlwapi.h"
+#endif
+
+#include <boost/filesystem.hpp>
+#include <boost/filesystem/fstream.hpp>
+#if BOOST_FILESYSTEM_VERSION >= 3
+#include <boost/filesystem/detail/utf8_codecvt_facet.hpp>
+#endif
+#include <boost/scoped_array.hpp>
+
+#include <QAbstractItemView>
+#include <QApplication>
+#include <QClipboard>
+#include <QDateTime>
+#include <QDesktopServices>
+#include <QDesktopWidget>
+#include <QDoubleValidator>
+#include <QFileDialog>
+#include <QFont>
+#include <QLineEdit>
+#include <QSettings>
+#include <QTextDocument> // for Qt::mightBeRichText
+#include <QThread>
+
+#if QT_VERSION < 0x050000
+#include <QUrl>
+#else
+#include <QUrlQuery>
+#endif
+
+#if BOOST_FILESYSTEM_VERSION >= 3
+static boost::filesystem::detail::utf8_codecvt_facet utf8;
+#endif
+
+#if defined(Q_OS_MAC)
+extern double NSAppKitVersionNumber;
+#if !defined(NSAppKitVersionNumber10_8)
+#define NSAppKitVersionNumber10_8 1187
+#endif
+#if !defined(NSAppKitVersionNumber10_9)
+#define NSAppKitVersionNumber10_9 1265
+#endif
+#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");
+#if QT_VERSION >= 0x040800
+ font.setStyleHint(QFont::Monospace);
+#else
+ font.setStyleHint(QFont::TypeWriter);
+#endif
+ return font;
+}
+
+void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent)
+{
+ parent->setFocusProxy(widget);
+
+ widget->setFont(bitcoinAddressFont());
+#if QT_VERSION >= 0x040700
+ // We don't want translators to use own addresses in translations
+ // and this is the only place, where this address is supplied.
+ widget->setPlaceholderText(QObject::tr("Enter a Bitcoin address (e.g. %1)").arg("1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L"));
+#endif
+ widget->setValidator(new BitcoinAddressEntryValidator(parent));
+ widget->setCheckValidator(new BitcoinAddressCheckValidator(parent));
+}
+
+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)
+{
+ // return if URI is not valid or is no bitcoin: URI
+ if(!uri.isValid() || uri.scheme() != QString("bitcoin"))
+ return false;
+
+ SendCoinsRecipient rv;
+ rv.address = uri.path();
+ // Trim any following forward slash which may have been added by the OS
+ if (rv.address.endsWith("/")) {
+ rv.address.truncate(rv.address.length() - 1);
+ }
+ rv.amount = 0;
+
+#if QT_VERSION < 0x050000
+ QList<QPair<QString, QString> > items = uri.queryItems();
+#else
+ QUrlQuery uriQuery(uri);
+ QList<QPair<QString, QString> > items = uriQuery.queryItems();
+#endif
+ for (QList<QPair<QString, QString> >::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;
+ }
+ if (i->first == "message")
+ {
+ rv.message = 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 bitcoin:// to bitcoin:
+ //
+ // Cannot handle this later, because bitcoin:// will cause Qt to see the part after // as host,
+ // which will lower-case it (and thus invalidate the address).
+ if(uri.startsWith("bitcoin://", Qt::CaseInsensitive))
+ {
+ uri.replace(0, 10, "bitcoin:");
+ }
+ QUrl uriInstance(uri);
+ return parseBitcoinURI(uriInstance, out);
+}
+
+QString formatBitcoinURI(const SendCoinsRecipient &info)
+{
+ QString ret = QString("bitcoin:%1").arg(info.address);
+ int paramCount = 0;
+
+ if (info.amount)
+ {
+ ret += QString("?amount=%1").arg(BitcoinUnits::format(BitcoinUnits::BTC, info.amount, false, BitcoinUnits::separatorNever));
+ paramCount++;
+ }
+
+ if (!info.label.isEmpty())
+ {
+ QString lbl(QUrl::toPercentEncoding(info.label));
+ ret += QString("%1label=%2").arg(paramCount == 0 ? "?" : "&").arg(lbl);
+ paramCount++;
+ }
+
+ if (!info.message.isEmpty())
+ {
+ QString msg(QUrl::toPercentEncoding(info.message));;
+ ret += QString("%1message=%2").arg(paramCount == 0 ? "?" : "&").arg(msg);
+ paramCount++;
+ }
+
+ return ret;
+}
+
+bool isDust(const QString& address, const CAmount& amount)
+{
+ CTxDestination dest = CBitcoinAddress(address.toStdString()).Get();
+ CScript script = GetScriptForDestination(dest);
+ CTxOut txOut(amount, script);
+ return txOut.IsDust(::minRelayTxFee);
+}
+
+QString HtmlEscape(const QString& str, bool fMultiLine)
+{
+#if QT_VERSION < 0x050000
+ QString escaped = Qt::escape(str);
+#else
+ QString escaped = str.toHtmlEscaped();
+#endif
+ if(fMultiLine)
+ {
+ escaped = escaped.replace("\n", "<br>\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
+ setClipboard(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
+ {
+#if QT_VERSION < 0x050000
+ myDir = QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation);
+#else
+ myDir = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
+#endif
+ }
+ else
+ {
+ myDir = dir;
+ }
+ /* Directly convert path to native OS path separators */
+ QString result = QDir::toNativeSeparators(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;
+}
+
+QString getOpenFileName(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
+ {
+#if QT_VERSION < 0x050000
+ myDir = QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation);
+#else
+ myDir = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
+#endif
+ }
+ else
+ {
+ myDir = dir;
+ }
+ /* Directly convert path to native OS path separators */
+ QString result = QDir::toNativeSeparators(QFileDialog::getOpenFileName(parent, caption, myDir, filter, &selectedFilter));
+
+ if(selectedSuffixOut)
+ {
+ /* 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);
+ }
+ *selectedSuffixOut = selectedSuffix;
+ }
+ return result;
+}
+
+Qt::ConnectionType blockingGUIThreadConnection()
+{
+ if(QThread::currentThread() != qApp->thread())
+ {
+ return Qt::BlockingQueuedConnection;
+ }
+ else
+ {
+ return Qt::DirectConnection;
+ }
+}
+
+bool checkPoint(const QPoint &p, const QWidget *w)
+{
+ QWidget *atW = QApplication::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(boostPathToQString(pathDebug)));
+}
+
+void SubstituteFonts(const QString& language)
+{
+#if defined(Q_OS_MAC)
+// Background:
+// OSX's default font changed in 10.9 and QT is unable to find it with its
+// usual fallback methods when building against the 10.7 sdk or lower.
+// The 10.8 SDK added a function to let it find the correct fallback font.
+// If this fallback is not properly loaded, some characters may fail to
+// render correctly.
+//
+// The same thing happened with 10.10. .Helvetica Neue DeskInterface is now default.
+//
+// Solution: If building with the 10.7 SDK or lower and the user's platform
+// is 10.9 or higher at runtime, substitute the correct font. This needs to
+// happen before the QApplication is created.
+#if defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_8
+ if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_8)
+ {
+ if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_9)
+ /* On a 10.9 - 10.9.x system */
+ QFont::insertSubstitution(".Lucida Grande UI", "Lucida Grande");
+ else
+ {
+ /* 10.10 or later system */
+ if (language == "zh_CN" || language == "zh_TW" || language == "zh_HK") // traditional or simplified Chinese
+ QFont::insertSubstitution(".Helvetica Neue DeskInterface", "Heiti SC");
+ else if (language == "ja") // Japanesee
+ QFont::insertSubstitution(".Helvetica Neue DeskInterface", "Songti SC");
+ else
+ QFont::insertSubstitution(".Helvetica Neue DeskInterface", "Lucida Grande");
+ }
+ }
+#endif
+#endif
+}
+
+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<QWidget*>(obj);
+ QString tooltip = widget->toolTip();
+ if(tooltip.size() > size_threshold && !tooltip.startsWith("<qt") && !Qt::mightBeRichText(tooltip))
+ {
+ // Envelop with <qt></qt> to make sure Qt detects this as rich text
+ // Escape the current message as HTML and replace \n by <br>
+ tooltip = "<qt>" + HtmlEscape(tooltip, true) + "</qt>";
+ widget->setToolTip(tooltip);
+ return true;
+ }
+ }
+ return QObject::eventFilter(obj, evt);
+}
+
+void TableViewLastColumnResizingFixer::connectViewHeadersSignals()
+{
+ connect(tableView->horizontalHeader(), SIGNAL(sectionResized(int,int,int)), this, SLOT(on_sectionResized(int,int,int)));
+ connect(tableView->horizontalHeader(), SIGNAL(geometriesChanged()), this, SLOT(on_geometriesChanged()));
+}
+
+// We need to disconnect these while handling the resize events, otherwise we can enter infinite loops.
+void TableViewLastColumnResizingFixer::disconnectViewHeadersSignals()
+{
+ disconnect(tableView->horizontalHeader(), SIGNAL(sectionResized(int,int,int)), this, SLOT(on_sectionResized(int,int,int)));
+ disconnect(tableView->horizontalHeader(), SIGNAL(geometriesChanged()), this, SLOT(on_geometriesChanged()));
+}
+
+// Setup the resize mode, handles compatibility for Qt5 and below as the method signatures changed.
+// Refactored here for readability.
+void TableViewLastColumnResizingFixer::setViewHeaderResizeMode(int logicalIndex, QHeaderView::ResizeMode resizeMode)
+{
+#if QT_VERSION < 0x050000
+ tableView->horizontalHeader()->setResizeMode(logicalIndex, resizeMode);
+#else
+ tableView->horizontalHeader()->setSectionResizeMode(logicalIndex, resizeMode);
+#endif
+}
+
+void TableViewLastColumnResizingFixer::resizeColumn(int nColumnIndex, int width)
+{
+ tableView->setColumnWidth(nColumnIndex, width);
+ tableView->horizontalHeader()->resizeSection(nColumnIndex, width);
+}
+
+int TableViewLastColumnResizingFixer::getColumnsWidth()
+{
+ int nColumnsWidthSum = 0;
+ for (int i = 0; i < columnCount; i++)
+ {
+ nColumnsWidthSum += tableView->horizontalHeader()->sectionSize(i);
+ }
+ return nColumnsWidthSum;
+}
+
+int TableViewLastColumnResizingFixer::getAvailableWidthForColumn(int column)
+{
+ int nResult = lastColumnMinimumWidth;
+ int nTableWidth = tableView->horizontalHeader()->width();
+
+ if (nTableWidth > 0)
+ {
+ int nOtherColsWidth = getColumnsWidth() - tableView->horizontalHeader()->sectionSize(column);
+ nResult = std::max(nResult, nTableWidth - nOtherColsWidth);
+ }
+
+ return nResult;
+}
+
+// Make sure we don't make the columns wider than the tables viewport width.
+void TableViewLastColumnResizingFixer::adjustTableColumnsWidth()
+{
+ disconnectViewHeadersSignals();
+ resizeColumn(lastColumnIndex, getAvailableWidthForColumn(lastColumnIndex));
+ connectViewHeadersSignals();
+
+ int nTableWidth = tableView->horizontalHeader()->width();
+ int nColsWidth = getColumnsWidth();
+ if (nColsWidth > nTableWidth)
+ {
+ resizeColumn(secondToLastColumnIndex,getAvailableWidthForColumn(secondToLastColumnIndex));
+ }
+}
+
+// Make column use all the space available, useful during window resizing.
+void TableViewLastColumnResizingFixer::stretchColumnWidth(int column)
+{
+ disconnectViewHeadersSignals();
+ resizeColumn(column, getAvailableWidthForColumn(column));
+ connectViewHeadersSignals();
+}
+
+// When a section is resized this is a slot-proxy for ajustAmountColumnWidth().
+void TableViewLastColumnResizingFixer::on_sectionResized(int logicalIndex, int oldSize, int newSize)
+{
+ adjustTableColumnsWidth();
+ int remainingWidth = getAvailableWidthForColumn(logicalIndex);
+ if (newSize > remainingWidth)
+ {
+ resizeColumn(logicalIndex, remainingWidth);
+ }
+}
+
+// When the tabless geometry is ready, we manually perform the stretch of the "Message" column,
+// as the "Stretch" resize mode does not allow for interactive resizing.
+void TableViewLastColumnResizingFixer::on_geometriesChanged()
+{
+ if ((getColumnsWidth() - this->tableView->horizontalHeader()->width()) != 0)
+ {
+ disconnectViewHeadersSignals();
+ resizeColumn(secondToLastColumnIndex, getAvailableWidthForColumn(secondToLastColumnIndex));
+ connectViewHeadersSignals();
+ }
+}
+
+/**
+ * Initializes all internal variables and prepares the
+ * the resize modes of the last 2 columns of the table and
+ */
+TableViewLastColumnResizingFixer::TableViewLastColumnResizingFixer(QTableView* table, int lastColMinimumWidth, int allColsMinimumWidth) :
+ tableView(table),
+ lastColumnMinimumWidth(lastColMinimumWidth),
+ allColumnsMinimumWidth(allColsMinimumWidth)
+{
+ columnCount = tableView->horizontalHeader()->count();
+ lastColumnIndex = columnCount - 1;
+ secondToLastColumnIndex = columnCount - 2;
+ tableView->horizontalHeader()->setMinimumSectionSize(allColumnsMinimumWidth);
+ setViewHeaderResizeMode(secondToLastColumnIndex, QHeaderView::Interactive);
+ setViewHeaderResizeMode(lastColumnIndex, QHeaderView::Interactive);
+}
+
+#ifdef WIN32
+boost::filesystem::path static StartupShortcutPath()
+{
+ if (GetBoolArg("-testnet", false))
+ return GetSpecialFolderPath(CSIDL_STARTUP) / "Bitcoin (testnet).lnk";
+ else if (GetBoolArg("-regtest", false))
+ return GetSpecialFolderPath(CSIDL_STARTUP) / "Bitcoin (regtest).lnk";
+
+ return GetSpecialFolderPath(CSIDL_STARTUP) / "Bitcoin.lnk";
+}
+
+bool GetStartOnSystemStartup()
+{
+ // check for Bitcoin*.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<void**>(&psl));
+
+ if (SUCCEEDED(hres))
+ {
+ // Get the current executable path
+ TCHAR pszExePath[MAX_PATH];
+ GetModuleFileName(NULL, pszExePath, sizeof(pszExePath));
+
+ // Start client minimized
+ QString strArgs = "-min";
+ // Set -testnet /-regtest options
+ strArgs += QString::fromStdString(strprintf(" -testnet=%d -regtest=%d", GetBoolArg("-testnet", false), GetBoolArg("-regtest", false)));
+
+#ifdef UNICODE
+ boost::scoped_array<TCHAR> args(new TCHAR[strArgs.length() + 1]);
+ // Convert the QString to TCHAR*
+ strArgs.toWCharArray(args.get());
+ // Add missing '\0'-termination to string
+ args[strArgs.length()] = '\0';
+#endif
+
+ // Set the path to the shortcut target
+ psl->SetPath(pszExePath);
+ PathRemoveFileSpec(pszExePath);
+ psl->SetWorkingDirectory(pszExePath);
+ psl->SetShowCmd(SW_SHOWMINNOACTIVE);
+#ifndef UNICODE
+ psl->SetArguments(strArgs.toStdString().c_str());
+#else
+ psl->SetArguments(args.get());
+#endif
+
+ // Query IShellLink for the IPersistFile interface for
+ // saving the shortcut in persistent storage.
+ IPersistFile* ppf = NULL;
+ hres = psl->QueryInterface(IID_IPersistFile, reinterpret_cast<void**>(&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(Q_OS_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() / "bitcoin.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 bitcoin.desktop file to the autostart directory:
+ optionFile << "[Desktop Entry]\n";
+ optionFile << "Type=Application\n";
+ if (GetBoolArg("-testnet", false))
+ optionFile << "Name=Bitcoin (testnet)\n";
+ else if (GetBoolArg("-regtest", false))
+ optionFile << "Name=Bitcoin (regtest)\n";
+ else
+ optionFile << "Name=Bitcoin\n";
+ optionFile << "Exec=" << pszExePath << strprintf(" -min -testnet=%d -regtest=%d\n", GetBoolArg("-testnet", false), GetBoolArg("-regtest", false));
+ optionFile << "Terminal=false\n";
+ optionFile << "Hidden=false\n";
+ optionFile.close();
+ }
+ return true;
+}
+
+
+#elif defined(Q_OS_MAC)
+// based on: https://github.com/Mozketo/LaunchAtLoginController/blob/master/LaunchAtLoginController.m
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <CoreServices/CoreServices.h>
+
+LSSharedFileListItemRef findStartupItemInList(LSSharedFileListRef list, CFURLRef findUrl);
+LSSharedFileListItemRef findStartupItemInList(LSSharedFileListRef list, CFURLRef findUrl)
+{
+ // loop through the list of startup items and try to find the bitcoin app
+ CFArrayRef listSnapshot = LSSharedFileListCopySnapshot(list, NULL);
+ for(int i = 0; i < CFArrayGetCount(listSnapshot); i++) {
+ LSSharedFileListItemRef item = (LSSharedFileListItemRef)CFArrayGetValueAtIndex(listSnapshot, i);
+ UInt32 resolutionFlags = kLSSharedFileListNoUserInteraction | kLSSharedFileListDoNotMountVolumes;
+ CFURLRef currentItemURL = NULL;
+
+#if defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED >= 10100
+ if(&LSSharedFileListItemCopyResolvedURL)
+ currentItemURL = LSSharedFileListItemCopyResolvedURL(item, resolutionFlags, NULL);
+#if defined(MAC_OS_X_VERSION_MIN_REQUIRED) && MAC_OS_X_VERSION_MIN_REQUIRED < 10100
+ else
+ LSSharedFileListItemResolve(item, resolutionFlags, &currentItemURL, NULL);
+#endif
+#else
+ LSSharedFileListItemResolve(item, resolutionFlags, &currentItemURL, NULL);
+#endif
+
+ if(currentItemURL && CFEqual(currentItemURL, findUrl)) {
+ // found
+ CFRelease(currentItemURL);
+ return item;
+ }
+ if(currentItemURL) {
+ CFRelease(currentItemURL);
+ }
+ }
+ return NULL;
+}
+
+bool GetStartOnSystemStartup()
+{
+ CFURLRef bitcoinAppUrl = CFBundleCopyBundleURL(CFBundleGetMainBundle());
+ LSSharedFileListRef loginItems = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);
+ LSSharedFileListItemRef foundItem = findStartupItemInList(loginItems, bitcoinAppUrl);
+ return !!foundItem; // return boolified object
+}
+
+bool SetStartOnSystemStartup(bool fAutoStart)
+{
+ CFURLRef bitcoinAppUrl = CFBundleCopyBundleURL(CFBundleGetMainBundle());
+ LSSharedFileListRef loginItems = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);
+ LSSharedFileListItemRef foundItem = findStartupItemInList(loginItems, bitcoinAppUrl);
+
+ if(fAutoStart && !foundItem) {
+ // add bitcoin app to startup item list
+ LSSharedFileListInsertItemURL(loginItems, kLSSharedFileListItemBeforeFirst, NULL, NULL, bitcoinAppUrl, NULL, NULL);
+ }
+ else if(!fAutoStart && foundItem) {
+ // remove item
+ LSSharedFileListItemRemove(loginItems, foundItem);
+ }
+ return true;
+}
+#else
+
+bool GetStartOnSystemStartup() { return false; }
+bool SetStartOnSystemStartup(bool fAutoStart) { return false; }
+
+#endif
+
+void saveWindowGeometry(const QString& strSetting, QWidget *parent)
+{
+ QSettings settings;
+ settings.setValue(strSetting + "Pos", parent->pos());
+ settings.setValue(strSetting + "Size", parent->size());
+}
+
+void restoreWindowGeometry(const QString& strSetting, const QSize& defaultSize, QWidget *parent)
+{
+ QSettings settings;
+ QPoint pos = settings.value(strSetting + "Pos").toPoint();
+ QSize size = settings.value(strSetting + "Size", defaultSize).toSize();
+
+ if (!pos.x() && !pos.y()) {
+ QRect screen = QApplication::desktop()->screenGeometry();
+ pos.setX((screen.width() - size.width()) / 2);
+ pos.setY((screen.height() - size.height()) / 2);
+ }
+
+ parent->resize(size);
+ parent->move(pos);
+}
+
+void setClipboard(const QString& str)
+{
+ QApplication::clipboard()->setText(str, QClipboard::Clipboard);
+ QApplication::clipboard()->setText(str, QClipboard::Selection);
+}
+
+#if BOOST_FILESYSTEM_VERSION >= 3
+boost::filesystem::path qstringToBoostPath(const QString &path)
+{
+ return boost::filesystem::path(path.toStdString(), utf8);
+}
+
+QString boostPathToQString(const boost::filesystem::path &path)
+{
+ return QString::fromStdString(path.string(utf8));
+}
+#else
+#warning Conversion between boost path and QString can use invalid character encoding with boost_filesystem v2 and older
+boost::filesystem::path qstringToBoostPath(const QString &path)
+{
+ return boost::filesystem::path(path.toStdString());
+}
+
+QString boostPathToQString(const boost::filesystem::path &path)
+{
+ return QString::fromStdString(path.string());
+}
+#endif
+
+QString formatDurationStr(int secs)
+{
+ QStringList strList;
+ int days = secs / 86400;
+ int hours = (secs % 86400) / 3600;
+ int mins = (secs % 3600) / 60;
+ int seconds = secs % 60;
+
+ if (days)
+ strList.append(QString(QObject::tr("%1 d")).arg(days));
+ if (hours)
+ strList.append(QString(QObject::tr("%1 h")).arg(hours));
+ if (mins)
+ strList.append(QString(QObject::tr("%1 m")).arg(mins));
+ if (seconds || (!days && !hours && !mins))
+ strList.append(QString(QObject::tr("%1 s")).arg(seconds));
+
+ return strList.join(" ");
+}
+
+QString formatServicesStr(quint64 mask)
+{
+ QStringList strList;
+
+ // Just scan the last 8 bits for now.
+ for (int i = 0; i < 8; i++) {
+ uint64_t check = 1 << i;
+ if (mask & check)
+ {
+ switch (check)
+ {
+ case NODE_NETWORK:
+ strList.append("NETWORK");
+ break;
+ case NODE_GETUTXO:
+ strList.append("GETUTXO");
+ break;
+ default:
+ strList.append(QString("%1[%2]").arg("UNKNOWN").arg(check));
+ }
+ }
+ }
+
+ if (strList.size())
+ return strList.join(" & ");
+ else
+ return QObject::tr("None");
+}
+
+QString formatPingTime(double dPingTime)
+{
+ return dPingTime == 0 ? QObject::tr("N/A") : QString(QObject::tr("%1 ms")).arg(QString::number((int)(dPingTime * 1000), 10));
+}
+
+QString formatTimeOffset(int64_t nTimeOffset)
+{
+ return QString(QObject::tr("%1 s")).arg(QString::number((int)nTimeOffset, 10));
+}
+
+} // namespace GUIUtil
diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h
new file mode 100644
index 0000000000..0a47f767db
--- /dev/null
+++ b/src/qt/guiutil.h
@@ -0,0 +1,211 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_GUIUTIL_H
+#define BITCOIN_QT_GUIUTIL_H
+
+#include "amount.h"
+
+#include <QEvent>
+#include <QHeaderView>
+#include <QMessageBox>
+#include <QObject>
+#include <QProgressBar>
+#include <QString>
+#include <QTableView>
+
+#include <boost/filesystem.hpp>
+
+class QValidatedLineEdit;
+class SendCoinsRecipient;
+
+QT_BEGIN_NAMESPACE
+class QAbstractItemView;
+class QDateTime;
+class QFont;
+class QLineEdit;
+class QUrl;
+class QWidget;
+QT_END_NAMESPACE
+
+/** Utility functions used by the Bitcoin Qt UI.
+ */
+namespace GUIUtil
+{
+ // Create human-readable string from date
+ QString dateTimeStr(const QDateTime &datetime);
+ QString dateTimeStr(qint64 nTime);
+
+ // Render Bitcoin addresses in monospace font
+ QFont bitcoinAddressFont();
+
+ // Set up widgets for address and amounts
+ void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent);
+ void setupAmountWidget(QLineEdit *widget, QWidget *parent);
+
+ // Parse "bitcoin:" URI into recipient object, return true on successful parsing
+ bool parseBitcoinURI(const QUrl &uri, SendCoinsRecipient *out);
+ bool parseBitcoinURI(QString uri, SendCoinsRecipient *out);
+ QString formatBitcoinURI(const SendCoinsRecipient &info);
+
+ // Returns true if given address+amount meets "dust" definition
+ bool isDust(const QString& address, const CAmount& amount);
+
+ // 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);
+
+ void setClipboard(const QString& str);
+
+ /** Get save filename, 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, const QString &caption, const QString &dir,
+ const QString &filter,
+ QString *selectedSuffixOut);
+
+ /** Get open filename, convenience wrapper for QFileDialog::getOpenFileName.
+
+ @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 getOpenFileName(QWidget *parent, const QString &caption, const QString &dir,
+ const QString &filter,
+ QString *selectedSuffixOut);
+
+ /** 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();
+
+ // Replace invalid default fonts with known good ones
+ void SubstituteFonts(const QString& language);
+
+ /** 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;
+ };
+
+ /**
+ * Makes a QTableView last column feel as if it was being resized from its left border.
+ * Also makes sure the column widths are never larger than the table's viewport.
+ * In Qt, all columns are resizable from the right, but it's not intuitive resizing the last column from the right.
+ * Usually our second to last columns behave as if stretched, and when on strech mode, columns aren't resizable
+ * interactively or programatically.
+ *
+ * This helper object takes care of this issue.
+ *
+ */
+ class TableViewLastColumnResizingFixer: public QObject
+ {
+ Q_OBJECT
+
+ public:
+ TableViewLastColumnResizingFixer(QTableView* table, int lastColMinimumWidth, int allColsMinimumWidth);
+ void stretchColumnWidth(int column);
+
+ private:
+ QTableView* tableView;
+ int lastColumnMinimumWidth;
+ int allColumnsMinimumWidth;
+ int lastColumnIndex;
+ int columnCount;
+ int secondToLastColumnIndex;
+
+ void adjustTableColumnsWidth();
+ int getAvailableWidthForColumn(int column);
+ int getColumnsWidth();
+ void connectViewHeadersSignals();
+ void disconnectViewHeadersSignals();
+ void setViewHeaderResizeMode(int logicalIndex, QHeaderView::ResizeMode resizeMode);
+ void resizeColumn(int nColumnIndex, int width);
+
+ private Q_SLOTS:
+ void on_sectionResized(int logicalIndex, int oldSize, int newSize);
+ void on_geometriesChanged();
+ };
+
+ bool GetStartOnSystemStartup();
+ bool SetStartOnSystemStartup(bool fAutoStart);
+
+ /** Save window size and position */
+ void saveWindowGeometry(const QString& strSetting, QWidget *parent);
+ /** Restore window size and position */
+ void restoreWindowGeometry(const QString& strSetting, const QSize &defaultSizeIn, QWidget *parent);
+
+ /* Convert QString to OS specific boost path through UTF-8 */
+ boost::filesystem::path qstringToBoostPath(const QString &path);
+
+ /* Convert OS specific boost path to QString through UTF-8 */
+ QString boostPathToQString(const boost::filesystem::path &path);
+
+ /* Convert seconds into a QString with days, hours, mins, secs */
+ QString formatDurationStr(int secs);
+
+ /* Format CNodeStats.nServices bitmask into a user-readable string */
+ QString formatServicesStr(quint64 mask);
+
+ /* Format a CNodeCombinedStats.dPingTime into a user-readable string or display N/A, if 0*/
+ QString formatPingTime(double dPingTime);
+
+ /* Format a CNodeCombinedStats.nTimeOffset into a user-readable string. */
+ QString formatTimeOffset(int64_t nTimeOffset);
+
+#if defined(Q_OS_MAC) && QT_VERSION >= 0x050000
+ // workaround for Qt OSX Bug:
+ // https://bugreports.qt-project.org/browse/QTBUG-15631
+ // QProgressBar uses around 10% CPU even when app is in background
+ class ProgressBar : public QProgressBar
+ {
+ bool event(QEvent *e) {
+ return (e->type() != QEvent::StyleAnimationUpdate) ? QProgressBar::event(e) : false;
+ }
+ };
+#else
+ typedef QProgressBar ProgressBar;
+#endif
+
+} // namespace GUIUtil
+
+#endif // BITCOIN_QT_GUIUTIL_H
diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp
new file mode 100644
index 0000000000..117969758c
--- /dev/null
+++ b/src/qt/intro.cpp
@@ -0,0 +1,293 @@
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "intro.h"
+#include "ui_intro.h"
+
+#include "guiutil.h"
+#include "scicon.h"
+
+#include "util.h"
+
+#include <boost/filesystem.hpp>
+
+#include <QFileDialog>
+#include <QSettings>
+#include <QMessageBox>
+
+/* Minimum free space (in bytes) needed for data directory */
+static const uint64_t GB_BYTES = 1000000000LL;
+static const uint64_t BLOCK_CHAIN_SIZE = 20LL * GB_BYTES;
+
+/* Check free space asynchronously to prevent hanging the UI thread.
+
+ Up to one request to check a path is in flight to this thread; when the check()
+ function runs, the current path is requested from the associated Intro object.
+ The reply is sent back through a signal.
+
+ This ensures that no queue of checking requests is built up while the user is
+ still entering the path, and that always the most recently entered path is checked as
+ soon as the thread becomes available.
+*/
+class FreespaceChecker : public QObject
+{
+ Q_OBJECT
+
+public:
+ FreespaceChecker(Intro *intro);
+
+ enum Status {
+ ST_OK,
+ ST_ERROR
+ };
+
+public Q_SLOTS:
+ void check();
+
+Q_SIGNALS:
+ void reply(int status, const QString &message, quint64 available);
+
+private:
+ Intro *intro;
+};
+
+#include "intro.moc"
+
+FreespaceChecker::FreespaceChecker(Intro *intro)
+{
+ this->intro = intro;
+}
+
+void FreespaceChecker::check()
+{
+ namespace fs = boost::filesystem;
+ QString dataDirStr = intro->getPathToCheck();
+ fs::path dataDir = GUIUtil::qstringToBoostPath(dataDirStr);
+ uint64_t freeBytesAvailable = 0;
+ int replyStatus = ST_OK;
+ QString replyMessage = tr("A new data directory will be created.");
+
+ /* Find first parent that exists, so that fs::space does not fail */
+ fs::path parentDir = dataDir;
+ fs::path parentDirOld = fs::path();
+ while(parentDir.has_parent_path() && !fs::exists(parentDir))
+ {
+ parentDir = parentDir.parent_path();
+
+ /* Check if we make any progress, break if not to prevent an infinite loop here */
+ if (parentDirOld == parentDir)
+ break;
+
+ parentDirOld = parentDir;
+ }
+
+ try {
+ freeBytesAvailable = fs::space(parentDir).available;
+ if(fs::exists(dataDir))
+ {
+ if(fs::is_directory(dataDir))
+ {
+ QString separator = "<code>" + QDir::toNativeSeparators("/") + tr("name") + "</code>";
+ replyStatus = ST_OK;
+ replyMessage = tr("Directory already exists. Add %1 if you intend to create a new directory here.").arg(separator);
+ } else {
+ replyStatus = ST_ERROR;
+ replyMessage = tr("Path already exists, and is not a directory.");
+ }
+ }
+ } catch (const fs::filesystem_error&)
+ {
+ /* Parent directory does not exist or is not accessible */
+ replyStatus = ST_ERROR;
+ replyMessage = tr("Cannot create data directory here.");
+ }
+ Q_EMIT reply(replyStatus, replyMessage, freeBytesAvailable);
+}
+
+
+Intro::Intro(QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::Intro),
+ thread(0),
+ signalled(false)
+{
+ ui->setupUi(this);
+ ui->sizeWarningLabel->setText(ui->sizeWarningLabel->text().arg(BLOCK_CHAIN_SIZE/GB_BYTES));
+ startThread();
+}
+
+Intro::~Intro()
+{
+ delete ui;
+ /* Ensure thread is finished before it is deleted */
+ Q_EMIT stopThread();
+ thread->wait();
+}
+
+QString Intro::getDataDirectory()
+{
+ return ui->dataDirectory->text();
+}
+
+void Intro::setDataDirectory(const QString &dataDir)
+{
+ ui->dataDirectory->setText(dataDir);
+ if(dataDir == getDefaultDataDirectory())
+ {
+ ui->dataDirDefault->setChecked(true);
+ ui->dataDirectory->setEnabled(false);
+ ui->ellipsisButton->setEnabled(false);
+ } else {
+ ui->dataDirCustom->setChecked(true);
+ ui->dataDirectory->setEnabled(true);
+ ui->ellipsisButton->setEnabled(true);
+ }
+}
+
+QString Intro::getDefaultDataDirectory()
+{
+ return GUIUtil::boostPathToQString(GetDefaultDataDir());
+}
+
+void Intro::pickDataDirectory()
+{
+ namespace fs = boost::filesystem;
+ QSettings settings;
+ /* If data directory provided on command line, no need to look at settings
+ or show a picking dialog */
+ if(!GetArg("-datadir", "").empty())
+ return;
+ /* 1) Default data directory for operating system */
+ QString dataDir = getDefaultDataDirectory();
+ /* 2) Allow QSettings to override default dir */
+ dataDir = settings.value("strDataDir", dataDir).toString();
+
+ if(!fs::exists(GUIUtil::qstringToBoostPath(dataDir)) || GetBoolArg("-choosedatadir", false))
+ {
+ /* If current default data directory does not exist, let the user choose one */
+ Intro intro;
+ intro.setDataDirectory(dataDir);
+ intro.setWindowIcon(SingleColorIcon(":icons/bitcoin"));
+
+ while(true)
+ {
+ if(!intro.exec())
+ {
+ /* Cancel clicked */
+ exit(0);
+ }
+ dataDir = intro.getDataDirectory();
+ try {
+ TryCreateDirectory(GUIUtil::qstringToBoostPath(dataDir));
+ break;
+ } catch (const fs::filesystem_error&) {
+ QMessageBox::critical(0, tr("Bitcoin Core"),
+ tr("Error: Specified data directory \"%1\" cannot be created.").arg(dataDir));
+ /* fall through, back to choosing screen */
+ }
+ }
+
+ settings.setValue("strDataDir", dataDir);
+ }
+ /* Only override -datadir if different from the default, to make it possible to
+ * override -datadir in the bitcoin.conf file in the default data directory
+ * (to be consistent with bitcoind behavior)
+ */
+ if(dataDir != getDefaultDataDirectory())
+ SoftSetArg("-datadir", GUIUtil::qstringToBoostPath(dataDir).string()); // use OS locale for path setting
+}
+
+void Intro::setStatus(int status, const QString &message, quint64 bytesAvailable)
+{
+ switch(status)
+ {
+ case FreespaceChecker::ST_OK:
+ ui->errorMessage->setText(message);
+ ui->errorMessage->setStyleSheet("");
+ break;
+ case FreespaceChecker::ST_ERROR:
+ ui->errorMessage->setText(tr("Error") + ": " + message);
+ ui->errorMessage->setStyleSheet("QLabel { color: #800000 }");
+ break;
+ }
+ /* Indicate number of bytes available */
+ if(status == FreespaceChecker::ST_ERROR)
+ {
+ ui->freeSpace->setText("");
+ } else {
+ QString freeString = tr("%n GB of free space available", "", bytesAvailable/GB_BYTES);
+ if(bytesAvailable < BLOCK_CHAIN_SIZE)
+ {
+ freeString += " " + tr("(of %n GB needed)", "", BLOCK_CHAIN_SIZE/GB_BYTES);
+ ui->freeSpace->setStyleSheet("QLabel { color: #800000 }");
+ } else {
+ ui->freeSpace->setStyleSheet("");
+ }
+ ui->freeSpace->setText(freeString + ".");
+ }
+ /* Don't allow confirm in ERROR state */
+ ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(status != FreespaceChecker::ST_ERROR);
+}
+
+void Intro::on_dataDirectory_textChanged(const QString &dataDirStr)
+{
+ /* Disable OK button until check result comes in */
+ ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
+ checkPath(dataDirStr);
+}
+
+void Intro::on_ellipsisButton_clicked()
+{
+ QString dir = QDir::toNativeSeparators(QFileDialog::getExistingDirectory(0, "Choose data directory", ui->dataDirectory->text()));
+ if(!dir.isEmpty())
+ ui->dataDirectory->setText(dir);
+}
+
+void Intro::on_dataDirDefault_clicked()
+{
+ setDataDirectory(getDefaultDataDirectory());
+}
+
+void Intro::on_dataDirCustom_clicked()
+{
+ ui->dataDirectory->setEnabled(true);
+ ui->ellipsisButton->setEnabled(true);
+}
+
+void Intro::startThread()
+{
+ thread = new QThread(this);
+ FreespaceChecker *executor = new FreespaceChecker(this);
+ executor->moveToThread(thread);
+
+ connect(executor, SIGNAL(reply(int,QString,quint64)), this, SLOT(setStatus(int,QString,quint64)));
+ connect(this, SIGNAL(requestCheck()), executor, SLOT(check()));
+ /* make sure executor object is deleted in its own thread */
+ connect(this, SIGNAL(stopThread()), executor, SLOT(deleteLater()));
+ connect(this, SIGNAL(stopThread()), thread, SLOT(quit()));
+
+ thread->start();
+}
+
+void Intro::checkPath(const QString &dataDir)
+{
+ mutex.lock();
+ pathToCheck = dataDir;
+ if(!signalled)
+ {
+ signalled = true;
+ Q_EMIT requestCheck();
+ }
+ mutex.unlock();
+}
+
+QString Intro::getPathToCheck()
+{
+ QString retval;
+ mutex.lock();
+ retval = pathToCheck;
+ signalled = false; /* new request can be queued now */
+ mutex.unlock();
+ return retval;
+}
diff --git a/src/qt/intro.h b/src/qt/intro.h
new file mode 100644
index 0000000000..50783f7225
--- /dev/null
+++ b/src/qt/intro.h
@@ -0,0 +1,73 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_INTRO_H
+#define BITCOIN_QT_INTRO_H
+
+#include <QDialog>
+#include <QMutex>
+#include <QThread>
+
+class FreespaceChecker;
+
+namespace Ui {
+ class Intro;
+}
+
+/** Introduction screen (pre-GUI startup).
+ Allows the user to choose a data directory,
+ in which the wallet and block chain will be stored.
+ */
+class Intro : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit Intro(QWidget *parent = 0);
+ ~Intro();
+
+ QString getDataDirectory();
+ void setDataDirectory(const QString &dataDir);
+
+ /**
+ * Determine data directory. Let the user choose if the current one doesn't exist.
+ *
+ * @note do NOT call global GetDataDir() before calling this function, this
+ * will cause the wrong path to be cached.
+ */
+ static void pickDataDirectory();
+
+ /**
+ * Determine default data directory for operating system.
+ */
+ static QString getDefaultDataDirectory();
+
+Q_SIGNALS:
+ void requestCheck();
+ void stopThread();
+
+public Q_SLOTS:
+ void setStatus(int status, const QString &message, quint64 bytesAvailable);
+
+private Q_SLOTS:
+ void on_dataDirectory_textChanged(const QString &arg1);
+ void on_ellipsisButton_clicked();
+ void on_dataDirDefault_clicked();
+ void on_dataDirCustom_clicked();
+
+private:
+ Ui::Intro *ui;
+ QThread *thread;
+ QMutex mutex;
+ bool signalled;
+ QString pathToCheck;
+
+ void startThread();
+ void checkPath(const QString &dataDir);
+ QString getPathToCheck();
+
+ friend class FreespaceChecker;
+};
+
+#endif // BITCOIN_QT_INTRO_H
diff --git a/src/qt/locale/bitcoin_ach.ts b/src/qt/locale/bitcoin_ach.ts
new file mode 100644
index 0000000000..ddb9fb85ce
--- /dev/null
+++ b/src/qt/locale/bitcoin_ach.ts
@@ -0,0 +1,110 @@
+<TS language="ach" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ </context>
+<context>
+ <name>AddressTableModel</name>
+ </context>
+<context>
+ <name>AskPassphraseDialog</name>
+ </context>
+<context>
+ <name>BitcoinGUI</name>
+ </context>
+<context>
+ <name>ClientModel</name>
+ </context>
+<context>
+ <name>CoinControlDialog</name>
+ </context>
+<context>
+ <name>EditAddressDialog</name>
+ </context>
+<context>
+ <name>FreespaceChecker</name>
+ </context>
+<context>
+ <name>HelpMessageDialog</name>
+ </context>
+<context>
+ <name>Intro</name>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ </context>
+<context>
+ <name>OptionsDialog</name>
+ </context>
+<context>
+ <name>OverviewPage</name>
+ </context>
+<context>
+ <name>PaymentServer</name>
+ </context>
+<context>
+ <name>PeerTableModel</name>
+ </context>
+<context>
+ <name>QObject</name>
+ </context>
+<context>
+ <name>QRImageWidget</name>
+ </context>
+<context>
+ <name>RPCConsole</name>
+ </context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ </context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ </context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ </context>
+<context>
+ <name>SendCoinsDialog</name>
+ </context>
+<context>
+ <name>SendCoinsEntry</name>
+ </context>
+<context>
+ <name>ShutdownWindow</name>
+ </context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ </context>
+<context>
+ <name>SplashScreen</name>
+ </context>
+<context>
+ <name>TrafficGraphWidget</name>
+ </context>
+<context>
+ <name>TransactionDesc</name>
+ </context>
+<context>
+ <name>TransactionDescDialog</name>
+ </context>
+<context>
+ <name>TransactionTableModel</name>
+ </context>
+<context>
+ <name>TransactionView</name>
+ </context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ </context>
+<context>
+ <name>WalletFrame</name>
+ </context>
+<context>
+ <name>WalletModel</name>
+ </context>
+<context>
+ <name>WalletView</name>
+ </context>
+<context>
+ <name>bitcoin-core</name>
+ </context>
+</TS> \ No newline at end of file
diff --git a/src/qt/locale/bitcoin_af_ZA.ts b/src/qt/locale/bitcoin_af_ZA.ts
new file mode 100644
index 0000000000..3767a4c830
--- /dev/null
+++ b/src/qt/locale/bitcoin_af_ZA.ts
@@ -0,0 +1,674 @@
+<TS language="af_ZA" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Create a new address</source>
+ <translation>Skep 'n nuwe adres</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Maak 'n kopie van die huidige adres na die stelsel klipbord</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;Verwyder</translation>
+ </message>
+ </context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Etiket</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adres</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(geen etiket)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Tik Wagwoord in</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Nuwe wagwoord</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Herhaal nuwe wagwoord</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>Enkripteer beursie</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>Hierdie operasie benodig 'n wagwoord om die beursie oop te sluit.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Sluit beursie oop</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>Hierdie operasie benodig 'n wagwoord om die beursie oop te sluit.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>Sluit beursie oop</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>Verander wagwoord</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>Bevestig beursie enkripsie.</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>Die beursie is nou bewaak</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>Die beursie kon nie bewaak word nie</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>Beursie bewaaking het misluk as gevolg van 'n interne fout. Die beursie is nie bewaak nie!</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>Die wagwoord stem nie ooreen nie</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>Beursie oopsluiting het misluk</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>Die wagwoord wat ingetik was om die beursie oop te sluit, was verkeerd.</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>Beursie dekripsie het misluk</translation>
+ </message>
+ </context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>Sinchroniseer met die netwerk ...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;Oorsig</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>Wys algemene oorsig van die beursie</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Transaksies</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>Besoek transaksie geskiedenis</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>S&amp;luit af</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>Sluit af</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>Wys inligting oor Qt</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;Opsies</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>Beursie</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;Lêer</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;Instellings</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>&amp;Hulp</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>Blad nutsbalk</translation>
+ </message>
+ <message>
+ <source>%1 behind</source>
+ <translation>%1 agter</translation>
+ </message>
+ <message>
+ <source>Last received block was generated %1 ago.</source>
+ <translation>Ontvangs van laaste blok is %1 terug.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Fout</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Informasie</translation>
+ </message>
+ </context>
+<context>
+ <name>ClientModel</name>
+ </context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Amount:</source>
+ <translation>Bedrag:</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Bedrag</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Datum</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Maak kopie van adres</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopieer bedrag</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(geen etiket)</translation>
+ </message>
+ </context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>New receiving address</source>
+ <translation>Nuwe ontvangende adres</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>Nuwe stuurende adres</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>Wysig ontvangende adres</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>Wysig stuurende adres</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>Kon nie die beursie oopsluit nie.</translation>
+ </message>
+ </context>
+<context>
+ <name>FreespaceChecker</name>
+ </context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Usage:</source>
+ <translation>Gebruik:</translation>
+ </message>
+ </context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Error</source>
+ <translation>Fout</translation>
+ </message>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ </context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>Opsies</translation>
+ </message>
+ </context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>Vorm</translation>
+ </message>
+ </context>
+<context>
+ <name>PaymentServer</name>
+ </context>
+<context>
+ <name>PeerTableModel</name>
+ </context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>Bedrag</translation>
+ </message>
+ </context>
+<context>
+ <name>QRImageWidget</name>
+ </context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>&amp;Information</source>
+ <translation>Informasie</translation>
+ </message>
+ </context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopieer bedrag</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>Address</source>
+ <translation>Adres</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Bedrag</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiket</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Boodskap</translation>
+ </message>
+ </context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Datum</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiket</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Boodskap</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Bedrag</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(geen etiket)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Stuur Munstukke</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Bedrag:</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>Stuur aan vele ontvangers op eens</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>Balans:</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>S&amp;tuur</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopieer bedrag</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(geen etiket)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>Message:</source>
+ <translation>Boodskap:</translation>
+ </message>
+ </context>
+<context>
+ <name>ShutdownWindow</name>
+ </context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>&amp;Sign Message</source>
+ <translation>&amp;Teken boodskap</translation>
+ </message>
+ <message>
+ <source>Signature</source>
+ <translation>Handtekening</translation>
+ </message>
+ <message>
+ <source>Sign &amp;Message</source>
+ <translation>Teken &amp;Boodskap</translation>
+ </message>
+ </context>
+<context>
+ <name>SplashScreen</name>
+ </context>
+<context>
+ <name>TrafficGraphWidget</name>
+ </context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Date</source>
+ <translation>Datum</translation>
+ </message>
+ <message>
+ <source>From</source>
+ <translation>Van</translation>
+ </message>
+ <message>
+ <source>To</source>
+ <translation>Na</translation>
+ </message>
+ <message>
+ <source>own address</source>
+ <translation>eie adres</translation>
+ </message>
+ <message>
+ <source>label</source>
+ <translation>etiket</translation>
+ </message>
+ <message>
+ <source>Credit</source>
+ <translation>Krediet</translation>
+ </message>
+ <message>
+ <source>not accepted</source>
+ <translation>nie aanvaar nie</translation>
+ </message>
+ <message>
+ <source>Debit</source>
+ <translation>Debiet</translation>
+ </message>
+ <message>
+ <source>Transaction fee</source>
+ <translation>Transaksie fooi</translation>
+ </message>
+ <message>
+ <source>Net amount</source>
+ <translation>Netto bedrag</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Boodskap</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>Transaksie ID</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Bedrag</translation>
+ </message>
+ <message>
+ <source>true</source>
+ <translation>waar</translation>
+ </message>
+ <message>
+ <source>false</source>
+ <translation>onwaar</translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>onbekend</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ </context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Datum</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Tipe</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiket</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Ontvang met</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>Ontvang van</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Gestuur na</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>Betalings Aan/na jouself</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Gemyn</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(n.v.t)</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Datum en tyd wat die transaksie ontvang was.</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>Tipe transaksie.</translation>
+ </message>
+ </context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>Alles</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>Vandag</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>Hierdie week</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>Hierdie maand</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>Verlede maand</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>Hierdie jaar</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>Reeks...</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Ontvang met</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Gestuur na</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>Aan/na jouself</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Gemyn</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>Ander</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>Min bedrag</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Maak kopie van adres</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopieer bedrag</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Datum</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Tipe</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiket</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adres</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>Reeks:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>aan</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ </context>
+<context>
+ <name>WalletFrame</name>
+ </context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Stuur Munstukke</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ </context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>Opsies:</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>Gebruik die toets netwerk</translation>
+ </message>
+ <message>
+ <source>Error: Disk space is low!</source>
+ <translation>Fout: Hardeskyf spasie is baie laag!</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Informasie</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>Hierdie help boodskap</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>Laai adresse...</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>Onvoldoende fondse</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>Laai blok indeks...</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>Laai beursie...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>Klaar gelaai</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Fout</translation>
+ </message>
+</context>
+</TS> \ No newline at end of file
diff --git a/src/qt/locale/bitcoin_ar.ts b/src/qt/locale/bitcoin_ar.ts
new file mode 100644
index 0000000000..fce09d7ca8
--- /dev/null
+++ b/src/qt/locale/bitcoin_ar.ts
@@ -0,0 +1,1730 @@
+<TS language="ar" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Right-click to edit address or label</source>
+ <translation>انقر بالزر الايمن لتعديل العنوان</translation>
+ </message>
+ <message>
+ <source>Create a new address</source>
+ <translation>انشأ عنوان جديد</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>&amp;جديد</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>قم بنسخ القوانين المختارة لحافظة النظام</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>&amp;نسخ</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>&amp;اغلاق</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>انسخ العنوان</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>حذف العنوان المحدد من القائمة</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>تحميل البيانات في علامة التبويب الحالية إلى ملف.</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;تصدير</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;أمسح</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>اختر العنوان الذي سترسل له العملات</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>اختر العنوان الذي تستقبل عليه العملات</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>&amp;اختر</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>ارسال العناوين</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>استقبال العناوين</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>هذه هي عناوين Bitcion التابعة لك من أجل إرسال الدفعات. تحقق دائما من المبلغ و عنوان المرسل المستقبل قبل إرسال العملات</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>هذه هي عناوين Bitcion التابعة لك من أجل إستقبال الدفعات. ينصح استخدام عنوان جديد من أجل كل صفقة</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>نسخ &amp;الوصف</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>تعديل</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>تصدير قائمة العناوين</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>ملف مفصول بفواصل (*.csv)</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>فشل التصدير</translation>
+ </message>
+ </context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>وصف</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>عنوان</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(لا وصف)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Passphrase Dialog</source>
+ <translation>حوار جملة السر</translation>
+ </message>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>ادخل كلمة المرور</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>كلمة مرور جديدة</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>ادخل كلمة المرور الجديدة مرة أخرى</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>تشفير المحفظة</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>هذه العملية تحتاج كلمة مرور محفظتك لفتحها</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>إفتح المحفظة</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>هذه العملية تحتاج كلمة مرور محفظتك لفك تشفيرها </translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>فك تشفير المحفظة</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>تغيير كلمة المرور</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>تأكيد تشفير المحفظة</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>تحذير: إذا قمت بتشفير محفظتك وفقدت كلمة المرور الخاص بك, ستفقد كل عملات BITCOINS الخاصة بك.</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>هل أنت متأكد من رغبتك في تشفير محفظتك ؟</translation>
+ </message>
+ <message>
+ <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
+ <translation>هام: أي نسخة إحتياطية سابقة قمت بها لمحفظتك يجب استبدالها بأخرى حديثة، مشفرة. لأسباب أمنية، النسخ الاحتياطية السابقة لملفات المحفظة الغير مشفرة تصبح عديمة الفائدة مع بداية استخدام المحفظة المشفرة الجديدة.</translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>تحذير: مفتاح الحروف الكبيرة مفعل</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>محفظة مشفرة</translation>
+ </message>
+ <message>
+ <source>Enter the new passphrase to the wallet.&lt;br/&gt;Please use a passphrase of &lt;b&gt;ten or more random characters&lt;/b&gt;, or &lt;b&gt;eight or more words&lt;/b&gt;.</source>
+ <translation>أدخل عبارة مرور جديدة إلى المحفظة. الرجاء استخدام عبارة مرور تتكون من10 حروف عشوائية على الاقل, أو أكثر من 7 كلمات</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>فشل تشفير المحفظة</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>فشل تشفير المحفظة بسبب خطأ داخلي. لم يتم تشفير محفظتك.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>كلمتي المرور ليستا متطابقتان</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>فشل فتح المحفظة</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>كلمة المرور التي تم إدخالها لفك تشفير المحفظة غير صحيحة.</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>فشل فك التشفير المحفظة</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>لقد تم تغير عبارة مرور المحفظة بنجاح</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>التوقيع و الرسائل</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>مزامنة مع الشبكة ...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;نظرة عامة</translation>
+ </message>
+ <message>
+ <source>Node</source>
+ <translation>جهاز</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>إظهار نظرة عامة على المحفظة</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;المعاملات</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>تصفح سجل المعاملات</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>خروج</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>الخروج من التطبيق</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>عن</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>اظهر المعلومات</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;خيارات ...</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>&amp;تشفير المحفظة</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>&amp;نسخ احتياط للمحفظة</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>&amp;تغيير كلمة المرور</translation>
+ </message>
+ <message>
+ <source>&amp;Sending addresses...</source>
+ <translation>ارسال العناوين.</translation>
+ </message>
+ <message>
+ <source>&amp;Receiving addresses...</source>
+ <translation>استقبال العناوين</translation>
+ </message>
+ <message>
+ <source>Open &amp;URI...</source>
+ <translation>افتح &amp;URI...</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core client</source>
+ <translation>عميل bitcion core</translation>
+ </message>
+ <message>
+ <source>Importing blocks from disk...</source>
+ <translation>استيراد كتل من القرص ...</translation>
+ </message>
+ <message>
+ <source>Reindexing blocks on disk...</source>
+ <translation>إعادة الفهرسة الكتل على القرص ...</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>ارسل عملات الى عنوان بيتكوين</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>احفظ نسخة احتياطية للمحفظة في مكان آخر</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>تغيير كلمة المرور المستخدمة لتشفير المحفظة</translation>
+ </message>
+ <message>
+ <source>&amp;Debug window</source>
+ <translation>&amp;نافذة المعالجة</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>&amp;التحقق من الرسالة...</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>بت كوين</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>محفظة</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>&amp;استقبل</translation>
+ </message>
+ <message>
+ <source>Show information about Bitcoin Core</source>
+ <translation> اظهار معلومات حول bitcion core</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>&amp;عرض / اخفاء</translation>
+ </message>
+ <message>
+ <source>Show or hide the main Window</source>
+ <translation>عرض او اخفاء النافذة الرئيسية</translation>
+ </message>
+ <message>
+ <source>Encrypt the private keys that belong to your wallet</source>
+ <translation>تشفير المفتاح الخاص بمحفظتك</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;ملف</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;الاعدادات</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>&amp;مساعدة</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>شريط أدوات علامات التبويب</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>جوهر البيت كوين</translation>
+ </message>
+ <message>
+ <source>&amp;About Bitcoin Core</source>
+ <translation>حول bitcoin core</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>خطأ</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>تحذير</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>معلومات</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>محدث</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>اللحاق بالركب ...</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>المعاملات المرسلة</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>المعاملات الواردة</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>المحفظة &lt;b&gt;مشفرة&lt;/b&gt; و &lt;b&gt;مفتوحة&lt;/b&gt; حاليا</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>المحفظة &lt;b&gt;مشفرة&lt;/b&gt; و &lt;b&gt;مقفلة&lt;/b&gt; حاليا</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <source>Network Alert</source>
+ <translation>تنبيه من الشبكة</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Quantity:</source>
+ <translation>الكمية :</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>القيمة :</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>افضلية :</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>رسوم :</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>بعد الرسوم :</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>تعديل :</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>المبلغ</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>التاريخ</translation>
+ </message>
+ <message>
+ <source>Confirmations</source>
+ <translation>تأكيد</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>تأكيد</translation>
+ </message>
+ <message>
+ <source>Priority</source>
+ <translation>أفضلية</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation> انسخ عنوان</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation> انسخ التسمية</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>نسخ الكمية</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>نسخ رقم العملية</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>نسخ الكمية </translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>نسخ الرسوم</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>نسخ بعد الرسوم</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>نسخ الافضلية</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>نسخ التعديل</translation>
+ </message>
+ <message>
+ <source>highest</source>
+ <translation>الاعلى</translation>
+ </message>
+ <message>
+ <source>higher</source>
+ <translation>اعلى</translation>
+ </message>
+ <message>
+ <source>high</source>
+ <translation>عالي</translation>
+ </message>
+ <message>
+ <source>medium-high</source>
+ <translation>متوسط-مرتفع</translation>
+ </message>
+ <message>
+ <source>low</source>
+ <translation>منخفض</translation>
+ </message>
+ <message>
+ <source>lower</source>
+ <translation>أدنى</translation>
+ </message>
+ <message>
+ <source>lowest</source>
+ <translation>الأدنى</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>لا شيء</translation>
+ </message>
+ <message>
+ <source>yes</source>
+ <translation>نعم</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>لا</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(لا وصف)</translation>
+ </message>
+ <message>
+ <source>(change)</source>
+ <translation>(تغير)</translation>
+ </message>
+</context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>عدل العنوان</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>&amp;وصف</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;العنوان</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>عنوان أستلام جديد</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>عنوان إرسال جديد</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>تعديل عنوان الأستلام</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>تعديل عنوان الارسال</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>هدا العنوان "%1" موجود مسبقا في دفتر العناوين</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation> يمكن فتح المحفظة.</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>فشل توليد مفتاح جديد.</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ <message>
+ <source>A new data directory will be created.</source>
+ <translation>سيتم انشاء دليل بيانات جديد</translation>
+ </message>
+ <message>
+ <source>name</source>
+ <translation>الاسم</translation>
+ </message>
+ <message>
+ <source>Cannot create data directory here.</source>
+ <translation>لا يمكن انشاء دليل بيانات هنا .</translation>
+ </message>
+</context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>جوهر البيت كوين</translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>النسخة</translation>
+ </message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>عن جوهر البيت كوين</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>المستخدم</translation>
+ </message>
+ </context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Welcome</source>
+ <translation>أهلا</translation>
+ </message>
+ <message>
+ <source>Use the default data directory</source>
+ <translation>استخدام دليل البانات الافتراضي</translation>
+ </message>
+ <message>
+ <source>Use a custom data directory:</source>
+ <translation>استخدام دليل بيانات مخصص:</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>جوهر البيت كوين</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>خطأ</translation>
+ </message>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ <message>
+ <source>Select payment request file</source>
+ <translation>حدد ملف طلب الدفع</translation>
+ </message>
+ <message>
+ <source>Select payment request file to open</source>
+ <translation>حدد ملف طلب الدفع لفتحه</translation>
+ </message>
+</context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>خيارات ...</translation>
+ </message>
+ <message>
+ <source>&amp;Main</source>
+ <translation>&amp;الرئيسي</translation>
+ </message>
+ <message>
+ <source>MB</source>
+ <translation>م ب</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside</source>
+ <translation>إقبل التواصل من الخارج</translation>
+ </message>
+ <message>
+ <source>Third party transaction URLs</source>
+ <translation>عنوان النطاق للطرف الثالث</translation>
+ </message>
+ <message>
+ <source>&amp;Reset Options</source>
+ <translation>&amp;استعادة الخيارات</translation>
+ </message>
+ <message>
+ <source>&amp;Network</source>
+ <translation>&amp;الشبكة</translation>
+ </message>
+ <message>
+ <source>W&amp;allet</source>
+ <translation>&amp;محفظة</translation>
+ </message>
+ <message>
+ <source>Expert</source>
+ <translation>تصدير</translation>
+ </message>
+ <message>
+ <source>Proxy &amp;IP:</source>
+ <translation>بروكسي &amp;اي بي:</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>&amp;المنفذ:</translation>
+ </message>
+ <message>
+ <source>Port of the proxy (e.g. 9050)</source>
+ <translation>منفذ البروكسي (مثلا 9050)</translation>
+ </message>
+ <message>
+ <source>&amp;Window</source>
+ <translation>نافذه</translation>
+ </message>
+ <message>
+ <source>&amp;Display</source>
+ <translation>&amp;عرض</translation>
+ </message>
+ <message>
+ <source>User Interface &amp;language:</source>
+ <translation>واجهة المستخدم &amp;اللغة:</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>تم</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>الغاء</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>الافتراضي</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>لا شيء</translation>
+ </message>
+ <message>
+ <source>Confirm options reset</source>
+ <translation>تأكيد استعادة الخيارات</translation>
+ </message>
+ <message>
+ <source>The supplied proxy address is invalid.</source>
+ <translation>عنوان الوكيل توفيره غير صالح.</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>نمودج</translation>
+ </message>
+ <message>
+ <source>Available:</source>
+ <translation>متوفر</translation>
+ </message>
+ <message>
+ <source>Pending:</source>
+ <translation>معلق:</translation>
+ </message>
+ <message>
+ <source>Immature:</source>
+ <translation>غير ناضجة</translation>
+ </message>
+ <message>
+ <source>Total:</source>
+ <translation>المجموع:</translation>
+ </message>
+ <message>
+ <source>Your current total balance</source>
+ <translation>رصيدك الكلي الحالي</translation>
+ </message>
+ </context>
+<context>
+ <name>PaymentServer</name>
+ </context>
+<context>
+ <name>PeerTableModel</name>
+ </context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>المبلغ</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>غير معروف</translation>
+ </message>
+ </context>
+<context>
+ <name>QRImageWidget</name>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;حفظ الصورة</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Image</source>
+ <translation>&amp;نسخ الصورة</translation>
+ </message>
+ <message>
+ <source>Save QR Code</source>
+ <translation>حفظ رمز الاستجابة السريعة QR</translation>
+ </message>
+ <message>
+ <source>PNG Image (*.png)</source>
+ <translation>صورة PNG (*.png)</translation>
+ </message>
+</context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>Client name</source>
+ <translation>اسم العميل</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>غير معروف</translation>
+ </message>
+ <message>
+ <source>Client version</source>
+ <translation>نسخه العميل</translation>
+ </message>
+ <message>
+ <source>&amp;Information</source>
+ <translation>المعلومات</translation>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>عام</translation>
+ </message>
+ <message>
+ <source>Startup time</source>
+ <translation>وقت البدء</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>الشبكه</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>الاسم</translation>
+ </message>
+ <message>
+ <source>Number of connections</source>
+ <translation>عدد الاتصالات</translation>
+ </message>
+ <message>
+ <source>Received</source>
+ <translation>إستقبل</translation>
+ </message>
+ <message>
+ <source>Sent</source>
+ <translation>تم الإرسال</translation>
+ </message>
+ <message>
+ <source>Direction</source>
+ <translation>جهة</translation>
+ </message>
+ <message>
+ <source>Services</source>
+ <translation>خدمات</translation>
+ </message>
+ <message>
+ <source>Last Send</source>
+ <translation>آخر استقبال</translation>
+ </message>
+ <message>
+ <source>Last Receive</source>
+ <translation>آخر إرسال</translation>
+ </message>
+ <message>
+ <source>&amp;Open</source>
+ <translation>الفتح</translation>
+ </message>
+ <message>
+ <source>&amp;Network Traffic</source>
+ <translation>&amp;حركة مرور الشبكة</translation>
+ </message>
+ <message>
+ <source>&amp;Clear</source>
+ <translation>&amp;مسح</translation>
+ </message>
+ <message>
+ <source>Totals</source>
+ <translation>المجاميع</translation>
+ </message>
+ <message>
+ <source>In:</source>
+ <translation>داخل:</translation>
+ </message>
+ <message>
+ <source>Out:</source>
+ <translation>خارج:</translation>
+ </message>
+ <message>
+ <source>Build date</source>
+ <translation>وقت البناء</translation>
+ </message>
+ <message>
+ <source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
+ <translation>استخدم اسهم الاعلى و الاسفل للتنقل بين السجلات و &lt;b&gt;Ctrl-L&lt;/b&gt; لمسح الشاشة</translation>
+ </message>
+ <message>
+ <source>Unknown</source>
+ <translation>غير معرف</translation>
+ </message>
+ <message>
+ <source>Fetching...</source>
+ <translation>جاري الجلب...</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Amount:</source>
+ <translation>&amp;القيمة</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;وصف :</translation>
+ </message>
+ <message>
+ <source>&amp;Message:</source>
+ <translation>&amp;رسالة:</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>مسح كل حقول النموذج المطلوبة</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation>مسح</translation>
+ </message>
+ <message>
+ <source>Requested payments history</source>
+ <translation>سجل طلبات الدفع</translation>
+ </message>
+ <message>
+ <source>Show</source>
+ <translation>عرض</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>ازل</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation> انسخ التسمية</translation>
+ </message>
+ <message>
+ <source>Copy message</source>
+ <translation>انسخ الرسالة</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>نسخ الكمية</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>QR Code</source>
+ <translation>رمز كيو ار</translation>
+ </message>
+ <message>
+ <source>Copy &amp;URI</source>
+ <translation>نسخ &amp;URI</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Address</source>
+ <translation>نسخ &amp;العنوان</translation>
+ </message>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;حفظ الصورة</translation>
+ </message>
+ <message>
+ <source>Payment information</source>
+ <translation>معلومات الدفع</translation>
+ </message>
+ <message>
+ <source>URI</source>
+ <translation> URI</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>عنوان</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>المبلغ</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>وصف</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>رسالة </translation>
+ </message>
+ </context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>التاريخ</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>وصف</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>رسالة </translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>المبلغ</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(لا وصف)</translation>
+ </message>
+ <message>
+ <source>(no message)</source>
+ <translation>( لا رسائل )</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>إرسال Coins</translation>
+ </message>
+ <message>
+ <source>automatically selected</source>
+ <translation>اختيار تلقائيا</translation>
+ </message>
+ <message>
+ <source>Insufficient funds!</source>
+ <translation>الرصيد غير كافي!</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>الكمية :</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>القيمة :</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>افضلية :</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>رسوم :</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>بعد الرسوم :</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>تعديل :</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>إرسال إلى عدة مستلمين في وقت واحد</translation>
+ </message>
+ <message>
+ <source>Add &amp;Recipient</source>
+ <translation>أضافة &amp;مستلم</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>مسح كل حقول النموذج المطلوبة</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>مسح الكل</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>الرصيد:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>تأكيد الإرسال</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>&amp;ارسال</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>تأكيد الإرسال Coins</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>نسخ الكمية </translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>نسخ الكمية</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>نسخ الرسوم</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>نسخ بعد الرسوم</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>نسخ الافضلية</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>نسخ التعديل</translation>
+ </message>
+ <message>
+ <source>or</source>
+ <translation>أو</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>المبلغ المدفوع يجب ان يكون اكبر من 0</translation>
+ </message>
+ <message>
+ <source>The amount exceeds your balance.</source>
+ <translation>القيمة تتجاوز رصيدك</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(لا وصف)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>ادفع &amp;الى :</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>إدخال تسمية لهذا العنوان لإضافته إلى دفتر العناوين الخاص بك</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;وصف :</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>انسخ العنوان من لوحة المفاتيح</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Message:</source>
+ <translation>الرسائل</translation>
+ </message>
+ </context>
+<context>
+ <name>ShutdownWindow</name>
+ <message>
+ <source>Do not shut down the computer until this window disappears.</source>
+ <translation>لا توقف عمل الكمبيوتر حتى تختفي هذه النافذة</translation>
+ </message>
+</context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>&amp;Sign Message</source>
+ <translation>&amp;توقيع الرسالة</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>انسخ العنوان من لوحة المفاتيح</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Enter the message you want to sign here</source>
+ <translation>ادخل الرسالة التي تريد توقيعها هنا</translation>
+ </message>
+ <message>
+ <source>Signature</source>
+ <translation>التوقيع</translation>
+ </message>
+ <message>
+ <source>Sign the message to prove you own this Bitcoin address</source>
+ <translation>وقع الرسالة لتثبت انك تمتلك عنوان البت كوين هذا</translation>
+ </message>
+ <message>
+ <source>Sign &amp;Message</source>
+ <translation>توقيع $الرسالة</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>مسح الكل</translation>
+ </message>
+ <message>
+ <source>&amp;Verify Message</source>
+ <translation>&amp;تحقق رسالة</translation>
+ </message>
+ <message>
+ <source>Verify &amp;Message</source>
+ <translation>تحقق &amp;الرسالة</translation>
+ </message>
+ <message>
+ <source>Click "Sign Message" to generate signature</source>
+ <translation>اضغط "توقيع الرسالة" لتوليد التوقيع</translation>
+ </message>
+ <message>
+ <source>The entered address is invalid.</source>
+ <translation>العنوان المدخل غير صالح</translation>
+ </message>
+ <message>
+ <source>Please check the address and try again.</source>
+ <translation>الرجاء التأكد من العنوان والمحاولة مرة اخرى</translation>
+ </message>
+ <message>
+ <source>The entered address does not refer to a key.</source>
+ <translation>العنوان المدخل لا يشير الى مفتاح</translation>
+ </message>
+ <message>
+ <source>Wallet unlock was cancelled.</source>
+ <translation>تم الغاء عملية فتح المحفظة</translation>
+ </message>
+ <message>
+ <source>Private key for the entered address is not available.</source>
+ <translation>المفتاح الخاص للعنوان المدخل غير موجود.</translation>
+ </message>
+ <message>
+ <source>Message signing failed.</source>
+ <translation>فشل توقيع الرسالة.</translation>
+ </message>
+ <message>
+ <source>Message signed.</source>
+ <translation>الرسالة موقعة.</translation>
+ </message>
+ <message>
+ <source>Please check the signature and try again.</source>
+ <translation>فضلا تاكد من التوقيع وحاول مرة اخرى</translation>
+ </message>
+ <message>
+ <source>Message verification failed.</source>
+ <translation>فشلت عملية التأكد من الرسالة.</translation>
+ </message>
+ <message>
+ <source>Message verified.</source>
+ <translation>تم تأكيد الرسالة.</translation>
+ </message>
+</context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>جوهر البيت كوين</translation>
+ </message>
+ <message>
+ <source>The Bitcoin Core developers</source>
+ <translation>مطوري جوهر البيت كوين</translation>
+ </message>
+ <message>
+ <source>[testnet]</source>
+ <translation>[testnet]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ </context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>conflicted</source>
+ <translation>يتعارض</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>تأكيد %1</translation>
+ </message>
+ <message>
+ <source>Status</source>
+ <translation>الحالة.</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>التاريخ</translation>
+ </message>
+ <message>
+ <source>Source</source>
+ <translation>المصدر</translation>
+ </message>
+ <message>
+ <source>Generated</source>
+ <translation>تم اصداره.</translation>
+ </message>
+ <message>
+ <source>From</source>
+ <translation>من</translation>
+ </message>
+ <message>
+ <source>To</source>
+ <translation>الى</translation>
+ </message>
+ <message>
+ <source>own address</source>
+ <translation>عنوانه</translation>
+ </message>
+ <message>
+ <source>label</source>
+ <translation>علامة</translation>
+ </message>
+ <message>
+ <source>not accepted</source>
+ <translation>غير مقبولة</translation>
+ </message>
+ <message>
+ <source>Debit</source>
+ <translation>دين</translation>
+ </message>
+ <message>
+ <source>Transaction fee</source>
+ <translation>رسوم المعاملة</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>رسالة </translation>
+ </message>
+ <message>
+ <source>Comment</source>
+ <translation>تعليق</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>رقم المعاملة</translation>
+ </message>
+ <message>
+ <source>Merchant</source>
+ <translation>تاجر</translation>
+ </message>
+ <message>
+ <source>Transaction</source>
+ <translation>معاملة</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>المبلغ</translation>
+ </message>
+ <message>
+ <source>true</source>
+ <translation>صحيح</translation>
+ </message>
+ <message>
+ <source>false</source>
+ <translation>خاطئ</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, لم يتم حتى الآن البث بنجاح</translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>غير معروف</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>تفاصيل المعاملة</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>يبين هذا الجزء وصفا مفصلا لهده المعاملة</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>التاريخ</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>النوع</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>لم يتم تلقى هذه الكتلة (Block) من قبل أي العقد الأخرى وربما لن تكون مقبولة!</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>ولدت ولكن لم تقبل</translation>
+ </message>
+ <message>
+ <source>Offline</source>
+ <translation>غير متصل</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>وصف</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>استقبل مع</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>استقبل من</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>أرسل إلى</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>دفع لنفسك</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Mined</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>غير متوفر</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>حالة المعاملة. تحوم حول هذا الحقل لعرض عدد التأكيدات.</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>التاريخ والوقت الذي تم فيه تلقي المعاملة.</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>نوع المعاملات</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>المبلغ الذي أزيل أو أضيف الى الرصيد</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>الكل</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>اليوم</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>هدا الاسبوع</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>هدا الشهر</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>الشهر الماضي</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>هدا العام</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>المدى...</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>استقبل مع</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>أرسل إلى</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>إليك</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Mined</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>اخرى</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>ادخل عنوان أووصف للبحث</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>الحد الأدنى</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation> انسخ عنوان</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation> انسخ التسمية</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>نسخ الكمية</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>نسخ رقم العملية</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>عدل الوصف</translation>
+ </message>
+ <message>
+ <source>Show transaction details</source>
+ <translation>عرض تفاصيل المعاملة</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>فشل التصدير</translation>
+ </message>
+ <message>
+ <source>Exporting Successful</source>
+ <translation>نجح التصدير</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>ملف مفصول بفواصل (*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>تأكيد</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>التاريخ</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>النوع</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>وصف</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>عنوان</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>العنوان</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>المدى:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>الى</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ </context>
+<context>
+ <name>WalletFrame</name>
+ </context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>إرسال Coins</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;تصدير</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>تحميل البيانات في علامة التبويب الحالية إلى ملف.</translation>
+ </message>
+ <message>
+ <source>Backup Wallet</source>
+ <translation>نسخ احتياط للمحفظة</translation>
+ </message>
+ <message>
+ <source>Backup Failed</source>
+ <translation>فشل النسخ الاحتياطي</translation>
+ </message>
+ <message>
+ <source>Backup Successful</source>
+ <translation>نجاح النسخ الاحتياطي</translation>
+ </message>
+</context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>خيارات: </translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>حدد مجلد المعلومات</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>استخدم التحقق من الشبكه</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
+ <translation>قبول الاتصالات من خارج</translation>
+ </message>
+ <message>
+ <source>Error: Disk space is low!</source>
+ <translation>تحذير: مساحة القرص منخفضة</translation>
+ </message>
+ <message>
+ <source>Failed to listen on any port. Use -listen=0 if you want this.</source>
+ <translation>فشل في الاستماع على أي منفذ. استخدام الاستماع = 0 إذا كنت تريد هذا.</translation>
+ </message>
+ <message>
+ <source>Invalid -onion address: '%s'</source>
+ <translation>عنوان اونيون غير صحيح : '%s'</translation>
+ </message>
+ <message>
+ <source>Verifying wallet...</source>
+ <translation>التحقق من المحفظة ...</translation>
+ </message>
+ <message>
+ <source>Wallet options:</source>
+ <translation>خيارات المحفظة :</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>معلومات</translation>
+ </message>
+ <message>
+ <source>Signing transaction failed</source>
+ <translation>فشل توقيع المعاملة</translation>
+ </message>
+ <message>
+ <source>Transaction amount too small</source>
+ <translation>قيمة العملية صغيره جدا</translation>
+ </message>
+ <message>
+ <source>Transaction amounts must be positive</source>
+ <translation>يجب ان يكون قيمة العملية بالموجب</translation>
+ </message>
+ <message>
+ <source>Transaction too large</source>
+ <translation>المعاملة طويلة جدا</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>تحذير</translation>
+ </message>
+ <message>
+ <source>Upgrade wallet to latest format</source>
+ <translation>تحديث المحفظة للنسخة الاخيرة</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>رسالة المساعدة هذه</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>تحميل العنوان</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>خطأ عند تنزيل wallet.dat: المحفظة تالفة</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>خطأ عند تنزيل wallet.dat</translation>
+ </message>
+ <message>
+ <source>Invalid -proxy address: '%s'</source>
+ <translation>عنوان البروكسي غير صحيح : '%s'</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>اموال غير كافية</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>تحميل المحفظه</translation>
+ </message>
+ <message>
+ <source>Cannot write default address</source>
+ <translation>لايمكن كتابة العنوان الافتراضي</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>إعادة مسح</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>انتهاء التحميل</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>خطأ</translation>
+ </message>
+</context>
+</TS> \ No newline at end of file
diff --git a/src/qt/locale/bitcoin_be_BY.ts b/src/qt/locale/bitcoin_be_BY.ts
new file mode 100644
index 0000000000..bfaff0fdb0
--- /dev/null
+++ b/src/qt/locale/bitcoin_be_BY.ts
@@ -0,0 +1,1536 @@
+<TS language="be_BY" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Right-click to edit address or label</source>
+ <translation>Правы клік, каб рэдагаваць адрас ці метку</translation>
+ </message>
+ <message>
+ <source>Create a new address</source>
+ <translation>Стварыць новы адрас</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>Новы</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Капіяваць пазначаны адрас у сістэмны буфер абмену</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>Капіяваць</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>Зачыніць</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>Капіяваць адрас</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>Выдаліць абраны адрас са спісу</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Экспартаваць гэтыя звесткі у файл</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>Экспарт</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>Выдаліць</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>Выбраць адрас, куды выслаць сродкі</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>Выбраць адрас, на які атрымаць сродкі</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>Выбраць</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>адрасы Адпраўкі</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>адрасы Прымання</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>Тут знаходзяцца Біткойн-адрасы для высылання плацяжоў. Заўсёды спраўджвайце колькасць і адрас прызначэння перад здзяйсненнем транзакцыі.</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>Тут знаходзяцца Біткойн-адрасы для прымання плацяжоў. Пажадана выкарыстоўваць новы адрас для кожнай транзакцыі.</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>Капіяваць Метку</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>Рэдагаваць</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>Экспартаваць Спіс Адрасоў</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Коскамі падзелены файл (*.csv)</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Экспартаванне няўдалае</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the address list to %1. Please try again.</source>
+ <translation>Адбылася памылка падчас спробы захаваць адрас у %1. Паспрабуйце зноў.</translation>
+ </message>
+</context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Метка</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Адрас</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>непазначаны</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Passphrase Dialog</source>
+ <translation>Дыялог сакрэтнай фразы</translation>
+ </message>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Увядзіце кодавую фразу</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Новая кодавая фраза</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Паўтарыце новую кодавую фразу</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>Зашыфраваць гаманец.</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>Гэтая аперацыя патрабуе кодавую фразу, каб рзблакаваць гаманец.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Разблакаваць гаманец</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>Гэтая аперацыя патрабуе пароль каб расшыфраваць гаманец.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>Рачшыфраваць гаманец</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>Змяніць пароль</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>Пацвердзіце шыфраванне гаманца</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>Увага: калі вы зашыфруеце свой гаманец і страціце парольную фразу, то &lt;b&gt;СТРАЦІЦЕ ЎСЕ СВАЕ БІТКОЙНЫ&lt;/b&gt;!</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>Ці ўпэўненыя вы, што жадаеце зашыфраваць свой гаманец?</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core 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.</source>
+ <translation>Bitcoin Core зараз будзе зачынены, каб фіналізаваць працэс шыфравання. Памятайце, што шыфраванне вашага гаманца не гарантуе абсалютную абарону ад магчымасці крадзяжу біткойнаў шкоднымі праграмамі, якія могуць інфікаваць ваш камп'ютар.</translation>
+ </message>
+ <message>
+ <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
+ <translation>ВАЖНА: Усе папярэднія копіі гаманца варта замяніць новым зашыфраваным файлам. У мэтах бяспекі папярэднія копіі незашыфраванага файла-гаманца стануць неўжывальнымі, калі вы станеце карыстацца новым зашыфраваным гаманцом.</translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>Увага: Caps Lock уключаны!</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>Гаманец зашыфраваны</translation>
+ </message>
+ <message>
+ <source>Enter the new passphrase to the wallet.&lt;br/&gt;Please use a passphrase of &lt;b&gt;ten or more random characters&lt;/b&gt;, or &lt;b&gt;eight or more words&lt;/b&gt;.</source>
+ <translation>Увядзіце новы пароль для гаманца.&lt;br/&gt;Парольная фраза павинна складацца&lt;b&gt; не меньш чым з дзесяці сімвалаў&lt;/b&gt;, ці &lt;b&gt;больш чым з васьмі слоў&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>Enter the old passphrase and new passphrase to the wallet.</source>
+ <translation>Увядзіце стары пароль і новы пароль для гаманца.</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>Шыфраванне гаманца няўдалае</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>Шыфраванне гаманца не адбылося з-за ўнутранай памылкі. Гаманец незашыфраваны.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>Уведдзеныя паролі не супадаюць</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>Разблакаванне гаманца няўдалае</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>Уведзены пароль для расшыфравання гаманца памылковы</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>Расшыфраванне гаманца няўдалае</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>Парольная фраза гаманца паспяхова зменена.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>Падпісаць паведамленне...</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>Сінхранізацыя з сецівам...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>Агляд</translation>
+ </message>
+ <message>
+ <source>Node</source>
+ <translation>Вузел</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>Паказвае агульныя звесткі аб гаманцы</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>Транзакцыі</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>Праглядзець гісторыю транзакцый</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>Выйсці</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>Выйсці з праграмы</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>Аб Qt</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>Паказаць інфармацыю аб Qt</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>Опцыі...</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>Зашыфраваць Гаманец...</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>Стварыць копію гаманца...</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>&amp;Change Passphrase...</translation>
+ </message>
+ <message>
+ <source>&amp;Sending addresses...</source>
+ <translation>Адрасы дасылання...</translation>
+ </message>
+ <message>
+ <source>&amp;Receiving addresses...</source>
+ <translation>Адрасы прымання...</translation>
+ </message>
+ <message>
+ <source>Open &amp;URI...</source>
+ <translation>Адчыниць &amp;URI...</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core client</source>
+ <translation>Bitcoin Core кліент</translation>
+ </message>
+ <message>
+ <source>Importing blocks from disk...</source>
+ <translation>Імпартуюцца блокі з дыску...</translation>
+ </message>
+ <message>
+ <source>Reindexing blocks on disk...</source>
+ <translation>Пераіндэксацыя блокаў на дыску...</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>Даслаць манеты на Біткойн-адрас</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>Зрабіце копію гаманца ў іншае месца</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Змяніць пароль шыфравання гаманца</translation>
+ </message>
+ <message>
+ <source>&amp;Debug window</source>
+ <translation>Вакно адладкі</translation>
+ </message>
+ <message>
+ <source>Open debugging and diagnostic console</source>
+ <translation>Адкрыць кансоль дыягностыкі і адладкі</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>Праверыць паведамленне...</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Біткойн</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>Гаманец</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>Даслаць</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>Атрымаць</translation>
+ </message>
+ <message>
+ <source>Show information about Bitcoin Core</source>
+ <translation>Паказаць інфармацыю аб Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>&amp;Паказаць / Схаваць</translation>
+ </message>
+ <message>
+ <source>Show or hide the main Window</source>
+ <translation>Паказаць альбо схаваць галоўнае вакно</translation>
+ </message>
+ <message>
+ <source>Encrypt the private keys that belong to your wallet</source>
+ <translation>Зашыфраваць прыватныя ключы, якия належаць вашаму гаманцу</translation>
+ </message>
+ <message>
+ <source>Sign messages with your Bitcoin addresses to prove you own them</source>
+ <translation>Падпісаць паведамленне з дапамогай Біткойн-адраса каб даказаць, што яно належыць вам</translation>
+ </message>
+ <message>
+ <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source>
+ <translation>Спраўдзіць паведамленне з дапамогай Біткойн-адраса каб даказаць, што яно належыць вам</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>Ф&amp;айл</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>Наладкі</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>Дапамога</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Request payments (generates QR codes and bitcoin: URIs)</source>
+ <translation>Запатрабаваць плацёж (генеруецца QR-код для біткойн URI)</translation>
+ </message>
+ <message>
+ <source>&amp;About Bitcoin Core</source>
+ <translation>Аб Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Modify configuration options for Bitcoin Core</source>
+ <translation>Мадыфікаваць опцыі канфігурацыі Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Show the list of used sending addresses and labels</source>
+ <translation>Паказаць спіс адрасоў і метак для дасылання</translation>
+ </message>
+ <message>
+ <source>Show the list of used receiving addresses and labels</source>
+ <translation>Паказаць спіс адрасоў і метак для прымання</translation>
+ </message>
+ <message>
+ <source>Open a bitcoin: URI or payment request</source>
+ <translation>Адкрыць біткойн: URI ці запыт плацяжу</translation>
+ </message>
+ <message>
+ <source>&amp;Command-line options</source>
+ <translation>Опцыі каманднага радка</translation>
+ </message>
+ <message>
+ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
+ <translation>Паказваць даведку Bitcoin Core каб атрымаць спіс магчымых опцый каманднага радка</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n active connection(s) to Bitcoin network</source>
+ <translation><numerusform>%n актыўнае злучэнне з сецівам Bitcoin</numerusform><numerusform>%n актыўных злучэнняў з сецівам Bitcoin</numerusform><numerusform>%n актыўных злучэнняў з сецівам Bitcoin</numerusform><numerusform>%n актыўных злучэнняў з сецівам Bitcoin</numerusform></translation>
+ </message>
+ <message>
+ <source>No block source available...</source>
+ <translation>Крыніца блокаў недасяжная...</translation>
+ </message>
+ <message numerus="yes">
+ <source>Processed %n block(s) of transaction history.</source>
+ <translation><numerusform>Апрацаваны %n блок гісторыі транзакцый.</numerusform><numerusform>Апрацавана %n блокі гісторыі транзакцый.</numerusform><numerusform>Апрацавана %n блокаў гісторыі транзакцый.</numerusform><numerusform>Апрацавана %n блокаў гісторыі транзакцый.</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n hour(s)</source>
+ <translation><numerusform>%n гадзіна</numerusform><numerusform>%n гадзіны</numerusform><numerusform>%n гадзін</numerusform><numerusform>%n гадзін</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n day(s)</source>
+ <translation><numerusform>%n дзень</numerusform><numerusform>%n дні</numerusform><numerusform>%n дзён</numerusform><numerusform>%n дзён</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n week(s)</source>
+ <translation><numerusform>%n тыдзень</numerusform><numerusform>%n тыдні</numerusform><numerusform>%n тыдняў</numerusform><numerusform>%n тыдняў</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 and %2</source>
+ <translation>%1 і %2</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n year(s)</source>
+ <translation><numerusform>%n год</numerusform><numerusform>%n гады</numerusform><numerusform>%n гадоў</numerusform><numerusform>%n гадоў</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 behind</source>
+ <translation>%1 таму</translation>
+ </message>
+ <message>
+ <source>Last received block was generated %1 ago.</source>
+ <translation>Апошні прыняты блок генераваны %1 таму.</translation>
+ </message>
+ <message>
+ <source>Transactions after this will not yet be visible.</source>
+ <translation>Транзакцыи пасля гэтай не будуць бачныя.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Памылка</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Увага</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Інфармацыя</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>Сінхранізавана</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>Наганяем...</translation>
+ </message>
+ <message>
+ <source>Date: %1
+</source>
+ <translation>Дата: %1
+</translation>
+ </message>
+ <message>
+ <source>Amount: %1
+</source>
+ <translation>Колькасць: %1
+</translation>
+ </message>
+ <message>
+ <source>Type: %1
+</source>
+ <translation>Тып: %1
+</translation>
+ </message>
+ <message>
+ <source>Label: %1
+</source>
+ <translation>Метка: %1
+</translation>
+ </message>
+ <message>
+ <source>Address: %1
+</source>
+ <translation>Адрас: %1
+</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>Дасланыя транзакцыі</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>Прынятыя транзакцыі</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>Гаманец &lt;b&gt;зашыфраваны&lt;/b&gt; і зараз &lt;b&gt;разблакаваны&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>Гаманец &lt;b&gt;зашыфраваны&lt;/b&gt; і зараз &lt;b&gt;заблакаваны&lt;/b&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <source>Network Alert</source>
+ <translation>Трывога Сеціва</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Quantity:</source>
+ <translation>Колькасць:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Байтаў:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Колькасць:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Прыярытэт:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Камісія:</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Пыл:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Пасля камісіі:</translation>
+ </message>
+ <message>
+ <source>(un)select all</source>
+ <translation>(не)выбраць ўсё</translation>
+ </message>
+ <message>
+ <source>Tree mode</source>
+ <translation>Рэжым дрэва</translation>
+ </message>
+ <message>
+ <source>List mode</source>
+ <translation>Рэжым спіса</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Колькасць</translation>
+ </message>
+ <message>
+ <source>Received with label</source>
+ <translation>Прыняць праз метку</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>Прыняць праз адрас</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Дата</translation>
+ </message>
+ <message>
+ <source>Confirmations</source>
+ <translation>Пацверджанняў</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Пацверджана</translation>
+ </message>
+ <message>
+ <source>Priority</source>
+ <translation>Прыярытэт</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Капіяваць адрас</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Капіяваць пазнаку</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Капіяваць колькасць</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Капіяваць ID транзакцыі</translation>
+ </message>
+ <message>
+ <source>Lock unspent</source>
+ <translation>Замкнуць непатрачанае</translation>
+ </message>
+ <message>
+ <source>Unlock unspent</source>
+ <translation>Адамкнуць непатрачанае</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Капіяваць колькасць</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Капіяваць камісію</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Капіяваць з выняткам камісіі</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Капіяваць байты</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Капіяваць прыярытэт</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Капіяваць пыл</translation>
+ </message>
+ <message>
+ <source>highest</source>
+ <translation>найвышэйшы</translation>
+ </message>
+ <message>
+ <source>higher</source>
+ <translation>вышэйшы</translation>
+ </message>
+ <message>
+ <source>high</source>
+ <translation>высокі</translation>
+ </message>
+ <message>
+ <source>medium-high</source>
+ <translation>вышэй сярэдняга</translation>
+ </message>
+ <message>
+ <source>medium</source>
+ <translation>сярэдні</translation>
+ </message>
+ <message>
+ <source>low-medium</source>
+ <translation>ніжэй сярэдняга</translation>
+ </message>
+ <message>
+ <source>low</source>
+ <translation>нізкі</translation>
+ </message>
+ <message>
+ <source>lower</source>
+ <translation>ніжэйшы</translation>
+ </message>
+ <message>
+ <source>lowest</source>
+ <translation>найніжэйшы</translation>
+ </message>
+ <message>
+ <source>yes</source>
+ <translation>так</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>не</translation>
+ </message>
+ <message>
+ <source>This means a fee of at least %1 per kB is required.</source>
+ <translation>Гэта значыць патрэбную камісію мінімум %1 на Кб.</translation>
+ </message>
+ <message>
+ <source>Transactions with higher priority are more likely to get included into a block.</source>
+ <translation>Транзакцыя большага прыярытэту больш прываблівая для ўключэння ў блок.</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>непазначаны</translation>
+ </message>
+ </context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>Рэдагаваць Адрас</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>Метка</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>Адрас</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>Новы адрас для атрымання</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>Новы адрас для дасылання</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>Рэдагаваць адрас прымання</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>Рэдагаваць адрас дасылання</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>Уведзены адрас "%1" ужо ў кніге адрасоў</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>Немагчыма разблакаваць гаманец</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>Генерацыя новага ключа няўдалая</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ <message>
+ <source>A new data directory will be created.</source>
+ <translation>Будзе створаны новы каталог з данымі.</translation>
+ </message>
+ <message>
+ <source>name</source>
+ <translation>імя</translation>
+ </message>
+ <message>
+ <source>Directory already exists. Add %1 if you intend to create a new directory here.</source>
+ <translation>Каталог ужо існуе. Дадайце %1 калі вы збіраецеся стварыць тут новы каталог.</translation>
+ </message>
+ </context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>(%1-bit)</source>
+ <translation>(%1-біт)</translation>
+ </message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>Аб Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Command-line options</source>
+ <translation>Опцыі каманднага радка</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>Ужыванне:</translation>
+ </message>
+ <message>
+ <source>command-line options</source>
+ <translation>опцыі каманднага радка</translation>
+ </message>
+</context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Welcome</source>
+ <translation>Вітаем</translation>
+ </message>
+ <message>
+ <source>Welcome to Bitcoin Core.</source>
+ <translation>Вітаем у Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Памылка</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n GB of free space available</source>
+ <translation><numerusform>%n Гб вольнага месца даступна</numerusform><numerusform>%n Гб вольнага месца даступна</numerusform><numerusform>%n Гб вольнага месца даступна</numerusform><numerusform>%n Гб вольнага месца даступна</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>(of %n GB needed)</source>
+ <translation><numerusform>(з %n Гб патрэбна)</numerusform><numerusform>(з %n Гб патрэбна)</numerusform><numerusform>(з %n Гб патрэбна)</numerusform><numerusform>(з %n Гб патрэбна)</numerusform></translation>
+ </message>
+</context>
+<context>
+ <name>OpenURIDialog</name>
+ <message>
+ <source>Open URI</source>
+ <translation>Адкрыць URI</translation>
+ </message>
+ </context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>Опцыі</translation>
+ </message>
+ <message>
+ <source>MB</source>
+ <translation>Мб</translation>
+ </message>
+ </context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>Форма</translation>
+ </message>
+ </context>
+<context>
+ <name>PaymentServer</name>
+ </context>
+<context>
+ <name>PeerTableModel</name>
+ </context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>Колькасць</translation>
+ </message>
+ </context>
+<context>
+ <name>QRImageWidget</name>
+ </context>
+<context>
+ <name>RPCConsole</name>
+ </context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>Метка:</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Капіяваць пазнаку</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Капіяваць колькасць</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>Address</source>
+ <translation>Адрас</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Колькасць</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Метка</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Паведамленне</translation>
+ </message>
+ </context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Дата</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Метка</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Паведамленне</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Колькасць</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>непазначаны</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Даслаць Манеты</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Колькасць:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Байтаў:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Колькасць:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Прыярытэт:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Камісія:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Пасля камісіі:</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>Даслаць адразу некалькім атрымальнікам</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Пыл:</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>Баланс:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>Пацвердзіць дасыланне</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>Пацвердзіць дасыланне манет</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Капіяваць колькасць</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Капіяваць колькасць</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Капіяваць камісію</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Капіяваць з выняткам камісіі</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Капіяваць байты</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Капіяваць прыярытэт</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>Велічыня плацяжу мае быць больш за 0.</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>непазначаны</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Капіяваць пыл</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>Колькасць:</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>Заплаціць да:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Увядзіце пазнаку гэтаму адрасу, каб дадаць яго ў адрасную кнігу</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>Метка:</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Уставіць адрас з буферу абмена</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Memo:</source>
+ <translation>Памятка:</translation>
+ </message>
+</context>
+<context>
+ <name>ShutdownWindow</name>
+ </context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Уставіць адрас з буферу абмена</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ </context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>The Bitcoin Core developers</source>
+ <translation>Распрацоўнікі Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>[testnet]</source>
+ <translation>[testnet]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ <message>
+ <source>KB/s</source>
+ <translation>Кб/с</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>%1/offline</source>
+ <translation>%1/offline</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/непацверджана</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 пацверджанняў</translation>
+ </message>
+ <message>
+ <source>Status</source>
+ <translation>Статус</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Дата</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Паведамленне</translation>
+ </message>
+ <message>
+ <source>Comment</source>
+ <translation>Каментар</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Колькасць</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, пакуль не было паспяхова транслявана</translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>невядома</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>Дэталі транзакцыі</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>Гэтая панэль паказвае дэтальнае апісанне транзакцыі</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Дата</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Тып</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>Пацверджана (%1 пацверджанняў)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>Гэты блок не быў прыняты іншымі вузламі і магчыма не будзе ўхвалены!</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>Згенеравана, але не прынята</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Метка</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Прынята з</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>Прынята ад</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Даслана да</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>Плацёж самому сабе</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Здабыта</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(n/a)</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>Статус транзакцыі. Навядзіце курсар на гэтае поле, каб паказаць колькасць пацверджанняў.</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Дата і час, калі транзакцыя была прынята.</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>Тып транзакцыі</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>Колькасць аднятая ці даданая да балансу.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>Усё</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>Сёння</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>Гэты тыдзень</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>Гэты месяц</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>Мінулы месяц</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>Гэты год</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>Прамежак...</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Прынята з</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Даслана да</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>Да сябе</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Здабыта</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>Іншыя</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>Увядзіце адрас ці пазнаку для пошуку</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>Мін. колькасць</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Капіяваць адрас</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Капіяваць пазнаку</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Капіяваць колькасць</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Капіяваць ID транзакцыі</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>Рэдагаваць пазнаку</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Экспартаванне няўдалае</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Коскамі падзелены файл (*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Пацверджана</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Дата</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Тып</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Метка</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Адрас</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>Прамежак:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>да</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ </context>
+<context>
+ <name>WalletFrame</name>
+ </context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Даслаць Манеты</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>Экспарт</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Экспартаваць гэтыя звесткі у файл</translation>
+ </message>
+ </context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>Опцыі:</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>Вызначыць каталог даных</translation>
+ </message>
+ <message>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>Прымаць камандны радок і JSON-RPC каманды</translation>
+ </message>
+ <message>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>Запусціць у фоне як дэман і прымаць каманды</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>Ужываць тэставае сеціва</translation>
+ </message>
+ <message>
+ <source>Do you want to rebuild the block database now?</source>
+ <translation>Ці жадаеце вы перабудаваць зараз базу звестак блокаў?</translation>
+ </message>
+ <message>
+ <source>Error initializing block database</source>
+ <translation>Памылка ініцыялізацыі базвы звестак блокаў</translation>
+ </message>
+ <message>
+ <source>Error initializing wallet database environment %s!</source>
+ <translation>Памалка ініцыялізацыі асяроддзя базы звестак гаманца %s!</translation>
+ </message>
+ <message>
+ <source>Error loading block database</source>
+ <translation>Памылка загрузкі базвы звестак блокаў</translation>
+ </message>
+ <message>
+ <source>Error opening block database</source>
+ <translation>Памылка адчынення базы звестак блокаў</translation>
+ </message>
+ <message>
+ <source>Error: Disk space is low!</source>
+ <translation>Памылка: Замала вольнага месца на дыску!</translation>
+ </message>
+ <message>
+ <source>Importing...</source>
+ <translation>Імпартаванне...</translation>
+ </message>
+ <message>
+ <source>Not enough file descriptors available.</source>
+ <translation>Не хапае файлавых дэскрыптараў.</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: %u)</source>
+ <translation>Use UPnP to map the listening port (default: %u)</translation>
+ </message>
+ <message>
+ <source>Verifying blocks...</source>
+ <translation>Праверка блокаў...</translation>
+ </message>
+ <message>
+ <source>Verifying wallet...</source>
+ <translation>Праверка гаманца...</translation>
+ </message>
+ <message>
+ <source>Wallet options:</source>
+ <translation>Опцыі гаманца:</translation>
+ </message>
+ <message>
+ <source>Imports blocks from external blk000??.dat file</source>
+ <translation>Імпартаванне блокаў з вонкавага blk000??.dat файла</translation>
+ </message>
+ <message>
+ <source>Activating best chain...</source>
+ <translation>Актывацыя лепшага ланцуга...</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Інфармацыя</translation>
+ </message>
+ <message>
+ <source>RPC server options:</source>
+ <translation>Опцыі RPC сервера:</translation>
+ </message>
+ <message>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>Слаць trace/debug звесткі ў кансоль замест файла debug.log</translation>
+ </message>
+ <message>
+ <source>Signing transaction failed</source>
+ <translation>Памылка подпісу транзакцыі</translation>
+ </message>
+ <message>
+ <source>Start minimized</source>
+ <translation>Стартаваць ммінімізаванай</translation>
+ </message>
+ <message>
+ <source>This is experimental software.</source>
+ <translation>Гэта эксперыментальная праграма.</translation>
+ </message>
+ <message>
+ <source>Transaction amount too small</source>
+ <translation>Транзакцыя занадта малая</translation>
+ </message>
+ <message>
+ <source>Transaction too large</source>
+ <translation>Транзакцыя занадта вялікая</translation>
+ </message>
+ <message>
+ <source>Username for JSON-RPC connections</source>
+ <translation>Імя карыстальника для JSON-RPC злучэнняў</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Увага</translation>
+ </message>
+ <message>
+ <source>Password for JSON-RPC connections</source>
+ <translation>Пароль для JSON-RPC злучэнняў</translation>
+ </message>
+ <message>
+ <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
+ <translation>Выканаць каманду калі лепшы блок зменіцца (%s замяняецца на хэш блока)</translation>
+ </message>
+ <message>
+ <source>Upgrade wallet to latest format</source>
+ <translation>Абнавіць гаманец на новы фармат</translation>
+ </message>
+ <message>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>Перасканаваць ланцуг блокаў дзеля пошуку адсутных транзакцый</translation>
+ </message>
+ <message>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>Ужываць OpenSSL (https) для JSON-RPC злучэнняў</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>Загружаем адрасы...</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>Памылка загрузкі wallet.dat: гаманец пашкоджаны</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>Памылка загрузкі wallet.dat</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>Недастаткова сродкаў</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>Загружаем індэкс блокаў...</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>Загружаем гаманец...</translation>
+ </message>
+ <message>
+ <source>Cannot downgrade wallet</source>
+ <translation>Немагчыма рэгрэсаваць гаманец</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>Перасканаванне...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>Загрузка выканана</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Памылка</translation>
+ </message>
+</context>
+</TS> \ No newline at end of file
diff --git a/src/qt/locale/bitcoin_bg.ts b/src/qt/locale/bitcoin_bg.ts
new file mode 100644
index 0000000000..dd311df76a
--- /dev/null
+++ b/src/qt/locale/bitcoin_bg.ts
@@ -0,0 +1,2534 @@
+<TS language="bg" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Right-click to edit address or label</source>
+ <translation>Десен клик за промяна на адреса или името</translation>
+ </message>
+ <message>
+ <source>Create a new address</source>
+ <translation>Създаване на нов адрес</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>Нов</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Копиране на избрания адрес към клипборда</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>Копирай</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>Затвори</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>&amp;Копирай адрес</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>Изтрий избрания адрес от списъка</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Запишете данните от текущия раздел във файл</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>Изнеси</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;Изтриване</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>Изберете адрес, на който да се изпращат монети</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>Изберете адрес, на който ще получавате монети</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>Избери</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>Адреси за изпращане</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>Адреси за получаване</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>Това са адресите на получателите на плащания. Винаги проверявайте размера на сумата и адреса на получателя, преди да изпратите монети.</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>Това са Вашите Биткойн адреси,благодарение на които ще получавате плащания.Препоръчително е да използвате нови адреси за получаване на всяка транзакция.</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>Копирай &amp;име</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>&amp;Редактирай</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>Изнасяне на списъка с адреси</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>CSV файл (*.csv)</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Грешка при изнасянето</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the address list to %1. Please try again.</source>
+ <translation>Възникна грешка при опита за запазване на списъка с адреси в %1.Моля опитайте отново.</translation>
+ </message>
+</context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Име</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Адрес</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(без име)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Passphrase Dialog</source>
+ <translation>Диалог за паролите</translation>
+ </message>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Въведете текущата парола</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Нова парола</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Въведете новата парола повторно</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>Шифриране на портфейла</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>Тази операция изисква Вашата парола за отключване на портфейла.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Отключване на портфейла</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>Тази операция изисква Вашата парола за дешифриране на портфейла.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>Дешифриране на портфейла</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>Смяна на паролата</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>Потвърдете на шифрирането на портфейла</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>ВНИМАНИЕ: Ако шифрирате вашият портфейл и изгубите паролата си, &lt;b&gt;ЩЕ ИЗГУБИТЕ ВСИЧКИТЕ СИ БИТКОИНИ&lt;/b&gt;!</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>Наистина ли желаете да шифрирате портфейла си?</translation>
+ </message>
+ <message>
+ <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
+ <translation>ВАЖНО: Всички стари запазвания, които сте направили на Вашият портфейл трябва да замените с запазване на новополучения, шифриран портфейл. От съображения за сигурност, предишните запазвания на нешифрирани портфейли ще станат неизползваеми веднага, щом започнете да използвате новият, шифриран портфейл.</translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>Внимание: Caps Lock (главни букви) е включен.</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>Портфейлът е шифриран</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>Шифрирането беше неуспешно</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>Шифрирането на портфейла беше неуспешно, поради софтуерен проблем. Портфейлът не е шифриран.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>Паролите не съвпадат</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>Неуспешно отключване на портфейла</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>Паролата въведена за дешифриране на портфейла е грешна.</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>Дешифрирането на портфейла беше неуспешно</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>Паролата на портфейла беше променена успешно.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>Подписване на &amp;съобщение...</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>Синхронизиране с мрежата...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;Баланс</translation>
+ </message>
+ <message>
+ <source>Node</source>
+ <translation>Сървър</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>Обобщена информация за портфейла</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Транзакции</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>История на транзакциите</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>Из&amp;ход</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>Изход от приложението</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>За &amp;Qt</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>Покажи информация за Qt</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;Опции...</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>&amp;Шифриране на портфейла...</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>&amp;Запазване на портфейла...</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>&amp;Смяна на паролата...</translation>
+ </message>
+ <message>
+ <source>&amp;Sending addresses...</source>
+ <translation>&amp;Изпращане на адресите...</translation>
+ </message>
+ <message>
+ <source>&amp;Receiving addresses...</source>
+ <translation>&amp;Получаване на адресите...</translation>
+ </message>
+ <message>
+ <source>Open &amp;URI...</source>
+ <translation>Отвори &amp;URI...</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core client</source>
+ <translation>Bitcoin Core клиент</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>Изпращане към Биткоин адрес</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>Запазване на портфейла на друго място</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Променя паролата за портфейла</translation>
+ </message>
+ <message>
+ <source>&amp;Debug window</source>
+ <translation>&amp;Прозорец за отстраняване на грешки</translation>
+ </message>
+ <message>
+ <source>Open debugging and diagnostic console</source>
+ <translation>Отворете конзолата за диагностика и отстраняване на грешки</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>&amp;Проверка на съобщение...</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Биткоин</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>Портфейл</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>&amp;Изпращане</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>&amp;Получаване</translation>
+ </message>
+ <message>
+ <source>Show information about Bitcoin Core</source>
+ <translation>Покажете информация за Биткойн ядрото</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>&amp;Показване / Скриване</translation>
+ </message>
+ <message>
+ <source>Show or hide the main Window</source>
+ <translation>Показване и скриване на основния прозорец</translation>
+ </message>
+ <message>
+ <source>Encrypt the private keys that belong to your wallet</source>
+ <translation>Шифроване на личните ключове,които принадлежат на портфейла Ви.</translation>
+ </message>
+ <message>
+ <source>Sign messages with your Bitcoin addresses to prove you own them</source>
+ <translation>Пишете съобщения със своя Биткойн адрес за да докажете,че е ваш.</translation>
+ </message>
+ <message>
+ <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source>
+ <translation>Потвърждаване на съобщения за да се знае,че са написани с дадените Биткойн адреси.</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;Файл</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;Настройки</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>&amp;Помощ</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>Раздели</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Биткойн ядро</translation>
+ </message>
+ <message>
+ <source>Request payments (generates QR codes and bitcoin: URIs)</source>
+ <translation>Изискване на плащания(генерира QR кодове и биткойн: URIs)</translation>
+ </message>
+ <message>
+ <source>&amp;About Bitcoin Core</source>
+ <translation>&amp;Относно Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Show the list of used sending addresses and labels</source>
+ <translation>Показване на списъка с използвани адреси и имена</translation>
+ </message>
+ <message>
+ <source>Show the list of used receiving addresses and labels</source>
+ <translation>Покажи списък с използваните адреси и имена.</translation>
+ </message>
+ <message>
+ <source>Open a bitcoin: URI or payment request</source>
+ <translation>Отворете биткойн: URI или заявка за плащане</translation>
+ </message>
+ <message>
+ <source>&amp;Command-line options</source>
+ <translation>&amp;Налични команди</translation>
+ </message>
+ <message>
+ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
+ <translation>Покажи помощните съобщения на Биткойн за да видиш наличните и валидни команди</translation>
+ </message>
+ <message>
+ <source>No block source available...</source>
+ <translation>Липсва източник на блоковете...</translation>
+ </message>
+ <message>
+ <source>%1 and %2</source>
+ <translation>%1 и %2</translation>
+ </message>
+ <message>
+ <source>%1 behind</source>
+ <translation>%1 зад</translation>
+ </message>
+ <message>
+ <source>Transactions after this will not yet be visible.</source>
+ <translation>Транзакции след това няма все още да бъдат видими.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Грешка</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Предупреждение</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Информация</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>Синхронизиран</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>Зарежда блокове...</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>Изходяща транзакция</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>Входяща транзакция</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>Портфейлът е &lt;b&gt;криптиран&lt;/b&gt; и &lt;b&gt;отключен&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>Портфейлът е &lt;b&gt;криптиран&lt;/b&gt; и &lt;b&gt;заключен&lt;/b&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <source>Network Alert</source>
+ <translation>Мрежови проблем</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Coin Selection</source>
+ <translation>Избор на монета</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Количество:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Байтове:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Сума:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Приоритет:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Такса:</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Прах:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>След прилагане на ДДС</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Ресто</translation>
+ </message>
+ <message>
+ <source>(un)select all</source>
+ <translation>(Пре)махни всички</translation>
+ </message>
+ <message>
+ <source>Tree mode</source>
+ <translation>Дървовиден режим</translation>
+ </message>
+ <message>
+ <source>List mode</source>
+ <translation>Списъчен режим</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Сума</translation>
+ </message>
+ <message>
+ <source>Received with label</source>
+ <translation>Получени с име</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>Получени с адрес</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Дата</translation>
+ </message>
+ <message>
+ <source>Confirmations</source>
+ <translation>Потвърждения</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Потвърдени</translation>
+ </message>
+ <message>
+ <source>Priority</source>
+ <translation>Приоритет</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Копирай адрес</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Копирай име</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Копирай сума</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Копирай транзакция с ID</translation>
+ </message>
+ <message>
+ <source>Lock unspent</source>
+ <translation>Заключване на неизхарченото</translation>
+ </message>
+ <message>
+ <source>Unlock unspent</source>
+ <translation>Отключване на неизхарченото</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Копиране на количеството</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Копиране на данък добавена стойност</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Копиране след прилагане на данък добавена стойност</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Копиране на байтовете</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Копиране на приоритет</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Копирай прахта:</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Копирай рестото</translation>
+ </message>
+ <message>
+ <source>highest</source>
+ <translation>Най-висок</translation>
+ </message>
+ <message>
+ <source>higher</source>
+ <translation>По-висок</translation>
+ </message>
+ <message>
+ <source>high</source>
+ <translation>Висок</translation>
+ </message>
+ <message>
+ <source>medium-high</source>
+ <translation>Средно-висок</translation>
+ </message>
+ <message>
+ <source>medium</source>
+ <translation>Среден</translation>
+ </message>
+ <message>
+ <source>low-medium</source>
+ <translation>Ниско-среден</translation>
+ </message>
+ <message>
+ <source>low</source>
+ <translation>Нисък</translation>
+ </message>
+ <message>
+ <source>lower</source>
+ <translation>По-нисък</translation>
+ </message>
+ <message>
+ <source>lowest</source>
+ <translation>Най-нисък</translation>
+ </message>
+ <message>
+ <source>(%1 locked)</source>
+ <translation>(%1 заключен)</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>нищо</translation>
+ </message>
+ <message>
+ <source>yes</source>
+ <translation>да</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>не</translation>
+ </message>
+ <message>
+ <source>This means a fee of at least %1 per kB is required.</source>
+ <translation>Това означава че се изисква такса от поне %1 на килобайт.</translation>
+ </message>
+ <message>
+ <source>Can vary +/- 1 byte per input.</source>
+ <translation>Може да варира с +-1 байт</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(без име)</translation>
+ </message>
+ <message>
+ <source>change from %1 (%2)</source>
+ <translation>ресто от %1 (%2)</translation>
+ </message>
+ <message>
+ <source>(change)</source>
+ <translation>(промени)</translation>
+ </message>
+</context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>Редактиране на адрес</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>&amp;Име</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;Адрес</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>Нов адрес за получаване</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>Нов адрес за изпращане</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>Редактиране на адрес за получаване</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>Редактиране на адрес за изпращане</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>Вече има адрес "%1" в списъка с адреси.</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is not a valid Bitcoin address.</source>
+ <translation>"%1" не е валиден Биткоин адрес.</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>Отключването на портфейла беше неуспешно.</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>Създаването на ключ беше неуспешно.</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ <message>
+ <source>A new data directory will be created.</source>
+ <translation>Ще се създаде нова папка за данни.</translation>
+ </message>
+ <message>
+ <source>name</source>
+ <translation>име</translation>
+ </message>
+ <message>
+ <source>Directory already exists. Add %1 if you intend to create a new directory here.</source>
+ <translation>Директорията вече съществува.Добавете %1 ако желаете да добавите нова директория тук.</translation>
+ </message>
+ <message>
+ <source>Path already exists, and is not a directory.</source>
+ <translation>Пътят вече съществува и не е папка.</translation>
+ </message>
+ <message>
+ <source>Cannot create data directory here.</source>
+ <translation>Не може да се създаде директория тук.</translation>
+ </message>
+</context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Биткойн ядро</translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>версия</translation>
+ </message>
+ <message>
+ <source>(%1-bit)</source>
+ <translation>(%1-битов)</translation>
+ </message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>Относно Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Command-line options</source>
+ <translation>Списък с команди</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>Използване:</translation>
+ </message>
+ <message>
+ <source>command-line options</source>
+ <translation>Списък с налични команди</translation>
+ </message>
+</context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Welcome</source>
+ <translation>Добре дошли</translation>
+ </message>
+ <message>
+ <source>Welcome to Bitcoin Core.</source>
+ <translation>Добре дошли в Биткойн ядрото.</translation>
+ </message>
+ <message>
+ <source>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</source>
+ <translation>Тъй като това е първото стартиране на програмата можете да изберете къде Биткон ядрото да запази данните си.</translation>
+ </message>
+ <message>
+ <source>Use the default data directory</source>
+ <translation>Използване на директория по подразбиране</translation>
+ </message>
+ <message>
+ <source>Use a custom data directory:</source>
+ <translation>Използване на директория ръчно</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Биткойн ядро</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Грешка</translation>
+ </message>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ <message>
+ <source>Open URI</source>
+ <translation>Отваряне на URI</translation>
+ </message>
+ </context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>Опции</translation>
+ </message>
+ <message>
+ <source>&amp;Main</source>
+ <translation>&amp;Основни</translation>
+ </message>
+ <message>
+ <source>Size of &amp;database cache</source>
+ <translation>Размер на кеша в &amp;базата данни</translation>
+ </message>
+ <message>
+ <source>MB</source>
+ <translation>Мегабайта</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside</source>
+ <translation>Приемай връзки отвън</translation>
+ </message>
+ <message>
+ <source>Allow incoming connections</source>
+ <translation>Позволи входящите връзки</translation>
+ </message>
+ <message>
+ <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
+ <translation>IP адрес на прокси (напр. за IPv4: 127.0.0.1 / за IPv6: ::1)</translation>
+ </message>
+ <message>
+ <source>Third party transaction URLs</source>
+ <translation>URL адреси на трети страни</translation>
+ </message>
+ <message>
+ <source>Reset all client options to default.</source>
+ <translation>Възстановете всички настройки по подразбиране.</translation>
+ </message>
+ <message>
+ <source>&amp;Reset Options</source>
+ <translation>&amp;Нулирай настройките</translation>
+ </message>
+ <message>
+ <source>&amp;Network</source>
+ <translation>&amp;Мрежа</translation>
+ </message>
+ <message>
+ <source>W&amp;allet</source>
+ <translation>По&amp;ртфейл</translation>
+ </message>
+ <message>
+ <source>Expert</source>
+ <translation>Експерт</translation>
+ </message>
+ <message>
+ <source>&amp;Spend unconfirmed change</source>
+ <translation>&amp;Похарчете непотвърденото ресто</translation>
+ </message>
+ <message>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>Автоматично отваряне на входящия Bitcoin порт. Работи само с рутери поддържащи UPnP.</translation>
+ </message>
+ <message>
+ <source>Map port using &amp;UPnP</source>
+ <translation>Отваряне на входящия порт чрез &amp;UPnP</translation>
+ </message>
+ <message>
+ <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
+ <translation>Свързване с Биткойн мрежата чрез SOCKS5 прокси.</translation>
+ </message>
+ <message>
+ <source>&amp;Connect through SOCKS5 proxy (default proxy):</source>
+ <translation>&amp;Свързване чрез SOCKS5 прокси (прокси по подразбиране):</translation>
+ </message>
+ <message>
+ <source>Proxy &amp;IP:</source>
+ <translation>Прокси &amp; АйПи:</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>&amp;Порт:</translation>
+ </message>
+ <message>
+ <source>Port of the proxy (e.g. 9050)</source>
+ <translation>Порт на прокси сървъра (пр. 9050)</translation>
+ </message>
+ <message>
+ <source>&amp;Window</source>
+ <translation>&amp;Прозорец</translation>
+ </message>
+ <message>
+ <source>Show only a tray icon after minimizing the window.</source>
+ <translation>След минимизиране ще е видима само иконата в системния трей.</translation>
+ </message>
+ <message>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>&amp;Минимизиране в системния трей</translation>
+ </message>
+ <message>
+ <source>M&amp;inimize on close</source>
+ <translation>М&amp;инимизиране при затваряне</translation>
+ </message>
+ <message>
+ <source>&amp;Display</source>
+ <translation>&amp;Интерфейс</translation>
+ </message>
+ <message>
+ <source>User Interface &amp;language:</source>
+ <translation>Език:</translation>
+ </message>
+ <message>
+ <source>&amp;Unit to show amounts in:</source>
+ <translation>Мерна единица за показваните суми:</translation>
+ </message>
+ <message>
+ <source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
+ <translation>Изберете единиците, показвани по подразбиране в интерфейса.</translation>
+ </message>
+ <message>
+ <source>Whether to show coin control features or not.</source>
+ <translation>Дали да покаже възможностите за контрол на монетите или не.</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>ОК</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>Отказ</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>подразбиране</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>нищо</translation>
+ </message>
+ <message>
+ <source>Confirm options reset</source>
+ <translation>Потвърдете отмяната на настройките.</translation>
+ </message>
+ <message>
+ <source>Client restart required to activate changes.</source>
+ <translation>Изисква се рестартиране на клиента за активиране на извършените промени.</translation>
+ </message>
+ <message>
+ <source>This change would require a client restart.</source>
+ <translation>Тази промяна изисква рестартиране на клиента Ви.</translation>
+ </message>
+ <message>
+ <source>The supplied proxy address is invalid.</source>
+ <translation>Текущият прокси адрес е невалиден.</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>Формуляр</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>Текущата информация на екрана може да не е актуална. Вашият портфейл ще се синхронизира автоматично с мрежата на Биткоин, щом поне една връзката с нея се установи; този процес все още не е приключил.</translation>
+ </message>
+ <message>
+ <source>Watch-only:</source>
+ <translation>В наблюдателен режим:</translation>
+ </message>
+ <message>
+ <source>Available:</source>
+ <translation>Налично:</translation>
+ </message>
+ <message>
+ <source>Your current spendable balance</source>
+ <translation>Вашата текуща сметка за изразходване</translation>
+ </message>
+ <message>
+ <source>Pending:</source>
+ <translation>Изчакващо:</translation>
+ </message>
+ <message>
+ <source>Immature:</source>
+ <translation>Неразвит:</translation>
+ </message>
+ <message>
+ <source>Mined balance that has not yet matured</source>
+ <translation>Миниран баланс,който все още не се е развил</translation>
+ </message>
+ <message>
+ <source>Balances</source>
+ <translation>Баланс</translation>
+ </message>
+ <message>
+ <source>Total:</source>
+ <translation>Общо:</translation>
+ </message>
+ <message>
+ <source>Your current total balance</source>
+ <translation>Текущият ви общ баланс</translation>
+ </message>
+ <message>
+ <source>Spendable:</source>
+ <translation>За харчене:</translation>
+ </message>
+ <message>
+ <source>Recent transactions</source>
+ <translation>Скорошни транзакции</translation>
+ </message>
+ </context>
+<context>
+ <name>PaymentServer</name>
+ <message>
+ <source>URI handling</source>
+ <translation>Справяне с URI</translation>
+ </message>
+ <message>
+ <source>Invalid payment address %1</source>
+ <translation>Невалиден адрес на плащане %1</translation>
+ </message>
+ <message>
+ <source>Payment request rejected</source>
+ <translation>Заявката за плащане беше отхвърлена</translation>
+ </message>
+ <message>
+ <source>Payment request network doesn't match client network.</source>
+ <translation>Мрежата от която се извършва заявката за плащане не съвпада с мрежата на клиента.</translation>
+ </message>
+ <message>
+ <source>Requested payment amount of %1 is too small (considered dust).</source>
+ <translation>Заявената сума за плащане: %1 е твърде малка (счита се за отпадък)</translation>
+ </message>
+ <message>
+ <source>Payment request error</source>
+ <translation>Възникна грешка по време назаявката за плащане</translation>
+ </message>
+ <message>
+ <source>Cannot start bitcoin: click-to-pay handler</source>
+ <translation>Биткойн не можe да се стартира: click-to-pay handler</translation>
+ </message>
+ <message>
+ <source>Payment request file handling</source>
+ <translation>Файл за справяне със заявки</translation>
+ </message>
+ <message>
+ <source>Refund from %1</source>
+ <translation>Възстановяване на сума от %1</translation>
+ </message>
+ <message>
+ <source>Payment request DoS protection</source>
+ <translation>Дос защита на заявката за плащане</translation>
+ </message>
+ <message>
+ <source>Error communicating with %1: %2</source>
+ <translation>Грешка при комуникацията с %1: %2</translation>
+ </message>
+ <message>
+ <source>Bad response from server %1</source>
+ <translation>Възникна проблем при свързването със сървър %1</translation>
+ </message>
+ <message>
+ <source>Payment acknowledged</source>
+ <translation>Плащането е прието</translation>
+ </message>
+ <message>
+ <source>Network request error</source>
+ <translation>Грешка в мрежата по време на заявката</translation>
+ </message>
+</context>
+<context>
+ <name>PeerTableModel</name>
+ <message>
+ <source>User Agent</source>
+ <translation>Клиент на потребителя</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Време за отговор</translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>Сума</translation>
+ </message>
+ <message>
+ <source>Enter a Bitcoin address (e.g. %1)</source>
+ <translation>Въведете Биткойн адрес (например: %1)</translation>
+ </message>
+ <message>
+ <source>%1 d</source>
+ <translation>%1 ден</translation>
+ </message>
+ <message>
+ <source>%1 h</source>
+ <translation>%1 час</translation>
+ </message>
+ <message>
+ <source>%1 m</source>
+ <translation>%1 минута</translation>
+ </message>
+ <message>
+ <source>%1 s</source>
+ <translation>%1 секунда</translation>
+ </message>
+ <message>
+ <source>None</source>
+ <translation>Неналичен</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>Несъществуващ</translation>
+ </message>
+ <message>
+ <source>%1 ms</source>
+ <translation>%1 милисекунда</translation>
+ </message>
+</context>
+<context>
+ <name>QRImageWidget</name>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Запиши изображение...</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Image</source>
+ <translation>&amp;Копирай изображение</translation>
+ </message>
+ <message>
+ <source>Save QR Code</source>
+ <translation>Запази QR Код</translation>
+ </message>
+ <message>
+ <source>PNG Image (*.png)</source>
+ <translation>PNG Изображение (*.png)</translation>
+ </message>
+</context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>Client name</source>
+ <translation>Име на клиента</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>Несъществуващ</translation>
+ </message>
+ <message>
+ <source>Client version</source>
+ <translation>Версия на клиента</translation>
+ </message>
+ <message>
+ <source>&amp;Information</source>
+ <translation>Данни</translation>
+ </message>
+ <message>
+ <source>Debug window</source>
+ <translation>Прозорец с грешки</translation>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>Основни</translation>
+ </message>
+ <message>
+ <source>Using OpenSSL version</source>
+ <translation>Използване на OpenSSL версия</translation>
+ </message>
+ <message>
+ <source>Using BerkeleyDB version</source>
+ <translation>Използване на база данни BerkeleyDB </translation>
+ </message>
+ <message>
+ <source>Startup time</source>
+ <translation>Време за стартиране</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Мрежа</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>Име</translation>
+ </message>
+ <message>
+ <source>Number of connections</source>
+ <translation>Брой връзки</translation>
+ </message>
+ <message>
+ <source>Current number of blocks</source>
+ <translation>Текущ брой блокове</translation>
+ </message>
+ <message>
+ <source>Received</source>
+ <translation>Получени</translation>
+ </message>
+ <message>
+ <source>Sent</source>
+ <translation>Изпратени</translation>
+ </message>
+ <message>
+ <source>&amp;Peers</source>
+ <translation>&amp;Пиъри</translation>
+ </message>
+ <message>
+ <source>Select a peer to view detailed information.</source>
+ <translation>Избери пиър за детайлна информация.</translation>
+ </message>
+ <message>
+ <source>Direction</source>
+ <translation>Посока</translation>
+ </message>
+ <message>
+ <source>Version</source>
+ <translation>Версия</translation>
+ </message>
+ <message>
+ <source>User Agent</source>
+ <translation>Клиент на потребителя</translation>
+ </message>
+ <message>
+ <source>Services</source>
+ <translation>Услуги</translation>
+ </message>
+ <message>
+ <source>Starting Height</source>
+ <translation>Стартова височина</translation>
+ </message>
+ <message>
+ <source>Connection Time</source>
+ <translation>Продължителност на връзката</translation>
+ </message>
+ <message>
+ <source>Last Send</source>
+ <translation>Изпратени за последно</translation>
+ </message>
+ <message>
+ <source>Last Receive</source>
+ <translation>Получени за последно</translation>
+ </message>
+ <message>
+ <source>Bytes Sent</source>
+ <translation>Изпратени байтове</translation>
+ </message>
+ <message>
+ <source>Bytes Received</source>
+ <translation>Получени байтове</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Време за отговор</translation>
+ </message>
+ <message>
+ <source>Last block time</source>
+ <translation>Време на последния блок</translation>
+ </message>
+ <message>
+ <source>&amp;Open</source>
+ <translation>&amp;Отвори</translation>
+ </message>
+ <message>
+ <source>&amp;Console</source>
+ <translation>&amp;Конзола</translation>
+ </message>
+ <message>
+ <source>&amp;Network Traffic</source>
+ <translation>&amp;Мрежов Трафик</translation>
+ </message>
+ <message>
+ <source>&amp;Clear</source>
+ <translation>&amp;Изчисти</translation>
+ </message>
+ <message>
+ <source>Totals</source>
+ <translation>Общо:</translation>
+ </message>
+ <message>
+ <source>In:</source>
+ <translation>Входящи:</translation>
+ </message>
+ <message>
+ <source>Out:</source>
+ <translation>Изходящи</translation>
+ </message>
+ <message>
+ <source>Build date</source>
+ <translation>Дата на създаване</translation>
+ </message>
+ <message>
+ <source>Debug log file</source>
+ <translation>Лог файл,съдържащ грешките</translation>
+ </message>
+ <message>
+ <source>Clear console</source>
+ <translation>Изчисти конзолата</translation>
+ </message>
+ <message>
+ <source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
+ <translation>Използвайте стрелки надолу и нагореза разглеждане на историятаот команди и &lt;b&gt;Ctrl-L&lt;/b&gt; за изчистване на конзолата.</translation>
+ </message>
+ <message>
+ <source>Type &lt;b&gt;help&lt;/b&gt; for an overview of available commands.</source>
+ <translation>Въведeте &lt;/b&gt;помощ&lt;/b&gt; за да видите наличните команди.</translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation>%1 Байт</translation>
+ </message>
+ <message>
+ <source>%1 KB</source>
+ <translation>%1 Килобайт</translation>
+ </message>
+ <message>
+ <source>%1 MB</source>
+ <translation>%1 Мегабайт</translation>
+ </message>
+ <message>
+ <source>%1 GB</source>
+ <translation>%1 Гигабайт</translation>
+ </message>
+ <message>
+ <source>via %1</source>
+ <translation>посредством %1</translation>
+ </message>
+ <message>
+ <source>never</source>
+ <translation>Никога</translation>
+ </message>
+ <message>
+ <source>Inbound</source>
+ <translation>Входящи</translation>
+ </message>
+ <message>
+ <source>Outbound</source>
+ <translation>Изходящи</translation>
+ </message>
+ <message>
+ <source>Unknown</source>
+ <translation>Неизвестен</translation>
+ </message>
+ <message>
+ <source>Fetching...</source>
+ <translation>Прихващане...</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Amount:</source>
+ <translation>&amp;Сума</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Име:</translation>
+ </message>
+ <message>
+ <source>&amp;Message:</source>
+ <translation>&amp;Съобщение:</translation>
+ </message>
+ <message>
+ <source>Use this form to request payments. All fields are &lt;b&gt;optional&lt;/b&gt;.</source>
+ <translation>Използвате този формуляр за заявяване на плащания. Всички полета са &lt;b&gt;незадължителни&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>An optional amount to request. Leave this empty or zero to not request a specific amount.</source>
+ <translation>Незадължително заявяване на сума. Оставете полето празно или нулево, за да не заявите конкретна сума.</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Изчисти всички полета от формуляра.</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation>Изчистване</translation>
+ </message>
+ <message>
+ <source>Requested payments history</source>
+ <translation>Изискана история на плащанията</translation>
+ </message>
+ <message>
+ <source>&amp;Request payment</source>
+ <translation>&amp;Изискване на плащане</translation>
+ </message>
+ <message>
+ <source>Show</source>
+ <translation>Показване</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>Премахване</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Копирай име</translation>
+ </message>
+ <message>
+ <source>Copy message</source>
+ <translation>Копиране на съобщението</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Копирай сума</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>QR Code</source>
+ <translation>QR код</translation>
+ </message>
+ <message>
+ <source>Copy &amp;URI</source>
+ <translation>Копиране на &amp;URI</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Address</source>
+ <translation>&amp;Копирай адрес</translation>
+ </message>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Запиши изображение...</translation>
+ </message>
+ <message>
+ <source>Request payment to %1</source>
+ <translation>Изискване на плащане от %1</translation>
+ </message>
+ <message>
+ <source>Payment information</source>
+ <translation>Данни за плащането</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Адрес</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Сума</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Име</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Съобщение</translation>
+ </message>
+ <message>
+ <source>Error encoding URI into QR Code.</source>
+ <translation>Грешка при създаването на QR Code от URI.</translation>
+ </message>
+</context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Дата</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Име</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Съобщение</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Сума</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(без име)</translation>
+ </message>
+ <message>
+ <source>(no message)</source>
+ <translation>(без съобщение)</translation>
+ </message>
+ <message>
+ <source>(no amount)</source>
+ <translation>(липсва сума)</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Изпращане</translation>
+ </message>
+ <message>
+ <source>Coin Control Features</source>
+ <translation>Настройки за контрол на монетите</translation>
+ </message>
+ <message>
+ <source>automatically selected</source>
+ <translation>астоматично избран</translation>
+ </message>
+ <message>
+ <source>Insufficient funds!</source>
+ <translation>Нямате достатъчно налични пари!</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Количество:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Байтове:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Сума:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Приоритет:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Такса:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>След прилагане на ДДС</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Ресто</translation>
+ </message>
+ <message>
+ <source>If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address.</source>
+ <translation>Ако тази опция е активирана,но адресът на промяна е празен или невалиден,промяната ще бъде изпратена на новосъздаден адрес.</translation>
+ </message>
+ <message>
+ <source>Transaction Fee:</source>
+ <translation>Такса за транзакцията:</translation>
+ </message>
+ <message>
+ <source>Choose...</source>
+ <translation>Избери...</translation>
+ </message>
+ <message>
+ <source>per kilobyte</source>
+ <translation>за килобайт</translation>
+ </message>
+ <message>
+ <source>total at least</source>
+ <translation>Крайна сума поне</translation>
+ </message>
+ <message>
+ <source>Recommended:</source>
+ <translation>Препоръчителна:</translation>
+ </message>
+ <message>
+ <source>Custom:</source>
+ <translation>По избор:</translation>
+ </message>
+ <message>
+ <source>Confirmation time:</source>
+ <translation>Време за потвърждение:</translation>
+ </message>
+ <message>
+ <source>normal</source>
+ <translation>нормален</translation>
+ </message>
+ <message>
+ <source>fast</source>
+ <translation>бърз</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>Изпращане към повече от един получател</translation>
+ </message>
+ <message>
+ <source>Add &amp;Recipient</source>
+ <translation>Добави &amp;получател</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Изчисти всички полета от формуляра.</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Прах:</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>&amp;Изчисти</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>Баланс:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>Потвърдете изпращането</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>И&amp;зпрати</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>Потвърждаване</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Копиране на количеството</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Копирай сума</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Копиране на данък добавена стойност</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Копиране след прилагане на данък добавена стойност</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Копиране на байтовете</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Копиране на приоритет</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Копирай рестото</translation>
+ </message>
+ <message>
+ <source>or</source>
+ <translation>или</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>Сумата трябва да е по-голяма от 0.</translation>
+ </message>
+ <message>
+ <source>The amount exceeds your balance.</source>
+ <translation>Сумата надвишава текущия баланс</translation>
+ </message>
+ <message>
+ <source>The total exceeds your balance when the %1 transaction fee is included.</source>
+ <translation>Сумата при добавяне на данък добавена стойност по %1 транзакцията надвишава сумата по вашата сметка.</translation>
+ </message>
+ <message>
+ <source>Transaction creation failed!</source>
+ <translation>Грешка при създаването на транзакция!</translation>
+ </message>
+ <message>
+ <source>Pay only the minimum fee of %1</source>
+ <translation>Платете минималната такса от %1</translation>
+ </message>
+ <message>
+ <source>Warning: Invalid Bitcoin address</source>
+ <translation>Внимание: Невалиден Биткойн адрес</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(без име)</translation>
+ </message>
+ <message>
+ <source>Warning: Unknown change address</source>
+ <translation>Внимание:Неизвестен адрес за промяна</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Копирай прахта:</translation>
+ </message>
+ <message>
+ <source>Are you sure you want to send?</source>
+ <translation>Наистина ли искате да изпратите?</translation>
+ </message>
+ <message>
+ <source>added as transaction fee</source>
+ <translation>добавено като такса за транзакция</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>С&amp;ума:</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>Плати &amp;На:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Въведете име за този адрес, за да го добавите в списъка с адреси</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Име:</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Изберете използван преди адрес</translation>
+ </message>
+ <message>
+ <source>This is a normal payment.</source>
+ <translation>Това е нормално плащане.</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Вмъкни от клипборда</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Remove this entry</source>
+ <translation>Премахване на този запис</translation>
+ </message>
+ <message>
+ <source>Message:</source>
+ <translation>Съобщение:</translation>
+ </message>
+ <message>
+ <source>Pay To:</source>
+ <translation>Плащане на:</translation>
+ </message>
+ <message>
+ <source>Memo:</source>
+ <translation>Бележка:</translation>
+ </message>
+</context>
+<context>
+ <name>ShutdownWindow</name>
+ <message>
+ <source>Bitcoin Core is shutting down...</source>
+ <translation>Биткойн ядрото се изключва...</translation>
+ </message>
+ <message>
+ <source>Do not shut down the computer until this window disappears.</source>
+ <translation>Не изключвайте компютъра докато този прозорец не изчезне.</translation>
+ </message>
+</context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Signatures - Sign / Verify a Message</source>
+ <translation>Подпиши / Провери съобщение</translation>
+ </message>
+ <message>
+ <source>&amp;Sign Message</source>
+ <translation>&amp;Подпиши</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Изберете използван преди адрес</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Вмъкни от клипборда</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Enter the message you want to sign here</source>
+ <translation>Въведете съобщението тук</translation>
+ </message>
+ <message>
+ <source>Signature</source>
+ <translation>Подпис</translation>
+ </message>
+ <message>
+ <source>Copy the current signature to the system clipboard</source>
+ <translation>Копиране на текущия подпис</translation>
+ </message>
+ <message>
+ <source>Sign the message to prove you own this Bitcoin address</source>
+ <translation>Подпишете съобщение като доказателство, че притежавате определен адрес</translation>
+ </message>
+ <message>
+ <source>Sign &amp;Message</source>
+ <translation>Подпиши &amp;съобщение</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>&amp;Изчисти</translation>
+ </message>
+ <message>
+ <source>&amp;Verify Message</source>
+ <translation>&amp;Провери</translation>
+ </message>
+ <message>
+ <source>Verify the message to ensure it was signed with the specified Bitcoin address</source>
+ <translation>Проверете съобщение, за да сте сигурни че е подписано с определен Биткоин адрес</translation>
+ </message>
+ <message>
+ <source>Verify &amp;Message</source>
+ <translation>Потвърди &amp;съобщението</translation>
+ </message>
+ <message>
+ <source>Click "Sign Message" to generate signature</source>
+ <translation>Натиснете "Подписване на съобщение" за да създадете подпис</translation>
+ </message>
+ <message>
+ <source>The entered address is invalid.</source>
+ <translation>Въведеният адрес е невалиден.</translation>
+ </message>
+ <message>
+ <source>Please check the address and try again.</source>
+ <translation>Моля проверете адреса и опитайте отново.</translation>
+ </message>
+ <message>
+ <source>The entered address does not refer to a key.</source>
+ <translation>Въведеният адрес не може да се съпостави с валиден ключ.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock was cancelled.</source>
+ <translation>Отключването на портфейла беше отменено.</translation>
+ </message>
+ <message>
+ <source>Private key for the entered address is not available.</source>
+ <translation>Не е наличен частен ключ за въведеният адрес.</translation>
+ </message>
+ <message>
+ <source>Message signing failed.</source>
+ <translation>Подписването на съобщение беше неуспешно.</translation>
+ </message>
+ <message>
+ <source>Message signed.</source>
+ <translation>Съобщението е подписано.</translation>
+ </message>
+ <message>
+ <source>The signature could not be decoded.</source>
+ <translation>Подписът не може да бъде декодиран.</translation>
+ </message>
+ <message>
+ <source>Please check the signature and try again.</source>
+ <translation>Проверете подписа и опитайте отново.</translation>
+ </message>
+ <message>
+ <source>The signature did not match the message digest.</source>
+ <translation>Подписът не отговаря на комбинацията от съобщение и адрес.</translation>
+ </message>
+ <message>
+ <source>Message verification failed.</source>
+ <translation>Проверката на съобщението беше неуспешна.</translation>
+ </message>
+ <message>
+ <source>Message verified.</source>
+ <translation>Съобщението е потвърдено.</translation>
+ </message>
+</context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Биткойн ядро</translation>
+ </message>
+ <message>
+ <source>The Bitcoin Core developers</source>
+ <translation>Разработчици на Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>[testnet]</source>
+ <translation>[testnet]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ <message>
+ <source>KB/s</source>
+ <translation>Килобайта в секунда</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>Подлежи на промяна до %1</translation>
+ </message>
+ <message>
+ <source>conflicted</source>
+ <translation>припокриващ се</translation>
+ </message>
+ <message>
+ <source>%1/offline</source>
+ <translation>%1/офлайн</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/непотвърдени</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>включена в %1 блока</translation>
+ </message>
+ <message>
+ <source>Status</source>
+ <translation>Статус</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Дата</translation>
+ </message>
+ <message>
+ <source>Source</source>
+ <translation>Източник</translation>
+ </message>
+ <message>
+ <source>Generated</source>
+ <translation>Издадени</translation>
+ </message>
+ <message>
+ <source>From</source>
+ <translation>От</translation>
+ </message>
+ <message>
+ <source>To</source>
+ <translation>За</translation>
+ </message>
+ <message>
+ <source>own address</source>
+ <translation>собствен адрес</translation>
+ </message>
+ <message>
+ <source>label</source>
+ <translation>име</translation>
+ </message>
+ <message>
+ <source>Credit</source>
+ <translation>Кредит</translation>
+ </message>
+ <message>
+ <source>not accepted</source>
+ <translation>не е приет</translation>
+ </message>
+ <message>
+ <source>Debit</source>
+ <translation>Дебит</translation>
+ </message>
+ <message>
+ <source>Total debit</source>
+ <translation>Общ дълг</translation>
+ </message>
+ <message>
+ <source>Total credit</source>
+ <translation>Общ дълг</translation>
+ </message>
+ <message>
+ <source>Transaction fee</source>
+ <translation>Такса</translation>
+ </message>
+ <message>
+ <source>Net amount</source>
+ <translation>Нетна сума</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Съобщение</translation>
+ </message>
+ <message>
+ <source>Comment</source>
+ <translation>Коментар</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>Merchant</source>
+ <translation>Търговец</translation>
+ </message>
+ <message>
+ <source>Generated coins must mature %1 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.</source>
+ <translation>Генерираните монети трябва да отлежат %1 блока преди да могат да бъдат похарчени. Когато генерираш блока, той се разпространява в мрежата, за да се добави в блок-веригата. Ако не успее да се добави във веригата, неговия статус ще се стане "неприет" и няма да може да се похарчи. Това е възможно да се случи случайно, ако друг възел генерира блок няколко секунди след твоя.</translation>
+ </message>
+ <message>
+ <source>Debug information</source>
+ <translation>Информация за грешките</translation>
+ </message>
+ <message>
+ <source>Transaction</source>
+ <translation>Транзакция</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Сума</translation>
+ </message>
+ <message>
+ <source>true</source>
+ <translation>true</translation>
+ </message>
+ <message>
+ <source>false</source>
+ <translation>false</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, все още не е изпратено</translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>неизвестен</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>Транзакция</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>Описание на транзакцията</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Дата</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Тип</translation>
+ </message>
+ <message>
+ <source>Immature (%1 confirmations, will be available after %2)</source>
+ <translation>Неплатим (%1 потвърждения, ще бъде платим след %2)</translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>Подлежи на промяна до %1</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>Потвърдени (%1 потвърждения)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>Блокът не е получен от останалите участници и най-вероятно няма да бъде одобрен.</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>Генерирана, но отхвърлена от мрежата</translation>
+ </message>
+ <message>
+ <source>Offline</source>
+ <translation>Извън линия</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Име</translation>
+ </message>
+ <message>
+ <source>Unconfirmed</source>
+ <translation>Непотвърдено</translation>
+ </message>
+ <message>
+ <source>Confirming (%1 of %2 recommended confirmations)</source>
+ <translation>Потвърждаване (%1 от %2 препоръчвани потвърждения)</translation>
+ </message>
+ <message>
+ <source>Conflicted</source>
+ <translation>Конфликтно</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Получени</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>Получен от</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Изпратени на</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>Плащане към себе си</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Емитирани</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(n/a)</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>Състояние на транзакцията. Задръжте върху това поле за брой потвърждения.</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Дата и час на получаване на транзакцията.</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>Вид транзакция.</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>Сума извадена или добавена към баланса.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>Всички</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>Днес</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>Тази седмица</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>Този месец</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>Предния месец</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>Тази година</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>От - до...</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Получени</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Изпратени на</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>Собствени</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Емитирани</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>Други</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>Търсене по адрес или име</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>Минимална сума</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Копирай адрес</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Копирай име</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Копирай сума</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Копирай транзакция с ID</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>Редактирай име</translation>
+ </message>
+ <message>
+ <source>Show transaction details</source>
+ <translation>Подробности за транзакцията</translation>
+ </message>
+ <message>
+ <source>Export Transaction History</source>
+ <translation>Изнасяне историята на транзакциите</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Грешка при изнасянето</translation>
+ </message>
+ <message>
+ <source>Exporting Successful</source>
+ <translation>Изнасянето е успешна</translation>
+ </message>
+ <message>
+ <source>The transaction history was successfully saved to %1.</source>
+ <translation>Историята с транзакциите беше успешно запазена в %1.</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>CSV файл (*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Потвърдени</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Дата</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Тип</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Име</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Адрес</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>ИД</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>От:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>до</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ </context>
+<context>
+ <name>WalletFrame</name>
+ <message>
+ <source>No wallet has been loaded.</source>
+ <translation>Няма зареден портфейл.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Изпращане</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>Изнеси</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Запишете данните от текущия раздел във файл</translation>
+ </message>
+ <message>
+ <source>Backup Wallet</source>
+ <translation>Запазване на портфейла</translation>
+ </message>
+ <message>
+ <source>Wallet Data (*.dat)</source>
+ <translation>Информация за портфейла (*.dat)</translation>
+ </message>
+ <message>
+ <source>Backup Failed</source>
+ <translation>Неуспешно запазване на портфейла</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the wallet data to %1.</source>
+ <translation>Възникна грешка при запазването на информацията за портфейла в %1.</translation>
+ </message>
+ <message>
+ <source>The wallet data was successfully saved to %1.</source>
+ <translation>Информацията за портфейла беше успешно запазена в %1.</translation>
+ </message>
+ <message>
+ <source>Backup Successful</source>
+ <translation>Успешно запазване на портфейла</translation>
+ </message>
+</context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>Опции:</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>Определете директория за данните</translation>
+ </message>
+ <message>
+ <source>Connect to a node to retrieve peer addresses, and disconnect</source>
+ <translation>Свържете се към сървър за да можете да извлечете адресите на пиърите след което се разкачете.</translation>
+ </message>
+ <message>
+ <source>Specify your own public address</source>
+ <translation>Въведете Ваш публичен адрес</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>Използвайте тестовата мрежа</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
+ <translation>Приемайте връзки отвън.(по подразбиране:1 в противен случай -proxy или -connect)</translation>
+ </message>
+ <message>
+ <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>Внимание: -paytxfee е с мното голяма зададена стойност! Това е транзакционната такса, която ще платите ако направите транзакция.</translation>
+ </message>
+ <message>
+ <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source>
+ <translation>Сложете в бял списък пиъри,свързващи се от дадената интернет маска или айпи адрес.Може да бъде заложено неколкократно.</translation>
+ </message>
+ <message>
+ <source>(default: 1)</source>
+ <translation>(по подразбиране 1)</translation>
+ </message>
+ <message>
+ <source>&lt;category&gt; can be:</source>
+ <translation>&lt;category&gt; може да бъде:</translation>
+ </message>
+ <message>
+ <source>Connection options:</source>
+ <translation>Настройки на връзката:</translation>
+ </message>
+ <message>
+ <source>Do you want to rebuild the block database now?</source>
+ <translation>Желаете ли да пресъздадете базата данни с блокове сега?</translation>
+ </message>
+ <message>
+ <source>Error initializing block database</source>
+ <translation>Грешка в пускането на базата данни с блокове</translation>
+ </message>
+ <message>
+ <source>Error: Disk space is low!</source>
+ <translation>Грешка: мястото на диска е малко!</translation>
+ </message>
+ <message>
+ <source>Failed to listen on any port. Use -listen=0 if you want this.</source>
+ <translation>Провалено "слушане" на всеки порт. Използвайте -listen=0 ако искате това.</translation>
+ </message>
+ <message>
+ <source>Importing...</source>
+ <translation>Внасяне...</translation>
+ </message>
+ <message>
+ <source>Verifying blocks...</source>
+ <translation>Проверка на блоковете...</translation>
+ </message>
+ <message>
+ <source>Verifying wallet...</source>
+ <translation>Проверка на портфейла...</translation>
+ </message>
+ <message>
+ <source>Wallet options:</source>
+ <translation>Настройки на портфейла:</translation>
+ </message>
+ <message>
+ <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source>
+ <translation>Заложете броя на нишки за генерация на монети ако е включено(-1 = всички ядра, по подразбиране: %d)</translation>
+ </message>
+ <message>
+ <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source>
+ <translation>Внимание: -maxtxfee има много висока стойност! Толкова високи такси могат да бъдат заплатени на една транзакция.</translation>
+ </message>
+ <message>
+ <source>Choose data directory on startup (default: 0)</source>
+ <translation>Изберете директория при стартиране на програмата.( настройка по подразбиране:0)</translation>
+ </message>
+ <message>
+ <source>Connect through SOCKS5 proxy</source>
+ <translation>Свързване чрез SOCKS5 прокси</translation>
+ </message>
+ <message>
+ <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source>
+ <translation>Всички права запазени (C) 2009-%i Доставчиците на Биткойн</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Информация</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -minrelaytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Невалидна сума за -minrelaytxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -mintxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Невалидна сума за -mintxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>Изпрати локализиращата или дебъг информацията към конзолата, вместо файлът debug.log</translation>
+ </message>
+ <message>
+ <source>Set language, for example "de_DE" (default: system locale)</source>
+ <translation>Задаване на език,например "de_DE" (по подразбиране: system locale)</translation>
+ </message>
+ <message>
+ <source>Start minimized</source>
+ <translation>Стартирай минимизирано</translation>
+ </message>
+ <message>
+ <source>This is experimental software.</source>
+ <translation>Това е експериментален софтуер.</translation>
+ </message>
+ <message>
+ <source>Transaction amount too small</source>
+ <translation>Сумата на транзакцията е твърде малка</translation>
+ </message>
+ <message>
+ <source>Transaction amounts must be positive</source>
+ <translation>Сумите на транзакциите трябва да са положителни</translation>
+ </message>
+ <message>
+ <source>Transaction too large</source>
+ <translation>Транзакцията е твърде голяма</translation>
+ </message>
+ <message>
+ <source>Username for JSON-RPC connections</source>
+ <translation>Потребителско име за JSON-RPC връзките</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Предупреждение</translation>
+ </message>
+ <message>
+ <source>on startup</source>
+ <translation>по време на стартирането</translation>
+ </message>
+ <message>
+ <source>Password for JSON-RPC connections</source>
+ <translation>Парола за JSON-RPC връзките</translation>
+ </message>
+ <message>
+ <source>Upgrade wallet to latest format</source>
+ <translation>Обновяване на портфейла до най-новия формат</translation>
+ </message>
+ <message>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>Повторно сканиране на блок-връзка за липсващи портфейлни транзакции</translation>
+ </message>
+ <message>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>Използвайте OpenSSL (https) за JSON-RPC връзките</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>Това помощно съобщение</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>Зареждане на адреси...</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>Грешка при зареждане на wallet.dat: портфейлът е повреден</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>Грешка при зареждане на wallet.dat</translation>
+ </message>
+ <message>
+ <source>Invalid -proxy address: '%s'</source>
+ <translation>Невалиден -proxy address: '%s'</translation>
+ </message>
+ <message>
+ <source>Specify configuration file (default: %s)</source>
+ <translation>Назовете конфигурационен файл(по подразбиране %s)</translation>
+ </message>
+ <message>
+ <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source>
+ <translation>Задайте време на изключване при проблеми със свързването в милисекунди(минимум:1, по подразбиране %d)</translation>
+ </message>
+ <message>
+ <source>Specify pid file (default: %s)</source>
+ <translation>Задайте pid файл(по подразбиране: %s)</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Невалидна сума за -paytxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>Недостатъчно средства</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>Зареждане на блок индекса...</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>Зареждане на портфейла...</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>Преразглеждане на последовтелността от блокове...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>Зареждането е завършено</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Грешка</translation>
+ </message>
+</context>
+</TS> \ No newline at end of file
diff --git a/src/qt/locale/bitcoin_bs.ts b/src/qt/locale/bitcoin_bs.ts
new file mode 100644
index 0000000000..86526022fe
--- /dev/null
+++ b/src/qt/locale/bitcoin_bs.ts
@@ -0,0 +1,166 @@
+<TS language="bs" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ </context>
+<context>
+ <name>AddressTableModel</name>
+ </context>
+<context>
+ <name>AskPassphraseDialog</name>
+ </context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Jezrga</translation>
+ </message>
+ </context>
+<context>
+ <name>ClientModel</name>
+ </context>
+<context>
+ <name>CoinControlDialog</name>
+ </context>
+<context>
+ <name>EditAddressDialog</name>
+ </context>
+<context>
+ <name>FreespaceChecker</name>
+ </context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Jezrga</translation>
+ </message>
+ </context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Jezrga</translation>
+ </message>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ </context>
+<context>
+ <name>OptionsDialog</name>
+ </context>
+<context>
+ <name>OverviewPage</name>
+ </context>
+<context>
+ <name>PaymentServer</name>
+ </context>
+<context>
+ <name>PeerTableModel</name>
+ </context>
+<context>
+ <name>QObject</name>
+ </context>
+<context>
+ <name>QRImageWidget</name>
+ </context>
+<context>
+ <name>RPCConsole</name>
+ </context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ </context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ </context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ </context>
+<context>
+ <name>SendCoinsDialog</name>
+ </context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ </context>
+<context>
+ <name>ShutdownWindow</name>
+ </context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ </context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Jezrga</translation>
+ </message>
+ </context>
+<context>
+ <name>TrafficGraphWidget</name>
+ </context>
+<context>
+ <name>TransactionDesc</name>
+ </context>
+<context>
+ <name>TransactionDescDialog</name>
+ </context>
+<context>
+ <name>TransactionTableModel</name>
+ </context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>Sve</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>Danas</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>Ovaj mjesec</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>Prošli mjesec</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>Ove godine</translation>
+ </message>
+ </context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ </context>
+<context>
+ <name>WalletFrame</name>
+ </context>
+<context>
+ <name>WalletModel</name>
+ </context>
+<context>
+ <name>WalletView</name>
+ </context>
+<context>
+ <name>bitcoin-core</name>
+ </context>
+</TS> \ No newline at end of file
diff --git a/src/qt/locale/bitcoin_ca.ts b/src/qt/locale/bitcoin_ca.ts
new file mode 100644
index 0000000000..b89faf0672
--- /dev/null
+++ b/src/qt/locale/bitcoin_ca.ts
@@ -0,0 +1,3575 @@
+<TS language="ca" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Right-click to edit address or label</source>
+ <translation>Feu clic dret per a editar l'adreça o l'etiqueta</translation>
+ </message>
+ <message>
+ <source>Create a new address</source>
+ <translation>Crea una nova adreça</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>&amp;Nova</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Copia l'adreça seleccionada al porta-retalls del sistema</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>&amp;Copia</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>&amp;Tanca</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>&amp;Copia l'adreça</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>Elimina l'adreça sel·leccionada actualment de la llista</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Exporta les dades de la pestanya actual a un fitxer</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Exporta</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;Elimina</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>Trieu una adreça on voleu enviar monedes</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>Trieu l'adreça on voleu rebre monedes</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>T&amp;ria</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>S'estan enviant les adreces</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>S'estan rebent les adreces</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>Aquestes són les vostres adreces de Bitcoin per enviar els pagaments. Sempre reviseu l'import i l'adreça del destinatari abans de transferir monedes.</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>Aquestes són les vostres adreces Bitcoin per rebre pagaments. Es recomana utilitzar una adreça nova de recepció per a cada transacció.</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>Copia l'&amp;etiqueta</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>&amp;Edita</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>Exporta la llista d'adreces</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Fitxer de separació amb comes (*.csv)</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>L'exportació ha fallat</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the address list to %1. Please try again.</source>
+ <translation>S'ha produït un error en desar la llista d'adreces a %1. Torneu-ho a provar.</translation>
+ </message>
+</context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Etiqueta</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adreça</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(sense etiqueta)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Passphrase Dialog</source>
+ <translation>Diàleg de contrasenya</translation>
+ </message>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Introduïu una contrasenya</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Nova contrasenya</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Repetiu la nova contrasenya</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>Encripta el moneder</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>Aquesta operació requereix la contrasenya del moneder per a desbloquejar-lo.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Desbloqueja el moneder</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>Aquesta operació requereix la contrasenya del moneder per desencriptar-lo.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>Desencripta el moneder</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>Canvia la contrasenya</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>Confirma l'encriptació del moneder</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>Avís: si encripteu el vostre moneder i perdeu la contrasenya, &lt;b&gt;PERDREU TOTS ELS VOSTRES BITCOINS&lt;/b&gt;!</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>Esteu segur que voleu encriptar el vostre moneder?</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core 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.</source>
+ <translation>Ara es tancarà el Bitcoin Core per finalitzar el procés d'encriptació. Tingueu present que encriptar el vostre moneder no garanteix que les vostres bitcoins no puguin ser robades per programari maliciós que infecti l'ordinador.</translation>
+ </message>
+ <message>
+ <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
+ <translation>IMPORTANT: Tota copia de seguretat que hàgiu realitzat hauria de ser reemplaçada pel, recentment generat, fitxer encriptat del moneder.</translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>Avís: Les lletres majúscules estan activades!</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>Moneder encriptat</translation>
+ </message>
+ <message>
+ <source>Enter the new passphrase to the wallet.&lt;br/&gt;Please use a passphrase of &lt;b&gt;ten or more random characters&lt;/b&gt;, or &lt;b&gt;eight or more words&lt;/b&gt;.</source>
+ <translation>Introduïu la contrasenya nova al moneder.&lt;br/&gt;Utilitzeu una contrasenya de &lt;b&gt;deu o més caràcters aleatoris&lt;/b&gt;, o &lt;b&gt;vuit o més paraules&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>Enter the old passphrase and new passphrase to the wallet.</source>
+ <translation>Introduïu la contrasenya antiga i la contrasenya nova al moneder.</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>L'encriptació del moneder ha fallat</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>L'encriptació del moneder ha fallat per un error intern. El moneder no ha estat encriptat.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>La contrasenya introduïda no coincideix.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>El desbloqueig del moneder ha fallat</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>La contrasenya introduïda per a desencriptar el moneder és incorrecta.</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>La desencriptació del moneder ha fallat</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>La contrasenya del moneder ha estat modificada correctament.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>Signa el &amp;missatge...</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>S'està sincronitzant amb la xarxa ...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;Panorama general</translation>
+ </message>
+ <message>
+ <source>Node</source>
+ <translation>Node</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>Mostra el panorama general del moneder</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Transaccions</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>Cerca a l'historial de transaccions</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>S&amp;urt</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>Surt de l'aplicació</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>Quant a &amp;Qt</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>Mostra informació sobre Qt</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;Opcions...</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>&amp;Encripta el moneder...</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>&amp;Realitza una còpia de seguretat del moneder...</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>&amp;Canvia la contrasenya...</translation>
+ </message>
+ <message>
+ <source>&amp;Sending addresses...</source>
+ <translation>Adreces d'e&amp;nviament...</translation>
+ </message>
+ <message>
+ <source>&amp;Receiving addresses...</source>
+ <translation>Adreces de &amp;recepció</translation>
+ </message>
+ <message>
+ <source>Open &amp;URI...</source>
+ <translation>Obre un &amp;URI...</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core client</source>
+ <translation>Client del Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Importing blocks from disk...</source>
+ <translation>S'estan important els blocs del disc...</translation>
+ </message>
+ <message>
+ <source>Reindexing blocks on disk...</source>
+ <translation>S'estan reindexant els blocs al disc...</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>Envia monedes a una adreça Bitcoin</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>Realitza una còpia de seguretat del moneder a una altra ubicació</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Canvia la contrasenya d'encriptació del moneder</translation>
+ </message>
+ <message>
+ <source>&amp;Debug window</source>
+ <translation>&amp;Finestra de depuració</translation>
+ </message>
+ <message>
+ <source>Open debugging and diagnostic console</source>
+ <translation>Obre la consola de diagnòstic i depuració</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>&amp;Verifica el missatge...</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>Moneder</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>&amp;Envia</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>&amp;Rep</translation>
+ </message>
+ <message>
+ <source>Show information about Bitcoin Core</source>
+ <translation>Mostra informació del Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>&amp;Mostra / Amaga</translation>
+ </message>
+ <message>
+ <source>Show or hide the main Window</source>
+ <translation>Mostra o amaga la finestra principal</translation>
+ </message>
+ <message>
+ <source>Encrypt the private keys that belong to your wallet</source>
+ <translation>Encripta les claus privades pertanyents al moneder</translation>
+ </message>
+ <message>
+ <source>Sign messages with your Bitcoin addresses to prove you own them</source>
+ <translation>Signa el missatges amb la seva adreça de Bitcoin per provar que les poseeixes</translation>
+ </message>
+ <message>
+ <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source>
+ <translation>Verifiqueu els missatges per assegurar-vos que han estat signats amb una adreça Bitcoin específica.</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;Fitxer</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;Configuració</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>&amp;Ajuda</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>Barra d'eines de les pestanyes</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Nucli de Bitcoin</translation>
+ </message>
+ <message>
+ <source>Request payments (generates QR codes and bitcoin: URIs)</source>
+ <translation>Sol·licita pagaments (genera codis QR i bitcoin: URI)</translation>
+ </message>
+ <message>
+ <source>&amp;About Bitcoin Core</source>
+ <translation>&amp;Quant al Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Modify configuration options for Bitcoin Core</source>
+ <translation>Modifica les opcions de configuració del Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Show the list of used sending addresses and labels</source>
+ <translation>Mostra la llista d'adreces d'enviament i etiquetes utilitzades</translation>
+ </message>
+ <message>
+ <source>Show the list of used receiving addresses and labels</source>
+ <translation>Mostra la llista d'adreces de recepció i etiquetes utilitzades</translation>
+ </message>
+ <message>
+ <source>Open a bitcoin: URI or payment request</source>
+ <translation>Obre una bitcoin: sol·licitud d'URI o pagament</translation>
+ </message>
+ <message>
+ <source>&amp;Command-line options</source>
+ <translation>Opcions de la &amp;línia d'ordres</translation>
+ </message>
+ <message>
+ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
+ <translation>Mostra el missatge d'ajuda del Bitcoin Core per obtenir una llista amb les possibles opcions de línia d'ordres de Bitcoin</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n active connection(s) to Bitcoin network</source>
+ <translation><numerusform>%n connexió activa a la xarxa Bitcoin</numerusform><numerusform>%n connexions actives a la xarxa Bitcoin</numerusform></translation>
+ </message>
+ <message>
+ <source>No block source available...</source>
+ <translation>No hi ha cap font de bloc disponible...</translation>
+ </message>
+ <message numerus="yes">
+ <source>Processed %n block(s) of transaction history.</source>
+ <translation><numerusform>S'han processat %n bloc de l'historial de transacció.</numerusform><numerusform>S'han processat %n blocs de l'historial de transacció.</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n hour(s)</source>
+ <translation><numerusform>%n hora</numerusform><numerusform>%n hores</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n day(s)</source>
+ <translation><numerusform>%n dia</numerusform><numerusform>%n dies</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n week(s)</source>
+ <translation><numerusform>%n setmana</numerusform><numerusform>%n setmanes</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 and %2</source>
+ <translation>%1 i %2</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n year(s)</source>
+ <translation><numerusform>%n any</numerusform><numerusform>%n anys</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 behind</source>
+ <translation>%1 darrere</translation>
+ </message>
+ <message>
+ <source>Last received block was generated %1 ago.</source>
+ <translation>El darrer bloc rebut ha estat generat fa %1.</translation>
+ </message>
+ <message>
+ <source>Transactions after this will not yet be visible.</source>
+ <translation>Les transaccions a partir d'això no seran visibles.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Error</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Avís</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Informació</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>Al dia</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>S'està posant al dia ...</translation>
+ </message>
+ <message>
+ <source>Date: %1
+</source>
+ <translation>Data: %1
+</translation>
+ </message>
+ <message>
+ <source>Amount: %1
+</source>
+ <translation>Import: %1
+</translation>
+ </message>
+ <message>
+ <source>Type: %1
+</source>
+ <translation>Tipus: %1
+</translation>
+ </message>
+ <message>
+ <source>Label: %1
+</source>
+ <translation>Etiqueta: %1
+</translation>
+ </message>
+ <message>
+ <source>Address: %1
+</source>
+ <translation>Adreça: %1
+</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>Transacció enviada</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>Transacció entrant</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>El moneder està &lt;b&gt;encriptat&lt;/b&gt; i actualment &lt;b&gt;desbloquejat&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>El moneder està &lt;b&gt;encriptat&lt;/b&gt; i actualment &lt;b&gt;bloquejat&lt;/b&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <source>Network Alert</source>
+ <translation>Alerta de xarxa</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Coin Selection</source>
+ <translation>Selecció de moneda</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Quantitat:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Bytes:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Import:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Prioritat:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Comissió</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Polsim:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Comissió posterior:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Canvi:</translation>
+ </message>
+ <message>
+ <source>(un)select all</source>
+ <translation>(des)selecciona-ho tot</translation>
+ </message>
+ <message>
+ <source>Tree mode</source>
+ <translation>Mode arbre</translation>
+ </message>
+ <message>
+ <source>List mode</source>
+ <translation>Mode llista</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Import</translation>
+ </message>
+ <message>
+ <source>Received with label</source>
+ <translation>Rebut amb l'etiqueta</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>Rebut amb l'adreça</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Confirmations</source>
+ <translation>Confirmacions</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Confirmat</translation>
+ </message>
+ <message>
+ <source>Priority</source>
+ <translation>Prioritat</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Copiar adreça </translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Copiar etiqueta</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copia l'import</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Copiar ID de transacció</translation>
+ </message>
+ <message>
+ <source>Lock unspent</source>
+ <translation>Bloqueja sense gastar</translation>
+ </message>
+ <message>
+ <source>Unlock unspent</source>
+ <translation>Desbloqueja sense gastar</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Copia la quantitat</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Copia la comissió</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Copia la comissió posterior</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Copia els bytes</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Copia la prioritat</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Copia el polsim</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Copia el canvi</translation>
+ </message>
+ <message>
+ <source>highest</source>
+ <translation>El més alt</translation>
+ </message>
+ <message>
+ <source>higher</source>
+ <translation>Més alt</translation>
+ </message>
+ <message>
+ <source>high</source>
+ <translation>Alt</translation>
+ </message>
+ <message>
+ <source>medium-high</source>
+ <translation>mig-alt</translation>
+ </message>
+ <message>
+ <source>medium</source>
+ <translation>mig</translation>
+ </message>
+ <message>
+ <source>low-medium</source>
+ <translation>baix-mig</translation>
+ </message>
+ <message>
+ <source>low</source>
+ <translation>baix</translation>
+ </message>
+ <message>
+ <source>lower</source>
+ <translation>més baix</translation>
+ </message>
+ <message>
+ <source>lowest</source>
+ <translation>el més baix</translation>
+ </message>
+ <message>
+ <source>(%1 locked)</source>
+ <translation>(%1 bloquejada)</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>cap</translation>
+ </message>
+ <message>
+ <source>This label turns red if the transaction size is greater than 1000 bytes.</source>
+ <translation>Aquesta etiqueta es torna en vermell si la transacció és superior a 1000 bytes.</translation>
+ </message>
+ <message>
+ <source>This label turns red if the priority is smaller than "medium".</source>
+ <translation>Aquesta etiqueta es torna en vermell si la propietat és inferior que la «mitjana».</translation>
+ </message>
+ <message>
+ <source>This label turns red if any recipient receives an amount smaller than %1.</source>
+ <translation>Aquesta etiqueta es torna vermella si el destinatari rep un import inferior de %1.</translation>
+ </message>
+ <message>
+ <source>Can vary +/- %1 satoshi(s) per input.</source>
+ <translation>Pot variar +/- %1 satoshi(s) per entrada.</translation>
+ </message>
+ <message>
+ <source>yes</source>
+ <translation>sí</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>no</translation>
+ </message>
+ <message>
+ <source>This means a fee of at least %1 per kB is required.</source>
+ <translation>Això comporta una comissió d'almenys %1 per kB.</translation>
+ </message>
+ <message>
+ <source>Can vary +/- 1 byte per input.</source>
+ <translation>Pot variar +/- 1 byte per entrada.</translation>
+ </message>
+ <message>
+ <source>Transactions with higher priority are more likely to get included into a block.</source>
+ <translation>Les transaccions amb una major prioritat són més propenses a ser incloses en un bloc.</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(sense etiqueta)</translation>
+ </message>
+ <message>
+ <source>change from %1 (%2)</source>
+ <translation>canvia de %1 (%2)</translation>
+ </message>
+ <message>
+ <source>(change)</source>
+ <translation>(canvia)</translation>
+ </message>
+</context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>Edita l'adreça</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>&amp;Etiqueta</translation>
+ </message>
+ <message>
+ <source>The label associated with this address list entry</source>
+ <translation>L'etiqueta associada amb aquesta entrada de llista d'adreces</translation>
+ </message>
+ <message>
+ <source>The address associated with this address list entry. This can only be modified for sending addresses.</source>
+ <translation>L'adreça associada amb aquesta entrada de llista d'adreces. Només es pot modificar per a les adreces d'enviament.</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;Adreça</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>Nova adreça de recepció.</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>Nova adreça d'enviament</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>Edita les adreces de recepció</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>Edita les adreces d'enviament</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>L'adreça introduïda «%1» ja és present a la llibreta d'adreces.</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is not a valid Bitcoin address.</source>
+ <translation>L'adreça introduïda «%1» no és una adreça de Bitcoin vàlida.</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>No s'ha pogut desbloquejar el moneder.</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>Ha fallat la generació d'una nova clau.</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ <message>
+ <source>A new data directory will be created.</source>
+ <translation>Es crearà un nou directori de dades.</translation>
+ </message>
+ <message>
+ <source>name</source>
+ <translation>nom</translation>
+ </message>
+ <message>
+ <source>Directory already exists. Add %1 if you intend to create a new directory here.</source>
+ <translation>El directori ja existeix. Afegeix %1 si vols crear un nou directori en aquesta ubicació.</translation>
+ </message>
+ <message>
+ <source>Path already exists, and is not a directory.</source>
+ <translation>El camí ja existeix i no és cap directori.</translation>
+ </message>
+ <message>
+ <source>Cannot create data directory here.</source>
+ <translation>No es pot crear el directori de dades aquí.</translation>
+ </message>
+</context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Nucli de Bitcoin</translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>versió</translation>
+ </message>
+ <message>
+ <source>(%1-bit)</source>
+ <translation>(%1-bit)</translation>
+ </message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>Quant al Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Command-line options</source>
+ <translation>Opcions de línia d'ordres</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>Ús:</translation>
+ </message>
+ <message>
+ <source>command-line options</source>
+ <translation>Opcions de la línia d'ordres</translation>
+ </message>
+</context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Welcome</source>
+ <translation>Us donem la benviguda</translation>
+ </message>
+ <message>
+ <source>Welcome to Bitcoin Core.</source>
+ <translation>Us donem la benvinguda al Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</source>
+ <translation>Atès que és la primera vegada que executeu el programa, podeu triar on emmagatzemarà el Bitcoin Core les dades.</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory.</source>
+ <translation>El Bitcoin Core descarregarà i emmagatzemarà una còpia de la cadena de blocs de Bitcoin. Com a mínim s'emmagatzemaran %1 GB de dades en aquest directori, que seguiran creixent gradualment. També s'hi emmagatzemarà el moneder.</translation>
+ </message>
+ <message>
+ <source>Use the default data directory</source>
+ <translation>Utilitza el directori de dades per defecte</translation>
+ </message>
+ <message>
+ <source>Use a custom data directory:</source>
+ <translation>Utilitza un directori de dades personalitzat:</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Nucli de Bitcoin</translation>
+ </message>
+ <message>
+ <source>Error: Specified data directory "%1" cannot be created.</source>
+ <translation>Error: el directori de dades «%1» especificat no pot ser creat.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Error</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n GB of free space available</source>
+ <translation><numerusform>%n GB d'espai lliure disponible</numerusform><numerusform>%n GB d'espai lliure disponible</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>(of %n GB needed)</source>
+ <translation><numerusform>(de %n GB necessari)</numerusform><numerusform>(de %n GB necessaris)</numerusform></translation>
+ </message>
+</context>
+<context>
+ <name>OpenURIDialog</name>
+ <message>
+ <source>Open URI</source>
+ <translation>Obre un URI</translation>
+ </message>
+ <message>
+ <source>Open payment request from URI or file</source>
+ <translation>Obre una sol·licitud de pagament des d'un URI o un fitxer</translation>
+ </message>
+ <message>
+ <source>URI:</source>
+ <translation>URI:</translation>
+ </message>
+ <message>
+ <source>Select payment request file</source>
+ <translation>Selecciona un fitxer de sol·licitud de pagament</translation>
+ </message>
+ <message>
+ <source>Select payment request file to open</source>
+ <translation>Selecciona el fitxer de sol·licitud de pagament per obrir</translation>
+ </message>
+</context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>Opcions</translation>
+ </message>
+ <message>
+ <source>&amp;Main</source>
+ <translation>&amp;Principal</translation>
+ </message>
+ <message>
+ <source>Size of &amp;database cache</source>
+ <translation>Mida de la memòria cau de la base de &amp;dades</translation>
+ </message>
+ <message>
+ <source>MB</source>
+ <translation>MB</translation>
+ </message>
+ <message>
+ <source>Number of script &amp;verification threads</source>
+ <translation>Nombre de fils de &amp;verificació d'scripts</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside</source>
+ <translation>Accepta connexions de fora</translation>
+ </message>
+ <message>
+ <source>Allow incoming connections</source>
+ <translation>Permet connexions entrants</translation>
+ </message>
+ <message>
+ <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
+ <translation>Adreça IP del proxy (p. ex. IPv4: 127.0.0.1 / IPv6: ::1)</translation>
+ </message>
+ <message>
+ <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source>
+ <translation>Minimitza en comptes de sortir de l'aplicació quan la finestra es tanca. Quan s'habilita aquesta opció l'aplicació es tancara només quan se selecciona Surt del menú. </translation>
+ </message>
+ <message>
+ <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source>
+ <translation>La interfície d'usuari pot definir-se des d'aquí. El paràmetre tindrà efecte després de reiniciar el Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source>
+ <translation>URL de terceres parts (p. ex. explorador de blocs) que apareix en la pestanya de transaccions com elements del menú contextual. %s en l'URL es reemplaçat pel resum de la transacció. Diferents URL estan separades per una barra vertical |.</translation>
+ </message>
+ <message>
+ <source>Third party transaction URLs</source>
+ <translation>URL de transaccions de terceres parts</translation>
+ </message>
+ <message>
+ <source>Active command-line options that override above options:</source>
+ <translation>Opcions de línies d'ordre active que sobreescriuen les opcions de dalt:</translation>
+ </message>
+ <message>
+ <source>Reset all client options to default.</source>
+ <translation>Reestableix totes les opcions del client.</translation>
+ </message>
+ <message>
+ <source>&amp;Reset Options</source>
+ <translation>&amp;Reestableix les opcions</translation>
+ </message>
+ <message>
+ <source>&amp;Network</source>
+ <translation>&amp;Xarxa</translation>
+ </message>
+ <message>
+ <source>Automatically start Bitcoin Core after logging in to the system.</source>
+ <translation>Inicia el Bitcoin Core automàticament després d'iniciar una sessió en el sistema.</translation>
+ </message>
+ <message>
+ <source>&amp;Start Bitcoin Core on system login</source>
+ <translation>&amp;Inicia el Bitcoin Core en inciar el sistema</translation>
+ </message>
+ <message>
+ <source>(0 = auto, &lt;0 = leave that many cores free)</source>
+ <translation>(0 = auto, &lt;0 = deixa tants nuclis lliures)</translation>
+ </message>
+ <message>
+ <source>W&amp;allet</source>
+ <translation>&amp;Moneder</translation>
+ </message>
+ <message>
+ <source>Expert</source>
+ <translation>Expert</translation>
+ </message>
+ <message>
+ <source>Enable coin &amp;control features</source>
+ <translation>Activa les funcions de &amp;control de les monedes</translation>
+ </message>
+ <message>
+ <source>If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.</source>
+ <translation>Si inhabiliteu la despesa d'un canvi sense confirmar, el canvi d'una transacció no pot ser utilitzat fins que la transacció no tingui com a mínim una confirmació. Això també afecta com es calcula el vostre balanç.</translation>
+ </message>
+ <message>
+ <source>&amp;Spend unconfirmed change</source>
+ <translation>&amp;Gasta el canvi sense confirmar</translation>
+ </message>
+ <message>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>Obre el port del client de Bitcoin al router de forma automàtica. Això només funciona quan el router implementa UPnP i l'opció està activada.</translation>
+ </message>
+ <message>
+ <source>Map port using &amp;UPnP</source>
+ <translation>Port obert amb &amp;UPnP</translation>
+ </message>
+ <message>
+ <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
+ <translation>Connecta a la xarxa Bitcoin a través d'un proxy SOCKS5.</translation>
+ </message>
+ <message>
+ <source>&amp;Connect through SOCKS5 proxy (default proxy):</source>
+ <translation>&amp;Connecta a través d'un proxy SOCKS5 (proxy per defecte):</translation>
+ </message>
+ <message>
+ <source>Proxy &amp;IP:</source>
+ <translation>&amp;IP del proxy:</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>&amp;Port:</translation>
+ </message>
+ <message>
+ <source>Port of the proxy (e.g. 9050)</source>
+ <translation>Port del proxy (per exemple 9050)</translation>
+ </message>
+ <message>
+ <source>&amp;Window</source>
+ <translation>&amp;Finestra</translation>
+ </message>
+ <message>
+ <source>Show only a tray icon after minimizing the window.</source>
+ <translation>Mostra només la icona de la barra en minimitzar la finestra.</translation>
+ </message>
+ <message>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>&amp;Minimitza a la barra d'aplicacions en comptes de la barra de tasques</translation>
+ </message>
+ <message>
+ <source>M&amp;inimize on close</source>
+ <translation>M&amp;inimitza en tancar</translation>
+ </message>
+ <message>
+ <source>&amp;Display</source>
+ <translation>&amp;Pantalla</translation>
+ </message>
+ <message>
+ <source>User Interface &amp;language:</source>
+ <translation>&amp;Llengua de la interfície d'usuari:</translation>
+ </message>
+ <message>
+ <source>&amp;Unit to show amounts in:</source>
+ <translation>&amp;Unitats per mostrar els imports en:</translation>
+ </message>
+ <message>
+ <source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
+ <translation>Selecciona la unitat de subdivisió per defecte per mostrar en la interfície quan s'envien monedes.</translation>
+ </message>
+ <message>
+ <source>Whether to show coin control features or not.</source>
+ <translation>Si voleu mostrar les funcions de control de monedes o no.</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>&amp;D'acord</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>&amp;Cancel·la</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>Per defecte</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>cap</translation>
+ </message>
+ <message>
+ <source>Confirm options reset</source>
+ <translation>Confirmeu el reestabliment de les opcions</translation>
+ </message>
+ <message>
+ <source>Client restart required to activate changes.</source>
+ <translation>Cal reiniciar el client per activar els canvis.</translation>
+ </message>
+ <message>
+ <source>Client will be shut down. Do you want to proceed?</source>
+ <translation>S'aturarà el client. Voleu procedir?</translation>
+ </message>
+ <message>
+ <source>This change would require a client restart.</source>
+ <translation>Amb aquest canvi cal un reinici del client.</translation>
+ </message>
+ <message>
+ <source>The supplied proxy address is invalid.</source>
+ <translation>L'adreça proxy introduïda és invalida.</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>Formulari</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>La informació mostrada pot no estar al día. El teu moneder es sincronitza automàticament amb la xarxa Bitcoin un cop s'ha establert connexió, però aquest proces no s'ha completat encara.</translation>
+ </message>
+ <message>
+ <source>Watch-only:</source>
+ <translation>Només lectura:</translation>
+ </message>
+ <message>
+ <source>Available:</source>
+ <translation>Disponible:</translation>
+ </message>
+ <message>
+ <source>Your current spendable balance</source>
+ <translation>El balanç que podeu gastar actualment</translation>
+ </message>
+ <message>
+ <source>Pending:</source>
+ <translation>Pendent:</translation>
+ </message>
+ <message>
+ <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source>
+ <translation>Total de transaccions que encara han de confirmar-se i que encara no compten en el balanç que es pot gastar</translation>
+ </message>
+ <message>
+ <source>Immature:</source>
+ <translation>Immadur:</translation>
+ </message>
+ <message>
+ <source>Mined balance that has not yet matured</source>
+ <translation>Balanç minat que encara no ha madurat</translation>
+ </message>
+ <message>
+ <source>Balances</source>
+ <translation>Balances</translation>
+ </message>
+ <message>
+ <source>Total:</source>
+ <translation>Total:</translation>
+ </message>
+ <message>
+ <source>Your current total balance</source>
+ <translation>El balanç total actual</translation>
+ </message>
+ <message>
+ <source>Your current balance in watch-only addresses</source>
+ <translation>El vostre balanç actual en adreces de només lectura</translation>
+ </message>
+ <message>
+ <source>Spendable:</source>
+ <translation>Que es pot gastar:</translation>
+ </message>
+ <message>
+ <source>Recent transactions</source>
+ <translation>Transaccions recents</translation>
+ </message>
+ <message>
+ <source>Unconfirmed transactions to watch-only addresses</source>
+ <translation>Transaccions sense confirmar a adreces de només lectura</translation>
+ </message>
+ <message>
+ <source>Mined balance in watch-only addresses that has not yet matured</source>
+ <translation>Balanç minat en adreces de només lectura que encara no ha madurat</translation>
+ </message>
+ <message>
+ <source>Current total balance in watch-only addresses</source>
+ <translation>Balanç total actual en adreces de només lectura</translation>
+ </message>
+</context>
+<context>
+ <name>PaymentServer</name>
+ <message>
+ <source>URI handling</source>
+ <translation>Gestió d'URI</translation>
+ </message>
+ <message>
+ <source>Invalid payment address %1</source>
+ <translation>Adreça de pagament no vàlida %1</translation>
+ </message>
+ <message>
+ <source>Payment request rejected</source>
+ <translation>La sol·licitud de pagament s'ha rebutjat</translation>
+ </message>
+ <message>
+ <source>Payment request network doesn't match client network.</source>
+ <translation>La xarxa de la sol·licitud de pagament no coincideix amb la xarxa del client.</translation>
+ </message>
+ <message>
+ <source>Payment request is not initialized.</source>
+ <translation>La sol·licitud de pagament no està inicialitzada.</translation>
+ </message>
+ <message>
+ <source>Requested payment amount of %1 is too small (considered dust).</source>
+ <translation>L'import de pagament sol·licitat %1 és massa petit (es considera polsim).</translation>
+ </message>
+ <message>
+ <source>Payment request error</source>
+ <translation>Error en la sol·licitud de pagament</translation>
+ </message>
+ <message>
+ <source>Cannot start bitcoin: click-to-pay handler</source>
+ <translation>No es pot iniciar bitcoin: gestor clica-per-pagar</translation>
+ </message>
+ <message>
+ <source>Payment request fetch URL is invalid: %1</source>
+ <translation>L'URL de recuperació de la sol·licitud de pagament no és vàlida: %1</translation>
+ </message>
+ <message>
+ <source>URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source>
+ <translation>L'URI no pot ser analitzat! Això pot ser a causa d'una adreça de Bitcoin no vàlida o per paràmetres URI amb mal format.</translation>
+ </message>
+ <message>
+ <source>Payment request file handling</source>
+ <translation>Gestió de fitxers de les sol·licituds de pagament</translation>
+ </message>
+ <message>
+ <source>Payment request file cannot be read! This can be caused by an invalid payment request file.</source>
+ <translation>No es pot llegir el fitxer de la sol·licitud de pagament. Això pot ser causat per un fitxer de sol·licitud de pagament no vàlid.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>La sol·licitud de pagament ha vençut.</translation>
+ </message>
+ <message>
+ <source>Unverified payment requests to custom payment scripts are unsupported.</source>
+ <translation>No s'accepten sol·licituds de pagament no verificades a scripts de pagament personalitzats.</translation>
+ </message>
+ <message>
+ <source>Invalid payment request.</source>
+ <translation>Sol·licitud de pagament no vàlida.</translation>
+ </message>
+ <message>
+ <source>Refund from %1</source>
+ <translation>Reemborsament de %1</translation>
+ </message>
+ <message>
+ <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source>
+ <translation>La sol·licitud de pagament %1 és massa gran (%2 bytes, permès %3 bytes).</translation>
+ </message>
+ <message>
+ <source>Payment request DoS protection</source>
+ <translation>Protecció de DoS per a la sol·licitud de pagament</translation>
+ </message>
+ <message>
+ <source>Error communicating with %1: %2</source>
+ <translation>Error en comunicar amb %1: %2</translation>
+ </message>
+ <message>
+ <source>Payment request cannot be parsed!</source>
+ <translation>No es pot analitzar la sol·licitud de pagament!</translation>
+ </message>
+ <message>
+ <source>Bad response from server %1</source>
+ <translation>Mala resposta del servidor %1</translation>
+ </message>
+ <message>
+ <source>Payment acknowledged</source>
+ <translation>Pagament reconegut</translation>
+ </message>
+ <message>
+ <source>Network request error</source>
+ <translation>Error en la sol·licitud de xarxa</translation>
+ </message>
+</context>
+<context>
+ <name>PeerTableModel</name>
+ <message>
+ <source>User Agent</source>
+ <translation>Agent d'usuari</translation>
+ </message>
+ <message>
+ <source>Node/Service</source>
+ <translation>Node/Servei</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Temps de ping</translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>Import</translation>
+ </message>
+ <message>
+ <source>Enter a Bitcoin address (e.g. %1)</source>
+ <translation>Introduïu una adreça de Bitcoin (p. ex. %1)</translation>
+ </message>
+ <message>
+ <source>%1 d</source>
+ <translation>%1 d</translation>
+ </message>
+ <message>
+ <source>%1 h</source>
+ <translation>%1 h</translation>
+ </message>
+ <message>
+ <source>%1 m</source>
+ <translation>%1 m</translation>
+ </message>
+ <message>
+ <source>%1 s</source>
+ <translation>%1 s</translation>
+ </message>
+ <message>
+ <source>None</source>
+ <translation>Cap</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>N/A</translation>
+ </message>
+ <message>
+ <source>%1 ms</source>
+ <translation>%1 ms</translation>
+ </message>
+</context>
+<context>
+ <name>QRImageWidget</name>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>De&amp;sa la imatge...</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Image</source>
+ <translation>&amp;Copia la imatge</translation>
+ </message>
+ <message>
+ <source>Save QR Code</source>
+ <translation>Desa el codi QR</translation>
+ </message>
+ <message>
+ <source>PNG Image (*.png)</source>
+ <translation>Imatge PNG (*.png)</translation>
+ </message>
+</context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>Client name</source>
+ <translation>Nom del client</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>N/A</translation>
+ </message>
+ <message>
+ <source>Client version</source>
+ <translation>Versió del client</translation>
+ </message>
+ <message>
+ <source>&amp;Information</source>
+ <translation>&amp;Informació</translation>
+ </message>
+ <message>
+ <source>Debug window</source>
+ <translation>Finestra de depuració</translation>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>General</translation>
+ </message>
+ <message>
+ <source>Using OpenSSL version</source>
+ <translation>Utilitzant OpenSSL versió</translation>
+ </message>
+ <message>
+ <source>Using BerkeleyDB version</source>
+ <translation>Utilitzant BerkeleyDB versió</translation>
+ </message>
+ <message>
+ <source>Startup time</source>
+ <translation>&amp;Temps d'inici</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Xarxa</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>Nom</translation>
+ </message>
+ <message>
+ <source>Number of connections</source>
+ <translation>Nombre de connexions</translation>
+ </message>
+ <message>
+ <source>Block chain</source>
+ <translation>Cadena de blocs</translation>
+ </message>
+ <message>
+ <source>Current number of blocks</source>
+ <translation>Nombre de blocs actuals</translation>
+ </message>
+ <message>
+ <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source>
+ <translation>Obre el fitxer de registre de depuració del Bitcoin Core del directori de dades actual. Pot portar uns quants segons per a fitxers de registre grans.</translation>
+ </message>
+ <message>
+ <source>Received</source>
+ <translation>Rebut</translation>
+ </message>
+ <message>
+ <source>Sent</source>
+ <translation>Enviat</translation>
+ </message>
+ <message>
+ <source>&amp;Peers</source>
+ <translation>&amp;Iguals</translation>
+ </message>
+ <message>
+ <source>Select a peer to view detailed information.</source>
+ <translation>Seleccioneu un igual per mostrar informació detallada.</translation>
+ </message>
+ <message>
+ <source>Direction</source>
+ <translation>Direcció</translation>
+ </message>
+ <message>
+ <source>Version</source>
+ <translation>Versió</translation>
+ </message>
+ <message>
+ <source>User Agent</source>
+ <translation>Agent d'usuari</translation>
+ </message>
+ <message>
+ <source>Services</source>
+ <translation>Serveis</translation>
+ </message>
+ <message>
+ <source>Starting Height</source>
+ <translation>Alçada inicial</translation>
+ </message>
+ <message>
+ <source>Sync Height</source>
+ <translation>Sincronitza l'alçada</translation>
+ </message>
+ <message>
+ <source>Ban Score</source>
+ <translation>Puntuació de bandeig</translation>
+ </message>
+ <message>
+ <source>Connection Time</source>
+ <translation>Temps de connexió</translation>
+ </message>
+ <message>
+ <source>Last Send</source>
+ <translation>Darrer enviament</translation>
+ </message>
+ <message>
+ <source>Last Receive</source>
+ <translation>Darrera recepció</translation>
+ </message>
+ <message>
+ <source>Bytes Sent</source>
+ <translation>Bytes enviats</translation>
+ </message>
+ <message>
+ <source>Bytes Received</source>
+ <translation>Bytes rebuts</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Temps de ping</translation>
+ </message>
+ <message>
+ <source>Time Offset</source>
+ <translation>Diferència horària</translation>
+ </message>
+ <message>
+ <source>Last block time</source>
+ <translation>Últim temps de bloc</translation>
+ </message>
+ <message>
+ <source>&amp;Open</source>
+ <translation>&amp;Obre</translation>
+ </message>
+ <message>
+ <source>&amp;Console</source>
+ <translation>&amp;Consola</translation>
+ </message>
+ <message>
+ <source>&amp;Network Traffic</source>
+ <translation>Trà&amp;nsit de la xarxa</translation>
+ </message>
+ <message>
+ <source>&amp;Clear</source>
+ <translation>Nete&amp;ja</translation>
+ </message>
+ <message>
+ <source>Totals</source>
+ <translation>Totals</translation>
+ </message>
+ <message>
+ <source>In:</source>
+ <translation>Dins:</translation>
+ </message>
+ <message>
+ <source>Out:</source>
+ <translation>Fora:</translation>
+ </message>
+ <message>
+ <source>Build date</source>
+ <translation>Data de compilació</translation>
+ </message>
+ <message>
+ <source>Debug log file</source>
+ <translation>Fitxer de registre de depuració</translation>
+ </message>
+ <message>
+ <source>Clear console</source>
+ <translation>Neteja la consola</translation>
+ </message>
+ <message>
+ <source>Welcome to the Bitcoin Core RPC console.</source>
+ <translation>Us donem la benviguda a la consola RPC del Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
+ <translation>Utilitza les fletxes d'amunt i avall per navegar per l'historial, i &lt;b&gt;Ctrl-L&lt;\b&gt; per netejar la pantalla.</translation>
+ </message>
+ <message>
+ <source>Type &lt;b&gt;help&lt;/b&gt; for an overview of available commands.</source>
+ <translation>Escriviu &lt;b&gt;help&lt;\b&gt; per a obtenir un llistat de les ordres disponibles.</translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation>%1 B</translation>
+ </message>
+ <message>
+ <source>%1 KB</source>
+ <translation>%1 KB</translation>
+ </message>
+ <message>
+ <source>%1 MB</source>
+ <translation>%1 MB</translation>
+ </message>
+ <message>
+ <source>%1 GB</source>
+ <translation>%1 GB</translation>
+ </message>
+ <message>
+ <source>via %1</source>
+ <translation>a través de %1</translation>
+ </message>
+ <message>
+ <source>never</source>
+ <translation>mai</translation>
+ </message>
+ <message>
+ <source>Inbound</source>
+ <translation>Entrant</translation>
+ </message>
+ <message>
+ <source>Outbound</source>
+ <translation>Sortint</translation>
+ </message>
+ <message>
+ <source>Unknown</source>
+ <translation>Desconegut</translation>
+ </message>
+ <message>
+ <source>Fetching...</source>
+ <translation>S'està obtenint...</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Amount:</source>
+ <translation>Im&amp;port:</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Etiqueta:</translation>
+ </message>
+ <message>
+ <source>&amp;Message:</source>
+ <translation>&amp;Missatge:</translation>
+ </message>
+ <message>
+ <source>Reuse one of the previously used receiving addresses. Reusing addresses has security and privacy issues. Do not use this unless re-generating a payment request made before.</source>
+ <translation>Reutilitza una de les adreces de recepció utilitzades anteriorment. La reutilització d'adreces pot comportar problemes de seguretat i privadesa. No ho utilitzeu llevat que torneu a generar una sol·licitud de pagament feta abans.</translation>
+ </message>
+ <message>
+ <source>R&amp;euse an existing receiving address (not recommended)</source>
+ <translation>R&amp;eutilitza una adreça de recepció anterior (no recomanat)</translation>
+ </message>
+ <message>
+ <source>An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network.</source>
+ <translation>Un missatge opcional que s'adjuntarà a la sol·licitud de pagament, que es mostrarà quan s'obri la sol·licitud. Nota: El missatge no s'enviarà amb el pagament per la xarxa Bitcoin.</translation>
+ </message>
+ <message>
+ <source>An optional label to associate with the new receiving address.</source>
+ <translation>Una etiqueta opcional que s'associarà amb la nova adreça receptora.</translation>
+ </message>
+ <message>
+ <source>Use this form to request payments. All fields are &lt;b&gt;optional&lt;/b&gt;.</source>
+ <translation>Utilitzeu aquest formulari per sol·licitar pagaments. Tots els camps són &lt;b&gt;opcionals&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>An optional amount to request. Leave this empty or zero to not request a specific amount.</source>
+ <translation>Un import opcional per sol·licitar. Deixeu-ho en blanc o zero per no sol·licitar cap import específic.</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Esborra tots els camps del formuari.</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation>Neteja</translation>
+ </message>
+ <message>
+ <source>Requested payments history</source>
+ <translation>Historial de pagaments sol·licitats</translation>
+ </message>
+ <message>
+ <source>&amp;Request payment</source>
+ <translation>&amp;Sol·licitud de pagament</translation>
+ </message>
+ <message>
+ <source>Show the selected request (does the same as double clicking an entry)</source>
+ <translation>Mostra la sol·licitud seleccionada (fa el mateix que el doble clic a una entrada)</translation>
+ </message>
+ <message>
+ <source>Show</source>
+ <translation>Mostra</translation>
+ </message>
+ <message>
+ <source>Remove the selected entries from the list</source>
+ <translation>Esborra les entrades seleccionades de la llista</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>Esborra</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Copia l'etiqueta</translation>
+ </message>
+ <message>
+ <source>Copy message</source>
+ <translation>Copia el missatge</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copia l'import</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>QR Code</source>
+ <translation>Codi QR</translation>
+ </message>
+ <message>
+ <source>Copy &amp;URI</source>
+ <translation>Copia l'&amp;URI</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Address</source>
+ <translation>Copia l'&amp;adreça</translation>
+ </message>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>De&amp;sa la imatge...</translation>
+ </message>
+ <message>
+ <source>Request payment to %1</source>
+ <translation>Sol·licita un pagament a %1</translation>
+ </message>
+ <message>
+ <source>Payment information</source>
+ <translation>Informació de pagament</translation>
+ </message>
+ <message>
+ <source>URI</source>
+ <translation>URI</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adreça</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Import</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiqueta</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Missatge</translation>
+ </message>
+ <message>
+ <source>Resulting URI too long, try to reduce the text for label / message.</source>
+ <translation>URI resultant massa llarga, intenta reduir el text per a la etiqueta / missatge</translation>
+ </message>
+ <message>
+ <source>Error encoding URI into QR Code.</source>
+ <translation>Error en codificar l'URI en un codi QR.</translation>
+ </message>
+</context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiqueta</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Missatge</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Import</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(sense etiqueta)</translation>
+ </message>
+ <message>
+ <source>(no message)</source>
+ <translation>(sense missatge)</translation>
+ </message>
+ <message>
+ <source>(no amount)</source>
+ <translation>(sense import)</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Envia monedes</translation>
+ </message>
+ <message>
+ <source>Coin Control Features</source>
+ <translation>Característiques de control de les monedes</translation>
+ </message>
+ <message>
+ <source>Inputs...</source>
+ <translation>Entrades...</translation>
+ </message>
+ <message>
+ <source>automatically selected</source>
+ <translation>seleccionat automàticament</translation>
+ </message>
+ <message>
+ <source>Insufficient funds!</source>
+ <translation>Fons insuficients!</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Quantitat:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Bytes:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Import:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Prioritat:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Comissió:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Comissió posterior:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Canvi:</translation>
+ </message>
+ <message>
+ <source>If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address.</source>
+ <translation>Si s'activa això, però l'adreça de canvi està buida o bé no és vàlida, el canvi s'enviarà a una adreça generada de nou.</translation>
+ </message>
+ <message>
+ <source>Custom change address</source>
+ <translation>Personalitza l'adreça de canvi</translation>
+ </message>
+ <message>
+ <source>Transaction Fee:</source>
+ <translation>Comissió de transacció</translation>
+ </message>
+ <message>
+ <source>Choose...</source>
+ <translation>Tria...</translation>
+ </message>
+ <message>
+ <source>collapse fee-settings</source>
+ <translation>redueix els paràmetres de comissió</translation>
+ </message>
+ <message>
+ <source>per kilobyte</source>
+ <translation>per kilobyte</translation>
+ </message>
+ <message>
+ <source>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "total at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source>
+ <translation>Si la comissió personalitzada es defineix a 1000 satoshis i la transacció és de només 250 bytes, llavors «per kilobyte» només es paguen 250 satoshis en una comissió, mentre que amb la de «total com a mínim» es pagarien 1000 satoshis. Per a transaccions superiors al kilobyte, en tots dos casos es paga per kilobyte.</translation>
+ </message>
+ <message>
+ <source>Hide</source>
+ <translation>Amaga</translation>
+ </message>
+ <message>
+ <source>total at least</source>
+ <translation>total com a mínim</translation>
+ </message>
+ <message>
+ <source>Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process.</source>
+ <translation>No hi ha cap problema en pagar només la comissió mínima sempre que hi hagi menys volum de transacció que espai en els blocs. Però tingueu present que això pot acabar en una transacció que mai es confirmi una vegada hi hagi més demanda de transaccions de bitcoins que la xarxa pugui processar.</translation>
+ </message>
+ <message>
+ <source>(read the tooltip)</source>
+ <translation>(llegiu l'indicador de funció)</translation>
+ </message>
+ <message>
+ <source>Recommended:</source>
+ <translation>Recomanada:</translation>
+ </message>
+ <message>
+ <source>Custom:</source>
+ <translation>Personalitzada:</translation>
+ </message>
+ <message>
+ <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source>
+ <translation>(No s'ha inicialitzat encara la comissió intel·ligent. Normalment pren uns pocs blocs...)</translation>
+ </message>
+ <message>
+ <source>Confirmation time:</source>
+ <translation>Temps de confirmació:</translation>
+ </message>
+ <message>
+ <source>normal</source>
+ <translation>normal</translation>
+ </message>
+ <message>
+ <source>fast</source>
+ <translation>ràpid</translation>
+ </message>
+ <message>
+ <source>Send as zero-fee transaction if possible</source>
+ <translation>Envia com a transacció de comissió zero si és possible</translation>
+ </message>
+ <message>
+ <source>(confirmation may take longer)</source>
+ <translation>(la confirmació pot trigar més temps)</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>Envia a múltiples destinataris al mateix temps</translation>
+ </message>
+ <message>
+ <source>Add &amp;Recipient</source>
+ <translation>Afegeix &amp;destinatari</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Netejar tots els camps del formulari.</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Polsim:</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Neteja-ho &amp;tot</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>Balanç:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>Confirma l'acció d'enviament</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>E&amp;nvia</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>Confirma l'enviament de monedes</translation>
+ </message>
+ <message>
+ <source>%1 to %2</source>
+ <translation>%1 a %2</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Copia la quantitat</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copia l'import</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Copia la comissió</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Copia la comissió posterior</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Copia els bytes</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Copia la prioritat</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Copia el canvi</translation>
+ </message>
+ <message>
+ <source>or</source>
+ <translation>o</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>L'import a pagar ha de ser major que 0.</translation>
+ </message>
+ <message>
+ <source>The amount exceeds your balance.</source>
+ <translation>L'import supera el vostre balanç.</translation>
+ </message>
+ <message>
+ <source>The total exceeds your balance when the %1 transaction fee is included.</source>
+ <translation>El total excedeix el teu balanç quan s'afegeix la comissió a la transacció %1.</translation>
+ </message>
+ <message>
+ <source>Transaction creation failed!</source>
+ <translation>Ha fallat la creació de la transacció!</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>S'ha rebutjat la transacció! Això pot passar si alguna de les monedes del vostre moneder ja s'han gastat; per exemple, si heu fet servir una còpia de seguretat del fitxer wallet.dat i s'haguessin gastat monedes de la còpia però sense marcar-les-hi com a gastades.</translation>
+ </message>
+ <message>
+ <source>A fee higher than %1 is considered an absurdly high fee.</source>
+ <translation>Una comissió superior a %1 es considera una comissió absurdament alta.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>La sol·licitud de pagament ha vençut.</translation>
+ </message>
+ <message numerus="yes">
+ <source>Estimated to begin confirmation within %n block(s).</source>
+ <translation><numerusform>Estimat per començar la confirmació en %n bloc.</numerusform><numerusform>Estimat per començar la confirmació en %n blocs.</numerusform></translation>
+ </message>
+ <message>
+ <source>Pay only the minimum fee of %1</source>
+ <translation>Paga només la comissió mínima de %1</translation>
+ </message>
+ <message>
+ <source>The recipient address is not valid. Please recheck.</source>
+ <translation>L'adreça de destinatari no és vàlida. Torneu-la a comprovar.</translation>
+ </message>
+ <message>
+ <source>Duplicate address found: addresses should only be used once each.</source>
+ <translation>S'ha trobat una adreça duplicada: cal utilitzar les adreces només un cop cada vegada.</translation>
+ </message>
+ <message>
+ <source>Warning: Invalid Bitcoin address</source>
+ <translation>Avís: adreça Bitcoin no vàlida</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(sense etiqueta)</translation>
+ </message>
+ <message>
+ <source>Warning: Unknown change address</source>
+ <translation>Avís: adreça de canvi desconeguda</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Copia el polsim</translation>
+ </message>
+ <message>
+ <source>Are you sure you want to send?</source>
+ <translation>Esteu segur que ho voleu enviar?</translation>
+ </message>
+ <message>
+ <source>added as transaction fee</source>
+ <translation>S'ha afegit una taxa de transacció</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>Q&amp;uantitat:</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>Paga &amp;a:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Introduïu una etiqueta per a aquesta adreça per afegir-la a la llibreta d'adreces</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Etiqueta:</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Escull una adreça feta servir anteriorment</translation>
+ </message>
+ <message>
+ <source>This is a normal payment.</source>
+ <translation>Això és un pagament normal.</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to send the payment to</source>
+ <translation>L'adreça Bitcoin on enviar el pagament</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alta+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Enganxar adreça del porta-retalls</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Remove this entry</source>
+ <translation>Elimina aquesta entrada</translation>
+ </message>
+ <message>
+ <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source>
+ <translation>La comissió es deduirà de l'import que s'enviarà. El destinatari rebrà menys bitcoins que les que introduïu al camp d'import. Si se seleccionen múltiples destinataris, la comissió es dividirà per igual.</translation>
+ </message>
+ <message>
+ <source>S&amp;ubtract fee from amount</source>
+ <translation>S&amp;ubstreu la comissió de l'import</translation>
+ </message>
+ <message>
+ <source>Message:</source>
+ <translation>Missatge:</translation>
+ </message>
+ <message>
+ <source>This is an unauthenticated payment request.</source>
+ <translation>Aquesta és una sol·licitud de pagament no autenticada.</translation>
+ </message>
+ <message>
+ <source>This is an authenticated payment request.</source>
+ <translation>Aquesta és una sol·licitud de pagament autenticada.</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to the list of used addresses</source>
+ <translation>Introduïu una etiqueta per a aquesta adreça per afegir-la a la llista d'adreces utilitzades</translation>
+ </message>
+ <message>
+ <source>A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network.</source>
+ <translation>Un missatge que s'ha adjuntat al bitcoin: URI que s'emmagatzemarà amb la transacció per a la vostra referència. Nota: el missatge no s'enviarà a través de la xarxa Bitcoin.</translation>
+ </message>
+ <message>
+ <source>Pay To:</source>
+ <translation>Paga a:</translation>
+ </message>
+ <message>
+ <source>Memo:</source>
+ <translation>Memo:</translation>
+ </message>
+</context>
+<context>
+ <name>ShutdownWindow</name>
+ <message>
+ <source>Bitcoin Core is shutting down...</source>
+ <translation>S'està aturant el Bitcoin Core...</translation>
+ </message>
+ <message>
+ <source>Do not shut down the computer until this window disappears.</source>
+ <translation>No apagueu l'ordinador fins que no desaparegui aquesta finestra.</translation>
+ </message>
+</context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Signatures - Sign / Verify a Message</source>
+ <translation>Signatures - Signa / verifica un missatge</translation>
+ </message>
+ <message>
+ <source>&amp;Sign Message</source>
+ <translation>&amp;Signa el missatge</translation>
+ </message>
+ <message>
+ <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source>
+ <translation>Podeu signar missatges/acords amb les vostres adreces per provar que rebeu les bitcoins que s'hi envien. Aneu amb compte no signar res que sigui vague o aleatori, perquè en alguns atacs de suplantació es pot provar que hi signeu la vostra identitat. Només signeu aquelles declaracions completament detallades en què hi esteu d'acord. </translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to sign the message with</source>
+ <translation>L'adreça Bitcoin amb què signar el missatge</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Tria les adreces fetes servir amb anterioritat</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Enganxa l'adreça del porta-retalls</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Enter the message you want to sign here</source>
+ <translation>Introduïu aquí el missatge que voleu signar</translation>
+ </message>
+ <message>
+ <source>Signature</source>
+ <translation>Signatura</translation>
+ </message>
+ <message>
+ <source>Copy the current signature to the system clipboard</source>
+ <translation>Copia la signatura actual al porta-retalls del sistema</translation>
+ </message>
+ <message>
+ <source>Sign the message to prove you own this Bitcoin address</source>
+ <translation>Signa el missatge per provar que ets propietari d'aquesta adreça Bitcoin</translation>
+ </message>
+ <message>
+ <source>Sign &amp;Message</source>
+ <translation>Signa el &amp;missatge</translation>
+ </message>
+ <message>
+ <source>Reset all sign message fields</source>
+ <translation>Neteja tots els camps de clau</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Neteja-ho &amp;tot</translation>
+ </message>
+ <message>
+ <source>&amp;Verify Message</source>
+ <translation>&amp;Verifica el missatge</translation>
+ </message>
+ <message>
+ <source>Enter the receiver's 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. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source>
+ <translation>Introduïu l'adreça del receptor, el missatge (assegureu-vos de copiar els salts de línia, espais, tabuladors, etc. exactament) i signatura de sota per verificar el missatge. Tingueu cura de no llegir més en la signatura del que està al missatge signat, per evitar ser enganyat per un atac d'home-en-el-mig. Tingueu en compte que això només demostra que la part que signa rep amb l'adreça, i no es pot provar l'enviament de qualsevol transacció!</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address the message was signed with</source>
+ <translation>L'adreça Bitcoin amb què va ser signat el missatge</translation>
+ </message>
+ <message>
+ <source>Verify the message to ensure it was signed with the specified Bitcoin address</source>
+ <translation>Verificar el missatge per assegurar-se que ha estat signat amb una adreça Bitcoin específica</translation>
+ </message>
+ <message>
+ <source>Verify &amp;Message</source>
+ <translation>Verifica el &amp;missatge</translation>
+ </message>
+ <message>
+ <source>Reset all verify message fields</source>
+ <translation>Neteja tots els camps de verificació de missatge</translation>
+ </message>
+ <message>
+ <source>Click "Sign Message" to generate signature</source>
+ <translation>Feu clic a «Signa el missatge» per a generar una signatura</translation>
+ </message>
+ <message>
+ <source>The entered address is invalid.</source>
+ <translation>L'adreça introduïda no és vàlida.</translation>
+ </message>
+ <message>
+ <source>Please check the address and try again.</source>
+ <translation>Comproveu l'adreça i torneu-ho a provar.</translation>
+ </message>
+ <message>
+ <source>The entered address does not refer to a key.</source>
+ <translation>L'adreça introduïda no referencia a cap clau.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock was cancelled.</source>
+ <translation>El desbloqueig del moneder ha estat cancelat.</translation>
+ </message>
+ <message>
+ <source>Private key for the entered address is not available.</source>
+ <translation>La clau privada per a la adreça introduïda no està disponible.</translation>
+ </message>
+ <message>
+ <source>Message signing failed.</source>
+ <translation>La signatura del missatge ha fallat.</translation>
+ </message>
+ <message>
+ <source>Message signed.</source>
+ <translation>Missatge signat.</translation>
+ </message>
+ <message>
+ <source>The signature could not be decoded.</source>
+ <translation>La signatura no s'ha pogut descodificar.</translation>
+ </message>
+ <message>
+ <source>Please check the signature and try again.</source>
+ <translation>Comproveu la signatura i torneu-ho a provar.</translation>
+ </message>
+ <message>
+ <source>The signature did not match the message digest.</source>
+ <translation>La signatura no coincideix amb el resum del missatge.</translation>
+ </message>
+ <message>
+ <source>Message verification failed.</source>
+ <translation>Ha fallat la verificació del missatge.</translation>
+ </message>
+ <message>
+ <source>Message verified.</source>
+ <translation>Missatge verificat.</translation>
+ </message>
+</context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>The Bitcoin Core developers</source>
+ <translation>Els desenvolupadors del Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>[testnet]</source>
+ <translation>[testnet]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ <message>
+ <source>KB/s</source>
+ <translation>KB/s</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>Obert fins %1</translation>
+ </message>
+ <message>
+ <source>conflicted</source>
+ <translation>en conflicte</translation>
+ </message>
+ <message>
+ <source>%1/offline</source>
+ <translation>%1/fora de línia</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/sense confirmar</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 confirmacions</translation>
+ </message>
+ <message>
+ <source>Status</source>
+ <translation>Estat</translation>
+ </message>
+ <message numerus="yes">
+ <source>, broadcast through %n node(s)</source>
+ <translation><numerusform>, difusió a través de %n node</numerusform><numerusform>, difusió a través de %n nodes</numerusform></translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Source</source>
+ <translation>Font</translation>
+ </message>
+ <message>
+ <source>Generated</source>
+ <translation>Generat</translation>
+ </message>
+ <message>
+ <source>From</source>
+ <translation>Des de</translation>
+ </message>
+ <message>
+ <source>To</source>
+ <translation>A</translation>
+ </message>
+ <message>
+ <source>own address</source>
+ <translation>Adreça pròpia</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>només lectura</translation>
+ </message>
+ <message>
+ <source>label</source>
+ <translation>etiqueta</translation>
+ </message>
+ <message>
+ <source>Credit</source>
+ <translation>Crèdit</translation>
+ </message>
+ <message numerus="yes">
+ <source>matures in %n more block(s)</source>
+ <translation><numerusform>disponible en %n bloc més</numerusform><numerusform>disponibles en %n blocs més</numerusform></translation>
+ </message>
+ <message>
+ <source>not accepted</source>
+ <translation>no acceptat</translation>
+ </message>
+ <message>
+ <source>Debit</source>
+ <translation>Dèbit</translation>
+ </message>
+ <message>
+ <source>Total debit</source>
+ <translation>Dèbit total</translation>
+ </message>
+ <message>
+ <source>Total credit</source>
+ <translation>Crèdit total</translation>
+ </message>
+ <message>
+ <source>Transaction fee</source>
+ <translation>Comissió de transacció</translation>
+ </message>
+ <message>
+ <source>Net amount</source>
+ <translation>Import net</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Missatge</translation>
+ </message>
+ <message>
+ <source>Comment</source>
+ <translation>Comentar</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>ID de transacció</translation>
+ </message>
+ <message>
+ <source>Merchant</source>
+ <translation>Mercader</translation>
+ </message>
+ <message>
+ <source>Generated coins must mature %1 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.</source>
+ <translation>Les monedes generades han de madurar %1 blocs abans de poder ser gastades. Quan genereu aquest bloc, es farà saber a la xarxa per tal d'afegir-lo a la cadena de blocs. Si no pot fer-se lloc a la cadena, el seu estat canviarà a «no acceptat» i no es podrà gastar. Això pot passar ocasionalment si un altre node genera un bloc en un marge de segons respecte al vostre.</translation>
+ </message>
+ <message>
+ <source>Debug information</source>
+ <translation>Informació de depuració</translation>
+ </message>
+ <message>
+ <source>Transaction</source>
+ <translation>Transacció</translation>
+ </message>
+ <message>
+ <source>Inputs</source>
+ <translation>Entrades</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Import</translation>
+ </message>
+ <message>
+ <source>true</source>
+ <translation>cert</translation>
+ </message>
+ <message>
+ <source>false</source>
+ <translation>fals</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, encara no ha estat emès correctement</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Obre per %n bloc més</numerusform><numerusform>Obre per %n blocs més</numerusform></translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>desconegut</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>Detall de la transacció</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>Aquest panell mostra una descripció detallada de la transacció</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Tipus</translation>
+ </message>
+ <message>
+ <source>Immature (%1 confirmations, will be available after %2)</source>
+ <translation>Immadur (%1 confirmacions, serà disponible després de %2)</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Obre per %n bloc més</numerusform><numerusform>Obre per %n blocs més</numerusform></translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>Obert fins %1</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>Confirmat (%1 confirmacions)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>Aquest bloc no ha estat rebut per cap altre node i probablement no serà acceptat!</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>Generat però no acceptat</translation>
+ </message>
+ <message>
+ <source>Offline</source>
+ <translation>Fora de línia</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiqueta</translation>
+ </message>
+ <message>
+ <source>Unconfirmed</source>
+ <translation>Sense confirmar</translation>
+ </message>
+ <message>
+ <source>Confirming (%1 of %2 recommended confirmations)</source>
+ <translation>Confirmant (%1 de %2 confirmacions recomanades)</translation>
+ </message>
+ <message>
+ <source>Conflicted</source>
+ <translation>En conflicte</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Rebut amb</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>Rebut de</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Enviat a</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>Pagament a un mateix</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Minat</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>només lectura</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(n/a)</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>Estat de la transacció. Desplaceu-vos sobre aquest camp per mostrar el nombre de confirmacions.</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Data i hora en que la transacció va ser rebuda.</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>Tipus de transacció.</translation>
+ </message>
+ <message>
+ <source>Whether or not a watch-only address is involved in this transaction.</source>
+ <translation>Si està implicada o no una adreça només de lectura en la transacció.</translation>
+ </message>
+ <message>
+ <source>User-defined intent/purpose of the transaction.</source>
+ <translation>Intenció/propòsit de la transacció definida per l'usuari.</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>Import extret o afegit del balanç.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>Tot</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>Avui</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>Aquesta setmana</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>Aquest mes</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>El mes passat</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>Enguany</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>Rang...</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Rebut amb</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Enviat a</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>A un mateix</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Minat</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>Altres</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>Introduïu una adreça o una etiqueta per cercar</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>Import mínim</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Copia l'adreça</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Copiar etiqueta</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copia l'import</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Copiar ID de transacció</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>Editar etiqueta</translation>
+ </message>
+ <message>
+ <source>Show transaction details</source>
+ <translation>Mostra detalls de la transacció</translation>
+ </message>
+ <message>
+ <source>Export Transaction History</source>
+ <translation>Exporta l'historial de transacció</translation>
+ </message>
+ <message>
+ <source>Watch-only</source>
+ <translation>Només de lectura</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>L'exportació ha fallat</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the transaction history to %1.</source>
+ <translation>S'ha produït un error en provar de desar l'historial de transacció a %1.</translation>
+ </message>
+ <message>
+ <source>Exporting Successful</source>
+ <translation>Exportació amb èxit</translation>
+ </message>
+ <message>
+ <source>The transaction history was successfully saved to %1.</source>
+ <translation>L'historial de transaccions s'ha desat correctament a %1.</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Fitxer separat per comes (*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Confirmat</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Tipus</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiqueta</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adreça</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>Rang:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>a</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ <message>
+ <source>Unit to show amounts in. Click to select another unit.</source>
+ <translation>Unitat en què mostrar els imports. Feu clic per seleccionar una altra unitat.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletFrame</name>
+ <message>
+ <source>No wallet has been loaded.</source>
+ <translation>No s'ha carregat cap moneder.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Envia monedes</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Exporta</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Exporta les dades de la pestanya actual a un fitxer</translation>
+ </message>
+ <message>
+ <source>Backup Wallet</source>
+ <translation>Còpia de seguretat del moneder</translation>
+ </message>
+ <message>
+ <source>Wallet Data (*.dat)</source>
+ <translation>Dades del moneder (*.dat)</translation>
+ </message>
+ <message>
+ <source>Backup Failed</source>
+ <translation>Ha fallat la còpia de seguretat</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the wallet data to %1.</source>
+ <translation>S'ha produït un error en provar de desar les dades del moneder a %1.</translation>
+ </message>
+ <message>
+ <source>The wallet data was successfully saved to %1.</source>
+ <translation>S'han desat les dades del moneder correctament a %1.</translation>
+ </message>
+ <message>
+ <source>Backup Successful</source>
+ <translation>La còpia de seguretat s'ha realitzat correctament</translation>
+ </message>
+</context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>Opcions:</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>Especifica el directori de dades</translation>
+ </message>
+ <message>
+ <source>Connect to a node to retrieve peer addresses, and disconnect</source>
+ <translation>Connecta al node per obtenir les adreces de les connexions, i desconnecta</translation>
+ </message>
+ <message>
+ <source>Specify your own public address</source>
+ <translation>Especifiqueu la vostra adreça pública</translation>
+ </message>
+ <message>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>Accepta la línia d'ordres i ordres JSON-RPC </translation>
+ </message>
+ <message>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>Executa en segon pla com a programa dimoni i accepta ordres</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>Utilitza la xarxa de prova</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
+ <translation>Accepta connexions de fora (per defecte: 1 si no -proxy o -connect)</translation>
+ </message>
+ <message>
+ <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
+ <translation>Vincula a una adreça específica i sempre escolta-hi. Utilitza la notació [host]:port per IPv6</translation>
+ </message>
+ <message>
+ <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
+ <translation>Elimina totes les transaccions del moneder i només recupera aquelles de la cadena de blocs a través de -rescan a l'inici</translation>
+ </message>
+ <message>
+ <source>Distributed under the MIT software license, see the accompanying file COPYING or &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</source>
+ <translation>Distribuït sota llicència de programari MIT. Vegeu el fitxer acompanyant COPYING o &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</translation>
+ </message>
+ <message>
+ <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
+ <translation>Executa una ordre quan una transacció del moneder canviï (%s en cmd es canvia per TxID)</translation>
+ </message>
+ <message>
+ <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source>
+ <translation>Comissions totals màximes que s'utilitzaran en una única transacció de moneder; si s'estableix un valor massa baix es poden interrompre transaccions grans (per defecte: %s)</translation>
+ </message>
+ <message>
+ <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, &gt;%u = target size in MiB to use for block files)</source>
+ <translation>Redueix els requeriments d'emmagatzemament podant (suprimint) els blocs antics. Aquest mode inhabilita l'ús de moneders i és incompatible amb -tindex. Avís: Revertir aquesta configuració comporta tornar a baixar la cadena de blocs sencera. (per defecte: 0 = inhabilita la poda de blocs, &gt;%u = mida objectiu en MiB per utilitzar els fitxers de blocs)</translation>
+ </message>
+ <message>
+ <source>Set the number of script verification threads (%u to %d, 0 = auto, &lt;0 = leave that many cores free, default: %d)</source>
+ <translation>Defineix el nombre de fils de verificació d'scripts (%u a %d, 0 = auto, &lt;0 = deixa tants nuclis lliures, per defecte: %d)</translation>
+ </message>
+ <message>
+ <source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source>
+ <translation>Aquesta és una versió de pre-llançament - utilitza-la sota la teva responsabilitat - No usar per a minería o aplicacions de compra-venda</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer. Bitcoin Core is probably already running.</source>
+ <translation>No es pot enllaçar %s a aquest ordinador. El Bitcoin Core probablement ja estigui executant-s'hi.</translation>
+ </message>
+ <message>
+ <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>AVÍS: s'ha generat un nombre anòmalament alt de blocs, %d blocs rebuts en les darreres %d hores (se n'esperaven %d)</translation>
+ </message>
+ <message>
+ <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>AVÍS: comproveu la vostra connexió a la xarxa, %d blocs rebuts en les darreres %d hores (se n'esperaven %d)</translation>
+ </message>
+ <message>
+ <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>Avís: el -paytxfee és molt elevat! Aquesta és la comissió de transacció que pagareu si envieu una transacció.</translation>
+ </message>
+ <message>
+ <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source>
+ <translation>Avís: la xarxa no sembla que hi estigui plenament d'acord. Alguns miners sembla que estan experimentant problemes.</translation>
+ </message>
+ <message>
+ <source>Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.</source>
+ <translation>Avís: sembla que no estem plenament d'acord amb els nostres iguals! Podria caler que actualitzar l'aplicació, o potser que ho facin altres nodes.</translation>
+ </message>
+ <message>
+ <source>Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
+ <translation>Avís: error en llegir el fitxer wallet.dat! Totes les claus es llegeixen correctament, però hi ha dades de transaccions o entrades de la llibreta d'adreces absents o bé son incorrectes.</translation>
+ </message>
+ <message>
+ <source>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</source>
+ <translation>Avís: el fitxer wallet.dat és corrupte, dades rescatades! L'arxiu wallet.dat original ha estat desat com wallet.{estampa_temporal}.bak al directori %s; si el teu balanç o transaccions son incorrectes hauries de restaurar-lo de un backup.</translation>
+ </message>
+ <message>
+ <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source>
+ <translation>Afegeix a la llista blanca els iguals que es connecten de la màscara de xarxa o adreça IP donada. Es pot especificar moltes vegades.</translation>
+ </message>
+ <message>
+ <source>(default: 1)</source>
+ <translation>(per defecte: 1)</translation>
+ </message>
+ <message>
+ <source>&lt;category&gt; can be:</source>
+ <translation>&lt;category&gt; pot ser:</translation>
+ </message>
+ <message>
+ <source>Attempt to recover private keys from a corrupt wallet.dat</source>
+ <translation>Intenta recuperar les claus privades d'un fitxer wallet.dat corrupte</translation>
+ </message>
+ <message>
+ <source>Block creation options:</source>
+ <translation>Opcions de la creació de blocs:</translation>
+ </message>
+ <message>
+ <source>Connect only to the specified node(s)</source>
+ <translation>Connecta només al(s) node(s) especificats</translation>
+ </message>
+ <message>
+ <source>Connection options:</source>
+ <translation>Opcions de connexió:</translation>
+ </message>
+ <message>
+ <source>Corrupted block database detected</source>
+ <translation>S'ha detectat una base de dades de blocs corrupta</translation>
+ </message>
+ <message>
+ <source>Debugging/Testing options:</source>
+ <translation>Opcions de depuració/proves:</translation>
+ </message>
+ <message>
+ <source>Do not load the wallet and disable wallet RPC calls</source>
+ <translation>No carreguis el moneder i inhabilita les crides RPC del moneder</translation>
+ </message>
+ <message>
+ <source>Do you want to rebuild the block database now?</source>
+ <translation>Voleu reconstruir la base de dades de blocs ara?</translation>
+ </message>
+ <message>
+ <source>Error initializing block database</source>
+ <translation>Error carregant la base de dades de blocs</translation>
+ </message>
+ <message>
+ <source>Error initializing wallet database environment %s!</source>
+ <translation>Error inicialitzant l'entorn de la base de dades del moneder %s!</translation>
+ </message>
+ <message>
+ <source>Error loading block database</source>
+ <translation>Error carregant la base de dades del bloc</translation>
+ </message>
+ <message>
+ <source>Error opening block database</source>
+ <translation>Error en obrir la base de dades de blocs</translation>
+ </message>
+ <message>
+ <source>Error: Disk space is low!</source>
+ <translation>Error: Espai al disc baix!</translation>
+ </message>
+ <message>
+ <source>Failed to listen on any port. Use -listen=0 if you want this.</source>
+ <translation>Ha fallat escoltar a qualsevol port. Feu servir -listen=0 si voleu fer això.</translation>
+ </message>
+ <message>
+ <source>If &lt;category&gt; is not supplied, output all debugging information.</source>
+ <translation>Si no se subministra &lt;category&gt;, mostra tota la informació de depuració.</translation>
+ </message>
+ <message>
+ <source>Importing...</source>
+ <translation>S'està important...</translation>
+ </message>
+ <message>
+ <source>Incorrect or no genesis block found. Wrong datadir for network?</source>
+ <translation>No s'ha trobat el bloc de gènesi o és incorrecte. El directori de dades de la xarxa és incorrecte?</translation>
+ </message>
+ <message>
+ <source>Invalid -onion address: '%s'</source>
+ <translation>Adreça -onion no vàlida: '%s'</translation>
+ </message>
+ <message>
+ <source>Not enough file descriptors available.</source>
+ <translation>No hi ha suficient descriptors de fitxers disponibles.</translation>
+ </message>
+ <message>
+ <source>Only connect to nodes in network &lt;net&gt; (ipv4, ipv6 or onion)</source>
+ <translation>Només connecta als nodes de la xarxa &lt;net&gt; (ipv4, ipv6 o onion)</translation>
+ </message>
+ <message>
+ <source>Prune cannot be configured with a negative value.</source>
+ <translation>La poda no es pot configurar amb un valor negatiu.</translation>
+ </message>
+ <message>
+ <source>Prune mode is incompatible with -txindex.</source>
+ <translation>El mode de poda és incompatible amb -txindex.</translation>
+ </message>
+ <message>
+ <source>Set database cache size in megabytes (%d to %d, default: %d)</source>
+ <translation>Defineix la mida de la memòria cau de la base de dades en megabytes (%d a %d, per defecte: %d)</translation>
+ </message>
+ <message>
+ <source>Set maximum block size in bytes (default: %d)</source>
+ <translation>Defineix la mida màxim del bloc en bytes (per defecte: %d)</translation>
+ </message>
+ <message>
+ <source>Specify wallet file (within data directory)</source>
+ <translation>Especifica un fitxer de moneder (dins del directori de dades)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: %u)</source>
+ <translation>Utilitza UPnP per a mapejar el port d'escolta (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Verifying blocks...</source>
+ <translation>S'estan verificant els blocs...</translation>
+ </message>
+ <message>
+ <source>Verifying wallet...</source>
+ <translation>S'està verificant el moneder...</translation>
+ </message>
+ <message>
+ <source>Wallet %s resides outside data directory %s</source>
+ <translation>El moneder %s resideix fora del directori de dades %s</translation>
+ </message>
+ <message>
+ <source>Wallet options:</source>
+ <translation>Opcions de moneder:</translation>
+ </message>
+ <message>
+ <source>Warning: This version is obsolete; upgrade required!</source>
+ <translation>Avís: aquesta versió és obsoleta; cal actualitzar-la!</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to change -txindex</source>
+ <translation>Cal que reconstruïu la base de dades fent servir -reindex per canviar -txindex</translation>
+ </message>
+ <message>
+ <source>Imports blocks from external blk000??.dat file</source>
+ <translation>Importa blocs de un fitxer blk000??.dat extern</translation>
+ </message>
+ <message>
+ <source>Allow JSON-RPC connections from specified source. Valid for &lt;ip&gt; are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times</source>
+ <translation>Permet les connexions JSON-RPC d'una font específica. Vàlid per a &lt;ip&gt; són una IP individual (p. ex., 1.2.3.4), una xarxa / màscara de xarxa (p. ex., 1.2.3.4/255.255.255.0) o una xarxa/CIDR (p. ex., 1.2.3.4/24). Es pot especificar aquesta opció moltes vegades</translation>
+ </message>
+ <message>
+ <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source>
+ <translation>Vincula l'adreça donada i posa a la llista blanca els iguals que s'hi connectin. Feu servir la notació [host]:port per a IPv6</translation>
+ </message>
+ <message>
+ <source>Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)</source>
+ <translation>Vincula a l'adreça donada per a escoltar les connexions JSON-RPC. Feu servir la notació [host]:port per a IPv6. Aquesta opció pot ser especificada moltes vegades (per defecte: vincula a totes les interfícies)</translation>
+ </message>
+ <message>
+ <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source>
+ <translation>No es pot obtenir un bloqueig del directori de dades %s. El Bitcoin Core probablement ja s'estigui executant.</translation>
+ </message>
+ <message>
+ <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
+ <translation>Crea fitxers nous amb els permisos per defecte del sistema, en comptes de l'umask 077 (només efectiu amb la funcionalitat de moneder inhabilitada)</translation>
+ </message>
+ <message>
+ <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source>
+ <translation>Descobreix l'adreça IP pròpia (per defecte: 1 quan s'escolta i no -externalip o -proxy)</translation>
+ </message>
+ <message>
+ <source>Error: Listening for incoming connections failed (listen returned error %s)</source>
+ <translation>Error: ha fallat escoltar les connexions entrants (l'escoltament ha retornat l'error %s)</translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source>
+ <translation>Error: s'ha trobat un argument no permès de -socks. Ja no es pot definir més la versió de SOCKS, només s'accepten els proxies de SOCKS5.ç</translation>
+ </message>
+ <message>
+ <source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source>
+ <translation>Executa l'ordre quan es rebi un avís rellevant o veiem una forquilla molt llarga (%s en cmd és reemplaçat per un missatge)</translation>
+ </message>
+ <message>
+ <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source>
+ <translation>Comissions (en BTC/Kb) inferiors a això es consideren de comissió zero per a la transmissió (per defecte: %s)</translation>
+ </message>
+ <message>
+ <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
+ <translation>Si no s'especifica una paytxfee (comissió de transacció de pagament), inclogueu suficient comissió per tal que les transaccions comencin a confirmar-se en una mitja de n blocs (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)</source>
+ <translation>Import no vàlid per a -maxtxfee=&lt;amount&gt;: '%s' (cal que sigui com a mínim la comissió de minrelay de %s per evitar que les comissions s'encallin)</translation>
+ </message>
+ <message>
+ <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source>
+ <translation>Mida màxima de les dades en les transaccions de l'operador en què confiem i en les meves (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Prune configured below the minimum of %d MB. Please use a higher number.</source>
+ <translation>Poda configurada per sota el mínim de %d MB. Feu servir un nombre superior.</translation>
+ </message>
+ <message>
+ <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source>
+ <translation>Consulta a adreces d'iguals a través de DNS, si es troba baix en adreces (per defecte: 1 a menys que -connect)</translation>
+ </message>
+ <message>
+ <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source>
+ <translation>Genera a l'atzar credencials per a cada connexió proxy. Això habilita l'aïllament del flux de Tor (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
+ <translation>Defineix la mida màxima de transaccions d'alta prioritat / baixa comissió en bytes (per defecte: %d)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source>
+ <translation>Defineix el nombre de fils per a la generació de moneda si està habilitat (-1 = tots els nuclis, per defecte: %d)</translation>
+ </message>
+ <message>
+ <source>The transaction amount is too small to send after the fee has been deducted</source>
+ <translation>L'import de la transacció és massa petit per enviar-la després que se'n dedueixi la comissió</translation>
+ </message>
+ <message>
+ <source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit &lt;https://www.openssl.org/&gt; and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source>
+ <translation>Aquest producte inclou programari desenvolupat pel projecte OpenSSL per a ús a l'OpenSSL Toolkit &lt;https://www.openssl.org/&gt; i programari criptogràfic escrit per Eric Young i programari UPnP escrit per Thomas Bernard.</translation>
+ </message>
+ <message>
+ <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an 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)
+The username and password MUST NOT be the same.
+If the file does not exist, create it with owner-readable-only file permissions.
+It is also recommended to set alertnotify so you are notified of problems;
+for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
+</source>
+ <translation>Per utilitzar bitcoind, o l'opció de serviddor de bitcoin-qt, heu de definir una rpcpassword en el fitxer de configuració:
+%s
+Es recomana que utilitzeu la contrasenya aleatòria següent:
+rpcuser=bitcoinrpc
+rpcpassword=%s
+(no cal que recordeu la contrasenya)
+El nom d'usuari i la contrasenya NO han de ser els mateixos.
+Si el fitxer no existeix, creeu-ne un amb permisos de lectura només per al seu propietari.
+Es recomana definir alertnotify per tal de ser notificat de qualsevol problema;
+per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</translation>
+ </message>
+ <message>
+ <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source>
+ <translation>Avís: s'ha especificat un -maxtxfee molt alt! Comissions tan grans podrien pagar-se en una única transacció.</translation>
+ </message>
+ <message>
+ <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source>
+ <translation>Avís: comproveu que la data i hora del vostre ordinador siguin correctes! Si el vostre rellotge no és correcte, el Bitcoin Core no funcionarà correctament.</translation>
+ </message>
+ <message>
+ <source>Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway</source>
+ <translation>Els iguals en la llista blanca no poden ser bandejats per DoS i es transmetran sempre llurs transaccions, fins i tot si ja són a la mempool. Això és útil, p. ex., per a una passarel·la</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source>
+ <translation>Cal que torneu a construir la base de dades fent servir -reindex per tornar al mode no podat. Això tornarà a baixar la cadena de blocs sencera</translation>
+ </message>
+ <message>
+ <source>(default: %u)</source>
+ <translation>(per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Accept public REST requests (default: %u)</source>
+ <translation>Accepta sol·licituds REST públiques (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Activating best chain...</source>
+ <translation>S'està activant la millor cadena...</translation>
+ </message>
+ <message>
+ <source>Can't run with a wallet in prune mode.</source>
+ <translation>No es pot executar amb un moneder en mode poda.</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -whitebind address: '%s'</source>
+ <translation>No es pot resoldre l'adreça -whitebind: «%s»</translation>
+ </message>
+ <message>
+ <source>Choose data directory on startup (default: 0)</source>
+ <translation>Tria el directori de dades a l'inici (per defecte: 0)</translation>
+ </message>
+ <message>
+ <source>Connect through SOCKS5 proxy</source>
+ <translation>Connecta a través del proxy SOCKS5</translation>
+ </message>
+ <message>
+ <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source>
+ <translation>Copyright (C) 2009-%i Els desenvolupadors del Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Could not parse -rpcbind value %s as network address</source>
+ <translation>No s'ha pogut analitzar el valor -rpcbind %s com una adreça de xarxa</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source>
+ <translation>Error en carregar wallet.dat: el moneder requereix una versió més nova del Bitcoin core</translation>
+ </message>
+ <message>
+ <source>Error reading from database, shutting down.</source>
+ <translation>Error en llegir la base de dades, tancant.</translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -tor found, use -onion.</source>
+ <translation>Error: s'ha trobat un argument -tor no acceptat. Feu servir -onion.</translation>
+ </message>
+ <message>
+ <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source>
+ <translation>Comissió en (BTC/kB) per afegir a les transaccions que envieu (per defecte: %s)</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>&amp;Informació</translation>
+ </message>
+ <message>
+ <source>Initialization sanity check failed. Bitcoin Core is shutting down.</source>
+ <translation>Ha fallat la inicialització de la comprovació de validesa. El Bitcoin Core s'està aturant.</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Import no vàlid per a -maxtxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -minrelaytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Import no vàlid per a -minrelaytxfee=&lt;amount&gt;: «%s»</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -mintxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Import no vàlid per a -mintxfee=&lt;amount&gt;: «%s»</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s' (must be at least %s)</source>
+ <translation>Import no vàlid per a -paytxfee=&lt;amount&gt;: «%s» (ha de ser com a mínim %s)</translation>
+ </message>
+ <message>
+ <source>Invalid netmask specified in -whitelist: '%s'</source>
+ <translation>S'ha especificat una màscara de xarxa no vàlida a -whitelist: «%s»</translation>
+ </message>
+ <message>
+ <source>Keep at most &lt;n&gt; unconnectable transactions in memory (default: %u)</source>
+ <translation>Manté com a màxim &lt;n&gt; transaccions no connectables en memòria (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Need to specify a port with -whitebind: '%s'</source>
+ <translation>Cal especificar un port amb -whitebind: «%s»</translation>
+ </message>
+ <message>
+ <source>Node relay options:</source>
+ <translation>Opcions de transmissió del node:</translation>
+ </message>
+ <message>
+ <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source>
+ <translation>Opcions RPC SSL: (veieu el wiki del Bitcoin per a instruccions de configuració de l'SSL)</translation>
+ </message>
+ <message>
+ <source>RPC server options:</source>
+ <translation>Opcions del servidor RPC:</translation>
+ </message>
+ <message>
+ <source>RPC support for HTTP persistent connections (default: %d)</source>
+ <translation>Suport RPC per a connexions HTTP persistents (per defecte: %d)</translation>
+ </message>
+ <message>
+ <source>Rebuild block chain index from current blk000??.dat files on startup</source>
+ <translation>Reconstrueix l'índex de la cadena de blocs dels fitxers blk000??.dat actuals a l'inici.</translation>
+ </message>
+ <message>
+ <source>Receive and display P2P network alerts (default: %u)</source>
+ <translation>Rep i mostra avisos de la xarxa P2P (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>Envia informació de traça/depuració a la consola en comptes del fitxer debug.log</translation>
+ </message>
+ <message>
+ <source>Send transactions as zero-fee transactions if possible (default: %u)</source>
+ <translation>Envia les transaccions com a transaccions de comissió zero sempre que sigui possible (per defecte: %u) </translation>
+ </message>
+ <message>
+ <source>Set SSL root certificates for payment request (default: -system-)</source>
+ <translation>Defineix certificats arrel SSL per a la sol·licitud de pagament (per defecte: -sistema-)</translation>
+ </message>
+ <message>
+ <source>Set language, for example "de_DE" (default: system locale)</source>
+ <translation>Defineix un idioma, per exemple «de_DE» (per defecte: preferències locals de sistema)</translation>
+ </message>
+ <message>
+ <source>Show all debugging options (usage: --help -help-debug)</source>
+ <translation>Mostra totes les opcions de depuració (ús: --help --help-debug)</translation>
+ </message>
+ <message>
+ <source>Show splash screen on startup (default: 1)</source>
+ <translation>Mostra la finestra de benvinguda a l'inici (per defecte: 1)</translation>
+ </message>
+ <message>
+ <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source>
+ <translation>Redueix el fitxer debug.log durant l'inici del client (per defecte: 1 quan no -debug)</translation>
+ </message>
+ <message>
+ <source>Signing transaction failed</source>
+ <translation>Ha fallat la signatura de la transacció</translation>
+ </message>
+ <message>
+ <source>Start minimized</source>
+ <translation>Inicia minimitzat</translation>
+ </message>
+ <message>
+ <source>The transaction amount is too small to pay the fee</source>
+ <translation>L'import de la transacció és massa petit per pagar-ne una comissió</translation>
+ </message>
+ <message>
+ <source>This is experimental software.</source>
+ <translation>Això és programari experimental.</translation>
+ </message>
+ <message>
+ <source>Transaction amount too small</source>
+ <translation>Import de la transacció massa petit</translation>
+ </message>
+ <message>
+ <source>Transaction amounts must be positive</source>
+ <translation>Els imports de les transaccions han de ser positius</translation>
+ </message>
+ <message>
+ <source>Transaction too large for fee policy</source>
+ <translation>Transacció massa gran per a la política de comissions</translation>
+ </message>
+ <message>
+ <source>Transaction too large</source>
+ <translation>La transacció és massa gran</translation>
+ </message>
+ <message>
+ <source>UI Options:</source>
+ <translation>Opcions d'interfície:</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer (bind returned error %s)</source>
+ <translation>No s'ha pogut vincular a %s en aquest ordinador (la vinculació ha retornat l'error %s)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: 1 when listening)</source>
+ <translation>Utilitza UPnP per a mapejar els ports d'escolta (per defecte: 1 quan s'escolta)</translation>
+ </message>
+ <message>
+ <source>Username for JSON-RPC connections</source>
+ <translation>Nom d'usuari per a connexions JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Wallet needed to be rewritten: restart Bitcoin Core to complete</source>
+ <translation>Cal reescriure el moneder: reiniceu el Bitcoin Core per completar-ho.</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Avís</translation>
+ </message>
+ <message>
+ <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source>
+ <translation>Avís: s'ha ignorat l'argument no acceptat de -benchmark. Feu servir -debug=bench.</translation>
+ </message>
+ <message>
+ <source>Warning: Unsupported argument -debugnet ignored, use -debug=net.</source>
+ <translation>Avís: s'ha ignorat l'argument no acceptat de -debugnet. Feu servir -debug=net.</translation>
+ </message>
+ <message>
+ <source>Zapping all transactions from wallet...</source>
+ <translation>Se suprimeixen totes les transaccions del moneder...</translation>
+ </message>
+ <message>
+ <source>on startup</source>
+ <translation>a l'inici de l'aplicació</translation>
+ </message>
+ <message>
+ <source>wallet.dat corrupt, salvage failed</source>
+ <translation>El fitxer wallet.data és corrupte. El rescat de les dades ha fallat</translation>
+ </message>
+ <message>
+ <source>Password for JSON-RPC connections</source>
+ <translation>Contrasenya per a connexions JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
+ <translation>Executa l'ordre quan el millor bloc canviï (%s en cmd es reemplaça per un resum de bloc)</translation>
+ </message>
+ <message>
+ <source>Upgrade wallet to latest format</source>
+ <translation>Actualitza el moneder a l'últim format</translation>
+ </message>
+ <message>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>Reescaneja la cadena de blocs en les transaccions de moneder perdudes</translation>
+ </message>
+ <message>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>Utilitza OpenSSL (https) per a connexions JSON-RPC</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>Aquest misatge d'ajuda</translation>
+ </message>
+ <message>
+ <source>Allow DNS lookups for -addnode, -seednode and -connect</source>
+ <translation>Permet consultes DNS per a -addnode, -seednode i -connect</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>S'estan carregant les adreces...</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>Error en carregar wallet.dat: Moneder corrupte</translation>
+ </message>
+ <message>
+ <source>(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source>
+ <translation>(1 = manté les metadades de les tx, p. ex., propietari del compte i informació de sol·licitud del pagament, 2 = prescindeix de les metadades de les tx)</translation>
+ </message>
+ <message>
+ <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
+ <translation>Com d'exhaustiva és la verificació de blocs del -checkblocks (0-4, per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
+ <translation>Manté un índex complet de transaccions, utilitzat per la crida rpc getrawtransaction (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source>
+ <translation>Nombre de segons necessaris perquè els iguals de comportament qüestionable puguin tornar a connectar-se (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Output debugging information (default: %u, supplying &lt;category&gt; is optional)</source>
+ <translation>Informació de sortida de la depuració (per defecte: %u, proporcionar &lt;category&gt; és opcional)</translation>
+ </message>
+ <message>
+ <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source>
+ <translation>Utilitza un proxy SOCKS4 apart per a arribar als iguals a través de serveis ocults de Tor (per defecte: %s)</translation>
+ </message>
+ <message>
+ <source>(default: %s)</source>
+ <translation>(per defecte: %s)</translation>
+ </message>
+ <message>
+ <source>Acceptable ciphers (default: %s)</source>
+ <translation>Xifrats acceptables (per defecte: %s)</translation>
+ </message>
+ <message>
+ <source>Always query for peer addresses via DNS lookup (default: %u)</source>
+ <translation>Demana sempre les adreces dels iguals a través de consultes DNS (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>Error en carregar wallet.dat</translation>
+ </message>
+ <message>
+ <source>Generate coins (default: %u)</source>
+ <translation>Genera monedes (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>How many blocks to check at startup (default: %u, 0 = all)</source>
+ <translation>Quants blocs per comprovar a l'inici (per defecte: %u, 0 = tots)</translation>
+ </message>
+ <message>
+ <source>Include IP addresses in debug output (default: %u)</source>
+ <translation>Inclou l'adreça IP a la sortida de depuració (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Invalid -proxy address: '%s'</source>
+ <translation>Adreça -proxy invalida: '%s'</translation>
+ </message>
+ <message>
+ <source>Listen for JSON-RPC connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>Escolta les connexions JSON-RPC en &lt;port&gt; (per defecte: %u o testnet: %u)</translation>
+ </message>
+ <message>
+ <source>Listen for connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>Escolta les connexions en &lt;port&gt; (per defecte: %u o testnet: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain at most &lt;n&gt; connections to peers (default: %u)</source>
+ <translation>Manté com a màxim &lt;n&gt; connexions a iguals (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Make the wallet broadcast transactions</source>
+ <translation>Fes que el moneder faci difusió de les transaccions</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection receive buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>Memòria intermèdia màxima de recepció per connexió, &lt;n&gt;*1000 bytes (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection send buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>Memòria intermèdia màxima d'enviament per connexió, &lt;n&gt;*1000 bytes (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Prepend debug output with timestamp (default: %u)</source>
+ <translation>Posa davant de la sortida de depuració una marca horària (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Relay and mine data carrier transactions (default: %u)</source>
+ <translation>Retransmet i mina les transaccions de l'operador (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Relay non-P2SH multisig (default: %u)</source>
+ <translation>Retransmet multisig no P2SH (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Server certificate file (default: %s)</source>
+ <translation>Fitxer de certificat del servidor (per defecte: %s)</translation>
+ </message>
+ <message>
+ <source>Server private key (default: %s)</source>
+ <translation>Clau privada del servidor (per defecte: %s)</translation>
+ </message>
+ <message>
+ <source>Set key pool size to &lt;n&gt; (default: %u)</source>
+ <translation>Defineix la mida clau disponible a &lt;n&gt; (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Set minimum block size in bytes (default: %u)</source>
+ <translation>Defineix la mida de bloc mínima en bytes (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads to service RPC calls (default: %d)</source>
+ <translation>Defineix el nombre de fils a crides de servei RPC (per defecte: %d)</translation>
+ </message>
+ <message>
+ <source>Specify configuration file (default: %s)</source>
+ <translation>Especifica el fitxer de configuració (per defecte: %s)</translation>
+ </message>
+ <message>
+ <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source>
+ <translation>Especifica el temps d'espera de la connexió en milisegons (mínim: 1, per defecte: %d)</translation>
+ </message>
+ <message>
+ <source>Specify pid file (default: %s)</source>
+ <translation>Especifica el fitxer pid (per defecte: %s)</translation>
+ </message>
+ <message>
+ <source>Spend unconfirmed change when sending transactions (default: %u)</source>
+ <translation>Gasta el canvi no confirmat en enviar les transaccions (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Threshold for disconnecting misbehaving peers (default: %u)</source>
+ <translation>Llindar per a desconnectar els iguals de comportament qüestionable (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Unknown network specified in -onlynet: '%s'</source>
+ <translation>Xarxa desconeguda especificada a -onlynet: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -bind address: '%s'</source>
+ <translation>No es pot resoldre l'adreça -bind: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -externalip address: '%s'</source>
+ <translation>No es pot resoldre l'adreça -externalip: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Import no vàlid per a -paytxfee=&lt;amount&gt;: «%s»</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>Balanç insuficient</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>S'està carregant l'índex de blocs...</translation>
+ </message>
+ <message>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>Afegeix un node per a connectar-s'hi i intenta mantenir-hi la connexió oberta</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>S'està carregant el moneder...</translation>
+ </message>
+ <message>
+ <source>Cannot downgrade wallet</source>
+ <translation>No es pot reduir la versió del moneder</translation>
+ </message>
+ <message>
+ <source>Cannot write default address</source>
+ <translation>No es pot escriure l'adreça per defecte</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>S'està reescanejant...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>Ha acabat la càrrega</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Error</translation>
+ </message>
+</context>
+</TS> \ No newline at end of file
diff --git a/src/qt/locale/bitcoin_ca@valencia.ts b/src/qt/locale/bitcoin_ca@valencia.ts
new file mode 100644
index 0000000000..e007a42e42
--- /dev/null
+++ b/src/qt/locale/bitcoin_ca@valencia.ts
@@ -0,0 +1,3571 @@
+<TS language="ca@valencia" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Right-click to edit address or label</source>
+ <translation>Feu clic dret per a editar l'adreça o l'etiqueta</translation>
+ </message>
+ <message>
+ <source>Create a new address</source>
+ <translation>Crea una nova adreça</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>&amp;Nova</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Copia l'adreça seleccionada al porta-retalls del sistema</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>&amp;Copia</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>&amp;Tanca</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>&amp;Copia l'adreça</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>Elimina l'adreça sel·leccionada actualment de la llista</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Exporta les dades de la pestanya actual a un fitxer</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Exporta</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;Elimina</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>Trieu una adreça on voleu enviar monedes</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>Trieu l'adreça on voleu rebre monedes</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>T&amp;ria</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>S'estan enviant les adreces</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>S'estan rebent les adreces</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>Estes són les vostres adreces de Bitcoin per enviar els pagaments. Sempre reviseu l'import i l'adreça del destinatari abans de transferir monedes.</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>Estes són les vostres adreces Bitcoin per rebre pagaments. Es recomana utilitzar una adreça nova de recepció per a cada transacció.</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>Copia l'&amp;etiqueta</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>&amp;Edita</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>Exporta la llista d'adreces</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Fitxer de separació amb comes (*.csv)</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>L'exportació ha fallat</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the address list to %1. Please try again.</source>
+ <translation>S'ha produït un error en guardar la llista d'adreces a %1. Torneu-ho a provar.</translation>
+ </message>
+</context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Etiqueta</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adreça</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(sense etiqueta)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Passphrase Dialog</source>
+ <translation>Diàleg de contrasenya</translation>
+ </message>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Introduïu una contrasenya</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Nova contrasenya</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Repetiu la nova contrasenya</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>Encripta el moneder</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>Esta operació requereix la contrasenya del moneder per a desbloquejar-lo.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Desbloqueja el moneder</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>Esta operació requereix la contrasenya del moneder per desencriptar-lo.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>Desencripta el moneder</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>Canvia la contrasenya</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>Confirma l'encriptació del moneder</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>Avís: si encripteu el vostre moneder i perdeu la contrasenya, &lt;b&gt;PERDREU TOTS ELS VOSTRES BITCOINS&lt;/b&gt;!</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>Esteu segur que voleu encriptar el vostre moneder?</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core 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.</source>
+ <translation>Ara es tancarà el Bitcoin Core per finalitzar el procés d'encriptació. Tingueu present que encriptar el vostre moneder no garanteix que les vostres bitcoins no puguen ser robades per programari maliciós que infecti l'ordinador.</translation>
+ </message>
+ <message>
+ <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
+ <translation>IMPORTANT: Tota copia de seguretat que hàgeu realitzat hauria de ser reemplaçada pel, recentment generat, fitxer encriptat del moneder.</translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>Avís: Les lletres majúscules estan activades!</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>Moneder encriptat</translation>
+ </message>
+ <message>
+ <source>Enter the new passphrase to the wallet.&lt;br/&gt;Please use a passphrase of &lt;b&gt;ten or more random characters&lt;/b&gt;, or &lt;b&gt;eight or more words&lt;/b&gt;.</source>
+ <translation>Introduïu la contrasenya nova al moneder.&lt;br/&gt;Utilitzeu una contrasenya de &lt;b&gt;deu o més caràcters aleatoris&lt;/b&gt;, o &lt;b&gt;vuit o més paraules&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>Enter the old passphrase and new passphrase to the wallet.</source>
+ <translation>Introduïu la contrasenya antiga i la contrasenya nova al moneder.</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>L'encriptació del moneder ha fallat</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>L'encriptació del moneder ha fallat per un error intern. El moneder no ha estat encriptat.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>La contrasenya introduïda no coincideix.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>El desbloqueig del moneder ha fallat</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>La contrasenya introduïda per a desencriptar el moneder és incorrecta.</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>La desencriptació del moneder ha fallat</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>La contrasenya del moneder ha estat modificada correctament.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>Signa el &amp;missatge...</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>S'està sincronitzant amb la xarxa ...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;Panorama general</translation>
+ </message>
+ <message>
+ <source>Node</source>
+ <translation>Node</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>Mostra el panorama general del moneder</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Transaccions</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>Cerca a l'historial de transaccions</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>I&amp;x</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>Ix de l'aplicació</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>Quant a &amp;Qt</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>Mostra informació sobre Qt</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;Opcions...</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>&amp;Encripta el moneder...</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>&amp;Realitza una còpia de seguretat del moneder...</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>&amp;Canvia la contrasenya...</translation>
+ </message>
+ <message>
+ <source>&amp;Sending addresses...</source>
+ <translation>Adreces d'e&amp;nviament...</translation>
+ </message>
+ <message>
+ <source>&amp;Receiving addresses...</source>
+ <translation>Adreces de &amp;recepció</translation>
+ </message>
+ <message>
+ <source>Open &amp;URI...</source>
+ <translation>Obri un &amp;URI...</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core client</source>
+ <translation>Client del Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Importing blocks from disk...</source>
+ <translation>S'estan important els blocs del disc...</translation>
+ </message>
+ <message>
+ <source>Reindexing blocks on disk...</source>
+ <translation>S'estan reindexant els blocs al disc...</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>Envia monedes a una adreça Bitcoin</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>Realitza una còpia de seguretat del moneder a una altra ubicació</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Canvia la contrasenya d'encriptació del moneder</translation>
+ </message>
+ <message>
+ <source>&amp;Debug window</source>
+ <translation>&amp;Finestra de depuració</translation>
+ </message>
+ <message>
+ <source>Open debugging and diagnostic console</source>
+ <translation>Obri la consola de diagnòstic i depuració</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>&amp;Verifica el missatge...</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>Moneder</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>&amp;Envia</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>&amp;Rep</translation>
+ </message>
+ <message>
+ <source>Show information about Bitcoin Core</source>
+ <translation>Mostra informació del Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>&amp;Mostra / Amaga</translation>
+ </message>
+ <message>
+ <source>Show or hide the main Window</source>
+ <translation>Mostra o amaga la finestra principal</translation>
+ </message>
+ <message>
+ <source>Encrypt the private keys that belong to your wallet</source>
+ <translation>Encripta les claus privades pertanyents al moneder</translation>
+ </message>
+ <message>
+ <source>Sign messages with your Bitcoin addresses to prove you own them</source>
+ <translation>Signa el missatges amb la seua adreça de Bitcoin per provar que les poseeixes</translation>
+ </message>
+ <message>
+ <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source>
+ <translation>Verifiqueu els missatges per assegurar-vos que han estat signats amb una adreça Bitcoin específica.</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;Fitxer</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;Configuració</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>&amp;Ajuda</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>Barra d'eines de les pestanyes</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Nucli de Bitcoin</translation>
+ </message>
+ <message>
+ <source>Request payments (generates QR codes and bitcoin: URIs)</source>
+ <translation>Sol·licita pagaments (genera codis QR i bitcoin: URI)</translation>
+ </message>
+ <message>
+ <source>&amp;About Bitcoin Core</source>
+ <translation>&amp;Quant al Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Modify configuration options for Bitcoin Core</source>
+ <translation>Modifica les opcions de configuració del Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Show the list of used sending addresses and labels</source>
+ <translation>Mostra la llista d'adreces d'enviament i etiquetes utilitzades</translation>
+ </message>
+ <message>
+ <source>Show the list of used receiving addresses and labels</source>
+ <translation>Mostra la llista d'adreces de recepció i etiquetes utilitzades</translation>
+ </message>
+ <message>
+ <source>Open a bitcoin: URI or payment request</source>
+ <translation>Obri una bitcoin: sol·licitud d'URI o pagament</translation>
+ </message>
+ <message>
+ <source>&amp;Command-line options</source>
+ <translation>Opcions de la &amp;línia d'ordes</translation>
+ </message>
+ <message>
+ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
+ <translation>Mostra el missatge d'ajuda del Bitcoin Core per obtindre una llista amb les possibles opcions de línia d'ordes de Bitcoin</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n active connection(s) to Bitcoin network</source>
+ <translation><numerusform>%n connexió activa a la xarxa Bitcoin</numerusform><numerusform>%n connexions actives a la xarxa Bitcoin</numerusform></translation>
+ </message>
+ <message>
+ <source>No block source available...</source>
+ <translation>No hi ha cap font de bloc disponible...</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n hour(s)</source>
+ <translation><numerusform>%n hora</numerusform><numerusform>%n hores</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n day(s)</source>
+ <translation><numerusform>%n dia</numerusform><numerusform>%n dies</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n week(s)</source>
+ <translation><numerusform>%n setmana</numerusform><numerusform>%n setmanes</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 and %2</source>
+ <translation>%1 i %2</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n year(s)</source>
+ <translation><numerusform>%n any</numerusform><numerusform>%n anys</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 behind</source>
+ <translation>%1 darrere</translation>
+ </message>
+ <message>
+ <source>Last received block was generated %1 ago.</source>
+ <translation>El darrer bloc rebut ha estat generat fa %1.</translation>
+ </message>
+ <message>
+ <source>Transactions after this will not yet be visible.</source>
+ <translation>Les transaccions a partir d'això no seran visibles.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Error</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Avís</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Informació</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>Al dia</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>S'està posant al dia ...</translation>
+ </message>
+ <message>
+ <source>Date: %1
+</source>
+ <translation>Data: %1
+</translation>
+ </message>
+ <message>
+ <source>Amount: %1
+</source>
+ <translation>Import: %1
+</translation>
+ </message>
+ <message>
+ <source>Type: %1
+</source>
+ <translation>Tipus: %1
+</translation>
+ </message>
+ <message>
+ <source>Label: %1
+</source>
+ <translation>Etiqueta: %1
+</translation>
+ </message>
+ <message>
+ <source>Address: %1
+</source>
+ <translation>Adreça: %1
+</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>Transacció enviada</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>Transacció entrant</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>El moneder està &lt;b&gt;encriptat&lt;/b&gt; i actualment &lt;b&gt;desbloquejat&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>El moneder està &lt;b&gt;encriptat&lt;/b&gt; i actualment &lt;b&gt;bloquejat&lt;/b&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <source>Network Alert</source>
+ <translation>Alerta de xarxa</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Coin Selection</source>
+ <translation>Selecció de moneda</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Quantitat:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Bytes:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Import:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Prioritat:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Comissió</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Polsim:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Comissió posterior:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Canvi:</translation>
+ </message>
+ <message>
+ <source>(un)select all</source>
+ <translation>(des)selecciona-ho tot</translation>
+ </message>
+ <message>
+ <source>Tree mode</source>
+ <translation>Mode arbre</translation>
+ </message>
+ <message>
+ <source>List mode</source>
+ <translation>Mode llista</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Import</translation>
+ </message>
+ <message>
+ <source>Received with label</source>
+ <translation>Rebut amb l'etiqueta</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>Rebut amb l'adreça</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Confirmations</source>
+ <translation>Confirmacions</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Confirmat</translation>
+ </message>
+ <message>
+ <source>Priority</source>
+ <translation>Prioritat</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Copiar adreça </translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Copiar etiqueta</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copia l'import</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Copiar ID de transacció</translation>
+ </message>
+ <message>
+ <source>Lock unspent</source>
+ <translation>Bloqueja sense gastar</translation>
+ </message>
+ <message>
+ <source>Unlock unspent</source>
+ <translation>Desbloqueja sense gastar</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Copia la quantitat</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Copia la comissió</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Copia la comissió posterior</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Copia els bytes</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Copia la prioritat</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Copia el polsim</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Copia el canvi</translation>
+ </message>
+ <message>
+ <source>highest</source>
+ <translation>El més alt</translation>
+ </message>
+ <message>
+ <source>higher</source>
+ <translation>Més alt</translation>
+ </message>
+ <message>
+ <source>high</source>
+ <translation>Alt</translation>
+ </message>
+ <message>
+ <source>medium-high</source>
+ <translation>mig-alt</translation>
+ </message>
+ <message>
+ <source>medium</source>
+ <translation>mig</translation>
+ </message>
+ <message>
+ <source>low-medium</source>
+ <translation>baix-mig</translation>
+ </message>
+ <message>
+ <source>low</source>
+ <translation>baix</translation>
+ </message>
+ <message>
+ <source>lower</source>
+ <translation>més baix</translation>
+ </message>
+ <message>
+ <source>lowest</source>
+ <translation>el més baix</translation>
+ </message>
+ <message>
+ <source>(%1 locked)</source>
+ <translation>(%1 bloquejada)</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>cap</translation>
+ </message>
+ <message>
+ <source>This label turns red if the transaction size is greater than 1000 bytes.</source>
+ <translation>Esta etiqueta es torna en roig si la transacció és superior a 1000 bytes.</translation>
+ </message>
+ <message>
+ <source>This label turns red if the priority is smaller than "medium".</source>
+ <translation>Esta etiqueta es torna en roig si la propietat és inferior que la «mitjana».</translation>
+ </message>
+ <message>
+ <source>This label turns red if any recipient receives an amount smaller than %1.</source>
+ <translation>Esta etiqueta es torna roja si el destinatari rep un import inferior de %1.</translation>
+ </message>
+ <message>
+ <source>Can vary +/- %1 satoshi(s) per input.</source>
+ <translation>Pot variar +/- %1 satoshi(s) per entrada.</translation>
+ </message>
+ <message>
+ <source>yes</source>
+ <translation>sí</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>no</translation>
+ </message>
+ <message>
+ <source>This means a fee of at least %1 per kB is required.</source>
+ <translation>Això comporta una comissió d'almenys %1 per kB.</translation>
+ </message>
+ <message>
+ <source>Can vary +/- 1 byte per input.</source>
+ <translation>Pot variar +/- 1 byte per entrada.</translation>
+ </message>
+ <message>
+ <source>Transactions with higher priority are more likely to get included into a block.</source>
+ <translation>Les transaccions amb una major prioritat són més propenses a ser incloses en un bloc.</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(sense etiqueta)</translation>
+ </message>
+ <message>
+ <source>change from %1 (%2)</source>
+ <translation>canvia de %1 (%2)</translation>
+ </message>
+ <message>
+ <source>(change)</source>
+ <translation>(canvia)</translation>
+ </message>
+</context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>Edita l'adreça</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>&amp;Etiqueta</translation>
+ </message>
+ <message>
+ <source>The label associated with this address list entry</source>
+ <translation>L'etiqueta associada amb esta entrada de llista d'adreces</translation>
+ </message>
+ <message>
+ <source>The address associated with this address list entry. This can only be modified for sending addresses.</source>
+ <translation>L'adreça associada amb esta entrada de llista d'adreces. Només es pot modificar per a les adreces d'enviament.</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;Adreça</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>Nova adreça de recepció.</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>Nova adreça d'enviament</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>Edita les adreces de recepció</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>Edita les adreces d'enviament</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>L'adreça introduïda «%1» ja és present a la llibreta d'adreces.</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is not a valid Bitcoin address.</source>
+ <translation>L'adreça introduïda «%1» no és una adreça de Bitcoin vàlida.</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>No s'ha pogut desbloquejar el moneder.</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>Ha fallat la generació d'una nova clau.</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ <message>
+ <source>A new data directory will be created.</source>
+ <translation>Es crearà un nou directori de dades.</translation>
+ </message>
+ <message>
+ <source>name</source>
+ <translation>nom</translation>
+ </message>
+ <message>
+ <source>Directory already exists. Add %1 if you intend to create a new directory here.</source>
+ <translation>El directori ja existeix. Afig %1 si vols crear un nou directori en esta ubicació.</translation>
+ </message>
+ <message>
+ <source>Path already exists, and is not a directory.</source>
+ <translation>El camí ja existeix i no és cap directori.</translation>
+ </message>
+ <message>
+ <source>Cannot create data directory here.</source>
+ <translation>No es pot crear el directori de dades ací.</translation>
+ </message>
+</context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Nucli de Bitcoin</translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>versió</translation>
+ </message>
+ <message>
+ <source>(%1-bit)</source>
+ <translation>(%1-bit)</translation>
+ </message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>Quant al Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Command-line options</source>
+ <translation>Opcions de línia d'ordes</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>Ús:</translation>
+ </message>
+ <message>
+ <source>command-line options</source>
+ <translation>Opcions de la línia d'ordes</translation>
+ </message>
+</context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Welcome</source>
+ <translation>Vos donem la benviguda</translation>
+ </message>
+ <message>
+ <source>Welcome to Bitcoin Core.</source>
+ <translation>Vos donem la benvinguda al Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</source>
+ <translation>Atès que és la primera vegada que executeu el programa, podeu triar on emmagatzemarà el Bitcoin Core les dades.</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory.</source>
+ <translation>El Bitcoin Core descarregarà i emmagatzemarà una còpia de la cadena de blocs de Bitcoin. Com a mínim s'emmagatzemaran %1 GB de dades en este directori, que seguiran creixent gradualment. També s'hi emmagatzemarà el moneder.</translation>
+ </message>
+ <message>
+ <source>Use the default data directory</source>
+ <translation>Utilitza el directori de dades per defecte</translation>
+ </message>
+ <message>
+ <source>Use a custom data directory:</source>
+ <translation>Utilitza un directori de dades personalitzat:</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Nucli de Bitcoin</translation>
+ </message>
+ <message>
+ <source>Error: Specified data directory "%1" cannot be created.</source>
+ <translation>Error: el directori de dades «%1» especificat no pot ser creat.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Error</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n GB of free space available</source>
+ <translation><numerusform>%n GB d'espai lliure disponible</numerusform><numerusform>%n GB d'espai lliure disponible</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>(of %n GB needed)</source>
+ <translation><numerusform>(de %n GB necessari)</numerusform><numerusform>(de %n GB necessaris)</numerusform></translation>
+ </message>
+</context>
+<context>
+ <name>OpenURIDialog</name>
+ <message>
+ <source>Open URI</source>
+ <translation>Obri un URI</translation>
+ </message>
+ <message>
+ <source>Open payment request from URI or file</source>
+ <translation>Obri una sol·licitud de pagament des d'un URI o un fitxer</translation>
+ </message>
+ <message>
+ <source>URI:</source>
+ <translation>URI:</translation>
+ </message>
+ <message>
+ <source>Select payment request file</source>
+ <translation>Selecciona un fitxer de sol·licitud de pagament</translation>
+ </message>
+ <message>
+ <source>Select payment request file to open</source>
+ <translation>Selecciona el fitxer de sol·licitud de pagament per obrir</translation>
+ </message>
+</context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>Opcions</translation>
+ </message>
+ <message>
+ <source>&amp;Main</source>
+ <translation>&amp;Principal</translation>
+ </message>
+ <message>
+ <source>Size of &amp;database cache</source>
+ <translation>Mida de la memòria cau de la base de &amp;dades</translation>
+ </message>
+ <message>
+ <source>MB</source>
+ <translation>MB</translation>
+ </message>
+ <message>
+ <source>Number of script &amp;verification threads</source>
+ <translation>Nombre de fils de &amp;verificació d'scripts</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside</source>
+ <translation>Accepta connexions de fora</translation>
+ </message>
+ <message>
+ <source>Allow incoming connections</source>
+ <translation>Permet connexions entrants</translation>
+ </message>
+ <message>
+ <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
+ <translation>Adreça IP del proxy (p. ex. IPv4: 127.0.0.1 / IPv6: ::1)</translation>
+ </message>
+ <message>
+ <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source>
+ <translation>Minimitza en comptes d'eixir de l'aplicació quan la finestra es tanca. Quan s'habilita esta opció l'aplicació es tancara només quan se selecciona Ix del menú. </translation>
+ </message>
+ <message>
+ <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source>
+ <translation>La interfície d'usuari pot definir-se des d'ací. El paràmetre tindrà efecte després de reiniciar el Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source>
+ <translation>URL de terceres parts (p. ex. explorador de blocs) que apareix en la pestanya de transaccions com elements del menú contextual. %s en l'URL es reemplaçat pel resum de la transacció. Diferents URL estan separades per una barra vertical |.</translation>
+ </message>
+ <message>
+ <source>Third party transaction URLs</source>
+ <translation>URL de transaccions de terceres parts</translation>
+ </message>
+ <message>
+ <source>Active command-line options that override above options:</source>
+ <translation>Opcions de línies d'orde active que sobreescriuen les opcions de dalt:</translation>
+ </message>
+ <message>
+ <source>Reset all client options to default.</source>
+ <translation>Reestableix totes les opcions del client.</translation>
+ </message>
+ <message>
+ <source>&amp;Reset Options</source>
+ <translation>&amp;Reestableix les opcions</translation>
+ </message>
+ <message>
+ <source>&amp;Network</source>
+ <translation>&amp;Xarxa</translation>
+ </message>
+ <message>
+ <source>Automatically start Bitcoin Core after logging in to the system.</source>
+ <translation>Inicia el Bitcoin Core automàticament després d'iniciar una sessió en el sistema.</translation>
+ </message>
+ <message>
+ <source>&amp;Start Bitcoin Core on system login</source>
+ <translation>&amp;Inicia el Bitcoin Core en inciar el sistema</translation>
+ </message>
+ <message>
+ <source>(0 = auto, &lt;0 = leave that many cores free)</source>
+ <translation>(0 = auto, &lt;0 = deixa tants nuclis lliures)</translation>
+ </message>
+ <message>
+ <source>W&amp;allet</source>
+ <translation>&amp;Moneder</translation>
+ </message>
+ <message>
+ <source>Expert</source>
+ <translation>Expert</translation>
+ </message>
+ <message>
+ <source>Enable coin &amp;control features</source>
+ <translation>Activa les funcions de &amp;control de les monedes</translation>
+ </message>
+ <message>
+ <source>If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.</source>
+ <translation>Si inhabiliteu la despesa d'un canvi sense confirmar, el canvi d'una transacció no pot ser utilitzat fins que la transacció no tinga com a mínim una confirmació. Això també afecta com es calcula el vostre balanç.</translation>
+ </message>
+ <message>
+ <source>&amp;Spend unconfirmed change</source>
+ <translation>&amp;Gasta el canvi sense confirmar</translation>
+ </message>
+ <message>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>Obri el port del client de Bitcoin al router de forma automàtica. Això només funciona quan el router implementa UPnP i l'opció està activada.</translation>
+ </message>
+ <message>
+ <source>Map port using &amp;UPnP</source>
+ <translation>Port obert amb &amp;UPnP</translation>
+ </message>
+ <message>
+ <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
+ <translation>Connecta a la xarxa Bitcoin a través d'un proxy SOCKS5.</translation>
+ </message>
+ <message>
+ <source>&amp;Connect through SOCKS5 proxy (default proxy):</source>
+ <translation>&amp;Connecta a través d'un proxy SOCKS5 (proxy per defecte):</translation>
+ </message>
+ <message>
+ <source>Proxy &amp;IP:</source>
+ <translation>&amp;IP del proxy:</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>&amp;Port:</translation>
+ </message>
+ <message>
+ <source>Port of the proxy (e.g. 9050)</source>
+ <translation>Port del proxy (per exemple 9050)</translation>
+ </message>
+ <message>
+ <source>&amp;Window</source>
+ <translation>&amp;Finestra</translation>
+ </message>
+ <message>
+ <source>Show only a tray icon after minimizing the window.</source>
+ <translation>Mostra només la icona de la barra en minimitzar la finestra.</translation>
+ </message>
+ <message>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>&amp;Minimitza a la barra d'aplicacions en comptes de la barra de tasques</translation>
+ </message>
+ <message>
+ <source>M&amp;inimize on close</source>
+ <translation>M&amp;inimitza en tancar</translation>
+ </message>
+ <message>
+ <source>&amp;Display</source>
+ <translation>&amp;Pantalla</translation>
+ </message>
+ <message>
+ <source>User Interface &amp;language:</source>
+ <translation>&amp;Llengua de la interfície d'usuari:</translation>
+ </message>
+ <message>
+ <source>&amp;Unit to show amounts in:</source>
+ <translation>&amp;Unitats per mostrar els imports en:</translation>
+ </message>
+ <message>
+ <source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
+ <translation>Selecciona la unitat de subdivisió per defecte per mostrar en la interfície quan s'envien monedes.</translation>
+ </message>
+ <message>
+ <source>Whether to show coin control features or not.</source>
+ <translation>Si voleu mostrar les funcions de control de monedes o no.</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>&amp;D'acord</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>&amp;Cancel·la</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>Per defecte</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>cap</translation>
+ </message>
+ <message>
+ <source>Confirm options reset</source>
+ <translation>Confirmeu el reestabliment de les opcions</translation>
+ </message>
+ <message>
+ <source>Client restart required to activate changes.</source>
+ <translation>Cal reiniciar el client per activar els canvis.</translation>
+ </message>
+ <message>
+ <source>Client will be shut down. Do you want to proceed?</source>
+ <translation>Es pararà el client. Voleu procedir?</translation>
+ </message>
+ <message>
+ <source>This change would require a client restart.</source>
+ <translation>Amb este canvi cal un reinici del client.</translation>
+ </message>
+ <message>
+ <source>The supplied proxy address is invalid.</source>
+ <translation>L'adreça proxy introduïda és invalida.</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>Formulari</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>La informació mostrada pot no estar al día. El teu moneder es sincronitza automàticament amb la xarxa Bitcoin un cop s'ha establit connexió, però este proces no s'ha completat encara.</translation>
+ </message>
+ <message>
+ <source>Watch-only:</source>
+ <translation>Només lectura:</translation>
+ </message>
+ <message>
+ <source>Available:</source>
+ <translation>Disponible:</translation>
+ </message>
+ <message>
+ <source>Your current spendable balance</source>
+ <translation>El balanç que podeu gastar actualment</translation>
+ </message>
+ <message>
+ <source>Pending:</source>
+ <translation>Pendent:</translation>
+ </message>
+ <message>
+ <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source>
+ <translation>Total de transaccions que encara han de confirmar-se i que encara no compten en el balanç que es pot gastar</translation>
+ </message>
+ <message>
+ <source>Immature:</source>
+ <translation>Immadur:</translation>
+ </message>
+ <message>
+ <source>Mined balance that has not yet matured</source>
+ <translation>Balanç minat que encara no ha madurat</translation>
+ </message>
+ <message>
+ <source>Balances</source>
+ <translation>Balances</translation>
+ </message>
+ <message>
+ <source>Total:</source>
+ <translation>Total:</translation>
+ </message>
+ <message>
+ <source>Your current total balance</source>
+ <translation>El balanç total actual</translation>
+ </message>
+ <message>
+ <source>Your current balance in watch-only addresses</source>
+ <translation>El vostre balanç actual en adreces de només lectura</translation>
+ </message>
+ <message>
+ <source>Spendable:</source>
+ <translation>Que es pot gastar:</translation>
+ </message>
+ <message>
+ <source>Recent transactions</source>
+ <translation>Transaccions recents</translation>
+ </message>
+ <message>
+ <source>Unconfirmed transactions to watch-only addresses</source>
+ <translation>Transaccions sense confirmar a adreces de només lectura</translation>
+ </message>
+ <message>
+ <source>Mined balance in watch-only addresses that has not yet matured</source>
+ <translation>Balanç minat en adreces de només lectura que encara no ha madurat</translation>
+ </message>
+ <message>
+ <source>Current total balance in watch-only addresses</source>
+ <translation>Balanç total actual en adreces de només lectura</translation>
+ </message>
+</context>
+<context>
+ <name>PaymentServer</name>
+ <message>
+ <source>URI handling</source>
+ <translation>Gestió d'URI</translation>
+ </message>
+ <message>
+ <source>Invalid payment address %1</source>
+ <translation>Adreça de pagament no vàlida %1</translation>
+ </message>
+ <message>
+ <source>Payment request rejected</source>
+ <translation>La sol·licitud de pagament s'ha rebutjat</translation>
+ </message>
+ <message>
+ <source>Payment request network doesn't match client network.</source>
+ <translation>La xarxa de la sol·licitud de pagament no coincideix amb la xarxa del client.</translation>
+ </message>
+ <message>
+ <source>Payment request is not initialized.</source>
+ <translation>La sol·licitud de pagament no està inicialitzada.</translation>
+ </message>
+ <message>
+ <source>Requested payment amount of %1 is too small (considered dust).</source>
+ <translation>L'import de pagament sol·licitat %1 és massa petit (es considera polsim).</translation>
+ </message>
+ <message>
+ <source>Payment request error</source>
+ <translation>Error en la sol·licitud de pagament</translation>
+ </message>
+ <message>
+ <source>Cannot start bitcoin: click-to-pay handler</source>
+ <translation>No es pot iniciar bitcoin: gestor clica-per-pagar</translation>
+ </message>
+ <message>
+ <source>Payment request fetch URL is invalid: %1</source>
+ <translation>L'URL de recuperació de la sol·licitud de pagament no és vàlida: %1</translation>
+ </message>
+ <message>
+ <source>URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source>
+ <translation>L'URI no pot ser analitzat! Això pot ser a causa d'una adreça de Bitcoin no vàlida o per paràmetres URI amb mal format.</translation>
+ </message>
+ <message>
+ <source>Payment request file handling</source>
+ <translation>Gestió de fitxers de les sol·licituds de pagament</translation>
+ </message>
+ <message>
+ <source>Payment request file cannot be read! This can be caused by an invalid payment request file.</source>
+ <translation>No es pot llegir el fitxer de la sol·licitud de pagament. Això pot ser causat per un fitxer de sol·licitud de pagament no vàlid.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>La sol·licitud de pagament ha vençut.</translation>
+ </message>
+ <message>
+ <source>Unverified payment requests to custom payment scripts are unsupported.</source>
+ <translation>No s'accepten sol·licituds de pagament no verificades a scripts de pagament personalitzats.</translation>
+ </message>
+ <message>
+ <source>Invalid payment request.</source>
+ <translation>Sol·licitud de pagament no vàlida.</translation>
+ </message>
+ <message>
+ <source>Refund from %1</source>
+ <translation>Reemborsament de %1</translation>
+ </message>
+ <message>
+ <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source>
+ <translation>La sol·licitud de pagament %1 és massa gran (%2 bytes, permés %3 bytes).</translation>
+ </message>
+ <message>
+ <source>Payment request DoS protection</source>
+ <translation>Protecció de DoS per a la sol·licitud de pagament</translation>
+ </message>
+ <message>
+ <source>Error communicating with %1: %2</source>
+ <translation>Error en comunicar amb %1: %2</translation>
+ </message>
+ <message>
+ <source>Payment request cannot be parsed!</source>
+ <translation>No es pot analitzar la sol·licitud de pagament!</translation>
+ </message>
+ <message>
+ <source>Bad response from server %1</source>
+ <translation>Mala resposta del servidor %1</translation>
+ </message>
+ <message>
+ <source>Payment acknowledged</source>
+ <translation>Pagament reconegut</translation>
+ </message>
+ <message>
+ <source>Network request error</source>
+ <translation>Error en la sol·licitud de xarxa</translation>
+ </message>
+</context>
+<context>
+ <name>PeerTableModel</name>
+ <message>
+ <source>User Agent</source>
+ <translation>Agent d'usuari</translation>
+ </message>
+ <message>
+ <source>Node/Service</source>
+ <translation>Node/Servei</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Temps de ping</translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>Import</translation>
+ </message>
+ <message>
+ <source>Enter a Bitcoin address (e.g. %1)</source>
+ <translation>Introduïu una adreça de Bitcoin (p. ex. %1)</translation>
+ </message>
+ <message>
+ <source>%1 d</source>
+ <translation>%1 d</translation>
+ </message>
+ <message>
+ <source>%1 h</source>
+ <translation>%1 h</translation>
+ </message>
+ <message>
+ <source>%1 m</source>
+ <translation>%1 m</translation>
+ </message>
+ <message>
+ <source>%1 s</source>
+ <translation>%1 s</translation>
+ </message>
+ <message>
+ <source>None</source>
+ <translation>Cap</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>N/A</translation>
+ </message>
+ <message>
+ <source>%1 ms</source>
+ <translation>%1 ms</translation>
+ </message>
+</context>
+<context>
+ <name>QRImageWidget</name>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Guarda la imatge...</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Image</source>
+ <translation>&amp;Copia la imatge</translation>
+ </message>
+ <message>
+ <source>Save QR Code</source>
+ <translation>Guarda el codi QR</translation>
+ </message>
+ <message>
+ <source>PNG Image (*.png)</source>
+ <translation>Imatge PNG (*.png)</translation>
+ </message>
+</context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>Client name</source>
+ <translation>Nom del client</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>N/A</translation>
+ </message>
+ <message>
+ <source>Client version</source>
+ <translation>Versió del client</translation>
+ </message>
+ <message>
+ <source>&amp;Information</source>
+ <translation>&amp;Informació</translation>
+ </message>
+ <message>
+ <source>Debug window</source>
+ <translation>Finestra de depuració</translation>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>General</translation>
+ </message>
+ <message>
+ <source>Using OpenSSL version</source>
+ <translation>Utilitzant OpenSSL versió</translation>
+ </message>
+ <message>
+ <source>Using BerkeleyDB version</source>
+ <translation>Utilitzant BerkeleyDB versió</translation>
+ </message>
+ <message>
+ <source>Startup time</source>
+ <translation>&amp;Temps d'inici</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Xarxa</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>Nom</translation>
+ </message>
+ <message>
+ <source>Number of connections</source>
+ <translation>Nombre de connexions</translation>
+ </message>
+ <message>
+ <source>Block chain</source>
+ <translation>Cadena de blocs</translation>
+ </message>
+ <message>
+ <source>Current number of blocks</source>
+ <translation>Nombre de blocs actuals</translation>
+ </message>
+ <message>
+ <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source>
+ <translation>Obri el fitxer de registre de depuració del Bitcoin Core del directori de dades actual. Pot portar uns quants segons per a fitxers de registre grans.</translation>
+ </message>
+ <message>
+ <source>Received</source>
+ <translation>Rebut</translation>
+ </message>
+ <message>
+ <source>Sent</source>
+ <translation>Enviat</translation>
+ </message>
+ <message>
+ <source>&amp;Peers</source>
+ <translation>&amp;Iguals</translation>
+ </message>
+ <message>
+ <source>Select a peer to view detailed information.</source>
+ <translation>Seleccioneu un igual per mostrar informació detallada.</translation>
+ </message>
+ <message>
+ <source>Direction</source>
+ <translation>Direcció</translation>
+ </message>
+ <message>
+ <source>Version</source>
+ <translation>Versió</translation>
+ </message>
+ <message>
+ <source>User Agent</source>
+ <translation>Agent d'usuari</translation>
+ </message>
+ <message>
+ <source>Services</source>
+ <translation>Serveis</translation>
+ </message>
+ <message>
+ <source>Starting Height</source>
+ <translation>Alçada inicial</translation>
+ </message>
+ <message>
+ <source>Sync Height</source>
+ <translation>Sincronitza l'alçada</translation>
+ </message>
+ <message>
+ <source>Ban Score</source>
+ <translation>Puntuació de bandeig</translation>
+ </message>
+ <message>
+ <source>Connection Time</source>
+ <translation>Temps de connexió</translation>
+ </message>
+ <message>
+ <source>Last Send</source>
+ <translation>Darrer enviament</translation>
+ </message>
+ <message>
+ <source>Last Receive</source>
+ <translation>Darrera recepció</translation>
+ </message>
+ <message>
+ <source>Bytes Sent</source>
+ <translation>Bytes enviats</translation>
+ </message>
+ <message>
+ <source>Bytes Received</source>
+ <translation>Bytes rebuts</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Temps de ping</translation>
+ </message>
+ <message>
+ <source>Time Offset</source>
+ <translation>Diferència horària</translation>
+ </message>
+ <message>
+ <source>Last block time</source>
+ <translation>Últim temps de bloc</translation>
+ </message>
+ <message>
+ <source>&amp;Open</source>
+ <translation>&amp;Obri</translation>
+ </message>
+ <message>
+ <source>&amp;Console</source>
+ <translation>&amp;Consola</translation>
+ </message>
+ <message>
+ <source>&amp;Network Traffic</source>
+ <translation>Trà&amp;nsit de la xarxa</translation>
+ </message>
+ <message>
+ <source>&amp;Clear</source>
+ <translation>Nete&amp;ja</translation>
+ </message>
+ <message>
+ <source>Totals</source>
+ <translation>Totals</translation>
+ </message>
+ <message>
+ <source>In:</source>
+ <translation>Dins:</translation>
+ </message>
+ <message>
+ <source>Out:</source>
+ <translation>Fora:</translation>
+ </message>
+ <message>
+ <source>Build date</source>
+ <translation>Data de compilació</translation>
+ </message>
+ <message>
+ <source>Debug log file</source>
+ <translation>Fitxer de registre de depuració</translation>
+ </message>
+ <message>
+ <source>Clear console</source>
+ <translation>Neteja la consola</translation>
+ </message>
+ <message>
+ <source>Welcome to the Bitcoin Core RPC console.</source>
+ <translation>Vos donem la benviguda a la consola RPC del Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
+ <translation>Utilitza les fletxes d'amunt i avall per navegar per l'historial, i &lt;b&gt;Ctrl-L&lt;\b&gt; per netejar la pantalla.</translation>
+ </message>
+ <message>
+ <source>Type &lt;b&gt;help&lt;/b&gt; for an overview of available commands.</source>
+ <translation>Escriviu &lt;b&gt;help&lt;\b&gt; per a obtindre un llistat de les ordes disponibles.</translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation>%1 B</translation>
+ </message>
+ <message>
+ <source>%1 KB</source>
+ <translation>%1 KB</translation>
+ </message>
+ <message>
+ <source>%1 MB</source>
+ <translation>%1 MB</translation>
+ </message>
+ <message>
+ <source>%1 GB</source>
+ <translation>%1 GB</translation>
+ </message>
+ <message>
+ <source>via %1</source>
+ <translation>a través de %1</translation>
+ </message>
+ <message>
+ <source>never</source>
+ <translation>mai</translation>
+ </message>
+ <message>
+ <source>Inbound</source>
+ <translation>Entrant</translation>
+ </message>
+ <message>
+ <source>Outbound</source>
+ <translation>Eixint</translation>
+ </message>
+ <message>
+ <source>Unknown</source>
+ <translation>Desconegut</translation>
+ </message>
+ <message>
+ <source>Fetching...</source>
+ <translation>S'està obtenint...</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Amount:</source>
+ <translation>Im&amp;port:</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Etiqueta:</translation>
+ </message>
+ <message>
+ <source>&amp;Message:</source>
+ <translation>&amp;Missatge:</translation>
+ </message>
+ <message>
+ <source>Reuse one of the previously used receiving addresses. Reusing addresses has security and privacy issues. Do not use this unless re-generating a payment request made before.</source>
+ <translation>Reutilitza una de les adreces de recepció utilitzades anteriorment. La reutilització d'adreces pot comportar problemes de seguretat i privadesa. No ho utilitzeu llevat que torneu a generar una sol·licitud de pagament feta abans.</translation>
+ </message>
+ <message>
+ <source>R&amp;euse an existing receiving address (not recommended)</source>
+ <translation>R&amp;eutilitza una adreça de recepció anterior (no recomanat)</translation>
+ </message>
+ <message>
+ <source>An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network.</source>
+ <translation>Un missatge opcional que s'adjuntarà a la sol·licitud de pagament, que es mostrarà quan s'òbriga la sol·licitud. Nota: El missatge no s'enviarà amb el pagament per la xarxa Bitcoin.</translation>
+ </message>
+ <message>
+ <source>An optional label to associate with the new receiving address.</source>
+ <translation>Una etiqueta opcional que s'associarà amb la nova adreça receptora.</translation>
+ </message>
+ <message>
+ <source>Use this form to request payments. All fields are &lt;b&gt;optional&lt;/b&gt;.</source>
+ <translation>Utilitzeu este formulari per sol·licitar pagaments. Tots els camps són &lt;b&gt;opcionals&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>An optional amount to request. Leave this empty or zero to not request a specific amount.</source>
+ <translation>Un import opcional per sol·licitar. Deixeu-ho en blanc o zero per no sol·licitar cap import específic.</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Esborra tots els camps del formuari.</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation>Neteja</translation>
+ </message>
+ <message>
+ <source>Requested payments history</source>
+ <translation>Historial de pagaments sol·licitats</translation>
+ </message>
+ <message>
+ <source>&amp;Request payment</source>
+ <translation>&amp;Sol·licitud de pagament</translation>
+ </message>
+ <message>
+ <source>Show the selected request (does the same as double clicking an entry)</source>
+ <translation>Mostra la sol·licitud seleccionada (fa el mateix que el doble clic a una entrada)</translation>
+ </message>
+ <message>
+ <source>Show</source>
+ <translation>Mostra</translation>
+ </message>
+ <message>
+ <source>Remove the selected entries from the list</source>
+ <translation>Esborra les entrades seleccionades de la llista</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>Esborra</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Copia l'etiqueta</translation>
+ </message>
+ <message>
+ <source>Copy message</source>
+ <translation>Copia el missatge</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copia l'import</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>QR Code</source>
+ <translation>Codi QR</translation>
+ </message>
+ <message>
+ <source>Copy &amp;URI</source>
+ <translation>Copia l'&amp;URI</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Address</source>
+ <translation>Copia l'&amp;adreça</translation>
+ </message>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Guarda la imatge...</translation>
+ </message>
+ <message>
+ <source>Request payment to %1</source>
+ <translation>Sol·licita un pagament a %1</translation>
+ </message>
+ <message>
+ <source>Payment information</source>
+ <translation>Informació de pagament</translation>
+ </message>
+ <message>
+ <source>URI</source>
+ <translation>URI</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adreça</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Import</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiqueta</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Missatge</translation>
+ </message>
+ <message>
+ <source>Resulting URI too long, try to reduce the text for label / message.</source>
+ <translation>URI resultant massa llarga, intenta reduir el text per a la etiqueta / missatge</translation>
+ </message>
+ <message>
+ <source>Error encoding URI into QR Code.</source>
+ <translation>Error en codificar l'URI en un codi QR.</translation>
+ </message>
+</context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiqueta</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Missatge</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Import</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(sense etiqueta)</translation>
+ </message>
+ <message>
+ <source>(no message)</source>
+ <translation>(sense missatge)</translation>
+ </message>
+ <message>
+ <source>(no amount)</source>
+ <translation>(sense import)</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Envia monedes</translation>
+ </message>
+ <message>
+ <source>Coin Control Features</source>
+ <translation>Característiques de control de les monedes</translation>
+ </message>
+ <message>
+ <source>Inputs...</source>
+ <translation>Entrades...</translation>
+ </message>
+ <message>
+ <source>automatically selected</source>
+ <translation>seleccionat automàticament</translation>
+ </message>
+ <message>
+ <source>Insufficient funds!</source>
+ <translation>Fons insuficients!</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Quantitat:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Bytes:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Import:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Prioritat:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Comissió:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Comissió posterior:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Canvi:</translation>
+ </message>
+ <message>
+ <source>If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address.</source>
+ <translation>Si s'activa això, però l'adreça de canvi està buida o bé no és vàlida, el canvi s'enviarà a una adreça generada de nou.</translation>
+ </message>
+ <message>
+ <source>Custom change address</source>
+ <translation>Personalitza l'adreça de canvi</translation>
+ </message>
+ <message>
+ <source>Transaction Fee:</source>
+ <translation>Comissió de transacció</translation>
+ </message>
+ <message>
+ <source>Choose...</source>
+ <translation>Tria...</translation>
+ </message>
+ <message>
+ <source>collapse fee-settings</source>
+ <translation>redueix els paràmetres de comissió</translation>
+ </message>
+ <message>
+ <source>per kilobyte</source>
+ <translation>per kilobyte</translation>
+ </message>
+ <message>
+ <source>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "total at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source>
+ <translation>Si la comissió personalitzada es defineix a 1000 satoshis i la transacció és de només 250 bytes, llavors «per kilobyte» només es paguen 250 satoshis en una comissió, mentre que amb la de «total com a mínim» es pagarien 1000 satoshis. Per a transaccions superiors al kilobyte, en tots dos casos es paga per kilobyte.</translation>
+ </message>
+ <message>
+ <source>Hide</source>
+ <translation>Amaga</translation>
+ </message>
+ <message>
+ <source>total at least</source>
+ <translation>total com a mínim</translation>
+ </message>
+ <message>
+ <source>Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process.</source>
+ <translation>No hi ha cap problema en pagar només la comissió mínima sempre que hi haja menys volum de transacció que espai en els blocs. Però tingueu present que això pot acabar en una transacció que mai es confirme una vegada hi haja més demanda de transaccions de bitcoins que la xarxa puga processar.</translation>
+ </message>
+ <message>
+ <source>(read the tooltip)</source>
+ <translation>(llegiu l'indicador de funció)</translation>
+ </message>
+ <message>
+ <source>Recommended:</source>
+ <translation>Recomanada:</translation>
+ </message>
+ <message>
+ <source>Custom:</source>
+ <translation>Personalitzada:</translation>
+ </message>
+ <message>
+ <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source>
+ <translation>(No s'ha inicialitzat encara la comissió intel·ligent. Normalment pren uns pocs blocs...)</translation>
+ </message>
+ <message>
+ <source>Confirmation time:</source>
+ <translation>Temps de confirmació:</translation>
+ </message>
+ <message>
+ <source>normal</source>
+ <translation>normal</translation>
+ </message>
+ <message>
+ <source>fast</source>
+ <translation>ràpid</translation>
+ </message>
+ <message>
+ <source>Send as zero-fee transaction if possible</source>
+ <translation>Envia com a transacció de comissió zero si és possible</translation>
+ </message>
+ <message>
+ <source>(confirmation may take longer)</source>
+ <translation>(la confirmació pot trigar més temps)</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>Envia a múltiples destinataris al mateix temps</translation>
+ </message>
+ <message>
+ <source>Add &amp;Recipient</source>
+ <translation>Afig &amp;destinatari</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Netejar tots els camps del formulari.</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Polsim:</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Neteja-ho &amp;tot</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>Balanç:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>Confirma l'acció d'enviament</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>E&amp;nvia</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>Confirma l'enviament de monedes</translation>
+ </message>
+ <message>
+ <source>%1 to %2</source>
+ <translation>%1 a %2</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Copia la quantitat</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copia l'import</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Copia la comissió</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Copia la comissió posterior</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Copia els bytes</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Copia la prioritat</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Copia el canvi</translation>
+ </message>
+ <message>
+ <source>or</source>
+ <translation>o</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>L'import a pagar ha de ser major que 0.</translation>
+ </message>
+ <message>
+ <source>The amount exceeds your balance.</source>
+ <translation>L'import supera el vostre balanç.</translation>
+ </message>
+ <message>
+ <source>The total exceeds your balance when the %1 transaction fee is included.</source>
+ <translation>El total excedeix el teu balanç quan s'afig la comissió a la transacció %1.</translation>
+ </message>
+ <message>
+ <source>Transaction creation failed!</source>
+ <translation>Ha fallat la creació de la transacció!</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>S'ha rebutjat la transacció! Això pot passar si alguna de les monedes del vostre moneder ja s'han gastat; per exemple, si heu fet servir una còpia de seguretat del fitxer wallet.dat i s'hagueren gastat monedes de la còpia però sense marcar-les-hi com a gastades.</translation>
+ </message>
+ <message>
+ <source>A fee higher than %1 is considered an absurdly high fee.</source>
+ <translation>Una comissió superior a %1 es considera una comissió absurdament alta.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>La sol·licitud de pagament ha vençut.</translation>
+ </message>
+ <message numerus="yes">
+ <source>Estimated to begin confirmation within %n block(s).</source>
+ <translation><numerusform>Estimat per començar la confirmació en %n bloc.</numerusform><numerusform>Estimat per començar la confirmació en %n blocs.</numerusform></translation>
+ </message>
+ <message>
+ <source>Pay only the minimum fee of %1</source>
+ <translation>Paga només la comissió mínima de %1</translation>
+ </message>
+ <message>
+ <source>The recipient address is not valid. Please recheck.</source>
+ <translation>L'adreça de destinatari no és vàlida. Torneu-la a comprovar.</translation>
+ </message>
+ <message>
+ <source>Duplicate address found: addresses should only be used once each.</source>
+ <translation>S'ha trobat una adreça duplicada: cal utilitzar les adreces només un cop cada vegada.</translation>
+ </message>
+ <message>
+ <source>Warning: Invalid Bitcoin address</source>
+ <translation>Avís: adreça Bitcoin no vàlida</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(sense etiqueta)</translation>
+ </message>
+ <message>
+ <source>Warning: Unknown change address</source>
+ <translation>Avís: adreça de canvi desconeguda</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Copia el polsim</translation>
+ </message>
+ <message>
+ <source>Are you sure you want to send?</source>
+ <translation>Esteu segur que ho voleu enviar?</translation>
+ </message>
+ <message>
+ <source>added as transaction fee</source>
+ <translation>S'ha afegit una taxa de transacció</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>Q&amp;uantitat:</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>Paga &amp;a:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Introduïu una etiqueta per a esta adreça per afegir-la a la llibreta d'adreces</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Etiqueta:</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Trieu una adreça feta servir anteriorment</translation>
+ </message>
+ <message>
+ <source>This is a normal payment.</source>
+ <translation>Això és un pagament normal.</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to send the payment to</source>
+ <translation>L'adreça Bitcoin on enviar el pagament</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alta+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Apegar adreça del porta-retalls</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Remove this entry</source>
+ <translation>Elimina esta entrada</translation>
+ </message>
+ <message>
+ <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source>
+ <translation>La comissió es deduirà de l'import que s'enviarà. El destinatari rebrà menys bitcoins que les que introduïu al camp d'import. Si se seleccionen múltiples destinataris, la comissió es dividirà per igual.</translation>
+ </message>
+ <message>
+ <source>S&amp;ubtract fee from amount</source>
+ <translation>S&amp;ubstreu la comissió de l'import</translation>
+ </message>
+ <message>
+ <source>Message:</source>
+ <translation>Missatge:</translation>
+ </message>
+ <message>
+ <source>This is an unauthenticated payment request.</source>
+ <translation>Esta és una sol·licitud de pagament no autenticada.</translation>
+ </message>
+ <message>
+ <source>This is an authenticated payment request.</source>
+ <translation>Esta és una sol·licitud de pagament autenticada.</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to the list of used addresses</source>
+ <translation>Introduïu una etiqueta per a esta adreça per afegir-la a la llista d'adreces utilitzades</translation>
+ </message>
+ <message>
+ <source>A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network.</source>
+ <translation>Un missatge que s'ha adjuntat al bitcoin: URI que s'emmagatzemarà amb la transacció per a la vostra referència. Nota: el missatge no s'enviarà a través de la xarxa Bitcoin.</translation>
+ </message>
+ <message>
+ <source>Pay To:</source>
+ <translation>Paga a:</translation>
+ </message>
+ <message>
+ <source>Memo:</source>
+ <translation>Memo:</translation>
+ </message>
+</context>
+<context>
+ <name>ShutdownWindow</name>
+ <message>
+ <source>Bitcoin Core is shutting down...</source>
+ <translation>S'està parant el Bitcoin Core...</translation>
+ </message>
+ <message>
+ <source>Do not shut down the computer until this window disappears.</source>
+ <translation>No apagueu l'ordinador fins que no desaparegui esta finestra.</translation>
+ </message>
+</context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Signatures - Sign / Verify a Message</source>
+ <translation>Signatures - Signa / verifica un missatge</translation>
+ </message>
+ <message>
+ <source>&amp;Sign Message</source>
+ <translation>&amp;Signa el missatge</translation>
+ </message>
+ <message>
+ <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source>
+ <translation>Podeu signar missatges/acords amb les vostres adreces per provar que rebeu les bitcoins que s'hi envien. Aneu amb compte no signar res que siga vague o aleatori, perquè en alguns atacs de suplantació es pot provar que hi signeu la vostra identitat. Només signeu aquelles declaracions completament detallades en què hi esteu d'acord. </translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to sign the message with</source>
+ <translation>L'adreça Bitcoin amb què signar el missatge</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Tria les adreces fetes servir amb anterioritat</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Apega l'adreça del porta-retalls</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Enter the message you want to sign here</source>
+ <translation>Introduïu ací el missatge que voleu signar</translation>
+ </message>
+ <message>
+ <source>Signature</source>
+ <translation>Signatura</translation>
+ </message>
+ <message>
+ <source>Copy the current signature to the system clipboard</source>
+ <translation>Copia la signatura actual al porta-retalls del sistema</translation>
+ </message>
+ <message>
+ <source>Sign the message to prove you own this Bitcoin address</source>
+ <translation>Signa el missatge per provar que ets propietari d'esta adreça Bitcoin</translation>
+ </message>
+ <message>
+ <source>Sign &amp;Message</source>
+ <translation>Signa el &amp;missatge</translation>
+ </message>
+ <message>
+ <source>Reset all sign message fields</source>
+ <translation>Neteja tots els camps de clau</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Neteja-ho &amp;tot</translation>
+ </message>
+ <message>
+ <source>&amp;Verify Message</source>
+ <translation>&amp;Verifica el missatge</translation>
+ </message>
+ <message>
+ <source>Enter the receiver's 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. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source>
+ <translation>Introduïu l'adreça del receptor, el missatge (assegureu-vos de copiar els salts de línia, espais, tabuladors, etc. exactament) i signatura de sota per verificar el missatge. Tingueu cura de no llegir més en la signatura del que està al missatge signat, per evitar ser enganyat per un atac d'home-en-el-mig. Tingueu en compte que això només demostra que la part que signa rep amb l'adreça, i no es pot provar l'enviament de qualsevol transacció!</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address the message was signed with</source>
+ <translation>L'adreça Bitcoin amb què va ser signat el missatge</translation>
+ </message>
+ <message>
+ <source>Verify the message to ensure it was signed with the specified Bitcoin address</source>
+ <translation>Verificar el missatge per assegurar-se que ha estat signat amb una adreça Bitcoin específica</translation>
+ </message>
+ <message>
+ <source>Verify &amp;Message</source>
+ <translation>Verifica el &amp;missatge</translation>
+ </message>
+ <message>
+ <source>Reset all verify message fields</source>
+ <translation>Neteja tots els camps de verificació de missatge</translation>
+ </message>
+ <message>
+ <source>Click "Sign Message" to generate signature</source>
+ <translation>Feu clic a «Signa el missatge» per a generar una signatura</translation>
+ </message>
+ <message>
+ <source>The entered address is invalid.</source>
+ <translation>L'adreça introduïda no és vàlida.</translation>
+ </message>
+ <message>
+ <source>Please check the address and try again.</source>
+ <translation>Comproveu l'adreça i torneu-ho a provar.</translation>
+ </message>
+ <message>
+ <source>The entered address does not refer to a key.</source>
+ <translation>L'adreça introduïda no referencia a cap clau.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock was cancelled.</source>
+ <translation>El desbloqueig del moneder ha estat cancelat.</translation>
+ </message>
+ <message>
+ <source>Private key for the entered address is not available.</source>
+ <translation>La clau privada per a la adreça introduïda no està disponible.</translation>
+ </message>
+ <message>
+ <source>Message signing failed.</source>
+ <translation>La signatura del missatge ha fallat.</translation>
+ </message>
+ <message>
+ <source>Message signed.</source>
+ <translation>Missatge signat.</translation>
+ </message>
+ <message>
+ <source>The signature could not be decoded.</source>
+ <translation>La signatura no s'ha pogut descodificar.</translation>
+ </message>
+ <message>
+ <source>Please check the signature and try again.</source>
+ <translation>Comproveu la signatura i torneu-ho a provar.</translation>
+ </message>
+ <message>
+ <source>The signature did not match the message digest.</source>
+ <translation>La signatura no coincideix amb el resum del missatge.</translation>
+ </message>
+ <message>
+ <source>Message verification failed.</source>
+ <translation>Ha fallat la verificació del missatge.</translation>
+ </message>
+ <message>
+ <source>Message verified.</source>
+ <translation>Missatge verificat.</translation>
+ </message>
+</context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>The Bitcoin Core developers</source>
+ <translation>Els desenvolupadors del Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>[testnet]</source>
+ <translation>[testnet]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ <message>
+ <source>KB/s</source>
+ <translation>KB/s</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>Obert fins %1</translation>
+ </message>
+ <message>
+ <source>conflicted</source>
+ <translation>en conflicte</translation>
+ </message>
+ <message>
+ <source>%1/offline</source>
+ <translation>%1/fora de línia</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/sense confirmar</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 confirmacions</translation>
+ </message>
+ <message>
+ <source>Status</source>
+ <translation>Estat</translation>
+ </message>
+ <message numerus="yes">
+ <source>, broadcast through %n node(s)</source>
+ <translation><numerusform>, difusió a través de %n node</numerusform><numerusform>, difusió a través de %n nodes</numerusform></translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Source</source>
+ <translation>Font</translation>
+ </message>
+ <message>
+ <source>Generated</source>
+ <translation>Generat</translation>
+ </message>
+ <message>
+ <source>From</source>
+ <translation>Des de</translation>
+ </message>
+ <message>
+ <source>To</source>
+ <translation>A</translation>
+ </message>
+ <message>
+ <source>own address</source>
+ <translation>Adreça pròpia</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>només lectura</translation>
+ </message>
+ <message>
+ <source>label</source>
+ <translation>etiqueta</translation>
+ </message>
+ <message>
+ <source>Credit</source>
+ <translation>Crèdit</translation>
+ </message>
+ <message numerus="yes">
+ <source>matures in %n more block(s)</source>
+ <translation><numerusform>madura en %n bloc més</numerusform><numerusform>madura en %n blocs més</numerusform></translation>
+ </message>
+ <message>
+ <source>not accepted</source>
+ <translation>no acceptat</translation>
+ </message>
+ <message>
+ <source>Debit</source>
+ <translation>Dèbit</translation>
+ </message>
+ <message>
+ <source>Total debit</source>
+ <translation>Dèbit total</translation>
+ </message>
+ <message>
+ <source>Total credit</source>
+ <translation>Crèdit total</translation>
+ </message>
+ <message>
+ <source>Transaction fee</source>
+ <translation>Comissió de transacció</translation>
+ </message>
+ <message>
+ <source>Net amount</source>
+ <translation>Import net</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Missatge</translation>
+ </message>
+ <message>
+ <source>Comment</source>
+ <translation>Comentar</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>ID de transacció</translation>
+ </message>
+ <message>
+ <source>Merchant</source>
+ <translation>Mercader</translation>
+ </message>
+ <message>
+ <source>Generated coins must mature %1 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.</source>
+ <translation>Les monedes generades han de madurar %1 blocs abans de poder ser gastades. Quan genereu este bloc, es farà saber a la xarxa per tal d'afegir-lo a la cadena de blocs. Si no pot fer-se lloc a la cadena, el seu estat canviarà a «no acceptat» i no es podrà gastar. Això pot passar ocasionalment si un altre node genera un bloc en un marge de segons respecte al vostre.</translation>
+ </message>
+ <message>
+ <source>Debug information</source>
+ <translation>Informació de depuració</translation>
+ </message>
+ <message>
+ <source>Transaction</source>
+ <translation>Transacció</translation>
+ </message>
+ <message>
+ <source>Inputs</source>
+ <translation>Entrades</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Import</translation>
+ </message>
+ <message>
+ <source>true</source>
+ <translation>cert</translation>
+ </message>
+ <message>
+ <source>false</source>
+ <translation>fals</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, encara no ha estat emés correctement</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Obri per %n bloc més</numerusform><numerusform>Obri per %n blocs més</numerusform></translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>desconegut</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>Detall de la transacció</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>Este panell mostra una descripció detallada de la transacció</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Tipus</translation>
+ </message>
+ <message>
+ <source>Immature (%1 confirmations, will be available after %2)</source>
+ <translation>Immadur (%1 confirmacions, serà disponible després de %2)</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Obri per %n bloc més</numerusform><numerusform>Obri per %n blocs més</numerusform></translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>Obert fins %1</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>Confirmat (%1 confirmacions)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>Este bloc no ha estat rebut per cap altre node i probablement no serà acceptat!</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>Generat però no acceptat</translation>
+ </message>
+ <message>
+ <source>Offline</source>
+ <translation>Fora de línia</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiqueta</translation>
+ </message>
+ <message>
+ <source>Unconfirmed</source>
+ <translation>Sense confirmar</translation>
+ </message>
+ <message>
+ <source>Confirming (%1 of %2 recommended confirmations)</source>
+ <translation>Confirmant (%1 de %2 confirmacions recomanades)</translation>
+ </message>
+ <message>
+ <source>Conflicted</source>
+ <translation>En conflicte</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Rebut amb</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>Rebut de</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Enviat a</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>Pagament a un mateix</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Minat</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>només lectura</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(n/a)</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>Estat de la transacció. Desplaceu-vos sobre este camp per mostrar el nombre de confirmacions.</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Data i hora en que la transacció va ser rebuda.</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>Tipus de transacció.</translation>
+ </message>
+ <message>
+ <source>Whether or not a watch-only address is involved in this transaction.</source>
+ <translation>Si està implicada o no una adreça només de lectura en la transacció.</translation>
+ </message>
+ <message>
+ <source>User-defined intent/purpose of the transaction.</source>
+ <translation>Intenció/propòsit de la transacció definida per l'usuari.</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>Import extret o afegit del balanç.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>Tot</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>Hui</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>Esta setmana</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>Este mes</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>El mes passat</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>Enguany</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>Rang...</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Rebut amb</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Enviat a</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>A un mateix</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Minat</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>Altres</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>Introduïu una adreça o una etiqueta per cercar</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>Import mínim</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Copia l'adreça</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Copiar etiqueta</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copia l'import</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Copiar ID de transacció</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>Editar etiqueta</translation>
+ </message>
+ <message>
+ <source>Show transaction details</source>
+ <translation>Mostra detalls de la transacció</translation>
+ </message>
+ <message>
+ <source>Export Transaction History</source>
+ <translation>Exporta l'historial de transacció</translation>
+ </message>
+ <message>
+ <source>Watch-only</source>
+ <translation>Només de lectura</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>L'exportació ha fallat</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the transaction history to %1.</source>
+ <translation>S'ha produït un error en provar de guardar l'historial de transacció a %1.</translation>
+ </message>
+ <message>
+ <source>Exporting Successful</source>
+ <translation>Exportació amb èxit</translation>
+ </message>
+ <message>
+ <source>The transaction history was successfully saved to %1.</source>
+ <translation>L'historial de transaccions s'ha guardat correctament a %1.</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Fitxer separat per comes (*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Confirmat</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Tipus</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiqueta</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adreça</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>Rang:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>a</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ <message>
+ <source>Unit to show amounts in. Click to select another unit.</source>
+ <translation>Unitat en què mostrar els imports. Feu clic per seleccionar una altra unitat.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletFrame</name>
+ <message>
+ <source>No wallet has been loaded.</source>
+ <translation>No s'ha carregat cap moneder.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Envia monedes</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Exporta</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Exporta les dades de la pestanya actual a un fitxer</translation>
+ </message>
+ <message>
+ <source>Backup Wallet</source>
+ <translation>Còpia de seguretat del moneder</translation>
+ </message>
+ <message>
+ <source>Wallet Data (*.dat)</source>
+ <translation>Dades del moneder (*.dat)</translation>
+ </message>
+ <message>
+ <source>Backup Failed</source>
+ <translation>Ha fallat la còpia de seguretat</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the wallet data to %1.</source>
+ <translation>S'ha produït un error en provar de guardar les dades del moneder a %1.</translation>
+ </message>
+ <message>
+ <source>The wallet data was successfully saved to %1.</source>
+ <translation>S'han guardat les dades del moneder correctament a %1.</translation>
+ </message>
+ <message>
+ <source>Backup Successful</source>
+ <translation>La còpia de seguretat s'ha realitzat correctament</translation>
+ </message>
+</context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>Opcions:</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>Especifica el directori de dades</translation>
+ </message>
+ <message>
+ <source>Connect to a node to retrieve peer addresses, and disconnect</source>
+ <translation>Connecta al node per obtindre les adreces de les connexions, i desconnecta</translation>
+ </message>
+ <message>
+ <source>Specify your own public address</source>
+ <translation>Especifiqueu la vostra adreça pública</translation>
+ </message>
+ <message>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>Accepta la línia d'ordes i ordes JSON-RPC </translation>
+ </message>
+ <message>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>Executa en segon pla com a programa dimoni i accepta ordes</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>Utilitza la xarxa de prova</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
+ <translation>Accepta connexions de fora (per defecte: 1 si no -proxy o -connect)</translation>
+ </message>
+ <message>
+ <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
+ <translation>Vincula a una adreça específica i sempre escolta-hi. Utilitza la notació [host]:port per IPv6</translation>
+ </message>
+ <message>
+ <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
+ <translation>Elimina totes les transaccions del moneder i només recupera aquelles de la cadena de blocs a través de -rescan a l'inici</translation>
+ </message>
+ <message>
+ <source>Distributed under the MIT software license, see the accompanying file COPYING or &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</source>
+ <translation>Distribuït sota llicència de programari MIT. Vegeu el fitxer acompanyant COPYING o &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</translation>
+ </message>
+ <message>
+ <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
+ <translation>Executa una orde quan una transacció del moneder canvie (%s en cmd es canvia per TxID)</translation>
+ </message>
+ <message>
+ <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source>
+ <translation>Comissions totals màximes que s'utilitzaran en una única transacció de moneder; si s'estableix un valor massa baix es poden interrompre transaccions grans (per defecte: %s)</translation>
+ </message>
+ <message>
+ <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, &gt;%u = target size in MiB to use for block files)</source>
+ <translation>Redueix els requeriments d'emmagatzemament podant (suprimint) els blocs antics. Este mode inhabilita l'ús de moneders i és incompatible amb -tindex. Avís: Revertir esta configuració comporta tornar a baixar la cadena de blocs sencera. (per defecte: 0 = inhabilita la poda de blocs, &gt;%u = mida objectiu en MiB per utilitzar els fitxers de blocs)</translation>
+ </message>
+ <message>
+ <source>Set the number of script verification threads (%u to %d, 0 = auto, &lt;0 = leave that many cores free, default: %d)</source>
+ <translation>Defineix el nombre de fils de verificació d'scripts (%u a %d, 0 = auto, &lt;0 = deixa tants nuclis lliures, per defecte: %d)</translation>
+ </message>
+ <message>
+ <source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source>
+ <translation>Esta és una versió de pre-llançament - utilitza-la sota la teva responsabilitat - No usar per a minería o aplicacions de compra-venda</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer. Bitcoin Core is probably already running.</source>
+ <translation>No es pot enllaçar %s a este ordinador. El Bitcoin Core probablement ja estiga executant-s'hi.</translation>
+ </message>
+ <message>
+ <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>AVÍS: s'ha generat un nombre anòmalament alt de blocs, %d blocs rebuts en les darreres %d hores (se n'esperaven %d)</translation>
+ </message>
+ <message>
+ <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>AVÍS: comproveu la vostra connexió a la xarxa, %d blocs rebuts en les darreres %d hores (se n'esperaven %d)</translation>
+ </message>
+ <message>
+ <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>Avís: el -paytxfee és molt elevat! Esta és la comissió de transacció que pagareu si envieu una transacció.</translation>
+ </message>
+ <message>
+ <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source>
+ <translation>Avís: la xarxa no pareix que hi estiga plenament d'acord. Alguns miners pareix que estan experimentant problemes.</translation>
+ </message>
+ <message>
+ <source>Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.</source>
+ <translation>Avís: pareix que no estem plenament d'acord amb els nostres iguals! Podria caldre que actualitzar l'aplicació, o potser que ho facen altres nodes.</translation>
+ </message>
+ <message>
+ <source>Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
+ <translation>Avís: error en llegir el fitxer wallet.dat! Totes les claus es lligen correctament, però hi ha dades de transaccions o entrades de la llibreta d'adreces absents o bé son incorrectes.</translation>
+ </message>
+ <message>
+ <source>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</source>
+ <translation>Avís: el fitxer wallet.dat és corrupte, dades rescatades! L'arxiu wallet.dat original ha estat guardat com wallet.{estampa_temporal}.bak al directori %s; si el teu balanç o transaccions son incorrectes hauries de restaurar-lo de un backup.</translation>
+ </message>
+ <message>
+ <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source>
+ <translation>Afig a la llista blanca els iguals que es connecten de la màscara de xarxa o adreça IP donada. Es pot especificar moltes vegades.</translation>
+ </message>
+ <message>
+ <source>(default: 1)</source>
+ <translation>(per defecte: 1)</translation>
+ </message>
+ <message>
+ <source>&lt;category&gt; can be:</source>
+ <translation>&lt;category&gt; pot ser:</translation>
+ </message>
+ <message>
+ <source>Attempt to recover private keys from a corrupt wallet.dat</source>
+ <translation>Intenta recuperar les claus privades d'un fitxer wallet.dat corrupte</translation>
+ </message>
+ <message>
+ <source>Block creation options:</source>
+ <translation>Opcions de la creació de blocs:</translation>
+ </message>
+ <message>
+ <source>Connect only to the specified node(s)</source>
+ <translation>Connecta només al(s) node(s) especificats</translation>
+ </message>
+ <message>
+ <source>Connection options:</source>
+ <translation>Opcions de connexió:</translation>
+ </message>
+ <message>
+ <source>Corrupted block database detected</source>
+ <translation>S'ha detectat una base de dades de blocs corrupta</translation>
+ </message>
+ <message>
+ <source>Debugging/Testing options:</source>
+ <translation>Opcions de depuració/proves:</translation>
+ </message>
+ <message>
+ <source>Do not load the wallet and disable wallet RPC calls</source>
+ <translation>No carreguis el moneder i inhabilita les crides RPC del moneder</translation>
+ </message>
+ <message>
+ <source>Do you want to rebuild the block database now?</source>
+ <translation>Voleu reconstruir la base de dades de blocs ara?</translation>
+ </message>
+ <message>
+ <source>Error initializing block database</source>
+ <translation>Error carregant la base de dades de blocs</translation>
+ </message>
+ <message>
+ <source>Error initializing wallet database environment %s!</source>
+ <translation>Error inicialitzant l'entorn de la base de dades del moneder %s!</translation>
+ </message>
+ <message>
+ <source>Error loading block database</source>
+ <translation>Error carregant la base de dades del bloc</translation>
+ </message>
+ <message>
+ <source>Error opening block database</source>
+ <translation>Error en obrir la base de dades de blocs</translation>
+ </message>
+ <message>
+ <source>Error: Disk space is low!</source>
+ <translation>Error: Espai al disc baix!</translation>
+ </message>
+ <message>
+ <source>Failed to listen on any port. Use -listen=0 if you want this.</source>
+ <translation>Ha fallat escoltar a qualsevol port. Feu servir -listen=0 si voleu fer això.</translation>
+ </message>
+ <message>
+ <source>If &lt;category&gt; is not supplied, output all debugging information.</source>
+ <translation>Si no se subministra &lt;category&gt;, mostra tota la informació de depuració.</translation>
+ </message>
+ <message>
+ <source>Importing...</source>
+ <translation>S'està important...</translation>
+ </message>
+ <message>
+ <source>Incorrect or no genesis block found. Wrong datadir for network?</source>
+ <translation>No s'ha trobat el bloc de gènesi o és incorrecte. El directori de dades de la xarxa és incorrecte?</translation>
+ </message>
+ <message>
+ <source>Invalid -onion address: '%s'</source>
+ <translation>Adreça -onion no vàlida: '%s'</translation>
+ </message>
+ <message>
+ <source>Not enough file descriptors available.</source>
+ <translation>No hi ha suficient descriptors de fitxers disponibles.</translation>
+ </message>
+ <message>
+ <source>Only connect to nodes in network &lt;net&gt; (ipv4, ipv6 or onion)</source>
+ <translation>Només connecta als nodes de la xarxa &lt;net&gt; (ipv4, ipv6 o onion)</translation>
+ </message>
+ <message>
+ <source>Prune cannot be configured with a negative value.</source>
+ <translation>La poda no es pot configurar amb un valor negatiu.</translation>
+ </message>
+ <message>
+ <source>Prune mode is incompatible with -txindex.</source>
+ <translation>El mode de poda és incompatible amb -txindex.</translation>
+ </message>
+ <message>
+ <source>Set database cache size in megabytes (%d to %d, default: %d)</source>
+ <translation>Defineix la mida de la memòria cau de la base de dades en megabytes (%d a %d, per defecte: %d)</translation>
+ </message>
+ <message>
+ <source>Set maximum block size in bytes (default: %d)</source>
+ <translation>Defineix la mida màxim del bloc en bytes (per defecte: %d)</translation>
+ </message>
+ <message>
+ <source>Specify wallet file (within data directory)</source>
+ <translation>Especifica un fitxer de moneder (dins del directori de dades)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: %u)</source>
+ <translation>Utilitza UPnP per a mapejar el port d'escolta (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Verifying blocks...</source>
+ <translation>S'estan verificant els blocs...</translation>
+ </message>
+ <message>
+ <source>Verifying wallet...</source>
+ <translation>S'està verificant el moneder...</translation>
+ </message>
+ <message>
+ <source>Wallet %s resides outside data directory %s</source>
+ <translation>El moneder %s resideix fora del directori de dades %s</translation>
+ </message>
+ <message>
+ <source>Wallet options:</source>
+ <translation>Opcions de moneder:</translation>
+ </message>
+ <message>
+ <source>Warning: This version is obsolete; upgrade required!</source>
+ <translation>Avís: esta versió és obsoleta; cal actualitzar-la!</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to change -txindex</source>
+ <translation>Cal que reconstruïu la base de dades fent servir -reindex per canviar -txindex</translation>
+ </message>
+ <message>
+ <source>Imports blocks from external blk000??.dat file</source>
+ <translation>Importa blocs d'un fitxer blk000??.dat extern</translation>
+ </message>
+ <message>
+ <source>Allow JSON-RPC connections from specified source. Valid for &lt;ip&gt; are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times</source>
+ <translation>Permet les connexions JSON-RPC d'una font específica. Vàlid per a &lt;ip&gt; són una IP individual (p. ex., 1.2.3.4), una xarxa / màscara de xarxa (p. ex., 1.2.3.4/255.255.255.0) o una xarxa/CIDR (p. ex., 1.2.3.4/24). Es pot especificar esta opció moltes vegades</translation>
+ </message>
+ <message>
+ <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source>
+ <translation>Vincula l'adreça donada i posa a la llista blanca els iguals que s'hi connecten. Feu servir la notació [host]:port per a IPv6</translation>
+ </message>
+ <message>
+ <source>Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)</source>
+ <translation>Vincula a l'adreça donada per a escoltar les connexions JSON-RPC. Feu servir la notació [host]:port per a IPv6. Esta opció pot ser especificada moltes vegades (per defecte: vincula a totes les interfícies)</translation>
+ </message>
+ <message>
+ <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source>
+ <translation>No es pot obtindre un bloqueig del directori de dades %s. El Bitcoin Core probablement ja s'estiga executant.</translation>
+ </message>
+ <message>
+ <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
+ <translation>Crea fitxers nous amb els permisos per defecte del sistema, en comptes de l'umask 077 (només efectiu amb la funcionalitat de moneder inhabilitada)</translation>
+ </message>
+ <message>
+ <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source>
+ <translation>Descobreix l'adreça IP pròpia (per defecte: 1 quan s'escolta i no -externalip o -proxy)</translation>
+ </message>
+ <message>
+ <source>Error: Listening for incoming connections failed (listen returned error %s)</source>
+ <translation>Error: ha fallat escoltar les connexions entrants (l'escoltament ha retornat l'error %s)</translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source>
+ <translation>Error: s'ha trobat un argument no permés de -socks. Ja no es pot definir més la versió de SOCKS, només s'accepten els proxies de SOCKS5.ç</translation>
+ </message>
+ <message>
+ <source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source>
+ <translation>Executa l'orde quan es reba un avís rellevant o veiem una forquilla molt llarga (%s en cmd és reemplaçat per un missatge)</translation>
+ </message>
+ <message>
+ <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source>
+ <translation>Comissions (en BTC/Kb) inferiors a això es consideren de comissió zero per a la transmissió (per defecte: %s)</translation>
+ </message>
+ <message>
+ <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
+ <translation>Si no s'especifica una paytxfee (comissió de transacció de pagament), inclogueu suficient comissió per tal que les transaccions comencen a confirmar-se en una mitja de n blocs (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)</source>
+ <translation>Import no vàlid per a -maxtxfee=&lt;amount&gt;: '%s' (cal que siga com a mínim la comissió de minrelay de %s per evitar que les comissions s'encallin)</translation>
+ </message>
+ <message>
+ <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source>
+ <translation>Mida màxima de les dades en les transaccions de l'operador en què confiem i en les meues (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Prune configured below the minimum of %d MB. Please use a higher number.</source>
+ <translation>Poda configurada per sota el mínim de %d MB. Feu servir un nombre superior.</translation>
+ </message>
+ <message>
+ <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source>
+ <translation>Consulta a adreces d'iguals a través de DNS, si es troba baix en adreces (per defecte: 1 a menys que -connect)</translation>
+ </message>
+ <message>
+ <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source>
+ <translation>Genera a l'atzar credencials per a cada connexió proxy. Això habilita l'aïllament del flux de Tor (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
+ <translation>Defineix la mida màxima de transaccions d'alta prioritat / baixa comissió en bytes (per defecte: %d)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source>
+ <translation>Defineix el nombre de fils per a la generació de moneda si està habilitat (-1 = tots els nuclis, per defecte: %d)</translation>
+ </message>
+ <message>
+ <source>The transaction amount is too small to send after the fee has been deducted</source>
+ <translation>L'import de la transacció és massa petit per enviar-la després que se'n deduïsca la comissió</translation>
+ </message>
+ <message>
+ <source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit &lt;https://www.openssl.org/&gt; and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source>
+ <translation>Este producte inclou programari desenvolupat pel projecte OpenSSL per a ús a l'OpenSSL Toolkit &lt;https://www.openssl.org/&gt; i programari criptogràfic escrit per Eric Young i programari UPnP escrit per Thomas Bernard.</translation>
+ </message>
+ <message>
+ <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an 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)
+The username and password MUST NOT be the same.
+If the file does not exist, create it with owner-readable-only file permissions.
+It is also recommended to set alertnotify so you are notified of problems;
+for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
+</source>
+ <translation>Per utilitzar bitcoind, o l'opció de serviddor de bitcoin-qt, heu de definir una rpcpassword en el fitxer de configuració:
+%s
+Es recomana que utilitzeu la contrasenya aleatòria següent:
+rpcuser=bitcoinrpc
+rpcpassword=%s
+(no cal que recordeu la contrasenya)
+El nom d'usuari i la contrasenya NO han de ser els mateixos.
+Si el fitxer no existeix, creeu-ne un amb permisos de lectura només per al seu propietari.
+Es recomana definir alertnotify per tal de ser notificat de qualsevol problema;
+per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</translation>
+ </message>
+ <message>
+ <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source>
+ <translation>Avís: s'ha especificat un -maxtxfee molt alt! Comissions tan grans podrien pagar-se en una única transacció.</translation>
+ </message>
+ <message>
+ <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source>
+ <translation>Avís: comproveu que la data i hora del vostre ordinador siguen correctes! Si el vostre rellotge no és correcte, el Bitcoin Core no funcionarà correctament.</translation>
+ </message>
+ <message>
+ <source>Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway</source>
+ <translation>Els iguals en la llista blanca no poden ser bandejats per DoS i es transmetran sempre llurs transaccions, fins i tot si ja són a la mempool. Això és útil, p. ex., per a una passarel·la</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source>
+ <translation>Cal que torneu a construir la base de dades fent servir -reindex per tornar al mode no podat. Això tornarà a baixar la cadena de blocs sencera</translation>
+ </message>
+ <message>
+ <source>(default: %u)</source>
+ <translation>(per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Accept public REST requests (default: %u)</source>
+ <translation>Accepta sol·licituds REST públiques (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Activating best chain...</source>
+ <translation>S'està activant la millor cadena...</translation>
+ </message>
+ <message>
+ <source>Can't run with a wallet in prune mode.</source>
+ <translation>No es pot executar amb un moneder en mode poda.</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -whitebind address: '%s'</source>
+ <translation>No es pot resoldre l'adreça -whitebind: «%s»</translation>
+ </message>
+ <message>
+ <source>Choose data directory on startup (default: 0)</source>
+ <translation>Tria el directori de dades a l'inici (per defecte: 0)</translation>
+ </message>
+ <message>
+ <source>Connect through SOCKS5 proxy</source>
+ <translation>Connecta a través del proxy SOCKS5</translation>
+ </message>
+ <message>
+ <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source>
+ <translation>Copyright (C) 2009-%i Els desenvolupadors del Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Could not parse -rpcbind value %s as network address</source>
+ <translation>No s'ha pogut analitzar el valor -rpcbind %s com una adreça de xarxa</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source>
+ <translation>Error en carregar wallet.dat: el moneder requereix una versió més nova del Bitcoin core</translation>
+ </message>
+ <message>
+ <source>Error reading from database, shutting down.</source>
+ <translation>Error en llegir la base de dades, tancant.</translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -tor found, use -onion.</source>
+ <translation>Error: s'ha trobat un argument -tor no acceptat. Feu servir -onion.</translation>
+ </message>
+ <message>
+ <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source>
+ <translation>Comissió en (BTC/kB) per afegir a les transaccions que envieu (per defecte: %s)</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>&amp;Informació</translation>
+ </message>
+ <message>
+ <source>Initialization sanity check failed. Bitcoin Core is shutting down.</source>
+ <translation>Ha fallat la inicialització de la comprovació de validesa. El Bitcoin Core s'està parant.</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Import no vàlid per a -maxtxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -minrelaytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Import no vàlid per a -minrelaytxfee=&lt;amount&gt;: «%s»</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -mintxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Import no vàlid per a -mintxfee=&lt;amount&gt;: «%s»</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s' (must be at least %s)</source>
+ <translation>Import no vàlid per a -paytxfee=&lt;amount&gt;: «%s» (ha de ser com a mínim %s)</translation>
+ </message>
+ <message>
+ <source>Invalid netmask specified in -whitelist: '%s'</source>
+ <translation>S'ha especificat una màscara de xarxa no vàlida a -whitelist: «%s»</translation>
+ </message>
+ <message>
+ <source>Keep at most &lt;n&gt; unconnectable transactions in memory (default: %u)</source>
+ <translation>Manté com a màxim &lt;n&gt; transaccions no connectables en memòria (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Need to specify a port with -whitebind: '%s'</source>
+ <translation>Cal especificar un port amb -whitebind: «%s»</translation>
+ </message>
+ <message>
+ <source>Node relay options:</source>
+ <translation>Opcions de transmissió del node:</translation>
+ </message>
+ <message>
+ <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source>
+ <translation>Opcions RPC SSL: (veieu el wiki del Bitcoin per a instruccions de configuració de l'SSL)</translation>
+ </message>
+ <message>
+ <source>RPC server options:</source>
+ <translation>Opcions del servidor RPC:</translation>
+ </message>
+ <message>
+ <source>RPC support for HTTP persistent connections (default: %d)</source>
+ <translation>Suport RPC per a connexions HTTP persistents (per defecte: %d)</translation>
+ </message>
+ <message>
+ <source>Rebuild block chain index from current blk000??.dat files on startup</source>
+ <translation>Reconstrueix l'índex de la cadena de blocs dels fitxers blk000??.dat actuals a l'inici.</translation>
+ </message>
+ <message>
+ <source>Receive and display P2P network alerts (default: %u)</source>
+ <translation>Rep i mostra avisos de la xarxa P2P (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>Envia informació de traça/depuració a la consola en comptes del fitxer debug.log</translation>
+ </message>
+ <message>
+ <source>Send transactions as zero-fee transactions if possible (default: %u)</source>
+ <translation>Envia les transaccions com a transaccions de comissió zero sempre que siga possible (per defecte: %u) </translation>
+ </message>
+ <message>
+ <source>Set SSL root certificates for payment request (default: -system-)</source>
+ <translation>Defineix certificats arrel SSL per a la sol·licitud de pagament (per defecte: -sistema-)</translation>
+ </message>
+ <message>
+ <source>Set language, for example "de_DE" (default: system locale)</source>
+ <translation>Defineix un idioma, per exemple «de_DE» (per defecte: preferències locals de sistema)</translation>
+ </message>
+ <message>
+ <source>Show all debugging options (usage: --help -help-debug)</source>
+ <translation>Mostra totes les opcions de depuració (ús: --help --help-debug)</translation>
+ </message>
+ <message>
+ <source>Show splash screen on startup (default: 1)</source>
+ <translation>Mostra la finestra de benvinguda a l'inici (per defecte: 1)</translation>
+ </message>
+ <message>
+ <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source>
+ <translation>Redueix el fitxer debug.log durant l'inici del client (per defecte: 1 quan no -debug)</translation>
+ </message>
+ <message>
+ <source>Signing transaction failed</source>
+ <translation>Ha fallat la signatura de la transacció</translation>
+ </message>
+ <message>
+ <source>Start minimized</source>
+ <translation>Inicia minimitzat</translation>
+ </message>
+ <message>
+ <source>The transaction amount is too small to pay the fee</source>
+ <translation>L'import de la transacció és massa petit per pagar-ne una comissió</translation>
+ </message>
+ <message>
+ <source>This is experimental software.</source>
+ <translation>Això és programari experimental.</translation>
+ </message>
+ <message>
+ <source>Transaction amount too small</source>
+ <translation>Import de la transacció massa petit</translation>
+ </message>
+ <message>
+ <source>Transaction amounts must be positive</source>
+ <translation>Els imports de les transaccions han de ser positius</translation>
+ </message>
+ <message>
+ <source>Transaction too large for fee policy</source>
+ <translation>Transacció massa gran per a la política de comissions</translation>
+ </message>
+ <message>
+ <source>Transaction too large</source>
+ <translation>La transacció és massa gran</translation>
+ </message>
+ <message>
+ <source>UI Options:</source>
+ <translation>Opcions d'interfície:</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer (bind returned error %s)</source>
+ <translation>No s'ha pogut vincular a %s en este ordinador (la vinculació ha retornat l'error %s)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: 1 when listening)</source>
+ <translation>Utilitza UPnP per a mapejar els ports d'escolta (per defecte: 1 quan s'escolta)</translation>
+ </message>
+ <message>
+ <source>Username for JSON-RPC connections</source>
+ <translation>Nom d'usuari per a connexions JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Wallet needed to be rewritten: restart Bitcoin Core to complete</source>
+ <translation>Cal reescriure el moneder: reiniceu el Bitcoin Core per completar-ho.</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Avís</translation>
+ </message>
+ <message>
+ <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source>
+ <translation>Avís: s'ha ignorat l'argument no acceptat de -benchmark. Feu servir -debug=bench.</translation>
+ </message>
+ <message>
+ <source>Warning: Unsupported argument -debugnet ignored, use -debug=net.</source>
+ <translation>Avís: s'ha ignorat l'argument no acceptat de -debugnet. Feu servir -debug=net.</translation>
+ </message>
+ <message>
+ <source>Zapping all transactions from wallet...</source>
+ <translation>Se suprimeixen totes les transaccions del moneder...</translation>
+ </message>
+ <message>
+ <source>on startup</source>
+ <translation>a l'inici de l'aplicació</translation>
+ </message>
+ <message>
+ <source>wallet.dat corrupt, salvage failed</source>
+ <translation>El fitxer wallet.data és corrupte. El rescat de les dades ha fallat</translation>
+ </message>
+ <message>
+ <source>Password for JSON-RPC connections</source>
+ <translation>Contrasenya per a connexions JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
+ <translation>Executa l'orde quan el millor bloc canvie (%s en cmd es reemplaça per un resum de bloc)</translation>
+ </message>
+ <message>
+ <source>Upgrade wallet to latest format</source>
+ <translation>Actualitza el moneder a l'últim format</translation>
+ </message>
+ <message>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>Reescaneja la cadena de blocs en les transaccions de moneder perdudes</translation>
+ </message>
+ <message>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>Utilitza OpenSSL (https) per a connexions JSON-RPC</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>Este misatge d'ajuda</translation>
+ </message>
+ <message>
+ <source>Allow DNS lookups for -addnode, -seednode and -connect</source>
+ <translation>Permet consultes DNS per a -addnode, -seednode i -connect</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>S'estan carregant les adreces...</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>Error en carregar wallet.dat: Moneder corrupte</translation>
+ </message>
+ <message>
+ <source>(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source>
+ <translation>(1 = manté les metadades de les tx, p. ex., propietari del compte i informació de sol·licitud del pagament, 2 = prescindeix de les metadades de les tx)</translation>
+ </message>
+ <message>
+ <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
+ <translation>Com d'exhaustiva és la verificació de blocs del -checkblocks (0-4, per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
+ <translation>Manté un índex complet de transaccions, utilitzat per la crida rpc getrawtransaction (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source>
+ <translation>Nombre de segons necessaris perquè els iguals de comportament qüestionable puguen tornar a connectar-se (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Output debugging information (default: %u, supplying &lt;category&gt; is optional)</source>
+ <translation>Informació d'eixida de la depuració (per defecte: %u, proporcionar &lt;category&gt; és opcional)</translation>
+ </message>
+ <message>
+ <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source>
+ <translation>Utilitza un proxy SOCKS4 apart per a arribar als iguals a través de serveis ocults de Tor (per defecte: %s)</translation>
+ </message>
+ <message>
+ <source>(default: %s)</source>
+ <translation>(per defecte: %s)</translation>
+ </message>
+ <message>
+ <source>Acceptable ciphers (default: %s)</source>
+ <translation>Xifrats acceptables (per defecte: %s)</translation>
+ </message>
+ <message>
+ <source>Always query for peer addresses via DNS lookup (default: %u)</source>
+ <translation>Demana sempre les adreces dels iguals a través de consultes DNS (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>Error en carregar wallet.dat</translation>
+ </message>
+ <message>
+ <source>Generate coins (default: %u)</source>
+ <translation>Genera monedes (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>How many blocks to check at startup (default: %u, 0 = all)</source>
+ <translation>Quants blocs per comprovar a l'inici (per defecte: %u, 0 = tots)</translation>
+ </message>
+ <message>
+ <source>Include IP addresses in debug output (default: %u)</source>
+ <translation>Inclou l'adreça IP a l'eixida de depuració (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Invalid -proxy address: '%s'</source>
+ <translation>Adreça -proxy invalida: '%s'</translation>
+ </message>
+ <message>
+ <source>Listen for JSON-RPC connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>Escolta les connexions JSON-RPC en &lt;port&gt; (per defecte: %u o testnet: %u)</translation>
+ </message>
+ <message>
+ <source>Listen for connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>Escolta les connexions en &lt;port&gt; (per defecte: %u o testnet: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain at most &lt;n&gt; connections to peers (default: %u)</source>
+ <translation>Manté com a màxim &lt;n&gt; connexions a iguals (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Make the wallet broadcast transactions</source>
+ <translation>Fes que el moneder faça difusió de les transaccions</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection receive buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>Memòria intermèdia màxima de recepció per connexió, &lt;n&gt;*1000 bytes (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection send buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>Memòria intermèdia màxima d'enviament per connexió, &lt;n&gt;*1000 bytes (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Prepend debug output with timestamp (default: %u)</source>
+ <translation>Posa davant de l'eixida de depuració una marca horària (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Relay and mine data carrier transactions (default: %u)</source>
+ <translation>Retransmet i mina les transaccions de l'operador (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Relay non-P2SH multisig (default: %u)</source>
+ <translation>Retransmet multisig no P2SH (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Server certificate file (default: %s)</source>
+ <translation>Fitxer de certificat del servidor (per defecte: %s)</translation>
+ </message>
+ <message>
+ <source>Server private key (default: %s)</source>
+ <translation>Clau privada del servidor (per defecte: %s)</translation>
+ </message>
+ <message>
+ <source>Set key pool size to &lt;n&gt; (default: %u)</source>
+ <translation>Defineix la mida clau disponible a &lt;n&gt; (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Set minimum block size in bytes (default: %u)</source>
+ <translation>Defineix la mida de bloc mínima en bytes (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads to service RPC calls (default: %d)</source>
+ <translation>Defineix el nombre de fils a crides de servei RPC (per defecte: %d)</translation>
+ </message>
+ <message>
+ <source>Specify configuration file (default: %s)</source>
+ <translation>Especifica el fitxer de configuració (per defecte: %s)</translation>
+ </message>
+ <message>
+ <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source>
+ <translation>Especifica el temps d'espera de la connexió en milisegons (mínim: 1, per defecte: %d)</translation>
+ </message>
+ <message>
+ <source>Specify pid file (default: %s)</source>
+ <translation>Especifica el fitxer pid (per defecte: %s)</translation>
+ </message>
+ <message>
+ <source>Spend unconfirmed change when sending transactions (default: %u)</source>
+ <translation>Gasta el canvi no confirmat en enviar les transaccions (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Threshold for disconnecting misbehaving peers (default: %u)</source>
+ <translation>Llindar per a desconnectar els iguals de comportament qüestionable (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Unknown network specified in -onlynet: '%s'</source>
+ <translation>Xarxa desconeguda especificada a -onlynet: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -bind address: '%s'</source>
+ <translation>No es pot resoldre l'adreça -bind: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -externalip address: '%s'</source>
+ <translation>No es pot resoldre l'adreça -externalip: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Import no vàlid per a -paytxfee=&lt;amount&gt;: «%s»</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>Balanç insuficient</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>S'està carregant l'índex de blocs...</translation>
+ </message>
+ <message>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>Afig un node per a connectar-s'hi i intenta mantindre-hi la connexió oberta</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>S'està carregant el moneder...</translation>
+ </message>
+ <message>
+ <source>Cannot downgrade wallet</source>
+ <translation>No es pot reduir la versió del moneder</translation>
+ </message>
+ <message>
+ <source>Cannot write default address</source>
+ <translation>No es pot escriure l'adreça per defecte</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>S'està reescanejant...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>Ha acabat la càrrega</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Error</translation>
+ </message>
+</context>
+</TS> \ 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 0000000000..cb68f98162
--- /dev/null
+++ b/src/qt/locale/bitcoin_ca_ES.ts
@@ -0,0 +1,3575 @@
+<TS language="ca_ES" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Right-click to edit address or label</source>
+ <translation>Feu clic dret per a editar l'adreça o l'etiqueta</translation>
+ </message>
+ <message>
+ <source>Create a new address</source>
+ <translation>Crea una nova adreça</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>&amp;Nova</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Copia l'adreça seleccionada al porta-retalls del sistema</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>&amp;Copia</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>&amp;Tanca</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>&amp;Copia l'adreça</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>Elimina l'adreça sel·leccionada actualment de la llista</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Exporta les dades de la pestanya actual a un fitxer</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Exporta</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;Elimina</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>Trieu una adreça on voleu enviar monedes</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>Trieu l'adreça on voleu rebre monedes</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>T&amp;ria</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>S'estan enviant les adreces</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>S'estan rebent les adreces</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>Aquestes són les vostres adreces de Bitcoin per enviar els pagaments. Sempre reviseu l'import i l'adreça del destinatari abans de transferir monedes.</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>Aquestes són les vostres adreces Bitcoin per rebre pagaments. Es recomana utilitzar una adreça nova de recepció per a cada transacció.</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>Copia l'&amp;etiqueta</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>&amp;Edita</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>Exporta la llista d'adreces</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Fitxer de separació amb comes (*.csv)</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>L'exportació ha fallat</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the address list to %1. Please try again.</source>
+ <translation>S'ha produït un error en desar la llista d'adreces a %1. Torneu-ho a provar.</translation>
+ </message>
+</context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Etiqueta</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adreça</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(sense etiqueta)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Passphrase Dialog</source>
+ <translation>Diàleg de contrasenya</translation>
+ </message>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Introduïu una contrasenya</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Nova contrasenya</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Repetiu la nova contrasenya</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>Encripta el moneder</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>Aquesta operació requereix la contrasenya del moneder per a desbloquejar-lo.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Desbloqueja el moneder</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>Aquesta operació requereix la contrasenya del moneder per desencriptar-lo.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>Desencripta el moneder</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>Canvia la contrasenya</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>Confirma l'encriptació del moneder</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>Avís: si encripteu el vostre moneder i perdeu la contrasenya, &lt;b&gt;PERDREU TOTS ELS VOSTRES BITCOINS&lt;/b&gt;!</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>Esteu segur que voleu encriptar el vostre moneder?</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core 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.</source>
+ <translation>Ara es tancarà el Bitcoin Core per finalitzar el procés d'encriptació. Tingueu present que encriptar el vostre moneder no garanteix que les vostres bitcoins no puguin ser robades per programari maliciós que infecti l'ordinador.</translation>
+ </message>
+ <message>
+ <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
+ <translation>IMPORTANT: Tota copia de seguretat que hàgiu realitzat hauria de ser reemplaçada pel, recentment generat, fitxer encriptat del moneder.</translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>Avís: Les lletres majúscules estan activades!</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>Moneder encriptat</translation>
+ </message>
+ <message>
+ <source>Enter the new passphrase to the wallet.&lt;br/&gt;Please use a passphrase of &lt;b&gt;ten or more random characters&lt;/b&gt;, or &lt;b&gt;eight or more words&lt;/b&gt;.</source>
+ <translation>Introduïu la contrasenya nova al moneder.&lt;br/&gt;Utilitzeu una contrasenya de &lt;b&gt;deu o més caràcters aleatoris&lt;/b&gt;, o &lt;b&gt;vuit o més paraules&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>Enter the old passphrase and new passphrase to the wallet.</source>
+ <translation>Introduïu la contrasenya antiga i la contrasenya nova al moneder.</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>L'encriptació del moneder ha fallat</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>L'encriptació del moneder ha fallat per un error intern. El moneder no ha estat encriptat.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>La contrasenya introduïda no coincideix.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>El desbloqueig del moneder ha fallat</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>La contrasenya introduïda per a desencriptar el moneder és incorrecta.</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>La desencriptació del moneder ha fallat</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>La contrasenya del moneder ha estat modificada correctament.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>Signa el &amp;missatge...</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>S'està sincronitzant amb la xarxa ...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;Panorama general</translation>
+ </message>
+ <message>
+ <source>Node</source>
+ <translation>Node</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>Mostra el panorama general del moneder</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Transaccions</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>Cerca a l'historial de transaccions</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>S&amp;urt</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>Surt de l'aplicació</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>Quant a &amp;Qt</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>Mostra informació sobre Qt</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;Opcions...</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>&amp;Encripta el moneder...</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>&amp;Realitza una còpia de seguretat del moneder...</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>&amp;Canvia la contrasenya...</translation>
+ </message>
+ <message>
+ <source>&amp;Sending addresses...</source>
+ <translation>Adreces d'e&amp;nviament...</translation>
+ </message>
+ <message>
+ <source>&amp;Receiving addresses...</source>
+ <translation>Adreces de &amp;recepció</translation>
+ </message>
+ <message>
+ <source>Open &amp;URI...</source>
+ <translation>Obre un &amp;URI...</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core client</source>
+ <translation>Client del Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Importing blocks from disk...</source>
+ <translation>S'estan important els blocs del disc...</translation>
+ </message>
+ <message>
+ <source>Reindexing blocks on disk...</source>
+ <translation>S'estan reindexant els blocs al disc...</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>Envia monedes a una adreça Bitcoin</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>Realitza una còpia de seguretat del moneder a una altra ubicació</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Canvia la contrasenya d'encriptació del moneder</translation>
+ </message>
+ <message>
+ <source>&amp;Debug window</source>
+ <translation>&amp;Finestra de depuració</translation>
+ </message>
+ <message>
+ <source>Open debugging and diagnostic console</source>
+ <translation>Obre la consola de diagnòstic i depuració</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>&amp;Verifica el missatge...</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>Moneder</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>&amp;Envia</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>&amp;Rep</translation>
+ </message>
+ <message>
+ <source>Show information about Bitcoin Core</source>
+ <translation>Mostra informació del Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>&amp;Mostra / Amaga</translation>
+ </message>
+ <message>
+ <source>Show or hide the main Window</source>
+ <translation>Mostra o amaga la finestra principal</translation>
+ </message>
+ <message>
+ <source>Encrypt the private keys that belong to your wallet</source>
+ <translation>Encripta les claus privades pertanyents al moneder</translation>
+ </message>
+ <message>
+ <source>Sign messages with your Bitcoin addresses to prove you own them</source>
+ <translation>Signa el missatges amb la seva adreça de Bitcoin per provar que les poseeixes</translation>
+ </message>
+ <message>
+ <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source>
+ <translation>Verifiqueu els missatges per assegurar-vos que han estat signats amb una adreça Bitcoin específica.</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;Fitxer</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;Configuració</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>&amp;Ajuda</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>Barra d'eines de les pestanyes</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Nucli de Bitcoin</translation>
+ </message>
+ <message>
+ <source>Request payments (generates QR codes and bitcoin: URIs)</source>
+ <translation>Sol·licita pagaments (genera codis QR i bitcoin: URI)</translation>
+ </message>
+ <message>
+ <source>&amp;About Bitcoin Core</source>
+ <translation>&amp;Quant al Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Modify configuration options for Bitcoin Core</source>
+ <translation>Modifica les opcions de configuració del Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Show the list of used sending addresses and labels</source>
+ <translation>Mostra la llista d'adreces d'enviament i etiquetes utilitzades</translation>
+ </message>
+ <message>
+ <source>Show the list of used receiving addresses and labels</source>
+ <translation>Mostra la llista d'adreces de recepció i etiquetes utilitzades</translation>
+ </message>
+ <message>
+ <source>Open a bitcoin: URI or payment request</source>
+ <translation>Obre una bitcoin: sol·licitud d'URI o pagament</translation>
+ </message>
+ <message>
+ <source>&amp;Command-line options</source>
+ <translation>Opcions de la &amp;línia d'ordres</translation>
+ </message>
+ <message>
+ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
+ <translation>Mostra el missatge d'ajuda del Bitcoin Core per obtenir una llista amb les possibles opcions de línia d'ordres de Bitcoin</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n active connection(s) to Bitcoin network</source>
+ <translation><numerusform>%n connexió activa a la xarxa Bitcoin</numerusform><numerusform>%n connexions actives a la xarxa Bitcoin</numerusform></translation>
+ </message>
+ <message>
+ <source>No block source available...</source>
+ <translation>No hi ha cap font de bloc disponible...</translation>
+ </message>
+ <message numerus="yes">
+ <source>Processed %n block(s) of transaction history.</source>
+ <translation><numerusform>S'han processat %n bloc de l'historial de transacció.</numerusform><numerusform>S'han processat %n blocs de l'historial de transacció.</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n hour(s)</source>
+ <translation><numerusform>%n hora</numerusform><numerusform>%n hores</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n day(s)</source>
+ <translation><numerusform>%n dia</numerusform><numerusform>%n dies</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n week(s)</source>
+ <translation><numerusform>%n setmana</numerusform><numerusform>%n setmanes</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 and %2</source>
+ <translation>%1 i %2</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n year(s)</source>
+ <translation><numerusform>%n any</numerusform><numerusform>%n anys</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 behind</source>
+ <translation>%1 darrere</translation>
+ </message>
+ <message>
+ <source>Last received block was generated %1 ago.</source>
+ <translation>El darrer bloc rebut ha estat generat fa %1.</translation>
+ </message>
+ <message>
+ <source>Transactions after this will not yet be visible.</source>
+ <translation>Les transaccions a partir d'això no seran visibles.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Error</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Avís</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Informació</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>Al dia</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>S'està posant al dia ...</translation>
+ </message>
+ <message>
+ <source>Date: %1
+</source>
+ <translation>Data: %1
+</translation>
+ </message>
+ <message>
+ <source>Amount: %1
+</source>
+ <translation>Import: %1
+</translation>
+ </message>
+ <message>
+ <source>Type: %1
+</source>
+ <translation>Tipus: %1
+</translation>
+ </message>
+ <message>
+ <source>Label: %1
+</source>
+ <translation>Etiqueta: %1
+</translation>
+ </message>
+ <message>
+ <source>Address: %1
+</source>
+ <translation>Adreça: %1
+</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>Transacció enviada</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>Transacció entrant</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>El moneder està &lt;b&gt;encriptat&lt;/b&gt; i actualment &lt;b&gt;desbloquejat&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>El moneder està &lt;b&gt;encriptat&lt;/b&gt; i actualment &lt;b&gt;bloquejat&lt;/b&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <source>Network Alert</source>
+ <translation>Alerta de xarxa</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Coin Selection</source>
+ <translation>Selecció de moneda</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Quantitat:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Bytes:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Import:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Prioritat:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Comissió</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Polsim:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Comissió posterior:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Canvi:</translation>
+ </message>
+ <message>
+ <source>(un)select all</source>
+ <translation>(des)selecciona-ho tot</translation>
+ </message>
+ <message>
+ <source>Tree mode</source>
+ <translation>Mode arbre</translation>
+ </message>
+ <message>
+ <source>List mode</source>
+ <translation>Mode llista</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Import</translation>
+ </message>
+ <message>
+ <source>Received with label</source>
+ <translation>Rebut amb l'etiqueta</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>Rebut amb l'adreça</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Confirmations</source>
+ <translation>Confirmacions</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Confirmat</translation>
+ </message>
+ <message>
+ <source>Priority</source>
+ <translation>Prioritat</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Copiar adreça </translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Copiar etiqueta</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copia l'import</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Copiar ID de transacció</translation>
+ </message>
+ <message>
+ <source>Lock unspent</source>
+ <translation>Bloqueja sense gastar</translation>
+ </message>
+ <message>
+ <source>Unlock unspent</source>
+ <translation>Desbloqueja sense gastar</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Copia la quantitat</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Copia la comissió</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Copia la comissió posterior</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Copia els bytes</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Copia la prioritat</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Copia el polsim</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Copia el canvi</translation>
+ </message>
+ <message>
+ <source>highest</source>
+ <translation>El més alt</translation>
+ </message>
+ <message>
+ <source>higher</source>
+ <translation>Més alt</translation>
+ </message>
+ <message>
+ <source>high</source>
+ <translation>Alt</translation>
+ </message>
+ <message>
+ <source>medium-high</source>
+ <translation>mig-alt</translation>
+ </message>
+ <message>
+ <source>medium</source>
+ <translation>mig</translation>
+ </message>
+ <message>
+ <source>low-medium</source>
+ <translation>baix-mig</translation>
+ </message>
+ <message>
+ <source>low</source>
+ <translation>baix</translation>
+ </message>
+ <message>
+ <source>lower</source>
+ <translation>més baix</translation>
+ </message>
+ <message>
+ <source>lowest</source>
+ <translation>el més baix</translation>
+ </message>
+ <message>
+ <source>(%1 locked)</source>
+ <translation>(%1 bloquejada)</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>cap</translation>
+ </message>
+ <message>
+ <source>This label turns red if the transaction size is greater than 1000 bytes.</source>
+ <translation>Aquesta etiqueta es torna en vermell si la transacció és superior a 1000 bytes.</translation>
+ </message>
+ <message>
+ <source>This label turns red if the priority is smaller than "medium".</source>
+ <translation>Aquesta etiqueta es torna en vermell si la propietat és inferior que la «mitjana».</translation>
+ </message>
+ <message>
+ <source>This label turns red if any recipient receives an amount smaller than %1.</source>
+ <translation>Aquesta etiqueta es torna vermella si el destinatari rep un import inferior de %1.</translation>
+ </message>
+ <message>
+ <source>Can vary +/- %1 satoshi(s) per input.</source>
+ <translation>Pot variar +/- %1 satoshi(s) per entrada.</translation>
+ </message>
+ <message>
+ <source>yes</source>
+ <translation>sí</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>no</translation>
+ </message>
+ <message>
+ <source>This means a fee of at least %1 per kB is required.</source>
+ <translation>Això comporta una comissió d'almenys %1 per kB.</translation>
+ </message>
+ <message>
+ <source>Can vary +/- 1 byte per input.</source>
+ <translation>Pot variar +/- 1 byte per entrada.</translation>
+ </message>
+ <message>
+ <source>Transactions with higher priority are more likely to get included into a block.</source>
+ <translation>Les transaccions amb una major prioritat són més propenses a ser incloses en un bloc.</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(sense etiqueta)</translation>
+ </message>
+ <message>
+ <source>change from %1 (%2)</source>
+ <translation>canvia de %1 (%2)</translation>
+ </message>
+ <message>
+ <source>(change)</source>
+ <translation>(canvia)</translation>
+ </message>
+</context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>Edita l'adreça</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>&amp;Etiqueta</translation>
+ </message>
+ <message>
+ <source>The label associated with this address list entry</source>
+ <translation>L'etiqueta associada amb aquesta entrada de llista d'adreces</translation>
+ </message>
+ <message>
+ <source>The address associated with this address list entry. This can only be modified for sending addresses.</source>
+ <translation>L'adreça associada amb aquesta entrada de llista d'adreces. Només es pot modificar per a les adreces d'enviament.</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;Adreça</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>Nova adreça de recepció.</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>Nova adreça d'enviament</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>Edita les adreces de recepció</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>Edita les adreces d'enviament</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>L'adreça introduïda «%1» ja és present a la llibreta d'adreces.</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is not a valid Bitcoin address.</source>
+ <translation>L'adreça introduïda «%1» no és una adreça de Bitcoin vàlida.</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>No s'ha pogut desbloquejar el moneder.</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>Ha fallat la generació d'una nova clau.</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ <message>
+ <source>A new data directory will be created.</source>
+ <translation>Es crearà un nou directori de dades.</translation>
+ </message>
+ <message>
+ <source>name</source>
+ <translation>nom</translation>
+ </message>
+ <message>
+ <source>Directory already exists. Add %1 if you intend to create a new directory here.</source>
+ <translation>El directori ja existeix. Afegeix %1 si vols crear un nou directori en aquesta ubicació.</translation>
+ </message>
+ <message>
+ <source>Path already exists, and is not a directory.</source>
+ <translation>El camí ja existeix i no és cap directori.</translation>
+ </message>
+ <message>
+ <source>Cannot create data directory here.</source>
+ <translation>No es pot crear el directori de dades aquí.</translation>
+ </message>
+</context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Nucli de Bitcoin</translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>versió</translation>
+ </message>
+ <message>
+ <source>(%1-bit)</source>
+ <translation>(%1-bit)</translation>
+ </message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>Quant al Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Command-line options</source>
+ <translation>Opcions de línia d'ordres</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>Ús:</translation>
+ </message>
+ <message>
+ <source>command-line options</source>
+ <translation>Opcions de la línia d'ordres</translation>
+ </message>
+</context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Welcome</source>
+ <translation>Us donem la benviguda</translation>
+ </message>
+ <message>
+ <source>Welcome to Bitcoin Core.</source>
+ <translation>Us donem la benvinguda al Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</source>
+ <translation>Atès que és la primera vegada que executeu el programa, podeu triar on emmagatzemarà el Bitcoin Core les dades.</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory.</source>
+ <translation>El Bitcoin Core descarregarà i emmagatzemarà una còpia de la cadena de blocs de Bitcoin. Com a mínim s'emmagatzemaran %1 GB de dades en aquest directori, que seguiran creixent gradualment. També s'hi emmagatzemarà el moneder.</translation>
+ </message>
+ <message>
+ <source>Use the default data directory</source>
+ <translation>Utilitza el directori de dades per defecte</translation>
+ </message>
+ <message>
+ <source>Use a custom data directory:</source>
+ <translation>Utilitza un directori de dades personalitzat:</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Nucli de Bitcoin</translation>
+ </message>
+ <message>
+ <source>Error: Specified data directory "%1" cannot be created.</source>
+ <translation>Error: el directori de dades «%1» especificat no pot ser creat.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Error</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n GB of free space available</source>
+ <translation><numerusform>%n GB d'espai lliure disponible</numerusform><numerusform>%n GB d'espai lliure disponible</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>(of %n GB needed)</source>
+ <translation><numerusform>(de %n GB necessari)</numerusform><numerusform>(de %n GB necessaris)</numerusform></translation>
+ </message>
+</context>
+<context>
+ <name>OpenURIDialog</name>
+ <message>
+ <source>Open URI</source>
+ <translation>Obre un URI</translation>
+ </message>
+ <message>
+ <source>Open payment request from URI or file</source>
+ <translation>Obre una sol·licitud de pagament des d'un URI o un fitxer</translation>
+ </message>
+ <message>
+ <source>URI:</source>
+ <translation>URI:</translation>
+ </message>
+ <message>
+ <source>Select payment request file</source>
+ <translation>Selecciona un fitxer de sol·licitud de pagament</translation>
+ </message>
+ <message>
+ <source>Select payment request file to open</source>
+ <translation>Selecciona el fitxer de sol·licitud de pagament per obrir</translation>
+ </message>
+</context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>Opcions</translation>
+ </message>
+ <message>
+ <source>&amp;Main</source>
+ <translation>&amp;Principal</translation>
+ </message>
+ <message>
+ <source>Size of &amp;database cache</source>
+ <translation>Mida de la memòria cau de la base de &amp;dades</translation>
+ </message>
+ <message>
+ <source>MB</source>
+ <translation>MB</translation>
+ </message>
+ <message>
+ <source>Number of script &amp;verification threads</source>
+ <translation>Nombre de fils de &amp;verificació d'scripts</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside</source>
+ <translation>Accepta connexions de fora</translation>
+ </message>
+ <message>
+ <source>Allow incoming connections</source>
+ <translation>Permet connexions entrants</translation>
+ </message>
+ <message>
+ <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
+ <translation>Adreça IP del proxy (p. ex. IPv4: 127.0.0.1 / IPv6: ::1)</translation>
+ </message>
+ <message>
+ <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source>
+ <translation>Minimitza en comptes de sortir de l'aplicació quan la finestra es tanca. Quan s'habilita aquesta opció l'aplicació es tancara només quan se selecciona Surt del menú. </translation>
+ </message>
+ <message>
+ <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source>
+ <translation>La interfície d'usuari pot definir-se des d'aquí. El paràmetre tindrà efecte després de reiniciar el Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source>
+ <translation>URL de terceres parts (p. ex. explorador de blocs) que apareix en la pestanya de transaccions com elements del menú contextual. %s en l'URL es reemplaçat pel resum de la transacció. Diferents URL estan separades per una barra vertical |.</translation>
+ </message>
+ <message>
+ <source>Third party transaction URLs</source>
+ <translation>URL de transaccions de terceres parts</translation>
+ </message>
+ <message>
+ <source>Active command-line options that override above options:</source>
+ <translation>Opcions de línies d'ordre active que sobreescriuen les opcions de dalt:</translation>
+ </message>
+ <message>
+ <source>Reset all client options to default.</source>
+ <translation>Reestableix totes les opcions del client.</translation>
+ </message>
+ <message>
+ <source>&amp;Reset Options</source>
+ <translation>&amp;Reestableix les opcions</translation>
+ </message>
+ <message>
+ <source>&amp;Network</source>
+ <translation>&amp;Xarxa</translation>
+ </message>
+ <message>
+ <source>Automatically start Bitcoin Core after logging in to the system.</source>
+ <translation>Inicia el Bitcoin Core automàticament després d'iniciar una sessió en el sistema.</translation>
+ </message>
+ <message>
+ <source>&amp;Start Bitcoin Core on system login</source>
+ <translation>&amp;Inicia el Bitcoin Core en inciar el sistema</translation>
+ </message>
+ <message>
+ <source>(0 = auto, &lt;0 = leave that many cores free)</source>
+ <translation>(0 = auto, &lt;0 = deixa tants nuclis lliures)</translation>
+ </message>
+ <message>
+ <source>W&amp;allet</source>
+ <translation>&amp;Moneder</translation>
+ </message>
+ <message>
+ <source>Expert</source>
+ <translation>Expert</translation>
+ </message>
+ <message>
+ <source>Enable coin &amp;control features</source>
+ <translation>Activa les funcions de &amp;control de les monedes</translation>
+ </message>
+ <message>
+ <source>If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.</source>
+ <translation>Si inhabiliteu la despesa d'un canvi sense confirmar, el canvi d'una transacció no pot ser utilitzat fins que la transacció no tingui com a mínim una confirmació. Això també afecta com es calcula el vostre balanç.</translation>
+ </message>
+ <message>
+ <source>&amp;Spend unconfirmed change</source>
+ <translation>&amp;Gasta el canvi sense confirmar</translation>
+ </message>
+ <message>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>Obre el port del client de Bitcoin al router de forma automàtica. Això només funciona quan el router implementa UPnP i l'opció està activada.</translation>
+ </message>
+ <message>
+ <source>Map port using &amp;UPnP</source>
+ <translation>Port obert amb &amp;UPnP</translation>
+ </message>
+ <message>
+ <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
+ <translation>Connecta a la xarxa Bitcoin a través d'un proxy SOCKS5.</translation>
+ </message>
+ <message>
+ <source>&amp;Connect through SOCKS5 proxy (default proxy):</source>
+ <translation>&amp;Connecta a través d'un proxy SOCKS5 (proxy per defecte):</translation>
+ </message>
+ <message>
+ <source>Proxy &amp;IP:</source>
+ <translation>&amp;IP del proxy:</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>&amp;Port:</translation>
+ </message>
+ <message>
+ <source>Port of the proxy (e.g. 9050)</source>
+ <translation>Port del proxy (per exemple 9050)</translation>
+ </message>
+ <message>
+ <source>&amp;Window</source>
+ <translation>&amp;Finestra</translation>
+ </message>
+ <message>
+ <source>Show only a tray icon after minimizing the window.</source>
+ <translation>Mostra només la icona de la barra en minimitzar la finestra.</translation>
+ </message>
+ <message>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>&amp;Minimitza a la barra d'aplicacions en comptes de la barra de tasques</translation>
+ </message>
+ <message>
+ <source>M&amp;inimize on close</source>
+ <translation>M&amp;inimitza en tancar</translation>
+ </message>
+ <message>
+ <source>&amp;Display</source>
+ <translation>&amp;Pantalla</translation>
+ </message>
+ <message>
+ <source>User Interface &amp;language:</source>
+ <translation>&amp;Llengua de la interfície d'usuari:</translation>
+ </message>
+ <message>
+ <source>&amp;Unit to show amounts in:</source>
+ <translation>&amp;Unitats per mostrar els imports en:</translation>
+ </message>
+ <message>
+ <source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
+ <translation>Selecciona la unitat de subdivisió per defecte per mostrar en la interfície quan s'envien monedes.</translation>
+ </message>
+ <message>
+ <source>Whether to show coin control features or not.</source>
+ <translation>Si voleu mostrar les funcions de control de monedes o no.</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>&amp;D'acord</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>&amp;Cancel·la</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>Per defecte</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>cap</translation>
+ </message>
+ <message>
+ <source>Confirm options reset</source>
+ <translation>Confirmeu el reestabliment de les opcions</translation>
+ </message>
+ <message>
+ <source>Client restart required to activate changes.</source>
+ <translation>Cal reiniciar el client per activar els canvis.</translation>
+ </message>
+ <message>
+ <source>Client will be shut down. Do you want to proceed?</source>
+ <translation>S'aturarà el client. Voleu procedir?</translation>
+ </message>
+ <message>
+ <source>This change would require a client restart.</source>
+ <translation>Amb aquest canvi cal un reinici del client.</translation>
+ </message>
+ <message>
+ <source>The supplied proxy address is invalid.</source>
+ <translation>L'adreça proxy introduïda és invalida.</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>Formulari</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>La informació mostrada pot no estar al día. El teu moneder es sincronitza automàticament amb la xarxa Bitcoin un cop s'ha establert connexió, però aquest proces no s'ha completat encara.</translation>
+ </message>
+ <message>
+ <source>Watch-only:</source>
+ <translation>Només lectura:</translation>
+ </message>
+ <message>
+ <source>Available:</source>
+ <translation>Disponible:</translation>
+ </message>
+ <message>
+ <source>Your current spendable balance</source>
+ <translation>El balanç que podeu gastar actualment</translation>
+ </message>
+ <message>
+ <source>Pending:</source>
+ <translation>Pendent:</translation>
+ </message>
+ <message>
+ <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source>
+ <translation>Total de transaccions que encara han de confirmar-se i que encara no compten en el balanç que es pot gastar</translation>
+ </message>
+ <message>
+ <source>Immature:</source>
+ <translation>Immadur:</translation>
+ </message>
+ <message>
+ <source>Mined balance that has not yet matured</source>
+ <translation>Balanç minat que encara no ha madurat</translation>
+ </message>
+ <message>
+ <source>Balances</source>
+ <translation>Balances</translation>
+ </message>
+ <message>
+ <source>Total:</source>
+ <translation>Total:</translation>
+ </message>
+ <message>
+ <source>Your current total balance</source>
+ <translation>El balanç total actual</translation>
+ </message>
+ <message>
+ <source>Your current balance in watch-only addresses</source>
+ <translation>El vostre balanç actual en adreces de només lectura</translation>
+ </message>
+ <message>
+ <source>Spendable:</source>
+ <translation>Que es pot gastar:</translation>
+ </message>
+ <message>
+ <source>Recent transactions</source>
+ <translation>Transaccions recents</translation>
+ </message>
+ <message>
+ <source>Unconfirmed transactions to watch-only addresses</source>
+ <translation>Transaccions sense confirmar a adreces de només lectura</translation>
+ </message>
+ <message>
+ <source>Mined balance in watch-only addresses that has not yet matured</source>
+ <translation>Balanç minat en adreces de només lectura que encara no ha madurat</translation>
+ </message>
+ <message>
+ <source>Current total balance in watch-only addresses</source>
+ <translation>Balanç total actual en adreces de només lectura</translation>
+ </message>
+</context>
+<context>
+ <name>PaymentServer</name>
+ <message>
+ <source>URI handling</source>
+ <translation>Gestió d'URI</translation>
+ </message>
+ <message>
+ <source>Invalid payment address %1</source>
+ <translation>Adreça de pagament no vàlida %1</translation>
+ </message>
+ <message>
+ <source>Payment request rejected</source>
+ <translation>La sol·licitud de pagament s'ha rebutjat</translation>
+ </message>
+ <message>
+ <source>Payment request network doesn't match client network.</source>
+ <translation>La xarxa de la sol·licitud de pagament no coincideix amb la xarxa del client.</translation>
+ </message>
+ <message>
+ <source>Payment request is not initialized.</source>
+ <translation>La sol·licitud de pagament no està inicialitzada.</translation>
+ </message>
+ <message>
+ <source>Requested payment amount of %1 is too small (considered dust).</source>
+ <translation>L'import de pagament sol·licitat %1 és massa petit (es considera polsim).</translation>
+ </message>
+ <message>
+ <source>Payment request error</source>
+ <translation>Error en la sol·licitud de pagament</translation>
+ </message>
+ <message>
+ <source>Cannot start bitcoin: click-to-pay handler</source>
+ <translation>No es pot iniciar bitcoin: gestor clica-per-pagar</translation>
+ </message>
+ <message>
+ <source>Payment request fetch URL is invalid: %1</source>
+ <translation>L'URL de recuperació de la sol·licitud de pagament no és vàlida: %1</translation>
+ </message>
+ <message>
+ <source>URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source>
+ <translation>L'URI no pot ser analitzat! Això pot ser a causa d'una adreça de Bitcoin no vàlida o per paràmetres URI amb mal format.</translation>
+ </message>
+ <message>
+ <source>Payment request file handling</source>
+ <translation>Gestió de fitxers de les sol·licituds de pagament</translation>
+ </message>
+ <message>
+ <source>Payment request file cannot be read! This can be caused by an invalid payment request file.</source>
+ <translation>No es pot llegir el fitxer de la sol·licitud de pagament. Això pot ser causat per un fitxer de sol·licitud de pagament no vàlid.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>La sol·licitud de pagament ha vençut.</translation>
+ </message>
+ <message>
+ <source>Unverified payment requests to custom payment scripts are unsupported.</source>
+ <translation>No s'accepten sol·licituds de pagament no verificades a scripts de pagament personalitzats.</translation>
+ </message>
+ <message>
+ <source>Invalid payment request.</source>
+ <translation>Sol·licitud de pagament no vàlida.</translation>
+ </message>
+ <message>
+ <source>Refund from %1</source>
+ <translation>Reemborsament de %1</translation>
+ </message>
+ <message>
+ <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source>
+ <translation>La sol·licitud de pagament %1 és massa gran (%2 bytes, permès %3 bytes).</translation>
+ </message>
+ <message>
+ <source>Payment request DoS protection</source>
+ <translation>Protecció de DoS per a la sol·licitud de pagament</translation>
+ </message>
+ <message>
+ <source>Error communicating with %1: %2</source>
+ <translation>Error en comunicar amb %1: %2</translation>
+ </message>
+ <message>
+ <source>Payment request cannot be parsed!</source>
+ <translation>No es pot analitzar la sol·licitud de pagament!</translation>
+ </message>
+ <message>
+ <source>Bad response from server %1</source>
+ <translation>Mala resposta del servidor %1</translation>
+ </message>
+ <message>
+ <source>Payment acknowledged</source>
+ <translation>Pagament reconegut</translation>
+ </message>
+ <message>
+ <source>Network request error</source>
+ <translation>Error en la sol·licitud de xarxa</translation>
+ </message>
+</context>
+<context>
+ <name>PeerTableModel</name>
+ <message>
+ <source>User Agent</source>
+ <translation>Agent d'usuari</translation>
+ </message>
+ <message>
+ <source>Node/Service</source>
+ <translation>Node/Servei</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Temps de ping</translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>Import</translation>
+ </message>
+ <message>
+ <source>Enter a Bitcoin address (e.g. %1)</source>
+ <translation>Introduïu una adreça de Bitcoin (p. ex. %1)</translation>
+ </message>
+ <message>
+ <source>%1 d</source>
+ <translation>%1 d</translation>
+ </message>
+ <message>
+ <source>%1 h</source>
+ <translation>%1 h</translation>
+ </message>
+ <message>
+ <source>%1 m</source>
+ <translation>%1 m</translation>
+ </message>
+ <message>
+ <source>%1 s</source>
+ <translation>%1 s</translation>
+ </message>
+ <message>
+ <source>None</source>
+ <translation>Cap</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>N/A</translation>
+ </message>
+ <message>
+ <source>%1 ms</source>
+ <translation>%1 ms</translation>
+ </message>
+</context>
+<context>
+ <name>QRImageWidget</name>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>De&amp;sa la imatge...</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Image</source>
+ <translation>&amp;Copia la imatge</translation>
+ </message>
+ <message>
+ <source>Save QR Code</source>
+ <translation>Desa el codi QR</translation>
+ </message>
+ <message>
+ <source>PNG Image (*.png)</source>
+ <translation>Imatge PNG (*.png)</translation>
+ </message>
+</context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>Client name</source>
+ <translation>Nom del client</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>N/A</translation>
+ </message>
+ <message>
+ <source>Client version</source>
+ <translation>Versió del client</translation>
+ </message>
+ <message>
+ <source>&amp;Information</source>
+ <translation>&amp;Informació</translation>
+ </message>
+ <message>
+ <source>Debug window</source>
+ <translation>Finestra de depuració</translation>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>General</translation>
+ </message>
+ <message>
+ <source>Using OpenSSL version</source>
+ <translation>Utilitzant OpenSSL versió</translation>
+ </message>
+ <message>
+ <source>Using BerkeleyDB version</source>
+ <translation>Utilitzant BerkeleyDB versió</translation>
+ </message>
+ <message>
+ <source>Startup time</source>
+ <translation>&amp;Temps d'inici</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Xarxa</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>Nom</translation>
+ </message>
+ <message>
+ <source>Number of connections</source>
+ <translation>Nombre de connexions</translation>
+ </message>
+ <message>
+ <source>Block chain</source>
+ <translation>Cadena de blocs</translation>
+ </message>
+ <message>
+ <source>Current number of blocks</source>
+ <translation>Nombre de blocs actuals</translation>
+ </message>
+ <message>
+ <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source>
+ <translation>Obre el fitxer de registre de depuració del Bitcoin Core del directori de dades actual. Pot portar uns quants segons per a fitxers de registre grans.</translation>
+ </message>
+ <message>
+ <source>Received</source>
+ <translation>Rebut</translation>
+ </message>
+ <message>
+ <source>Sent</source>
+ <translation>Enviat</translation>
+ </message>
+ <message>
+ <source>&amp;Peers</source>
+ <translation>&amp;Iguals</translation>
+ </message>
+ <message>
+ <source>Select a peer to view detailed information.</source>
+ <translation>Seleccioneu un igual per mostrar informació detallada.</translation>
+ </message>
+ <message>
+ <source>Direction</source>
+ <translation>Direcció</translation>
+ </message>
+ <message>
+ <source>Version</source>
+ <translation>Versió</translation>
+ </message>
+ <message>
+ <source>User Agent</source>
+ <translation>Agent d'usuari</translation>
+ </message>
+ <message>
+ <source>Services</source>
+ <translation>Serveis</translation>
+ </message>
+ <message>
+ <source>Starting Height</source>
+ <translation>Alçada inicial</translation>
+ </message>
+ <message>
+ <source>Sync Height</source>
+ <translation>Sincronitza l'alçada</translation>
+ </message>
+ <message>
+ <source>Ban Score</source>
+ <translation>Puntuació de bandeig</translation>
+ </message>
+ <message>
+ <source>Connection Time</source>
+ <translation>Temps de connexió</translation>
+ </message>
+ <message>
+ <source>Last Send</source>
+ <translation>Darrer enviament</translation>
+ </message>
+ <message>
+ <source>Last Receive</source>
+ <translation>Darrera recepció</translation>
+ </message>
+ <message>
+ <source>Bytes Sent</source>
+ <translation>Bytes enviats</translation>
+ </message>
+ <message>
+ <source>Bytes Received</source>
+ <translation>Bytes rebuts</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Temps de ping</translation>
+ </message>
+ <message>
+ <source>Time Offset</source>
+ <translation>Diferència horària</translation>
+ </message>
+ <message>
+ <source>Last block time</source>
+ <translation>Últim temps de bloc</translation>
+ </message>
+ <message>
+ <source>&amp;Open</source>
+ <translation>&amp;Obre</translation>
+ </message>
+ <message>
+ <source>&amp;Console</source>
+ <translation>&amp;Consola</translation>
+ </message>
+ <message>
+ <source>&amp;Network Traffic</source>
+ <translation>Trà&amp;nsit de la xarxa</translation>
+ </message>
+ <message>
+ <source>&amp;Clear</source>
+ <translation>Nete&amp;ja</translation>
+ </message>
+ <message>
+ <source>Totals</source>
+ <translation>Totals</translation>
+ </message>
+ <message>
+ <source>In:</source>
+ <translation>Dins:</translation>
+ </message>
+ <message>
+ <source>Out:</source>
+ <translation>Fora:</translation>
+ </message>
+ <message>
+ <source>Build date</source>
+ <translation>Data de compilació</translation>
+ </message>
+ <message>
+ <source>Debug log file</source>
+ <translation>Fitxer de registre de depuració</translation>
+ </message>
+ <message>
+ <source>Clear console</source>
+ <translation>Neteja la consola</translation>
+ </message>
+ <message>
+ <source>Welcome to the Bitcoin Core RPC console.</source>
+ <translation>Us donem la benviguda a la consola RPC del Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
+ <translation>Utilitza les fletxes d'amunt i avall per navegar per l'historial, i &lt;b&gt;Ctrl-L&lt;\b&gt; per netejar la pantalla.</translation>
+ </message>
+ <message>
+ <source>Type &lt;b&gt;help&lt;/b&gt; for an overview of available commands.</source>
+ <translation>Escriviu &lt;b&gt;help&lt;\b&gt; per a obtenir un llistat de les ordres disponibles.</translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation>%1 B</translation>
+ </message>
+ <message>
+ <source>%1 KB</source>
+ <translation>%1 KB</translation>
+ </message>
+ <message>
+ <source>%1 MB</source>
+ <translation>%1 MB</translation>
+ </message>
+ <message>
+ <source>%1 GB</source>
+ <translation>%1 GB</translation>
+ </message>
+ <message>
+ <source>via %1</source>
+ <translation>a través de %1</translation>
+ </message>
+ <message>
+ <source>never</source>
+ <translation>mai</translation>
+ </message>
+ <message>
+ <source>Inbound</source>
+ <translation>Entrant</translation>
+ </message>
+ <message>
+ <source>Outbound</source>
+ <translation>Sortint</translation>
+ </message>
+ <message>
+ <source>Unknown</source>
+ <translation>Desconegut</translation>
+ </message>
+ <message>
+ <source>Fetching...</source>
+ <translation>S'està obtenint...</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Amount:</source>
+ <translation>Im&amp;port:</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Etiqueta:</translation>
+ </message>
+ <message>
+ <source>&amp;Message:</source>
+ <translation>&amp;Missatge:</translation>
+ </message>
+ <message>
+ <source>Reuse one of the previously used receiving addresses. Reusing addresses has security and privacy issues. Do not use this unless re-generating a payment request made before.</source>
+ <translation>Reutilitza una de les adreces de recepció utilitzades anteriorment. La reutilització d'adreces pot comportar problemes de seguretat i privadesa. No ho utilitzeu llevat que torneu a generar una sol·licitud de pagament feta abans.</translation>
+ </message>
+ <message>
+ <source>R&amp;euse an existing receiving address (not recommended)</source>
+ <translation>R&amp;eutilitza una adreça de recepció anterior (no recomanat)</translation>
+ </message>
+ <message>
+ <source>An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network.</source>
+ <translation>Un missatge opcional que s'adjuntarà a la sol·licitud de pagament, que es mostrarà quan s'obri la sol·licitud. Nota: El missatge no s'enviarà amb el pagament per la xarxa Bitcoin.</translation>
+ </message>
+ <message>
+ <source>An optional label to associate with the new receiving address.</source>
+ <translation>Una etiqueta opcional que s'associarà amb la nova adreça receptora.</translation>
+ </message>
+ <message>
+ <source>Use this form to request payments. All fields are &lt;b&gt;optional&lt;/b&gt;.</source>
+ <translation>Utilitzeu aquest formulari per sol·licitar pagaments. Tots els camps són &lt;b&gt;opcionals&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>An optional amount to request. Leave this empty or zero to not request a specific amount.</source>
+ <translation>Un import opcional per sol·licitar. Deixeu-ho en blanc o zero per no sol·licitar cap import específic.</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Esborra tots els camps del formuari.</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation>Neteja</translation>
+ </message>
+ <message>
+ <source>Requested payments history</source>
+ <translation>Historial de pagaments sol·licitats</translation>
+ </message>
+ <message>
+ <source>&amp;Request payment</source>
+ <translation>&amp;Sol·licitud de pagament</translation>
+ </message>
+ <message>
+ <source>Show the selected request (does the same as double clicking an entry)</source>
+ <translation>Mostra la sol·licitud seleccionada (fa el mateix que el doble clic a una entrada)</translation>
+ </message>
+ <message>
+ <source>Show</source>
+ <translation>Mostra</translation>
+ </message>
+ <message>
+ <source>Remove the selected entries from the list</source>
+ <translation>Esborra les entrades seleccionades de la llista</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>Esborra</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Copia l'etiqueta</translation>
+ </message>
+ <message>
+ <source>Copy message</source>
+ <translation>Copia el missatge</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copia l'import</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>QR Code</source>
+ <translation>Codi QR</translation>
+ </message>
+ <message>
+ <source>Copy &amp;URI</source>
+ <translation>Copia l'&amp;URI</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Address</source>
+ <translation>Copia l'&amp;adreça</translation>
+ </message>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>De&amp;sa la imatge...</translation>
+ </message>
+ <message>
+ <source>Request payment to %1</source>
+ <translation>Sol·licita un pagament a %1</translation>
+ </message>
+ <message>
+ <source>Payment information</source>
+ <translation>Informació de pagament</translation>
+ </message>
+ <message>
+ <source>URI</source>
+ <translation>URI</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adreça</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Import</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiqueta</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Missatge</translation>
+ </message>
+ <message>
+ <source>Resulting URI too long, try to reduce the text for label / message.</source>
+ <translation>URI resultant massa llarga, intenta reduir el text per a la etiqueta / missatge</translation>
+ </message>
+ <message>
+ <source>Error encoding URI into QR Code.</source>
+ <translation>Error en codificar l'URI en un codi QR.</translation>
+ </message>
+</context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiqueta</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Missatge</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Import</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(sense etiqueta)</translation>
+ </message>
+ <message>
+ <source>(no message)</source>
+ <translation>(sense missatge)</translation>
+ </message>
+ <message>
+ <source>(no amount)</source>
+ <translation>(sense import)</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Envia monedes</translation>
+ </message>
+ <message>
+ <source>Coin Control Features</source>
+ <translation>Característiques de control de les monedes</translation>
+ </message>
+ <message>
+ <source>Inputs...</source>
+ <translation>Entrades...</translation>
+ </message>
+ <message>
+ <source>automatically selected</source>
+ <translation>seleccionat automàticament</translation>
+ </message>
+ <message>
+ <source>Insufficient funds!</source>
+ <translation>Fons insuficients!</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Quantitat:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Bytes:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Import:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Prioritat:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Comissió:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Comissió posterior:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Canvi:</translation>
+ </message>
+ <message>
+ <source>If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address.</source>
+ <translation>Si s'activa això, però l'adreça de canvi està buida o bé no és vàlida, el canvi s'enviarà a una adreça generada de nou.</translation>
+ </message>
+ <message>
+ <source>Custom change address</source>
+ <translation>Personalitza l'adreça de canvi</translation>
+ </message>
+ <message>
+ <source>Transaction Fee:</source>
+ <translation>Comissió de transacció</translation>
+ </message>
+ <message>
+ <source>Choose...</source>
+ <translation>Tria...</translation>
+ </message>
+ <message>
+ <source>collapse fee-settings</source>
+ <translation>redueix els paràmetres de comissió</translation>
+ </message>
+ <message>
+ <source>per kilobyte</source>
+ <translation>per kilobyte</translation>
+ </message>
+ <message>
+ <source>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "total at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source>
+ <translation>Si la comissió personalitzada es defineix a 1000 satoshis i la transacció és de només 250 bytes, llavors «per kilobyte» només es paguen 250 satoshis en una comissió, mentre que amb la de «total com a mínim» es pagarien 1000 satoshis. Per a transaccions superiors al kilobyte, en tots dos casos es paga per kilobyte.</translation>
+ </message>
+ <message>
+ <source>Hide</source>
+ <translation>Amaga</translation>
+ </message>
+ <message>
+ <source>total at least</source>
+ <translation>total com a mínim</translation>
+ </message>
+ <message>
+ <source>Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process.</source>
+ <translation>No hi ha cap problema en pagar només la comissió mínima sempre que hi hagi menys volum de transacció que espai en els blocs. Però tingueu present que això pot acabar en una transacció que mai es confirmi una vegada hi hagi més demanda de transaccions de bitcoins que la xarxa pugui processar.</translation>
+ </message>
+ <message>
+ <source>(read the tooltip)</source>
+ <translation>(llegiu l'indicador de funció)</translation>
+ </message>
+ <message>
+ <source>Recommended:</source>
+ <translation>Recomanada:</translation>
+ </message>
+ <message>
+ <source>Custom:</source>
+ <translation>Personalitzada:</translation>
+ </message>
+ <message>
+ <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source>
+ <translation>(No s'ha inicialitzat encara la comissió intel·ligent. Normalment pren uns pocs blocs...)</translation>
+ </message>
+ <message>
+ <source>Confirmation time:</source>
+ <translation>Temps de confirmació:</translation>
+ </message>
+ <message>
+ <source>normal</source>
+ <translation>normal</translation>
+ </message>
+ <message>
+ <source>fast</source>
+ <translation>ràpid</translation>
+ </message>
+ <message>
+ <source>Send as zero-fee transaction if possible</source>
+ <translation>Envia com a transacció de comissió zero si és possible</translation>
+ </message>
+ <message>
+ <source>(confirmation may take longer)</source>
+ <translation>(la confirmació pot trigar més temps)</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>Envia a múltiples destinataris al mateix temps</translation>
+ </message>
+ <message>
+ <source>Add &amp;Recipient</source>
+ <translation>Afegeix &amp;destinatari</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Netejar tots els camps del formulari.</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Polsim:</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Neteja-ho &amp;tot</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>Balanç:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>Confirma l'acció d'enviament</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>E&amp;nvia</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>Confirma l'enviament de monedes</translation>
+ </message>
+ <message>
+ <source>%1 to %2</source>
+ <translation>%1 a %2</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Copia la quantitat</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copia l'import</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Copia la comissió</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Copia la comissió posterior</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Copia els bytes</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Copia la prioritat</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Copia el canvi</translation>
+ </message>
+ <message>
+ <source>or</source>
+ <translation>o</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>L'import a pagar ha de ser major que 0.</translation>
+ </message>
+ <message>
+ <source>The amount exceeds your balance.</source>
+ <translation>L'import supera el vostre balanç.</translation>
+ </message>
+ <message>
+ <source>The total exceeds your balance when the %1 transaction fee is included.</source>
+ <translation>El total excedeix el teu balanç quan s'afegeix la comissió a la transacció %1.</translation>
+ </message>
+ <message>
+ <source>Transaction creation failed!</source>
+ <translation>Ha fallat la creació de la transacció!</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>S'ha rebutjat la transacció! Això pot passar si alguna de les monedes del vostre moneder ja s'han gastat; per exemple, si heu fet servir una còpia de seguretat del fitxer wallet.dat i s'haguessin gastat monedes de la còpia però sense marcar-les-hi com a gastades.</translation>
+ </message>
+ <message>
+ <source>A fee higher than %1 is considered an absurdly high fee.</source>
+ <translation>Una comissió superior a %1 es considera una comissió absurdament alta.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>La sol·licitud de pagament ha vençut.</translation>
+ </message>
+ <message numerus="yes">
+ <source>Estimated to begin confirmation within %n block(s).</source>
+ <translation><numerusform>Estimat per començar la confirmació en %n bloc.</numerusform><numerusform>Estimat per començar la confirmació en %n blocs.</numerusform></translation>
+ </message>
+ <message>
+ <source>Pay only the minimum fee of %1</source>
+ <translation>Paga només la comissió mínima de %1</translation>
+ </message>
+ <message>
+ <source>The recipient address is not valid. Please recheck.</source>
+ <translation>L'adreça de destinatari no és vàlida. Torneu-la a comprovar.</translation>
+ </message>
+ <message>
+ <source>Duplicate address found: addresses should only be used once each.</source>
+ <translation>S'ha trobat una adreça duplicada: cal utilitzar les adreces només un cop cada vegada.</translation>
+ </message>
+ <message>
+ <source>Warning: Invalid Bitcoin address</source>
+ <translation>Avís: adreça Bitcoin no vàlida</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(sense etiqueta)</translation>
+ </message>
+ <message>
+ <source>Warning: Unknown change address</source>
+ <translation>Avís: adreça de canvi desconeguda</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Copia el polsim</translation>
+ </message>
+ <message>
+ <source>Are you sure you want to send?</source>
+ <translation>Esteu segur que ho voleu enviar?</translation>
+ </message>
+ <message>
+ <source>added as transaction fee</source>
+ <translation>S'ha afegit una taxa de transacció</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>Q&amp;uantitat:</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>Paga &amp;a:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Introduïu una etiqueta per a aquesta adreça per afegir-la a la llibreta d'adreces</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Etiqueta:</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Escull una adreça feta servir anteriorment</translation>
+ </message>
+ <message>
+ <source>This is a normal payment.</source>
+ <translation>Això és un pagament normal.</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to send the payment to</source>
+ <translation>L'adreça Bitcoin on enviar el pagament</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alta+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Enganxar adreça del porta-retalls</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Remove this entry</source>
+ <translation>Elimina aquesta entrada</translation>
+ </message>
+ <message>
+ <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source>
+ <translation>La comissió es deduirà de l'import que s'enviarà. El destinatari rebrà menys bitcoins que les que introduïu al camp d'import. Si se seleccionen múltiples destinataris, la comissió es dividirà per igual.</translation>
+ </message>
+ <message>
+ <source>S&amp;ubtract fee from amount</source>
+ <translation>S&amp;ubstreu la comissió de l'import</translation>
+ </message>
+ <message>
+ <source>Message:</source>
+ <translation>Missatge:</translation>
+ </message>
+ <message>
+ <source>This is an unauthenticated payment request.</source>
+ <translation>Aquesta és una sol·licitud de pagament no autenticada.</translation>
+ </message>
+ <message>
+ <source>This is an authenticated payment request.</source>
+ <translation>Aquesta és una sol·licitud de pagament autenticada.</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to the list of used addresses</source>
+ <translation>Introduïu una etiqueta per a aquesta adreça per afegir-la a la llista d'adreces utilitzades</translation>
+ </message>
+ <message>
+ <source>A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network.</source>
+ <translation>Un missatge que s'ha adjuntat al bitcoin: URI que s'emmagatzemarà amb la transacció per a la vostra referència. Nota: el missatge no s'enviarà a través de la xarxa Bitcoin.</translation>
+ </message>
+ <message>
+ <source>Pay To:</source>
+ <translation>Paga a:</translation>
+ </message>
+ <message>
+ <source>Memo:</source>
+ <translation>Memo:</translation>
+ </message>
+</context>
+<context>
+ <name>ShutdownWindow</name>
+ <message>
+ <source>Bitcoin Core is shutting down...</source>
+ <translation>S'està aturant el Bitcoin Core...</translation>
+ </message>
+ <message>
+ <source>Do not shut down the computer until this window disappears.</source>
+ <translation>No apagueu l'ordinador fins que no desaparegui aquesta finestra.</translation>
+ </message>
+</context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Signatures - Sign / Verify a Message</source>
+ <translation>Signatures - Signa / verifica un missatge</translation>
+ </message>
+ <message>
+ <source>&amp;Sign Message</source>
+ <translation>&amp;Signa el missatge</translation>
+ </message>
+ <message>
+ <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source>
+ <translation>Podeu signar missatges/acords amb les vostres adreces per provar que rebeu les bitcoins que s'hi envien. Aneu amb compte no signar res que sigui vague o aleatori, perquè en alguns atacs de suplantació es pot provar que hi signeu la vostra identitat. Només signeu aquelles declaracions completament detallades en què hi esteu d'acord. </translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to sign the message with</source>
+ <translation>L'adreça Bitcoin amb què signar el missatge</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Tria les adreces fetes servir amb anterioritat</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Enganxa l'adreça del porta-retalls</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Enter the message you want to sign here</source>
+ <translation>Introduïu aquí el missatge que voleu signar</translation>
+ </message>
+ <message>
+ <source>Signature</source>
+ <translation>Signatura</translation>
+ </message>
+ <message>
+ <source>Copy the current signature to the system clipboard</source>
+ <translation>Copia la signatura actual al porta-retalls del sistema</translation>
+ </message>
+ <message>
+ <source>Sign the message to prove you own this Bitcoin address</source>
+ <translation>Signa el missatge per provar que ets propietari d'aquesta adreça Bitcoin</translation>
+ </message>
+ <message>
+ <source>Sign &amp;Message</source>
+ <translation>Signa el &amp;missatge</translation>
+ </message>
+ <message>
+ <source>Reset all sign message fields</source>
+ <translation>Neteja tots els camps de clau</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Neteja-ho &amp;tot</translation>
+ </message>
+ <message>
+ <source>&amp;Verify Message</source>
+ <translation>&amp;Verifica el missatge</translation>
+ </message>
+ <message>
+ <source>Enter the receiver's 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. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source>
+ <translation>Introduïu l'adreça del receptor, el missatge (assegureu-vos de copiar els salts de línia, espais, tabuladors, etc. exactament) i signatura de sota per verificar el missatge. Tingueu cura de no llegir més en la signatura del que està al missatge signat, per evitar ser enganyat per un atac d'home-en-el-mig. Tingueu en compte que això només demostra que la part que signa rep amb l'adreça, i no es pot provar l'enviament de qualsevol transacció!</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address the message was signed with</source>
+ <translation>L'adreça Bitcoin amb què va ser signat el missatge</translation>
+ </message>
+ <message>
+ <source>Verify the message to ensure it was signed with the specified Bitcoin address</source>
+ <translation>Verificar el missatge per assegurar-se que ha estat signat amb una adreça Bitcoin específica</translation>
+ </message>
+ <message>
+ <source>Verify &amp;Message</source>
+ <translation>Verifica el &amp;missatge</translation>
+ </message>
+ <message>
+ <source>Reset all verify message fields</source>
+ <translation>Neteja tots els camps de verificació de missatge</translation>
+ </message>
+ <message>
+ <source>Click "Sign Message" to generate signature</source>
+ <translation>Feu clic a «Signa el missatge» per a generar una signatura</translation>
+ </message>
+ <message>
+ <source>The entered address is invalid.</source>
+ <translation>L'adreça introduïda no és vàlida.</translation>
+ </message>
+ <message>
+ <source>Please check the address and try again.</source>
+ <translation>Comproveu l'adreça i torneu-ho a provar.</translation>
+ </message>
+ <message>
+ <source>The entered address does not refer to a key.</source>
+ <translation>L'adreça introduïda no referencia a cap clau.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock was cancelled.</source>
+ <translation>El desbloqueig del moneder ha estat cancelat.</translation>
+ </message>
+ <message>
+ <source>Private key for the entered address is not available.</source>
+ <translation>La clau privada per a la adreça introduïda no està disponible.</translation>
+ </message>
+ <message>
+ <source>Message signing failed.</source>
+ <translation>La signatura del missatge ha fallat.</translation>
+ </message>
+ <message>
+ <source>Message signed.</source>
+ <translation>Missatge signat.</translation>
+ </message>
+ <message>
+ <source>The signature could not be decoded.</source>
+ <translation>La signatura no s'ha pogut descodificar.</translation>
+ </message>
+ <message>
+ <source>Please check the signature and try again.</source>
+ <translation>Comproveu la signatura i torneu-ho a provar.</translation>
+ </message>
+ <message>
+ <source>The signature did not match the message digest.</source>
+ <translation>La signatura no coincideix amb el resum del missatge.</translation>
+ </message>
+ <message>
+ <source>Message verification failed.</source>
+ <translation>Ha fallat la verificació del missatge.</translation>
+ </message>
+ <message>
+ <source>Message verified.</source>
+ <translation>Missatge verificat.</translation>
+ </message>
+</context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>The Bitcoin Core developers</source>
+ <translation>Els desenvolupadors del Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>[testnet]</source>
+ <translation>[testnet]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ <message>
+ <source>KB/s</source>
+ <translation>KB/s</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>Obert fins %1</translation>
+ </message>
+ <message>
+ <source>conflicted</source>
+ <translation>en conflicte</translation>
+ </message>
+ <message>
+ <source>%1/offline</source>
+ <translation>%1/fora de línia</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/sense confirmar</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 confirmacions</translation>
+ </message>
+ <message>
+ <source>Status</source>
+ <translation>Estat</translation>
+ </message>
+ <message numerus="yes">
+ <source>, broadcast through %n node(s)</source>
+ <translation><numerusform>, difusió a través de %n node</numerusform><numerusform>, difusió a través de %n nodes</numerusform></translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Source</source>
+ <translation>Font</translation>
+ </message>
+ <message>
+ <source>Generated</source>
+ <translation>Generat</translation>
+ </message>
+ <message>
+ <source>From</source>
+ <translation>Des de</translation>
+ </message>
+ <message>
+ <source>To</source>
+ <translation>A</translation>
+ </message>
+ <message>
+ <source>own address</source>
+ <translation>Adreça pròpia</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>només lectura</translation>
+ </message>
+ <message>
+ <source>label</source>
+ <translation>etiqueta</translation>
+ </message>
+ <message>
+ <source>Credit</source>
+ <translation>Crèdit</translation>
+ </message>
+ <message numerus="yes">
+ <source>matures in %n more block(s)</source>
+ <translation><numerusform>disponible en %n bloc més</numerusform><numerusform>disponibles en %n blocs més</numerusform></translation>
+ </message>
+ <message>
+ <source>not accepted</source>
+ <translation>no acceptat</translation>
+ </message>
+ <message>
+ <source>Debit</source>
+ <translation>Dèbit</translation>
+ </message>
+ <message>
+ <source>Total debit</source>
+ <translation>Dèbit total</translation>
+ </message>
+ <message>
+ <source>Total credit</source>
+ <translation>Crèdit total</translation>
+ </message>
+ <message>
+ <source>Transaction fee</source>
+ <translation>Comissió de transacció</translation>
+ </message>
+ <message>
+ <source>Net amount</source>
+ <translation>Import net</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Missatge</translation>
+ </message>
+ <message>
+ <source>Comment</source>
+ <translation>Comentar</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>ID de transacció</translation>
+ </message>
+ <message>
+ <source>Merchant</source>
+ <translation>Mercader</translation>
+ </message>
+ <message>
+ <source>Generated coins must mature %1 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.</source>
+ <translation>Les monedes generades han de madurar %1 blocs abans de poder ser gastades. Quan genereu aquest bloc, es farà saber a la xarxa per tal d'afegir-lo a la cadena de blocs. Si no pot fer-se lloc a la cadena, el seu estat canviarà a «no acceptat» i no es podrà gastar. Això pot passar ocasionalment si un altre node genera un bloc en un marge de segons respecte al vostre.</translation>
+ </message>
+ <message>
+ <source>Debug information</source>
+ <translation>Informació de depuració</translation>
+ </message>
+ <message>
+ <source>Transaction</source>
+ <translation>Transacció</translation>
+ </message>
+ <message>
+ <source>Inputs</source>
+ <translation>Entrades</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Import</translation>
+ </message>
+ <message>
+ <source>true</source>
+ <translation>cert</translation>
+ </message>
+ <message>
+ <source>false</source>
+ <translation>fals</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, encara no ha estat emès correctement</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Obre per %n bloc més</numerusform><numerusform>Obre per %n blocs més</numerusform></translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>desconegut</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>Detall de la transacció</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>Aquest panell mostra una descripció detallada de la transacció</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Tipus</translation>
+ </message>
+ <message>
+ <source>Immature (%1 confirmations, will be available after %2)</source>
+ <translation>Immadur (%1 confirmacions, serà disponible després de %2)</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Obre per %n bloc més</numerusform><numerusform>Obre per %n blocs més</numerusform></translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>Obert fins %1</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>Confirmat (%1 confirmacions)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>Aquest bloc no ha estat rebut per cap altre node i probablement no serà acceptat!</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>Generat però no acceptat</translation>
+ </message>
+ <message>
+ <source>Offline</source>
+ <translation>Fora de línia</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiqueta</translation>
+ </message>
+ <message>
+ <source>Unconfirmed</source>
+ <translation>Sense confirmar</translation>
+ </message>
+ <message>
+ <source>Confirming (%1 of %2 recommended confirmations)</source>
+ <translation>Confirmant (%1 de %2 confirmacions recomanades)</translation>
+ </message>
+ <message>
+ <source>Conflicted</source>
+ <translation>En conflicte</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Rebut amb</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>Rebut de</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Enviat a</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>Pagament a un mateix</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Minat</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>només lectura</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(n/a)</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>Estat de la transacció. Desplaceu-vos sobre aquest camp per mostrar el nombre de confirmacions.</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Data i hora en que la transacció va ser rebuda.</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>Tipus de transacció.</translation>
+ </message>
+ <message>
+ <source>Whether or not a watch-only address is involved in this transaction.</source>
+ <translation>Si està implicada o no una adreça només de lectura en la transacció.</translation>
+ </message>
+ <message>
+ <source>User-defined intent/purpose of the transaction.</source>
+ <translation>Intenció/propòsit de la transacció definida per l'usuari.</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>Import extret o afegit del balanç.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>Tot</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>Avui</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>Aquesta setmana</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>Aquest mes</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>El mes passat</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>Enguany</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>Rang...</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Rebut amb</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Enviat a</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>A un mateix</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Minat</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>Altres</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>Introduïu una adreça o una etiqueta per cercar</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>Import mínim</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Copia l'adreça</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Copiar etiqueta</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copia l'import</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Copiar ID de transacció</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>Editar etiqueta</translation>
+ </message>
+ <message>
+ <source>Show transaction details</source>
+ <translation>Mostra detalls de la transacció</translation>
+ </message>
+ <message>
+ <source>Export Transaction History</source>
+ <translation>Exporta l'historial de transacció</translation>
+ </message>
+ <message>
+ <source>Watch-only</source>
+ <translation>Només de lectura</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>L'exportació ha fallat</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the transaction history to %1.</source>
+ <translation>S'ha produït un error en provar de desar l'historial de transacció a %1.</translation>
+ </message>
+ <message>
+ <source>Exporting Successful</source>
+ <translation>Exportació amb èxit</translation>
+ </message>
+ <message>
+ <source>The transaction history was successfully saved to %1.</source>
+ <translation>L'historial de transaccions s'ha desat correctament a %1.</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Fitxer separat per comes (*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Confirmat</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Tipus</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiqueta</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adreça</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>Rang:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>a</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ <message>
+ <source>Unit to show amounts in. Click to select another unit.</source>
+ <translation>Unitat en què mostrar els imports. Feu clic per seleccionar una altra unitat.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletFrame</name>
+ <message>
+ <source>No wallet has been loaded.</source>
+ <translation>No s'ha carregat cap moneder.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Envia monedes</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Exporta</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Exporta les dades de la pestanya actual a un fitxer</translation>
+ </message>
+ <message>
+ <source>Backup Wallet</source>
+ <translation>Còpia de seguretat del moneder</translation>
+ </message>
+ <message>
+ <source>Wallet Data (*.dat)</source>
+ <translation>Dades del moneder (*.dat)</translation>
+ </message>
+ <message>
+ <source>Backup Failed</source>
+ <translation>Ha fallat la còpia de seguretat</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the wallet data to %1.</source>
+ <translation>S'ha produït un error en provar de desar les dades del moneder a %1.</translation>
+ </message>
+ <message>
+ <source>The wallet data was successfully saved to %1.</source>
+ <translation>S'han desat les dades del moneder correctament a %1.</translation>
+ </message>
+ <message>
+ <source>Backup Successful</source>
+ <translation>La còpia de seguretat s'ha realitzat correctament</translation>
+ </message>
+</context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>Opcions:</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>Especifica el directori de dades</translation>
+ </message>
+ <message>
+ <source>Connect to a node to retrieve peer addresses, and disconnect</source>
+ <translation>Connecta al node per obtenir les adreces de les connexions, i desconnecta</translation>
+ </message>
+ <message>
+ <source>Specify your own public address</source>
+ <translation>Especifiqueu la vostra adreça pública</translation>
+ </message>
+ <message>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>Accepta la línia d'ordres i ordres JSON-RPC </translation>
+ </message>
+ <message>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>Executa en segon pla com a programa dimoni i accepta ordres</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>Utilitza la xarxa de prova</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
+ <translation>Accepta connexions de fora (per defecte: 1 si no -proxy o -connect)</translation>
+ </message>
+ <message>
+ <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
+ <translation>Vincula a una adreça específica i sempre escolta-hi. Utilitza la notació [host]:port per IPv6</translation>
+ </message>
+ <message>
+ <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
+ <translation>Elimina totes les transaccions del moneder i només recupera aquelles de la cadena de blocs a través de -rescan a l'inici</translation>
+ </message>
+ <message>
+ <source>Distributed under the MIT software license, see the accompanying file COPYING or &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</source>
+ <translation>Distribuït sota llicència de programari MIT. Vegeu el fitxer acompanyant COPYING o &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</translation>
+ </message>
+ <message>
+ <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
+ <translation>Executa una ordre quan una transacció del moneder canviï (%s en cmd es canvia per TxID)</translation>
+ </message>
+ <message>
+ <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source>
+ <translation>Comissions totals màximes que s'utilitzaran en una única transacció de moneder; si s'estableix un valor massa baix es poden interrompre transaccions grans (per defecte: %s)</translation>
+ </message>
+ <message>
+ <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, &gt;%u = target size in MiB to use for block files)</source>
+ <translation>Redueix els requeriments d'emmagatzemament podant (suprimint) els blocs antics. Aquest mode inhabilita l'ús de moneders i és incompatible amb -tindex. Avís: Revertir aquesta configuració comporta tornar a baixar la cadena de blocs sencera. (per defecte: 0 = inhabilita la poda de blocs, &gt;%u = mida objectiu en MiB per utilitzar els fitxers de blocs)</translation>
+ </message>
+ <message>
+ <source>Set the number of script verification threads (%u to %d, 0 = auto, &lt;0 = leave that many cores free, default: %d)</source>
+ <translation>Defineix el nombre de fils de verificació d'scripts (%u a %d, 0 = auto, &lt;0 = deixa tants nuclis lliures, per defecte: %d)</translation>
+ </message>
+ <message>
+ <source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source>
+ <translation>Aquesta és una versió de pre-llançament - utilitza-la sota la teva responsabilitat - No usar per a minería o aplicacions de compra-venda</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer. Bitcoin Core is probably already running.</source>
+ <translation>No es pot enllaçar %s a aquest ordinador. El Bitcoin Core probablement ja estigui executant-s'hi.</translation>
+ </message>
+ <message>
+ <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>AVÍS: s'ha generat un nombre anòmalament alt de blocs, %d blocs rebuts en les darreres %d hores (se n'esperaven %d)</translation>
+ </message>
+ <message>
+ <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>AVÍS: comproveu la vostra connexió a la xarxa, %d blocs rebuts en les darreres %d hores (se n'esperaven %d)</translation>
+ </message>
+ <message>
+ <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>Avís: el -paytxfee és molt elevat! Aquesta és la comissió de transacció que pagareu si envieu una transacció.</translation>
+ </message>
+ <message>
+ <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source>
+ <translation>Avís: la xarxa no sembla que hi estigui plenament d'acord. Alguns miners sembla que estan experimentant problemes.</translation>
+ </message>
+ <message>
+ <source>Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.</source>
+ <translation>Avís: sembla que no estem plenament d'acord amb els nostres iguals! Podria caler que actualitzar l'aplicació, o potser que ho facin altres nodes.</translation>
+ </message>
+ <message>
+ <source>Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
+ <translation>Avís: error en llegir el fitxer wallet.dat! Totes les claus es llegeixen correctament, però hi ha dades de transaccions o entrades de la llibreta d'adreces absents o bé son incorrectes.</translation>
+ </message>
+ <message>
+ <source>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</source>
+ <translation>Avís: el fitxer wallet.dat és corrupte, dades rescatades! L'arxiu wallet.dat original ha estat desat com wallet.{estampa_temporal}.bak al directori %s; si el teu balanç o transaccions son incorrectes hauries de restaurar-lo de un backup.</translation>
+ </message>
+ <message>
+ <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source>
+ <translation>Afegeix a la llista blanca els iguals que es connecten de la màscara de xarxa o adreça IP donada. Es pot especificar moltes vegades.</translation>
+ </message>
+ <message>
+ <source>(default: 1)</source>
+ <translation>(per defecte: 1)</translation>
+ </message>
+ <message>
+ <source>&lt;category&gt; can be:</source>
+ <translation>&lt;category&gt; pot ser:</translation>
+ </message>
+ <message>
+ <source>Attempt to recover private keys from a corrupt wallet.dat</source>
+ <translation>Intenta recuperar les claus privades d'un fitxer wallet.dat corrupte</translation>
+ </message>
+ <message>
+ <source>Block creation options:</source>
+ <translation>Opcions de la creació de blocs:</translation>
+ </message>
+ <message>
+ <source>Connect only to the specified node(s)</source>
+ <translation>Connecta només al(s) node(s) especificats</translation>
+ </message>
+ <message>
+ <source>Connection options:</source>
+ <translation>Opcions de connexió:</translation>
+ </message>
+ <message>
+ <source>Corrupted block database detected</source>
+ <translation>S'ha detectat una base de dades de blocs corrupta</translation>
+ </message>
+ <message>
+ <source>Debugging/Testing options:</source>
+ <translation>Opcions de depuració/proves:</translation>
+ </message>
+ <message>
+ <source>Do not load the wallet and disable wallet RPC calls</source>
+ <translation>No carreguis el moneder i inhabilita les crides RPC del moneder</translation>
+ </message>
+ <message>
+ <source>Do you want to rebuild the block database now?</source>
+ <translation>Voleu reconstruir la base de dades de blocs ara?</translation>
+ </message>
+ <message>
+ <source>Error initializing block database</source>
+ <translation>Error carregant la base de dades de blocs</translation>
+ </message>
+ <message>
+ <source>Error initializing wallet database environment %s!</source>
+ <translation>Error inicialitzant l'entorn de la base de dades del moneder %s!</translation>
+ </message>
+ <message>
+ <source>Error loading block database</source>
+ <translation>Error carregant la base de dades del bloc</translation>
+ </message>
+ <message>
+ <source>Error opening block database</source>
+ <translation>Error en obrir la base de dades de blocs</translation>
+ </message>
+ <message>
+ <source>Error: Disk space is low!</source>
+ <translation>Error: Espai al disc baix!</translation>
+ </message>
+ <message>
+ <source>Failed to listen on any port. Use -listen=0 if you want this.</source>
+ <translation>Ha fallat escoltar a qualsevol port. Feu servir -listen=0 si voleu fer això.</translation>
+ </message>
+ <message>
+ <source>If &lt;category&gt; is not supplied, output all debugging information.</source>
+ <translation>Si no se subministra &lt;category&gt;, mostra tota la informació de depuració.</translation>
+ </message>
+ <message>
+ <source>Importing...</source>
+ <translation>S'està important...</translation>
+ </message>
+ <message>
+ <source>Incorrect or no genesis block found. Wrong datadir for network?</source>
+ <translation>No s'ha trobat el bloc de gènesi o és incorrecte. El directori de dades de la xarxa és incorrecte?</translation>
+ </message>
+ <message>
+ <source>Invalid -onion address: '%s'</source>
+ <translation>Adreça -onion no vàlida: '%s'</translation>
+ </message>
+ <message>
+ <source>Not enough file descriptors available.</source>
+ <translation>No hi ha suficient descriptors de fitxers disponibles.</translation>
+ </message>
+ <message>
+ <source>Only connect to nodes in network &lt;net&gt; (ipv4, ipv6 or onion)</source>
+ <translation>Només connecta als nodes de la xarxa &lt;net&gt; (ipv4, ipv6 o onion)</translation>
+ </message>
+ <message>
+ <source>Prune cannot be configured with a negative value.</source>
+ <translation>La poda no es pot configurar amb un valor negatiu.</translation>
+ </message>
+ <message>
+ <source>Prune mode is incompatible with -txindex.</source>
+ <translation>El mode de poda és incompatible amb -txindex.</translation>
+ </message>
+ <message>
+ <source>Set database cache size in megabytes (%d to %d, default: %d)</source>
+ <translation>Defineix la mida de la memòria cau de la base de dades en megabytes (%d a %d, per defecte: %d)</translation>
+ </message>
+ <message>
+ <source>Set maximum block size in bytes (default: %d)</source>
+ <translation>Defineix la mida màxim del bloc en bytes (per defecte: %d)</translation>
+ </message>
+ <message>
+ <source>Specify wallet file (within data directory)</source>
+ <translation>Especifica un fitxer de moneder (dins del directori de dades)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: %u)</source>
+ <translation>Utilitza UPnP per a mapejar el port d'escolta (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Verifying blocks...</source>
+ <translation>S'estan verificant els blocs...</translation>
+ </message>
+ <message>
+ <source>Verifying wallet...</source>
+ <translation>S'està verificant el moneder...</translation>
+ </message>
+ <message>
+ <source>Wallet %s resides outside data directory %s</source>
+ <translation>El moneder %s resideix fora del directori de dades %s</translation>
+ </message>
+ <message>
+ <source>Wallet options:</source>
+ <translation>Opcions de moneder:</translation>
+ </message>
+ <message>
+ <source>Warning: This version is obsolete; upgrade required!</source>
+ <translation>Avís: aquesta versió és obsoleta; cal actualitzar-la!</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to change -txindex</source>
+ <translation>Cal que reconstruïu la base de dades fent servir -reindex per canviar -txindex</translation>
+ </message>
+ <message>
+ <source>Imports blocks from external blk000??.dat file</source>
+ <translation>Importa blocs de un fitxer blk000??.dat extern</translation>
+ </message>
+ <message>
+ <source>Allow JSON-RPC connections from specified source. Valid for &lt;ip&gt; are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times</source>
+ <translation>Permet les connexions JSON-RPC d'una font específica. Vàlid per a &lt;ip&gt; són una IP individual (p. ex., 1.2.3.4), una xarxa / màscara de xarxa (p. ex., 1.2.3.4/255.255.255.0) o una xarxa/CIDR (p. ex., 1.2.3.4/24). Es pot especificar aquesta opció moltes vegades</translation>
+ </message>
+ <message>
+ <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source>
+ <translation>Vincula l'adreça donada i posa a la llista blanca els iguals que s'hi connectin. Feu servir la notació [host]:port per a IPv6</translation>
+ </message>
+ <message>
+ <source>Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)</source>
+ <translation>Vincula a l'adreça donada per a escoltar les connexions JSON-RPC. Feu servir la notació [host]:port per a IPv6. Aquesta opció pot ser especificada moltes vegades (per defecte: vincula a totes les interfícies)</translation>
+ </message>
+ <message>
+ <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source>
+ <translation>No es pot obtenir un bloqueig del directori de dades %s. El Bitcoin Core probablement ja s'estigui executant.</translation>
+ </message>
+ <message>
+ <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
+ <translation>Crea fitxers nous amb els permisos per defecte del sistema, en comptes de l'umask 077 (només efectiu amb la funcionalitat de moneder inhabilitada)</translation>
+ </message>
+ <message>
+ <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source>
+ <translation>Descobreix l'adreça IP pròpia (per defecte: 1 quan s'escolta i no -externalip o -proxy)</translation>
+ </message>
+ <message>
+ <source>Error: Listening for incoming connections failed (listen returned error %s)</source>
+ <translation>Error: ha fallat escoltar les connexions entrants (l'escoltament ha retornat l'error %s)</translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source>
+ <translation>Error: s'ha trobat un argument no permès de -socks. Ja no es pot definir més la versió de SOCKS, només s'accepten els proxies de SOCKS5.ç</translation>
+ </message>
+ <message>
+ <source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source>
+ <translation>Executa l'ordre quan es rebi un avís rellevant o veiem una forquilla molt llarga (%s en cmd és reemplaçat per un missatge)</translation>
+ </message>
+ <message>
+ <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source>
+ <translation>Comissions (en BTC/Kb) inferiors a això es consideren de comissió zero per a la transmissió (per defecte: %s)</translation>
+ </message>
+ <message>
+ <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
+ <translation>Si no s'especifica una paytxfee (comissió de transacció de pagament), inclogueu suficient comissió per tal que les transaccions comencin a confirmar-se en una mitja de n blocs (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)</source>
+ <translation>Import no vàlid per a -maxtxfee=&lt;amount&gt;: '%s' (cal que sigui com a mínim la comissió de minrelay de %s per evitar que les comissions s'encallin)</translation>
+ </message>
+ <message>
+ <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source>
+ <translation>Mida màxima de les dades en les transaccions de l'operador en què confiem i en les meves (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Prune configured below the minimum of %d MB. Please use a higher number.</source>
+ <translation>Poda configurada per sota el mínim de %d MB. Feu servir un nombre superior.</translation>
+ </message>
+ <message>
+ <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source>
+ <translation>Consulta a adreces d'iguals a través de DNS, si es troba baix en adreces (per defecte: 1 a menys que -connect)</translation>
+ </message>
+ <message>
+ <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source>
+ <translation>Genera a l'atzar credencials per a cada connexió proxy. Això habilita l'aïllament del flux de Tor (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
+ <translation>Defineix la mida màxima de transaccions d'alta prioritat / baixa comissió en bytes (per defecte: %d)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source>
+ <translation>Defineix el nombre de fils per a la generació de moneda si està habilitat (-1 = tots els nuclis, per defecte: %d)</translation>
+ </message>
+ <message>
+ <source>The transaction amount is too small to send after the fee has been deducted</source>
+ <translation>L'import de la transacció és massa petit per enviar-la després que se'n dedueixi la comissió</translation>
+ </message>
+ <message>
+ <source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit &lt;https://www.openssl.org/&gt; and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source>
+ <translation>Aquest producte inclou programari desenvolupat pel projecte OpenSSL per a ús a l'OpenSSL Toolkit &lt;https://www.openssl.org/&gt; i programari criptogràfic escrit per Eric Young i programari UPnP escrit per Thomas Bernard.</translation>
+ </message>
+ <message>
+ <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an 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)
+The username and password MUST NOT be the same.
+If the file does not exist, create it with owner-readable-only file permissions.
+It is also recommended to set alertnotify so you are notified of problems;
+for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
+</source>
+ <translation>Per utilitzar bitcoind, o l'opció de serviddor de bitcoin-qt, heu de definir una rpcpassword en el fitxer de configuració:
+%s
+Es recomana que utilitzeu la contrasenya aleatòria següent:
+rpcuser=bitcoinrpc
+rpcpassword=%s
+(no cal que recordeu la contrasenya)
+El nom d'usuari i la contrasenya NO han de ser els mateixos.
+Si el fitxer no existeix, creeu-ne un amb permisos de lectura només per al seu propietari.
+Es recomana definir alertnotify per tal de ser notificat de qualsevol problema;
+per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</translation>
+ </message>
+ <message>
+ <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source>
+ <translation>Avís: s'ha especificat un -maxtxfee molt alt! Comissions tan grans podrien pagar-se en una única transacció.</translation>
+ </message>
+ <message>
+ <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source>
+ <translation>Avís: comproveu que la data i hora del vostre ordinador siguin correctes! Si el vostre rellotge no és correcte, el Bitcoin Core no funcionarà correctament.</translation>
+ </message>
+ <message>
+ <source>Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway</source>
+ <translation>Els iguals en la llista blanca no poden ser bandejats per DoS i es transmetran sempre llurs transaccions, fins i tot si ja són a la mempool. Això és útil, p. ex., per a una passarel·la</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source>
+ <translation>Cal que torneu a construir la base de dades fent servir -reindex per tornar al mode no podat. Això tornarà a baixar la cadena de blocs sencera</translation>
+ </message>
+ <message>
+ <source>(default: %u)</source>
+ <translation>(per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Accept public REST requests (default: %u)</source>
+ <translation>Accepta sol·licituds REST públiques (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Activating best chain...</source>
+ <translation>S'està activant la millor cadena...</translation>
+ </message>
+ <message>
+ <source>Can't run with a wallet in prune mode.</source>
+ <translation>No es pot executar amb un moneder en mode poda.</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -whitebind address: '%s'</source>
+ <translation>No es pot resoldre l'adreça -whitebind: «%s»</translation>
+ </message>
+ <message>
+ <source>Choose data directory on startup (default: 0)</source>
+ <translation>Tria el directori de dades a l'inici (per defecte: 0)</translation>
+ </message>
+ <message>
+ <source>Connect through SOCKS5 proxy</source>
+ <translation>Connecta a través del proxy SOCKS5</translation>
+ </message>
+ <message>
+ <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source>
+ <translation>Copyright (C) 2009-%i Els desenvolupadors del Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Could not parse -rpcbind value %s as network address</source>
+ <translation>No s'ha pogut analitzar el valor -rpcbind %s com una adreça de xarxa</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source>
+ <translation>Error en carregar wallet.dat: el moneder requereix una versió més nova del Bitcoin core</translation>
+ </message>
+ <message>
+ <source>Error reading from database, shutting down.</source>
+ <translation>Error en llegir la base de dades, tancant.</translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -tor found, use -onion.</source>
+ <translation>Error: s'ha trobat un argument -tor no acceptat. Feu servir -onion.</translation>
+ </message>
+ <message>
+ <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source>
+ <translation>Comissió en (BTC/kB) per afegir a les transaccions que envieu (per defecte: %s)</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>&amp;Informació</translation>
+ </message>
+ <message>
+ <source>Initialization sanity check failed. Bitcoin Core is shutting down.</source>
+ <translation>Ha fallat la inicialització de la comprovació de validesa. El Bitcoin Core s'està aturant.</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Import no vàlid per a -maxtxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -minrelaytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Import no vàlid per a -minrelaytxfee=&lt;amount&gt;: «%s»</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -mintxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Import no vàlid per a -mintxfee=&lt;amount&gt;: «%s»</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s' (must be at least %s)</source>
+ <translation>Import no vàlid per a -paytxfee=&lt;amount&gt;: «%s» (ha de ser com a mínim %s)</translation>
+ </message>
+ <message>
+ <source>Invalid netmask specified in -whitelist: '%s'</source>
+ <translation>S'ha especificat una màscara de xarxa no vàlida a -whitelist: «%s»</translation>
+ </message>
+ <message>
+ <source>Keep at most &lt;n&gt; unconnectable transactions in memory (default: %u)</source>
+ <translation>Manté com a màxim &lt;n&gt; transaccions no connectables en memòria (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Need to specify a port with -whitebind: '%s'</source>
+ <translation>Cal especificar un port amb -whitebind: «%s»</translation>
+ </message>
+ <message>
+ <source>Node relay options:</source>
+ <translation>Opcions de transmissió del node:</translation>
+ </message>
+ <message>
+ <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source>
+ <translation>Opcions RPC SSL: (veieu el wiki del Bitcoin per a instruccions de configuració de l'SSL)</translation>
+ </message>
+ <message>
+ <source>RPC server options:</source>
+ <translation>Opcions del servidor RPC:</translation>
+ </message>
+ <message>
+ <source>RPC support for HTTP persistent connections (default: %d)</source>
+ <translation>Suport RPC per a connexions HTTP persistents (per defecte: %d)</translation>
+ </message>
+ <message>
+ <source>Rebuild block chain index from current blk000??.dat files on startup</source>
+ <translation>Reconstrueix l'índex de la cadena de blocs dels fitxers blk000??.dat actuals a l'inici.</translation>
+ </message>
+ <message>
+ <source>Receive and display P2P network alerts (default: %u)</source>
+ <translation>Rep i mostra avisos de la xarxa P2P (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>Envia informació de traça/depuració a la consola en comptes del fitxer debug.log</translation>
+ </message>
+ <message>
+ <source>Send transactions as zero-fee transactions if possible (default: %u)</source>
+ <translation>Envia les transaccions com a transaccions de comissió zero sempre que sigui possible (per defecte: %u) </translation>
+ </message>
+ <message>
+ <source>Set SSL root certificates for payment request (default: -system-)</source>
+ <translation>Defineix certificats arrel SSL per a la sol·licitud de pagament (per defecte: -sistema-)</translation>
+ </message>
+ <message>
+ <source>Set language, for example "de_DE" (default: system locale)</source>
+ <translation>Defineix un idioma, per exemple «de_DE» (per defecte: preferències locals de sistema)</translation>
+ </message>
+ <message>
+ <source>Show all debugging options (usage: --help -help-debug)</source>
+ <translation>Mostra totes les opcions de depuració (ús: --help --help-debug)</translation>
+ </message>
+ <message>
+ <source>Show splash screen on startup (default: 1)</source>
+ <translation>Mostra la finestra de benvinguda a l'inici (per defecte: 1)</translation>
+ </message>
+ <message>
+ <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source>
+ <translation>Redueix el fitxer debug.log durant l'inici del client (per defecte: 1 quan no -debug)</translation>
+ </message>
+ <message>
+ <source>Signing transaction failed</source>
+ <translation>Ha fallat la signatura de la transacció</translation>
+ </message>
+ <message>
+ <source>Start minimized</source>
+ <translation>Inicia minimitzat</translation>
+ </message>
+ <message>
+ <source>The transaction amount is too small to pay the fee</source>
+ <translation>L'import de la transacció és massa petit per pagar-ne una comissió</translation>
+ </message>
+ <message>
+ <source>This is experimental software.</source>
+ <translation>Això és programari experimental.</translation>
+ </message>
+ <message>
+ <source>Transaction amount too small</source>
+ <translation>Import de la transacció massa petit</translation>
+ </message>
+ <message>
+ <source>Transaction amounts must be positive</source>
+ <translation>Els imports de les transaccions han de ser positius</translation>
+ </message>
+ <message>
+ <source>Transaction too large for fee policy</source>
+ <translation>Transacció massa gran per a la política de comissions</translation>
+ </message>
+ <message>
+ <source>Transaction too large</source>
+ <translation>La transacció és massa gran</translation>
+ </message>
+ <message>
+ <source>UI Options:</source>
+ <translation>Opcions d'interfície:</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer (bind returned error %s)</source>
+ <translation>No s'ha pogut vincular a %s en aquest ordinador (la vinculació ha retornat l'error %s)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: 1 when listening)</source>
+ <translation>Utilitza UPnP per a mapejar els ports d'escolta (per defecte: 1 quan s'escolta)</translation>
+ </message>
+ <message>
+ <source>Username for JSON-RPC connections</source>
+ <translation>Nom d'usuari per a connexions JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Wallet needed to be rewritten: restart Bitcoin Core to complete</source>
+ <translation>Cal reescriure el moneder: reiniceu el Bitcoin Core per completar-ho.</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Avís</translation>
+ </message>
+ <message>
+ <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source>
+ <translation>Avís: s'ha ignorat l'argument no acceptat de -benchmark. Feu servir -debug=bench.</translation>
+ </message>
+ <message>
+ <source>Warning: Unsupported argument -debugnet ignored, use -debug=net.</source>
+ <translation>Avís: s'ha ignorat l'argument no acceptat de -debugnet. Feu servir -debug=net.</translation>
+ </message>
+ <message>
+ <source>Zapping all transactions from wallet...</source>
+ <translation>Se suprimeixen totes les transaccions del moneder...</translation>
+ </message>
+ <message>
+ <source>on startup</source>
+ <translation>a l'inici de l'aplicació</translation>
+ </message>
+ <message>
+ <source>wallet.dat corrupt, salvage failed</source>
+ <translation>El fitxer wallet.data és corrupte. El rescat de les dades ha fallat</translation>
+ </message>
+ <message>
+ <source>Password for JSON-RPC connections</source>
+ <translation>Contrasenya per a connexions JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
+ <translation>Executa l'ordre quan el millor bloc canviï (%s en cmd es reemplaça per un resum de bloc)</translation>
+ </message>
+ <message>
+ <source>Upgrade wallet to latest format</source>
+ <translation>Actualitza el moneder a l'últim format</translation>
+ </message>
+ <message>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>Reescaneja la cadena de blocs en les transaccions de moneder perdudes</translation>
+ </message>
+ <message>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>Utilitza OpenSSL (https) per a connexions JSON-RPC</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>Aquest misatge d'ajuda</translation>
+ </message>
+ <message>
+ <source>Allow DNS lookups for -addnode, -seednode and -connect</source>
+ <translation>Permet consultes DNS per a -addnode, -seednode i -connect</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>S'estan carregant les adreces...</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>Error en carregar wallet.dat: Moneder corrupte</translation>
+ </message>
+ <message>
+ <source>(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source>
+ <translation>(1 = manté les metadades de les tx, p. ex., propietari del compte i informació de sol·licitud del pagament, 2 = prescindeix de les metadades de les tx)</translation>
+ </message>
+ <message>
+ <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
+ <translation>Com d'exhaustiva és la verificació de blocs del -checkblocks (0-4, per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
+ <translation>Manté un índex complet de transaccions, utilitzat per la crida rpc getrawtransaction (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source>
+ <translation>Nombre de segons necessaris perquè els iguals de comportament qüestionable puguin tornar a connectar-se (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Output debugging information (default: %u, supplying &lt;category&gt; is optional)</source>
+ <translation>Informació de sortida de la depuració (per defecte: %u, proporcionar &lt;category&gt; és opcional)</translation>
+ </message>
+ <message>
+ <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source>
+ <translation>Utilitza un proxy SOCKS4 apart per a arribar als iguals a través de serveis ocults de Tor (per defecte: %s)</translation>
+ </message>
+ <message>
+ <source>(default: %s)</source>
+ <translation>(per defecte: %s)</translation>
+ </message>
+ <message>
+ <source>Acceptable ciphers (default: %s)</source>
+ <translation>Xifrats acceptables (per defecte: %s)</translation>
+ </message>
+ <message>
+ <source>Always query for peer addresses via DNS lookup (default: %u)</source>
+ <translation>Demana sempre les adreces dels iguals a través de consultes DNS (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>Error en carregar wallet.dat</translation>
+ </message>
+ <message>
+ <source>Generate coins (default: %u)</source>
+ <translation>Genera monedes (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>How many blocks to check at startup (default: %u, 0 = all)</source>
+ <translation>Quants blocs per comprovar a l'inici (per defecte: %u, 0 = tots)</translation>
+ </message>
+ <message>
+ <source>Include IP addresses in debug output (default: %u)</source>
+ <translation>Inclou l'adreça IP a la sortida de depuració (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Invalid -proxy address: '%s'</source>
+ <translation>Adreça -proxy invalida: '%s'</translation>
+ </message>
+ <message>
+ <source>Listen for JSON-RPC connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>Escolta les connexions JSON-RPC en &lt;port&gt; (per defecte: %u o testnet: %u)</translation>
+ </message>
+ <message>
+ <source>Listen for connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>Escolta les connexions en &lt;port&gt; (per defecte: %u o testnet: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain at most &lt;n&gt; connections to peers (default: %u)</source>
+ <translation>Manté com a màxim &lt;n&gt; connexions a iguals (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Make the wallet broadcast transactions</source>
+ <translation>Fes que el moneder faci difusió de les transaccions</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection receive buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>Memòria intermèdia màxima de recepció per connexió, &lt;n&gt;*1000 bytes (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection send buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>Memòria intermèdia màxima d'enviament per connexió, &lt;n&gt;*1000 bytes (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Prepend debug output with timestamp (default: %u)</source>
+ <translation>Posa davant de la sortida de depuració una marca horària (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Relay and mine data carrier transactions (default: %u)</source>
+ <translation>Retransmet i mina les transaccions de l'operador (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Relay non-P2SH multisig (default: %u)</source>
+ <translation>Retransmet multisig no P2SH (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Server certificate file (default: %s)</source>
+ <translation>Fitxer de certificat del servidor (per defecte: %s)</translation>
+ </message>
+ <message>
+ <source>Server private key (default: %s)</source>
+ <translation>Clau privada del servidor (per defecte: %s)</translation>
+ </message>
+ <message>
+ <source>Set key pool size to &lt;n&gt; (default: %u)</source>
+ <translation>Defineix la mida clau disponible a &lt;n&gt; (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Set minimum block size in bytes (default: %u)</source>
+ <translation>Defineix la mida de bloc mínima en bytes (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads to service RPC calls (default: %d)</source>
+ <translation>Defineix el nombre de fils a crides de servei RPC (per defecte: %d)</translation>
+ </message>
+ <message>
+ <source>Specify configuration file (default: %s)</source>
+ <translation>Especifica el fitxer de configuració (per defecte: %s)</translation>
+ </message>
+ <message>
+ <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source>
+ <translation>Especifica el temps d'espera de la connexió en milisegons (mínim: 1, per defecte: %d)</translation>
+ </message>
+ <message>
+ <source>Specify pid file (default: %s)</source>
+ <translation>Especifica el fitxer pid (per defecte: %s)</translation>
+ </message>
+ <message>
+ <source>Spend unconfirmed change when sending transactions (default: %u)</source>
+ <translation>Gasta el canvi no confirmat en enviar les transaccions (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Threshold for disconnecting misbehaving peers (default: %u)</source>
+ <translation>Llindar per a desconnectar els iguals de comportament qüestionable (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Unknown network specified in -onlynet: '%s'</source>
+ <translation>Xarxa desconeguda especificada a -onlynet: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -bind address: '%s'</source>
+ <translation>No es pot resoldre l'adreça -bind: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -externalip address: '%s'</source>
+ <translation>No es pot resoldre l'adreça -externalip: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Import no vàlid per a -paytxfee=&lt;amount&gt;: «%s»</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>Balanç insuficient</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>S'està carregant l'índex de blocs...</translation>
+ </message>
+ <message>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>Afegeix un node per a connectar-s'hi i intenta mantenir-hi la connexió oberta</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>S'està carregant el moneder...</translation>
+ </message>
+ <message>
+ <source>Cannot downgrade wallet</source>
+ <translation>No es pot reduir la versió del moneder</translation>
+ </message>
+ <message>
+ <source>Cannot write default address</source>
+ <translation>No es pot escriure l'adreça per defecte</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>S'està reescanejant...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>Ha acabat la càrrega</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Error</translation>
+ </message>
+</context>
+</TS> \ No newline at end of file
diff --git a/src/qt/locale/bitcoin_cmn.ts b/src/qt/locale/bitcoin_cmn.ts
new file mode 100644
index 0000000000..37c937b864
--- /dev/null
+++ b/src/qt/locale/bitcoin_cmn.ts
@@ -0,0 +1,114 @@
+<TS language="cmn" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Create a new address</source>
+ <translation>创建新地址</translation>
+ </message>
+ </context>
+<context>
+ <name>AddressTableModel</name>
+ </context>
+<context>
+ <name>AskPassphraseDialog</name>
+ </context>
+<context>
+ <name>BitcoinGUI</name>
+ </context>
+<context>
+ <name>ClientModel</name>
+ </context>
+<context>
+ <name>CoinControlDialog</name>
+ </context>
+<context>
+ <name>EditAddressDialog</name>
+ </context>
+<context>
+ <name>FreespaceChecker</name>
+ </context>
+<context>
+ <name>HelpMessageDialog</name>
+ </context>
+<context>
+ <name>Intro</name>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ </context>
+<context>
+ <name>OptionsDialog</name>
+ </context>
+<context>
+ <name>OverviewPage</name>
+ </context>
+<context>
+ <name>PaymentServer</name>
+ </context>
+<context>
+ <name>PeerTableModel</name>
+ </context>
+<context>
+ <name>QObject</name>
+ </context>
+<context>
+ <name>QRImageWidget</name>
+ </context>
+<context>
+ <name>RPCConsole</name>
+ </context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ </context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ </context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ </context>
+<context>
+ <name>SendCoinsDialog</name>
+ </context>
+<context>
+ <name>SendCoinsEntry</name>
+ </context>
+<context>
+ <name>ShutdownWindow</name>
+ </context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ </context>
+<context>
+ <name>SplashScreen</name>
+ </context>
+<context>
+ <name>TrafficGraphWidget</name>
+ </context>
+<context>
+ <name>TransactionDesc</name>
+ </context>
+<context>
+ <name>TransactionDescDialog</name>
+ </context>
+<context>
+ <name>TransactionTableModel</name>
+ </context>
+<context>
+ <name>TransactionView</name>
+ </context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ </context>
+<context>
+ <name>WalletFrame</name>
+ </context>
+<context>
+ <name>WalletModel</name>
+ </context>
+<context>
+ <name>WalletView</name>
+ </context>
+<context>
+ <name>bitcoin-core</name>
+ </context>
+</TS> \ 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 0000000000..f809b292b4
--- /dev/null
+++ b/src/qt/locale/bitcoin_cs.ts
@@ -0,0 +1,3576 @@
+<TS language="cs" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Right-click to edit address or label</source>
+ <translation>Pravým tlačítkem myši začneš upravovat označení adresy</translation>
+ </message>
+ <message>
+ <source>Create a new address</source>
+ <translation>Vytvoř novou adresu</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>&amp;Nová</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Zkopíruj aktuálně vybranou adresu do systémové schránky</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>&amp;Kopíruj</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>&amp;Zavřít</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>&amp;Kopíruj adresu</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>Smaž zvolenou adresu ze seznamu</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Exportuj data z tohoto panelu do souboru</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Export</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>S&amp;maž</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>Zvol adresu, na kterou pošleš mince</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>Zvol adres na příjem mincí</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>&amp;Zvol</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>Odesílací adresy</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>Přijímací adresy</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>Tohle jsou tvé Bitcoinové adresy pro posílání plateb. Před odesláním mincí si vždy zkontroluj částku a cílovou adresu.</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>Tohle jsou tvé Bitcoinové adresy pro příjem plateb. Je doporučené používat pokaždé novou adresu pro každou transakci.</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>Kopíruj &amp;označení</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>&amp;Uprav</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>Exportuj seznam adres</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>CSV formát (*.csv)</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Exportování selhalo</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the address list to %1. Please try again.</source>
+ <translation>Při ukládání seznamu adres do %1 se přihodila nějaká chyba. Zkus to prosím znovu.</translation>
+ </message>
+</context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Označení</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adresa</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(bez označení)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Passphrase Dialog</source>
+ <translation>Změna hesla</translation>
+ </message>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Zadej platné heslo</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Zadej nové heslo</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Totéž heslo ještě jednou</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>Zašifruj peněženku</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>K provedení této operace musíš zadat heslo k peněžence, aby se mohla odemknout.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Odemkni peněženku</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>K provedení této operace musíš zadat heslo k peněžence, aby se mohla dešifrovat.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>Dešifruj peněženku</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>Změň heslo</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>Potvrď zašifrování peněženky</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>Upozornění: Pokud si zašifruješ peněženku a ztratíš či zapomeneš heslo, &lt;b&gt;PŘIJDEŠ O VŠECHNY BITCOINY&lt;/b&gt;!</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>Jsi si jistý, že chceš peněženku zašifrovat?</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core 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.</source>
+ <translation>Bitcoin Core se teď ukončí, aby dokončil zašifrování. Pamatuj však, že pouhé zašifrování peněženky nemůže zabránit krádeži tvých bitcoinů malwarem, kterým se může počítač nakazit.</translation>
+ </message>
+ <message>
+ <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
+ <translation>DŮLEŽITÉ: Všechny předchozí zálohy peněženky by měly být nahrazeny nově vygenerovanou, zašifrovanou peněženkou. Z bezpečnostních důvodů budou předchozí zálohy nešifrované peněženky nepoužitelné, jakmile začneš používat novou zašifrovanou peněženku.</translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>Upozornění: Caps Lock je zapnutý!</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>Peněženka je zašifrována</translation>
+ </message>
+ <message>
+ <source>Enter the new passphrase to the wallet.&lt;br/&gt;Please use a passphrase of &lt;b&gt;ten or more random characters&lt;/b&gt;, or &lt;b&gt;eight or more words&lt;/b&gt;.</source>
+ <translation>Zadej nové heslo k peněžence.&lt;br/&gt;Použij &lt;b&gt;alespoň deset náhodných znaků&lt;/b&gt; nebo &lt;b&gt;alespoň osm slov&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>Enter the old passphrase and new passphrase to the wallet.</source>
+ <translation>Zadej staré a nové heslo k peněžence.</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>Zašifrování peněženky selhalo</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>Zašifrování peněženky selhalo kvůli vnitřní chybě. Tvá peněženka tedy nebyla zašifrována.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>Zadaná hesla nejsou shodná.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>Nepodařilo se odemknout peněženku</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>Nezadal jsi správné heslo pro dešifrování peněženky.</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>Nepodařilo se dešifrovat peněženku</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>Heslo k peněžence bylo v pořádku změněno.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>Po&amp;depiš zprávu...</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>Synchronizuji se se sítí...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;Přehled</translation>
+ </message>
+ <message>
+ <source>Node</source>
+ <translation>Uzel</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>Zobraz celkový přehled peněženky</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Transakce</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>Procházej historii transakcí</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>&amp;Konec</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>Ukonči aplikaci</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>O &amp;Qt</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>Zobraz informace o Qt</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;Možnosti...</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>Zaši&amp;fruj peněženku...</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>&amp;Zazálohuj peněženku...</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>Změň &amp;heslo...</translation>
+ </message>
+ <message>
+ <source>&amp;Sending addresses...</source>
+ <translation>Od&amp;esílací adresy...</translation>
+ </message>
+ <message>
+ <source>&amp;Receiving addresses...</source>
+ <translation>Př&amp;ijímací adresy...</translation>
+ </message>
+ <message>
+ <source>Open &amp;URI...</source>
+ <translation>Načíst &amp;URI...</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core client</source>
+ <translation>Bitcoin Core klient</translation>
+ </message>
+ <message>
+ <source>Importing blocks from disk...</source>
+ <translation>Importuji bloky z disku...</translation>
+ </message>
+ <message>
+ <source>Reindexing blocks on disk...</source>
+ <translation>Vytvářím nový index bloků na disku...</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>Pošli mince na Bitcoinovou adresu</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>Zazálohuj peněženku na jiné místo</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Změň heslo k šifrování peněženky</translation>
+ </message>
+ <message>
+ <source>&amp;Debug window</source>
+ <translation>&amp;Ladicí okno</translation>
+ </message>
+ <message>
+ <source>Open debugging and diagnostic console</source>
+ <translation>Otevři ladicí a diagnostickou konzoli</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>&amp;Ověř zprávu...</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>Peněženka</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>&amp;Pošli</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>Při&amp;jmi</translation>
+ </message>
+ <message>
+ <source>Show information about Bitcoin Core</source>
+ <translation>Zobraz informace o Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>&amp;Zobraz/Skryj</translation>
+ </message>
+ <message>
+ <source>Show or hide the main Window</source>
+ <translation>Zobraz nebo skryj hlavní okno</translation>
+ </message>
+ <message>
+ <source>Encrypt the private keys that belong to your wallet</source>
+ <translation>Zašifruj soukromé klíče ve své peněžence</translation>
+ </message>
+ <message>
+ <source>Sign messages with your Bitcoin addresses to prove you own them</source>
+ <translation>Podepiš zprávy svými Bitcoinovými adresami, čímž prokážeš, že jsi jejich vlastníkem</translation>
+ </message>
+ <message>
+ <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source>
+ <translation>Ověř zprávy, aby ses ujistil, že byly podepsány danými Bitcoinovými adresami</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;Soubor</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;Nastavení</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>Ná&amp;pověda</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>Panel s listy</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Request payments (generates QR codes and bitcoin: URIs)</source>
+ <translation>Požaduj platby (generuje QR kódy a bitcoin: URI)</translation>
+ </message>
+ <message>
+ <source>&amp;About Bitcoin Core</source>
+ <translation>O &amp;Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Modify configuration options for Bitcoin Core</source>
+ <translation>Uprav nastavení Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Show the list of used sending addresses and labels</source>
+ <translation>Ukaž seznam použitých odesílacích adres a jejich označení</translation>
+ </message>
+ <message>
+ <source>Show the list of used receiving addresses and labels</source>
+ <translation>Ukaž seznam použitých přijímacích adres a jejich označení</translation>
+ </message>
+ <message>
+ <source>Open a bitcoin: URI or payment request</source>
+ <translation>Načti bitcoin: URI nebo platební požadavek</translation>
+ </message>
+ <message>
+ <source>&amp;Command-line options</source>
+ <translation>Ar&amp;gumenty z příkazové řádky</translation>
+ </message>
+ <message>
+ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
+ <translation>Seznam argumentů Bitcoinu pro příkazovou řádku získáš v nápovědě Bitcoinu Core</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n active connection(s) to Bitcoin network</source>
+ <translation><numerusform>%n aktivní spojení do Bitcoinové sítě</numerusform><numerusform>%n aktivní spojení do Bitcoinové sítě</numerusform><numerusform>%n aktivních spojení do Bitcoinové sítě</numerusform></translation>
+ </message>
+ <message>
+ <source>No block source available...</source>
+ <translation>Není dostupný žádný zdroj bloků...</translation>
+ </message>
+ <message numerus="yes">
+ <source>Processed %n block(s) of transaction history.</source>
+ <translation><numerusform>Zpracován %n blok transakční historie.</numerusform><numerusform>Zpracovány %n bloky transakční historie.</numerusform><numerusform>Zpracováno %n bloků transakční historie.</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n hour(s)</source>
+ <translation><numerusform>%n hodinu</numerusform><numerusform>%n hodiny</numerusform><numerusform>%n hodin</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n day(s)</source>
+ <translation><numerusform>%n den</numerusform><numerusform>%n dny</numerusform><numerusform>%n dnů</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n week(s)</source>
+ <translation><numerusform>%n týden</numerusform><numerusform>%n týdny</numerusform><numerusform>%n týdnů</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 and %2</source>
+ <translation>%1 a %2</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n year(s)</source>
+ <translation><numerusform>%n rok</numerusform><numerusform>%n roky</numerusform><numerusform>%n roků</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 behind</source>
+ <translation>Stahuji ještě bloky transakcí za poslední %1</translation>
+ </message>
+ <message>
+ <source>Last received block was generated %1 ago.</source>
+ <translation>Poslední stažený blok byl vygenerován %1 zpátky.</translation>
+ </message>
+ <message>
+ <source>Transactions after this will not yet be visible.</source>
+ <translation>Následné transakce ještě nebudou vidět.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Chyba</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Upozornění</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Informace</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>Aktuální</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>Stahuji...</translation>
+ </message>
+ <message>
+ <source>Date: %1
+</source>
+ <translation>Datum: %1
+</translation>
+ </message>
+ <message>
+ <source>Amount: %1
+</source>
+ <translation>Částka: %1
+</translation>
+ </message>
+ <message>
+ <source>Type: %1
+</source>
+ <translation>Typ: %1
+</translation>
+ </message>
+ <message>
+ <source>Label: %1
+</source>
+ <translation>Označení: %1
+</translation>
+ </message>
+ <message>
+ <source>Address: %1
+</source>
+ <translation>Adresa: %1
+</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>Odeslané transakce</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>Příchozí transakce</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>Peněženka je &lt;b&gt;zašifrovaná&lt;/b&gt; a momentálně &lt;b&gt;odemčená&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>Peněženka je &lt;b&gt;zašifrovaná&lt;/b&gt; a momentálně &lt;b&gt;zamčená&lt;/b&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <source>Network Alert</source>
+ <translation>Upozornění sítě</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Coin Selection</source>
+ <translation>Výběr mincí</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Počet:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Bajtů:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Částka:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Priorita:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Poplatek:</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Prach:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Čistá částka:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Drobné:</translation>
+ </message>
+ <message>
+ <source>(un)select all</source>
+ <translation>(od)označit všechny</translation>
+ </message>
+ <message>
+ <source>Tree mode</source>
+ <translation>Zobrazit jako strom</translation>
+ </message>
+ <message>
+ <source>List mode</source>
+ <translation>Vypsat jako seznam</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Částka</translation>
+ </message>
+ <message>
+ <source>Received with label</source>
+ <translation>Příjem na označení</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>Příjem na adrese</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Datum</translation>
+ </message>
+ <message>
+ <source>Confirmations</source>
+ <translation>Potvrzení</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Potvrzeno</translation>
+ </message>
+ <message>
+ <source>Priority</source>
+ <translation>Priorita</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Kopíruj adresu</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Kopíruj její označení</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopíruj částku</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Kopíruj ID transakce</translation>
+ </message>
+ <message>
+ <source>Lock unspent</source>
+ <translation>Zamkni neutracené</translation>
+ </message>
+ <message>
+ <source>Unlock unspent</source>
+ <translation>Odemkni k utracení</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Kopíruj počet</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Kopíruj poplatek</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Kopíruj čistou částku</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Kopíruj bajty</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Kopíruj prioritu</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Kopíruj prach</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Kopíruj drobné</translation>
+ </message>
+ <message>
+ <source>highest</source>
+ <translation>nejvyšší</translation>
+ </message>
+ <message>
+ <source>higher</source>
+ <translation>vyšší</translation>
+ </message>
+ <message>
+ <source>high</source>
+ <translation>vysoká</translation>
+ </message>
+ <message>
+ <source>medium-high</source>
+ <translation>vyšší střední</translation>
+ </message>
+ <message>
+ <source>medium</source>
+ <translation>střední</translation>
+ </message>
+ <message>
+ <source>low-medium</source>
+ <translation>nižší střední</translation>
+ </message>
+ <message>
+ <source>low</source>
+ <translation>nízká</translation>
+ </message>
+ <message>
+ <source>lower</source>
+ <translation>nižší</translation>
+ </message>
+ <message>
+ <source>lowest</source>
+ <translation>nejnižší</translation>
+ </message>
+ <message>
+ <source>(%1 locked)</source>
+ <translation>(%1 zamčeno)</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>žádná</translation>
+ </message>
+ <message>
+ <source>This label turns red if the transaction size is greater than 1000 bytes.</source>
+ <translation>Popisek zčervená, pokud je velikost transakce větší než 1000 bajtů.</translation>
+ </message>
+ <message>
+ <source>This label turns red if the priority is smaller than "medium".</source>
+ <translation>Popisek zčervená, pokud je priorita menší než „střední“.</translation>
+ </message>
+ <message>
+ <source>This label turns red if any recipient receives an amount smaller than %1.</source>
+ <translation>Popisek zčervená, pokud má některý příjemce obdržet částku menší než %1.</translation>
+ </message>
+ <message>
+ <source>Can vary +/- %1 satoshi(s) per input.</source>
+ <translation>Může se lišit o +/– %1 satoshi na každý vstup.</translation>
+ </message>
+ <message>
+ <source>yes</source>
+ <translation>ano</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>ne</translation>
+ </message>
+ <message>
+ <source>This means a fee of at least %1 per kB is required.</source>
+ <translation>To znamená, že je vyžadován poplatek alespoň %1 za kB.</translation>
+ </message>
+ <message>
+ <source>Can vary +/- 1 byte per input.</source>
+ <translation>Může se lišit o +/– 1 bajt na každý vstup.</translation>
+ </message>
+ <message>
+ <source>Transactions with higher priority are more likely to get included into a block.</source>
+ <translation>Transakce s vyšší prioritou mají větší šanci na zařazení do bloku.</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(bez označení)</translation>
+ </message>
+ <message>
+ <source>change from %1 (%2)</source>
+ <translation>drobné z %1 (%2)</translation>
+ </message>
+ <message>
+ <source>(change)</source>
+ <translation>(drobné)</translation>
+ </message>
+</context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>Uprav adresu</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>&amp;Označení</translation>
+ </message>
+ <message>
+ <source>The label associated with this address list entry</source>
+ <translation>Označení spojené s tímto záznamem v seznamu adres</translation>
+ </message>
+ <message>
+ <source>The address associated with this address list entry. This can only be modified for sending addresses.</source>
+ <translation>Adresa spojená s tímto záznamem v seznamu adres. Lze upravovat jen pro odesílací adresy.</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;Adresa</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>Nová přijímací adresa</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>Nová odesílací adresa</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>Uprav přijímací adresu</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>Uprav odesílací adresu</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>Zadaná adresa "%1" už v adresáři je.</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is not a valid Bitcoin address.</source>
+ <translation>Zadaná adresa "%1" není platná Bitcoinová adresa.</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>Nemohu odemknout peněženku.</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>Nepodařilo se mi vygenerovat nový klíč.</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ <message>
+ <source>A new data directory will be created.</source>
+ <translation>Vytvoří se nový adresář pro data.</translation>
+ </message>
+ <message>
+ <source>name</source>
+ <translation>název</translation>
+ </message>
+ <message>
+ <source>Directory already exists. Add %1 if you intend to create a new directory here.</source>
+ <translation>Adresář už existuje. Přidej %1, pokud tady chceš vytvořit nový adresář.</translation>
+ </message>
+ <message>
+ <source>Path already exists, and is not a directory.</source>
+ <translation>Taková cesta už existuje, ale není adresářem.</translation>
+ </message>
+ <message>
+ <source>Cannot create data directory here.</source>
+ <translation>Tady nemůžu vytvořit adresář pro data.</translation>
+ </message>
+</context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>verze</translation>
+ </message>
+ <message>
+ <source>(%1-bit)</source>
+ <translation>(%1-bit)</translation>
+ </message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>O Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Command-line options</source>
+ <translation>Argumenty z příkazové řádky</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>Užití:</translation>
+ </message>
+ <message>
+ <source>command-line options</source>
+ <translation>možnosti příkazové řádky</translation>
+ </message>
+</context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Welcome</source>
+ <translation>Vítej</translation>
+ </message>
+ <message>
+ <source>Welcome to Bitcoin Core.</source>
+ <translation>Vítej v Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</source>
+ <translation>Tohle je poprvé, co spouštíš Bitcoin Core, takže si můžeš zvolit, kam bude ukládat svá data.</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory.</source>
+ <translation>Bitcoin Core bude stahovat kopii řetězce bloků. Proto bude potřeba do tohoto adresáře uložit nejméně %1 GB dat – toto číslo bude navíc v průběhu času pomalu růst. Tvá peněženka bude rovněž uložena v tomto adresáři.</translation>
+ </message>
+ <message>
+ <source>Use the default data directory</source>
+ <translation>Použij výchozí adresář pro data</translation>
+ </message>
+ <message>
+ <source>Use a custom data directory:</source>
+ <translation>Použij tento adresář pro data:</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Error: Specified data directory "%1" cannot be created.</source>
+ <translation>Chyba: Nejde vytvořit požadovaný adresář pro data „%1“.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Chyba</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n GB of free space available</source>
+ <translation><numerusform>%n GB volného místa</numerusform><numerusform>%n GB volného místa</numerusform><numerusform>%n GB volného místa</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>(of %n GB needed)</source>
+ <translation><numerusform>(z potřebného %n GB)</numerusform><numerusform>(z potřebných %n GB)</numerusform><numerusform>(z potřebných %n GB)</numerusform></translation>
+ </message>
+</context>
+<context>
+ <name>OpenURIDialog</name>
+ <message>
+ <source>Open URI</source>
+ <translation>Načíst URI</translation>
+ </message>
+ <message>
+ <source>Open payment request from URI or file</source>
+ <translation>Načíst platební požadavek z URI nebo ze souboru</translation>
+ </message>
+ <message>
+ <source>URI:</source>
+ <translation>URI:</translation>
+ </message>
+ <message>
+ <source>Select payment request file</source>
+ <translation>Vyber soubor platebního požadavku</translation>
+ </message>
+ <message>
+ <source>Select payment request file to open</source>
+ <translation>Vyber soubor platebního požadavku k načtení</translation>
+ </message>
+</context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>Možnosti</translation>
+ </message>
+ <message>
+ <source>&amp;Main</source>
+ <translation>&amp;Hlavní</translation>
+ </message>
+ <message>
+ <source>Size of &amp;database cache</source>
+ <translation>Velikost &amp;databázové cache</translation>
+ </message>
+ <message>
+ <source>MB</source>
+ <translation>MB</translation>
+ </message>
+ <message>
+ <source>Number of script &amp;verification threads</source>
+ <translation>Počet vláken pro &amp;verifikaci skriptů</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside</source>
+ <translation>Přijímat spojení zvenčí</translation>
+ </message>
+ <message>
+ <source>Allow incoming connections</source>
+ <translation>Přijímat příchozí spojení</translation>
+ </message>
+ <message>
+ <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
+ <translation>IP adresa proxy (např. IPv4: 127.0.0.1/IPv6: ::1)</translation>
+ </message>
+ <message>
+ <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source>
+ <translation>Zavřením se aplikace minimalizuje. Pokud je tato volba zaškrtnuta, tak se aplikace ukončí pouze zvolením Konec v menu.</translation>
+ </message>
+ <message>
+ <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source>
+ <translation>Tady lze nastavit jazyk uživatelského rozhraní. Nastavení se projeví až po restartování Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source>
+ <translation>URL třetích stran (např. block exploreru), které se zobrazí v kontextovém menu v záložce Transakce. %s v URL se nahradí hashem transakce. Více URL odděl svislítkem |.</translation>
+ </message>
+ <message>
+ <source>Third party transaction URLs</source>
+ <translation>URL transakcí třetích stran</translation>
+ </message>
+ <message>
+ <source>Active command-line options that override above options:</source>
+ <translation>Aktivní argumenty z příkazové řádky, které přetloukly tato nastavení:</translation>
+ </message>
+ <message>
+ <source>Reset all client options to default.</source>
+ <translation>Vrátí všechny volby na výchozí hodnoty.</translation>
+ </message>
+ <message>
+ <source>&amp;Reset Options</source>
+ <translation>&amp;Obnovit nastavení</translation>
+ </message>
+ <message>
+ <source>&amp;Network</source>
+ <translation>&amp;Síť</translation>
+ </message>
+ <message>
+ <source>Automatically start Bitcoin Core after logging in to the system.</source>
+ <translation>Automaticky spustí Bitcoin Core po přihlášení do systému.</translation>
+ </message>
+ <message>
+ <source>&amp;Start Bitcoin Core on system login</source>
+ <translation>S&amp;pustit Bitcoin Core po přihlášení do systému</translation>
+ </message>
+ <message>
+ <source>(0 = auto, &lt;0 = leave that many cores free)</source>
+ <translation>(0 = automaticky, &lt;0 = nechat daný počet jader volný, výchozí: 0)</translation>
+ </message>
+ <message>
+ <source>W&amp;allet</source>
+ <translation>P&amp;eněženka</translation>
+ </message>
+ <message>
+ <source>Expert</source>
+ <translation>Odborník</translation>
+ </message>
+ <message>
+ <source>Enable coin &amp;control features</source>
+ <translation>Povolit ruční správu &amp;mincí</translation>
+ </message>
+ <message>
+ <source>If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.</source>
+ <translation>Pokud zakážeš utrácení ještě nepotvrzených drobných, nepůjde použít drobné z transakce, dokud nebude mít alespoň jedno potvrzení. Ovlivní to také výpočet stavu účtu.</translation>
+ </message>
+ <message>
+ <source>&amp;Spend unconfirmed change</source>
+ <translation>&amp;Utrácet i ještě nepotvrzené drobné</translation>
+ </message>
+ <message>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>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é.</translation>
+ </message>
+ <message>
+ <source>Map port using &amp;UPnP</source>
+ <translation>Namapovat port přes &amp;UPnP</translation>
+ </message>
+ <message>
+ <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
+ <translation>Připojí se do Bitcoinové sítě přes SOCKS5 proxy.</translation>
+ </message>
+ <message>
+ <source>&amp;Connect through SOCKS5 proxy (default proxy):</source>
+ <translation>&amp;Připojit přes SOCKS5 proxy (výchozí proxy):</translation>
+ </message>
+ <message>
+ <source>Proxy &amp;IP:</source>
+ <translation>&amp;IP adresa proxy:</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>Por&amp;t:</translation>
+ </message>
+ <message>
+ <source>Port of the proxy (e.g. 9050)</source>
+ <translation>Port proxy (např. 9050)</translation>
+ </message>
+ <message>
+ <source>&amp;Window</source>
+ <translation>O&amp;kno</translation>
+ </message>
+ <message>
+ <source>Show only a tray icon after minimizing the window.</source>
+ <translation>Po minimalizaci okna zobrazí pouze ikonu v panelu.</translation>
+ </message>
+ <message>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>&amp;Minimalizovávat do ikony v panelu</translation>
+ </message>
+ <message>
+ <source>M&amp;inimize on close</source>
+ <translation>Za&amp;vřením minimalizovat</translation>
+ </message>
+ <message>
+ <source>&amp;Display</source>
+ <translation>Zobr&amp;azení</translation>
+ </message>
+ <message>
+ <source>User Interface &amp;language:</source>
+ <translation>&amp;Jazyk uživatelského rozhraní:</translation>
+ </message>
+ <message>
+ <source>&amp;Unit to show amounts in:</source>
+ <translation>J&amp;ednotka pro částky:</translation>
+ </message>
+ <message>
+ <source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
+ <translation>Zvol výchozí podjednotku, která se bude zobrazovat v programu a při posílání mincí.</translation>
+ </message>
+ <message>
+ <source>Whether to show coin control features or not.</source>
+ <translation>Zda ukazovat možnosti pro ruční správu mincí nebo ne.</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>&amp;Budiž</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>&amp;Zrušit</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>výchozí</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>žádné</translation>
+ </message>
+ <message>
+ <source>Confirm options reset</source>
+ <translation>Potvrzení obnovení nastavení</translation>
+ </message>
+ <message>
+ <source>Client restart required to activate changes.</source>
+ <translation>K aktivaci změn je potřeba restartovat klienta.</translation>
+ </message>
+ <message>
+ <source>Client will be shut down. Do you want to proceed?</source>
+ <translation>Klient se vypne, chceš pokračovat?</translation>
+ </message>
+ <message>
+ <source>This change would require a client restart.</source>
+ <translation>Tahle změna bude chtít restartovat klienta.</translation>
+ </message>
+ <message>
+ <source>The supplied proxy address is invalid.</source>
+ <translation>Zadaná adresa proxy je neplatná.</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>Formulář</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>Zobrazené informace nemusí být aktuální. Tvá peněženka se automaticky sesynchronizuje s Bitcoinovou sítí, jakmile se s ní spojí. Zatím ale ještě není synchronizace dokončena.</translation>
+ </message>
+ <message>
+ <source>Watch-only:</source>
+ <translation>Sledované:</translation>
+ </message>
+ <message>
+ <source>Available:</source>
+ <translation>K dispozici:</translation>
+ </message>
+ <message>
+ <source>Your current spendable balance</source>
+ <translation>Aktuální disponibilní stav tvého účtu</translation>
+ </message>
+ <message>
+ <source>Pending:</source>
+ <translation>Očekáváno:</translation>
+ </message>
+ <message>
+ <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source>
+ <translation>Souhrn transakcí, které ještě nejsou potvrzené a které se ještě nezapočítávají do celkového disponibilního stavu účtu</translation>
+ </message>
+ <message>
+ <source>Immature:</source>
+ <translation>Nedozráno:</translation>
+ </message>
+ <message>
+ <source>Mined balance that has not yet matured</source>
+ <translation>Vytěžené mince, které ještě nejsou zralé</translation>
+ </message>
+ <message>
+ <source>Balances</source>
+ <translation>Stavy účtů</translation>
+ </message>
+ <message>
+ <source>Total:</source>
+ <translation>Celkem:</translation>
+ </message>
+ <message>
+ <source>Your current total balance</source>
+ <translation>Celkový stav tvého účtu</translation>
+ </message>
+ <message>
+ <source>Your current balance in watch-only addresses</source>
+ <translation>Aktuální stav účtu sledovaných adres</translation>
+ </message>
+ <message>
+ <source>Spendable:</source>
+ <translation>Běžné:</translation>
+ </message>
+ <message>
+ <source>Recent transactions</source>
+ <translation>Poslední transakce</translation>
+ </message>
+ <message>
+ <source>Unconfirmed transactions to watch-only addresses</source>
+ <translation>Nepotvrzené transakce sledovaných adres</translation>
+ </message>
+ <message>
+ <source>Mined balance in watch-only addresses that has not yet matured</source>
+ <translation>Vytěžené mince na sledovaných adresách, které ještě nejsou zralé</translation>
+ </message>
+ <message>
+ <source>Current total balance in watch-only addresses</source>
+ <translation>Aktuální stav účtu sledovaných adres</translation>
+ </message>
+</context>
+<context>
+ <name>PaymentServer</name>
+ <message>
+ <source>URI handling</source>
+ <translation>Zpracování URI</translation>
+ </message>
+ <message>
+ <source>Invalid payment address %1</source>
+ <translation>Neplatná platební adresa %1</translation>
+ </message>
+ <message>
+ <source>Payment request rejected</source>
+ <translation>Platební požadavek byl odmítnut</translation>
+ </message>
+ <message>
+ <source>Payment request network doesn't match client network.</source>
+ <translation>Síť platebního požadavku neodpovídá síti klienta.</translation>
+ </message>
+ <message>
+ <source>Payment request is not initialized.</source>
+ <translation>Platební požadavek není zahájený.</translation>
+ </message>
+ <message>
+ <source>Requested payment amount of %1 is too small (considered dust).</source>
+ <translation>Požadovaná platební částka %1 je příliš malá (je považována za prach).</translation>
+ </message>
+ <message>
+ <source>Payment request error</source>
+ <translation>Chyba platebního požadavku</translation>
+ </message>
+ <message>
+ <source>Cannot start bitcoin: click-to-pay handler</source>
+ <translation>Nemůžu spustit bitcoin: obsluha click-to-pay</translation>
+ </message>
+ <message>
+ <source>Payment request fetch URL is invalid: %1</source>
+ <translation>Zdrojová URL platebního požadavku není platná: %1</translation>
+ </message>
+ <message>
+ <source>URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source>
+ <translation>Nepodařilo se analyzovat URI! Důvodem může být neplatná Bitcoinová adresa nebo poškozené parametry URI.</translation>
+ </message>
+ <message>
+ <source>Payment request file handling</source>
+ <translation>Zpracování souboru platebního požadavku</translation>
+ </message>
+ <message>
+ <source>Payment request file cannot be read! This can be caused by an invalid payment request file.</source>
+ <translation>Soubor platebního požadavku nejde přečíst nebo zpracovat! Příčinou může být špatný soubor platebního požadavku.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>Platební požadavek vypršel.</translation>
+ </message>
+ <message>
+ <source>Unverified payment requests to custom payment scripts are unsupported.</source>
+ <translation>Neověřené platební požadavky k uživatelským platebním skriptům nejsou podporované.</translation>
+ </message>
+ <message>
+ <source>Invalid payment request.</source>
+ <translation>Neplatný platební požadavek.</translation>
+ </message>
+ <message>
+ <source>Refund from %1</source>
+ <translation>Vrácení peněz od %1</translation>
+ </message>
+ <message>
+ <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source>
+ <translation>Platební požadavek %1 je moc velký (%2 bajtů, povoleno %3 bajtů).</translation>
+ </message>
+ <message>
+ <source>Payment request DoS protection</source>
+ <translation>DoS ochrana platebního požadavku</translation>
+ </message>
+ <message>
+ <source>Error communicating with %1: %2</source>
+ <translation>Chyba při komunikaci s %1: %2</translation>
+ </message>
+ <message>
+ <source>Payment request cannot be parsed!</source>
+ <translation>Platební požadavek je nečitelný!</translation>
+ </message>
+ <message>
+ <source>Bad response from server %1</source>
+ <translation>Chybná odpověď ze serveru %1</translation>
+ </message>
+ <message>
+ <source>Payment acknowledged</source>
+ <translation>Platba potvrzena</translation>
+ </message>
+ <message>
+ <source>Network request error</source>
+ <translation>Chyba síťového požadavku</translation>
+ </message>
+</context>
+<context>
+ <name>PeerTableModel</name>
+ <message>
+ <source>User Agent</source>
+ <translation>Typ klienta</translation>
+ </message>
+ <message>
+ <source>Node/Service</source>
+ <translation>Uzel/Služba</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Odezva</translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>Částka</translation>
+ </message>
+ <message>
+ <source>Enter a Bitcoin address (e.g. %1)</source>
+ <translation>Zadej Bitcoinovou adresu (např. %1)</translation>
+ </message>
+ <message>
+ <source>%1 d</source>
+ <translation>%1 d</translation>
+ </message>
+ <message>
+ <source>%1 h</source>
+ <translation>%1 h</translation>
+ </message>
+ <message>
+ <source>%1 m</source>
+ <translation>%1 m</translation>
+ </message>
+ <message>
+ <source>%1 s</source>
+ <translation>%1 s</translation>
+ </message>
+ <message>
+ <source>None</source>
+ <translation>Žádné</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>N/A</translation>
+ </message>
+ <message>
+ <source>%1 ms</source>
+ <translation>%1 ms</translation>
+ </message>
+</context>
+<context>
+ <name>QRImageWidget</name>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Ulož obrázek...</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Image</source>
+ <translation>&amp;Kopíruj obrázek</translation>
+ </message>
+ <message>
+ <source>Save QR Code</source>
+ <translation>Ulož QR kód</translation>
+ </message>
+ <message>
+ <source>PNG Image (*.png)</source>
+ <translation>PNG obrázek (*.png)</translation>
+ </message>
+</context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>Client name</source>
+ <translation>Název klienta</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>N/A</translation>
+ </message>
+ <message>
+ <source>Client version</source>
+ <translation>Verze klienta</translation>
+ </message>
+ <message>
+ <source>&amp;Information</source>
+ <translation>&amp;Informace</translation>
+ </message>
+ <message>
+ <source>Debug window</source>
+ <translation>Ladicí okno</translation>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>Obecné</translation>
+ </message>
+ <message>
+ <source>Using OpenSSL version</source>
+ <translation>Používaná verze OpenSSL</translation>
+ </message>
+ <message>
+ <source>Using BerkeleyDB version</source>
+ <translation>Používaná verze BerkeleyDB</translation>
+ </message>
+ <message>
+ <source>Startup time</source>
+ <translation>Čas spuštění</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Síť</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>Název</translation>
+ </message>
+ <message>
+ <source>Number of connections</source>
+ <translation>Počet spojení</translation>
+ </message>
+ <message>
+ <source>Block chain</source>
+ <translation>Řetězec bloků</translation>
+ </message>
+ <message>
+ <source>Current number of blocks</source>
+ <translation>Aktuální počet bloků</translation>
+ </message>
+ <message>
+ <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source>
+ <translation>Otevři soubor s ladicími záznamy Bitcoin Core z aktuálního datového adresáře. U velkých logů to může pár vteřin zabrat.</translation>
+ </message>
+ <message>
+ <source>Received</source>
+ <translation>Přijato</translation>
+ </message>
+ <message>
+ <source>Sent</source>
+ <translation>Odesláno</translation>
+ </message>
+ <message>
+ <source>&amp;Peers</source>
+ <translation>&amp;Protějšky</translation>
+ </message>
+ <message>
+ <source>Select a peer to view detailed information.</source>
+ <translation>Vyber protějšek a uvidíš jeho detailní informace.</translation>
+ </message>
+ <message>
+ <source>Direction</source>
+ <translation>Směr</translation>
+ </message>
+ <message>
+ <source>Version</source>
+ <translation>Verze</translation>
+ </message>
+ <message>
+ <source>User Agent</source>
+ <translation>Typ klienta</translation>
+ </message>
+ <message>
+ <source>Services</source>
+ <translation>Služby</translation>
+ </message>
+ <message>
+ <source>Starting Height</source>
+ <translation>Prvotní výška</translation>
+ </message>
+ <message>
+ <source>Sync Height</source>
+ <translation>Aktuální výška</translation>
+ </message>
+ <message>
+ <source>Ban Score</source>
+ <translation>Skóre pro klatbu</translation>
+ </message>
+ <message>
+ <source>Connection Time</source>
+ <translation>Doba spojení</translation>
+ </message>
+ <message>
+ <source>Last Send</source>
+ <translation>Poslední odeslání</translation>
+ </message>
+ <message>
+ <source>Last Receive</source>
+ <translation>Poslední příjem</translation>
+ </message>
+ <message>
+ <source>Bytes Sent</source>
+ <translation>Bajtů odesláno</translation>
+ </message>
+ <message>
+ <source>Bytes Received</source>
+ <translation>Bajtů přijato</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Odezva</translation>
+ </message>
+ <message>
+ <source>Time Offset</source>
+ <translation>Časový posun</translation>
+ </message>
+ <message>
+ <source>Last block time</source>
+ <translation>Čas posledního bloku</translation>
+ </message>
+ <message>
+ <source>&amp;Open</source>
+ <translation>&amp;Otevřít</translation>
+ </message>
+ <message>
+ <source>&amp;Console</source>
+ <translation>&amp;Konzole</translation>
+ </message>
+ <message>
+ <source>&amp;Network Traffic</source>
+ <translation>&amp;Síťový provoz</translation>
+ </message>
+ <message>
+ <source>&amp;Clear</source>
+ <translation>&amp;Vyčistit</translation>
+ </message>
+ <message>
+ <source>Totals</source>
+ <translation>Součty</translation>
+ </message>
+ <message>
+ <source>In:</source>
+ <translation>Sem:</translation>
+ </message>
+ <message>
+ <source>Out:</source>
+ <translation>Ven:</translation>
+ </message>
+ <message>
+ <source>Build date</source>
+ <translation>Datum kompilace</translation>
+ </message>
+ <message>
+ <source>Debug log file</source>
+ <translation>Soubor s ladicími záznamy</translation>
+ </message>
+ <message>
+ <source>Clear console</source>
+ <translation>Vyčistit konzoli</translation>
+ </message>
+ <message>
+ <source>Welcome to the Bitcoin Core RPC console.</source>
+ <translation>Vítej v RPC konzoli Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
+ <translation>V historii se pohybuješ šipkami nahoru a dolů a pomocí &lt;b&gt;Ctrl-L&lt;/b&gt; čistíš obrazovku.</translation>
+ </message>
+ <message>
+ <source>Type &lt;b&gt;help&lt;/b&gt; for an overview of available commands.</source>
+ <translation>Napsáním &lt;b&gt;help&lt;/b&gt; si vypíšeš přehled dostupných příkazů.</translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation>%1 B</translation>
+ </message>
+ <message>
+ <source>%1 KB</source>
+ <translation>%1 kB</translation>
+ </message>
+ <message>
+ <source>%1 MB</source>
+ <translation>%1 MB</translation>
+ </message>
+ <message>
+ <source>%1 GB</source>
+ <translation>%1 GB</translation>
+ </message>
+ <message>
+ <source>via %1</source>
+ <translation>via %1</translation>
+ </message>
+ <message>
+ <source>never</source>
+ <translation>nikdy</translation>
+ </message>
+ <message>
+ <source>Inbound</source>
+ <translation>Sem</translation>
+ </message>
+ <message>
+ <source>Outbound</source>
+ <translation>Ven</translation>
+ </message>
+ <message>
+ <source>Unknown</source>
+ <translation>Neznámá</translation>
+ </message>
+ <message>
+ <source>Fetching...</source>
+ <translation>Stahuji...</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Amount:</source>
+ <translation>Čás&amp;tka:</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Označení:</translation>
+ </message>
+ <message>
+ <source>&amp;Message:</source>
+ <translation>&amp;Zpráva:</translation>
+ </message>
+ <message>
+ <source>Reuse one of the previously used receiving addresses. Reusing addresses has security and privacy issues. Do not use this unless re-generating a payment request made before.</source>
+ <translation>Recyklovat již dříve použité adresy. Recyklace adres má bezpečnostní rizika a narušuje soukromí. Nezaškrtávejte to, pokud znovu nevytváříte již dříve vytvořený platební požadavek.</translation>
+ </message>
+ <message>
+ <source>R&amp;euse an existing receiving address (not recommended)</source>
+ <translation>&amp;Recyklovat již existující adresy (nedoporučeno)</translation>
+ </message>
+ <message>
+ <source>An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network.</source>
+ <translation>Volitelná zpráva, která se připojí k platebnímu požadavku a která se zobrazí, když se požadavek otevře. Poznámka: Tahle zpráva se neposílá s platbou po Bitcoinové síti.</translation>
+ </message>
+ <message>
+ <source>An optional label to associate with the new receiving address.</source>
+ <translation>Volitelné označení, které se má přiřadit k nové adrese.</translation>
+ </message>
+ <message>
+ <source>Use this form to request payments. All fields are &lt;b&gt;optional&lt;/b&gt;.</source>
+ <translation>Tímto formulář můžeš požadovat platby. Všechna pole jsou &lt;b&gt;volitelná&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>An optional amount to request. Leave this empty or zero to not request a specific amount.</source>
+ <translation>Volitelná částka, kterou požaduješ. Nech prázdné nebo nulové, pokud nepožaduješ konkrétní částku.</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Promaž obsah ze všech formulářových políček.</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation>Vyčistit</translation>
+ </message>
+ <message>
+ <source>Requested payments history</source>
+ <translation>Historie vyžádaných plateb</translation>
+ </message>
+ <message>
+ <source>&amp;Request payment</source>
+ <translation>&amp;Vyžádat platbu</translation>
+ </message>
+ <message>
+ <source>Show the selected request (does the same as double clicking an entry)</source>
+ <translation>Zobraz zvolený požadavek (stejně tak můžeš přímo na něj dvakrát poklepat)</translation>
+ </message>
+ <message>
+ <source>Show</source>
+ <translation>Zobrazit</translation>
+ </message>
+ <message>
+ <source>Remove the selected entries from the list</source>
+ <translation>Smaž zvolené požadavky ze seznamu</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>Smazat</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Kopíruj její označení</translation>
+ </message>
+ <message>
+ <source>Copy message</source>
+ <translation>Kopíruj zprávu</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopíruj částku</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>QR Code</source>
+ <translation>QR kód</translation>
+ </message>
+ <message>
+ <source>Copy &amp;URI</source>
+ <translation>&amp;Kopíruj URI</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Address</source>
+ <translation>Kopíruj &amp;adresu</translation>
+ </message>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Ulož obrázek...</translation>
+ </message>
+ <message>
+ <source>Request payment to %1</source>
+ <translation>Platební požadavek: %1</translation>
+ </message>
+ <message>
+ <source>Payment information</source>
+ <translation>Informace o platbě</translation>
+ </message>
+ <message>
+ <source>URI</source>
+ <translation>URI</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adresa</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Částka</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Označení</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Zpráva</translation>
+ </message>
+ <message>
+ <source>Resulting URI too long, try to reduce the text for label / message.</source>
+ <translation>Výsledná URI je příliš dlouhá, zkus zkrátit text označení/zprávy.</translation>
+ </message>
+ <message>
+ <source>Error encoding URI into QR Code.</source>
+ <translation>Chyba při kódování URI do QR kódu.</translation>
+ </message>
+</context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Datum</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Označení</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Zpráva</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Částka</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(bez označení)</translation>
+ </message>
+ <message>
+ <source>(no message)</source>
+ <translation>(bez zprávy)</translation>
+ </message>
+ <message>
+ <source>(no amount)</source>
+ <translation>(bez částky)</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Pošli mince</translation>
+ </message>
+ <message>
+ <source>Coin Control Features</source>
+ <translation>Možnosti ruční správy mincí</translation>
+ </message>
+ <message>
+ <source>Inputs...</source>
+ <translation>Vstupy...</translation>
+ </message>
+ <message>
+ <source>automatically selected</source>
+ <translation>automaticky vybrané</translation>
+ </message>
+ <message>
+ <source>Insufficient funds!</source>
+ <translation>Nedostatek prostředků!</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Počet:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Bajtů:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Částka:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Priorita:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Poplatek:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Čistá částka:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Drobné:</translation>
+ </message>
+ <message>
+ <source>If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address.</source>
+ <translation>Pokud aktivováno, ale adresa pro drobné je prázdná nebo neplatná, tak se drobné pošlou na nově vygenerovanou adresu.</translation>
+ </message>
+ <message>
+ <source>Custom change address</source>
+ <translation>Vlastní adresa pro drobné</translation>
+ </message>
+ <message>
+ <source>Transaction Fee:</source>
+ <translation>Transakční poplatek:</translation>
+ </message>
+ <message>
+ <source>Choose...</source>
+ <translation>Zvol...</translation>
+ </message>
+ <message>
+ <source>collapse fee-settings</source>
+ <translation>sbal nastavení poplatků</translation>
+ </message>
+ <message>
+ <source>per kilobyte</source>
+ <translation>za kilobajt</translation>
+ </message>
+ <message>
+ <source>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "total at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source>
+ <translation>Pokud je vlastní poplatek nastavený na 1000 satoshi a transakce má pouze 250 bajtů, tak „za kilobajt“ zaplatí poplatek jen 250 satoshi, zatímco „přinejmenším“ zaplatí 1000 satoshi. Pro transakce větší než kilobajt obě možnosti platí za kilobajt.</translation>
+ </message>
+ <message>
+ <source>Hide</source>
+ <translation>Skryj</translation>
+ </message>
+ <message>
+ <source>total at least</source>
+ <translation>přinejmenším</translation>
+ </message>
+ <message>
+ <source>Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process.</source>
+ <translation>Platit jen minimální poplatek je v pořádku, pokud je zrovna méně transakcí než místa v blocích. Ale počítej s tím, že to také může skončit transakcí, která nikdy nebude potvrzena, pokud je větší poptávka po bitcoinových transakcích, než síť zvládne zpracovat.</translation>
+ </message>
+ <message>
+ <source>(read the tooltip)</source>
+ <translation>(viz bublina)</translation>
+ </message>
+ <message>
+ <source>Recommended:</source>
+ <translation>Doporučený:</translation>
+ </message>
+ <message>
+ <source>Custom:</source>
+ <translation>Vlastní:</translation>
+ </message>
+ <message>
+ <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source>
+ <translation>(Inteligentní poplatek ještě není inicializovaný. Obvykle mu to tak pár bloků trvá...)</translation>
+ </message>
+ <message>
+ <source>Confirmation time:</source>
+ <translation>Rychlost potvrzení:</translation>
+ </message>
+ <message>
+ <source>normal</source>
+ <translation>normální</translation>
+ </message>
+ <message>
+ <source>fast</source>
+ <translation>rychlá</translation>
+ </message>
+ <message>
+ <source>Send as zero-fee transaction if possible</source>
+ <translation>Pošli transakci pokud možno bez poplatku</translation>
+ </message>
+ <message>
+ <source>(confirmation may take longer)</source>
+ <translation>(potvrzení může trvat déle)</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>Pošli více příjemcům naráz</translation>
+ </message>
+ <message>
+ <source>Add &amp;Recipient</source>
+ <translation>Při&amp;dej příjemce</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Promaž obsah ze všech formulářových políček.</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Prach:</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Všechno s&amp;maž</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>Stav účtu:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>Potvrď odeslání</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>P&amp;ošli</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>Potvrď odeslání mincí</translation>
+ </message>
+ <message>
+ <source>%1 to %2</source>
+ <translation>%1 pro %2</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Kopíruj počet</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopíruj částku</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Kopíruj poplatek</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Kopíruj čistou částku</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Kopíruj bajty</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Kopíruj prioritu</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Kopíruj drobné</translation>
+ </message>
+ <message>
+ <source>or</source>
+ <translation>nebo</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>Odesílaná částka musí být větší než 0.</translation>
+ </message>
+ <message>
+ <source>The amount exceeds your balance.</source>
+ <translation>Částka překračuje stav účtu.</translation>
+ </message>
+ <message>
+ <source>The total exceeds your balance when the %1 transaction fee is included.</source>
+ <translation>Celková částka při připočítání poplatku %1 překročí stav účtu.</translation>
+ </message>
+ <message>
+ <source>Transaction creation failed!</source>
+ <translation>Vytvoření transakce selhalo!</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>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.</translation>
+ </message>
+ <message>
+ <source>A fee higher than %1 is considered an absurdly high fee.</source>
+ <translation>Poplatek vyšší než %1 je považován za absurdně vysoký.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>Platební požadavek vypršel.</translation>
+ </message>
+ <message numerus="yes">
+ <source>Estimated to begin confirmation within %n block(s).</source>
+ <translation><numerusform>Potvrzování by podle odhadu mělo začít během %n bloku.</numerusform><numerusform>Potvrzování by podle odhadu mělo začít během %n bloků.</numerusform><numerusform>Potvrzování by podle odhadu mělo začít během %n bloků.</numerusform></translation>
+ </message>
+ <message>
+ <source>Pay only the minimum fee of %1</source>
+ <translation>Zaplatit pouze minimální poplatek %1</translation>
+ </message>
+ <message>
+ <source>The recipient address is not valid. Please recheck.</source>
+ <translation>Adresa příjemce je neplatná – překontroluj ji prosím.</translation>
+ </message>
+ <message>
+ <source>Duplicate address found: addresses should only be used once each.</source>
+ <translation>Zaznamenána duplicitní adresa: každá adresa by ale měla být použita vždy jen jednou.</translation>
+ </message>
+ <message>
+ <source>Warning: Invalid Bitcoin address</source>
+ <translation>Upozornění: Neplatná Bitcoinová adresa</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(bez označení)</translation>
+ </message>
+ <message>
+ <source>Warning: Unknown change address</source>
+ <translation>Upozornění: Neznámá adresa pro drobné</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Kopíruj prach</translation>
+ </message>
+ <message>
+ <source>Are you sure you want to send?</source>
+ <translation>Jsi si jistý, že to chceš poslat?</translation>
+ </message>
+ <message>
+ <source>added as transaction fee</source>
+ <translation>přidán jako transakční poplatek</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>Čás&amp;tka:</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>&amp;Komu:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Zadej označení této adresy; obojí se ti pak uloží do adresáře</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>O&amp;značení:</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Vyber již použitou adresu</translation>
+ </message>
+ <message>
+ <source>This is a normal payment.</source>
+ <translation>Tohle je normální platba.</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to send the payment to</source>
+ <translation>Bitcoinová adresa příjemce</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Vlož adresu ze schránky</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Remove this entry</source>
+ <translation>Smaž tento záznam</translation>
+ </message>
+ <message>
+ <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source>
+ <translation>Poplatek se odečte od posílané částky. Příjemce tak dostane méně bitcoinů, než zadáš do pole Částka. Pokud vybereš více příjemců, tak se poplatek rovnoměrně rozloží.</translation>
+ </message>
+ <message>
+ <source>S&amp;ubtract fee from amount</source>
+ <translation>&amp;Odečíst poplatek od částky</translation>
+ </message>
+ <message>
+ <source>Message:</source>
+ <translation>Zpráva:</translation>
+ </message>
+ <message>
+ <source>This is an unauthenticated payment request.</source>
+ <translation>Tohle je neověřený platební požadavek.</translation>
+ </message>
+ <message>
+ <source>This is an authenticated payment request.</source>
+ <translation>Tohle je ověřený platební požadavek.</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to the list of used addresses</source>
+ <translation>Zadej označení této adresy; obojí se ti pak uloží do adresáře</translation>
+ </message>
+ <message>
+ <source>A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network.</source>
+ <translation>Zpráva, která byla připojena k bitcoin: URI a která se ti pro přehled uloží k transakci. Poznámka: Tahle zpráva se neposílá s platbou po Bitcoinové síti.</translation>
+ </message>
+ <message>
+ <source>Pay To:</source>
+ <translation>Komu:</translation>
+ </message>
+ <message>
+ <source>Memo:</source>
+ <translation>Poznámka:</translation>
+ </message>
+</context>
+<context>
+ <name>ShutdownWindow</name>
+ <message>
+ <source>Bitcoin Core is shutting down...</source>
+ <translation>Bitcoin Core se ukončuje...</translation>
+ </message>
+ <message>
+ <source>Do not shut down the computer until this window disappears.</source>
+ <translation>Nevypínej počítač, dokud toto okno nezmizí.</translation>
+ </message>
+</context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Signatures - Sign / Verify a Message</source>
+ <translation>Podpisy - podepsat/ověřit zprávu</translation>
+ </message>
+ <message>
+ <source>&amp;Sign Message</source>
+ <translation>&amp;Podepiš zprávu</translation>
+ </message>
+ <message>
+ <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source>
+ <translation>Podepsáním zprávy/smlouvy svými adresami můžeš prokázat, že jsi na ně schopen přijmout bitcoiny. Buď opatrný a nepodepisuj nic vágního nebo náhodného; například při phishingových útocích můžeš být lákán, abys něco takového podepsal. Podepisuj pouze naprosto úplná a detailní prohlášení, se kterými souhlasíš.</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to sign the message with</source>
+ <translation>Bitcoinová adresa, kterou se zpráva podepíše</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Vyber již použitou adresu</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Vlož adresu ze schránky</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Enter the message you want to sign here</source>
+ <translation>Sem vepiš zprávu, kterou chceš podepsat</translation>
+ </message>
+ <message>
+ <source>Signature</source>
+ <translation>Podpis</translation>
+ </message>
+ <message>
+ <source>Copy the current signature to the system clipboard</source>
+ <translation>Zkopíruj aktuálně vybraný podpis do systémové schránky</translation>
+ </message>
+ <message>
+ <source>Sign the message to prove you own this Bitcoin address</source>
+ <translation>Podepiš zprávu, čímž prokážeš, že jsi vlastníkem této Bitcoinové adresy</translation>
+ </message>
+ <message>
+ <source>Sign &amp;Message</source>
+ <translation>Po&amp;depiš zprávu</translation>
+ </message>
+ <message>
+ <source>Reset all sign message fields</source>
+ <translation>Vymaž všechna pole formuláře pro podepsání zrávy</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Všechno &amp;smaž</translation>
+ </message>
+ <message>
+ <source>&amp;Verify Message</source>
+ <translation>&amp;Ověř zprávu</translation>
+ </message>
+ <message>
+ <source>Enter the receiver's 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. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source>
+ <translation>K ověření podpisu zprávy zadej adresu příjemce, zprávu (ověř si, že správně kopíruješ zalomení řádků, mezery, tabulátory apod.) a podpis. Dávej pozor na to, abys nezkopíroval do podpisu víc, než co je v samotné podepsané zprávě, abys nebyl napálen man-in-the-middle útokem. Poznamenejme však, že takto lze pouze prokázat, že podepisující je schopný na dané adrese přijmout platbu, ale není možnéprokázat, že odeslal jakoukoli transakci!</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address the message was signed with</source>
+ <translation>Bitcoinová adresa, kterou je zpráva podepsána</translation>
+ </message>
+ <message>
+ <source>Verify the message to ensure it was signed with the specified Bitcoin address</source>
+ <translation>Ověř zprávu, aby ses ujistil, že byla podepsána danou Bitcoinovou adresou</translation>
+ </message>
+ <message>
+ <source>Verify &amp;Message</source>
+ <translation>O&amp;věř zprávu</translation>
+ </message>
+ <message>
+ <source>Reset all verify message fields</source>
+ <translation>Vymaž všechna pole formuláře pro ověření zrávy</translation>
+ </message>
+ <message>
+ <source>Click "Sign Message" to generate signature</source>
+ <translation>Kliknutím na "Podepiš zprávu" vygeneruješ podpis</translation>
+ </message>
+ <message>
+ <source>The entered address is invalid.</source>
+ <translation>Zadaná adresa je neplatná.</translation>
+ </message>
+ <message>
+ <source>Please check the address and try again.</source>
+ <translation>Zkontroluj ji prosím a zkus to pak znovu.</translation>
+ </message>
+ <message>
+ <source>The entered address does not refer to a key.</source>
+ <translation>Zadaná adresa nepasuje ke klíči.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock was cancelled.</source>
+ <translation>Odemčení peněženky bylo zrušeno.</translation>
+ </message>
+ <message>
+ <source>Private key for the entered address is not available.</source>
+ <translation>Soukromý klíč pro zadanou adresu není dostupný.</translation>
+ </message>
+ <message>
+ <source>Message signing failed.</source>
+ <translation>Nepodařilo se podepsat zprávu.</translation>
+ </message>
+ <message>
+ <source>Message signed.</source>
+ <translation>Zpráv podepsána.</translation>
+ </message>
+ <message>
+ <source>The signature could not be decoded.</source>
+ <translation>Podpis nejde dekódovat.</translation>
+ </message>
+ <message>
+ <source>Please check the signature and try again.</source>
+ <translation>Zkontroluj ho prosím a zkus to pak znovu.</translation>
+ </message>
+ <message>
+ <source>The signature did not match the message digest.</source>
+ <translation>Podpis se neshoduje s hašem zprávy.</translation>
+ </message>
+ <message>
+ <source>Message verification failed.</source>
+ <translation>Nepodařilo se ověřit zprávu.</translation>
+ </message>
+ <message>
+ <source>Message verified.</source>
+ <translation>Zpráva ověřena.</translation>
+ </message>
+</context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>The Bitcoin Core developers</source>
+ <translation>Vývojáři Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>[testnet]</source>
+ <translation>[testnet]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ <message>
+ <source>KB/s</source>
+ <translation>kB/s</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>Otřevřeno dokud %1</translation>
+ </message>
+ <message>
+ <source>conflicted</source>
+ <translation>kolidující</translation>
+ </message>
+ <message>
+ <source>%1/offline</source>
+ <translation>%1/offline</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/nepotvrzeno</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 potvrzení</translation>
+ </message>
+ <message>
+ <source>Status</source>
+ <translation>Stav</translation>
+ </message>
+ <message numerus="yes">
+ <source>, broadcast through %n node(s)</source>
+ <translation><numerusform>, rozesláno přes %n uzel</numerusform><numerusform>, rozesláno přes %n uzly</numerusform><numerusform>, rozesláno přes %n uzlů</numerusform></translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Datum</translation>
+ </message>
+ <message>
+ <source>Source</source>
+ <translation>Zdroj</translation>
+ </message>
+ <message>
+ <source>Generated</source>
+ <translation>Vygenerováno</translation>
+ </message>
+ <message>
+ <source>From</source>
+ <translation>Od</translation>
+ </message>
+ <message>
+ <source>To</source>
+ <translation>Pro</translation>
+ </message>
+ <message>
+ <source>own address</source>
+ <translation>vlastní adresa</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>sledovaná</translation>
+ </message>
+ <message>
+ <source>label</source>
+ <translation>označení</translation>
+ </message>
+ <message>
+ <source>Credit</source>
+ <translation>Příjem</translation>
+ </message>
+ <message numerus="yes">
+ <source>matures in %n more block(s)</source>
+ <translation><numerusform>dozraje po %n bloku</numerusform><numerusform>dozraje po %n blocích</numerusform><numerusform>dozraje po %n blocích</numerusform></translation>
+ </message>
+ <message>
+ <source>not accepted</source>
+ <translation>neakceptováno</translation>
+ </message>
+ <message>
+ <source>Debit</source>
+ <translation>Výdaj</translation>
+ </message>
+ <message>
+ <source>Total debit</source>
+ <translation>Celkové výdaje</translation>
+ </message>
+ <message>
+ <source>Total credit</source>
+ <translation>Celkové příjmy</translation>
+ </message>
+ <message>
+ <source>Transaction fee</source>
+ <translation>Transakční poplatek</translation>
+ </message>
+ <message>
+ <source>Net amount</source>
+ <translation>Čistá částka</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Zpráva</translation>
+ </message>
+ <message>
+ <source>Comment</source>
+ <translation>Komentář</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>ID transakce</translation>
+ </message>
+ <message>
+ <source>Merchant</source>
+ <translation>Obchodník</translation>
+ </message>
+ <message>
+ <source>Generated coins must mature %1 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.</source>
+ <translation>Vygenerované mince musí čekat %1 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. To se občas může stát, pokud jiný uzel vygeneruje blok zhruba ve stejném okamžiku jako ty.</translation>
+ </message>
+ <message>
+ <source>Debug information</source>
+ <translation>Ladicí informace</translation>
+ </message>
+ <message>
+ <source>Transaction</source>
+ <translation>Transakce</translation>
+ </message>
+ <message>
+ <source>Inputs</source>
+ <translation>Vstupy</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Částka</translation>
+ </message>
+ <message>
+ <source>true</source>
+ <translation>true</translation>
+ </message>
+ <message>
+ <source>false</source>
+ <translation>false</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, ještě nebylo rozesláno</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Otevřeno pro %n další blok</numerusform><numerusform>Otevřeno pro %n další bloky</numerusform><numerusform>Otevřeno pro %n dalších bloků</numerusform></translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>neznámo</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>Detaily transakce</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>Toto okno zobrazuje detailní popis transakce</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Datum</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Typ</translation>
+ </message>
+ <message>
+ <source>Immature (%1 confirmations, will be available after %2)</source>
+ <translation>Nedozráno (%1 potvrzení, bude k dispozici za %2)</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Otevřeno pro %n další blok</numerusform><numerusform>Otevřeno pro %n další bloky</numerusform><numerusform>Otevřeno pro %n dalších bloků</numerusform></translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>Otřevřeno dokud %1</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>Potvrzeno (%1 potvrzení)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>Tento blok nedostal žádný jiný uzel a pravděpodobně nebude akceptován!</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>Vygenerováno, ale neakceptováno</translation>
+ </message>
+ <message>
+ <source>Offline</source>
+ <translation>Offline</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Označení</translation>
+ </message>
+ <message>
+ <source>Unconfirmed</source>
+ <translation>Nepotvrzeno</translation>
+ </message>
+ <message>
+ <source>Confirming (%1 of %2 recommended confirmations)</source>
+ <translation>Potvrzuje se (%1 z %2 doporučených potvrzení)</translation>
+ </message>
+ <message>
+ <source>Conflicted</source>
+ <translation>V kolizi</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Přijato do</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>Přijato od</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Posláno na</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>Platba sama sobě</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Vytěženo</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>sledovací</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(n/a)</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>Stav transakce. Najetím myši na toto políčko si zobrazíš počet potvrzení.</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Datum a čas přijetí transakce.</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>Druh transakce.</translation>
+ </message>
+ <message>
+ <source>Whether or not a watch-only address is involved in this transaction.</source>
+ <translation>Zda tato transakce zahrnuje i některou sledovanou adresu.</translation>
+ </message>
+ <message>
+ <source>User-defined intent/purpose of the transaction.</source>
+ <translation>Uživatelsky určený účel transakce.</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>Částka odečtená z nebo přičtená k účtu.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>Vše</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>Dnes</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>Tento týden</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>Tento měsíc</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>Minulý měsíc</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>Letos</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>Rozsah...</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Přijato</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Posláno</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>Sám sobě</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Vytěženo</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>Ostatní</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>Zadej adresu nebo označení pro její vyhledání</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>Minimální částka</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Kopíruj adresu</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Kopíruj její označení</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopíruj částku</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Kopíruj ID transakce</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>Uprav označení</translation>
+ </message>
+ <message>
+ <source>Show transaction details</source>
+ <translation>Zobraz detaily transakce</translation>
+ </message>
+ <message>
+ <source>Export Transaction History</source>
+ <translation>Exportuj transakční historii</translation>
+ </message>
+ <message>
+ <source>Watch-only</source>
+ <translation>Sledovaná</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Exportování selhalo</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the transaction history to %1.</source>
+ <translation>Při ukládání transakční historie do %1 se přihodila nějaká chyba.</translation>
+ </message>
+ <message>
+ <source>Exporting Successful</source>
+ <translation>Úspěšně vyexportováno</translation>
+ </message>
+ <message>
+ <source>The transaction history was successfully saved to %1.</source>
+ <translation>Transakční historie byla v pořádku uložena do %1.</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>CSV formát (*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Potvrzeno</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Datum</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Typ</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Označení</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adresa</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>Rozsah:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>až</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ <message>
+ <source>Unit to show amounts in. Click to select another unit.</source>
+ <translation>Jednotka pro částky. Klikni pro výběr nějaké jiné.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletFrame</name>
+ <message>
+ <source>No wallet has been loaded.</source>
+ <translation>Žádná peněženka se nenačetla.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Pošli mince</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Export</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Exportuj data z tohoto panelu do souboru</translation>
+ </message>
+ <message>
+ <source>Backup Wallet</source>
+ <translation>Záloha peněženky</translation>
+ </message>
+ <message>
+ <source>Wallet Data (*.dat)</source>
+ <translation>Data peněženky (*.dat)</translation>
+ </message>
+ <message>
+ <source>Backup Failed</source>
+ <translation>Zálohování selhalo</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the wallet data to %1.</source>
+ <translation>Při ukládání peněženky do %1 se přihodila nějaká chyba.</translation>
+ </message>
+ <message>
+ <source>The wallet data was successfully saved to %1.</source>
+ <translation>Data z peněženky byla v pořádku uložena do %1.</translation>
+ </message>
+ <message>
+ <source>Backup Successful</source>
+ <translation>Úspěšně zazálohováno</translation>
+ </message>
+</context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>Možnosti:</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>Adresář pro data</translation>
+ </message>
+ <message>
+ <source>Connect to a node to retrieve peer addresses, and disconnect</source>
+ <translation>Připojit se k uzlu, získat adresy jeho protějšků a odpojit se</translation>
+ </message>
+ <message>
+ <source>Specify your own public address</source>
+ <translation>Udej svou veřejnou adresu</translation>
+ </message>
+ <message>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>Akceptovat příkazy z příkazové řádky a přes JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>Běžet na pozadí jako démon a akceptovat příkazy</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>Použít testovací síť (testnet)</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
+ <translation>Přijímat spojení zvenčí (výchozí: 1, pokud není zadáno -proxy nebo -connect)</translation>
+ </message>
+ <message>
+ <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
+ <translation>Poslouchat na zadané adrese. Pro zápis IPv6 adresy použij notaci [adresa]:port</translation>
+ </message>
+ <message>
+ <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
+ <translation>Smazat všechny transakce peněženky a při startu obnovit pouze relevantní části řetězce bloků pomocí -rescan</translation>
+ </message>
+ <message>
+ <source>Distributed under the MIT software license, see the accompanying file COPYING or &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</source>
+ <translation>Šířen pod softwarovou licencí MIT, viz přiložený soubor COPYING nebo &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</translation>
+ </message>
+ <message>
+ <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
+ <translation>Spustit příkaz, když se objeví transakce týkající se peněženky (%s se v příkazu nahradí za TxID)</translation>
+ </message>
+ <message>
+ <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source>
+ <translation>Horní hranice pro celkový poplatek za jednu transakci z peněženky; příliš nízká hodnota může zmařit velké transakce (výchozí: %s)</translation>
+ </message>
+ <message>
+ <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, &gt;%u = target size in MiB to use for block files)</source>
+ <translation>Omezit nároky na úložný prostor prořezáváním (mazáním) starých bloků. V tomto režimu chybí peněženka a rovněž tento režim není slučitelný s -txindex. Upozornění: opětovná změna tohoto nastavení bude vyžadovat nové stažení celého řetězce bloků. (výchozí: 0 = bloky neprořezávat, &gt;%u = cílová velikost souborů s bloky, v MiB)</translation>
+ </message>
+ <message>
+ <source>Set the number of script verification threads (%u to %d, 0 = auto, &lt;0 = leave that many cores free, default: %d)</source>
+ <translation>Nastavení počtu vláken pro verifikaci skriptů (%u až %d, 0 = automaticky, &lt;0 = nechat daný počet jader volný, výchozí: %d)</translation>
+ </message>
+ <message>
+ <source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source>
+ <translation>Tohle je testovací verze – používej ji jen na vlastní riziko, ale rozhodně ji nepoužívej k těžbě nebo pro obchodní aplikace</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer. Bitcoin Core is probably already running.</source>
+ <translation>Nedaří se mi připojit na %s na tomhle počítači. Bitcoin Core už pravděpodobně jednou běží.</translation>
+ </message>
+ <message>
+ <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>UPOZORNĚNÍ: vygenerováno nezvykle mnoho bloků – přijato %d bloků jen za posledních %d hodin (očekáváno %d)</translation>
+ </message>
+ <message>
+ <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>UPOZORNĚNÍ: zkontroluj své spojení do sítě – bylo přijato %d bloků za posledních %d hodin (očekáváno %d)</translation>
+ </message>
+ <message>
+ <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>Upozornění: -paytxfee je nastaveno velmi vysoko! Toto je transakční poplatek, který zaplatíš za každou poslanou transakci.</translation>
+ </message>
+ <message>
+ <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source>
+ <translation>Upozornění: Síť podle všeho není v konzistentním stavu. Někteří těžaři jsou zřejmě v potížích.</translation>
+ </message>
+ <message>
+ <source>Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.</source>
+ <translation>Upozornění: Nesouhlasím zcela se svými protějšky! Možná potřebuji aktualizovat nebo ostatní uzly potřebují aktualizovat.</translation>
+ </message>
+ <message>
+ <source>Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
+ <translation>Upozornění: nastala chyba při čtení souboru wallet.dat! Všechny klíče se přečetly správně, ale data o transakcích nebo záznamy v adresáři mohou chybět či být nesprávné.</translation>
+ </message>
+ <message>
+ <source>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</source>
+ <translation>Upozornění: soubor wallet.dat je poškozený, data jsou však zachráněna! Původní soubor wallet.dat je uložený jako wallet.{timestamp}.bak v %s. Pokud je stav tvého účtu nebo transakce nesprávné, zřejmě bys měl obnovit zálohu.</translation>
+ </message>
+ <message>
+ <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source>
+ <translation>Umístit na bílou listinu protějšky připojující se z dané podsítě či IP adresy. Lze zadat i vícekrát.</translation>
+ </message>
+ <message>
+ <source>(default: 1)</source>
+ <translation>(výchozí: 1)</translation>
+ </message>
+ <message>
+ <source>&lt;category&gt; can be:</source>
+ <translation>&lt;category&gt; může být:</translation>
+ </message>
+ <message>
+ <source>Attempt to recover private keys from a corrupt wallet.dat</source>
+ <translation>Pokusit se zachránit soukromé klíče z poškozeného souboru wallet.dat</translation>
+ </message>
+ <message>
+ <source>Block creation options:</source>
+ <translation>Možnosti vytváření bloku:</translation>
+ </message>
+ <message>
+ <source>Connect only to the specified node(s)</source>
+ <translation>Připojit se pouze k zadanému uzlu (příp. zadaným uzlům)</translation>
+ </message>
+ <message>
+ <source>Connection options:</source>
+ <translation>Možnosti připojení:</translation>
+ </message>
+ <message>
+ <source>Corrupted block database detected</source>
+ <translation>Bylo zjištěno poškození databáze bloků</translation>
+ </message>
+ <message>
+ <source>Debugging/Testing options:</source>
+ <translation>Možnosti ladění/testování:</translation>
+ </message>
+ <message>
+ <source>Do not load the wallet and disable wallet RPC calls</source>
+ <translation>Nenačítat peněženku a vypnout její RPC volání</translation>
+ </message>
+ <message>
+ <source>Do you want to rebuild the block database now?</source>
+ <translation>Chceš přestavět databázi bloků hned teď?</translation>
+ </message>
+ <message>
+ <source>Error initializing block database</source>
+ <translation>Chyba při zakládání databáze bloků</translation>
+ </message>
+ <message>
+ <source>Error initializing wallet database environment %s!</source>
+ <translation>Chyba při vytváření databázového prostředí %s pro peněženku!</translation>
+ </message>
+ <message>
+ <source>Error loading block database</source>
+ <translation>Chyba při načítání databáze bloků</translation>
+ </message>
+ <message>
+ <source>Error opening block database</source>
+ <translation>Chyba při otevírání databáze bloků</translation>
+ </message>
+ <message>
+ <source>Error: Disk space is low!</source>
+ <translation>Problém: Na disku je málo místa!</translation>
+ </message>
+ <message>
+ <source>Failed to listen on any port. Use -listen=0 if you want this.</source>
+ <translation>Nepodařilo se naslouchat na žádném portu. Použij -listen=0, pokud to byl tvůj záměr.</translation>
+ </message>
+ <message>
+ <source>If &lt;category&gt; is not supplied, output all debugging information.</source>
+ <translation>Pokud není &lt;category&gt; zadána, bude tisknout veškeré ladicí informace.</translation>
+ </message>
+ <message>
+ <source>Importing...</source>
+ <translation>Importuji...</translation>
+ </message>
+ <message>
+ <source>Incorrect or no genesis block found. Wrong datadir for network?</source>
+ <translation>Nemám žádný nebo jen špatný genesis blok. Není špatně nastavený datadir?</translation>
+ </message>
+ <message>
+ <source>Invalid -onion address: '%s'</source>
+ <translation>Neplatná -onion adresa: '%s'</translation>
+ </message>
+ <message>
+ <source>Not enough file descriptors available.</source>
+ <translation>Je nedostatek deskriptorů souborů.</translation>
+ </message>
+ <message>
+ <source>Only connect to nodes in network &lt;net&gt; (ipv4, ipv6 or onion)</source>
+ <translation>Připojovat se pouze k uzlům v &lt;net&gt; síti (ipv4, ipv6 nebo onion)</translation>
+ </message>
+ <message>
+ <source>Prune cannot be configured with a negative value.</source>
+ <translation>Prořezávání nemůže být zkonfigurováno s negativní hodnotou.</translation>
+ </message>
+ <message>
+ <source>Prune mode is incompatible with -txindex.</source>
+ <translation>Prořezávací režim není kompatibilní s -txindex.</translation>
+ </message>
+ <message>
+ <source>Set database cache size in megabytes (%d to %d, default: %d)</source>
+ <translation>Nastavit velikost databázové vyrovnávací paměti v megabajtech (%d až %d, výchozí: %d)</translation>
+ </message>
+ <message>
+ <source>Set maximum block size in bytes (default: %d)</source>
+ <translation>Nastavit maximální velikost bloku v bajtech (výchozí: %d)</translation>
+ </message>
+ <message>
+ <source>Specify wallet file (within data directory)</source>
+ <translation>Udej název souboru s peněženkou (v rámci datového adresáře)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: %u)</source>
+ <translation>Použít UPnP k namapování naslouchacího portu (výchozí: %u)</translation>
+ </message>
+ <message>
+ <source>Verifying blocks...</source>
+ <translation>Ověřuji bloky...</translation>
+ </message>
+ <message>
+ <source>Verifying wallet...</source>
+ <translation>Kontroluji peněženku...</translation>
+ </message>
+ <message>
+ <source>Wallet %s resides outside data directory %s</source>
+ <translation>Peněženka %s se nachází mimo datový adresář %s</translation>
+ </message>
+ <message>
+ <source>Wallet options:</source>
+ <translation>Možnosti peněženky:</translation>
+ </message>
+ <message>
+ <source>Warning: This version is obsolete; upgrade required!</source>
+ <translation>Upozornění: tahle verze je zastaralá, měl bys ji aktualizovat!</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to change -txindex</source>
+ <translation>Je třeba přestavět databázi použitím -reindex, aby bylo možné změnit -txindex</translation>
+ </message>
+ <message>
+ <source>Imports blocks from external blk000??.dat file</source>
+ <translation>Importovat bloky z externího souboru blk000??.dat</translation>
+ </message>
+ <message>
+ <source>Allow JSON-RPC connections from specified source. Valid for &lt;ip&gt; are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times</source>
+ <translation>Povolit JSON-RPC spojení ze specifikovaného zdroje. Platnou hodnotou &lt;ip&gt; je jednotlivá IP adresa (např. 1.2.3.4), síť/maska (např. 1.2.3.4/255.255.255.0) nebo síť/CIDR (např. 1.2.3.4/24). Tuto volbu lze použít i vícekrát</translation>
+ </message>
+ <message>
+ <source>An error occurred while setting up the RPC address %s port %u for listening: %s</source>
+ <translation>Při nastavování naslouchací RPC adresy %s a portu %u nastala chyba: %s</translation>
+ </message>
+ <message>
+ <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source>
+ <translation>Obsadit zadanou adresu a protějšky, které se na ní připojí, umístit na bílou listinu. Pro zápis IPv6 adresy použij notaci [adresa]:port</translation>
+ </message>
+ <message>
+ <source>Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)</source>
+ <translation>Čekat na zadané adrese na JSON-RPC spojení. Pro zápis IPv6 adresy použij notaci [adresa]:port. Tuto volbu lze použít i vícekrát (výchozí: poslouchat na všech rozhraních)</translation>
+ </message>
+ <message>
+ <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source>
+ <translation>Nedaří se mi získat zámek na datový adresář %s. Bitcoin Core pravděpodobně už jednou běží.</translation>
+ </message>
+ <message>
+ <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
+ <translation>Vytvářet nové soubory s výchozími systémovými právy namísto umask 077 (uplatní se, pouze pokud je vypnutá funkce peněženky)</translation>
+ </message>
+ <message>
+ <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source>
+ <translation>Zjistit vlastní IP adresu (výchozí: 1, pokud naslouchá a není zadáno -externalip nebo -proxy)</translation>
+ </message>
+ <message>
+ <source>Error: Listening for incoming connections failed (listen returned error %s)</source>
+ <translation>Chyba: Nelze naslouchat příchozí spojení (listen vrátil chybu %s)</translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source>
+ <translation>Chyba: Byl použit nepodporovaný argument -socks. Nastavení verze SOCKS už není možné, podporovány jsou pouze SOCKS5 proxy.</translation>
+ </message>
+ <message>
+ <source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source>
+ <translation>Spustit příkaz, když přijde relevantní upozornění nebo když dojde k opravdu dlouhému rozštěpení řetezce bloků (%s se v příkazu nahradí zprávou)</translation>
+ </message>
+ <message>
+ <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source>
+ <translation>Poplatky (v BTC/kB) menší než tato hodnota jsou považovány za nulové pro účely přeposílání transakcí (výchozí: %s)</translation>
+ </message>
+ <message>
+ <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
+ <translation>Pokud paytxfee není nastaveno, platit dostatečný poplatek na to, aby začaly být transakce potvrzovány v průměru během n bloků (výchozí: %u)</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)</source>
+ <translation>Neplatná částka pro -maxtxfee=&lt;amount&gt;: '%s' (musí být alespoň jako poplatek minrelay %s, aby transakce nezůstávaly trčet)</translation>
+ </message>
+ <message>
+ <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source>
+ <translation>Maximální velikost dat v transakcích nesoucích data, se kterou jsme ochotni je ještě přeposílat a těžit (výchozí: %u)</translation>
+ </message>
+ <message>
+ <source>Prune configured below the minimum of %d MB. Please use a higher number.</source>
+ <translation>Prořezávání je nastaveno pod minimum %d MB. Použij prosím nějaké vyšší číslo.</translation>
+ </message>
+ <message>
+ <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source>
+ <translation>Při nedostatku adres získat další protějšky z DNS (výchozí: 1, pokud není použito -connect)</translation>
+ </message>
+ <message>
+ <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source>
+ <translation>Použít náhodné údaje pro každé proxy spojení. To umožní izolovat nesouvisející datové toky v Toru (výchozí: %u)</translation>
+ </message>
+ <message>
+ <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
+ <translation>Nastavit maximální velikost prioritních/nízkopoplatkových transakcí v bajtech (výchozí: %d)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source>
+ <translation>Nastavení počtu vláken pro těžení, je-li zapnuté (-1 = všechna jádra, výchozí: %d)</translation>
+ </message>
+ <message>
+ <source>The transaction amount is too small to send after the fee has been deducted</source>
+ <translation>Částka v transakci po odečtení poplatku je příliš malá na odeslání</translation>
+ </message>
+ <message>
+ <source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit &lt;https://www.openssl.org/&gt; and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source>
+ <translation>Tento produkt zahrnuje programy vyvinuté OpenSSL Projektem pro použití v OpenSSL Toolkitu &lt;https://www.openssl.org/&gt; a kryptografický program od Erika Younga a program UPnP od Thomase Bernarda.</translation>
+ </message>
+ <message>
+ <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an 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)
+The username and password MUST NOT be the same.
+If the file does not exist, create it with owner-readable-only file permissions.
+It is also recommended to set alertnotify so you are notified of problems;
+for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
+</source>
+ <translation>K používání bitcoind nebo volby -server u bitcoin-qt 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)
+rpcuser a rpcpassword NESMÍ být stejné.
+Pokud konfigurační soubor ještě neexistuje, vytvoř ho tak, aby ho mohl číst pouze vlastník.
+Je také doporučeno si nastavit alertnotify, abys byl upozorněn na případné problémy;
+například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
+</translation>
+ </message>
+ <message>
+ <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source>
+ <translation>Upozornění: -maxtxfee je nastaveno velmi vysoko! Takto vysoký poplatek může být zaplacen v jednotlivé transakci.</translation>
+ </message>
+ <message>
+ <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source>
+ <translation>Upozornění: Zkontroluj, že máš v počítači správně nastavený datum a čas! Pokud jsou nastaveny špatně, Bitcoin Core nebude fungovat správně.</translation>
+ </message>
+ <message>
+ <source>Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway</source>
+ <translation>Na protějšky na bílé listině se nevztahuje DoS klatba a jejich transakce jsou vždy přeposílány, i když už třeba jsou v mempoolu, což je užitečné např. pro bránu</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source>
+ <translation>K návratu k neprořezávacímu režimu je potřeba přestavět databázi použitím -reindex. Také se znovu stáhne celý řetězec bloků</translation>
+ </message>
+ <message>
+ <source>(default: %u)</source>
+ <translation>(výchozí: %u)</translation>
+ </message>
+ <message>
+ <source>Accept public REST requests (default: %u)</source>
+ <translation>Přijímat veřejné REST požadavky (výchozí: %u)</translation>
+ </message>
+ <message>
+ <source>Activating best chain...</source>
+ <translation>Aktivuji nejlepší řetězec...</translation>
+ </message>
+ <message>
+ <source>Can't run with a wallet in prune mode.</source>
+ <translation>V prořezávacím režimu se s pěněženkou nemůžu spustit.</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -whitebind address: '%s'</source>
+ <translation>Nemohu přeložit -whitebind adresu: '%s'</translation>
+ </message>
+ <message>
+ <source>Choose data directory on startup (default: 0)</source>
+ <translation>Zvolit adresář pro data při startu (výchozí: 0)</translation>
+ </message>
+ <message>
+ <source>Connect through SOCKS5 proxy</source>
+ <translation>Připojit se přes SOCKS5 proxy</translation>
+ </message>
+ <message>
+ <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source>
+ <translation>Copyright (C) 2009-%i Vývojáři Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Could not parse -rpcbind value %s as network address</source>
+ <translation>Nejde mi přečíst hodnotu -rpcbind %s jako síťovou adresu</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source>
+ <translation>Chyba při načítání wallet.dat: peněženka vyžaduje novější verzi Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Error reading from database, shutting down.</source>
+ <translation>Chyba při čtení z databáze, ukončuji se.</translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -tor found, use -onion.</source>
+ <translation>Chyba: Argument -tor již není podporovaný, použij -onion.</translation>
+ </message>
+ <message>
+ <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source>
+ <translation>Poplatek (v BTC/kB), který se přidá ke každé odeslané transakci (výchozí: %s)</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Informace</translation>
+ </message>
+ <message>
+ <source>Initialization sanity check failed. Bitcoin Core is shutting down.</source>
+ <translation>Selhala úvodní zevrubná prověrka. Bitcoin Core se ukončuje.</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Neplatná částka pro -maxtxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -minrelaytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Neplatná částka pro -minrelaytxfee=&lt;částka&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -mintxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Neplatná částka pro -mintxfee=&lt;částka&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s' (must be at least %s)</source>
+ <translation>Neplatná částka pro -paytxfee=&lt;částka&gt;: '%s' (musí být alespoň %s)</translation>
+ </message>
+ <message>
+ <source>Invalid netmask specified in -whitelist: '%s'</source>
+ <translation>Ve -whitelist byla zadána neplatná podsíť: '%s'</translation>
+ </message>
+ <message>
+ <source>Keep at most &lt;n&gt; unconnectable transactions in memory (default: %u)</source>
+ <translation>Držet v paměti nejvýše &lt;n&gt; nespojitelných transakcí (výchozí: %u)</translation>
+ </message>
+ <message>
+ <source>Need to specify a port with -whitebind: '%s'</source>
+ <translation>V rámci -whitebind je třeba specifikovat i port: '%s'</translation>
+ </message>
+ <message>
+ <source>Node relay options:</source>
+ <translation>Možnosti přeposílání:</translation>
+ </message>
+ <message>
+ <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source>
+ <translation>Možnosti SSL pro RPC: (viz instrukce nastavení SSL na Bitcoin Wiki)</translation>
+ </message>
+ <message>
+ <source>RPC server options:</source>
+ <translation>Možnosti RPC serveru:</translation>
+ </message>
+ <message>
+ <source>RPC support for HTTP persistent connections (default: %d)</source>
+ <translation>Podpora RPC pro perzistentní HTTP spojení (výchozí: %d)</translation>
+ </message>
+ <message>
+ <source>Rebuild block chain index from current blk000??.dat files on startup</source>
+ <translation>Při startu znovu vytvořit index řetězce bloků z aktuálních blk000??.dat souborů</translation>
+ </message>
+ <message>
+ <source>Receive and display P2P network alerts (default: %u)</source>
+ <translation>Přijímat a zobrazovat poplachy z P2P sítě (výchozí: %u)</translation>
+ </message>
+ <message>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>Posílat stopovací/ladicí informace do konzole místo do souboru debug.log</translation>
+ </message>
+ <message>
+ <source>Send transactions as zero-fee transactions if possible (default: %u)</source>
+ <translation>Posílat transakce pokud možno bez poplatků (výchozí: %u)</translation>
+ </message>
+ <message>
+ <source>Set SSL root certificates for payment request (default: -system-)</source>
+ <translation>Nastavit kořenové SSL certifikáty pro platební požadavky (výchozí: -system-)</translation>
+ </message>
+ <message>
+ <source>Set language, for example "de_DE" (default: system locale)</source>
+ <translation>Nastavit jazyk, například „de_DE“ (výchozí: systémové nastavení)</translation>
+ </message>
+ <message>
+ <source>Show all debugging options (usage: --help -help-debug)</source>
+ <translation>Zobrazit všechny možnosti ladění (užití: --help -help-debug)</translation>
+ </message>
+ <message>
+ <source>Show splash screen on startup (default: 1)</source>
+ <translation>Zobrazit startovací obrazovku (výchozí: 1)</translation>
+ </message>
+ <message>
+ <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source>
+ <translation>Při spuštění klienta zmenšit soubor debug.log (výchozí: 1, pokud není zadáno -debug)</translation>
+ </message>
+ <message>
+ <source>Signing transaction failed</source>
+ <translation>Nepodařilo se podepsat transakci</translation>
+ </message>
+ <message>
+ <source>Start minimized</source>
+ <translation>Nastartovat minimalizovaně</translation>
+ </message>
+ <message>
+ <source>The transaction amount is too small to pay the fee</source>
+ <translation>Částka v transakci je příliš malá na pokrytí poplatku</translation>
+ </message>
+ <message>
+ <source>This is experimental software.</source>
+ <translation>Tohle je experimentální program.</translation>
+ </message>
+ <message>
+ <source>Transaction amount too small</source>
+ <translation>Částka v transakci je příliš malá</translation>
+ </message>
+ <message>
+ <source>Transaction amounts must be positive</source>
+ <translation>Částky v transakci musí být kladné</translation>
+ </message>
+ <message>
+ <source>Transaction too large for fee policy</source>
+ <translation>Transakce je na poplatkovou politiku příliš velká</translation>
+ </message>
+ <message>
+ <source>Transaction too large</source>
+ <translation>Transakce je příliš velká</translation>
+ </message>
+ <message>
+ <source>UI Options:</source>
+ <translation>Možnosti UI:</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer (bind returned error %s)</source>
+ <translation>Nedaří se mi připojit na %s na tomhle počítači (operace bind vrátila chybu %s)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: 1 when listening)</source>
+ <translation>Použít UPnP k namapování naslouchacího portu (výchozí: 1, pokud naslouchá)</translation>
+ </message>
+ <message>
+ <source>Username for JSON-RPC connections</source>
+ <translation>Uživatelské jméno pro JSON-RPC spojení</translation>
+ </message>
+ <message>
+ <source>Wallet needed to be rewritten: restart Bitcoin Core to complete</source>
+ <translation>Soubor s peněženkou potřeboval přepsat: restartuj Bitcoin Core, aby se operace dokončila</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Upozornění</translation>
+ </message>
+ <message>
+ <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source>
+ <translation>Upozornění: Nepodporovaný argument -benchmark se ignoruje, použij -debug=bench.</translation>
+ </message>
+ <message>
+ <source>Warning: Unsupported argument -debugnet ignored, use -debug=net.</source>
+ <translation>Upozornění: Nepodporovaný argument -debugnet se ignoruje, použij -debug=net.</translation>
+ </message>
+ <message>
+ <source>Zapping all transactions from wallet...</source>
+ <translation>Vymazat všechny transakce z peněženky...</translation>
+ </message>
+ <message>
+ <source>on startup</source>
+ <translation>při startu</translation>
+ </message>
+ <message>
+ <source>wallet.dat corrupt, salvage failed</source>
+ <translation>Soubor wallet.dat je poškozen, jeho záchrana se nezdařila</translation>
+ </message>
+ <message>
+ <source>Password for JSON-RPC connections</source>
+ <translation>Heslo pro JSON-RPC spojení</translation>
+ </message>
+ <message>
+ <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
+ <translation>Spustit příkaz, když se změní nejlepší blok (%s se v příkazu nahradí hashem bloku)</translation>
+ </message>
+ <message>
+ <source>Upgrade wallet to latest format</source>
+ <translation>Převést peněženku na nejnovější formát</translation>
+ </message>
+ <message>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>Přeskenovat řetězec bloků na chybějící transakce tvé pěněženky</translation>
+ </message>
+ <message>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>Použít OpenSSL (https) pro JSON-RPC spojení</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>Tato nápověda</translation>
+ </message>
+ <message>
+ <source>Allow DNS lookups for -addnode, -seednode and -connect</source>
+ <translation>Povolit DNS dotazy pro -addnode (přidání uzlu), -seednode a -connect (připojení)</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>Načítám adresy...</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>Chyba při načítání wallet.dat: peněženka je poškozená</translation>
+ </message>
+ <message>
+ <source>(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source>
+ <translation>(1 = ukládat transakční metadata, např. majitele účtu a informace o platebním požadavku, 2 = mazat transakční metadata)</translation>
+ </message>
+ <message>
+ <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
+ <translation>Jak moc důkladná má být verifikace bloků -checkblocks (0-4, výchozí: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
+ <translation>Spravovat úplný index transakcí, který je využíván rpc voláním getrawtransaction (výchozí: %u)</translation>
+ </message>
+ <message>
+ <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source>
+ <translation>Doba ve vteřinách, po kterou se nebudou moci zlobivé protějšky znovu připojit (výchozí: %u)</translation>
+ </message>
+ <message>
+ <source>Output debugging information (default: %u, supplying &lt;category&gt; is optional)</source>
+ <translation>Tisknout ladicí informace (výchozí: %u, zadání &lt;category&gt; je volitelné)</translation>
+ </message>
+ <message>
+ <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source>
+ <translation>Použít samostatnou SOCKS5 proxy ke spojení s protějšky přes skryté služby v Toru (výchozí: %s)</translation>
+ </message>
+ <message>
+ <source>(default: %s)</source>
+ <translation>(výchozí: %s)</translation>
+ </message>
+ <message>
+ <source>Acceptable ciphers (default: %s)</source>
+ <translation>Akceptovatelné šifry (výchozí: %s)</translation>
+ </message>
+ <message>
+ <source>Always query for peer addresses via DNS lookup (default: %u)</source>
+ <translation>Vždy získávat adresy dalších protějšků přes DNS (výchozí: %u)</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>Chyba při načítání wallet.dat</translation>
+ </message>
+ <message>
+ <source>Generate coins (default: %u)</source>
+ <translation>Těžit (výchozí: %u)</translation>
+ </message>
+ <message>
+ <source>How many blocks to check at startup (default: %u, 0 = all)</source>
+ <translation>Kolik bloků při startu zkontrolovat (výchozí: %u, 0 = všechny)</translation>
+ </message>
+ <message>
+ <source>Include IP addresses in debug output (default: %u)</source>
+ <translation>Zaznamenávat do ladicích výstupů i IP adresy (výchozí: %u)</translation>
+ </message>
+ <message>
+ <source>Invalid -proxy address: '%s'</source>
+ <translation>Neplatná -proxy adresa: '%s'</translation>
+ </message>
+ <message>
+ <source>Listen for JSON-RPC connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>Čekat na JSON-RPC spojení na &lt;portu&gt; (výchozí: %u nebo testnet: %u)</translation>
+ </message>
+ <message>
+ <source>Listen for connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>Čekat na spojení na &lt;portu&gt; (výchozí: %u nebo testnet: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain at most &lt;n&gt; connections to peers (default: %u)</source>
+ <translation>Povolit nejvýše &lt;n&gt; protějšků (výchozí: %u)</translation>
+ </message>
+ <message>
+ <source>Make the wallet broadcast transactions</source>
+ <translation>Transakce z peněženky rozesílat</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection receive buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>Maximální velikost přijímacího bufferu pro každé spojení, &lt;n&gt;*1000 bajtů (výchozí: %u)</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection send buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>Maximální velikost odesílacího bufferu pro každé spojení, &lt;n&gt;*1000 bajtů (výchozí: %u)</translation>
+ </message>
+ <message>
+ <source>Prepend debug output with timestamp (default: %u)</source>
+ <translation>Připojit před ladicí výstup časové razítko (výchozí: %u)</translation>
+ </message>
+ <message>
+ <source>Relay and mine data carrier transactions (default: %u)</source>
+ <translation>Přeposílat a těžit transakce nesoucí data (výchozí: %u)</translation>
+ </message>
+ <message>
+ <source>Relay non-P2SH multisig (default: %u)</source>
+ <translation>Přeposílat ne-P2SH multisig (výchozí: %u)</translation>
+ </message>
+ <message>
+ <source>Server certificate file (default: %s)</source>
+ <translation>Soubor se serverovým certifikátem (výchozí: %s)</translation>
+ </message>
+ <message>
+ <source>Server private key (default: %s)</source>
+ <translation>Soubor se serverovým soukromým klíčem (výchozí: %s)</translation>
+ </message>
+ <message>
+ <source>Set key pool size to &lt;n&gt; (default: %u)</source>
+ <translation>Nastavit zásobník klíčů na velikost &lt;n&gt; (výchozí: %u)</translation>
+ </message>
+ <message>
+ <source>Set minimum block size in bytes (default: %u)</source>
+ <translation>Nastavit minimální velikost bloku v bajtech (výchozí: %u)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads to service RPC calls (default: %d)</source>
+ <translation>Nastavení počtu vláken pro servisní RPC volání (výchozí: %d)</translation>
+ </message>
+ <message>
+ <source>Specify configuration file (default: %s)</source>
+ <translation>Konfigurační soubor (výchozí: %s)</translation>
+ </message>
+ <message>
+ <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source>
+ <translation>Zadej časový limit spojení v milivteřinách (minimum: 1, výchozí: %d)</translation>
+ </message>
+ <message>
+ <source>Spend unconfirmed change when sending transactions (default: %u)</source>
+ <translation>Utrácet i ještě nepotvrzené drobné při posílání transakcí (výchozí: %u)</translation>
+ </message>
+ <message>
+ <source>Threshold for disconnecting misbehaving peers (default: %u)</source>
+ <translation>Práh pro odpojování zlobivých protějšků (výchozí: %u)</translation>
+ </message>
+ <message>
+ <source>Unknown network specified in -onlynet: '%s'</source>
+ <translation>V -onlynet byla uvedena neznámá síť: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -bind address: '%s'</source>
+ <translation>Nemohu přeložit -bind adresu: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -externalip address: '%s'</source>
+ <translation>Nemohu přeložit -externalip adresu: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Neplatná částka pro -paytxfee=&lt;částka&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>Nedostatek prostředků</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>Načítám index bloků...</translation>
+ </message>
+ <message>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>Přidat uzel, ke kterému se připojit a snažit se spojení udržet</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>Načítám peněženku...</translation>
+ </message>
+ <message>
+ <source>Cannot downgrade wallet</source>
+ <translation>Nemohu převést peněženku do staršího formátu</translation>
+ </message>
+ <message>
+ <source>Cannot write default address</source>
+ <translation>Nemohu napsat výchozí adresu</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>Přeskenovávám...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>Načítání dokončeno</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Chyba</translation>
+ </message>
+</context>
+</TS> \ No newline at end of file
diff --git a/src/qt/locale/bitcoin_cy.ts b/src/qt/locale/bitcoin_cy.ts
new file mode 100644
index 0000000000..1b8eb3dc41
--- /dev/null
+++ b/src/qt/locale/bitcoin_cy.ts
@@ -0,0 +1,506 @@
+<TS language="cy" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Create a new address</source>
+ <translation>Creu cyfeiriad newydd</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Copio'r cyfeiriad sydd wedi'i ddewis i'r clipfwrdd system</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;Dileu</translation>
+ </message>
+ </context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Label</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Cyfeiriad</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(heb label)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Teipiwch gyfrinymadrodd</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Cyfrinymadrodd newydd</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Ailadroddwch gyfrinymadrodd newydd</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>Amgryptio'r waled</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>Mae angen i'r gweithred hon ddefnyddio'ch cyfrinymadrodd er mwyn datgloi'r waled.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Datgloi'r waled</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>Mae angen i'r gweithred hon ddefnyddio'ch cyfrinymadrodd er mwyn dadgryptio'r waled.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>Dadgryptio'r waled</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>Newid cyfrinymadrodd</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>Cadarnau amgryptiad y waled</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>Waled wedi'i amgryptio</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>Amgryptiad waled wedi methu</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>Methodd amgryptiad y waled oherwydd gwall mewnol. Ni amgryptwyd eich waled.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>Dydy'r cyfrinymadroddion a ddarparwyd ddim yn cyd-fynd â'u gilydd.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>Methodd ddatgloi'r waled</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>Methodd dadgryptiad y waled</translation>
+ </message>
+ </context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>Cysoni â'r rhwydwaith...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;Trosolwg</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>Dangos trosolwg cyffredinol y waled</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Trafodion</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>Pori hanes trafodion</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>Gadael rhaglen</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;Opsiynau</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Newid y cyfrinymadrodd a ddefnyddiwyd ar gyfer amgryptio'r waled</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;Ffeil</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;Gosodiadau</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>&amp;Cymorth</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>Bar offer tabiau</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Gwall</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Rhybudd</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Gwybodaeth</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>Cyfamserol</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>Dal i fyny</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>Trafodiad a anfonwyd</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>Trafodiad sy'n cyrraedd</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>Mae'r waled &lt;b&gt;wedi'i amgryptio&lt;/b&gt; ac &lt;b&gt;heb ei gloi&lt;/b&gt; ar hyn o bryd</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>Mae'r waled &lt;b&gt;wedi'i amgryptio&lt;/b&gt; ac &lt;b&gt;ar glo&lt;/b&gt; ar hyn o bryd</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ </context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Date</source>
+ <translation>Dyddiad</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(heb label)</translation>
+ </message>
+ </context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>Golygu'r cyfeiriad</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>&amp;Label</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;Cyfeiriad</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>Cyfeiriad derbyn newydd</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>Cyfeiriad anfon newydd</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>Golygu'r cyfeiriad derbyn</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>Golygu'r cyfeiriad anfon</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>Mae'r cyfeiriad "%1" sydd newydd gael ei geisio gennych yn y llyfr cyfeiriad yn barod.</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>Methodd ddatgloi'r waled.</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>Methodd gynhyrchu allwedd newydd.</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ </context>
+<context>
+ <name>HelpMessageDialog</name>
+ </context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Error</source>
+ <translation>Gwall</translation>
+ </message>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ </context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>Opsiynau</translation>
+ </message>
+ </context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>Ffurflen</translation>
+ </message>
+ </context>
+<context>
+ <name>PaymentServer</name>
+ </context>
+<context>
+ <name>PeerTableModel</name>
+ </context>
+<context>
+ <name>QObject</name>
+ </context>
+<context>
+ <name>QRImageWidget</name>
+ </context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>&amp;Information</source>
+ <translation>Gwybodaeth</translation>
+ </message>
+ </context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Label:</translation>
+ </message>
+ </context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>Address</source>
+ <translation>Cyfeiriad</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Label</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Neges</translation>
+ </message>
+ </context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Dyddiad</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Label</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Neges</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(heb label)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Anfon arian</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>Anfon at pobl lluosog ar yr un pryd</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>Gweddill:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>Cadarnhau'r gweithrediad anfon</translation>
+ </message>
+ <message>
+ <source>%1 to %2</source>
+ <translation>%1 i %2</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(heb label)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>&amp;Maint</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Label:</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Gludo cyfeiriad o'r glipfwrdd</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ </context>
+<context>
+ <name>ShutdownWindow</name>
+ </context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Gludo cyfeiriad o'r glipfwrdd</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ </context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>[testnet]</source>
+ <translation>[testnet]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ </context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>Agor tan %1</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Dyddiad</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Neges</translation>
+ </message>
+ </context>
+<context>
+ <name>TransactionDescDialog</name>
+ </context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Dyddiad</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Math</translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>Agor tan %1</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Label</translation>
+ </message>
+ </context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>Today</source>
+ <translation>Heddiw</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>Eleni</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Dyddiad</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Math</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Label</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Cyfeiriad</translation>
+ </message>
+ </context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ </context>
+<context>
+ <name>WalletFrame</name>
+ </context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Anfon arian</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ </context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Information</source>
+ <translation>Gwybodaeth</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Rhybudd</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Gwall</translation>
+ </message>
+</context>
+</TS> \ 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 0000000000..f5c8ca65ff
--- /dev/null
+++ b/src/qt/locale/bitcoin_da.ts
@@ -0,0 +1,3590 @@
+<TS language="da" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Right-click to edit address or label</source>
+ <translation>Højreklik for at redigere adresse eller mærke</translation>
+ </message>
+ <message>
+ <source>Create a new address</source>
+ <translation>Opret en ny adresse</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>&amp;Ny</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Kopiér den valgte adresse til systemets udklipsholder</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>&amp;Kopiér</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>&amp;Luk</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>&amp;Kopiér adresse</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>Slet den markerede adresse fra listen</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Eksportér den aktuelle visning til en fil</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Eksportér</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;Slet</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>Vælg adresse at sende bitcoins til</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>Vælg adresse at modtage bitcoins med</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>&amp;Vælg</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>Afsendelsesadresser</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>Modtagelsesadresser</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>Disse er dine Bitcoin-adresser for at sende betalinger. Tjek altid beløb og modtageradresse, inden du sender bitcoins.</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>Dette er dine Bitcoin-adresser til at modtage betalinger med. Det anbefales are bruge en ny modtagelsesadresse for hver transaktion.</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>Kopiér &amp;mærkat</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>&amp;Redigér</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>Eksportér adresseliste</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Kommasepareret fil (*.csv)</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Eksport mislykkedes</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the address list to %1. Please try again.</source>
+ <translation>Der opstod en fejl under gemning af adresselisten til %1. Prøv venligst igen.</translation>
+ </message>
+</context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Mærkat</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adresse</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(ingen mærkat)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Passphrase Dialog</source>
+ <translation>Adgangskodedialog</translation>
+ </message>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Indtast adgangskode</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Ny adgangskode</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Gentag ny adgangskode</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>Kryptér tegnebog</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>Denne funktion har brug for din tegnebogs adgangskode for at låse tegnebogen op.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Lås tegnebog op</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>Denne funktion har brug for din tegnebogs adgangskode for at dekryptere tegnebogen.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>Dekryptér tegnebog</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>Skift adgangskode</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>Bekræft tegnebogskryptering</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>Advarsel: Hvis du krypterer din tegnebog og mister din adgangskode, vil du &lt;b&gt;MISTE ALLE DINE BITCOINS&lt;/b&gt;!</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>Er du sikker på, at du ønsker at kryptere din tegnebog?</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core 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.</source>
+ <translation>Bitcoin Core vil nu lukke for at færdiggøre krypteringsprocessen. Husk at kryptering af din tegnebog kan ikke beskytte dine bitcoin fuldt ud mod at blive stjålet af eventuel malware, der måtte have inficeret din computer.</translation>
+ </message>
+ <message>
+ <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
+ <translation>VIGTIGT: Enhver tidligere sikkerhedskopi, som du har lavet af tegnebogsfilen, bør blive erstattet af den nyligt genererede, krypterede tegnebogsfil. Af sikkerhedsmæssige årsager vil tidligere sikkerhedskopier af den ikke-krypterede tegnebogsfil blive ubrugelige i det øjeblik, du starter med at anvende den nye, krypterede tegnebog.</translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>Advarsel: Caps Lock-tasten er aktiveret!</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>Tegnebog krypteret</translation>
+ </message>
+ <message>
+ <source>Enter the new passphrase to the wallet.&lt;br/&gt;Please use a passphrase of &lt;b&gt;ten or more random characters&lt;/b&gt;, or &lt;b&gt;eight or more words&lt;/b&gt;.</source>
+ <translation>Indtast det nye kodeord til tegnebogen.&lt;br/&gt;Brug venligst et kodeord på &lt;b&gt;ti eller flere tilfældige tegn&lt;/b&gt; eller &lt;b&gt;otte eller flere ord&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>Enter the old passphrase and new passphrase to the wallet.</source>
+ <translation>Indtast den gamle adgangskode og en ny adgangskode til tegnebogen.</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>Tegnebogskryptering mislykkedes</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>Tegnebogskryptering mislykkedes på grund af en intern fejl. Din tegnebog blev ikke krypteret.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>De angivne adgangskoder stemmer ikke overens.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>Tegnebogsoplåsning mislykkedes</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>Den angivne adgangskode for tegnebogsdekrypteringen er forkert.</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>Tegnebogsdekryptering mislykkedes</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>Tegnebogens adgangskode blev ændret.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>Underskriv &amp;besked…</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>Synkroniserer med netværk…</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;Oversigt</translation>
+ </message>
+ <message>
+ <source>Node</source>
+ <translation>Knude</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>Vis generel oversigt over tegnebog</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Transaktioner</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>Gennemse transaktionshistorik</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>&amp;Luk</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>Afslut program</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>Om &amp;Qt</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>Vis informationer om Qt</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;Indstillinger…</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>&amp;Kryptér tegnebog…</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>&amp;Sikkerhedskopiér tegnebog…</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>&amp;Skift adgangskode…</translation>
+ </message>
+ <message>
+ <source>&amp;Sending addresses...</source>
+ <translation>&amp;Afsendelsesadresser…</translation>
+ </message>
+ <message>
+ <source>&amp;Receiving addresses...</source>
+ <translation>&amp;Modtagelsesadresser…</translation>
+ </message>
+ <message>
+ <source>Open &amp;URI...</source>
+ <translation>&amp;Åbn URI…</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core client</source>
+ <translation>Bitcoin Core-klient</translation>
+ </message>
+ <message>
+ <source>Importing blocks from disk...</source>
+ <translation>Importerer blokke fra disken…</translation>
+ </message>
+ <message>
+ <source>Reindexing blocks on disk...</source>
+ <translation>Genindekserer blokke på disken…</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>Send bitcoins til en Bitcoin-adresse</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>Lav sikkerhedskopi af tegnebogen til et andet sted</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Skift adgangskode anvendt til tegnebogskryptering</translation>
+ </message>
+ <message>
+ <source>&amp;Debug window</source>
+ <translation>&amp;Fejlsøgningsvindue</translation>
+ </message>
+ <message>
+ <source>Open debugging and diagnostic console</source>
+ <translation>Åbn fejlsøgnings- og diagnosticeringskonsollen</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>&amp;Verificér besked…</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>Tegnebog</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>&amp;Send</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>&amp;Modtag</translation>
+ </message>
+ <message>
+ <source>Show information about Bitcoin Core</source>
+ <translation>Vis oplysninger om Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>&amp;Vis / skjul</translation>
+ </message>
+ <message>
+ <source>Show or hide the main Window</source>
+ <translation>Vis eller skjul hovedvinduet</translation>
+ </message>
+ <message>
+ <source>Encrypt the private keys that belong to your wallet</source>
+ <translation>Kryptér de private nøgler, der hører til din tegnebog</translation>
+ </message>
+ <message>
+ <source>Sign messages with your Bitcoin addresses to prove you own them</source>
+ <translation>Underskriv beskeder med dine Bitcoin-adresser for at bevise, at de tilhører dig</translation>
+ </message>
+ <message>
+ <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source>
+ <translation>Verificér beskeder for at sikre, at de er underskrevet med de angivne Bitcoin-adresser</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;Fil</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;Opsætning</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>&amp;Hjælp</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>Faneværktøjslinje</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Request payments (generates QR codes and bitcoin: URIs)</source>
+ <translation>Anmod om betalinger (genererer QR-koder og "bitcoin:"-URI'er)</translation>
+ </message>
+ <message>
+ <source>&amp;About Bitcoin Core</source>
+ <translation>&amp;Om Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Modify configuration options for Bitcoin Core</source>
+ <translation>Ændr opsætning af Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Show the list of used sending addresses and labels</source>
+ <translation>Vis listen over brugte afsendelsesadresser og -mærkater</translation>
+ </message>
+ <message>
+ <source>Show the list of used receiving addresses and labels</source>
+ <translation>Vis listen over brugte modtagelsesadresser og -mærkater</translation>
+ </message>
+ <message>
+ <source>Open a bitcoin: URI or payment request</source>
+ <translation>Åbn en "bitcoin:"-URI eller betalingsanmodning</translation>
+ </message>
+ <message>
+ <source>&amp;Command-line options</source>
+ <translation>Tilvalg for &amp;kommandolinje</translation>
+ </message>
+ <message>
+ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
+ <translation>Vis Bitcoin Core hjælpebesked for at få en liste over mulige tilvalg for Bitcoin kommandolinje</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n active connection(s) to Bitcoin network</source>
+ <translation><numerusform>%n aktiv forbindelse til Bitcoin-netværket</numerusform><numerusform>%n aktive forbindelser til Bitcoin-netværket</numerusform></translation>
+ </message>
+ <message>
+ <source>No block source available...</source>
+ <translation>Ingen blokkilde tilgængelig…</translation>
+ </message>
+ <message numerus="yes">
+ <source>Processed %n block(s) of transaction history.</source>
+ <translation><numerusform>Bearbejdede %n blok med transaktionshistorik.</numerusform><numerusform>Bearbejdede %n blokke med transaktionshistorik.</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n hour(s)</source>
+ <translation><numerusform>%n time</numerusform><numerusform>%n timer</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n day(s)</source>
+ <translation><numerusform>%n dag</numerusform><numerusform>%n dage</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n week(s)</source>
+ <translation><numerusform>%n uge</numerusform><numerusform>%n uger</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 and %2</source>
+ <translation>%1 og %2</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n year(s)</source>
+ <translation><numerusform>%n år</numerusform><numerusform>%n år</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 behind</source>
+ <translation>%1 bagud</translation>
+ </message>
+ <message>
+ <source>Last received block was generated %1 ago.</source>
+ <translation>Senest modtagne blok blev genereret for %1 siden.</translation>
+ </message>
+ <message>
+ <source>Transactions after this will not yet be visible.</source>
+ <translation>Transaktioner herefter vil endnu ikke være synlige.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Fejl</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Advarsel</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Information</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>Opdateret</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>Indhenter…</translation>
+ </message>
+ <message>
+ <source>Date: %1
+</source>
+ <translation>Dato: %1
+</translation>
+ </message>
+ <message>
+ <source>Amount: %1
+</source>
+ <translation>Beløb: %1
+</translation>
+ </message>
+ <message>
+ <source>Type: %1
+</source>
+ <translation>Type: %1
+</translation>
+ </message>
+ <message>
+ <source>Label: %1
+</source>
+ <translation>Mærkat: %1
+</translation>
+ </message>
+ <message>
+ <source>Address: %1
+</source>
+ <translation>Adresse: %1
+</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>Afsendt transaktion</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>Indgående transaktion</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>Tegnebog er &lt;b&gt;krypteret&lt;/b&gt; og i øjeblikket &lt;b&gt;ulåst&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>Tegnebog er &lt;b&gt;krypteret&lt;/b&gt; og i øjeblikket &lt;b&gt;låst&lt;/b&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <source>Network Alert</source>
+ <translation>Netværksadvarsel</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Coin Selection</source>
+ <translation>Coin-styring</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Mængde:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Byte:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Beløb:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Prioritet:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Gebyr:</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Støv:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Efter gebyr:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Byttepenge:</translation>
+ </message>
+ <message>
+ <source>(un)select all</source>
+ <translation>(af)vælg alle</translation>
+ </message>
+ <message>
+ <source>Tree mode</source>
+ <translation>Trætilstand</translation>
+ </message>
+ <message>
+ <source>List mode</source>
+ <translation>Listetilstand</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Beløb</translation>
+ </message>
+ <message>
+ <source>Received with label</source>
+ <translation>Modtaget med mærke</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>Modtaget med adresse</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Dato</translation>
+ </message>
+ <message>
+ <source>Confirmations</source>
+ <translation>Bekræftelser</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Bekræftet</translation>
+ </message>
+ <message>
+ <source>Priority</source>
+ <translation>Prioritet</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Kopiér adresse</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Kopiér mærkat</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopiér beløb</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Kopiér transaktions-ID</translation>
+ </message>
+ <message>
+ <source>Lock unspent</source>
+ <translation>Fastlås ubrugte</translation>
+ </message>
+ <message>
+ <source>Unlock unspent</source>
+ <translation>Lås ubrugte op</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Kopiér mængde</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Kopiér gebyr</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Kopiér efter-gebyr</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Kopiér byte</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Kopiér prioritet</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Kopiér støv</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Kopiér byttepenge</translation>
+ </message>
+ <message>
+ <source>highest</source>
+ <translation>højest</translation>
+ </message>
+ <message>
+ <source>higher</source>
+ <translation>højere</translation>
+ </message>
+ <message>
+ <source>high</source>
+ <translation>højt</translation>
+ </message>
+ <message>
+ <source>medium-high</source>
+ <translation>mellemhøj</translation>
+ </message>
+ <message>
+ <source>medium</source>
+ <translation>medium</translation>
+ </message>
+ <message>
+ <source>low-medium</source>
+ <translation>mellemlav</translation>
+ </message>
+ <message>
+ <source>low</source>
+ <translation>lav</translation>
+ </message>
+ <message>
+ <source>lower</source>
+ <translation>lavere</translation>
+ </message>
+ <message>
+ <source>lowest</source>
+ <translation>lavest</translation>
+ </message>
+ <message>
+ <source>(%1 locked)</source>
+ <translation>(%1 fastlåst)</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>ingen</translation>
+ </message>
+ <message>
+ <source>This label turns red if the transaction size is greater than 1000 bytes.</source>
+ <translation>Denne mærkat bliver rød, hvis transaktionsstørrelsen er større end 1000 byte.</translation>
+ </message>
+ <message>
+ <source>This label turns red if the priority is smaller than "medium".</source>
+ <translation>Denne mærkat bliver rød, hvis prioriteten er mindre end "medium".</translation>
+ </message>
+ <message>
+ <source>This label turns red if any recipient receives an amount smaller than %1.</source>
+ <translation>Denne mærkat bliver rød, hvis en eller flere modtagere modtager et beløb, der er mindre end %1.</translation>
+ </message>
+ <message>
+ <source>Can vary +/- %1 satoshi(s) per input.</source>
+ <translation>Kan variere med +/- %1 satoshi per input.</translation>
+ </message>
+ <message>
+ <source>yes</source>
+ <translation>ja</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>nej</translation>
+ </message>
+ <message>
+ <source>This means a fee of at least %1 per kB is required.</source>
+ <translation>Dette betyder, at et gebyr på mindst %1 pr. kB er nødvendigt.</translation>
+ </message>
+ <message>
+ <source>Can vary +/- 1 byte per input.</source>
+ <translation>Kan variere ±1 byte pr. input.</translation>
+ </message>
+ <message>
+ <source>Transactions with higher priority are more likely to get included into a block.</source>
+ <translation>Transaktioner med højere prioritet har højere sansynlighed for at blive inkluderet i en blok.</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(ingen mærkat)</translation>
+ </message>
+ <message>
+ <source>change from %1 (%2)</source>
+ <translation>byttepenge fra %1 (%2)</translation>
+ </message>
+ <message>
+ <source>(change)</source>
+ <translation>(byttepange)</translation>
+ </message>
+</context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>Redigér adresse</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>&amp;Mærkat</translation>
+ </message>
+ <message>
+ <source>The label associated with this address list entry</source>
+ <translation>Mærkatet, der er associeret med denne indgang i adresselisten</translation>
+ </message>
+ <message>
+ <source>The address associated with this address list entry. This can only be modified for sending addresses.</source>
+ <translation>Adressen, der er associeret med denne indgang i adresselisten. Denne kan kune ændres for afsendelsesadresser.</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;Adresse</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>Ny modtagelsesadresse</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>Ny afsendelsesadresse</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>Redigér modtagelsesadresse</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>Redigér afsendelsesadresse</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>Den indtastede adresse "%1" er allerede i adressebogen.</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is not a valid Bitcoin address.</source>
+ <translation>Den indtastede adresse "%1" er ikke en gyldig Bitcoin-adresse.</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>Kunne ikke låse tegnebog op.</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>Ny nøglegenerering mislykkedes.</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ <message>
+ <source>A new data directory will be created.</source>
+ <translation>En ny datamappe vil blive oprettet.</translation>
+ </message>
+ <message>
+ <source>name</source>
+ <translation>navn</translation>
+ </message>
+ <message>
+ <source>Directory already exists. Add %1 if you intend to create a new directory here.</source>
+ <translation>Mappe eksisterer allerede. Tilføj %1, hvis du vil oprette en ny mappe her.</translation>
+ </message>
+ <message>
+ <source>Path already exists, and is not a directory.</source>
+ <translation>Sti eksisterer allerede og er ikke en mappe.</translation>
+ </message>
+ <message>
+ <source>Cannot create data directory here.</source>
+ <translation>Kan ikke oprette en mappe her.</translation>
+ </message>
+</context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>version</translation>
+ </message>
+ <message>
+ <source>(%1-bit)</source>
+ <translation>(%1-bit)</translation>
+ </message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>Om Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Command-line options</source>
+ <translation>Kommandolinjetilvalg</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>Anvendelse:</translation>
+ </message>
+ <message>
+ <source>command-line options</source>
+ <translation>kommandolinjetilvalg</translation>
+ </message>
+</context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Welcome</source>
+ <translation>Velkommen</translation>
+ </message>
+ <message>
+ <source>Welcome to Bitcoin Core.</source>
+ <translation>Velkommen til Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</source>
+ <translation>Siden dette er første gang, programmet startes, kan du vælge, hvor Bitcoin Core skal gemme sin data.</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory.</source>
+ <translation>Bitcoin Core vil downloade og gemme et kopi af Bitcoin-blokkæden. Mindst %1 GB data vil blive gemt i denne mappe, og den vil vokse over tid. Tegnebogen vil også blive gemt i denne mappe.</translation>
+ </message>
+ <message>
+ <source>Use the default data directory</source>
+ <translation>Brug standardmappen for data</translation>
+ </message>
+ <message>
+ <source>Use a custom data directory:</source>
+ <translation>Brug tilpasset mappe for data:</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Error: Specified data directory "%1" cannot be created.</source>
+ <translation>Fejl: Angivet datamappe "%1" kan ikke oprettes.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Fejl</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n GB of free space available</source>
+ <translation><numerusform>%n GB fri plads tilgængelig</numerusform><numerusform>%n GB fri plads tilgængelig</numerusform></translation>
+ </message>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ <message>
+ <source>Open URI</source>
+ <translation>Åbn URI</translation>
+ </message>
+ <message>
+ <source>Open payment request from URI or file</source>
+ <translation>Åbn betalingsanmodning fra URI eller fil</translation>
+ </message>
+ <message>
+ <source>URI:</source>
+ <translation>URI:</translation>
+ </message>
+ <message>
+ <source>Select payment request file</source>
+ <translation>Vælg fil for betalingsanmodning</translation>
+ </message>
+ <message>
+ <source>Select payment request file to open</source>
+ <translation>Vælg fil for betalingsanmodning til åbning</translation>
+ </message>
+</context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>Indstillinger</translation>
+ </message>
+ <message>
+ <source>&amp;Main</source>
+ <translation>&amp;Generelt</translation>
+ </message>
+ <message>
+ <source>Size of &amp;database cache</source>
+ <translation>Størrelsen på &amp;databasens cache</translation>
+ </message>
+ <message>
+ <source>MB</source>
+ <translation>MB</translation>
+ </message>
+ <message>
+ <source>Number of script &amp;verification threads</source>
+ <translation>Antallet af script&amp;verificeringstråde</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside</source>
+ <translation>Acceptér forbindelser udefra</translation>
+ </message>
+ <message>
+ <source>Allow incoming connections</source>
+ <translation>Tillad indkommende forbindelser</translation>
+ </message>
+ <message>
+ <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
+ <translation>IP-adresse for proxyen (fx IPv4: 127.0.0.1 / IPv6: ::1)</translation>
+ </message>
+ <message>
+ <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source>
+ <translation>Minimér i stedet for at lukke applikationen, når vinduet lukkes. Når denne indstilling er slået til, vil applikationen først blive lukket, når Afslut vælges i menuen.</translation>
+ </message>
+ <message>
+ <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source>
+ <translation>Sproget for brugerfladen kan vælges her. Denne indstilling vil træde i kraft efter genstart af Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source>
+ <translation>Tredjeparts-URL'er (fx et blokhåndteringsværktøj), der vises i transaktionsfanen som genvejsmenupunkter. %s i URL'en erstattes med transaktionens hash. Flere URL'er separeres med en lodret streg |.</translation>
+ </message>
+ <message>
+ <source>Third party transaction URLs</source>
+ <translation>Tredjeparts-transaktions-URL'er</translation>
+ </message>
+ <message>
+ <source>Active command-line options that override above options:</source>
+ <translation>Aktuelle tilvalg for kommandolinjen, der tilsidesætter ovenstående tilvalg:</translation>
+ </message>
+ <message>
+ <source>Reset all client options to default.</source>
+ <translation>Nulstil alle klientindstillinger til deres standard.</translation>
+ </message>
+ <message>
+ <source>&amp;Reset Options</source>
+ <translation>&amp;Nulstil indstillinger</translation>
+ </message>
+ <message>
+ <source>&amp;Network</source>
+ <translation>&amp;Netværk</translation>
+ </message>
+ <message>
+ <source>Automatically start Bitcoin Core after logging in to the system.</source>
+ <translation>Start Bitcoin Core automatisk efter der logges ind på systemet.</translation>
+ </message>
+ <message>
+ <source>&amp;Start Bitcoin Core on system login</source>
+ <translation>&amp;Start Bitcoin Core ved system-login</translation>
+ </message>
+ <message>
+ <source>(0 = auto, &lt;0 = leave that many cores free)</source>
+ <translation>(0 = auto, &lt;0 = efterlad så mange kerner fri)</translation>
+ </message>
+ <message>
+ <source>W&amp;allet</source>
+ <translation>&amp;Tegnebog</translation>
+ </message>
+ <message>
+ <source>Expert</source>
+ <translation>Ekspert</translation>
+ </message>
+ <message>
+ <source>Enable coin &amp;control features</source>
+ <translation>Slå egenskaber for &amp;coin-styring til</translation>
+ </message>
+ <message>
+ <source>If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.</source>
+ <translation>Hvis du slår brug af ubekræftede byttepenge fra, kan byttepengene fra en transaktion ikke bruges, før pågældende transaktion har mindst én bekræftelse. Dette påvirker også måden hvorpå din saldo beregnes.</translation>
+ </message>
+ <message>
+ <source>&amp;Spend unconfirmed change</source>
+ <translation>&amp;Brug ubekræftede byttepenge</translation>
+ </message>
+ <message>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>Åbn automatisk Bitcoin-klientens port på routeren. Dette virker kun, når din router understøtter UPnP, og UPnP er aktiveret.</translation>
+ </message>
+ <message>
+ <source>Map port using &amp;UPnP</source>
+ <translation>Konfigurér port vha. &amp;UPnP</translation>
+ </message>
+ <message>
+ <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
+ <translation>Forbind til Bitcoin-netværket gennem en SOCKS5-proxy.</translation>
+ </message>
+ <message>
+ <source>&amp;Connect through SOCKS5 proxy (default proxy):</source>
+ <translation>&amp;Forbind gennem SOCKS5-proxy (standard-proxy):</translation>
+ </message>
+ <message>
+ <source>Proxy &amp;IP:</source>
+ <translation>Proxy-&amp;IP:</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>&amp;Port:</translation>
+ </message>
+ <message>
+ <source>Port of the proxy (e.g. 9050)</source>
+ <translation>Port for proxyen (fx 9050)</translation>
+ </message>
+ <message>
+ <source>&amp;Window</source>
+ <translation>&amp;Vindue</translation>
+ </message>
+ <message>
+ <source>Show only a tray icon after minimizing the window.</source>
+ <translation>Vis kun et statusikon efter minimering af vinduet.</translation>
+ </message>
+ <message>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>&amp;Minimér til statusfeltet i stedet for proceslinjen</translation>
+ </message>
+ <message>
+ <source>M&amp;inimize on close</source>
+ <translation>M&amp;inimér ved lukning</translation>
+ </message>
+ <message>
+ <source>&amp;Display</source>
+ <translation>&amp;Visning</translation>
+ </message>
+ <message>
+ <source>User Interface &amp;language:</source>
+ <translation>&amp;Sprog for brugergrænseflade:</translation>
+ </message>
+ <message>
+ <source>&amp;Unit to show amounts in:</source>
+ <translation>&amp;Enhed at vise beløb i:</translation>
+ </message>
+ <message>
+ <source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
+ <translation>Vælg standard for underopdeling af enhed, som skal vises i brugergrænsefladen og ved afsendelse af bitcoins.</translation>
+ </message>
+ <message>
+ <source>Whether to show coin control features or not.</source>
+ <translation>Hvorvidt egenskaber for coin-styring skal vises eller ej.</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>&amp;O.k.</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>&amp;Annullér</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>standard</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>ingen</translation>
+ </message>
+ <message>
+ <source>Confirm options reset</source>
+ <translation>Bekræft nulstilling af indstillinger</translation>
+ </message>
+ <message>
+ <source>Client restart required to activate changes.</source>
+ <translation>Genstart af klienten er nødvendig for at aktivere ændringer.</translation>
+ </message>
+ <message>
+ <source>Client will be shut down. Do you want to proceed?</source>
+ <translation>Klienten vil lukke ned. Vil du fortsætte?</translation>
+ </message>
+ <message>
+ <source>This change would require a client restart.</source>
+ <translation>Denne ændring vil kræve en genstart af klienten.</translation>
+ </message>
+ <message>
+ <source>The supplied proxy address is invalid.</source>
+ <translation>Den angivne proxy-adresse er ugyldig.</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>Formular</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>Den viste information kan være forældet. Din tegnebog synkroniserer automatisk med Bitcoin-netværket, når en forbindelse etableres, men denne proces er ikke gennemført endnu.</translation>
+ </message>
+ <message>
+ <source>Watch-only:</source>
+ <translation>Kigge:</translation>
+ </message>
+ <message>
+ <source>Available:</source>
+ <translation>Tilgængelig:</translation>
+ </message>
+ <message>
+ <source>Your current spendable balance</source>
+ <translation>Din nuværende tilgængelige saldo</translation>
+ </message>
+ <message>
+ <source>Pending:</source>
+ <translation>Uafgjort:</translation>
+ </message>
+ <message>
+ <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source>
+ <translation>Total saldo for transaktioner, som ikke er blevet bekræftet endnu, og som ikke endnu er en del af den tilgængelige saldo</translation>
+ </message>
+ <message>
+ <source>Immature:</source>
+ <translation>Umodne:</translation>
+ </message>
+ <message>
+ <source>Mined balance that has not yet matured</source>
+ <translation>Minet saldo, som endnu ikke er modnet</translation>
+ </message>
+ <message>
+ <source>Balances</source>
+ <translation>Saldi:</translation>
+ </message>
+ <message>
+ <source>Total:</source>
+ <translation>Total:</translation>
+ </message>
+ <message>
+ <source>Your current total balance</source>
+ <translation>Din nuværende totale saldo</translation>
+ </message>
+ <message>
+ <source>Your current balance in watch-only addresses</source>
+ <translation>Din nuværende saldo på kigge-adresser</translation>
+ </message>
+ <message>
+ <source>Spendable:</source>
+ <translation>Spendérbar:</translation>
+ </message>
+ <message>
+ <source>Recent transactions</source>
+ <translation>Nylige transaktioner</translation>
+ </message>
+ <message>
+ <source>Unconfirmed transactions to watch-only addresses</source>
+ <translation>Ubekræftede transaktioner til kigge-adresser</translation>
+ </message>
+ <message>
+ <source>Mined balance in watch-only addresses that has not yet matured</source>
+ <translation>Minet saldo på kigge-adresser, som endnu ikke er modnet</translation>
+ </message>
+ <message>
+ <source>Current total balance in watch-only addresses</source>
+ <translation>Nuværende totalsaldo på kigge-adresser</translation>
+ </message>
+</context>
+<context>
+ <name>PaymentServer</name>
+ <message>
+ <source>URI handling</source>
+ <translation>URI-håndtering</translation>
+ </message>
+ <message>
+ <source>Invalid payment address %1</source>
+ <translation>Ugyldig betalingsadresse %1</translation>
+ </message>
+ <message>
+ <source>Payment request rejected</source>
+ <translation>Betalingsanmodning afvist</translation>
+ </message>
+ <message>
+ <source>Payment request network doesn't match client network.</source>
+ <translation>Netværk for betalingsanmodning stemmer ikke overens med klientens netværk.</translation>
+ </message>
+ <message>
+ <source>Payment request is not initialized.</source>
+ <translation>Betalingsanmodning er ikke klargjort.</translation>
+ </message>
+ <message>
+ <source>Requested payment amount of %1 is too small (considered dust).</source>
+ <translation>Anmodet betalingsbeløb på %1 er for lille (regnes som støv).</translation>
+ </message>
+ <message>
+ <source>Payment request error</source>
+ <translation>Fejl i betalingsanmodning</translation>
+ </message>
+ <message>
+ <source>Cannot start bitcoin: click-to-pay handler</source>
+ <translation>Kan ikke starte bitcoin: click-to-pay-håndtering</translation>
+ </message>
+ <message>
+ <source>Payment request fetch URL is invalid: %1</source>
+ <translation>Hentnings-URL for betalingsanmodning er ugyldig: %1</translation>
+ </message>
+ <message>
+ <source>URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source>
+ <translation>URI kan ikke tolkes! Dette kan skyldes en ugyldig Bitcoin-adresse eller forkert udformede URL-parametre.</translation>
+ </message>
+ <message>
+ <source>Payment request file handling</source>
+ <translation>Filhåndtering for betalingsanmodninger</translation>
+ </message>
+ <message>
+ <source>Payment request file cannot be read! This can be caused by an invalid payment request file.</source>
+ <translation>Fil for betalingsanmodning kan ikke læses! Dette kan skyldes en ugyldig fil for betalingsanmodning.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>Betalingsanmodning er udløbet.</translation>
+ </message>
+ <message>
+ <source>Unverified payment requests to custom payment scripts are unsupported.</source>
+ <translation>Ikke-verificerede betalingsanmodninger for tilpassede betalings-scripts understøttes ikke.</translation>
+ </message>
+ <message>
+ <source>Invalid payment request.</source>
+ <translation>Ugyldig betalingsanmodning.</translation>
+ </message>
+ <message>
+ <source>Refund from %1</source>
+ <translation>Tilbagebetaling fra %1</translation>
+ </message>
+ <message>
+ <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source>
+ <translation>Betalingsanmodning %1 er for stor (%2 byte, %3 byte tilladt).</translation>
+ </message>
+ <message>
+ <source>Payment request DoS protection</source>
+ <translation>Beskyttelse mod DoS-angreb via betalingsanmodninger</translation>
+ </message>
+ <message>
+ <source>Error communicating with %1: %2</source>
+ <translation>Fejl under kommunikation med %1: %2</translation>
+ </message>
+ <message>
+ <source>Payment request cannot be parsed!</source>
+ <translation>Betalingsanmodning kan ikke tolkes!</translation>
+ </message>
+ <message>
+ <source>Bad response from server %1</source>
+ <translation>Fejlagtigt svar fra server %1</translation>
+ </message>
+ <message>
+ <source>Payment acknowledged</source>
+ <translation>Betaling anerkendt</translation>
+ </message>
+ <message>
+ <source>Network request error</source>
+ <translation>Fejl i netværksforespørgsel</translation>
+ </message>
+</context>
+<context>
+ <name>PeerTableModel</name>
+ <message>
+ <source>User Agent</source>
+ <translation>Brugeragent</translation>
+ </message>
+ <message>
+ <source>Node/Service</source>
+ <translation>Knude/tjeneste</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Ping-tid</translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>Beløb</translation>
+ </message>
+ <message>
+ <source>Enter a Bitcoin address (e.g. %1)</source>
+ <translation>Indtast en Bitcoin-adresse (fx %1)</translation>
+ </message>
+ <message>
+ <source>%1 d</source>
+ <translation>%1 d</translation>
+ </message>
+ <message>
+ <source>%1 h</source>
+ <translation>%1 t</translation>
+ </message>
+ <message>
+ <source>%1 m</source>
+ <translation>%1 m</translation>
+ </message>
+ <message>
+ <source>%1 s</source>
+ <translation>%1 s</translation>
+ </message>
+ <message>
+ <source>None</source>
+ <translation>Ingen</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>N/A</translation>
+ </message>
+ <message>
+ <source>%1 ms</source>
+ <translation>%1 ms</translation>
+ </message>
+</context>
+<context>
+ <name>QRImageWidget</name>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Gem billede…</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Image</source>
+ <translation>&amp;Kopiér foto</translation>
+ </message>
+ <message>
+ <source>Save QR Code</source>
+ <translation>Gem QR-kode</translation>
+ </message>
+ <message>
+ <source>PNG Image (*.png)</source>
+ <translation>PNG-billede (*.png)</translation>
+ </message>
+</context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>Client name</source>
+ <translation>Klientnavn</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>N/A</translation>
+ </message>
+ <message>
+ <source>Client version</source>
+ <translation>Klientversion</translation>
+ </message>
+ <message>
+ <source>&amp;Information</source>
+ <translation>&amp;Information</translation>
+ </message>
+ <message>
+ <source>Debug window</source>
+ <translation>Fejlsøgningsvindue</translation>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>Generelt</translation>
+ </message>
+ <message>
+ <source>Using OpenSSL version</source>
+ <translation>Anvender OpenSSL-version</translation>
+ </message>
+ <message>
+ <source>Using BerkeleyDB version</source>
+ <translation>Bruger BerkeleyDB version</translation>
+ </message>
+ <message>
+ <source>Startup time</source>
+ <translation>Opstartstidspunkt</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Netværk</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>Navn</translation>
+ </message>
+ <message>
+ <source>Number of connections</source>
+ <translation>Antal forbindelser</translation>
+ </message>
+ <message>
+ <source>Block chain</source>
+ <translation>Blokkæde</translation>
+ </message>
+ <message>
+ <source>Current number of blocks</source>
+ <translation>Nuværende antal blokke</translation>
+ </message>
+ <message>
+ <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source>
+ <translation>Åbn Bitcoin Cores fejlsøgningslogfil fra den aktuelle datamappe. Dette kan tage nogle få sekunder for store logfiler.</translation>
+ </message>
+ <message>
+ <source>Received</source>
+ <translation>Modtaget</translation>
+ </message>
+ <message>
+ <source>Sent</source>
+ <translation>Sendt</translation>
+ </message>
+ <message>
+ <source>&amp;Peers</source>
+ <translation>Andre &amp;knuder</translation>
+ </message>
+ <message>
+ <source>Select a peer to view detailed information.</source>
+ <translation>Vælg en anden knude for at se detaljeret information.</translation>
+ </message>
+ <message>
+ <source>Direction</source>
+ <translation>Retning</translation>
+ </message>
+ <message>
+ <source>Version</source>
+ <translation>Version</translation>
+ </message>
+ <message>
+ <source>User Agent</source>
+ <translation>Brugeragent</translation>
+ </message>
+ <message>
+ <source>Services</source>
+ <translation>Tjenester</translation>
+ </message>
+ <message>
+ <source>Starting Height</source>
+ <translation>Starthøjde</translation>
+ </message>
+ <message>
+ <source>Sync Height</source>
+ <translation>Synkroniseringshøjde</translation>
+ </message>
+ <message>
+ <source>Ban Score</source>
+ <translation>Bandlysningsscore</translation>
+ </message>
+ <message>
+ <source>Connection Time</source>
+ <translation>Forbindelsestid</translation>
+ </message>
+ <message>
+ <source>Last Send</source>
+ <translation>Seneste afsendelse</translation>
+ </message>
+ <message>
+ <source>Last Receive</source>
+ <translation>Seneste modtagelse</translation>
+ </message>
+ <message>
+ <source>Bytes Sent</source>
+ <translation>Byte sendt</translation>
+ </message>
+ <message>
+ <source>Bytes Received</source>
+ <translation>Byte modtaget</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Ping-tid</translation>
+ </message>
+ <message>
+ <source>Time Offset</source>
+ <translation>Tidsforskydning</translation>
+ </message>
+ <message>
+ <source>Last block time</source>
+ <translation>Tidsstempel for seneste blok</translation>
+ </message>
+ <message>
+ <source>&amp;Open</source>
+ <translation>&amp;Åbn</translation>
+ </message>
+ <message>
+ <source>&amp;Console</source>
+ <translation>&amp;Konsol</translation>
+ </message>
+ <message>
+ <source>&amp;Network Traffic</source>
+ <translation>&amp;Netværkstrafik</translation>
+ </message>
+ <message>
+ <source>&amp;Clear</source>
+ <translation>&amp;Ryd</translation>
+ </message>
+ <message>
+ <source>Totals</source>
+ <translation>Totaler</translation>
+ </message>
+ <message>
+ <source>In:</source>
+ <translation>Indkommende:</translation>
+ </message>
+ <message>
+ <source>Out:</source>
+ <translation>Udgående:</translation>
+ </message>
+ <message>
+ <source>Build date</source>
+ <translation>Byggedato</translation>
+ </message>
+ <message>
+ <source>Debug log file</source>
+ <translation>Fejlsøgningslogfil</translation>
+ </message>
+ <message>
+ <source>Clear console</source>
+ <translation>Ryd konsol</translation>
+ </message>
+ <message>
+ <source>Welcome to the Bitcoin Core RPC console.</source>
+ <translation>Velkommen til Bitcoin Cores RPC-konsol.</translation>
+ </message>
+ <message>
+ <source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
+ <translation>Brug op- og ned-piletasterne til at navigere i historikken og &lt;b&gt;Ctrl-L&lt;/b&gt; til at rydde skærmen.</translation>
+ </message>
+ <message>
+ <source>Type &lt;b&gt;help&lt;/b&gt; for an overview of available commands.</source>
+ <translation>Tast &lt;b&gt;help&lt;/b&gt; for en oversigt over de tilgængelige kommandoer.</translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation>%1 B</translation>
+ </message>
+ <message>
+ <source>%1 KB</source>
+ <translation>%1 KB</translation>
+ </message>
+ <message>
+ <source>%1 MB</source>
+ <translation>%1 MB</translation>
+ </message>
+ <message>
+ <source>%1 GB</source>
+ <translation>%1 GB</translation>
+ </message>
+ <message>
+ <source>via %1</source>
+ <translation>via %1</translation>
+ </message>
+ <message>
+ <source>never</source>
+ <translation>aldrig</translation>
+ </message>
+ <message>
+ <source>Inbound</source>
+ <translation>Indkommende</translation>
+ </message>
+ <message>
+ <source>Outbound</source>
+ <translation>Udgående</translation>
+ </message>
+ <message>
+ <source>Unknown</source>
+ <translation>Ukendt</translation>
+ </message>
+ <message>
+ <source>Fetching...</source>
+ <translation>Henter…</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Amount:</source>
+ <translation>&amp;Beløb:</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Mærkat:</translation>
+ </message>
+ <message>
+ <source>&amp;Message:</source>
+ <translation>&amp;Besked:</translation>
+ </message>
+ <message>
+ <source>Reuse one of the previously used receiving addresses. Reusing addresses has security and privacy issues. Do not use this unless re-generating a payment request made before.</source>
+ <translation>Genbrug en af de tidligere brugte modtagelsesadresser. Genbrug af adresser har indflydelse på sikkerhed og privatliv. Brug ikke dette med mindre du genskaber en betalingsanmodning fra tidligere.</translation>
+ </message>
+ <message>
+ <source>R&amp;euse an existing receiving address (not recommended)</source>
+ <translation>&amp;Genbrug en eksisterende modtagelsesadresse (anbefales ikke)</translation>
+ </message>
+ <message>
+ <source>An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network.</source>
+ <translation>En valgfri besked, der føjes til betalingsanmodningen, og som vil vises, når anmodningen åbnes. Bemærk: Beskeden vil ikke sendes sammen med betalingen over Bitcoin-netværket.</translation>
+ </message>
+ <message>
+ <source>An optional label to associate with the new receiving address.</source>
+ <translation>Et valgfrit mærkat, der associeres med den nye modtagelsesadresse.</translation>
+ </message>
+ <message>
+ <source>Use this form to request payments. All fields are &lt;b&gt;optional&lt;/b&gt;.</source>
+ <translation>Brug denne formular for at anmode om betalinger. Alle felter er &lt;b&gt;valgfri&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>An optional amount to request. Leave this empty or zero to not request a specific amount.</source>
+ <translation>Et valgfrit beløb til anmodning. Lad dette felt være tomt eller indeholde nul for at anmode om et ikke-specifikt beløb.</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Ryd alle felter af formen.</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation>Ryd</translation>
+ </message>
+ <message>
+ <source>Requested payments history</source>
+ <translation>Historik over betalingsanmodninger</translation>
+ </message>
+ <message>
+ <source>&amp;Request payment</source>
+ <translation>&amp;Anmod om betaling</translation>
+ </message>
+ <message>
+ <source>Show the selected request (does the same as double clicking an entry)</source>
+ <translation>Vis den valgte anmodning (gør det samme som dobbeltklik på en indgang)</translation>
+ </message>
+ <message>
+ <source>Show</source>
+ <translation>Vis</translation>
+ </message>
+ <message>
+ <source>Remove the selected entries from the list</source>
+ <translation>Fjern de valgte indgange fra listen</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>Fjern</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Kopiér mærkat</translation>
+ </message>
+ <message>
+ <source>Copy message</source>
+ <translation>Kopiér besked</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopier beløb</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>QR Code</source>
+ <translation>QR-kode</translation>
+ </message>
+ <message>
+ <source>Copy &amp;URI</source>
+ <translation>Kopiér &amp;URI</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Address</source>
+ <translation>Kopiér &amp;adresse</translation>
+ </message>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Gem billede…</translation>
+ </message>
+ <message>
+ <source>Request payment to %1</source>
+ <translation>Anmod om betaling til %1</translation>
+ </message>
+ <message>
+ <source>Payment information</source>
+ <translation>Betalingsinformation</translation>
+ </message>
+ <message>
+ <source>URI</source>
+ <translation>URI</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adresse</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Beløb</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Mærkat</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Besked</translation>
+ </message>
+ <message>
+ <source>Resulting URI too long, try to reduce the text for label / message.</source>
+ <translation>Resulterende URI var for lang; prøv at forkorte teksten til mærkaten/beskeden.</translation>
+ </message>
+ <message>
+ <source>Error encoding URI into QR Code.</source>
+ <translation>Fejl ved kodning fra URI til QR-kode.</translation>
+ </message>
+</context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Dato</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Mærkat</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Besked</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Beløb</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(ingen mærkat)</translation>
+ </message>
+ <message>
+ <source>(no message)</source>
+ <translation>(ingen besked)</translation>
+ </message>
+ <message>
+ <source>(no amount)</source>
+ <translation>(intet beløb)</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Send bitcoins</translation>
+ </message>
+ <message>
+ <source>Coin Control Features</source>
+ <translation>Egenskaber for coin-styring</translation>
+ </message>
+ <message>
+ <source>Inputs...</source>
+ <translation>Inputs…</translation>
+ </message>
+ <message>
+ <source>automatically selected</source>
+ <translation>valgt automatisk</translation>
+ </message>
+ <message>
+ <source>Insufficient funds!</source>
+ <translation>Utilstrækkelige midler!</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Mængde:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Byte:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Beløb:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Prioritet:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Gebyr:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Efter gebyr:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Byttepenge:</translation>
+ </message>
+ <message>
+ <source>If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address.</source>
+ <translation>Hvis dette aktiveres, men byttepengeadressen er tom eller ugyldig, vil byttepenge blive sendt til en nygenereret adresse.</translation>
+ </message>
+ <message>
+ <source>Custom change address</source>
+ <translation>Tilpasset byttepengeadresse</translation>
+ </message>
+ <message>
+ <source>Transaction Fee:</source>
+ <translation>Transaktionsgebyr:</translation>
+ </message>
+ <message>
+ <source>Choose...</source>
+ <translation>Vælg…</translation>
+ </message>
+ <message>
+ <source>collapse fee-settings</source>
+ <translation>sammenfold gebyropsætning</translation>
+ </message>
+ <message>
+ <source>per kilobyte</source>
+ <translation>pr. kilobyte</translation>
+ </message>
+ <message>
+ <source>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "total at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source>
+ <translation>Hvis det brugertilpassede gebyr er sat til 1000 satoshis, og transaktionen kun fylder 250 byte, betaler "pr. kilobyte" kun 250 satoshis i gebyr, mens "total mindst" betaler 1000 satoshis. For transaktioner større end en kilobyte betaler begge pr. kilobyte.</translation>
+ </message>
+ <message>
+ <source>Hide</source>
+ <translation>Skjul</translation>
+ </message>
+ <message>
+ <source>total at least</source>
+ <translation>total mindst</translation>
+ </message>
+ <message>
+ <source>Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process.</source>
+ <translation>Det er helt fint kun at betale det minimale gebyr, så længe den totale transaktionsvolumen er mindre end den plads, der er tilgængelig i blokkene. Men vær opmærksom på, at dette kan ende ud i transaktioner, der aldrig bliver bekræftet, når der bliver større forespørgsel efter bitcoin-transaktioner, end hvad netværket kan bearbejde.</translation>
+ </message>
+ <message>
+ <source>(read the tooltip)</source>
+ <translation>(læs værktøjstippet)</translation>
+ </message>
+ <message>
+ <source>Recommended:</source>
+ <translation>Anbefalet:</translation>
+ </message>
+ <message>
+ <source>Custom:</source>
+ <translation>Brugertilpasset:</translation>
+ </message>
+ <message>
+ <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source>
+ <translation>(Smart-gebyr er ikke initialiseret endnu. Dette tager typisk nogle få blokke…)</translation>
+ </message>
+ <message>
+ <source>Confirmation time:</source>
+ <translation>Bekræftelsestid:</translation>
+ </message>
+ <message>
+ <source>normal</source>
+ <translation>normal</translation>
+ </message>
+ <message>
+ <source>fast</source>
+ <translation>hurtig</translation>
+ </message>
+ <message>
+ <source>Send as zero-fee transaction if possible</source>
+ <translation>Send som nul-gebyr-transaktion hvis muligt</translation>
+ </message>
+ <message>
+ <source>(confirmation may take longer)</source>
+ <translation>(bekræftelse kan tage længere)</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>Send til flere modtagere på en gang</translation>
+ </message>
+ <message>
+ <source>Add &amp;Recipient</source>
+ <translation>Tilføj &amp;modtager</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Ryd alle felter af formen.</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Støv:</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Ryd &amp;alle</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>Saldo:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>Bekræft afsendelsen</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>&amp;Afsend</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>Bekræft afsendelse af bitcoins</translation>
+ </message>
+ <message>
+ <source>%1 to %2</source>
+ <translation>%1 til %2</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Kopiér mængde</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopier beløb</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Kopiér gebyr</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Kopiér efter-gebyr</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Kopiér byte</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Kopiér prioritet</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Kopiér byttepenge</translation>
+ </message>
+ <message>
+ <source>or</source>
+ <translation>eller</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>Beløbet til betaling skal være større end 0.</translation>
+ </message>
+ <message>
+ <source>The amount exceeds your balance.</source>
+ <translation>Beløbet overstiger din saldo.</translation>
+ </message>
+ <message>
+ <source>The total exceeds your balance when the %1 transaction fee is included.</source>
+ <translation>Totalen overstiger din saldo, når transaktionsgebyret på %1 er inkluderet.</translation>
+ </message>
+ <message>
+ <source>Transaction creation failed!</source>
+ <translation>Oprettelse af transaktion mislykkedes!</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>Transaktionen blev afvist! Dette kan ske, hvis nogle af dine bitcoins i din tegnebog allerede er brugt, som hvis du brugte en kopi af wallet.dat og dine bitcoins er blevet brugt i kopien, men ikke er markeret som brugt her.</translation>
+ </message>
+ <message>
+ <source>A fee higher than %1 is considered an absurdly high fee.</source>
+ <translation>Et gebyr højere end %1 opfattes som et absurd højt gebyr.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>Betalingsanmodning er udløbet.</translation>
+ </message>
+ <message numerus="yes">
+ <source>Estimated to begin confirmation within %n block(s).</source>
+ <translation><numerusform>Bekræftelse estimeres til at begynde inden for %n blok.</numerusform><numerusform>Bekræftelse estimeres til at begynde inden for %n blokke.</numerusform></translation>
+ </message>
+ <message>
+ <source>Pay only the minimum fee of %1</source>
+ <translation>Betal kun det minimale gebyr på %1</translation>
+ </message>
+ <message>
+ <source>Total Amount %1&lt;span style='font-size:10pt;font-weight:normal;'&gt;&lt;br /&gt;(=%2)&lt;/span&gt;</source>
+ <translation>Totalbeløb %1&lt;span style='font-size:10pt;font-weight:normal;'&gt;&lt;br /&gt;(=%2)&lt;/span&gt;</translation>
+ </message>
+ <message>
+ <source>The recipient address is not valid. Please recheck.</source>
+ <translation>Modtageradressen er ikke gyldig. Tjek venligst igen.</translation>
+ </message>
+ <message>
+ <source>Duplicate address found: addresses should only be used once each.</source>
+ <translation>Adressegenganger fundet. Adresser bør kun bruges én gang hver.</translation>
+ </message>
+ <message>
+ <source>Warning: Invalid Bitcoin address</source>
+ <translation>Advarsel: Ugyldig Bitcoin-adresse</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(ingen mærkat)</translation>
+ </message>
+ <message>
+ <source>Warning: Unknown change address</source>
+ <translation>Advarsel: Ukendt byttepengeadresse</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Kopiér støv</translation>
+ </message>
+ <message>
+ <source>Are you sure you want to send?</source>
+ <translation>Er du sikker på, at du vil sende?</translation>
+ </message>
+ <message>
+ <source>added as transaction fee</source>
+ <translation>tilføjet som transaktionsgebyr</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>&amp;Beløb:</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>Betal &amp;til:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Indtast en mærkat for denne adresse for at føje den til din adressebog</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Mærkat:</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Vælg tidligere brugt adresse</translation>
+ </message>
+ <message>
+ <source>This is a normal payment.</source>
+ <translation>Dette er en normal betaling.</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to send the payment to</source>
+ <translation>Bitcoin-adresse, som betalingen skal sendes til</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Indsæt adresse fra udklipsholderen</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Remove this entry</source>
+ <translation>Fjern denne indgang</translation>
+ </message>
+ <message>
+ <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source>
+ <translation>Gebyret vil blive trukket fra det sendte beløb. Modtageren vil modtage færre bitcoin, end du indtaster i beløbfeltet. Hvis flere modtagere vælges, vil gebyret deles ligeligt.</translation>
+ </message>
+ <message>
+ <source>S&amp;ubtract fee from amount</source>
+ <translation>&amp;Træk gebyr fra beløb</translation>
+ </message>
+ <message>
+ <source>Message:</source>
+ <translation>Besked:</translation>
+ </message>
+ <message>
+ <source>This is an unauthenticated payment request.</source>
+ <translation>Dette er en uautentificeret betalingsanmodning.</translation>
+ </message>
+ <message>
+ <source>This is an authenticated payment request.</source>
+ <translation>Dette er en autentificeret betalingsanmodning.</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to the list of used addresses</source>
+ <translation>Indtast et mærkat for denne adresse for at føje den til listen over brugte adresser</translation>
+ </message>
+ <message>
+ <source>A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network.</source>
+ <translation>En besked, som blev føjet til "bitcon:"-URI'en, som vil gemmes med transaktionen til din reference. Bemærk: Denne besked vil ikke blive sendt over Bitcoin-netværket.</translation>
+ </message>
+ <message>
+ <source>Pay To:</source>
+ <translation>Betal til:</translation>
+ </message>
+ <message>
+ <source>Memo:</source>
+ <translation>Memo:</translation>
+ </message>
+</context>
+<context>
+ <name>ShutdownWindow</name>
+ <message>
+ <source>Bitcoin Core is shutting down...</source>
+ <translation>Bitcoin Core lukker ned…</translation>
+ </message>
+ <message>
+ <source>Do not shut down the computer until this window disappears.</source>
+ <translation>Luk ikke computeren ned, før dette vindue forsvinder.</translation>
+ </message>
+</context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Signatures - Sign / Verify a Message</source>
+ <translation>Signature - Underskriv/verificér en besked</translation>
+ </message>
+ <message>
+ <source>&amp;Sign Message</source>
+ <translation>&amp;Underskriv besked</translation>
+ </message>
+ <message>
+ <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source>
+ <translation>Du kan signere beskeder/aftaler med dine adresser for at bevise, at du kan modtage bitcoin, der bliver sendt til adresserne. Vær forsigtig med ikke at signere noget vagt eller tilfældigt, da eventuelle phishing-angreb kan snyde dig til at overlade din identitet til dem. Signér kun fuldt ud detaljerede udsagn, som du er enig i.</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to sign the message with</source>
+ <translation>Bitcoin-adresse, som beskeden skal signeres med</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Vælg tidligere brugt adresse</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Indsæt adresse fra udklipsholderen</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Enter the message you want to sign here</source>
+ <translation>Indtast her beskeden, du ønsker at underskrive</translation>
+ </message>
+ <message>
+ <source>Signature</source>
+ <translation>Underskrift</translation>
+ </message>
+ <message>
+ <source>Copy the current signature to the system clipboard</source>
+ <translation>Kopiér den nuværende underskrift til systemets udklipsholder</translation>
+ </message>
+ <message>
+ <source>Sign the message to prove you own this Bitcoin address</source>
+ <translation>Underskriv denne besked for at bevise, at Bitcoin-adressen tilhører dig</translation>
+ </message>
+ <message>
+ <source>Sign &amp;Message</source>
+ <translation>Underskriv &amp;besked</translation>
+ </message>
+ <message>
+ <source>Reset all sign message fields</source>
+ <translation>Nulstil alle "underskriv besked"-felter</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Ryd &amp;alle</translation>
+ </message>
+ <message>
+ <source>&amp;Verify Message</source>
+ <translation>&amp;Verificér besked</translation>
+ </message>
+ <message>
+ <source>Enter the receiver's 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. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source>
+ <translation>Indtast modtagerens adresse, besked (vær sikker på at kopiere linjeskift, mellemrum, tabuleringer, etc. præcist) og signatur herunder for at verificere beskeden. Vær forsigtig med ikke at læse noget ud fra signaturen, som ikke står i selve beskeden, for at undgå at blive snydt af et eventuelt man-in-the-middle-angreb. Bemærk, at dette kun beviser, at den signerende person kan modtage med adressen; det kan ikke bevise hvem der har sendt en given transaktion!</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address the message was signed with</source>
+ <translation>Bitcoin-adressen, som beskeden blev signeret med</translation>
+ </message>
+ <message>
+ <source>Verify the message to ensure it was signed with the specified Bitcoin address</source>
+ <translation>Verificér beskeden for at sikre, at den er underskrevet med den angivne Bitcoin-adresse</translation>
+ </message>
+ <message>
+ <source>Verify &amp;Message</source>
+ <translation>Verificér &amp;besked</translation>
+ </message>
+ <message>
+ <source>Reset all verify message fields</source>
+ <translation>Nulstil alle "verificér besked"-felter</translation>
+ </message>
+ <message>
+ <source>Click "Sign Message" to generate signature</source>
+ <translation>Klik "Underskriv besked" for at generere underskriften</translation>
+ </message>
+ <message>
+ <source>The entered address is invalid.</source>
+ <translation>Den indtastede adresse er ugyldig.</translation>
+ </message>
+ <message>
+ <source>Please check the address and try again.</source>
+ <translation>Tjek venligst adressen og forsøg igen.</translation>
+ </message>
+ <message>
+ <source>The entered address does not refer to a key.</source>
+ <translation>Den indtastede adresse henviser ikke til en nøgle.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock was cancelled.</source>
+ <translation>Tegnebogsoplåsning annulleret.</translation>
+ </message>
+ <message>
+ <source>Private key for the entered address is not available.</source>
+ <translation>Den private nøgle for den indtastede adresse er ikke tilgængelig.</translation>
+ </message>
+ <message>
+ <source>Message signing failed.</source>
+ <translation>Underskrivning af besked mislykkedes.</translation>
+ </message>
+ <message>
+ <source>Message signed.</source>
+ <translation>Besked underskrevet.</translation>
+ </message>
+ <message>
+ <source>The signature could not be decoded.</source>
+ <translation>Underskriften kunne ikke afkodes.</translation>
+ </message>
+ <message>
+ <source>Please check the signature and try again.</source>
+ <translation>Tjek venligst underskriften, og forsøg igen.</translation>
+ </message>
+ <message>
+ <source>The signature did not match the message digest.</source>
+ <translation>Underskriften matcher ikke beskedens indhold.</translation>
+ </message>
+ <message>
+ <source>Message verification failed.</source>
+ <translation>Verificering af besked mislykkedes.</translation>
+ </message>
+ <message>
+ <source>Message verified.</source>
+ <translation>Besked verificeret.</translation>
+ </message>
+</context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>The Bitcoin Core developers</source>
+ <translation>Udviklerne af Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>[testnet]</source>
+ <translation>[testnetværk]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ <message>
+ <source>KB/s</source>
+ <translation>KB/s</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>Åben indtil %1</translation>
+ </message>
+ <message>
+ <source>conflicted</source>
+ <translation>konflikt</translation>
+ </message>
+ <message>
+ <source>%1/offline</source>
+ <translation>%1/offline</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/ubekræftet</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 bekræftelser</translation>
+ </message>
+ <message>
+ <source>Status</source>
+ <translation>Status</translation>
+ </message>
+ <message numerus="yes">
+ <source>, broadcast through %n node(s)</source>
+ <translation><numerusform>, transmitteret igennem %n knude</numerusform><numerusform>, transmitteret igennem %n knuder</numerusform></translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Dato</translation>
+ </message>
+ <message>
+ <source>Source</source>
+ <translation>Kilde</translation>
+ </message>
+ <message>
+ <source>Generated</source>
+ <translation>Genereret</translation>
+ </message>
+ <message>
+ <source>From</source>
+ <translation>Fra</translation>
+ </message>
+ <message>
+ <source>To</source>
+ <translation>Til</translation>
+ </message>
+ <message>
+ <source>own address</source>
+ <translation>egen adresse</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>kigge</translation>
+ </message>
+ <message>
+ <source>label</source>
+ <translation>mærkat</translation>
+ </message>
+ <message>
+ <source>Credit</source>
+ <translation>Kredit</translation>
+ </message>
+ <message numerus="yes">
+ <source>matures in %n more block(s)</source>
+ <translation><numerusform>modner efter yderligere %n blok</numerusform><numerusform>modner efter yderligere %n blokke</numerusform></translation>
+ </message>
+ <message>
+ <source>not accepted</source>
+ <translation>ikke accepteret</translation>
+ </message>
+ <message>
+ <source>Debit</source>
+ <translation>Debet</translation>
+ </message>
+ <message>
+ <source>Total debit</source>
+ <translation>Total debet</translation>
+ </message>
+ <message>
+ <source>Total credit</source>
+ <translation>Total kredit</translation>
+ </message>
+ <message>
+ <source>Transaction fee</source>
+ <translation>Transaktionsgebyr</translation>
+ </message>
+ <message>
+ <source>Net amount</source>
+ <translation>Nettobeløb</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Besked</translation>
+ </message>
+ <message>
+ <source>Comment</source>
+ <translation>Kommentar</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>Transaktions-ID</translation>
+ </message>
+ <message>
+ <source>Merchant</source>
+ <translation>Forretningsdrivende</translation>
+ </message>
+ <message>
+ <source>Generated coins must mature %1 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.</source>
+ <translation>Minede bitcoins skal modne %1 blokke, før de kan bruges. Da du genererede denne blok, blev den transmitteret til netværket for at blive føjet til blokkæden. Hvis det ikke lykkes at få den i kæden, vil dens tilstand ændres til "ikke accepteret", og den vil ikke kunne bruges. Dette kan ske nu og da, hvis en anden knude udvinder en blok inden for nogle få sekunder fra din.</translation>
+ </message>
+ <message>
+ <source>Debug information</source>
+ <translation>Fejlsøgningsinformation</translation>
+ </message>
+ <message>
+ <source>Transaction</source>
+ <translation>Transaktion</translation>
+ </message>
+ <message>
+ <source>Inputs</source>
+ <translation>Input</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Beløb</translation>
+ </message>
+ <message>
+ <source>true</source>
+ <translation>sand</translation>
+ </message>
+ <message>
+ <source>false</source>
+ <translation>falsk</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, er ikke blevet transmitteret endnu</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Åbn yderligere %n blok</numerusform><numerusform>Åbn yderligere %n blokke</numerusform></translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>ukendt</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>Transaktionsdetaljer</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>Denne rude viser en detaljeret beskrivelse af transaktionen</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Dato</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Type</translation>
+ </message>
+ <message>
+ <source>Immature (%1 confirmations, will be available after %2)</source>
+ <translation>Umoden (%1 bekræftelser; vil være tilgængelig efter %2)</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Åbn yderligere %n blok</numerusform><numerusform>Åbn yderligere %n blokke</numerusform></translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>Åben indtil %1</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>Bekræftet (%1 bekræftelser)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>Denne blok blev ikke modtaget af nogen andre knuder og vil formentlig ikke blive accepteret!</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>Genereret, men ikke accepteret</translation>
+ </message>
+ <message>
+ <source>Offline</source>
+ <translation>Offline</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Mærkat</translation>
+ </message>
+ <message>
+ <source>Unconfirmed</source>
+ <translation>Ubekræftet</translation>
+ </message>
+ <message>
+ <source>Confirming (%1 of %2 recommended confirmations)</source>
+ <translation>Bekræfter (%1 af %2 anbefalede bekræftelser)</translation>
+ </message>
+ <message>
+ <source>Conflicted</source>
+ <translation>Konflikt</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Modtaget med</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>Modtaget fra</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Sendt til</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>Betaling til dig selv</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Minet</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>kigge</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(n/a)</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>Transaktionsstatus. Hold musen over dette felt for at vise antallet af bekræftelser.</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Dato og klokkeslæt for modtagelse af transaktionen.</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>Transaktionstype.</translation>
+ </message>
+ <message>
+ <source>Whether or not a watch-only address is involved in this transaction.</source>
+ <translation>Afgør hvorvidt en kigge-adresse er involveret i denne transaktion.</translation>
+ </message>
+ <message>
+ <source>User-defined intent/purpose of the transaction.</source>
+ <translation>Brugerdefineret hensigt/formål med transaktionen.</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>Beløb trukket fra eller tilføjet balance.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>Alle</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>I dag</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>Denne uge</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>Denne måned</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>Sidste måned</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>Dette år</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>Interval…</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Modtaget med</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Sendt til</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>Til dig selv</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Minet</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>Andet</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>Indtast adresse eller mærkat for at søge</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>Minimumsbeløb</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Kopiér adresse</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Kopiér mærkat</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopiér beløb</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Kopiér transaktions-ID</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>Redigér mærkat</translation>
+ </message>
+ <message>
+ <source>Show transaction details</source>
+ <translation>Vis transaktionsdetaljer</translation>
+ </message>
+ <message>
+ <source>Export Transaction History</source>
+ <translation>Historik for eksport af transaktioner</translation>
+ </message>
+ <message>
+ <source>Watch-only</source>
+ <translation>Kigge</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Eksport mislykkedes</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the transaction history to %1.</source>
+ <translation>En fejl opstod under gemning af transaktionshistorik til %1.</translation>
+ </message>
+ <message>
+ <source>Exporting Successful</source>
+ <translation>Eksport problemfri</translation>
+ </message>
+ <message>
+ <source>The transaction history was successfully saved to %1.</source>
+ <translation>Transaktionshistorikken blev gemt til %1 med succes.</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Kommasepareret fil (*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Bekræftet</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Dato</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Type</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Mærkat</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adresse</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>Interval:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>til</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ <message>
+ <source>Unit to show amounts in. Click to select another unit.</source>
+ <translation>Enhed, som beløb vises i. Klik for at vælge en anden enhed.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletFrame</name>
+ <message>
+ <source>No wallet has been loaded.</source>
+ <translation>Ingen tegnebog er indlæst.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Send bitcoins</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Eksportér</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Eksportér den aktuelle visning til en fil</translation>
+ </message>
+ <message>
+ <source>Backup Wallet</source>
+ <translation>Sikkerhedskopiér tegnebog</translation>
+ </message>
+ <message>
+ <source>Wallet Data (*.dat)</source>
+ <translation>Tegnebogsdata (*.dat)</translation>
+ </message>
+ <message>
+ <source>Backup Failed</source>
+ <translation>Sikkerhedskopiering mislykkedes</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the wallet data to %1.</source>
+ <translation>Der skete en fejl under gemning af tegnebogsdata til %1.</translation>
+ </message>
+ <message>
+ <source>The wallet data was successfully saved to %1.</source>
+ <translation>Tegnebogsdata blev gemt til %1 med succes.</translation>
+ </message>
+ <message>
+ <source>Backup Successful</source>
+ <translation>Sikkerhedskopiering problemfri</translation>
+ </message>
+</context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>Indstillinger:</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>Angiv datamappe</translation>
+ </message>
+ <message>
+ <source>Connect to a node to retrieve peer addresses, and disconnect</source>
+ <translation>Forbind til en knude for at modtage adresser på andre knuder, og afbryd derefter</translation>
+ </message>
+ <message>
+ <source>Specify your own public address</source>
+ <translation>Angiv din egen offentlige adresse</translation>
+ </message>
+ <message>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>Acceptér kommandolinje- og JSON-RPC-kommandoer</translation>
+ </message>
+ <message>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>Kør i baggrunden som en service, og acceptér kommandoer</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>Brug testnetværket</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
+ <translation>Acceptér forbindelser udefra (standard: 1 hvis hverken -proxy eller -connect)</translation>
+ </message>
+ <message>
+ <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
+ <translation>Tildel til den givne adresse og lyt altid på den. Brug [vært]:port-notation for IPv6</translation>
+ </message>
+ <message>
+ <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
+ <translation>Slet alle transaktioner i tegnebogen og genskab kun disse dele af blokkæden gennem -rescan under opstart</translation>
+ </message>
+ <message>
+ <source>Distributed under the MIT software license, see the accompanying file COPYING or &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</source>
+ <translation>Distribueret under MIT-softwarelicensen; se den vedlagte fil COPYING eller &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</translation>
+ </message>
+ <message>
+ <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
+ <translation>Udfør kommando, når en transaktion i tegnebogen ændres (%s i kommandoen erstattes med TxID)</translation>
+ </message>
+ <message>
+ <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source>
+ <translation>Maksimalt totalt gebyr der kan bruges i en enkelt tegnebogstransaktion. For lav en værdi kan afbryde store transaktioner (standard: %s)</translation>
+ </message>
+ <message>
+ <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, &gt;%u = target size in MiB to use for block files)</source>
+ <translation>Reducér pladskravene ved at beskære (slette, "prune") gamle blokke. Denne tilstand slår understøttelse af tegnebogen fra og er ikke kompatibel med -txindex. Advarsel: Fortrydelse af denne indstilling kræver download af hele blokkæden igen. (standard: 0 = slå beskæring af blokke fra, &gt;%u = målstørrelse i MiB der skal bruges til blokfiler)</translation>
+ </message>
+ <message>
+ <source>Set the number of script verification threads (%u to %d, 0 = auto, &lt;0 = leave that many cores free, default: %d)</source>
+ <translation>Sæt antallet af scriptverificeringstråde (%u til %d, 0 = auto, &lt;0 = efterlad det antal kernet fri, standard: %d)</translation>
+ </message>
+ <message>
+ <source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source>
+ <translation>Dette er en foreløbig testudgivelse - brug på eget ansvar - brug ikke til udvinding eller handelsprogrammer</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer. Bitcoin Core is probably already running.</source>
+ <translation>Ikke i stand til at tildele til %s på denne computer. Bitcoin Core kører sansynligvis allerede.</translation>
+ </message>
+ <message>
+ <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>ADVARSEL: unormalt mange blokke er genereret; %d blokke er modtaget i løbet af de seneste %d timer (%d forventet)</translation>
+ </message>
+ <message>
+ <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>ADVARSEL: tjek din netværksforbindelse; %d blokke er modtaget i løbet af de seneste %d timer (%d forventet)</translation>
+ </message>
+ <message>
+ <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>Advarsel: -paytxfee er sat meget højt! Dette er det gebyr du vil betale, hvis du sender en transaktion.</translation>
+ </message>
+ <message>
+ <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source>
+ <translation>Advarsel: Netværket ser ikke ud til at være fuldt ud enige! Enkelte minere ser ud til at opleve problemer.</translation>
+ </message>
+ <message>
+ <source>Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.</source>
+ <translation>Advarsel: Vi ser ikke ud til at være fuldt ud enige med andre knuder! Du kan være nødt til at opgradere, eller andre knuder kan være nødt til at opgradere.</translation>
+ </message>
+ <message>
+ <source>Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
+ <translation>Advarsel: fejl under læsning af wallet.dat! Alle nøgler blev læst korrekt, men transaktionsdata eller adressebogsposter kan mangle eller være forkerte.</translation>
+ </message>
+ <message>
+ <source>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</source>
+ <translation>Advarsel: wallet.dat ødelagt, data reddet! Oprindelig wallet.dat gemt som wallet.{timestamp}.bak i %s; hvis din saldo eller dine transaktioner er forkert, bør du genskabe fra en sikkerhedskopi.</translation>
+ </message>
+ <message>
+ <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source>
+ <translation>Sæt andre knuder, der forbinder fra den angivne netmaske eller IP, på hvidliste. Kan angives flere gange.</translation>
+ </message>
+ <message>
+ <source>(default: 1)</source>
+ <translation>(standard: 1)</translation>
+ </message>
+ <message>
+ <source>&lt;category&gt; can be:</source>
+ <translation>&lt;kategori&gt; kan være:</translation>
+ </message>
+ <message>
+ <source>Attempt to recover private keys from a corrupt wallet.dat</source>
+ <translation>Forsøg at genskabe private nøgler fra ødelagt wallet.dat</translation>
+ </message>
+ <message>
+ <source>Block creation options:</source>
+ <translation>Blokoprettelsestilvalg:</translation>
+ </message>
+ <message>
+ <source>Connect only to the specified node(s)</source>
+ <translation>Tilslut kun til de(n) angivne knude(r)</translation>
+ </message>
+ <message>
+ <source>Connection options:</source>
+ <translation>Tilvalg for forbindelser:</translation>
+ </message>
+ <message>
+ <source>Corrupted block database detected</source>
+ <translation>Ødelagt blokdatabase opdaget</translation>
+ </message>
+ <message>
+ <source>Debugging/Testing options:</source>
+ <translation>Tilvalg for fejlfinding/test:</translation>
+ </message>
+ <message>
+ <source>Do not load the wallet and disable wallet RPC calls</source>
+ <translation>Indlæs ikke tegnebogen og slå tegnebogs-RPC-kald fra</translation>
+ </message>
+ <message>
+ <source>Do you want to rebuild the block database now?</source>
+ <translation>Ønsker du at genopbygge blokdatabasen nu?</translation>
+ </message>
+ <message>
+ <source>Error initializing block database</source>
+ <translation>Klargøring af blokdatabase mislykkedes</translation>
+ </message>
+ <message>
+ <source>Error initializing wallet database environment %s!</source>
+ <translation>Klargøring af tegnebogsdatabasemiljøet %s mislykkedes!</translation>
+ </message>
+ <message>
+ <source>Error loading block database</source>
+ <translation>Indlæsning af blokdatabase mislykkedes</translation>
+ </message>
+ <message>
+ <source>Error opening block database</source>
+ <translation>Åbning af blokdatabase mislykkedes</translation>
+ </message>
+ <message>
+ <source>Error: Disk space is low!</source>
+ <translation>Fejl: Mangel på ledig diskplads!</translation>
+ </message>
+ <message>
+ <source>Failed to listen on any port. Use -listen=0 if you want this.</source>
+ <translation>Lytning på enhver port mislykkedes. Brug -listen=0, hvis du ønsker dette.</translation>
+ </message>
+ <message>
+ <source>If &lt;category&gt; is not supplied, output all debugging information.</source>
+ <translation>Hvis &lt;kategori&gt; ikke angives, udskriv al fejlsøgningsinformation.</translation>
+ </message>
+ <message>
+ <source>Importing...</source>
+ <translation>Importerer…</translation>
+ </message>
+ <message>
+ <source>Incorrect or no genesis block found. Wrong datadir for network?</source>
+ <translation>Ukorrekt eller ingen tilblivelsesblok fundet. Forkert datamappe for netværk?</translation>
+ </message>
+ <message>
+ <source>Invalid -onion address: '%s'</source>
+ <translation>Ugyldig -onion adresse: "%s"</translation>
+ </message>
+ <message>
+ <source>Not enough file descriptors available.</source>
+ <translation>For få tilgængelige fildeskriptorer.</translation>
+ </message>
+ <message>
+ <source>Only connect to nodes in network &lt;net&gt; (ipv4, ipv6 or onion)</source>
+ <translation>Tilslut kun til knuder i netværk &lt;net&gt; (IPv4, IPv6 eller Onion)</translation>
+ </message>
+ <message>
+ <source>Prune cannot be configured with a negative value.</source>
+ <translation>Beskæring kan ikke opsættes med en negativ værdi.</translation>
+ </message>
+ <message>
+ <source>Prune mode is incompatible with -txindex.</source>
+ <translation>Beskæringstilstand er ikke kompatibel med -txindex.</translation>
+ </message>
+ <message>
+ <source>Set database cache size in megabytes (%d to %d, default: %d)</source>
+ <translation>Sæt cache-størrelse for database i megabytes (%d til %d; standard: %d)</translation>
+ </message>
+ <message>
+ <source>Set maximum block size in bytes (default: %d)</source>
+ <translation>Sæt maksimum blokstørrelse i byte (standard: %d)</translation>
+ </message>
+ <message>
+ <source>Specify wallet file (within data directory)</source>
+ <translation>Angiv tegnebogsfil (inden for datamappe)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: %u)</source>
+ <translation>Brug UPnP til at konfigurere den lyttende port (standard: %u)</translation>
+ </message>
+ <message>
+ <source>Verifying blocks...</source>
+ <translation>Verificerer blokke…</translation>
+ </message>
+ <message>
+ <source>Verifying wallet...</source>
+ <translation>Verificerer tegnebog…</translation>
+ </message>
+ <message>
+ <source>Wallet %s resides outside data directory %s</source>
+ <translation>Tegnebog %s findes uden for datamappe %s</translation>
+ </message>
+ <message>
+ <source>Wallet options:</source>
+ <translation>Tilvalg for tegnebog:</translation>
+ </message>
+ <message>
+ <source>Warning: This version is obsolete; upgrade required!</source>
+ <translation>Advarsel: Denne version er forældet; opgradering påkrævet!</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to change -txindex</source>
+ <translation>Du er nødt til at genopbygge databasen ved hjælp af -reindex for at ændre -txindex</translation>
+ </message>
+ <message>
+ <source>Imports blocks from external blk000??.dat file</source>
+ <translation>Importerer blokke fra ekstern blk000??.dat fil</translation>
+ </message>
+ <message>
+ <source>Allow JSON-RPC connections from specified source. Valid for &lt;ip&gt; are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times</source>
+ <translation>Tillad JSON-RPC-forbindelser fra angivet kilde. Gyldig for &lt;ip&gt; er en enkelt IP (fx 1.2.3.4), et netværk/netmaske (fx 1.2.3.4/255.255.255.0) eller et netværk/CIDR (fx 1.2.3.4/24). Dette tilvalg kan angives flere gange</translation>
+ </message>
+ <message>
+ <source>An error occurred while setting up the RPC address %s port %u for listening: %s</source>
+ <translation>Der opstod en fejl under opsætning af RPC-adresse %s port %u for lytning: %s</translation>
+ </message>
+ <message>
+ <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source>
+ <translation>Tildel given adresse og sæt andre knuder, der forbinder til den, på hvidliste. Brug [vært]:port notation for IPv6</translation>
+ </message>
+ <message>
+ <source>Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)</source>
+ <translation>Tildel til den givne adresse for at lytte efter JSON-RPC-forbindelser. Brug [vært]:port-notation for IPv6. Denne valgmulighed kan angives flere gange (standard: tildel til alle grænseflader)</translation>
+ </message>
+ <message>
+ <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source>
+ <translation>Kan ikke opnå en lås på datamappe %s. Bitcoin Core kører sansynligvis allerede.</translation>
+ </message>
+ <message>
+ <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
+ <translation>Opret nye filer med systemstandard for rettigheder i stedet for umask 077 (kun virksomt med tegnebogsfunktionalitet slået fra)</translation>
+ </message>
+ <message>
+ <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source>
+ <translation>Opdag egne IP-adresser (standard: 1 under lytning og ingen -externalip eller -proxy)</translation>
+ </message>
+ <message>
+ <source>Error: Listening for incoming connections failed (listen returned error %s)</source>
+ <translation>Fejl: Lytning efter indkommende forbindelser mislykkedes (lytning resultarede i fejl %s)</translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source>
+ <translation>Fejl: Ikke understøttet argument -socks blev fundet. Det er ikke muligt at angive SOCKS-version længere, da kun SOCKS5-proxier er understøttet.</translation>
+ </message>
+ <message>
+ <source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source>
+ <translation>Udfør kommando, når en relevant alarm modtages eller vi ser en virkelig lang udsplitning (%s i cmd erstattes af besked)</translation>
+ </message>
+ <message>
+ <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source>
+ <translation>Gebyrer (i BTC/Kb) mindre end dette opfattes som nulgebyr for videresendelse (standard: %s)</translation>
+ </message>
+ <message>
+ <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
+ <translation>Hvis paytxfee ikke er sat, inkluderes nok gebyr til at transaktioner begynder at blive bekræftet ingen for gennemsnitligt n blokke (standard: %u)</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)</source>
+ <translation>Ugyldigt beløb for -maxtxfee=&lt;beløb&gt;: "%s" (skal være på mindst minrelay-gebyret på %s for at undgå hængende transaktioner)</translation>
+ </message>
+ <message>
+ <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source>
+ <translation>Maksimal størrelse på data i transaktioner til dataoverførsel, som vi videresender og miner (standard: %u)</translation>
+ </message>
+ <message>
+ <source>Prune configured below the minimum of %d MB. Please use a higher number.</source>
+ <translation>Beskæring opsat under minimumsværdien %d MB. Brug venligst en højere værdi.</translation>
+ </message>
+ <message>
+ <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source>
+ <translation>Forespørgsel</translation>
+ </message>
+ <message>
+ <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source>
+ <translation>Brug tilfældige akkreditiver for hver proxy-forbindelse. Dette tillader strømisolation med Tor (standard: %u)</translation>
+ </message>
+ <message>
+ <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
+ <translation>Sæt maksimumstørrelse for højprioritet/lavgebyr-transaktioner i byte (standard: %d)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source>
+ <translation>Sæt antaller af tråde for coin-generering, hvis aktiveret (-1 = alle kerner, standard: %d)</translation>
+ </message>
+ <message>
+ <source>The transaction amount is too small to send after the fee has been deducted</source>
+ <translation>Transaktionsbeløbet er for lille til at sende, når gebyret er trukket fra</translation>
+ </message>
+ <message>
+ <source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit &lt;https://www.openssl.org/&gt; and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source>
+ <translation>Dette produkt indeholder software, der er udviklet af OpenSSL-projektet for brug i OpenSSL-værktøjskassen &lt;https://www.openssl.org/&gt;, samt kryptografisk software, der er skrevet af Eric Young, samt UPnP-software, der er skrevet af Thomas Bernard.</translation>
+ </message>
+ <message>
+ <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an 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)
+The username and password MUST NOT be the same.
+If the file does not exist, create it with owner-readable-only file permissions.
+It is also recommended to set alertnotify so you are notified of problems;
+for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
+</source>
+ <translation>For at bruge bitcoind eller valgmuligheden -server i bitcoin-qt skal du oprette et rpcpassword i konfigurationsfilen:
+%s
+Det anbefales, at du bruger følgende tilfældige adgangskode:
+rpcuser=bitcoinrpc
+rpcpassword=%s
+(du behøver ikke at huske adgangskoden)
+Brugernavnet og adgangskoden MÅ IKKE være det samme.
+Hvis filen ikke eksisterer, opret den da så kun ejeren har læserettigheder.
+Det anbefales også at sætte alertnotify, så du får besked omkring problemer;
+for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
+</translation>
+ </message>
+ <message>
+ <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source>
+ <translation>Advarsel: -maxtxfee er sat meget højt! Så store gebyrer kan betales på en enkelt transaktion.</translation>
+ </message>
+ <message>
+ <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source>
+ <translation>Advarsel: Undersøg venligst at din computers dato og klokkeslet er korrekt indstillet! Hvis der er fejl i disse vil Bitcoin Core ikke fungere korrekt.</translation>
+ </message>
+ <message>
+ <source>Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway</source>
+ <translation>Andre knuder på hvidliste kan ikke DoS-bandlyses, og deres transaktioner videresendes altid, selv hvis de allerede er i mempool'en. Brugbart til fx et adgangspunkt</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source>
+ <translation>Du er nødt til at genopbygge databasen ved hjælp af -reindex for at gå tilbage til ikke-beskåret tilstand. Dette vil downloade hele blokkæden igen</translation>
+ </message>
+ <message>
+ <source>(default: %u)</source>
+ <translation>(standard: %u)</translation>
+ </message>
+ <message>
+ <source>Accept public REST requests (default: %u)</source>
+ <translation>Acceptér offentlige REST-anmodninger (standard: %u)</translation>
+ </message>
+ <message>
+ <source>Activating best chain...</source>
+ <translation>Aktiverer bedste kæde…</translation>
+ </message>
+ <message>
+ <source>Can't run with a wallet in prune mode.</source>
+ <translation>Kan ikke køre med en tegnebog i beskåret tilstand.</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -whitebind address: '%s'</source>
+ <translation>Kan ikke løse -whitebind adresse: "%s"</translation>
+ </message>
+ <message>
+ <source>Choose data directory on startup (default: 0)</source>
+ <translation>Vælg datamappe ved opstart (standard: 0)</translation>
+ </message>
+ <message>
+ <source>Connect through SOCKS5 proxy</source>
+ <translation>Forbind gennem SOCKS5-proxy</translation>
+ </message>
+ <message>
+ <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source>
+ <translation>Ophavsret © 2009-%i Udviklerne af Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Could not parse -rpcbind value %s as network address</source>
+ <translation>Kunne ikke tolke -rpcbind-værdi %s som en netværksadresse</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source>
+ <translation>Fejl ved indlæsning af wallet.dat: Tegnebog kræver en nyere version af Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Error reading from database, shutting down.</source>
+ <translation>Fejl under læsning fra database; lukker ned.</translation>
+ </message>
+ <message>
+ <source>Error: A fatal internal error occurred, see debug.log for details</source>
+ <translation>Fejl: En alvorlig intern fejl er opstået. Se debug.log for detaljer</translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -tor found, use -onion.</source>
+ <translation>Fejl: Ikke understøttet argument -tor fundet, brug -onion.</translation>
+ </message>
+ <message>
+ <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source>
+ <translation>Gebyr (i BTC/kB) som skal føjes til transaktioner, du sender (standard: %s)</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Information</translation>
+ </message>
+ <message>
+ <source>Initialization sanity check failed. Bitcoin Core is shutting down.</source>
+ <translation>Sundhedstjek under klargøring mislykkedes. Bitcoin Core lukker ned.</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Ugyldigt beløb for -maxtxfee=&lt;beløb&gt;: "%s"</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -minrelaytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Ugyldigt beløb til -minrelaytxfee=&lt;beløb&gt;: "%s"</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -mintxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Ugyldigt beløb til -mintxfee=&lt;beløb&gt;: "%s"</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s' (must be at least %s)</source>
+ <translation>Ugyldigt beløb for -paytxfee=&lt;beløb&gt;: "%s" (skal være mindst %s)</translation>
+ </message>
+ <message>
+ <source>Invalid netmask specified in -whitelist: '%s'</source>
+ <translation>Ugyldig netmaske angivet i -whitelist: "%s"</translation>
+ </message>
+ <message>
+ <source>Keep at most &lt;n&gt; unconnectable transactions in memory (default: %u)</source>
+ <translation>Behold højest &lt;n&gt; uforbindelige transaktioner i hukommelsen (standard: %u)</translation>
+ </message>
+ <message>
+ <source>Need to specify a port with -whitebind: '%s'</source>
+ <translation>Nødt til at angive en port med -whitebinde: "%s"</translation>
+ </message>
+ <message>
+ <source>Node relay options:</source>
+ <translation>Videresendelsesvalgmuligheder for knude:</translation>
+ </message>
+ <message>
+ <source>Pruning blockstore...</source>
+ <translation>Beskærer bloklager…</translation>
+ </message>
+ <message>
+ <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source>
+ <translation>Tilvalg for RPC SSL: (se Bitcoin Wiki for instruktioner i SSL-opstart)</translation>
+ </message>
+ <message>
+ <source>RPC server options:</source>
+ <translation>Tilvalg for RPC-server:</translation>
+ </message>
+ <message>
+ <source>RPC support for HTTP persistent connections (default: %d)</source>
+ <translation>RPC-understøttelse for HTTP-persistente forbindelser (standard: %d)</translation>
+ </message>
+ <message>
+ <source>Rebuild block chain index from current blk000??.dat files on startup</source>
+ <translation>Genopbyg blokkædeindeks fra nuværende blk000??.dat-filer ved opstart</translation>
+ </message>
+ <message>
+ <source>Receive and display P2P network alerts (default: %u)</source>
+ <translation>Modtag og vis P2P-netværksadvarsler (standard: %u)</translation>
+ </message>
+ <message>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>Send sporings-/fejlsøgningsinformation til konsollen i stedet for debug.log filen</translation>
+ </message>
+ <message>
+ <source>Send transactions as zero-fee transactions if possible (default: %u)</source>
+ <translation>Send transaktioner som nul-gebyr-transaktioner hvis muligt (standard: %u)</translation>
+ </message>
+ <message>
+ <source>Set SSL root certificates for payment request (default: -system-)</source>
+ <translation>Sæt SSL-rodcertifikater for betalingsanmodning (standard: -system-)</translation>
+ </message>
+ <message>
+ <source>Set language, for example "de_DE" (default: system locale)</source>
+ <translation>Angiv sprog, fx "da_DK" (standard: systemlokalitet)</translation>
+ </message>
+ <message>
+ <source>Show all debugging options (usage: --help -help-debug)</source>
+ <translation>Vis alle tilvalg for fejlsøgning (brug: --help -help-debug)</translation>
+ </message>
+ <message>
+ <source>Show splash screen on startup (default: 1)</source>
+ <translation>Vis opstartsbillede ved opstart (standard: 1)</translation>
+ </message>
+ <message>
+ <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source>
+ <translation>Formindsk debug.log filen ved klientopstart (standard: 1 hvis ikke -debug)</translation>
+ </message>
+ <message>
+ <source>Signing transaction failed</source>
+ <translation>Underskrift af transaktion mislykkedes</translation>
+ </message>
+ <message>
+ <source>Start minimized</source>
+ <translation>Start minimeret</translation>
+ </message>
+ <message>
+ <source>The transaction amount is too small to pay the fee</source>
+ <translation>Transaktionsbeløbet er for lille til at betale gebyret</translation>
+ </message>
+ <message>
+ <source>This is experimental software.</source>
+ <translation>Dette er eksperimentelt software.</translation>
+ </message>
+ <message>
+ <source>Transaction amount too small</source>
+ <translation>Transaktionsbeløb er for lavt</translation>
+ </message>
+ <message>
+ <source>Transaction amounts must be positive</source>
+ <translation>Transaktionsbeløb skal være positive</translation>
+ </message>
+ <message>
+ <source>Transaction too large for fee policy</source>
+ <translation>Transaktion for stor til gebyrretningslinjer</translation>
+ </message>
+ <message>
+ <source>Transaction too large</source>
+ <translation>Transaktionen er for stor</translation>
+ </message>
+ <message>
+ <source>UI Options:</source>
+ <translation>Indstillinger for brugerflade:</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer (bind returned error %s)</source>
+ <translation>Ikke i stand til at tildele til %s på denne computer (bind returnerede fejl %s)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: 1 when listening)</source>
+ <translation>Brug UPnP til at konfigurere den lyttende port (standard: 1 under lytning)</translation>
+ </message>
+ <message>
+ <source>Username for JSON-RPC connections</source>
+ <translation>Brugernavn til JSON-RPC-forbindelser</translation>
+ </message>
+ <message>
+ <source>Wallet needed to be rewritten: restart Bitcoin Core to complete</source>
+ <translation>Det var nødvendigt at genskrive tegnebogen: genstart Bitcoin Core for at gennemføre</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Advarsel</translation>
+ </message>
+ <message>
+ <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source>
+ <translation>Advarsel: Ikke understøttet argument -benchmark ignoreret, brug -debug=bench.</translation>
+ </message>
+ <message>
+ <source>Warning: Unsupported argument -debugnet ignored, use -debug=net.</source>
+ <translation>Advarsel: Ikke understøttet argument -debugnet ignoreret, brug -debug=net.</translation>
+ </message>
+ <message>
+ <source>Zapping all transactions from wallet...</source>
+ <translation>Zapper alle transaktioner fra tegnebog…</translation>
+ </message>
+ <message>
+ <source>on startup</source>
+ <translation>under opstart</translation>
+ </message>
+ <message>
+ <source>wallet.dat corrupt, salvage failed</source>
+ <translation>wallet.dat ødelagt, redning af data mislykkedes</translation>
+ </message>
+ <message>
+ <source>Password for JSON-RPC connections</source>
+ <translation>Adgangskode til JSON-RPC-forbindelser</translation>
+ </message>
+ <message>
+ <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
+ <translation>Udfør kommando, når den bedste blok ændres (%s i kommandoen erstattes med blokhash)</translation>
+ </message>
+ <message>
+ <source>Upgrade wallet to latest format</source>
+ <translation>Opgrader tegnebog til seneste format</translation>
+ </message>
+ <message>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>Gennemsøg blokkæden for manglende tegnebogstransaktioner</translation>
+ </message>
+ <message>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>Brug OpenSSL (https) for JSON-RPC-forbindelser</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>Denne hjælpebesked</translation>
+ </message>
+ <message>
+ <source>Allow DNS lookups for -addnode, -seednode and -connect</source>
+ <translation>Tillad DNS-opslag for -addnode, -seednode og -connect</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>Indlæser adresser…</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>Fejl ved indlæsning af wallet.dat: Tegnebog ødelagt</translation>
+ </message>
+ <message>
+ <source>(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source>
+ <translation>(1 = behold metadata for transaktion, fx kontoindehaver og information om betalingsanmodning, 2 = drop metadata for transaktion)</translation>
+ </message>
+ <message>
+ <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
+ <translation>Hvor gennemarbejdet blokverificeringen for -checkblocks er (0-4; standard: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
+ <translation>Vedligehold et komplet transaktionsindeks, der bruges af rpc-kaldet getrawtransaction (standard: %u)</translation>
+ </message>
+ <message>
+ <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source>
+ <translation>Antal sekunder, som knuder der opfører sig upassende, skal vente før reetablering (standard: %u)</translation>
+ </message>
+ <message>
+ <source>Output debugging information (default: %u, supplying &lt;category&gt; is optional)</source>
+ <translation>Udskriv fejlsøgningsinformation (standard: %u, angivelse af &lt;kategori&gt; er valgfri)</translation>
+ </message>
+ <message>
+ <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source>
+ <translation>Brug separat SOCS5-proxy for at nå andre knuder via Tor skjulte tjenester (standard: %s)</translation>
+ </message>
+ <message>
+ <source>(default: %s)</source>
+ <translation>(standard: %s)</translation>
+ </message>
+ <message>
+ <source>Acceptable ciphers (default: %s)</source>
+ <translation>Accepterede kodninger (standard: %s)</translation>
+ </message>
+ <message>
+ <source>Always query for peer addresses via DNS lookup (default: %u)</source>
+ <translation>Forespørg altid adresser på andre knuder via DNS-opslag (default: %u)</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>Fejl ved indlæsning af wallet.dat</translation>
+ </message>
+ <message>
+ <source>Generate coins (default: %u)</source>
+ <translation>Generér bitcoins (standard: %u)</translation>
+ </message>
+ <message>
+ <source>How many blocks to check at startup (default: %u, 0 = all)</source>
+ <translation>Antal blokke som tjekkes ved opstart (standard: %u, 0 = alle)</translation>
+ </message>
+ <message>
+ <source>Include IP addresses in debug output (default: %u)</source>
+ <translation>Inkludér IP-adresser i fejlretningsoutput (standard: %u)</translation>
+ </message>
+ <message>
+ <source>Invalid -proxy address: '%s'</source>
+ <translation>Ugyldig -proxy adresse: "%s"</translation>
+ </message>
+ <message>
+ <source>Listen for JSON-RPC connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>Lyt efter JSON-RPC-forbindelser på &lt;port&gt; (standard: %u eller testnet: %u)</translation>
+ </message>
+ <message>
+ <source>Listen for connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>Lyt efter forbindelser på &lt;port&gt; (standard: %u eller testnet: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain at most &lt;n&gt; connections to peers (default: %u)</source>
+ <translation>Oprethold højest &lt;n&gt; forbindelser til andre knuder (standard: %u)</translation>
+ </message>
+ <message>
+ <source>Make the wallet broadcast transactions</source>
+ <translation>Få tegnebogen til at transmittere transaktioner</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection receive buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>Maksimum for modtagelsesbuffer pr. forbindelse, &lt;n&gt;*1000 byte (standard: %u)</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection send buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>Maksimum for afsendelsesbuffer pr. forbindelse, &lt;n&gt;*1000 byte (standard: %u)</translation>
+ </message>
+ <message>
+ <source>Prepend debug output with timestamp (default: %u)</source>
+ <translation>Føj tidsstempel foran fejlsøgningsoutput (standard: %u)</translation>
+ </message>
+ <message>
+ <source>Relay and mine data carrier transactions (default: %u)</source>
+ <translation>Videresend og udvind databærer-transaktioner (standard: %u)</translation>
+ </message>
+ <message>
+ <source>Relay non-P2SH multisig (default: %u)</source>
+ <translation>Videresend ikke-P2SH multisig (standard: %u)</translation>
+ </message>
+ <message>
+ <source>Server certificate file (default: %s)</source>
+ <translation>Servercertifikat-fil (standard: %s)
+</translation>
+ </message>
+ <message>
+ <source>Server private key (default: %s)</source>
+ <translation>Serverens private nøgle (standard: %s)</translation>
+ </message>
+ <message>
+ <source>Set key pool size to &lt;n&gt; (default: %u)</source>
+ <translation>Sæt nøglepuljestørrelse til &lt;n&gt; (standard: %u)
+</translation>
+ </message>
+ <message>
+ <source>Set minimum block size in bytes (default: %u)</source>
+ <translation>Angiv minimumsblokstørrelse i byte (standard: %u)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads to service RPC calls (default: %d)</source>
+ <translation>Angiv antallet af tråde til at håndtere RPC-kald (standard: %d)</translation>
+ </message>
+ <message>
+ <source>Specify configuration file (default: %s)</source>
+ <translation>Angiv konfigurationsfil (standard: %s)</translation>
+ </message>
+ <message>
+ <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source>
+ <translation>Angiv tilslutningstimeout i millisekunder (minimum: 1, standard: %d)</translation>
+ </message>
+ <message>
+ <source>Specify pid file (default: %s)</source>
+ <translation>Angiv pid-fil (standard: %s)</translation>
+ </message>
+ <message>
+ <source>Spend unconfirmed change when sending transactions (default: %u)</source>
+ <translation>Brug ubekræftede byttepenge under afsendelse af transaktioner (standard: %u)</translation>
+ </message>
+ <message>
+ <source>Threshold for disconnecting misbehaving peers (default: %u)</source>
+ <translation>Grænse for afbrydelse af forbindelse til knuder, der opfører sig upassende (standard: %u)</translation>
+ </message>
+ <message>
+ <source>Unknown network specified in -onlynet: '%s'</source>
+ <translation>Ukendt netværk anført i -onlynet: "%s"</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -bind address: '%s'</source>
+ <translation>Kan ikke finde -bind adressen: "%s"</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -externalip address: '%s'</source>
+ <translation>Kan ikke finde -externalip adressen: "%s"</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Ugyldigt beløb for -paytxfee=&lt;beløb&gt;: "%s"</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>Manglende dækning</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>Indlæser blokindeks…</translation>
+ </message>
+ <message>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>Tilføj en knude til at forbinde til og forsøg at holde forbindelsen åben</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>Indlæser tegnebog…</translation>
+ </message>
+ <message>
+ <source>Cannot downgrade wallet</source>
+ <translation>Kan ikke nedgradere tegnebog</translation>
+ </message>
+ <message>
+ <source>Cannot write default address</source>
+ <translation>Kan ikke skrive standardadresse</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>Genindlæser…</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>Indlæsning gennemført</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Fejl</translation>
+ </message>
+</context>
+</TS> \ 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 0000000000..3cb94b3c70
--- /dev/null
+++ b/src/qt/locale/bitcoin_de.ts
@@ -0,0 +1,3584 @@
+<TS language="de" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Right-click to edit address or label</source>
+ <translation>Rechtsklick zum Bearbeiten der Adresse oder der Bezeichnung</translation>
+ </message>
+ <message>
+ <source>Create a new address</source>
+ <translation>Eine neue Adresse erstellen</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>&amp;Neu</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Ausgewählte Adresse in die Zwischenablage kopieren</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>&amp;Kopieren</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>&amp;Schließen</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>Adresse &amp;kopieren</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>Ausgewählte Adresse aus der Liste entfernen</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Daten der aktuellen Ansicht in eine Datei exportieren</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>E&amp;xportieren</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;Löschen</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>Wählen Sie die Adresse aus, an die Sie Bitcoins überweisen möchten</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>Wählen Sie die Adresse aus, über die Sie Bitcoins empfangen wollen</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>&amp;Auswählen</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>Zahlungsadressen</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>Empfangsadressen</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>Dies sind Ihre Bitcoin-Adressen zum Tätigen von Überweisungen. Bitte prüfen Sie den Betrag und die Empfangsadresse, bevor Sie Bitcoins überweisen.</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>Dies sind Ihre Bitcoin-Adressen zum Empfangen von Zahlungen. Es wird empfohlen für jede Transaktion eine neue Empfangsadresse zu verwenden.</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>&amp;Bezeichnung kopieren</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>&amp;Editieren</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>Addressliste exportieren</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Kommagetrennte-Datei (*.csv)</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Exportieren fehlgeschlagen</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the address list to %1. Please try again.</source>
+ <translation>Beim Speichern der Adressliste nach %1 ist ein Fehler aufgetreten. Bitte versuchen Sie es erneut.</translation>
+ </message>
+</context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Bezeichnung</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adresse</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(keine Bezeichnung)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Passphrase Dialog</source>
+ <translation>Passphrasendialog</translation>
+ </message>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Passphrase eingeben</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Neue Passphrase</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Neue Passphrase bestätigen</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>Wallet verschlüsseln</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>Dieser Vorgang benötigt Ihre Passphrase, um die Wallet zu entsperren.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Wallet entsperren</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>Dieser Vorgang benötigt Ihre Passphrase, um die Wallet zu entschlüsseln.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>Wallet entschlüsseln</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>Passphrase ändern</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>Wallet-Verschlüsselung bestätigen</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>Warnung: Wenn Sie Ihre Wallet verschlüsseln und Ihre Passphrase verlieren, werden Sie &lt;b&gt;alle Ihre Bitcoins verlieren&lt;/b&gt;!</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>Sind Sie sich sicher, dass Sie Ihre Wallet verschlüsseln möchten?</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core 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.</source>
+ <translation>Bitcoin Core wird jetzt beendet, um den Verschlüsselungsprozess abzuschließen. Vergessen Sie nicht, dass eine Wallet-Verschlüsselung nicht vollständig vor Diebstahl Ihrer Bitcoins durch Schadsoftware schützen kann, die Ihren Computer infiziert.</translation>
+ </message>
+ <message>
+ <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
+ <translation>WICHTIG: Alle vorherigen Wallet-Sicherungen sollten durch die neu erzeugte, verschlüsselte Wallet ersetzt werden. Aus Sicherheitsgründen werden vorherige Sicherungen der unverschlüsselten Wallet nutzlos, sobald Sie die neue, verschlüsselte Wallet verwenden.</translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>Warnung: Die Feststelltaste ist aktiviert!</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>Wallet verschlüsselt</translation>
+ </message>
+ <message>
+ <source>Enter the new passphrase to the wallet.&lt;br/&gt;Please use a passphrase of &lt;b&gt;ten or more random characters&lt;/b&gt;, or &lt;b&gt;eight or more words&lt;/b&gt;.</source>
+ <translation>Geben Sie die neue Passphrase für die Wallet ein.&lt;br&gt;Bitte benutzen Sie eine Passphrase bestehend aus &lt;b&gt;zehn oder mehr zufälligen Zeichen&lt;/b&gt; oder &lt;b&gt;acht oder mehr Wörtern&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>Enter the old passphrase and new passphrase to the wallet.</source>
+ <translation>Geben Sie die alte und neue Wallet-Passphrase ein.</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>Wallet-Verschlüsselung fehlgeschlagen</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>Die Wallet-Verschlüsselung ist aufgrund eines internen Fehlers fehlgeschlagen. Ihre Wallet wurde nicht verschlüsselt.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>Die eingegebenen Passphrasen stimmen nicht überein.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>Wallet-Entsperrung fehlgeschlagen</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>Die eingegebene Passphrase zur Wallet-Entschlüsselung war nicht korrekt.</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>Wallet-Entschlüsselung fehlgeschlagen</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>Die Wallet-Passphrase wurde erfolgreich geändert.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>Nachricht s&amp;ignieren...</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>Synchronisiere mit Netzwerk...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;Übersicht</translation>
+ </message>
+ <message>
+ <source>Node</source>
+ <translation>Knoten</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>Allgemeine Wallet-Übersicht anzeigen</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Transaktionen</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>Transaktionsverlauf durchsehen</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>&amp;Beenden</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>Anwendung beenden</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>Über &amp;Qt</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>Informationen über Qt anzeigen</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;Konfiguration...</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>Wallet &amp;verschlüsseln...</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>Wallet &amp;sichern...</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>Passphrase &amp;ändern...</translation>
+ </message>
+ <message>
+ <source>&amp;Sending addresses...</source>
+ <translation>&amp;Zahlungsadressen...</translation>
+ </message>
+ <message>
+ <source>&amp;Receiving addresses...</source>
+ <translation>&amp;Empfangsadressen...</translation>
+ </message>
+ <message>
+ <source>Open &amp;URI...</source>
+ <translation>&amp;URI öffnen...</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core client</source>
+ <translation>"Bitcoin Core"-Client</translation>
+ </message>
+ <message>
+ <source>Importing blocks from disk...</source>
+ <translation>Importiere Blöcke von Datenträger...</translation>
+ </message>
+ <message>
+ <source>Reindexing blocks on disk...</source>
+ <translation>Reindiziere Blöcke auf Datenträger...</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>Bitcoins an eine Bitcoin-Adresse überweisen</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>Eine Wallet-Sicherungskopie erstellen und abspeichern</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Ändert die Passphrase, die für die Wallet-Verschlüsselung benutzt wird</translation>
+ </message>
+ <message>
+ <source>&amp;Debug window</source>
+ <translation>&amp;Debugfenster</translation>
+ </message>
+ <message>
+ <source>Open debugging and diagnostic console</source>
+ <translation>Debugging- und Diagnosekonsole öffnen</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>Nachricht &amp;verifizieren...</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>Wallet</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>&amp;Überweisen</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>&amp;Empfangen</translation>
+ </message>
+ <message>
+ <source>Show information about Bitcoin Core</source>
+ <translation>Informationen über Bitcoin Core anzeigen</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>&amp;Anzeigen / Verstecken</translation>
+ </message>
+ <message>
+ <source>Show or hide the main Window</source>
+ <translation>Das Hauptfenster anzeigen oder verstecken</translation>
+ </message>
+ <message>
+ <source>Encrypt the private keys that belong to your wallet</source>
+ <translation>Verschlüsselt die zu Ihrer Wallet gehörenden privaten Schlüssel</translation>
+ </message>
+ <message>
+ <source>Sign messages with your Bitcoin addresses to prove you own them</source>
+ <translation>Nachrichten signieren, um den Besitz Ihrer Bitcoin-Adressen zu beweisen</translation>
+ </message>
+ <message>
+ <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source>
+ <translation>Nachrichten verifizieren, um sicherzustellen, dass diese mit den angegebenen Bitcoin-Adressen signiert wurden</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;Datei</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;Einstellungen</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>&amp;Hilfe</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>Registerkartenleiste</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Request payments (generates QR codes and bitcoin: URIs)</source>
+ <translation>Zahlungen anfordern (erzeugt QR-Codes und "bitcoin:"-URIs)</translation>
+ </message>
+ <message>
+ <source>&amp;About Bitcoin Core</source>
+ <translation>&amp;Über Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Modify configuration options for Bitcoin Core</source>
+ <translation>Konfiguration von Bitcoin Core bearbeiten</translation>
+ </message>
+ <message>
+ <source>Show the list of used sending addresses and labels</source>
+ <translation>Liste verwendeter Zahlungsadressen und Bezeichnungen anzeigen</translation>
+ </message>
+ <message>
+ <source>Show the list of used receiving addresses and labels</source>
+ <translation>Liste verwendeter Empfangsadressen und Bezeichnungen anzeigen</translation>
+ </message>
+ <message>
+ <source>Open a bitcoin: URI or payment request</source>
+ <translation>Eine "bitcoin:"-URI oder Zahlungsanforderung öffnen</translation>
+ </message>
+ <message>
+ <source>&amp;Command-line options</source>
+ <translation>&amp;Kommandozeilenoptionen</translation>
+ </message>
+ <message>
+ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
+ <translation>Zeige den "Bitcoin Core"-Hilfetext, um eine Liste mit möglichen Kommandozeilenoptionen zu erhalten</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n active connection(s) to Bitcoin network</source>
+ <translation><numerusform>%n aktive Verbindung zum Bitcoin-Netzwerk</numerusform><numerusform>%n aktive Verbindungen zum Bitcoin-Netzwerk</numerusform></translation>
+ </message>
+ <message>
+ <source>No block source available...</source>
+ <translation>Keine Blockquelle verfügbar...</translation>
+ </message>
+ <message numerus="yes">
+ <source>Processed %n block(s) of transaction history.</source>
+ <translation><numerusform>%n Block des Transaktionsverlaufs verarbeitet.</numerusform><numerusform>%n Blöcke des Transaktionsverlaufs verarbeitet.</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n hour(s)</source>
+ <translation><numerusform>%n Stunde</numerusform><numerusform>%n Stunden</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n day(s)</source>
+ <translation><numerusform>%n Tag</numerusform><numerusform>%n Tage</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n week(s)</source>
+ <translation><numerusform>%n Woche</numerusform><numerusform>%n Wochen</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 and %2</source>
+ <translation>%1 und %2</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n year(s)</source>
+ <translation><numerusform>%n Jahr</numerusform><numerusform>%n Jahre</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 behind</source>
+ <translation>%1 im Rückstand</translation>
+ </message>
+ <message>
+ <source>Last received block was generated %1 ago.</source>
+ <translation>Der letzte empfangene Block ist %1 alt.</translation>
+ </message>
+ <message>
+ <source>Transactions after this will not yet be visible.</source>
+ <translation>Transaktionen hiernach werden noch nicht angezeigt.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Fehler</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Warnung</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Hinweis</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>Auf aktuellem Stand</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>Hole auf...</translation>
+ </message>
+ <message>
+ <source>Date: %1
+</source>
+ <translation>Datum: %1
+</translation>
+ </message>
+ <message>
+ <source>Amount: %1
+</source>
+ <translation>Betrag: %1
+</translation>
+ </message>
+ <message>
+ <source>Type: %1
+</source>
+ <translation>Typ: %1
+</translation>
+ </message>
+ <message>
+ <source>Label: %1
+</source>
+ <translation>Bezeichnung: %1
+</translation>
+ </message>
+ <message>
+ <source>Address: %1
+</source>
+ <translation>Adresse: %1
+</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>Gesendete Transaktion</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>Eingehende Transaktion</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>Wallet ist &lt;b&gt;verschlüsselt&lt;/b&gt; und aktuell &lt;b&gt;entsperrt&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>Wallet ist &lt;b&gt;verschlüsselt&lt;/b&gt; und aktuell &lt;b&gt;gesperrt&lt;/b&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <source>Network Alert</source>
+ <translation>Netzwerkalarm</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Coin Selection</source>
+ <translation>Münzauswahl ("Coin Control")</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Anzahl:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Byte:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Betrag:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Priorität:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Gebühr:</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>"Dust":</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Abzüglich Gebühr:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Wechselgeld:</translation>
+ </message>
+ <message>
+ <source>(un)select all</source>
+ <translation>Alles (de)selektieren</translation>
+ </message>
+ <message>
+ <source>Tree mode</source>
+ <translation>Baumansicht</translation>
+ </message>
+ <message>
+ <source>List mode</source>
+ <translation>Listenansicht</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Betrag</translation>
+ </message>
+ <message>
+ <source>Received with label</source>
+ <translation>Empfangen über Bezeichnung</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>Empfangen über Adresse</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Datum</translation>
+ </message>
+ <message>
+ <source>Confirmations</source>
+ <translation>Bestätigungen</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Bestätigt</translation>
+ </message>
+ <message>
+ <source>Priority</source>
+ <translation>Priorität</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Adresse kopieren</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Bezeichnung kopieren</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Betrag kopieren</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Transaktions-ID kopieren</translation>
+ </message>
+ <message>
+ <source>Lock unspent</source>
+ <translation>Nicht ausgegebenen Betrag sperren</translation>
+ </message>
+ <message>
+ <source>Unlock unspent</source>
+ <translation>Nicht ausgegebenen Betrag entsperren</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Anzahl kopieren</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Gebühr kopieren</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Abzüglich Gebühr kopieren</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Byte kopieren</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Priorität kopieren</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>"Dust" kopieren</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Wechselgeld kopieren</translation>
+ </message>
+ <message>
+ <source>highest</source>
+ <translation>am höchsten</translation>
+ </message>
+ <message>
+ <source>higher</source>
+ <translation>höher</translation>
+ </message>
+ <message>
+ <source>high</source>
+ <translation>hoch</translation>
+ </message>
+ <message>
+ <source>medium-high</source>
+ <translation>mittel-hoch</translation>
+ </message>
+ <message>
+ <source>medium</source>
+ <translation>mittel</translation>
+ </message>
+ <message>
+ <source>low-medium</source>
+ <translation>niedrig-mittel</translation>
+ </message>
+ <message>
+ <source>low</source>
+ <translation>niedrig</translation>
+ </message>
+ <message>
+ <source>lower</source>
+ <translation>niedriger</translation>
+ </message>
+ <message>
+ <source>lowest</source>
+ <translation>am niedrigsten</translation>
+ </message>
+ <message>
+ <source>(%1 locked)</source>
+ <translation>(%1 gesperrt)</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>keine</translation>
+ </message>
+ <message>
+ <source>This label turns red if the transaction size is greater than 1000 bytes.</source>
+ <translation>Diese Bezeichnung wird rot, wenn die Transaktion größer als 1000 Byte ist.</translation>
+ </message>
+ <message>
+ <source>This label turns red if the priority is smaller than "medium".</source>
+ <translation>Diese Bezeichnung wird rot, wenn die Priorität niedriger als "mittel" ist.</translation>
+ </message>
+ <message>
+ <source>This label turns red if any recipient receives an amount smaller than %1.</source>
+ <translation>Diese Bezeichnung wird rot, wenn irgendein Empfänger einen Betrag kleiner als %1 erhält.</translation>
+ </message>
+ <message>
+ <source>Can vary +/- %1 satoshi(s) per input.</source>
+ <translation>Kann pro Eingabe um +/- %1 Satoshi(s) abweichen.</translation>
+ </message>
+ <message>
+ <source>yes</source>
+ <translation>ja</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>nein</translation>
+ </message>
+ <message>
+ <source>This means a fee of at least %1 per kB is required.</source>
+ <translation>Das bedeutet, dass eine Gebühr von mindestens %1 pro kB erforderlich ist.</translation>
+ </message>
+ <message>
+ <source>Can vary +/- 1 byte per input.</source>
+ <translation>Kann um +/- 1 Byte pro Eingabe variieren.</translation>
+ </message>
+ <message>
+ <source>Transactions with higher priority are more likely to get included into a block.</source>
+ <translation>Transaktionen mit höherer Priorität haben eine größere Chance in einen Block aufgenommen zu werden.</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(keine Bezeichnung)</translation>
+ </message>
+ <message>
+ <source>change from %1 (%2)</source>
+ <translation>Wechselgeld von %1 (%2)</translation>
+ </message>
+ <message>
+ <source>(change)</source>
+ <translation>(Wechselgeld)</translation>
+ </message>
+</context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>Adresse bearbeiten</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>&amp;Bezeichnung</translation>
+ </message>
+ <message>
+ <source>The label associated with this address list entry</source>
+ <translation>Bezeichnung, die dem Adresslisteneintrag zugeordnet ist.</translation>
+ </message>
+ <message>
+ <source>The address associated with this address list entry. This can only be modified for sending addresses.</source>
+ <translation>Adresse, die dem Adresslisteneintrag zugeordnet ist. Diese kann nur bei Zahlungsadressen verändert werden.</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;Adresse</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>Neue Empfangsadresse</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>Neue Zahlungsadresse</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>Empfangsadresse bearbeiten</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>Zahlungsadresse bearbeiten</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>Die eingegebene Adresse "%1" befindet sich bereits im Adressbuch.</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is not a valid Bitcoin address.</source>
+ <translation>Die eingegebene Adresse "%1" ist keine gültige Bitcoin-Adresse.</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>Wallet konnte nicht entsperrt werden.</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>Erzeugung eines neuen Schlüssels fehlgeschlagen.</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ <message>
+ <source>A new data directory will be created.</source>
+ <translation>Es wird ein neues Datenverzeichnis angelegt.</translation>
+ </message>
+ <message>
+ <source>name</source>
+ <translation>Name</translation>
+ </message>
+ <message>
+ <source>Directory already exists. Add %1 if you intend to create a new directory here.</source>
+ <translation>Verzeichnis existiert bereits. Fügen Sie %1 an, wenn Sie beabsichtigen hier ein neues Verzeichnis anzulegen.</translation>
+ </message>
+ <message>
+ <source>Path already exists, and is not a directory.</source>
+ <translation>Pfad existiert bereits und ist kein Verzeichnis.</translation>
+ </message>
+ <message>
+ <source>Cannot create data directory here.</source>
+ <translation>Datenverzeichnis kann hier nicht angelegt werden.</translation>
+ </message>
+</context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>Version</translation>
+ </message>
+ <message>
+ <source>(%1-bit)</source>
+ <translation>(%1-Bit)</translation>
+ </message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>Über Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Command-line options</source>
+ <translation>Kommandozeilenoptionen</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>Benutzung:</translation>
+ </message>
+ <message>
+ <source>command-line options</source>
+ <translation>Kommandozeilenoptionen</translation>
+ </message>
+</context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Welcome</source>
+ <translation>Willkommen</translation>
+ </message>
+ <message>
+ <source>Welcome to Bitcoin Core.</source>
+ <translation>Willkommen zu Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</source>
+ <translation>Da Sie das Programm gerade zum ersten Mal starten, können Sie nun auswählen wo Bitcoin Core seine Daten ablegen soll.</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory.</source>
+ <translation>Bitcoin Core wird eine Kopie der Blockkette herunterladen und speichern. Mindestens %1GB Daten werden in diesem Verzeichnis abgelegt und die Datenmenge wächst über die Zeit an. Auch die Wallet wird in diesem Verzeichnis abgelegt.</translation>
+ </message>
+ <message>
+ <source>Use the default data directory</source>
+ <translation>Standard-Datenverzeichnis verwenden</translation>
+ </message>
+ <message>
+ <source>Use a custom data directory:</source>
+ <translation>Ein benutzerdefiniertes Datenverzeichnis verwenden:</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Error: Specified data directory "%1" cannot be created.</source>
+ <translation>Fehler: Angegebenes Datenverzeichnis "%1" kann nicht angelegt werden.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Fehler</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n GB of free space available</source>
+ <translation><numerusform>%n GB freier Speicherplatz verfügbar</numerusform><numerusform>%n GB freier Speicherplatz verfügbar</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>(of %n GB needed)</source>
+ <translation><numerusform>(von benötigtem %n GB)</numerusform><numerusform>(von benötigten %n GB)</numerusform></translation>
+ </message>
+</context>
+<context>
+ <name>OpenURIDialog</name>
+ <message>
+ <source>Open URI</source>
+ <translation>URI öffnen</translation>
+ </message>
+ <message>
+ <source>Open payment request from URI or file</source>
+ <translation>Zahlungsanforderung über URI oder aus Datei öffnen</translation>
+ </message>
+ <message>
+ <source>URI:</source>
+ <translation>URI:</translation>
+ </message>
+ <message>
+ <source>Select payment request file</source>
+ <translation>Zahlungsanforderungsdatei auswählen</translation>
+ </message>
+ <message>
+ <source>Select payment request file to open</source>
+ <translation>Zu öffnende Zahlungsanforderungsdatei auswählen</translation>
+ </message>
+</context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>Konfiguration</translation>
+ </message>
+ <message>
+ <source>&amp;Main</source>
+ <translation>&amp;Allgemein</translation>
+ </message>
+ <message>
+ <source>Size of &amp;database cache</source>
+ <translation>Größe des &amp;Datenbankcaches</translation>
+ </message>
+ <message>
+ <source>MB</source>
+ <translation>MB</translation>
+ </message>
+ <message>
+ <source>Number of script &amp;verification threads</source>
+ <translation>Anzahl an Skript-&amp;Verifizierungs-Threads</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside</source>
+ <translation>Eingehende Verbindungen annehmen</translation>
+ </message>
+ <message>
+ <source>Allow incoming connections</source>
+ <translation>Erlaubt eingehende Verbindungen</translation>
+ </message>
+ <message>
+ <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
+ <translation>IP-Adresse des Proxies (z.B. IPv4: 127.0.0.1 / IPv6: ::1)</translation>
+ </message>
+ <message>
+ <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source>
+ <translation>Minimiert die Anwendung anstatt sie zu beenden wenn das Fenster geschlossen wird. Wenn dies aktiviert ist, müssen Sie die Anwendung über "Beenden" im Menü schließen.</translation>
+ </message>
+ <message>
+ <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source>
+ <translation>Legt die Sprache der Benutzeroberfläche fest. Diese Einstellung wird erst nach einem Neustart von Bitcoin Core aktiv.</translation>
+ </message>
+ <message>
+ <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source>
+ <translation>Externe URLs (z.B. ein Block-Explorer), die im Kontextmenü des Transaktionsverlaufs eingefügt werden. In der URL wird %s durch den Transaktionshash ersetzt. Bei Angabe mehrerer URLs müssen diese durch "|" voneinander getrennt werden.</translation>
+ </message>
+ <message>
+ <source>Third party transaction URLs</source>
+ <translation>Externe Transaktions-URLs</translation>
+ </message>
+ <message>
+ <source>Active command-line options that override above options:</source>
+ <translation>Aktive Kommandozeilenoptionen, die obige Konfiguration überschreiben:</translation>
+ </message>
+ <message>
+ <source>Reset all client options to default.</source>
+ <translation>Setzt die Clientkonfiguration auf Standardwerte zurück.</translation>
+ </message>
+ <message>
+ <source>&amp;Reset Options</source>
+ <translation>Konfiguration &amp;zurücksetzen</translation>
+ </message>
+ <message>
+ <source>&amp;Network</source>
+ <translation>&amp;Netzwerk</translation>
+ </message>
+ <message>
+ <source>Automatically start Bitcoin Core after logging in to the system.</source>
+ <translation>Bitcoin Core nach der Anmeldung am System automatisch starten.</translation>
+ </message>
+ <message>
+ <source>&amp;Start Bitcoin Core on system login</source>
+ <translation>&amp;Bitcoin Core nach Systemanmeldung starten</translation>
+ </message>
+ <message>
+ <source>(0 = auto, &lt;0 = leave that many cores free)</source>
+ <translation>(0 = automatisch, &lt;0 = so viele Kerne frei lassen)</translation>
+ </message>
+ <message>
+ <source>W&amp;allet</source>
+ <translation>W&amp;allet</translation>
+ </message>
+ <message>
+ <source>Expert</source>
+ <translation>Erweiterte Wallet-Optionen</translation>
+ </message>
+ <message>
+ <source>Enable coin &amp;control features</source>
+ <translation>"&amp;Coin Control"-Funktionen aktivieren</translation>
+ </message>
+ <message>
+ <source>If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.</source>
+ <translation>Wenn Sie das Ausgeben von unbestätigtem Wechselgeld deaktivieren, kann das Wechselgeld einer Transaktion nicht verwendet werden, bis es mindestens eine Bestätigung erhalten hat. Dies wirkt sich auf die Berechnung des Kontostands aus.</translation>
+ </message>
+ <message>
+ <source>&amp;Spend unconfirmed change</source>
+ <translation>&amp;Unbestätigtes Wechselgeld darf ausgegeben werden</translation>
+ </message>
+ <message>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>Automatisch den Bitcoin-Clientport auf dem Router öffnen. Dies funktioniert nur, wenn Ihr Router UPnP unterstützt und dies aktiviert ist.</translation>
+ </message>
+ <message>
+ <source>Map port using &amp;UPnP</source>
+ <translation>Portweiterleitung via &amp;UPnP</translation>
+ </message>
+ <message>
+ <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
+ <translation>Über einen SOCKS5-Proxy mit dem Bitcoin-Netzwerk verbinden.</translation>
+ </message>
+ <message>
+ <source>&amp;Connect through SOCKS5 proxy (default proxy):</source>
+ <translation>Über einen SOCKS5-Proxy &amp;verbinden (Standardproxy):</translation>
+ </message>
+ <message>
+ <source>Proxy &amp;IP:</source>
+ <translation>Proxy-&amp;IP:</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>&amp;Port:</translation>
+ </message>
+ <message>
+ <source>Port of the proxy (e.g. 9050)</source>
+ <translation>Port des Proxies (z.B. 9050)</translation>
+ </message>
+ <message>
+ <source>&amp;Window</source>
+ <translation>&amp;Programmfenster</translation>
+ </message>
+ <message>
+ <source>Show only a tray icon after minimizing the window.</source>
+ <translation>Nur ein Symbol im Infobereich anzeigen, nachdem das Programmfenster minimiert wurde.</translation>
+ </message>
+ <message>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>In den Infobereich anstatt in die Taskleiste &amp;minimieren</translation>
+ </message>
+ <message>
+ <source>M&amp;inimize on close</source>
+ <translation>Beim Schließen m&amp;inimieren</translation>
+ </message>
+ <message>
+ <source>&amp;Display</source>
+ <translation>Anzei&amp;ge</translation>
+ </message>
+ <message>
+ <source>User Interface &amp;language:</source>
+ <translation>&amp;Sprache der Benutzeroberfläche:</translation>
+ </message>
+ <message>
+ <source>&amp;Unit to show amounts in:</source>
+ <translation>&amp;Einheit der Beträge:</translation>
+ </message>
+ <message>
+ <source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
+ <translation>Wählen Sie die standardmäßige Untereinheit, die in der Benutzeroberfläche und beim Überweisen von Bitcoins angezeigt werden soll.</translation>
+ </message>
+ <message>
+ <source>Whether to show coin control features or not.</source>
+ <translation>Legt fest, ob die "Coin Control"-Funktionen angezeigt werden.</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>&amp;OK</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>A&amp;bbrechen</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>Standard</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>keine</translation>
+ </message>
+ <message>
+ <source>Confirm options reset</source>
+ <translation>Zurücksetzen der Konfiguration bestätigen</translation>
+ </message>
+ <message>
+ <source>Client restart required to activate changes.</source>
+ <translation>Clientneustart nötig, um die Änderungen zu aktivieren.</translation>
+ </message>
+ <message>
+ <source>Client will be shut down. Do you want to proceed?</source>
+ <translation>Client wird beendet. Möchten Sie den Vorgang fortsetzen?</translation>
+ </message>
+ <message>
+ <source>This change would require a client restart.</source>
+ <translation>Diese Änderung würde einen Clientneustart benötigen.</translation>
+ </message>
+ <message>
+ <source>The supplied proxy address is invalid.</source>
+ <translation>Die eingegebene Proxyadresse ist ungültig.</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>Formular</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>Die angezeigten Informationen sind möglicherweise nicht mehr aktuell. Ihre Wallet wird automatisch synchronisiert, nachdem eine Verbindung zum Bitcoin-Netzwerk hergestellt wurde. Dieser Prozess ist jedoch derzeit noch nicht abgeschlossen.</translation>
+ </message>
+ <message>
+ <source>Watch-only:</source>
+ <translation>Beobachtet:</translation>
+ </message>
+ <message>
+ <source>Available:</source>
+ <translation>Verfügbar:</translation>
+ </message>
+ <message>
+ <source>Your current spendable balance</source>
+ <translation>Ihr aktuell verfügbarer Kontostand</translation>
+ </message>
+ <message>
+ <source>Pending:</source>
+ <translation>Ausstehend:</translation>
+ </message>
+ <message>
+ <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source>
+ <translation>Betrag aus unbestätigten Transaktionen, der noch nicht im aktuell verfügbaren Kontostand enthalten ist</translation>
+ </message>
+ <message>
+ <source>Immature:</source>
+ <translation>Unreif:</translation>
+ </message>
+ <message>
+ <source>Mined balance that has not yet matured</source>
+ <translation>Erarbeiteter Betrag der noch nicht gereift ist</translation>
+ </message>
+ <message>
+ <source>Balances</source>
+ <translation>Kontostände</translation>
+ </message>
+ <message>
+ <source>Total:</source>
+ <translation>Gesamtbetrag:</translation>
+ </message>
+ <message>
+ <source>Your current total balance</source>
+ <translation>Aktueller Gesamtbetrag aus obigen Kategorien</translation>
+ </message>
+ <message>
+ <source>Your current balance in watch-only addresses</source>
+ <translation>Ihr aktueller Kontostand beobachteter Adressen</translation>
+ </message>
+ <message>
+ <source>Spendable:</source>
+ <translation>Verfügbar:</translation>
+ </message>
+ <message>
+ <source>Recent transactions</source>
+ <translation>Letzte Transaktionen</translation>
+ </message>
+ <message>
+ <source>Unconfirmed transactions to watch-only addresses</source>
+ <translation>Unbestätigte Transaktionen von beobachteten Adressen</translation>
+ </message>
+ <message>
+ <source>Mined balance in watch-only addresses that has not yet matured</source>
+ <translation>Erarbeiteter Betrag in beobachteten Adressen der noch nicht gereift ist</translation>
+ </message>
+ <message>
+ <source>Current total balance in watch-only addresses</source>
+ <translation>Aktueller Gesamtbetrag in beobachteten Adressen aus obigen Kategorien</translation>
+ </message>
+</context>
+<context>
+ <name>PaymentServer</name>
+ <message>
+ <source>URI handling</source>
+ <translation>URI-Verarbeitung</translation>
+ </message>
+ <message>
+ <source>Invalid payment address %1</source>
+ <translation>Ungültige Zahlungsadresse %1</translation>
+ </message>
+ <message>
+ <source>Payment request rejected</source>
+ <translation>Zahlungsanforderung abgelehnt</translation>
+ </message>
+ <message>
+ <source>Payment request network doesn't match client network.</source>
+ <translation>Netzwerk der Zahlungsanforderung stimmt nicht mit dem Client-Netzwerk überein.</translation>
+ </message>
+ <message>
+ <source>Payment request is not initialized.</source>
+ <translation>Zahlungsanforderung ist nicht initialisiert.</translation>
+ </message>
+ <message>
+ <source>Requested payment amount of %1 is too small (considered dust).</source>
+ <translation>Angeforderter Zahlungsbetrag in Höhe von %1 ist zu niedrig und wurde als "Dust" eingestuft.</translation>
+ </message>
+ <message>
+ <source>Payment request error</source>
+ <translation>fehlerhafte Zahlungsanforderung</translation>
+ </message>
+ <message>
+ <source>Cannot start bitcoin: click-to-pay handler</source>
+ <translation>"bitcoin: Klicken-zum-Bezahlen"-Handler konnte nicht gestartet werden</translation>
+ </message>
+ <message>
+ <source>Payment request fetch URL is invalid: %1</source>
+ <translation>Abruf-URL der Zahlungsanforderung ist ungültig: %1</translation>
+ </message>
+ <message>
+ <source>URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source>
+ <translation>URI kann nicht analysiert werden! Dies kann durch eine ungültige Bitcoin-Adresse oder fehlerhafte URI-Parameter verursacht werden.</translation>
+ </message>
+ <message>
+ <source>Payment request file handling</source>
+ <translation>Zahlungsanforderungsdatei-Verarbeitung</translation>
+ </message>
+ <message>
+ <source>Payment request file cannot be read! This can be caused by an invalid payment request file.</source>
+ <translation>Zahlungsanforderungsdatei kann nicht gelesen werden! Dies kann durch eine ungültige Zahlungsanforderungsdatei verursacht werden.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>Zahlungsanforderung abgelaufen.</translation>
+ </message>
+ <message>
+ <source>Unverified payment requests to custom payment scripts are unsupported.</source>
+ <translation>Unverifizierte Zahlungsanforderungen an benutzerdefinierte Zahlungsskripte werden nicht unterstützt.</translation>
+ </message>
+ <message>
+ <source>Invalid payment request.</source>
+ <translation>Ungültige Zahlungsanforderung.</translation>
+ </message>
+ <message>
+ <source>Refund from %1</source>
+ <translation>Rücküberweisung von %1</translation>
+ </message>
+ <message>
+ <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source>
+ <translation>Zahlungsanforderung %1 ist zu groß (%2 Byte, erlaubt sind %3 Byte).</translation>
+ </message>
+ <message>
+ <source>Payment request DoS protection</source>
+ <translation>Zahlungsanforderungs-DoS-Schutz</translation>
+ </message>
+ <message>
+ <source>Error communicating with %1: %2</source>
+ <translation>Kommunikationsfehler mit %1: %2</translation>
+ </message>
+ <message>
+ <source>Payment request cannot be parsed!</source>
+ <translation>Zahlungsanforderung kann nicht verarbeitet werden!</translation>
+ </message>
+ <message>
+ <source>Bad response from server %1</source>
+ <translation>Fehlerhafte Antwort vom Server: %1</translation>
+ </message>
+ <message>
+ <source>Payment acknowledged</source>
+ <translation>Zahlung bestätigt</translation>
+ </message>
+ <message>
+ <source>Network request error</source>
+ <translation>fehlerhafte Netzwerkanfrage</translation>
+ </message>
+</context>
+<context>
+ <name>PeerTableModel</name>
+ <message>
+ <source>User Agent</source>
+ <translation>User-Agent</translation>
+ </message>
+ <message>
+ <source>Node/Service</source>
+ <translation>Knoten/Dienst</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Pingzeit</translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>Betrag</translation>
+ </message>
+ <message>
+ <source>Enter a Bitcoin address (e.g. %1)</source>
+ <translation>Bitcoin-Adresse eingeben (z.B. %1)</translation>
+ </message>
+ <message>
+ <source>%1 d</source>
+ <translation>%1 d</translation>
+ </message>
+ <message>
+ <source>%1 h</source>
+ <translation>%1 h</translation>
+ </message>
+ <message>
+ <source>%1 m</source>
+ <translation>%1 m</translation>
+ </message>
+ <message>
+ <source>%1 s</source>
+ <translation>%1 s</translation>
+ </message>
+ <message>
+ <source>None</source>
+ <translation>Keine</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>k.A.</translation>
+ </message>
+ <message>
+ <source>%1 ms</source>
+ <translation>%1 ms</translation>
+ </message>
+</context>
+<context>
+ <name>QRImageWidget</name>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>Grafik &amp;speichern...</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Image</source>
+ <translation>Grafik &amp;kopieren</translation>
+ </message>
+ <message>
+ <source>Save QR Code</source>
+ <translation>QR-Code speichern</translation>
+ </message>
+ <message>
+ <source>PNG Image (*.png)</source>
+ <translation>PNG-Grafik (*.png)</translation>
+ </message>
+</context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>Client name</source>
+ <translation>Clientname</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>k.A.</translation>
+ </message>
+ <message>
+ <source>Client version</source>
+ <translation>Clientversion</translation>
+ </message>
+ <message>
+ <source>&amp;Information</source>
+ <translation>Hinweis</translation>
+ </message>
+ <message>
+ <source>Debug window</source>
+ <translation>Debugfenster</translation>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>Allgemein</translation>
+ </message>
+ <message>
+ <source>Using OpenSSL version</source>
+ <translation>Verwendete OpenSSL-Version</translation>
+ </message>
+ <message>
+ <source>Using BerkeleyDB version</source>
+ <translation>Verwendete BerkeleyDB-Version</translation>
+ </message>
+ <message>
+ <source>Startup time</source>
+ <translation>Startzeit</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Netzwerk</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>Name</translation>
+ </message>
+ <message>
+ <source>Number of connections</source>
+ <translation>Anzahl Verbindungen</translation>
+ </message>
+ <message>
+ <source>Block chain</source>
+ <translation>Blockkette</translation>
+ </message>
+ <message>
+ <source>Current number of blocks</source>
+ <translation>Aktuelle Anzahl Blöcke</translation>
+ </message>
+ <message>
+ <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source>
+ <translation>Öffnet die "Bitcoin Core"-Debugprotokolldatei aus dem aktuellen Datenverzeichnis. Dies kann bei großen Protokolldateien einige Sekunden dauern.</translation>
+ </message>
+ <message>
+ <source>Received</source>
+ <translation>Empfangen</translation>
+ </message>
+ <message>
+ <source>Sent</source>
+ <translation>Übertragen</translation>
+ </message>
+ <message>
+ <source>&amp;Peers</source>
+ <translation>&amp;Gegenstellen</translation>
+ </message>
+ <message>
+ <source>Select a peer to view detailed information.</source>
+ <translation>Gegenstelle auswählen, um detaillierte Informationen zu erhalten.</translation>
+ </message>
+ <message>
+ <source>Direction</source>
+ <translation>Richtung</translation>
+ </message>
+ <message>
+ <source>Version</source>
+ <translation>Version</translation>
+ </message>
+ <message>
+ <source>User Agent</source>
+ <translation>User-Agent</translation>
+ </message>
+ <message>
+ <source>Services</source>
+ <translation>Dienste</translation>
+ </message>
+ <message>
+ <source>Starting Height</source>
+ <translation>Start-Höhe</translation>
+ </message>
+ <message>
+ <source>Sync Height</source>
+ <translation>Sync-Höhe</translation>
+ </message>
+ <message>
+ <source>Ban Score</source>
+ <translation>Sperrpunktzahl</translation>
+ </message>
+ <message>
+ <source>Connection Time</source>
+ <translation>Verbindungsdauer</translation>
+ </message>
+ <message>
+ <source>Last Send</source>
+ <translation>Letzte Übertragung</translation>
+ </message>
+ <message>
+ <source>Last Receive</source>
+ <translation>Letzter Empfang</translation>
+ </message>
+ <message>
+ <source>Bytes Sent</source>
+ <translation>Übertragene Byte</translation>
+ </message>
+ <message>
+ <source>Bytes Received</source>
+ <translation>Empfangene Byte</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Pingzeit</translation>
+ </message>
+ <message>
+ <source>Time Offset</source>
+ <translation>Zeitversatz</translation>
+ </message>
+ <message>
+ <source>Last block time</source>
+ <translation>Letzte Blockzeit</translation>
+ </message>
+ <message>
+ <source>&amp;Open</source>
+ <translation>&amp;Öffnen</translation>
+ </message>
+ <message>
+ <source>&amp;Console</source>
+ <translation>&amp;Konsole</translation>
+ </message>
+ <message>
+ <source>&amp;Network Traffic</source>
+ <translation>&amp;Netzwerkauslastung</translation>
+ </message>
+ <message>
+ <source>&amp;Clear</source>
+ <translation>&amp;Zurücksetzen</translation>
+ </message>
+ <message>
+ <source>Totals</source>
+ <translation>Gesamtbetrag:</translation>
+ </message>
+ <message>
+ <source>In:</source>
+ <translation>eingehend:</translation>
+ </message>
+ <message>
+ <source>Out:</source>
+ <translation>ausgehend:</translation>
+ </message>
+ <message>
+ <source>Build date</source>
+ <translation>Erstellungsdatum</translation>
+ </message>
+ <message>
+ <source>Debug log file</source>
+ <translation>Debugprotokolldatei</translation>
+ </message>
+ <message>
+ <source>Clear console</source>
+ <translation>Konsole zurücksetzen</translation>
+ </message>
+ <message>
+ <source>Welcome to the Bitcoin Core RPC console.</source>
+ <translation>Willkommen in der "Bitcoin Core"-RPC-Konsole.</translation>
+ </message>
+ <message>
+ <source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
+ <translation>Pfeiltaste hoch und runter, um den Verlauf durchzublättern und &lt;b&gt;Strg-L&lt;/b&gt;, um die Konsole zurückzusetzen.</translation>
+ </message>
+ <message>
+ <source>Type &lt;b&gt;help&lt;/b&gt; for an overview of available commands.</source>
+ <translation>Bitte &lt;b&gt;help&lt;/b&gt; eingeben, um eine Übersicht verfügbarer Befehle zu erhalten.</translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation>%1 B</translation>
+ </message>
+ <message>
+ <source>%1 KB</source>
+ <translation>%1 KB</translation>
+ </message>
+ <message>
+ <source>%1 MB</source>
+ <translation>%1 MB</translation>
+ </message>
+ <message>
+ <source>%1 GB</source>
+ <translation>%1 GB</translation>
+ </message>
+ <message>
+ <source>via %1</source>
+ <translation>über %1</translation>
+ </message>
+ <message>
+ <source>never</source>
+ <translation>nie</translation>
+ </message>
+ <message>
+ <source>Inbound</source>
+ <translation>eingehend</translation>
+ </message>
+ <message>
+ <source>Outbound</source>
+ <translation>ausgehend</translation>
+ </message>
+ <message>
+ <source>Unknown</source>
+ <translation>Unbekannt</translation>
+ </message>
+ <message>
+ <source>Fetching...</source>
+ <translation>Aktualisiere...</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Amount:</source>
+ <translation>&amp;Betrag:</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Bezeichnung:</translation>
+ </message>
+ <message>
+ <source>&amp;Message:</source>
+ <translation>&amp;Nachricht:</translation>
+ </message>
+ <message>
+ <source>Reuse one of the previously used receiving addresses. Reusing addresses has security and privacy issues. Do not use this unless re-generating a payment request made before.</source>
+ <translation>Eine der bereits verwendeten Empfangsadressen wiederverwenden. Addressen wiederzuverwenden birgt Sicherheits- und Datenschutzrisiken. Außer zum Neuerstellen einer bereits erzeugten Zahlungsanforderung sollten Sie dies nicht nutzen.</translation>
+ </message>
+ <message>
+ <source>R&amp;euse an existing receiving address (not recommended)</source>
+ <translation>Vorhandene Empfangsadresse &amp;wiederverwenden (nicht empfohlen)</translation>
+ </message>
+ <message>
+ <source>An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network.</source>
+ <translation>Eine optionale Nachricht, die an die Zahlungsanforderung angehängt wird. Sie wird angezeigt, wenn die Anforderung geöffnet wird. Hinweis: Diese Nachricht wird nicht mit der Zahlung über das Bitcoin-Netzwerk gesendet.</translation>
+ </message>
+ <message>
+ <source>An optional label to associate with the new receiving address.</source>
+ <translation>Eine optionale Bezeichnung, die der neuen Empfangsadresse zugeordnet wird.</translation>
+ </message>
+ <message>
+ <source>Use this form to request payments. All fields are &lt;b&gt;optional&lt;/b&gt;.</source>
+ <translation>Verwenden Sie dieses Formular, um Zahlungen anzufordern. Alle Felder sind &lt;b&gt;optional&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>An optional amount to request. Leave this empty or zero to not request a specific amount.</source>
+ <translation>Ein optional angeforderte Betrag. Lassen Sie dieses Feld leer oder setzen Sie es auf 0, um keinen spezifischen Betrag anzufordern.</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Alle Formularfelder zurücksetzen.</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation>Zurücksetzen</translation>
+ </message>
+ <message>
+ <source>Requested payments history</source>
+ <translation>Verlauf der angeforderten Zahlungen</translation>
+ </message>
+ <message>
+ <source>&amp;Request payment</source>
+ <translation>&amp;Zahlung anfordern</translation>
+ </message>
+ <message>
+ <source>Show the selected request (does the same as double clicking an entry)</source>
+ <translation>Ausgewählte Zahlungsanforderungen anzeigen (entspricht einem Doppelklick auf einen Eintrag)</translation>
+ </message>
+ <message>
+ <source>Show</source>
+ <translation>Anzeigen</translation>
+ </message>
+ <message>
+ <source>Remove the selected entries from the list</source>
+ <translation>Ausgewählte Einträge aus der Liste entfernen</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>Entfernen</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Bezeichnung kopieren</translation>
+ </message>
+ <message>
+ <source>Copy message</source>
+ <translation>Nachricht kopieren</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Betrag kopieren</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>QR Code</source>
+ <translation>QR-Code</translation>
+ </message>
+ <message>
+ <source>Copy &amp;URI</source>
+ <translation>&amp;URI kopieren</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Address</source>
+ <translation>&amp;Addresse kopieren</translation>
+ </message>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>Grafik &amp;speichern...</translation>
+ </message>
+ <message>
+ <source>Request payment to %1</source>
+ <translation>Zahlung anfordern an %1</translation>
+ </message>
+ <message>
+ <source>Payment information</source>
+ <translation>Zahlungsinformationen</translation>
+ </message>
+ <message>
+ <source>URI</source>
+ <translation>URI</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adresse</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Betrag</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Bezeichnung</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Nachricht</translation>
+ </message>
+ <message>
+ <source>Resulting URI too long, try to reduce the text for label / message.</source>
+ <translation>Resultierende URI ist zu lang, bitte den Text für Bezeichnung/Nachricht kürzen.</translation>
+ </message>
+ <message>
+ <source>Error encoding URI into QR Code.</source>
+ <translation>Beim Enkodieren der URI in den QR-Code ist ein Fehler aufgetreten.</translation>
+ </message>
+</context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Datum</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Bezeichnung</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Nachricht</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Betrag</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(keine Bezeichnung)</translation>
+ </message>
+ <message>
+ <source>(no message)</source>
+ <translation>(keine Nachricht)</translation>
+ </message>
+ <message>
+ <source>(no amount)</source>
+ <translation>(kein Betrag)</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Bitcoins überweisen</translation>
+ </message>
+ <message>
+ <source>Coin Control Features</source>
+ <translation>"Coin Control"-Funktionen</translation>
+ </message>
+ <message>
+ <source>Inputs...</source>
+ <translation>Eingaben...</translation>
+ </message>
+ <message>
+ <source>automatically selected</source>
+ <translation>automatisch ausgewählt</translation>
+ </message>
+ <message>
+ <source>Insufficient funds!</source>
+ <translation>Unzureichender Kontostand!</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Anzahl:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Byte:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Betrag:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Priorität:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Gebühr:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Abzüglich Gebühr:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Wechselgeld:</translation>
+ </message>
+ <message>
+ <source>If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address.</source>
+ <translation>Wenn dies aktivert, und die Wechselgeld-Adresse leer oder ungültig ist, wird das Wechselgeld einer neu erzeugten Adresse gutgeschrieben.</translation>
+ </message>
+ <message>
+ <source>Custom change address</source>
+ <translation>Benutzerdefinierte Wechselgeld-Adresse</translation>
+ </message>
+ <message>
+ <source>Transaction Fee:</source>
+ <translation>Transaktionsgebühr:</translation>
+ </message>
+ <message>
+ <source>Choose...</source>
+ <translation>Auswählen...</translation>
+ </message>
+ <message>
+ <source>collapse fee-settings</source>
+ <translation>Transaktionsgebühreneinstellungen ausblenden</translation>
+ </message>
+ <message>
+ <source>per kilobyte</source>
+ <translation>pro Kilobyte</translation>
+ </message>
+ <message>
+ <source>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "total at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source>
+ <translation>Wenn die benutzerdefinierte Gebühr 1000 Satoshis beträgt und die Transaktion nur 250 Byte groß ist, wird bei Auswahl von "pro Kilobyte" eine Gebühr in Höhe von 250 Satoshis, bei Auswahl von "Mindestbetrag" eine Gebühr in Höhe von 1000 Satoshis bezahlt. Bei Transaktionen die Größer als ein Kilobyte sind, werden bei beiden Optionen die Gebühren pro Kilobyte bezahlt.</translation>
+ </message>
+ <message>
+ <source>Hide</source>
+ <translation>Ausblenden</translation>
+ </message>
+ <message>
+ <source>total at least</source>
+ <translation>Mindestbetrag</translation>
+ </message>
+ <message>
+ <source>Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process.</source>
+ <translation>Nur die minimale Gebühr zu bezahlen ist so lange in Ordnung, wie weniger Transaktionsvolumen als Platz in den Blöcken vorhanden ist. Aber Vorsicht, diese Option kann dazu führen, dass Transaktionen nicht bestätigt werden, wenn mehr Bedarf an Bitcoin-Transaktionen besteht als das Netzwerk verarbeiten kann.</translation>
+ </message>
+ <message>
+ <source>(read the tooltip)</source>
+ <translation>(den Hinweistext lesen)</translation>
+ </message>
+ <message>
+ <source>Recommended:</source>
+ <translation>Empfehlungen:</translation>
+ </message>
+ <message>
+ <source>Custom:</source>
+ <translation>Benutzerdefiniert:</translation>
+ </message>
+ <message>
+ <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source>
+ <translation>(Intelligente Gebührenlogik ist noch nicht verfügbar. Normalerweise dauert dies einige Blöcke lang...)</translation>
+ </message>
+ <message>
+ <source>Confirmation time:</source>
+ <translation>Bestätigungszeit:</translation>
+ </message>
+ <message>
+ <source>normal</source>
+ <translation>normal</translation>
+ </message>
+ <message>
+ <source>fast</source>
+ <translation>schnell</translation>
+ </message>
+ <message>
+ <source>Send as zero-fee transaction if possible</source>
+ <translation>Wenn möglich als gebührenfreie Transaktion senden</translation>
+ </message>
+ <message>
+ <source>(confirmation may take longer)</source>
+ <translation>(Bestätigung kann länger dauern)</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>An mehrere Empfänger auf einmal überweisen</translation>
+ </message>
+ <message>
+ <source>Add &amp;Recipient</source>
+ <translation>Empfänger &amp;hinzufügen</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Alle Formularfelder zurücksetzen.</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>"Dust":</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>&amp;Zurücksetzen</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>Kontostand:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>Überweisung bestätigen</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>&amp;Überweisen</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>Überweisung bestätigen</translation>
+ </message>
+ <message>
+ <source>%1 to %2</source>
+ <translation>%1 an %2</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Anzahl kopieren</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Betrag kopieren</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Gebühr kopieren</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Abzüglich Gebühr kopieren</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Byte kopieren</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Priorität kopieren</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Wechselgeld kopieren</translation>
+ </message>
+ <message>
+ <source>or</source>
+ <translation>oder</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>Der zu zahlende Betrag muss größer als 0 sein.</translation>
+ </message>
+ <message>
+ <source>The amount exceeds your balance.</source>
+ <translation>Der angegebene Betrag übersteigt Ihren Kontostand.</translation>
+ </message>
+ <message>
+ <source>The total exceeds your balance when the %1 transaction fee is included.</source>
+ <translation>Der angegebene Betrag übersteigt aufgrund der Transaktionsgebühr in Höhe von %1 Ihren Kontostand.</translation>
+ </message>
+ <message>
+ <source>Transaction creation failed!</source>
+ <translation>Transaktionserstellung fehlgeschlagen!</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>Die Transaktion wurde abgelehnt! Dies kann passieren, wenn einige Bitcoins aus Ihrer Wallet bereits ausgegeben wurden. Beispielsweise weil Sie eine Kopie Ihrer wallet.dat genutzt, die Bitcoins dort ausgegeben haben und dies daher in der derzeit aktiven Wallet nicht vermerkt ist.</translation>
+ </message>
+ <message>
+ <source>A fee higher than %1 is considered an absurdly high fee.</source>
+ <translation>Eine höhere Gebühr als %1 wird als unsinnig hohe Gebühr angesehen.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>Zahlungsanforderung abgelaufen.</translation>
+ </message>
+ <message numerus="yes">
+ <source>Estimated to begin confirmation within %n block(s).</source>
+ <translation><numerusform>Voraussichtlicher Beginn der Bestätigung innerhalb von %n Block.</numerusform><numerusform>Voraussichtlicher Beginn der Bestätigung innerhalb von %n Blöcken.</numerusform></translation>
+ </message>
+ <message>
+ <source>Pay only the minimum fee of %1</source>
+ <translation>Nur die minimale Gebühr in Höhe von %1 zahlen</translation>
+ </message>
+ <message>
+ <source>Total Amount %1&lt;span style='font-size:10pt;font-weight:normal;'&gt;&lt;br /&gt;(=%2)&lt;/span&gt;</source>
+ <translation>Gesamtbetrag %1&lt;span style='font-size:10pt;font-weight:normal;'&gt;&lt;br /&gt;(=%2)&lt;/span&gt;</translation>
+ </message>
+ <message>
+ <source>The recipient address is not valid. Please recheck.</source>
+ <translation>Die Zahlungsadresse ist ungültig, bitte nochmals überprüfen.</translation>
+ </message>
+ <message>
+ <source>Duplicate address found: addresses should only be used once each.</source>
+ <translation>Doppelte Adresse entdeckt: Adressen dürfen jeweils nur einmal vorkommen.</translation>
+ </message>
+ <message>
+ <source>Warning: Invalid Bitcoin address</source>
+ <translation>Warnung: Ungültige Bitcoin-Adresse</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(keine Bezeichnung)</translation>
+ </message>
+ <message>
+ <source>Warning: Unknown change address</source>
+ <translation>Warnung: Unbekannte Wechselgeld-Adresse</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>"Dust" kopieren</translation>
+ </message>
+ <message>
+ <source>Are you sure you want to send?</source>
+ <translation>Wollen Sie die Überweisung ausführen?</translation>
+ </message>
+ <message>
+ <source>added as transaction fee</source>
+ <translation>als Transaktionsgebühr hinzugefügt</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>Betra&amp;g:</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>E&amp;mpfänger:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Adressbezeichnung eingeben (diese wird zusammen mit der Adresse dem Adressbuch hinzugefügt)</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Bezeichnung:</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Bereits verwendete Adresse auswählen</translation>
+ </message>
+ <message>
+ <source>This is a normal payment.</source>
+ <translation>Dies ist eine normale Überweisung.</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to send the payment to</source>
+ <translation>Die Zahlungsadresse der Überweisung</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Adresse aus der Zwischenablage einfügen</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Remove this entry</source>
+ <translation>Diesen Eintrag entfernen</translation>
+ </message>
+ <message>
+ <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source>
+ <translation>Die Gebühr wird vom zu überweisenden Betrag abgezogen. Der Empfänger wird also weniger Bitcoins erhalten, als Sie im Betrags-Feld eingegeben haben. Falls mehrere Empfänger ausgewählt wurden, wird die Gebühr gleichmäßig verteilt.</translation>
+ </message>
+ <message>
+ <source>S&amp;ubtract fee from amount</source>
+ <translation>Gebühr vom Betrag ab&amp;ziehen</translation>
+ </message>
+ <message>
+ <source>Message:</source>
+ <translation>Nachricht:</translation>
+ </message>
+ <message>
+ <source>This is an unauthenticated payment request.</source>
+ <translation>Dies ist keine beglaubigte Zahlungsanforderung.</translation>
+ </message>
+ <message>
+ <source>This is an authenticated payment request.</source>
+ <translation>Dies ist eine beglaubigte Zahlungsanforderung.</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to the list of used addresses</source>
+ <translation>Adressbezeichnung eingeben, die dann zusammen mit der Adresse der Liste bereits verwendeter Adressen hinzugefügt wird.</translation>
+ </message>
+ <message>
+ <source>A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network.</source>
+ <translation>Eine an die "bitcoin:"-URI angefügte Nachricht, die zusammen mit der Transaktion gespeichert wird. Hinweis: Diese Nachricht wird nicht über das Bitcoin-Netzwerk gesendet.</translation>
+ </message>
+ <message>
+ <source>Pay To:</source>
+ <translation>Empfänger:</translation>
+ </message>
+ <message>
+ <source>Memo:</source>
+ <translation>Memo:</translation>
+ </message>
+</context>
+<context>
+ <name>ShutdownWindow</name>
+ <message>
+ <source>Bitcoin Core is shutting down...</source>
+ <translation>Bitcoin Core wird beendet...</translation>
+ </message>
+ <message>
+ <source>Do not shut down the computer until this window disappears.</source>
+ <translation>Fahren Sie den Computer nicht herunter, bevor dieses Fenster verschwindet.</translation>
+ </message>
+</context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Signatures - Sign / Verify a Message</source>
+ <translation>Signaturen - eine Nachricht signieren / verifizieren</translation>
+ </message>
+ <message>
+ <source>&amp;Sign Message</source>
+ <translation>Nachricht &amp;signieren</translation>
+ </message>
+ <message>
+ <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source>
+ <translation>Sie können Nachrichten/Vereinbarungen mit Hilfe Ihrer Adressen signieren, um zu beweisen, dass Sie Bitcoins empfangen können, die an diese Adressen überwiesen werden. Seien Sie vorsichtig und signieren Sie nichts Vages oder Willkürliches, um Ihre Indentität vor Phishingangriffen zu schützen. Signieren Sie nur vollständig-detaillierte Aussagen, mit denen Sie auch einverstanden sind.</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to sign the message with</source>
+ <translation>Die Bitcoin-Adresse mit der die Nachricht signiert wird</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Bereits verwendete Adresse auswählen</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Adresse aus der Zwischenablage einfügen</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Enter the message you want to sign here</source>
+ <translation>Zu signierende Nachricht hier eingeben</translation>
+ </message>
+ <message>
+ <source>Signature</source>
+ <translation>Signatur</translation>
+ </message>
+ <message>
+ <source>Copy the current signature to the system clipboard</source>
+ <translation>Aktuelle Signatur in die Zwischenablage kopieren</translation>
+ </message>
+ <message>
+ <source>Sign the message to prove you own this Bitcoin address</source>
+ <translation>Die Nachricht signieren, um den Besitz dieser Bitcoin-Adresse zu beweisen</translation>
+ </message>
+ <message>
+ <source>Sign &amp;Message</source>
+ <translation>&amp;Nachricht signieren</translation>
+ </message>
+ <message>
+ <source>Reset all sign message fields</source>
+ <translation>Alle "Nachricht signieren"-Felder zurücksetzen</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>&amp;Zurücksetzen</translation>
+ </message>
+ <message>
+ <source>&amp;Verify Message</source>
+ <translation>Nachricht &amp;verifizieren</translation>
+ </message>
+ <message>
+ <source>Enter the receiver's 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. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source>
+ <translation>Geben Sie die Zahlungsadresse des Empfängers, Nachricht (achten Sie darauf Zeilenumbrüche, Leerzeichen, Tabulatoren usw. exakt zu kopieren) und Signatur unten ein, um die Nachricht zu verifizieren. Vorsicht, interpretieren Sie nicht mehr in die Signatur hinein, als in der signierten Nachricht selber enthalten ist, um nicht von einem Man-in-the-middle-Angriff hinters Licht geführt zu werden. Beachten Sie dass dies nur beweißt, dass die signierende Partei über diese Adresse Überweisungen empfangen kann.</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address the message was signed with</source>
+ <translation>Die Bitcoin-Adresse mit der die Nachricht signiert wurde</translation>
+ </message>
+ <message>
+ <source>Verify the message to ensure it was signed with the specified Bitcoin address</source>
+ <translation>Die Nachricht verifizieren, um sicherzustellen, dass diese mit der angegebenen Bitcoin-Adresse signiert wurde</translation>
+ </message>
+ <message>
+ <source>Verify &amp;Message</source>
+ <translation>&amp;Nachricht verifizieren</translation>
+ </message>
+ <message>
+ <source>Reset all verify message fields</source>
+ <translation>Alle "Nachricht verifizieren"-Felder zurücksetzen</translation>
+ </message>
+ <message>
+ <source>Click "Sign Message" to generate signature</source>
+ <translation>Auf "Nachricht signieren" klicken, um die Signatur zu erzeugen</translation>
+ </message>
+ <message>
+ <source>The entered address is invalid.</source>
+ <translation>Die eingegebene Adresse ist ungültig.</translation>
+ </message>
+ <message>
+ <source>Please check the address and try again.</source>
+ <translation>Bitte überprüfen Sie die Adresse und versuchen Sie es erneut.</translation>
+ </message>
+ <message>
+ <source>The entered address does not refer to a key.</source>
+ <translation>Die eingegebene Adresse verweist nicht auf einen Schlüssel.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock was cancelled.</source>
+ <translation>Wallet-Entsperrung wurde abgebrochen.</translation>
+ </message>
+ <message>
+ <source>Private key for the entered address is not available.</source>
+ <translation>Privater Schlüssel zur eingegebenen Adresse ist nicht verfügbar.</translation>
+ </message>
+ <message>
+ <source>Message signing failed.</source>
+ <translation>Signierung der Nachricht fehlgeschlagen.</translation>
+ </message>
+ <message>
+ <source>Message signed.</source>
+ <translation>Nachricht signiert.</translation>
+ </message>
+ <message>
+ <source>The signature could not be decoded.</source>
+ <translation>Die Signatur konnte nicht dekodiert werden.</translation>
+ </message>
+ <message>
+ <source>Please check the signature and try again.</source>
+ <translation>Bitte überprüfen Sie die Signatur und versuchen Sie es erneut.</translation>
+ </message>
+ <message>
+ <source>The signature did not match the message digest.</source>
+ <translation>Die Signatur entspricht nicht dem "Message Digest".</translation>
+ </message>
+ <message>
+ <source>Message verification failed.</source>
+ <translation>Verifikation der Nachricht fehlgeschlagen.</translation>
+ </message>
+ <message>
+ <source>Message verified.</source>
+ <translation>Nachricht verifiziert.</translation>
+ </message>
+</context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>The Bitcoin Core developers</source>
+ <translation>Die "Bitcoin Core"-Entwickler</translation>
+ </message>
+ <message>
+ <source>[testnet]</source>
+ <translation>[Testnetz]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ <message>
+ <source>KB/s</source>
+ <translation>KB/s</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>Offen bis %1</translation>
+ </message>
+ <message>
+ <source>conflicted</source>
+ <translation>in Konflikt stehend</translation>
+ </message>
+ <message>
+ <source>%1/offline</source>
+ <translation>%1/offline</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/unbestätigt</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 Bestätigungen</translation>
+ </message>
+ <message>
+ <source>Status</source>
+ <translation>Status</translation>
+ </message>
+ <message numerus="yes">
+ <source>, broadcast through %n node(s)</source>
+ <translation><numerusform>, über %n Knoten übertragen</numerusform><numerusform>, über %n Knoten übertragen</numerusform></translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Datum</translation>
+ </message>
+ <message>
+ <source>Source</source>
+ <translation>Quelle</translation>
+ </message>
+ <message>
+ <source>Generated</source>
+ <translation>Erzeugt</translation>
+ </message>
+ <message>
+ <source>From</source>
+ <translation>Von</translation>
+ </message>
+ <message>
+ <source>To</source>
+ <translation>An</translation>
+ </message>
+ <message>
+ <source>own address</source>
+ <translation>eigene Adresse</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>beobachtet</translation>
+ </message>
+ <message>
+ <source>label</source>
+ <translation>Bezeichnung</translation>
+ </message>
+ <message>
+ <source>Credit</source>
+ <translation>Gutschrift</translation>
+ </message>
+ <message numerus="yes">
+ <source>matures in %n more block(s)</source>
+ <translation><numerusform>reift noch %n weiteren Block</numerusform><numerusform>reift noch %n weitere Blöcke</numerusform></translation>
+ </message>
+ <message>
+ <source>not accepted</source>
+ <translation>nicht angenommen</translation>
+ </message>
+ <message>
+ <source>Debit</source>
+ <translation>Belastung</translation>
+ </message>
+ <message>
+ <source>Total debit</source>
+ <translation>Gesamtbelastung</translation>
+ </message>
+ <message>
+ <source>Total credit</source>
+ <translation>Gesamtgutschrift</translation>
+ </message>
+ <message>
+ <source>Transaction fee</source>
+ <translation>Transaktionsgebühr</translation>
+ </message>
+ <message>
+ <source>Net amount</source>
+ <translation>Nettobetrag</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Nachricht</translation>
+ </message>
+ <message>
+ <source>Comment</source>
+ <translation>Kommentar</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>Transaktions-ID</translation>
+ </message>
+ <message>
+ <source>Merchant</source>
+ <translation>Händler</translation>
+ </message>
+ <message>
+ <source>Generated coins must mature %1 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.</source>
+ <translation>Erzeugte Bitcoins müssen %1 Blöcke lang reifen, bevor sie ausgegeben werden können. Als Sie diesen Block erzeugten, 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 Sie werden keine Bitcoins gutgeschrieben bekommen. Das kann gelegentlich passieren, wenn ein anderer Knoten einen Block fast zeitgleich erzeugt.</translation>
+ </message>
+ <message>
+ <source>Debug information</source>
+ <translation>Debuginformationen</translation>
+ </message>
+ <message>
+ <source>Transaction</source>
+ <translation>Transaktion</translation>
+ </message>
+ <message>
+ <source>Inputs</source>
+ <translation>Eingaben</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Betrag</translation>
+ </message>
+ <message>
+ <source>true</source>
+ <translation>wahr</translation>
+ </message>
+ <message>
+ <source>false</source>
+ <translation>falsch</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, wurde noch nicht erfolgreich übertragen</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Offen für %n weiteren Block</numerusform><numerusform>Offen für %n weitere Blöcke</numerusform></translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>unbekannt</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>Transaktionsdetails</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>Dieser Bereich zeigt eine detaillierte Beschreibung der Transaktion an</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Datum</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Typ</translation>
+ </message>
+ <message>
+ <source>Immature (%1 confirmations, will be available after %2)</source>
+ <translation>Unreif (%1 Bestätigungen, wird verfügbar sein nach %2)</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Offen für %n weiteren Block</numerusform><numerusform>Offen für %n weitere Blöcke</numerusform></translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>Offen bis %1</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>Bestätigt (%1 Bestätigungen)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>Dieser Block wurde von keinem anderen Knoten empfangen und wird wahrscheinlich nicht angenommen werden!</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>Erzeugt, jedoch nicht angenommen</translation>
+ </message>
+ <message>
+ <source>Offline</source>
+ <translation>Offline</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Bezeichnung</translation>
+ </message>
+ <message>
+ <source>Unconfirmed</source>
+ <translation>Unbestätigt</translation>
+ </message>
+ <message>
+ <source>Confirming (%1 of %2 recommended confirmations)</source>
+ <translation>Wird bestätigt (%1 von %2 empfohlenen Bestätigungen)</translation>
+ </message>
+ <message>
+ <source>Conflicted</source>
+ <translation>in Konflikt stehend</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Empfangen über</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>Empfangen von</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Überwiesen an</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>Eigenüberweisung</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Erarbeitet</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>beobachtet</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(k.A.)</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>Transaktionsstatus, fahren Sie mit der Maus über dieses Feld, um die Anzahl der Bestätigungen zu sehen.</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Datum und Uhrzeit zu der die Transaktion empfangen wurde.</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>Art der Transaktion</translation>
+ </message>
+ <message>
+ <source>Whether or not a watch-only address is involved in this transaction.</source>
+ <translation>Zeigt an, ob eine beobachtete Adresse in diese Transaktion involviert ist.</translation>
+ </message>
+ <message>
+ <source>User-defined intent/purpose of the transaction.</source>
+ <translation>Benutzerdefinierte Absicht bzw. Verwendungszweck der Transaktion</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>Der Betrag, der dem Kontostand abgezogen oder hinzugefügt wurde.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>Alle</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>Heute</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>Diese Woche</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>Diesen Monat</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>Letzten Monat</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>Dieses Jahr</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>Zeitraum</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Empfangen über</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Überwiesen an</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>Eigenüberweisung</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Erarbeitet</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>Andere</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>Zu suchende Adresse oder Bezeichnung eingeben</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>Minimaler Betrag</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Adresse kopieren</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Bezeichnung kopieren</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Betrag kopieren</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Transaktions-ID kopieren</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>Bezeichnung bearbeiten</translation>
+ </message>
+ <message>
+ <source>Show transaction details</source>
+ <translation>Transaktionsdetails anzeigen</translation>
+ </message>
+ <message>
+ <source>Export Transaction History</source>
+ <translation>Transaktionsverlauf exportieren</translation>
+ </message>
+ <message>
+ <source>Watch-only</source>
+ <translation>Beobachtet</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Exportieren fehlgeschlagen</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the transaction history to %1.</source>
+ <translation>Beim Speichern des Transaktionsverlaufs nach %1 ist ein Fehler aufgetreten.</translation>
+ </message>
+ <message>
+ <source>Exporting Successful</source>
+ <translation>Exportieren erfolgreich</translation>
+ </message>
+ <message>
+ <source>The transaction history was successfully saved to %1.</source>
+ <translation>Speichern des Transaktionsverlaufs nach %1 war erfolgreich.</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Kommagetrennte-Datei (*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Bestätigt</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Datum</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Typ</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Bezeichnung</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adresse</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>Zeitraum:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>bis</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ <message>
+ <source>Unit to show amounts in. Click to select another unit.</source>
+ <translation>Die Einheit in der Beträge angezeigt werden. Klicken, um eine andere Einheit auszuwählen.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletFrame</name>
+ <message>
+ <source>No wallet has been loaded.</source>
+ <translation>Es wurde keine Wallet geladen.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Bitcoins überweisen</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>E&amp;xportieren</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Daten der aktuellen Ansicht in eine Datei exportieren</translation>
+ </message>
+ <message>
+ <source>Backup Wallet</source>
+ <translation>Wallet sichern</translation>
+ </message>
+ <message>
+ <source>Wallet Data (*.dat)</source>
+ <translation>Wallet-Daten (*.dat)</translation>
+ </message>
+ <message>
+ <source>Backup Failed</source>
+ <translation>Sicherung fehlgeschlagen</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the wallet data to %1.</source>
+ <translation>Beim Speichern der Wallet-Daten nach %1 ist ein Fehler aufgetreten.</translation>
+ </message>
+ <message>
+ <source>The wallet data was successfully saved to %1.</source>
+ <translation>Speichern der Wallet-Daten nach %1 war erfolgreich.</translation>
+ </message>
+ <message>
+ <source>Backup Successful</source>
+ <translation>Sicherung erfolgreich</translation>
+ </message>
+</context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>Optionen:</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>Datenverzeichnis festlegen</translation>
+ </message>
+ <message>
+ <source>Connect to a node to retrieve peer addresses, and disconnect</source>
+ <translation>Mit dem angegebenen Knoten verbinden, um Adressen von Gegenstellen abzufragen, danach trennen</translation>
+ </message>
+ <message>
+ <source>Specify your own public address</source>
+ <translation>Die eigene öffentliche Adresse angeben</translation>
+ </message>
+ <message>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>Kommandozeilen- und JSON-RPC-Befehle annehmen</translation>
+ </message>
+ <message>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>Als Hintergrunddienst ausführen und Befehle annehmen</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>Das Testnetz verwenden</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
+ <translation>Eingehende Verbindungen annehmen (Standard: 1, wenn nicht -proxy oder -connect)</translation>
+ </message>
+ <message>
+ <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
+ <translation>An die angegebene Adresse binden und immer abhören. Für IPv6 "[Host]:Port"-Notation verwenden</translation>
+ </message>
+ <message>
+ <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
+ <translation>Alle Wallet-Transaktionen löschen und nur diese Teilbereiche der Blockkette durch -rescan beim Starten wiederherstellen</translation>
+ </message>
+ <message>
+ <source>Distributed under the MIT software license, see the accompanying file COPYING or &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</source>
+ <translation>Veröffentlicht unter der MIT-Softwarelizenz, siehe beiligende Datei COPYING oder &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</translation>
+ </message>
+ <message>
+ <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
+ <translation>Befehl ausführen wenn sich eine Wallet-Transaktion verändert (%s im Befehl wird durch die Transaktions-ID ersetzt)</translation>
+ </message>
+ <message>
+ <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source>
+ <translation>Maximale Gesamtgebühren je Wallet-Transaktion, ein zu niedriger Wert kann große Transaktionen abbrechen (Standard: %s)</translation>
+ </message>
+ <message>
+ <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, &gt;%u = target size in MiB to use for block files)</source>
+ <translation>Speicherplatzanforderung durch kürzen (löschen) alter Blöcke reduzieren. Dieser Modus deaktiviert die Wallet-Unterstützung und ist nicht mit -txindex kompatibel. Warnung: Die Umkehr dieser Einstellung erfordert das erneute Herunterladen der gesamten Blockkette. (Standard: 0 = deaktiviert das Kürzen von Blöcken, &gt;%u = Zielgröße in MiB, die für Blockdateien verwendet werden darf)</translation>
+ </message>
+ <message>
+ <source>Set the number of script verification threads (%u to %d, 0 = auto, &lt;0 = leave that many cores free, default: %d)</source>
+ <translation>Maximale Anzahl an Skript-Verifizierungs-Threads festlegen (%u bis %d, 0 = automatisch, &lt;0 = so viele Kerne frei lassen, Standard: %d)</translation>
+ </message>
+ <message>
+ <source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source>
+ <translation>Dies ist eine Vorab-Testversion - Verwendung auf eigene Gefahr - nicht für Mining- oder Handelsanwendungen nutzen!</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer. Bitcoin Core is probably already running.</source>
+ <translation>Kann auf diesem Computer nicht an %s binden, da Bitcoin Core wahrscheinlich bereits gestartet wurde.</translation>
+ </message>
+ <message>
+ <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>Warnung: Es wurde eine ungewöhnlich hohe Anzahl Blöcke erzeugt, %d Blöcke wurden in den letzten %d Stunden empfangen (%d wurden erwartet).</translation>
+ </message>
+ <message>
+ <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>Warnung: Überprüpfen Sie ihre Netzwerkverbindung, %d Blöcke wurden in den letzten %d Stunden empfangen (%d wurden erwartet).</translation>
+ </message>
+ <message>
+ <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>Warnung: -paytxfee ist auf einen sehr hohen Wert festgelegt! Dies ist die Gebühr die beim Senden einer Transaktion fällig wird.</translation>
+ </message>
+ <message>
+ <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source>
+ <translation>Warnung: Das Netzwerk scheint nicht vollständig übereinzustimmen! Einige Miner scheinen Probleme zu haben.</translation>
+ </message>
+ <message>
+ <source>Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.</source>
+ <translation>Warnung: Wir scheinen nicht vollständig mit unseren Gegenstellen übereinzustimmen! Sie oder die anderen Knoten müssen unter Umständen Ihre Client-Software aktualisieren.</translation>
+ </message>
+ <message>
+ <source>Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
+ <translation>Warnung: Lesen von wallet.dat fehlgeschlagen! Alle Schlüssel wurden korrekt gelesen, Transaktionsdaten bzw. Adressbucheinträge fehlen aber möglicherweise oder sind inkorrekt.</translation>
+ </message>
+ <message>
+ <source>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</source>
+ <translation>Warnung: wallet.dat beschädigt, Datenrettung erfolgreich! Original wallet.dat wurde als wallet.{Zeitstempel}.dat in %s gespeichert. Falls Ihr Kontostand oder Transaktionen nicht korrekt sind, sollten Sie von einer Datensicherung wiederherstellen.</translation>
+ </message>
+ <message>
+ <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source>
+ <translation>Gegenstellen die sich von der angegebenen Netzmaske oder IP-Adresse aus verbinden immer zulassen. Kann mehrmals angegeben werden.</translation>
+ </message>
+ <message>
+ <source>(default: 1)</source>
+ <translation>(Standard: 1)</translation>
+ </message>
+ <message>
+ <source>&lt;category&gt; can be:</source>
+ <translation>&lt;category&gt; kann sein:</translation>
+ </message>
+ <message>
+ <source>Attempt to recover private keys from a corrupt wallet.dat</source>
+ <translation>Versuchen, private Schlüssel aus einer beschädigten wallet.dat wiederherzustellen</translation>
+ </message>
+ <message>
+ <source>Block creation options:</source>
+ <translation>Blockerzeugungsoptionen:</translation>
+ </message>
+ <message>
+ <source>Connect only to the specified node(s)</source>
+ <translation>Mit nur dem oder den angegebenen Knoten verbinden</translation>
+ </message>
+ <message>
+ <source>Connection options:</source>
+ <translation>Verbindungsoptionen:</translation>
+ </message>
+ <message>
+ <source>Corrupted block database detected</source>
+ <translation>Beschädigte Blockdatenbank erkannt</translation>
+ </message>
+ <message>
+ <source>Debugging/Testing options:</source>
+ <translation>Debugging-/Testoptionen:</translation>
+ </message>
+ <message>
+ <source>Do not load the wallet and disable wallet RPC calls</source>
+ <translation>Die Wallet nicht laden und Wallet-RPC-Aufrufe deaktivieren</translation>
+ </message>
+ <message>
+ <source>Do you want to rebuild the block database now?</source>
+ <translation>Möchten Sie die Blockdatenbank jetzt neu aufbauen?</translation>
+ </message>
+ <message>
+ <source>Error initializing block database</source>
+ <translation>Fehler beim Initialisieren der Blockdatenbank</translation>
+ </message>
+ <message>
+ <source>Error initializing wallet database environment %s!</source>
+ <translation>Fehler beim Initialisieren der Wallet-Datenbankumgebung %s!</translation>
+ </message>
+ <message>
+ <source>Error loading block database</source>
+ <translation>Fehler beim Laden der Blockdatenbank</translation>
+ </message>
+ <message>
+ <source>Error opening block database</source>
+ <translation>Fehler beim Öffnen der Blockdatenbank</translation>
+ </message>
+ <message>
+ <source>Error: Disk space is low!</source>
+ <translation>Fehler: Zu wenig freier Speicherplatz auf dem Datenträger!</translation>
+ </message>
+ <message>
+ <source>Failed to listen on any port. Use -listen=0 if you want this.</source>
+ <translation>Fehler, es konnte kein Port abgehört werden. Wenn dies so gewünscht wird -listen=0 verwenden.</translation>
+ </message>
+ <message>
+ <source>If &lt;category&gt; is not supplied, output all debugging information.</source>
+ <translation>Wenn &lt;category&gt; nicht angegeben wird, jegliche Debugginginformationen ausgeben.</translation>
+ </message>
+ <message>
+ <source>Importing...</source>
+ <translation>Importiere...</translation>
+ </message>
+ <message>
+ <source>Incorrect or no genesis block found. Wrong datadir for network?</source>
+ <translation>Fehlerhafter oder kein Genesis-Block gefunden. Falsches Datenverzeichnis für das Netzwerk?</translation>
+ </message>
+ <message>
+ <source>Invalid -onion address: '%s'</source>
+ <translation>Ungültige "-onion"-Adresse: '%s'</translation>
+ </message>
+ <message>
+ <source>Not enough file descriptors available.</source>
+ <translation>Nicht genügend Datei-Deskriptoren verfügbar.</translation>
+ </message>
+ <message>
+ <source>Only connect to nodes in network &lt;net&gt; (ipv4, ipv6 or onion)</source>
+ <translation>Nur zu Knoten des Netzwerktyps &lt;net&gt; verbinden (ipv4, ipv6 oder onion)</translation>
+ </message>
+ <message>
+ <source>Prune cannot be configured with a negative value.</source>
+ <translation>Kürzungsmodus kann nicht mit einem negativen Wert konfiguriert werden.</translation>
+ </message>
+ <message>
+ <source>Prune mode is incompatible with -txindex.</source>
+ <translation>Kürzungsmodus ist nicht mit -txindex kompatibel.</translation>
+ </message>
+ <message>
+ <source>Set database cache size in megabytes (%d to %d, default: %d)</source>
+ <translation>Größe des Datenbankcaches in Megabyte festlegen (%d bis %d, Standard: %d)</translation>
+ </message>
+ <message>
+ <source>Set maximum block size in bytes (default: %d)</source>
+ <translation>Maximale Blockgröße in Byte festlegen (Standard: %d)</translation>
+ </message>
+ <message>
+ <source>Specify wallet file (within data directory)</source>
+ <translation>Wallet-Datei angeben (innerhalb des Datenverzeichnisses)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: %u)</source>
+ <translation>UPnP verwenden, um eine Portweiterleitung einzurichten (Standard: %u)</translation>
+ </message>
+ <message>
+ <source>Verifying blocks...</source>
+ <translation>Verifiziere Blöcke...</translation>
+ </message>
+ <message>
+ <source>Verifying wallet...</source>
+ <translation>Verifiziere Wallet...</translation>
+ </message>
+ <message>
+ <source>Wallet %s resides outside data directory %s</source>
+ <translation>Wallet %s liegt außerhalb des Datenverzeichnisses %s</translation>
+ </message>
+ <message>
+ <source>Wallet options:</source>
+ <translation>Wallet-Optionen:</translation>
+ </message>
+ <message>
+ <source>Warning: This version is obsolete; upgrade required!</source>
+ <translation>Warnung: Diese Version is veraltet, Aktualisierung erforderlich!</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to change -txindex</source>
+ <translation>Sie müssen die Datenbank mit Hilfe von -reindex neu aufbauen, um -txindex zu verändern</translation>
+ </message>
+ <message>
+ <source>Imports blocks from external blk000??.dat file</source>
+ <translation>Blöcke aus externer Datei blk000??.dat importieren</translation>
+ </message>
+ <message>
+ <source>Allow JSON-RPC connections from specified source. Valid for &lt;ip&gt; are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times</source>
+ <translation>JSON-RPC-Verbindungen von der angegeben Quelle erlauben. Gültig für &lt;ip&gt; ist eine einzelne IP-Adresse (z.B. 1.2.3.4), ein Netzwerk bzw. eine Netzmaske (z.B. 1.2.3.4/255.255.255.0), oder die CIDR-Notation (z.B. 1.2.3.4/24). Kann mehrmals angegeben werden.</translation>
+ </message>
+ <message>
+ <source>An error occurred while setting up the RPC address %s port %u for listening: %s</source>
+ <translation>Beim Einrichten der abzuhörenden RPC-Adresse %s auf Port %u ist ein Fehler aufgetreten: %s</translation>
+ </message>
+ <message>
+ <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source>
+ <translation>An die angegebene Adresse binden und Gegenstellen, die sich dorthin verbinden, immer zulassen. Für IPv6 "[Host]:Port"-Notation verwenden</translation>
+ </message>
+ <message>
+ <source>Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)</source>
+ <translation>An die angegebene Adresse binden und nach eingehenden JSON-RPC-Verbindungen abhören. Für IPv6 "[Host]:Port"-Notation verwenden. Kann mehrmals angegeben werden. (Standard: an alle Schnittstellen binden)</translation>
+ </message>
+ <message>
+ <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source>
+ <translation>Datenverzeichnis %s kann nicht gesperrt werden, da Bitcoin Core wahrscheinlich bereits gestartet wurde.</translation>
+ </message>
+ <message>
+ <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
+ <translation>Neue Dateien mit Standard-Systemrechten erzeugen, anstatt mit umask 077 (nur mit deaktivierter Walletfunktion nutzbar)</translation>
+ </message>
+ <message>
+ <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source>
+ <translation>Eigene IP-Adressen ermitteln (Standard: 1, wenn abgehört wird und nicht -externalip oder -proxy)</translation>
+ </message>
+ <message>
+ <source>Error: Listening for incoming connections failed (listen returned error %s)</source>
+ <translation>Fehler: Abhören nach eingehenden Verbindungen fehlgeschlagen (listen meldete Fehler %s)</translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source>
+ <translation>Fehler: Nicht unterstütztes Argument -socks gefunden. Das Festlegen der SOCKS-Version ist nicht mehr möglich, nur noch SOCKS5-Proxies werden unterstützt.</translation>
+ </message>
+ <message>
+ <source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source>
+ <translation>Befehl ausführen wenn ein relevanter Alarm empfangen wird oder wir einen wirklich langen Fork entdecken (%s im Befehl wird durch die Nachricht ersetzt)</translation>
+ </message>
+ <message>
+ <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source>
+ <translation>Niedrigere Gebühren (in BTC/Kb) als diese werden bei der Weiterleitung als gebührenfrei angesehen (Standard: %s)</translation>
+ </message>
+ <message>
+ <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
+ <translation>Wenn -paytxfee nicht festgelegt wurde Gebühren einschließen, so dass mit der Bestätigung von Transaktionen im Schnitt innerhalb von n Blöcken begonnen wird (Standard: %u)</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)</source>
+ <translation>Ungültiger Betrag für -maxtxfee=&lt;amount&gt;: '%s' (muss mindestens die minimale Weiterleitungsgebühr in Höhe von %s sein, um zu verhindern dass Transaktionen nicht bearbeitet werden)</translation>
+ </message>
+ <message>
+ <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source>
+ <translation>Maximale Datengröße in "Data Carrier"-Transaktionen die weitergeleitet und erarbeitet werden (Standard: %u)</translation>
+ </message>
+ <message>
+ <source>Prune configured below the minimum of %d MB. Please use a higher number.</source>
+ <translation>Kürzungsmodus wurde kleiner als das Minimum in Höhe von %d MiB konfiguriert. Bitte verwenden Sie einen größeren Wert.</translation>
+ </message>
+ <message>
+ <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source>
+ <translation>Adressen von Gegenstellen via DNS-Namensauflösung finden, falls zu wenige Adressen verfügbar sind (Standard: 1, außer bei -connect)</translation>
+ </message>
+ <message>
+ <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source>
+ <translation>Zufällige Anmeldedaten für jede Proxyverbindung verwenden. Dies aktiviert Tor-Datenflussisolation (Standard: %u)</translation>
+ </message>
+ <message>
+ <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
+ <translation>Maximale Größe in Byte von "high-priority/low-fee"-Transaktionen festlegen (Standard: %d)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source>
+ <translation>Maximale Anzahl an Threads zur Bitcoinerzeugung, wenn aktiviert, festlegen (-1 = alle Kerne, Standard: %d)</translation>
+ </message>
+ <message>
+ <source>The transaction amount is too small to send after the fee has been deducted</source>
+ <translation>Der Transaktionsbetrag ist zum senden zu niedrig, nachdem die Gebühr abgezogen wurde.</translation>
+ </message>
+ <message>
+ <source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit &lt;https://www.openssl.org/&gt; and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source>
+ <translation>Dieses Produkt enthält Software, die vom OpenSSL-Projekt zur Verwendung im OpenSSL-Toolkit &lt;https://www.openssl.org/&gt; entwickelt wird, sowie von Eric Young geschriebene kryptographische Software und von Thomas Bernard geschriebene UPnP-Software.</translation>
+ </message>
+ <message>
+ <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an 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)
+The username and password MUST NOT be the same.
+If the file does not exist, create it with owner-readable-only file permissions.
+It is also recommended to set alertnotify so you are notified of problems;
+for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
+</source>
+ <translation>Um bitcoind oder die Option -server mit bitcoin-qt verwenden zu können, müssen Sie rpcpassword 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!)
+Der Benutzername und das Passwort dürfen NICHT identisch sein.
+Falls die Konfigurationsdatei nicht existiert, erzeugen Sie diese bitte mit Leserechten nur für den Dateibesitzer.
+Es wird ebenfalls empfohlen alertnotify anzugeben, um im Problemfall benachrichtigt zu werden.
+Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
+</translation>
+ </message>
+ <message>
+ <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source>
+ <translation>Warnung: -maxtxfee ist auf einen sehr hohen Wert festgelegt! Gebühren dieser Höhe könnten für eine einzelne Transaktion bezahlt werden.</translation>
+ </message>
+ <message>
+ <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source>
+ <translation>Warnung: Bitte korrigieren Sie die Datums- und Uhrzeiteinstellungen Ihres Computers, da Bitcoin Core ansonsten nicht ordnungsgemäß funktionieren wird.</translation>
+ </message>
+ <message>
+ <source>Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway</source>
+ <translation>Erlaubte Gegenstellen werden nicht für DoS-Attacken gesperrt und ihre Transkationen werden immer weitergeleitet, auch wenn sie sich bereits im Speicherpool befinden, was z.B. für Gateways sinnvoll ist.</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source>
+ <translation>Sie müssen die Datenbank mit Hilfe von -reindex neu aufbauen, um zum ungekürzten Modus zurückzukehren. Dies erfordert, dass die gesamte Blockkette erneut heruntergeladen wird.</translation>
+ </message>
+ <message>
+ <source>(default: %u)</source>
+ <translation>(Standard: %u)</translation>
+ </message>
+ <message>
+ <source>Accept public REST requests (default: %u)</source>
+ <translation>Öffentliche REST-Anfragen annehmen (Standard: %u)</translation>
+ </message>
+ <message>
+ <source>Activating best chain...</source>
+ <translation>Aktiviere beste Blockkette...</translation>
+ </message>
+ <message>
+ <source>Can't run with a wallet in prune mode.</source>
+ <translation>Eine Wallet kann im Kürzungsmodus nicht verwendet werden.</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -whitebind address: '%s'</source>
+ <translation>Kann Adresse in -whitebind nicht auflösen: '%s'</translation>
+ </message>
+ <message>
+ <source>Choose data directory on startup (default: 0)</source>
+ <translation>Datenverzeichnis beim Starten auswählen (Standard: 0)</translation>
+ </message>
+ <message>
+ <source>Connect through SOCKS5 proxy</source>
+ <translation>Über einen SOCKS5-Proxy &amp;verbinden</translation>
+ </message>
+ <message>
+ <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source>
+ <translation>Urheberrecht (C) 2009-%i Die "Bitcoin Core"-Entwickler</translation>
+ </message>
+ <message>
+ <source>Could not parse -rpcbind value %s as network address</source>
+ <translation>Der Wert %s von -rpcbind wurde nicht als Netzwerkadresse erkannt</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source>
+ <translation>Fehler beim Laden von wallet.dat: Wallet benötigt neuere Version von Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Error reading from database, shutting down.</source>
+ <translation>Fehler beim lesen der Datenbank, Ausführung wird beendet.</translation>
+ </message>
+ <message>
+ <source>Error: A fatal internal error occurred, see debug.log for details</source>
+ <translation>Fehler: Ein schwerer interner Fehler ist aufgetreten, siehe debug.log für Details.</translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -tor found, use -onion.</source>
+ <translation>Fehler: Nicht unterstütztes Argument -tor gefunden, bitte -onion verwenden.</translation>
+ </message>
+ <message>
+ <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source>
+ <translation>Gebühr (in BTC/kB), die von Ihnen gesendeten Transaktionen hinzugefügt wird (Standard: %s)</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Hinweis</translation>
+ </message>
+ <message>
+ <source>Initialization sanity check failed. Bitcoin Core is shutting down.</source>
+ <translation>Initialisierungsplausibilitätsprüfung fehlgeschlagen. Bitcoin Core wird beendet.</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Ungültiger Betrag für -maxtxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -minrelaytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Ungültiger Betrag für -minrelaytxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -mintxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Ungültiger Betrag für -mintxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s' (must be at least %s)</source>
+ <translation>Ungültiger Betrag für -paytxfee=&lt;amount&gt;: '%s' (muss mindestens %s sein)</translation>
+ </message>
+ <message>
+ <source>Invalid netmask specified in -whitelist: '%s'</source>
+ <translation>Ungültige Netzmaske angegeben in -whitelist: '%s'</translation>
+ </message>
+ <message>
+ <source>Keep at most &lt;n&gt; unconnectable transactions in memory (default: %u)</source>
+ <translation>Maximal &lt;n&gt; nicht-verbindbare Transaktionen im Speicher halten (Standard: %u)</translation>
+ </message>
+ <message>
+ <source>Need to specify a port with -whitebind: '%s'</source>
+ <translation>Angabe eines Ports benötigt für -whitebind: '%s'</translation>
+ </message>
+ <message>
+ <source>Node relay options:</source>
+ <translation>Knoten-Weiterleitungsoptionen:</translation>
+ </message>
+ <message>
+ <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source>
+ <translation>RPC-SSL-Optionen (siehe Bitcoin-Wiki für SSL-Einrichtung):</translation>
+ </message>
+ <message>
+ <source>RPC server options:</source>
+ <translation>RPC-Serveroptionen:</translation>
+ </message>
+ <message>
+ <source>RPC support for HTTP persistent connections (default: %d)</source>
+ <translation>Unterstützung für persistente HTTP-Verbindungen bei RPC (Standard: %d)</translation>
+ </message>
+ <message>
+ <source>Rebuild block chain index from current blk000??.dat files on startup</source>
+ <translation>Blockkettenindex aus aktuellen Dateien blk000??.dat beim Starten wiederaufbauen</translation>
+ </message>
+ <message>
+ <source>Receive and display P2P network alerts (default: %u)</source>
+ <translation>P2P-Netzwerk-Alarme empfangen und anzeigen (Standard: %u)</translation>
+ </message>
+ <message>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>Rückverfolgungs- und Debuginformationen an die Konsole senden, anstatt sie in debug.log zu schreiben</translation>
+ </message>
+ <message>
+ <source>Send transactions as zero-fee transactions if possible (default: %u)</source>
+ <translation>Transaktionen, wenn möglich, als gebührenfreie Transaktion senden (Standard: %u)</translation>
+ </message>
+ <message>
+ <source>Set SSL root certificates for payment request (default: -system-)</source>
+ <translation>SSL-Wurzelzertifikate für Zahlungsanforderungen festlegen (Standard: -system-)</translation>
+ </message>
+ <message>
+ <source>Set language, for example "de_DE" (default: system locale)</source>
+ <translation>Sprache festlegen, z.B. "de_DE" (Standard: Systemstandard)</translation>
+ </message>
+ <message>
+ <source>Show all debugging options (usage: --help -help-debug)</source>
+ <translation>Zeige alle Debuggingoptionen (Benutzung: --help -help-debug)</translation>
+ </message>
+ <message>
+ <source>Show splash screen on startup (default: 1)</source>
+ <translation>Startbildschirm beim Starten anzeigen (Standard: 1)</translation>
+ </message>
+ <message>
+ <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source>
+ <translation>Protokolldatei debug.log beim Starten des Clients kürzen (Standard: 1, wenn kein -debug)</translation>
+ </message>
+ <message>
+ <source>Signing transaction failed</source>
+ <translation>Signierung der Transaktion fehlgeschlagen</translation>
+ </message>
+ <message>
+ <source>Start minimized</source>
+ <translation>Minimiert starten</translation>
+ </message>
+ <message>
+ <source>The transaction amount is too small to pay the fee</source>
+ <translation>Der Transaktionsbetrag ist zu niedrig, um die Gebühr zu bezahlen.</translation>
+ </message>
+ <message>
+ <source>This is experimental software.</source>
+ <translation>Dies ist experimentelle Software.</translation>
+ </message>
+ <message>
+ <source>Transaction amount too small</source>
+ <translation>Transaktionsbetrag zu niedrig</translation>
+ </message>
+ <message>
+ <source>Transaction amounts must be positive</source>
+ <translation>Transaktionsbeträge müssen positiv sein</translation>
+ </message>
+ <message>
+ <source>Transaction too large for fee policy</source>
+ <translation>Transaktion ist für die Gebührenrichtlinie zu groß</translation>
+ </message>
+ <message>
+ <source>Transaction too large</source>
+ <translation>Transaktion zu groß</translation>
+ </message>
+ <message>
+ <source>UI Options:</source>
+ <translation>Benutzeroberflächenoptionen:</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer (bind returned error %s)</source>
+ <translation>Kann auf diesem Computer nicht an %s binden (bind meldete Fehler %s)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: 1 when listening)</source>
+ <translation>UPnP verwenden, um eine Portweiterleitung einzurichten (Standard: 1, wenn abgehört wird)</translation>
+ </message>
+ <message>
+ <source>Username for JSON-RPC connections</source>
+ <translation>Benutzername für JSON-RPC-Verbindungen</translation>
+ </message>
+ <message>
+ <source>Wallet needed to be rewritten: restart Bitcoin Core to complete</source>
+ <translation>Wallet musste neu geschrieben werden: starten Sie Bitcoin Core zur Fertigstellung neu</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Warnung</translation>
+ </message>
+ <message>
+ <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source>
+ <translation>Warnung: Nicht unterstütztes Argument -benchmark wurde ignoriert, bitte -debug=bench verwenden.</translation>
+ </message>
+ <message>
+ <source>Warning: Unsupported argument -debugnet ignored, use -debug=net.</source>
+ <translation>Warnung: Nicht unterstütztes Argument -debugnet wurde ignoriert, bitte -debug=net verwenden.</translation>
+ </message>
+ <message>
+ <source>Zapping all transactions from wallet...</source>
+ <translation>Lösche alle Transaktionen aus Wallet...</translation>
+ </message>
+ <message>
+ <source>on startup</source>
+ <translation>beim Starten</translation>
+ </message>
+ <message>
+ <source>wallet.dat corrupt, salvage failed</source>
+ <translation>wallet.dat beschädigt, Datenrettung fehlgeschlagen</translation>
+ </message>
+ <message>
+ <source>Password for JSON-RPC connections</source>
+ <translation>Passwort für JSON-RPC-Verbindungen</translation>
+ </message>
+ <message>
+ <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
+ <translation>Befehl ausführen wenn der beste Block wechselt (%s im Befehl wird durch den Hash des Blocks ersetzt)</translation>
+ </message>
+ <message>
+ <source>Upgrade wallet to latest format</source>
+ <translation>Wallet auf das neueste Format aktualisieren</translation>
+ </message>
+ <message>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>Blockkette erneut nach fehlenden Wallet-Transaktionen durchsuchen</translation>
+ </message>
+ <message>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>OpenSSL (https) für JSON-RPC-Verbindungen verwenden</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>Dieser Hilfetext</translation>
+ </message>
+ <message>
+ <source>Allow DNS lookups for -addnode, -seednode and -connect</source>
+ <translation>Erlaube DNS-Abfragen für -addnode, -seednode und -connect</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>Lade Adressen...</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>Fehler beim Laden von wallet.dat: Wallet beschädigt</translation>
+ </message>
+ <message>
+ <source>(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source>
+ <translation>(1 = TX-Metadaten wie z.B. Accountbesitzer und Zahlungsanforderungsinformationen behalten, 2 = TX-Metadaten verwerfen)</translation>
+ </message>
+ <message>
+ <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
+ <translation>Legt fest, wie gründlich die Blockverifikation von -checkblocks ist (0-4, Standard: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
+ <translation>Einen vollständigen Transaktionsindex führen, der vom RPC-Befehl "getrawtransaction" genutzt wird (Standard: %u)</translation>
+ </message>
+ <message>
+ <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source>
+ <translation>Anzahl Sekunden, während denen sich nicht konform verhaltenden Gegenstellen die Wiederverbindung verweigert wird (Standard: %u)</translation>
+ </message>
+ <message>
+ <source>Output debugging information (default: %u, supplying &lt;category&gt; is optional)</source>
+ <translation>Debugginginformationen ausgeben (Standard: %u, &lt;category&gt; anzugeben ist optional)</translation>
+ </message>
+ <message>
+ <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source>
+ <translation>Separaten SOCKS5-Proxy verwenden, um Gegenstellen über versteckte Tor-Dienste zu erreichen (Standard: %s)</translation>
+ </message>
+ <message>
+ <source>(default: %s)</source>
+ <translation>(Standard: %s)</translation>
+ </message>
+ <message>
+ <source>Acceptable ciphers (default: %s)</source>
+ <translation>Zulässige Chiffren (Standard: %s)</translation>
+ </message>
+ <message>
+ <source>Always query for peer addresses via DNS lookup (default: %u)</source>
+ <translation>Adressen von Gegenstellen immer über DNS-Namensauflösung abfragen (Standard: %u)</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>Fehler beim Laden von wallet.dat</translation>
+ </message>
+ <message>
+ <source>Generate coins (default: %u)</source>
+ <translation>Bitcoins erzeugen (Standard: %u)</translation>
+ </message>
+ <message>
+ <source>How many blocks to check at startup (default: %u, 0 = all)</source>
+ <translation>Wieviele Blöcke beim Starten geprüft werden sollen (Standard: %u, 0 = alle)</translation>
+ </message>
+ <message>
+ <source>Include IP addresses in debug output (default: %u)</source>
+ <translation>IP-Adressen in Debugausgabe einschließen (Standard: %u)</translation>
+ </message>
+ <message>
+ <source>Invalid -proxy address: '%s'</source>
+ <translation>Ungültige Adresse in -proxy: '%s'</translation>
+ </message>
+ <message>
+ <source>Listen for JSON-RPC connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>&lt;port&gt; nach JSON-RPC-Verbindungen abhören (Standard: %u oder Testnetz: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain at most &lt;n&gt; connections to peers (default: %u)</source>
+ <translation>Maximal &lt;n&gt; Verbindungen zu Gegenstellen aufrechterhalten (Standard: %u)</translation>
+ </message>
+ <message>
+ <source>Make the wallet broadcast transactions</source>
+ <translation>Die Wallet soll Transaktionen übertragen/broadcasten</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection receive buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>Maximale Größe des Empfangspuffers pro Verbindung, &lt;n&gt; * 1000 Byte (Standard: %u)</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection send buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>Maximale Größe des Sendepuffers pro Verbindung, &lt;n&gt; * 1000 Byte (Standard: %u)</translation>
+ </message>
+ <message>
+ <source>Prepend debug output with timestamp (default: %u)</source>
+ <translation>Debugausgaben einen Zeitstempel voranstellen (Standard: %u)</translation>
+ </message>
+ <message>
+ <source>Relay and mine data carrier transactions (default: %u)</source>
+ <translation>"Data Carrier"-Transaktionen weiterleiten und erarbeiten (Standard: %u)</translation>
+ </message>
+ <message>
+ <source>Relay non-P2SH multisig (default: %u)</source>
+ <translation>Nicht-"P2SH-Multisig" weiterleiten (Standard: %u)</translation>
+ </message>
+ <message>
+ <source>Server certificate file (default: %s)</source>
+ <translation>Serverzertifikat (Standard: %s)</translation>
+ </message>
+ <message>
+ <source>Server private key (default: %s)</source>
+ <translation>Privater Serverschlüssel (Standard: %s)</translation>
+ </message>
+ <message>
+ <source>Set key pool size to &lt;n&gt; (default: %u)</source>
+ <translation>Größe des Schlüsselpools festlegen auf &lt;n&gt; (Standard: %u)</translation>
+ </message>
+ <message>
+ <source>Set minimum block size in bytes (default: %u)</source>
+ <translation>Minimale Blockgröße in Byte festlegen (Standard: %u)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads to service RPC calls (default: %d)</source>
+ <translation>Maximale Anzahl an Threads zur Verarbeitung von RPC-Anfragen festlegen (Standard: %d)</translation>
+ </message>
+ <message>
+ <source>Specify configuration file (default: %s)</source>
+ <translation>Konfigurationsdatei festlegen (Standard: %s)</translation>
+ </message>
+ <message>
+ <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source>
+ <translation>Verbindungzeitüberschreitung in Millisekunden festlegen (Minimum: 1, Standard: %d)</translation>
+ </message>
+ <message>
+ <source>Specify pid file (default: %s)</source>
+ <translation>PID-Datei festlegen (Standard: %s)</translation>
+ </message>
+ <message>
+ <source>Spend unconfirmed change when sending transactions (default: %u)</source>
+ <translation>Unbestätigtes Wechselgeld darf beim Senden von Transaktionen ausgegeben werden (Standard: %u)</translation>
+ </message>
+ <message>
+ <source>Threshold for disconnecting misbehaving peers (default: %u)</source>
+ <translation>Schwellenwert, um Verbindungen zu sich nicht konform verhaltenden Gegenstellen zu beenden (Standard: %u)</translation>
+ </message>
+ <message>
+ <source>Unknown network specified in -onlynet: '%s'</source>
+ <translation>Unbekannter Netztyp in -onlynet angegeben: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -bind address: '%s'</source>
+ <translation>Kann Adresse in -bind nicht auflösen: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -externalip address: '%s'</source>
+ <translation>Kann Adresse in -externalip nicht auflösen: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Ungültiger Betrag für -paytxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>Unzureichender Kontostand</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>Lade Blockindex...</translation>
+ </message>
+ <message>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>Mit dem angegebenen Knoten verbinden und versuchen die Verbindung aufrecht zu erhalten</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>Lade Wallet...</translation>
+ </message>
+ <message>
+ <source>Cannot downgrade wallet</source>
+ <translation>Wallet kann nicht auf eine ältere Version herabgestuft werden</translation>
+ </message>
+ <message>
+ <source>Cannot write default address</source>
+ <translation>Standardadresse kann nicht geschrieben werden</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>Durchsuche erneut...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>Laden abgeschlossen</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Fehler</translation>
+ </message>
+</context>
+</TS> \ 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 0000000000..ad0ee1d030
--- /dev/null
+++ b/src/qt/locale/bitcoin_el_GR.ts
@@ -0,0 +1,2935 @@
+<TS language="el_GR" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Right-click to edit address or label</source>
+ <translation>Δεξί-κλικ για επεξεργασία της διεύθυνσης ή της ετικέτας</translation>
+ </message>
+ <message>
+ <source>Create a new address</source>
+ <translation>Δημιουργία νέας διεύθυνσης</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>&amp;Νέo</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Αντέγραψε την επιλεγμένη διεύθυνση στο πρόχειρο του συστήματος</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>&amp;Αντιγραφή</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>Κ&amp;λείσιμο</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>&amp;Αντιγραφή διεύθυνσης</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>Αντιγραφη της επιλεγμενης διεύθυνσης στο πρόχειρο του συστηματος</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Εξαγωγή δεδομένων καρτέλας σε αρχείο</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Εξαγωγή</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;Διαγραφή</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>Επιλογή διεύθυνσης όπου θα σταλθούν νομίσματα</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>Επιλογή διεύθυνσης απ' όπου θα ληφθούν νομίσματα</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>Ε&amp;πιλογή</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>Διευθύνσεις αποστολής</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>Διευθύνσεις λήψης</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>Αυτές είναι οι Bitcoin διευθύνσεις σας για να λαμβάνετε πληρωμές. Δίνοντας μία ξεχωριστή διεύθυνση σε κάθε αποστολέα, θα μπορείτε να ελέγχετε ποιος σας πληρώνει.</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>Αυτές είναι οι Bitcoin διευθύνσεις σας για να λαμβάνετε πληρωμές. Δίνοντας μία ξεχωριστή διεύθυνση σε κάθε αποστολέα, θα μπορείτε να ελέγχετε ποιος σας πληρώνει.</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>Αντιγραφή &amp;επιγραφής</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>&amp;Επεξεργασία</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>Εξαγωγή της λίστας διευθύνσεων</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Αρχείο οριοθετημένο με κόμματα (*.csv)</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Η Εξαγωγή Απέτυχε</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the address list to %1. Please try again.</source>
+ <translation>Παρουσιάστηκε σφάλμα κατά την αποθήκευση της λίστας πορτοφολιών στο %1. Παρακαλώ δοκιμάστε ξανά</translation>
+ </message>
+</context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Επιγραφή</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Διεύθυνση</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(χωρίς ετικέτα)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Passphrase Dialog</source>
+ <translation>Φράση πρόσβασης </translation>
+ </message>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Βάλτε κωδικό πρόσβασης</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>&amp;Αλλαγή κωδικού</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Επανέλαβε τον νέο κωδικό πρόσβασης</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>&amp;Κρυπτογράφηση πορτοφολιού</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>Αυτη η ενεργεία χρειάζεται τον κωδικό του πορτοφολιού για να ξεκλειδώσει το πορτοφόλι.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Ξεκλειδωσε το πορτοφολι</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>Αυτη η ενεργεια χρειάζεται τον κωδικο του πορτοφολιου για να αποκρυπτογραφησειι το πορτοφολι.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>Αποκρυπτογράφησε το πορτοφολι</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>Άλλαξε κωδικο πρόσβασης</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>Επιβεβαίωσε την κρυπτογραφηση του πορτοφολιού</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>Προσοχη: Εαν κρυπτογραφησεις το πορτοφολι σου και χάσεις τον κωδικο σου θα χάσεις &lt;b&gt; ΟΛΑ ΣΟΥ ΤΑ BITCOINS&lt;/b&gt;!
+Είσαι σίγουρος ότι θέλεις να κρυπτογραφησεις το πορτοφολι;</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>Είστε σίγουροι ότι θέλετε να κρυπτογραφήσετε το πορτοφόλι σας;</translation>
+ </message>
+ <message>
+ <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
+ <translation>ΣΗΜΑΝΤΙΚΟ: Τα προηγούμενα αντίγραφα ασφαλείας που έχετε κάνει από το αρχείο του πορτοφόλιου σας θα πρέπει να αντικατασταθουν με το νέο που δημιουργείται, κρυπτογραφημένο αρχείο πορτοφόλιου. Για λόγους ασφαλείας, τα προηγούμενα αντίγραφα ασφαλείας του μη κρυπτογραφημένου αρχείου πορτοφόλιου θα καταστουν άχρηστα μόλις αρχίσετε να χρησιμοποιείτε το νέο κρυπτογραφημένο πορτοφόλι. </translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>Προσοχη: το πλήκτρο Caps Lock είναι ενεργο.</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>Κρυπτογραφημενο πορτοφολι</translation>
+ </message>
+ <message>
+ <source>Enter the new passphrase to the wallet.&lt;br/&gt;Please use a passphrase of &lt;b&gt;ten or more random characters&lt;/b&gt;, or &lt;b&gt;eight or more words&lt;/b&gt;.</source>
+ <translation>Εισάγετε τον νέο κωδικό πρόσβασης στον πορτοφόλι &lt;br/&gt; Παρακαλώ χρησιμοποιείστε ένα κωδικό με &lt;b&gt; 10 ή περισσότερους τυχαίους χαρακτήρες&lt;/b&gt; ή &lt;b&gt; οχτώ ή παραπάνω λέξεις&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>Η κρυπτογραφηση του πορτοφολιού απέτυχε</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>Η κρυπτογράφηση του πορτοφολιού απέτυχε λογω εσωτερικού σφάλματος. Το πορτοφολι δεν κρυπτογραφηθηκε.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>Οι εισαχθέντες κωδικοί δεν ταιριάζουν.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>το ξεκλείδωμα του πορτοφολιού απέτυχε</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>Ο κωδικος που εισήχθη για την αποκρυπτογραφηση του πορτοφολιού ήταν λαθος.</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>Η αποκρυπτογραφηση του πορτοφολιού απέτυχε</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>Ο κωδικος του πορτοφολιού άλλαξε με επιτυχία.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>Υπογραφή &amp;Μηνύματος...</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>Συγχρονισμός με το δίκτυο...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;Επισκόπηση</translation>
+ </message>
+ <message>
+ <source>Node</source>
+ <translation>Κόμβος</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>Εμφάνισε τη γενική εικόνα του πορτοφολιού</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Συναλλαγές</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>Περιήγηση στο ιστορικό συναλλαγών</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>Έ&amp;ξοδος</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>Εξοδος από την εφαρμογή</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>Σχετικά με &amp;Qt</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>Εμφάνισε πληροφορίες σχετικά με Qt</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;Επιλογές...</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>&amp;Κρυπτογράφησε το πορτοφόλι</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>&amp;Αντίγραφο ασφαλείας του πορτοφολιού</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>&amp;Άλλαξε κωδικο πρόσβασης</translation>
+ </message>
+ <message>
+ <source>&amp;Sending addresses...</source>
+ <translation>Διευθύνσεις αποστολής</translation>
+ </message>
+ <message>
+ <source>&amp;Receiving addresses...</source>
+ <translation>Διευθύνσεις λήψης</translation>
+ </message>
+ <message>
+ <source>Open &amp;URI...</source>
+ <translation>'Ανοιγμα &amp;URI</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core client</source>
+ <translation>Εφαρμογή Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Importing blocks from disk...</source>
+ <translation>Εισαγωγή μπλοκ από τον σκληρο δίσκο ... </translation>
+ </message>
+ <message>
+ <source>Reindexing blocks on disk...</source>
+ <translation>Φόρτωση ευρετηρίου μπλοκ στον σκληρο δισκο...</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>Στείλε νομίσματα σε μια διεύθυνση bitcoin</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>Δημιουργία αντιγράφου ασφαλείας πορτοφολιού σε άλλη τοποθεσία</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Αλλαγή του κωδικού κρυπτογράφησης του πορτοφολιού</translation>
+ </message>
+ <message>
+ <source>&amp;Debug window</source>
+ <translation>&amp;Παράθυρο αποσφαλμάτωσης</translation>
+ </message>
+ <message>
+ <source>Open debugging and diagnostic console</source>
+ <translation>Άνοιγμα κονσόλας αποσφαλμάτωσης και διαγνωστικών</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>&amp;Επιβεβαίωση μηνύματος</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>Πορτοφόλι</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>&amp;Αποστολή</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>&amp;Παραλαβή </translation>
+ </message>
+ <message>
+ <source>Show information about Bitcoin Core</source>
+ <translation>Σχετικά με το Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>&amp;Εμφάνισε/Κρύψε</translation>
+ </message>
+ <message>
+ <source>Show or hide the main Window</source>
+ <translation>Εμφάνιση ή αποκρύψη του κεντρικου παράθυρου </translation>
+ </message>
+ <message>
+ <source>Encrypt the private keys that belong to your wallet</source>
+ <translation>Κρυπτογραφήστε τα ιδιωτικά κλειδιά που ανήκουν στο πορτοφόλι σας </translation>
+ </message>
+ <message>
+ <source>Sign messages with your Bitcoin addresses to prove you own them</source>
+ <translation>Υπογράψτε ένα μήνυμα για να βεβαιώσετε πως είστε ο κάτοχος αυτής της διεύθυνσης</translation>
+ </message>
+ <message>
+ <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source>
+ <translation>Υπογράψτε ένα μήνυμα για ν' αποδείξετε πως ανήκει μια συγκεκριμένη διεύθυνση Bitcoin</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;Αρχείο</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;Ρυθμίσεις</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>&amp;Βοήθεια</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>Εργαλειοθήκη καρτελών</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Request payments (generates QR codes and bitcoin: URIs)</source>
+ <translation>Αίτηση πληρωμών (δημιουργεί QR codes και διευθύνσεις bitcoin: )</translation>
+ </message>
+ <message>
+ <source>&amp;About Bitcoin Core</source>
+ <translation>&amp;Σχετικά με το Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Show the list of used sending addresses and labels</source>
+ <translation>Προβολή της λίστας των χρησιμοποιημένων διευθύνσεων και ετικετών αποστολής</translation>
+ </message>
+ <message>
+ <source>Show the list of used receiving addresses and labels</source>
+ <translation>Προβολή της λίστας των χρησιμοποιημένων διευθύνσεων και ετικετών λήψεως</translation>
+ </message>
+ <message>
+ <source>Open a bitcoin: URI or payment request</source>
+ <translation>Άνοιγμα bitcoin: URI αίτησης πληρωμής</translation>
+ </message>
+ <message>
+ <source>&amp;Command-line options</source>
+ <translation>&amp;Επιλογές γραμμής εντολών</translation>
+ </message>
+ <message>
+ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
+ <translation>Εμφανιση του Bitcoin-Qt μήνυματος βοήθειας για να πάρετε μια λίστα με τις πιθανές επιλογές Bitcoin γραμμής εντολών.</translation>
+ </message>
+ <message>
+ <source>No block source available...</source>
+ <translation>Η πηγή του μπλοκ δεν ειναι διαθέσιμη... </translation>
+ </message>
+ <message>
+ <source>%1 and %2</source>
+ <translation>%1 και %2</translation>
+ </message>
+ <message>
+ <source>%1 behind</source>
+ <translation>%1 πίσω</translation>
+ </message>
+ <message>
+ <source>Last received block was generated %1 ago.</source>
+ <translation>Το τελευταίο μπλοκ που ελήφθη δημιουργήθηκε %1 πριν.</translation>
+ </message>
+ <message>
+ <source>Transactions after this will not yet be visible.</source>
+ <translation>Οι συναλλαγές μετά από αυτό δεν θα είναι ακόμη ορατες.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Σφάλμα</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Προειδοποίηση</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Πληροφορία</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>Ενημερωμένο</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>Ενημέρωση...</translation>
+ </message>
+ <message>
+ <source>Date: %1
+</source>
+ <translation>Ημερομηνία: %1
+</translation>
+ </message>
+ <message>
+ <source>Amount: %1
+</source>
+ <translation>Ποσό: %1
+</translation>
+ </message>
+ <message>
+ <source>Type: %1
+</source>
+ <translation>Τύπος: %1
+</translation>
+ </message>
+ <message>
+ <source>Label: %1
+</source>
+ <translation>Ετικέτα: %1
+</translation>
+ </message>
+ <message>
+ <source>Address: %1
+</source>
+ <translation>Διεύθυνση: %1
+</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>Η συναλλαγή απεστάλη</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>Εισερχόμενη συναλλαγή</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>Το πορτοφόλι είναι &lt;b&gt;κρυπτογραφημένο&lt;/b&gt; και &lt;b&gt;ξεκλείδωτο&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>Το πορτοφόλι είναι &lt;b&gt;κρυπτογραφημένο&lt;/b&gt; και &lt;b&gt;κλειδωμένο&lt;/b&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <source>Network Alert</source>
+ <translation>Ειδοποίηση Δικτύου</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Coin Selection</source>
+ <translation>Επιλογή κερμάτων</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Ποσότητα:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Bytes:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Ποσό:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Προτεραιότητα:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Ταρίφα</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Σκόνη</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Ταρίφα αλλαγής</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Ρέστα:</translation>
+ </message>
+ <message>
+ <source>(un)select all</source>
+ <translation>(από)επιλογή όλων</translation>
+ </message>
+ <message>
+ <source>Tree mode</source>
+ <translation>Εμφάνιση τύπου δέντρο</translation>
+ </message>
+ <message>
+ <source>List mode</source>
+ <translation>Λίστα εντολών</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Ποσό</translation>
+ </message>
+ <message>
+ <source>Received with label</source>
+ <translation>Παραλήφθηκε με επιγραφή</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>Παραλείφθηκε με την εξής διεύθυνση</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Ημερομηνία</translation>
+ </message>
+ <message>
+ <source>Confirmations</source>
+ <translation>Επικυρώσεις</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Επικυρωμένες</translation>
+ </message>
+ <message>
+ <source>Priority</source>
+ <translation>Προτεραιότητα</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Αντιγραφή διεύθυνσης</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Αντιγραφή επιγραφής</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Αντιγραφή ποσού</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Αντιγραφη του ID Συναλλαγής</translation>
+ </message>
+ <message>
+ <source>Lock unspent</source>
+ <translation>Κλείδωμα αξόδευτων</translation>
+ </message>
+ <message>
+ <source>Unlock unspent</source>
+ <translation>Ξεκλείδωμα αξόδευτων</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Αντιγραφή ποσότητας</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Αντιγραφή ταρίφας</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Αντιγραφή μετα-ταρίφας</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Αντιγραφή των byte</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Αντιγραφή προτεραιότητας</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Αντιγραφή 'σκόνης'</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Αντιγραφή των ρέστων</translation>
+ </message>
+ <message>
+ <source>highest</source>
+ <translation>ύψιστη</translation>
+ </message>
+ <message>
+ <source>higher</source>
+ <translation>υψηλότερη</translation>
+ </message>
+ <message>
+ <source>high</source>
+ <translation>ψηλή</translation>
+ </message>
+ <message>
+ <source>medium-high</source>
+ <translation>μεσαία-ψηλή</translation>
+ </message>
+ <message>
+ <source>medium</source>
+ <translation>μεσαία</translation>
+ </message>
+ <message>
+ <source>low-medium</source>
+ <translation>μεσαία-χαμηλή</translation>
+ </message>
+ <message>
+ <source>low</source>
+ <translation>χαμηλή</translation>
+ </message>
+ <message>
+ <source>lower</source>
+ <translation>χαμηλότερη</translation>
+ </message>
+ <message>
+ <source>lowest</source>
+ <translation>χαμηλότατη</translation>
+ </message>
+ <message>
+ <source>(%1 locked)</source>
+ <translation>(%1 κλειδωμένο)</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>κανένα</translation>
+ </message>
+ <message>
+ <source>This label turns red if the transaction size is greater than 1000 bytes.</source>
+ <translation>Αυτή η ετικέτα γίνεται κόκκινη αν το μέγεθος της συναλλαγής είναι μεγαλύτερο από 1000 bytes.</translation>
+ </message>
+ <message>
+ <source>This label turns red if the priority is smaller than "medium".</source>
+ <translation>Αυτή η ετικέτα γίνεται κόκκινη αν η προτεραιότητα είναι μικρότερη από "μεσαία".</translation>
+ </message>
+ <message>
+ <source>This label turns red if any recipient receives an amount smaller than %1.</source>
+ <translation>Αυτή η ετικέτα γίνεται κόκκινη αν οποιοσδήποτε παραλήπτης λάβει ποσό μικρότερο από %1.</translation>
+ </message>
+ <message>
+ <source>yes</source>
+ <translation>ναι</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>όχι</translation>
+ </message>
+ <message>
+ <source>This means a fee of at least %1 per kB is required.</source>
+ <translation>Ελάχιστο χρεώσιμο ποσό τουλάχιστο %1 ανα kB</translation>
+ </message>
+ <message>
+ <source>Transactions with higher priority are more likely to get included into a block.</source>
+ <translation>Συναλλαγές με υψηλότερη προτεραιότητα είναι πιο πιθανό να περιλαμβάνονται σε ένα μπλοκ.</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(χωρίς ετικέτα)</translation>
+ </message>
+ <message>
+ <source>change from %1 (%2)</source>
+ <translation>ρέστα από %1 (%2) </translation>
+ </message>
+ <message>
+ <source>(change)</source>
+ <translation>(ρέστα)
+</translation>
+ </message>
+</context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>Επεξεργασία Διεύθυνσης</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>&amp;Επιγραφή</translation>
+ </message>
+ <message>
+ <source>The label associated with this address list entry</source>
+ <translation>Η ετικέτα που συνδέεται με αυτήν την καταχώρηση στο βιβλίο διευθύνσεων</translation>
+ </message>
+ <message>
+ <source>The address associated with this address list entry. This can only be modified for sending addresses.</source>
+ <translation>Η διεύθυνση σχετίζεται με αυτή την καταχώρηση του βιβλίου διευθύνσεων. Μπορεί να τροποποιηθεί μόνο για τις διευθύνσεις αποστολής.</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;Διεύθυνση</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>Νέα διεύθυνση λήψης</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>Νέα διεύθυνση αποστολής</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>Επεξεργασία διεύθυνσης λήψης</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>Επεξεργασία διεύθυνσης αποστολής</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>Η διεύθυνση "%1" βρίσκεται ήδη στο βιβλίο διευθύνσεων.</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is not a valid Bitcoin address.</source>
+ <translation>Η διεύθυνση "%1" δεν είναι έγκυρη Bitcoin διεύθυνση.</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>Δεν είναι δυνατό το ξεκλείδωμα του πορτοφολιού.</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>Η δημιουργία νέου κλειδιού απέτυχε.</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ <message>
+ <source>A new data directory will be created.</source>
+ <translation>Θα δημιουργηθεί ένας νέος φάκελος δεδομένων.</translation>
+ </message>
+ <message>
+ <source>name</source>
+ <translation>όνομα</translation>
+ </message>
+ <message>
+ <source>Directory already exists. Add %1 if you intend to create a new directory here.</source>
+ <translation>Κατάλογος ήδη υπάρχει. Προσθήκη %1, αν σκοπεύετε να δημιουργήσετε έναν νέο κατάλογο εδώ.</translation>
+ </message>
+ <message>
+ <source>Path already exists, and is not a directory.</source>
+ <translation>Η διαδρομή υπάρχει ήδη αλλά δεν είναι φάκελος</translation>
+ </message>
+ <message>
+ <source>Cannot create data directory here.</source>
+ <translation>Δεν μπορεί να δημιουργηθεί φάκελος δεδομένων εδώ.</translation>
+ </message>
+</context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>έκδοση</translation>
+ </message>
+ <message>
+ <source>(%1-bit)</source>
+ <translation>(%1-bit)</translation>
+ </message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>Σχετικά με το Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Command-line options</source>
+ <translation>επιλογής γραμμής εντολών</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>Χρήση:</translation>
+ </message>
+ <message>
+ <source>command-line options</source>
+ <translation>επιλογής γραμμής εντολών</translation>
+ </message>
+</context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Welcome</source>
+ <translation>Καλώς ήρθατε</translation>
+ </message>
+ <message>
+ <source>Welcome to Bitcoin Core.</source>
+ <translation>Καλώς ήρθατε στο Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</source>
+ <translation>Καθώς αυτή είναι η πρώτη φορά που εκκινείται το πρόγραμμα, μπορείτε να διαλέξετε πού θα αποθηκεύει το Bitcoin Core τα δεδομένα του.</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory.</source>
+ <translation>O πυρήνας Bitcoin θα κατεβάσει και να αποθηκεύσει ένα αντίγραφο της αλυσίδας μπλοκ Bitcoin. Τουλάχιστον %1GB δεδομένων θα αποθηκευτούν σε αυτόν τον κατάλογο, και θα αυξηθεί με την πάροδο του χρόνου. Το πορτοφόλι θα αποθηκευτεί σε αυτόν τον κατάλογο.</translation>
+ </message>
+ <message>
+ <source>Use the default data directory</source>
+ <translation>Χρήση του προεπιλεγμένου φακέλου δεδομένων</translation>
+ </message>
+ <message>
+ <source>Use a custom data directory:</source>
+ <translation>Προσαρμογή του φακέλου δεδομένων: </translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Error: Specified data directory "%1" cannot be created.</source>
+ <translation>Σφάλμα: Ο καθορισμένος φάκελος δεδομένων "%1" δεν μπορεί να δημιουργηθεί.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Σφάλμα</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n GB of free space available</source>
+ <translation><numerusform>%n GB ελεύθερου χώρου διαθέσιμα</numerusform><numerusform>%n GB ελεύθερου χώρου διαθέσιμα</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>(of %n GB needed)</source>
+ <translation><numerusform>(από το %n GB που απαιτείται)</numerusform><numerusform>(από τα %n GB που απαιτούνται)</numerusform></translation>
+ </message>
+</context>
+<context>
+ <name>OpenURIDialog</name>
+ <message>
+ <source>Open URI</source>
+ <translation>'Ανοιγμα &amp;URI</translation>
+ </message>
+ <message>
+ <source>Open payment request from URI or file</source>
+ <translation>Ανοιχτό αίτημα πληρωμής από URI ή απο αρχείο</translation>
+ </message>
+ <message>
+ <source>URI:</source>
+ <translation>URI:</translation>
+ </message>
+ <message>
+ <source>Select payment request file</source>
+ <translation>Επιλέξτε πληρωμή αρχείου αίτησης</translation>
+ </message>
+ <message>
+ <source>Select payment request file to open</source>
+ <translation>Επιλέξτε αρχείο πληρωμής για άνοιγμα.</translation>
+ </message>
+</context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>Ρυθμίσεις</translation>
+ </message>
+ <message>
+ <source>&amp;Main</source>
+ <translation>&amp;Κύριο</translation>
+ </message>
+ <message>
+ <source>Size of &amp;database cache</source>
+ <translation>Μέγεθος κρυφής μνήμης βάσης δεδομένων.</translation>
+ </message>
+ <message>
+ <source>MB</source>
+ <translation>MB</translation>
+ </message>
+ <message>
+ <source>Number of script &amp;verification threads</source>
+ <translation>Αριθμός script και γραμμές επαλήθευσης </translation>
+ </message>
+ <message>
+ <source>Accept connections from outside</source>
+ <translation>Αποδοχή συνδέσεων απο έξω</translation>
+ </message>
+ <message>
+ <source>Allow incoming connections</source>
+ <translation>Αποδοχή εισερχόμενων συναλλαγών</translation>
+ </message>
+ <message>
+ <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
+ <translation>Διεύθυνση IP του διαμεσολαβητή (π.χ. 127.0.0.1 / IPv6: ::1)</translation>
+ </message>
+ <message>
+ <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source>
+ <translation>Ελαχιστοποίηση αντί για έξοδο κατά το κλείσιμο του παραθύρου. Όταν αυτή η επιλογή είναι ενεργοποιημένη, η εφαρμογή θα κλείνει μόνο αν επιλεχθεί η Έξοδος στο μενού.</translation>
+ </message>
+ <message>
+ <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source>
+ <translation>URLs από τρίτους (π.χ. ένας εξερευνητής μπλοκ) τα οποία εμφανίζονται στην καρτέλα συναλλαγών ως στοιχεία μενού. Το %s στα URL αντικαθιστάται από την τιμή της κατατεμαχισμένης συναλλαγής.</translation>
+ </message>
+ <message>
+ <source>Third party transaction URLs</source>
+ <translation>Διευθύνσεις τρίτων συναλλαγών.</translation>
+ </message>
+ <message>
+ <source>Active command-line options that override above options:</source>
+ <translation>Ενεργές επιλογές γραμμής-εντολών που παρακάμπτουν τις παραπάνω επιλογές:</translation>
+ </message>
+ <message>
+ <source>Reset all client options to default.</source>
+ <translation>Επαναφορα όλων των επιλογων του πελάτη σε default.</translation>
+ </message>
+ <message>
+ <source>&amp;Reset Options</source>
+ <translation>Επαναφορα ρυθμίσεων</translation>
+ </message>
+ <message>
+ <source>&amp;Network</source>
+ <translation>&amp;Δίκτυο</translation>
+ </message>
+ <message>
+ <source>(0 = auto, &lt;0 = leave that many cores free)</source>
+ <translation>(0 = αυτόματο, &lt;0 = ελεύθεροι πυρήνες)</translation>
+ </message>
+ <message>
+ <source>W&amp;allet</source>
+ <translation>Π&amp;ορτοφόλι</translation>
+ </message>
+ <message>
+ <source>Expert</source>
+ <translation>Έμπειρος</translation>
+ </message>
+ <message>
+ <source>Enable coin &amp;control features</source>
+ <translation>Επιλογή κατα πόσο να αναδείχνονται οι δυνατότητες ελέγχου κερμάτων.</translation>
+ </message>
+ <message>
+ <source>If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.</source>
+ <translation>Εάν απενεργοποιήσετε το ξόδεμα μη επικυρωμένων ρέστων, τα ρέστα από μια συναλλαγή δεν μπορούν να χρησιμοποιηθούν έως ότου αυτή η συναλλαγή έχει έστω μια επικύρωση. Αυτό επίσης επηρεάζει το πως υπολογίζεται το υπόλοιπό σας.</translation>
+ </message>
+ <message>
+ <source>&amp;Spend unconfirmed change</source>
+ <translation>&amp;Ξόδεμα μη επικυρωμένων ρέστων</translation>
+ </message>
+ <message>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>Αυτόματο άνοιγμα των θυρών Bitcoin στον δρομολογητή. Λειτουργεί μόνο αν ο δρομολογητής σας υποστηρίζει τη λειτουργία UPnP.</translation>
+ </message>
+ <message>
+ <source>Map port using &amp;UPnP</source>
+ <translation>Απόδοση θυρών με χρήστη &amp;UPnP</translation>
+ </message>
+ <message>
+ <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
+ <translation>Σύνδεση στο Bitcoin δίκτυο μέσω διαμεσολαβητή SOCKS5 (π.χ. για σύνδεση μέσω Tor)</translation>
+ </message>
+ <message>
+ <source>&amp;Connect through SOCKS5 proxy (default proxy):</source>
+ <translation>&amp;Σύνδεση μέσω διαμεσολαβητή SOCKS5 (προεπιλεγμένος)</translation>
+ </message>
+ <message>
+ <source>Proxy &amp;IP:</source>
+ <translation>&amp;IP διαμεσολαβητή:</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>&amp;Θύρα:</translation>
+ </message>
+ <message>
+ <source>Port of the proxy (e.g. 9050)</source>
+ <translation>Θύρα διαμεσολαβητή</translation>
+ </message>
+ <message>
+ <source>&amp;Window</source>
+ <translation>&amp;Παράθυρο</translation>
+ </message>
+ <message>
+ <source>Show only a tray icon after minimizing the window.</source>
+ <translation>Εμφάνιση μόνο εικονιδίου στην περιοχή ειδοποιήσεων κατά την ελαχιστοποίηση</translation>
+ </message>
+ <message>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>&amp;Ελαχιστοποίηση στην περιοχή ειδοποιήσεων αντί της γραμμής εργασιών</translation>
+ </message>
+ <message>
+ <source>M&amp;inimize on close</source>
+ <translation>Ε&amp;λαχιστοποίηση κατά το κλείσιμο</translation>
+ </message>
+ <message>
+ <source>&amp;Display</source>
+ <translation>&amp;Απεικόνιση</translation>
+ </message>
+ <message>
+ <source>User Interface &amp;language:</source>
+ <translation>Γλώσσα περιβάλλοντος εργασίας: </translation>
+ </message>
+ <message>
+ <source>&amp;Unit to show amounts in:</source>
+ <translation>&amp;Μονάδα μέτρησης:</translation>
+ </message>
+ <message>
+ <source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
+ <translation>Διαλέξτε την προεπιλεγμένη υποδιαίρεση που θα εμφανίζεται όταν στέλνετε νομίσματα.</translation>
+ </message>
+ <message>
+ <source>Whether to show coin control features or not.</source>
+ <translation>Επιλογή κατα πόσο να αναδείχνονται οι δυνατότητες ελέγχου κερμάτων.
+</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>&amp;ΟΚ</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>&amp;Ακύρωση</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>προεπιλογή</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>κανένα</translation>
+ </message>
+ <message>
+ <source>Confirm options reset</source>
+ <translation>Επιβεβαιώση των επιλογων επαναφοράς </translation>
+ </message>
+ <message>
+ <source>Client restart required to activate changes.</source>
+ <translation>Χρειάζεται επανεκκίνηση του προγράμματος για να ενεργοποιηθούν οι αλλαγές.</translation>
+ </message>
+ <message>
+ <source>This change would require a client restart.</source>
+ <translation>Η αλλαγή αυτή θα χρειαστεί επανεκκίνηση του προγράμματος</translation>
+ </message>
+ <message>
+ <source>The supplied proxy address is invalid.</source>
+ <translation>Δεν είναι έγκυρη η διεύθυνση διαμεσολαβητή</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>Φόρμα</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>Οι πληροφορίες που εμφανίζονται μπορεί να είναι ξεπερασμένες. Το πορτοφόλι σας συγχρονίζεται αυτόματα με το δίκτυο Bitcoin μετά από μια σύνδεση, αλλά αυτή η διαδικασία δεν έχει ακόμη ολοκληρωθεί. </translation>
+ </message>
+ <message>
+ <source>Watch-only:</source>
+ <translation>Επίβλεψη μόνο:</translation>
+ </message>
+ <message>
+ <source>Available:</source>
+ <translation>Διαθέσιμο:</translation>
+ </message>
+ <message>
+ <source>Your current spendable balance</source>
+ <translation>Το τρέχον διαθέσιμο υπόλοιπο</translation>
+ </message>
+ <message>
+ <source>Pending:</source>
+ <translation>Εκκρεμούν:</translation>
+ </message>
+ <message>
+ <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source>
+ <translation>Το άθροισμα των συναλλαγών που δεν έχουν ακόμα επιβεβαιωθεί και δεν προσμετρώνται στο τρέχον διαθέσιμο υπόλοιπό σας</translation>
+ </message>
+ <message>
+ <source>Immature:</source>
+ <translation>Ανώριμος</translation>
+ </message>
+ <message>
+ <source>Mined balance that has not yet matured</source>
+ <translation>Εξορυγμενο υπόλοιπο που δεν έχει ακόμα ωριμάσει </translation>
+ </message>
+ <message>
+ <source>Balances</source>
+ <translation>Υπόλοιπο:</translation>
+ </message>
+ <message>
+ <source>Total:</source>
+ <translation>Σύνολο:</translation>
+ </message>
+ <message>
+ <source>Your current total balance</source>
+ <translation>Το τρέχον συνολικό υπόλοιπο</translation>
+ </message>
+ <message>
+ <source>Your current balance in watch-only addresses</source>
+ <translation>Το τρέχον υπόλοιπο σας σε διευθύνσεις παρακολούθησης μόνο</translation>
+ </message>
+ <message>
+ <source>Spendable:</source>
+ <translation>Ξοδεμένα:</translation>
+ </message>
+ <message>
+ <source>Recent transactions</source>
+ <translation>Πρόσφατες συναλλαγές</translation>
+ </message>
+ <message>
+ <source>Unconfirmed transactions to watch-only addresses</source>
+ <translation>Μη επικυρωμένες συναλλαγές σε διευθύνσεις παρακολούθησης μόνο</translation>
+ </message>
+ <message>
+ <source>Mined balance in watch-only addresses that has not yet matured</source>
+ <translation>Εξορυγμένο υπόλοιπο σε διευθύνσεις παρακολούθησης μόνο που δεν έχει ωριμάσει ακόμα</translation>
+ </message>
+ <message>
+ <source>Current total balance in watch-only addresses</source>
+ <translation>Το τρέχον συνολικό υπόλοιπο σε διευθύνσεις παρακολούθησης μόνο</translation>
+ </message>
+</context>
+<context>
+ <name>PaymentServer</name>
+ <message>
+ <source>URI handling</source>
+ <translation>Χειρισμός URI</translation>
+ </message>
+ <message>
+ <source>Invalid payment address %1</source>
+ <translation>Μη έγκυρη διεύθυνση πληρωμής %1</translation>
+ </message>
+ <message>
+ <source>Payment request rejected</source>
+ <translation>Η αίτηση πληρωμής έχει αρνηθεί.</translation>
+ </message>
+ <message>
+ <source>Payment request is not initialized.</source>
+ <translation>Η αίτηση πληρωμής δεν έχει αρχίζει ακόμα.</translation>
+ </message>
+ <message>
+ <source>Requested payment amount of %1 is too small (considered dust).</source>
+ <translation>Το ζητούμενο ποσό πληρωμής του %1 είναι πολύ μικρό (θεωρείται σκόνη)</translation>
+ </message>
+ <message>
+ <source>Payment request error</source>
+ <translation>Σφάλμα αιτήματος πληρωμής</translation>
+ </message>
+ <message>
+ <source>Cannot start bitcoin: click-to-pay handler</source>
+ <translation>Δεν είναι δυνατή η εκκίνηση του Bitcoin: click-to-pay handler</translation>
+ </message>
+ <message>
+ <source>Payment request fetch URL is invalid: %1</source>
+ <translation>Η διεύθυνση πληρωμής (URL) δεν είναι έγκυρη: %1</translation>
+ </message>
+ <message>
+ <source>Payment request file handling</source>
+ <translation>Επιλέξτε αρχείο πληρωμής για άνοιγμα.</translation>
+ </message>
+ <message>
+ <source>Refund from %1</source>
+ <translation>Επιστροφή ποσού από %1</translation>
+ </message>
+ <message>
+ <source>Error communicating with %1: %2</source>
+ <translation>Σφάλμα επικοινωνίας με %1: %2</translation>
+ </message>
+ <message>
+ <source>Payment request cannot be parsed!</source>
+ <translation>Η αίτηση πληρωμής δεν μπορεί να αναλυθεί!</translation>
+ </message>
+ <message>
+ <source>Bad response from server %1</source>
+ <translation>Κακή απάντηση από διακομιστή %1</translation>
+ </message>
+ <message>
+ <source>Payment acknowledged</source>
+ <translation>Πληρωμή αναγνωρίστηκε</translation>
+ </message>
+ <message>
+ <source>Network request error</source>
+ <translation>Σφάλμα αιτήματος δικτύου</translation>
+ </message>
+</context>
+<context>
+ <name>PeerTableModel</name>
+ <message>
+ <source>Ping Time</source>
+ <translation>Χρόνος καθυστέρησης</translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>Ποσό</translation>
+ </message>
+ <message>
+ <source>Enter a Bitcoin address (e.g. %1)</source>
+ <translation>Εισάγετε μια διεύθυνση Bitcoin (π.χ. %1)</translation>
+ </message>
+ <message>
+ <source>%1 d</source>
+ <translation>%1 d</translation>
+ </message>
+ <message>
+ <source>%1 h</source>
+ <translation>%1 ώ</translation>
+ </message>
+ <message>
+ <source>%1 m</source>
+ <translation>%1 λ</translation>
+ </message>
+ <message>
+ <source>%1 s</source>
+ <translation>%1 s</translation>
+ </message>
+ <message>
+ <source>None</source>
+ <translation>Κανένα</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>Μη διαθέσιμο</translation>
+ </message>
+ <message>
+ <source>%1 ms</source>
+ <translation>%1 ms</translation>
+ </message>
+</context>
+<context>
+ <name>QRImageWidget</name>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Αποθήκευση εικόνας...</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Image</source>
+ <translation>&amp;Αντιγραφή εικόνας</translation>
+ </message>
+ <message>
+ <source>Save QR Code</source>
+ <translation>Αποθήκευση κώδικα QR</translation>
+ </message>
+ <message>
+ <source>PNG Image (*.png)</source>
+ <translation>Εικόνες PNG (*.png)</translation>
+ </message>
+</context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>Client name</source>
+ <translation>Όνομα Πελάτη</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>Μη διαθέσιμο</translation>
+ </message>
+ <message>
+ <source>Client version</source>
+ <translation>Έκδοση Πελάτη</translation>
+ </message>
+ <message>
+ <source>&amp;Information</source>
+ <translation>&amp;Πληροφορία</translation>
+ </message>
+ <message>
+ <source>Debug window</source>
+ <translation>Παράθυρο αποσφαλμάτωσης</translation>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>Γενικά</translation>
+ </message>
+ <message>
+ <source>Using OpenSSL version</source>
+ <translation>Χρησιμοποιηση της OpenSSL εκδοσης</translation>
+ </message>
+ <message>
+ <source>Using BerkeleyDB version</source>
+ <translation>Χρήση BerkeleyDB έκδοσης</translation>
+ </message>
+ <message>
+ <source>Startup time</source>
+ <translation>Χρόνος εκκίνησης</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Δίκτυο</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>Όνομα</translation>
+ </message>
+ <message>
+ <source>Number of connections</source>
+ <translation>Αριθμός συνδέσεων</translation>
+ </message>
+ <message>
+ <source>Block chain</source>
+ <translation>Αλυσίδα μπλοκ</translation>
+ </message>
+ <message>
+ <source>Current number of blocks</source>
+ <translation>Τρέχον αριθμός μπλοκ</translation>
+ </message>
+ <message>
+ <source>Received</source>
+ <translation>Παραλήφθησαν</translation>
+ </message>
+ <message>
+ <source>Sent</source>
+ <translation>Αποστολή</translation>
+ </message>
+ <message>
+ <source>&amp;Peers</source>
+ <translation>&amp;Χρήστες</translation>
+ </message>
+ <message>
+ <source>Select a peer to view detailed information.</source>
+ <translation>Επιλέξτε ένα χρήστη για να δείτε αναλυτικές πληροφορίες.</translation>
+ </message>
+ <message>
+ <source>Version</source>
+ <translation>Έκδοση</translation>
+ </message>
+ <message>
+ <source>Services</source>
+ <translation>Υπηρεσίες</translation>
+ </message>
+ <message>
+ <source>Starting Height</source>
+ <translation>Αρχικό ύψος</translation>
+ </message>
+ <message>
+ <source>Sync Height</source>
+ <translation>Ύψος συγχονισμού</translation>
+ </message>
+ <message>
+ <source>Ban Score</source>
+ <translation>Σκορ αποκλησμού</translation>
+ </message>
+ <message>
+ <source>Connection Time</source>
+ <translation>Χρόνος σύνδεσης</translation>
+ </message>
+ <message>
+ <source>Last Send</source>
+ <translation>Τελευταία αποστολή</translation>
+ </message>
+ <message>
+ <source>Last Receive</source>
+ <translation>Τελευταία λήψη</translation>
+ </message>
+ <message>
+ <source>Bytes Sent</source>
+ <translation>Σταλθέντα bytes</translation>
+ </message>
+ <message>
+ <source>Bytes Received</source>
+ <translation>Ληφθέντα bytes</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Χρόνος καθυστέρησης</translation>
+ </message>
+ <message>
+ <source>Last block time</source>
+ <translation>Χρόνος τελευταίου μπλοκ</translation>
+ </message>
+ <message>
+ <source>&amp;Open</source>
+ <translation>&amp;Άνοιγμα</translation>
+ </message>
+ <message>
+ <source>&amp;Console</source>
+ <translation>&amp;Κονσόλα</translation>
+ </message>
+ <message>
+ <source>&amp;Network Traffic</source>
+ <translation>&amp;Κίνηση δικτύου</translation>
+ </message>
+ <message>
+ <source>&amp;Clear</source>
+ <translation>&amp;Εκκαθάριση</translation>
+ </message>
+ <message>
+ <source>Totals</source>
+ <translation>Σύνολα</translation>
+ </message>
+ <message>
+ <source>In:</source>
+ <translation>Εισερχόμενα:</translation>
+ </message>
+ <message>
+ <source>Out:</source>
+ <translation>Εξερχόμενα:</translation>
+ </message>
+ <message>
+ <source>Build date</source>
+ <translation>Ημερομηνία κατασκευής</translation>
+ </message>
+ <message>
+ <source>Debug log file</source>
+ <translation>Αρχείο καταγραφής εντοπισμού σφαλμάτων </translation>
+ </message>
+ <message>
+ <source>Clear console</source>
+ <translation>Καθαρισμός κονσόλας</translation>
+ </message>
+ <message>
+ <source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
+ <translation>Χρησιμοποιήστε το πάνω και κάτω βέλος για να περιηγηθείτε στο ιστορικο, και &lt;b&gt;Ctrl-L&lt;/b&gt; για εκκαθαριση οθονης.</translation>
+ </message>
+ <message>
+ <source>Type &lt;b&gt;help&lt;/b&gt; for an overview of available commands.</source>
+ <translation>Γράψτε &lt;b&gt;help&lt;/b&gt; για μια επισκόπηση των διαθέσιμων εντολών</translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation>%1 B</translation>
+ </message>
+ <message>
+ <source>%1 KB</source>
+ <translation>%1 KB</translation>
+ </message>
+ <message>
+ <source>%1 MB</source>
+ <translation>%1 MB</translation>
+ </message>
+ <message>
+ <source>%1 GB</source>
+ <translation>%1 GB</translation>
+ </message>
+ <message>
+ <source>via %1</source>
+ <translation>μέσω %1</translation>
+ </message>
+ <message>
+ <source>never</source>
+ <translation>ποτέ</translation>
+ </message>
+ <message>
+ <source>Inbound</source>
+ <translation>Εισερχόμενα</translation>
+ </message>
+ <message>
+ <source>Outbound</source>
+ <translation>Εξερχόμενα</translation>
+ </message>
+ <message>
+ <source>Unknown</source>
+ <translation>Άγνωστο(α)</translation>
+ </message>
+ <message>
+ <source>Fetching...</source>
+ <translation>Ανάκτηση...</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Amount:</source>
+ <translation>&amp;Ποσό:</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Επιγραφή</translation>
+ </message>
+ <message>
+ <source>&amp;Message:</source>
+ <translation>&amp;Μήνυμα:</translation>
+ </message>
+ <message>
+ <source>R&amp;euse an existing receiving address (not recommended)</source>
+ <translation>Ε&amp;παναχρησιμοποίηση υπάρχουσας διεύθυνσης λήψης (δεν συνιστάται)</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Καθαρισμός όλων των πεδίων της φόρμας.</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation>Καθαρισμός</translation>
+ </message>
+ <message>
+ <source>&amp;Request payment</source>
+ <translation>&amp;Αίτηση πληρωμής</translation>
+ </message>
+ <message>
+ <source>Show</source>
+ <translation>Εμφάνιση</translation>
+ </message>
+ <message>
+ <source>Remove the selected entries from the list</source>
+ <translation>Αφαίρεση επιλεγμένων καταχωρίσεων από τη λίστα</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>Αφαίρεση</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Αντιγραφή επιγραφής</translation>
+ </message>
+ <message>
+ <source>Copy message</source>
+ <translation>Αντιγραφή μηνύματος</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Αντιγραφή ποσού</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>QR Code</source>
+ <translation>Κώδικας QR</translation>
+ </message>
+ <message>
+ <source>Copy &amp;URI</source>
+ <translation>Αντιγραφη της επιλεγμενης διεύθυνσης στο πρόχειρο του συστηματος</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Address</source>
+ <translation>Αντιγραφή &amp;Διεύθυνσης</translation>
+ </message>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Αποθήκευση εικόνας...</translation>
+ </message>
+ <message>
+ <source>Request payment to %1</source>
+ <translation>Αίτηση πληρωμής για %1</translation>
+ </message>
+ <message>
+ <source>Payment information</source>
+ <translation>Πληροφορίες πληρωμής</translation>
+ </message>
+ <message>
+ <source>URI</source>
+ <translation>URI:</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Διεύθυνση</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Ποσό</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Επιγραφή</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Μήνυμα</translation>
+ </message>
+ <message>
+ <source>Resulting URI too long, try to reduce the text for label / message.</source>
+ <translation>Το αποτέλεσμα της διεύθυνσης είναι πολύ μεγάλο. Μειώστε το μέγεθος για το κείμενο της ετικέτας/ μηνύματος.</translation>
+ </message>
+ <message>
+ <source>Error encoding URI into QR Code.</source>
+ <translation>Σφάλμα κατά την κωδικοποίηση του URI σε κώδικα QR</translation>
+ </message>
+</context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Ημερομηνία</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Επιγραφή</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Μήνυμα</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Ποσό</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(χωρίς ετικέτα)</translation>
+ </message>
+ <message>
+ <source>(no message)</source>
+ <translation>(κανένα μήνυμα)</translation>
+ </message>
+ <message>
+ <source>(no amount)</source>
+ <translation>(κανένα ποσό)</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Αποστολή νομισμάτων</translation>
+ </message>
+ <message>
+ <source>Coin Control Features</source>
+ <translation>Χαρακτηρηστικά επιλογής κερμάτων</translation>
+ </message>
+ <message>
+ <source>Inputs...</source>
+ <translation>Εισροές...</translation>
+ </message>
+ <message>
+ <source>automatically selected</source>
+ <translation>επιλεγμένο αυτόματα</translation>
+ </message>
+ <message>
+ <source>Insufficient funds!</source>
+ <translation>Ανεπαρκές κεφάλαιο!</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Ποσότητα:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Bytes:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Ποσό:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Προτεραιότητα:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Ταρίφα</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Ταρίφα αλλαγής</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Ρέστα:</translation>
+ </message>
+ <message>
+ <source>If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address.</source>
+ <translation>Όταν ενεργό, αλλά η διεύθυνση ρέστων είναι κενή ή άκυρη, τα ρέστα θα σταλούν σε μία πρόσφατα δημιουργημένη διεύθυνση.</translation>
+ </message>
+ <message>
+ <source>Custom change address</source>
+ <translation>Προσαρμοσμένη διεύθυνση ρέστων</translation>
+ </message>
+ <message>
+ <source>Transaction Fee:</source>
+ <translation>Τέλος συναλλαγής:</translation>
+ </message>
+ <message>
+ <source>Choose...</source>
+ <translation>Επιλογή...</translation>
+ </message>
+ <message>
+ <source>per kilobyte</source>
+ <translation>ανά kilobyte</translation>
+ </message>
+ <message>
+ <source>Hide</source>
+ <translation>Απόκρυψη</translation>
+ </message>
+ <message>
+ <source>total at least</source>
+ <translation>συνολικά τουλάχιστον</translation>
+ </message>
+ <message>
+ <source>Recommended:</source>
+ <translation>Προτεινόμενο: </translation>
+ </message>
+ <message>
+ <source>Custom:</source>
+ <translation>Προσαρμογή:</translation>
+ </message>
+ <message>
+ <source>Confirmation time:</source>
+ <translation>Χρόνος επικύρωσης:</translation>
+ </message>
+ <message>
+ <source>normal</source>
+ <translation>κανονικό</translation>
+ </message>
+ <message>
+ <source>fast</source>
+ <translation>Γρήγορο</translation>
+ </message>
+ <message>
+ <source>(confirmation may take longer)</source>
+ <translation>(η επικύρωση ίσως χρειαστεί περισσότερο χρόνο)</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>Αποστολή σε πολλούς αποδέκτες ταυτόχρονα</translation>
+ </message>
+ <message>
+ <source>Add &amp;Recipient</source>
+ <translation>&amp;Προσθήκη αποδέκτη</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Καθαρισμός όλων των πεδίων της φόρμας.</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Σκόνη</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Καθαρισμός &amp;Όλων</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>Υπόλοιπο:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>Επιβεβαίωση αποστολής</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>Αποστολη</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>Επιβεβαίωση αποστολής νομισμάτων</translation>
+ </message>
+ <message>
+ <source>%1 to %2</source>
+ <translation>%1 σε %2</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Αντιγραφή ποσότητας</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Αντιγραφή ποσού</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Αντιγραφή ταρίφας</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Αντιγραφή μετα-ταρίφας</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Αντιγραφή των byte</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Αντιγραφή προτεραιότητας</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Αντιγραφή των ρέστων</translation>
+ </message>
+ <message>
+ <source>or</source>
+ <translation>ή</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>Το ποσό πληρωμής πρέπει να είναι μεγαλύτερο από 0.</translation>
+ </message>
+ <message>
+ <source>The amount exceeds your balance.</source>
+ <translation>Το ποσό ξεπερνάει το διαθέσιμο υπόλοιπο</translation>
+ </message>
+ <message>
+ <source>The total exceeds your balance when the %1 transaction fee is included.</source>
+ <translation>Το σύνολο υπερβαίνει το υπόλοιπό σας όταν συμπεριληφθεί και η αμοιβή %1</translation>
+ </message>
+ <message>
+ <source>Transaction creation failed!</source>
+ <translation>Η δημιουργία της συναλλαγής απέτυχε!</translation>
+ </message>
+ <message>
+ <source>Warning: Invalid Bitcoin address</source>
+ <translation>Προειδοποίηση: Μη έγκυρη διεύθυνση Bitcoin</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(χωρίς ετικέτα)</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Αντιγραφή 'σκόνης'</translation>
+ </message>
+ <message>
+ <source>Are you sure you want to send?</source>
+ <translation>Είστε βέβαιοι για την αποστολή;</translation>
+ </message>
+ <message>
+ <source>added as transaction fee</source>
+ <translation>προστέθηκαν ως αμοιβή συναλλαγής</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>&amp;Ποσό:</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>Πληρωμή &amp;σε:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Εισάγετε μια επιγραφή για αυτή τη διεύθυνση ώστε να καταχωρηθεί στο βιβλίο διευθύνσεων</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Επιγραφή</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Επιλογή διεύθυνσης που έχει ήδη χρησιμοποιηθεί</translation>
+ </message>
+ <message>
+ <source>This is a normal payment.</source>
+ <translation>Αυτή είναι μια απλή πληρωμή.</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to send the payment to</source>
+ <translation>Η διεύθυνση Bitcoin που θα σταλεί η πληρωμή</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Επικόλληση διεύθυνσης από το βιβλίο διευθύνσεων</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Remove this entry</source>
+ <translation>Αφαίρεση αυτής της καταχώρησης</translation>
+ </message>
+ <message>
+ <source>Message:</source>
+ <translation>Μήνυμα:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to the list of used addresses</source>
+ <translation>Εισάγεται μία ετικέτα για αυτή την διεύθυνση για να προστεθεί στη λίστα με τις χρησιμοποιημένες διευθύνσεις</translation>
+ </message>
+ <message>
+ <source>Pay To:</source>
+ <translation>Πληρωμή σε:</translation>
+ </message>
+ <message>
+ <source>Memo:</source>
+ <translation>Σημείωση:</translation>
+ </message>
+</context>
+<context>
+ <name>ShutdownWindow</name>
+ <message>
+ <source>Bitcoin Core is shutting down...</source>
+ <translation>Το Bitcoin Core τερματίζεται...</translation>
+ </message>
+ <message>
+ <source>Do not shut down the computer until this window disappears.</source>
+ <translation>Μην απενεργοποιήσετε τον υπολογιστή μέχρι να κλείσει αυτό το παράθυρο.</translation>
+ </message>
+</context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Signatures - Sign / Verify a Message</source>
+ <translation>Υπογραφές - Είσοδος / Επαλήθευση μήνυματος </translation>
+ </message>
+ <message>
+ <source>&amp;Sign Message</source>
+ <translation>&amp;Υπογραφή Μηνύματος</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to sign the message with</source>
+ <translation>Διεύθυνση Bitcoin που θα σταλεί το μήνυμα</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Επιλογή διεύθυνσης που έχει ήδη χρησιμοποιηθεί</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Επικόλληση διεύθυνσης από το βιβλίο διευθύνσεων</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Enter the message you want to sign here</source>
+ <translation>Εισάγετε εδώ το μήνυμα που θέλετε να υπογράψετε</translation>
+ </message>
+ <message>
+ <source>Signature</source>
+ <translation>Υπογραφή</translation>
+ </message>
+ <message>
+ <source>Copy the current signature to the system clipboard</source>
+ <translation>Αντέγραφη της επιλεγμενης διεύθυνσης στο πρόχειρο του συστηματος</translation>
+ </message>
+ <message>
+ <source>Sign the message to prove you own this Bitcoin address</source>
+ <translation>Υπογράψτε ένα μήνυμα για ν' αποδείξετε πως σας ανήκει μια συγκεκριμένη διεύθυνση Bitcoin</translation>
+ </message>
+ <message>
+ <source>Sign &amp;Message</source>
+ <translation>Υπογραφη μήνυματος</translation>
+ </message>
+ <message>
+ <source>Reset all sign message fields</source>
+ <translation>Επαναφορά όλων των πεδίων μήνυματος</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Καθαρισμός &amp;Όλων</translation>
+ </message>
+ <message>
+ <source>&amp;Verify Message</source>
+ <translation>&amp;Επιβεβαίωση μηνύματος</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address the message was signed with</source>
+ <translation>Διεύθυνση Bitcoin η οποία το μήνυμα έχει υπογραφεί</translation>
+ </message>
+ <message>
+ <source>Verify the message to ensure it was signed with the specified Bitcoin address</source>
+ <translation>Υπογράψτε ένα μήνυμα για ν' αποδείξετε πως υπογραφθηκε απο μια συγκεκριμένη διεύθυνση Bitcoin</translation>
+ </message>
+ <message>
+ <source>Verify &amp;Message</source>
+ <translation>Επιβεβαίωση μηνύματος</translation>
+ </message>
+ <message>
+ <source>Reset all verify message fields</source>
+ <translation>Επαναφορά όλων επαλήθευμενων πεδίων μήνυματος </translation>
+ </message>
+ <message>
+ <source>Click "Sign Message" to generate signature</source>
+ <translation>Κάντε κλικ στο "Υπογραφή Μηνύματος" για να λάβετε την υπογραφή</translation>
+ </message>
+ <message>
+ <source>The entered address is invalid.</source>
+ <translation>Η διεύθυνση που εισήχθη είναι λάθος.</translation>
+ </message>
+ <message>
+ <source>Please check the address and try again.</source>
+ <translation>Παρακαλούμε ελέγξτε την διεύθυνση και δοκιμάστε ξανά.</translation>
+ </message>
+ <message>
+ <source>The entered address does not refer to a key.</source>
+ <translation>Η διεύθυνση που έχει εισαχθεί δεν αναφέρεται σε ένα πλήκτρο.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock was cancelled.</source>
+ <translation>το ξεκλείδωμα του πορτοφολιού απέτυχε</translation>
+ </message>
+ <message>
+ <source>Private key for the entered address is not available.</source>
+ <translation>Το προσωπικό κλειδί εισαγμενης διευθυνσης δεν είναι διαθέσιμο.</translation>
+ </message>
+ <message>
+ <source>Message signing failed.</source>
+ <translation>Η υπογραφή του μηνύματος απέτυχε.</translation>
+ </message>
+ <message>
+ <source>Message signed.</source>
+ <translation>Μήνυμα υπεγράφη.</translation>
+ </message>
+ <message>
+ <source>The signature could not be decoded.</source>
+ <translation>Η υπογραφή δεν μπόρεσε να αποκρυπτογραφηθεί.</translation>
+ </message>
+ <message>
+ <source>Please check the signature and try again.</source>
+ <translation>Παρακαλούμε ελέγξτε την υπογραφή και δοκιμάστε ξανά.</translation>
+ </message>
+ <message>
+ <source>The signature did not match the message digest.</source>
+ <translation>Η υπογραφή δεν ταιριάζει με το μήνυμα. </translation>
+ </message>
+ <message>
+ <source>Message verification failed.</source>
+ <translation>Η επιβεβαίωση του μηνύματος απέτυχε</translation>
+ </message>
+ <message>
+ <source>Message verified.</source>
+ <translation>Μήνυμα επιβεβαιώθηκε.</translation>
+ </message>
+</context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>The Bitcoin Core developers</source>
+ <translation>Οι προγραμματιστές του Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>[testnet]</source>
+ <translation>[testnet]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ <message>
+ <source>KB/s</source>
+ <translation>KB/s</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>Ανοιχτό μέχρι %1</translation>
+ </message>
+ <message>
+ <source>conflicted</source>
+ <translation>σύγκρουση</translation>
+ </message>
+ <message>
+ <source>%1/offline</source>
+ <translation>%1/χωρίς σύνδεση;</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/χωρίς επιβεβαίωση</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 επιβεβαιώσεις</translation>
+ </message>
+ <message>
+ <source>Status</source>
+ <translation>Κατάσταση</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Ημερομηνία</translation>
+ </message>
+ <message>
+ <source>Source</source>
+ <translation>Πηγή</translation>
+ </message>
+ <message>
+ <source>Generated</source>
+ <translation>Δημιουργία </translation>
+ </message>
+ <message>
+ <source>From</source>
+ <translation>Από</translation>
+ </message>
+ <message>
+ <source>To</source>
+ <translation>Προς</translation>
+ </message>
+ <message>
+ <source>own address</source>
+ <translation> δική σας διεύθυνση </translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>Επίβλεψη μόνο:</translation>
+ </message>
+ <message>
+ <source>label</source>
+ <translation>eπιγραφή</translation>
+ </message>
+ <message>
+ <source>Credit</source>
+ <translation>Πίστωση </translation>
+ </message>
+ <message>
+ <source>not accepted</source>
+ <translation>μη αποδεκτό</translation>
+ </message>
+ <message>
+ <source>Debit</source>
+ <translation>Debit</translation>
+ </message>
+ <message>
+ <source>Total debit</source>
+ <translation>Σύνολο χρέωσης</translation>
+ </message>
+ <message>
+ <source>Total credit</source>
+ <translation>Συνολική πίστωση</translation>
+ </message>
+ <message>
+ <source>Transaction fee</source>
+ <translation>Τέλος συναλλαγής </translation>
+ </message>
+ <message>
+ <source>Net amount</source>
+ <translation>Καθαρό ποσό</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Μήνυμα</translation>
+ </message>
+ <message>
+ <source>Comment</source>
+ <translation>Σχόλιο:</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>ID Συναλλαγής:</translation>
+ </message>
+ <message>
+ <source>Merchant</source>
+ <translation>Έμπορος</translation>
+ </message>
+ <message>
+ <source>Generated coins must mature %1 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.</source>
+ <translation>Πρέπει να περιμένετε %1 μπλοκ πριν μπορέσετε να χρησιμοποιήσετε τα νομίσματα που έχετε δημιουργήσει. Το μπλοκ που δημιουργήσατε μεταδόθηκε στο δίκτυο για να συμπεριληφθεί στην αλυσίδα των μπλοκ. Αν δεν μπει σε αυτή θα μετατραπεί σε "μη αποδεκτό" και δε θα μπορεί να καταναλωθεί. Αυτό συμβαίνει σπάνια όταν κάποιος άλλος κόμβος δημιουργήσει ένα μπλοκ λίγα δευτερόλεπτα πριν από εσάς.</translation>
+ </message>
+ <message>
+ <source>Debug information</source>
+ <translation>Πληροφορίες αποσφαλμάτωσης</translation>
+ </message>
+ <message>
+ <source>Transaction</source>
+ <translation>Συναλλαγή</translation>
+ </message>
+ <message>
+ <source>Inputs</source>
+ <translation>εισροές </translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Ποσό</translation>
+ </message>
+ <message>
+ <source>true</source>
+ <translation>αληθής</translation>
+ </message>
+ <message>
+ <source>false</source>
+ <translation>αναληθής </translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, δεν έχει ακόμα μεταδοθεί μ' επιτυχία</translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>άγνωστο</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>Λεπτομέρειες συναλλαγής</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>Αυτό το παράθυρο δείχνει μια λεπτομερή περιγραφή της συναλλαγής</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Ημερομηνία</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Τύπος</translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>Ανοιχτό μέχρι %1</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>Επικυρωμένη (%1 επικυρώσεις)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>Αυτό το μπλοκ δεν έχει παραληφθεί από κανέναν άλλο κόμβο και κατά πάσα πιθανότητα θα απορριφθεί!</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>Δημιουργήθηκε αλλά απορρίφθηκε</translation>
+ </message>
+ <message>
+ <source>Offline</source>
+ <translation>Offline</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Επιγραφή</translation>
+ </message>
+ <message>
+ <source>Unconfirmed</source>
+ <translation>Ανεπιβεβαίωτες</translation>
+ </message>
+ <message>
+ <source>Conflicted</source>
+ <translation>Σύγκρουση</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Ελήφθη με</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>Ελήφθη από</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Απεστάλη προς</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>Πληρωμή προς εσάς</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Εξόρυξη</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>Επίβλεψη μόνο:</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(δ/α)</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>Κατάσταση συναλλαγής. Πηγαίνετε το ποντίκι πάνω από αυτό το πεδίο για να δείτε τον αριθμό των επικυρώσεων</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Ημερομηνία κι ώρα λήψης της συναλλαγής.</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>Είδος συναλλαγής.</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>Ποσό που αφαιρέθηκε ή προστέθηκε στο υπόλοιπο.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>Όλα</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>Σήμερα</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>Αυτή την εβδομάδα</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>Αυτόν τον μήνα</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>Τον προηγούμενο μήνα</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>Αυτό το έτος</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>Έκταση...</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Ελήφθη με</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Απεστάλη προς</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>Προς εσάς</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Εξόρυξη</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>Άλλο</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>Αναζήτηση με βάση τη διεύθυνση ή την επιγραφή</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>Ελάχιστο ποσό</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Αντιγραφή διεύθυνσης</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Αντιγραφή επιγραφής</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Αντιγραφή ποσού</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Αντιγραφη του ID Συναλλαγής</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>Επεξεργασία επιγραφής</translation>
+ </message>
+ <message>
+ <source>Show transaction details</source>
+ <translation>Εμφάνιση λεπτομερειών συναλλαγής</translation>
+ </message>
+ <message>
+ <source>Export Transaction History</source>
+ <translation>Εξαγωγή Ιστορικού Συναλλαγών</translation>
+ </message>
+ <message>
+ <source>Watch-only</source>
+ <translation>Επίβλεψη μόνο:</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Η Εξαγωγή Απέτυχε</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the transaction history to %1.</source>
+ <translation>Yπήρξε σφάλμα κατά την προσπάθεια αποθήκευσης του ιστορικού συναλλαγών στο %1.</translation>
+ </message>
+ <message>
+ <source>Exporting Successful</source>
+ <translation>Επιτυχής εξαγωγή</translation>
+ </message>
+ <message>
+ <source>The transaction history was successfully saved to %1.</source>
+ <translation>Το ιστορικό συναλλαγών αποθηκεύτηκε επιτυχώς στο %1.</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Αρχείο οριοθετημένο με κόμματα (*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Επικυρωμένες</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Ημερομηνία</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Τύπος</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Επιγραφή</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Διεύθυνση</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>Έκταση:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>έως</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ <message>
+ <source>Unit to show amounts in. Click to select another unit.</source>
+ <translation>Μονάδα μέτρησης προβολής ποσών. Κάντε κλικ για επιλογή άλλης μονάδας.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletFrame</name>
+ <message>
+ <source>No wallet has been loaded.</source>
+ <translation>Δεν έχει φορτωθεί πορτοφόλι</translation>
+ </message>
+</context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Αποστολή νομισμάτων</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Εξαγωγή</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Εξαγωγή δεδομένων καρτέλας σε αρχείο</translation>
+ </message>
+ <message>
+ <source>Backup Wallet</source>
+ <translation>Αντίγραφο ασφαλείας του πορτοφολιού</translation>
+ </message>
+ <message>
+ <source>Wallet Data (*.dat)</source>
+ <translation>Αρχεία δεδομένων πορτοφολιού (*.dat)</translation>
+ </message>
+ <message>
+ <source>Backup Failed</source>
+ <translation>Αποτυχία κατά τη δημιουργία αντιγράφου</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the wallet data to %1.</source>
+ <translation>Παρουσιάστηκε σφάλμα κατά την αποθήκευση των δεδομένων πορτοφολιού στο %1.</translation>
+ </message>
+ <message>
+ <source>The wallet data was successfully saved to %1.</source>
+ <translation>Τα δεδομένα πορτοφολιού αποθηκεύτηκαν με επιτυχία στο %1.</translation>
+ </message>
+ <message>
+ <source>Backup Successful</source>
+ <translation>Η δημιουργια αντιγραφου ασφαλειας πετυχε</translation>
+ </message>
+</context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>Επιλογές:</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>Ορισμός φακέλου δεδομένων</translation>
+ </message>
+ <message>
+ <source>Connect to a node to retrieve peer addresses, and disconnect</source>
+ <translation>Σύνδεση σε έναν κόμβο για την ανάκτηση διευθύνσεων από ομοτίμους, και αποσυνδέσh</translation>
+ </message>
+ <message>
+ <source>Specify your own public address</source>
+ <translation>Διευκρινίστε τη δικιά σας δημόσια διεύθυνση.</translation>
+ </message>
+ <message>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>Αποδοχή εντολών κονσόλας και JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>Εκτέλεση στο παρασκήνιο κι αποδοχή εντολών</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>Χρήση του δοκιμαστικού δικτύου</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
+ <translation>Να δέχεσαι συνδέσεις από έξω(προεπιλογή:1)</translation>
+ </message>
+ <message>
+ <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
+ <translation>Αποθηκευση σε συγκεκριμένη διεύθυνση. Χρησιμοποιήστε τα πλήκτρα [Host] : συμβολισμός θύρα για IPv6</translation>
+ </message>
+ <message>
+ <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
+ <translation>Εκτέλεσε την εντολή όταν το καλύτερο μπλοκ αλλάξει(%s στην εντολή αντικαθίσταται από το hash του μπλοκ)</translation>
+ </message>
+ <message>
+ <source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source>
+ <translation>Αυτό είναι ένα προ-τεστ κυκλοφορίας - χρησιμοποιήστε το με δική σας ευθύνη - δεν χρησιμοποιείτε για εξόρυξη ή για αλλες εφαρμογές</translation>
+ </message>
+ <message>
+ <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>Προειδοποίηση: Η παράμετρος -paytxfee είναι πολύ υψηλή. Πρόκειται για την αμοιβή που θα πληρώνετε για κάθε συναλλαγή που θα στέλνετε.</translation>
+ </message>
+ <message>
+ <source>Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
+ <translation>Προειδοποίηση : Σφάλμα wallet.dat κατα την ανάγνωση ! Όλα τα κλειδιά αναγνωρισθηκαν σωστά, αλλά τα δεδομένα των συναλλαγών ή καταχωρήσεις στο βιβλίο διευθύνσεων μπορεί να είναι ελλιπείς ή λανθασμένα. </translation>
+ </message>
+ <message>
+ <source>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</source>
+ <translation>Προειδοποίηση : το αρχειο wallet.dat ειναι διεφθαρμένο, τα δεδομένα σώζονται ! Original wallet.dat αποθηκεύονται ως wallet.{timestamp}.bak στο %s . Αν το υπόλοιπο του ή τις συναλλαγές σας, είναι λάθος θα πρέπει να επαναφέρετε από ένα αντίγραφο ασφαλείας</translation>
+ </message>
+ <message>
+ <source>(default: 1)</source>
+ <translation>(προεπιλογή: 1)</translation>
+ </message>
+ <message>
+ <source>Attempt to recover private keys from a corrupt wallet.dat</source>
+ <translation>Προσπάθεια για ανακτησει ιδιωτικων κλειδιων από ενα διεφθαρμένο αρχειο wallet.dat </translation>
+ </message>
+ <message>
+ <source>Block creation options:</source>
+ <translation>Αποκλεισμός επιλογων δημιουργίας: </translation>
+ </message>
+ <message>
+ <source>Connect only to the specified node(s)</source>
+ <translation>Σύνδεση μόνο με ορισμένους κόμβους</translation>
+ </message>
+ <message>
+ <source>Connection options:</source>
+ <translation>Επιλογές σύνδεσης:</translation>
+ </message>
+ <message>
+ <source>Corrupted block database detected</source>
+ <translation>Εντοπισθηκε διεφθαρμενη βαση δεδομενων των μπλοκ</translation>
+ </message>
+ <message>
+ <source>Do you want to rebuild the block database now?</source>
+ <translation>Θελετε να δημιουργηθει τωρα η βαση δεδομενων του μπλοκ? </translation>
+ </message>
+ <message>
+ <source>Error initializing block database</source>
+ <translation>Σφάλμα κατά την ενεργοποίηση της βάσης δεδομένων μπλοκ</translation>
+ </message>
+ <message>
+ <source>Error initializing wallet database environment %s!</source>
+ <translation>Σφάλμα κατά την ενεργοποίηση της βάσης δεδομένων πορτοφόλιου %s!</translation>
+ </message>
+ <message>
+ <source>Error loading block database</source>
+ <translation>Σφάλμα φορτωσης της βασης δεδομενων των μπλοκ</translation>
+ </message>
+ <message>
+ <source>Error opening block database</source>
+ <translation>Σφάλμα φορτωσης της βασης δεδομενων των μπλοκ</translation>
+ </message>
+ <message>
+ <source>Error: Disk space is low!</source>
+ <translation>Προειδοποίηση: Χαμηλός χώρος στο δίσκο </translation>
+ </message>
+ <message>
+ <source>Failed to listen on any port. Use -listen=0 if you want this.</source>
+ <translation>ταλαιπωρηθειτε για να ακούσετε σε οποιαδήποτε θύρα. Χρήση - ακούστε = 0 , αν θέλετε αυτό.</translation>
+ </message>
+ <message>
+ <source>Importing...</source>
+ <translation>ΕΙσαγωγή...</translation>
+ </message>
+ <message>
+ <source>Invalid -onion address: '%s'</source>
+ <translation>Άκυρη διεύθυνση -onion : '%s'</translation>
+ </message>
+ <message>
+ <source>Not enough file descriptors available.</source>
+ <translation>Δεν ειναι αρκετες περιγραφες αρχείων διαθέσιμες.</translation>
+ </message>
+ <message>
+ <source>Only connect to nodes in network &lt;net&gt; (ipv4, ipv6 or onion)</source>
+ <translation>Μόνο σύνδεση σε κόμβους του δικτύου &lt;net&gt; (ipv4, ipv6 ή onion)</translation>
+ </message>
+ <message>
+ <source>Specify wallet file (within data directory)</source>
+ <translation>Επιλέξτε αρχείο πορτοφολιού (μέσα απο κατάλογο δεδομένων)</translation>
+ </message>
+ <message>
+ <source>Verifying blocks...</source>
+ <translation>Επαλήθευση των μπλοκ... </translation>
+ </message>
+ <message>
+ <source>Verifying wallet...</source>
+ <translation>Επαλήθευση πορτοφολιου... </translation>
+ </message>
+ <message>
+ <source>Wallet %s resides outside data directory %s</source>
+ <translation>Το πορτοφόλι %s βρίσκεται έξω από το φάκελο δεδομένων %s</translation>
+ </message>
+ <message>
+ <source>Wallet options:</source>
+ <translation>Επιλογές πορτοφολιού:</translation>
+ </message>
+ <message>
+ <source>Imports blocks from external blk000??.dat file</source>
+ <translation>Εισαγωγή μπλοκ από εξωτερικό αρχείο blk000?.dat</translation>
+ </message>
+ <message>
+ <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source>
+ <translation>Αδυναμία κλειδώματος του φακέλου δεδομένων %s. Πιθανώς το Bitcoin να είναι ήδη ενεργό.</translation>
+ </message>
+ <message>
+ <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source>
+ <translation>Προειδοποίηση: Παρακαλώ ελέγξτε ότι η ημερομηνία και ώρα του υπολογιστή σας είναι σωστά ρυθμισμένες! Εάν το ρολόι σας είναι λάθος το Bitcoin Core δεν θα λειτουργήσει σωστά. </translation>
+ </message>
+ <message>
+ <source>Choose data directory on startup (default: 0)</source>
+ <translation>Επιλογή φακέλου δεδομένων στην εκκίνηση (προεπιλεγμένο: 0)</translation>
+ </message>
+ <message>
+ <source>Connect through SOCKS5 proxy</source>
+ <translation>Σύνδεση μέσω διαμεσολαβητή SOCKS5</translation>
+ </message>
+ <message>
+ <source>Could not parse -rpcbind value %s as network address</source>
+ <translation>Δεν μπόρεσε να αναλυθεί η παράμετρος -rpcbind value %s ως διεύθυνση δικτύου</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source>
+ <translation>Σφάλμα φόρτωσης wallet.dat: Το Πορτοφόλι απαιτεί μια νεότερη έκδοση του Bitcoin</translation>
+ </message>
+ <message>
+ <source>Error reading from database, shutting down.</source>
+ <translation>Σφάλμα ανάγνωσης από τη βάση δεδομένων, γίνεται τερματισμός.</translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -tor found, use -onion.</source>
+ <translation>Σφάλμα: Μη συμβατή παράμετρος -tor. Χρησιμοποιήσε την παράμετρο -onion</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Πληροφορία</translation>
+ </message>
+ <message>
+ <source>Initialization sanity check failed. Bitcoin Core is shutting down.</source>
+ <translation>Η εκκίνηση ελέγχου ορθότητας απέτυχε. Γίνεται τερματισμός του Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -minrelaytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Μη έγκυρο ποσό για την παράμετρο -paytxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -mintxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Μη έγκυρο ποσό για την παράμετρο -paytxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Node relay options:</source>
+ <translation>Επιλογές αναμετάδοσης κόμβου: </translation>
+ </message>
+ <message>
+ <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source>
+ <translation>Ρυθμίσεις SSL: (ανατρέξτε στο Bitcoin Wiki για οδηγίες ρυθμίσεων SSL)</translation>
+ </message>
+ <message>
+ <source>RPC server options:</source>
+ <translation>Επιλογές διακομιστή RPC:</translation>
+ </message>
+ <message>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>Αποστολή πληροφοριών εντοπισμού σφαλμάτων στην κονσόλα αντί του αρχείου debug.log</translation>
+ </message>
+ <message>
+ <source>Set SSL root certificates for payment request (default: -system-)</source>
+ <translation>Ορίστε SSL root certificates για αίτηση πληρωμής (default: -system-)</translation>
+ </message>
+ <message>
+ <source>Set language, for example "de_DE" (default: system locale)</source>
+ <translation>Όρισε γλώσσα, για παράδειγμα "de_DE"(προεπιλογή:τοπικές ρυθμίσεις)</translation>
+ </message>
+ <message>
+ <source>Show all debugging options (usage: --help -help-debug)</source>
+ <translation>Προβολή όλων των επιλογών εντοπισμού σφαλμάτων (χρήση: --help -help-debug)</translation>
+ </message>
+ <message>
+ <source>Show splash screen on startup (default: 1)</source>
+ <translation>Εμφάνισε την οθόνη εκκίνησης κατά την εκκίνηση(προεπιλογή:1)</translation>
+ </message>
+ <message>
+ <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source>
+ <translation>Συρρίκνωση του αρχείο debug.log κατα την εκκίνηση του πελάτη (προεπιλογή: 1 όταν δεν-debug)</translation>
+ </message>
+ <message>
+ <source>Signing transaction failed</source>
+ <translation>Η υπογραφή συναλλαγής απέτυχε </translation>
+ </message>
+ <message>
+ <source>Start minimized</source>
+ <translation>Έναρξη ελαχιστοποιημένο</translation>
+ </message>
+ <message>
+ <source>This is experimental software.</source>
+ <translation>Η εφαρμογή είναι σε πειραματικό στάδιο.</translation>
+ </message>
+ <message>
+ <source>Transaction amount too small</source>
+ <translation>Το ποσό της συναλλαγής είναι πολύ μικρο </translation>
+ </message>
+ <message>
+ <source>Transaction amounts must be positive</source>
+ <translation>Τα ποσά των συναλλαγών πρέπει να είναι θετικα</translation>
+ </message>
+ <message>
+ <source>Transaction too large</source>
+ <translation>Η συναλλαγή ειναι πολύ μεγάλη </translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: 1 when listening)</source>
+ <translation>Χρησιμοποίηση του UPnP για την χρήση της πόρτας αναμονής (προεπιλογή:1)</translation>
+ </message>
+ <message>
+ <source>Username for JSON-RPC connections</source>
+ <translation>Όνομα χρήστη για τις συνδέσεις JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Προειδοποίηση</translation>
+ </message>
+ <message>
+ <source>Zapping all transactions from wallet...</source>
+ <translation>Μεταφορά όλων των συναλλαγών απο το πορτοφόλι</translation>
+ </message>
+ <message>
+ <source>on startup</source>
+ <translation>κατά την εκκίνηση</translation>
+ </message>
+ <message>
+ <source>wallet.dat corrupt, salvage failed</source>
+ <translation>Το αρχειο wallet.dat ειναι διεφθαρμένο, η διάσωση απέτυχε</translation>
+ </message>
+ <message>
+ <source>Password for JSON-RPC connections</source>
+ <translation>Κωδικός για τις συνδέσεις JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
+ <translation>Εκτέλεσε την εντολή όταν το καλύτερο μπλοκ αλλάξει(%s στην εντολή αντικαθίσταται από το hash του μπλοκ)</translation>
+ </message>
+ <message>
+ <source>Upgrade wallet to latest format</source>
+ <translation>Αναβάθμισε το πορτοφόλι στην τελευταία έκδοση</translation>
+ </message>
+ <message>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>Επανέλεγχος της αλυσίδας μπλοκ για απούσες συναλλαγές</translation>
+ </message>
+ <message>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>Χρήση του OpenSSL (https) για συνδέσεις JSON-RPC</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>Αυτό το κείμενο βοήθειας</translation>
+ </message>
+ <message>
+ <source>Allow DNS lookups for -addnode, -seednode and -connect</source>
+ <translation>Να επιτρέπονται οι έλεγχοι DNS για προσθήκη και σύνδεση κόμβων</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>Φόρτωση διευθύνσεων...</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>Σφάλμα φόρτωσης wallet.dat: Κατεστραμμένο Πορτοφόλι</translation>
+ </message>
+ <message>
+ <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
+ <translation>Πόσο εξονυχιστική να είναι η επιβεβαίωση του μπλοκ (0-4, προεπιλογή: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
+ <translation>Διατηρήση ένος πλήρες ευρετήριου συναλλαγών (προεπιλογή: %u) </translation>
+ </message>
+ <message>
+ <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source>
+ <translation>Δευτερόλεπτα πριν επιτραπεί ξανά η σύνδεση των προβληματικών peers (προεπιλογή: %u)</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>Σφάλμα φόρτωσης αρχείου wallet.dat</translation>
+ </message>
+ <message>
+ <source>Generate coins (default: %u)</source>
+ <translation>Δημιουργία νομισμάτων (προκαθορισμος: %u)</translation>
+ </message>
+ <message>
+ <source>How many blocks to check at startup (default: %u, 0 = all)</source>
+ <translation>Πόσα μπλοκ να ελέγχθουν κατά την εκκίνηση (προεπιλογή: %u, 0 = όλα)</translation>
+ </message>
+ <message>
+ <source>Include IP addresses in debug output (default: %u)</source>
+ <translation>Να συμπεριληφθεί η διεύθυνση IP στην αναφορά? (προεπιλογή: %u)</translation>
+ </message>
+ <message>
+ <source>Invalid -proxy address: '%s'</source>
+ <translation>Δεν είναι έγκυρη η διεύθυνση διαμεσολαβητή: '%s'</translation>
+ </message>
+ <message>
+ <source>Server certificate file (default: %s)</source>
+ <translation>Αρχείο πιστοποιητικού του διακομιστή (προεπιλογή: %s)</translation>
+ </message>
+ <message>
+ <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source>
+ <translation>Ορισμός λήξης χρονικού ορίου σε χιλιοστά του δευτερολέπτου(προεπιλογή: %d)</translation>
+ </message>
+ <message>
+ <source>Specify pid file (default: %s)</source>
+ <translation>Ορίστε αρχείο pid (προεπιλογή: %s)</translation>
+ </message>
+ <message>
+ <source>Threshold for disconnecting misbehaving peers (default: %u)</source>
+ <translation>Όριο αποσύνδεσης προβληματικών peers (προεπιλογή: %u)</translation>
+ </message>
+ <message>
+ <source>Unknown network specified in -onlynet: '%s'</source>
+ <translation>Άγνωστo δίκτυο ορίζεται σε onlynet: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -bind address: '%s'</source>
+ <translation>Δεν μπορώ να γράψω την προεπιλεγμένη διεύθυνση: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -externalip address: '%s'</source>
+ <translation>Δεν μπορώ να γράψω την προεπιλεγμένη διεύθυνση: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Μη έγκυρο ποσό για την παράμετρο -paytxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>Ανεπαρκές κεφάλαιο</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>Φόρτωση ευρετηρίου μπλοκ...</translation>
+ </message>
+ <message>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>Προσέθεσε ένα κόμβο για σύνδεση και προσπάθησε να κρατήσεις την σύνδεση ανοιχτή</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>Φόρτωση πορτοφολιού...</translation>
+ </message>
+ <message>
+ <source>Cannot downgrade wallet</source>
+ <translation>Δεν μπορώ να υποβαθμίσω το πορτοφόλι</translation>
+ </message>
+ <message>
+ <source>Cannot write default address</source>
+ <translation>Δεν μπορώ να γράψω την προεπιλεγμένη διεύθυνση</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>Ανίχνευση...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>Η φόρτωση ολοκληρώθηκε</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Σφάλμα</translation>
+ </message>
+</context>
+</TS> \ 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 0000000000..2285158545
--- /dev/null
+++ b/src/qt/locale/bitcoin_en.ts
@@ -0,0 +1,4576 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="en">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="+30"/>
+ <source>Right-click to edit address or label</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+27"/>
+ <source>Create a new address</source>
+ <translation>Create a new address</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>&amp;New</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+14"/>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Copy the currently selected address to the system clipboard</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>&amp;Copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+67"/>
+ <source>C&amp;lose</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../addressbookpage.cpp" line="+80"/>
+ <source>&amp;Copy Address</source>
+ <translation>&amp;Copy Address</translation>
+ </message>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="-53"/>
+ <source>Delete the currently selected address from the list</source>
+ <translation>Delete the currently selected address from the list</translation>
+ </message>
+ <message>
+ <location line="+30"/>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Export the data in the current tab to a file</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>&amp;Export</source>
+ <translation>&amp;Export</translation>
+ </message>
+ <message>
+ <location line="-30"/>
+ <source>&amp;Delete</source>
+ <translation>&amp;Delete</translation>
+ </message>
+ <message>
+ <location filename="../addressbookpage.cpp" line="-30"/>
+ <source>Choose the address to send coins to</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Choose the address to receive coins with</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>C&amp;hoose</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Sending addresses</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Receiving addresses</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>Copy &amp;Label</source>
+ <translation>Copy &amp;Label</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>&amp;Edit</source>
+ <translation>&amp;Edit</translation>
+ </message>
+ <message>
+ <location line="+193"/>
+ <source>Export Address List</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Comma separated file (*.csv)</translation>
+ </message>
+ <message>
+ <location line="+13"/>
+ <source>Exporting Failed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>There was an error trying to save the address list to %1. Please try again.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <location filename="../addresstablemodel.cpp" line="+170"/>
+ <source>Label</source>
+ <translation>Label</translation>
+ </message>
+ <message>
+ <location line="+0"/>
+ <source>Address</source>
+ <translation>Address</translation>
+ </message>
+ <message>
+ <location line="+36"/>
+ <source>(no label)</source>
+ <translation>(no label)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <location filename="../forms/askpassphrasedialog.ui" line="+26"/>
+ <source>Passphrase Dialog</source>
+ <translation>Passphrase Dialog</translation>
+ </message>
+ <message>
+ <location line="+30"/>
+ <source>Enter passphrase</source>
+ <translation>Enter passphrase</translation>
+ </message>
+ <message>
+ <location line="+14"/>
+ <source>New passphrase</source>
+ <translation>New passphrase</translation>
+ </message>
+ <message>
+ <location line="+14"/>
+ <source>Repeat new passphrase</source>
+ <translation>Repeat new passphrase</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="+45"/>
+ <source>Encrypt wallet</source>
+ <translation>Encrypt wallet</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>This operation needs your wallet passphrase to unlock the wallet.</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Unlock wallet</source>
+ <translation>Unlock wallet</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>This operation needs your wallet passphrase to decrypt the wallet.</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Decrypt wallet</source>
+ <translation>Decrypt wallet</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Change passphrase</source>
+ <translation>Change passphrase</translation>
+ </message>
+ <message>
+ <location line="+46"/>
+ <source>Confirm wallet encryption</source>
+ <translation>Confirm wallet encryption</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</translation>
+ </message>
+ <message>
+ <location line="+0"/>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>Are you sure you wish to encrypt your wallet?</translation>
+ </message>
+ <message>
+ <location line="+11"/>
+ <source>Bitcoin Core 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.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
+ <translation>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</translation>
+ </message>
+ <message>
+ <location line="+100"/>
+ <location line="+24"/>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>Warning: The Caps Lock key is on!</translation>
+ </message>
+ <message>
+ <location line="-130"/>
+ <location line="+58"/>
+ <source>Wallet encrypted</source>
+ <translation>Wallet encrypted</translation>
+ </message>
+ <message>
+ <location line="-136"/>
+ <source>Enter the new passphrase to the wallet.&lt;br/&gt;Please use a passphrase of &lt;b&gt;ten or more random characters&lt;/b&gt;, or &lt;b&gt;eight or more words&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+23"/>
+ <source>Enter the old passphrase and new passphrase to the wallet.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+70"/>
+ <location line="+7"/>
+ <location line="+42"/>
+ <location line="+6"/>
+ <source>Wallet encryption failed</source>
+ <translation>Wallet encryption failed</translation>
+ </message>
+ <message>
+ <location line="-54"/>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <location line="+48"/>
+ <source>The supplied passphrases do not match.</source>
+ <translation>The supplied passphrases do not match.</translation>
+ </message>
+ <message>
+ <location line="-37"/>
+ <source>Wallet unlock failed</source>
+ <translation>Wallet unlock failed</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <location line="+11"/>
+ <location line="+19"/>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>The passphrase entered for the wallet decryption was incorrect.</translation>
+ </message>
+ <message>
+ <location line="-20"/>
+ <source>Wallet decryption failed</source>
+ <translation>Wallet decryption failed</translation>
+ </message>
+ <message>
+ <location line="+14"/>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>Wallet passphrase was successfully changed.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <location filename="../bitcoingui.cpp" line="+326"/>
+ <source>Sign &amp;message...</source>
+ <translation>Sign &amp;message...</translation>
+ </message>
+ <message>
+ <location line="+343"/>
+ <source>Synchronizing with network...</source>
+ <translation>Synchronizing with network...</translation>
+ </message>
+ <message>
+ <location line="-419"/>
+ <source>&amp;Overview</source>
+ <translation>&amp;Overview</translation>
+ </message>
+ <message>
+ <location line="-134"/>
+ <source>Node</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+135"/>
+ <source>Show general overview of wallet</source>
+ <translation>Show general overview of wallet</translation>
+ </message>
+ <message>
+ <location line="+28"/>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Transactions</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Browse transaction history</source>
+ <translation>Browse transaction history</translation>
+ </message>
+ <message>
+ <location line="+23"/>
+ <source>E&amp;xit</source>
+ <translation>E&amp;xit</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Quit application</source>
+ <translation>Quit application</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>About &amp;Qt</source>
+ <translation>About &amp;Qt</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Show information about Qt</source>
+ <translation>Show information about Qt</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>&amp;Options...</source>
+ <translation>&amp;Options...</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>&amp;Encrypt Wallet...</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>&amp;Backup Wallet...</source>
+ <translation>&amp;Backup Wallet...</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>&amp;Change Passphrase...</source>
+ <translation>&amp;Change Passphrase...</translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>&amp;Sending addresses...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>&amp;Receiving addresses...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Open &amp;URI...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+176"/>
+ <source>Bitcoin Core client</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+157"/>
+ <source>Importing blocks from disk...</source>
+ <translation>Importing blocks from disk...</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Reindexing blocks on disk...</source>
+ <translation>Reindexing blocks on disk...</translation>
+ </message>
+ <message>
+ <location line="-417"/>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>Send coins to a Bitcoin address</translation>
+ </message>
+ <message>
+ <location line="+65"/>
+ <source>Backup wallet to another location</source>
+ <translation>Backup wallet to another location</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Change the passphrase used for wallet encryption</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>&amp;Debug window</source>
+ <translation>&amp;Debug window</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Open debugging and diagnostic console</source>
+ <translation>Open debugging and diagnostic console</translation>
+ </message>
+ <message>
+ <location line="-4"/>
+ <source>&amp;Verify message...</source>
+ <translation>&amp;Verify message...</translation>
+ </message>
+ <message>
+ <location line="+440"/>
+ <source>Bitcoin</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <location line="-654"/>
+ <source>Wallet</source>
+ <translation>Wallet</translation>
+ </message>
+ <message>
+ <location line="+143"/>
+ <source>&amp;Send</source>
+ <translation>&amp;Send</translation>
+ </message>
+ <message>
+ <location line="+11"/>
+ <source>&amp;Receive</source>
+ <translation>&amp;Receive</translation>
+ </message>
+ <message>
+ <location line="+40"/>
+ <source>Show information about Bitcoin Core</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>&amp;Show / Hide</source>
+ <translation>&amp;Show / Hide</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Show or hide the main Window</source>
+ <translation>Show or hide the main Window</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Encrypt the private keys that belong to your wallet</source>
+ <translation>Encrypt the private keys that belong to your wallet</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>Sign messages with your Bitcoin addresses to prove you own them</source>
+ <translation>Sign messages with your Bitcoin addresses to prove you own them</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source>
+ <translation>Verify messages to ensure they were signed with specified Bitcoin addresses</translation>
+ </message>
+ <message>
+ <location line="+49"/>
+ <source>&amp;File</source>
+ <translation>&amp;File</translation>
+ </message>
+ <message>
+ <location line="+14"/>
+ <source>&amp;Settings</source>
+ <translation>&amp;Settings</translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>&amp;Help</source>
+ <translation>&amp;Help</translation>
+ </message>
+ <message>
+ <location line="+15"/>
+ <source>Tabs toolbar</source>
+ <translation>Tabs toolbar</translation>
+ </message>
+ <message>
+ <location line="-311"/>
+ <source>Bitcoin Core</source>
+ <translation type="unfinished">Bitcoin Core</translation>
+ </message>
+ <message>
+ <location line="+164"/>
+ <source>Request payments (generates QR codes and bitcoin: URIs)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+38"/>
+ <source>&amp;About Bitcoin Core</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>Modify configuration options for Bitcoin Core</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+21"/>
+ <source>Show the list of used sending addresses and labels</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Show the list of used receiving addresses and labels</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Open a bitcoin: URI or payment request</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>&amp;Command-line options</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location line="+310"/>
+ <source>%n active connection(s) to Bitcoin network</source>
+ <translation>
+ <numerusform>%n active connection to Bitcoin network</numerusform>
+ <numerusform>%n active connections to Bitcoin network</numerusform>
+ </translation>
+ </message>
+ <message>
+ <location line="+25"/>
+ <source>No block source available...</source>
+ <translation>No block source available...</translation>
+ </message>
+ <message numerus="yes">
+ <location line="+9"/>
+ <source>Processed %n block(s) of transaction history.</source>
+ <translation>
+ <numerusform>Processed %n block of transaction history.</numerusform>
+ <numerusform>Processed %n blocks of transaction history.</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location line="+26"/>
+ <source>%n hour(s)</source>
+ <translation>
+ <numerusform>%n hour</numerusform>
+ <numerusform>%n hours</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location line="+4"/>
+ <source>%n day(s)</source>
+ <translation>
+ <numerusform>%n day</numerusform>
+ <numerusform>%n days</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location line="+4"/>
+ <location line="+6"/>
+ <source>%n week(s)</source>
+ <translation>
+ <numerusform>%n week</numerusform>
+ <numerusform>%n weeks</numerusform>
+ </translation>
+ </message>
+ <message>
+ <location line="+0"/>
+ <source>%1 and %2</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location line="+0"/>
+ <source>%n year(s)</source>
+ <translation type="unfinished">
+ <numerusform>%n year</numerusform>
+ <numerusform>%n years</numerusform>
+ </translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>%1 behind</source>
+ <translation>%1 behind</translation>
+ </message>
+ <message>
+ <location line="+21"/>
+ <source>Last received block was generated %1 ago.</source>
+ <translation>Last received block was generated %1 ago.</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Transactions after this will not yet be visible.</source>
+ <translation>Transactions after this will not yet be visible.</translation>
+ </message>
+ <message>
+ <location line="+27"/>
+ <source>Error</source>
+ <translation>Error</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Warning</source>
+ <translation>Warning</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Information</source>
+ <translation>Information</translation>
+ </message>
+ <message>
+ <location line="-95"/>
+ <source>Up to date</source>
+ <translation>Up to date</translation>
+ </message>
+ <message>
+ <location line="+44"/>
+ <source>Catching up...</source>
+ <translation>Catching up...</translation>
+ </message>
+ <message>
+ <location line="+129"/>
+ <source>Date: %1
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Amount: %1
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Type: %1
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Label: %1
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Address: %1
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Sent transaction</source>
+ <translation>Sent transaction</translation>
+ </message>
+ <message>
+ <location line="+0"/>
+ <source>Incoming transaction</source>
+ <translation>Incoming transaction</translation>
+ </message>
+ <message>
+ <location line="+62"/>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <location filename="../clientmodel.cpp" line="+141"/>
+ <source>Network Alert</source>
+ <translation>Network Alert</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <location filename="../forms/coincontroldialog.ui" line="+14"/>
+ <source>Coin Selection</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+34"/>
+ <source>Quantity:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+29"/>
+ <source>Bytes:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+45"/>
+ <source>Amount:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+29"/>
+ <source>Priority:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+45"/>
+ <source>Fee:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+32"/>
+ <source>Dust:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+48"/>
+ <source>After Fee:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+32"/>
+ <source>Change:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+56"/>
+ <source>(un)select all</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+16"/>
+ <source>Tree mode</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+13"/>
+ <source>List mode</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+56"/>
+ <source>Amount</source>
+ <translation type="unfinished">Amount</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Received with label</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Received with address</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Date</source>
+ <translation type="unfinished">Date</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Confirmations</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Confirmed</source>
+ <translation type="unfinished">Confirmed</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Priority</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../coincontroldialog.cpp" line="+46"/>
+ <source>Copy address</source>
+ <translation type="unfinished">Copy address</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Copy label</source>
+ <translation type="unfinished">Copy label</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <location line="+26"/>
+ <source>Copy amount</source>
+ <translation type="unfinished">Copy amount</translation>
+ </message>
+ <message>
+ <location line="-25"/>
+ <source>Copy transaction ID</source>
+ <translation type="unfinished">Copy transaction ID</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Lock unspent</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Unlock unspent</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+22"/>
+ <source>Copy quantity</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Copy fee</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Copy after fee</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Copy bytes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Copy priority</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Copy dust</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Copy change</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+351"/>
+ <source>highest</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>higher</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>high</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>medium-high</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>low-medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>low</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>lower</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>lowest</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>(%1 locked)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+28"/>
+ <source>none</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+161"/>
+ <source>This label turns red if the transaction size is greater than 1000 bytes.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>This label turns red if the priority is smaller than &quot;medium&quot;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>This label turns red if any recipient receives an amount smaller than %1.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>Can vary +/- %1 satoshi(s) per input.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="-32"/>
+ <source>yes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+0"/>
+ <source>no</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+17"/>
+ <location line="+5"/>
+ <source>This means a fee of at least %1 per kB is required.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="-4"/>
+ <source>Can vary +/- 1 byte per input.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Transactions with higher priority are more likely to get included into a block.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+59"/>
+ <location line="+61"/>
+ <source>(no label)</source>
+ <translation type="unfinished">(no label)</translation>
+ </message>
+ <message>
+ <location line="-7"/>
+ <source>change from %1 (%2)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>(change)</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <location filename="../forms/editaddressdialog.ui" line="+14"/>
+ <source>Edit Address</source>
+ <translation>Edit Address</translation>
+ </message>
+ <message>
+ <location line="+11"/>
+ <source>&amp;Label</source>
+ <translation>&amp;Label</translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>The label associated with this address list entry</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+17"/>
+ <source>The address associated with this address list entry. This can only be modified for sending addresses.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="-10"/>
+ <source>&amp;Address</source>
+ <translation>&amp;Address</translation>
+ </message>
+ <message>
+ <location filename="../editaddressdialog.cpp" line="+28"/>
+ <source>New receiving address</source>
+ <translation>New receiving address</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>New sending address</source>
+ <translation>New sending address</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Edit receiving address</source>
+ <translation>Edit receiving address</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Edit sending address</source>
+ <translation>Edit sending address</translation>
+ </message>
+ <message>
+ <location line="+76"/>
+ <source>The entered address &quot;%1&quot; is already in the address book.</source>
+ <translation>The entered address &quot;%1&quot; is already in the address book.</translation>
+ </message>
+ <message>
+ <location line="-5"/>
+ <source>The entered address &quot;%1&quot; is not a valid Bitcoin address.</source>
+ <translation>The entered address &quot;%1&quot; is not a valid Bitcoin address.</translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>Could not unlock wallet.</source>
+ <translation>Could not unlock wallet.</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>New key generation failed.</source>
+ <translation>New key generation failed.</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ <message>
+ <location filename="../intro.cpp" line="+69"/>
+ <source>A new data directory will be created.</source>
+ <translation>A new data directory will be created.</translation>
+ </message>
+ <message>
+ <location line="+22"/>
+ <source>name</source>
+ <translation>name</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Directory already exists. Add %1 if you intend to create a new directory here.</source>
+ <translation>Directory already exists. Add %1 if you intend to create a new directory here.</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Path already exists, and is not a directory.</source>
+ <translation>Path already exists, and is not a directory.</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>Cannot create data directory here.</source>
+ <translation>Cannot create data directory here.</translation>
+ </message>
+</context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <location filename="../utilitydialog.cpp" line="+33"/>
+ <source>Bitcoin Core</source>
+ <translation type="unfinished">Bitcoin Core</translation>
+ </message>
+ <message>
+ <location line="+0"/>
+ <source>version</source>
+ <translation type="unfinished">version</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <location line="+2"/>
+ <source>(%1-bit)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>About Bitcoin Core</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+19"/>
+ <source>Command-line options</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Usage:</source>
+ <translation type="unfinished">Usage:</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>command-line options</source>
+ <translation type="unfinished">command-line options</translation>
+ </message>
+</context>
+<context>
+ <name>Intro</name>
+ <message>
+ <location filename="../forms/intro.ui" line="+14"/>
+ <source>Welcome</source>
+ <translation>Welcome</translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>Welcome to Bitcoin Core.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+26"/>
+ <source>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>Use the default data directory</source>
+ <translation>Use the default data directory</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>Use a custom data directory:</source>
+ <translation>Use a custom data directory:</translation>
+ </message>
+ <message>
+ <location filename="../intro.cpp" line="+82"/>
+ <source>Bitcoin Core</source>
+ <translation type="unfinished">Bitcoin Core</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Error: Specified data directory &quot;%1&quot; cannot be created.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+24"/>
+ <source>Error</source>
+ <translation>Error</translation>
+ </message>
+ <message numerus="yes">
+ <location line="+9"/>
+ <source>%n GB of free space available</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location line="+3"/>
+ <source>(of %n GB needed)</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+</context>
+<context>
+ <name>OpenURIDialog</name>
+ <message>
+ <location filename="../forms/openuridialog.ui" line="+14"/>
+ <source>Open URI</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Open payment request from URI or file</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>URI:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>Select payment request file</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../openuridialog.cpp" line="+47"/>
+ <source>Select payment request file to open</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <location filename="../forms/optionsdialog.ui" line="+14"/>
+ <source>Options</source>
+ <translation>Options</translation>
+ </message>
+ <message>
+ <location line="+13"/>
+ <source>&amp;Main</source>
+ <translation>&amp;Main</translation>
+ </message>
+ <message>
+ <location line="+18"/>
+ <source>Size of &amp;database cache</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+16"/>
+ <source>MB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+27"/>
+ <source>Number of script &amp;verification threads</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+114"/>
+ <source>Accept connections from outside</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Allow incoming connections</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+44"/>
+ <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+84"/>
+ <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+45"/>
+ <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+35"/>
+ <location line="+13"/>
+ <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="-10"/>
+ <source>Third party transaction URLs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+41"/>
+ <source>Active command-line options that override above options:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+43"/>
+ <source>Reset all client options to default.</source>
+ <translation>Reset all client options to default.</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>&amp;Reset Options</source>
+ <translation>&amp;Reset Options</translation>
+ </message>
+ <message>
+ <location line="-317"/>
+ <source>&amp;Network</source>
+ <translation>&amp;Network</translation>
+ </message>
+ <message>
+ <location line="-153"/>
+ <source>Automatically start Bitcoin Core after logging in to the system.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>&amp;Start Bitcoin Core on system login</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+65"/>
+ <source>(0 = auto, &lt;0 = leave that many cores free)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+36"/>
+ <source>W&amp;allet</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Expert</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>Enable coin &amp;control features</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>&amp;Spend unconfirmed change</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+30"/>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Map port using &amp;UPnP</source>
+ <translation>Map port using &amp;UPnP</translation>
+ </message>
+ <message>
+ <location line="+17"/>
+ <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>&amp;Connect through SOCKS5 proxy (default proxy):</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>Proxy &amp;IP:</source>
+ <translation>Proxy &amp;IP:</translation>
+ </message>
+ <message>
+ <location line="+32"/>
+ <source>&amp;Port:</source>
+ <translation>&amp;Port:</translation>
+ </message>
+ <message>
+ <location line="+25"/>
+ <source>Port of the proxy (e.g. 9050)</source>
+ <translation>Port of the proxy (e.g. 9050)</translation>
+ </message>
+ <message>
+ <location line="+36"/>
+ <source>&amp;Window</source>
+ <translation>&amp;Window</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Show only a tray icon after minimizing the window.</source>
+ <translation>Show only a tray icon after minimizing the window.</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>&amp;Minimize to the tray instead of the taskbar</translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>M&amp;inimize on close</source>
+ <translation>M&amp;inimize on close</translation>
+ </message>
+ <message>
+ <location line="+21"/>
+ <source>&amp;Display</source>
+ <translation>&amp;Display</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>User Interface &amp;language:</source>
+ <translation>User Interface &amp;language:</translation>
+ </message>
+ <message>
+ <location line="+24"/>
+ <source>&amp;Unit to show amounts in:</source>
+ <translation>&amp;Unit to show amounts in:</translation>
+ </message>
+ <message>
+ <location line="+13"/>
+ <source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
+ <translation>Choose the default subdivision unit to show in the interface and when sending coins.</translation>
+ </message>
+ <message>
+ <location line="-253"/>
+ <source>Whether to show coin control features or not.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+415"/>
+ <source>&amp;OK</source>
+ <translation>&amp;OK</translation>
+ </message>
+ <message>
+ <location line="+13"/>
+ <source>&amp;Cancel</source>
+ <translation>&amp;Cancel</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="+75"/>
+ <source>default</source>
+ <translation>default</translation>
+ </message>
+ <message>
+ <location line="+59"/>
+ <source>none</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+76"/>
+ <source>Confirm options reset</source>
+ <translation>Confirm options reset</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <location line="+29"/>
+ <source>Client restart required to activate changes.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="-29"/>
+ <source>Client will be shut down. Do you want to proceed?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+33"/>
+ <source>This change would require a client restart.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+25"/>
+ <source>The supplied proxy address is invalid.</source>
+ <translation>The supplied proxy address is invalid.</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <location filename="../forms/overviewpage.ui" line="+14"/>
+ <source>Form</source>
+ <translation>Form</translation>
+ </message>
+ <message>
+ <location line="+59"/>
+ <location line="+386"/>
+ <source>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.</source>
+ <translation>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.</translation>
+ </message>
+ <message>
+ <location line="-139"/>
+ <source>Watch-only:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>Available:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+16"/>
+ <source>Your current spendable balance</source>
+ <translation>Your current spendable balance</translation>
+ </message>
+ <message>
+ <location line="+41"/>
+ <source>Pending:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="-236"/>
+ <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source>
+ <translation>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</translation>
+ </message>
+ <message>
+ <location line="+112"/>
+ <source>Immature:</source>
+ <translation>Immature:</translation>
+ </message>
+ <message>
+ <location line="-29"/>
+ <source>Mined balance that has not yet matured</source>
+ <translation>Mined balance that has not yet matured</translation>
+ </message>
+ <message>
+ <location line="-177"/>
+ <source>Balances</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+161"/>
+ <source>Total:</source>
+ <translation>Total:</translation>
+ </message>
+ <message>
+ <location line="+61"/>
+ <source>Your current total balance</source>
+ <translation>Your current total balance</translation>
+ </message>
+ <message>
+ <location line="+92"/>
+ <source>Your current balance in watch-only addresses</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+23"/>
+ <source>Spendable:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+49"/>
+ <source>Recent transactions</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="-317"/>
+ <source>Unconfirmed transactions to watch-only addresses</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+50"/>
+ <source>Mined balance in watch-only addresses that has not yet matured</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+128"/>
+ <source>Current total balance in watch-only addresses</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PaymentServer</name>
+ <message>
+ <location filename="../paymentserver.cpp" line="+434"/>
+ <location line="+14"/>
+ <location line="+7"/>
+ <source>URI handling</source>
+ <translation type="unfinished">URI handling</translation>
+ </message>
+ <message>
+ <location line="-7"/>
+ <source>Invalid payment address %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+88"/>
+ <location line="+9"/>
+ <location line="+31"/>
+ <location line="+10"/>
+ <location line="+17"/>
+ <source>Payment request rejected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="-67"/>
+ <source>Payment request network doesn&apos;t match client network.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+15"/>
+ <source>Payment request is not initialized.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+42"/>
+ <source>Requested payment amount of %1 is too small (considered dust).</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="-263"/>
+ <location line="+221"/>
+ <location line="+42"/>
+ <location line="+114"/>
+ <location line="+14"/>
+ <location line="+18"/>
+ <source>Payment request error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="-408"/>
+ <source>Cannot start bitcoin: click-to-pay handler</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+104"/>
+ <source>Payment request fetch URL is invalid: %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+21"/>
+ <source>URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+13"/>
+ <source>Payment request file handling</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Payment request file cannot be read! This can be caused by an invalid payment request file.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+75"/>
+ <source>Payment request expired.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+32"/>
+ <source>Unverified payment requests to custom payment scripts are unsupported.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <location line="+17"/>
+ <source>Invalid payment request.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+45"/>
+ <source>Refund from %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+43"/>
+ <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Payment request DoS protection</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Error communicating with %1: %2</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+20"/>
+ <source>Payment request cannot be parsed!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+13"/>
+ <source>Bad response from server %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+33"/>
+ <source>Payment acknowledged</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="-11"/>
+ <source>Network request error</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PeerTableModel</name>
+ <message>
+ <location filename="../peertablemodel.cpp" line="+118"/>
+ <source>User Agent</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+0"/>
+ <source>Node/Service</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+0"/>
+ <source>Ping Time</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <location filename="../bitcoinunits.cpp" line="+183"/>
+ <source>Amount</source>
+ <translation type="unfinished">Amount</translation>
+ </message>
+ <message>
+ <location filename="../guiutil.cpp" line="+110"/>
+ <source>Enter a Bitcoin address (e.g. %1)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+748"/>
+ <source>%1 d</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>%1 h</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>%1 m</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <location line="+41"/>
+ <source>%1 s</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="-10"/>
+ <source>None</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>N/A</source>
+ <translation type="unfinished">N/A</translation>
+ </message>
+ <message>
+ <location line="+0"/>
+ <source>%1 ms</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>QRImageWidget</name>
+ <message>
+ <location filename="../receiverequestdialog.cpp" line="+36"/>
+ <source>&amp;Save Image...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>&amp;Copy Image</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+32"/>
+ <source>Save QR Code</source>
+ <translation type="unfinished">Save QR Code</translation>
+ </message>
+ <message>
+ <location line="+0"/>
+ <source>PNG Image (*.png)</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="+46"/>
+ <source>Client name</source>
+ <translation>Client name</translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <location line="+23"/>
+ <location line="+26"/>
+ <location line="+26"/>
+ <location line="+23"/>
+ <location line="+23"/>
+ <location line="+36"/>
+ <location line="+23"/>
+ <location line="+36"/>
+ <location line="+23"/>
+ <location line="+465"/>
+ <location line="+23"/>
+ <location line="+23"/>
+ <location line="+23"/>
+ <location line="+23"/>
+ <location line="+23"/>
+ <location line="+23"/>
+ <location line="+23"/>
+ <location line="+23"/>
+ <location line="+23"/>
+ <location line="+23"/>
+ <location line="+23"/>
+ <location line="+23"/>
+ <location line="+23"/>
+ <source>N/A</source>
+ <translation>N/A</translation>
+ </message>
+ <message>
+ <location line="-990"/>
+ <source>Client version</source>
+ <translation>Client version</translation>
+ </message>
+ <message>
+ <location line="-45"/>
+ <source>&amp;Information</source>
+ <translation>&amp;Information</translation>
+ </message>
+ <message>
+ <location line="-10"/>
+ <source>Debug window</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+25"/>
+ <source>General</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+53"/>
+ <source>Using OpenSSL version</source>
+ <translation>Using OpenSSL version</translation>
+ </message>
+ <message>
+ <location line="+26"/>
+ <source>Using BerkeleyDB version</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+49"/>
+ <source>Startup time</source>
+ <translation>Startup time</translation>
+ </message>
+ <message>
+ <location line="+29"/>
+ <source>Network</source>
+ <translation>Network</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>Name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+23"/>
+ <source>Number of connections</source>
+ <translation>Number of connections</translation>
+ </message>
+ <message>
+ <location line="+29"/>
+ <source>Block chain</source>
+ <translation>Block chain</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>Current number of blocks</source>
+ <translation>Current number of blocks</translation>
+ </message>
+ <message>
+ <location line="+72"/>
+ <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+231"/>
+ <source>Received</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+80"/>
+ <source>Sent</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+41"/>
+ <source>&amp;Peers</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+39"/>
+ <location filename="../rpcconsole.cpp" line="+238"/>
+ <location line="+326"/>
+ <source>Select a peer to view detailed information.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+25"/>
+ <source>Direction</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+23"/>
+ <source>Version</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+23"/>
+ <source>User Agent</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+23"/>
+ <source>Services</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+23"/>
+ <source>Starting Height</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+23"/>
+ <source>Sync Height</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+23"/>
+ <source>Ban Score</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+23"/>
+ <source>Connection Time</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+23"/>
+ <source>Last Send</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+23"/>
+ <source>Last Receive</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+23"/>
+ <source>Bytes Sent</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+23"/>
+ <source>Bytes Received</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+23"/>
+ <source>Ping Time</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+23"/>
+ <source>Time Offset</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="-764"/>
+ <source>Last block time</source>
+ <translation>Last block time</translation>
+ </message>
+ <message>
+ <location line="+52"/>
+ <source>&amp;Open</source>
+ <translation>&amp;Open</translation>
+ </message>
+ <message>
+ <location line="+24"/>
+ <source>&amp;Console</source>
+ <translation>&amp;Console</translation>
+ </message>
+ <message>
+ <location line="+72"/>
+ <source>&amp;Network Traffic</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+52"/>
+ <source>&amp;Clear</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+16"/>
+ <source>Totals</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../rpcconsole.cpp" line="-164"/>
+ <source>In:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Out:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="-357"/>
+ <source>Build date</source>
+ <translation>Build date</translation>
+ </message>
+ <message>
+ <location line="+183"/>
+ <source>Debug log file</source>
+ <translation>Debug log file</translation>
+ </message>
+ <message>
+ <location line="+83"/>
+ <source>Clear console</source>
+ <translation>Clear console</translation>
+ </message>
+ <message>
+ <location filename="../rpcconsole.cpp" line="-36"/>
+ <source>Welcome to the Bitcoin Core RPC console.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
+ <translation>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Type &lt;b&gt;help&lt;/b&gt; for an overview of available commands.</source>
+ <translation>Type &lt;b&gt;help&lt;/b&gt; for an overview of available commands.</translation>
+ </message>
+ <message>
+ <location line="+134"/>
+ <source>%1 B</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>%1 KB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>%1 MB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>%1 GB</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+95"/>
+ <source>via %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <location line="+1"/>
+ <source>never</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>Inbound</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+0"/>
+ <source>Outbound</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+13"/>
+ <source>Unknown</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <location line="+1"/>
+ <source>Fetching...</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <location filename="../forms/receivecoinsdialog.ui" line="+107"/>
+ <source>&amp;Amount:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="-16"/>
+ <source>&amp;Label:</source>
+ <translation type="unfinished">&amp;Label:</translation>
+ </message>
+ <message>
+ <location line="-37"/>
+ <source>&amp;Message:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="-20"/>
+ <source>Reuse one of the previously used receiving addresses. Reusing addresses has security and privacy issues. Do not use this unless re-generating a payment request made before.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>R&amp;euse an existing receiving address (not recommended)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+14"/>
+ <location line="+23"/>
+ <source>An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="-7"/>
+ <location line="+21"/>
+ <source>An optional label to associate with the new receiving address.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="-7"/>
+ <source>Use this form to request payments. All fields are &lt;b&gt;optional&lt;/b&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+23"/>
+ <location line="+22"/>
+ <source>An optional amount to request. Leave this empty or zero to not request a specific amount.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+32"/>
+ <source>Clear all fields of the form.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Clear</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+75"/>
+ <source>Requested payments history</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="-95"/>
+ <source>&amp;Request payment</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+120"/>
+ <source>Show the selected request (does the same as double clicking an entry)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Show</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+17"/>
+ <source>Remove the selected entries from the list</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Remove</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../receivecoinsdialog.cpp" line="+45"/>
+ <source>Copy label</source>
+ <translation type="unfinished">Copy label</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Copy message</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Copy amount</source>
+ <translation type="unfinished">Copy amount</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <location filename="../forms/receiverequestdialog.ui" line="+29"/>
+ <source>QR Code</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+46"/>
+ <source>Copy &amp;URI</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>Copy &amp;Address</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>&amp;Save Image...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../receiverequestdialog.cpp" line="+65"/>
+ <source>Request payment to %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Payment information</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>URI</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Address</source>
+ <translation type="unfinished">Address</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Amount</source>
+ <translation type="unfinished">Amount</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Label</source>
+ <translation type="unfinished">Label</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Message</source>
+ <translation type="unfinished">Message</translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>Resulting URI too long, try to reduce the text for label / message.</source>
+ <translation type="unfinished">Resulting URI too long, try to reduce the text for label / message.</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Error encoding URI into QR Code.</source>
+ <translation type="unfinished">Error encoding URI into QR Code.</translation>
+ </message>
+</context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <location filename="../recentrequeststablemodel.cpp" line="+29"/>
+ <source>Date</source>
+ <translation type="unfinished">Date</translation>
+ </message>
+ <message>
+ <location line="+0"/>
+ <source>Label</source>
+ <translation type="unfinished">Label</translation>
+ </message>
+ <message>
+ <location line="+0"/>
+ <source>Message</source>
+ <translation type="unfinished">Message</translation>
+ </message>
+ <message>
+ <location line="+99"/>
+ <source>Amount</source>
+ <translation type="unfinished">Amount</translation>
+ </message>
+ <message>
+ <location line="-59"/>
+ <source>(no label)</source>
+ <translation type="unfinished">(no label)</translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>(no message)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>(no amount)</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <location filename="../forms/sendcoinsdialog.ui" line="+14"/>
+ <location filename="../sendcoinsdialog.cpp" line="+543"/>
+ <source>Send Coins</source>
+ <translation>Send Coins</translation>
+ </message>
+ <message>
+ <location line="+76"/>
+ <source>Coin Control Features</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+20"/>
+ <source>Inputs...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>automatically selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+19"/>
+ <source>Insufficient funds!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+89"/>
+ <source>Quantity:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+35"/>
+ <source>Bytes:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+48"/>
+ <source>Amount:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+32"/>
+ <source>Priority:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+48"/>
+ <source>Fee:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+80"/>
+ <source>After Fee:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+32"/>
+ <source>Change:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+44"/>
+ <source>If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Custom change address</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+206"/>
+ <source>Transaction Fee:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+14"/>
+ <source>Choose...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+37"/>
+ <source>collapse fee-settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+54"/>
+ <source>per kilobyte</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="-3"/>
+ <location line="+16"/>
+ <source>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then &quot;per kilobyte&quot; only pays 250 satoshis in fee, while &quot;total at least&quot; pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="-64"/>
+ <source>Hide</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+67"/>
+ <source>total at least</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+30"/>
+ <location line="+13"/>
+ <source>Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>(read the tooltip)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+29"/>
+ <source>Recommended:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+30"/>
+ <source>Custom:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+52"/>
+ <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+29"/>
+ <source>Confirmation time:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+60"/>
+ <source>normal</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+20"/>
+ <source>fast</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+38"/>
+ <source>Send as zero-fee transaction if possible</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>(confirmation may take longer)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+110"/>
+ <source>Send to multiple recipients at once</source>
+ <translation>Send to multiple recipients at once</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Add &amp;Recipient</source>
+ <translation>Add &amp;Recipient</translation>
+ </message>
+ <message>
+ <location line="-20"/>
+ <source>Clear all fields of the form.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="-858"/>
+ <source>Dust:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+861"/>
+ <source>Clear &amp;All</source>
+ <translation>Clear &amp;All</translation>
+ </message>
+ <message>
+ <location line="+55"/>
+ <source>Balance:</source>
+ <translation>Balance:</translation>
+ </message>
+ <message>
+ <location line="-84"/>
+ <source>Confirm the send action</source>
+ <translation>Confirm the send action</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>S&amp;end</source>
+ <translation>S&amp;end</translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsdialog.cpp" line="-226"/>
+ <source>Confirm send coins</source>
+ <translation>Confirm send coins</translation>
+ </message>
+ <message>
+ <location line="-48"/>
+ <location line="+5"/>
+ <location line="+5"/>
+ <location line="+4"/>
+ <source>%1 to %2</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="-221"/>
+ <source>Copy quantity</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Copy amount</source>
+ <translation type="unfinished">Copy amount</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Copy fee</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Copy after fee</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Copy bytes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Copy priority</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Copy change</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+246"/>
+ <source>or</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+196"/>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>The amount to pay must be larger than 0.</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>The amount exceeds your balance.</source>
+ <translation>The amount exceeds your balance.</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>The total exceeds your balance when the %1 transaction fee is included.</source>
+ <translation>The total exceeds your balance when the %1 transaction fee is included.</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Transaction creation failed!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>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.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>A fee higher than %1 is considered an absurdly high fee.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Payment request expired.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location line="+110"/>
+ <source>Estimated to begin confirmation within %n block(s).</source>
+ <translation type="unfinished">
+ <numerusform>Estimated to begin confirmation within %n block.</numerusform>
+ <numerusform>Estimated to begin confirmation within %n blocks.</numerusform>
+ </translation>
+ </message>
+ <message>
+ <location line="-22"/>
+ <source>Pay only the minimum fee of %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="-309"/>
+ <source>Total Amount %1&lt;span style=&apos;font-size:10pt;font-weight:normal;&apos;&gt;&lt;br /&gt;(=%2)&lt;/span&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+195"/>
+ <source>The recipient address is not valid. Please recheck.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+12"/>
+ <source>Duplicate address found: addresses should only be used once each.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+231"/>
+ <source>Warning: Invalid Bitcoin address</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+20"/>
+ <source>(no label)</source>
+ <translation type="unfinished">(no label)</translation>
+ </message>
+ <message>
+ <location line="-11"/>
+ <source>Warning: Unknown change address</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="-692"/>
+ <source>Copy dust</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+221"/>
+ <source>Are you sure you want to send?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>added as transaction fee</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <location filename="../forms/sendcoinsentry.ui" line="+155"/>
+ <location line="+539"/>
+ <location line="+533"/>
+ <source>A&amp;mount:</source>
+ <translation>A&amp;mount:</translation>
+ </message>
+ <message>
+ <location line="-1185"/>
+ <source>Pay &amp;To:</source>
+ <translation>Pay &amp;To:</translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsentry.cpp" line="+37"/>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Enter a label for this address to add it to your address book</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsentry.ui" line="+93"/>
+ <source>&amp;Label:</source>
+ <translation>&amp;Label:</translation>
+ </message>
+ <message>
+ <location line="-68"/>
+ <source>Choose previously used address</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="-46"/>
+ <source>This is a normal payment.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+39"/>
+ <source>The Bitcoin address to send the payment to</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+23"/>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>Paste address from clipboard</source>
+ <translation>Paste address from clipboard</translation>
+ </message>
+ <message>
+ <location line="+16"/>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <location line="+548"/>
+ <location line="+533"/>
+ <source>Remove this entry</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="-1021"/>
+ <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>S&amp;ubtract fee from amount</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>Message:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+443"/>
+ <source>This is an unauthenticated payment request.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+529"/>
+ <source>This is an authenticated payment request.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="-1009"/>
+ <source>Enter a label for this address to add it to the list of used addresses</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+47"/>
+ <source>A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+448"/>
+ <location line="+529"/>
+ <source>Pay To:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="-495"/>
+ <location line="+533"/>
+ <source>Memo:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>ShutdownWindow</name>
+ <message>
+ <location filename="../utilitydialog.cpp" line="+81"/>
+ <source>Bitcoin Core is shutting down...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Do not shut down the computer until this window disappears.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <location filename="../forms/signverifymessagedialog.ui" line="+14"/>
+ <source>Signatures - Sign / Verify a Message</source>
+ <translation>Signatures - Sign / Verify a Message</translation>
+ </message>
+ <message>
+ <location line="+13"/>
+ <source>&amp;Sign Message</source>
+ <translation>&amp;Sign Message</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+18"/>
+ <source>The Bitcoin address to sign the message with</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <location line="+210"/>
+ <source>Choose previously used address</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="-200"/>
+ <location line="+210"/>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <location line="-200"/>
+ <source>Paste address from clipboard</source>
+ <translation>Paste address from clipboard</translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <location line="+12"/>
+ <source>Enter the message you want to sign here</source>
+ <translation>Enter the message you want to sign here</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>Signature</source>
+ <translation>Signature</translation>
+ </message>
+ <message>
+ <location line="+27"/>
+ <source>Copy the current signature to the system clipboard</source>
+ <translation>Copy the current signature to the system clipboard</translation>
+ </message>
+ <message>
+ <location line="+21"/>
+ <source>Sign the message to prove you own this Bitcoin address</source>
+ <translation>Sign the message to prove you own this Bitcoin address</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Sign &amp;Message</source>
+ <translation>Sign &amp;Message</translation>
+ </message>
+ <message>
+ <location line="+14"/>
+ <source>Reset all sign message fields</source>
+ <translation>Reset all sign message fields</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <location line="+143"/>
+ <source>Clear &amp;All</source>
+ <translation>Clear &amp;All</translation>
+ </message>
+ <message>
+ <location line="-84"/>
+ <source>&amp;Verify Message</source>
+ <translation>&amp;Verify Message</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Enter the receiver&apos;s 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. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+21"/>
+ <source>The Bitcoin address the message was signed with</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+37"/>
+ <source>Verify the message to ensure it was signed with the specified Bitcoin address</source>
+ <translation>Verify the message to ensure it was signed with the specified Bitcoin address</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Verify &amp;Message</source>
+ <translation>Verify &amp;Message</translation>
+ </message>
+ <message>
+ <location line="+14"/>
+ <source>Reset all verify message fields</source>
+ <translation>Reset all verify message fields</translation>
+ </message>
+ <message>
+ <location filename="../signverifymessagedialog.cpp" line="+40"/>
+ <source>Click &quot;Sign Message&quot; to generate signature</source>
+ <translation>Click &quot;Sign Message&quot; to generate signature</translation>
+ </message>
+ <message>
+ <location line="+83"/>
+ <location line="+80"/>
+ <source>The entered address is invalid.</source>
+ <translation>The entered address is invalid.</translation>
+ </message>
+ <message>
+ <location line="-80"/>
+ <location line="+8"/>
+ <location line="+72"/>
+ <location line="+8"/>
+ <source>Please check the address and try again.</source>
+ <translation>Please check the address and try again.</translation>
+ </message>
+ <message>
+ <location line="-80"/>
+ <location line="+80"/>
+ <source>The entered address does not refer to a key.</source>
+ <translation>The entered address does not refer to a key.</translation>
+ </message>
+ <message>
+ <location line="-72"/>
+ <source>Wallet unlock was cancelled.</source>
+ <translation>Wallet unlock was cancelled.</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>Private key for the entered address is not available.</source>
+ <translation>Private key for the entered address is not available.</translation>
+ </message>
+ <message>
+ <location line="+12"/>
+ <source>Message signing failed.</source>
+ <translation>Message signing failed.</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Message signed.</source>
+ <translation>Message signed.</translation>
+ </message>
+ <message>
+ <location line="+58"/>
+ <source>The signature could not be decoded.</source>
+ <translation>The signature could not be decoded.</translation>
+ </message>
+ <message>
+ <location line="+0"/>
+ <location line="+13"/>
+ <source>Please check the signature and try again.</source>
+ <translation>Please check the signature and try again.</translation>
+ </message>
+ <message>
+ <location line="+0"/>
+ <source>The signature did not match the message digest.</source>
+ <translation>The signature did not match the message digest.</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>Message verification failed.</source>
+ <translation>Message verification failed.</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Message verified.</source>
+ <translation>Message verified.</translation>
+ </message>
+</context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <location filename="../splashscreen.cpp" line="+41"/>
+ <source>Bitcoin Core</source>
+ <translation type="unfinished">Bitcoin Core</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>The Bitcoin Core developers</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../networkstyle.cpp" line="+20"/>
+ <source>[testnet]</source>
+ <translation>[testnet]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ <message>
+ <location filename="../trafficgraphwidget.cpp" line="+79"/>
+ <source>KB/s</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <location filename="../transactiondesc.cpp" line="+34"/>
+ <source>Open until %1</source>
+ <translation>Open until %1</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>conflicted</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>%1/offline</source>
+ <translation>%1/offline</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>%1/unconfirmed</source>
+ <translation>%1/unconfirmed</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>%1 confirmations</source>
+ <translation>%1 confirmations</translation>
+ </message>
+ <message>
+ <location line="+17"/>
+ <source>Status</source>
+ <translation>Status</translation>
+ </message>
+ <message numerus="yes">
+ <location line="+7"/>
+ <source>, broadcast through %n node(s)</source>
+ <translation>
+ <numerusform>, broadcast through %n node</numerusform>
+ <numerusform>, broadcast through %n nodes</numerusform>
+ </translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Date</source>
+ <translation>Date</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>Source</source>
+ <translation>Source</translation>
+ </message>
+ <message>
+ <location line="+0"/>
+ <source>Generated</source>
+ <translation>Generated</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <location line="+13"/>
+ <location line="+72"/>
+ <source>From</source>
+ <translation>From</translation>
+ </message>
+ <message>
+ <location line="-71"/>
+ <location line="+20"/>
+ <location line="+69"/>
+ <source>To</source>
+ <translation>To</translation>
+ </message>
+ <message>
+ <location line="-87"/>
+ <source>own address</source>
+ <translation>own address</translation>
+ </message>
+ <message>
+ <location line="+0"/>
+ <location line="+69"/>
+ <source>watch-only</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="-67"/>
+ <source>label</source>
+ <translation>label</translation>
+ </message>
+ <message>
+ <location line="+34"/>
+ <location line="+12"/>
+ <location line="+53"/>
+ <location line="+26"/>
+ <location line="+53"/>
+ <source>Credit</source>
+ <translation>Credit</translation>
+ </message>
+ <message numerus="yes">
+ <location line="-142"/>
+ <source>matures in %n more block(s)</source>
+ <translation>
+ <numerusform>matures in %n more block</numerusform>
+ <numerusform>matures in %n more blocks</numerusform>
+ </translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>not accepted</source>
+ <translation>not accepted</translation>
+ </message>
+ <message>
+ <location line="+59"/>
+ <location line="+25"/>
+ <location line="+53"/>
+ <source>Debit</source>
+ <translation>Debit</translation>
+ </message>
+ <message>
+ <location line="-68"/>
+ <source>Total debit</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Total credit</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Transaction fee</source>
+ <translation>Transaction fee</translation>
+ </message>
+ <message>
+ <location line="+16"/>
+ <source>Net amount</source>
+ <translation>Net amount</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <location line="+9"/>
+ <source>Message</source>
+ <translation>Message</translation>
+ </message>
+ <message>
+ <location line="-7"/>
+ <source>Comment</source>
+ <translation>Comment</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Transaction ID</source>
+ <translation>Transaction ID</translation>
+ </message>
+ <message>
+ <location line="+18"/>
+ <source>Merchant</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>Generated coins must mature %1 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 &quot;not accepted&quot; and it won&apos;t be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>Debug information</source>
+ <translation>Debug information</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>Transaction</source>
+ <translation>Transaction</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Inputs</source>
+ <translation>Inputs</translation>
+ </message>
+ <message>
+ <location line="+21"/>
+ <source>Amount</source>
+ <translation>Amount</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <location line="+1"/>
+ <source>true</source>
+ <translation>true</translation>
+ </message>
+ <message>
+ <location line="-1"/>
+ <location line="+1"/>
+ <source>false</source>
+ <translation>false</translation>
+ </message>
+ <message>
+ <location line="-242"/>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, has not been successfully broadcast yet</translation>
+ </message>
+ <message numerus="yes">
+ <location line="-36"/>
+ <source>Open for %n more block(s)</source>
+ <translation>
+ <numerusform>Open for %n more block</numerusform>
+ <numerusform>Open for %n more blocks</numerusform>
+ </translation>
+ </message>
+ <message>
+ <location line="+67"/>
+ <source>unknown</source>
+ <translation>unknown</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <location filename="../forms/transactiondescdialog.ui" line="+14"/>
+ <source>Transaction details</source>
+ <translation>Transaction details</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>This pane shows a detailed description of the transaction</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="+230"/>
+ <source>Date</source>
+ <translation>Date</translation>
+ </message>
+ <message>
+ <location line="+0"/>
+ <source>Type</source>
+ <translation>Type</translation>
+ </message>
+ <message>
+ <location line="+79"/>
+ <source>Immature (%1 confirmations, will be available after %2)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location line="-21"/>
+ <source>Open for %n more block(s)</source>
+ <translation>
+ <numerusform>Open for %n more block</numerusform>
+ <numerusform>Open for %n more blocks</numerusform>
+ </translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Open until %1</source>
+ <translation>Open until %1</translation>
+ </message>
+ <message>
+ <location line="+12"/>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>Confirmed (%1 confirmations)</translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>This block was not received by any other nodes and will probably not be accepted!</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Generated but not accepted</source>
+ <translation>Generated but not accepted</translation>
+ </message>
+ <message>
+ <location line="-21"/>
+ <source>Offline</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="-64"/>
+ <source>Label</source>
+ <translation type="unfinished">Label</translation>
+ </message>
+ <message>
+ <location line="+67"/>
+ <source>Unconfirmed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Confirming (%1 of %2 recommended confirmations)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Conflicted</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+48"/>
+ <source>Received with</source>
+ <translation>Received with</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Received from</source>
+ <translation>Received from</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Sent to</source>
+ <translation>Sent to</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Payment to yourself</source>
+ <translation>Payment to yourself</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Mined</source>
+ <translation>Mined</translation>
+ </message>
+ <message>
+ <location line="+28"/>
+ <source>watch-only</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+15"/>
+ <source>(n/a)</source>
+ <translation>(n/a)</translation>
+ </message>
+ <message>
+ <location line="+215"/>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>Transaction status. Hover over this field to show number of confirmations.</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Date and time that the transaction was received.</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Type of transaction.</source>
+ <translation>Type of transaction.</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Whether or not a watch-only address is involved in this transaction.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>User-defined intent/purpose of the transaction.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Amount removed from or added to balance.</source>
+ <translation>Amount removed from or added to balance.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <location filename="../transactionview.cpp" line="+68"/>
+ <location line="+16"/>
+ <source>All</source>
+ <translation>All</translation>
+ </message>
+ <message>
+ <location line="-15"/>
+ <source>Today</source>
+ <translation>Today</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>This week</source>
+ <translation>This week</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>This month</source>
+ <translation>This month</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Last month</source>
+ <translation>Last month</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>This year</source>
+ <translation>This year</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Range...</source>
+ <translation>Range...</translation>
+ </message>
+ <message>
+ <location line="+11"/>
+ <source>Received with</source>
+ <translation>Received with</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Sent to</source>
+ <translation>Sent to</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>To yourself</source>
+ <translation>To yourself</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Mined</source>
+ <translation>Mined</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Other</source>
+ <translation>Other</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Enter address or label to search</source>
+ <translation>Enter address or label to search</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Min amount</source>
+ <translation>Min amount</translation>
+ </message>
+ <message>
+ <location line="+36"/>
+ <source>Copy address</source>
+ <translation>Copy address</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Copy label</source>
+ <translation>Copy label</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Copy amount</source>
+ <translation>Copy amount</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Copy transaction ID</source>
+ <translation>Copy transaction ID</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Edit label</source>
+ <translation>Edit label</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Show transaction details</source>
+ <translation>Show transaction details</translation>
+ </message>
+ <message>
+ <location line="+179"/>
+ <source>Export Transaction History</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+12"/>
+ <source>Watch-only</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>Exporting Failed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+0"/>
+ <source>There was an error trying to save the transaction history to %1.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Exporting Successful</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+0"/>
+ <source>The transaction history was successfully saved to %1.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="-24"/>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Comma separated file (*.csv)</translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>Confirmed</source>
+ <translation>Confirmed</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Date</source>
+ <translation>Date</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Type</source>
+ <translation>Type</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Label</source>
+ <translation>Label</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Address</source>
+ <translation>Address</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <location line="+116"/>
+ <source>Range:</source>
+ <translation>Range:</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>to</source>
+ <translation>to</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ <message>
+ <location filename="../bitcoingui.cpp" line="+106"/>
+ <source>Unit to show amounts in. Click to select another unit.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>WalletFrame</name>
+ <message>
+ <location filename="../walletframe.cpp" line="+26"/>
+ <source>No wallet has been loaded.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <location filename="../walletmodel.cpp" line="+288"/>
+ <source>Send Coins</source>
+ <translation>Send Coins</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <location filename="../walletview.cpp" line="+45"/>
+ <source>&amp;Export</source>
+ <translation>&amp;Export</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Export the data in the current tab to a file</translation>
+ </message>
+ <message>
+ <location line="+189"/>
+ <source>Backup Wallet</source>
+ <translation>Backup Wallet</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Wallet Data (*.dat)</source>
+ <translation>Wallet Data (*.dat)</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Backup Failed</source>
+ <translation>Backup Failed</translation>
+ </message>
+ <message>
+ <location line="+0"/>
+ <source>There was an error trying to save the wallet data to %1.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>The wallet data was successfully saved to %1.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+0"/>
+ <source>Backup Successful</source>
+ <translation>Backup Successful</translation>
+ </message>
+</context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="+250"/>
+ <source>Options:</source>
+ <translation>Options:</translation>
+ </message>
+ <message>
+ <location line="+33"/>
+ <source>Specify data directory</source>
+ <translation>Specify data directory</translation>
+ </message>
+ <message>
+ <location line="-88"/>
+ <source>Connect to a node to retrieve peer addresses, and disconnect</source>
+ <translation>Connect to a node to retrieve peer addresses, and disconnect</translation>
+ </message>
+ <message>
+ <location line="+91"/>
+ <source>Specify your own public address</source>
+ <translation>Specify your own public address</translation>
+ </message>
+ <message>
+ <location line="-110"/>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>Accept command line and JSON-RPC commands</translation>
+ </message>
+ <message>
+ <location line="+89"/>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>Run in the background as a daemon and accept commands</translation>
+ </message>
+ <message>
+ <location line="+39"/>
+ <source>Use the test network</source>
+ <translation>Use the test network</translation>
+ </message>
+ <message>
+ <location line="-127"/>
+ <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
+ <translation>Accept connections from outside (default: 1 if no -proxy or -connect)</translation>
+ </message>
+ <message>
+ <location line="-155"/>
+ <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
+ <translation>Bind to given address and always listen on it. Use [host]:port notation for IPv6</translation>
+ </message>
+ <message>
+ <location line="+16"/>
+ <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Distributed under the MIT software license, see the accompanying file COPYING or &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+11"/>
+ <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
+ <translation>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</translation>
+ </message>
+ <message>
+ <location line="+23"/>
+ <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+15"/>
+ <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, &gt;%u = target size in MiB to use for block files)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>Set the number of script verification threads (%u to %d, 0 = auto, &lt;0 = leave that many cores free, default: %d)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source>
+ <translation>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</translation>
+ </message>
+ <message>
+ <location line="+20"/>
+ <source>Unable to bind to %s on this computer. Bitcoin Core is probably already running.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source>
+ <translation>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.</source>
+ <translation>Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
+ <translation>Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</source>
+ <translation>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+11"/>
+ <source>(default: 1)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>&lt;category&gt; can be:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>Attempt to recover private keys from a corrupt wallet.dat</source>
+ <translation>Attempt to recover private keys from a corrupt wallet.dat</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Block creation options:</source>
+ <translation>Block creation options:</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>Connect only to the specified node(s)</source>
+ <translation>Connect only to the specified node(s)</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Connection options:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Corrupted block database detected</source>
+ <translation>Corrupted block database detected</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Debugging/Testing options:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Do not load the wallet and disable wallet RPC calls</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Do you want to rebuild the block database now?</source>
+ <translation>Do you want to rebuild the block database now?</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Error initializing block database</source>
+ <translation>Error initializing block database</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Error initializing wallet database environment %s!</source>
+ <translation>Error initializing wallet database environment %s!</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Error loading block database</source>
+ <translation>Error loading block database</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Error opening block database</source>
+ <translation>Error opening block database</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Error: Disk space is low!</source>
+ <translation>Error: Disk space is low!</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Failed to listen on any port. Use -listen=0 if you want this.</source>
+ <translation>Failed to listen on any port. Use -listen=0 if you want this.</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>If &lt;category&gt; is not supplied, output all debugging information.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Importing...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Incorrect or no genesis block found. Wrong datadir for network?</source>
+ <translation>Incorrect or no genesis block found. Wrong datadir for network?</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Invalid -onion address: &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+20"/>
+ <source>Not enough file descriptors available.</source>
+ <translation>Not enough file descriptors available.</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Only connect to nodes in network &lt;net&gt; (ipv4, ipv6 or onion)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Prune cannot be configured with a negative value.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Prune mode is incompatible with -txindex.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+17"/>
+ <source>Set database cache size in megabytes (%d to %d, default: %d)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Set maximum block size in bytes (default: %d)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+11"/>
+ <source>Specify wallet file (within data directory)</source>
+ <translation>Specify wallet file (within data directory)</translation>
+ </message>
+ <message>
+ <location line="+17"/>
+ <source>Use UPnP to map the listening port (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Verifying blocks...</source>
+ <translation>Verifying blocks...</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Verifying wallet...</source>
+ <translation>Verifying wallet...</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Wallet %s resides outside data directory %s</source>
+ <translation>Wallet %s resides outside data directory %s</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Wallet options:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Warning: This version is obsolete; upgrade required!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>You need to rebuild the database using -reindex to change -txindex</source>
+ <translation>You need to rebuild the database using -reindex to change -txindex</translation>
+ </message>
+ <message>
+ <location line="-93"/>
+ <source>Imports blocks from external blk000??.dat file</source>
+ <translation>Imports blocks from external blk000??.dat file</translation>
+ </message>
+ <message>
+ <location line="-207"/>
+ <source>Allow JSON-RPC connections from specified source. Valid for &lt;ip&gt; are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>An error occurred while setting up the RPC address %s port %u for listening: %s</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Error: Listening for incoming connections failed (listen returned error %s)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Error: Unsupported argument -socks found. Setting SOCKS version isn&apos;t possible anymore, only SOCKS5 proxies are supported.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source>
+ <translation>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: &apos;%s&apos; (must be at least the minrelay fee of %s to prevent stuck transactions)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>Prune configured below the minimum of %d MB. Please use a higher number.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>The transaction amount is too small to send after the fee has been deducted</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit &lt;https://www.openssl.org/&gt; and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an 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)
+The username and password MUST NOT be the same.
+If the file does not exist, create it with owner-readable-only file permissions.
+It is also recommended to set alertnotify so you are notified of problems;
+for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.com
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+25"/>
+ <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Warning: Please check that your computer&apos;s date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+19"/>
+ <source>Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>(default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Accept public REST requests (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Activating best chain...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Can&apos;t run with a wallet in prune mode.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Cannot resolve -whitebind address: &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Choose data directory on startup (default: 0)</source>
+ <translation type="unfinished">Choose data directory on startup (default: 0)</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Connect through SOCKS5 proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Could not parse -rpcbind value %s as network address</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Error reading from database, shutting down.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Error: A fatal internal error occurred, see debug.log for details</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Error: Unsupported argument -tor found, use -onion.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>Information</source>
+ <translation>Information</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Initialization sanity check failed. Bitcoin Core is shutting down.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Invalid amount for -minrelaytxfee=&lt;amount&gt;: &apos;%s&apos;</source>
+ <translation>Invalid amount for -minrelaytxfee=&lt;amount&gt;: &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Invalid amount for -mintxfee=&lt;amount&gt;: &apos;%s&apos;</source>
+ <translation>Invalid amount for -mintxfee=&lt;amount&gt;: &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: &apos;%s&apos; (must be at least %s)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Invalid netmask specified in -whitelist: &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Keep at most &lt;n&gt; unconnectable transactions in memory (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>Need to specify a port with -whitebind: &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Node relay options:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>Pruning blockstore...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>RPC server options:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>RPC support for HTTP persistent connections (default: %d)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Rebuild block chain index from current blk000??.dat files on startup</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Receive and display P2P network alerts (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>Send trace/debug info to console instead of debug.log file</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Send transactions as zero-fee transactions if possible (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Set SSL root certificates for payment request (default: -system-)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Set language, for example &quot;de_DE&quot; (default: system locale)</source>
+ <translation type="unfinished">Set language, for example &quot;de_DE&quot; (default: system locale)</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Show all debugging options (usage: --help -help-debug)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Show splash screen on startup (default: 1)</source>
+ <translation type="unfinished">Show splash screen on startup (default: 1)</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source>
+ <translation>Shrink debug.log file on client startup (default: 1 when no -debug)</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Signing transaction failed</source>
+ <translation>Signing transaction failed</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>Start minimized</source>
+ <translation type="unfinished">Start minimized</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>The transaction amount is too small to pay the fee</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>This is experimental software.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Transaction amount too small</source>
+ <translation>Transaction amount too small</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Transaction amounts must be positive</source>
+ <translation>Transaction amounts must be positive</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Transaction too large for fee policy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Transaction too large</source>
+ <translation>Transaction too large</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>UI Options:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Unable to bind to %s on this computer (bind returned error %s)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Use UPnP to map the listening port (default: 1 when listening)</source>
+ <translation>Use UPnP to map the listening port (default: 1 when listening)</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Username for JSON-RPC connections</source>
+ <translation>Username for JSON-RPC connections</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Wallet needed to be rewritten: restart Bitcoin Core to complete</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Warning</source>
+ <translation>Warning</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Warning: Unsupported argument -debugnet ignored, use -debug=net.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Zapping all transactions from wallet...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>on startup</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>wallet.dat corrupt, salvage failed</source>
+ <translation>wallet.dat corrupt, salvage failed</translation>
+ </message>
+ <message>
+ <location line="-67"/>
+ <source>Password for JSON-RPC connections</source>
+ <translation>Password for JSON-RPC connections</translation>
+ </message>
+ <message>
+ <location line="-193"/>
+ <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
+ <translation>Execute command when the best block changes (%s in cmd is replaced by block hash)</translation>
+ </message>
+ <message>
+ <location line="+242"/>
+ <source>Upgrade wallet to latest format</source>
+ <translation>Upgrade wallet to latest format</translation>
+ </message>
+ <message>
+ <location line="-37"/>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>Rescan the block chain for missing wallet transactions</translation>
+ </message>
+ <message>
+ <location line="+38"/>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>Use OpenSSL (https) for JSON-RPC connections</translation>
+ </message>
+ <message>
+ <location line="-11"/>
+ <source>This help message</source>
+ <translation>This help message</translation>
+ </message>
+ <message>
+ <location line="-108"/>
+ <source>Allow DNS lookups for -addnode, -seednode and -connect</source>
+ <translation>Allow DNS lookups for -addnode, -seednode and -connect</translation>
+ </message>
+ <message>
+ <location line="+57"/>
+ <source>Loading addresses...</source>
+ <translation>Loading addresses...</translation>
+ </message>
+ <message>
+ <location line="-31"/>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>Error loading wallet.dat: Wallet corrupted</translation>
+ </message>
+ <message>
+ <location line="-196"/>
+ <source>(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+52"/>
+ <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Output debugging information (default: %u, supplying &lt;category&gt; is optional)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+49"/>
+ <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+40"/>
+ <source>(default: %s)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>Acceptable ciphers (default: %s)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Always query for peer addresses via DNS lookup (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+24"/>
+ <source>Error loading wallet.dat</source>
+ <translation>Error loading wallet.dat</translation>
+ </message>
+ <message>
+ <location line="+11"/>
+ <source>Generate coins (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>How many blocks to check at startup (default: %u, 0 = all)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Include IP addresses in debug output (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Invalid -proxy address: &apos;%s&apos;</source>
+ <translation>Invalid -proxy address: &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>Listen for JSON-RPC connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Listen for connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Maintain at most &lt;n&gt; connections to peers (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Make the wallet broadcast transactions</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Maximum per-connection receive buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Maximum per-connection send buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>Prepend debug output with timestamp (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>Relay and mine data carrier transactions (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Relay non-P2SH multisig (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Server certificate file (default: %s)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Server private key (default: %s)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Set key pool size to &lt;n&gt; (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Set minimum block size in bytes (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Set the number of threads to service RPC calls (default: %d)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Specify configuration file (default: %s)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Specify pid file (default: %s)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Spend unconfirmed change when sending transactions (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Threshold for disconnecting misbehaving peers (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>Unknown network specified in -onlynet: &apos;%s&apos;</source>
+ <translation>Unknown network specified in -onlynet: &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location line="-111"/>
+ <source>Cannot resolve -bind address: &apos;%s&apos;</source>
+ <translation>Cannot resolve -bind address: &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Cannot resolve -externalip address: &apos;%s&apos;</source>
+ <translation>Cannot resolve -externalip address: &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location line="+45"/>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: &apos;%s&apos;</source>
+ <translation>Invalid amount for -paytxfee=&lt;amount&gt;: &apos;%s&apos;</translation>
+ </message>
+ <message>
+ <location line="-7"/>
+ <source>Insufficient funds</source>
+ <translation>Insufficient funds</translation>
+ </message>
+ <message>
+ <location line="+13"/>
+ <source>Loading block index...</source>
+ <translation>Loading block index...</translation>
+ </message>
+ <message>
+ <location line="-59"/>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>Add a node to connect to and attempt to keep the connection open</translation>
+ </message>
+ <message>
+ <location line="+60"/>
+ <source>Loading wallet...</source>
+ <translation>Loading wallet...</translation>
+ </message>
+ <message>
+ <location line="-54"/>
+ <source>Cannot downgrade wallet</source>
+ <translation>Cannot downgrade wallet</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Cannot write default address</source>
+ <translation>Cannot write default address</translation>
+ </message>
+ <message>
+ <location line="+73"/>
+ <source>Rescanning...</source>
+ <translation>Rescanning...</translation>
+ </message>
+ <message>
+ <location line="-61"/>
+ <source>Done loading</source>
+ <translation>Done loading</translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>Error</source>
+ <translation>Error</translation>
+ </message>
+</context>
+</TS>
diff --git a/src/qt/locale/bitcoin_eo.ts b/src/qt/locale/bitcoin_eo.ts
new file mode 100644
index 0000000000..a5f92d4220
--- /dev/null
+++ b/src/qt/locale/bitcoin_eo.ts
@@ -0,0 +1,2402 @@
+<TS language="eo" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Right-click to edit address or label</source>
+ <translation>Dekstre-klaku por redakti adreson aŭ etikedon</translation>
+ </message>
+ <message>
+ <source>Create a new address</source>
+ <translation>Krei novan adreson</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>&amp;Nova</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Kopii elektitan adreson al la tondejo</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>&amp;Kopii</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>&amp;Fermi</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>&amp;Kopii Adreson</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>Forigi la elektitan adreson el la listo</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Eksporti la datumojn el la aktuala langeto al dosiero</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Eksporti</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;Forigi</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>Elektu la alsendotan adreson</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>Elektu la ricevontan adreson</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>&amp;Elekti</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>Sendaj adresoj</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>Ricevaj adresoj</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>Jen viaj Bitmon-adresoj por sendi pagojn. Zorge kontrolu la sumon kaj la alsendan adreson antaŭ ol sendi.</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>Jen viaj bitmonaj adresoj por ricevi pagojn. Estas konsilinde uzi apartan ricevan adreson por ĉiu transakcio.</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>Kopii &amp;Etikedon</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>&amp;Redakti</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>Eksporti Adresliston</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Perkome disigita dosiero (*.csv)</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>ekspotado malsukcesinta</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the address list to %1. Please try again.</source>
+ <translation>Okazis eraron dum konservo de adreslisto al %1. Bonvolu provi denove.</translation>
+ </message>
+</context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Etikedo</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adreso</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(neniu etikedo)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Passphrase Dialog</source>
+ <translation>Dialogo pri pasfrazo</translation>
+ </message>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Enigu pasfrazon</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Nova pasfrazo</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Ripetu la novan pasfrazon</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>Ĉifri la monujon</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>Ĉi tiu operacio bezonas vian monujan pasfrazon, por malŝlosi la monujon.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Malŝlosi la monujon</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>Ĉi tiu operacio bezonas vian monujan pasfrazon, por malĉifri la monujon.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>Malĉifri la monujon</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>Ŝanĝi la pasfrazon</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>Konfirmo de ĉifrado de la monujo</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>Atentu! Se vi ĉifras vian monujon kaj perdas la pasfrazon, vi &lt;b&gt;PERDOS LA TUTON DE VIA BITMONO&lt;b&gt;!</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>Ĉu vi certas, ke vi volas ĉifri la monujon?</translation>
+ </message>
+ <message>
+ <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
+ <translation>GRAVE: antaŭaj sekur-kopioj de via monujo-dosiero estas forigindaj kiam vi havas nove kreitan ĉifritan monujo-dosieron. Pro sekureco, antaŭaj kopioj de la neĉifrita dosiero ne plu funkcios tuj kiam vi ekuzos la novan ĉifritan dosieron.</translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>Atentu: la majuskla baskulo estas ŝaltita!</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>La monujo estas ĉifrita</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>Ĉifrado de la monujo fiaskis</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>Ĉifrado de monujo fiaskis pro interna eraro. Via monujo ne estas ĉifrita.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>La pasfrazoj entajpitaj ne samas.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>Malŝloso de la monujo fiaskis</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>La pasfrazo enigita por ĉifrado de monujo ne ĝustas.</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>Malĉifrado de la monujo fiaskis</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>Vi sukcese ŝanĝis la pasfrazon de la monujo.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>Subskribi &amp;mesaĝon...</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>Sinkronigante kun reto...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;Superrigardo</translation>
+ </message>
+ <message>
+ <source>Node</source>
+ <translation>Nodo</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>Vidigi ĝeneralan superrigardon de la monujo</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Transakcioj</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>Esplori historion de transakcioj</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>&amp;Eliri</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>Eliri la aplikaĵon</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>Pri &amp;Qt</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>Vidigi informojn pri Qt</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;Agordoj...</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>Ĉifri &amp;Monujon...</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>&amp;Krei sekurkopion de la monujo...</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>Ŝanĝi &amp;Pasfrazon...</translation>
+ </message>
+ <message>
+ <source>&amp;Sending addresses...</source>
+ <translation>&amp;Sendaj adresoj...</translation>
+ </message>
+ <message>
+ <source>&amp;Receiving addresses...</source>
+ <translation>&amp;Ricevaj adresoj...</translation>
+ </message>
+ <message>
+ <source>Open &amp;URI...</source>
+ <translation>Malfermi &amp;URI-on...</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core client</source>
+ <translation>kliento de bitmon-kerno</translation>
+ </message>
+ <message>
+ <source>Importing blocks from disk...</source>
+ <translation>Importado de blokoj el disko...</translation>
+ </message>
+ <message>
+ <source>Reindexing blocks on disk...</source>
+ <translation>Reindeksado de blokoj sur disko...</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>Sendi monon al Bitmon-adreso</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>Krei alilokan sekurkopion de monujo</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Ŝanĝi la pasfrazon por ĉifri la monujon</translation>
+ </message>
+ <message>
+ <source>&amp;Debug window</source>
+ <translation>Sen&amp;cimiga fenestro</translation>
+ </message>
+ <message>
+ <source>Open debugging and diagnostic console</source>
+ <translation>Malfermi konzolon de sencimigo kaj diagnozo</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>&amp;Kontroli mesaĝon...</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Bitmono</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>Monujo</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>&amp;Sendi</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>&amp;Ricevi</translation>
+ </message>
+ <message>
+ <source>Show information about Bitcoin Core</source>
+ <translation>Vidigi informon pri Bitmona Kerno</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>&amp;Montri / Kaŝi</translation>
+ </message>
+ <message>
+ <source>Show or hide the main Window</source>
+ <translation>Montri aŭ kaŝi la ĉefan fenestron</translation>
+ </message>
+ <message>
+ <source>Encrypt the private keys that belong to your wallet</source>
+ <translation>Ĉifri la privatajn ŝlosilojn de via monujo</translation>
+ </message>
+ <message>
+ <source>Sign messages with your Bitcoin addresses to prove you own them</source>
+ <translation>Subskribi mesaĝojn per via Bitmon-adresoj por pravigi, ke vi estas la posedanto</translation>
+ </message>
+ <message>
+ <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source>
+ <translation>Kontroli mesaĝojn por kontroli ĉu ili estas subskribitaj per specifaj Bitmon-adresoj</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;Dosiero</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;Agordoj</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>&amp;Helpo</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>Langeto-breto</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Kerno de Bitmono</translation>
+ </message>
+ <message>
+ <source>Request payments (generates QR codes and bitcoin: URIs)</source>
+ <translation>Peti pagon (kreas QR-kodojn kaj URI-ojn kun prefikso bitcoin:)</translation>
+ </message>
+ <message>
+ <source>&amp;About Bitcoin Core</source>
+ <translation>&amp;Pri la Bitmona Kerno</translation>
+ </message>
+ <message>
+ <source>Show the list of used sending addresses and labels</source>
+ <translation>Vidigi la liston de uzitaj sendaj adresoj kaj etikedoj</translation>
+ </message>
+ <message>
+ <source>Show the list of used receiving addresses and labels</source>
+ <translation>Vidigi la liston de uzitaj ricevaj adresoj kaj etikedoj</translation>
+ </message>
+ <message>
+ <source>Open a bitcoin: URI or payment request</source>
+ <translation>Malfermi bitcoin:-URI-on aŭ pagpeton</translation>
+ </message>
+ <message>
+ <source>&amp;Command-line options</source>
+ <translation>&amp;Komandliniaj agordaĵoj</translation>
+ </message>
+ <message>
+ <source>No block source available...</source>
+ <translation>Neniu fonto de blokoj trovebla...</translation>
+ </message>
+ <message>
+ <source>%1 and %2</source>
+ <translation>%1 kaj %2</translation>
+ </message>
+ <message>
+ <source>%1 behind</source>
+ <translation>mankas %1</translation>
+ </message>
+ <message>
+ <source>Last received block was generated %1 ago.</source>
+ <translation>Lasta ricevita bloko kreiĝis antaŭ %1.</translation>
+ </message>
+ <message>
+ <source>Transactions after this will not yet be visible.</source>
+ <translation>Transakcioj por tio ankoraŭ ne videblas.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Eraro</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Averto</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Informoj</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>Ĝisdata</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>Ĝisdatigante...</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>Sendita transakcio</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>Envenanta transakcio</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>Monujo estas &lt;b&gt;ĉifrita&lt;/b&gt; kaj aktuale &lt;b&gt;malŝlosita&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>Monujo estas &lt;b&gt;ĉifrita&lt;/b&gt; kaj aktuale &lt;b&gt;ŝlosita&lt;/b&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <source>Network Alert</source>
+ <translation>Reta Averto</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Quantity:</source>
+ <translation>Kvanto:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Bajtoj:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Sumo:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Prioritato:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Krompago:</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Polvo:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Post krompago:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Restmono:</translation>
+ </message>
+ <message>
+ <source>(un)select all</source>
+ <translation>(mal)elekti ĉion</translation>
+ </message>
+ <message>
+ <source>Tree mode</source>
+ <translation>Arboreĝimo</translation>
+ </message>
+ <message>
+ <source>List mode</source>
+ <translation>Listreĝimo</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Sumo</translation>
+ </message>
+ <message>
+ <source>Received with label</source>
+ <translation>Ricevita kun etikedo</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>Ricevita kun adreso</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Dato</translation>
+ </message>
+ <message>
+ <source>Confirmations</source>
+ <translation>Konfirmoj</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Konfirmita</translation>
+ </message>
+ <message>
+ <source>Priority</source>
+ <translation>Prioritato</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Kopii adreson</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Kopii etikedon</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopii sumon</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Kopii transakcian ID-on</translation>
+ </message>
+ <message>
+ <source>Lock unspent</source>
+ <translation>Ŝlosi la neelspezitajn</translation>
+ </message>
+ <message>
+ <source>Unlock unspent</source>
+ <translation>Malŝlosi la neelspezitajn</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Kopii kvanton</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Kopii krompagon</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Kopii post krompago</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Kopii bajtojn</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Kopii prioritaton</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Kopii polvon</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Kopii restmonon</translation>
+ </message>
+ <message>
+ <source>highest</source>
+ <translation>plej alta</translation>
+ </message>
+ <message>
+ <source>higher</source>
+ <translation>pli alta</translation>
+ </message>
+ <message>
+ <source>high</source>
+ <translation>alta</translation>
+ </message>
+ <message>
+ <source>medium-high</source>
+ <translation>mezalta</translation>
+ </message>
+ <message>
+ <source>medium</source>
+ <translation>meza</translation>
+ </message>
+ <message>
+ <source>low-medium</source>
+ <translation>mezmalalta</translation>
+ </message>
+ <message>
+ <source>low</source>
+ <translation>malalta</translation>
+ </message>
+ <message>
+ <source>lower</source>
+ <translation>pli malalta</translation>
+ </message>
+ <message>
+ <source>lowest</source>
+ <translation>plej malalta</translation>
+ </message>
+ <message>
+ <source>(%1 locked)</source>
+ <translation>(%1 ŝlosita)</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>neniu</translation>
+ </message>
+ <message>
+ <source>yes</source>
+ <translation>jes</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>ne</translation>
+ </message>
+ <message>
+ <source>This means a fee of at least %1 per kB is required.</source>
+ <translation>Tio signifas, ke krompago de almenaŭ po %1 por ĉiu kB estas deviga.</translation>
+ </message>
+ <message>
+ <source>Can vary +/- 1 byte per input.</source>
+ <translation>Povas varii po +/- 1 bajton por ĉiu enigo.</translation>
+ </message>
+ <message>
+ <source>Transactions with higher priority are more likely to get included into a block.</source>
+ <translation>Transakcioj kun pli alta prioritato havas pli altan ŝancon inkluziviĝi en bloko.</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(neniu etikedo)</translation>
+ </message>
+ <message>
+ <source>change from %1 (%2)</source>
+ <translation>restmono de %1 (%2)</translation>
+ </message>
+ <message>
+ <source>(change)</source>
+ <translation>(restmono)</translation>
+ </message>
+</context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>Redakti Adreson</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>&amp;Etikedo</translation>
+ </message>
+ <message>
+ <source>The label associated with this address list entry</source>
+ <translation>La etikedo ligita al tiu ĉi adreslistero</translation>
+ </message>
+ <message>
+ <source>The address associated with this address list entry. This can only be modified for sending addresses.</source>
+ <translation>La adreso ligita al tiu ĉi adreslistero. Eblas modifi tion nur por sendaj adresoj.</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;Adreso</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>Nova adreso por ricevi</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>Nova adreso por sendi</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>Redakti adreson por ricevi</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>Redakti adreson por sendi</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>La adreso enigita "%1" jam ekzistas en la adresaro.</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is not a valid Bitcoin address.</source>
+ <translation>La adreso enigita "%1" ne estas valida Bitmon-adreso.</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>Ne eblis malŝlosi monujon.</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>Fiaskis kreo de nova ŝlosilo.</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ <message>
+ <source>A new data directory will be created.</source>
+ <translation>Kreiĝos nova dosierujo por la datumoj.</translation>
+ </message>
+ <message>
+ <source>name</source>
+ <translation>nomo</translation>
+ </message>
+ <message>
+ <source>Directory already exists. Add %1 if you intend to create a new directory here.</source>
+ <translation>Tiu dosierujo jam ekzistas. Aldonu %1 si vi volas krei novan dosierujon ĉi tie.</translation>
+ </message>
+ <message>
+ <source>Path already exists, and is not a directory.</source>
+ <translation>Vojo jam ekzistas, kaj ne estas dosierujo.</translation>
+ </message>
+ <message>
+ <source>Cannot create data directory here.</source>
+ <translation>Ne eblas krei dosierujon por datumoj ĉi tie.</translation>
+ </message>
+</context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Kerno de Bitmono</translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>versio</translation>
+ </message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>Pri la Bitmona Kerno</translation>
+ </message>
+ <message>
+ <source>Command-line options</source>
+ <translation>Komandliniaj agordaĵoj</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>Uzado:</translation>
+ </message>
+ <message>
+ <source>command-line options</source>
+ <translation>komandliniaj agordaĵoj</translation>
+ </message>
+</context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Welcome</source>
+ <translation>Bonvenon</translation>
+ </message>
+ <message>
+ <source>Welcome to Bitcoin Core.</source>
+ <translation>Bonvenon al la bitmona kerno, Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</source>
+ <translation>Dum tiu ĉi unua uzo de la programo, vi povas elekti lokon, kie Bitcoin Core stokos siajn datumojn.</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory.</source>
+ <translation>Bitcoin Core elŝutos kaj konservos kopion de la bitmona blokĉeno. Almenaŭ %1GB da datumoj konserviĝos en tiu loko, kaj tio poiome kreskos. Ankaŭ via monujo konserviĝos en tiu dosierujo.</translation>
+ </message>
+ <message>
+ <source>Use the default data directory</source>
+ <translation>Uzi la defaŭltan dosierujon por datumoj</translation>
+ </message>
+ <message>
+ <source>Use a custom data directory:</source>
+ <translation>Uzi alian dosierujon por datumoj:</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Kerno de Bitmono</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Eraro</translation>
+ </message>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ <message>
+ <source>Open URI</source>
+ <translation>Malfermi URI-on</translation>
+ </message>
+ <message>
+ <source>Open payment request from URI or file</source>
+ <translation>Malfermi pagpeton el URI aŭ dosiero</translation>
+ </message>
+ <message>
+ <source>URI:</source>
+ <translation>URI:</translation>
+ </message>
+ <message>
+ <source>Select payment request file</source>
+ <translation>Elektu la dosieron de la pagpeto</translation>
+ </message>
+ <message>
+ <source>Select payment request file to open</source>
+ <translation>Elektu la malfermotan dosieron de la pagpeto</translation>
+ </message>
+</context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>Agordaĵoj</translation>
+ </message>
+ <message>
+ <source>&amp;Main</source>
+ <translation>Ĉ&amp;efa</translation>
+ </message>
+ <message>
+ <source>Size of &amp;database cache</source>
+ <translation>Dosiergrando de &amp;datumbasa kaŝmemoro</translation>
+ </message>
+ <message>
+ <source>MB</source>
+ <translation>MB</translation>
+ </message>
+ <message>
+ <source>Reset all client options to default.</source>
+ <translation>Reagordi ĉion al defaŭlataj valoroj.</translation>
+ </message>
+ <message>
+ <source>&amp;Reset Options</source>
+ <translation>&amp;Rekomenci agordadon</translation>
+ </message>
+ <message>
+ <source>&amp;Network</source>
+ <translation>&amp;Reto</translation>
+ </message>
+ <message>
+ <source>Expert</source>
+ <translation>Fakulo</translation>
+ </message>
+ <message>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>Aŭtomate malfermi la kursilan pordon por Bitmono. Tio funkcias nur se via kursilo havas la UPnP-funkcion, kaj se tiu ĉi estas ŝaltita.</translation>
+ </message>
+ <message>
+ <source>Map port using &amp;UPnP</source>
+ <translation>Mapigi pordon per &amp;UPnP</translation>
+ </message>
+ <message>
+ <source>Proxy &amp;IP:</source>
+ <translation>Prokurila &amp;IP:</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>&amp;Pordo:</translation>
+ </message>
+ <message>
+ <source>Port of the proxy (e.g. 9050)</source>
+ <translation>la pordo de la prokurilo (ekz. 9050)</translation>
+ </message>
+ <message>
+ <source>&amp;Window</source>
+ <translation>&amp;Fenestro</translation>
+ </message>
+ <message>
+ <source>Show only a tray icon after minimizing the window.</source>
+ <translation>Montri nur sistempletan piktogramon post minimumigo de la fenestro.</translation>
+ </message>
+ <message>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>&amp;Minimumigi al la sistempleto anstataŭ al la taskopleto</translation>
+ </message>
+ <message>
+ <source>M&amp;inimize on close</source>
+ <translation>M&amp;inimumigi je fermo</translation>
+ </message>
+ <message>
+ <source>&amp;Display</source>
+ <translation>&amp;Aspekto</translation>
+ </message>
+ <message>
+ <source>User Interface &amp;language:</source>
+ <translation>&amp;Lingvo de la fasado:</translation>
+ </message>
+ <message>
+ <source>&amp;Unit to show amounts in:</source>
+ <translation>&amp;Unuo por vidigi sumojn:</translation>
+ </message>
+ <message>
+ <source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
+ <translation>Elekti la defaŭltan manieron por montri bitmonajn sumojn en la interfaco, kaj kiam vi sendos bitmonon.</translation>
+ </message>
+ <message>
+ <source>Whether to show coin control features or not.</source>
+ <translation>Ĉu montri detalan adres-regilon, aŭ ne.</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>&amp;Bone</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>&amp;Nuligi</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>defaŭlta</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>neniu</translation>
+ </message>
+ <message>
+ <source>Confirm options reset</source>
+ <translation>Konfirmi reŝargo de agordoj</translation>
+ </message>
+ <message>
+ <source>The supplied proxy address is invalid.</source>
+ <translation>La prokurila adreso estas malvalida.</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>Formularo</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>Eblas, ke la informoj videblaj ĉi tie estas eksdataj. Via monujo aŭtomate sinkoniĝas kun la bitmona reto kiam ili konektiĝas, sed tiu procezo ankoraŭ ne finfariĝis.</translation>
+ </message>
+ <message>
+ <source>Your current spendable balance</source>
+ <translation>via aktuala elspezebla saldo</translation>
+ </message>
+ <message>
+ <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source>
+ <translation>la sumo de transakcioj ankoraŭ ne konfirmitaj, kiuj ankoraŭ ne elspezeblas</translation>
+ </message>
+ <message>
+ <source>Immature:</source>
+ <translation>Nematura:</translation>
+ </message>
+ <message>
+ <source>Mined balance that has not yet matured</source>
+ <translation>Minita saldo, kiu ankoraŭ ne maturiĝis</translation>
+ </message>
+ <message>
+ <source>Total:</source>
+ <translation>Totalo:</translation>
+ </message>
+ <message>
+ <source>Your current total balance</source>
+ <translation>via aktuala totala saldo</translation>
+ </message>
+ </context>
+<context>
+ <name>PaymentServer</name>
+ <message>
+ <source>URI handling</source>
+ <translation>Traktado de URI-oj</translation>
+ </message>
+ <message>
+ <source>Invalid payment address %1</source>
+ <translation>Nevalida pagadreso %1</translation>
+ </message>
+ <message>
+ <source>Requested payment amount of %1 is too small (considered dust).</source>
+ <translation>La petita pagosumo de %1 estas tro malgranda (konsiderata kiel polvo).</translation>
+ </message>
+ <message>
+ <source>Payment request error</source>
+ <translation>Eraro dum pagopeto</translation>
+ </message>
+ <message>
+ <source>Cannot start bitcoin: click-to-pay handler</source>
+ <translation>Ne eblas lanĉi la ilon 'klaki-por-pagi'</translation>
+ </message>
+ <message>
+ <source>Refund from %1</source>
+ <translation>Repago de %1</translation>
+ </message>
+ <message>
+ <source>Error communicating with %1: %2</source>
+ <translation>Eraro dum komunikado kun %1: %2</translation>
+ </message>
+ <message>
+ <source>Bad response from server %1</source>
+ <translation>Malbona respondo de la servilo %1</translation>
+ </message>
+ <message>
+ <source>Payment acknowledged</source>
+ <translation>Pago agnoskita</translation>
+ </message>
+ <message>
+ <source>Network request error</source>
+ <translation>Eraro dum ret-peto</translation>
+ </message>
+</context>
+<context>
+ <name>PeerTableModel</name>
+ </context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>Sumo</translation>
+ </message>
+ <message>
+ <source>%1 h</source>
+ <translation>%1 h</translation>
+ </message>
+ <message>
+ <source>%1 m</source>
+ <translation>%1 m</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>neaplikebla</translation>
+ </message>
+ </context>
+<context>
+ <name>QRImageWidget</name>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Konservi Bildon...</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Image</source>
+ <translation>&amp;Kopii Bildon</translation>
+ </message>
+ <message>
+ <source>Save QR Code</source>
+ <translation>Konservi QR-kodon</translation>
+ </message>
+ <message>
+ <source>PNG Image (*.png)</source>
+ <translation>PNG-bildo (*.png)</translation>
+ </message>
+</context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>Client name</source>
+ <translation>Nomo de kliento</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>neaplikebla</translation>
+ </message>
+ <message>
+ <source>Client version</source>
+ <translation>Versio de kliento</translation>
+ </message>
+ <message>
+ <source>&amp;Information</source>
+ <translation>&amp;Informoj</translation>
+ </message>
+ <message>
+ <source>Debug window</source>
+ <translation>Sencimiga fenestro</translation>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>Ĝenerala</translation>
+ </message>
+ <message>
+ <source>Using OpenSSL version</source>
+ <translation>uzas OpenSSL-version</translation>
+ </message>
+ <message>
+ <source>Startup time</source>
+ <translation>Horo de lanĉo</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Reto</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>Nomo</translation>
+ </message>
+ <message>
+ <source>Number of connections</source>
+ <translation>Nombro de konektoj</translation>
+ </message>
+ <message>
+ <source>Block chain</source>
+ <translation>Blokĉeno</translation>
+ </message>
+ <message>
+ <source>Current number of blocks</source>
+ <translation>Aktuala nombro de blokoj</translation>
+ </message>
+ <message>
+ <source>Bytes Sent</source>
+ <translation>Bajtoj Senditaj:</translation>
+ </message>
+ <message>
+ <source>Last block time</source>
+ <translation>Horo de la lasta bloko</translation>
+ </message>
+ <message>
+ <source>&amp;Open</source>
+ <translation>&amp;Malfermi</translation>
+ </message>
+ <message>
+ <source>&amp;Console</source>
+ <translation>&amp;Konzolo</translation>
+ </message>
+ <message>
+ <source>&amp;Network Traffic</source>
+ <translation>&amp;Reta Trafiko</translation>
+ </message>
+ <message>
+ <source>&amp;Clear</source>
+ <translation>&amp;Forigi ĉion</translation>
+ </message>
+ <message>
+ <source>Totals</source>
+ <translation>Totaloj</translation>
+ </message>
+ <message>
+ <source>In:</source>
+ <translation>En:</translation>
+ </message>
+ <message>
+ <source>Out:</source>
+ <translation>El:</translation>
+ </message>
+ <message>
+ <source>Build date</source>
+ <translation>Dato de kompilado</translation>
+ </message>
+ <message>
+ <source>Debug log file</source>
+ <translation>Sencimiga protokoldosiero</translation>
+ </message>
+ <message>
+ <source>Clear console</source>
+ <translation>Malplenigi konzolon</translation>
+ </message>
+ <message>
+ <source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
+ <translation>Uzu la sagojn supran kaj malsupran por esplori la historion, kaj &lt;b&gt;stir-L&lt;/b&gt; por malplenigi la ekranon.</translation>
+ </message>
+ <message>
+ <source>Type &lt;b&gt;help&lt;/b&gt; for an overview of available commands.</source>
+ <translation>Tajpu &lt;b&gt;help&lt;/b&gt; por superrigardo de la disponeblaj komandoj.</translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation>%1 B</translation>
+ </message>
+ <message>
+ <source>%1 KB</source>
+ <translation>%1 KB</translation>
+ </message>
+ <message>
+ <source>%1 MB</source>
+ <translation>%1 MB</translation>
+ </message>
+ <message>
+ <source>%1 GB</source>
+ <translation>%1 GB</translation>
+ </message>
+ </context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Amount:</source>
+ <translation>&amp;Kvanto:</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Etikedo:</translation>
+ </message>
+ <message>
+ <source>&amp;Message:</source>
+ <translation>&amp;Mesaĝo:</translation>
+ </message>
+ <message>
+ <source>Reuse one of the previously used receiving addresses. Reusing addresses has security and privacy issues. Do not use this unless re-generating a payment request made before.</source>
+ <translation>Reuzi unu el la jam uzitaj ricevaj adresoj. Reuzo de adresoj povas krei problemojn pri sekureco kaj privateco. Ne uzu tiun ĉi funkcion krom por rekrei antaŭe faritan pagopeton.</translation>
+ </message>
+ <message>
+ <source>R&amp;euse an existing receiving address (not recommended)</source>
+ <translation>R&amp;euzi ekzistantan ricevan adreson (malrekomendinda)</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Malplenigi ĉiujn kampojn de la formularo.</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation>Forigi</translation>
+ </message>
+ <message>
+ <source>&amp;Request payment</source>
+ <translation>&amp;Peti pagon</translation>
+ </message>
+ <message>
+ <source>Show</source>
+ <translation>Vidigi</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>Forigi</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Kopii etikedon</translation>
+ </message>
+ <message>
+ <source>Copy message</source>
+ <translation>Kopiu mesaĝon</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopii sumon</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>QR Code</source>
+ <translation>QR-kodo</translation>
+ </message>
+ <message>
+ <source>Copy &amp;URI</source>
+ <translation>Kopii &amp;URI</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Address</source>
+ <translation>Kopii &amp;Adreson</translation>
+ </message>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Konservi Bildon...</translation>
+ </message>
+ <message>
+ <source>Request payment to %1</source>
+ <translation>Peti pagon al %1</translation>
+ </message>
+ <message>
+ <source>Payment information</source>
+ <translation>Paginformoj</translation>
+ </message>
+ <message>
+ <source>URI</source>
+ <translation>URI</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adreso</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Sumo</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etikedo</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Mesaĝo</translation>
+ </message>
+ <message>
+ <source>Resulting URI too long, try to reduce the text for label / message.</source>
+ <translation>La rezultanta URI estas tro longa. Provu malplilongigi la tekston de la etikedo / mesaĝo.</translation>
+ </message>
+ <message>
+ <source>Error encoding URI into QR Code.</source>
+ <translation>Eraro de kodigo de URI en la QR-kodon.</translation>
+ </message>
+</context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Dato</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etikedo</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Mesaĝo</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Sumo</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(neniu etikedo)</translation>
+ </message>
+ <message>
+ <source>(no message)</source>
+ <translation>(neniu mesaĝo)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Sendi Bitmonon</translation>
+ </message>
+ <message>
+ <source>Coin Control Features</source>
+ <translation>Monregaj Opcioj</translation>
+ </message>
+ <message>
+ <source>Inputs...</source>
+ <translation>Enigoj...</translation>
+ </message>
+ <message>
+ <source>Insufficient funds!</source>
+ <translation>Nesufiĉa mono!</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Kvanto:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Bajtoj:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Sumo:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Prioritato:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Krompago:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Post krompago:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Restmono:</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>Sendi samtempe al pluraj ricevantoj</translation>
+ </message>
+ <message>
+ <source>Add &amp;Recipient</source>
+ <translation>Aldoni &amp;Ricevonton</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Malplenigi ĉiujn kampojn de la formularo.</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Polvo:</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>&amp;Forigi Ĉion</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>Saldo:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>Konfirmi la sendon</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>Ŝendi</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>Konfirmi sendon de bitmono</translation>
+ </message>
+ <message>
+ <source>%1 to %2</source>
+ <translation>%1 al %2</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Kopii kvanton</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopii sumon</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Kopii krompagon</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Kopii post krompago</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Kopii bajtojn</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Kopii prioritaton</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Kopii restmonon</translation>
+ </message>
+ <message>
+ <source>or</source>
+ <translation>aŭ</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>La pagenda sumo devas esti pli ol 0.</translation>
+ </message>
+ <message>
+ <source>The amount exceeds your balance.</source>
+ <translation>La sumo estas pli granda ol via saldo.</translation>
+ </message>
+ <message>
+ <source>The total exceeds your balance when the %1 transaction fee is included.</source>
+ <translation>La sumo kun la %1 krompago estas pli granda ol via saldo.</translation>
+ </message>
+ <message>
+ <source>Transaction creation failed!</source>
+ <translation>Kreo de transakcio fiaskis!</translation>
+ </message>
+ <message>
+ <source>Warning: Invalid Bitcoin address</source>
+ <translation>Averto: Nevalida Bitmon-adreso</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(neniu etikedo)</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Kopii polvon</translation>
+ </message>
+ <message>
+ <source>Are you sure you want to send?</source>
+ <translation>Ĉu vi certas, ke vi volas sendi?</translation>
+ </message>
+ <message>
+ <source>added as transaction fee</source>
+ <translation>aldonita kiel krompago</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>&amp;Sumo:</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>&amp;Ricevonto:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Tajpu etikedon por tiu ĉi adreso kaj aldonu ĝin al via adresaro</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Etikedo:</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Elektu la jam uzitan adreson</translation>
+ </message>
+ <message>
+ <source>This is a normal payment.</source>
+ <translation>Tio estas normala pago.</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Alglui adreson de tondejo</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Remove this entry</source>
+ <translation>Forigu ĉi tiun enskribon</translation>
+ </message>
+ <message>
+ <source>Message:</source>
+ <translation>Mesaĝo:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to the list of used addresses</source>
+ <translation>Tajpu etikedon por tiu ĉi adreso por aldoni ĝin al la listo de uzitaj adresoj</translation>
+ </message>
+ <message>
+ <source>Pay To:</source>
+ <translation>Pagi Al:</translation>
+ </message>
+ <message>
+ <source>Memo:</source>
+ <translation>Memorando:</translation>
+ </message>
+</context>
+<context>
+ <name>ShutdownWindow</name>
+ <message>
+ <source>Do not shut down the computer until this window disappears.</source>
+ <translation>Ne sistemfermu ĝis ĉi tiu fenestro malaperas.</translation>
+ </message>
+</context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Signatures - Sign / Verify a Message</source>
+ <translation>Subskriboj - Subskribi / Kontroli mesaĝon</translation>
+ </message>
+ <message>
+ <source>&amp;Sign Message</source>
+ <translation>&amp;Subskribi Mesaĝon</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Elektu la jam uzitan adreson</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Alglui adreson de tondejo</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Enter the message you want to sign here</source>
+ <translation>Tajpu la mesaĝon, kiun vi volas sendi, cîi tie</translation>
+ </message>
+ <message>
+ <source>Signature</source>
+ <translation>Subskribo</translation>
+ </message>
+ <message>
+ <source>Copy the current signature to the system clipboard</source>
+ <translation>Kopii la aktualan subskribon al la tondejo</translation>
+ </message>
+ <message>
+ <source>Sign the message to prove you own this Bitcoin address</source>
+ <translation>Subskribi la mesaĝon por pravigi, ke vi estas la posedanto de tiu Bitmon-adreso</translation>
+ </message>
+ <message>
+ <source>Sign &amp;Message</source>
+ <translation>Subskribi &amp;Mesaĝon</translation>
+ </message>
+ <message>
+ <source>Reset all sign message fields</source>
+ <translation>Reagordigi ĉiujn prisubskribajn kampojn</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>&amp;Forigi Ĉion</translation>
+ </message>
+ <message>
+ <source>&amp;Verify Message</source>
+ <translation>&amp;Kontroli Mesaĝon</translation>
+ </message>
+ <message>
+ <source>Verify the message to ensure it was signed with the specified Bitcoin address</source>
+ <translation>Kontroli la mesaĝon por pravigi, ke ĝi ja estas subskribita per la specifa Bitmon-adreso</translation>
+ </message>
+ <message>
+ <source>Verify &amp;Message</source>
+ <translation>Kontroli &amp;Mesaĝon</translation>
+ </message>
+ <message>
+ <source>Reset all verify message fields</source>
+ <translation>Reagordigi ĉiujn prikontrolajn kampojn</translation>
+ </message>
+ <message>
+ <source>Click "Sign Message" to generate signature</source>
+ <translation>Klaku "Subskribi Mesaĝon" por krei subskribon</translation>
+ </message>
+ <message>
+ <source>The entered address is invalid.</source>
+ <translation>La adreso, kiun vi enmetis, estas nevalida.</translation>
+ </message>
+ <message>
+ <source>Please check the address and try again.</source>
+ <translation>Bonvolu kontroli la adreson kaj reprovi.</translation>
+ </message>
+ <message>
+ <source>The entered address does not refer to a key.</source>
+ <translation>La adreso, kiun vi enmetis, referencas neniun ŝlosilon.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock was cancelled.</source>
+ <translation>Malŝloso de monujo estas nuligita.</translation>
+ </message>
+ <message>
+ <source>Private key for the entered address is not available.</source>
+ <translation>La privata ŝlosilo por la enigita adreso ne disponeblas.</translation>
+ </message>
+ <message>
+ <source>Message signing failed.</source>
+ <translation>Subskribo de mesaĝo fiaskis.</translation>
+ </message>
+ <message>
+ <source>Message signed.</source>
+ <translation>Mesaĝo estas subskribita.</translation>
+ </message>
+ <message>
+ <source>The signature could not be decoded.</source>
+ <translation>Ne eblis malĉifri la subskribon.</translation>
+ </message>
+ <message>
+ <source>Please check the signature and try again.</source>
+ <translation>Bonvolu kontroli la subskribon kaj reprovu.</translation>
+ </message>
+ <message>
+ <source>The signature did not match the message digest.</source>
+ <translation>La subskribo ne kongruis kun la mesaĝ-kompilaĵo.</translation>
+ </message>
+ <message>
+ <source>Message verification failed.</source>
+ <translation>Kontrolo de mesaĝo malsukcesis.</translation>
+ </message>
+ <message>
+ <source>Message verified.</source>
+ <translation>Mesaĝo sukcese kontrolita.</translation>
+ </message>
+</context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Kerno de Bitmono</translation>
+ </message>
+ <message>
+ <source>The Bitcoin Core developers</source>
+ <translation>La programistoj de Bitmona Kerno</translation>
+ </message>
+ <message>
+ <source>[testnet]</source>
+ <translation>[testnet]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ <message>
+ <source>KB/s</source>
+ <translation>KB/s</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>Malferma ĝis %1</translation>
+ </message>
+ <message>
+ <source>%1/offline</source>
+ <translation>%1/senkonekte</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/nekonfirmite</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 konfirmoj</translation>
+ </message>
+ <message>
+ <source>Status</source>
+ <translation>Stato</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Dato</translation>
+ </message>
+ <message>
+ <source>Source</source>
+ <translation>Fonto</translation>
+ </message>
+ <message>
+ <source>Generated</source>
+ <translation>Kreita</translation>
+ </message>
+ <message>
+ <source>From</source>
+ <translation>De</translation>
+ </message>
+ <message>
+ <source>To</source>
+ <translation>Al</translation>
+ </message>
+ <message>
+ <source>own address</source>
+ <translation>propra adreso</translation>
+ </message>
+ <message>
+ <source>label</source>
+ <translation>etikedo</translation>
+ </message>
+ <message>
+ <source>Credit</source>
+ <translation>Kredito</translation>
+ </message>
+ <message>
+ <source>not accepted</source>
+ <translation>ne akceptita</translation>
+ </message>
+ <message>
+ <source>Debit</source>
+ <translation>Debeto</translation>
+ </message>
+ <message>
+ <source>Transaction fee</source>
+ <translation>Krompago</translation>
+ </message>
+ <message>
+ <source>Net amount</source>
+ <translation>Neta sumo</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Mesaĝo</translation>
+ </message>
+ <message>
+ <source>Comment</source>
+ <translation>Komento</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>Transakcia ID</translation>
+ </message>
+ <message>
+ <source>Merchant</source>
+ <translation>Vendisto</translation>
+ </message>
+ <message>
+ <source>Generated coins must mature %1 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.</source>
+ <translation>Kreitaj moneroj devas esti maturaj je %1 blokoj antaŭ ol eblas elspezi ilin. Kiam vi generis tiun ĉi blokon, ĝi estis elsendita al la reto por aldono al la blokĉeno. Se tiu aldono malsukcesas, ĝia stato ŝanĝiĝos al "neakceptita" kaj ne eblos elspezi ĝin. Tio estas malofta, sed povas okazi se alia bloko estas kreita je preskaŭ la sama momento kiel la via.</translation>
+ </message>
+ <message>
+ <source>Debug information</source>
+ <translation>Sencimigaj informoj</translation>
+ </message>
+ <message>
+ <source>Transaction</source>
+ <translation>Transakcio</translation>
+ </message>
+ <message>
+ <source>Inputs</source>
+ <translation>Enigoj</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Sumo</translation>
+ </message>
+ <message>
+ <source>true</source>
+ <translation>vera</translation>
+ </message>
+ <message>
+ <source>false</source>
+ <translation>malvera</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, ankoraŭ ne elsendita sukcese</translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>nekonata</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>Transakciaj detaloj</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>Tiu ĉi panelo montras detalan priskribon de la transakcio</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Dato</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Tipo</translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>Malferma ĝis %1</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>Konfirmita (%1 konfirmoj)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>Tiun ĉi blokon ne ricevis ajna alia nodo, kaj ĝi verŝajne ne akceptiĝos!</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>Kreita sed ne akceptita</translation>
+ </message>
+ <message>
+ <source>Offline</source>
+ <translation>Senkonekte</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etikedo</translation>
+ </message>
+ <message>
+ <source>Unconfirmed</source>
+ <translation>Nekonfirmita</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Ricevita kun</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>Ricevita de</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Sendita al</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>Pago al vi mem</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Minita</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>neaplikebla</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>Transakcia stato. Ŝvebi super tiu ĉi kampo por montri la nombron de konfirmoj.</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Dato kaj horo kiam la transakcio alvenis.</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>Tipo de transakcio.</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>Sumo elprenita de aŭ aldonita al la saldo.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>Ĉiuj</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>Hodiaŭ</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>Ĉi-semajne</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>Ĉi-monate</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>Pasintmonate</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>Ĉi-jare</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>Intervalo...</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Ricevita kun</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Sendita al</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>Al vi mem</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Minita</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>Aliaj</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>Tajpu adreson aŭ etikedon por serĉi</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>Minimuma sumo</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Kopii adreson</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Kopii etikedon</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopii sumon</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Kopii transakcian ID-on</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>Redakti etikedon</translation>
+ </message>
+ <message>
+ <source>Show transaction details</source>
+ <translation>Montri detalojn de transakcio</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>ekspotado malsukcesinta</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Perkome disigita dosiero (*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Konfirmita</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Dato</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Tipo</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etikedo</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adreso</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>Intervalo:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>al</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ </context>
+<context>
+ <name>WalletFrame</name>
+ </context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Sendi Bitmonon</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Eksporti</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Eksporti la datumojn el la aktuala langeto al dosiero</translation>
+ </message>
+ <message>
+ <source>Backup Wallet</source>
+ <translation>Krei sekurkopion de monujo</translation>
+ </message>
+ <message>
+ <source>Wallet Data (*.dat)</source>
+ <translation>Monuj-datumoj (*.dat)</translation>
+ </message>
+ <message>
+ <source>Backup Failed</source>
+ <translation>Malsukcesis sekurkopio</translation>
+ </message>
+ <message>
+ <source>Backup Successful</source>
+ <translation>Sukcesis krei sekurkopion</translation>
+ </message>
+</context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>Agordoj:</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>Specifi dosieron por datumoj</translation>
+ </message>
+ <message>
+ <source>Connect to a node to retrieve peer addresses, and disconnect</source>
+ <translation>Konekti al nodo por ricevi adresojn de samtavolanoj, kaj malkonekti</translation>
+ </message>
+ <message>
+ <source>Specify your own public address</source>
+ <translation>Specifi vian propran publikan adreson</translation>
+ </message>
+ <message>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>Akcepti komandojn JSON-RPC kaj el komandlinio</translation>
+ </message>
+ <message>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>Ruli fone kiel demono kaj akcepti komandojn</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>Uzi la test-reton</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
+ <translation>Akcepti konektojn el ekstere (defaŭlte: 1 se ne estas -proxy nek -connect)</translation>
+ </message>
+ <message>
+ <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
+ <translation>Bindi al donita adreso kaj ĉiam aŭskulti per ĝi. Uzu la formaton [gastigo]:pordo por IPv6</translation>
+ </message>
+ <message>
+ <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
+ <translation>Plenumi komandon kiam monuja transakcio ŝanĝiĝas (%s en cmd anstataŭiĝas per TxID)</translation>
+ </message>
+ <message>
+ <source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source>
+ <translation>Tiu ĉi estas antaŭeldona testa versio - uzu laŭ via propra risko - ne uzu por minado aŭ por aplikaĵoj por vendistoj</translation>
+ </message>
+ <message>
+ <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>Averto: -paytxfee estas agordita per tre alta valoro! Tio estas la krompago, kion vi pagos se vi sendas la transakcion.</translation>
+ </message>
+ <message>
+ <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source>
+ <translation>Averto: La reto ne tute konsentas! Kelkaj minantoj ŝajne spertas problemojn aktuale.</translation>
+ </message>
+ <message>
+ <source>Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.</source>
+ <translation>Averto: ŝajne ni ne tute konsentas kun niaj samtavolanoj! Eble vi devas ĝisdatigi vian klienton, aŭ eble aliaj nodoj faru same.</translation>
+ </message>
+ <message>
+ <source>Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
+ <translation>Averto: okazis eraro dum lego de wallet.dat! Ĉiuj ŝlosiloj sukcese legiĝis, sed la transakciaj datumoj aŭ la adresaro eble mankas aŭ malĝustas.</translation>
+ </message>
+ <message>
+ <source>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</source>
+ <translation>Averto: via wallet.dat estas difektita, sed la datumoj sukcese saviĝis! La originala wallet.dat estas nun konservita kiel wallet.{timestamp}.bak en %s; se via saldo aŭ transakcioj estas malĝustaj vi devus restaŭri per alia sekurkopio.</translation>
+ </message>
+ <message>
+ <source>&lt;category&gt; can be:</source>
+ <translation>&lt;category&gt; povas esti:</translation>
+ </message>
+ <message>
+ <source>Attempt to recover private keys from a corrupt wallet.dat</source>
+ <translation>Provo ripari privatajn ŝlosilojn el difektita wallet.dat</translation>
+ </message>
+ <message>
+ <source>Block creation options:</source>
+ <translation>Blok-kreaj agordaĵoj:</translation>
+ </message>
+ <message>
+ <source>Connect only to the specified node(s)</source>
+ <translation>Konekti nur al specifita(j) nodo(j)</translation>
+ </message>
+ <message>
+ <source>Corrupted block database detected</source>
+ <translation>Difektita blokdatumbazo trovita</translation>
+ </message>
+ <message>
+ <source>Do you want to rebuild the block database now?</source>
+ <translation>Ĉu vi volas rekonstrui la blokdatumbazon nun?</translation>
+ </message>
+ <message>
+ <source>Error initializing block database</source>
+ <translation>Eraro dum pravalorizado de blokdatumbazo</translation>
+ </message>
+ <message>
+ <source>Error initializing wallet database environment %s!</source>
+ <translation>Eraro dum pravalorizado de monuj-datumbaza ĉirkaŭaĵo %s!</translation>
+ </message>
+ <message>
+ <source>Error loading block database</source>
+ <translation>Eraro dum ŝargado de blokdatumbazo</translation>
+ </message>
+ <message>
+ <source>Error opening block database</source>
+ <translation>Eraro dum malfermado de blokdatumbazo</translation>
+ </message>
+ <message>
+ <source>Error: Disk space is low!</source>
+ <translation>Eraro: restas malmulte da diskospaco!</translation>
+ </message>
+ <message>
+ <source>Failed to listen on any port. Use -listen=0 if you want this.</source>
+ <translation>Ne sukcesis aŭskulti ajnan pordon. Uzu -listen=0 se tion vi volas.</translation>
+ </message>
+ <message>
+ <source>Incorrect or no genesis block found. Wrong datadir for network?</source>
+ <translation>Geneza bloko aŭ netrovita aŭ neĝusta. Ĉu eble la datadir de la reto malĝustas?</translation>
+ </message>
+ <message>
+ <source>Invalid -onion address: '%s'</source>
+ <translation>Nevalida -onion-adreso: '%s'</translation>
+ </message>
+ <message>
+ <source>Not enough file descriptors available.</source>
+ <translation>Nesufiĉa nombro de dosierpriskribiloj disponeblas.</translation>
+ </message>
+ <message>
+ <source>Specify wallet file (within data directory)</source>
+ <translation>Specifi monujan dosieron (ene de dosierujo por datumoj)</translation>
+ </message>
+ <message>
+ <source>Verifying blocks...</source>
+ <translation>Kontrolado de blokoj...</translation>
+ </message>
+ <message>
+ <source>Verifying wallet...</source>
+ <translation>Kontrolado de monujo...</translation>
+ </message>
+ <message>
+ <source>Wallet %s resides outside data directory %s</source>
+ <translation>Monujo %s troviĝas ekster la dosierujo por datumoj %s</translation>
+ </message>
+ <message>
+ <source>Wallet options:</source>
+ <translation>Monujaj opcioj:</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to change -txindex</source>
+ <translation>Vi devas rekontrui la datumbazon kun -reindex por ŝanĝi -txindex</translation>
+ </message>
+ <message>
+ <source>Imports blocks from external blk000??.dat file</source>
+ <translation>Importas blokojn el ekstera dosiero blk000??.dat</translation>
+ </message>
+ <message>
+ <source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source>
+ <translation>Plenumi komandon kiam rilata alerto riceviĝas, aŭ kiam ni vidas tre longan forkon (%s en cms anstataŭiĝas per mesaĝo)</translation>
+ </message>
+ <message>
+ <source>Choose data directory on startup (default: 0)</source>
+ <translation>Elekti dosierujon por datumoj dum lanĉo (defaŭlte: 0)</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Informoj</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -minrelaytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Nevalida sumo por -minrelaytxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -mintxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Nevalida sumo por -mintxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>Sendi spurajn/sencimigajn informojn al la konzolo anstataŭ al dosiero debug.log</translation>
+ </message>
+ <message>
+ <source>Set language, for example "de_DE" (default: system locale)</source>
+ <translation>Agordi lingvon, ekzemple "de_DE" (defaŭlte: tiu de la sistemo)</translation>
+ </message>
+ <message>
+ <source>Show splash screen on startup (default: 1)</source>
+ <translation>Montri salutŝildon dum lanĉo (defaŭlte: 1)</translation>
+ </message>
+ <message>
+ <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source>
+ <translation>Malpligrandigi la sencimigan protokol-dosieron kiam kliento lanĉiĝas (defaŭlte: 1 kiam mankas -debug)</translation>
+ </message>
+ <message>
+ <source>Signing transaction failed</source>
+ <translation>Subskriba transakcio fiaskis</translation>
+ </message>
+ <message>
+ <source>Start minimized</source>
+ <translation>Lanĉiĝi plejete</translation>
+ </message>
+ <message>
+ <source>This is experimental software.</source>
+ <translation>ĝi estas eksperimenta programo</translation>
+ </message>
+ <message>
+ <source>Transaction amount too small</source>
+ <translation>Transakcia sumo tro malgranda</translation>
+ </message>
+ <message>
+ <source>Transaction amounts must be positive</source>
+ <translation>Transakcia sumo devas esti pozitiva</translation>
+ </message>
+ <message>
+ <source>Transaction too large</source>
+ <translation>Transakcio estas tro granda</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: 1 when listening)</source>
+ <translation>Uzi UPnP por mapi la aŭskultan pordon (defaŭlte: 1 dum aŭskultado)</translation>
+ </message>
+ <message>
+ <source>Username for JSON-RPC connections</source>
+ <translation>Salutnomo por konektoj JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Averto</translation>
+ </message>
+ <message>
+ <source>wallet.dat corrupt, salvage failed</source>
+ <translation>wallet.dat estas difektita, riparo malsukcesis</translation>
+ </message>
+ <message>
+ <source>Password for JSON-RPC connections</source>
+ <translation>Pasvorto por konektoj JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
+ <translation>Plenumi komandon kiam plej bona bloko ŝanĝiĝas (%s en cmd anstataŭiĝas per bloka haketaĵo)</translation>
+ </message>
+ <message>
+ <source>Upgrade wallet to latest format</source>
+ <translation>Ĝisdatigi monujon al plej lasta formato</translation>
+ </message>
+ <message>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>Reskani la blokĉenon por mankantaj monujaj transakcioj</translation>
+ </message>
+ <message>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>Uzi OpenSSL (https) por konektoj JSON-RPC</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>Tiu ĉi helpmesaĝo</translation>
+ </message>
+ <message>
+ <source>Allow DNS lookups for -addnode, -seednode and -connect</source>
+ <translation>Permesi DNS-elserĉojn por -addnote, -seednote kaj -connect</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>Ŝarĝante adresojn...</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>Eraro dum ŝargado de wallet.dat: monujo difektita</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>Eraro dum ŝargado de wallet.dat</translation>
+ </message>
+ <message>
+ <source>Invalid -proxy address: '%s'</source>
+ <translation>Nevalid adreso -proxy: '%s'</translation>
+ </message>
+ <message>
+ <source>Unknown network specified in -onlynet: '%s'</source>
+ <translation>Nekonata reto specifita en -onlynet: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -bind address: '%s'</source>
+ <translation>Ne eblas trovi la adreson -bind: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -externalip address: '%s'</source>
+ <translation>Ne eblas trovi la adreson -externalip: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Nevalida sumo por -paytxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>Nesufiĉa mono</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>Ŝarĝante blok-indekson...</translation>
+ </message>
+ <message>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>Aldoni nodon por alkonekti kaj provi daŭrigi la malferman konekton</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>Ŝargado de monujo...</translation>
+ </message>
+ <message>
+ <source>Cannot downgrade wallet</source>
+ <translation>Ne eblas malpromocii monujon</translation>
+ </message>
+ <message>
+ <source>Cannot write default address</source>
+ <translation>Ne eblas skribi defaŭltan adreson</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>Reskanado...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>Ŝargado finiĝis</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Eraro</translation>
+ </message>
+</context>
+</TS> \ No newline at end of file
diff --git a/src/qt/locale/bitcoin_es.ts b/src/qt/locale/bitcoin_es.ts
new file mode 100644
index 0000000000..0620961342
--- /dev/null
+++ b/src/qt/locale/bitcoin_es.ts
@@ -0,0 +1,3588 @@
+<TS language="es" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Right-click to edit address or label</source>
+ <translation>Haz clic derecho para editar la dirección o etiqueta</translation>
+ </message>
+ <message>
+ <source>Create a new address</source>
+ <translation>Crear una nueva dirección</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>&amp;Nuevo</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Copiar la dirección seleccionada al portapapeles del sistema</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>&amp;Copiar</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>&amp;Cerrar</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>&amp;Copiar dirección</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>Eliminar la dirección seleccionada de la lista</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Exportar los datos en la ficha actual a un archivo</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Exportar</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;Eliminar</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>Elija la dirección para enviar monedas a</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>Elija la dirección para recibir monedas con</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>&amp;Escoger</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>Direcciones de envío</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>Direcciones de recepción</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>Estas son tus direcciones Bitcoin para enviar los pagos. Comprueba siempre la cantidad y la dirección receptora antes de enviar las monedas.</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>Estas son tus direcciones de Bitcoin para recibir los pagos. Se recomienda utilizar una nueva dirección de recepción para cada transacción.</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>Copiar &amp;Etiqueta</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>&amp;Editar</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>Exportar la lista de direcciones </translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Archivos separados por coma (*.csv)</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Fallo al exportar</translation>
+ </message>
+ </context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Etiqueta</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Dirección</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(sin etiqueta)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Passphrase Dialog</source>
+ <translation>Diálogo de contraseña</translation>
+ </message>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Introducir contraseña</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Nueva contraseña</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Repita la nueva contraseña</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>Cifrar el monedero</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>Esta operación requiere su contraseña para desbloquear el monedero.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Desbloquear monedero</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>Esta operación requiere su contraseña para descifrar el monedero.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>Descifrar el monedero</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>Cambiar contraseña</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>Confirmar cifrado del monedero</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>Atencion: ¡Si cifra su monedero y pierde la contraseña perderá &lt;b&gt;TODOS SUS BITCOINS&lt;/b&gt;!"</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>¿Estás seguro que deseas cifrar tu monedero ?</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core 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.</source>
+ <translation>Bitcoin Core se cerrará ahora para completar el procedo de encriptación. Recuerda que encriptar tu cartera no te protegerá completamente de la pérdida de bitcoins por infección de malware en tu computadora.</translation>
+ </message>
+ <message>
+ <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
+ <translation>IMPORTANTE: Cualquier copia de seguridad que haya realizado previamente de su archivo de monedero debe reemplazarse con el nuevo archivo de monedero cifrado. Por razones de seguridad, las copias de seguridad previas del archivo de monedero no cifradas serán inservibles en cuanto comience a usar el nuevo monedero cifrado.</translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>Aviso: ¡La tecla de Mayúsculas está activada!</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>Monedero cifrado</translation>
+ </message>
+ <message>
+ <source>Enter the new passphrase to the wallet.&lt;br/&gt;Please use a passphrase of &lt;b&gt;ten or more random characters&lt;/b&gt;, or &lt;b&gt;eight or more words&lt;/b&gt;.</source>
+ <translation>Introduzca la nueva contraseña para el monedero.&lt;br/&gt;Utilice por favor una contraseña con &lt;b&gt;diez o más caracteres aleatorios&lt;/b&gt; o con &lt;b&gt;ocho o más palabras&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>Enter the old passphrase and new passphrase to the wallet.</source>
+ <translation>Introduce la antigua y la nueva contraseña de la cartera.</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>Ha fallado el cifrado del monedero</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>Ha fallado el cifrado del monedero debido a un error interno. El monedero no ha sido cifrado.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>Las contraseñas no coinciden.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>Ha fallado el desbloqueo del monedero</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>La contraseña introducida para descifrar el monedero es incorrecta.</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>Ha fallado el descifrado del monedero</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>Se ha cambiado correctamente la contraseña del monedero.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>Firmar &amp;mensaje...</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>Sincronizando con la red…</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;Vista general</translation>
+ </message>
+ <message>
+ <source>Node</source>
+ <translation>Nodo</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>Mostrar vista general del monedero</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Transacciones</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>Examinar el historial de transacciones</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>&amp;Salir</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>Salir de la aplicación</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>Acerca de &amp;Qt</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>Mostrar información acerca de Qt</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;Opciones...</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>&amp;Cifrar monedero…</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>&amp;Guardar copia del monedero...</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>&amp;Cambiar la contraseña…</translation>
+ </message>
+ <message>
+ <source>&amp;Sending addresses...</source>
+ <translation>Direcciones de &amp;envío...</translation>
+ </message>
+ <message>
+ <source>&amp;Receiving addresses...</source>
+ <translation>Direcciones de &amp;recepción...</translation>
+ </message>
+ <message>
+ <source>Open &amp;URI...</source>
+ <translation>Abrir &amp;URI...</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core client</source>
+ <translation>Cliente Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Importing blocks from disk...</source>
+ <translation>Importando bloques de disco...</translation>
+ </message>
+ <message>
+ <source>Reindexing blocks on disk...</source>
+ <translation>Reindexando bloques en disco...</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>Enviar bitcoins a una dirección Bitcoin</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>Copia de seguridad del monedero en otra ubicación</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Cambiar la contraseña utilizada para el cifrado del monedero</translation>
+ </message>
+ <message>
+ <source>&amp;Debug window</source>
+ <translation>&amp;Ventana de depuración</translation>
+ </message>
+ <message>
+ <source>Open debugging and diagnostic console</source>
+ <translation>Abrir la consola de depuración y diagnóstico</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>&amp;Verificar mensaje...</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>Monedero</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>&amp;Enviar</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>&amp;Recibir</translation>
+ </message>
+ <message>
+ <source>Show information about Bitcoin Core</source>
+ <translation>Mostrar información acerca de Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>&amp;Mostrar / Ocultar</translation>
+ </message>
+ <message>
+ <source>Show or hide the main Window</source>
+ <translation>Mostrar u ocultar la ventana principal</translation>
+ </message>
+ <message>
+ <source>Encrypt the private keys that belong to your wallet</source>
+ <translation>Cifrar las claves privadas de su monedero</translation>
+ </message>
+ <message>
+ <source>Sign messages with your Bitcoin addresses to prove you own them</source>
+ <translation>Firmar mensajes con sus direcciones Bitcoin para demostrar la propiedad</translation>
+ </message>
+ <message>
+ <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source>
+ <translation>Verificar mensajes comprobando que están firmados con direcciones Bitcoin concretas</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;Archivo</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;Configuración</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>&amp;Ayuda</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>Barra de pestañas</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Request payments (generates QR codes and bitcoin: URIs)</source>
+ <translation>Solicitar pagos (generando códigos QR e identificadores URI "bitcoin:")</translation>
+ </message>
+ <message>
+ <source>&amp;About Bitcoin Core</source>
+ <translation>&amp;Acerca de Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Modify configuration options for Bitcoin Core</source>
+ <translation>Modificar las opciones de configuración de Bitcoin</translation>
+ </message>
+ <message>
+ <source>Show the list of used sending addresses and labels</source>
+ <translation>Mostrar la lista de direcciones de envío y etiquetas</translation>
+ </message>
+ <message>
+ <source>Show the list of used receiving addresses and labels</source>
+ <translation>Muestra la lista de direcciones de recepción y etiquetas</translation>
+ </message>
+ <message>
+ <source>Open a bitcoin: URI or payment request</source>
+ <translation>Abrir un identificador URI "bitcoin:" o una petición de pago</translation>
+ </message>
+ <message>
+ <source>&amp;Command-line options</source>
+ <translation>&amp;Opciones de consola de comandos</translation>
+ </message>
+ <message>
+ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
+ <translation>Mostrar el mensaje de ayuda de Bitcoin Core con una lista de las posibles opciones de la consola de comandos de Bitcoin</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n active connection(s) to Bitcoin network</source>
+ <translation><numerusform>%n conexión activa hacia la red Bitcoin</numerusform><numerusform>%n conexiones activas hacia la red Bitcoin</numerusform></translation>
+ </message>
+ <message>
+ <source>No block source available...</source>
+ <translation>Ninguna fuente de bloques disponible ...</translation>
+ </message>
+ <message numerus="yes">
+ <source>Processed %n block(s) of transaction history.</source>
+ <translation><numerusform>%n bloque procesado del historial de transacciones.</numerusform><numerusform>%n bloques procesados del historial de transacciones.</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n hour(s)</source>
+ <translation><numerusform>%n hora</numerusform><numerusform>%n horas</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n day(s)</source>
+ <translation><numerusform>%n día</numerusform><numerusform>%n días</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n week(s)</source>
+ <translation><numerusform>%n semana</numerusform><numerusform>%n semanas</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 and %2</source>
+ <translation>%1 y %2</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n year(s)</source>
+ <translation><numerusform>%n año</numerusform><numerusform>%n años</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 behind</source>
+ <translation>%1 atrás</translation>
+ </message>
+ <message>
+ <source>Last received block was generated %1 ago.</source>
+ <translation>El último bloque recibido fue generado hace %1.</translation>
+ </message>
+ <message>
+ <source>Transactions after this will not yet be visible.</source>
+ <translation>Las transacciones posteriores aún no están visibles.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Error</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Aviso</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Información</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>Actualizado</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>Actualizando...</translation>
+ </message>
+ <message>
+ <source>Date: %1
+</source>
+ <translation>Fecha: %1
+</translation>
+ </message>
+ <message>
+ <source>Amount: %1
+</source>
+ <translation>Amount: %1
+</translation>
+ </message>
+ <message>
+ <source>Type: %1
+</source>
+ <translation>Tipo: %1
+</translation>
+ </message>
+ <message>
+ <source>Label: %1
+</source>
+ <translation>Etiqueta: %1
+</translation>
+ </message>
+ <message>
+ <source>Address: %1
+</source>
+ <translation>Dirección: %1
+</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>Transacción enviada</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>Transacción entrante</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>El monedero está &lt;b&gt;cifrado&lt;/b&gt; y actualmente &lt;b&gt;desbloqueado&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>El monedero está &lt;b&gt;cifrado&lt;/b&gt; y actualmente &lt;b&gt;bloqueado&lt;/b&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <source>Network Alert</source>
+ <translation>Alerta de red</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Coin Selection</source>
+ <translation>Selección de la moneda</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Cantidad:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Bytes:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Cuantía:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Prioridad:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Tasa:</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Polvo:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Después de aplicar la comisión:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Cambio:</translation>
+ </message>
+ <message>
+ <source>(un)select all</source>
+ <translation>(des)marcar todos</translation>
+ </message>
+ <message>
+ <source>Tree mode</source>
+ <translation>Modo árbol</translation>
+ </message>
+ <message>
+ <source>List mode</source>
+ <translation>Modo lista</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Cantidad</translation>
+ </message>
+ <message>
+ <source>Received with label</source>
+ <translation>Recibido con etiqueta</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>Recibido con dirección</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Fecha</translation>
+ </message>
+ <message>
+ <source>Confirmations</source>
+ <translation>Confirmaciones</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Confirmado</translation>
+ </message>
+ <message>
+ <source>Priority</source>
+ <translation>Prioridad</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Copiar dirección</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Copiar etiqueta</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copiar cuantía</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Copiar identificador de transacción</translation>
+ </message>
+ <message>
+ <source>Lock unspent</source>
+ <translation>Bloquear lo no gastado</translation>
+ </message>
+ <message>
+ <source>Unlock unspent</source>
+ <translation>Desbloquear lo no gastado</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Copiar cantidad</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Copiar comisión</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Copiar después de aplicar comisión</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Copiar bytes</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Copiar prioridad</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Copiar polvo</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Copiar cambio</translation>
+ </message>
+ <message>
+ <source>highest</source>
+ <translation>lo más alto</translation>
+ </message>
+ <message>
+ <source>higher</source>
+ <translation>más alto</translation>
+ </message>
+ <message>
+ <source>high</source>
+ <translation>alto</translation>
+ </message>
+ <message>
+ <source>medium-high</source>
+ <translation>medio-alto</translation>
+ </message>
+ <message>
+ <source>medium</source>
+ <translation>medio</translation>
+ </message>
+ <message>
+ <source>low-medium</source>
+ <translation>bajo-medio</translation>
+ </message>
+ <message>
+ <source>low</source>
+ <translation>bajo</translation>
+ </message>
+ <message>
+ <source>lower</source>
+ <translation>más bajo</translation>
+ </message>
+ <message>
+ <source>lowest</source>
+ <translation>lo más bajo</translation>
+ </message>
+ <message>
+ <source>(%1 locked)</source>
+ <translation>(%1 bloqueado)</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>ninguna</translation>
+ </message>
+ <message>
+ <source>This label turns red if the transaction size is greater than 1000 bytes.</source>
+ <translation>Esta etiqueta se mostrará en rojo si el tamaño de la transacción es mayor de 1000 bytes.</translation>
+ </message>
+ <message>
+ <source>This label turns red if the priority is smaller than "medium".</source>
+ <translation>Esta etiqueta se mostrará en rojo si la prioridad es menor a "media"</translation>
+ </message>
+ <message>
+ <source>This label turns red if any recipient receives an amount smaller than %1.</source>
+ <translation>Esta etiqueta se vuelve roja si el cambio es menor que %1</translation>
+ </message>
+ <message>
+ <source>Can vary +/- %1 satoshi(s) per input.</source>
+ <translation>Puede variar en +/- %1 satoshi(s) por entrada.</translation>
+ </message>
+ <message>
+ <source>yes</source>
+ <translation>si</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>no</translation>
+ </message>
+ <message>
+ <source>This means a fee of at least %1 per kB is required.</source>
+ <translation>Esto implica que se requiere una comisión de al menos %1 por kB</translation>
+ </message>
+ <message>
+ <source>Can vary +/- 1 byte per input.</source>
+ <translation>Puede variar en +/- 1 byte por entrada.</translation>
+ </message>
+ <message>
+ <source>Transactions with higher priority are more likely to get included into a block.</source>
+ <translation>Las transacciones con mayor prioridad tienen mayor probabilidad de ser incluidas en un bloque.</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(sin etiqueta)</translation>
+ </message>
+ <message>
+ <source>change from %1 (%2)</source>
+ <translation>Cambio desde %1 (%2)</translation>
+ </message>
+ <message>
+ <source>(change)</source>
+ <translation>(cambio)</translation>
+ </message>
+</context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>Editar Dirección</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>&amp;Etiqueta</translation>
+ </message>
+ <message>
+ <source>The label associated with this address list entry</source>
+ <translation>La etiqueta asociada con esta entrada de la lista de direcciones</translation>
+ </message>
+ <message>
+ <source>The address associated with this address list entry. This can only be modified for sending addresses.</source>
+ <translation>La dirección asociada con esta entrada de la lista de direcciones. Solo puede ser modificada para direcciones de envío.</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;Dirección</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>Nueva dirección de recepción</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>Nueva dirección de envío</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>Editar dirección de recepción</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>Editar dirección de envío</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>La dirección introducida "%1" ya está presente en la libreta de direcciones.</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is not a valid Bitcoin address.</source>
+ <translation>La dirección introducida "%1" no es una dirección Bitcoin válida.</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>No se pudo desbloquear el monedero.</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>Ha fallado la generación de la nueva clave.</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ <message>
+ <source>A new data directory will be created.</source>
+ <translation>Se creará un nuevo directorio de datos.</translation>
+ </message>
+ <message>
+ <source>name</source>
+ <translation>nombre</translation>
+ </message>
+ <message>
+ <source>Directory already exists. Add %1 if you intend to create a new directory here.</source>
+ <translation>El directorio ya existe. Añada %1 si pretende crear aquí un directorio nuevo.</translation>
+ </message>
+ <message>
+ <source>Path already exists, and is not a directory.</source>
+ <translation>La ruta ya existe y no es un directorio.</translation>
+ </message>
+ <message>
+ <source>Cannot create data directory here.</source>
+ <translation>No se puede crear un directorio de datos aquí.</translation>
+ </message>
+</context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>versión</translation>
+ </message>
+ <message>
+ <source>(%1-bit)</source>
+ <translation>(%1-bit)</translation>
+ </message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>Acerca de Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Command-line options</source>
+ <translation>Opciones de la línea de órdenes</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>Uso:</translation>
+ </message>
+ <message>
+ <source>command-line options</source>
+ <translation>opciones de la consola de comandos</translation>
+ </message>
+</context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Welcome</source>
+ <translation>Bienvenido</translation>
+ </message>
+ <message>
+ <source>Welcome to Bitcoin Core.</source>
+ <translation>Bienvenido a Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</source>
+ <translation>Al ser la primera vez que se ejecuta el programa, puede elegir dónde almacenará sus datos Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory.</source>
+ <translation>Bitcoin Core va a descargar y guardar una copia de la cadena de bloques de Bitcoin. Se almacenará al menos %1GB de datos en este directorio, que irá creciendo con el tiempo. El monedero se guardará también en este directorio.</translation>
+ </message>
+ <message>
+ <source>Use the default data directory</source>
+ <translation>Utilizar el directorio de datos predeterminado</translation>
+ </message>
+ <message>
+ <source>Use a custom data directory:</source>
+ <translation>Utilizar un directorio de datos personalizado:</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Error: Specified data directory "%1" cannot be created.</source>
+ <translation>Error: no ha podido crearse el directorio de datos especificado "%1".</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Error</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n GB of free space available</source>
+ <translation><numerusform>%n GB de espacio libre</numerusform><numerusform>%n GB de espacio disponible</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>(of %n GB needed)</source>
+ <translation><numerusform>(de %n GB necesitados)</numerusform><numerusform>(de %n GB requeridos)</numerusform></translation>
+ </message>
+</context>
+<context>
+ <name>OpenURIDialog</name>
+ <message>
+ <source>Open URI</source>
+ <translation>Abrir URI...</translation>
+ </message>
+ <message>
+ <source>Open payment request from URI or file</source>
+ <translation>Abrir solicitud de pago a partir de un identificador URI o de un archivo</translation>
+ </message>
+ <message>
+ <source>URI:</source>
+ <translation>URI:</translation>
+ </message>
+ <message>
+ <source>Select payment request file</source>
+ <translation>Seleccionar archivo de sulicitud de pago</translation>
+ </message>
+ <message>
+ <source>Select payment request file to open</source>
+ <translation>Seleccionar el archivo de solicitud de pago para abrir</translation>
+ </message>
+</context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>Opciones</translation>
+ </message>
+ <message>
+ <source>&amp;Main</source>
+ <translation>&amp;Principal</translation>
+ </message>
+ <message>
+ <source>Size of &amp;database cache</source>
+ <translation>Tamaño de cache de la &amp;base de datos</translation>
+ </message>
+ <message>
+ <source>MB</source>
+ <translation>MB</translation>
+ </message>
+ <message>
+ <source>Number of script &amp;verification threads</source>
+ <translation>Número de hilos de &amp;verificación de scripts</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside</source>
+ <translation>Aceptar conexiones desde el exterior</translation>
+ </message>
+ <message>
+ <source>Allow incoming connections</source>
+ <translation>Aceptar conexiones entrantes</translation>
+ </message>
+ <message>
+ <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
+ <translation>Dirección IP del proxy (p. ej. IPv4: 127.0.0.1 / IPv6: ::1)</translation>
+ </message>
+ <message>
+ <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source>
+ <translation>Minimizar en lugar de salir de la aplicación cuando la ventana está cerrada. Cuando se activa esta opción, la aplicación sólo se cerrará después de seleccionar Salir en el menú.</translation>
+ </message>
+ <message>
+ <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source>
+ <translation>El idioma de la interfaz de usuario puede establecerse aquí. Este ajuste se aplicará cuando se reinicie Bitcoin.</translation>
+ </message>
+ <message>
+ <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source>
+ <translation>Identificadores URL de terceros (por ejemplo, un explorador de bloques) que aparecen en la pestaña de transacciones como elementos del menú contextual. El %s en la URL es reemplazado por el valor hash de la transacción. Se pueden separar URL múltiples por una barra vertical |.</translation>
+ </message>
+ <message>
+ <source>Third party transaction URLs</source>
+ <translation>Identificadores URL de transacciones de terceros</translation>
+ </message>
+ <message>
+ <source>Active command-line options that override above options:</source>
+ <translation>Opciones activas de consola de comandos que tienen preferencia sobre las opciones anteriores:</translation>
+ </message>
+ <message>
+ <source>Reset all client options to default.</source>
+ <translation>Restablecer todas las opciones predeterminadas del cliente.</translation>
+ </message>
+ <message>
+ <source>&amp;Reset Options</source>
+ <translation>&amp;Restablecer opciones</translation>
+ </message>
+ <message>
+ <source>&amp;Network</source>
+ <translation>&amp;Red</translation>
+ </message>
+ <message>
+ <source>Automatically start Bitcoin Core after logging in to the system.</source>
+ <translation>Iniciar automáticamente Bitcoin Core al iniciar el sistema.</translation>
+ </message>
+ <message>
+ <source>&amp;Start Bitcoin Core on system login</source>
+ <translation>&amp;Iniciar Bitcoin Core al inicio del sistema</translation>
+ </message>
+ <message>
+ <source>(0 = auto, &lt;0 = leave that many cores free)</source>
+ <translation>(0 = automático, &lt;0 = dejar libres ese número de núcleos)</translation>
+ </message>
+ <message>
+ <source>W&amp;allet</source>
+ <translation>&amp;Monedero</translation>
+ </message>
+ <message>
+ <source>Expert</source>
+ <translation>Experto</translation>
+ </message>
+ <message>
+ <source>Enable coin &amp;control features</source>
+ <translation>Habilitar funcionalidad de &amp;coin control</translation>
+ </message>
+ <message>
+ <source>If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.</source>
+ <translation>Si desactiva el gasto del cambio no confirmado, no se podrá usar el cambio de una transacción hasta que se alcance al menos una confirmación. Esto afecta también a cómo se calcula su saldo.</translation>
+ </message>
+ <message>
+ <source>&amp;Spend unconfirmed change</source>
+ <translation>&amp;Gastar cambio no confirmado</translation>
+ </message>
+ <message>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>Abrir automáticamente el puerto del cliente Bitcoin en el router. Esta opción solo funciona si el router admite UPnP y está activado.</translation>
+ </message>
+ <message>
+ <source>Map port using &amp;UPnP</source>
+ <translation>Mapear el puerto mediante &amp;UPnP</translation>
+ </message>
+ <message>
+ <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
+ <translation>Conectarse a la red Bitcoin a través de un proxy SOCKS5.</translation>
+ </message>
+ <message>
+ <source>&amp;Connect through SOCKS5 proxy (default proxy):</source>
+ <translation>&amp;Conectarse a través de proxy SOCKS5 (proxy predeterminado):</translation>
+ </message>
+ <message>
+ <source>Proxy &amp;IP:</source>
+ <translation>Dirección &amp;IP del proxy:</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>&amp;Puerto:</translation>
+ </message>
+ <message>
+ <source>Port of the proxy (e.g. 9050)</source>
+ <translation>Puerto del servidor proxy (ej. 9050)</translation>
+ </message>
+ <message>
+ <source>&amp;Window</source>
+ <translation>&amp;Ventana</translation>
+ </message>
+ <message>
+ <source>Show only a tray icon after minimizing the window.</source>
+ <translation>Minimizar la ventana a la bandeja de iconos del sistema.</translation>
+ </message>
+ <message>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>&amp;Minimizar a la bandeja en vez de a la barra de tareas</translation>
+ </message>
+ <message>
+ <source>M&amp;inimize on close</source>
+ <translation>M&amp;inimizar al cerrar</translation>
+ </message>
+ <message>
+ <source>&amp;Display</source>
+ <translation>&amp;Interfaz</translation>
+ </message>
+ <message>
+ <source>User Interface &amp;language:</source>
+ <translation>I&amp;dioma de la interfaz de usuario</translation>
+ </message>
+ <message>
+ <source>&amp;Unit to show amounts in:</source>
+ <translation>Mostrar las cantidades en la &amp;unidad:</translation>
+ </message>
+ <message>
+ <source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
+ <translation>Elegir la subdivisión predeterminada para mostrar cantidades en la interfaz y cuando se envían bitcoins.</translation>
+ </message>
+ <message>
+ <source>Whether to show coin control features or not.</source>
+ <translation>Mostrar o no funcionalidad de Coin Control</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>&amp;Aceptar</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>&amp;Cancelar</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>predeterminado</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>ninguna</translation>
+ </message>
+ <message>
+ <source>Confirm options reset</source>
+ <translation>Confirme el restablecimiento de las opciones</translation>
+ </message>
+ <message>
+ <source>Client restart required to activate changes.</source>
+ <translation>Se necesita reiniciar el cliente para activar los cambios.</translation>
+ </message>
+ <message>
+ <source>Client will be shut down. Do you want to proceed?</source>
+ <translation>El cliente se cerrará. ¿Desea continuar?</translation>
+ </message>
+ <message>
+ <source>This change would require a client restart.</source>
+ <translation>Este cambio exige el reinicio del cliente.</translation>
+ </message>
+ <message>
+ <source>The supplied proxy address is invalid.</source>
+ <translation>La dirección proxy indicada es inválida.</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>Formulario</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>La información mostrada puede estar desactualizada. Su monedero se sincroniza automáticamente con la red Bitcoin después de que se haya establecido una conexión, pero este proceso aún no se ha completado.</translation>
+ </message>
+ <message>
+ <source>Watch-only:</source>
+ <translation>De observación:</translation>
+ </message>
+ <message>
+ <source>Available:</source>
+ <translation>Disponible:</translation>
+ </message>
+ <message>
+ <source>Your current spendable balance</source>
+ <translation>Su saldo disponible actual</translation>
+ </message>
+ <message>
+ <source>Pending:</source>
+ <translation>Pendiente:</translation>
+ </message>
+ <message>
+ <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source>
+ <translation>Total de transacciones pendientes de confirmar y que aún no contribuye al saldo disponible</translation>
+ </message>
+ <message>
+ <source>Immature:</source>
+ <translation>No madurado:</translation>
+ </message>
+ <message>
+ <source>Mined balance that has not yet matured</source>
+ <translation>Saldo recién minado que aún no ha madurado.</translation>
+ </message>
+ <message>
+ <source>Balances</source>
+ <translation>Saldos</translation>
+ </message>
+ <message>
+ <source>Total:</source>
+ <translation>Total:</translation>
+ </message>
+ <message>
+ <source>Your current total balance</source>
+ <translation>Su saldo actual total</translation>
+ </message>
+ <message>
+ <source>Your current balance in watch-only addresses</source>
+ <translation>Su saldo actual en direcciones watch-only</translation>
+ </message>
+ <message>
+ <source>Spendable:</source>
+ <translation>Gastable:</translation>
+ </message>
+ <message>
+ <source>Recent transactions</source>
+ <translation>Transacciones recientes</translation>
+ </message>
+ <message>
+ <source>Unconfirmed transactions to watch-only addresses</source>
+ <translation>Transacciones sin confirmar en direcciones watch-only</translation>
+ </message>
+ <message>
+ <source>Mined balance in watch-only addresses that has not yet matured</source>
+ <translation>Saldo minado en direcciones watch-only que aún no ha madurado</translation>
+ </message>
+ <message>
+ <source>Current total balance in watch-only addresses</source>
+ <translation>Saldo total en las direcciones watch-only</translation>
+ </message>
+</context>
+<context>
+ <name>PaymentServer</name>
+ <message>
+ <source>URI handling</source>
+ <translation>Gestión de URI</translation>
+ </message>
+ <message>
+ <source>Invalid payment address %1</source>
+ <translation>Dirección de pago no válida %1</translation>
+ </message>
+ <message>
+ <source>Payment request rejected</source>
+ <translation>Solicitud de pago rechazada</translation>
+ </message>
+ <message>
+ <source>Payment request network doesn't match client network.</source>
+ <translation>La red de solicitud de pago no coincide con la red cliente</translation>
+ </message>
+ <message>
+ <source>Payment request is not initialized.</source>
+ <translation>La solicitud de pago no está inicializada</translation>
+ </message>
+ <message>
+ <source>Requested payment amount of %1 is too small (considered dust).</source>
+ <translation>La cantidad del pago solicitado (%1) es demasiado pequeña (considerada polvo).</translation>
+ </message>
+ <message>
+ <source>Payment request error</source>
+ <translation>Error en solicitud de pago</translation>
+ </message>
+ <message>
+ <source>Cannot start bitcoin: click-to-pay handler</source>
+ <translation>No se puede iniciar el gestor de identificadores "bitcoin:" de clic-para-pagar</translation>
+ </message>
+ <message>
+ <source>Payment request fetch URL is invalid: %1</source>
+ <translation>La URL de obtención de la solicitud de pago es inválida: %1</translation>
+ </message>
+ <message>
+ <source>URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source>
+ <translation>¡No se puede leer el identificador URI! Esto puede deberse a una dirección Bitcoin inválida o a parámetros de la URI mal formados</translation>
+ </message>
+ <message>
+ <source>Payment request file handling</source>
+ <translation>Procesado del archivo de solicitud de pago</translation>
+ </message>
+ <message>
+ <source>Payment request file cannot be read! This can be caused by an invalid payment request file.</source>
+ <translation>¡No puede leerse el archivo de solicitud de pago! Esto puede deberse a un archivo inválido de solicitud de pago.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>Solicitud de pago caducada.</translation>
+ </message>
+ <message>
+ <source>Unverified payment requests to custom payment scripts are unsupported.</source>
+ <translation>No están soportadas las peticiones inseguras a scripts de pago personalizados</translation>
+ </message>
+ <message>
+ <source>Invalid payment request.</source>
+ <translation>Petición de pago no válida.</translation>
+ </message>
+ <message>
+ <source>Refund from %1</source>
+ <translation>Devolución desde %1</translation>
+ </message>
+ <message>
+ <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source>
+ <translation>La petición de pago %1 es demasiado grande (%2 bytes, permitidos %3 bytes).</translation>
+ </message>
+ <message>
+ <source>Payment request DoS protection</source>
+ <translation> Solicitud pago de protección DoS</translation>
+ </message>
+ <message>
+ <source>Error communicating with %1: %2</source>
+ <translation>Error en la comunicación con %1: %2</translation>
+ </message>
+ <message>
+ <source>Payment request cannot be parsed!</source>
+ <translation>¡No puede leerse la solicitud de pago!</translation>
+ </message>
+ <message>
+ <source>Bad response from server %1</source>
+ <translation>Respuesta errónea del servidor %1</translation>
+ </message>
+ <message>
+ <source>Payment acknowledged</source>
+ <translation>Pago aceptado</translation>
+ </message>
+ <message>
+ <source>Network request error</source>
+ <translation>Error en petición de red</translation>
+ </message>
+</context>
+<context>
+ <name>PeerTableModel</name>
+ <message>
+ <source>User Agent</source>
+ <translation>User Agent</translation>
+ </message>
+ <message>
+ <source>Node/Service</source>
+ <translation>Nodo/Servicio</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Ping</translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>Cantidad</translation>
+ </message>
+ <message>
+ <source>Enter a Bitcoin address (e.g. %1)</source>
+ <translation>Introducir una dirección Bitcoin (p. ej. %1)</translation>
+ </message>
+ <message>
+ <source>%1 d</source>
+ <translation>%1 d</translation>
+ </message>
+ <message>
+ <source>%1 h</source>
+ <translation>%1 h</translation>
+ </message>
+ <message>
+ <source>%1 m</source>
+ <translation>%1 m</translation>
+ </message>
+ <message>
+ <source>%1 s</source>
+ <translation>%1 s</translation>
+ </message>
+ <message>
+ <source>None</source>
+ <translation>Ninguno</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>N/D</translation>
+ </message>
+ <message>
+ <source>%1 ms</source>
+ <translation>%1 ms</translation>
+ </message>
+</context>
+<context>
+ <name>QRImageWidget</name>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>Guardar Imagen...</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Image</source>
+ <translation>Copiar imagen</translation>
+ </message>
+ <message>
+ <source>Save QR Code</source>
+ <translation>Guardar código QR</translation>
+ </message>
+ <message>
+ <source>PNG Image (*.png)</source>
+ <translation>Imágenes PNG (*.png)</translation>
+ </message>
+</context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>Client name</source>
+ <translation>Nombre del cliente</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>N/D</translation>
+ </message>
+ <message>
+ <source>Client version</source>
+ <translation>Versión del cliente</translation>
+ </message>
+ <message>
+ <source>&amp;Information</source>
+ <translation>&amp;Información</translation>
+ </message>
+ <message>
+ <source>Debug window</source>
+ <translation>Ventana de depuración</translation>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>General</translation>
+ </message>
+ <message>
+ <source>Using OpenSSL version</source>
+ <translation>Utilizando la versión de OpenSSL</translation>
+ </message>
+ <message>
+ <source>Using BerkeleyDB version</source>
+ <translation>Utilizando la versión de BerkeleyDB</translation>
+ </message>
+ <message>
+ <source>Startup time</source>
+ <translation>Hora de inicio</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Red</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>Nombre</translation>
+ </message>
+ <message>
+ <source>Number of connections</source>
+ <translation>Número de conexiones</translation>
+ </message>
+ <message>
+ <source>Block chain</source>
+ <translation>Cadena de bloques</translation>
+ </message>
+ <message>
+ <source>Current number of blocks</source>
+ <translation>Número actual de bloques</translation>
+ </message>
+ <message>
+ <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source>
+ <translation>Abre el archivo de registro de depuración de Bitcoin desde el directorio de datos actual. Esto puede tardar unos segundos para ficheros de registro de gran tamaño.</translation>
+ </message>
+ <message>
+ <source>Received</source>
+ <translation>Recibido</translation>
+ </message>
+ <message>
+ <source>Sent</source>
+ <translation>Enviado</translation>
+ </message>
+ <message>
+ <source>&amp;Peers</source>
+ <translation>&amp;Pares</translation>
+ </message>
+ <message>
+ <source>Select a peer to view detailed information.</source>
+ <translation>Seleccionar un par para ver su información detallada.</translation>
+ </message>
+ <message>
+ <source>Direction</source>
+ <translation>Dirección</translation>
+ </message>
+ <message>
+ <source>Version</source>
+ <translation>Versión</translation>
+ </message>
+ <message>
+ <source>User Agent</source>
+ <translation>User Agent</translation>
+ </message>
+ <message>
+ <source>Services</source>
+ <translation>Servicios</translation>
+ </message>
+ <message>
+ <source>Starting Height</source>
+ <translation>Altura de comienzo</translation>
+ </message>
+ <message>
+ <source>Sync Height</source>
+ <translation>Altura de sincronización</translation>
+ </message>
+ <message>
+ <source>Ban Score</source>
+ <translation>Puntuación de bloqueo</translation>
+ </message>
+ <message>
+ <source>Connection Time</source>
+ <translation>Duración de la conexión</translation>
+ </message>
+ <message>
+ <source>Last Send</source>
+ <translation>Ultimo envío</translation>
+ </message>
+ <message>
+ <source>Last Receive</source>
+ <translation>Ultima recepción</translation>
+ </message>
+ <message>
+ <source>Bytes Sent</source>
+ <translation>Bytes enviados</translation>
+ </message>
+ <message>
+ <source>Bytes Received</source>
+ <translation>Bytes recibidos</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Ping</translation>
+ </message>
+ <message>
+ <source>Time Offset</source>
+ <translation>Desplazamiento de tiempo</translation>
+ </message>
+ <message>
+ <source>Last block time</source>
+ <translation>Hora del último bloque</translation>
+ </message>
+ <message>
+ <source>&amp;Open</source>
+ <translation>&amp;Abrir</translation>
+ </message>
+ <message>
+ <source>&amp;Console</source>
+ <translation>&amp;Consola</translation>
+ </message>
+ <message>
+ <source>&amp;Network Traffic</source>
+ <translation>&amp;Tráfico de Red</translation>
+ </message>
+ <message>
+ <source>&amp;Clear</source>
+ <translation>&amp;Vaciar</translation>
+ </message>
+ <message>
+ <source>Totals</source>
+ <translation>Total:</translation>
+ </message>
+ <message>
+ <source>In:</source>
+ <translation>Entrante:</translation>
+ </message>
+ <message>
+ <source>Out:</source>
+ <translation>Saliente:</translation>
+ </message>
+ <message>
+ <source>Build date</source>
+ <translation>Fecha de compilación</translation>
+ </message>
+ <message>
+ <source>Debug log file</source>
+ <translation>Archivo de registro de depuración</translation>
+ </message>
+ <message>
+ <source>Clear console</source>
+ <translation>Borrar consola</translation>
+ </message>
+ <message>
+ <source>Welcome to the Bitcoin Core RPC console.</source>
+ <translation>Bienvenido a la consola RPC de Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
+ <translation>Use las flechas arriba y abajo para navegar por el historial y &lt;b&gt;Control+L&lt;/b&gt; para vaciar la pantalla.</translation>
+ </message>
+ <message>
+ <source>Type &lt;b&gt;help&lt;/b&gt; for an overview of available commands.</source>
+ <translation>Escriba &lt;b&gt;help&lt;/b&gt; para ver un resumen de los comandos disponibles.</translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation>%1 B</translation>
+ </message>
+ <message>
+ <source>%1 KB</source>
+ <translation>%1 KB</translation>
+ </message>
+ <message>
+ <source>%1 MB</source>
+ <translation>%1 MB</translation>
+ </message>
+ <message>
+ <source>%1 GB</source>
+ <translation>%1 GB</translation>
+ </message>
+ <message>
+ <source>via %1</source>
+ <translation>via %1</translation>
+ </message>
+ <message>
+ <source>never</source>
+ <translation>nunca</translation>
+ </message>
+ <message>
+ <source>Inbound</source>
+ <translation>Entrante</translation>
+ </message>
+ <message>
+ <source>Outbound</source>
+ <translation>Saliente</translation>
+ </message>
+ <message>
+ <source>Unknown</source>
+ <translation>Desconocido</translation>
+ </message>
+ <message>
+ <source>Fetching...</source>
+ <translation>Adquiriendo....</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Amount:</source>
+ <translation>Cantidad</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Etiqueta:</translation>
+ </message>
+ <message>
+ <source>&amp;Message:</source>
+ <translation>Mensaje:</translation>
+ </message>
+ <message>
+ <source>Reuse one of the previously used receiving addresses. Reusing addresses has security and privacy issues. Do not use this unless re-generating a payment request made before.</source>
+ <translation>Reutilizar una de las direcciones previamente usadas para recibir. Reutilizar direcciones tiene problemas de seguridad y privacidad. No lo uses a menos que antes regeneres una solicitud de pago.</translation>
+ </message>
+ <message>
+ <source>R&amp;euse an existing receiving address (not recommended)</source>
+ <translation>R&amp;eutilizar una dirección existente para recibir (no recomendado)</translation>
+ </message>
+ <message>
+ <source>An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network.</source>
+ <translation>Un mensaje opcional para adjuntar a la solicitud de pago, que se muestra cuando se abre la solicitud. Nota: El mensaje no se enviará con el pago por la red Bitcoin.</translation>
+ </message>
+ <message>
+ <source>An optional label to associate with the new receiving address.</source>
+ <translation>Etiqueta opcional para asociar con la nueva dirección de recepción.</translation>
+ </message>
+ <message>
+ <source>Use this form to request payments. All fields are &lt;b&gt;optional&lt;/b&gt;.</source>
+ <translation>Utilice este formulario para solicitar pagos. Todos los campos son &lt;b&gt;opcionales&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>An optional amount to request. Leave this empty or zero to not request a specific amount.</source>
+ <translation>Para solicitar una cantidad opcional. Deje este vacío o cero para no solicitar una cantidad específica.</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Vaciar todos los campos del formulario.</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation>Vaciar</translation>
+ </message>
+ <message>
+ <source>Requested payments history</source>
+ <translation>Historial de pagos solicitados</translation>
+ </message>
+ <message>
+ <source>&amp;Request payment</source>
+ <translation>&amp;Solicitar pago</translation>
+ </message>
+ <message>
+ <source>Show the selected request (does the same as double clicking an entry)</source>
+ <translation>Muestra la petición seleccionada (También doble clic)</translation>
+ </message>
+ <message>
+ <source>Show</source>
+ <translation>Mostrar</translation>
+ </message>
+ <message>
+ <source>Remove the selected entries from the list</source>
+ <translation>Borrar de la lista las direcciónes actualmente seleccionadas</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>Eliminar</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Copiar etiqueta</translation>
+ </message>
+ <message>
+ <source>Copy message</source>
+ <translation>Mensaje</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copiar cuantía</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>QR Code</source>
+ <translation>Código QR</translation>
+ </message>
+ <message>
+ <source>Copy &amp;URI</source>
+ <translation>Copiar &amp;URI</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Address</source>
+ <translation>Copiar &amp;Dirección</translation>
+ </message>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>Guardar Imagen...</translation>
+ </message>
+ <message>
+ <source>Request payment to %1</source>
+ <translation>Solicitar pago a %1</translation>
+ </message>
+ <message>
+ <source>Payment information</source>
+ <translation>Información de pago</translation>
+ </message>
+ <message>
+ <source>URI</source>
+ <translation>URI</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Dirección</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Cantidad</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiqueta</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Mensaje</translation>
+ </message>
+ <message>
+ <source>Resulting URI too long, try to reduce the text for label / message.</source>
+ <translation>URI resultante demasiado larga. Intente reducir el texto de la etiqueta / mensaje.</translation>
+ </message>
+ <message>
+ <source>Error encoding URI into QR Code.</source>
+ <translation>Error al codificar la URI en el código QR.</translation>
+ </message>
+</context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Fecha</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiqueta</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Mensaje</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Cantidad</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(sin etiqueta)</translation>
+ </message>
+ <message>
+ <source>(no message)</source>
+ <translation>(Ningun mensaje)</translation>
+ </message>
+ <message>
+ <source>(no amount)</source>
+ <translation>(sin cantidad)</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Enviar bitcoins</translation>
+ </message>
+ <message>
+ <source>Coin Control Features</source>
+ <translation>Características de Coin Control</translation>
+ </message>
+ <message>
+ <source>Inputs...</source>
+ <translation>Entradas...</translation>
+ </message>
+ <message>
+ <source>automatically selected</source>
+ <translation>Seleccionado automáticamente</translation>
+ </message>
+ <message>
+ <source>Insufficient funds!</source>
+ <translation>Fondos insuficientes!</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Cantidad:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Bytes:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Cuantía:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Prioridad:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Tasa:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Después de tasas:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Cambio:</translation>
+ </message>
+ <message>
+ <source>If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address.</source>
+ <translation>Si se marca esta opción pero la dirección de cambio está vacía o es inválida, el cambio se enviará a una nueva dirección recién generada.</translation>
+ </message>
+ <message>
+ <source>Custom change address</source>
+ <translation>Dirección propia</translation>
+ </message>
+ <message>
+ <source>Transaction Fee:</source>
+ <translation>Comisión de Transacción:</translation>
+ </message>
+ <message>
+ <source>Choose...</source>
+ <translation>Elija...</translation>
+ </message>
+ <message>
+ <source>collapse fee-settings</source>
+ <translation>Colapsar ajustes de cuota</translation>
+ </message>
+ <message>
+ <source>per kilobyte</source>
+ <translation>por kilobyte</translation>
+ </message>
+ <message>
+ <source>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "total at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source>
+ <translation>Si la tarifa de aduana se establece en 1000 satoshis y la transacción está a sólo 250 bytes, entonces "por kilobyte" sólo paga 250 satoshis de cuota, mientras que "el mínimo total" pagaría 1.000 satoshis. Para las transacciones más grandes que un kilobyte ambos pagan por kilobyte</translation>
+ </message>
+ <message>
+ <source>Hide</source>
+ <translation>Ocultar</translation>
+ </message>
+ <message>
+ <source>total at least</source>
+ <translation>total por lo menos</translation>
+ </message>
+ <message>
+ <source>Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process.</source>
+ <translation>Pagando solamente la cuota mínima es correcto, siempre y cuando haya menos volumen de transacciones que el espacio en los bloques. Pero tenga en cuenta que esto puede terminar en una transacción nunca confirmada, una vez que haya más demanda para transacciones Bitcoin que la red pueda procesar.</translation>
+ </message>
+ <message>
+ <source>(read the tooltip)</source>
+ <translation>(leer la sugerencia)</translation>
+ </message>
+ <message>
+ <source>Recommended:</source>
+ <translation>Recomendado:</translation>
+ </message>
+ <message>
+ <source>Custom:</source>
+ <translation>Personalizado:</translation>
+ </message>
+ <message>
+ <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source>
+ <translation>(Tarifa inteligente no inicializado aún. Esto generalmente lleva a pocos bloques...)</translation>
+ </message>
+ <message>
+ <source>Confirmation time:</source>
+ <translation>Tiempo de confirmación:</translation>
+ </message>
+ <message>
+ <source>normal</source>
+ <translation>normal</translation>
+ </message>
+ <message>
+ <source>fast</source>
+ <translation>rápido</translation>
+ </message>
+ <message>
+ <source>Send as zero-fee transaction if possible</source>
+ <translation>Enviar transacción, si es posible, sin comisión</translation>
+ </message>
+ <message>
+ <source>(confirmation may take longer)</source>
+ <translation>(confirmación puede tardar más tiempo)</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>Enviar a múltiples destinatarios de una vez</translation>
+ </message>
+ <message>
+ <source>Add &amp;Recipient</source>
+ <translation>Añadir &amp;destinatario</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Vaciar todos los campos del formulario</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Polvo:</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Vaciar &amp;todo</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>Saldo:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>Confirmar el envío</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>&amp;Enviar</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>Confirmar el envío de bitcoins</translation>
+ </message>
+ <message>
+ <source>%1 to %2</source>
+ <translation>%1 a %2</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Copiar cantidad</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copiar cuantía</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Copiar donación</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Copiar después de aplicar donación</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Copiar bytes</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Copiar prioridad</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Copiar Cambio</translation>
+ </message>
+ <message>
+ <source>or</source>
+ <translation>o</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>La cantidad por pagar tiene que ser mayor de 0.</translation>
+ </message>
+ <message>
+ <source>The amount exceeds your balance.</source>
+ <translation>La cantidad sobrepasa su saldo.</translation>
+ </message>
+ <message>
+ <source>The total exceeds your balance when the %1 transaction fee is included.</source>
+ <translation>El total sobrepasa su saldo cuando se incluye la tasa de envío de %1</translation>
+ </message>
+ <message>
+ <source>Transaction creation failed!</source>
+ <translation>¡Ha fallado la creación de la transacción!</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>¡La transacción fue rechazada! Esto puede haber ocurrido si alguno de los bitcoins de su monedero ya estaba gastado o si ha usado una copia de wallet.dat y los bitcoins estaban gastados en la copia pero no se habían marcado como gastados aqui.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>Solicitud de pago caducada.</translation>
+ </message>
+ <message numerus="yes">
+ <source>Estimated to begin confirmation within %n block(s).</source>
+ <translation><numerusform>Estimado para empezar la confirmación dentro de %n bloque.</numerusform><numerusform>Estimado para empezar la confirmación dentro de %n bloques.</numerusform></translation>
+ </message>
+ <message>
+ <source>Pay only the minimum fee of %1</source>
+ <translation>Paga sólo la cuota mínima de %1</translation>
+ </message>
+ <message>
+ <source>Total Amount %1&lt;span style='font-size:10pt;font-weight:normal;'&gt;&lt;br /&gt;(=%2)&lt;/span&gt;</source>
+ <translation>Monto Total %1&lt;span style='font-size:10pt;font-weight:normal;'&gt;&lt;br /&gt;(=%2)&lt;/span&gt;</translation>
+ </message>
+ <message>
+ <source>The recipient address is not valid. Please recheck.</source>
+ <translation>La dirección del destinatario no es válida. Por favor, compruébela de nuevo.</translation>
+ </message>
+ <message>
+ <source>Duplicate address found: addresses should only be used once each.</source>
+ <translation>Se ha encontrado una dirección duplicada. Solo se puede enviar a cada dirección una vez por operación de envío.</translation>
+ </message>
+ <message>
+ <source>Warning: Invalid Bitcoin address</source>
+ <translation>Alerta: Dirección de Bitcoin inválida</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(sin etiqueta)</translation>
+ </message>
+ <message>
+ <source>Warning: Unknown change address</source>
+ <translation>Alerta: Dirección de Bitcoin inválida</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Copiar polvo</translation>
+ </message>
+ <message>
+ <source>Are you sure you want to send?</source>
+ <translation>¿Está seguro que desea enviar?</translation>
+ </message>
+ <message>
+ <source>added as transaction fee</source>
+ <translation>añadido como comisión de transacción</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>Ca&amp;ntidad:</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>&amp;Pagar a:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Etiquete esta dirección para añadirla a la libreta</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Etiqueta:</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Escoger direcciones previamente usadas</translation>
+ </message>
+ <message>
+ <source>This is a normal payment.</source>
+ <translation>Esto es un pago ordinario.</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to send the payment to</source>
+ <translation>Dirección Bitcoin a la que enviar el pago</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Pegar dirección desde portapapeles</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Remove this entry</source>
+ <translation>Eliminar esta transacción</translation>
+ </message>
+ <message>
+ <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source>
+ <translation>La cuota será deducida de la cantidad que sea mandada. El destinatario recibirá menos bitcoins de los que entres en el </translation>
+ </message>
+ <message>
+ <source>S&amp;ubtract fee from amount</source>
+ <translation>Restar comisiones a la cantidad</translation>
+ </message>
+ <message>
+ <source>Message:</source>
+ <translation>Mensaje:</translation>
+ </message>
+ <message>
+ <source>This is an unauthenticated payment request.</source>
+ <translation>Esta es una petición de pago no autentificada.</translation>
+ </message>
+ <message>
+ <source>This is an authenticated payment request.</source>
+ <translation>Esta es una petición de pago autentificada.</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to the list of used addresses</source>
+ <translation>Introduce una etiqueta para esta dirección para añadirla a la lista de direcciones utilizadas</translation>
+ </message>
+ <message>
+ <source>A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network.</source>
+ <translation>Un mensaje que se adjuntó a la bitcoin: URL que será almacenada con la transacción para su referencia. Nota: Este mensaje no se envía a través de la red Bitcoin.</translation>
+ </message>
+ <message>
+ <source>Pay To:</source>
+ <translation>Paga a:</translation>
+ </message>
+ <message>
+ <source>Memo:</source>
+ <translation>Memo:</translation>
+ </message>
+</context>
+<context>
+ <name>ShutdownWindow</name>
+ <message>
+ <source>Bitcoin Core is shutting down...</source>
+ <translation>Bitcoin Core se está cerrando...</translation>
+ </message>
+ <message>
+ <source>Do not shut down the computer until this window disappears.</source>
+ <translation>No apague el equipo hasta que desaparezca esta ventana.</translation>
+ </message>
+</context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Signatures - Sign / Verify a Message</source>
+ <translation>Firmas - Firmar / verificar un mensaje</translation>
+ </message>
+ <message>
+ <source>&amp;Sign Message</source>
+ <translation>&amp;Firmar mensaje</translation>
+ </message>
+ <message>
+ <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source>
+ <translation>Puede firmar los mensajes con sus direcciones para demostrar que las posee. Tenga cuidado de no firmar cualquier cosa de manera vaga o aleatoria, pues los ataques de phishing pueden tratar de engañarle firmando su identidad a través de ellos. Sólo firme declaraciones totalmente detalladas con las que usted esté de acuerdo.</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to sign the message with</source>
+ <translation>Dirección Bitcoin con la que firmar el mensaje</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Escoger dirección previamente usada</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Pegar dirección desde portapapeles</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Enter the message you want to sign here</source>
+ <translation>Introduzca el mensaje que desea firmar aquí</translation>
+ </message>
+ <message>
+ <source>Signature</source>
+ <translation>Firma</translation>
+ </message>
+ <message>
+ <source>Copy the current signature to the system clipboard</source>
+ <translation>Copiar la firma actual al portapapeles del sistema</translation>
+ </message>
+ <message>
+ <source>Sign the message to prove you own this Bitcoin address</source>
+ <translation>Firmar el mensaje para demostrar que se posee esta dirección Bitcoin</translation>
+ </message>
+ <message>
+ <source>Sign &amp;Message</source>
+ <translation>Firmar &amp;mensaje</translation>
+ </message>
+ <message>
+ <source>Reset all sign message fields</source>
+ <translation>Vaciar todos los campos de la firma de mensaje</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Vaciar &amp;todo</translation>
+ </message>
+ <message>
+ <source>&amp;Verify Message</source>
+ <translation>&amp;Verificar mensaje</translation>
+ </message>
+ <message>
+ <source>Enter the receiver's 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. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source>
+ <translation>Introduzca la dirección para la firma, el mensaje (asegurándose de copiar tal cual los saltos de línea, espacios, tabulaciones, etc.) y la firma a continuación para verificar el mensaje. Tenga cuidado de no asumir más información de lo que dice el propio mensaje firmado para evitar fraudes basados en ataques de tipo man-in-the-middle. </translation>
+ </message>
+ <message>
+ <source>The Bitcoin address the message was signed with</source>
+ <translation>La dirección Bitcoin con la que se firmó el mensaje</translation>
+ </message>
+ <message>
+ <source>Verify the message to ensure it was signed with the specified Bitcoin address</source>
+ <translation>Verificar el mensaje para comprobar que fue firmado con la dirección Bitcoin indicada</translation>
+ </message>
+ <message>
+ <source>Verify &amp;Message</source>
+ <translation>Verificar &amp;mensaje</translation>
+ </message>
+ <message>
+ <source>Reset all verify message fields</source>
+ <translation>Vaciar todos los campos de la verificación de mensaje</translation>
+ </message>
+ <message>
+ <source>Click "Sign Message" to generate signature</source>
+ <translation>Haga clic en "Firmar mensaje" para generar la firma</translation>
+ </message>
+ <message>
+ <source>The entered address is invalid.</source>
+ <translation>La dirección introducida es inválida.</translation>
+ </message>
+ <message>
+ <source>Please check the address and try again.</source>
+ <translation>Verifique la dirección e inténtelo de nuevo.</translation>
+ </message>
+ <message>
+ <source>The entered address does not refer to a key.</source>
+ <translation>La dirección introducida no corresponde a una clave.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock was cancelled.</source>
+ <translation>Se ha cancelado el desbloqueo del monedero. </translation>
+ </message>
+ <message>
+ <source>Private key for the entered address is not available.</source>
+ <translation>No se dispone de la clave privada para la dirección introducida.</translation>
+ </message>
+ <message>
+ <source>Message signing failed.</source>
+ <translation>Ha fallado la firma del mensaje.</translation>
+ </message>
+ <message>
+ <source>Message signed.</source>
+ <translation>Mensaje firmado.</translation>
+ </message>
+ <message>
+ <source>The signature could not be decoded.</source>
+ <translation>No se puede decodificar la firma.</translation>
+ </message>
+ <message>
+ <source>Please check the signature and try again.</source>
+ <translation>Compruebe la firma e inténtelo de nuevo.</translation>
+ </message>
+ <message>
+ <source>The signature did not match the message digest.</source>
+ <translation>La firma no coincide con el resumen del mensaje.</translation>
+ </message>
+ <message>
+ <source>Message verification failed.</source>
+ <translation>La verificación del mensaje ha fallado.</translation>
+ </message>
+ <message>
+ <source>Message verified.</source>
+ <translation>Mensaje verificado.</translation>
+ </message>
+</context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>The Bitcoin Core developers</source>
+ <translation>Los desarrolladores de Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>[testnet]</source>
+ <translation>[testnet]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ <message>
+ <source>KB/s</source>
+ <translation>KB/s</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>Abierto hasta %1</translation>
+ </message>
+ <message>
+ <source>conflicted</source>
+ <translation>en conflicto</translation>
+ </message>
+ <message>
+ <source>%1/offline</source>
+ <translation>%1/fuera de línea</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/no confirmado</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 confirmaciones</translation>
+ </message>
+ <message>
+ <source>Status</source>
+ <translation>Estado</translation>
+ </message>
+ <message numerus="yes">
+ <source>, broadcast through %n node(s)</source>
+ <translation><numerusform>, transmitir a través de %n nodo</numerusform><numerusform>, transmitir a través de %n nodos</numerusform></translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Fecha</translation>
+ </message>
+ <message>
+ <source>Source</source>
+ <translation>Fuente</translation>
+ </message>
+ <message>
+ <source>Generated</source>
+ <translation>Generado</translation>
+ </message>
+ <message>
+ <source>From</source>
+ <translation>De</translation>
+ </message>
+ <message>
+ <source>To</source>
+ <translation>Para</translation>
+ </message>
+ <message>
+ <source>own address</source>
+ <translation>dirección propia</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>de observación</translation>
+ </message>
+ <message>
+ <source>label</source>
+ <translation>etiqueta</translation>
+ </message>
+ <message>
+ <source>Credit</source>
+ <translation>Crédito</translation>
+ </message>
+ <message numerus="yes">
+ <source>matures in %n more block(s)</source>
+ <translation><numerusform>disponible en %n bloque más</numerusform><numerusform>disponible en %n bloques más</numerusform></translation>
+ </message>
+ <message>
+ <source>not accepted</source>
+ <translation>no aceptada</translation>
+ </message>
+ <message>
+ <source>Debit</source>
+ <translation>Débito</translation>
+ </message>
+ <message>
+ <source>Total debit</source>
+ <translation>Débito total</translation>
+ </message>
+ <message>
+ <source>Total credit</source>
+ <translation>Crédito total</translation>
+ </message>
+ <message>
+ <source>Transaction fee</source>
+ <translation>Comisión de transacción</translation>
+ </message>
+ <message>
+ <source>Net amount</source>
+ <translation>Cantidad neta</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Mensaje</translation>
+ </message>
+ <message>
+ <source>Comment</source>
+ <translation>Comentario</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>Identificador de transacción</translation>
+ </message>
+ <message>
+ <source>Merchant</source>
+ <translation>Vendedor</translation>
+ </message>
+ <message>
+ <source>Generated coins must mature %1 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.</source>
+ <translation>Los bitcoins generados deben madurar %1 bloques antes de que puedan gastarse. Cuando generó este bloque, se transmitió a la red para que se añadiera a la cadena de bloques. Si no consigue entrar en la cadena, su estado cambiará a "no aceptado" y ya no se podrá gastar. Esto puede ocurrir ocasionalmente si otro nodo genera un bloque a pocos segundos del suyo.</translation>
+ </message>
+ <message>
+ <source>Debug information</source>
+ <translation>Información de depuración</translation>
+ </message>
+ <message>
+ <source>Transaction</source>
+ <translation>Transacción</translation>
+ </message>
+ <message>
+ <source>Inputs</source>
+ <translation>entradas</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Cantidad</translation>
+ </message>
+ <message>
+ <source>true</source>
+ <translation>verdadero</translation>
+ </message>
+ <message>
+ <source>false</source>
+ <translation>falso</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, todavía no se ha sido difundido satisfactoriamente</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Abrir para %n bloque más</numerusform><numerusform>Abrir para %n bloques más</numerusform></translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>desconocido</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>Detalles de transacción</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>Esta ventana muestra información detallada sobre la transacción</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Fecha</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Tipo</translation>
+ </message>
+ <message>
+ <source>Immature (%1 confirmations, will be available after %2)</source>
+ <translation>No vencidos (%1 confirmaciones. Estarán disponibles al cabo de %2)</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Abrir para %n bloque más</numerusform><numerusform>Abrir para %n bloques más</numerusform></translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>Abierto hasta %1</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>Confirmado (%1 confirmaciones)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>Este bloque no ha sido recibido por otros nodos y probablemente no sea aceptado!</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>Generado pero no aceptado</translation>
+ </message>
+ <message>
+ <source>Offline</source>
+ <translation>Sin conexión</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiqueta</translation>
+ </message>
+ <message>
+ <source>Unconfirmed</source>
+ <translation>Sin confirmar</translation>
+ </message>
+ <message>
+ <source>Confirming (%1 of %2 recommended confirmations)</source>
+ <translation>Confirmando (%1 de %2 confirmaciones recomendadas)</translation>
+ </message>
+ <message>
+ <source>Conflicted</source>
+ <translation>En conflicto</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Recibido con</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>Recibidos de</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Enviado a</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>Pago propio</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Minado</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>de observación</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(nd)</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>Estado de transacción. Pasa el ratón sobre este campo para ver el número de confirmaciones.</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Fecha y hora en que se recibió la transacción.</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>Tipo de transacción.</translation>
+ </message>
+ <message>
+ <source>Whether or not a watch-only address is involved in this transaction.</source>
+ <translation>Sea o no una dirección sólo está involucrada en esta transacción.</translation>
+ </message>
+ <message>
+ <source>User-defined intent/purpose of the transaction.</source>
+ <translation>intento/propósito de la transacción definido por el usuario.</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>Cantidad retirada o añadida al saldo.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>Todo</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>Hoy</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>Esta semana</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>Este mes</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>Mes pasado</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>Este año</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>Rango...</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Recibido con</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Enviado a</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>A usted mismo</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Minado</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>Otra</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>Introduzca una dirección o etiqueta que buscar</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>Cantidad mínima</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Copiar dirección</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Copiar etiqueta</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copiar cuantía</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Copiar identificador de transacción</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>Editar etiqueta</translation>
+ </message>
+ <message>
+ <source>Show transaction details</source>
+ <translation>Mostrar detalles de la transacción</translation>
+ </message>
+ <message>
+ <source>Export Transaction History</source>
+ <translation>Exportar historial de transacciones</translation>
+ </message>
+ <message>
+ <source>Watch-only</source>
+ <translation>De observación</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Error exportando</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the transaction history to %1.</source>
+ <translation>Ha habido un error al intentar guardar la transacción con %1.</translation>
+ </message>
+ <message>
+ <source>Exporting Successful</source>
+ <translation>Exportación finalizada</translation>
+ </message>
+ <message>
+ <source>The transaction history was successfully saved to %1.</source>
+ <translation>La transacción ha sido guardada en %1.</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Archivos de columnas separadas por coma (*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Confirmado</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Fecha</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Tipo</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiqueta</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Dirección</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>Rango:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>para</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ <message>
+ <source>Unit to show amounts in. Click to select another unit.</source>
+ <translation>Unidad en la que se muestran las cantidades. Haga clic para seleccionar otra unidad.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletFrame</name>
+ <message>
+ <source>No wallet has been loaded.</source>
+ <translation>No se ha cargado ningún monedero</translation>
+ </message>
+</context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Enviar bitcoins</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Exportar</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Exportar a un archivo los datos de esta pestaña</translation>
+ </message>
+ <message>
+ <source>Backup Wallet</source>
+ <translation>Copia de seguridad del monedero</translation>
+ </message>
+ <message>
+ <source>Wallet Data (*.dat)</source>
+ <translation>Datos de monedero (*.dat)</translation>
+ </message>
+ <message>
+ <source>Backup Failed</source>
+ <translation>Ha fallado el respaldo</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the wallet data to %1.</source>
+ <translation>Ha habido un error al intentar guardar los datos del monedero en %1.</translation>
+ </message>
+ <message>
+ <source>The wallet data was successfully saved to %1.</source>
+ <translation>Los datos del monedero se han guardado con éxito en %1.</translation>
+ </message>
+ <message>
+ <source>Backup Successful</source>
+ <translation>Se ha completado la copia de seguridad del monedero</translation>
+ </message>
+</context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>Opciones:
+</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>Especificar directorio para los datos</translation>
+ </message>
+ <message>
+ <source>Connect to a node to retrieve peer addresses, and disconnect</source>
+ <translation>Conectar a un nodo para obtener direcciones de pares y desconectar</translation>
+ </message>
+ <message>
+ <source>Specify your own public address</source>
+ <translation>Especifique su propia dirección pública</translation>
+ </message>
+ <message>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>Aceptar comandos consola y JSON-RPC
+</translation>
+ </message>
+ <message>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>Ejecutar en segundo plano como daemon y aceptar comandos
+</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>Usar la red de pruebas
+</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
+ <translation>Aceptar conexiones desde el exterior (predeterminado: 1 si no -proxy o -connect)</translation>
+ </message>
+ <message>
+ <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
+ <translation>Vincular a la dirección dada y escuchar siempre en ella. Utilice la notación [host]:port para IPv6</translation>
+ </message>
+ <message>
+ <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
+ <translation>Borrar todas las transacciones del monedero y sólo recuperar aquellas partes de la cadena de bloques por medio de -rescan on startup.</translation>
+ </message>
+ <message>
+ <source>Distributed under the MIT software license, see the accompanying file COPYING or &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</source>
+ <translation>Distribuido bajo la licencia de software MIT, vea la copia del archivo adjunto o &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</translation>
+ </message>
+ <message>
+ <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
+ <translation>Ejecutar comando cuando una transacción del monedero cambia (%s en cmd se remplazará por TxID)</translation>
+ </message>
+ <message>
+ <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source>
+ <translation>Maximo Comisión totales para usar en una sola transacción billetera; establecer esta demasiado bajo puede abortar transacciones grandes (por defecto: %s)</translation>
+ </message>
+ <message>
+ <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, &gt;%u = target size in MiB to use for block files)</source>
+ <translation>Reducir los requerimientos de almacenamiento mediante la poda (borrado) bloquea viejos. Este modo desactiva el apoyo cartera y es incompatible con -txindex. Advertencia: Revertir esta configuración requiere volver a descargar toda la blockchain. (por defecto: 0 = desactivar bloques de poda, &gt;%u = tamaño de destino en MiB de usar para los archivos de bloques)</translation>
+ </message>
+ <message>
+ <source>Set the number of script verification threads (%u to %d, 0 = auto, &lt;0 = leave that many cores free, default: %d)</source>
+ <translation>Establecer el número de hilos (threads) de verificación de scripts (entre %u y %d, 0 = automático, &lt;0 = dejar libres ese número de núcleos; predeterminado: %d)</translation>
+ </message>
+ <message>
+ <source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source>
+ <translation>Esta es una versión de pre-prueba - utilícela bajo su propio riesgo. No la utilice para usos comerciales o de minería.</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer. Bitcoin Core is probably already running.</source>
+ <translation>No se ha podido acceder a %s en esta máquina. Probablemente ya se está ejecutando Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>ADVERTENCIA: anormalmente alto número de bloques generado, %d bloques recibidos en las últimas horas %d (%d espera)</translation>
+ </message>
+ <message>
+ <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>ADVERTENCIA: comprueba tu conexión de red, %d bloques recibidos en las últimas %d horas (%d esperados)</translation>
+ </message>
+ <message>
+ <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>Aviso: ¡-paytxfee tiene un valor muy alto! Esta es la comisión que pagará si envía una transacción.</translation>
+ </message>
+ <message>
+ <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source>
+ <translation>Atención: ¡Parece que la red no está totalmente de acuerdo! Algunos mineros están presentando inconvenientes.</translation>
+ </message>
+ <message>
+ <source>Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.</source>
+ <translation>Atención: ¡Parece que no estamos completamente de acuerdo con nuestros pares! Podría necesitar una actualización, u otros nodos podrían necesitarla.</translation>
+ </message>
+ <message>
+ <source>Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
+ <translation>Aviso: ¡Error al leer wallet.dat! Todas las claves se han leído correctamente, pero podrían faltar o ser incorrectos los datos de transacciones o las entradas de la libreta de direcciones.</translation>
+ </message>
+ <message>
+ <source>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</source>
+ <translation>Aviso: ¡Recuperados datos de wallet.dat corrupto! El wallet.dat original se ha guardado como wallet.{timestamp}.bak en %s; si hubiera errores en su saldo o transacciones, deberá restaurar una copia de seguridad.</translation>
+ </message>
+ <message>
+ <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source>
+ <translation>Poner en lista blanca a los equipos que se conecten desde la máscara de subred o dirección IP especificada. Se puede especificar múltiples veces.</translation>
+ </message>
+ <message>
+ <source>(default: 1)</source>
+ <translation>(predeterminado: 1)</translation>
+ </message>
+ <message>
+ <source>&lt;category&gt; can be:</source>
+ <translation>&lt;category&gt; puede ser:</translation>
+ </message>
+ <message>
+ <source>Attempt to recover private keys from a corrupt wallet.dat</source>
+ <translation>Intento de recuperar claves privadas de un wallet.dat corrupto</translation>
+ </message>
+ <message>
+ <source>Block creation options:</source>
+ <translation>Opciones de creación de bloques:</translation>
+ </message>
+ <message>
+ <source>Connect only to the specified node(s)</source>
+ <translation>Conectar sólo a los nodos (o nodo) especificados</translation>
+ </message>
+ <message>
+ <source>Connection options:</source>
+ <translation>Opciones de conexión:</translation>
+ </message>
+ <message>
+ <source>Corrupted block database detected</source>
+ <translation>Corrupción de base de datos de bloques detectada.</translation>
+ </message>
+ <message>
+ <source>Debugging/Testing options:</source>
+ <translation>Opciones de depuración/pruebas:</translation>
+ </message>
+ <message>
+ <source>Do not load the wallet and disable wallet RPC calls</source>
+ <translation>No cargar el monedero y desactivar las llamadas RPC del monedero</translation>
+ </message>
+ <message>
+ <source>Do you want to rebuild the block database now?</source>
+ <translation>¿Quieres reconstruir la base de datos de bloques ahora?</translation>
+ </message>
+ <message>
+ <source>Error initializing block database</source>
+ <translation>Error al inicializar la base de datos de bloques</translation>
+ </message>
+ <message>
+ <source>Error initializing wallet database environment %s!</source>
+ <translation>Error al inicializar el entorno de la base de datos del monedero %s</translation>
+ </message>
+ <message>
+ <source>Error loading block database</source>
+ <translation>Error cargando base de datos de bloques</translation>
+ </message>
+ <message>
+ <source>Error opening block database</source>
+ <translation>Error al abrir base de datos de bloques.</translation>
+ </message>
+ <message>
+ <source>Error: Disk space is low!</source>
+ <translation>Error: ¡Espacio en disco bajo!</translation>
+ </message>
+ <message>
+ <source>Failed to listen on any port. Use -listen=0 if you want this.</source>
+ <translation>Ha fallado la escucha en todos los puertos. Use -listen=0 si desea esto.</translation>
+ </message>
+ <message>
+ <source>If &lt;category&gt; is not supplied, output all debugging information.</source>
+ <translation>Si no se proporciona &lt;category&gt;, mostrar toda la depuración</translation>
+ </message>
+ <message>
+ <source>Importing...</source>
+ <translation>Importando...</translation>
+ </message>
+ <message>
+ <source>Incorrect or no genesis block found. Wrong datadir for network?</source>
+ <translation>Incorrecto o bloque de génesis no encontrado. Datadir equivocada para la red?</translation>
+ </message>
+ <message>
+ <source>Invalid -onion address: '%s'</source>
+ <translation>Dirección -onion inválida: '%s'</translation>
+ </message>
+ <message>
+ <source>Not enough file descriptors available.</source>
+ <translation>No hay suficientes descriptores de archivo disponibles. </translation>
+ </message>
+ <message>
+ <source>Only connect to nodes in network &lt;net&gt; (ipv4, ipv6 or onion)</source>
+ <translation>Sólo conectar a nodos en redes &lt;net&gt; (ipv4, ipv6 o onion)</translation>
+ </message>
+ <message>
+ <source>Prune cannot be configured with a negative value.</source>
+ <translation>Pode no se puede configurar con un valor negativo.</translation>
+ </message>
+ <message>
+ <source>Prune mode is incompatible with -txindex.</source>
+ <translation>El modo recorte es incompatible con -txindex.</translation>
+ </message>
+ <message>
+ <source>Set database cache size in megabytes (%d to %d, default: %d)</source>
+ <translation>Asignar tamaño de cache en megabytes (entre %d y %d; predeterminado: %d)</translation>
+ </message>
+ <message>
+ <source>Set maximum block size in bytes (default: %d)</source>
+ <translation>Establecer tamaño máximo de bloque en bytes (predeterminado: %d)</translation>
+ </message>
+ <message>
+ <source>Specify wallet file (within data directory)</source>
+ <translation>Especificar archivo de monedero (dentro del directorio de datos)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: %u)</source>
+ <translation>Usar UPnP para asignar el puerto de escucha (predeterminado:: %u)</translation>
+ </message>
+ <message>
+ <source>Verifying blocks...</source>
+ <translation>Verificando bloques...</translation>
+ </message>
+ <message>
+ <source>Verifying wallet...</source>
+ <translation>Verificando monedero...</translation>
+ </message>
+ <message>
+ <source>Wallet %s resides outside data directory %s</source>
+ <translation>El monedero %s se encuentra fuera del directorio de datos %s</translation>
+ </message>
+ <message>
+ <source>Wallet options:</source>
+ <translation>Opciones de monedero:</translation>
+ </message>
+ <message>
+ <source>Warning: This version is obsolete; upgrade required!</source>
+ <translation>Peligro: Esta versión es obsoleta; actualización requerida!</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to change -txindex</source>
+ <translation>Usted necesita reconstruir la base de datos utilizando -reindex para cambiar -txindex</translation>
+ </message>
+ <message>
+ <source>Imports blocks from external blk000??.dat file</source>
+ <translation>Importa los bloques desde un archivo blk000??.dat externo</translation>
+ </message>
+ <message>
+ <source>Allow JSON-RPC connections from specified source. Valid for &lt;ip&gt; are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times</source>
+ <translation>Permitir conexiones JSON-RPC de origen especificado. Válido para son una sola IP (por ejemplo 1.2.3.4), una red/máscara de red (por ejemplo 1.2.3.4/255.255.255.0) o una red/CIDR (e.g. 1.2.3.4/24). Esta opción se puede especificar varias veces</translation>
+ </message>
+ <message>
+ <source>An error occurred while setting up the RPC address %s port %u for listening: %s</source>
+ <translation>Ocurrió un error al configurar la dirección de RPC %s puerto %u para escuchar en: %s</translation>
+ </message>
+ <message>
+ <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source>
+ <translation>Ligar a las direcciones especificadas y poner en lista blanca a los equipos conectados a ellas. Usar la notación para IPv6 [host]:puerto.</translation>
+ </message>
+ <message>
+ <source>Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)</source>
+ <translation>Ligar a las direcciones especificadas para escuchar por conexiones JSON-RPC. Usar la notación para IPv6 [host]:puerto. Esta opción se puede especificar múltiples veces (por defecto: ligar a todas las interfaces)</translation>
+ </message>
+ <message>
+ <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source>
+ <translation>No se ha podido bloquear el directorio de datos %s. Probablemente ya se está ejecutando Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
+ <translation>Crear nuevos archivos con permisos por defecto del sistema, en lugar de umask 077 (sólo efectivo con la funcionalidad de monedero desactivada)</translation>
+ </message>
+ <message>
+ <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source>
+ <translation>Descubra direcciones IP propias (por defecto: 1 cuando se escucha y nadie -externalip o -proxy)</translation>
+ </message>
+ <message>
+ <source>Error: Listening for incoming connections failed (listen returned error %s)</source>
+ <translation>Error: la escucha para conexiones entrantes falló (la escucha regresó el error %s)</translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source>
+ <translation>Error: Unsupported argumento -socks encontrados. SOCKS versión ajuste ya no es posible, sólo SOCKS5 proxies son compatibles.</translation>
+ </message>
+ <message>
+ <source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source>
+ <translation>Ejecutar un comando cuando se reciba una alerta importante o cuando veamos un fork demasiado largo (%s en cmd se reemplazará por el mensaje)</translation>
+ </message>
+ <message>
+ <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source>
+ <translation>Tarifas (en BTC/Kb) más pequeños que esto se consideran cero cuota de reinstalación (por defecto: %s)</translation>
+ </message>
+ <message>
+ <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
+ <translation>Si el pago de comisión no está establecido, incluir la cuota suficiente para que las transacciones comiencen la confirmación en una media de n bloques ( por defecto :%u)</translation>
+ </message>
+ <message>
+ <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source>
+ <translation>El tamaño máximo de los datos en las operaciones de transporte de datos que transmitimos y el mio (default: %u)</translation>
+ </message>
+ <message>
+ <source>Prune configured below the minimum of %d MB. Please use a higher number.</source>
+ <translation>Pode configurado por debajo del mínimo de %d MB. Por favor, use un número más alto.</translation>
+ </message>
+ <message>
+ <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source>
+ <translation>Consulta de direcciones pares mediante búsqueda de DNS, si bajo en direcciones (por defecto: 1 a menos que - conectar)</translation>
+ </message>
+ <message>
+ <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source>
+ <translation>Aleatorizar las credenciales para cada conexión proxy. Esto habilita la Tor stream isolation (por defecto: %u)</translation>
+ </message>
+ <message>
+ <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
+ <translation>Establecer tamaño máximo de las transacciones de alta prioridad/baja comisión en bytes (predeterminado: %d)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source>
+ <translation>Ajuste el número de hilos para la generación de moneda si está habilitado (-1 = all cores, default: %d)</translation>
+ </message>
+ <message>
+ <source>The transaction amount is too small to send after the fee has been deducted</source>
+ <translation>Monto de transacción muy pequeña luego de la deducción por comisión</translation>
+ </message>
+ <message>
+ <source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit &lt;https://www.openssl.org/&gt; and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source>
+ <translation>Este producto incluye software desarrollado por el OpenSSL Project para su uso en OpenSSL Toolkit &lt;https://www.openssl.org/&gt;, software de cifrado escrito por Eric Young y software UPnP escrito por Thomas Bernard.</translation>
+ </message>
+ <message>
+ <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an 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)
+The username and password MUST NOT be the same.
+If the file does not exist, create it with owner-readable-only file permissions.
+It is also recommended to set alertnotify so you are notified of problems;
+for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
+</source>
+ <translation>Para utilizar bitcoind, o la -opción servidor a bitcoin-qt, debes establecer una rpcpassword en el fichero de configuración:
+%s
+Se recomienda utilizar la siguiente contraseña aleatoria:
+rpcuser=bitcoinrpc
+rpcpassword=%s
+(no es necesario que recuerdes esta contraseña)
+El nombre de usuario y contraseña NO DEBEN ser la misma.
+Si no existe el archivo, crearlo con los permisos de archivos de propietarios de -sólo lectura-.
+También se recomienda establecer una notificación de alerta para ser notificado de problemas;
+por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com
+</translation>
+ </message>
+ <message>
+ <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source>
+ <translation>Advertencia: ¡-maxtxfee se establece muy alta! Esta gran tarifa podría ser pagada en una sola transacción .</translation>
+ </message>
+ <message>
+ <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source>
+ <translation>Aviso: ¡Comprueba la fecha y hora de tu ordenador y verifica si es correcta! Si no es correcta Bitcoin Core no funcionará adecuadamente.</translation>
+ </message>
+ <message>
+ <source>Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway</source>
+ <translation>A los equipos en lista blanca no se les pueden prohibir los ataques DoS y sus transacciones siempre son retransmitidas, incluso si ya están en el mempool, es útil por ejemplo para un gateway.</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source>
+ <translation>Necesitas reconstruir la base de datos utilizando -reindex para volver al modo sin recorte. Esto volverá a descargar toda la cadena de bloques</translation>
+ </message>
+ <message>
+ <source>(default: %u)</source>
+ <translation>(por defecto: %u)</translation>
+ </message>
+ <message>
+ <source>Accept public REST requests (default: %u)</source>
+ <translation>Aceptar solicitudes públicas en FERIADOS (por defecto: %u)</translation>
+ </message>
+ <message>
+ <source>Activating best chain...</source>
+ <translation>Activando la mejor cadena...</translation>
+ </message>
+ <message>
+ <source>Can't run with a wallet in prune mode.</source>
+ <translation>No se puede ejecutar con un monedero en modo recorte.</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -whitebind address: '%s'</source>
+ <translation>No se puede resolver -whitebind address: '%s'</translation>
+ </message>
+ <message>
+ <source>Choose data directory on startup (default: 0)</source>
+ <translation>Elegir directorio de datos al iniciar (predeterminado: 0)</translation>
+ </message>
+ <message>
+ <source>Connect through SOCKS5 proxy</source>
+ <translation>Conectar usando SOCKS5 proxy</translation>
+ </message>
+ <message>
+ <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source>
+ <translation>Copyright (C) 2009-%i The Bitcoin Core Developers</translation>
+ </message>
+ <message>
+ <source>Could not parse -rpcbind value %s as network address</source>
+ <translation>No se pudo analizar -rpcbind valor%s como dirección de red</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source>
+ <translation>Error al cargar wallet.dat: El monedero requiere una versión más reciente de Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Error reading from database, shutting down.</source>
+ <translation>Error al leer la base de datos, cerrando.</translation>
+ </message>
+ <message>
+ <source>Error: A fatal internal error occurred, see debug.log for details</source>
+ <translation>Un error interno fatal ocurrió, ver debug.log para detalles</translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -tor found, use -onion.</source>
+ <translation>Error: Argumento encontrado -tor no soportado, utilice -onion</translation>
+ </message>
+ <message>
+ <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source>
+ <translation>Cuota (in BTC/kB) para añadir a las transacciones que envíes (por defecto: %s)</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Información</translation>
+ </message>
+ <message>
+ <source>Initialization sanity check failed. Bitcoin Core is shutting down.</source>
+ <translation>La inicialización de la verificación de validez falló. Se está apagando Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Monto inválido para -maxtxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -minrelaytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Cantidad inválida para -minrelaytxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -mintxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Cantidad inválida para -mintxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s' (must be at least %s)</source>
+ <translation>Cantidad inválida para -paytxfee=&lt;amount&gt;: '%s' (debe ser por lo menos %s)</translation>
+ </message>
+ <message>
+ <source>Invalid netmask specified in -whitelist: '%s'</source>
+ <translation>Máscara de red inválida especificada en -whitelist: '%s'</translation>
+ </message>
+ <message>
+ <source>Keep at most &lt;n&gt; unconnectable transactions in memory (default: %u)</source>
+ <translation>Mantener como máximo &lt;n&gt; transacciones no conectables en memoria (por defecto: %u)</translation>
+ </message>
+ <message>
+ <source>Need to specify a port with -whitebind: '%s'</source>
+ <translation>Necesita especificar un puerto con -whitebind: '%s'</translation>
+ </message>
+ <message>
+ <source>Node relay options:</source>
+ <translation>Opciones de nodos de retransmisión:</translation>
+ </message>
+ <message>
+ <source>Pruning blockstore...</source>
+ <translation>Poda blockstore ...</translation>
+ </message>
+ <message>
+ <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source>
+ <translation>Opciones SSL de RPC: (véase la wiki de Bitcoin para las instrucciones de instalación de SSL)</translation>
+ </message>
+ <message>
+ <source>RPC server options:</source>
+ <translation>Opciones de servidor RPC:</translation>
+ </message>
+ <message>
+ <source>RPC support for HTTP persistent connections (default: %d)</source>
+ <translation>Soporte RPC para conexiones HTTP persistentes (por defecto: %d)</translation>
+ </message>
+ <message>
+ <source>Rebuild block chain index from current blk000??.dat files on startup</source>
+ <translation>Reconstruir el índice de la cadena de bloques en el arranque desde los actuales ficheros blk000??.dat</translation>
+ </message>
+ <message>
+ <source>Receive and display P2P network alerts (default: %u)</source>
+ <translation>Recibir y mostrar alertas de red P2P (default: %u)</translation>
+ </message>
+ <message>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>Enviar información de trazas/depuración a la consola en lugar de al archivo debug.log</translation>
+ </message>
+ <message>
+ <source>Send transactions as zero-fee transactions if possible (default: %u)</source>
+ <translation>Mandar transacciones como comisión-cero si es posible (por defecto: %u)</translation>
+ </message>
+ <message>
+ <source>Set SSL root certificates for payment request (default: -system-)</source>
+ <translation>Establecer los certificados raíz SSL para solicitudes de pago (predeterminado: -system-)</translation>
+ </message>
+ <message>
+ <source>Set language, for example "de_DE" (default: system locale)</source>
+ <translation>Establecer el idioma, por ejemplo, "es_ES" (predeterminado: configuración regional del sistema)</translation>
+ </message>
+ <message>
+ <source>Show all debugging options (usage: --help -help-debug)</source>
+ <translation>Muestra todas las opciones de depuración (uso: --help -help-debug)</translation>
+ </message>
+ <message>
+ <source>Show splash screen on startup (default: 1)</source>
+ <translation>Mostrar pantalla de bienvenida en el inicio (predeterminado: 1)</translation>
+ </message>
+ <message>
+ <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source>
+ <translation>Reducir el archivo debug.log al iniciar el cliente (predeterminado: 1 sin -debug)</translation>
+ </message>
+ <message>
+ <source>Signing transaction failed</source>
+ <translation>Transacción falló</translation>
+ </message>
+ <message>
+ <source>Start minimized</source>
+ <translation>Arrancar minimizado</translation>
+ </message>
+ <message>
+ <source>The transaction amount is too small to pay the fee</source>
+ <translation>Cantidad de la transacción demasiado pequeña para pagar la comisión</translation>
+ </message>
+ <message>
+ <source>This is experimental software.</source>
+ <translation>Este software es experimental.</translation>
+ </message>
+ <message>
+ <source>Transaction amount too small</source>
+ <translation>Cantidad de la transacción demasiado pequeña</translation>
+ </message>
+ <message>
+ <source>Transaction amounts must be positive</source>
+ <translation>Las cantidades en las transacciones deben ser positivas</translation>
+ </message>
+ <message>
+ <source>Transaction too large for fee policy</source>
+ <translation>Operación demasiado grande para la política de tasas</translation>
+ </message>
+ <message>
+ <source>Transaction too large</source>
+ <translation>Transacción demasiado grande</translation>
+ </message>
+ <message>
+ <source>UI Options:</source>
+ <translation>Opciones de interfaz de usuario</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer (bind returned error %s)</source>
+ <translation>No es posible conectar con %s en este sistema (bind ha dado el error %s)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: 1 when listening)</source>
+ <translation>Usar UPnP para asignar el puerto de escucha (predeterminado: 1 al escuchar)</translation>
+ </message>
+ <message>
+ <source>Username for JSON-RPC connections</source>
+ <translation>Nombre de usuario para las conexiones JSON-RPC
+</translation>
+ </message>
+ <message>
+ <source>Wallet needed to be rewritten: restart Bitcoin Core to complete</source>
+ <translation>Monedero es necesario volver a escribir: reiniciar Bitcoin Core para completar</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Aviso</translation>
+ </message>
+ <message>
+ <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source>
+ <translation>Advertencia: Argumento no soportado -benchmark ignored, use -debug=bench.</translation>
+ </message>
+ <message>
+ <source>Warning: Unsupported argument -debugnet ignored, use -debug=net.</source>
+ <translation>Aviso: Argumento no sportado -debugnet anticuado, utilice -debug=net.</translation>
+ </message>
+ <message>
+ <source>Zapping all transactions from wallet...</source>
+ <translation>Eliminando todas las transacciones del monedero...</translation>
+ </message>
+ <message>
+ <source>on startup</source>
+ <translation>al iniciar</translation>
+ </message>
+ <message>
+ <source>wallet.dat corrupt, salvage failed</source>
+ <translation>wallet.dat corrupto. Ha fallado la recuperación.</translation>
+ </message>
+ <message>
+ <source>Password for JSON-RPC connections</source>
+ <translation>Contraseña para las conexiones JSON-RPC
+</translation>
+ </message>
+ <message>
+ <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
+ <translation>Ejecutar un comando cuando cambia el mejor bloque (%s en cmd se sustituye por el hash de bloque)</translation>
+ </message>
+ <message>
+ <source>Upgrade wallet to latest format</source>
+ <translation>Actualizar el monedero al último formato</translation>
+ </message>
+ <message>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>Volver a examinar la cadena de bloques en busca de transacciones del monedero perdidas</translation>
+ </message>
+ <message>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>Usar OpenSSL (https) para las conexiones JSON-RPC
+</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>Este mensaje de ayuda
+</translation>
+ </message>
+ <message>
+ <source>Allow DNS lookups for -addnode, -seednode and -connect</source>
+ <translation>Permitir búsquedas DNS para -addnode, -seednode y -connect</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>Cargando direcciones...</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>Error al cargar wallet.dat: el monedero está dañado</translation>
+ </message>
+ <message>
+ <source>(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source>
+ <translation>(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</translation>
+ </message>
+ <message>
+ <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
+ <translation>Nivel de rigor en la verificación de bloques de -checkblocks (0-4; predeterminado: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
+ <translation>Mantener el índice completo de transacciones, usado por la llamada rpc de getrawtransaction (por defecto: %u)</translation>
+ </message>
+ <message>
+ <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source>
+ <translation>Número de segundos en que se evita la reconexión de pares con mal comportamiento (predeterminado: %u)</translation>
+ </message>
+ <message>
+ <source>Output debugging information (default: %u, supplying &lt;category&gt; is optional)</source>
+ <translation>Mostrar depuración (por defecto: %u, proporcionar &lt;category&gt; es opcional)</translation>
+ </message>
+ <message>
+ <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source>
+ <translation>Usar distintos proxys SOCKS5 para comunicarse vía Tor de forma anónima (Por defecto: %s)</translation>
+ </message>
+ <message>
+ <source>(default: %s)</source>
+ <translation>(predeterminado: %s)</translation>
+ </message>
+ <message>
+ <source>Acceptable ciphers (default: %s)</source>
+ <translation>Aceptar cifrado (por defecto: %s)</translation>
+ </message>
+ <message>
+ <source>Always query for peer addresses via DNS lookup (default: %u)</source>
+ <translation>Siempre consultar direcciones de otros equipos por medio de DNS lookup (por defecto: %u)</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>Error al cargar wallet.dat</translation>
+ </message>
+ <message>
+ <source>Generate coins (default: %u)</source>
+ <translation>Generar monedas (por defecto: %u)</translation>
+ </message>
+ <message>
+ <source>How many blocks to check at startup (default: %u, 0 = all)</source>
+ <translation>Cuántos bloques comprobar al iniciar (predeterminado: %u, 0 = todos)</translation>
+ </message>
+ <message>
+ <source>Include IP addresses in debug output (default: %u)</source>
+ <translation>Incluir direcciones IP en la salida de depuración (por defecto: %u)</translation>
+ </message>
+ <message>
+ <source>Invalid -proxy address: '%s'</source>
+ <translation>Dirección -proxy inválida: '%s'</translation>
+ </message>
+ <message>
+ <source>Listen for JSON-RPC connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>Escuchar conexiones JSON-RPC en &lt;puerto&gt; (predeterminado: %u o testnet: %u)</translation>
+ </message>
+ <message>
+ <source>Listen for connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>Escuchar conexiones en &lt;puerto&gt; (predeterminado: %u o testnet: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain at most &lt;n&gt; connections to peers (default: %u)</source>
+ <translation>Mantener como máximo &lt;n&gt; conexiones a pares (predeterminado: %u)</translation>
+ </message>
+ <message>
+ <source>Make the wallet broadcast transactions</source>
+ <translation>Realiza las operaciones de difusión del monedero</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection receive buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>Búfer de recepción máximo por conexión, &lt;n&gt;*1000 bytes (por defecto: %u)</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection send buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>Búfer de recepción máximo por conexión, , &lt;n&gt;*1000 bytes (por defecto: %u)</translation>
+ </message>
+ <message>
+ <source>Prepend debug output with timestamp (default: %u)</source>
+ <translation>Anteponer marca temporal a la información de depuración (por defecto: %u)</translation>
+ </message>
+ <message>
+ <source>Relay and mine data carrier transactions (default: %u)</source>
+ <translation>Retransmitir y minar transacciones de transporte de datos (por defecto: %u)</translation>
+ </message>
+ <message>
+ <source>Relay non-P2SH multisig (default: %u)</source>
+ <translation>Relay non-P2SH multisig (default: %u)</translation>
+ </message>
+ <message>
+ <source>Server certificate file (default: %s)</source>
+ <translation>Archivo de certificado del servidor (por defecto: %s)</translation>
+ </message>
+ <message>
+ <source>Server private key (default: %s)</source>
+ <translation>Llave privada del servidor (por defecto: %s)</translation>
+ </message>
+ <message>
+ <source>Set key pool size to &lt;n&gt; (default: %u)</source>
+ <translation>Ajustar el número de claves en reserva &lt;n&gt; (predeterminado: %u)</translation>
+ </message>
+ <message>
+ <source>Set minimum block size in bytes (default: %u)</source>
+ <translation>Establecer tamaño mínimo de bloque en bytes (por defecto: %u)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads to service RPC calls (default: %d)</source>
+ <translation>Establecer el número de procesos para llamadas del servicio RPC (por defecto: %d)</translation>
+ </message>
+ <message>
+ <source>Specify configuration file (default: %s)</source>
+ <translation>Especificar archivo de configuración (por defecto: %s)</translation>
+ </message>
+ <message>
+ <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source>
+ <translation>Especificar tiempo de espera de la conexión (mínimo: 1, por defecto: %d)</translation>
+ </message>
+ <message>
+ <source>Specify pid file (default: %s)</source>
+ <translation>Especificar archivo pid (predeterminado: %s)</translation>
+ </message>
+ <message>
+ <source>Spend unconfirmed change when sending transactions (default: %u)</source>
+ <translation>Gastar cambio no confirmado al enviar transacciones (predeterminado: %u)</translation>
+ </message>
+ <message>
+ <source>Threshold for disconnecting misbehaving peers (default: %u)</source>
+ <translation>Umbral para la desconexión de pares con mal comportamiento (predeterminado: %u)</translation>
+ </message>
+ <message>
+ <source>Unknown network specified in -onlynet: '%s'</source>
+ <translation>La red especificada en -onlynet '%s' es desconocida</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -bind address: '%s'</source>
+ <translation>No se puede resolver la dirección de -bind: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -externalip address: '%s'</source>
+ <translation>No se puede resolver la dirección de -externalip: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Cantidad inválida para -paytxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>Fondos insuficientes</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>Cargando el índice de bloques...</translation>
+ </message>
+ <message>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>Añadir un nodo al que conectarse y tratar de mantener la conexión abierta</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>Cargando monedero...</translation>
+ </message>
+ <message>
+ <source>Cannot downgrade wallet</source>
+ <translation>No se puede rebajar el monedero</translation>
+ </message>
+ <message>
+ <source>Cannot write default address</source>
+ <translation>No se puede escribir la dirección predeterminada</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>Reexplorando...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>Se terminó de cargar</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Error</translation>
+ </message>
+</context>
+</TS> \ 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 0000000000..c35acf2c67
--- /dev/null
+++ b/src/qt/locale/bitcoin_es_CL.ts
@@ -0,0 +1,1425 @@
+<TS language="es_CL" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Right-click to edit address or label</source>
+ <translation>Haga clic para editar la dirección o etiqueta</translation>
+ </message>
+ <message>
+ <source>Create a new address</source>
+ <translation>Crea una nueva direCrea una nueva direccióncción</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>y nueva</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Copia la dirección seleccionada al portapapeles</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>y copiar</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>C y perder</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>&amp;Copia dirección</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>Eliminar la dirección seleccionada de la lista</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Exportar los datos de la pestaña actual a un archivo</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>y exportar</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;Borrar</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>Copia &amp;etiqueta</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>&amp;Editar</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Archivos separados por coma (*.csv)</translation>
+ </message>
+ </context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Etiqueta</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Dirección</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(sin etiqueta)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Introduce contraseña actual </translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Nueva contraseña</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Repite nueva contraseña</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>Codificar billetera</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>Esta operación necesita la contraseña para desbloquear la billetera.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Desbloquea billetera</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>Esta operación necesita la contraseña para decodificar la billetara.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>Decodificar cartera</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>Cambia contraseña</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>Confirma la codificación de cartera</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>Atención: ¡Si codificas tu billetera y pierdes la contraseña perderás &lt;b&gt;TODOS TUS BITCOINS&lt;/b&gt;!</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>¿Seguro que quieres seguir codificando la billetera?</translation>
+ </message>
+ <message>
+ <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
+ <translation>IMPORTANTE: Cualquier versión anterior que hayas realizado de tu archivo de billetera será reemplazada por el nuevo archivo de billetera encriptado. Por razones de seguridad, los respaldos anteriores de los archivos de billetera se volverán inútiles en tanto comiences a usar la nueva billetera encriptada.</translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>Precaucion: Mayúsculas Activadas</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>Billetera codificada</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>Falló la codificación de la billetera</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>La codificación de la billetera falló debido a un error interno. Tu billetera no ha sido codificada.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>Las contraseñas no coinciden.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>Ha fallado el desbloqueo de la billetera</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>La contraseña introducida para decodificar la billetera es incorrecta.</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>Ha fallado la decodificación de la billetera</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>La contraseña de billetera ha sido cambiada con éxito.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>Firmar &amp;Mensaje...</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>Sincronizando con la red...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;Vista general</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>Muestra una vista general de la billetera</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Transacciones</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>Explora el historial de transacciónes</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>&amp;Salir</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>Salir del programa</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>Acerca de</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>Mostrar Información sobre Qt</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;Opciones</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>&amp;Codificar la billetera...</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>&amp;Respaldar billetera...</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>&amp;Cambiar la contraseña...</translation>
+ </message>
+ <message>
+ <source>Open &amp;URI...</source>
+ <translation>Abrir y url...</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core client</source>
+ <translation>cliente bitcoin core</translation>
+ </message>
+ <message>
+ <source>Reindexing blocks on disk...</source>
+ <translation>Cargando el index de bloques...</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>Enviar monedas a una dirección bitcoin</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>Respaldar billetera en otra ubicación</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Cambiar la contraseña utilizada para la codificación de la billetera</translation>
+ </message>
+ <message>
+ <source>&amp;Debug window</source>
+ <translation>Ventana &amp;Debug</translation>
+ </message>
+ <message>
+ <source>Open debugging and diagnostic console</source>
+ <translation>Abre consola de depuración y diagnóstico</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>Cartera</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>&amp;Envía</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>y recibir</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>&amp;Mostrar/Ocultar</translation>
+ </message>
+ <message>
+ <source>Sign messages with your Bitcoin addresses to prove you own them</source>
+ <translation>Firmar un mensaje para provar que usted es dueño de esta dirección</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;Archivo</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;Configuración</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>&amp;Ayuda</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>Barra de pestañas</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>bitcoin core</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Error</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Atención</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Información</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>Actualizado</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>Recuperando...</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>Transacción enviada</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>Transacción entrante</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>La billetera esta &lt;b&gt;codificada&lt;/b&gt; y actualmente &lt;b&gt;desbloqueda&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>La billetera esta &lt;b&gt;codificada&lt;/b&gt; y actualmente &lt;b&gt;bloqueda&lt;/b&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <source>Network Alert</source>
+ <translation>Alerta de Red</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Amount:</source>
+ <translation>Cantidad:</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Cantidad</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Fecha</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Confirmado</translation>
+ </message>
+ <message>
+ <source>Priority</source>
+ <translation>prioridad</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Copia dirección</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Copia etiqueta</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copiar Cantidad</translation>
+ </message>
+ <message>
+ <source>medium</source>
+ <translation>medio</translation>
+ </message>
+ <message>
+ <source>yes</source>
+ <translation>si</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>no</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(sin etiqueta)</translation>
+ </message>
+ </context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>Editar dirección</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>&amp;Etiqueta</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;Dirección</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>Nueva dirección para recibir</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>Nueva dirección para enviar</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>Editar dirección de recepción</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>Editar dirección de envio</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>La dirección introducida "%1" ya esta guardada en la libreta de direcciones.</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is not a valid Bitcoin address.</source>
+ <translation>La dirección introducida "%1" no es una dirección Bitcoin valida.</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>No se pudo desbloquear la billetera.</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>La generación de nueva clave falló.</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ <message>
+ <source>name</source>
+ <translation>Nombre</translation>
+ </message>
+ </context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>bitcoin core</translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>versión</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>Uso:</translation>
+ </message>
+ </context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Welcome</source>
+ <translation>bienvenido</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>bitcoin core</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Error</translation>
+ </message>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ <message>
+ <source>URI:</source>
+ <translation>url:</translation>
+ </message>
+ </context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>Opciones</translation>
+ </message>
+ <message>
+ <source>&amp;Main</source>
+ <translation>&amp;Principal</translation>
+ </message>
+ <message>
+ <source>Reset all client options to default.</source>
+ <translation>Reestablece todas las opciones.</translation>
+ </message>
+ <message>
+ <source>&amp;Network</source>
+ <translation>&amp;Red</translation>
+ </message>
+ <message>
+ <source>Expert</source>
+ <translation>experto</translation>
+ </message>
+ <message>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>Abre automáticamente el puerto del cliente Bitcoin en el router. Esto funciona solo cuando tu router es compatible con UPnP y está habilitado.</translation>
+ </message>
+ <message>
+ <source>Map port using &amp;UPnP</source>
+ <translation>Direcciona el puerto usando &amp;UPnP</translation>
+ </message>
+ <message>
+ <source>Proxy &amp;IP:</source>
+ <translation>&amp;IP Proxy:</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>&amp;Puerto:</translation>
+ </message>
+ <message>
+ <source>Port of the proxy (e.g. 9050)</source>
+ <translation>Puerto del servidor proxy (ej. 9050)</translation>
+ </message>
+ <message>
+ <source>&amp;Window</source>
+ <translation>y windows
+</translation>
+ </message>
+ <message>
+ <source>Show only a tray icon after minimizing the window.</source>
+ <translation>Muestra solo un ícono en la bandeja después de minimizar la ventana</translation>
+ </message>
+ <message>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>&amp;Minimiza a la bandeja en vez de la barra de tareas</translation>
+ </message>
+ <message>
+ <source>M&amp;inimize on close</source>
+ <translation>M&amp;inimiza a la bandeja al cerrar</translation>
+ </message>
+ <message>
+ <source>&amp;Display</source>
+ <translation>&amp;Mostrado</translation>
+ </message>
+ <message>
+ <source>&amp;Unit to show amounts in:</source>
+ <translation>&amp;Unidad en la que mostrar cantitades:</translation>
+ </message>
+ <message>
+ <source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
+ <translation>Elige la subdivisión por defecto para mostrar cantidaded en la interfaz cuando se envien monedas</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>&amp;OK</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>&amp;Cancela</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>predeterminado</translation>
+ </message>
+ <message>
+ <source>Confirm options reset</source>
+ <translation>Confirmar reestablecimiento de las opciones</translation>
+ </message>
+ </context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>Formulario</translation>
+ </message>
+ <message>
+ <source>Total:</source>
+ <translation>Total:</translation>
+ </message>
+ </context>
+<context>
+ <name>PaymentServer</name>
+ <message>
+ <source>Payment acknowledged</source>
+ <translation>Pago completado</translation>
+ </message>
+ </context>
+<context>
+ <name>PeerTableModel</name>
+ </context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>Cantidad</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>N/A</translation>
+ </message>
+ </context>
+<context>
+ <name>QRImageWidget</name>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>Guardar imagen...</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Image</source>
+ <translation>Copiar Imagen</translation>
+ </message>
+ </context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>Client name</source>
+ <translation>Nombre del cliente</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>N/A</translation>
+ </message>
+ <message>
+ <source>Client version</source>
+ <translation>Versión del Cliente</translation>
+ </message>
+ <message>
+ <source>&amp;Information</source>
+ <translation>&amp;Información</translation>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>General</translation>
+ </message>
+ <message>
+ <source>Startup time</source>
+ <translation>Tiempo de inicio</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Red</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>Nombre</translation>
+ </message>
+ <message>
+ <source>Number of connections</source>
+ <translation>Número de conexiones</translation>
+ </message>
+ <message>
+ <source>Block chain</source>
+ <translation>Bloquea cadena</translation>
+ </message>
+ <message>
+ <source>Version</source>
+ <translation>version
+</translation>
+ </message>
+ <message>
+ <source>&amp;Open</source>
+ <translation>&amp;Abrir</translation>
+ </message>
+ <message>
+ <source>&amp;Console</source>
+ <translation>&amp;Consola</translation>
+ </message>
+ <message>
+ <source>Totals</source>
+ <translation>Total:</translation>
+ </message>
+ <message>
+ <source>Clear console</source>
+ <translation>Limpiar Consola</translation>
+ </message>
+ </context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Etiqueta:</translation>
+ </message>
+ <message>
+ <source>&amp;Message:</source>
+ <translation>&amp;mensaje</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Copia etiqueta</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copiar Cantidad</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>QR Code</source>
+ <translation>Código QR </translation>
+ </message>
+ <message>
+ <source>Copy &amp;Address</source>
+ <translation>&amp;Copia dirección</translation>
+ </message>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>Guardar imagen...</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Dirección</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Cantidad</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiqueta</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Mensaje</translation>
+ </message>
+ </context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Fecha</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiqueta</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Mensaje</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Cantidad</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(sin etiqueta)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Enviar monedas</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Cantidad:</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>Enviar a múltiples destinatarios</translation>
+ </message>
+ <message>
+ <source>Add &amp;Recipient</source>
+ <translation>&amp;Agrega destinatario</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>&amp;Borra todos</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>Balance:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>Confirma el envio</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>&amp;Envía</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>Confirmar el envio de monedas</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copiar Cantidad</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>La cantidad por pagar tiene que ser mayor 0.</translation>
+ </message>
+ <message>
+ <source>The amount exceeds your balance.</source>
+ <translation>La cantidad sobrepasa tu saldo.</translation>
+ </message>
+ <message>
+ <source>The total exceeds your balance when the %1 transaction fee is included.</source>
+ <translation>El total sobrepasa tu saldo cuando se incluyen %1 como tasa de envio.</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(sin etiqueta)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>Cantidad:</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>&amp;Pagar a:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Introduce una etiqueta a esta dirección para añadirla a tu guia</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Etiqueta:</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Pega dirección desde portapapeles</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Message:</source>
+ <translation>Mensaje:</translation>
+ </message>
+ </context>
+<context>
+ <name>ShutdownWindow</name>
+ </context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>&amp;Sign Message</source>
+ <translation>&amp;Firmar Mensaje</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Pega dirección desde portapapeles</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Enter the message you want to sign here</source>
+ <translation>Escriba el mensaje que desea firmar</translation>
+ </message>
+ <message>
+ <source>Signature</source>
+ <translation>Firma</translation>
+ </message>
+ <message>
+ <source>Sign the message to prove you own this Bitcoin address</source>
+ <translation>Firmar un mensjage para probar que usted es dueño de esta dirección</translation>
+ </message>
+ <message>
+ <source>Sign &amp;Message</source>
+ <translation>Firmar Mensaje</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>&amp;Borra todos</translation>
+ </message>
+ <message>
+ <source>&amp;Verify Message</source>
+ <translation>&amp;Firmar Mensaje</translation>
+ </message>
+ <message>
+ <source>Verify &amp;Message</source>
+ <translation>&amp;Firmar Mensaje</translation>
+ </message>
+ <message>
+ <source>Click "Sign Message" to generate signature</source>
+ <translation>Click en "Firmar Mensage" para conseguir firma</translation>
+ </message>
+ <message>
+ <source>Please check the address and try again.</source>
+ <translation>Por favor, revise la dirección Bitcoin e inténtelo denuevo</translation>
+ </message>
+ <message>
+ <source>Wallet unlock was cancelled.</source>
+ <translation>Ha fallado el desbloqueo de la billetera</translation>
+ </message>
+ <message>
+ <source>Message signing failed.</source>
+ <translation>Firma fallida</translation>
+ </message>
+ <message>
+ <source>Message signed.</source>
+ <translation>Mensaje firmado</translation>
+ </message>
+ <message>
+ <source>Message verified.</source>
+ <translation>Mensaje comprobado</translation>
+ </message>
+</context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>bitcoin core</translation>
+ </message>
+ <message>
+ <source>[testnet]</source>
+ <translation>[red-de-pruebas]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ <message>
+ <source>KB/s</source>
+ <translation>KB/s</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>Abierto hasta %1</translation>
+ </message>
+ <message>
+ <source>%1/offline</source>
+ <translation>%1/fuera de linea</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/no confirmado</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 confirmaciónes</translation>
+ </message>
+ <message>
+ <source>Status</source>
+ <translation>Estado</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Fecha</translation>
+ </message>
+ <message>
+ <source>Generated</source>
+ <translation>Generado</translation>
+ </message>
+ <message>
+ <source>From</source>
+ <translation>De</translation>
+ </message>
+ <message>
+ <source>To</source>
+ <translation>A</translation>
+ </message>
+ <message>
+ <source>own address</source>
+ <translation>propia dirección</translation>
+ </message>
+ <message>
+ <source>label</source>
+ <translation>etiqueta</translation>
+ </message>
+ <message>
+ <source>Credit</source>
+ <translation>Credito</translation>
+ </message>
+ <message>
+ <source>not accepted</source>
+ <translation>no aceptada</translation>
+ </message>
+ <message>
+ <source>Debit</source>
+ <translation>Debito</translation>
+ </message>
+ <message>
+ <source>Transaction fee</source>
+ <translation>Comisión transacción</translation>
+ </message>
+ <message>
+ <source>Net amount</source>
+ <translation>Cantidad total</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Mensaje</translation>
+ </message>
+ <message>
+ <source>Comment</source>
+ <translation>Comentario</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>ID de Transacción</translation>
+ </message>
+ <message>
+ <source>Transaction</source>
+ <translation>Transacción</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Cantidad</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, no ha sido emitido satisfactoriamente todavía</translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>desconocido</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>Detalles de transacción</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>Esta ventana muestra información detallada sobre la transacción</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Fecha</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Tipo</translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>Abierto hasta %1</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>Confirmado (%1 confirmaciones)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>Este bloque no ha sido recibido por otros nodos y probablemente no sea aceptado !</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>Generado pero no acceptado</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiqueta</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Recibido con</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>Recibido de</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Enviado a</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>Pagar a usted mismo</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Minado</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(n/a)</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>Estado de transacción. Pasa el raton sobre este campo para ver el numero de confirmaciónes.</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Fecha y hora cuando se recibió la transaccion</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>Tipo de transacción.</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>Cantidad restada o añadida al balance</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>Todo</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>Hoy</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>Esta semana</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>Esta mes</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>Mes pasado</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>Este año</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>Rango...</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Recibido con</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Enviado a</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>A ti mismo</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Minado</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>Otra</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>Introduce una dirección o etiqueta para buscar</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>Cantidad minima</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Copia dirección</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Copia etiqueta</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copiar Cantidad</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>Edita etiqueta</translation>
+ </message>
+ <message>
+ <source>Show transaction details</source>
+ <translation>Mostrar detalles de la transacción</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Archivos separados por coma (*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Confirmado</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Fecha</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Tipo</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiqueta</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Dirección</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>Rango:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>para</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ </context>
+<context>
+ <name>WalletFrame</name>
+ </context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Enviar monedas</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>y exportar</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Exportar los datos de la pestaña actual a un archivo</translation>
+ </message>
+ <message>
+ <source>Backup Wallet</source>
+ <translation>Respaldar billetera</translation>
+ </message>
+ <message>
+ <source>Wallet Data (*.dat)</source>
+ <translation>Datos de billetera (*.dat)</translation>
+ </message>
+ <message>
+ <source>Backup Failed</source>
+ <translation>Ha fallado el respaldo</translation>
+ </message>
+ </context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>Opciones:
+</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>Especifica directorio para los datos
+</translation>
+ </message>
+ <message>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>Aceptar comandos consola y JSON-RPC
+</translation>
+ </message>
+ <message>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>Correr como demonio y acepta comandos
+</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>Usa la red de pruebas
+</translation>
+ </message>
+ <message>
+ <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>Precaución: -paytxfee es muy alta. Esta es la comisión que pagarás si envias una transacción.</translation>
+ </message>
+ <message>
+ <source>Connect only to the specified node(s)</source>
+ <translation>Conecta solo al nodo especificado
+</translation>
+ </message>
+ <message>
+ <source>Error loading block database</source>
+ <translation>Error cargando blkindex.dat</translation>
+ </message>
+ <message>
+ <source>Error: Disk space is low!</source>
+ <translation>Atención: Poco espacio en el disco duro</translation>
+ </message>
+ <message>
+ <source>Imports blocks from external blk000??.dat file</source>
+ <translation>Importar bloques desde el archivo externo blk000??.dat </translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Información</translation>
+ </message>
+ <message>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>Enviar informacion de seguimiento a la consola en vez del archivo debug.log</translation>
+ </message>
+ <message>
+ <source>Start minimized</source>
+ <translation>Arranca minimizado
+</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: 1 when listening)</source>
+ <translation>Intenta usar UPnP para mapear el puerto de escucha (default: 1 when listening)</translation>
+ </message>
+ <message>
+ <source>Username for JSON-RPC connections</source>
+ <translation>Usuario para las conexiones JSON-RPC
+</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Atención</translation>
+ </message>
+ <message>
+ <source>wallet.dat corrupt, salvage failed</source>
+ <translation>wallet.dat corrompió, guardado fallido</translation>
+ </message>
+ <message>
+ <source>Password for JSON-RPC connections</source>
+ <translation>Contraseña para las conexiones JSON-RPC
+</translation>
+ </message>
+ <message>
+ <source>Upgrade wallet to latest format</source>
+ <translation>Actualizar billetera al formato actual</translation>
+ </message>
+ <message>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>Rescanea la cadena de bloques para transacciones perdidas de la cartera
+</translation>
+ </message>
+ <message>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>Usa OpenSSL (https) para las conexiones JSON-RPC
+</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>Este mensaje de ayuda
+</translation>
+ </message>
+ <message>
+ <source>Allow DNS lookups for -addnode, -seednode and -connect</source>
+ <translation>Permite búsqueda DNS para addnode y connect
+</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>Cargando direcciónes...</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>Error cargando wallet.dat: Billetera corrupta</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>Error cargando wallet.dat</translation>
+ </message>
+ <message>
+ <source>Invalid -proxy address: '%s'</source>
+ <translation>Dirección -proxy invalida: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Cantidad inválida para -paytxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>Fondos insuficientes</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>Cargando el index de bloques...</translation>
+ </message>
+ <message>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>Agrega un nodo para conectarse and attempt to keep the connection open</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>Cargando cartera...</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>Rescaneando...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>Carga completa</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Error</translation>
+ </message>
+</context>
+</TS> \ No newline at end of file
diff --git a/src/qt/locale/bitcoin_es_DO.ts b/src/qt/locale/bitcoin_es_DO.ts
new file mode 100644
index 0000000000..082de1a085
--- /dev/null
+++ b/src/qt/locale/bitcoin_es_DO.ts
@@ -0,0 +1,2430 @@
+<TS language="es_DO" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Create a new address</source>
+ <translation>Crear una nueva dirección</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>Nuevo</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Copiar la dirección seleccionada al portapapeles del sistema</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>&amp;Copiar</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>&amp;Cerrar</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>&amp;Copiar dirección</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>Borrar de la lista la dirección seleccionada</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Exportar a un archivo los datos de esta pestaña</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Exportar</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;Eliminar</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>Escoja la dirección para enviar monedas</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>Escoja la dirección para recibir monedas</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>&amp;Escoger</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>Enviando dirección</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>Recibiendo dirección</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>Estas son sus direcciones Bitcoin para enviar pagos. Compruebe siempre la cantidad y la dirección receptora antes de transferir monedas.</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>Estas son sus direcciones de Bitcoin para recibir pagos. Se recomienda utilizar una nueva dirección de recepción para cada transacción.</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>Copiar &amp;etiqueta</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>&amp;Editar</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>Exportar la lista de direcciones </translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Archivos de columnas separadas por coma (*.csv)</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Error exportando</translation>
+ </message>
+ </context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Etiqueta</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Dirección</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(sin etiqueta)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Passphrase Dialog</source>
+ <translation>Diálogo de contraseña</translation>
+ </message>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Introducir contraseña</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Nueva contraseña</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Repita la nueva contraseña</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>Cifrar la cartera</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>Esta operación requiere su contraseña para desbloquear la cartera</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Desbloquear cartera</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>Esta operación requiere su contraseña para descifrar la cartera.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>Descifrar la certare</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>Cambiar contraseña</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>Confirmar cifrado de la cartera</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>Atencion: ¡Si cifra su monedero y pierde la contraseña perderá &lt;b&gt;TODOS SUS BITCOINS&lt;/b&gt;!"</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>¿Seguro que desea cifrar su monedero?</translation>
+ </message>
+ <message>
+ <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
+ <translation>IMPORTANTE: Cualquier copia de seguridad que haya realizado previamente de su archivo de monedero debe reemplazarse con el nuevo archivo de monedero cifrado. Por razones de seguridad, las copias de seguridad previas del archivo de monedero no cifradas serán inservibles en cuanto comience a usar el nuevo monedero cifrado.</translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>Aviso: ¡La tecla de bloqueo de mayúsculas está activada!</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>Monedero cifrado</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>Ha fallado el cifrado del monedero</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>Ha fallado el cifrado del monedero debido a un error interno. El monedero no ha sido cifrado.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>Las contraseñas no coinciden.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>Ha fallado el desbloqueo del monedero</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>La contraseña introducida para descifrar el monedero es incorrecta.</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>Ha fallado el descifrado del monedero</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>Se ha cambiado correctamente la contraseña del monedero.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>Firmar &amp;mensaje...</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>Sincronizando con la red…</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;Vista general</translation>
+ </message>
+ <message>
+ <source>Node</source>
+ <translation>Nodo</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>Mostrar vista general del monedero</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Transacciones</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>Examinar el historial de transacciones</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>&amp;Salir</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>Salir de la aplicación</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>Acerca de &amp;Qt</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>Mostrar información acerca de Qt</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;Opciones...</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>&amp;Cifrar monedero…</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>Copia de &amp;respaldo del monedero...</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>&amp;Cambiar la contraseña…</translation>
+ </message>
+ <message>
+ <source>&amp;Sending addresses...</source>
+ <translation>$Enviando dirección...</translation>
+ </message>
+ <message>
+ <source>&amp;Receiving addresses...</source>
+ <translation>&amp;Recibiendo dirección</translation>
+ </message>
+ <message>
+ <source>Open &amp;URI...</source>
+ <translation>Abrir URI...</translation>
+ </message>
+ <message>
+ <source>Importing blocks from disk...</source>
+ <translation>Importando bloques de disco...</translation>
+ </message>
+ <message>
+ <source>Reindexing blocks on disk...</source>
+ <translation>Reindexando bloques en disco...</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>Enviar monedas a una dirección Bitcoin</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>Copia de seguridad del monedero en otra ubicación</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Cambiar la contraseña utilizada para el cifrado del monedero</translation>
+ </message>
+ <message>
+ <source>&amp;Debug window</source>
+ <translation>Ventana de &amp;depuración</translation>
+ </message>
+ <message>
+ <source>Open debugging and diagnostic console</source>
+ <translation>Abrir la consola de depuración y diagnóstico</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>&amp;Verificar mensaje...</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>Monedero</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>&amp;Enviar</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>&amp;Recibir</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>Mo&amp;strar/ocultar</translation>
+ </message>
+ <message>
+ <source>Show or hide the main Window</source>
+ <translation>Mostrar u ocultar la ventana principal</translation>
+ </message>
+ <message>
+ <source>Encrypt the private keys that belong to your wallet</source>
+ <translation>Cifrar las claves privadas de su monedero</translation>
+ </message>
+ <message>
+ <source>Sign messages with your Bitcoin addresses to prove you own them</source>
+ <translation>Firmar mensajes con sus direcciones Bitcoin para demostrar la propiedad</translation>
+ </message>
+ <message>
+ <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source>
+ <translation>Verificar mensajes comprobando que están firmados con direcciones Bitcoin concretas</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;Archivo</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;Configuración</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>A&amp;yuda</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>Barra de pestañas</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Núcleo de Bitcoin</translation>
+ </message>
+ <message>
+ <source>Request payments (generates QR codes and bitcoin: URIs)</source>
+ <translation>Solicitar pagos (genera codigo QR y URL's de Bitcoin)</translation>
+ </message>
+ <message>
+ <source>&amp;About Bitcoin Core</source>
+ <translation>&amp;Acerca del Núcleo de Bitcoin</translation>
+ </message>
+ <message>
+ <source>Show the list of used sending addresses and labels</source>
+ <translation>Mostrar la lista de direcciones de envío y etiquetas</translation>
+ </message>
+ <message>
+ <source>Show the list of used receiving addresses and labels</source>
+ <translation>Muestra la lista de direcciones de recepción y etiquetas</translation>
+ </message>
+ <message>
+ <source>Open a bitcoin: URI or payment request</source>
+ <translation>Abrir un bitcoin: URI o petición de pago</translation>
+ </message>
+ <message>
+ <source>&amp;Command-line options</source>
+ <translation>&amp;Opciones de linea de comando</translation>
+ </message>
+ <message>
+ <source>No block source available...</source>
+ <translation>Ninguna fuente de bloques disponible ...</translation>
+ </message>
+ <message>
+ <source>%1 behind</source>
+ <translation>%1 atrás</translation>
+ </message>
+ <message>
+ <source>Last received block was generated %1 ago.</source>
+ <translation>El último bloque recibido fue generado hace %1.</translation>
+ </message>
+ <message>
+ <source>Transactions after this will not yet be visible.</source>
+ <translation>Las transacciones posteriores aún no están visibles.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Error</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Aviso</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Información</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>Actualizado</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>Actualizando...</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>Transacción enviada</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>Transacción entrante</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>El monedero está &lt;b&gt;cifrado&lt;/b&gt; y actualmente &lt;b&gt;desbloqueado&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>El monedero está &lt;b&gt;cifrado&lt;/b&gt; y actualmente &lt;b&gt;bloqueado&lt;/b&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <source>Network Alert</source>
+ <translation>Alerta de red</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Quantity:</source>
+ <translation>Cantidad:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Bytes:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Cuantía:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Prioridad:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Tasa:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Después de tasas:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Cambio:</translation>
+ </message>
+ <message>
+ <source>(un)select all</source>
+ <translation>(des)selecciona todos</translation>
+ </message>
+ <message>
+ <source>Tree mode</source>
+ <translation>Modo arbol</translation>
+ </message>
+ <message>
+ <source>List mode</source>
+ <translation>Modo lista</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Cantidad</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Fecha</translation>
+ </message>
+ <message>
+ <source>Confirmations</source>
+ <translation>Confirmaciones</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Confirmado</translation>
+ </message>
+ <message>
+ <source>Priority</source>
+ <translation>Prioridad</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Copiar dirección</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Copiar etiqueta</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copiar cantidad</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Copiar identificador de transacción</translation>
+ </message>
+ <message>
+ <source>Lock unspent</source>
+ <translation>Bloquear lo no gastado</translation>
+ </message>
+ <message>
+ <source>Unlock unspent</source>
+ <translation>Desbloquear lo no gastado</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Copiar cantidad</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Copiar donación</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Copiar después de aplicar donación</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Copiar bytes</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Copiar prioridad</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Copiar Cambio</translation>
+ </message>
+ <message>
+ <source>highest</source>
+ <translation>lo más alto</translation>
+ </message>
+ <message>
+ <source>higher</source>
+ <translation>más alto</translation>
+ </message>
+ <message>
+ <source>high</source>
+ <translation>alto</translation>
+ </message>
+ <message>
+ <source>medium-high</source>
+ <translation>medio-alto</translation>
+ </message>
+ <message>
+ <source>medium</source>
+ <translation>medio</translation>
+ </message>
+ <message>
+ <source>low-medium</source>
+ <translation>bajo-medio</translation>
+ </message>
+ <message>
+ <source>low</source>
+ <translation>bajo</translation>
+ </message>
+ <message>
+ <source>lower</source>
+ <translation>más bajo</translation>
+ </message>
+ <message>
+ <source>lowest</source>
+ <translation>lo más bajo</translation>
+ </message>
+ <message>
+ <source>(%1 locked)</source>
+ <translation>(%1 bloqueado)</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>ninguno</translation>
+ </message>
+ <message>
+ <source>yes</source>
+ <translation>si</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>no</translation>
+ </message>
+ <message>
+ <source>This means a fee of at least %1 per kB is required.</source>
+ <translation>Esto implica que se requiere una tarifa de al menos %1 por kB</translation>
+ </message>
+ <message>
+ <source>Can vary +/- 1 byte per input.</source>
+ <translation>Puede variar +/- 1 byte por entrada.</translation>
+ </message>
+ <message>
+ <source>Transactions with higher priority are more likely to get included into a block.</source>
+ <translation>Las transacciones con alta prioridad son más propensas a ser incluidas dentro de un bloque.</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(sin etiqueta)</translation>
+ </message>
+ <message>
+ <source>change from %1 (%2)</source>
+ <translation>Enviar desde %1 (%2)</translation>
+ </message>
+ <message>
+ <source>(change)</source>
+ <translation>(cambio)</translation>
+ </message>
+</context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>Editar Dirección</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>&amp;Etiqueta</translation>
+ </message>
+ <message>
+ <source>The label associated with this address list entry</source>
+ <translation>La etiqueta asociada con esta entrada de la lista de direcciones</translation>
+ </message>
+ <message>
+ <source>The address associated with this address list entry. This can only be modified for sending addresses.</source>
+ <translation>La dirección asociada con esta entrada de la lista de direcciones. Solo puede ser modificada para direcciones de envío.</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;Dirección</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>Nueva dirección de recepción</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>Nueva dirección de envío</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>Editar dirección de recepción</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>Editar dirección de envío</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>La dirección introducida "%1" ya está presente en la libreta de direcciones.</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is not a valid Bitcoin address.</source>
+ <translation>La dirección introducida "%1" no es una dirección Bitcoin válida.</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>No se pudo desbloquear el monedero.</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>Ha fallado la generación de la nueva clave.</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ <message>
+ <source>A new data directory will be created.</source>
+ <translation>Se creará un nuevo directorio de datos.</translation>
+ </message>
+ <message>
+ <source>name</source>
+ <translation>nombre</translation>
+ </message>
+ <message>
+ <source>Directory already exists. Add %1 if you intend to create a new directory here.</source>
+ <translation>El directorio ya existe. Añada %1 si pretende crear aquí un directorio nuevo.</translation>
+ </message>
+ <message>
+ <source>Path already exists, and is not a directory.</source>
+ <translation>La ruta ya existe y no es un directorio.</translation>
+ </message>
+ <message>
+ <source>Cannot create data directory here.</source>
+ <translation>No se puede crear un directorio de datos aquí.</translation>
+ </message>
+</context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Núcleo de Bitcoin</translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>versión</translation>
+ </message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>Acerca del Núcleo de Bitcoin</translation>
+ </message>
+ <message>
+ <source>Command-line options</source>
+ <translation>Opciones de la línea de órdenes</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>Uso:</translation>
+ </message>
+ <message>
+ <source>command-line options</source>
+ <translation>opciones de la línea de órdenes</translation>
+ </message>
+</context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Welcome</source>
+ <translation>Bienvenido</translation>
+ </message>
+ <message>
+ <source>Welcome to Bitcoin Core.</source>
+ <translation>Bienvenido al Núcleo de Bitcoin</translation>
+ </message>
+ <message>
+ <source>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</source>
+ <translation>Al ser la primera vez que se ejecuta el programa, puede elegir dónde almacenará sus datos Bitcoin-Qt.</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory.</source>
+ <translation>Bitcoin-Qt va a descargar y guardar una copia de la cadena de bloques de Bitcoin. Se almacenará al menos %1GB de datos en este directorio, que irá creciendo con el tiempo. El monedero se guardará también en este directorio.</translation>
+ </message>
+ <message>
+ <source>Use the default data directory</source>
+ <translation>Utilizar el directorio de datos predeterminado</translation>
+ </message>
+ <message>
+ <source>Use a custom data directory:</source>
+ <translation>Utilice un directorio de datos personalizado:</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Núcleo de Bitcoin</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Error</translation>
+ </message>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ <message>
+ <source>Open URI</source>
+ <translation>Abrir URI...</translation>
+ </message>
+ <message>
+ <source>Open payment request from URI or file</source>
+ <translation>El pago requiere una URI o archivo</translation>
+ </message>
+ <message>
+ <source>URI:</source>
+ <translation>URI:</translation>
+ </message>
+ <message>
+ <source>Select payment request file</source>
+ <translation>Seleccione archivo de sulicitud de pago</translation>
+ </message>
+ <message>
+ <source>Select payment request file to open</source>
+ <translation>Abrir archivo de solicitud de pago</translation>
+ </message>
+</context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>Opciones</translation>
+ </message>
+ <message>
+ <source>&amp;Main</source>
+ <translation>&amp;Principal</translation>
+ </message>
+ <message>
+ <source>MB</source>
+ <translation>MB</translation>
+ </message>
+ <message>
+ <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
+ <translation>Dirección IP del proxy (ej. IPv4: 127.0.0.1 / IPv6: ::1)</translation>
+ </message>
+ <message>
+ <source>Reset all client options to default.</source>
+ <translation>Restablecer todas las opciones del cliente a las predeterminadas.</translation>
+ </message>
+ <message>
+ <source>&amp;Reset Options</source>
+ <translation>&amp;Restablecer opciones</translation>
+ </message>
+ <message>
+ <source>&amp;Network</source>
+ <translation>&amp;Red</translation>
+ </message>
+ <message>
+ <source>Expert</source>
+ <translation>Experto</translation>
+ </message>
+ <message>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>Abrir automáticamente el puerto del cliente Bitcoin en el router. Esta opción solo funciona si el router admite UPnP y está activado.</translation>
+ </message>
+ <message>
+ <source>Map port using &amp;UPnP</source>
+ <translation>Mapear el puerto usando &amp;UPnP</translation>
+ </message>
+ <message>
+ <source>Proxy &amp;IP:</source>
+ <translation>Dirección &amp;IP del proxy:</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>&amp;Puerto:</translation>
+ </message>
+ <message>
+ <source>Port of the proxy (e.g. 9050)</source>
+ <translation>Puerto del servidor proxy (ej. 9050)</translation>
+ </message>
+ <message>
+ <source>&amp;Window</source>
+ <translation>&amp;Ventana</translation>
+ </message>
+ <message>
+ <source>Show only a tray icon after minimizing the window.</source>
+ <translation>Minimizar la ventana a la bandeja de iconos del sistema.</translation>
+ </message>
+ <message>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>&amp;Minimizar a la bandeja en vez de a la barra de tareas</translation>
+ </message>
+ <message>
+ <source>M&amp;inimize on close</source>
+ <translation>M&amp;inimizar al cerrar</translation>
+ </message>
+ <message>
+ <source>&amp;Display</source>
+ <translation>&amp;Interfaz</translation>
+ </message>
+ <message>
+ <source>User Interface &amp;language:</source>
+ <translation>I&amp;dioma de la interfaz de usuario</translation>
+ </message>
+ <message>
+ <source>&amp;Unit to show amounts in:</source>
+ <translation>Mostrar las cantidades en la &amp;unidad:</translation>
+ </message>
+ <message>
+ <source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
+ <translation>Elegir la subdivisión predeterminada para mostrar cantidades en la interfaz y cuando se envían monedas.</translation>
+ </message>
+ <message>
+ <source>Whether to show coin control features or not.</source>
+ <translation>Mostrar o no características de control de moneda</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>&amp;Aceptar</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>&amp;Cancelar</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>predeterminado</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>ninguno</translation>
+ </message>
+ <message>
+ <source>Confirm options reset</source>
+ <translation>Confirme el restablecimiento de las opciones</translation>
+ </message>
+ <message>
+ <source>Client restart required to activate changes.</source>
+ <translation>Reinicio del cliente para activar cambios.</translation>
+ </message>
+ <message>
+ <source>This change would require a client restart.</source>
+ <translation>Este cambio requiere reinicio por parte del cliente.</translation>
+ </message>
+ <message>
+ <source>The supplied proxy address is invalid.</source>
+ <translation>La dirección proxy indicada es inválida.</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>Desde</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>La información mostrada puede estar desactualizada. Su monedero se sincroniza automáticamente con la red Bitcoin después de que se haya establecido una conexión, pero este proceso aún no se ha completado.</translation>
+ </message>
+ <message>
+ <source>Your current spendable balance</source>
+ <translation>Su balance actual gastable</translation>
+ </message>
+ <message>
+ <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source>
+ <translation>Total de transacciones que deben ser confirmadas, y que no cuentan con el balance gastable necesario</translation>
+ </message>
+ <message>
+ <source>Immature:</source>
+ <translation>No disponible:</translation>
+ </message>
+ <message>
+ <source>Mined balance that has not yet matured</source>
+ <translation>Saldo recién minado que aún no está disponible.</translation>
+ </message>
+ <message>
+ <source>Total:</source>
+ <translation>Total:</translation>
+ </message>
+ <message>
+ <source>Your current total balance</source>
+ <translation>Su balance actual total</translation>
+ </message>
+ </context>
+<context>
+ <name>PaymentServer</name>
+ <message>
+ <source>URI handling</source>
+ <translation>Gestión de URI</translation>
+ </message>
+ <message>
+ <source>Invalid payment address %1</source>
+ <translation>Dirección de pago no válida %1</translation>
+ </message>
+ <message>
+ <source>Requested payment amount of %1 is too small (considered dust).</source>
+ <translation>La cantidad del pago solicitado (%1) es demasiado pequeña (considerada polvo).</translation>
+ </message>
+ <message>
+ <source>Payment request error</source>
+ <translation>Error en petición de pago</translation>
+ </message>
+ <message>
+ <source>Cannot start bitcoin: click-to-pay handler</source>
+ <translation>No se pudo iniciar bitcoin: manejador de pago-al-clic</translation>
+ </message>
+ <message>
+ <source>Unverified payment requests to custom payment scripts are unsupported.</source>
+ <translation>No están soportadas las peticiones inseguras a scripts de pago personalizados</translation>
+ </message>
+ <message>
+ <source>Refund from %1</source>
+ <translation>Devolución de %1</translation>
+ </message>
+ <message>
+ <source>Error communicating with %1: %2</source>
+ <translation>Error en la comunicación con %1: %2</translation>
+ </message>
+ <message>
+ <source>Bad response from server %1</source>
+ <translation>Respuesta errónea del servidor %1</translation>
+ </message>
+ <message>
+ <source>Payment acknowledged</source>
+ <translation>Pago aceptado</translation>
+ </message>
+ <message>
+ <source>Network request error</source>
+ <translation>Error en petición de red</translation>
+ </message>
+</context>
+<context>
+ <name>PeerTableModel</name>
+ </context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>Cantidad</translation>
+ </message>
+ <message>
+ <source>%1 h</source>
+ <translation>%1 h</translation>
+ </message>
+ <message>
+ <source>%1 m</source>
+ <translation>%1 m</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>N/D</translation>
+ </message>
+ </context>
+<context>
+ <name>QRImageWidget</name>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>Guardar Imagen...</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Image</source>
+ <translation>Copiar imagen</translation>
+ </message>
+ <message>
+ <source>Save QR Code</source>
+ <translation>Guardar código QR</translation>
+ </message>
+ <message>
+ <source>PNG Image (*.png)</source>
+ <translation>Imágenes PNG (*.png)</translation>
+ </message>
+</context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>Client name</source>
+ <translation>Nombre del cliente</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>N/D</translation>
+ </message>
+ <message>
+ <source>Client version</source>
+ <translation>Versión del cliente</translation>
+ </message>
+ <message>
+ <source>&amp;Information</source>
+ <translation>Información</translation>
+ </message>
+ <message>
+ <source>Debug window</source>
+ <translation>Ventana de depuración</translation>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>General</translation>
+ </message>
+ <message>
+ <source>Using OpenSSL version</source>
+ <translation>Utilizando la versión OpenSSL</translation>
+ </message>
+ <message>
+ <source>Startup time</source>
+ <translation>Hora de inicio</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Red</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>Nombre</translation>
+ </message>
+ <message>
+ <source>Number of connections</source>
+ <translation>Número de conexiones</translation>
+ </message>
+ <message>
+ <source>Block chain</source>
+ <translation>Cadena de bloques</translation>
+ </message>
+ <message>
+ <source>Current number of blocks</source>
+ <translation>Número actual de bloques</translation>
+ </message>
+ <message>
+ <source>Last block time</source>
+ <translation>Hora del último bloque</translation>
+ </message>
+ <message>
+ <source>&amp;Open</source>
+ <translation>&amp;Abrir</translation>
+ </message>
+ <message>
+ <source>&amp;Console</source>
+ <translation>&amp;Consola</translation>
+ </message>
+ <message>
+ <source>&amp;Network Traffic</source>
+ <translation>&amp;Tráfico de Red</translation>
+ </message>
+ <message>
+ <source>&amp;Clear</source>
+ <translation>&amp;Limpiar</translation>
+ </message>
+ <message>
+ <source>Totals</source>
+ <translation>Total:</translation>
+ </message>
+ <message>
+ <source>In:</source>
+ <translation>Dentro:</translation>
+ </message>
+ <message>
+ <source>Out:</source>
+ <translation>Fuera:</translation>
+ </message>
+ <message>
+ <source>Build date</source>
+ <translation>Fecha de compilación</translation>
+ </message>
+ <message>
+ <source>Debug log file</source>
+ <translation>Archivo de registro de depuración</translation>
+ </message>
+ <message>
+ <source>Clear console</source>
+ <translation>Borrar consola</translation>
+ </message>
+ <message>
+ <source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
+ <translation>Use las flechas arriba y abajo para navegar por el historial y &lt;b&gt;Control+L&lt;/b&gt; para limpiar la pantalla.</translation>
+ </message>
+ <message>
+ <source>Type &lt;b&gt;help&lt;/b&gt; for an overview of available commands.</source>
+ <translation>Escriba &lt;b&gt;help&lt;/b&gt; para ver un resumen de los comandos disponibles.</translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation>%1 B</translation>
+ </message>
+ <message>
+ <source>%1 KB</source>
+ <translation>%1 KB</translation>
+ </message>
+ <message>
+ <source>%1 MB</source>
+ <translation>%1 MB</translation>
+ </message>
+ <message>
+ <source>%1 GB</source>
+ <translation>%1 GB</translation>
+ </message>
+ </context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Amount:</source>
+ <translation>Cantidad</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Etiqueta:</translation>
+ </message>
+ <message>
+ <source>&amp;Message:</source>
+ <translation>Mensaje:</translation>
+ </message>
+ <message>
+ <source>Reuse one of the previously used receiving addresses. Reusing addresses has security and privacy issues. Do not use this unless re-generating a payment request made before.</source>
+ <translation>Reutilizar una de las direcciones previamente usadas para recibir. Reutilizar direcciones tiene problemas de seguridad y privacidad. No lo uses a menos que antes regeneres una solicitud de pago.</translation>
+ </message>
+ <message>
+ <source>R&amp;euse an existing receiving address (not recommended)</source>
+ <translation>R&amp;eutilizar una dirección existente para recibir (no recomendado)</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Limpiar todos los campos del formulario</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation>Limpiar</translation>
+ </message>
+ <message>
+ <source>&amp;Request payment</source>
+ <translation>&amp;Solicitar pago</translation>
+ </message>
+ <message>
+ <source>Show the selected request (does the same as double clicking an entry)</source>
+ <translation>Muestra la petición seleccionada (También doble clic)</translation>
+ </message>
+ <message>
+ <source>Show</source>
+ <translation>Mostrar</translation>
+ </message>
+ <message>
+ <source>Remove the selected entries from the list</source>
+ <translation>Borrar de la lista las direcciónes actualmente seleccionadas</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>Eliminar</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Copiar etiqueta</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copiar cantidad</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>QR Code</source>
+ <translation>Código QR</translation>
+ </message>
+ <message>
+ <source>Copy &amp;URI</source>
+ <translation>Copiar &amp;URI</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Address</source>
+ <translation>Copiar &amp;Dirección</translation>
+ </message>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>Guardar Imagen...</translation>
+ </message>
+ <message>
+ <source>Request payment to %1</source>
+ <translation>Solicitar pago a %1</translation>
+ </message>
+ <message>
+ <source>Payment information</source>
+ <translation>Información de pago</translation>
+ </message>
+ <message>
+ <source>URI</source>
+ <translation>URI</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Dirección</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Cantidad</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiqueta</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Mensaje</translation>
+ </message>
+ <message>
+ <source>Resulting URI too long, try to reduce the text for label / message.</source>
+ <translation>URI resultante demasiado larga. Intente reducir el texto de la etiqueta / mensaje.</translation>
+ </message>
+ <message>
+ <source>Error encoding URI into QR Code.</source>
+ <translation>Error al codificar la URI en el código QR.</translation>
+ </message>
+</context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Fecha</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiqueta</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Mensaje</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Cantidad</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(sin etiqueta)</translation>
+ </message>
+ <message>
+ <source>(no message)</source>
+ <translation>(Ningun mensaje)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Enviar monedas</translation>
+ </message>
+ <message>
+ <source>Coin Control Features</source>
+ <translation>Características de control de la moneda</translation>
+ </message>
+ <message>
+ <source>Inputs...</source>
+ <translation>Entradas...</translation>
+ </message>
+ <message>
+ <source>automatically selected</source>
+ <translation>Seleccionado automaticamente</translation>
+ </message>
+ <message>
+ <source>Insufficient funds!</source>
+ <translation>Fondos insuficientes!</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Cantidad:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Bytes:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Cuantía:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Prioridad:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Tasa:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Después de tasas:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Cambio:</translation>
+ </message>
+ <message>
+ <source>If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address.</source>
+ <translation>Al activarse, si la dirección esta vacía o es inválida, las monedas serán enviadas a una nueva dirección generada.</translation>
+ </message>
+ <message>
+ <source>Custom change address</source>
+ <translation>Dirección propia</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>Enviar a múltiples destinatarios de una vez</translation>
+ </message>
+ <message>
+ <source>Add &amp;Recipient</source>
+ <translation>Añadir &amp;destinatario</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Limpiar todos los campos del formulario</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Limpiar &amp;todo</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>Saldo:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>Confirmar el envío</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>&amp;Enviar</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>Confirmar el envío de monedas</translation>
+ </message>
+ <message>
+ <source>%1 to %2</source>
+ <translation>%1 a %2</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Copiar cantidad</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copiar cantidad</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Copiar donación</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Copiar después de aplicar donación</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Copiar bytes</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Copiar prioridad</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Copiar Cambio</translation>
+ </message>
+ <message>
+ <source>or</source>
+ <translation>o</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>La cantidad por pagar tiene que ser mayor de 0.</translation>
+ </message>
+ <message>
+ <source>The amount exceeds your balance.</source>
+ <translation>La cantidad sobrepasa su saldo.</translation>
+ </message>
+ <message>
+ <source>The total exceeds your balance when the %1 transaction fee is included.</source>
+ <translation>El total sobrepasa su saldo cuando se incluye la tasa de envío de %1</translation>
+ </message>
+ <message>
+ <source>Transaction creation failed!</source>
+ <translation>¡Ha fallado la creación de la transacción!</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>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.</translation>
+ </message>
+ <message>
+ <source>Warning: Invalid Bitcoin address</source>
+ <translation>Alerta: Dirección de Bitcoin inválida</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(sin etiqueta)</translation>
+ </message>
+ <message>
+ <source>Warning: Unknown change address</source>
+ <translation>Alerta: Dirección de Bitcoin inválida</translation>
+ </message>
+ <message>
+ <source>Are you sure you want to send?</source>
+ <translation>¿Está seguro que desea enviar?</translation>
+ </message>
+ <message>
+ <source>added as transaction fee</source>
+ <translation>añadido como comisión de transacción</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>Ca&amp;ntidad:</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>&amp;Pagar a:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Etiquete esta dirección para añadirla a la libreta</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Etiqueta:</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Escoger dirección previamente usada</translation>
+ </message>
+ <message>
+ <source>This is a normal payment.</source>
+ <translation>Esto es un pago ordinario.</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Pegar dirección desde portapapeles</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Remove this entry</source>
+ <translation>Eliminar esta transacción</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to the list of used addresses</source>
+ <translation>Introduce una etiqueta para esta dirección para añadirla a la lista de direcciones utilizadas</translation>
+ </message>
+ <message>
+ <source>Pay To:</source>
+ <translation>Paga a:</translation>
+ </message>
+ <message>
+ <source>Memo:</source>
+ <translation>Memo:</translation>
+ </message>
+</context>
+<context>
+ <name>ShutdownWindow</name>
+ </context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Signatures - Sign / Verify a Message</source>
+ <translation>Firmas - Firmar / verificar un mensaje</translation>
+ </message>
+ <message>
+ <source>&amp;Sign Message</source>
+ <translation>&amp;Firmar mensaje</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Escoger dirección previamente usada</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Pegar dirección desde portapapeles</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Enter the message you want to sign here</source>
+ <translation>Introduzca el mensaje que desea firmar aquí</translation>
+ </message>
+ <message>
+ <source>Signature</source>
+ <translation>Firma</translation>
+ </message>
+ <message>
+ <source>Copy the current signature to the system clipboard</source>
+ <translation>Copiar la firma actual al portapapeles del sistema</translation>
+ </message>
+ <message>
+ <source>Sign the message to prove you own this Bitcoin address</source>
+ <translation>Firmar el mensaje para demostrar que se posee esta dirección Bitcoin</translation>
+ </message>
+ <message>
+ <source>Sign &amp;Message</source>
+ <translation>Firmar &amp;mensaje</translation>
+ </message>
+ <message>
+ <source>Reset all sign message fields</source>
+ <translation>Limpiar todos los campos de la firma de mensaje</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Limpiar &amp;todo</translation>
+ </message>
+ <message>
+ <source>&amp;Verify Message</source>
+ <translation>&amp;Verificar mensaje</translation>
+ </message>
+ <message>
+ <source>Verify the message to ensure it was signed with the specified Bitcoin address</source>
+ <translation>Verificar el mensaje para comprobar que fue firmado con la dirección Bitcoin indicada</translation>
+ </message>
+ <message>
+ <source>Verify &amp;Message</source>
+ <translation>Verificar &amp;mensaje</translation>
+ </message>
+ <message>
+ <source>Reset all verify message fields</source>
+ <translation>Limpiar todos los campos de la verificación de mensaje</translation>
+ </message>
+ <message>
+ <source>Click "Sign Message" to generate signature</source>
+ <translation>Haga clic en "Firmar mensaje" para generar la firma</translation>
+ </message>
+ <message>
+ <source>The entered address is invalid.</source>
+ <translation>La dirección introducida es inválida.</translation>
+ </message>
+ <message>
+ <source>Please check the address and try again.</source>
+ <translation>Verifique la dirección e inténtelo de nuevo.</translation>
+ </message>
+ <message>
+ <source>The entered address does not refer to a key.</source>
+ <translation>La dirección introducida no corresponde a una clave.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock was cancelled.</source>
+ <translation>Se ha cancelado el desbloqueo del monedero. </translation>
+ </message>
+ <message>
+ <source>Private key for the entered address is not available.</source>
+ <translation>No se dispone de la clave privada para la dirección introducida.</translation>
+ </message>
+ <message>
+ <source>Message signing failed.</source>
+ <translation>Ha fallado la firma del mensaje.</translation>
+ </message>
+ <message>
+ <source>Message signed.</source>
+ <translation>Mensaje firmado.</translation>
+ </message>
+ <message>
+ <source>The signature could not be decoded.</source>
+ <translation>No se puede decodificar la firma.</translation>
+ </message>
+ <message>
+ <source>Please check the signature and try again.</source>
+ <translation>Compruebe la firma e inténtelo de nuevo.</translation>
+ </message>
+ <message>
+ <source>The signature did not match the message digest.</source>
+ <translation>La firma no coincide con el resumen del mensaje.</translation>
+ </message>
+ <message>
+ <source>Message verification failed.</source>
+ <translation>La verificación del mensaje ha fallado.</translation>
+ </message>
+ <message>
+ <source>Message verified.</source>
+ <translation>Mensaje verificado.</translation>
+ </message>
+</context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Núcleo de Bitcoin</translation>
+ </message>
+ <message>
+ <source>The Bitcoin Core developers</source>
+ <translation>Los desarrolladores del Núcleo de Bitcoin</translation>
+ </message>
+ <message>
+ <source>[testnet]</source>
+ <translation>[testnet]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ <message>
+ <source>KB/s</source>
+ <translation>KB/s</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>Abierto hasta %1</translation>
+ </message>
+ <message>
+ <source>%1/offline</source>
+ <translation>%1/fuera de línea</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/no confirmado</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 confirmaciones</translation>
+ </message>
+ <message>
+ <source>Status</source>
+ <translation>Estado</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Fecha</translation>
+ </message>
+ <message>
+ <source>Source</source>
+ <translation>Fuente</translation>
+ </message>
+ <message>
+ <source>Generated</source>
+ <translation>Generado</translation>
+ </message>
+ <message>
+ <source>From</source>
+ <translation>De</translation>
+ </message>
+ <message>
+ <source>To</source>
+ <translation>Para</translation>
+ </message>
+ <message>
+ <source>own address</source>
+ <translation>dirección propia</translation>
+ </message>
+ <message>
+ <source>label</source>
+ <translation>etiqueta</translation>
+ </message>
+ <message>
+ <source>Credit</source>
+ <translation>Crédito</translation>
+ </message>
+ <message>
+ <source>not accepted</source>
+ <translation>no aceptada</translation>
+ </message>
+ <message>
+ <source>Debit</source>
+ <translation>Débito</translation>
+ </message>
+ <message>
+ <source>Transaction fee</source>
+ <translation>Comisión de transacción</translation>
+ </message>
+ <message>
+ <source>Net amount</source>
+ <translation>Cantidad neta</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Mensaje</translation>
+ </message>
+ <message>
+ <source>Comment</source>
+ <translation>Comentario</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>Merchant</source>
+ <translation>Vendedor</translation>
+ </message>
+ <message>
+ <source>Generated coins must mature %1 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.</source>
+ <translation>Las monedas generadas deben madurar %1 bloques antes de que puedan ser gastadas. Una vez que generas este bloque, es propagado por la red para ser añadido a la cadena de bloques. Si falla el intento de meterse en la cadena, su estado cambiará a "no aceptado" y ya no se puede gastar. Esto puede ocurrir ocasionalmente si otro nodo genera un bloque a pocos segundos del tuyo.</translation>
+ </message>
+ <message>
+ <source>Debug information</source>
+ <translation>Información de depuración</translation>
+ </message>
+ <message>
+ <source>Transaction</source>
+ <translation>Transacción</translation>
+ </message>
+ <message>
+ <source>Inputs</source>
+ <translation>entradas</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Cantidad</translation>
+ </message>
+ <message>
+ <source>true</source>
+ <translation>verdadero</translation>
+ </message>
+ <message>
+ <source>false</source>
+ <translation>falso</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, todavía no se ha sido difundido satisfactoriamente</translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>desconocido</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>Detalles de transacción</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>Esta ventana muestra información detallada sobre la transacción</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Fecha</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Tipo</translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>Abierto hasta %1</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>Confirmado (%1 confirmaciones)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>Este bloque no ha sido recibido por otros nodos y probablemente no sea aceptado!</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>Generado pero no aceptado</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiqueta</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Recibido con</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>Recibidos de</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Enviado a</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>Pago propio</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Minado</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(nd)</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>Estado de transacción. Pasa el ratón sobre este campo para ver el número de confirmaciones.</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Fecha y hora en que se recibió la transacción.</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>Tipo de transacción.</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>Cantidad retirada o añadida al saldo.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>Todo</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>Hoy</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>Esta semana</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>Este mes</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>Mes pasado</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>Este año</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>Rango...</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Recibido con</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Enviado a</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>A usted mismo</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Minado</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>Otra</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>Introduzca una dirección o etiqueta que buscar</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>Cantidad mínima</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Copiar dirección</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Copiar etiqueta</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copiar cantidad</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Copiar identificador de transacción</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>Editar etiqueta</translation>
+ </message>
+ <message>
+ <source>Show transaction details</source>
+ <translation>Mostrar detalles de la transacción</translation>
+ </message>
+ <message>
+ <source>Export Transaction History</source>
+ <translation>Exportar historial de transacciones</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Error exportando</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the transaction history to %1.</source>
+ <translation>Ha habido un error al intentar guardar la transacción con %1.</translation>
+ </message>
+ <message>
+ <source>Exporting Successful</source>
+ <translation>Exportación finalizada</translation>
+ </message>
+ <message>
+ <source>The transaction history was successfully saved to %1.</source>
+ <translation>La transacción ha sido guardada en %1.</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Archivos de columnas separadas por coma (*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Confirmado</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Fecha</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Tipo</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiqueta</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Dirección</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>Rango:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>para</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ </context>
+<context>
+ <name>WalletFrame</name>
+ <message>
+ <source>No wallet has been loaded.</source>
+ <translation>No se ha cargado ningún monedero</translation>
+ </message>
+</context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Enviar monedas</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Exportar</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Exportar a un archivo los datos de esta pestaña</translation>
+ </message>
+ <message>
+ <source>Backup Wallet</source>
+ <translation>Respaldo de monedero</translation>
+ </message>
+ <message>
+ <source>Wallet Data (*.dat)</source>
+ <translation>Datos de monedero (*.dat)</translation>
+ </message>
+ <message>
+ <source>Backup Failed</source>
+ <translation>Ha fallado el respaldo</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the wallet data to %1.</source>
+ <translation>Ha habido un error al intentar guardar los datos del monedero en %1.</translation>
+ </message>
+ <message>
+ <source>The wallet data was successfully saved to %1.</source>
+ <translation>Los datos del monedero se han guardado con éxito en %1.</translation>
+ </message>
+ <message>
+ <source>Backup Successful</source>
+ <translation>Se ha completado con éxito la copia de respaldo</translation>
+ </message>
+</context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>Opciones:
+</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>Especificar directorio para los datos</translation>
+ </message>
+ <message>
+ <source>Connect to a node to retrieve peer addresses, and disconnect</source>
+ <translation>Conectar a un nodo para obtener direcciones de pares y desconectar</translation>
+ </message>
+ <message>
+ <source>Specify your own public address</source>
+ <translation>Especifique su propia dirección pública</translation>
+ </message>
+ <message>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>Aceptar comandos consola y JSON-RPC
+</translation>
+ </message>
+ <message>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>Ejecutar en segundo plano como daemon y aceptar comandos
+</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>Usar la red de pruebas
+</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
+ <translation>Aceptar conexiones desde el exterior (predeterminado: 1 si no -proxy o -connect)</translation>
+ </message>
+ <message>
+ <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
+ <translation>Vincular a la dirección dada y escuchar siempre en ella. Utilice la notación [host]:port para IPv6</translation>
+ </message>
+ <message>
+ <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
+ <translation>Ejecutar comando cuando una transacción del monedero cambia (%s en cmd se remplazará por TxID)</translation>
+ </message>
+ <message>
+ <source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source>
+ <translation>Esta es una versión de pre-prueba - utilícela bajo su propio riesgo. No la utilice para usos comerciales o de minería.</translation>
+ </message>
+ <message>
+ <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>Aviso: ¡-paytxfee tiene un valor muy alto! Esta es la comisión que pagará si envía una transacción.</translation>
+ </message>
+ <message>
+ <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source>
+ <translation>Atención: ¡Parece que la red no está totalmente de acuerdo! Algunos mineros están presentando inconvenientes.</translation>
+ </message>
+ <message>
+ <source>Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.</source>
+ <translation>Atención: ¡Parece que no estamos completamente de acuerdo con nuestros pares! Podría necesitar una actualización, u otros nodos podrían necesitarla.</translation>
+ </message>
+ <message>
+ <source>Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
+ <translation>Aviso: ¡Error al leer wallet.dat! Todas las claves se han leído correctamente, pero podrían faltar o ser incorrectos los datos de transacciones o las entradas de la libreta de direcciones.</translation>
+ </message>
+ <message>
+ <source>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</source>
+ <translation>Aviso: ¡Recuperados datos de wallet.dat corrupto! El wallet.dat original se ha guardado como wallet.{timestamp}.bak en %s; si hubiera errores en su saldo o transacciones, deberá restaurar una copia de seguridad.</translation>
+ </message>
+ <message>
+ <source>&lt;category&gt; can be:</source>
+ <translation>&lt;category&gt; puede ser:</translation>
+ </message>
+ <message>
+ <source>Attempt to recover private keys from a corrupt wallet.dat</source>
+ <translation>Intento de recuperar claves privadas de un wallet.dat corrupto</translation>
+ </message>
+ <message>
+ <source>Block creation options:</source>
+ <translation>Opciones de creación de bloques:</translation>
+ </message>
+ <message>
+ <source>Connect only to the specified node(s)</source>
+ <translation>Conectar sólo a los nodos (o nodo) especificados</translation>
+ </message>
+ <message>
+ <source>Corrupted block database detected</source>
+ <translation>Corrupción de base de datos de bloques detectada.</translation>
+ </message>
+ <message>
+ <source>Do you want to rebuild the block database now?</source>
+ <translation>¿Quieres reconstruir la base de datos de bloques ahora?</translation>
+ </message>
+ <message>
+ <source>Error initializing block database</source>
+ <translation>Error al inicializar la base de datos de bloques</translation>
+ </message>
+ <message>
+ <source>Error initializing wallet database environment %s!</source>
+ <translation>Error al inicializar el entorno de la base de datos del monedero %s</translation>
+ </message>
+ <message>
+ <source>Error loading block database</source>
+ <translation>Error cargando base de datos de bloques</translation>
+ </message>
+ <message>
+ <source>Error opening block database</source>
+ <translation>Error al abrir base de datos de bloques.</translation>
+ </message>
+ <message>
+ <source>Error: Disk space is low!</source>
+ <translation>Error: ¡Espacio en disco bajo!</translation>
+ </message>
+ <message>
+ <source>Failed to listen on any port. Use -listen=0 if you want this.</source>
+ <translation>Ha fallado la escucha en todos los puertos. Use -listen=0 si desea esto.</translation>
+ </message>
+ <message>
+ <source>If &lt;category&gt; is not supplied, output all debugging information.</source>
+ <translation>Si no se proporciona &lt;category&gt;, mostrar toda la depuración</translation>
+ </message>
+ <message>
+ <source>Incorrect or no genesis block found. Wrong datadir for network?</source>
+ <translation>Incorrecto o bloque de génesis no encontrado. Datadir equivocada para la red?</translation>
+ </message>
+ <message>
+ <source>Invalid -onion address: '%s'</source>
+ <translation>Dirección -onion inválida: '%s'</translation>
+ </message>
+ <message>
+ <source>Not enough file descriptors available.</source>
+ <translation>No hay suficientes descriptores de archivo disponibles. </translation>
+ </message>
+ <message>
+ <source>Set maximum block size in bytes (default: %d)</source>
+ <translation>Establecer tamaño máximo de bloque en bytes (por defecto: %d)</translation>
+ </message>
+ <message>
+ <source>Specify wallet file (within data directory)</source>
+ <translation>Especificar archivo de monedero (dentro del directorio de datos)</translation>
+ </message>
+ <message>
+ <source>Verifying blocks...</source>
+ <translation>Verificando bloques...</translation>
+ </message>
+ <message>
+ <source>Verifying wallet...</source>
+ <translation>Verificando monedero...</translation>
+ </message>
+ <message>
+ <source>Wallet %s resides outside data directory %s</source>
+ <translation>El monedero %s se encuentra fuera del directorio de datos %s</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to change -txindex</source>
+ <translation>Usted necesita reconstruir la base de datos utilizando -reindex para cambiar -txindex</translation>
+ </message>
+ <message>
+ <source>Imports blocks from external blk000??.dat file</source>
+ <translation>Importa los bloques desde un archivo blk000??.dat externo</translation>
+ </message>
+ <message>
+ <source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source>
+ <translation>Ejecutar un comando cuando se reciba una alerta importante o cuando veamos un fork demasiado largo (%s en cmd se reemplazará por el mensaje)</translation>
+ </message>
+ <message>
+ <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
+ <translation>Establecer tamaño máximo de las transacciones de alta prioridad/comisión baja en bytes (por defecto: %d)</translation>
+ </message>
+ <message>
+ <source>Choose data directory on startup (default: 0)</source>
+ <translation>Elegir directorio de datos al iniciar (predeterminado: 0)</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Información</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -minrelaytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Inválido por el monto -minrelaytxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -mintxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Inválido por el monto -mintxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source>
+ <translation>Opciones RPC SSL: (Vea la Wiki de Bitcoin para las instrucciones de la configuración de SSL)</translation>
+ </message>
+ <message>
+ <source>RPC server options:</source>
+ <translation>Opciones del sservidor RPC:</translation>
+ </message>
+ <message>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>Enviar información de trazas/depuración a la consola en lugar de al archivo debug.log</translation>
+ </message>
+ <message>
+ <source>Set language, for example "de_DE" (default: system locale)</source>
+ <translation>Establecer el idioma, por ejemplo, "es_ES" (predeterminado: configuración regional del sistema)</translation>
+ </message>
+ <message>
+ <source>Show all debugging options (usage: --help -help-debug)</source>
+ <translation>Mostrar todas las opciones de depuración (uso: --help -help-debug)</translation>
+ </message>
+ <message>
+ <source>Show splash screen on startup (default: 1)</source>
+ <translation>Mostrar pantalla de bienvenida en el inicio (predeterminado: 1)</translation>
+ </message>
+ <message>
+ <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source>
+ <translation>Reducir el archivo debug.log al iniciar el cliente (predeterminado: 1 sin -debug)</translation>
+ </message>
+ <message>
+ <source>Signing transaction failed</source>
+ <translation>Transacción falló</translation>
+ </message>
+ <message>
+ <source>Start minimized</source>
+ <translation>Arrancar minimizado</translation>
+ </message>
+ <message>
+ <source>Transaction amount too small</source>
+ <translation>Monto de la transacción muy pequeño</translation>
+ </message>
+ <message>
+ <source>Transaction amounts must be positive</source>
+ <translation>Montos de transacciones deben ser positivos</translation>
+ </message>
+ <message>
+ <source>Transaction too large</source>
+ <translation>Transacción demasiado grande</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: 1 when listening)</source>
+ <translation>Usar UPnP para asignar el puerto de escucha (predeterminado: 1 al escuchar)</translation>
+ </message>
+ <message>
+ <source>Username for JSON-RPC connections</source>
+ <translation>Nombre de usuario para las conexiones JSON-RPC
+</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Aviso</translation>
+ </message>
+ <message>
+ <source>on startup</source>
+ <translation>al iniciar</translation>
+ </message>
+ <message>
+ <source>wallet.dat corrupt, salvage failed</source>
+ <translation>wallet.dat corrupto. Ha fallado la recuperación.</translation>
+ </message>
+ <message>
+ <source>Password for JSON-RPC connections</source>
+ <translation>Contraseña para las conexiones JSON-RPC
+</translation>
+ </message>
+ <message>
+ <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
+ <translation>Ejecutar un comando cuando cambia el mejor bloque (%s en cmd se sustituye por el hash de bloque)</translation>
+ </message>
+ <message>
+ <source>Upgrade wallet to latest format</source>
+ <translation>Actualizar el monedero al último formato</translation>
+ </message>
+ <message>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>Volver a examinar la cadena de bloques en busca de transacciones del monedero perdidas</translation>
+ </message>
+ <message>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>Usar OpenSSL (https) para las conexiones JSON-RPC
+</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>Este mensaje de ayuda
+</translation>
+ </message>
+ <message>
+ <source>Allow DNS lookups for -addnode, -seednode and -connect</source>
+ <translation>Permitir búsquedas DNS para -addnode, -seednode y -connect</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>Cargando direcciones...</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>Error al cargar wallet.dat: el monedero está dañado</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>Error al cargar wallet.dat</translation>
+ </message>
+ <message>
+ <source>Invalid -proxy address: '%s'</source>
+ <translation>Dirección -proxy inválida: '%s'</translation>
+ </message>
+ <message>
+ <source>Unknown network specified in -onlynet: '%s'</source>
+ <translation>La red especificada en -onlynet '%s' es desconocida</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -bind address: '%s'</source>
+ <translation>No se puede resolver la dirección de -bind: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -externalip address: '%s'</source>
+ <translation>No se puede resolver la dirección de -externalip: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Cantidad inválida para -paytxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>Fondos insuficientes</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>Cargando el índice de bloques...</translation>
+ </message>
+ <message>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>Añadir un nodo al que conectarse y tratar de mantener la conexión abierta</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>Cargando monedero...</translation>
+ </message>
+ <message>
+ <source>Cannot downgrade wallet</source>
+ <translation>No se puede rebajar el monedero</translation>
+ </message>
+ <message>
+ <source>Cannot write default address</source>
+ <translation>No se puede escribir la dirección predeterminada</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>Reexplorando...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>Generado pero no aceptado</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Error</translation>
+ </message>
+</context>
+</TS> \ No newline at end of file
diff --git a/src/qt/locale/bitcoin_es_MX.ts b/src/qt/locale/bitcoin_es_MX.ts
new file mode 100644
index 0000000000..d6af5222f3
--- /dev/null
+++ b/src/qt/locale/bitcoin_es_MX.ts
@@ -0,0 +1,1094 @@
+<TS language="es_MX" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Create a new address</source>
+ <translation>Crear una dirección nueva</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>&amp;Nuevo</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Copiar el domicilio seleccionado al portapapeles del sistema</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>&amp;Copiar</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>Cerrar</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>&amp;Copiar dirección</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>Eliminar la dirección actualmente seleccionada de la lista</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Exportar la información en la tabla actual a un archivo</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Exportar</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;Borrar</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>Elija una dirección a la cual enviar monedas</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>Elija la dirección con la cual recibir monedas</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>Elegir</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>Enviando direcciones</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>Recibiendo direcciones</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>Estas son tus direcciones de Bitcoin para enviar pagos. Siempre revise la cantidad y la dirección receptora antes de enviar monedas</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>Estas son tus direcciones Bitcoin para recibir pagos. Es recomendado usar una nueva dirección receptora para cada transacción.</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>Copiar &amp;Etiqueta</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>&amp;Editar</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>Exportar Lista de direcciones</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Arhchivo separado por comas (*.CSV)</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Exportación fallida</translation>
+ </message>
+ </context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Etiqueta</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Domicilio</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(sin etiqueta)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Ingrese la contraseña</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Nueva contraseña</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Repita la nueva contraseña</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>Encriptar cartera.</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>Esta operación necesita la contraseña de su cartera para desbloquear su cartera.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Desbloquear cartera.</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>Esta operación necesita la contraseña de su cartera para desencriptar su cartera.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>Desencriptar cartera</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>Cambiar contraseña</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>Confirmar la encriptación de cartera</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>Advertencia: Si encripta su cartera y pierde su contraseña, &lt;b&gt;PERDERÁ TODOS SUS BITCOINS&lt;/b&gt;!</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>¿Está seguro que desea encriptar su cartera?</translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>Advertencia: ¡La tecla Bloq Mayus está activada!</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>Cartera encriptada</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>Encriptación de la cartera fallida</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>La encriptación de la cartera falló debido a un error interno. Su cartera no fue encriptada.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>Las contraseñas dadas no coinciden</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>El desbloqueo de la cartera falló</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>La contraseña ingresada para la desencriptación de la cartera es incorrecto</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>La desencriptación de la cartera fallo</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>La contraseña de la cartera ha sido exitosamente cambiada.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>Sign &amp;mensaje</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>Sincronizando con la red...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;Vista previa</translation>
+ </message>
+ <message>
+ <source>Node</source>
+ <translation>Nodo</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>Mostrar la vista previa general de la cartera</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Transacciones</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>Explorar el historial de transacciones</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>S&amp;alir</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>Salir de la aplicación</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>Acerca de &amp;Qt</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>Mostrar información acerca de Qt</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;Opciones</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>&amp;Encriptar cartera</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>&amp;Respaldar cartera</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>&amp;Cambiar contraseña...</translation>
+ </message>
+ <message>
+ <source>&amp;Sending addresses...</source>
+ <translation>&amp;Enviando direcciones...</translation>
+ </message>
+ <message>
+ <source>&amp;Receiving addresses...</source>
+ <translation>&amp;Recibiendo direcciones...</translation>
+ </message>
+ <message>
+ <source>Open &amp;URI...</source>
+ <translation>Abrir &amp;URL...</translation>
+ </message>
+ <message>
+ <source>Importing blocks from disk...</source>
+ <translation>Importando bloques desde el disco...</translation>
+ </message>
+ <message>
+ <source>Reindexing blocks on disk...</source>
+ <translation>Reindexando bloques en el disco...</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>Enviar monedas a una dirección Bitcoin</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>Respaldar cartera en otra ubicación</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Cambiar la contraseña usada para la encriptación de la cartera</translation>
+ </message>
+ <message>
+ <source>&amp;Debug window</source>
+ <translation>&amp;Depurar ventana</translation>
+ </message>
+ <message>
+ <source>Open debugging and diagnostic console</source>
+ <translation>Abrir la consola de depuración y disgnostico</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>&amp;Verificar mensaje...</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;Archivo</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;Configuraciones</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>&amp;Ayuda</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>Pestañas</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>nucleo Bitcoin</translation>
+ </message>
+ <message>
+ <source>&amp;Command-line options</source>
+ <translation>opciones de la &amp;Linea de comandos</translation>
+ </message>
+ <message>
+ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
+ <translation>Mostrar mensaje de ayuda del nucleo de Bitcoin para optener una lista con los posibles comandos de Bitcoin</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>Actualizado al dia </translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>Resiviendo...</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>Enviar Transacción</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>Transacción entrante</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>La cartera esta &lt;b&gt;encriptada&lt;/b&gt; y &lt;b&gt;desbloqueada&lt;/b&gt; actualmente </translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>La cartera esta &lt;b&gt;encriptada&lt;/b&gt; y &lt;b&gt;bloqueada&lt;/b&gt; actualmente </translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ </context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Bytes:</source>
+ <translation>Bytes:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Monto:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Prioridad:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Cuota:</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Monto</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Fecha</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Confirmado </translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Copiar dirección </translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Copiar capa </translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>copiar monto</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>copiar cantidad</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>copiar cuota</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>copiar despues de cuota</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>copiar bytes</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>copiar prioridad</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>copiar cambio</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(sin etiqueta)</translation>
+ </message>
+ </context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>Editar dirección</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>&amp;Etiqueta</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;Dirección</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>Nueva dirección de entregas</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>Nueva dirección de entregas</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>Editar dirección de entregas</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>Editar dirección de envios</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>El domicilio ingresado "%1" ya existe en la libreta de direcciones</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>No se puede desbloquear la cartera</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>La generación de la nueva clave fallo</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ </context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>nucleo Bitcoin</translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>Versión</translation>
+ </message>
+ <message>
+ <source>(%1-bit)</source>
+ <translation>(%1-bit)</translation>
+ </message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>Acerca de Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>Uso:</translation>
+ </message>
+ <message>
+ <source>command-line options</source>
+ <translation>Opciones de comando de lineas</translation>
+ </message>
+</context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>nucleo Bitcoin</translation>
+ </message>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ </context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>Opciones</translation>
+ </message>
+ <message>
+ <source>Active command-line options that override above options:</source>
+ <translation>Activar las opciones de linea de comando que sobre escriben las siguientes opciones:</translation>
+ </message>
+ </context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>Formulario</translation>
+ </message>
+ </context>
+<context>
+ <name>PaymentServer</name>
+ </context>
+<context>
+ <name>PeerTableModel</name>
+ </context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>Monto</translation>
+ </message>
+ </context>
+<context>
+ <name>QRImageWidget</name>
+ </context>
+<context>
+ <name>RPCConsole</name>
+ </context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Etiqueta</translation>
+ </message>
+ <message>
+ <source>An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network.</source>
+ <translation>Mensaje opcional para agregar a la solicitud de pago, el cual será mostrado cuando la solicitud este abierta. Nota: El mensaje no se manda con el pago a travéz de la red de Bitcoin.</translation>
+ </message>
+ <message>
+ <source>Use this form to request payments. All fields are &lt;b&gt;optional&lt;/b&gt;.</source>
+ <translation>Use este formulario para la solicitud de pagos. Todos los campos son &lt;b&gt;opcionales&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>An optional amount to request. Leave this empty or zero to not request a specific amount.</source>
+ <translation>Monto opcional a solicitar. Dejarlo vacion o en cero no solicita un monto especifico.</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Copiar capa </translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>copiar monto</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>Address</source>
+ <translation>Domicilio</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Monto</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiqueta</translation>
+ </message>
+ </context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Fecha</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiqueta</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Monto</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(sin etiqueta)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Mandar monedas</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Bytes:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Monto:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Prioridad:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Cuota:</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>Enviar a múltiples receptores a la vez</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>Saldo:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>Confirme la acción de enviar</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>Confirme para mandar monedas</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>copiar cantidad</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>copiar monto</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>copiar cuota</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>copiar despues de cuota</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>copiar bytes</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>copiar prioridad</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>copiar cambio</translation>
+ </message>
+ <message>
+ <source>or</source>
+ <translation>o</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>El monto a pagar debe ser mayor a 0</translation>
+ </message>
+ <message>
+ <source>Transaction creation failed!</source>
+ <translation>¡La creación de transacion falló!</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>¡La transación fue rechazada! Esto puede ocurrir si algunas de tus monedas en tu cartera han sido gastadas, al igual que si usas una cartera copiada y la monedas fueron gastadas en la copia pero no se marcaron como gastadas.</translation>
+ </message>
+ <message>
+ <source>Warning: Invalid Bitcoin address</source>
+ <translation>Advertencia: Dirección de Bitcoin invalida</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(sin etiqueta)</translation>
+ </message>
+ <message>
+ <source>Warning: Unknown change address</source>
+ <translation>Advertencia: Cambio de dirección desconocido</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>M&amp;onto</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>Pagar &amp;a:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Ingrese una etiqueta para esta dirección para agregarlo en su libreta de direcciones.</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Etiqueta</translation>
+ </message>
+ <message>
+ <source>This is a normal payment.</source>
+ <translation>Este es un pago normal</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Pegar dirección del portapapeles</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Remove this entry</source>
+ <translation>Quitar esta entrada</translation>
+ </message>
+ <message>
+ <source>Message:</source>
+ <translation>Mensaje:</translation>
+ </message>
+ <message>
+ <source>Pay To:</source>
+ <translation>Pago para:</translation>
+ </message>
+ </context>
+<context>
+ <name>ShutdownWindow</name>
+ <message>
+ <source>Bitcoin Core is shutting down...</source>
+ <translation>Apagando el nucleo de Bitcoin...</translation>
+ </message>
+ <message>
+ <source>Do not shut down the computer until this window disappears.</source>
+ <translation>No apague su computadora hasta que esta ventana desaparesca.</translation>
+ </message>
+</context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Pegar dirección del portapapeles</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ </context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>nucleo Bitcoin</translation>
+ </message>
+ <message>
+ <source>The Bitcoin Core developers</source>
+ <translation>Los desarrolladores de Bitcoin Core</translation>
+ </message>
+ </context>
+<context>
+ <name>TrafficGraphWidget</name>
+ </context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>Abrir hasta %1</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/No confirmado</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 confirmaciones</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Fecha</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Monto</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, no ha sido transmitido aun</translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>desconocido</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>Detalles de la transacción</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>Este panel muestras una descripción detallada de la transacción</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Fecha</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Tipo</translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>Abrir hasta %1</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>Confimado (%1 confirmaciones)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>Este bloque no fue recibido por ningun nodo y probablemente no fue aceptado !</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>Generado pero no aprovado</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiqueta</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Recivido con</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Enviar a</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>Pagar a si mismo</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Minado </translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(n/a)</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Fecha y hora en que la transacción fue recibida </translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>Escriba una transacción</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>Cantidad removida del saldo o agregada </translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>Todo</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>Hoy</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>Esta semana </translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>Este mes </translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>El mes pasado </translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>Este año</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Recivido con</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Enviar a</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>Para ti mismo</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Minado </translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>Otro</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>Ingrese dirección o capa a buscar </translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>Monto minimo </translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Copiar dirección </translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Copiar capa </translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>copiar monto</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>Editar capa </translation>
+ </message>
+ <message>
+ <source>Export Transaction History</source>
+ <translation>Exportar el historial de transacción</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Exportación fallida</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the transaction history to %1.</source>
+ <translation>Ocurrio un error intentando guardar el historial de transaciones a %1</translation>
+ </message>
+ <message>
+ <source>Exporting Successful</source>
+ <translation>Exportacion satisfactoria</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Arhchivo separado por comas (*.CSV)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Confirmado </translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Fecha</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Tipo</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiqueta</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Domicilio</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>Para</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ </context>
+<context>
+ <name>WalletFrame</name>
+ <message>
+ <source>No wallet has been loaded.</source>
+ <translation>No se há cargado la cartera.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Mandar monedas</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Exportar</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Exportar la información en la tabla actual a un archivo</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the wallet data to %1.</source>
+ <translation>Ocurrio un error tratando de guardar la información de la cartera %1</translation>
+ </message>
+ </context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>&lt;category&gt; can be:</source>
+ <translation>&lt;categoria&gt; puede ser:</translation>
+ </message>
+ <message>
+ <source>Wallet options:</source>
+ <translation>Opciones de cartera:</translation>
+ </message>
+ <message>
+ <source>Choose data directory on startup (default: 0)</source>
+ <translation>Escojer el directorio de información al iniciar (por defecto : 0)</translation>
+ </message>
+ <message>
+ <source>Set language, for example "de_DE" (default: system locale)</source>
+ <translation>Definir idioma, por ejemplo "de_DE" (por defecto: Sistema local)</translation>
+ </message>
+ <message>
+ <source>Show splash screen on startup (default: 1)</source>
+ <translation>Mostrar pantalla de arraque al iniciar (por defecto: 1)</translation>
+ </message>
+ <message>
+ <source>Start minimized</source>
+ <translation>Iniciar minimizado</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>Cargando direcciones...</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>Cargando indice de bloques... </translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>Cargando billetera...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>Carga completa</translation>
+ </message>
+ </context>
+</TS> \ No newline at end of file
diff --git a/src/qt/locale/bitcoin_es_UY.ts b/src/qt/locale/bitcoin_es_UY.ts
new file mode 100644
index 0000000000..bb99466619
--- /dev/null
+++ b/src/qt/locale/bitcoin_es_UY.ts
@@ -0,0 +1,470 @@
+<TS language="es_UY" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Create a new address</source>
+ <translation>Crear una nueva dirección </translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Copia la dirección seleccionada al portapapeles del sistema</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;Borrar</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Archivos separados por coma (*.csv)</translation>
+ </message>
+ </context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Etiqueta</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Direccion </translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(Sin etiqueta)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Escriba la contraseña</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Nueva contraseña</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Repetir nueva contraseña</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>Monedero cifrado</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>Esta operacion necesita la contraseña del monedero para desbloquear el mismo</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Monedero destrabado</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>Esta operacion necesita la contraseña del monedero para descifrar el mismo</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>Monedero descifrado</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>Cambiar contraseña</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>Confirme el cifrado del monedero</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>Monedero cifrado</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>Fallo en el cifrado del monedero</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>Fallo en el cifrado del monedero a causa de un error interno. Su monedero no esta cifrado</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>Las contraseñas suministradas no coinciden.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>Fallo en el desbloqueo del mondero</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>La contraseña introducida para el descifrado del monedero es incorrecta.</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>Fallo en el descifrado del monedero</translation>
+ </message>
+ </context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>Sincronizando con la red...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;Vista previa</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>Mostrar descripción general del monedero</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;transaciones </translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>Buscar en el historial de transacciones</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>Salir de la aplicacion </translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;Opciones...</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Cambie la clave utilizada para el cifrado del monedero</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;Archivo</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;Configuracion </translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>&amp;Ayuda</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>Barra de herramientas</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>A la fecha</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>Ponerse al dia...</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>Transaccion enviada</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>Transacción entrante</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>El Monedero esta &lt;b&gt;cifrado&lt;/b&gt; y actualmente &lt;b&gt;desbloqueado&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>El Monedero esta &lt;b&gt;cifrado&lt;/b&gt; y actualmente &lt;b&gt;bloqueado&lt;/b&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ </context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Date</source>
+ <translation>Fecha</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(Sin etiqueta)</translation>
+ </message>
+ </context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>Editar dirección</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>&amp;Etiqueta</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;Direccion </translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>Nueva dirección de recepción </translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>Nueva dirección de envío </translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>Editar dirección de recepcion </translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>Editar dirección de envío </translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>No se puede abrir el monedero.</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>Fallo en la nueva clave generada.</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ </context>
+<context>
+ <name>HelpMessageDialog</name>
+ </context>
+<context>
+ <name>Intro</name>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ </context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>Opciones</translation>
+ </message>
+ </context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>Formulario</translation>
+ </message>
+ </context>
+<context>
+ <name>PaymentServer</name>
+ </context>
+<context>
+ <name>PeerTableModel</name>
+ </context>
+<context>
+ <name>QObject</name>
+ </context>
+<context>
+ <name>QRImageWidget</name>
+ </context>
+<context>
+ <name>RPCConsole</name>
+ </context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Etiqueta:</translation>
+ </message>
+ </context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>Address</source>
+ <translation>Direccion </translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiqueta</translation>
+ </message>
+ </context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Fecha</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiqueta</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(Sin etiqueta)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Enviar monedas</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>Enviar a varios destinatarios a la vez</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>Balance:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>Confirmar el envío</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>Confirmar el envio de monedas</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>La cantidad a pagar debe ser mayor que 0.</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(Sin etiqueta)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>A&amp;Monto:</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>Pagar &amp;A:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Introduzca una etiqueta para esta dirección para añadirla a su libreta de direcciones</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Etiqueta:</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Pegar la dirección desde el portapapeles</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ </context>
+<context>
+ <name>ShutdownWindow</name>
+ </context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Pegar la dirección desde el portapapeles</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ </context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>[testnet]</source>
+ <translation>[prueba_de_red]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ </context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>Abrir hasta %1</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Fecha</translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>desconocido</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ </context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Fecha</translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>Abrir hasta %1</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiqueta</translation>
+ </message>
+ </context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Archivos separados por coma (*.csv)</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Fecha</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiqueta</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Direccion </translation>
+ </message>
+ </context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ </context>
+<context>
+ <name>WalletFrame</name>
+ </context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Enviar monedas</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ </context>
+<context>
+ <name>bitcoin-core</name>
+ </context>
+</TS> \ 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 0000000000..c746107bc7
--- /dev/null
+++ b/src/qt/locale/bitcoin_et.ts
@@ -0,0 +1,1920 @@
+<TS language="et" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Create a new address</source>
+ <translation>Loo uus aadress</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>&amp;Uus</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Kopeeri märgistatud aadress vahemällu</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>&amp;Kopeeri</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>S&amp;ulge</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>&amp;Kopeeri Aadress</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>Kustuta märgistatud aadress loetelust</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Ekspordi kuvatava vahelehe sisu faili</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Ekspordi</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;Kustuta</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>V&amp;ali</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>Need on sinu Bitcoini aadressid maksete saatmiseks. Müntide saatmisel kontrolli alati summat ning saaja aadressi.</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>&amp;Märgise kopeerimine</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>&amp;Muuda</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Komaeraldatud fail (*.csv)</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Eksportimine Ebaõnnestus</translation>
+ </message>
+ </context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Silt</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Aadress</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(silti pole)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Passphrase Dialog</source>
+ <translation>Salafraasi dialoog</translation>
+ </message>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Sisesta salafraas</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Uus salafraas</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Korda salafraasi</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>Krüpteeri rahakott</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>See toiming nõuab sinu rahakoti salafraasi.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Tee rahakott lukust lahti.</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>See toiming nõuab sinu rahakoti salafraasi.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>Dekrüpteeri rahakott.</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>Muuda salafraasi</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>Kinnita rahakoti krüpteering</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>Hoiatus: Kui sa kaotad oma, rahakoti krüpteerimisel kasutatud, salafraasi, siis &lt;b&gt;KAOTAD KA KÕIK OMA BITCOINID&lt;/b&gt;!</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>Kas soovid oma rahakoti krüpteerida?</translation>
+ </message>
+ <message>
+ <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
+ <translation>TÄHTIS: Kõik varasemad rahakoti varundfailid tuleks üle kirjutada äsja loodud krüpteeritud rahakoti failiga. Turvakaalutlustel tühistatakse krüpteerimata rahakoti failid alates uue, krüpteeritud rahakoti, kasutusele võtust.</translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>Hoiatus: Caps Lock on sisse lülitatud!</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>Rahakott krüpteeritud</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>Tõrge rahakoti krüpteerimisel</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>Rahakoti krüpteering ebaõnnestus tõrke tõttu. Sinu rahakotti ei krüpteeritud.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>Salafraasid ei kattu.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>Rahakoti avamine ebaõnnestus</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>Rahakoti salafraas ei ole õige.</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>Rahakoti dekrüpteerimine ei õnnestunud</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>Rahakoti salafraasi muutmine õnnestus.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>Signeeri &amp;sõnum</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>Võrgusünkimine...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;Ülevaade</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>Kuva rahakoti üld-ülevaade</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Tehingud</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>Sirvi tehingute ajalugu</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>V&amp;älju</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>Väljumine</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>Teave &amp;Qt kohta</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>Kuva Qt kohta käiv info</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;Valikud...</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>&amp;Krüpteeri Rahakott</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>&amp;Varunda Rahakott</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>&amp;Salafraasi muutmine</translation>
+ </message>
+ <message>
+ <source>Open &amp;URI...</source>
+ <translation>Ava &amp;URI...</translation>
+ </message>
+ <message>
+ <source>Importing blocks from disk...</source>
+ <translation>Impordi blokid kettalt...</translation>
+ </message>
+ <message>
+ <source>Reindexing blocks on disk...</source>
+ <translation>Kettal olevate blokkide re-indekseerimine...</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>Saada münte Bitcoini aadressile</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>Varunda rahakott teise asukohta</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Rahakoti krüpteerimise salafraasi muutmine</translation>
+ </message>
+ <message>
+ <source>&amp;Debug window</source>
+ <translation>&amp;Debugimise aken</translation>
+ </message>
+ <message>
+ <source>Open debugging and diagnostic console</source>
+ <translation>Ava debugimise ja diagnostika konsool</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>&amp;Kontrolli sõnumit...</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>Rahakott</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>&amp;Saada</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>&amp;Saama</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>&amp;Näita / Peida</translation>
+ </message>
+ <message>
+ <source>Show or hide the main Window</source>
+ <translation>Näita või peida peaaken</translation>
+ </message>
+ <message>
+ <source>Encrypt the private keys that belong to your wallet</source>
+ <translation>Krüpteeri oma rahakoti privaatvõtmed</translation>
+ </message>
+ <message>
+ <source>Sign messages with your Bitcoin addresses to prove you own them</source>
+ <translation>Omandi tõestamiseks allkirjasta sõnumid oma Bitcoini aadressiga</translation>
+ </message>
+ <message>
+ <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source>
+ <translation>Kinnita sõnumid kindlustamaks et need allkirjastati määratud Bitcoini aadressiga</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;Fail</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;Seaded</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>&amp;Abi</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>Vahelehe tööriistariba</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoini tuumik</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n hour(s)</source>
+ <translation><numerusform>%n tund</numerusform><numerusform>%n tundi</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n day(s)</source>
+ <translation><numerusform>%n päev</numerusform><numerusform>%n päeva</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n week(s)</source>
+ <translation><numerusform>%n nädal</numerusform><numerusform>%n nädalat</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 and %2</source>
+ <translation>%1 ja %2</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n year(s)</source>
+ <translation><numerusform>%n aasta</numerusform><numerusform>%n aastat</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 behind</source>
+ <translation>%1 maas</translation>
+ </message>
+ <message>
+ <source>Last received block was generated %1 ago.</source>
+ <translation>Viimane saabunud blokk loodi %1 tagasi.</translation>
+ </message>
+ <message>
+ <source>Transactions after this will not yet be visible.</source>
+ <translation>Peale seda ei ole tehingud veel nähtavad.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Tõrge</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Hoiatus</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Informatsioon</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>Ajakohane</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>Jõuan...</translation>
+ </message>
+ <message>
+ <source>Date: %1
+</source>
+ <translation>Kuupäev: %1
+</translation>
+ </message>
+ <message>
+ <source>Amount: %1
+</source>
+ <translation>Summa: %1
+</translation>
+ </message>
+ <message>
+ <source>Type: %1
+</source>
+ <translation>Tüüp: %1
+</translation>
+ </message>
+ <message>
+ <source>Label: %1
+</source>
+ <translation>&amp;Märgis: %1
+</translation>
+ </message>
+ <message>
+ <source>Address: %1
+</source>
+ <translation>Aadress: %1
+</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>Saadetud tehing</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>Sisenev tehing</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>Rahakott on &lt;b&gt;krüpteeritud&lt;/b&gt; ning hetkel &lt;b&gt;avatud&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>Rahakott on &lt;b&gt;krüpteeritud&lt;/b&gt; ning hetkel &lt;b&gt;suletud&lt;/b&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <source>Network Alert</source>
+ <translation>Võrgu Häire</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Quantity:</source>
+ <translation>Kogus:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Summa:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Tasu:</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Kogus</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Kuupäev</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Kinnitatud</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Aadressi kopeerimine</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Märgise kopeerimine</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopeeri summa</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Kopeeri tehingu ID</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Kopeeri tasu</translation>
+ </message>
+ <message>
+ <source>highest</source>
+ <translation>kõrgeim</translation>
+ </message>
+ <message>
+ <source>higher</source>
+ <translation>kõrgem</translation>
+ </message>
+ <message>
+ <source>high</source>
+ <translation>kõrge</translation>
+ </message>
+ <message>
+ <source>medium</source>
+ <translation>keskmine</translation>
+ </message>
+ <message>
+ <source>low</source>
+ <translation>madal</translation>
+ </message>
+ <message>
+ <source>lower</source>
+ <translation>madalam</translation>
+ </message>
+ <message>
+ <source>lowest</source>
+ <translation>madalaim</translation>
+ </message>
+ <message>
+ <source>(%1 locked)</source>
+ <translation>(%1 lukustatud)</translation>
+ </message>
+ <message>
+ <source>yes</source>
+ <translation>jah</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>ei</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(silti pole)</translation>
+ </message>
+ </context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>Muuda aadressi</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>&amp;Märgis</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;Aadress</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>Uus sissetulev aadress</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>Uus väljaminev aadress</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>Sissetulevate aadresside muutmine</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>Väljaminevate aadresside muutmine</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>Selline aadress on juba olemas: "%1"</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is not a valid Bitcoin address.</source>
+ <translation>Sisestatud aadress "%1" ei ole Bitcoinis kehtiv.</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>Rahakotti ei avatud</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>Tõrge uue võtme loomisel.</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ <message>
+ <source>name</source>
+ <translation>nimi</translation>
+ </message>
+ </context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoini tuumik</translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>versioon</translation>
+ </message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>Kirjeldus Bitcoini Tuumast</translation>
+ </message>
+ <message>
+ <source>Command-line options</source>
+ <translation>Käsurea valikud</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>Kasutus:</translation>
+ </message>
+ <message>
+ <source>command-line options</source>
+ <translation>käsurea valikud</translation>
+ </message>
+</context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Welcome</source>
+ <translation>Teretulemast</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoini tuumik</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Tõrge</translation>
+ </message>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ <message>
+ <source>Open URI</source>
+ <translation>Ava URI</translation>
+ </message>
+ <message>
+ <source>URI:</source>
+ <translation>URI:</translation>
+ </message>
+ </context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>Valikud</translation>
+ </message>
+ <message>
+ <source>MB</source>
+ <translation>MB</translation>
+ </message>
+ <message>
+ <source>Reset all client options to default.</source>
+ <translation>Taasta kõik klientprogrammi seadete vaikeväärtused.</translation>
+ </message>
+ <message>
+ <source>&amp;Reset Options</source>
+ <translation>&amp;Lähtesta valikud</translation>
+ </message>
+ <message>
+ <source>&amp;Network</source>
+ <translation>&amp;Võrk</translation>
+ </message>
+ <message>
+ <source>W&amp;allet</source>
+ <translation>R&amp;ahakott</translation>
+ </message>
+ <message>
+ <source>Expert</source>
+ <translation>Ekspert</translation>
+ </message>
+ <message>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>Bitcoini kliendi pordi automaatne avamine ruuteris. Toimib, kui sinu ruuter aktsepteerib UPnP ühendust.</translation>
+ </message>
+ <message>
+ <source>Map port using &amp;UPnP</source>
+ <translation>Suuna port &amp;UPnP kaudu</translation>
+ </message>
+ <message>
+ <source>Proxy &amp;IP:</source>
+ <translation>Proxi &amp;IP:</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>&amp;Port:</translation>
+ </message>
+ <message>
+ <source>Port of the proxy (e.g. 9050)</source>
+ <translation>Proxi port (nt 9050)</translation>
+ </message>
+ <message>
+ <source>&amp;Window</source>
+ <translation>&amp;Aken</translation>
+ </message>
+ <message>
+ <source>Show only a tray icon after minimizing the window.</source>
+ <translation>Minimeeri systray alale.</translation>
+ </message>
+ <message>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>&amp;Minimeeri systray alale</translation>
+ </message>
+ <message>
+ <source>M&amp;inimize on close</source>
+ <translation>M&amp;inimeeri sulgemisel</translation>
+ </message>
+ <message>
+ <source>&amp;Display</source>
+ <translation>&amp;Kuva</translation>
+ </message>
+ <message>
+ <source>User Interface &amp;language:</source>
+ <translation>Kasutajaliidese &amp;keel:</translation>
+ </message>
+ <message>
+ <source>&amp;Unit to show amounts in:</source>
+ <translation>Summade kuvamise &amp;Unit:</translation>
+ </message>
+ <message>
+ <source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
+ <translation>Vali liideses ning müntide saatmisel kuvatav vaikimisi alajaotus.</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>&amp;OK</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>&amp;Katkesta</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>vaikeväärtus</translation>
+ </message>
+ <message>
+ <source>Confirm options reset</source>
+ <translation>Kinnita valikute algseadistamine</translation>
+ </message>
+ <message>
+ <source>The supplied proxy address is invalid.</source>
+ <translation>Sisestatud kehtetu proxy aadress.</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>Vorm</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>Kuvatav info ei pruugi olla ajakohane. Ühenduse loomisel süngitakse sinu rahakott automaatselt Bitconi võrgustikuga, kuid see toiming on hetkel lõpetamata.</translation>
+ </message>
+ <message>
+ <source>Immature:</source>
+ <translation>Ebaküps:</translation>
+ </message>
+ <message>
+ <source>Mined balance that has not yet matured</source>
+ <translation>Mitte aegunud mine'itud jääk</translation>
+ </message>
+ <message>
+ <source>Recent transactions</source>
+ <translation>Hiljutised tehingud</translation>
+ </message>
+ </context>
+<context>
+ <name>PaymentServer</name>
+ <message>
+ <source>URI handling</source>
+ <translation>URI käsitsemine</translation>
+ </message>
+ <message>
+ <source>Cannot start bitcoin: click-to-pay handler</source>
+ <translation>Bitcoin ei käivitu: vajuta-maksa toiming</translation>
+ </message>
+ </context>
+<context>
+ <name>PeerTableModel</name>
+ </context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>Kogus</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>N/A</translation>
+ </message>
+ </context>
+<context>
+ <name>QRImageWidget</name>
+ <message>
+ <source>Save QR Code</source>
+ <translation>Salvesta QR kood</translation>
+ </message>
+ </context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>Client name</source>
+ <translation>Kliendi nimi</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>N/A</translation>
+ </message>
+ <message>
+ <source>Client version</source>
+ <translation>Kliendi versioon</translation>
+ </message>
+ <message>
+ <source>&amp;Information</source>
+ <translation>&amp;Informatsioon</translation>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>Üldine</translation>
+ </message>
+ <message>
+ <source>Using OpenSSL version</source>
+ <translation>Kasutan OpenSSL versiooni</translation>
+ </message>
+ <message>
+ <source>Startup time</source>
+ <translation>Käivitamise hetk</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Võrgustik</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>Nimi</translation>
+ </message>
+ <message>
+ <source>Number of connections</source>
+ <translation>Ühenduste arv</translation>
+ </message>
+ <message>
+ <source>Block chain</source>
+ <translation>Ploki jada</translation>
+ </message>
+ <message>
+ <source>Current number of blocks</source>
+ <translation>Plokkide hetkearv</translation>
+ </message>
+ <message>
+ <source>Received</source>
+ <translation>Vastuvõetud</translation>
+ </message>
+ <message>
+ <source>Sent</source>
+ <translation>Saadetud</translation>
+ </message>
+ <message>
+ <source>Direction</source>
+ <translation>Suund</translation>
+ </message>
+ <message>
+ <source>Version</source>
+ <translation>Versioon</translation>
+ </message>
+ <message>
+ <source>Services</source>
+ <translation>Teenused</translation>
+ </message>
+ <message>
+ <source>Last block time</source>
+ <translation>Viimane ploki aeg</translation>
+ </message>
+ <message>
+ <source>&amp;Open</source>
+ <translation>&amp;Ava</translation>
+ </message>
+ <message>
+ <source>&amp;Console</source>
+ <translation>&amp;Konsool</translation>
+ </message>
+ <message>
+ <source>Build date</source>
+ <translation>Valmistusaeg</translation>
+ </message>
+ <message>
+ <source>Debug log file</source>
+ <translation>Debugimise logifail</translation>
+ </message>
+ <message>
+ <source>Clear console</source>
+ <translation>Puhasta konsool</translation>
+ </message>
+ <message>
+ <source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
+ <translation>Ajaloo sirvimiseks kasuta üles ja alla nooli, ekraani puhastamiseks &lt;b&gt;Ctrl-L&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>Type &lt;b&gt;help&lt;/b&gt; for an overview of available commands.</source>
+ <translation>Ülevaateks võimalikest käsklustest trüki &lt;b&gt;help&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation>%1 B</translation>
+ </message>
+ <message>
+ <source>%1 KB</source>
+ <translation>%1 B</translation>
+ </message>
+ <message>
+ <source>%1 MB</source>
+ <translation>%1 MB</translation>
+ </message>
+ <message>
+ <source>%1 GB</source>
+ <translation>%1 GB</translation>
+ </message>
+ </context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Amount:</source>
+ <translation>&amp;Summa:</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Märgis</translation>
+ </message>
+ <message>
+ <source>&amp;Message:</source>
+ <translation>&amp;Sõnum:</translation>
+ </message>
+ <message>
+ <source>Show</source>
+ <translation>Näita</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>Eemalda</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Märgise kopeerimine</translation>
+ </message>
+ <message>
+ <source>Copy message</source>
+ <translation>Kopeeri sõnum</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopeeri summa</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>Address</source>
+ <translation>Aadress</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Kogus</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Silt</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Sõnum</translation>
+ </message>
+ <message>
+ <source>Resulting URI too long, try to reduce the text for label / message.</source>
+ <translation>Tulemuseks on liiga pikk URL, püüa lühendada märgise/teate teksti.</translation>
+ </message>
+ <message>
+ <source>Error encoding URI into QR Code.</source>
+ <translation>Tõrge URI'st QR koodi loomisel</translation>
+ </message>
+</context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Kuupäev</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Silt</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Sõnum</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Kogus</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(silti pole)</translation>
+ </message>
+ <message>
+ <source>(no message)</source>
+ <translation>(sõnum puudub)</translation>
+ </message>
+ <message>
+ <source>(no amount)</source>
+ <translation>(summa puudub)</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Müntide saatmine</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Kogus:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Summa:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Tasu:</translation>
+ </message>
+ <message>
+ <source>Choose...</source>
+ <translation>Vali...</translation>
+ </message>
+ <message>
+ <source>Hide</source>
+ <translation>Peida</translation>
+ </message>
+ <message>
+ <source>Recommended:</source>
+ <translation>Soovitatud:</translation>
+ </message>
+ <message>
+ <source>normal</source>
+ <translation>normaalne</translation>
+ </message>
+ <message>
+ <source>fast</source>
+ <translation>kiire</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>Saatmine mitmele korraga</translation>
+ </message>
+ <message>
+ <source>Add &amp;Recipient</source>
+ <translation>Lisa &amp;Saaja</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Puhasta &amp;Kõik</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>Jääk:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>Saatmise kinnitamine</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>S&amp;aada</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>Müntide saatmise kinnitamine</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopeeri summa</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Kopeeri tasu</translation>
+ </message>
+ <message>
+ <source>or</source>
+ <translation>või</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>Makstav summa peab olema suurem kui 0.</translation>
+ </message>
+ <message>
+ <source>The amount exceeds your balance.</source>
+ <translation>Summa ületab jäägi.</translation>
+ </message>
+ <message>
+ <source>The total exceeds your balance when the %1 transaction fee is included.</source>
+ <translation>Summa koos tehingu tasuga %1 ületab sinu jääki.</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(silti pole)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>S&amp;umma:</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>Maksa &amp;:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Aadressiraamatusse sisestamiseks märgista aadress</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Märgis</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Kleebi aadress vahemälust</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Message:</source>
+ <translation>Sõnum:</translation>
+ </message>
+ </context>
+<context>
+ <name>ShutdownWindow</name>
+ </context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Signatures - Sign / Verify a Message</source>
+ <translation>Signatuurid - Allkirjasta / Kinnita Sõnum</translation>
+ </message>
+ <message>
+ <source>&amp;Sign Message</source>
+ <translation>&amp;Allkirjastamise teade</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Kleebi aadress vahemälust</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Enter the message you want to sign here</source>
+ <translation>Sisesta siia allkirjastamise sõnum</translation>
+ </message>
+ <message>
+ <source>Signature</source>
+ <translation>Signatuur</translation>
+ </message>
+ <message>
+ <source>Copy the current signature to the system clipboard</source>
+ <translation>Kopeeri praegune signatuur vahemällu</translation>
+ </message>
+ <message>
+ <source>Sign the message to prove you own this Bitcoin address</source>
+ <translation>Allkirjasta sõnum Bitcoini aadressi sulle kuulumise tõestamiseks</translation>
+ </message>
+ <message>
+ <source>Sign &amp;Message</source>
+ <translation>Allkirjasta &amp;Sõnum</translation>
+ </message>
+ <message>
+ <source>Reset all sign message fields</source>
+ <translation>Tühjenda kõik sõnumi allkirjastamise väljad</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Puhasta &amp;Kõik</translation>
+ </message>
+ <message>
+ <source>&amp;Verify Message</source>
+ <translation>&amp;Kinnita Sõnum</translation>
+ </message>
+ <message>
+ <source>Verify the message to ensure it was signed with the specified Bitcoin address</source>
+ <translation>Kinnita sõnum tõestamaks selle allkirjastatust määratud Bitcoini aadressiga.</translation>
+ </message>
+ <message>
+ <source>Verify &amp;Message</source>
+ <translation>Kinnita &amp;Sõnum</translation>
+ </message>
+ <message>
+ <source>Reset all verify message fields</source>
+ <translation>Tühjenda kõik sõnumi kinnitamise väljad</translation>
+ </message>
+ <message>
+ <source>Click "Sign Message" to generate signature</source>
+ <translation>Signatuuri genereerimiseks vajuta "Allkirjasta Sõnum"</translation>
+ </message>
+ <message>
+ <source>The entered address is invalid.</source>
+ <translation>Sisestatud aadress ei kehti.</translation>
+ </message>
+ <message>
+ <source>Please check the address and try again.</source>
+ <translation>Palun kontrolli aadressi ning proovi uuesti.</translation>
+ </message>
+ <message>
+ <source>The entered address does not refer to a key.</source>
+ <translation>Sisestatud aadress ei viita võtmele.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock was cancelled.</source>
+ <translation>Rahakoti avamine katkestati.</translation>
+ </message>
+ <message>
+ <source>Private key for the entered address is not available.</source>
+ <translation>Sisestatud aadressi privaatvõti ei ole saadaval.</translation>
+ </message>
+ <message>
+ <source>Message signing failed.</source>
+ <translation>Sõnumi signeerimine ebaõnnestus.</translation>
+ </message>
+ <message>
+ <source>Message signed.</source>
+ <translation>Sõnum signeeritud.</translation>
+ </message>
+ <message>
+ <source>The signature could not be decoded.</source>
+ <translation>Signatuuri ei õnnestunud dekodeerida.</translation>
+ </message>
+ <message>
+ <source>Please check the signature and try again.</source>
+ <translation>Palun kontrolli signatuuri ning proovi uuesti.</translation>
+ </message>
+ <message>
+ <source>The signature did not match the message digest.</source>
+ <translation>Signatuur ei kattunud sõnumi kokkuvõttega.</translation>
+ </message>
+ <message>
+ <source>Message verification failed.</source>
+ <translation>Sõnumi kontroll ebaõnnestus.</translation>
+ </message>
+ <message>
+ <source>Message verified.</source>
+ <translation>Sõnum kontrollitud.</translation>
+ </message>
+</context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoini tuumik</translation>
+ </message>
+ <message>
+ <source>The Bitcoin Core developers</source>
+ <translation>Bitcoini Tuuma arendajad</translation>
+ </message>
+ <message>
+ <source>[testnet]</source>
+ <translation>[testnet]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ <message>
+ <source>KB/s</source>
+ <translation>KB/s</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>Avatud kuni %1</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/kinnitamata</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 kinnitust</translation>
+ </message>
+ <message>
+ <source>Status</source>
+ <translation>Staatus</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Kuupäev</translation>
+ </message>
+ <message>
+ <source>Source</source>
+ <translation>Allikas</translation>
+ </message>
+ <message>
+ <source>Generated</source>
+ <translation>Genereeritud</translation>
+ </message>
+ <message>
+ <source>From</source>
+ <translation>Saatja</translation>
+ </message>
+ <message>
+ <source>To</source>
+ <translation>Saaja</translation>
+ </message>
+ <message>
+ <source>own address</source>
+ <translation>oma aadress</translation>
+ </message>
+ <message>
+ <source>label</source>
+ <translation>märgis</translation>
+ </message>
+ <message>
+ <source>Credit</source>
+ <translation>Krediit</translation>
+ </message>
+ <message>
+ <source>not accepted</source>
+ <translation>mitte aktsepteeritud</translation>
+ </message>
+ <message>
+ <source>Debit</source>
+ <translation>Deebet</translation>
+ </message>
+ <message>
+ <source>Transaction fee</source>
+ <translation>Tehingu tasu</translation>
+ </message>
+ <message>
+ <source>Net amount</source>
+ <translation>Neto summa</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Sõnum</translation>
+ </message>
+ <message>
+ <source>Comment</source>
+ <translation>Kommentaar</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>Tehingu ID</translation>
+ </message>
+ <message>
+ <source>Debug information</source>
+ <translation>Debug'imise info</translation>
+ </message>
+ <message>
+ <source>Transaction</source>
+ <translation>Tehing</translation>
+ </message>
+ <message>
+ <source>Inputs</source>
+ <translation>Sisendid</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Kogus</translation>
+ </message>
+ <message>
+ <source>true</source>
+ <translation>õige</translation>
+ </message>
+ <message>
+ <source>false</source>
+ <translation>vale</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, veel esitlemata</translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>tundmatu</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>Tehingu üksikasjad</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>Paan kuvab tehingu detailid</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Kuupäev</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Tüüp</translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>Avatud kuni %1</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>Kinnitatud (%1 kinnitust)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>Antud klotsi pole saanud ükski osapool ning tõenäoliselt seda ei aktsepteerita!</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>Loodud, kuid aktsepteerimata</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Silt</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Saadud koos</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>Kellelt saadud</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Saadetud</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>Makse iseendale</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Mine'itud</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(n/a)</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>Tehingu staatus. Kinnituste arvu kuvamiseks liigu hiire noolega selle peale.</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Tehingu saamise kuupäev ning kellaaeg.</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>Tehingu tüüp.</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>Jäägile lisatud või eemaldatud summa.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>Kõik</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>Täna</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>Jooksev nädal</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>Jooksev kuu</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>Eelmine kuu</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>Jooksev aasta</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>Ulatus...</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Saadud koos</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Saadetud</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>Iseendale</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Mine'itud</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>Muu</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>Otsimiseks sisesta märgis või aadress</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>Vähim summa</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Aadressi kopeerimine</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Märgise kopeerimine</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopeeri summa</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Kopeeri tehingu ID</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>Märgise muutmine</translation>
+ </message>
+ <message>
+ <source>Show transaction details</source>
+ <translation>Kuva tehingu detailid</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Eksportimine Ebaõnnestus</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Komaeraldatud fail (*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Kinnitatud</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Kuupäev</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Tüüp</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Silt</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Aadress</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>Ulatus:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>saaja</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ </context>
+<context>
+ <name>WalletFrame</name>
+ </context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Müntide saatmine</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Ekspordi</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Ekspordi kuvatava vahelehe sisu faili</translation>
+ </message>
+ <message>
+ <source>Backup Wallet</source>
+ <translation>Varundatud Rahakott</translation>
+ </message>
+ <message>
+ <source>Wallet Data (*.dat)</source>
+ <translation>Rahakoti andmed (*.dat)</translation>
+ </message>
+ <message>
+ <source>Backup Failed</source>
+ <translation>Varundamine nurjus</translation>
+ </message>
+ <message>
+ <source>Backup Successful</source>
+ <translation>Varundamine õnnestus</translation>
+ </message>
+</context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>Valikud:</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>Täpsusta andmekataloog</translation>
+ </message>
+ <message>
+ <source>Connect to a node to retrieve peer addresses, and disconnect</source>
+ <translation>Peeri aadressi saamiseks ühendu korraks node'iga</translation>
+ </message>
+ <message>
+ <source>Specify your own public address</source>
+ <translation>Täpsusta enda avalik aadress</translation>
+ </message>
+ <message>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>Luba käsurea ning JSON-RPC käsklusi</translation>
+ </message>
+ <message>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>Tööta taustal ning aktsepteeri käsklusi</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>Testvõrgu kasutamine</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
+ <translation>Luba välisühendusi (vaikeväärtus: 1 kui puudub -proxy või -connect)</translation>
+ </message>
+ <message>
+ <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
+ <translation>Määratud aadressiga sidumine ning sellelt kuulamine. IPv6 jaoks kasuta vormingut [host]:port</translation>
+ </message>
+ <message>
+ <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
+ <translation>Käivita käsklus, kui rahakoti tehing muutub (%s cmd's muudetakse TxID'ks)</translation>
+ </message>
+ <message>
+ <source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source>
+ <translation>See on test-versioon - kasutamine omal riisikol - ära kasuta mining'uks ega kaupmeeste programmides</translation>
+ </message>
+ <message>
+ <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>Hoiatus: -paytxfee on seatud väga kõrgeks! See on sinu poolt makstav tehingu lisatasu.</translation>
+ </message>
+ <message>
+ <source>Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
+ <translation>Hoiatus: ilmnes tõrge wallet.dat faili lugemisel! Võtmed on terved, kuid tehingu andmed või aadressiraamatu kirjed võivad olla kadunud või vigased.</translation>
+ </message>
+ <message>
+ <source>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</source>
+ <translation>Hoiatus: toimus wallet.dat faili andmete päästmine! Originaal wallet.dat nimetati kaustas %s ümber wallet.{ajatempel}.bak'iks, jäägi või tehingute ebakõlade puhul tuleks teha backup'ist taastamine.</translation>
+ </message>
+ <message>
+ <source>Attempt to recover private keys from a corrupt wallet.dat</source>
+ <translation>Püüa vigasest wallet.dat failist taastada turvavõtmed</translation>
+ </message>
+ <message>
+ <source>Block creation options:</source>
+ <translation>Blokeeri loomise valikud:</translation>
+ </message>
+ <message>
+ <source>Connect only to the specified node(s)</source>
+ <translation>Ühendu ainult määratud node'i(de)ga</translation>
+ </message>
+ <message>
+ <source>Corrupted block database detected</source>
+ <translation>Tuvastati vigane bloki andmebaas</translation>
+ </message>
+ <message>
+ <source>Do you want to rebuild the block database now?</source>
+ <translation>Kas soovid bloki andmebaasi taastada?</translation>
+ </message>
+ <message>
+ <source>Error initializing block database</source>
+ <translation>Tõrge bloki andmebaasi käivitamisel</translation>
+ </message>
+ <message>
+ <source>Error initializing wallet database environment %s!</source>
+ <translation>Tõrge rahakoti keskkonna %s käivitamisel!</translation>
+ </message>
+ <message>
+ <source>Error loading block database</source>
+ <translation>Tõrge bloki baasi lugemisel</translation>
+ </message>
+ <message>
+ <source>Error opening block database</source>
+ <translation>Tõrge bloki andmebaasi avamisel</translation>
+ </message>
+ <message>
+ <source>Error: Disk space is low!</source>
+ <translation>Tõrge: liiga vähe kettaruumi!</translation>
+ </message>
+ <message>
+ <source>Failed to listen on any port. Use -listen=0 if you want this.</source>
+ <translation>Pordi kuulamine nurjus. Soovikorral kasuta -listen=0.</translation>
+ </message>
+ <message>
+ <source>Verifying blocks...</source>
+ <translation>Kontrollin blokke...</translation>
+ </message>
+ <message>
+ <source>Verifying wallet...</source>
+ <translation>Kontrollin rahakotti...</translation>
+ </message>
+ <message>
+ <source>Wallet options:</source>
+ <translation>Rahakoti valikud:</translation>
+ </message>
+ <message>
+ <source>Imports blocks from external blk000??.dat file</source>
+ <translation>Impordi blokid välisest blk000??.dat failist</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Informatsioon</translation>
+ </message>
+ <message>
+ <source>RPC server options:</source>
+ <translation>RPC serveri valikud:</translation>
+ </message>
+ <message>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>Saada jälitus/debug, debug.log faili asemel, konsooli</translation>
+ </message>
+ <message>
+ <source>Set language, for example "de_DE" (default: system locale)</source>
+ <translation>Keele valik, nt "ee_ET" (vaikeväärtus: system locale)</translation>
+ </message>
+ <message>
+ <source>Show splash screen on startup (default: 1)</source>
+ <translation>Käivitamisel teabeakna kuvamine (vaikeväärtus: 1)</translation>
+ </message>
+ <message>
+ <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source>
+ <translation>Kahanda programmi käivitamisel debug.log faili (vaikeväärtus: 1, kui ei ole -debug)</translation>
+ </message>
+ <message>
+ <source>Signing transaction failed</source>
+ <translation>Tehingu allkirjastamine ebaõnnestus</translation>
+ </message>
+ <message>
+ <source>Start minimized</source>
+ <translation>Käivitu tegumiribale</translation>
+ </message>
+ <message>
+ <source>The transaction amount is too small to pay the fee</source>
+ <translation>Tehingu summa on tasu maksmiseks liiga väikene</translation>
+ </message>
+ <message>
+ <source>Transaction amount too small</source>
+ <translation>Tehingu summa liiga väikene</translation>
+ </message>
+ <message>
+ <source>Transaction too large</source>
+ <translation>Tehing liiga suur</translation>
+ </message>
+ <message>
+ <source>UI Options:</source>
+ <translation>UI Valikud:</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: 1 when listening)</source>
+ <translation>Kasuta kuulatava pordi määramiseks UPnP ühendust (vaikeväärtus: 1, kui kuulatakse)</translation>
+ </message>
+ <message>
+ <source>Username for JSON-RPC connections</source>
+ <translation>JSON-RPC ühenduste kasutajatunnus</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Hoiatus</translation>
+ </message>
+ <message>
+ <source>on startup</source>
+ <translation>käivitamisel</translation>
+ </message>
+ <message>
+ <source>wallet.dat corrupt, salvage failed</source>
+ <translation>wallet.dat fail on katki, päästmine ebaõnnestus</translation>
+ </message>
+ <message>
+ <source>Password for JSON-RPC connections</source>
+ <translation>JSON-RPC ühenduste salasõna</translation>
+ </message>
+ <message>
+ <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
+ <translation>Käivita käsklus, kui parim plokk muutub (käskluse %s asendatakse ploki hash'iga)</translation>
+ </message>
+ <message>
+ <source>Upgrade wallet to latest format</source>
+ <translation>Uuenda rahakott uusimasse vormingusse</translation>
+ </message>
+ <message>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>Otsi ploki jadast rahakoti kadunud tehinguid</translation>
+ </message>
+ <message>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>Kasuta JSON-RPC ühenduste jaoks OpenSSL'i (https)</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>Käesolev abitekst</translation>
+ </message>
+ <message>
+ <source>Allow DNS lookups for -addnode, -seednode and -connect</source>
+ <translation>-addnode, -seednode ja -connect tohivad kasutada DNS lookup'i</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>Aadresside laadimine...</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>Viga wallet.dat käivitamisel. Vigane rahakkott</translation>
+ </message>
+ <message>
+ <source>(default: %s)</source>
+ <translation>(vaikimisi: %s)</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>Viga wallet.dat käivitamisel</translation>
+ </message>
+ <message>
+ <source>Invalid -proxy address: '%s'</source>
+ <translation>Vigane -proxi aadress: '%s'</translation>
+ </message>
+ <message>
+ <source>Unknown network specified in -onlynet: '%s'</source>
+ <translation>Kirjeldatud tundmatu võrgustik -onlynet'is: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -bind address: '%s'</source>
+ <translation>Tundmatu -bind aadress: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -externalip address: '%s'</source>
+ <translation>Tundmatu -externalip aadress: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>-paytxfee=&lt;amount&gt; jaoks vigane kogus: '%s'</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>Liiga suur summa</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>Klotside indeksi laadimine...</translation>
+ </message>
+ <message>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>Lisa node ning hoia ühendus avatud</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>Rahakoti laadimine...</translation>
+ </message>
+ <message>
+ <source>Cannot downgrade wallet</source>
+ <translation>Rahakoti vanandamine ebaõnnestus</translation>
+ </message>
+ <message>
+ <source>Cannot write default address</source>
+ <translation>Tõrge vaikimisi aadressi kirjutamisel</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>Üleskaneerimine...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>Laetud</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Tõrge</translation>
+ </message>
+</context>
+</TS> \ 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 0000000000..3de9ad5a2f
--- /dev/null
+++ b/src/qt/locale/bitcoin_eu_ES.ts
@@ -0,0 +1,686 @@
+<TS language="eu_ES" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Create a new address</source>
+ <translation>Sortu helbide berria</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Kopiatu hautatutako helbidea sistemaren arbelera</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;Ezabatu</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Komaz bereizitako artxiboa (*.csv)</translation>
+ </message>
+ </context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Etiketa</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Helbidea</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(etiketarik ez)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Sartu pasahitza</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Pasahitz berria</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Errepikatu pasahitz berria</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>Enkriptatu zorroa</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>Eragiketa honek zorroaren pasahitza behar du zorroa desblokeatzeko.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Desblokeatu zorroa</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>Eragiketa honek zure zorroaren pasahitza behar du, zorroa desenkriptatzeko.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>Desenkriptatu zorroa</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>Aldatu pasahitza</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>Berretsi zorroaren enkriptazioa</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>Zorroa enkriptatuta</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>Zorroaren enkriptazioak huts egin du</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>Zorroaren enkriptazioak huts egin du barne-errore baten ondorioz. Zure zorroa ez da enkriptatu.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>Eman dituzun pasahitzak ez datoz bat.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>Zorroaren desblokeoak huts egin du</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>Zorroa desenkriptatzeko sartutako pasahitza okerra da.</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>Zorroaren desenkriptazioak huts egin du</translation>
+ </message>
+ </context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>Sarearekin sinkronizatzen...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;Gainbegiratu</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>Ikusi zorroaren begirada orokorra</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Transakzioak</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>Ikusi transakzioen historia</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>Irten</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>Irten aplikaziotik</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>&amp;Qt-ari buruz</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>Erakutsi Bitcoin-i buruzko informazioa</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;Aukerak...</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Aldatu zorroa enkriptatzeko erabilitako pasahitza</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;Artxiboa</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;Ezarpenak</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>&amp;Laguntza</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>Fitxen tresna-barra</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>Egunean</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>Eguneratzen...</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>Bidalitako transakzioa</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>Sarrerako transakzioa</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>Zorroa &lt;b&gt;enkriptatuta&lt;/b&gt; eta &lt;b&gt;desblokeatuta&lt;/b&gt; dago une honetan</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>Zorroa &lt;b&gt;enkriptatuta&lt;/b&gt; eta &lt;b&gt;blokeatuta&lt;/b&gt; dago une honetan</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ </context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Amount:</source>
+ <translation>Kopurua</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Kopurua</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Kopiatu helbidea</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Kopiatu etiketa</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(etiketarik ez)</translation>
+ </message>
+ </context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>Editatu helbidea</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>&amp;Etiketa</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;Helbidea</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>Jasotzeko helbide berria</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>Bidaltzeko helbide berria</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>Editatu jasotzeko helbidea</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>Editatu bidaltzeko helbidea</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>Sartu berri den helbidea, "%1", helbide-liburuan dago jadanik.</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>Ezin desblokeatu zorroa.</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>Gako berriaren sorrerak huts egin du.</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ </context>
+<context>
+ <name>HelpMessageDialog</name>
+ </context>
+<context>
+ <name>Intro</name>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ </context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>Aukerak</translation>
+ </message>
+ </context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>Inprimakia</translation>
+ </message>
+ </context>
+<context>
+ <name>PaymentServer</name>
+ </context>
+<context>
+ <name>PeerTableModel</name>
+ </context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>Kopurua</translation>
+ </message>
+ </context>
+<context>
+ <name>QRImageWidget</name>
+ </context>
+<context>
+ <name>RPCConsole</name>
+ </context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Etiketa:</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Kopiatu etiketa</translation>
+ </message>
+ </context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>Address</source>
+ <translation>Helbidea</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Kopurua</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiketa</translation>
+ </message>
+ </context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiketa</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Kopurua</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(etiketarik ez)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Bidali txanponak</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Kopurua</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>Bidali hainbat jasotzaileri batera</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>Saldoa:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>Berretsi bidaltzeko ekintza</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>Berretsi txanponak bidaltzea</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>Ordaintzeko kopurua 0 baino handiagoa izan behar du.</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(etiketarik ez)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>K&amp;opurua:</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>Ordaindu &amp;honi:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Sartu etiketa bat helbide honetarako, eta gehitu zure helbide-liburuan</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Etiketa:</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Itsatsi helbidea arbeletik</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Message:</source>
+ <translation>Mezua</translation>
+ </message>
+ </context>
+<context>
+ <name>ShutdownWindow</name>
+ </context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Itsatsi helbidea arbeletik</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ </context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>[testnet]</source>
+ <translation>[testnet]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ </context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>Zabalik %1 arte</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/konfirmatu gabe</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 konfirmazioak</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Kopurua</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, ez da arrakastaz emititu oraindik</translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>ezezaguna</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>Transakzioaren xehetasunak</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>Panel honek transakzioaren deskribapen xehea erakusten du</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Mota</translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>Zabalik %1 arte</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>Konfirmatuta (%1 konfirmazio)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>Bloke hau ez du beste inongo nodorik jaso, eta seguruenik ez da onartuko!</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>Sortua, baina ez onartua</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiketa</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Jasota honekin: </translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Hona bidalia: </translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>Ordainketa zeure buruari</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Bildua</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(n/a)</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>Transakzioaren egoera. Pasatu sagua gainetik konfirmazio kopurua ikusteko.</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Transakzioa jasotako data eta ordua.</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>Transakzio mota.</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>Saldoan kendu edo gehitutako kopurua.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>Denak</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>Gaur</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>Aste honetan</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>Hil honetan</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>Azken hilean</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>Aurten</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>Muga...</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Jasota honekin: </translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Hona bidalia: </translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>Zeure buruari</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Bildua</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>Beste</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>Sartu bilatzeko helbide edo etiketa</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>Kopuru minimoa</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Kopiatu helbidea</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Kopiatu etiketa</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Komaz bereizitako artxiboa (*.csv)</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Mota</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiketa</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Helbidea</translation>
+ </message>
+ </context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ </context>
+<context>
+ <name>WalletFrame</name>
+ </context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Bidali txanponak</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ </context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>Aukerak</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>Laguntza mezu hau</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>Birbilatzen...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>Zamaketa amaitua</translation>
+ </message>
+ </context>
+</TS> \ 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 0000000000..e8437bdcf2
--- /dev/null
+++ b/src/qt/locale/bitcoin_fa.ts
@@ -0,0 +1,2070 @@
+<TS language="fa" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Right-click to edit address or label</source>
+ <translation>برای تغییر آدرس و یا برچسب کلیک راست کنید.</translation>
+ </message>
+ <message>
+ <source>Create a new address</source>
+ <translation>ایجاد نشانی جدید</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>&amp;جدید</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>کپی نشانی انتخاب شده به حافظهٔ سیستم</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>&amp;رونوشت</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>&amp;بستن</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>&amp;کپی نشانی</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>حذف نشانی انتخاب‌شده از لیست</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>خروجی گرفتن داده‌های برگهٔ فعلی به یک پرونده</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;صدور</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;حذف</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>آدرس مورد نظر برای ارسال کوین ها را انتخاب کنید</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>آدرس موردنظر برای دریافت کوین ها را انتخاب کنید.</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>آدرس های ارسال کننده</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>آدرس های دریافت کننده</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>این‌ها نشانی‌های بیت‌کوین شما برای ارسال وجود هستند. همیشه قبل از ارسال سکه‌ها، نشانی دریافت‌کننده و مقدار ارسالی را بررسی کنید.</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>این‌ها نشانی‌های بیت‌کوین شما برای دریافت وجوه هستند. توصیه می‌شود یک نشانی دریافت جدید برای هر تبادل استفاده کنید.</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>کپی و برچسب‌&amp;گذاری</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>&amp;ویرایش</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>استخراج لیست آدرس</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>پروندهٔ نوع CSV جداشونده با کاما (*.csv)</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>استخراج انجام نشد</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the address list to %1. Please try again.</source>
+ <translation>خطایی هنگام تلاش برای ذخیرهٔ لیست آدرس ها در %1 رخ داد.</translation>
+ </message>
+</context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>برچسب</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>آدرس</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(بدون برچسب)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Passphrase Dialog</source>
+ <translation>پنجرهٔ گذرواژه</translation>
+ </message>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>گذرواژه را وارد کنید</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>گذرواژهٔ جدید</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>تکرار گذرواژهٔ جدید</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>رمزنگاری کیف پول</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>انجام این عملیات نیازمند گذرواژهٔ کیف پول شما برای باز کردن قفل آن است.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>باز کردن قفل کیف پول</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>انجام این عملیات نیازمند گذرواژهٔ کیف پول شما برای رمزگشایی کردن آن است.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>رمزگشایی کیف پول</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>تغییر گذرواژه</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>تأیید رمزنگاری کیف پول</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>هشدار: اگر کیف پول خود را رمزنگاری کنید و گذرواژه را فراموش کنید، &lt;b&gt;تمام دارایی بیت‌کوین خود را از دست خواهید داد&lt;/b&gt;!</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>آیا مطمئن هستید که می‌خواهید کیف پول خود را رمزنگاری کنید؟</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core 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.</source>
+ <translation>هسته بیت‌کوین هم اکنون بسته می‌شود تا فرایند رمزگذاری را تمام کند. به خاطر داشته باشید که رمزگذاری کردن کیف پول‌تان نمی‌تواند به طور کامل بیت‌کوین‌های شما را در برابر دزدیده شدن توسط بدافزارهایی که رایانه‌ی شما را آلوده می‌کنند، محافظت نماید.</translation>
+ </message>
+ <message>
+ <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
+ <translation>مهم: هر نسخهٔ پشتیبانی که تا کنون از کیف پول خود تهیه کرده‌اید، باید با کیف پول رمزنگاری شدهٔ جدید جایگزین شود. به دلایل امنیتی، پروندهٔ قدیمی کیف پول بدون رمزنگاری، تا زمانی که از کیف پول رمزنگاری‌شدهٔ جدید استفاده نکنید، غیرقابل استفاده خواهد بود.</translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>هشدار: کلید Caps Lock روشن است!</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>کیف پول رمزنگاری شد</translation>
+ </message>
+ <message>
+ <source>Enter the new passphrase to the wallet.&lt;br/&gt;Please use a passphrase of &lt;b&gt;ten or more random characters&lt;/b&gt;, or &lt;b&gt;eight or more words&lt;/b&gt;.</source>
+ <translation>رمز جدید کیف پول خود را وارد کنید.&lt;br/&gt;از رمز عبوری استفاده کنید که&lt;b&gt; حداقل 10 کاراکتر تصادفی &lt;/b&gt; و یا &lt;b&gt; حداقل 8 حرف داشته باشد.&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Enter the old passphrase and new passphrase to the wallet.</source>
+ <translation>رمز عبور قدیمی و رمز عبور جدید کیف پول خود را وارد گنید.</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>رمزنگاری کیف پول با شکست مواجه شد</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>رمزنگاری کیف پول بنا به یک خطای داخلی با شکست مواجه شد. کیف پول شما رمزنگاری نشد.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>گذرواژه‌های داده شده با هم تطابق ندارند.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>بازگشایی قفل کیف‌پول با شکست مواجه شد</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>گذرواژهٔ وارد شده برای رمزگشایی کیف پول نادرست بود.</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>رمزگشایی ناموفق کیف پول</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>گذرواژهٔ کیف پول با موفقیت عوض شد.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>&amp;امضای پیام...</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>همگام‌سازی با شبکه...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;بررسی اجمالی</translation>
+ </message>
+ <message>
+ <source>Node</source>
+ <translation>گره</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>نمایش بررسی اجمالی کیف پول</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;تراکنش‌ها</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>مرور تاریخچهٔ تراکنش‌ها</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>&amp;خروج</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>خروج از برنامه</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>دربارهٔ &amp;کیوت</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>نمایش اطلاعات دربارهٔ کیوت</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;تنظیمات...</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>&amp;رمزنگاری کیف پول...</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>&amp;پیشتیبان‌گیری از کیف پول...</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>&amp;تغییر گذرواژه...</translation>
+ </message>
+ <message>
+ <source>&amp;Sending addresses...</source>
+ <translation>&amp;در حال ارسال آدرس ها...</translation>
+ </message>
+ <message>
+ <source>&amp;Receiving addresses...</source>
+ <translation>&amp;در حال دریافت آدرس ها...</translation>
+ </message>
+ <message>
+ <source>Open &amp;URI...</source>
+ <translation>باز کردن &amp;آدرس</translation>
+ </message>
+ <message>
+ <source>Importing blocks from disk...</source>
+ <translation>دریافت بلوک‌ها از دیسک...</translation>
+ </message>
+ <message>
+ <source>Reindexing blocks on disk...</source>
+ <translation>بازنشانی بلوک‌ها روی دیسک...</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>ارسال وجه به نشانی بیت‌کوین</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>تهیهٔ پشتیبان از کیف پول در یک مکان دیگر</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>تغییر گذرواژهٔ مورد استفاده در رمزنگاری کیف پول</translation>
+ </message>
+ <message>
+ <source>&amp;Debug window</source>
+ <translation>پنجرهٔ ا&amp;شکال‌زدایی</translation>
+ </message>
+ <message>
+ <source>Open debugging and diagnostic console</source>
+ <translation>باز کردن کنسول خطایابی و اشکال‌زدایی</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>با&amp;زبینی پیام...</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>بیت‌کوین</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>کیف پول</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>&amp;ارسال</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>&amp;دریافت</translation>
+ </message>
+ <message>
+ <source>Show information about Bitcoin Core</source>
+ <translation>نمایش اطلاعات در مورد بیت‌کوین</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>&amp;نمایش/ عدم نمایش</translation>
+ </message>
+ <message>
+ <source>Show or hide the main Window</source>
+ <translation>نمایش یا مخفی‌کردن پنجرهٔ اصلی</translation>
+ </message>
+ <message>
+ <source>Encrypt the private keys that belong to your wallet</source>
+ <translation>رمزنگاری کلیدهای خصوصی متعلق به کیف پول شما</translation>
+ </message>
+ <message>
+ <source>Sign messages with your Bitcoin addresses to prove you own them</source>
+ <translation>برای اثبات اینکه پیام‌ها به شما تعلق دارند، آن‌ها را با نشانی بیت‌کوین خود امضا کنید</translation>
+ </message>
+ <message>
+ <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source>
+ <translation>برای حصول اطمینان از اینکه پیام با نشانی بیت‌کوین مشخص شده امضا است یا خیر، پیام را شناسایی کنید</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;فایل</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;تنظیمات</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>&amp;کمک‌رسانی</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>نوارابزار برگه‌ها</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation> هسته Bitcoin </translation>
+ </message>
+ <message>
+ <source>&amp;About Bitcoin Core</source>
+ <translation>درباره هسته ی بیت کوین</translation>
+ </message>
+ <message>
+ <source>Show the list of used sending addresses and labels</source>
+ <translation>نمایش لیست آدرس های ارسال و لیبل ها</translation>
+ </message>
+ <message>
+ <source>Show the list of used receiving addresses and labels</source>
+ <translation>نمایش لیست آدرس های دریافت و لیبل ها</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n active connection(s) to Bitcoin network</source>
+ <translation><numerusform>%n ارتباط فعال با شبکهٔ بیت‌کوین</numerusform></translation>
+ </message>
+ <message>
+ <source>No block source available...</source>
+ <translation>منبعی برای دریافت بلاک در دسترس نیست...</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n hour(s)</source>
+ <translation><numerusform>%n ساعت</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n day(s)</source>
+ <translation><numerusform>%n روز</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n week(s)</source>
+ <translation><numerusform>%n هفته</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 behind</source>
+ <translation>%1 عقب‌تر</translation>
+ </message>
+ <message>
+ <source>Last received block was generated %1 ago.</source>
+ <translation>آخرین بلاک دریافتی %1 پیش ایجاد شده است.</translation>
+ </message>
+ <message>
+ <source>Transactions after this will not yet be visible.</source>
+ <translation>تراکنش‌های بعد از این هنوز قابل مشاهده نیستند.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>خطا</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>هشدار</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>اطلاعات</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>وضعیت به‌روز</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>به‌روز رسانی...</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>تراکنش ارسال شد</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>تراکنش دریافت شد</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>کیف پول &lt;b&gt;رمزنگاری شده&lt;/b&gt; است و هم‌اکنون &lt;b&gt;باز&lt;/b&gt; است</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>کیف پول &lt;b&gt;رمزنگاری شده&lt;/b&gt; است و هم‌اکنون &lt;b&gt;قفل&lt;/b&gt; است</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <source>Network Alert</source>
+ <translation>پیام شبکه</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Coin Selection</source>
+ <translation>انتخاب سکه</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>تعداد:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>بایت ها:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>مبلغ:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>اولویت:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>هزینه:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>هزینه ی پسین:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>پول خورد:</translation>
+ </message>
+ <message>
+ <source>Tree mode</source>
+ <translation>مدل درختی</translation>
+ </message>
+ <message>
+ <source>List mode</source>
+ <translation>مدل لیست</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>مبلغ</translation>
+ </message>
+ <message>
+ <source>Received with label</source>
+ <translation>دریافت شده با برچسب</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>دریافت شده با نشانی</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>تاریخ</translation>
+ </message>
+ <message>
+ <source>Confirmations</source>
+ <translation>تاییدیه ها</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>تأیید شده</translation>
+ </message>
+ <message>
+ <source>Priority</source>
+ <translation>اولویت</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>کپی نشانی</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>کپی برچسب</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>کپی مقدار</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>کپی شناسهٔ تراکنش</translation>
+ </message>
+ <message>
+ <source>highest</source>
+ <translation>بیشترین</translation>
+ </message>
+ <message>
+ <source>higher</source>
+ <translation>بیشتر</translation>
+ </message>
+ <message>
+ <source>high</source>
+ <translation>زیاد</translation>
+ </message>
+ <message>
+ <source>medium-high</source>
+ <translation>متوسط متمایل به زیاد</translation>
+ </message>
+ <message>
+ <source>medium</source>
+ <translation>متوسط</translation>
+ </message>
+ <message>
+ <source>low-medium</source>
+ <translation>متوسط متمایل به کم</translation>
+ </message>
+ <message>
+ <source>low</source>
+ <translation>کم</translation>
+ </message>
+ <message>
+ <source>lower</source>
+ <translation>کمتر</translation>
+ </message>
+ <message>
+ <source>lowest</source>
+ <translation>کمترین</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>هیچکدام</translation>
+ </message>
+ <message>
+ <source>yes</source>
+ <translation>بله</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>خیر</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(بدون برچسب)</translation>
+ </message>
+ <message>
+ <source>(change)</source>
+ <translation>(تغییر)</translation>
+ </message>
+</context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>ویرایش نشانی</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>&amp;برچسب</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;نشانی</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>نشانی دریافتی جدید</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>نشانی ارسالی جدید</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>ویرایش نشانی دریافتی</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>ویرایش نشانی ارسالی</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>نشانی وارد شده «%1» در حال حاضر در دفترچه وجود دارد.</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is not a valid Bitcoin address.</source>
+ <translation>نشانی وارد شده «%1» یک نشانی معتبر بیت‌کوین نیست.</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>نمی‌توان کیف پول را رمزگشایی کرد.</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>ایجاد کلید جدید با شکست مواجه شد.</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ <message>
+ <source>A new data directory will be created.</source>
+ <translation>یک مسیر دادهٔ جدید ایجاد خواهد شد.</translation>
+ </message>
+ <message>
+ <source>name</source>
+ <translation>نام</translation>
+ </message>
+ <message>
+ <source>Directory already exists. Add %1 if you intend to create a new directory here.</source>
+ <translation>این پوشه در حال حاضر وجود دارد. اگر می‌خواهید یک دایرکتوری جدید در این‌جا ایجاد کنید، %1 را اضافه کنید.</translation>
+ </message>
+ <message>
+ <source>Path already exists, and is not a directory.</source>
+ <translation>مسیر داده شده موجود است و به یک پوشه اشاره نمی‌کند.</translation>
+ </message>
+ <message>
+ <source>Cannot create data directory here.</source>
+ <translation>نمی‌توان پوشهٔ داده در این‌جا ایجاد کرد.</translation>
+ </message>
+</context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation> هسته Bitcoin </translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>نسخه</translation>
+ </message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>درباره هسته ی بیت کوین</translation>
+ </message>
+ <message>
+ <source>Command-line options</source>
+ <translation>گزینه‌های خط‌فرمان</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>استفاده:</translation>
+ </message>
+ <message>
+ <source>command-line options</source>
+ <translation>گزینه‌های خط فرمان</translation>
+ </message>
+</context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Welcome</source>
+ <translation>خوش‌آمدید</translation>
+ </message>
+ <message>
+ <source>Welcome to Bitcoin Core.</source>
+ <translation>به هسته بیت کوین خوش آمدید.</translation>
+ </message>
+ <message>
+ <source>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</source>
+ <translation>از آنجایی که این اولین اجرای برنامه است، شما می‌توانید مسیر ذخیرهٔ داده‌ها را انتخاب کنید.</translation>
+ </message>
+ <message>
+ <source>Use the default data directory</source>
+ <translation>استفاده از مسیر پیش‌فرض</translation>
+ </message>
+ <message>
+ <source>Use a custom data directory:</source>
+ <translation>استفاده از یک مسیر سفارشی:</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation> هسته Bitcoin </translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>خطا</translation>
+ </message>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ </context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>گزینه‌ها</translation>
+ </message>
+ <message>
+ <source>&amp;Main</source>
+ <translation>&amp;عمومی</translation>
+ </message>
+ <message>
+ <source>Reset all client options to default.</source>
+ <translation>بازنشانی تمام تنظیمات به پیش‌فرض.</translation>
+ </message>
+ <message>
+ <source>&amp;Reset Options</source>
+ <translation>&amp;بازنشانی تنظیمات</translation>
+ </message>
+ <message>
+ <source>&amp;Network</source>
+ <translation>&amp;شبکه</translation>
+ </message>
+ <message>
+ <source>Expert</source>
+ <translation>استخراج</translation>
+ </message>
+ <message>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>باز کردن خودکار درگاه شبکهٔ بیت‌کوین روی روترها. تنها زمانی کار می‌کند که روتر از پروتکل UPnP پشتیبانی کند و این پروتکل فعال باشد.</translation>
+ </message>
+ <message>
+ <source>Map port using &amp;UPnP</source>
+ <translation>نگاشت درگاه شبکه با استفاده از پروتکل &amp;UPnP</translation>
+ </message>
+ <message>
+ <source>Proxy &amp;IP:</source>
+ <translation>آ&amp;ی‌پی پراکسی:</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>&amp;درگاه:</translation>
+ </message>
+ <message>
+ <source>Port of the proxy (e.g. 9050)</source>
+ <translation>درگاه پراکسی (مثال 9050)</translation>
+ </message>
+ <message>
+ <source>&amp;Window</source>
+ <translation>&amp;پنجره</translation>
+ </message>
+ <message>
+ <source>Show only a tray icon after minimizing the window.</source>
+ <translation>تنها بعد از کوچک کردن پنجره، tray icon را نشان بده.</translation>
+ </message>
+ <message>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>&amp;کوچک کردن به سینی به‌جای نوار وظیفه</translation>
+ </message>
+ <message>
+ <source>M&amp;inimize on close</source>
+ <translation>کوچک کردن &amp;در زمان بسته شدن</translation>
+ </message>
+ <message>
+ <source>&amp;Display</source>
+ <translation>&amp;نمایش</translation>
+ </message>
+ <message>
+ <source>User Interface &amp;language:</source>
+ <translation>زبان &amp;رابط کاربری:</translation>
+ </message>
+ <message>
+ <source>&amp;Unit to show amounts in:</source>
+ <translation>&amp;واحد نمایش مبالغ:</translation>
+ </message>
+ <message>
+ <source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
+ <translation>انتخاب واحد پول مورد استفاده برای نمایش در پنجره‌ها و برای ارسال سکه.</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>&amp;تأیید</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>&amp;لغو</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>پیش‌فرض</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>هیچکدام</translation>
+ </message>
+ <message>
+ <source>Confirm options reset</source>
+ <translation>تأییدِ بازنشانی گزینه‌ها</translation>
+ </message>
+ <message>
+ <source>This change would require a client restart.</source>
+ <translation>برای این تغییرات بازنشانی مشتری ضروری است</translation>
+ </message>
+ <message>
+ <source>The supplied proxy address is invalid.</source>
+ <translation>آدرس پراکسی داده شده صحیح نیست.</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>فرم</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>اطلاعات نمایش‌داده شده ممکن است قدیمی باشند. بعد از این که یک اتصال با شبکه برقرار شد، کیف پول شما به‌صورت خودکار با شبکهٔ بیت‌کوین همگام‌سازی می‌شود. اما این روند هنوز کامل نشده است.</translation>
+ </message>
+ <message>
+ <source>Available:</source>
+ <translation>در دسترس:</translation>
+ </message>
+ <message>
+ <source>Your current spendable balance</source>
+ <translation>تراز علی‌الحساب شما</translation>
+ </message>
+ <message>
+ <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source>
+ <translation>مجموع تراکنش‌هایی که هنوز تأیید نشده‌اند؛ و هنوز روی تراز علی‌الحساب اعمال نشده‌اند</translation>
+ </message>
+ <message>
+ <source>Immature:</source>
+ <translation>نارسیده:</translation>
+ </message>
+ <message>
+ <source>Mined balance that has not yet matured</source>
+ <translation>تراز استخراج شده از معدن که هنوز بالغ نشده است</translation>
+ </message>
+ <message>
+ <source>Balances</source>
+ <translation>تراز ها</translation>
+ </message>
+ <message>
+ <source>Total:</source>
+ <translation>جمع کل:</translation>
+ </message>
+ <message>
+ <source>Your current total balance</source>
+ <translation>تراز کل فعلی شما</translation>
+ </message>
+ <message>
+ <source>Spendable:</source>
+ <translation>:قابل خرج کردن</translation>
+ </message>
+ <message>
+ <source>Recent transactions</source>
+ <translation>تراکنش های اخیر</translation>
+ </message>
+ </context>
+<context>
+ <name>PaymentServer</name>
+ <message>
+ <source>URI handling</source>
+ <translation>مدیریت URI</translation>
+ </message>
+ <message>
+ <source>Payment request rejected</source>
+ <translation>درخواست پرداخت رد شد.</translation>
+ </message>
+ <message>
+ <source>Payment request error</source>
+ <translation>خطای درخواست پرداخت</translation>
+ </message>
+ <message>
+ <source>Cannot start bitcoin: click-to-pay handler</source>
+ <translation>نمی‌توان بیت‌کوین را اجرا کرد: کنترل‌کنندهٔ کلیک-و-پرداخت</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>درخواست پرداخت منقضی شد.</translation>
+ </message>
+ <message>
+ <source>Invalid payment request.</source>
+ <translation>درخواست پرداخت نامعتبر</translation>
+ </message>
+ </context>
+<context>
+ <name>PeerTableModel</name>
+ </context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>مبلغ</translation>
+ </message>
+ <message>
+ <source>None</source>
+ <translation>هیچکدام</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>ناموجود</translation>
+ </message>
+ </context>
+<context>
+ <name>QRImageWidget</name>
+ <message>
+ <source>Save QR Code</source>
+ <translation>ذخیرهٔ کد QR</translation>
+ </message>
+ </context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>Client name</source>
+ <translation>نام کلاینت</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>ناموجود</translation>
+ </message>
+ <message>
+ <source>Client version</source>
+ <translation>نسخهٔ کلاینت</translation>
+ </message>
+ <message>
+ <source>&amp;Information</source>
+ <translation>&amp;اطلاعات</translation>
+ </message>
+ <message>
+ <source>Using OpenSSL version</source>
+ <translation>نسخهٔ OpenSSL استفاده شده</translation>
+ </message>
+ <message>
+ <source>Startup time</source>
+ <translation>زمان آغاز به کار</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>شبکه</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>اسم</translation>
+ </message>
+ <message>
+ <source>Number of connections</source>
+ <translation>تعداد ارتباطات</translation>
+ </message>
+ <message>
+ <source>Block chain</source>
+ <translation>زنجیرهٔ بلوک‌ها</translation>
+ </message>
+ <message>
+ <source>Current number of blocks</source>
+ <translation>تعداد فعلی بلوک‌ها</translation>
+ </message>
+ <message>
+ <source>Received</source>
+ <translation>دریافتی</translation>
+ </message>
+ <message>
+ <source>Sent</source>
+ <translation>ارسال شده</translation>
+ </message>
+ <message>
+ <source>Version</source>
+ <translation>نسخه</translation>
+ </message>
+ <message>
+ <source>Services</source>
+ <translation>سرویس ها</translation>
+ </message>
+ <message>
+ <source>Last block time</source>
+ <translation>زمان آخرین بلوک</translation>
+ </message>
+ <message>
+ <source>&amp;Open</source>
+ <translation>با&amp;ز کردن</translation>
+ </message>
+ <message>
+ <source>&amp;Console</source>
+ <translation>&amp;کنسول</translation>
+ </message>
+ <message>
+ <source>Totals</source>
+ <translation>جمع کل:</translation>
+ </message>
+ <message>
+ <source>Build date</source>
+ <translation>ساخت تاریخ</translation>
+ </message>
+ <message>
+ <source>Debug log file</source>
+ <translation>فایلِ لاگِ اشکال زدایی</translation>
+ </message>
+ <message>
+ <source>Clear console</source>
+ <translation>پاکسازی کنسول</translation>
+ </message>
+ <message>
+ <source>Welcome to the Bitcoin Core RPC console.</source>
+ <translation>به کنسول RPC هسته بیت کوین خوش آمدید.</translation>
+ </message>
+ <message>
+ <source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
+ <translation>دکمه‌های بالا و پایین برای پیمایش تاریخچه و &lt;b&gt;Ctrl-L&lt;/b&gt; برای پاک کردن صفحه.</translation>
+ </message>
+ <message>
+ <source>Type &lt;b&gt;help&lt;/b&gt; for an overview of available commands.</source>
+ <translation>برای نمایش یک مرور کلی از دستورات ممکن، عبارت &lt;b&gt;help&lt;/b&gt; را بنویسید.</translation>
+ </message>
+ <message>
+ <source>Unknown</source>
+ <translation>ناشناخته</translation>
+ </message>
+ </context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;برچسب:</translation>
+ </message>
+ <message>
+ <source>Show</source>
+ <translation>نمایش</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>حذف کردن</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>کپی برچسب</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>کپی مقدار</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>QR Code</source>
+ <translation>کد QR</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>نشانی</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>مبلغ</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>برچسب</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>پیام</translation>
+ </message>
+ <message>
+ <source>Resulting URI too long, try to reduce the text for label / message.</source>
+ <translation>URL ایجاد شده خیلی طولانی است. سعی کنید طول برچسب و یا پیام را کمتر کنید.</translation>
+ </message>
+ <message>
+ <source>Error encoding URI into QR Code.</source>
+ <translation>خطا در تبدیل نشانی اینترنتی به صورت کد QR.</translation>
+ </message>
+</context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>تاریخ</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>برچسب</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>پیام</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>مبلغ</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(بدون برچسب)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>ارسال سکه</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>تعداد:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>بایت ها:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>مبلغ:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>اولویت:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>هزینه:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>هزینه ی پسین:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>پول خورد:</translation>
+ </message>
+ <message>
+ <source>fast</source>
+ <translation>سریع</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>ارسال به چند دریافت‌کنندهٔ به‌طور همزمان</translation>
+ </message>
+ <message>
+ <source>Add &amp;Recipient</source>
+ <translation>&amp;دریافت‌کنندهٔ جدید</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>پاکسازی &amp;همه</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>تزار:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>عملیات ارسال را تأیید کنید</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>&amp;ارسال</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>ارسال سکه را تأیید کنید</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>کپی مقدار</translation>
+ </message>
+ <message>
+ <source>or</source>
+ <translation>یا</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>مبلغ پرداخت باید بیشتر از ۰ باشد.</translation>
+ </message>
+ <message>
+ <source>The amount exceeds your balance.</source>
+ <translation>میزان پرداخت از تراز شما بیشتر است.</translation>
+ </message>
+ <message>
+ <source>The total exceeds your balance when the %1 transaction fee is included.</source>
+ <translation>با احتساب هزینهٔ %1 برای هر تراکنش، مجموع میزان پرداختی از مبلغ تراز شما بیشتر می‌شود.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>درخواست پرداخت منقضی شد.</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(بدون برچسب)</translation>
+ </message>
+ <message>
+ <source>Are you sure you want to send?</source>
+ <translation>آیا مطمئن هستید که می خواهید ارسال کنید؟</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>A&amp;مبلغ :</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>پرداخ&amp;ت به:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>برای این نشانی یک برچسب وارد کنید تا در دفترچهٔ آدرس ذخیره شود</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;برچسب:</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>انتخاب نشانی پیش‌تر استفاده شده</translation>
+ </message>
+ <message>
+ <source>This is a normal payment.</source>
+ <translation>این یک پرداخت عادی است</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to send the payment to</source>
+ <translation>نشانی بیت‌کوین برای ارسال پرداخت به آن</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>چسباندن نشانی از حافظهٔ سیستم</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Remove this entry</source>
+ <translation>حذف این مدخل</translation>
+ </message>
+ <message>
+ <source>Message:</source>
+ <translation>پیام:</translation>
+ </message>
+ </context>
+<context>
+ <name>ShutdownWindow</name>
+ </context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Signatures - Sign / Verify a Message</source>
+ <translation>امضاها - امضا / تأیید یک پیام</translation>
+ </message>
+ <message>
+ <source>&amp;Sign Message</source>
+ <translation>ا&amp;مضای پیام</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to sign the message with</source>
+ <translation>نشانی بیت‌کوین برای امضاء پیغام با آن</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>انتخاب نشانی پیشتر استفاده شده</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>چسباندن نشانی از حافظهٔ سیستم</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Enter the message you want to sign here</source>
+ <translation>پیامی را که می‌خواهید امضا کنید در اینجا وارد کنید</translation>
+ </message>
+ <message>
+ <source>Signature</source>
+ <translation>امضا</translation>
+ </message>
+ <message>
+ <source>Copy the current signature to the system clipboard</source>
+ <translation>امضای فعلی را به حافظهٔ سیستم کپی کن</translation>
+ </message>
+ <message>
+ <source>Sign the message to prove you own this Bitcoin address</source>
+ <translation>برای اثبات تعلق این نشانی به شما، پیام را امضا کنید</translation>
+ </message>
+ <message>
+ <source>Sign &amp;Message</source>
+ <translation>ا&amp;مضای پیام</translation>
+ </message>
+ <message>
+ <source>Reset all sign message fields</source>
+ <translation>بازنشانی تمام فیلدهای پیام</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>پاک &amp;کردن همه</translation>
+ </message>
+ <message>
+ <source>&amp;Verify Message</source>
+ <translation>&amp;شناسایی پیام</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address the message was signed with</source>
+ <translation>نشانی بیت‌کوین که پیغام با آن امضاء شده</translation>
+ </message>
+ <message>
+ <source>Verify the message to ensure it was signed with the specified Bitcoin address</source>
+ <translation>برای حصول اطمینان از اینکه پیام با نشانی بیت‌کوین مشخص شده امضا است یا خیر، پیام را شناسایی کنید</translation>
+ </message>
+ <message>
+ <source>Verify &amp;Message</source>
+ <translation>&amp;شناسایی پیام</translation>
+ </message>
+ <message>
+ <source>Reset all verify message fields</source>
+ <translation>بازنشانی تمام فیلدهای پیام</translation>
+ </message>
+ <message>
+ <source>Click "Sign Message" to generate signature</source>
+ <translation>برای ایجاد یک امضای جدید روی «امضای پیام» کلیک کنید</translation>
+ </message>
+ <message>
+ <source>The entered address is invalid.</source>
+ <translation>نشانی وارد شده نامعتبر است.</translation>
+ </message>
+ <message>
+ <source>Please check the address and try again.</source>
+ <translation>لطفاً نشانی را بررسی کنید و دوباره تلاش کنید.</translation>
+ </message>
+ <message>
+ <source>The entered address does not refer to a key.</source>
+ <translation>نشانی وارد شده به هیچ کلیدی اشاره نمی‌کند.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock was cancelled.</source>
+ <translation>عملیات باز کرن قفل کیف پول لغو شد.</translation>
+ </message>
+ <message>
+ <source>Private key for the entered address is not available.</source>
+ <translation>کلید خصوصی برای نشانی وارد شده در دسترس نیست.</translation>
+ </message>
+ <message>
+ <source>Message signing failed.</source>
+ <translation>امضای پیام با شکست مواجه شد.</translation>
+ </message>
+ <message>
+ <source>Message signed.</source>
+ <translation>پیام امضا شد.</translation>
+ </message>
+ <message>
+ <source>The signature could not be decoded.</source>
+ <translation>امضا نمی‌تواند کدگشایی شود.</translation>
+ </message>
+ <message>
+ <source>Please check the signature and try again.</source>
+ <translation>لطفاً امضا را بررسی نموده و دوباره تلاش کنید.</translation>
+ </message>
+ <message>
+ <source>The signature did not match the message digest.</source>
+ <translation>امضا با خلاصهٔ پیام مطابقت ندارد.</translation>
+ </message>
+ <message>
+ <source>Message verification failed.</source>
+ <translation>شناسایی پیام با شکست مواجه شد.</translation>
+ </message>
+ <message>
+ <source>Message verified.</source>
+ <translation>پیام شناسایی شد.</translation>
+ </message>
+</context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation> هسته Bitcoin </translation>
+ </message>
+ <message>
+ <source>The Bitcoin Core developers</source>
+ <translation>توسعه‌دهندگان هسته بیت‌کوین</translation>
+ </message>
+ <message>
+ <source>[testnet]</source>
+ <translation>آزمایش شبکه</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ <message>
+ <source>KB/s</source>
+ <translation>کیلوبایت</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>باز تا %1</translation>
+ </message>
+ <message>
+ <source>%1/offline</source>
+ <translation>%1/آفلاین</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/تأیید نشده</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 تأییدیه</translation>
+ </message>
+ <message>
+ <source>Status</source>
+ <translation>وضعیت</translation>
+ </message>
+ <message numerus="yes">
+ <source>, broadcast through %n node(s)</source>
+ <translation><numerusform>، پخش از طریق %n گره</numerusform></translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>تاریخ</translation>
+ </message>
+ <message>
+ <source>Source</source>
+ <translation>منبع</translation>
+ </message>
+ <message>
+ <source>Generated</source>
+ <translation>تولید شده</translation>
+ </message>
+ <message>
+ <source>From</source>
+ <translation>فرستنده</translation>
+ </message>
+ <message>
+ <source>To</source>
+ <translation>گیرنده</translation>
+ </message>
+ <message>
+ <source>own address</source>
+ <translation>آدرس شما</translation>
+ </message>
+ <message>
+ <source>label</source>
+ <translation>برچسب</translation>
+ </message>
+ <message>
+ <source>Credit</source>
+ <translation>بدهی</translation>
+ </message>
+ <message numerus="yes">
+ <source>matures in %n more block(s)</source>
+ <translation><numerusform>بلوغ در %n بلوک دیگر</numerusform></translation>
+ </message>
+ <message>
+ <source>not accepted</source>
+ <translation>پذیرفته نشد</translation>
+ </message>
+ <message>
+ <source>Debit</source>
+ <translation>اعتبار</translation>
+ </message>
+ <message>
+ <source>Transaction fee</source>
+ <translation>هزینهٔ تراکنش</translation>
+ </message>
+ <message>
+ <source>Net amount</source>
+ <translation>مبلغ خالص</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>پیام</translation>
+ </message>
+ <message>
+ <source>Comment</source>
+ <translation>نظر</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>شناسهٔ تراکنش</translation>
+ </message>
+ <message>
+ <source>Debug information</source>
+ <translation>اطلاعات اشکال‌زدایی</translation>
+ </message>
+ <message>
+ <source>Transaction</source>
+ <translation>تراکنش</translation>
+ </message>
+ <message>
+ <source>Inputs</source>
+ <translation>ورودی‌ها</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>مبلغ</translation>
+ </message>
+ <message>
+ <source>true</source>
+ <translation>درست</translation>
+ </message>
+ <message>
+ <source>false</source>
+ <translation>نادرست</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>، هنوز با موفقیت ارسال نشده</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>باز برای %n بلوک دیگر</numerusform></translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>ناشناس</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>جزئیات تراکنش</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>این پانل شامل توصیف کاملی از جزئیات تراکنش است</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>تاریخ</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>نوع</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>باز برای %n بلوک دیگر</numerusform></translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>باز شده تا %1</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>تأیید شده (%1 تأییدیه)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>این بلوک از هیچ همتای دیگری دریافت نشده است و احتمال می‌رود پذیرفته نشود!</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>تولید شده ولی قبول نشده</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>برچسب</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>دریافت‌شده با</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>دریافت‌شده از</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>ارسال‌شده به</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>پر داخت به خودتان</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>استخراج‌شده</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(ناموجود)</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>وضعیت تراکنش. نشانگر را روی این فیلد نگه دارید تا تعداد تأییدیه‌ها نشان داده شود.</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>تاریخ و ساعت دریافت تراکنش.</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>نوع تراکنش.</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>مبلغ کسر شده و یا اضافه شده به تراز.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>همه</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>امروز</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>این هفته</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>این ماه</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>ماه گذشته</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>امسال</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>محدوده...</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>دریافت‌شده با </translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>ارسال به</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>به خودتان</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>استخراج‌شده</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>دیگر</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>برای جست‌‌وجو نشانی یا برچسب را وارد کنید</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>مبلغ حداقل</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>کپی نشانی</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>کپی برچسب</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>کپی مقدار</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>کپی شناسهٔ تراکنش</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>ویرایش برچسب</translation>
+ </message>
+ <message>
+ <source>Show transaction details</source>
+ <translation>نمایش جزئیات تراکنش</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>استخراج انجام نشد</translation>
+ </message>
+ <message>
+ <source>Exporting Successful</source>
+ <translation>استخراج موفق</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>پروندهٔ نوع CSV جداشونده با کاما (*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>تأیید شده</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>تاریخ</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>نوع</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>برچسب</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>نشانی</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>شناسه</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>محدوده:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>به</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ </context>
+<context>
+ <name>WalletFrame</name>
+ </context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>ارسال وجه</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;صدور</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>داده ها نوارِ جاری را به فایل انتقال دهید</translation>
+ </message>
+ <message>
+ <source>Backup Wallet</source>
+ <translation>نسخهٔ پشتیبان کیف پول</translation>
+ </message>
+ <message>
+ <source>Wallet Data (*.dat)</source>
+ <translation>دادهٔ کیف پول (*.dat)</translation>
+ </message>
+ <message>
+ <source>Backup Failed</source>
+ <translation>خطا در پشتیبان‌گیری</translation>
+ </message>
+ <message>
+ <source>Backup Successful</source>
+ <translation>پشتیبان‌گیری موفق</translation>
+ </message>
+</context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>گزینه‌ها:</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>مشخص کردن دایرکتوری داده‌ها</translation>
+ </message>
+ <message>
+ <source>Connect to a node to retrieve peer addresses, and disconnect</source>
+ <translation>اتصال به یک گره برای دریافت آدرس‌های همتا و قطع اتصال پس از اتمام عملیات</translation>
+ </message>
+ <message>
+ <source>Specify your own public address</source>
+ <translation>آدرس عمومی خود را مشخص کنید</translation>
+ </message>
+ <message>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>پذیرش دستورات خط فرمان و دستورات JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>اجرا در پشت زمینه به‌صورت یک سرویس و پذیرش دستورات</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>استفاده از شبکهٔ آزمایش</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
+ <translation>پذیرش اتصالات از بیرون (پیش فرض:1 بدون پراکسی یا اتصال)</translation>
+ </message>
+ <message>
+ <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
+ <translation>مقید به نشانی داده شده باشید و همیشه از آن پیروی کنید. از نشانه گذاری استاندار IPv6 به صورت Host]:Port] استفاده کنید.</translation>
+ </message>
+ <message>
+ <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
+ <translation>هنگامی که یک تراکنش در کیف پولی رخ می دهد، دستور را اجرا کن(%s در دستورات بوسیله ی TxID جایگزین می شود)</translation>
+ </message>
+ <message>
+ <source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source>
+ <translation>این یک نسخه ی آزمایشی است - با مسئولیت خودتان از آن استفاده کنید - آن را در معدن و بازرگانی بکار نگیرید.</translation>
+ </message>
+ <message>
+ <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>هشدار: مبلغ paytxfee بسیار بالایی تنظیم شده است! این مبلغ هزینه‌ای است که شما برای تراکنش‌ها پرداخت می‌کنید.</translation>
+ </message>
+ <message>
+ <source>Block creation options:</source>
+ <translation>بستن گزینه ایجاد</translation>
+ </message>
+ <message>
+ <source>Connect only to the specified node(s)</source>
+ <translation>تنها در گره (های) مشخص شده متصل شوید</translation>
+ </message>
+ <message>
+ <source>Corrupted block database detected</source>
+ <translation>یک پایگاه داده ی بلوک خراب یافت شد</translation>
+ </message>
+ <message>
+ <source>Do you want to rebuild the block database now?</source>
+ <translation>آیا مایلید که اکنون پایگاه داده ی بلوک را بازسازی کنید؟</translation>
+ </message>
+ <message>
+ <source>Error initializing block database</source>
+ <translation>خطا در آماده سازی پایگاه داده ی بلوک</translation>
+ </message>
+ <message>
+ <source>Error loading block database</source>
+ <translation>خطا در بارگذاری پایگاه داده ها</translation>
+ </message>
+ <message>
+ <source>Error opening block database</source>
+ <translation>خطا در بازگشایی پایگاه داده ی بلوک</translation>
+ </message>
+ <message>
+ <source>Error: Disk space is low!</source>
+ <translation>خطا: فضای دیسک کم است!</translation>
+ </message>
+ <message>
+ <source>Failed to listen on any port. Use -listen=0 if you want this.</source>
+ <translation>شنیدن هر گونه درگاه انجام پذیر نیست. ازlisten=0 برای اینکار استفاده کیند.</translation>
+ </message>
+ <message>
+ <source>Importing...</source>
+ <translation>در حال پیاده‌سازی...</translation>
+ </message>
+ <message>
+ <source>Verifying blocks...</source>
+ <translation>در حال بازبینی بلوک ها...</translation>
+ </message>
+ <message>
+ <source>Verifying wallet...</source>
+ <translation>در حال بازبینی کیف پول...</translation>
+ </message>
+ <message>
+ <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source>
+ <translation>هشدار: تاریخ و ساعت کامپیوتر خود را بررسی کنید. اگر ساعت درست نباشد هسته بیت‌کوین به درستی کار نخواهد کرد.</translation>
+ </message>
+ <message>
+ <source>Choose data directory on startup (default: 0)</source>
+ <translation>انتخاب مسیر داده‌ها در ابتدای اجرای برنامه (پیش‌فرض: 0)</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>اطلاعات</translation>
+ </message>
+ <message>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>اطلاعات ردگیری/اشکال‌زدایی را به جای فایل لاگ اشکال‌زدایی به کنسول بفرستید</translation>
+ </message>
+ <message>
+ <source>Set language, for example "de_DE" (default: system locale)</source>
+ <translation>زبان را تنظیم کنید؛ برای مثال «de_DE» (زبان پیش‌فرض محلی)</translation>
+ </message>
+ <message>
+ <source>Show splash screen on startup (default: 1)</source>
+ <translation>نمایش پنجرهٔ خوشامدگویی در ابتدای اجرای برنامه (پیش‌فرض: 1)</translation>
+ </message>
+ <message>
+ <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source>
+ <translation>فایل debug.log را در startup مشتری کوچک کن (پیش فرض:1 اگر اشکال زدایی روی نداد)</translation>
+ </message>
+ <message>
+ <source>Start minimized</source>
+ <translation>اجرای برنامه به صورت کوچک‌شده</translation>
+ </message>
+ <message>
+ <source>UI Options:</source>
+ <translation>گزینه‌های رابط کاربری:</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: 1 when listening)</source>
+ <translation>از UPnP برای شناسایی درگاه شنیداری استفاده کنید (پیش فرض:1 در زمان شنیدن)</translation>
+ </message>
+ <message>
+ <source>Username for JSON-RPC connections</source>
+ <translation>JSON-RPC شناسه برای ارتباطات</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>هشدار</translation>
+ </message>
+ <message>
+ <source>Password for JSON-RPC connections</source>
+ <translation>JSON-RPC عبارت عبور برای ارتباطات</translation>
+ </message>
+ <message>
+ <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
+ <translation>زمانی که بهترین بلاک تغییر کرد، دستور را اجرا کن (%s در cmd با block hash جایگزین شده است)</translation>
+ </message>
+ <message>
+ <source>Upgrade wallet to latest format</source>
+ <translation>wallet را به جدیدترین فرمت روزآمد کنید</translation>
+ </message>
+ <message>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>اسکان مجدد زنجیر بلوکها برای گم والت معامله</translation>
+ </message>
+ <message>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>JSON-RPCبرای ارتباطات استفاده کنید OpenSSL (https)</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>پیام کمکی</translation>
+ </message>
+ <message>
+ <source>Allow DNS lookups for -addnode, -seednode and -connect</source>
+ <translation>به DNS اجازه بده تا برای addnode ، seednode و اتصال جستجو کند</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>بار گیری آدرس ها</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>خطا در بارگیری wallet.dat: کیف پول خراب شده است</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>خطا در بارگیری wallet.dat</translation>
+ </message>
+ <message>
+ <source>Invalid -proxy address: '%s'</source>
+ <translation>آدرس پراکسی اشتباه %s</translation>
+ </message>
+ <message>
+ <source>Unknown network specified in -onlynet: '%s'</source>
+ <translation>شبکه مشخص شده غیرقابل شناسایی در onlynet: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -bind address: '%s'</source>
+ <translation>آدرس قابل اتصال- شناسایی نیست %s</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -externalip address: '%s'</source>
+ <translation>آدرس خارجی قابل اتصال- شناسایی نیست %s</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>میزان وجه اشتباه برای paytxfee=&lt;میزان وجه&gt;: %s</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>بود جه نا کافی </translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>بار گیری شاخص بلوک</translation>
+ </message>
+ <message>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>به اتصال یک گره اضافه کنید و اتصال را باز نگاه دارید</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>بار گیری والت</translation>
+ </message>
+ <message>
+ <source>Cannot downgrade wallet</source>
+ <translation>امکان تنزل نسخه در wallet وجود ندارد</translation>
+ </message>
+ <message>
+ <source>Cannot write default address</source>
+ <translation>آدرس پیش فرض قابل ذخیره نیست</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>اسکان مجدد</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>بار گیری انجام شده است</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>خطا</translation>
+ </message>
+</context>
+</TS> \ 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 0000000000..1174e24b46
--- /dev/null
+++ b/src/qt/locale/bitcoin_fa_IR.ts
@@ -0,0 +1,1112 @@
+<TS language="fa_IR" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Create a new address</source>
+ <translation>گشایش حسابی جدید</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>جدید</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>کپی کردن حساب انتخاب شده به حافظه سیستم - کلیپ بورد</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>کپی</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>بستن</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>کپی آدرس</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>حذف آدرس های انتخاب شده از لیست</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>صدور داده نوار جاری به یک فایل</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>صدور</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>حذف</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>انتخاب آدرس جهت ارسال کوین ها به آن آدرس</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>انتخاب آدرس جهت دریافت کوین ها از آن آدرس</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>انتخاب</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>ارسال آدرس ها</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>دریافت آدرس ها</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>کپی برچسب</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>ویرایش</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>صدور لیست آدرس</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>فایل سی اس وی (*.csv)</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>صدور با شکست مواجه شد</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the address list to %1. Please try again.</source>
+ <translation>خطایی به هنگام ذخیره لیست آدرس در %1 رخ داده است. لطفا دوباره تلاش کنید.</translation>
+ </message>
+</context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>برچسب</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>حساب</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(برچسب ندارد)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Passphrase Dialog</source>
+ <translation>دیالوگ رمزعبور</translation>
+ </message>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>رمز/پَس فرِیز را وارد کنید</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>رمز/پَس فرِیز جدید را وارد کنید</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>رمز/پَس فرِیز را دوباره وارد کنید</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>wallet را رمزگذاری کنید</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>برای انجام این عملکرد به رمز/پَس فرِیزِwallet نیاز است تا آن را از حالت قفل درآورد.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>باز کردن قفل wallet </translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>برای کشف رمز wallet، به رمز/پَس فرِیزِwallet نیاز است.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>کشف رمز wallet</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>تغییر رمز/پَس فرِیز</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>رمزگذاری wallet را تایید کنید</translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>اخطار: کلید Caps Lock فعال است!</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>تایید رمزگذاری</translation>
+ </message>
+ <message>
+ <source>Enter the old passphrase and new passphrase to the wallet.</source>
+ <translation>رمز قدیمی و جدید کیف پول را وارد کنید.</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>رمزگذاری تایید نشد</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>رمزگذاری به علت خطای داخلی تایید نشد. wallet شما رمزگذاری نشد</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>رمزهای/پَس فرِیزهایِ وارد شده با هم تطابق ندارند</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>قفل wallet باز نشد</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>رمزهای/پَس فرِیزهایِ وارد شده wallet برای کشف رمز اشتباه است.</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>کشف رمز wallet انجام نشد</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>رمز عبور کیف پول با موفقیت تغییر کرد.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>امضا و پیام</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>به روز رسانی با شبکه...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>و بازبینی</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>نمای کلی از wallet را نشان بده</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>و تراکنش</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>تاریخچه تراکنش را باز کن</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>خروج</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>از "درخواست نامه"/ application خارج شو</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>درباره و Qt</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>نمایش اطلاعات درباره Qt</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>و انتخابها</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>و رمزگذاری wallet</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>و گرفتن نسخه پیشتیبان از wallet</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>تغییر رمز/پَس فرِیز</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>گرفتن نسخه پیشتیبان در آدرسی دیگر</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>رمز مربوط به رمزگذاریِ wallet را تغییر دهید</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>bitcoin</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>کیف پول</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>و ارسال</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>&amp;نمایش/ عدم نمایش و</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>و فایل</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>و تنظیمات</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>و راهنما</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>نوار ابزار</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>خطا</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>روزآمد</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>در حال روزآمد سازی..</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>ارسال تراکنش</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>تراکنش دریافتی</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>wallet رمزگذاری شد و در حال حاضر از حالت قفل در آمده است</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>wallet رمزگذاری شد و در حال حاضر قفل است</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <source>Network Alert</source>
+ <translation>هشدار شبکه</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Amount:</source>
+ <translation>میزان وجه:</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>میزان</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>تاریخ</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>تایید شده</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>آدرس را کپی کنید</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>برچسب را کپی کنید</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>میزان وجه کپی شود</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(برچسب ندارد)</translation>
+ </message>
+ </context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>ویرایش حساب</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>و برچسب</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>حساب&amp;</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>حساب دریافت کننده جدید
+</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>حساب ارسال کننده جدید</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>ویرایش حساب دریافت کننده</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>ویرایش حساب ارسال کننده</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is not a valid Bitcoin address.</source>
+ <translation>آدرس وارد شده "%1" یک آدرس صحیح برای bitcoin نسشت</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>عدم توانیی برای قفل گشایی wallet</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>عدم توانیی در ایجاد کلید جدید</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ </context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>version</source>
+ <translation>نسخه</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>میزان استفاده:</translation>
+ </message>
+ </context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Error</source>
+ <translation>خطا</translation>
+ </message>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ </context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>انتخاب/آپشن</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>و تایید</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>و رد</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>پیش فرض</translation>
+ </message>
+ </context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>فرم</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>اطلاعات نمایش داده شده ممکن است روزآمد نباشد. wallet شما به صورت خودکار بعد از برقراری اتصال با شبکه bitcoin به روز می شود اما این فرایند هنوز تکمیل نشده است.</translation>
+ </message>
+ </context>
+<context>
+ <name>PaymentServer</name>
+ </context>
+<context>
+ <name>PeerTableModel</name>
+ </context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>میزان</translation>
+ </message>
+ </context>
+<context>
+ <name>QRImageWidget</name>
+ </context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>Client name</source>
+ <translation>نام کنسول RPC</translation>
+ </message>
+ <message>
+ <source>Client version</source>
+ <translation>ویرایش کنسول RPC</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>شبکه</translation>
+ </message>
+ <message>
+ <source>Number of connections</source>
+ <translation>تعداد اتصال</translation>
+ </message>
+ <message>
+ <source>Block chain</source>
+ <translation>زنجیره مجموعه تراکنش ها</translation>
+ </message>
+ <message>
+ <source>Current number of blocks</source>
+ <translation>تعداد زنجیره های حاضر</translation>
+ </message>
+ </context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>و برچسب</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>برچسب را کپی کنید</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>میزان وجه کپی شود</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>Address</source>
+ <translation>حساب</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>میزان</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>برچسب</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>پیام</translation>
+ </message>
+ <message>
+ <source>Resulting URI too long, try to reduce the text for label / message.</source>
+ <translation>متن وارد شده طولانی است، متنِ برچسب/پیام را کوتاه کنید</translation>
+ </message>
+ <message>
+ <source>Error encoding URI into QR Code.</source>
+ <translation>خطای تبدیل URI به کد QR</translation>
+ </message>
+</context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>تاریخ</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>برچسب</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>پیام</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>میزان</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(برچسب ندارد)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>سکه های ارسالی</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>میزان وجه:</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>ارسال همزمان به گیرنده های متعدد</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>مانده حساب:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>تایید عملیات ارسال </translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>و ارسال</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>تایید ارسال بیت کوین ها</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>میزان وجه کپی شود</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>میزان پرداخت باید بیشتر از 0 باشد</translation>
+ </message>
+ <message>
+ <source>The amount exceeds your balance.</source>
+ <translation>مقدار مورد نظر از مانده حساب بیشتر است.</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(برچسب ندارد)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>و میزان وجه</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>پرداخت و به چه کسی</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>یک برچسب برای این آدرس بنویسید تا به دفترچه آدرسهای شما اضافه شود</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>و برچسب</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt و A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>آدرس را بر کلیپ بورد کپی کنید</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt و P</translation>
+ </message>
+ <message>
+ <source>Message:</source>
+ <translation>پیام:</translation>
+ </message>
+ <message>
+ <source>Pay To:</source>
+ <translation>پرداخت به:</translation>
+ </message>
+ <message>
+ <source>Memo:</source>
+ <translation>یادداشت:</translation>
+ </message>
+</context>
+<context>
+ <name>ShutdownWindow</name>
+ <message>
+ <source>Bitcoin Core is shutting down...</source>
+ <translation>هسته بیت کوین در حال خاموش شدن است...</translation>
+ </message>
+ <message>
+ <source>Do not shut down the computer until this window disappears.</source>
+ <translation>تا پیش از بسته شدن این پنجره کامپیوتر خود را خاموش نکنید.</translation>
+ </message>
+</context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>&amp;Sign Message</source>
+ <translation>و امضای پیام </translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt و A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>آدرس را بر کلیپ بورد کپی کنید</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt و P</translation>
+ </message>
+ </context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>[testnet]</source>
+ <translation>[testnet]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ </context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>باز کن تا %1</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1 / تایید نشده</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 تایید</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>تاریخ</translation>
+ </message>
+ <message>
+ <source>label</source>
+ <translation>برچسب</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>پیام</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>شناسه کاربری</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>میزان</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>، هنوز با موفقیت ارسال نگردیده است</translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>ناشناس</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>جزئیات تراکنش</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>این بخش جزئیات تراکنش را نشان می دهد</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>تاریخ</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>گونه</translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>باز کن تا %1</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>تایید شده (%1 تاییدها)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>این block توسط گره های دیگری دریافت نشده است و ممکن است قبول نشود</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>تولید شده اما قبول نشده است</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>برچسب</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>دریافت با</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>دریافت شده از</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>ارسال به</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>وجه برای شما </translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>استخراج شده</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>خالی</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>وضعیت تراکنش. با اشاره به این بخش تعداد تاییدها نمایش داده می شود</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>زمان و تاریخی که تراکنش دریافت شده است</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>نوع تراکنش</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>میزان وجه کم شده یا اضافه شده به حساب</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>همه</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>امروز</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>این هفته</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>این ماه</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>ماه گذشته</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>این سال</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>حدود..</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>دریافت با</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>ارسال به</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>به شما</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>استخراج شده</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>دیگر</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>آدرس یا برچسب را برای جستجو وارد کنید</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>حداقل میزان وجه</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>آدرس را کپی کنید</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>برچسب را کپی کنید</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>میزان وجه کپی شود</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>برچسب را ویرایش کنید</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>صدور با شکست مواجه شد</translation>
+ </message>
+ <message>
+ <source>Exporting Successful</source>
+ <translation>صدور با موفقیت انجام شد</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Comma separated file (*.csv) فایل جداگانه دستوری</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>تایید شده</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>تاریخ</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>گونه</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>برچسب</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>حساب</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>شناسه کاربری</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>دامنه:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>به</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ </context>
+<context>
+ <name>WalletFrame</name>
+ </context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>سکه های ارسالی</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>صدور</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>صدور داده نوار جاری به یک فایل</translation>
+ </message>
+ <message>
+ <source>Backup Wallet</source>
+ <translation>گرفتن نسخه پیشتیبان از Wallet</translation>
+ </message>
+ <message>
+ <source>Wallet Data (*.dat)</source>
+ <translation>داده های Wallet
+(*.dat)</translation>
+ </message>
+ <message>
+ <source>Backup Failed</source>
+ <translation>عملیات گرفتن نسخه پیشتیبان انجام نشد</translation>
+ </message>
+ </context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>انتخابها:</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>دایرکتوری داده را مشخص کن</translation>
+ </message>
+ <message>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>command line و JSON-RPC commands را قبول کنید</translation>
+ </message>
+ <message>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>به عنوان daemon بک گراند را اجرا کنید و دستورات را قبول نمایید</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>از تستِ شبکه استفاده نمایید</translation>
+ </message>
+ <message>
+ <source>The transaction amount is too small to send after the fee has been deducted</source>
+ <translation>مبلغ تراکنش کمتر از آن است که پس از کسر هزینه تراکنش قابل ارسال باشد</translation>
+ </message>
+ <message>
+ <source>RPC server options:</source>
+ <translation>گزینه های سرویس دهنده RPC:</translation>
+ </message>
+ <message>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>ارسال اطلاعات پیگیری/خطایابی به کنسول به جای ارسال به فایل debug.log</translation>
+ </message>
+ <message>
+ <source>Send transactions as zero-fee transactions if possible (default: %u)</source>
+ <translation>ارسال تراکنش ها به صورت بدون کارمزد در صورت امکان (پیش فرض: %u)</translation>
+ </message>
+ <message>
+ <source>Username for JSON-RPC connections</source>
+ <translation>شناسه کاربری برای ارتباطاتِ JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Password for JSON-RPC connections</source>
+ <translation>رمز برای ارتباطاتِ JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
+ <translation>دستور را وقتی بهترین بلاک تغییر کرد اجرا کن (%s در دستور توسط block hash جایگزین شده است)</translation>
+ </message>
+ <message>
+ <source>Upgrade wallet to latest format</source>
+ <translation>wallet را به جدیدترین نسخه روزآمد کنید</translation>
+ </message>
+ <message>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>زنجیره بلاک را برای تراکنش جا افتاده در WALLET دوباره اسکن کنید</translation>
+ </message>
+ <message>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>برای ارتباطاتِ JSON-RPC از OpenSSL (https) استفاده کنید</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>این پیام راهنما</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>لود شدن آدرسها..</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>خطا در هنگام لود شدن wallet.dat: Wallet corrupted</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>خطا در هنگام لود شدن wallet.dat</translation>
+ </message>
+ <message>
+ <source>Set minimum block size in bytes (default: %u)</source>
+ <translation>تنظیم کمینه اندازه بلاک بر حسب بایت (پیش فرض: %u)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads to service RPC calls (default: %d)</source>
+ <translation>تنظیم تعداد ریسمان ها برای سرویس دهی فراخوانی های RPC (پیش فرض: %d)</translation>
+ </message>
+ <message>
+ <source>Specify configuration file (default: %s)</source>
+ <translation>فایل تنظیمات را مشخص کنید (پیش فرض: %s)</translation>
+ </message>
+ <message>
+ <source>Specify pid file (default: %s)</source>
+ <translation>فایل pid را مشخص کنید (پیش فرض: %s)</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>میزان اشتباه است for -paytxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>وجوه ناکافی</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>لود شدن نمایه بلاکها..</translation>
+ </message>
+ <message>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>یک گره برای اتصال اضافه کنید و تلاش کنید تا اتصال را باز نگاه دارید</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>wallet در حال لود شدن است...</translation>
+ </message>
+ <message>
+ <source>Cannot downgrade wallet</source>
+ <translation>قابلیت برگشت به نسخه قبلی برای wallet امکان پذیر نیست</translation>
+ </message>
+ <message>
+ <source>Cannot write default address</source>
+ <translation>آدرس پیش فرض قابل ذخیره نیست</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>اسکنِ دوباره...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>اتمام لود شدن</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>خطا</translation>
+ </message>
+</context>
+</TS> \ 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 0000000000..6618649648
--- /dev/null
+++ b/src/qt/locale/bitcoin_fi.ts
@@ -0,0 +1,3272 @@
+<TS language="fi" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Right-click to edit address or label</source>
+ <translation>Valitse hiiren oikealla painikkeella muokataksesi osoitetta tai nimikettä</translation>
+ </message>
+ <message>
+ <source>Create a new address</source>
+ <translation>Luo uusi osoite</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>&amp;Uusi</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Kopioi valittu osoite leikepöydälle</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>&amp;Kopioi</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>S&amp;ulje</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>&amp;Kopioi osoite</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>Poista valittu osoite listalta</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Vie auki olevan välilehden tiedot tiedostoon</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Vie</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;Poista</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>Valitse osoite johon kolikot lähetetään</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>Valitse osoite johon vastaanotetaan kolikoita</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>V&amp;alitse</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>Lähettävä osoite</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>Vastaanottava osoite</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>Nämä ovat sinun Bitcoin osoitteita maksujen lähetykseen. Tarkista aina summa ja vastaanottajan osoite ennenkuin lähetät kolikkoja.</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>Nämä ovat sinun Bitcoin-osoitteesi suoritusten vastaanottamiseen. Suositellaan että annat uuden osoitteen kullekin transaktiolle.</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>Kopioi &amp;nimike</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>&amp;Muokkaa</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>Vie osoitekirja</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Comma separated file (*.csv)</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Vienti epäonnistui</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the address list to %1. Please try again.</source>
+ <translation>Virhe tallentaessa osoitelistaa %1. Yritä uudelleen.</translation>
+ </message>
+</context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Nimi</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Osoite</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(ei nimikettä)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Passphrase Dialog</source>
+ <translation>Tunnuslauseen tekstinsyöttökenttä</translation>
+ </message>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Kirjoita tunnuslause</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Uusi tunnuslause</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Toista uusi tunnuslause</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>Salaa lompakko</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>Tätä toimintoa varten sinun täytyy antaa lompakon tunnuslause sen avaamiseksi.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Avaa lompakko</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>Tätä toimintoa varten sinun täytyy antaa lompakon tunnuslause salauksen purkuun.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>Pura lompakon salaus</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>Vaihda tunnuslause</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>Vahvista lompakon salaus</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>Varoitus: Jos salaat lompakkosi ja menetät tunnuslauseesi, &lt;b&gt;MENETÄT KAIKKI BITCOINISI&lt;/b&gt;!</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>Haluatko varmasti salata lompakkosi?</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core 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.</source>
+ <translation>Bitcoin Core sammuu nyt viimeistelläkseen kryptaamisen. Muista että lompakon kryptaaminen ei voi täysin suojata bitcoinejasi varkaudelta malwaren saastuttamalla tietokoneella.</translation>
+ </message>
+ <message>
+ <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
+ <translation>TÄRKEÄÄ: Kaikki vanhat lompakon varmuuskopiot pitäisi korvata uusilla suojatuilla varmuuskopioilla. Turvallisuussyistä edelliset varmuuskopiot muuttuvat turhiksi, kun aloitat suojatun lompakon käytön.</translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>Varoitus: Caps Lock on käytössä!</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>Lompakko salattu</translation>
+ </message>
+ <message>
+ <source>Enter the new passphrase to the wallet.&lt;br/&gt;Please use a passphrase of &lt;b&gt;ten or more random characters&lt;/b&gt;, or &lt;b&gt;eight or more words&lt;/b&gt;.</source>
+ <translation>Anna salauslause lompakkoon. &lt;br/&gt;Ole hyvä ja käytä lausetta jossa on &lt;b&gt;kymmenen tai enemmän satunnaista merkkiä&lt;/b&gt; tai &lt;b&gt;kahdeksan tai useampi sanaa&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>Enter the old passphrase and new passphrase to the wallet.</source>
+ <translation>Syötä vanha ja uusi salasana lompakolle.</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>Lompakon salaus epäonnistui</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>Lompakon salaaminen epäonnistui sisäisen virheen vuoksi. Lompakkoasi ei salattu.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>Annetut tunnuslauseet eivät täsmää.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>Lompakon avaaminen epäonnistui.</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>Annettu tunnuslause oli väärä.</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>Lompakon salauksen purku epäonnistui.</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>Lompakon tunnuslause vaihdettiin onnistuneesti.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>&amp;Allekirjoita viesti...</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>Synkronoidaan verkon kanssa...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;Yleisnäkymä</translation>
+ </message>
+ <message>
+ <source>Node</source>
+ <translation>Solmu</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>Lompakon tilanteen yleiskatsaus</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Rahansiirrot</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>Selaa rahansiirtohistoriaa</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>L&amp;opeta</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>Sulje ohjelma</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>Tietoja &amp;Qt</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>Näytä tietoja Qt:ta</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;Asetukset...</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>&amp;Salaa lompakko...</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>&amp;Varmuuskopioi Lompakko...</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>&amp;Vaihda Tunnuslause...</translation>
+ </message>
+ <message>
+ <source>&amp;Sending addresses...</source>
+ <translation>&amp;Lähetysosoitteet...</translation>
+ </message>
+ <message>
+ <source>&amp;Receiving addresses...</source>
+ <translation>&amp;Vastaanotto-osoitteet...</translation>
+ </message>
+ <message>
+ <source>Open &amp;URI...</source>
+ <translation>Avaa &amp;URI...</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core client</source>
+ <translation>Bitcoin Core ohjelma</translation>
+ </message>
+ <message>
+ <source>Importing blocks from disk...</source>
+ <translation>Tuodaan lohkoja levyltä</translation>
+ </message>
+ <message>
+ <source>Reindexing blocks on disk...</source>
+ <translation>Ladataan lohkoindeksiä...</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>Lähetä kolikoita Bitcoin-osoitteeseen</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>Varmuuskopioi lompakko toiseen sijaintiin</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Vaihda lompakon salaukseen käytettävä tunnuslause</translation>
+ </message>
+ <message>
+ <source>&amp;Debug window</source>
+ <translation>&amp;Testausikkuna</translation>
+ </message>
+ <message>
+ <source>Open debugging and diagnostic console</source>
+ <translation>Avaa debuggaus- ja diagnostiikkakonsoli</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>Varmista &amp;viesti...</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>Lompakko</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>&amp;Lähetä</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>&amp;Vastaanota</translation>
+ </message>
+ <message>
+ <source>Show information about Bitcoin Core</source>
+ <translation>Näytä tietoja Bitcoin Core:sta</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>&amp;Näytä / Piilota</translation>
+ </message>
+ <message>
+ <source>Show or hide the main Window</source>
+ <translation>Näytä tai piilota Bitcoin-ikkuna</translation>
+ </message>
+ <message>
+ <source>Encrypt the private keys that belong to your wallet</source>
+ <translation>Suojaa yksityiset avaimet, jotka kuuluvat lompakkoosi</translation>
+ </message>
+ <message>
+ <source>Sign messages with your Bitcoin addresses to prove you own them</source>
+ <translation>Allekirjoita viestisi omalla Bitcoin -osoitteellasi todistaaksesi, että omistat ne</translation>
+ </message>
+ <message>
+ <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source>
+ <translation>Varmista, että viestisi on allekirjoitettu määritetyllä Bitcoin -osoitteella</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;Tiedosto</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;Asetukset</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>&amp;Apua</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>Välilehtipalkki</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin-ydin</translation>
+ </message>
+ <message>
+ <source>Request payments (generates QR codes and bitcoin: URIs)</source>
+ <translation>Pyydä maksuja (Luo QR koodit ja bitcoin: URIt)</translation>
+ </message>
+ <message>
+ <source>&amp;About Bitcoin Core</source>
+ <translation>&amp;Tietoja Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Modify configuration options for Bitcoin Core</source>
+ <translation>Muokkaa kokoonpanoasetuksia Bitcoin Corelle</translation>
+ </message>
+ <message>
+ <source>Show the list of used sending addresses and labels</source>
+ <translation>Näytä lähettämiseen käytettyjen osoitteiden ja nimien lista</translation>
+ </message>
+ <message>
+ <source>Show the list of used receiving addresses and labels</source>
+ <translation>Näytä vastaanottamiseen käytettyjen osoitteiden ja nimien lista</translation>
+ </message>
+ <message>
+ <source>Open a bitcoin: URI or payment request</source>
+ <translation>Avaa bitcoin: URI tai maksupyyntö</translation>
+ </message>
+ <message>
+ <source>&amp;Command-line options</source>
+ <translation>&amp;Komentorivin valinnat</translation>
+ </message>
+ <message>
+ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
+ <translation>Näytä Bitcoin Core ohjeet saadaksesi listan mahdollisista Bitcoinin komentorivivalinnoista</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n active connection(s) to Bitcoin network</source>
+ <translation><numerusform>%n aktiivinen yhteys Bitcoin-verkkoon</numerusform><numerusform>%n aktiivista yhteyttä Bitcoin-verkkoon</numerusform></translation>
+ </message>
+ <message>
+ <source>No block source available...</source>
+ <translation>Lohkojen lähdettä ei saatavilla...</translation>
+ </message>
+ <message numerus="yes">
+ <source>Processed %n block(s) of transaction history.</source>
+ <translation><numerusform>Prosessoitu %n lohko rahansiirtohistoriasta.</numerusform><numerusform>Prosessoitu %n lohkoa rahansiirtohistoriasta.</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n hour(s)</source>
+ <translation><numerusform>%n tunti</numerusform><numerusform>%n tuntia</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n day(s)</source>
+ <translation><numerusform>%n päivä</numerusform><numerusform>%n päivää</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n week(s)</source>
+ <translation><numerusform>%n viikko</numerusform><numerusform>%n viikkoa</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 and %2</source>
+ <translation>%1 ja %2</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n year(s)</source>
+ <translation><numerusform>%n vuosi</numerusform><numerusform>%n vuotta</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 behind</source>
+ <translation>%1 jäljessä</translation>
+ </message>
+ <message>
+ <source>Last received block was generated %1 ago.</source>
+ <translation>Viimeisin vastaanotettu lohko tuotettu %1.</translation>
+ </message>
+ <message>
+ <source>Transactions after this will not yet be visible.</source>
+ <translation>Tämän jälkeiset rahansiirrot eivät ole vielä näkyvissä.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Virhe</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Varoitus</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Tietoa</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>Rahansiirtohistoria on ajan tasalla</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>Saavutetaan verkkoa...</translation>
+ </message>
+ <message>
+ <source>Date: %1
+</source>
+ <translation>Päivämäärä: %1
+</translation>
+ </message>
+ <message>
+ <source>Amount: %1
+</source>
+ <translation>Määrä: %1
+</translation>
+ </message>
+ <message>
+ <source>Type: %1
+</source>
+ <translation>Tyyppi: %1
+</translation>
+ </message>
+ <message>
+ <source>Label: %1
+</source>
+ <translation>Nimike: %1
+</translation>
+ </message>
+ <message>
+ <source>Address: %1
+</source>
+ <translation>Osoite: %1
+</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>Lähetetyt rahansiirrot</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>Saapuva rahansiirto</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>Lompakko on &lt;b&gt;salattu&lt;/b&gt; ja tällä hetkellä &lt;b&gt;avoinna&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>Lompakko on &lt;b&gt;salattu&lt;/b&gt; ja tällä hetkellä &lt;b&gt;lukittuna&lt;/b&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <source>Network Alert</source>
+ <translation>Verkkohälytys</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Coin Selection</source>
+ <translation>Kolikoiden valinta</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Määrä:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Tavuja:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Määrä:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Prioriteetti:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Palkkio:</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Tomu:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Palkkion jälkeen:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Vaihtoraha:</translation>
+ </message>
+ <message>
+ <source>(un)select all</source>
+ <translation>(epä)valitse kaikki</translation>
+ </message>
+ <message>
+ <source>Tree mode</source>
+ <translation>Puurakenne</translation>
+ </message>
+ <message>
+ <source>List mode</source>
+ <translation>Listarakenne</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Määrä</translation>
+ </message>
+ <message>
+ <source>Received with label</source>
+ <translation>Vastaanotettu nimikkeellä</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>Vastaanotettu osoitteella</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Aika</translation>
+ </message>
+ <message>
+ <source>Confirmations</source>
+ <translation>Vahvistuksia</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Vahvistettu</translation>
+ </message>
+ <message>
+ <source>Priority</source>
+ <translation>Prioriteetti</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Kopioi osoite</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Kopioi nimi</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopioi määrä</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Kopioi siirtotunnus</translation>
+ </message>
+ <message>
+ <source>Lock unspent</source>
+ <translation>Lukitse käyttämättömät</translation>
+ </message>
+ <message>
+ <source>Unlock unspent</source>
+ <translation>Avaa käyttämättömät</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Kopioi määrä</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Kopioi palkkio</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Kopioi palkkion jälkeen</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Kopioi tavut</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Kopioi prioriteetti</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Kopioi tomu</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Kopioi vaihtoraha</translation>
+ </message>
+ <message>
+ <source>highest</source>
+ <translation>korkein</translation>
+ </message>
+ <message>
+ <source>higher</source>
+ <translation>korkeampi</translation>
+ </message>
+ <message>
+ <source>high</source>
+ <translation>korkea</translation>
+ </message>
+ <message>
+ <source>medium-high</source>
+ <translation>keski-korkea</translation>
+ </message>
+ <message>
+ <source>medium</source>
+ <translation>keskisuuri</translation>
+ </message>
+ <message>
+ <source>low-medium</source>
+ <translation>pieni-keskisuuri</translation>
+ </message>
+ <message>
+ <source>low</source>
+ <translation>pieni</translation>
+ </message>
+ <message>
+ <source>lower</source>
+ <translation>pienempi</translation>
+ </message>
+ <message>
+ <source>lowest</source>
+ <translation>pienin</translation>
+ </message>
+ <message>
+ <source>(%1 locked)</source>
+ <translation>(%1 lukittu)</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>ei mitään</translation>
+ </message>
+ <message>
+ <source>This label turns red if the transaction size is greater than 1000 bytes.</source>
+ <translation>Tämä nimi muuttuu punaiseksi mikäli rahansiirron koko on suurempi kuin 1000 tavua.</translation>
+ </message>
+ <message>
+ <source>This label turns red if the priority is smaller than "medium".</source>
+ <translation>Tämä nimi muuttuu punaiseksi mikäli prioriteetti on pienempi kuin "medium".</translation>
+ </message>
+ <message>
+ <source>This label turns red if any recipient receives an amount smaller than %1.</source>
+ <translation>Tämä nimike muuttuu punaiseksi mikäli mikä tahansa saaja vastaanottaa pienemmän määrän kuin %1.</translation>
+ </message>
+ <message>
+ <source>Can vary +/- %1 satoshi(s) per input.</source>
+ <translation>Saattaa vaihdella +/- %1 satoshia per syöte.</translation>
+ </message>
+ <message>
+ <source>yes</source>
+ <translation>kyllä</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>ei</translation>
+ </message>
+ <message>
+ <source>This means a fee of at least %1 per kB is required.</source>
+ <translation>Tämä tarkoittaa että vähintään %1 per kB palkkio on pakollinen.</translation>
+ </message>
+ <message>
+ <source>Can vary +/- 1 byte per input.</source>
+ <translation>Voi vaihdella +/- 1 tavu per syöte</translation>
+ </message>
+ <message>
+ <source>Transactions with higher priority are more likely to get included into a block.</source>
+ <translation>Rahansiirrot korkeammalla prioriteetilla sisällytetään varmemmin lohkoon.</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(ei nimeä)</translation>
+ </message>
+ <message>
+ <source>change from %1 (%2)</source>
+ <translation>Vaihda %1 (%2)</translation>
+ </message>
+ <message>
+ <source>(change)</source>
+ <translation>(vaihtoraha)</translation>
+ </message>
+</context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>Muokkaa osoitetta</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>&amp;Nimi</translation>
+ </message>
+ <message>
+ <source>The label associated with this address list entry</source>
+ <translation>Tähän osoitteeseen liitetty nimi</translation>
+ </message>
+ <message>
+ <source>The address associated with this address list entry. This can only be modified for sending addresses.</source>
+ <translation>Osoite liitettynä tähän osoitekirjan alkioon. Tämä voidaan muokata vain lähetysosoitteissa.</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;Osoite</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>Uusi vastaanottava osoite</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>Uusi lähettävä osoite</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>Muokkaa vastaanottajan osoitetta</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>Muokkaa lähtevää osoitetta</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>Osoite "%1" on jo osoitekirjassa.</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is not a valid Bitcoin address.</source>
+ <translation>Antamasi osoite "%1" ei ole validi Bitcoin-osoite.</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>Lompakkoa ei voitu avata.</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>Uuden avaimen luonti epäonnistui.</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ <message>
+ <source>A new data directory will be created.</source>
+ <translation>Luodaan uusi kansio.</translation>
+ </message>
+ <message>
+ <source>name</source>
+ <translation>Nimi</translation>
+ </message>
+ <message>
+ <source>Directory already exists. Add %1 if you intend to create a new directory here.</source>
+ <translation>Hakemisto on jo olemassa. Lisää %1 jos tarkoitus on luoda hakemisto tänne.</translation>
+ </message>
+ <message>
+ <source>Path already exists, and is not a directory.</source>
+ <translation>Polku on jo olemassa, eikä se ole kansio.</translation>
+ </message>
+ <message>
+ <source>Cannot create data directory here.</source>
+ <translation>Ei voida luoda data-hakemistoa tänne.</translation>
+ </message>
+</context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin-ydin</translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>versio</translation>
+ </message>
+ <message>
+ <source>(%1-bit)</source>
+ <translation>(%1-bit)</translation>
+ </message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>Tietoja Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Command-line options</source>
+ <translation>Komentorivi parametrit</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>Käyttö:</translation>
+ </message>
+ <message>
+ <source>command-line options</source>
+ <translation>komentorivi parametrit</translation>
+ </message>
+</context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Welcome</source>
+ <translation>Tervetuloa</translation>
+ </message>
+ <message>
+ <source>Welcome to Bitcoin Core.</source>
+ <translation>Tervetuloa Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</source>
+ <translation>Tämän on ensimmäinen kerta kun Bitcoin Core on käynnistetty joten voit valita data-hakemiston paikan.</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory.</source>
+ <translation>Bitcoin Core lataa ja tallentaa kopion Bitcoinin lohkoketjusta. Vähintään %1GB dataa tullaan tallentamaan tähän hakemistoon ja tarve kasvaa ajan myötä. Lomakko tullaan myös tallentamaan tähän hakemistoon.</translation>
+ </message>
+ <message>
+ <source>Use the default data directory</source>
+ <translation>Käytä oletuskansiota</translation>
+ </message>
+ <message>
+ <source>Use a custom data directory:</source>
+ <translation>Määritä oma kansio:</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin-ydin</translation>
+ </message>
+ <message>
+ <source>Error: Specified data directory "%1" cannot be created.</source>
+ <translation>Virhe: Annettu datahakemistoa "%1" ei voida luoda.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Virhe</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n GB of free space available</source>
+ <translation><numerusform>%n Gt vapaata tilaa käytettävissä</numerusform><numerusform>%n Gt vapaata tilaa käytettävissä</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>(of %n GB needed)</source>
+ <translation><numerusform>(%n Gt tarvittavasta tilasta)</numerusform><numerusform>(%n Gt tarvittavasta tilasta)</numerusform></translation>
+ </message>
+</context>
+<context>
+ <name>OpenURIDialog</name>
+ <message>
+ <source>Open URI</source>
+ <translation>Avaa URI</translation>
+ </message>
+ <message>
+ <source>Open payment request from URI or file</source>
+ <translation>Avaa maksupyyntö URI:sta tai tiedostosta</translation>
+ </message>
+ <message>
+ <source>URI:</source>
+ <translation>URI:</translation>
+ </message>
+ <message>
+ <source>Select payment request file</source>
+ <translation>Valitse maksupyynnön tiedosto</translation>
+ </message>
+ <message>
+ <source>Select payment request file to open</source>
+ <translation>Valitse maksypyynnön tiedosto avattavaksi</translation>
+ </message>
+</context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>Asetukset</translation>
+ </message>
+ <message>
+ <source>&amp;Main</source>
+ <translation>&amp;Yleiset</translation>
+ </message>
+ <message>
+ <source>Size of &amp;database cache</source>
+ <translation>&amp;Tietokannan välimuistin koko</translation>
+ </message>
+ <message>
+ <source>MB</source>
+ <translation>MB</translation>
+ </message>
+ <message>
+ <source>Number of script &amp;verification threads</source>
+ <translation>Script &amp;varmistuksen threadien määrä</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside</source>
+ <translation>Hyväksy yhteysiä ulkopuolelta</translation>
+ </message>
+ <message>
+ <source>Allow incoming connections</source>
+ <translation>Hyväksy sisääntulevia yhteyksiä</translation>
+ </message>
+ <message>
+ <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
+ <translation>IP osoite proxille (esim. IPv4: 127.0.0.1 / IPv6: ::1)</translation>
+ </message>
+ <message>
+ <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source>
+ <translation>Ulkopuoliset URL-osoitteet (esim. block explorer,) jotka esiintyvät siirrot-välilehdellä valikossa. %s URL-osoitteessa korvataan siirtotunnuksella. Useampi URL-osoite on eroteltu pystyviivalla |.</translation>
+ </message>
+ <message>
+ <source>Third party transaction URLs</source>
+ <translation>Kolmannen osapuolen rahansiirto URL:t</translation>
+ </message>
+ <message>
+ <source>Active command-line options that override above options:</source>
+ <translation>Aktiiviset komentorivivalinnat jotka ohittavat ylläolevat valinnat:</translation>
+ </message>
+ <message>
+ <source>Reset all client options to default.</source>
+ <translation>Palauta kaikki asetukset takaisin alkuperäisiksi.</translation>
+ </message>
+ <message>
+ <source>&amp;Reset Options</source>
+ <translation>&amp;Palauta asetukset</translation>
+ </message>
+ <message>
+ <source>&amp;Network</source>
+ <translation>&amp;Verkko</translation>
+ </message>
+ <message>
+ <source>Automatically start Bitcoin Core after logging in to the system.</source>
+ <translation>Käynnistä Bitcoin Core automaattisesti järjestelmään kirjautumisen jälkeen.</translation>
+ </message>
+ <message>
+ <source>&amp;Start Bitcoin Core on system login</source>
+ <translation>&amp;Käynnistä Bitcoin Core järjestelmään kirjautuessa</translation>
+ </message>
+ <message>
+ <source>(0 = auto, &lt;0 = leave that many cores free)</source>
+ <translation>(0 = auto, &lt;0 = jätä näin monta ydintä vapaaksi)</translation>
+ </message>
+ <message>
+ <source>W&amp;allet</source>
+ <translation>&amp;Lompakko</translation>
+ </message>
+ <message>
+ <source>Expert</source>
+ <translation>Expertti</translation>
+ </message>
+ <message>
+ <source>Enable coin &amp;control features</source>
+ <translation>Ota käytöön &amp;Kolikkokontrolli-ominaisuudet</translation>
+ </message>
+ <message>
+ <source>If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.</source>
+ <translation>Jos poistat varmistamattomien vaihtorahojen käytön, rahansiirron vaihtorahaa ei voida käyttää ennen vähintään yhtä varmistusta. Tämä vaikuttaa myös kuinka taseesi lasketaan.</translation>
+ </message>
+ <message>
+ <source>&amp;Spend unconfirmed change</source>
+ <translation>&amp;Käytä varmistamattomia vaihtorahoja</translation>
+ </message>
+ <message>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>Avaa Bitcoin-asiakasohjelman portti reitittimellä automaattisesti. Tämä toimii vain, jos reitittimesi tukee UPnP:tä ja se on käytössä.</translation>
+ </message>
+ <message>
+ <source>Map port using &amp;UPnP</source>
+ <translation>Portin uudelleenohjaus &amp;UPnP:llä</translation>
+ </message>
+ <message>
+ <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
+ <translation>Yhdistä Bitcoin-verkkoon SOCKS5-välityspalvelimen kautta.</translation>
+ </message>
+ <message>
+ <source>&amp;Connect through SOCKS5 proxy (default proxy):</source>
+ <translation>&amp;Yhdistä SOCKS5-välityspalvelimen kautta (oletus välityspalvelin):</translation>
+ </message>
+ <message>
+ <source>Proxy &amp;IP:</source>
+ <translation>Proxyn &amp;IP:</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>&amp;Portti</translation>
+ </message>
+ <message>
+ <source>Port of the proxy (e.g. 9050)</source>
+ <translation>Proxyn Portti (esim. 9050)</translation>
+ </message>
+ <message>
+ <source>&amp;Window</source>
+ <translation>&amp;Ikkuna</translation>
+ </message>
+ <message>
+ <source>Show only a tray icon after minimizing the window.</source>
+ <translation>Näytä ainoastaan ilmaisinalueella ikkunan pienentämisen jälkeen.</translation>
+ </message>
+ <message>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>&amp;Pienennä ilmaisinalueelle työkalurivin sijasta</translation>
+ </message>
+ <message>
+ <source>M&amp;inimize on close</source>
+ <translation>P&amp;ienennä suljettaessa</translation>
+ </message>
+ <message>
+ <source>&amp;Display</source>
+ <translation>&amp;Käyttöliittymä</translation>
+ </message>
+ <message>
+ <source>User Interface &amp;language:</source>
+ <translation>&amp;Käyttöliittymän kieli</translation>
+ </message>
+ <message>
+ <source>&amp;Unit to show amounts in:</source>
+ <translation>Yksikkö jona bitcoin-määrät näytetään</translation>
+ </message>
+ <message>
+ <source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
+ <translation>Valitse mitä yksikköä käytetään ensisijaisesti bitcoin-määrien näyttämiseen.</translation>
+ </message>
+ <message>
+ <source>Whether to show coin control features or not.</source>
+ <translation>Näytetäänkö kolikkokontrollin ominaisuuksia vai ei</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>&amp;OK</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>&amp;Peruuta</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>oletus</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>ei mitään</translation>
+ </message>
+ <message>
+ <source>Confirm options reset</source>
+ <translation>Varmista asetusten palautus</translation>
+ </message>
+ <message>
+ <source>Client restart required to activate changes.</source>
+ <translation>Ohjelman uudelleenkäynnistys aktivoi muutokset.</translation>
+ </message>
+ <message>
+ <source>Client will be shut down. Do you want to proceed?</source>
+ <translation>Asiakasohjelma sammutetaan. Haluatko jatkaa?</translation>
+ </message>
+ <message>
+ <source>This change would require a client restart.</source>
+ <translation>Tämä muutos vaatii ohjelman uudelleenkäynnistyksen.</translation>
+ </message>
+ <message>
+ <source>The supplied proxy address is invalid.</source>
+ <translation>Antamasi proxy-osoite on virheellinen.</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>Lomake</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>Näytetyt tiedot eivät välttämättä ole ajantasalla. Lompakkosi synkronoituu Bitcoin-verkon kanssa automaattisesti yhteyden muodostamisen jälkeen, mutta synkronointi on vielä meneillään.</translation>
+ </message>
+ <message>
+ <source>Watch-only:</source>
+ <translation>Seuranta:</translation>
+ </message>
+ <message>
+ <source>Available:</source>
+ <translation>Käytettävissä:</translation>
+ </message>
+ <message>
+ <source>Your current spendable balance</source>
+ <translation>Nykyinen käytettävissä oleva tase</translation>
+ </message>
+ <message>
+ <source>Pending:</source>
+ <translation>Odotetaan:</translation>
+ </message>
+ <message>
+ <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source>
+ <translation>Varmistamattomien rahansiirtojen summa, jota ei lasketa käytettävissä olevaan taseeseen.</translation>
+ </message>
+ <message>
+ <source>Immature:</source>
+ <translation>Epäkypsää:</translation>
+ </message>
+ <message>
+ <source>Mined balance that has not yet matured</source>
+ <translation>Louhittu saldo, joka ei ole vielä kypsynyt</translation>
+ </message>
+ <message>
+ <source>Balances</source>
+ <translation>Saldot</translation>
+ </message>
+ <message>
+ <source>Total:</source>
+ <translation>Yhteensä:</translation>
+ </message>
+ <message>
+ <source>Your current total balance</source>
+ <translation>Tililläsi tällä hetkellä olevien Bitcoinien määrä</translation>
+ </message>
+ <message>
+ <source>Your current balance in watch-only addresses</source>
+ <translation>Nykyinen tase seurantaosoitetteissa</translation>
+ </message>
+ <message>
+ <source>Spendable:</source>
+ <translation>Käytettävissä:</translation>
+ </message>
+ <message>
+ <source>Recent transactions</source>
+ <translation>Viimeisimmät rahansiirrot</translation>
+ </message>
+ <message>
+ <source>Unconfirmed transactions to watch-only addresses</source>
+ <translation>Vahvistamattomat rahansiirrot vain katseltaviin osoitteisiin</translation>
+ </message>
+ <message>
+ <source>Mined balance in watch-only addresses that has not yet matured</source>
+ <translation>Louhittu, ei vielä kypsynyt saldo vain katseltavissa osoitteissa</translation>
+ </message>
+ <message>
+ <source>Current total balance in watch-only addresses</source>
+ <translation>Nykyinen tase seurantaosoitetteissa</translation>
+ </message>
+</context>
+<context>
+ <name>PaymentServer</name>
+ <message>
+ <source>URI handling</source>
+ <translation>URI käsittely</translation>
+ </message>
+ <message>
+ <source>Invalid payment address %1</source>
+ <translation>Virheellinen maksuosoite %1</translation>
+ </message>
+ <message>
+ <source>Payment request rejected</source>
+ <translation>Maksupyyntö hylätty</translation>
+ </message>
+ <message>
+ <source>Payment request network doesn't match client network.</source>
+ <translation>Maksypyyntö verkossa ei täsmää asiakasohjelman verkkoon.</translation>
+ </message>
+ <message>
+ <source>Payment request is not initialized.</source>
+ <translation>Maksupyyntöä ei ole alustettu.</translation>
+ </message>
+ <message>
+ <source>Requested payment amount of %1 is too small (considered dust).</source>
+ <translation>Maksupyyntö %1 on liian pieni (huomioidaan tomuna).</translation>
+ </message>
+ <message>
+ <source>Payment request error</source>
+ <translation>Maksupyyntövirhe</translation>
+ </message>
+ <message>
+ <source>Cannot start bitcoin: click-to-pay handler</source>
+ <translation>Ei voida käynnistää bitcoin: klikkaa-maksu käsittelijää</translation>
+ </message>
+ <message>
+ <source>Payment request fetch URL is invalid: %1</source>
+ <translation>Maksupyynnön haku URL on virheellinen: %1</translation>
+ </message>
+ <message>
+ <source>URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source>
+ <translation>URIa ei voitu jäsentää! Tämä voi johtua kelvottomasta Bitcoin-osoitteesta tai virheellisistä URI parametreista.</translation>
+ </message>
+ <message>
+ <source>Payment request file handling</source>
+ <translation>Maksupyynnön tiedoston käsittely</translation>
+ </message>
+ <message>
+ <source>Payment request file cannot be read! This can be caused by an invalid payment request file.</source>
+ <translation>Maksupyynnön tiedostoa ei voida lukea! Tämä voi aiheutua sopimattomasta maksupyyntötiedostosta.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>Maksupyyntö on vanhentunut.</translation>
+ </message>
+ <message>
+ <source>Unverified payment requests to custom payment scripts are unsupported.</source>
+ <translation>Varmistamattomia maksupyyntöjä kustomoituun maksupalveluun ei tueta.</translation>
+ </message>
+ <message>
+ <source>Invalid payment request.</source>
+ <translation>Epäkelpo maksupyyntö.</translation>
+ </message>
+ <message>
+ <source>Refund from %1</source>
+ <translation>Maksupalautus %1:sta</translation>
+ </message>
+ <message>
+ <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source>
+ <translation>Maksupyyntö %1 on liian suuri (%2 tavua, sallittu %3 tavua).</translation>
+ </message>
+ <message>
+ <source>Payment request DoS protection</source>
+ <translation>Maksupyynnön DoS-suojaus</translation>
+ </message>
+ <message>
+ <source>Error communicating with %1: %2</source>
+ <translation>Virhe kommunikoidessa %1n kanssa: %2</translation>
+ </message>
+ <message>
+ <source>Payment request cannot be parsed!</source>
+ <translation>Maksupyyntöä ei voida jäsentää!</translation>
+ </message>
+ <message>
+ <source>Bad response from server %1</source>
+ <translation>Huono vastaus palvelimelta %1</translation>
+ </message>
+ <message>
+ <source>Payment acknowledged</source>
+ <translation>Rahansiirto tunnistettu</translation>
+ </message>
+ <message>
+ <source>Network request error</source>
+ <translation>Tietoverkon pyyntövirhe</translation>
+ </message>
+</context>
+<context>
+ <name>PeerTableModel</name>
+ <message>
+ <source>User Agent</source>
+ <translation>Käyttöliittymä</translation>
+ </message>
+ <message>
+ <source>Node/Service</source>
+ <translation>Noodi/Palvelu</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Vasteaika</translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>Määrä</translation>
+ </message>
+ <message>
+ <source>Enter a Bitcoin address (e.g. %1)</source>
+ <translation>Syötä Bitcoin-osoite (esim. %1)</translation>
+ </message>
+ <message>
+ <source>%1 d</source>
+ <translation>%1 d</translation>
+ </message>
+ <message>
+ <source>%1 h</source>
+ <translation>%1 h</translation>
+ </message>
+ <message>
+ <source>%1 m</source>
+ <translation>%1 m</translation>
+ </message>
+ <message>
+ <source>%1 s</source>
+ <translation>%1 s</translation>
+ </message>
+ <message>
+ <source>None</source>
+ <translation>Ei yhtään</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>Ei saatavilla</translation>
+ </message>
+ <message>
+ <source>%1 ms</source>
+ <translation>%1 ms</translation>
+ </message>
+</context>
+<context>
+ <name>QRImageWidget</name>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Tallenna kuva</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Image</source>
+ <translation>&amp;Kopioi kuva</translation>
+ </message>
+ <message>
+ <source>Save QR Code</source>
+ <translation>Tallenna QR-koodi</translation>
+ </message>
+ <message>
+ <source>PNG Image (*.png)</source>
+ <translation>PNG kuva (*.png)</translation>
+ </message>
+</context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>Client name</source>
+ <translation>Pääteohjelman nimi</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>Ei saatavilla</translation>
+ </message>
+ <message>
+ <source>Client version</source>
+ <translation>Pääteohjelman versio</translation>
+ </message>
+ <message>
+ <source>&amp;Information</source>
+ <translation>T&amp;ietoa</translation>
+ </message>
+ <message>
+ <source>Debug window</source>
+ <translation>&amp;Debug-ikkuna</translation>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>Yleinen</translation>
+ </message>
+ <message>
+ <source>Using OpenSSL version</source>
+ <translation>Käytössä oleva OpenSSL-versio</translation>
+ </message>
+ <message>
+ <source>Using BerkeleyDB version</source>
+ <translation>Käyttää BerkeleyDB-versiota</translation>
+ </message>
+ <message>
+ <source>Startup time</source>
+ <translation>Käynnistysaika</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Verkko</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>Nimi</translation>
+ </message>
+ <message>
+ <source>Number of connections</source>
+ <translation>Yhteyksien lukumäärä</translation>
+ </message>
+ <message>
+ <source>Block chain</source>
+ <translation>Lohkoketju</translation>
+ </message>
+ <message>
+ <source>Current number of blocks</source>
+ <translation>Nykyinen Lohkojen määrä</translation>
+ </message>
+ <message>
+ <source>Received</source>
+ <translation>Vastaanotetut</translation>
+ </message>
+ <message>
+ <source>Sent</source>
+ <translation>Lähetetyt</translation>
+ </message>
+ <message>
+ <source>&amp;Peers</source>
+ <translation>&amp;Vertaiset</translation>
+ </message>
+ <message>
+ <source>Select a peer to view detailed information.</source>
+ <translation>Valitse vertainen eriteltyjä tietoja varten.</translation>
+ </message>
+ <message>
+ <source>Direction</source>
+ <translation>Suunta</translation>
+ </message>
+ <message>
+ <source>Version</source>
+ <translation>Versio</translation>
+ </message>
+ <message>
+ <source>User Agent</source>
+ <translation>Käyttöliittymä</translation>
+ </message>
+ <message>
+ <source>Services</source>
+ <translation>Palvelut</translation>
+ </message>
+ <message>
+ <source>Starting Height</source>
+ <translation>Aloituskorkeus</translation>
+ </message>
+ <message>
+ <source>Sync Height</source>
+ <translation>Synkronointikorkeus</translation>
+ </message>
+ <message>
+ <source>Ban Score</source>
+ <translation>Panna-pisteytys</translation>
+ </message>
+ <message>
+ <source>Connection Time</source>
+ <translation>Yhteysaika</translation>
+ </message>
+ <message>
+ <source>Last Send</source>
+ <translation>Viimeisin lähetetty</translation>
+ </message>
+ <message>
+ <source>Last Receive</source>
+ <translation>Viimeisin vastaanotettu</translation>
+ </message>
+ <message>
+ <source>Bytes Sent</source>
+ <translation>Tavua lähetetty</translation>
+ </message>
+ <message>
+ <source>Bytes Received</source>
+ <translation>Tavua vastaanotettu</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Vasteaika</translation>
+ </message>
+ <message>
+ <source>Time Offset</source>
+ <translation>Ajan poikkeama</translation>
+ </message>
+ <message>
+ <source>Last block time</source>
+ <translation>Viimeisimmän lohkon aika</translation>
+ </message>
+ <message>
+ <source>&amp;Open</source>
+ <translation>&amp;Avaa</translation>
+ </message>
+ <message>
+ <source>&amp;Console</source>
+ <translation>&amp;Konsoli</translation>
+ </message>
+ <message>
+ <source>&amp;Network Traffic</source>
+ <translation>&amp;Verkkoliikenne</translation>
+ </message>
+ <message>
+ <source>&amp;Clear</source>
+ <translation>&amp;Tyhjennä</translation>
+ </message>
+ <message>
+ <source>Totals</source>
+ <translation>Yhteensä</translation>
+ </message>
+ <message>
+ <source>In:</source>
+ <translation>Sisään:</translation>
+ </message>
+ <message>
+ <source>Out:</source>
+ <translation>Ulos:</translation>
+ </message>
+ <message>
+ <source>Build date</source>
+ <translation>Kääntöpäiväys</translation>
+ </message>
+ <message>
+ <source>Debug log file</source>
+ <translation>Debug lokitiedosto</translation>
+ </message>
+ <message>
+ <source>Clear console</source>
+ <translation>Tyhjennä konsoli</translation>
+ </message>
+ <message>
+ <source>Welcome to the Bitcoin Core RPC console.</source>
+ <translation>Tervetuloa Bitcoin Coren RPC-konsoliin.</translation>
+ </message>
+ <message>
+ <source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
+ <translation>Ylös- ja alas-nuolet selaavat historiaa ja &lt;b&gt;Ctrl-L&lt;/b&gt; tyhjentää ruudun.</translation>
+ </message>
+ <message>
+ <source>Type &lt;b&gt;help&lt;/b&gt; for an overview of available commands.</source>
+ <translation>Kirjoita &lt;b&gt;help&lt;/b&gt; nähdäksesi yleiskatsauksen käytettävissä olevista komennoista.</translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation>%1 B</translation>
+ </message>
+ <message>
+ <source>%1 KB</source>
+ <translation>%1 KB</translation>
+ </message>
+ <message>
+ <source>%1 MB</source>
+ <translation>%1 MB</translation>
+ </message>
+ <message>
+ <source>%1 GB</source>
+ <translation>%1 GB</translation>
+ </message>
+ <message>
+ <source>via %1</source>
+ <translation>%1 kautta</translation>
+ </message>
+ <message>
+ <source>never</source>
+ <translation>ei koskaan</translation>
+ </message>
+ <message>
+ <source>Inbound</source>
+ <translation>Sisääntuleva</translation>
+ </message>
+ <message>
+ <source>Outbound</source>
+ <translation>Ulosmenevä</translation>
+ </message>
+ <message>
+ <source>Unknown</source>
+ <translation>Tuntematon</translation>
+ </message>
+ <message>
+ <source>Fetching...</source>
+ <translation>Hankitaan...</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Amount:</source>
+ <translation>&amp;Määrä</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Nimi:</translation>
+ </message>
+ <message>
+ <source>&amp;Message:</source>
+ <translation>&amp;Viesti:</translation>
+ </message>
+ <message>
+ <source>Reuse one of the previously used receiving addresses. Reusing addresses has security and privacy issues. Do not use this unless re-generating a payment request made before.</source>
+ <translation>Uudelleenkäytä yksi vanhoista vastaanotto-osoitteista. Uudelleenkäyttössä on turvallisuus- ja yksityisyysongelmia. Älä käytä tätä ellet ole uudelleenluomassa aikaisempaa maksupyyntöä.</translation>
+ </message>
+ <message>
+ <source>R&amp;euse an existing receiving address (not recommended)</source>
+ <translation>&amp;Uudelleenkäytä vastaanotto-osoitetta (ei suositella)</translation>
+ </message>
+ <message>
+ <source>An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network.</source>
+ <translation>Valinnainen viesti liitetään maksupyyntöön ja näytetään avattaessa. Viestiä ei lähetetä Bitcoin-verkkoon.</translation>
+ </message>
+ <message>
+ <source>An optional label to associate with the new receiving address.</source>
+ <translation>Valinnainen nimi liitetään vastaanottavaan osoitteeseen.</translation>
+ </message>
+ <message>
+ <source>Use this form to request payments. All fields are &lt;b&gt;optional&lt;/b&gt;.</source>
+ <translation>Käytä lomaketta maksupyyntöihin. Kaikki kentät ovat &lt;b&gt;valinnaisia&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>An optional amount to request. Leave this empty or zero to not request a specific amount.</source>
+ <translation>Valinnainen pyyntömäärä. Jätä tyhjäksi tai nollaksi jos et pyydä tiettyä määrää.</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Tyhjennä lomakkeen kaikki kentät.</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation>Tyhjennä</translation>
+ </message>
+ <message>
+ <source>Requested payments history</source>
+ <translation>Pyydettyjen maksujen historia</translation>
+ </message>
+ <message>
+ <source>&amp;Request payment</source>
+ <translation>&amp;Vastaanota maksu</translation>
+ </message>
+ <message>
+ <source>Show the selected request (does the same as double clicking an entry)</source>
+ <translation>Näytä valittu pyyntö (sama toiminta kuin alkion tuplaklikkaus)</translation>
+ </message>
+ <message>
+ <source>Show</source>
+ <translation>Näytä</translation>
+ </message>
+ <message>
+ <source>Remove the selected entries from the list</source>
+ <translation>Poista valitut alkiot listasta</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>Poista</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Kopioi nimi</translation>
+ </message>
+ <message>
+ <source>Copy message</source>
+ <translation>Kopioi viesti</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopioi määrä</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>QR Code</source>
+ <translation>QR-koodi</translation>
+ </message>
+ <message>
+ <source>Copy &amp;URI</source>
+ <translation>Kopioi &amp;URI</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Address</source>
+ <translation>Kopioi &amp;Osoite</translation>
+ </message>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Tallenna kuva</translation>
+ </message>
+ <message>
+ <source>Request payment to %1</source>
+ <translation>Vastaanota maksu %1</translation>
+ </message>
+ <message>
+ <source>Payment information</source>
+ <translation>Maksutiedot</translation>
+ </message>
+ <message>
+ <source>URI</source>
+ <translation>URI</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Osoite</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Määrä</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Nimi</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Viesti</translation>
+ </message>
+ <message>
+ <source>Resulting URI too long, try to reduce the text for label / message.</source>
+ <translation>Tuloksen URI liian pitkä, yritä lyhentää otsikon tekstiä / viestiä.</translation>
+ </message>
+ <message>
+ <source>Error encoding URI into QR Code.</source>
+ <translation>Virhe käännettäessä URI:a QR-koodiksi.</translation>
+ </message>
+</context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Aika</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Nimi</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Viesti</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Määrä</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(ei nimeä)</translation>
+ </message>
+ <message>
+ <source>(no message)</source>
+ <translation>(ei viestiä)</translation>
+ </message>
+ <message>
+ <source>(no amount)</source>
+ <translation>(ei määrää)</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Lähetä Bitcoineja</translation>
+ </message>
+ <message>
+ <source>Coin Control Features</source>
+ <translation>Kolikkokontrolli ominaisuudet</translation>
+ </message>
+ <message>
+ <source>Inputs...</source>
+ <translation>Sisääntulot...</translation>
+ </message>
+ <message>
+ <source>automatically selected</source>
+ <translation>automaattisesti valitut</translation>
+ </message>
+ <message>
+ <source>Insufficient funds!</source>
+ <translation>Lompakon saldo ei riitä!</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Määrä:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Tavuja:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Määrä:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Prioriteetti:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Palkkio:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Palkkion jälkeen:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Vaihtoraha:</translation>
+ </message>
+ <message>
+ <source>If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address.</source>
+ <translation>Jos tämä aktivoidaan mutta vaihtorahan osoite on tyhjä tai virheellinen, vaihtoraha tullaan lähettämään uuteen luotuun osoitteeseen.</translation>
+ </message>
+ <message>
+ <source>Custom change address</source>
+ <translation>Kustomoitu vaihtorahan osoite</translation>
+ </message>
+ <message>
+ <source>Transaction Fee:</source>
+ <translation>Rahansiirtokulu:</translation>
+ </message>
+ <message>
+ <source>Choose...</source>
+ <translation>Valitse...</translation>
+ </message>
+ <message>
+ <source>collapse fee-settings</source>
+ <translation>pudota kulujen asetukset</translation>
+ </message>
+ <message>
+ <source>per kilobyte</source>
+ <translation>per kilotavu</translation>
+ </message>
+ <message>
+ <source>Hide</source>
+ <translation>Piilota</translation>
+ </message>
+ <message>
+ <source>total at least</source>
+ <translation>yhteensä ainakin</translation>
+ </message>
+ <message>
+ <source>(read the tooltip)</source>
+ <translation>(lue työkaluvinkki)</translation>
+ </message>
+ <message>
+ <source>Recommended:</source>
+ <translation>Suositeltu:</translation>
+ </message>
+ <message>
+ <source>Custom:</source>
+ <translation>Muokattu:</translation>
+ </message>
+ <message>
+ <source>Confirmation time:</source>
+ <translation>Vahvistusaika:</translation>
+ </message>
+ <message>
+ <source>normal</source>
+ <translation>normaali</translation>
+ </message>
+ <message>
+ <source>fast</source>
+ <translation>nopea</translation>
+ </message>
+ <message>
+ <source>Send as zero-fee transaction if possible</source>
+ <translation>Lähetä siirtokuluttomana jos mahdollista</translation>
+ </message>
+ <message>
+ <source>(confirmation may take longer)</source>
+ <translation>(vahvistaminen voi viedä kauemmin)</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>Lähetä usealla vastaanottajalle samanaikaisesti</translation>
+ </message>
+ <message>
+ <source>Add &amp;Recipient</source>
+ <translation>Lisää &amp;Vastaanottaja</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Tyhjennä lomakkeen kaikki kentät</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Tomu:</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>&amp;Tyhjennnä Kaikki</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>Balanssi:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>Vahvista lähetys</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>&amp;Lähetä</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>Hyväksy Bitcoinien lähettäminen</translation>
+ </message>
+ <message>
+ <source>%1 to %2</source>
+ <translation>%1 to %2</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Kopioi määrä</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopioi määrä</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Kopioi palkkio</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Kopioi palkkion jälkeen</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Kopioi tavut</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Kopioi prioriteetti</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Kopioi vaihtoraha</translation>
+ </message>
+ <message>
+ <source>or</source>
+ <translation>tai</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>Maksettavan summan tulee olla suurempi kuin 0 Bitcoinia.</translation>
+ </message>
+ <message>
+ <source>The amount exceeds your balance.</source>
+ <translation>Määrä ylittää käytettävissä olevan saldon.</translation>
+ </message>
+ <message>
+ <source>The total exceeds your balance when the %1 transaction fee is included.</source>
+ <translation>Kokonaismäärä ylittää saldosi kun %1 maksukulu lisätään summaan.</translation>
+ </message>
+ <message>
+ <source>Transaction creation failed!</source>
+ <translation>Rahansiirron luonti epäonnistui!</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>Rahansiirto hylättiin! Tämä saattaa tapahtua jos lompakossa olevat kolikot on jo kulutettu, kuten jos käytät kopioita wallet.dat tiedostosta ja kolikot oli jos käytetty mutta ei merkattu täällä.</translation>
+ </message>
+ <message>
+ <source>A fee higher than %1 is considered an absurdly high fee.</source>
+ <translation>Rahansiirtokulua %1 ja sitä suurempia määriä pidetään järjenvastaisen korkeana kuluna.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>Maksupyyntö on vanhentunut.</translation>
+ </message>
+ <message>
+ <source>Pay only the minimum fee of %1</source>
+ <translation>Maksa vain vähimmäiskulu %1</translation>
+ </message>
+ <message>
+ <source>The recipient address is not valid. Please recheck.</source>
+ <translation>Vastaanottajan osoite ei ole kelvollinen. Tarkistathan uudelleen.</translation>
+ </message>
+ <message>
+ <source>Warning: Invalid Bitcoin address</source>
+ <translation>Varoitus: Virheellinen Bitcoin osoite</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(ei nimeä)</translation>
+ </message>
+ <message>
+ <source>Warning: Unknown change address</source>
+ <translation>Varoitus: Tuntematon vaihtorahan osoite</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Kopioi tomu</translation>
+ </message>
+ <message>
+ <source>Are you sure you want to send?</source>
+ <translation>Haluatko varmasti lähettää?</translation>
+ </message>
+ <message>
+ <source>added as transaction fee</source>
+ <translation>lisätty rahansiirtomaksuna</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>M&amp;äärä:</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>Maksun saaja:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Anna nimi tälle osoitteelle, jos haluat lisätä sen osoitekirjaan</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Nimi:</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Valitse aikaisemmin käytetty osoite</translation>
+ </message>
+ <message>
+ <source>This is a normal payment.</source>
+ <translation>Tämä on normaali maksu.</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to send the payment to</source>
+ <translation>Bitcoin-osoite johon maksu lähetetään</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Liitä osoite leikepöydältä</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Remove this entry</source>
+ <translation>Poista tämä alkio</translation>
+ </message>
+ <message>
+ <source>S&amp;ubtract fee from amount</source>
+ <translation>V&amp;ähennä maksukulu määrästä</translation>
+ </message>
+ <message>
+ <source>Message:</source>
+ <translation>Viesti:</translation>
+ </message>
+ <message>
+ <source>This is an unauthenticated payment request.</source>
+ <translation>Tämä on todentamaton maksupyyntö.</translation>
+ </message>
+ <message>
+ <source>This is an authenticated payment request.</source>
+ <translation>Tämä on todennettu maksupyyntö.</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to the list of used addresses</source>
+ <translation>Aseta nimi tälle osoitteelle lisätäksesi sen käytettyjen osoitteiden listalle.</translation>
+ </message>
+ <message>
+ <source>A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network.</source>
+ <translation>Viesti joka liitettiin bitcoin: URI:iin tallennetaan rahansiirtoon viitteeksi. Tätä viestiä ei lähetetä Bitcoin-verkkoon.</translation>
+ </message>
+ <message>
+ <source>Pay To:</source>
+ <translation>Saaja:</translation>
+ </message>
+ <message>
+ <source>Memo:</source>
+ <translation>Muistio:</translation>
+ </message>
+</context>
+<context>
+ <name>ShutdownWindow</name>
+ <message>
+ <source>Bitcoin Core is shutting down...</source>
+ <translation>Bitcoin core sulkeutuu...</translation>
+ </message>
+ <message>
+ <source>Do not shut down the computer until this window disappears.</source>
+ <translation>Älä sammuta tietokonetta ennenkuin tämä ikkuna katoaa.</translation>
+ </message>
+</context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Signatures - Sign / Verify a Message</source>
+ <translation>Allekirjoitukset - Allekirjoita / Varmista viesti</translation>
+ </message>
+ <message>
+ <source>&amp;Sign Message</source>
+ <translation>&amp;Allekirjoita viesti</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to sign the message with</source>
+ <translation>Bitcoin-osoite jolla viesti allekirjoitetaan</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Valitse aikaisemmin käytetty osoite</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Liitä osoite leikepöydältä</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Enter the message you want to sign here</source>
+ <translation>Kirjoita tähän viesti minkä haluat allekirjoittaa</translation>
+ </message>
+ <message>
+ <source>Signature</source>
+ <translation>Allekirjoitus</translation>
+ </message>
+ <message>
+ <source>Copy the current signature to the system clipboard</source>
+ <translation>Kopioi tämänhetkinen allekirjoitus leikepöydälle</translation>
+ </message>
+ <message>
+ <source>Sign the message to prove you own this Bitcoin address</source>
+ <translation>Allekirjoita viesti todistaaksesi, että omistat tämän Bitcoin-osoitteen</translation>
+ </message>
+ <message>
+ <source>Sign &amp;Message</source>
+ <translation>Allekirjoita &amp;viesti</translation>
+ </message>
+ <message>
+ <source>Reset all sign message fields</source>
+ <translation>Tyhjennä kaikki allekirjoita-viesti-kentät</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>&amp;Tyhjennä Kaikki</translation>
+ </message>
+ <message>
+ <source>&amp;Verify Message</source>
+ <translation>&amp;Varmista viesti</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address the message was signed with</source>
+ <translation>Bitcoin-osoite jolla viesti on allekirjoitettu</translation>
+ </message>
+ <message>
+ <source>Verify the message to ensure it was signed with the specified Bitcoin address</source>
+ <translation>Tarkista viestin allekirjoitus varmistaaksesi, että se allekirjoitettiin tietyllä Bitcoin-osoitteella</translation>
+ </message>
+ <message>
+ <source>Verify &amp;Message</source>
+ <translation>Varmista &amp;viesti...</translation>
+ </message>
+ <message>
+ <source>Reset all verify message fields</source>
+ <translation>Tyhjennä kaikki varmista-viesti-kentät</translation>
+ </message>
+ <message>
+ <source>Click "Sign Message" to generate signature</source>
+ <translation>Klikkaa "Allekirjoita Viesti luodaksesi allekirjoituksen </translation>
+ </message>
+ <message>
+ <source>The entered address is invalid.</source>
+ <translation>Syötetty osoite on virheellinen.</translation>
+ </message>
+ <message>
+ <source>Please check the address and try again.</source>
+ <translation>Tarkista osoite ja yritä uudelleen.</translation>
+ </message>
+ <message>
+ <source>The entered address does not refer to a key.</source>
+ <translation>Syötetyn osoitteen avainta ei löydy.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock was cancelled.</source>
+ <translation>Lompakon avaaminen peruttiin.</translation>
+ </message>
+ <message>
+ <source>Private key for the entered address is not available.</source>
+ <translation>Yksityistä avainta syötetylle osoitteelle ei ole saatavilla.</translation>
+ </message>
+ <message>
+ <source>Message signing failed.</source>
+ <translation>Viestin allekirjoitus epäonnistui.</translation>
+ </message>
+ <message>
+ <source>Message signed.</source>
+ <translation>Viesti allekirjoitettu.</translation>
+ </message>
+ <message>
+ <source>The signature could not be decoded.</source>
+ <translation>Allekirjoitusta ei pystytty tulkitsemaan.</translation>
+ </message>
+ <message>
+ <source>Please check the signature and try again.</source>
+ <translation>Tarkista allekirjoitus ja yritä uudelleen.</translation>
+ </message>
+ <message>
+ <source>The signature did not match the message digest.</source>
+ <translation>Allekirjoitus ei täsmää viestin tiivisteeseen.</translation>
+ </message>
+ <message>
+ <source>Message verification failed.</source>
+ <translation>Viestin varmistus epäonnistui.</translation>
+ </message>
+ <message>
+ <source>Message verified.</source>
+ <translation>Viesti varmistettu.</translation>
+ </message>
+</context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin-ydin</translation>
+ </message>
+ <message>
+ <source>The Bitcoin Core developers</source>
+ <translation>Bitcoin Core kehittäjät</translation>
+ </message>
+ <message>
+ <source>[testnet]</source>
+ <translation>[testnet]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ <message>
+ <source>KB/s</source>
+ <translation>KB/s</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>Avoinna %1 asti</translation>
+ </message>
+ <message>
+ <source>conflicted</source>
+ <translation>ristiriitainen</translation>
+ </message>
+ <message>
+ <source>%1/offline</source>
+ <translation>%1/offline</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/vahvistamaton</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 vahvistusta</translation>
+ </message>
+ <message>
+ <source>Status</source>
+ <translation>Tila</translation>
+ </message>
+ <message numerus="yes">
+ <source>, broadcast through %n node(s)</source>
+ <translation><numerusform>lähetetty %n noodin läpi</numerusform><numerusform>lähetetty %n noodin läpi</numerusform></translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Päivämäärä</translation>
+ </message>
+ <message>
+ <source>Source</source>
+ <translation>Lähde</translation>
+ </message>
+ <message>
+ <source>Generated</source>
+ <translation>Generoitu</translation>
+ </message>
+ <message>
+ <source>From</source>
+ <translation>Lähettäjä</translation>
+ </message>
+ <message>
+ <source>To</source>
+ <translation>Saaja</translation>
+ </message>
+ <message>
+ <source>own address</source>
+ <translation>oma osoite</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>vain katseltava</translation>
+ </message>
+ <message>
+ <source>label</source>
+ <translation>nimi</translation>
+ </message>
+ <message>
+ <source>Credit</source>
+ <translation>Credit</translation>
+ </message>
+ <message numerus="yes">
+ <source>matures in %n more block(s)</source>
+ <translation><numerusform>kypsyy %n lohkon kuluttua</numerusform><numerusform>kypsyy %n lohkon kuluttua</numerusform></translation>
+ </message>
+ <message>
+ <source>not accepted</source>
+ <translation>ei hyväksytty</translation>
+ </message>
+ <message>
+ <source>Debit</source>
+ <translation>Debit</translation>
+ </message>
+ <message>
+ <source>Total debit</source>
+ <translation>Yhteensä debit</translation>
+ </message>
+ <message>
+ <source>Total credit</source>
+ <translation>Yhteensä credit</translation>
+ </message>
+ <message>
+ <source>Transaction fee</source>
+ <translation>Maksukulu</translation>
+ </message>
+ <message>
+ <source>Net amount</source>
+ <translation>Netto määrä</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Viesti</translation>
+ </message>
+ <message>
+ <source>Comment</source>
+ <translation>Viesti</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>Siirtotunnus</translation>
+ </message>
+ <message>
+ <source>Merchant</source>
+ <translation>Kauppias</translation>
+ </message>
+ <message>
+ <source>Generated coins must mature %1 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.</source>
+ <translation>Luodut kolikot täytyy kypsyttää %1 lohkoa kunnes ne voidaan käyttää. Kun loit tämän lohkon, se lähetettiin verkkoon lisänä lohkoketjuun. Jos se epäonnistuu pääsemään ketjuun sen tila tulee muuttumaan "ei hyväksytty" ja sitä ei voida käyttää. Tämä voi ajoittain tapahtua kun toisen solmun lohko luodaan samanaikaisesti omasi kanssa.</translation>
+ </message>
+ <message>
+ <source>Debug information</source>
+ <translation>Debug tiedot</translation>
+ </message>
+ <message>
+ <source>Transaction</source>
+ <translation>Rahansiirto</translation>
+ </message>
+ <message>
+ <source>Inputs</source>
+ <translation>Sisääntulot</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Määrä</translation>
+ </message>
+ <message>
+ <source>true</source>
+ <translation>tosi</translation>
+ </message>
+ <message>
+ <source>false</source>
+ <translation>epätosi</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, ei ole vielä onnistuneesti lähetetty</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Avoinna %n lisälohkolle</numerusform><numerusform>Avoinna %n lisälohkolle</numerusform></translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>tuntematon</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>Rahansiirron yksityiskohdat</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>Tämä ruutu näyttää yksityiskohtaisen tiedon rahansiirrosta</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Päivämäärä</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Laatu</translation>
+ </message>
+ <message>
+ <source>Immature (%1 confirmations, will be available after %2)</source>
+ <translation>Epäkypsä (%1 varmistusta, saatavilla %2 jälkeen)</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Avoinna %n lisälohkolle</numerusform><numerusform>Avoinna %n lisälohkolle</numerusform></translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>Avoinna %1 asti</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>Vahvistettu (%1 vahvistusta)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>Tätä lohkoa ei vastaanotettu mistään muusta solmusta ja sitä ei mahdollisesti hyväksytä!</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>Generoitu mutta ei hyväksytty</translation>
+ </message>
+ <message>
+ <source>Offline</source>
+ <translation>Offline</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Nimi</translation>
+ </message>
+ <message>
+ <source>Unconfirmed</source>
+ <translation>Varmistamaton</translation>
+ </message>
+ <message>
+ <source>Confirming (%1 of %2 recommended confirmations)</source>
+ <translation>Varmistetaan (%1 kehoitetusta %2 varmistuksesta)</translation>
+ </message>
+ <message>
+ <source>Conflicted</source>
+ <translation>Ristiriitainen</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Vastaanotettu osoitteella</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>Vastaanotettu</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Saaja</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>Maksu itsellesi</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Louhittu</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>vain katseltava</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(ei saatavilla)</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>Rahansiirron tila. Siirrä osoitin kentän päälle nähdäksesi vahvistusten lukumäärä.</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Rahansiirron vastaanottamisen päivämäärä ja aika.</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>Rahansiirron laatu.</translation>
+ </message>
+ <message>
+ <source>Whether or not a watch-only address is involved in this transaction.</source>
+ <translation>Onko rahansiirrossa mukana ainoastaan katseltava osoite vai ei.</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>Saldoon lisätty tai siitä vähennetty määrä.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>Kaikki</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>Tänään</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>Tällä viikolla</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>Tässä kuussa</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>Viime kuussa</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>Tänä vuonna</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>Alue...</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Vastaanotettu osoitteella</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Saaja</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>Itsellesi</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Louhittu</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>Muu</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>Anna etsittävä osoite tai tunniste</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>Minimimäärä</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Kopioi osoite</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Kopioi nimi</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopioi määrä</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Kopioi siirtotunnus</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>Muokkaa nimeä</translation>
+ </message>
+ <message>
+ <source>Show transaction details</source>
+ <translation>Näytä rahansiirron yksityiskohdat</translation>
+ </message>
+ <message>
+ <source>Export Transaction History</source>
+ <translation>Vie rahansiirtohistoria</translation>
+ </message>
+ <message>
+ <source>Watch-only</source>
+ <translation>Vain katseltava</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Vienti epäonnistui</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the transaction history to %1.</source>
+ <translation>Rahansiirron historian tallentamisessa tapahtui virhe paikkaan %1.</translation>
+ </message>
+ <message>
+ <source>Exporting Successful</source>
+ <translation>Vienti onnistui</translation>
+ </message>
+ <message>
+ <source>The transaction history was successfully saved to %1.</source>
+ <translation>Rahansiirron historia tallennettiin onnistuneesti paikkaan %1.</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Comma separated file (*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Vahvistettu</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Aika</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Laatu</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Nimi</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Osoite</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>Alue:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>kenelle</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ <message>
+ <source>Unit to show amounts in. Click to select another unit.</source>
+ <translation>Yksikkö jossa määrät näytetään. Klikkaa valitaksesi toisen yksikön.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletFrame</name>
+ <message>
+ <source>No wallet has been loaded.</source>
+ <translation>Lomakkoa ei ole ladattu.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Lähetä Bitcoineja</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Vie...</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Vie auki olevan välilehden tiedot tiedostoon</translation>
+ </message>
+ <message>
+ <source>Backup Wallet</source>
+ <translation>Varmuuskopioi lompakko</translation>
+ </message>
+ <message>
+ <source>Wallet Data (*.dat)</source>
+ <translation>Lompakkodata (*.dat)</translation>
+ </message>
+ <message>
+ <source>Backup Failed</source>
+ <translation>Varmuuskopio epäonnistui</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the wallet data to %1.</source>
+ <translation>Lompakon tallennuksessa tapahtui virhe %1.</translation>
+ </message>
+ <message>
+ <source>The wallet data was successfully saved to %1.</source>
+ <translation>Lompakko tallennettiin onnistuneesti tiedostoon %1.</translation>
+ </message>
+ <message>
+ <source>Backup Successful</source>
+ <translation>Varmuuskopio Onnistui</translation>
+ </message>
+</context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>Asetukset:</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>Määritä data-hakemisto</translation>
+ </message>
+ <message>
+ <source>Connect to a node to retrieve peer addresses, and disconnect</source>
+ <translation>Yhdistä noodiin hakeaksesi naapurien osoitteet ja katkaise yhteys</translation>
+ </message>
+ <message>
+ <source>Specify your own public address</source>
+ <translation>Määritä julkinen osoitteesi</translation>
+ </message>
+ <message>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>Hyväksy merkkipohjaiset- ja JSON-RPC-käskyt</translation>
+ </message>
+ <message>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>Aja taustalla daemonina ja hyväksy komennot</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>Käytä test -verkkoa</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
+ <translation>Hyväksy yhteyksiä ulkopuolelta (vakioasetus: 1 jos -proxy tai -connect ei määritelty)</translation>
+ </message>
+ <message>
+ <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
+ <translation>Kytkeydy annettuun osoitteeseen ja pidä linja aina auki. Käytä [host]:portin merkintätapaa IPv6:lle.</translation>
+ </message>
+ <message>
+ <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
+ <translation>Suorita käsky kun lompakossa rahansiirto muuttuu (%s cmd on vaihdettu TxID kanssa)</translation>
+ </message>
+ <message>
+ <source>Set the number of script verification threads (%u to %d, 0 = auto, &lt;0 = leave that many cores free, default: %d)</source>
+ <translation>Aseta script varmistuksen threadien lukumäärä (%u - %d, 0= auto, &lt;0 = jätä näin monta ydintä vapaaksi, oletus: %d)</translation>
+ </message>
+ <message>
+ <source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source>
+ <translation>Tämä on esi-julkaistu testiversio - Käytä omalla riskillä - Ei saa käytää louhimiseen tai kauppasovelluksiin.</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer. Bitcoin Core is probably already running.</source>
+ <translation>Ei voida yhdistää %s tässä tietokoneessa. Bitcoin Core on luultavasti jo käynnissä.</translation>
+ </message>
+ <message>
+ <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>Varoitus: -paytxfee on asetettu erittäin korkeaksi! Tämä on maksukulu jonka tulet maksamaan kun lähetät siirron.</translation>
+ </message>
+ <message>
+ <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source>
+ <translation>Varoitus: Tietoverkko ei ole sovussa! Luohijat näyttävät kokevan virhetilanteita.</translation>
+ </message>
+ <message>
+ <source>Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.</source>
+ <translation>Varoitus: Olemme vertaisverkon kanssa ristiriidassa! Sinun tulee päivittää tai toisten solmujen tulee päivitää.</translation>
+ </message>
+ <message>
+ <source>Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
+ <translation>Varoitus: virhe luettaessa wallet.dat-lompakkotiedostoa. Kaikki avaimet luettiin onnistuneesti, mutta siirtohistoria tai osoitekirja saattavat olla kadonneet tai virheellisiä.</translation>
+ </message>
+ <message>
+ <source>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</source>
+ <translation>Varoitus: wallet.dat -lompakkotiedosto on korruptoitunut, tiedot pelastettu. Alkuperäinen wallet.dat -lompakkotiedosto on tallennettu wallet.{timestamp}.bak kansioon %s; jos balanssisi tai siirtohistoria on virheellinen, sinun tulisi palauttaa lompakkotiedosto varmuuskopiosta.</translation>
+ </message>
+ <message>
+ <source>(default: 1)</source>
+ <translation>(oletus: 1)</translation>
+ </message>
+ <message>
+ <source>&lt;category&gt; can be:</source>
+ <translation>&lt;category&gt; voi olla:</translation>
+ </message>
+ <message>
+ <source>Attempt to recover private keys from a corrupt wallet.dat</source>
+ <translation>Yritetään palauttaa privaattiavaimia korruptoituneesta wallet.dat -lompakkotiedostosta</translation>
+ </message>
+ <message>
+ <source>Block creation options:</source>
+ <translation>Lohkon luonnin asetukset:</translation>
+ </message>
+ <message>
+ <source>Connect only to the specified node(s)</source>
+ <translation>Yhidstä ainoastaan määrättyihin noodeihin</translation>
+ </message>
+ <message>
+ <source>Connection options:</source>
+ <translation>Yhteyden valinnat:</translation>
+ </message>
+ <message>
+ <source>Corrupted block database detected</source>
+ <translation>Vioittunut lohkotietokanta havaittu</translation>
+ </message>
+ <message>
+ <source>Debugging/Testing options:</source>
+ <translation>Debuggaus/Testauksen valinnat:</translation>
+ </message>
+ <message>
+ <source>Do not load the wallet and disable wallet RPC calls</source>
+ <translation>Älä lataa lompakkoa ja poista lompakon RPC kutsut</translation>
+ </message>
+ <message>
+ <source>Do you want to rebuild the block database now?</source>
+ <translation>Haluatko uudelleenrakentaa lohkotietokannan nyt?</translation>
+ </message>
+ <message>
+ <source>Error initializing block database</source>
+ <translation>Virhe alustaessa lohkotietokantaa</translation>
+ </message>
+ <message>
+ <source>Error initializing wallet database environment %s!</source>
+ <translation>Virhe alustaessa lompakon tietokantaympäristöä %s!</translation>
+ </message>
+ <message>
+ <source>Error loading block database</source>
+ <translation>Virhe avattaessa lohkoketjua</translation>
+ </message>
+ <message>
+ <source>Error opening block database</source>
+ <translation>Virhe avattaessa lohkoindeksiä</translation>
+ </message>
+ <message>
+ <source>Error: Disk space is low!</source>
+ <translation>Varoitus: Levytila on vähissä!</translation>
+ </message>
+ <message>
+ <source>Failed to listen on any port. Use -listen=0 if you want this.</source>
+ <translation>Ei onnistuttu kuuntelemaan missään portissa. Käytä -listen=0 jos haluat tätä.</translation>
+ </message>
+ <message>
+ <source>If &lt;category&gt; is not supplied, output all debugging information.</source>
+ <translation>Jos &lt;kategoria&gt; ei annettu, tulosta kaikki debuggaustieto.</translation>
+ </message>
+ <message>
+ <source>Importing...</source>
+ <translation>Tuodaan...</translation>
+ </message>
+ <message>
+ <source>Incorrect or no genesis block found. Wrong datadir for network?</source>
+ <translation>Virheellinen tai olematon alkulohko löydetty. Väärä data-hakemisto verkolle?</translation>
+ </message>
+ <message>
+ <source>Invalid -onion address: '%s'</source>
+ <translation>Virheellinen -onion osoite: '%s'</translation>
+ </message>
+ <message>
+ <source>Not enough file descriptors available.</source>
+ <translation>Ei tarpeeksi tiedostomerkintöjä vapaana.</translation>
+ </message>
+ <message>
+ <source>Only connect to nodes in network &lt;net&gt; (ipv4, ipv6 or onion)</source>
+ <translation>Yhdistä vain solmukohtiin &lt;net&gt;-verkossa (ipv4, ipv6 tai onion)</translation>
+ </message>
+ <message>
+ <source>Prune mode is incompatible with -txindex.</source>
+ <translation>Karsittu tila ei ole yhteensopiva -txindex:n kanssa.</translation>
+ </message>
+ <message>
+ <source>Set database cache size in megabytes (%d to %d, default: %d)</source>
+ <translation>Aseta tietokannan välimuistin koko megatavuissa (%d - %d, oletus: %d</translation>
+ </message>
+ <message>
+ <source>Set maximum block size in bytes (default: %d)</source>
+ <translation>Aseta lohkon maksimikoko tavuissa (oletus: %d)</translation>
+ </message>
+ <message>
+ <source>Specify wallet file (within data directory)</source>
+ <translation>Aseta lompakkotiedosto (data-hakemiston sisällä)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: %u)</source>
+ <translation>Käytä UPnP:ta kuuntelevan portin kartoittamiseen (oletus: %u)</translation>
+ </message>
+ <message>
+ <source>Verifying blocks...</source>
+ <translation>Varmistetaan lohkoja...</translation>
+ </message>
+ <message>
+ <source>Verifying wallet...</source>
+ <translation>Varmistetaan lompakko...</translation>
+ </message>
+ <message>
+ <source>Wallet %s resides outside data directory %s</source>
+ <translation>Lompakko %s sijaitsee data-hakemiston ulkopuolella %s</translation>
+ </message>
+ <message>
+ <source>Wallet options:</source>
+ <translation>Lompakon valinnat:</translation>
+ </message>
+ <message>
+ <source>Warning: This version is obsolete; upgrade required!</source>
+ <translation>Varoitus: Tämä versio on vanhentunut; päivittämistä vaaditaan!</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to change -txindex</source>
+ <translation>Sinun tulee uudelleenrakentaa tietokanta käyttäen -reindex vaihtaen -txindex</translation>
+ </message>
+ <message>
+ <source>Imports blocks from external blk000??.dat file</source>
+ <translation>Tuodaan lohkoja ulkoisesta blk000??.dat tiedostosta</translation>
+ </message>
+ <message>
+ <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source>
+ <translation>Ei voida lukita data-hakemistoa %s. Bitcoin Core on luultavasti jo käynnissä.</translation>
+ </message>
+ <message>
+ <source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source>
+ <translation>Aja komento kun olennainen hälytys vastaanotetaan tai nähdään todella pitkä haara (%s komennossa korvataan viestillä)</translation>
+ </message>
+ <message>
+ <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
+ <translation>Aseta maksimikoko korkea prioriteetti/pieni palkkio rahansiirtoihin tavuissa (oletus: %d)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source>
+ <translation>Aseta kolikoiden luomiseen tarkoitettujen säikeiden lukumäärä (-1 = kaikki ytimet, oletus: %d)</translation>
+ </message>
+ <message>
+ <source>(default: %u)</source>
+ <translation>(oletus: %u)</translation>
+ </message>
+ <message>
+ <source>Accept public REST requests (default: %u)</source>
+ <translation>Hyväksy julkisia REST-pyyntöjä (oletus: %u)</translation>
+ </message>
+ <message>
+ <source>Activating best chain...</source>
+ <translation>Aktivoidaan parhainta ketjua...</translation>
+ </message>
+ <message>
+ <source>Can't run with a wallet in prune mode.</source>
+ <translation>Lompakkoa ei voida ajaa karsitussa tilassa.</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -whitebind address: '%s'</source>
+ <translation>-whitebind -osoitetta '%s' ei voida jäsentää</translation>
+ </message>
+ <message>
+ <source>Choose data directory on startup (default: 0)</source>
+ <translation>Valitse data-hakemisto käynnistyksessä (oletus: 0)</translation>
+ </message>
+ <message>
+ <source>Connect through SOCKS5 proxy</source>
+ <translation>Yhdistä SOCKS5 proxin kautta</translation>
+ </message>
+ <message>
+ <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source>
+ <translation>Copyright (C) 2009-%i Bitcoin kehittäjät</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source>
+ <translation>Virhe ladattaessa wallet.dat-tiedostoa: Tarvitset uudemman version Bitcoinista</translation>
+ </message>
+ <message>
+ <source>Error reading from database, shutting down.</source>
+ <translation>Virheitä tietokantaa luettaessa, ohjelma pysäytetään.</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Tietoa</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -minrelaytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Virheellinen määrä -minrelaytxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -mintxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Virheellinen määrä -mintxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Node relay options:</source>
+ <translation>Välityssolmukohdan asetukset:</translation>
+ </message>
+ <message>
+ <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source>
+ <translation>RPC SSL valinnat: (katso Bitcoin Wikistä SSL-asennuksen ohjeet)</translation>
+ </message>
+ <message>
+ <source>RPC server options:</source>
+ <translation>RPC-palvelimen valinnat:</translation>
+ </message>
+ <message>
+ <source>RPC support for HTTP persistent connections (default: %d)</source>
+ <translation>RPC-tuki pysyville HTTP-yhteyksille (oletus: %d)</translation>
+ </message>
+ <message>
+ <source>Receive and display P2P network alerts (default: %u)</source>
+ <translation>Vastaanota ja näytä P2P-verkon hälytyksiä (oletus: %u)</translation>
+ </message>
+ <message>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>Lähetä jäljitys/debug-tieto konsoliin, debug.log-tiedoston sijaan</translation>
+ </message>
+ <message>
+ <source>Set SSL root certificates for payment request (default: -system-)</source>
+ <translation>Aseta SSL root varmenne maksupyynnöille (oletus: -system-)</translation>
+ </message>
+ <message>
+ <source>Set language, for example "de_DE" (default: system locale)</source>
+ <translation>Set language, for example "de_DE" (default: system locale)</translation>
+ </message>
+ <message>
+ <source>Show all debugging options (usage: --help -help-debug)</source>
+ <translation>Näytä kaikki debuggaus valinnat: (käyttö: --help -help-debug)</translation>
+ </message>
+ <message>
+ <source>Show splash screen on startup (default: 1)</source>
+ <translation>Näytä aloitusruutu käynnistettäessä (oletus: 1)</translation>
+ </message>
+ <message>
+ <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source>
+ <translation>Pienennä debug.log tiedosto käynnistyksen yhteydessä (vakioasetus: 1 kun ei -debug)</translation>
+ </message>
+ <message>
+ <source>Signing transaction failed</source>
+ <translation>Siirron vahvistus epäonnistui</translation>
+ </message>
+ <message>
+ <source>Start minimized</source>
+ <translation>Käynnistä pienennettynä</translation>
+ </message>
+ <message>
+ <source>This is experimental software.</source>
+ <translation>Tämä on ohjelmistoa kokeelliseen käyttöön.</translation>
+ </message>
+ <message>
+ <source>Transaction amount too small</source>
+ <translation>Siirtosumma liian pieni</translation>
+ </message>
+ <message>
+ <source>Transaction amounts must be positive</source>
+ <translation>Siirtosumman tulee olla positiivinen</translation>
+ </message>
+ <message>
+ <source>Transaction too large</source>
+ <translation>Siirtosumma liian iso</translation>
+ </message>
+ <message>
+ <source>UI Options:</source>
+ <translation>Ulkoasun asetukset:</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: 1 when listening)</source>
+ <translation>Käytä UPnP:tä kuunneltavan portin avaamiseen (vakioasetus: 1 kun kuuntelemassa)</translation>
+ </message>
+ <message>
+ <source>Username for JSON-RPC connections</source>
+ <translation>Käyttäjätunnus JSON-RPC-yhteyksille</translation>
+ </message>
+ <message>
+ <source>Wallet needed to be rewritten: restart Bitcoin Core to complete</source>
+ <translation>Lompakko tarvitsee uudelleenkirjoittaa: käynnistä Bitcoin uudelleen</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Varoitus</translation>
+ </message>
+ <message>
+ <source>Zapping all transactions from wallet...</source>
+ <translation>Tyhjennetään kaikki rahansiirrot lompakosta....</translation>
+ </message>
+ <message>
+ <source>on startup</source>
+ <translation>käynnistyksessä</translation>
+ </message>
+ <message>
+ <source>wallet.dat corrupt, salvage failed</source>
+ <translation>wallet.dat -lompakkotiedosto korruptoitunut, korjaaminen epäonnistui</translation>
+ </message>
+ <message>
+ <source>Password for JSON-RPC connections</source>
+ <translation>Salasana JSON-RPC-yhteyksille</translation>
+ </message>
+ <message>
+ <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
+ <translation>Suorita käsky kun paras lohko muuttuu (%s cmd on vaihdettu block hashin kanssa)</translation>
+ </message>
+ <message>
+ <source>Upgrade wallet to latest format</source>
+ <translation>Päivitä lompakko uusimpaan formaattiin</translation>
+ </message>
+ <message>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>Skannaa uudelleen lohkoketju lompakon puuttuvien rahasiirtojen vuoksi</translation>
+ </message>
+ <message>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>Käytä OpenSSL:ää (https) JSON-RPC-yhteyksille</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>Tämä ohjeviesti</translation>
+ </message>
+ <message>
+ <source>Allow DNS lookups for -addnode, -seednode and -connect</source>
+ <translation>Salli DNS kyselyt -addnode, -seednode ja -connect yhteydessä</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>Ladataan osoitteita...</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>Virhe ladattaessa wallet.dat-tiedostoa: Lompakko vioittunut</translation>
+ </message>
+ <message>
+ <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source>
+ <translation>Käytä erillistä SOCKS5-proxyä tavoittaaksesi vertaisia Tor-piilopalveluiden kautta (oletus: %s)</translation>
+ </message>
+ <message>
+ <source>(default: %s)</source>
+ <translation>(oletus: %s)</translation>
+ </message>
+ <message>
+ <source>Acceptable ciphers (default: %s)</source>
+ <translation>Hyväksyttävät salaukset (oletus: %s)</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>Virhe ladattaessa wallet.dat-tiedostoa</translation>
+ </message>
+ <message>
+ <source>Generate coins (default: %u)</source>
+ <translation>Luo kolikoita (oletus: %u)</translation>
+ </message>
+ <message>
+ <source>How many blocks to check at startup (default: %u, 0 = all)</source>
+ <translation>Kuinka monta lohkoa tarkistetaan käynnistyksessä (oletus: %u, 0 = kaikki)</translation>
+ </message>
+ <message>
+ <source>Include IP addresses in debug output (default: %u)</source>
+ <translation>Sisällytä IP-osoitteet virheenkorjauslokissa (oletus: %u)</translation>
+ </message>
+ <message>
+ <source>Invalid -proxy address: '%s'</source>
+ <translation>Virheellinen proxy-osoite '%s'</translation>
+ </message>
+ <message>
+ <source>Listen for connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>Kuuntele yhteyksiä portissa &lt;port&gt; (oletus: %u tai testnet: %u)</translation>
+ </message>
+ <message>
+ <source>Make the wallet broadcast transactions</source>
+ <translation>Aseta lompakko kuuluttamaan rahansiirtoja</translation>
+ </message>
+ <message>
+ <source>Relay non-P2SH multisig (default: %u)</source>
+ <translation>Välitä ei-P2SH-multisig (oletus: %u)</translation>
+ </message>
+ <message>
+ <source>Server certificate file (default: %s)</source>
+ <translation>Palvelimen sertifikaattitiedosto (oletus: %s)</translation>
+ </message>
+ <message>
+ <source>Server private key (default: %s)</source>
+ <translation>Palvelimen private key (oletus: %s)</translation>
+ </message>
+ <message>
+ <source>Set key pool size to &lt;n&gt; (default: %u)</source>
+ <translation>Aseta avainaltaan kooksi &lt;n&gt; (oletus: %u)</translation>
+ </message>
+ <message>
+ <source>Set minimum block size in bytes (default: %u)</source>
+ <translation>Aseta pienin mahdollinen lohkokoko tavuina (oletus: %u)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads to service RPC calls (default: %d)</source>
+ <translation>Aseta RPC-kutsujen palvelemiseen tarkoitettujen säikeiden lukumäärä (oletus: %d)</translation>
+ </message>
+ <message>
+ <source>Specify configuration file (default: %s)</source>
+ <translation>Määritä asetustiedosto (oletus: %s)</translation>
+ </message>
+ <message>
+ <source>Specify pid file (default: %s)</source>
+ <translation>Määritä pid-tiedosto (oletus: %s)</translation>
+ </message>
+ <message>
+ <source>Spend unconfirmed change when sending transactions (default: %u)</source>
+ <translation>Käytä vahvistamattomia vaihtorahoja lähetettäessä rahansiirtoja (oletus: %u)</translation>
+ </message>
+ <message>
+ <source>Unknown network specified in -onlynet: '%s'</source>
+ <translation>Tuntematon verkko -onlynet parametrina: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -bind address: '%s'</source>
+ <translation>-bind osoitteen '%s' selvittäminen epäonnistui</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -externalip address: '%s'</source>
+ <translation>-externalip osoitteen '%s' selvittäminen epäonnistui</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>-paytxfee=&lt;amount&gt;: '%s' on virheellinen</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>Lompakon saldo ei riitä</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>Ladataan lohkoindeksiä...</translation>
+ </message>
+ <message>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>Linää solmu mihin liittyä pitääksesi yhteyden auki</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>Ladataan lompakkoa...</translation>
+ </message>
+ <message>
+ <source>Cannot downgrade wallet</source>
+ <translation>Et voi päivittää lompakkoasi vanhempaan versioon</translation>
+ </message>
+ <message>
+ <source>Cannot write default address</source>
+ <translation>Oletusosoitetta ei voi kirjoittaa</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>Skannataan uudelleen...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>Lataus on valmis</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Virhe</translation>
+ </message>
+</context>
+</TS> \ 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 0000000000..00eef6cb50
--- /dev/null
+++ b/src/qt/locale/bitcoin_fr.ts
@@ -0,0 +1,3560 @@
+<TS language="fr" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Right-click to edit address or label</source>
+ <translation>Cliquer à droite pour modifier l'adresse ou l'étiquette</translation>
+ </message>
+ <message>
+ <source>Create a new address</source>
+ <translation>Créer une nouvelle adresse</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>&amp;Nouveau</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Copier l'adresse courante sélectionnée dans le presse-papiers</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>&amp;Copier</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>&amp;Fermer</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>&amp;Copier l'adresse</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>Supprimer l'adresse actuellement sélectionnée de la liste</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Exporter les données de l'onglet courant vers un fichier</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Exporter</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;Supprimer</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>Choisir l'adresse à laquelle envoyer des pièces</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>Choisir l'adresse avec laquelle recevoir des pièces</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>C&amp;hoisir</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>Adresses d'envoi</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>Adresses de réception</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>Voici vos adresses Bitcoin pour envoyer des paiements. Vérifiez toujours le montant et l'adresse du destinataire avant d'envoyer des pièces.</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>Voici vos adresses Bitcoin pour recevoir des paiements. Il est recommandé d'utiliser une nouvelle adresse de réception pour chaque transaction.</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>Copier l'é&amp;tiquette</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>&amp;Modifier</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>Exporter la liste d'adresses</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Valeurs séparées par des virgules (*.csv)</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>L'exportation a échoué</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the address list to %1. Please try again.</source>
+ <translation>Une erreur est survenue lors de l'enregistrement de la liste d'adresses vers %1. Veuillez ressayer plus tard.</translation>
+ </message>
+</context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Étiquette</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adresse</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(aucune étiquette)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Passphrase Dialog</source>
+ <translation>Fenêtre de dialogue de la phrase de passe</translation>
+ </message>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Saisir la phrase de passe</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Nouvelle phrase de passe</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Répéter la phrase de passe</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>Chiffrer le portefeuille</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>Cette opération nécessite votre phrase de passe pour déverrouiller le portefeuille.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Déverrouiller le portefeuille</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>Cette opération nécessite votre phrase de passe pour déchiffrer le portefeuille.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>Déchiffrer le portefeuille</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>Changer la phrase de passe</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>Confirmer le chiffrement du portefeuille</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>Avertissement : si vous chiffrez votre portefeuille et perdez votre phrase de passe, vous &lt;b&gt;PERDREZ TOUS VOS BITCOINS&lt;/b&gt; !</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>Êtes-vous sûr de vouloir chiffrer votre portefeuille ?</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core 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.</source>
+ <translation>Bitcoin Core va maintenant se fermer pour terminer le processus de chiffrement. Souvenez-vous que le chiffrement de votre portefeuille ne peut pas vous protéger complètement contre le vol de vos bitcoins par des programmes malveillants infectant votre ordinateur.</translation>
+ </message>
+ <message>
+ <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
+ <translation>IMPORTANT : Toute sauvegarde précédente de votre fichier de portefeuille devrait être remplacée par le nouveau fichier de portefeuille chiffré. Pour des raisons de sécurité, les sauvegardes précédentes de votre fichier de portefeuille non chiffré deviendront inutilisables dès que vous commencerez à utiliser le nouveau portefeuille chiffré.</translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>Avertissement : la touche Verr. Maj. est activée !</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>Portefeuille chiffré</translation>
+ </message>
+ <message>
+ <source>Enter the new passphrase to the wallet.&lt;br/&gt;Please use a passphrase of &lt;b&gt;ten or more random characters&lt;/b&gt;, or &lt;b&gt;eight or more words&lt;/b&gt;.</source>
+ <translation>Saisissez une nouvelle phrase de passe pour le portefeuille.&lt;br/&gt;Veuillez utiliser une phrase composée de &lt;b&gt;dix caractères aléatoires ou plus&lt;/b&gt;, ou bien de &lt;b&gt;huit mots ou plus&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>Enter the old passphrase and new passphrase to the wallet.</source>
+ <translation>Saisir l'ancienne phrase de passe puis la nouvelle phrase de passe du portefeuille.</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>Le chiffrement du portefeuille a échoué</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>Le chiffrement du portefeuille a échoué en raison d'une erreur interne. Votre portefeuille n'a pas été chiffré.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>Les phrases de passe saisies ne correspondent pas.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>Le déverrouillage du portefeuille a échoué</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>La phrase de passe saisie pour déchiffrer le portefeuille était incorrecte.</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>Le déchiffrage du portefeuille a échoué</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>La phrase de passe du portefeuille a été modifiée avec succès.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>&amp;Signer le message...</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>Synchronisation avec le réseau en cours…</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;Vue d'ensemble</translation>
+ </message>
+ <message>
+ <source>Node</source>
+ <translation>Nœud</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>Afficher une vue d’ensemble du portefeuille</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Transactions</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>Parcourir l'historique des transactions</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>Q&amp;uitter</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>Quitter l’application</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>À propos de &amp;Qt</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>Afficher des informations sur Qt</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;Options…</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>&amp;Chiffrer le portefeuille...</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>Sauvegarder le &amp;portefeuille...</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>&amp;Changer la phrase de passe...</translation>
+ </message>
+ <message>
+ <source>&amp;Sending addresses...</source>
+ <translation>Adresses d'&amp;envoi...</translation>
+ </message>
+ <message>
+ <source>&amp;Receiving addresses...</source>
+ <translation>Adresses de &amp;réception...</translation>
+ </message>
+ <message>
+ <source>Open &amp;URI...</source>
+ <translation>Ouvrir un &amp;URI...</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core client</source>
+ <translation>Client Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Importing blocks from disk...</source>
+ <translation>Importation des blocs à partir du disque...</translation>
+ </message>
+ <message>
+ <source>Reindexing blocks on disk...</source>
+ <translation>Réindexation des blocs sur le disque...</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>Envoyer des pièces à une adresse Bitcoin</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>Sauvegarder le portefeuille vers un autre emplacement</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Modifier la phrase de passe utilisée pour le chiffrement du portefeuille</translation>
+ </message>
+ <message>
+ <source>&amp;Debug window</source>
+ <translation>Fenêtre de &amp;débogage</translation>
+ </message>
+ <message>
+ <source>Open debugging and diagnostic console</source>
+ <translation>Ouvrir une console de débogage et de diagnostic</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>&amp;Vérifier un message...</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>Portefeuille</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>&amp;Envoyer</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>&amp;Recevoir</translation>
+ </message>
+ <message>
+ <source>Show information about Bitcoin Core</source>
+ <translation>Montrer des informations à propos de Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>&amp;Afficher / Cacher</translation>
+ </message>
+ <message>
+ <source>Show or hide the main Window</source>
+ <translation>Afficher ou masquer la fenêtre principale</translation>
+ </message>
+ <message>
+ <source>Encrypt the private keys that belong to your wallet</source>
+ <translation>Chiffrer les clefs privées de votre portefeuille</translation>
+ </message>
+ <message>
+ <source>Sign messages with your Bitcoin addresses to prove you own them</source>
+ <translation>Signer les messages avec vos adresses Bitcoin pour prouver que vous les détenez</translation>
+ </message>
+ <message>
+ <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source>
+ <translation>Vérifier les messages pour vous assurer qu'ils ont été signés avec les adresses Bitcoin spécifiées</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;Fichier</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;Réglages</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>&amp;Aide</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>Barre d'outils des onglets</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Request payments (generates QR codes and bitcoin: URIs)</source>
+ <translation>Demander des paiements (génère des codes QR et des URIs bitcoin:)</translation>
+ </message>
+ <message>
+ <source>&amp;About Bitcoin Core</source>
+ <translation>À &amp;propos de Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Modify configuration options for Bitcoin Core</source>
+ <translation>Modifier les options de configuration de Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Show the list of used sending addresses and labels</source>
+ <translation>Afficher la liste d'adresses d'envoi et d'étiquettes utilisées</translation>
+ </message>
+ <message>
+ <source>Show the list of used receiving addresses and labels</source>
+ <translation>Afficher la liste d'adresses de réception et d'étiquettes utilisées</translation>
+ </message>
+ <message>
+ <source>Open a bitcoin: URI or payment request</source>
+ <translation>Ouvrir un URI bitcoin: ou une demande de paiement</translation>
+ </message>
+ <message>
+ <source>&amp;Command-line options</source>
+ <translation>Options de ligne de &amp;commande</translation>
+ </message>
+ <message>
+ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
+ <translation>Afficher le message d'aide de Bitcoin Core pour obtenir une liste des options de ligne de commande Bitcoin possibles.</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n active connection(s) to Bitcoin network</source>
+ <translation><numerusform>%n connexion active avec le réseau Bitcoin</numerusform><numerusform>%n connexions actives avec le réseau Bitcoin</numerusform></translation>
+ </message>
+ <message>
+ <source>No block source available...</source>
+ <translation>Aucune source de blocs disponible...</translation>
+ </message>
+ <message numerus="yes">
+ <source>Processed %n block(s) of transaction history.</source>
+ <translation><numerusform>%n bloc d'historique transactionnel a été traité</numerusform><numerusform>%n blocs d'historique transactionnel ont été traités</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n hour(s)</source>
+ <translation><numerusform>%n heure</numerusform><numerusform>%n heures</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n day(s)</source>
+ <translation><numerusform>%n jour</numerusform><numerusform>%n jours</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n week(s)</source>
+ <translation><numerusform>%n semaine</numerusform><numerusform>%n semaines</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 and %2</source>
+ <translation>%1 et %2</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n year(s)</source>
+ <translation><numerusform>%n an</numerusform><numerusform>%n ans</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 behind</source>
+ <translation>%1 en retard</translation>
+ </message>
+ <message>
+ <source>Last received block was generated %1 ago.</source>
+ <translation>Le dernier bloc reçu avait été généré il y a %1.</translation>
+ </message>
+ <message>
+ <source>Transactions after this will not yet be visible.</source>
+ <translation>Les transactions après ceci ne sont pas encore visibles.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Erreur</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Avertissement</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Information</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>À jour</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>Rattrapage en cours…</translation>
+ </message>
+ <message>
+ <source>Date: %1
+</source>
+ <translation>Date : %1
+</translation>
+ </message>
+ <message>
+ <source>Amount: %1
+</source>
+ <translation>Montant : %1
+</translation>
+ </message>
+ <message>
+ <source>Type: %1
+</source>
+ <translation>Type : %1
+</translation>
+ </message>
+ <message>
+ <source>Label: %1
+</source>
+ <translation>Étiquette : %1
+</translation>
+ </message>
+ <message>
+ <source>Address: %1
+</source>
+ <translation>Adresse : %1
+</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>Transaction envoyée</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>Transaction entrante</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>Le portefeuille est &lt;b&gt;chiffré&lt;/b&gt; et est actuellement &lt;b&gt;déverrouillé&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>Le portefeuille est &lt;b&gt;chiffré&lt;/b&gt; et actuellement &lt;b&gt;verrouillé&lt;/b&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <source>Network Alert</source>
+ <translation>Alerte réseau</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Coin Selection</source>
+ <translation>Sélection des pièces</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Quantité :</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Octets :</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Montant :</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Priorité :</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Frais :</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Poussière :</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Après les frais :</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Monnaie :</translation>
+ </message>
+ <message>
+ <source>(un)select all</source>
+ <translation>Tout (dé)sélectionner</translation>
+ </message>
+ <message>
+ <source>Tree mode</source>
+ <translation>Mode arborescence</translation>
+ </message>
+ <message>
+ <source>List mode</source>
+ <translation>Mode liste</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Montant</translation>
+ </message>
+ <message>
+ <source>Received with label</source>
+ <translation>Reçu avec une étiquette</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>Reçu avec une adresse</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Date</translation>
+ </message>
+ <message>
+ <source>Confirmations</source>
+ <translation>Confirmations</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Confirmée</translation>
+ </message>
+ <message>
+ <source>Priority</source>
+ <translation>Priorité</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Copier l’adresse</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Copier l’étiquette</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copier le montant</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Copier l'ID de la transaction</translation>
+ </message>
+ <message>
+ <source>Lock unspent</source>
+ <translation>Verrouiller ce qui n'est pas dépensé</translation>
+ </message>
+ <message>
+ <source>Unlock unspent</source>
+ <translation>Déverrouiller ce qui n'est pas dépensé</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Copier la quantité</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Copier les frais</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Copier le montant après les frais</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Copier les octets</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Copier la priorité</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Copier la poussière</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Copier la monnaie</translation>
+ </message>
+ <message>
+ <source>highest</source>
+ <translation>la plus élevée</translation>
+ </message>
+ <message>
+ <source>higher</source>
+ <translation>plus élevée</translation>
+ </message>
+ <message>
+ <source>high</source>
+ <translation>élevée</translation>
+ </message>
+ <message>
+ <source>medium-high</source>
+ <translation>moyennement-élevée</translation>
+ </message>
+ <message>
+ <source>medium</source>
+ <translation>moyenne</translation>
+ </message>
+ <message>
+ <source>low-medium</source>
+ <translation>moyennement-basse</translation>
+ </message>
+ <message>
+ <source>low</source>
+ <translation>basse</translation>
+ </message>
+ <message>
+ <source>lower</source>
+ <translation>plus basse</translation>
+ </message>
+ <message>
+ <source>lowest</source>
+ <translation>la plus basse</translation>
+ </message>
+ <message>
+ <source>(%1 locked)</source>
+ <translation>(%1 verrouillé)</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>aucun</translation>
+ </message>
+ <message>
+ <source>This label turns red if the transaction size is greater than 1000 bytes.</source>
+ <translation>Cette étiquette devient rouge si la taille de la transaction est plus grande que 1 000 octets.</translation>
+ </message>
+ <message>
+ <source>This label turns red if the priority is smaller than "medium".</source>
+ <translation>Cette étiquette devient rouge si la priorité est plus basse que « moyenne ».</translation>
+ </message>
+ <message>
+ <source>Can vary +/- %1 satoshi(s) per input.</source>
+ <translation>Peut varier +/- %1 satoshi(s) par entrée.</translation>
+ </message>
+ <message>
+ <source>yes</source>
+ <translation>oui</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>non</translation>
+ </message>
+ <message>
+ <source>This means a fee of at least %1 per kB is required.</source>
+ <translation>Ceci signifie que des frais d'au moins %1 par ko sont exigés.</translation>
+ </message>
+ <message>
+ <source>Can vary +/- 1 byte per input.</source>
+ <translation>Peut varier +/- 1 octet par entrée.</translation>
+ </message>
+ <message>
+ <source>Transactions with higher priority are more likely to get included into a block.</source>
+ <translation>Les transactions à priorité plus haute sont plus à même d'être incluses dans un bloc.</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(aucune étiquette)</translation>
+ </message>
+ <message>
+ <source>change from %1 (%2)</source>
+ <translation>monnaie de %1 (%2)</translation>
+ </message>
+ <message>
+ <source>(change)</source>
+ <translation>(monnaie)</translation>
+ </message>
+</context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>Modifier l'adresse</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>&amp;Étiquette</translation>
+ </message>
+ <message>
+ <source>The label associated with this address list entry</source>
+ <translation>L'étiquette associée à cette entrée de la liste d'adresses</translation>
+ </message>
+ <message>
+ <source>The address associated with this address list entry. This can only be modified for sending addresses.</source>
+ <translation>L'adresse associée à cette entrée de la liste d'adresses. Ceci ne peut être modifié que pour les adresses d'envoi.</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;Adresse</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>Nouvelle adresse de réception</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>Nouvelle adresse d’envoi</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>Modifier l’adresse de réception</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>Modifier l’adresse d'envoi</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>L’adresse fournie « %1 » est déjà présente dans le carnet d'adresses.</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is not a valid Bitcoin address.</source>
+ <translation>L'adresse fournie « %1 » n'est pas une adresse Bitcoin valide.</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>Impossible de déverrouiller le portefeuille.</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>Échec de génération de la nouvelle clef.</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ <message>
+ <source>A new data directory will be created.</source>
+ <translation>Un nouveau répertoire de données sera créé.</translation>
+ </message>
+ <message>
+ <source>name</source>
+ <translation>nom</translation>
+ </message>
+ <message>
+ <source>Directory already exists. Add %1 if you intend to create a new directory here.</source>
+ <translation>Le répertoire existe déjà. Ajoutez %1 si vous voulez créer un nouveau répertoire ici.</translation>
+ </message>
+ <message>
+ <source>Path already exists, and is not a directory.</source>
+ <translation>Le chemin existe déjà et n'est pas un répertoire.</translation>
+ </message>
+ <message>
+ <source>Cannot create data directory here.</source>
+ <translation>Impossible de créer un répertoire de données ici.</translation>
+ </message>
+</context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>version</translation>
+ </message>
+ <message>
+ <source>(%1-bit)</source>
+ <translation>(%1-bit)</translation>
+ </message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>À propos de Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Command-line options</source>
+ <translation>Options de ligne de commande</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>Utilisation :</translation>
+ </message>
+ <message>
+ <source>command-line options</source>
+ <translation>options de ligne de commande</translation>
+ </message>
+</context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Welcome</source>
+ <translation>Bienvenue</translation>
+ </message>
+ <message>
+ <source>Welcome to Bitcoin Core.</source>
+ <translation>Bienvenue à Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</source>
+ <translation>Comme c'est la première fois que le logiciel est lancé, vous pouvez choisir où Bitcoin Core stockera ses données.</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory.</source>
+ <translation>Bitcoin Core va télécharger et stocker une copie de la chaîne de blocs Bitcoin. Au moins %1Go de données seront stockées dans ce répertoire et cela augmentera avec le temps. Le portefeuille sera également stocké dans ce répertoire.</translation>
+ </message>
+ <message>
+ <source>Use the default data directory</source>
+ <translation>Utiliser le répertoire de données par défaut</translation>
+ </message>
+ <message>
+ <source>Use a custom data directory:</source>
+ <translation>Utiliser un répertoire de données personnalisé :</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Error: Specified data directory "%1" cannot be created.</source>
+ <translation>Erreur : le répertoire de données spécifié « %1 » ne peut pas être créé.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Erreur</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n GB of free space available</source>
+ <translation><numerusform>%n Go d'espace libre disponible</numerusform><numerusform>%n Go d'espace libre disponibles</numerusform></translation>
+ </message>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ <message>
+ <source>Open URI</source>
+ <translation>Ouvrir un URI</translation>
+ </message>
+ <message>
+ <source>Open payment request from URI or file</source>
+ <translation>Ouvrir une demande de paiement à partir d'un URI ou d'un fichier</translation>
+ </message>
+ <message>
+ <source>URI:</source>
+ <translation>URI :</translation>
+ </message>
+ <message>
+ <source>Select payment request file</source>
+ <translation>Choisir le fichier de demande de paiement</translation>
+ </message>
+ <message>
+ <source>Select payment request file to open</source>
+ <translation>Choisir le fichier de demande de paiement à ouvrir</translation>
+ </message>
+</context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>Options</translation>
+ </message>
+ <message>
+ <source>&amp;Main</source>
+ <translation>Réglages &amp;principaux</translation>
+ </message>
+ <message>
+ <source>Size of &amp;database cache</source>
+ <translation>Taille du cache de la base de &amp;données</translation>
+ </message>
+ <message>
+ <source>MB</source>
+ <translation>Mo</translation>
+ </message>
+ <message>
+ <source>Number of script &amp;verification threads</source>
+ <translation>Nombre d'exétrons de &amp;vérification de script</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside</source>
+ <translation>Accepter les connexions provenant de l'extérieur</translation>
+ </message>
+ <message>
+ <source>Allow incoming connections</source>
+ <translation>Permettre les transactions entrantes</translation>
+ </message>
+ <message>
+ <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
+ <translation>Adresse IP du mandataire (par ex. IPv4 : 127.0.0.1 / IPv6 : ::1)</translation>
+ </message>
+ <message>
+ <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source>
+ <translation>Minimiser au lieu de quitter l'application lorsque la fenêtre est fermée. Si cette option est activée, l'application ne sera fermée qu'en sélectionnant Quitter dans le menu.</translation>
+ </message>
+ <message>
+ <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source>
+ <translation>La langue de l'interface utilisateur peut être définie ici. Ce réglage sera pris en compte après redémarrage de Bitcoin.</translation>
+ </message>
+ <message>
+ <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source>
+ <translation>URL de tiers (par ex. un explorateur de blocs) apparaissant dans l'onglet des transactions comme éléments du menu contextuel. %s dans l'URL est remplacé par le hachage de la transaction. Les URL multiples sont séparées par une barre verticale |.</translation>
+ </message>
+ <message>
+ <source>Third party transaction URLs</source>
+ <translation>URL de transaction d'un tiers</translation>
+ </message>
+ <message>
+ <source>Active command-line options that override above options:</source>
+ <translation>Options actives de ligne de commande qui annulent les options ci-dessus :</translation>
+ </message>
+ <message>
+ <source>Reset all client options to default.</source>
+ <translation>Réinitialiser toutes les options du client aux valeurs par défaut.</translation>
+ </message>
+ <message>
+ <source>&amp;Reset Options</source>
+ <translation>&amp;Réinitialisation des options</translation>
+ </message>
+ <message>
+ <source>&amp;Network</source>
+ <translation>&amp;Réseau</translation>
+ </message>
+ <message>
+ <source>Automatically start Bitcoin Core after logging in to the system.</source>
+ <translation>Démarrer Bitcoin Core automatiquement après avoir ouvert une session sur le système.</translation>
+ </message>
+ <message>
+ <source>&amp;Start Bitcoin Core on system login</source>
+ <translation>&amp;Démarrer Bitcoin Core lors de l'ouverture d'une session</translation>
+ </message>
+ <message>
+ <source>(0 = auto, &lt;0 = leave that many cores free)</source>
+ <translation>(0 = auto, &lt; 0 = laisser ce nombre de cœurs inutilisés)</translation>
+ </message>
+ <message>
+ <source>W&amp;allet</source>
+ <translation>&amp;Portefeuille</translation>
+ </message>
+ <message>
+ <source>Expert</source>
+ <translation>Expert</translation>
+ </message>
+ <message>
+ <source>Enable coin &amp;control features</source>
+ <translation>Activer les fonctions de &amp;contrôle des pièces </translation>
+ </message>
+ <message>
+ <source>If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.</source>
+ <translation>Si vous désactivé la dépense de la monnaie non confirmée, la monnaie d'une transaction ne peut pas être utilisée tant que cette transaction n'a pas reçu au moins une confirmation. Ceci affecte aussi comment votre solde est calculé.</translation>
+ </message>
+ <message>
+ <source>&amp;Spend unconfirmed change</source>
+ <translation>&amp;Dépenser la monnaie non confirmée</translation>
+ </message>
+ <message>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>Ouvrir le port du client Bitcoin automatiquement sur le routeur. Ceci ne fonctionne que si votre routeur supporte l'UPnP et si la fonctionnalité est activée.</translation>
+ </message>
+ <message>
+ <source>Map port using &amp;UPnP</source>
+ <translation>Mapper le port avec l'&amp;UPnP</translation>
+ </message>
+ <message>
+ <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
+ <translation>Se connecter au réseau Bitcoin par un mandataire SOCKS5.</translation>
+ </message>
+ <message>
+ <source>&amp;Connect through SOCKS5 proxy (default proxy):</source>
+ <translation>Se &amp;connecter par un mandataire SOCKS5 (mandataire par défaut) :</translation>
+ </message>
+ <message>
+ <source>Proxy &amp;IP:</source>
+ <translation>&amp;IP du serveur mandataire :</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>&amp;Port :</translation>
+ </message>
+ <message>
+ <source>Port of the proxy (e.g. 9050)</source>
+ <translation>Port du serveur mandataire (par ex. 9050)</translation>
+ </message>
+ <message>
+ <source>&amp;Window</source>
+ <translation>&amp;Fenêtre</translation>
+ </message>
+ <message>
+ <source>Show only a tray icon after minimizing the window.</source>
+ <translation>Afficher uniquement une icône système après minimisation.</translation>
+ </message>
+ <message>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>&amp;Minimiser dans la barre système au lieu de la barre des tâches</translation>
+ </message>
+ <message>
+ <source>M&amp;inimize on close</source>
+ <translation>M&amp;inimiser lors de la fermeture</translation>
+ </message>
+ <message>
+ <source>&amp;Display</source>
+ <translation>&amp;Affichage</translation>
+ </message>
+ <message>
+ <source>User Interface &amp;language:</source>
+ <translation>&amp;Langue de l'interface utilisateur :</translation>
+ </message>
+ <message>
+ <source>&amp;Unit to show amounts in:</source>
+ <translation>&amp;Unité d'affichage des montants :</translation>
+ </message>
+ <message>
+ <source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
+ <translation>Choisissez la sous-unité par défaut pour l'affichage dans l'interface et lors de l'envoi de pièces.</translation>
+ </message>
+ <message>
+ <source>Whether to show coin control features or not.</source>
+ <translation>Afficher ou non les fonctions de contrôle des pièces.</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>&amp;OK</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>A&amp;nnuler</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>par défaut</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>aucune</translation>
+ </message>
+ <message>
+ <source>Confirm options reset</source>
+ <translation>Confirmer la réinitialisation des options</translation>
+ </message>
+ <message>
+ <source>Client restart required to activate changes.</source>
+ <translation>Le redémarrage du client est nécessaire pour activer les changements.</translation>
+ </message>
+ <message>
+ <source>Client will be shut down. Do you want to proceed?</source>
+ <translation>Le client sera arrêté. Voulez-vous continuer ?</translation>
+ </message>
+ <message>
+ <source>This change would require a client restart.</source>
+ <translation>Ce changement demanderait un redémarrage du client.</translation>
+ </message>
+ <message>
+ <source>The supplied proxy address is invalid.</source>
+ <translation>L'adresse de serveur mandataire fournie est invalide.</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>Formulaire</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>Les informations affichées peuvent être obsolètes. Votre portefeuille est automatiquement synchronisé avec le réseau Bitcoin lorsque la connexion s'établit, or ce processus n'est pas encore terminé.</translation>
+ </message>
+ <message>
+ <source>Watch-only:</source>
+ <translation>Juste-regarder :</translation>
+ </message>
+ <message>
+ <source>Available:</source>
+ <translation>Disponible :</translation>
+ </message>
+ <message>
+ <source>Your current spendable balance</source>
+ <translation>Votre solde actuel pouvant être dépensé</translation>
+ </message>
+ <message>
+ <source>Pending:</source>
+ <translation>En attente :</translation>
+ </message>
+ <message>
+ <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source>
+ <translation>Total des transactions qui doivent encore être confirmées et qu'il n'est pas encore possible de dépenser</translation>
+ </message>
+ <message>
+ <source>Immature:</source>
+ <translation>Immature :</translation>
+ </message>
+ <message>
+ <source>Mined balance that has not yet matured</source>
+ <translation>Le solde généré n'est pas encore mûr</translation>
+ </message>
+ <message>
+ <source>Balances</source>
+ <translation>Soldes</translation>
+ </message>
+ <message>
+ <source>Total:</source>
+ <translation>Total :</translation>
+ </message>
+ <message>
+ <source>Your current total balance</source>
+ <translation>Votre solde total actuel</translation>
+ </message>
+ <message>
+ <source>Your current balance in watch-only addresses</source>
+ <translation>Votre balance actuelle en adresses juste-regarder</translation>
+ </message>
+ <message>
+ <source>Spendable:</source>
+ <translation>Disponible :</translation>
+ </message>
+ <message>
+ <source>Recent transactions</source>
+ <translation>Transactions récentes</translation>
+ </message>
+ <message>
+ <source>Unconfirmed transactions to watch-only addresses</source>
+ <translation>Transactions non confirmées vers des adresses juste-regarder</translation>
+ </message>
+ <message>
+ <source>Mined balance in watch-only addresses that has not yet matured</source>
+ <translation>Le solde miné dans des adresses juste-regarder, qui n'est pas encore mûr</translation>
+ </message>
+ <message>
+ <source>Current total balance in watch-only addresses</source>
+ <translation>Solde total actuel dans des adresses juste-regarder</translation>
+ </message>
+</context>
+<context>
+ <name>PaymentServer</name>
+ <message>
+ <source>URI handling</source>
+ <translation>Gestion des URIs</translation>
+ </message>
+ <message>
+ <source>Invalid payment address %1</source>
+ <translation>Adresse de paiement invalide %1</translation>
+ </message>
+ <message>
+ <source>Payment request rejected</source>
+ <translation>La demande de paiement est rejetée</translation>
+ </message>
+ <message>
+ <source>Payment request network doesn't match client network.</source>
+ <translation>Le réseau de la demande de paiement ne correspond pas au réseau du client.</translation>
+ </message>
+ <message>
+ <source>Payment request is not initialized.</source>
+ <translation>La demande de paiement n'est pas initialisée.</translation>
+ </message>
+ <message>
+ <source>Requested payment amount of %1 is too small (considered dust).</source>
+ <translation>Le paiement demandé d'un montant de %1 est trop faible (considéré comme de la poussière).</translation>
+ </message>
+ <message>
+ <source>Payment request error</source>
+ <translation>Erreur de demande de paiement</translation>
+ </message>
+ <message>
+ <source>Cannot start bitcoin: click-to-pay handler</source>
+ <translation>Impossible de démarrer le gestionnaire de cliquer-pour-payer bitcoin :</translation>
+ </message>
+ <message>
+ <source>Payment request fetch URL is invalid: %1</source>
+ <translation>L'URL de récupération de la demande de paiement est invalide : %1</translation>
+ </message>
+ <message>
+ <source>URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source>
+ <translation>L'URI ne peut pas être analysé ! Ceci peut être causé par une adresse Bitcoin invalide ou par des paramètres d'URI mal formés.</translation>
+ </message>
+ <message>
+ <source>Payment request file handling</source>
+ <translation>Gestion des fichiers de demande de paiement</translation>
+ </message>
+ <message>
+ <source>Payment request file cannot be read! This can be caused by an invalid payment request file.</source>
+ <translation>Le fichier de demande de paiement ne peut pas être lu ! Ceci peut être causé par un fichier de demande de paiement invalide.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>Demande de paiement expirée.</translation>
+ </message>
+ <message>
+ <source>Unverified payment requests to custom payment scripts are unsupported.</source>
+ <translation>Les demandes de paiements non vérifiées à des scripts de paiement personnalisés ne sont pas prises en charge.</translation>
+ </message>
+ <message>
+ <source>Invalid payment request.</source>
+ <translation>Demande de paiement invalide.</translation>
+ </message>
+ <message>
+ <source>Refund from %1</source>
+ <translation>Remboursement de %1</translation>
+ </message>
+ <message>
+ <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source>
+ <translation>La demande de paiement %1 est trop grande (%2 octets, %3 octets permis).</translation>
+ </message>
+ <message>
+ <source>Payment request DoS protection</source>
+ <translation>Protection DdS des demandes de paiement</translation>
+ </message>
+ <message>
+ <source>Error communicating with %1: %2</source>
+ <translation>Erreur de communication avec %1 : %2</translation>
+ </message>
+ <message>
+ <source>Payment request cannot be parsed!</source>
+ <translation>La demande de paiement ne peut pas être analysée !</translation>
+ </message>
+ <message>
+ <source>Bad response from server %1</source>
+ <translation>Mauvaise réponse du serveur %1</translation>
+ </message>
+ <message>
+ <source>Payment acknowledged</source>
+ <translation>Le paiement a été confirmé</translation>
+ </message>
+ <message>
+ <source>Network request error</source>
+ <translation>Erreur de demande réseau</translation>
+ </message>
+</context>
+<context>
+ <name>PeerTableModel</name>
+ <message>
+ <source>User Agent</source>
+ <translation>Agent utilisateur</translation>
+ </message>
+ <message>
+ <source>Node/Service</source>
+ <translation>Nœud/service</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Temps de ping</translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>Montant</translation>
+ </message>
+ <message>
+ <source>Enter a Bitcoin address (e.g. %1)</source>
+ <translation>Saisir une adresse Bitcoin (p. ex. %1)</translation>
+ </message>
+ <message>
+ <source>%1 d</source>
+ <translation>%1 d</translation>
+ </message>
+ <message>
+ <source>%1 h</source>
+ <translation>%1 h</translation>
+ </message>
+ <message>
+ <source>%1 m</source>
+ <translation>%1 min</translation>
+ </message>
+ <message>
+ <source>%1 s</source>
+ <translation>%1 s</translation>
+ </message>
+ <message>
+ <source>None</source>
+ <translation>Aucun</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>N.D.</translation>
+ </message>
+ <message>
+ <source>%1 ms</source>
+ <translation>%1 ms</translation>
+ </message>
+</context>
+<context>
+ <name>QRImageWidget</name>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Sauvegarder l'image...</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Image</source>
+ <translation>&amp;Copier l'image</translation>
+ </message>
+ <message>
+ <source>Save QR Code</source>
+ <translation>Sauvegarder le code QR</translation>
+ </message>
+ <message>
+ <source>PNG Image (*.png)</source>
+ <translation>Image PNG (*.png)</translation>
+ </message>
+</context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>Client name</source>
+ <translation>Nom du client</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>N.D.</translation>
+ </message>
+ <message>
+ <source>Client version</source>
+ <translation>Version du client</translation>
+ </message>
+ <message>
+ <source>&amp;Information</source>
+ <translation>&amp;Informations</translation>
+ </message>
+ <message>
+ <source>Debug window</source>
+ <translation>Fenêtre de débogage</translation>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>Général</translation>
+ </message>
+ <message>
+ <source>Using OpenSSL version</source>
+ <translation>Version d'OpenSSL utilisée</translation>
+ </message>
+ <message>
+ <source>Using BerkeleyDB version</source>
+ <translation>Version BerkeleyDB utilisée</translation>
+ </message>
+ <message>
+ <source>Startup time</source>
+ <translation>Heure de démarrage</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Réseau</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>Nom</translation>
+ </message>
+ <message>
+ <source>Number of connections</source>
+ <translation>Nombre de connexions</translation>
+ </message>
+ <message>
+ <source>Block chain</source>
+ <translation>Chaîne de blocs</translation>
+ </message>
+ <message>
+ <source>Current number of blocks</source>
+ <translation>Nombre actuel de blocs</translation>
+ </message>
+ <message>
+ <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source>
+ <translation>Ouvrir le journal de débogage du répertoire de données actuel. Ceci pourrait prendre quelques secondes pour les gros fichiers de journalisation.</translation>
+ </message>
+ <message>
+ <source>Received</source>
+ <translation>Reçu</translation>
+ </message>
+ <message>
+ <source>Sent</source>
+ <translation>Envoyé</translation>
+ </message>
+ <message>
+ <source>&amp;Peers</source>
+ <translation>&amp;Pairs</translation>
+ </message>
+ <message>
+ <source>Select a peer to view detailed information.</source>
+ <translation>Choisir un pair pour voir l'information détaillée.</translation>
+ </message>
+ <message>
+ <source>Direction</source>
+ <translation>Direction</translation>
+ </message>
+ <message>
+ <source>Version</source>
+ <translation>Version</translation>
+ </message>
+ <message>
+ <source>User Agent</source>
+ <translation>Agent utilisateur</translation>
+ </message>
+ <message>
+ <source>Services</source>
+ <translation>Services</translation>
+ </message>
+ <message>
+ <source>Starting Height</source>
+ <translation>Hauteur de démarrage</translation>
+ </message>
+ <message>
+ <source>Sync Height</source>
+ <translation>Hauteur de synchro</translation>
+ </message>
+ <message>
+ <source>Ban Score</source>
+ <translation>Pointage des bannissements</translation>
+ </message>
+ <message>
+ <source>Connection Time</source>
+ <translation>Temps de connexion</translation>
+ </message>
+ <message>
+ <source>Last Send</source>
+ <translation>Dernier envoi</translation>
+ </message>
+ <message>
+ <source>Last Receive</source>
+ <translation>Dernière réception</translation>
+ </message>
+ <message>
+ <source>Bytes Sent</source>
+ <translation>Octets envoyés</translation>
+ </message>
+ <message>
+ <source>Bytes Received</source>
+ <translation>Octets reçus</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Temps de ping</translation>
+ </message>
+ <message>
+ <source>Time Offset</source>
+ <translation>Décalage temporel</translation>
+ </message>
+ <message>
+ <source>Last block time</source>
+ <translation>Horodatage du dernier bloc</translation>
+ </message>
+ <message>
+ <source>&amp;Open</source>
+ <translation>&amp;Ouvrir</translation>
+ </message>
+ <message>
+ <source>&amp;Console</source>
+ <translation>&amp;Console</translation>
+ </message>
+ <message>
+ <source>&amp;Network Traffic</source>
+ <translation>Trafic &amp;réseau</translation>
+ </message>
+ <message>
+ <source>&amp;Clear</source>
+ <translation>&amp;Nettoyer</translation>
+ </message>
+ <message>
+ <source>Totals</source>
+ <translation>Totaux</translation>
+ </message>
+ <message>
+ <source>In:</source>
+ <translation>Entrant :</translation>
+ </message>
+ <message>
+ <source>Out:</source>
+ <translation>Sortant :</translation>
+ </message>
+ <message>
+ <source>Build date</source>
+ <translation>Date de compilation</translation>
+ </message>
+ <message>
+ <source>Debug log file</source>
+ <translation>Journal de débogage</translation>
+ </message>
+ <message>
+ <source>Clear console</source>
+ <translation>Nettoyer la console</translation>
+ </message>
+ <message>
+ <source>Welcome to the Bitcoin Core RPC console.</source>
+ <translation>Bienvenue dans le console RPC de Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
+ <translation>Utiliser les touches de curseur pour naviguer dans l'historique et &lt;b&gt;Ctrl-L&lt;/b&gt; pour effacer l'écran.</translation>
+ </message>
+ <message>
+ <source>Type &lt;b&gt;help&lt;/b&gt; for an overview of available commands.</source>
+ <translation>Taper &lt;b&gt;help&lt;/b&gt; pour afficher une vue générale des commandes proposées.</translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation>%1 o</translation>
+ </message>
+ <message>
+ <source>%1 KB</source>
+ <translation>%1 Ko</translation>
+ </message>
+ <message>
+ <source>%1 MB</source>
+ <translation>%1 Mo</translation>
+ </message>
+ <message>
+ <source>%1 GB</source>
+ <translation>%1 Go</translation>
+ </message>
+ <message>
+ <source>via %1</source>
+ <translation>par %1</translation>
+ </message>
+ <message>
+ <source>never</source>
+ <translation>jamais</translation>
+ </message>
+ <message>
+ <source>Inbound</source>
+ <translation>Entrant</translation>
+ </message>
+ <message>
+ <source>Outbound</source>
+ <translation>Sortant</translation>
+ </message>
+ <message>
+ <source>Unknown</source>
+ <translation>Inconnu</translation>
+ </message>
+ <message>
+ <source>Fetching...</source>
+ <translation>Récupération...</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Amount:</source>
+ <translation>&amp;Montant :</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Étiquette :</translation>
+ </message>
+ <message>
+ <source>&amp;Message:</source>
+ <translation>M&amp;essage :</translation>
+ </message>
+ <message>
+ <source>Reuse one of the previously used receiving addresses. Reusing addresses has security and privacy issues. Do not use this unless re-generating a payment request made before.</source>
+ <translation>Réutilise une adresse de réception précédemment utilisée. Réutiliser une adresse pose des problèmes de sécurité et de vie privée. N'utilisez pas cette option sauf si vous générez à nouveau une demande de paiement déjà faite.</translation>
+ </message>
+ <message>
+ <source>R&amp;euse an existing receiving address (not recommended)</source>
+ <translation>Ré&amp;utiliser une adresse de réception existante (non recommandé)</translation>
+ </message>
+ <message>
+ <source>An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network.</source>
+ <translation>Un message optionnel à joindre à la demande de paiement qui sera affiché à l'ouverture de celle-ci. Note : le message ne sera pas envoyé avec le paiement par le réseau Bitcoin.</translation>
+ </message>
+ <message>
+ <source>An optional label to associate with the new receiving address.</source>
+ <translation>Un étiquette optionnelle à associer à la nouvelle adresse de réception</translation>
+ </message>
+ <message>
+ <source>Use this form to request payments. All fields are &lt;b&gt;optional&lt;/b&gt;.</source>
+ <translation>Utiliser ce formulaire pour demander des paiements. Tous les champs sont &lt;b&gt;optionnels&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>An optional amount to request. Leave this empty or zero to not request a specific amount.</source>
+ <translation>Un montant optionnel à demander. Laisser ceci vide ou à zéro pour ne pas demander de montant spécifique.</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Effacer tous les champs du formulaire.</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation>Effacer</translation>
+ </message>
+ <message>
+ <source>Requested payments history</source>
+ <translation>Historique des paiements demandés</translation>
+ </message>
+ <message>
+ <source>&amp;Request payment</source>
+ <translation>&amp;Demande de paiement</translation>
+ </message>
+ <message>
+ <source>Show the selected request (does the same as double clicking an entry)</source>
+ <translation>Afficher la demande choisie (identique à un double-clic sur une entrée)</translation>
+ </message>
+ <message>
+ <source>Show</source>
+ <translation>Afficher</translation>
+ </message>
+ <message>
+ <source>Remove the selected entries from the list</source>
+ <translation>Enlever les entrées sélectionnées de la liste</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>Enlever</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Copier l’étiquette</translation>
+ </message>
+ <message>
+ <source>Copy message</source>
+ <translation>Copier le message</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copier le montant</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>QR Code</source>
+ <translation>Code QR</translation>
+ </message>
+ <message>
+ <source>Copy &amp;URI</source>
+ <translation>Copier l'&amp;URI</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Address</source>
+ <translation>Copier l'&amp;adresse</translation>
+ </message>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Sauvegarder l'image...</translation>
+ </message>
+ <message>
+ <source>Request payment to %1</source>
+ <translation>Demande de paiement à %1</translation>
+ </message>
+ <message>
+ <source>Payment information</source>
+ <translation>Informations de paiement</translation>
+ </message>
+ <message>
+ <source>URI</source>
+ <translation>URI</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adresse</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Montant</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Étiquette</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Message</translation>
+ </message>
+ <message>
+ <source>Resulting URI too long, try to reduce the text for label / message.</source>
+ <translation>L'URI résultant est trop long, essayez de réduire le texte d'étiquette / de message.</translation>
+ </message>
+ <message>
+ <source>Error encoding URI into QR Code.</source>
+ <translation>Erreur d'encodage de l'URI en code QR.</translation>
+ </message>
+</context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Date</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Étiquette</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Message</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Montant</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(pas d'étiquette)</translation>
+ </message>
+ <message>
+ <source>(no message)</source>
+ <translation>(pas de message)</translation>
+ </message>
+ <message>
+ <source>(no amount)</source>
+ <translation>(aucun montant)</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Envoyer des pièces</translation>
+ </message>
+ <message>
+ <source>Coin Control Features</source>
+ <translation>Fonctions de contrôle des pièces</translation>
+ </message>
+ <message>
+ <source>Inputs...</source>
+ <translation>Entrants...</translation>
+ </message>
+ <message>
+ <source>automatically selected</source>
+ <translation>choisi automatiquement</translation>
+ </message>
+ <message>
+ <source>Insufficient funds!</source>
+ <translation>Fonds insuffisants !</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Quantité :</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Octets :</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Montant :</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Priorité :</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Frais :</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Après les frais :</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Monnaie :</translation>
+ </message>
+ <message>
+ <source>If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address.</source>
+ <translation>Si ceci est actif mais l'adresse de monnaie rendue est vide ou invalide, la monnaie sera envoyée vers une adresse nouvellement générée.</translation>
+ </message>
+ <message>
+ <source>Custom change address</source>
+ <translation>Adresse personnalisée de monnaie rendue</translation>
+ </message>
+ <message>
+ <source>Transaction Fee:</source>
+ <translation>Frais de transaction :</translation>
+ </message>
+ <message>
+ <source>Choose...</source>
+ <translation>Choisir...</translation>
+ </message>
+ <message>
+ <source>collapse fee-settings</source>
+ <translation>réduire les paramètres des frais</translation>
+ </message>
+ <message>
+ <source>per kilobyte</source>
+ <translation>par kilo-octet</translation>
+ </message>
+ <message>
+ <source>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "total at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source>
+ <translation>Si les frais personnalisés sont définis à 1 000 satoshis et que la transaction est seulement de 250 octets, donc le « par kilo-octet » ne paiera que 250 satoshis de frais, alors que le « total au moins » paiera 1 000 satoshis. Pour des transactions supérieures à un kilo-octet, les deux paieront par kilo-octets.</translation>
+ </message>
+ <message>
+ <source>Hide</source>
+ <translation>Cacher</translation>
+ </message>
+ <message>
+ <source>total at least</source>
+ <translation>total au moins</translation>
+ </message>
+ <message>
+ <source>Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process.</source>
+ <translation>Il est correct de payer les frais minimum tant que le volume transactionnel est inférieur à l'espace dans les blocs. Mais soyez conscient que ceci pourrait résulter en une transaction n'étant jamais confirmée une fois qu'il y aura plus de transactions que le réseau ne pourra en traiter.</translation>
+ </message>
+ <message>
+ <source>(read the tooltip)</source>
+ <translation>(lire l'infobulle)</translation>
+ </message>
+ <message>
+ <source>Recommended:</source>
+ <translation>Recommandés :</translation>
+ </message>
+ <message>
+ <source>Custom:</source>
+ <translation>Personnalisés : </translation>
+ </message>
+ <message>
+ <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source>
+ <translation>(Les frais intelligents ne sont pas encore initialisés. Ceci prend habituellement quelques blocs...)</translation>
+ </message>
+ <message>
+ <source>Confirmation time:</source>
+ <translation>Temps de confirmation :</translation>
+ </message>
+ <message>
+ <source>normal</source>
+ <translation>normal</translation>
+ </message>
+ <message>
+ <source>fast</source>
+ <translation>rapide</translation>
+ </message>
+ <message>
+ <source>Send as zero-fee transaction if possible</source>
+ <translation>Envoyer si possible une transaction sans frais</translation>
+ </message>
+ <message>
+ <source>(confirmation may take longer)</source>
+ <translation>(la confirmation pourrait prendre plus longtemps)</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>Envoyer à plusieurs destinataires à la fois</translation>
+ </message>
+ <message>
+ <source>Add &amp;Recipient</source>
+ <translation>Ajouter un &amp;destinataire</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Effacer tous les champs du formulaire.</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Poussière :</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>&amp;Tout nettoyer</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>Solde :</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>Confirmer l’action d'envoi</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>E&amp;nvoyer</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>Confirmer l’envoi des pièces</translation>
+ </message>
+ <message>
+ <source>%1 to %2</source>
+ <translation>%1 à %2</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Copier la quantité</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copier le montant</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Copier les frais</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Copier le montant après les frais</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Copier les octets</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Copier la priorité</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Copier la monnaie</translation>
+ </message>
+ <message>
+ <source>or</source>
+ <translation>ou</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>Le montant à payer doit être supérieur à 0.</translation>
+ </message>
+ <message>
+ <source>The amount exceeds your balance.</source>
+ <translation>Le montant dépasse votre solde.</translation>
+ </message>
+ <message>
+ <source>The total exceeds your balance when the %1 transaction fee is included.</source>
+ <translation>Le montant dépasse votre solde lorsque les frais de transaction de %1 sont inclus.</translation>
+ </message>
+ <message>
+ <source>Transaction creation failed!</source>
+ <translation>La création de la transaction a échoué !</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>La transaction a été rejetée ! Ceci peut arriver si certaines pièces de votre portefeuille étaient déjà dépensées, par exemple si vous avez utilisé une copie de wallet.dat et que des pièces ont été dépensées dans la copie sans être marquées comme telles ici.</translation>
+ </message>
+ <message>
+ <source>A fee higher than %1 is considered an absurdly high fee.</source>
+ <translation>Des frais supérieurs à %1 sont considérés comme ridiculement élevés.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>Demande de paiement expirée.</translation>
+ </message>
+ <message numerus="yes">
+ <source>Estimated to begin confirmation within %n block(s).</source>
+ <translation><numerusform>Il est estimé que la confirmation commencera dans %n bloc.</numerusform><numerusform>Il est estimé que la confirmation commencera dans %n blocs.</numerusform></translation>
+ </message>
+ <message>
+ <source>Pay only the minimum fee of %1</source>
+ <translation>Payer seulement les frais minimum de %1</translation>
+ </message>
+ <message>
+ <source>The recipient address is not valid. Please recheck.</source>
+ <translation>L'adresse du destinataire est invalide. Veuillez la vérifier.</translation>
+ </message>
+ <message>
+ <source>Duplicate address found: addresses should only be used once each.</source>
+ <translation>Adresse identique trouvée : chaque adresse ne devrait être utilisée qu'une fois.</translation>
+ </message>
+ <message>
+ <source>Warning: Invalid Bitcoin address</source>
+ <translation>Avertissement : adresse Bitcoin invalide</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(pas d'étiquette)</translation>
+ </message>
+ <message>
+ <source>Warning: Unknown change address</source>
+ <translation>Avertissement : adresse de monnaie rendue inconnue</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Copier la poussière</translation>
+ </message>
+ <message>
+ <source>Are you sure you want to send?</source>
+ <translation>Êtes-vous sûr de vouloir envoyer ?</translation>
+ </message>
+ <message>
+ <source>added as transaction fee</source>
+ <translation>ajouté en tant que frais de transaction</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>&amp;Montant :</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>&amp;Payer à :</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Saisir une étiquette pour cette adresse afin de l’ajouter à votre carnet d’adresses</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>É&amp;tiquette :</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Choisir une adresse déjà utilisée</translation>
+ </message>
+ <message>
+ <source>This is a normal payment.</source>
+ <translation>Ceci est un paiement normal.</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to send the payment to</source>
+ <translation>L'adresse Bitcoin à laquelle envoyer le paiement</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Coller l'adresse depuis le presse-papiers</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Remove this entry</source>
+ <translation>Enlever cette entrée</translation>
+ </message>
+ <message>
+ <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source>
+ <translation>Les frais seront déduits du montant envoyé. Le destinataire recevra moins de bitcoins que le montant saisi dans le champ de montant. Si plusieurs destinataires sont sélectionnés, les frais seront partagés également..</translation>
+ </message>
+ <message>
+ <source>S&amp;ubtract fee from amount</source>
+ <translation>S&amp;oustraire les frais du montant</translation>
+ </message>
+ <message>
+ <source>Message:</source>
+ <translation>Message :</translation>
+ </message>
+ <message>
+ <source>This is an unauthenticated payment request.</source>
+ <translation>Cette demande de paiement n'est pas authentifiée.</translation>
+ </message>
+ <message>
+ <source>This is an authenticated payment request.</source>
+ <translation>Cette demande de paiement est authentifiée.</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to the list of used addresses</source>
+ <translation>Saisir une étiquette pour cette adresse afin de l'ajouter à la liste d'adresses utilisées</translation>
+ </message>
+ <message>
+ <source>A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network.</source>
+ <translation>Un message qui était joint à l'URI Bitcoin et qui sera stocké avec la transaction pour référence. Note : ce message ne sera pas envoyé par le réseau Bitcoin.</translation>
+ </message>
+ <message>
+ <source>Pay To:</source>
+ <translation>Payer à :</translation>
+ </message>
+ <message>
+ <source>Memo:</source>
+ <translation>Mémo :</translation>
+ </message>
+</context>
+<context>
+ <name>ShutdownWindow</name>
+ <message>
+ <source>Bitcoin Core is shutting down...</source>
+ <translation>Arrêt de Bitcoin Core...</translation>
+ </message>
+ <message>
+ <source>Do not shut down the computer until this window disappears.</source>
+ <translation>Ne pas fermer l'ordinateur jusqu'à la disparition de cette fenêtre.</translation>
+ </message>
+</context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Signatures - Sign / Verify a Message</source>
+ <translation>Signatures - Signer / Vérifier un message</translation>
+ </message>
+ <message>
+ <source>&amp;Sign Message</source>
+ <translation>&amp;Signer un message</translation>
+ </message>
+ <message>
+ <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source>
+ <translation>Vous pouvez signer des messages/accords avec vos adresses pour prouver que vous pouvez recevoir des bitcoins à ces dernières. Faites attention de ne rien signer de vague ou au hasard, car des attaques d'hameçonnage pourraient essayer de vous faire signer avec votre identité afin de l'usurper. Ne signez que des déclarations entièrement détaillées et avec lesquelles vous êtes d'accord.</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to sign the message with</source>
+ <translation>L'adresse Bitcoin avec laquelle signer le message</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Choisir une adresse précédemment utilisée</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Coller une adresse depuis le presse-papiers</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Enter the message you want to sign here</source>
+ <translation>Saisir ici le message que vous désirez signer</translation>
+ </message>
+ <message>
+ <source>Signature</source>
+ <translation>Signature</translation>
+ </message>
+ <message>
+ <source>Copy the current signature to the system clipboard</source>
+ <translation>Copier la signature actuelle dans le presse-papiers</translation>
+ </message>
+ <message>
+ <source>Sign the message to prove you own this Bitcoin address</source>
+ <translation>Signer le message pour prouver que vous détenez cette adresse Bitcoin</translation>
+ </message>
+ <message>
+ <source>Sign &amp;Message</source>
+ <translation>Signer le &amp;message</translation>
+ </message>
+ <message>
+ <source>Reset all sign message fields</source>
+ <translation>Réinitialiser tous les champs de signature de message</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>&amp;Tout nettoyer</translation>
+ </message>
+ <message>
+ <source>&amp;Verify Message</source>
+ <translation>&amp;Vérifier un message</translation>
+ </message>
+ <message>
+ <source>Enter the receiver's 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. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source>
+ <translation>Saisissez ci-dessous l'adresse de destinataire, le message (assurez-vous de copier exactement les retours à la ligne, les espaces, les tabulations, etc.) et la signature pour vérifier le message. Faites attention à ne pas déduire davantage de la signature que ce qui est contenu dans le message signé même, pour éviter d'être trompé par une attaque d'homme du milieu. Notez que ceci ne fait que prouver que le signataire reçoit l'adresse et ne peut pas prouver la provenance d'une transaction.</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address the message was signed with</source>
+ <translation>L'adresse Bitcoin avec laquelle le message a été signé</translation>
+ </message>
+ <message>
+ <source>Verify the message to ensure it was signed with the specified Bitcoin address</source>
+ <translation>Vérifier le message pour vous assurer qu'il a bien été signé par l'adresse Bitcoin spécifiée</translation>
+ </message>
+ <message>
+ <source>Verify &amp;Message</source>
+ <translation>Vérifier le &amp;message</translation>
+ </message>
+ <message>
+ <source>Reset all verify message fields</source>
+ <translation>Réinitialiser tous les champs de vérification de message</translation>
+ </message>
+ <message>
+ <source>Click "Sign Message" to generate signature</source>
+ <translation>Cliquez sur « Signer le message » pour générer la signature</translation>
+ </message>
+ <message>
+ <source>The entered address is invalid.</source>
+ <translation>L'adresse saisie est invalide.</translation>
+ </message>
+ <message>
+ <source>Please check the address and try again.</source>
+ <translation>Veuillez vérifier l'adresse et réessayer.</translation>
+ </message>
+ <message>
+ <source>The entered address does not refer to a key.</source>
+ <translation>L'adresse saisie ne fait pas référence à une clef.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock was cancelled.</source>
+ <translation>Le déverrouillage du portefeuille a été annulé.</translation>
+ </message>
+ <message>
+ <source>Private key for the entered address is not available.</source>
+ <translation>La clef privée n'est pas disponible pour l'adresse indiquée.</translation>
+ </message>
+ <message>
+ <source>Message signing failed.</source>
+ <translation>La signature du message a échoué.</translation>
+ </message>
+ <message>
+ <source>Message signed.</source>
+ <translation>Le message a été signé.</translation>
+ </message>
+ <message>
+ <source>The signature could not be decoded.</source>
+ <translation>La signature n'a pu être décodée.</translation>
+ </message>
+ <message>
+ <source>Please check the signature and try again.</source>
+ <translation>Veuillez vérifier la signature et réessayer.</translation>
+ </message>
+ <message>
+ <source>The signature did not match the message digest.</source>
+ <translation>La signature ne correspond pas à l'empreinte du message.</translation>
+ </message>
+ <message>
+ <source>Message verification failed.</source>
+ <translation>Échec de la vérification du message.</translation>
+ </message>
+ <message>
+ <source>Message verified.</source>
+ <translation>Message vérifié.</translation>
+ </message>
+</context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>The Bitcoin Core developers</source>
+ <translation>Les développeurs Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>[testnet]</source>
+ <translation>[testnet]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ <message>
+ <source>KB/s</source>
+ <translation>Ko/s</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>Ouvert jusqu'à %1</translation>
+ </message>
+ <message>
+ <source>conflicted</source>
+ <translation>en conflit</translation>
+ </message>
+ <message>
+ <source>%1/offline</source>
+ <translation>%1/hors ligne</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/non confirmée</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 confirmations</translation>
+ </message>
+ <message>
+ <source>Status</source>
+ <translation>État</translation>
+ </message>
+ <message numerus="yes">
+ <source>, broadcast through %n node(s)</source>
+ <translation><numerusform>, diffusée à travers %n nœud</numerusform><numerusform>, diffusée à travers %n nœuds</numerusform></translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Date</translation>
+ </message>
+ <message>
+ <source>Source</source>
+ <translation>Source</translation>
+ </message>
+ <message>
+ <source>Generated</source>
+ <translation>Généré</translation>
+ </message>
+ <message>
+ <source>From</source>
+ <translation>De</translation>
+ </message>
+ <message>
+ <source>To</source>
+ <translation>À</translation>
+ </message>
+ <message>
+ <source>own address</source>
+ <translation>votre propre adresse</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>juste-regarder</translation>
+ </message>
+ <message>
+ <source>label</source>
+ <translation>étiquette</translation>
+ </message>
+ <message>
+ <source>Credit</source>
+ <translation>Crédit</translation>
+ </message>
+ <message numerus="yes">
+ <source>matures in %n more block(s)</source>
+ <translation><numerusform>arrive à maturité dans %n bloc de plus</numerusform><numerusform>arrive à maturité dans %n blocs de plus</numerusform></translation>
+ </message>
+ <message>
+ <source>not accepted</source>
+ <translation>refusé</translation>
+ </message>
+ <message>
+ <source>Debit</source>
+ <translation>Débit</translation>
+ </message>
+ <message>
+ <source>Total debit</source>
+ <translation>Débit total</translation>
+ </message>
+ <message>
+ <source>Total credit</source>
+ <translation>Crédit total</translation>
+ </message>
+ <message>
+ <source>Transaction fee</source>
+ <translation>Frais de transaction</translation>
+ </message>
+ <message>
+ <source>Net amount</source>
+ <translation>Montant net</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Message</translation>
+ </message>
+ <message>
+ <source>Comment</source>
+ <translation>Commentaire</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>ID de la transaction</translation>
+ </message>
+ <message>
+ <source>Merchant</source>
+ <translation>Marchand</translation>
+ </message>
+ <message>
+ <source>Generated coins must mature %1 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.</source>
+ <translation>Les pièces générées doivent mûrir pendant %1 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 de blocs. S’il échoue a intégrer la chaîne, son état sera modifié en « non accepté » et il ne sera pas possible de le dépenser. Ceci peut arriver occasionnellement si un autre nœud génère un bloc à quelques secondes du votre.</translation>
+ </message>
+ <message>
+ <source>Debug information</source>
+ <translation>Informations de débogage</translation>
+ </message>
+ <message>
+ <source>Transaction</source>
+ <translation>Transaction</translation>
+ </message>
+ <message>
+ <source>Inputs</source>
+ <translation>Entrants</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Montant</translation>
+ </message>
+ <message>
+ <source>true</source>
+ <translation>vrai</translation>
+ </message>
+ <message>
+ <source>false</source>
+ <translation>faux</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, n’a pas encore été diffusée avec succès</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Ouvert pour %n bloc de plus</numerusform><numerusform>Ouvert pour %n blocs de plus</numerusform></translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>inconnu</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>Détails de la transaction</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>Ce panneau affiche une description détaillée de la transaction</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Date</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Type</translation>
+ </message>
+ <message>
+ <source>Immature (%1 confirmations, will be available after %2)</source>
+ <translation>Immature (%1 confirmations, sera disponible après %2)</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Ouvert pour %n bloc de plus</numerusform><numerusform>Ouvert pour %n blocs de plus</numerusform></translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>Ouvert jusqu'à %1</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>Confirmée (%1 confirmations)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>Ce bloc n’a été reçu par aucun autre nœud et ne sera probablement pas accepté !</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>Généré mais pas accepté</translation>
+ </message>
+ <message>
+ <source>Offline</source>
+ <translation>Hors ligne</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Étiquette</translation>
+ </message>
+ <message>
+ <source>Unconfirmed</source>
+ <translation>Non confirmé</translation>
+ </message>
+ <message>
+ <source>Confirming (%1 of %2 recommended confirmations)</source>
+ <translation>Confirmation (%1 sur %2 confirmations recommandées)</translation>
+ </message>
+ <message>
+ <source>Conflicted</source>
+ <translation>En conflit</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Reçue avec</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>Reçue de</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Envoyée à</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>Paiement à vous-même</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Miné</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>juste-regarder</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(n.d)</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>État de la transaction. Laissez le pointeur de la souris sur ce champ pour voir le nombre de confirmations.</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Date et heure de réception de la transaction.</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>Type de transaction.</translation>
+ </message>
+ <message>
+ <source>Whether or not a watch-only address is involved in this transaction.</source>
+ <translation>Une adresse juste-regarder est-elle impliquée dans cette transaction.</translation>
+ </message>
+ <message>
+ <source>User-defined intent/purpose of the transaction.</source>
+ <translation>Intention/but de la transaction défini par l'utilisateur.</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>Montant ajouté ou enlevé au solde.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>Toutes</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>Aujourd’hui</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>Cette semaine</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>Ce mois-ci</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>Le mois dernier</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>Cette année</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>Intervalle…</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Reçue avec</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Envoyée à</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>À vous-même</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Miné</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>Autres</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>Saisir une adresse ou une étiquette à rechercher</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>Montant min.</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Copier l’adresse</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Copier l’étiquette</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copier le montant</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Copier l'ID de la transaction</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>Modifier l’étiquette</translation>
+ </message>
+ <message>
+ <source>Show transaction details</source>
+ <translation>Afficher les détails de la transaction</translation>
+ </message>
+ <message>
+ <source>Export Transaction History</source>
+ <translation>Exporter l'historique des transactions</translation>
+ </message>
+ <message>
+ <source>Watch-only</source>
+ <translation>Juste-regarder :</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>L'exportation a échoué</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the transaction history to %1.</source>
+ <translation>Une erreur est survenue lors de l'enregistrement de l'historique des transactions vers %1.</translation>
+ </message>
+ <message>
+ <source>Exporting Successful</source>
+ <translation>Exportation réussie</translation>
+ </message>
+ <message>
+ <source>The transaction history was successfully saved to %1.</source>
+ <translation>L'historique des transactions a été sauvegardée avec succès vers %1.</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Valeurs séparées par des virgules (*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Confirmée</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Date</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Type</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Étiquette</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adresse</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>Intervalle :</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>à</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ <message>
+ <source>Unit to show amounts in. Click to select another unit.</source>
+ <translation>Unité d'affichage des montants. Cliquer pour choisir une autre unité.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletFrame</name>
+ <message>
+ <source>No wallet has been loaded.</source>
+ <translation>Aucun portefeuille de chargé.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Envoyer des pièces</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Exporter</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Exporter les données de l'onglet courant vers un fichier</translation>
+ </message>
+ <message>
+ <source>Backup Wallet</source>
+ <translation>Sauvegarder le portefeuille</translation>
+ </message>
+ <message>
+ <source>Wallet Data (*.dat)</source>
+ <translation>Données de portefeuille (*.dat)</translation>
+ </message>
+ <message>
+ <source>Backup Failed</source>
+ <translation>Échec de la sauvegarde</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the wallet data to %1.</source>
+ <translation>Une erreur est survenue lors de l'enregistrement des données de portefeuille vers %1.</translation>
+ </message>
+ <message>
+ <source>The wallet data was successfully saved to %1.</source>
+ <translation>Les données de portefeuille ont été enregistrées avec succès vers %1</translation>
+ </message>
+ <message>
+ <source>Backup Successful</source>
+ <translation>Sauvegarde réussie</translation>
+ </message>
+</context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>Options :</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>Spécifier le répertoire de données</translation>
+ </message>
+ <message>
+ <source>Connect to a node to retrieve peer addresses, and disconnect</source>
+ <translation>Se connecter à un nœud pour obtenir des adresses de pairs puis se déconnecter</translation>
+ </message>
+ <message>
+ <source>Specify your own public address</source>
+ <translation>Spécifier votre propre adresse publique</translation>
+ </message>
+ <message>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>Accepter les commandes de JSON-RPC et de la ligne de commande</translation>
+ </message>
+ <message>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>Fonctionner en arrière-plan en tant que démon et accepter les commandes</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>Utiliser le réseau de test</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
+ <translation>Accepter les connexions entrantes (par défaut : 1 si aucun -proxy ou -connect )</translation>
+ </message>
+ <message>
+ <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
+ <translation>Se lier à l'adresse donnée et toujours l'écouter. Utilisez la notation [host]:port pour l'IPv6</translation>
+ </message>
+ <message>
+ <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
+ <translation>Supprimer toutes les transactions du portefeuille et ne récupérer que ces parties de la chaîne de bloc avec -rescan au démarrage</translation>
+ </message>
+ <message>
+ <source>Distributed under the MIT software license, see the accompanying file COPYING or &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</source>
+ <translation>Distribué sous la licence MIT d'utilisation d'un logiciel. Consultez le fichier joint COPYING ou &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</translation>
+ </message>
+ <message>
+ <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
+ <translation>Exécuter la commande lorsqu'une transaction de portefeuille change (%s dans la commande est remplacée par TxID)</translation>
+ </message>
+ <message>
+ <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source>
+ <translation>Total maximal des frais à utiliser en une seule transaction de portefeuille. Le définir trop bas pourrait interrompre les grosses transactions (par défaut : %s)</translation>
+ </message>
+ <message>
+ <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, &gt;%u = target size in MiB to use for block files)</source>
+ <translation>Réduire les exigences de stockage en élaguant (supprimant) les anciens blocs. Ce mode désactive la prise en charge de portefeuilles et n'est pas compatible avec -txindex. Avertissement : configurer ce paramètre à sa valeur antérieure retéléchargera complètement la chaîne de blocs (par défaut : 0 = désactiver l'élagage des blocs, &gt;%u = taille cible en Mo à utiliser pour les fichiers de blocs).</translation>
+ </message>
+ <message>
+ <source>Set the number of script verification threads (%u to %d, 0 = auto, &lt;0 = leave that many cores free, default: %d)</source>
+ <translation>Définir le nombre d'exétrons de vérification des scripts (%u à %d, 0 = auto, &lt; 0 = laisser ce nombre de cœurs inutilisés, par défaut : %d)</translation>
+ </message>
+ <message>
+ <source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source>
+ <translation>Ceci est une pré-version de test - l'utiliser à vos risques et périls - ne pas l'utiliser pour miner ou pour des applications marchandes</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer. Bitcoin Core is probably already running.</source>
+ <translation>Impossible de se lier à %s sur cet ordinateur. Bitcoin Core fonctionne probablement déjà.</translation>
+ </message>
+ <message>
+ <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>AVERTISSEMENT : un nombre anormalement élevé de blocs a été généré, %d blocs reçus durant les %d dernières heures (%d attendus)</translation>
+ </message>
+ <message>
+ <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>AVERTISSEMENT : vérifiez votre connexion réseau, %d blocs reçus durant les %d dernières heures (%d attendus)</translation>
+ </message>
+ <message>
+ <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>Avertissement : -paytxfee est réglé sur un montant très élevé ! Il s'agit des frais de transaction que vous payerez si vous envoyez une transaction.</translation>
+ </message>
+ <message>
+ <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source>
+ <translation>Avertissement : le réseau ne semble pas totalement d'accord ! Quelques mineurs semblent éprouver des difficultés.</translation>
+ </message>
+ <message>
+ <source>Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.</source>
+ <translation>Avertissement : nous ne semblons pas être en accord complet avec nos pairs ! Vous pourriez avoir besoin d'effectuer une mise à niveau, ou d'autres nœuds du réseau pourraient avoir besoin d'effectuer une mise à niveau.</translation>
+ </message>
+ <message>
+ <source>Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
+ <translation>Avertissement : une erreur est survenue lors de la lecture de wallet.dat ! Toutes les clefs ont été lues correctement mais les données de transaction ou les entrées du carnet d'adresses sont peut-être incorrectes ou manquantes.</translation>
+ </message>
+ <message>
+ <source>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</source>
+ <translation>Avertissement : wallet.dat corrompu, données récupérées ! Le fichier wallet.dat original a été enregistré en tant que wallet.{timestamp}.bak dans %s ; si votre solde ou transactions sont incorrects vous devriez effectuer une restauration depuis une sauvegarde.</translation>
+ </message>
+ <message>
+ <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source>
+ <translation>Pairs de la liste blanche se connectant à partir du masque réseau ou de l'IP donné. Peut être spécifié plusieurs fois.</translation>
+ </message>
+ <message>
+ <source>(default: 1)</source>
+ <translation>(par défaut : 1)</translation>
+ </message>
+ <message>
+ <source>&lt;category&gt; can be:</source>
+ <translation>&lt;category&gt; peut être :</translation>
+ </message>
+ <message>
+ <source>Attempt to recover private keys from a corrupt wallet.dat</source>
+ <translation>Tenter de récupérer les clefs privées d'un wallet.dat corrompu</translation>
+ </message>
+ <message>
+ <source>Block creation options:</source>
+ <translation>Options de création de bloc :</translation>
+ </message>
+ <message>
+ <source>Connect only to the specified node(s)</source>
+ <translation>Ne se connecter qu'au(x) nœud(s) spécifié(s)</translation>
+ </message>
+ <message>
+ <source>Connection options:</source>
+ <translation>Options de connexion :</translation>
+ </message>
+ <message>
+ <source>Corrupted block database detected</source>
+ <translation>Base corrompue de données des blocs détectée</translation>
+ </message>
+ <message>
+ <source>Debugging/Testing options:</source>
+ <translation>Options de test/de débogage :</translation>
+ </message>
+ <message>
+ <source>Do not load the wallet and disable wallet RPC calls</source>
+ <translation>Ne pas charger le portefeuille et désactiver les appels RPC</translation>
+ </message>
+ <message>
+ <source>Do you want to rebuild the block database now?</source>
+ <translation>Voulez-vous reconstruire la base de données des blocs maintenant ?</translation>
+ </message>
+ <message>
+ <source>Error initializing block database</source>
+ <translation>Erreur lors de l'initialisation de la base de données des blocs</translation>
+ </message>
+ <message>
+ <source>Error initializing wallet database environment %s!</source>
+ <translation>Erreur lors de l'initialisation de l'environnement de la base de données du portefeuille %s !</translation>
+ </message>
+ <message>
+ <source>Error loading block database</source>
+ <translation>Erreur du chargement de la base de données des blocs</translation>
+ </message>
+ <message>
+ <source>Error opening block database</source>
+ <translation>Erreur lors de l'ouverture de la base de données des blocs</translation>
+ </message>
+ <message>
+ <source>Error: Disk space is low!</source>
+ <translation>Erreur : l'espace disque est faible !</translation>
+ </message>
+ <message>
+ <source>Failed to listen on any port. Use -listen=0 if you want this.</source>
+ <translation>Échec de l'écoute sur un port quelconque. Utilisez -listen=0 si vous voulez ceci.</translation>
+ </message>
+ <message>
+ <source>If &lt;category&gt; is not supplied, output all debugging information.</source>
+ <translation>Si &lt;category&gt; n'est pas indiqué, extraire toutes les données de débogage.</translation>
+ </message>
+ <message>
+ <source>Importing...</source>
+ <translation>Importation...</translation>
+ </message>
+ <message>
+ <source>Incorrect or no genesis block found. Wrong datadir for network?</source>
+ <translation>Bloc de genèse incorrect ou introuvable. Mauvais répertoire de données pour le réseau ?</translation>
+ </message>
+ <message>
+ <source>Invalid -onion address: '%s'</source>
+ <translation>Adresse -onion invalide : « %s »</translation>
+ </message>
+ <message>
+ <source>Not enough file descriptors available.</source>
+ <translation>Pas assez de descripteurs de fichiers proposés.</translation>
+ </message>
+ <message>
+ <source>Only connect to nodes in network &lt;net&gt; (ipv4, ipv6 or onion)</source>
+ <translation>Seulement se connecter aux nœuds du réseau &lt;net&gt; (IPv4, IPv6 ou oignon)</translation>
+ </message>
+ <message>
+ <source>Prune cannot be configured with a negative value.</source>
+ <translation>L'élagage ne peut pas être configuré avec une valeur négative.</translation>
+ </message>
+ <message>
+ <source>Prune mode is incompatible with -txindex.</source>
+ <translation>Le mode élagage n'est pas compatible avec -txindex.</translation>
+ </message>
+ <message>
+ <source>Set database cache size in megabytes (%d to %d, default: %d)</source>
+ <translation>Définir la taille du cache de la base de données en mégaoctets (%d to %d, default: %d)</translation>
+ </message>
+ <message>
+ <source>Set maximum block size in bytes (default: %d)</source>
+ <translation>Définir la taille minimale de bloc en octets (par défaut : %d)</translation>
+ </message>
+ <message>
+ <source>Specify wallet file (within data directory)</source>
+ <translation>Spécifiez le fichier de portefeuille (dans le répertoire de données)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: %u)</source>
+ <translation>Utiliser l'UPnP pour mapper le port d'écoute (par défaut : %u)</translation>
+ </message>
+ <message>
+ <source>Verifying blocks...</source>
+ <translation>Vérification des blocs en cours...</translation>
+ </message>
+ <message>
+ <source>Verifying wallet...</source>
+ <translation>Vérification du portefeuille en cours...</translation>
+ </message>
+ <message>
+ <source>Wallet %s resides outside data directory %s</source>
+ <translation>Le portefeuille %s réside en dehors du répertoire de données %s</translation>
+ </message>
+ <message>
+ <source>Wallet options:</source>
+ <translation>Options du portefeuille :</translation>
+ </message>
+ <message>
+ <source>Warning: This version is obsolete; upgrade required!</source>
+ <translation>Avertissement : cette version est obsolète. Une mise à niveau est exigée !</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to change -txindex</source>
+ <translation>Vous devez reconstruire la base de données en utilisant -reindex afin de modifier -txindex</translation>
+ </message>
+ <message>
+ <source>Imports blocks from external blk000??.dat file</source>
+ <translation>Importe des blocs depuis un fichier blk000??.dat externe</translation>
+ </message>
+ <message>
+ <source>Allow JSON-RPC connections from specified source. Valid for &lt;ip&gt; are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times</source>
+ <translation>Permettre les connexions JSON-RPC de sources spécifiques. Valide pour &lt;ip&gt; qui sont une IP simple (p. ex. 1.2.3.4), un réseau/masque réseau (p. ex. 1.2.3.4/255.255.255.0) ou un réseau/CIDR (p. ex. 1.2.3.4/24). Cette option peut être être spécifiée plusieurs fois</translation>
+ </message>
+ <message>
+ <source>An error occurred while setting up the RPC address %s port %u for listening: %s</source>
+ <translation>Une erreur est survenue lors de la mise en place de l'adresse %s port %u d'écoute RPC : %s</translation>
+ </message>
+ <message>
+ <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source>
+ <translation>Se lier à l'adresse donnée et aux pairs s'y connectant. Utiliser la notation [host]:port pour l'IPv6</translation>
+ </message>
+ <message>
+ <source>Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)</source>
+ <translation>Se lier à l'adresse donnée pour écouter des connexions JSON-RPC. Utiliser la notation [host]:port pour l'IPv6. Cette option peut être spécifiée plusieurs fois (par défaut : se lier à toutes les interfaces)</translation>
+ </message>
+ <message>
+ <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source>
+ <translation>Impossible d’obtenir un verrou sur le répertoire de données %s. Bitcoin Core fonctionne probablement déjà.</translation>
+ </message>
+ <message>
+ <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
+ <translation>Créer de nouveaux fichiers avec les permissions système par défaut, au lieu de umask 077 (effectif seulement avec la fonction du portefeuille désactivée)</translation>
+ </message>
+ <message>
+ <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source>
+ <translation>Découvrir ses propres adresses (par défaut : 1 en écoute et sans externalip ou -proxy)</translation>
+ </message>
+ <message>
+ <source>Error: Listening for incoming connections failed (listen returned error %s)</source>
+ <translation>Erreur : l'écoute des connexions entrantes a échoué (l'écoute a retourné l'erreur %s)</translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source>
+ <translation>Erreur : l'argument non pris en charge -socks a été trouvé. Il n'est plus possible de définir la version de SOCKS, seuls les serveurs mandataires SOCKS5 sont pris en charge.</translation>
+ </message>
+ <message>
+ <source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source>
+ <translation>Exécuter une commande lorsqu'une alerte pertinente est reçue ou si nous voyons une bifurcation vraiment étendue (%s dans la commande est remplacé par le message)</translation>
+ </message>
+ <message>
+ <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source>
+ <translation>Les frais (en BTC/Ko) inférieurs à ce seuil sont considérés comme étant nuls pour le relayage (par défaut : %s)</translation>
+ </message>
+ <message>
+ <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
+ <translation>Si paytxfee n'est pas défini, inclure suffisamment de frais afin que les transactions commencent la confirmation en moyenne avant n blocs (par défaut : %u)</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)</source>
+ <translation>Montant invalide pour -maxtxfee=&lt;amount&gt; : « %s » (doit être au moins les frais minrelay de %s pour prévenir le blocage des transactions)</translation>
+ </message>
+ <message>
+ <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source>
+ <translation>Quantité maximale de données dans les transactions du porteur de données que nous relayons et minons (par défaut : %u)</translation>
+ </message>
+ <message>
+ <source>Prune configured below the minimum of %d MB. Please use a higher number.</source>
+ <translation>L'élagage est configuré au-dessous du minimum de %d Mo. Veuillez utiliser un nombre plus élevé.</translation>
+ </message>
+ <message>
+ <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source>
+ <translation>Demander les adresses des pairs par recherche DNS si l'on manque d'adresses (par défaut : 1 sauf si -connect)</translation>
+ </message>
+ <message>
+ <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source>
+ <translation>Aléer les authentifiants pour chaque connexion mandataire. Ceci active l'isolement de flux de Tor (par défaut : %u) </translation>
+ </message>
+ <message>
+ <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
+ <translation>Définir la taille maximale en octets des transactions prioritaires/à frais modiques (par défaut : %d)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source>
+ <translation>Définir le nombre de fils de génération de pièces, si elle est activée (-1 = tous les cœurs, par défaut : %d)</translation>
+ </message>
+ <message>
+ <source>The transaction amount is too small to send after the fee has been deducted</source>
+ <translation>Le montant de la transaction est trop bas pour être envoyé une fois que les frais ont été déduits</translation>
+ </message>
+ <message>
+ <source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit &lt;https://www.openssl.org/&gt; and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source>
+ <translation>Ce produit comprend des logiciels développés par le projet OpenSSL pour être utilisés dans la boîte à outils OpenSSL &lt;https://www.openssl.org/&gt; et un logiciel cryptographique écrit par Eric Young, ainsi qu'un logiciel UPnP écrit par Thomas Bernard.</translation>
+ </message>
+ <message>
+ <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an 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)
+The username and password MUST NOT be the same.
+If the file does not exist, create it with owner-readable-only file permissions.
+It is also recommended to set alertnotify so you are notified of problems;
+for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
+</source>
+ <translation>Pour utiliser bitcoind, ou l'option -server de bitcoin-qt, vous devez définir un mot de passe rpc dans le fichier de configuration :
+%s
+Il est recommandé d'utiliser le mot de passe aléatoire suivant :
+rpcuser=bitcoinrpc
+rpcpassword=%s
+(vous n'avez pas à mémoriser ce mot de passe)
+Le nom d'utilisateur et le mot de passe NE DOIVENT PAS être identiques.
+Si le fichier n'existe pas, créez-le avec la permission lecture-seule-par-le-propriétaire.
+Il est aussi recommandé de définir alertnotify afin que les problèmes vous soient signalés ;
+par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com
+</translation>
+ </message>
+ <message>
+ <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source>
+ <translation>Avertissement :-maxtxfee est défini très haut ! Des frais aussi élevés pourraient être payés sur une seule transaction.</translation>
+ </message>
+ <message>
+ <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source>
+ <translation>Avertissement : veuillez vérifier que l'heure et la date de votre ordinateur sont correctes ! Si votre horloge n'est pas à l'heure, Bitcoin Core ne fonctionnera pas correctement.</translation>
+ </message>
+ <message>
+ <source>Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway</source>
+ <translation>Les pairs de la liste blanche ne peuvent pas être bannis DoS et leurs transactions sont toujours relayées, même si elles sont déjà dans le mempool, utile p. ex. pour une passerelle</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source>
+ <translation>Vous devez reconstruire la base de données en utilisant -reindex afin de revenir au mode sans élagage. Ceci retéléchargera complètement la chaîne de blocs.</translation>
+ </message>
+ <message>
+ <source>(default: %u)</source>
+ <translation>(par défaut : %u)</translation>
+ </message>
+ <message>
+ <source>Accept public REST requests (default: %u)</source>
+ <translation>Accepter les demandes REST publiques (par défaut : %u)</translation>
+ </message>
+ <message>
+ <source>Activating best chain...</source>
+ <translation>Activation de la meilleure chaîne...</translation>
+ </message>
+ <message>
+ <source>Can't run with a wallet in prune mode.</source>
+ <translation>L'exécution est impossible quand le portefeuille est en mode élagage.</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -whitebind address: '%s'</source>
+ <translation>Impossible de résoudre l'adresse -whitebind : « %s »</translation>
+ </message>
+ <message>
+ <source>Choose data directory on startup (default: 0)</source>
+ <translation>Choisir un répertoire de données au démarrage (par défaut : 0)</translation>
+ </message>
+ <message>
+ <source>Connect through SOCKS5 proxy</source>
+ <translation>Se connecter par un mandataire SOCKS5</translation>
+ </message>
+ <message>
+ <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source>
+ <translation>Copyright © 2009-%i Les développeurs de Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Could not parse -rpcbind value %s as network address</source>
+ <translation>Impossible d'analyser la valeur -rpcbind %s comme adresse réseau</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source>
+ <translation>Erreur lors du chargement de wallet.dat : le portefeuille exige une version plus récente de Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Error reading from database, shutting down.</source>
+ <translation>Erreur de lecture de la base de données, fermeture en cours.</translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -tor found, use -onion.</source>
+ <translation>Erreur : argument non pris en charge -tor trouvé, utiliser -onion.</translation>
+ </message>
+ <message>
+ <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source>
+ <translation>Les frais (en BTC/ko) à ajouter aux transactions que vous envoyez (par défaut : %s)</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Informations</translation>
+ </message>
+ <message>
+ <source>Initialization sanity check failed. Bitcoin Core is shutting down.</source>
+ <translation>L'initialisation du test de cohérence a échoué. Bitcoin est en cours de fermeture. </translation>
+ </message>
+ <message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Montant invalide pour -maxtxfee=&lt;amount&gt; : « %s »</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -minrelaytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Montant invalide pour -minrelayfee=&lt;montant&gt; : « %s »</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -mintxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Montant invalide pour -mintxfee=&lt;montant&gt; : « %s »</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s' (must be at least %s)</source>
+ <translation>Montant invalide pour -paytxfee=&lt;montant&gt; : « %s » (doit être au moins %s)</translation>
+ </message>
+ <message>
+ <source>Invalid netmask specified in -whitelist: '%s'</source>
+ <translation>Masque réseau invalide spécifié dans -whitelist : « %s »</translation>
+ </message>
+ <message>
+ <source>Keep at most &lt;n&gt; unconnectable transactions in memory (default: %u)</source>
+ <translation>Garder au plus &lt;n&gt; transactions non connectables en mémoire (par défaut : %u)</translation>
+ </message>
+ <message>
+ <source>Need to specify a port with -whitebind: '%s'</source>
+ <translation>Un port doit être spécifié avec -whitebind : « %s »</translation>
+ </message>
+ <message>
+ <source>Node relay options:</source>
+ <translation>Options de relais du nœud :</translation>
+ </message>
+ <message>
+ <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source>
+ <translation>Options RPC SSL : (voir le wiki Bitcoin pour les instructions de configuration de SSL)</translation>
+ </message>
+ <message>
+ <source>RPC server options:</source>
+ <translation>Options du serveur RPC :</translation>
+ </message>
+ <message>
+ <source>RPC support for HTTP persistent connections (default: %d)</source>
+ <translation>Prise en charge de RPC pour les connexions persistantes HTTP (par défaut : %d)</translation>
+ </message>
+ <message>
+ <source>Rebuild block chain index from current blk000??.dat files on startup</source>
+ <translation>Reconstruire au démarrage l'index de la chaîne de blocs à partir des fichiers blk000??.dat actuels</translation>
+ </message>
+ <message>
+ <source>Receive and display P2P network alerts (default: %u)</source>
+ <translation>Recevoir et afficher les alertes du réseau poste à poste (%u par défaut)</translation>
+ </message>
+ <message>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>Envoyer les informations de débogage/trace à la console au lieu du fichier debug.log</translation>
+ </message>
+ <message>
+ <source>Send transactions as zero-fee transactions if possible (default: %u)</source>
+ <translation>Envoyer si possible les transactions comme étant sans frais (par défaut : %u)</translation>
+ </message>
+ <message>
+ <source>Set SSL root certificates for payment request (default: -system-)</source>
+ <translation>Définir les certificats racine SSL pour les demandes de paiement (par défaut : -système-)</translation>
+ </message>
+ <message>
+ <source>Set language, for example "de_DE" (default: system locale)</source>
+ <translation>Définir la langue, par exemple « fr_CA » (par défaut : la langue du système)</translation>
+ </message>
+ <message>
+ <source>Show all debugging options (usage: --help -help-debug)</source>
+ <translation>Montrer toutes les options de débogage (utilisation : --help --help-debug)</translation>
+ </message>
+ <message>
+ <source>Show splash screen on startup (default: 1)</source>
+ <translation>Afficher la page de garde au démarrage (par défaut : 1)</translation>
+ </message>
+ <message>
+ <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source>
+ <translation>Réduire le fichier debug.log lors du démarrage du client (par défaut : 1 lorsque -debug n'est pas présent)</translation>
+ </message>
+ <message>
+ <source>Signing transaction failed</source>
+ <translation>La signature de la transaction a échoué</translation>
+ </message>
+ <message>
+ <source>Start minimized</source>
+ <translation>Démarrer minimisé</translation>
+ </message>
+ <message>
+ <source>The transaction amount is too small to pay the fee</source>
+ <translation>Le montant de la transaction est trop bas pour que les frais soient payés</translation>
+ </message>
+ <message>
+ <source>This is experimental software.</source>
+ <translation>Ceci est un logiciel expérimental.</translation>
+ </message>
+ <message>
+ <source>Transaction amount too small</source>
+ <translation>Montant de la transaction trop bas</translation>
+ </message>
+ <message>
+ <source>Transaction amounts must be positive</source>
+ <translation>Les montants de transaction doivent être positifs</translation>
+ </message>
+ <message>
+ <source>Transaction too large for fee policy</source>
+ <translation>La transaction est trop grosse pour la politique de frais</translation>
+ </message>
+ <message>
+ <source>Transaction too large</source>
+ <translation>Transaction trop volumineuse</translation>
+ </message>
+ <message>
+ <source>UI Options:</source>
+ <translation>Options de l'IU :</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer (bind returned error %s)</source>
+ <translation>Impossible de se lier à %s sur cet ordinateur (bind a retourné l'erreur %s)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: 1 when listening)</source>
+ <translation>Utiliser l'UPnP pour mapper le port d'écoute (par défaut : 1 lors de l'écoute)</translation>
+ </message>
+ <message>
+ <source>Username for JSON-RPC connections</source>
+ <translation>Nom d'utilisateur pour les connexions JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Wallet needed to be rewritten: restart Bitcoin Core to complete</source>
+ <translation>Le portefeuille avait besoin d'être réécrit : veuillez redémarrer Bitcoin Core pour terminer</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Avertissement</translation>
+ </message>
+ <message>
+ <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source>
+ <translation>Avertissement : l'argument -benchmark non pris en charge a été ignoré, utiliser -debug=bench.</translation>
+ </message>
+ <message>
+ <source>Warning: Unsupported argument -debugnet ignored, use -debug=net.</source>
+ <translation>Avertissement : l'argument -debugnet non pris en charge a été ignoré, utiliser -debug=net.</translation>
+ </message>
+ <message>
+ <source>Zapping all transactions from wallet...</source>
+ <translation>Supprimer toutes les transactions du portefeuille...</translation>
+ </message>
+ <message>
+ <source>on startup</source>
+ <translation>au démarrage</translation>
+ </message>
+ <message>
+ <source>wallet.dat corrupt, salvage failed</source>
+ <translation>wallet.dat corrompu, la récupération a échoué</translation>
+ </message>
+ <message>
+ <source>Password for JSON-RPC connections</source>
+ <translation>Mot de passe pour les connexions JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
+ <translation>Exécuter la commande lorsque le meilleur bloc change (%s dans cmd est remplacé par le hachage du bloc)</translation>
+ </message>
+ <message>
+ <source>Upgrade wallet to latest format</source>
+ <translation>Mettre à niveau le portefeuille vers le format le plus récent</translation>
+ </message>
+ <message>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>Réanalyser la chaîne de blocs pour les transactions de portefeuille manquantes</translation>
+ </message>
+ <message>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>Utiliser OpenSSL (https) pour les connexions JSON-RPC</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>Ce message d'aide</translation>
+ </message>
+ <message>
+ <source>Allow DNS lookups for -addnode, -seednode and -connect</source>
+ <translation>Autoriser les recherches DNS pour -addnode, -seednode et -connect</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>Chargement des adresses…</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>Erreur lors du chargement de wallet.dat : portefeuille corrompu</translation>
+ </message>
+ <message>
+ <source>(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source>
+ <translation>(1 = conserver les métadonnées de transmission, par ex. les informations du propriétaire du compte et de la demande de paiement, 2 = abandonner les métadonnées de transmission)</translation>
+ </message>
+ <message>
+ <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
+ <translation>Degré de profondeur de la vérification des blocs -checkblocks (0-4, par défaut : %u)</translation>
+ </message>
+ <message>
+ <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
+ <translation>Maintenir un index complet des transactions, utilisé par l'appel RPC getrawtransaction (obtenir la transaction brute) (par défaut : %u)</translation>
+ </message>
+ <message>
+ <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source>
+ <translation>Délai en secondes de refus de reconnexion pour les pairs présentant un mauvais comportement (par défaut : %u)</translation>
+ </message>
+ <message>
+ <source>Output debugging information (default: %u, supplying &lt;category&gt; is optional)</source>
+ <translation>Extraire les informations de débogage (par défaut : %u, fournir &lt;category&gt; est optionnel)</translation>
+ </message>
+ <message>
+ <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source>
+ <translation>Utiliser un serveur mandataire SOCKS5 séparé pour atteindre les pairs par les services cachés de Tor (par défaut : %s)</translation>
+ </message>
+ <message>
+ <source>(default: %s)</source>
+ <translation>(par défaut : %s)</translation>
+ </message>
+ <message>
+ <source>Acceptable ciphers (default: %s)</source>
+ <translation>Chiffrements acceptables (par défaut : %s)</translation>
+ </message>
+ <message>
+ <source>Always query for peer addresses via DNS lookup (default: %u)</source>
+ <translation>Toujours demander les adresses des pairs par recherche DNS (par défaut : %u)</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>Erreur lors du chargement de wallet.dat</translation>
+ </message>
+ <message>
+ <source>Generate coins (default: %u)</source>
+ <translation>Générer des pièces (défaut : %u)</translation>
+ </message>
+ <message>
+ <source>How many blocks to check at startup (default: %u, 0 = all)</source>
+ <translation>Nombre de blocs à vérifier au démarrage (par défaut : %u, 0 = tous)</translation>
+ </message>
+ <message>
+ <source>Include IP addresses in debug output (default: %u)</source>
+ <translation>Inclure les adresses IP à la sortie de débogage (par défaut : %u)</translation>
+ </message>
+ <message>
+ <source>Invalid -proxy address: '%s'</source>
+ <translation>Adresse -proxy invalide : « %s »</translation>
+ </message>
+ <message>
+ <source>Listen for JSON-RPC connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>Écouter les connexions JSON-RPC sur &lt;port&gt; (par défaut : %u ou tesnet : %u)</translation>
+ </message>
+ <message>
+ <source>Listen for connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>Écouter les connexions sur &lt;port&gt; (par défaut : %u ou tesnet : %u)</translation>
+ </message>
+ <message>
+ <source>Maintain at most &lt;n&gt; connections to peers (default: %u)</source>
+ <translation>Garder au plus &lt;n&gt; connexions avec les pairs (par défaut : %u)</translation>
+ </message>
+ <message>
+ <source>Make the wallet broadcast transactions</source>
+ <translation>Obliger le portefeuille à diffuser les transactions</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection receive buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>Tampon maximal de réception par connexion, &lt;n&gt;*1000 octets (par défaut : %u)</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection send buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>Tampon maximal d'envoi par connexion », &lt;n&gt;*1000 octets (par défaut : %u)</translation>
+ </message>
+ <message>
+ <source>Prepend debug output with timestamp (default: %u)</source>
+ <translation>Ajouter l'horodatage au début de la sortie de débogage (par défaut : %u)</translation>
+ </message>
+ <message>
+ <source>Relay and mine data carrier transactions (default: %u)</source>
+ <translation>Relayer et miner les transactions du porteur de données (par défaut : %u)</translation>
+ </message>
+ <message>
+ <source>Relay non-P2SH multisig (default: %u)</source>
+ <translation>Relayer les multisignatures non-P2SH (par défaut : %u)</translation>
+ </message>
+ <message>
+ <source>Set key pool size to &lt;n&gt; (default: %u)</source>
+ <translation>Définir la taille de la réserve de clefs à &lt;n&gt; (par défaut : %u)</translation>
+ </message>
+ <message>
+ <source>Set minimum block size in bytes (default: %u)</source>
+ <translation>Définir la taille de bloc minimale en octets (par défaut : %u)</translation>
+ </message>
+ <message>
+ <source>Specify configuration file (default: %s)</source>
+ <translation>Spécifier le fichier de configuration (par défaut : %s)</translation>
+ </message>
+ <message>
+ <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source>
+ <translation>Spécifier le délai d'expiration de la connexion en millisecondes (minimum : 1, par défaut : %d)</translation>
+ </message>
+ <message>
+ <source>Specify pid file (default: %s)</source>
+ <translation>Spécifier le fichier pid (par défaut : %s)</translation>
+ </message>
+ <message>
+ <source>Spend unconfirmed change when sending transactions (default: %u)</source>
+ <translation>Dépenser la monnaie non confirmée lors de l'envoi de transactions (par défaut : %u)</translation>
+ </message>
+ <message>
+ <source>Threshold for disconnecting misbehaving peers (default: %u)</source>
+ <translation>Seuil de déconnexion des pairs présentant un mauvais comportement (par défaut : %u)</translation>
+ </message>
+ <message>
+ <source>Unknown network specified in -onlynet: '%s'</source>
+ <translation>Réseau inconnu spécifié sur -onlynet : « %s »</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -bind address: '%s'</source>
+ <translation>Impossible de résoudre l'adresse -bind : « %s »</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -externalip address: '%s'</source>
+ <translation>Impossible de résoudre l'adresse -externalip : « %s »</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Montant invalide pour -paytxfee=&lt;montant&gt; : « %s »</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>Fonds insuffisants</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>Chargement de l’index des blocs…</translation>
+ </message>
+ <message>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>Ajouter un nœud auquel se connecter et tenter de garder la connexion ouverte</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>Chargement du portefeuille…</translation>
+ </message>
+ <message>
+ <source>Cannot downgrade wallet</source>
+ <translation>Impossible de revenir à une version inférieure du portefeuille</translation>
+ </message>
+ <message>
+ <source>Cannot write default address</source>
+ <translation>Impossible d'écrire l'adresse par défaut</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>Nouvelle analyse…</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>Chargement terminé</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Erreur</translation>
+ </message>
+</context>
+</TS> \ 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 0000000000..f4fe7d6597
--- /dev/null
+++ b/src/qt/locale/bitcoin_fr_CA.ts
@@ -0,0 +1,206 @@
+<TS language="fr_CA" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Create a new address</source>
+ <translation>Créer une nouvelle adresse</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Copier l'adresse surligné a votre presse-papier</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;Supprimer</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Fichier séparé par une virgule (*.csv)</translation>
+ </message>
+ </context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Record</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Addresse</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(pas de record)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Entrer Mot de Passe</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Nouveau Mot de passe</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Répéter Mot de Passe</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>Encrypter Porte-Feuille</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>Cette opération nécessite le mot de passe de votre porte-feuille pour débarrer le porte-feuille.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Débarrer Porte-Feuille</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>Cette opération nécessite le mot de passe de votre porte-feuille pour le décrypter.</translation>
+ </message>
+ </context>
+<context>
+ <name>BitcoinGUI</name>
+ </context>
+<context>
+ <name>ClientModel</name>
+ </context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>(no label)</source>
+ <translation>(pas de record)</translation>
+ </message>
+ </context>
+<context>
+ <name>EditAddressDialog</name>
+ </context>
+<context>
+ <name>FreespaceChecker</name>
+ </context>
+<context>
+ <name>HelpMessageDialog</name>
+ </context>
+<context>
+ <name>Intro</name>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ </context>
+<context>
+ <name>OptionsDialog</name>
+ </context>
+<context>
+ <name>OverviewPage</name>
+ </context>
+<context>
+ <name>PaymentServer</name>
+ </context>
+<context>
+ <name>PeerTableModel</name>
+ </context>
+<context>
+ <name>QObject</name>
+ </context>
+<context>
+ <name>QRImageWidget</name>
+ </context>
+<context>
+ <name>RPCConsole</name>
+ </context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ </context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>Address</source>
+ <translation>Addresse</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Record</translation>
+ </message>
+ </context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Record</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(pas de record)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>(no label)</source>
+ <translation>(pas de record)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsEntry</name>
+ </context>
+<context>
+ <name>ShutdownWindow</name>
+ </context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ </context>
+<context>
+ <name>SplashScreen</name>
+ </context>
+<context>
+ <name>TrafficGraphWidget</name>
+ </context>
+<context>
+ <name>TransactionDesc</name>
+ </context>
+<context>
+ <name>TransactionDescDialog</name>
+ </context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Record</translation>
+ </message>
+ </context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Fichier séparé par une virgule (*.csv)</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Record</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Addresse</translation>
+ </message>
+ </context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ </context>
+<context>
+ <name>WalletFrame</name>
+ </context>
+<context>
+ <name>WalletModel</name>
+ </context>
+<context>
+ <name>WalletView</name>
+ </context>
+<context>
+ <name>bitcoin-core</name>
+ </context>
+</TS> \ No newline at end of file
diff --git a/src/qt/locale/bitcoin_gl.ts b/src/qt/locale/bitcoin_gl.ts
new file mode 100644
index 0000000000..709b17e2f7
--- /dev/null
+++ b/src/qt/locale/bitcoin_gl.ts
@@ -0,0 +1,2226 @@
+<TS language="gl" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Create a new address</source>
+ <translation>Crear unha nova dirección</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>&amp;Novo</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Copiar a dirección seleccionada ao cartafol</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>&amp;Copiar</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>&amp;Pechar</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>&amp;Copiar Dirección</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>Borrar a dirección actualmente seleccionada da listaxe</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Exportar os datos da pestaña actual a un arquivo.</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Exportar</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;Borrar</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>Escolle a dirección á que enviar moedas</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>Escolle a dirección da que recibir moedas</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>&amp;Escoller</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>Direccións para enviar</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>Direccións para recibir</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>Estas son as túas direccións Bitcoin para enviar pagos. Revisa sempre a cantidade e a dirección receptora antes de enviar moedas.</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>Estas son as túas direccións Bitcoin para recibir pagos. Recoméndase empregar unha nova dirección de recepción por cada transacción.</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>Copiar &amp;Etiqueta</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>&amp;Modificar</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>Exportar Lista de Direccións</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Arquivo separado por comas (*.csv)</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Exportación falida</translation>
+ </message>
+ </context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Etiqueta</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Dirección</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(sen etiqueta)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Passphrase Dialog</source>
+ <translation>Diálogo de Contrasinal</translation>
+ </message>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Introduce contrasinal</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Novo contrasinal</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Repite novo contrasinal</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>Encriptar moedeiro</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>Esta operación precisa o contrasinal do teu moedeiro para desbloquear o moedeiro.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Desbloquear moedeiro</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>Esta operación precisa o contrasinal do teu moedeiro para desencriptar o moedeiro.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>Desencriptar moedeiro</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>Cambiar contrasinal</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>Confirmar encriptación de moedeiro</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>Precaución: Se encriptas o teu moedeiro e perdes o teu contrasinal, ti &lt;b&gt;PERDERÁS TÓDOLOS TEUS BITCOINS&lt;/b&gt;!</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>Estás seguro de que desexas encriptar o teu moedeiro?</translation>
+ </message>
+ <message>
+ <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
+ <translation>IMPORTANTE: Calquera copia de seguridade previa que fixeses do teu arquivo de moedeiro debería ser substituída polo recén xerado arquivo encriptado de moedeiro. Por razóns de seguridade, as copias de seguridade previas de un arquivo de moedeiro desencriptado tornaránse inútiles no momento no que comeces a emprega-lo novo, encriptado, moedeiro.</translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>Precaución: A tecla de Bloqueo de Maiúsculas está activada!</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>Moedeiro encriptado</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>Encriptación de moedeiro fallida</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>A encriptación do moedeiro fallou por mor dun erro interno. O teu moedeiro non foi encriptado.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>Os contrasinais suministrados non coinciden.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>Desbloqueo de moedeiro fallido</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>O contrasinal introducido para a desencriptación do moedeiro foi incorrecto.</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>Desencriptación de moedeiro fallida</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>Cambiouse con éxito o contrasinal do moedeiro.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>&amp;Asinar mensaxe...</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>Sincronizando coa rede...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;Vista xeral</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>Amosar vista xeral do moedeiro</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Transacciones</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>Navegar historial de transaccións</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>&amp;Saír</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>Saír da aplicación</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>Acerca de &amp;Qt</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>Amosar información acerca de Qt</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;Opcións...</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>&amp;Encriptar Moedeiro...</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>Copia de &amp;Seguridade do Moedeiro...</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>&amp;Cambiar contrasinal...</translation>
+ </message>
+ <message>
+ <source>Importing blocks from disk...</source>
+ <translation>Importando bloques de disco...</translation>
+ </message>
+ <message>
+ <source>Reindexing blocks on disk...</source>
+ <translation>Reindexando bloques no disco...</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>Enviar moedas a unha dirección Bitcoin</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>Facer copia de seguridade do moedeiro noutra localización</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Cambiar o contrasinal empregado para a encriptación do moedeiro</translation>
+ </message>
+ <message>
+ <source>&amp;Debug window</source>
+ <translation>Ventana de &amp;Depuración</translation>
+ </message>
+ <message>
+ <source>Open debugging and diagnostic console</source>
+ <translation>Abrir consola de depuración e diagnóstico</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>&amp;Verificar mensaxe...</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>Moedeiro</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>&amp;Enviar</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>&amp;Recibir</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>&amp;Amosar/Agachar</translation>
+ </message>
+ <message>
+ <source>Show or hide the main Window</source>
+ <translation>Amosar ou agachar a ventana principal</translation>
+ </message>
+ <message>
+ <source>Encrypt the private keys that belong to your wallet</source>
+ <translation>Encriptar as claves privadas que pertencen ao teu moedeiro</translation>
+ </message>
+ <message>
+ <source>Sign messages with your Bitcoin addresses to prove you own them</source>
+ <translation>Asina mensaxes coas túas direccións Bitcoin para probar que te pertencen</translation>
+ </message>
+ <message>
+ <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source>
+ <translation>Verificar mensaxes para asegurar que foron asinados con direccións Bitcoin dadas.</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;Arquivo</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>Axus&amp;tes</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>A&amp;xuda</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>Barra de ferramentas</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Core de Bitcoin</translation>
+ </message>
+ <message>
+ <source>Request payments (generates QR codes and bitcoin: URIs)</source>
+ <translation>Solicitar pagos (xenera códigos QR e bitcoin: URIs)</translation>
+ </message>
+ <message>
+ <source>&amp;About Bitcoin Core</source>
+ <translation>&amp;Sobre Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Show the list of used sending addresses and labels</source>
+ <translation>Amosar a listaxe de direccións e etiquetas para enviar empregadas</translation>
+ </message>
+ <message>
+ <source>Show the list of used receiving addresses and labels</source>
+ <translation>Amosar a listaxe de etiquetas e direccións para recibir empregadas</translation>
+ </message>
+ <message>
+ <source>Open a bitcoin: URI or payment request</source>
+ <translation>Abrir un bitcoin: URI ou solicitude de pago</translation>
+ </message>
+ <message>
+ <source>No block source available...</source>
+ <translation>Non hai orixe de bloques dispoñible...</translation>
+ </message>
+ <message>
+ <source>%1 behind</source>
+ <translation>%1 detrás</translation>
+ </message>
+ <message>
+ <source>Last received block was generated %1 ago.</source>
+ <translation>O último bloque recibido foi xerado fai %1.</translation>
+ </message>
+ <message>
+ <source>Transactions after this will not yet be visible.</source>
+ <translation>As transaccións despois desta non serán todavía visibles.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Erro</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Precaución</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Información</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>Actualizado</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>Poñendo ao día...</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>Transacción enviada</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>Transacción entrante</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>O moedeiro está &lt;b&gt;encriptado&lt;/b&gt; e actualmente &lt;b&gt;desbloqueado&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>O moedeiro está &lt;b&gt;encriptado&lt;/b&gt; e actualmente &lt;b&gt;bloqueado&lt;/b&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <source>Network Alert</source>
+ <translation>Alerta de Rede</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Quantity:</source>
+ <translation>Cantidade:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Bytes:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Importe:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Prioridade:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Pago:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Cambiar:</translation>
+ </message>
+ <message>
+ <source>(un)select all</source>
+ <translation>(des)selecciona todo</translation>
+ </message>
+ <message>
+ <source>Tree mode</source>
+ <translation>Modo árbore</translation>
+ </message>
+ <message>
+ <source>List mode</source>
+ <translation>Modo lista</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Cantidade</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Confirmations</source>
+ <translation>Confirmacións</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Confirmado</translation>
+ </message>
+ <message>
+ <source>Priority</source>
+ <translation>Prioridade</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Copiar dirección</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Copiar etiqueta</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copiar cantidade</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Copiar ID de transacción</translation>
+ </message>
+ <message>
+ <source>Lock unspent</source>
+ <translation>Bloquear o aforrado</translation>
+ </message>
+ <message>
+ <source>Unlock unspent</source>
+ <translation>Desbloquear o aforrado</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Copiar cantidade</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Copiar pago</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Copiar despóis do pago</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Copiar bytes</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Copiar prioridade</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Copiar cambio</translation>
+ </message>
+ <message>
+ <source>highest</source>
+ <translation>O máis alto</translation>
+ </message>
+ <message>
+ <source>higher</source>
+ <translation>Máis alto que</translation>
+ </message>
+ <message>
+ <source>high</source>
+ <translation>alto</translation>
+ </message>
+ <message>
+ <source>medium-high</source>
+ <translation>medio-alto</translation>
+ </message>
+ <message>
+ <source>low-medium</source>
+ <translation>medio-baixo</translation>
+ </message>
+ <message>
+ <source>low</source>
+ <translation>baixo</translation>
+ </message>
+ <message>
+ <source>lower</source>
+ <translation>máis baixo que</translation>
+ </message>
+ <message>
+ <source>lowest</source>
+ <translation>o máis baixo</translation>
+ </message>
+ <message>
+ <source>(%1 locked)</source>
+ <translation>(%1 bloqueado)</translation>
+ </message>
+ <message>
+ <source>yes</source>
+ <translation>Si</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>non</translation>
+ </message>
+ <message>
+ <source>Transactions with higher priority are more likely to get included into a block.</source>
+ <translation>As transacción con maior prioridade teñen máis posibilidades de ser incluidas nun bloque</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(sen etiqueta)</translation>
+ </message>
+ <message>
+ <source>(change)</source>
+ <translation>(cambio)</translation>
+ </message>
+</context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>Modificar Dirección</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>&amp;Etiqueta</translation>
+ </message>
+ <message>
+ <source>The label associated with this address list entry</source>
+ <translation>A etiqueta asociada con esta entrada da listaxe de direccións</translation>
+ </message>
+ <message>
+ <source>The address associated with this address list entry. This can only be modified for sending addresses.</source>
+ <translation>A dirección asociada con esta entrada na listaxe de dirección. Esta so pode ser modificada por direccións para enviar.</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;Dirección</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>Nova dirección para recibir</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>Nova dirección para enviar</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>Modificar dirección para recibir</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>Modificar dirección para enviar</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>A dirección introducida "%1" xa está no libro de direccións.</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is not a valid Bitcoin address.</source>
+ <translation>A dirección introducida '%1' non é unha dirección Bitcoin válida.</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>Non se puido desbloquear o moedeiro.</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>A xeración de nova clave fallou.</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ <message>
+ <source>A new data directory will be created.</source>
+ <translation>Crearáse un novo directorio de datos.</translation>
+ </message>
+ <message>
+ <source>name</source>
+ <translation>nome</translation>
+ </message>
+ <message>
+ <source>Directory already exists. Add %1 if you intend to create a new directory here.</source>
+ <translation>O directorio xa existe. Engade %1 se queres crear un novo directorio aquí.</translation>
+ </message>
+ <message>
+ <source>Path already exists, and is not a directory.</source>
+ <translation>A ruta xa existe e non é un directorio.</translation>
+ </message>
+ <message>
+ <source>Cannot create data directory here.</source>
+ <translation>Non se pode crear directorio de datos aquí</translation>
+ </message>
+</context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Core de Bitcoin</translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>versión</translation>
+ </message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>Sobre Bitcoin core</translation>
+ </message>
+ <message>
+ <source>Command-line options</source>
+ <translation>Opcións da liña de comandos</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>Emprego:</translation>
+ </message>
+ <message>
+ <source>command-line options</source>
+ <translation>opcións da liña de comandos</translation>
+ </message>
+</context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Welcome</source>
+ <translation>Benvido</translation>
+ </message>
+ <message>
+ <source>Use the default data directory</source>
+ <translation>Empregar o directorio de datos por defecto</translation>
+ </message>
+ <message>
+ <source>Use a custom data directory:</source>
+ <translation>Empregar un directorio de datos personalizado</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Core de Bitcoin</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Erro</translation>
+ </message>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ <message>
+ <source>Open URI</source>
+ <translation>Abrir URI</translation>
+ </message>
+ <message>
+ <source>Open payment request from URI or file</source>
+ <translation>Abrir solicitude de pago dende URI ou ficheiro</translation>
+ </message>
+ <message>
+ <source>URI:</source>
+ <translation>URI:</translation>
+ </message>
+ <message>
+ <source>Select payment request file</source>
+ <translation>Seleccionar ficheiro de solicitude de pago</translation>
+ </message>
+ <message>
+ <source>Select payment request file to open</source>
+ <translation>Seleccione ficheiro de solicitude de pago para abrir</translation>
+ </message>
+</context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>Opcións</translation>
+ </message>
+ <message>
+ <source>&amp;Main</source>
+ <translation>&amp;Principal</translation>
+ </message>
+ <message>
+ <source>Reset all client options to default.</source>
+ <translation>Restaurar todas as opcións de cliente ás por defecto</translation>
+ </message>
+ <message>
+ <source>&amp;Reset Options</source>
+ <translation>Opcións de &amp;Restaurar</translation>
+ </message>
+ <message>
+ <source>&amp;Network</source>
+ <translation>&amp;Rede</translation>
+ </message>
+ <message>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>Abrir automáticamente o porto do cliente Bitcoin no router. Esto so funciona se o teu router soporta UPnP e está habilitado.</translation>
+ </message>
+ <message>
+ <source>Map port using &amp;UPnP</source>
+ <translation>Mapear porto empregando &amp;UPnP</translation>
+ </message>
+ <message>
+ <source>Proxy &amp;IP:</source>
+ <translation>&amp;IP do Proxy:</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>&amp;Porto:</translation>
+ </message>
+ <message>
+ <source>Port of the proxy (e.g. 9050)</source>
+ <translation>Porto do proxy (exemplo: 9050)</translation>
+ </message>
+ <message>
+ <source>&amp;Window</source>
+ <translation>&amp;Xanela</translation>
+ </message>
+ <message>
+ <source>Show only a tray icon after minimizing the window.</source>
+ <translation>Amosar so un icono na bandexa tras minimiza-la xanela.</translation>
+ </message>
+ <message>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>&amp;Minimizar á bandexa en lugar de á barra de tarefas.</translation>
+ </message>
+ <message>
+ <source>M&amp;inimize on close</source>
+ <translation>M&amp;inimizar ao pechar</translation>
+ </message>
+ <message>
+ <source>&amp;Display</source>
+ <translation>&amp;Visualización</translation>
+ </message>
+ <message>
+ <source>User Interface &amp;language:</source>
+ <translation>&amp;Linguaxe de interface de usuario:</translation>
+ </message>
+ <message>
+ <source>&amp;Unit to show amounts in:</source>
+ <translation>&amp;Unidade na que amosar as cantidades:</translation>
+ </message>
+ <message>
+ <source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
+ <translation>Escolle a unidade de subdivisión por defecto para amosar na interface e ao enviar moedas.</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>&amp;OK</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>&amp;Cancelar</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>por defecto</translation>
+ </message>
+ <message>
+ <source>Confirm options reset</source>
+ <translation>Confirmar opcións de restaurar</translation>
+ </message>
+ <message>
+ <source>The supplied proxy address is invalid.</source>
+ <translation>A dirección de proxy suministrada é inválida.</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>Formulario</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>A información amosada por estar desactualizada. O teu moedeiro sincronízase automáticamente coa rede Bitcoin despois de que se estableza unha conexión, pero este proceso non está todavía rematado.</translation>
+ </message>
+ <message>
+ <source>Your current spendable balance</source>
+ <translation>O teu balance actualmente dispoñible</translation>
+ </message>
+ <message>
+ <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source>
+ <translation>Total de transaccións que aínda teñen que ser confirmadas, e non contan todavía dentro do balance gastable</translation>
+ </message>
+ <message>
+ <source>Immature:</source>
+ <translation>Inmaduro:</translation>
+ </message>
+ <message>
+ <source>Mined balance that has not yet matured</source>
+ <translation>O balance minado todavía non madurou</translation>
+ </message>
+ <message>
+ <source>Total:</source>
+ <translation>Total:</translation>
+ </message>
+ <message>
+ <source>Your current total balance</source>
+ <translation>O teu balance actual total</translation>
+ </message>
+ </context>
+<context>
+ <name>PaymentServer</name>
+ <message>
+ <source>URI handling</source>
+ <translation>Manexo de URI</translation>
+ </message>
+ <message>
+ <source>Invalid payment address %1</source>
+ <translation>Dirección de pago %1 inválida</translation>
+ </message>
+ <message>
+ <source>Requested payment amount of %1 is too small (considered dust).</source>
+ <translation>A cantidade de %1 na solicitude de pado é moi pequena (considerada po).</translation>
+ </message>
+ <message>
+ <source>Payment request error</source>
+ <translation>Erro na petición de pago</translation>
+ </message>
+ <message>
+ <source>Refund from %1</source>
+ <translation>Devolución dende %1</translation>
+ </message>
+ <message>
+ <source>Error communicating with %1: %2</source>
+ <translation>Erro comunicando con %1: %2</translation>
+ </message>
+ <message>
+ <source>Bad response from server %1</source>
+ <translation>Responsa errónea do servidor %1</translation>
+ </message>
+ <message>
+ <source>Payment acknowledged</source>
+ <translation>Pago admitido</translation>
+ </message>
+ <message>
+ <source>Network request error</source>
+ <translation>Erro de solicitude de rede</translation>
+ </message>
+</context>
+<context>
+ <name>PeerTableModel</name>
+ </context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>Cantidade</translation>
+ </message>
+ <message>
+ <source>%1 h</source>
+ <translation>%1 h</translation>
+ </message>
+ <message>
+ <source>%1 m</source>
+ <translation>%1 m</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>N/A</translation>
+ </message>
+ </context>
+<context>
+ <name>QRImageWidget</name>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Gardar Imaxe...</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Image</source>
+ <translation>&amp;Copiar Imaxe</translation>
+ </message>
+ <message>
+ <source>Save QR Code</source>
+ <translation>Gardar Código QR</translation>
+ </message>
+ </context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>Client name</source>
+ <translation>Nome do cliente</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>N/A</translation>
+ </message>
+ <message>
+ <source>Client version</source>
+ <translation>Versión do cliente</translation>
+ </message>
+ <message>
+ <source>&amp;Information</source>
+ <translation>&amp;Información</translation>
+ </message>
+ <message>
+ <source>Using OpenSSL version</source>
+ <translation>Usar versión OpenSSL</translation>
+ </message>
+ <message>
+ <source>Startup time</source>
+ <translation>Tempo de arranque</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Rede</translation>
+ </message>
+ <message>
+ <source>Number of connections</source>
+ <translation>Número de conexións</translation>
+ </message>
+ <message>
+ <source>Block chain</source>
+ <translation>Cadea de bloques</translation>
+ </message>
+ <message>
+ <source>Current number of blocks</source>
+ <translation>Número actual de bloques</translation>
+ </message>
+ <message>
+ <source>Last block time</source>
+ <translation>Hora do último bloque</translation>
+ </message>
+ <message>
+ <source>&amp;Open</source>
+ <translation>&amp;Abrir</translation>
+ </message>
+ <message>
+ <source>&amp;Console</source>
+ <translation>&amp;Consola</translation>
+ </message>
+ <message>
+ <source>&amp;Network Traffic</source>
+ <translation>&amp;Tráfico de Rede</translation>
+ </message>
+ <message>
+ <source>&amp;Clear</source>
+ <translation>&amp;Limpar</translation>
+ </message>
+ <message>
+ <source>Totals</source>
+ <translation>Totais</translation>
+ </message>
+ <message>
+ <source>In:</source>
+ <translation>Dentro:</translation>
+ </message>
+ <message>
+ <source>Out:</source>
+ <translation>Fóra:</translation>
+ </message>
+ <message>
+ <source>Build date</source>
+ <translation>Data de construción</translation>
+ </message>
+ <message>
+ <source>Debug log file</source>
+ <translation>Arquivo de log de depuración</translation>
+ </message>
+ <message>
+ <source>Clear console</source>
+ <translation>Limpar consola</translation>
+ </message>
+ <message>
+ <source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
+ <translation>Emprega as flechas arriba e abaixo para navegar polo historial, e &lt;b&gt;Ctrl-L&lt;/b&gt; para limpar a pantalla.</translation>
+ </message>
+ <message>
+ <source>Type &lt;b&gt;help&lt;/b&gt; for an overview of available commands.</source>
+ <translation>Escribe &lt;b&gt;axuda&lt;/b&gt; para unha vista xeral dos comandos dispoñibles.</translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation>%1 B</translation>
+ </message>
+ <message>
+ <source>%1 KB</source>
+ <translation>%1 KB</translation>
+ </message>
+ <message>
+ <source>%1 MB</source>
+ <translation>%1 MB</translation>
+ </message>
+ <message>
+ <source>%1 GB</source>
+ <translation>%1 GB</translation>
+ </message>
+ </context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Amount:</source>
+ <translation>&amp;Cantidade:</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Etiqueta:</translation>
+ </message>
+ <message>
+ <source>&amp;Message:</source>
+ <translation>&amp;Mensaxe:</translation>
+ </message>
+ <message>
+ <source>Reuse one of the previously used receiving addresses. Reusing addresses has security and privacy issues. Do not use this unless re-generating a payment request made before.</source>
+ <translation>Reutilizar unha das direccións para recibir previas. Reutilizar direccións ten problemas de seguridade e privacidade. Non empregues esto agás que antes se fixese unha solicitude de rexeneración dun pago.</translation>
+ </message>
+ <message>
+ <source>R&amp;euse an existing receiving address (not recommended)</source>
+ <translation>R&amp;eutilizar unha dirección para recibir existente (non recomendado)</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Limpar tódolos campos do formulario</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation>Limpar</translation>
+ </message>
+ <message>
+ <source>&amp;Request payment</source>
+ <translation>&amp;Solicitar pago</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Copiar etiqueta</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copiar cantidade</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>QR Code</source>
+ <translation>Código QR</translation>
+ </message>
+ <message>
+ <source>Copy &amp;URI</source>
+ <translation>Copiar &amp;URI</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Address</source>
+ <translation>Copiar &amp;Dirección</translation>
+ </message>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Gardar Imaxe...</translation>
+ </message>
+ <message>
+ <source>Request payment to %1</source>
+ <translation>Solicitar pago a %1</translation>
+ </message>
+ <message>
+ <source>Payment information</source>
+ <translation>Información de Pago</translation>
+ </message>
+ <message>
+ <source>URI</source>
+ <translation>URI</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Dirección</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Cantidade</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiqueta</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Mensaxe</translation>
+ </message>
+ <message>
+ <source>Resulting URI too long, try to reduce the text for label / message.</source>
+ <translation>A URI resultante é demasiado larga, tenta reducir o texto para a etiqueta / mensaxe.</translation>
+ </message>
+ <message>
+ <source>Error encoding URI into QR Code.</source>
+ <translation>Erro codificando URI nun Código QR.</translation>
+ </message>
+</context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiqueta</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Mensaxe</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Cantidade</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(sen etiqueta)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Moedas Enviadas</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Cantidade:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Bytes:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Importe:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Prioridade:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Pago:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Cambiar:</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>Enviar a múltiples receptores á vez</translation>
+ </message>
+ <message>
+ <source>Add &amp;Recipient</source>
+ <translation>Engadir &amp;Receptor</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Limpar tódolos campos do formulario</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Limpar &amp;Todo</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>Balance:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>Confirmar a acción de envío</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>&amp;Enviar</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>Confirmar envío de moedas</translation>
+ </message>
+ <message>
+ <source>%1 to %2</source>
+ <translation>%1 a %2</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Copiar cantidade</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copiar cantidade</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Copiar pago</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Copiar despóis do pago</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Copiar bytes</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Copiar prioridade</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Copiar cambio</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>A cantidade a pagar debe ser maior que 0.</translation>
+ </message>
+ <message>
+ <source>The amount exceeds your balance.</source>
+ <translation>A cantidade sobrepasa o teu balance.</translation>
+ </message>
+ <message>
+ <source>The total exceeds your balance when the %1 transaction fee is included.</source>
+ <translation>O total sobrepasa o teu balance cando se inclúe a tarifa de transacción %1.</translation>
+ </message>
+ <message>
+ <source>Warning: Invalid Bitcoin address</source>
+ <translation>Atención: Enderezo Bitcoin non válido</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(sen etiqueta)</translation>
+ </message>
+ <message>
+ <source>Warning: Unknown change address</source>
+ <translation>Atención: Enderezo de cambio desconocido</translation>
+ </message>
+ <message>
+ <source>Are you sure you want to send?</source>
+ <translation>Seguro que queres enviar?</translation>
+ </message>
+ <message>
+ <source>added as transaction fee</source>
+ <translation>engadido como tarifa de transacción</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>&amp;Cantidade:</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>Pagar &amp;A:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Introduce unha etiqueta para esta dirección para engadila ao teu libro de direccións</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Etiqueta:</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Escoller dirección previamente empregada</translation>
+ </message>
+ <message>
+ <source>This is a normal payment.</source>
+ <translation>Este é un pago normal</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Pegar dirección dende portapapeis</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Remove this entry</source>
+ <translation>Eliminar esta entrada</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to the list of used addresses</source>
+ <translation>Introduce unha etiqueta para esta dirección para engadila á listaxe de direccións empregadas</translation>
+ </message>
+ <message>
+ <source>Pay To:</source>
+ <translation>Pagar A:</translation>
+ </message>
+ <message>
+ <source>Memo:</source>
+ <translation>Memo:</translation>
+ </message>
+</context>
+<context>
+ <name>ShutdownWindow</name>
+ </context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Signatures - Sign / Verify a Message</source>
+ <translation>Sinaturas - Asinar / Verificar unha Mensaxe</translation>
+ </message>
+ <message>
+ <source>&amp;Sign Message</source>
+ <translation>&amp;Asinar Mensaxe</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Escoller dirección previamente empregada</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Pegar dirección dende portapapeis</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Enter the message you want to sign here</source>
+ <translation>Introduce a mensaxe que queres asinar aquí</translation>
+ </message>
+ <message>
+ <source>Signature</source>
+ <translation>Sinatura</translation>
+ </message>
+ <message>
+ <source>Copy the current signature to the system clipboard</source>
+ <translation>Copiar a sinatura actual ao portapapeis do sistema</translation>
+ </message>
+ <message>
+ <source>Sign the message to prove you own this Bitcoin address</source>
+ <translation>Asina a mensaxe para probar que posees esta dirección Bitcoin</translation>
+ </message>
+ <message>
+ <source>Sign &amp;Message</source>
+ <translation>Asinar &amp;Mensaxe</translation>
+ </message>
+ <message>
+ <source>Reset all sign message fields</source>
+ <translation>Restaurar todos os campos de sinatura de mensaxe</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Limpar &amp;Todo</translation>
+ </message>
+ <message>
+ <source>&amp;Verify Message</source>
+ <translation>&amp;Verificar Mensaxe</translation>
+ </message>
+ <message>
+ <source>Verify the message to ensure it was signed with the specified Bitcoin address</source>
+ <translation>Verificar a mensaxe para asegurar que foi asinada coa dirección Bitcoin especificada</translation>
+ </message>
+ <message>
+ <source>Verify &amp;Message</source>
+ <translation>Verificar &amp;Mensaxe</translation>
+ </message>
+ <message>
+ <source>Reset all verify message fields</source>
+ <translation>Restaurar todos os campos de verificación de mensaxe</translation>
+ </message>
+ <message>
+ <source>Click "Sign Message" to generate signature</source>
+ <translation>Click en "Asinar Mensaxe" para xerar sinatura</translation>
+ </message>
+ <message>
+ <source>The entered address is invalid.</source>
+ <translation>A dirección introducida é inválida.</translation>
+ </message>
+ <message>
+ <source>Please check the address and try again.</source>
+ <translation>Por favor comproba a dirección e proba de novo.</translation>
+ </message>
+ <message>
+ <source>The entered address does not refer to a key.</source>
+ <translation>A dirección introducida non se refire a ninguna clave.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock was cancelled.</source>
+ <translation>Cancelouse o desbloqueo do moedeiro.</translation>
+ </message>
+ <message>
+ <source>Private key for the entered address is not available.</source>
+ <translation>A clave privada da dirección introducida non está dispoñible.</translation>
+ </message>
+ <message>
+ <source>Message signing failed.</source>
+ <translation>Fallou a sinatura da mensaxe.</translation>
+ </message>
+ <message>
+ <source>Message signed.</source>
+ <translation>Mensaxe asinada.</translation>
+ </message>
+ <message>
+ <source>The signature could not be decoded.</source>
+ <translation>A sinatura non puido ser decodificada.</translation>
+ </message>
+ <message>
+ <source>Please check the signature and try again.</source>
+ <translation>Por favor revise a sinatura e probe de novo.</translation>
+ </message>
+ <message>
+ <source>The signature did not match the message digest.</source>
+ <translation>A sinatura non coincide co resumo da mensaxe.</translation>
+ </message>
+ <message>
+ <source>Message verification failed.</source>
+ <translation>A verificación da mensaxe fallou.</translation>
+ </message>
+ <message>
+ <source>Message verified.</source>
+ <translation>Mensaxe verificada.</translation>
+ </message>
+</context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Core de Bitcoin</translation>
+ </message>
+ <message>
+ <source>The Bitcoin Core developers</source>
+ <translation>Os desarrolladores de Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>[testnet]</source>
+ <translation>[testnet]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ <message>
+ <source>KB/s</source>
+ <translation>KB/s</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>Aberto ata %1</translation>
+ </message>
+ <message>
+ <source>%1/offline</source>
+ <translation>%1/fóra de liña</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/sen confirmar</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 confirmacións</translation>
+ </message>
+ <message>
+ <source>Status</source>
+ <translation>Estado</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Source</source>
+ <translation>Orixe</translation>
+ </message>
+ <message>
+ <source>Generated</source>
+ <translation>Xerado</translation>
+ </message>
+ <message>
+ <source>From</source>
+ <translation>Dende</translation>
+ </message>
+ <message>
+ <source>To</source>
+ <translation>A</translation>
+ </message>
+ <message>
+ <source>own address</source>
+ <translation>dirección propia</translation>
+ </message>
+ <message>
+ <source>label</source>
+ <translation>etiqueta</translation>
+ </message>
+ <message>
+ <source>Credit</source>
+ <translation>Crédito</translation>
+ </message>
+ <message>
+ <source>not accepted</source>
+ <translation>non aceptado</translation>
+ </message>
+ <message>
+ <source>Debit</source>
+ <translation>Débito</translation>
+ </message>
+ <message>
+ <source>Transaction fee</source>
+ <translation>Tarifa de transacción</translation>
+ </message>
+ <message>
+ <source>Net amount</source>
+ <translation>Cantidade neta</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Mensaxe</translation>
+ </message>
+ <message>
+ <source>Comment</source>
+ <translation>Comentario</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>ID de Transacción</translation>
+ </message>
+ <message>
+ <source>Merchant</source>
+ <translation>Comerciante</translation>
+ </message>
+ <message>
+ <source>Generated coins must mature %1 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.</source>
+ <translation>As moedas xeradas deben madurar %1 bloques antes de que poidan ser gastadas. Cando xeraste este bloque, foi propagado á rede para ser engadido á cadeas de bloques. Se falla ao tentar meterse na cadea, o seu estado cambiará a "non aceptado" e non poderá ser gastado. Esto pode ocorrir ocasionalmente se outro nodo xera un bloque en poucos segundos de diferencia co teu.</translation>
+ </message>
+ <message>
+ <source>Debug information</source>
+ <translation>Información de depuración</translation>
+ </message>
+ <message>
+ <source>Transaction</source>
+ <translation>Transacción</translation>
+ </message>
+ <message>
+ <source>Inputs</source>
+ <translation>Entradas</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Cantidade</translation>
+ </message>
+ <message>
+ <source>true</source>
+ <translation>verdadeiro</translation>
+ </message>
+ <message>
+ <source>false</source>
+ <translation>falso</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, non foi propagado con éxito todavía</translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>descoñecido</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>Detalles de transacción</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>Este panel amosa unha descripción detallada da transacción</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Tipo</translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>Aberto ata %1</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>Confirmado (%1 confirmacións)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>Este bloque non foi recibido por ningún outro nodo e probablemente non será aceptado!</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>Xerado pero non aceptado</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiqueta</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Recibido con</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>Recibido de</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Enviado a</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>Pago a ti mesmo</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Minado</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(n/a)</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>Estado da transacción. Pasa por riba deste campo para amosar o número de confirmacións.</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Data e hora na que foi recibida a transacción.</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>Tipo de transacción.</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>Cantidade borrada ou engadida no balance.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>Todo</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>Hoxe</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>Esta semana</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>Este mes</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>O último mes</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>Este ano</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>Periodo...</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Recibido con</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Enviado a</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>A ti mesmo</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Minado</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>Outro</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>Introduce dirección ou etiqueta para buscar</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>Cantidade mínima</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Copiar dirección</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Copiar etiqueta</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copiar cantidade</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Copiar ID de transacción</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>Modificar etiqueta</translation>
+ </message>
+ <message>
+ <source>Show transaction details</source>
+ <translation>Amosar detalles da transacción</translation>
+ </message>
+ <message>
+ <source>Export Transaction History</source>
+ <translation>Exportar Historial de Transaccións</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Exportación falida</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the transaction history to %1.</source>
+ <translation>Houbo un erro intentando salvar o historial de transaccións a %1.</translation>
+ </message>
+ <message>
+ <source>Exporting Successful</source>
+ <translation>Exportado correctamente</translation>
+ </message>
+ <message>
+ <source>The transaction history was successfully saved to %1.</source>
+ <translation>O historial de transaccións foi salvado correctamente en %1.</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Arquivo separado por comas (*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Confirmado</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Tipo</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiqueta</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Dirección</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>Periodo:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>a</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ </context>
+<context>
+ <name>WalletFrame</name>
+ <message>
+ <source>No wallet has been loaded.</source>
+ <translation>Ningún moedeiro cargado</translation>
+ </message>
+</context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Moedas Enviadas</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Exportar</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Exportar os datos da pestaña actual a un arquivo.</translation>
+ </message>
+ <message>
+ <source>Backup Wallet</source>
+ <translation>Copia de Seguridade de Moedeiro</translation>
+ </message>
+ <message>
+ <source>Wallet Data (*.dat)</source>
+ <translation>Datos de Moedeiro (*.dat)</translation>
+ </message>
+ <message>
+ <source>Backup Failed</source>
+ <translation>Copia de Seguridade Fallida</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the wallet data to %1.</source>
+ <translation>Houbo un erro intentando gardar os datos de moedeiro en %1.</translation>
+ </message>
+ <message>
+ <source>The wallet data was successfully saved to %1.</source>
+ <translation>Os datos do moedeiro foron gardados correctamente en %1.</translation>
+ </message>
+ <message>
+ <source>Backup Successful</source>
+ <translation>Copia de Seguridade Correcta</translation>
+ </message>
+</context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>Opcións:</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>Especificar directorio de datos</translation>
+ </message>
+ <message>
+ <source>Connect to a node to retrieve peer addresses, and disconnect</source>
+ <translation>Conectar a nodo para recuperar direccións de pares, e desconectar</translation>
+ </message>
+ <message>
+ <source>Specify your own public address</source>
+ <translation>Especificar a túa propia dirección pública</translation>
+ </message>
+ <message>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>Aceptar liña de comandos e comandos JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>Executar no fondo como un demo e aceptar comandos</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>Empregar a rede de proba</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
+ <translation>Aceptar conexións de fóra (por defecto: 1 se non -proxy ou -connect)</translation>
+ </message>
+ <message>
+ <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
+ <translation>Enlazar a unha dirección dada e escoitar sempre nela. Emprega a notación [host]:post para IPv6</translation>
+ </message>
+ <message>
+ <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
+ <translation>Executar comando cando unha transacción do moedeiro cambia (%s no comando é substituído por TxID)</translation>
+ </message>
+ <message>
+ <source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source>
+ <translation>Esta é unha build de test pre-lanzamento - emprégaa baixo o teu propio risco - non empregar para minado ou aplicacións de comerciantes</translation>
+ </message>
+ <message>
+ <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>Precaución: -paytxfee está posto moi algo! Esta é a tarifa de transacción que ti pagarás se envías unha transacción.</translation>
+ </message>
+ <message>
+ <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source>
+ <translation>Precaución: A rede non parece estar totalmente de acordo! Algúns mineitos parecen estar experimentando problemas.</translation>
+ </message>
+ <message>
+ <source>Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.</source>
+ <translation>Precaución: Non parece que esteamos totalmente de acordo cos nosos pares! Pode que precises actualizar, ou outros nodos poden precisar actualizarse.</translation>
+ </message>
+ <message>
+ <source>Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
+ <translation>Precaución: erro lendo wallet.dat! Tódalas claves lidas correctamente, pero os datos de transacción ou as entradas do libro de direccións podrían estar ausentes ou incorrectos.</translation>
+ </message>
+ <message>
+ <source>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</source>
+ <translation>Precaución: wallet.dat corrupto, datos salvagardados! O wallet.dat orixinal foi gardado como wallet.{timestamp}.bak en %s; se o teu balance ou transaccións son incorrectas deberías restauralas dende unha copia de seguridade.</translation>
+ </message>
+ <message>
+ <source>&lt;category&gt; can be:</source>
+ <translation>&lt;categoría&gt; pode ser:</translation>
+ </message>
+ <message>
+ <source>Attempt to recover private keys from a corrupt wallet.dat</source>
+ <translation>Tentar recuperar claves privadas dende un wallet.dat corrupto</translation>
+ </message>
+ <message>
+ <source>Block creation options:</source>
+ <translation>Opcións de creación de bloque:</translation>
+ </message>
+ <message>
+ <source>Connect only to the specified node(s)</source>
+ <translation>Conectar so ao(s) nodo(s) especificado(s)</translation>
+ </message>
+ <message>
+ <source>Corrupted block database detected</source>
+ <translation>Detectada base de datos de bloques corrupta.</translation>
+ </message>
+ <message>
+ <source>Do you want to rebuild the block database now?</source>
+ <translation>Queres reconstruír a base de datos de bloques agora?</translation>
+ </message>
+ <message>
+ <source>Error initializing block database</source>
+ <translation>Erro inicializando a base de datos de bloques</translation>
+ </message>
+ <message>
+ <source>Error initializing wallet database environment %s!</source>
+ <translation>Erro inicializando entorno de base de datos de moedeiro %s!</translation>
+ </message>
+ <message>
+ <source>Error loading block database</source>
+ <translation>Erro cargando base de datos do bloque</translation>
+ </message>
+ <message>
+ <source>Error opening block database</source>
+ <translation>Erro abrindo base de datos de bloques</translation>
+ </message>
+ <message>
+ <source>Error: Disk space is low!</source>
+ <translation>Erro: Espacio en disco escaso!</translation>
+ </message>
+ <message>
+ <source>Failed to listen on any port. Use -listen=0 if you want this.</source>
+ <translation>Fallou escoitar en calquera porto. Emprega -listen=0 se queres esto.</translation>
+ </message>
+ <message>
+ <source>Incorrect or no genesis block found. Wrong datadir for network?</source>
+ <translation>Bloque genesis incorrecto o no existente. Datadir erróneo para a rede?</translation>
+ </message>
+ <message>
+ <source>Invalid -onion address: '%s'</source>
+ <translation>Dirección -onion inválida: '%s'</translation>
+ </message>
+ <message>
+ <source>Not enough file descriptors available.</source>
+ <translation>Non hai suficientes descritores de arquivo dispoñibles.</translation>
+ </message>
+ <message>
+ <source>Specify wallet file (within data directory)</source>
+ <translation>Especificar arquivo do moedeiro (dentro do directorio de datos)</translation>
+ </message>
+ <message>
+ <source>Verifying blocks...</source>
+ <translation>Verificando bloques...</translation>
+ </message>
+ <message>
+ <source>Verifying wallet...</source>
+ <translation>Verificando moedeiro...</translation>
+ </message>
+ <message>
+ <source>Wallet %s resides outside data directory %s</source>
+ <translation>O moedeiro %s reside fóra do directorio de datos %s</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to change -txindex</source>
+ <translation>Precisas reconstruír a base de datos empregando -reindex para cambiar -txindex</translation>
+ </message>
+ <message>
+ <source>Imports blocks from external blk000??.dat file</source>
+ <translation>Importa bloques dende arquivos blk000??.dat externos</translation>
+ </message>
+ <message>
+ <source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source>
+ <translation>Executar comando cando se recibe unha alerta relevante ou vemos un fork realmente longo (%s no cmd é substituído pola mensaxe)</translation>
+ </message>
+ <message>
+ <source>Choose data directory on startup (default: 0)</source>
+ <translation>Escolle directorio de datos ao arrancar (por defecto: 0)</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Información</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -minrelaytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Cantidade inválida para -minrelaytxfee=&lt;cantidade&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -mintxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Cantidade inválida para -mintxfee=&lt;cantidade&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>Enviar traza/información de depuración á consola en lugar de ao arquivo debug.log</translation>
+ </message>
+ <message>
+ <source>Set language, for example "de_DE" (default: system locale)</source>
+ <translation>Fixar idioma, por exemplo "de_DE" (por defecto: locale del sistema)</translation>
+ </message>
+ <message>
+ <source>Show splash screen on startup (default: 1)</source>
+ <translation>Amosar pantalla splash no arranque (por defecto: 1)</translation>
+ </message>
+ <message>
+ <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source>
+ <translation>Recortar o arquivo debug.log ao arrancar o cliente (por defecto: 1 cando no-debug)</translation>
+ </message>
+ <message>
+ <source>Signing transaction failed</source>
+ <translation>Fallou a sinatura da transacción</translation>
+ </message>
+ <message>
+ <source>Start minimized</source>
+ <translation>Comezar minimizado</translation>
+ </message>
+ <message>
+ <source>Transaction amount too small</source>
+ <translation>A cantidade da transacción é demasiado pequena</translation>
+ </message>
+ <message>
+ <source>Transaction amounts must be positive</source>
+ <translation>As cantidades da transacción deben ser positivas</translation>
+ </message>
+ <message>
+ <source>Transaction too large</source>
+ <translation>A transacción é demasiado grande</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: 1 when listening)</source>
+ <translation>Usar UPnP para mapear o porto de escoita (por defecto: 1 se á escoita)</translation>
+ </message>
+ <message>
+ <source>Username for JSON-RPC connections</source>
+ <translation>Nome de usuario para conexións JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Precaución</translation>
+ </message>
+ <message>
+ <source>wallet.dat corrupt, salvage failed</source>
+ <translation>wallet.dat corrupto, fallou o gardado</translation>
+ </message>
+ <message>
+ <source>Password for JSON-RPC connections</source>
+ <translation>Contrasinal para conexións JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
+ <translation>Executar comando cando o mellor bloque cambie (%s no comando é sustituído polo hash do bloque)</translation>
+ </message>
+ <message>
+ <source>Upgrade wallet to latest format</source>
+ <translation>Actualizar moedeiro ao formato máis recente</translation>
+ </message>
+ <message>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>Rescanear transaccións ausentes na cadea de bloques</translation>
+ </message>
+ <message>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>Empregar OpenSSL (https) para conexións JSON-RPC</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>Esta mensaxe de axuda</translation>
+ </message>
+ <message>
+ <source>Allow DNS lookups for -addnode, -seednode and -connect</source>
+ <translation>Permitir lookup de DNS para -addnote, -seednote e -connect</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>Cargando direccións...</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>Erro cargando wallet.dat: Moedeiro corrupto</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>Erro cargando wallet.dat</translation>
+ </message>
+ <message>
+ <source>Invalid -proxy address: '%s'</source>
+ <translation>Dirección -proxy inválida: '%s'</translation>
+ </message>
+ <message>
+ <source>Unknown network specified in -onlynet: '%s'</source>
+ <translation>Rede descoñecida especificada en -onlynet: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -bind address: '%s'</source>
+ <translation>Non se pode resolver a dirección -bind: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -externalip address: '%s'</source>
+ <translation>Non se pode resolver dirección -externalip: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Cantidade inválida para -paytxfee=&lt;cantidade&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>Fondos insuficientes</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>Cargando índice de bloques...</translation>
+ </message>
+ <message>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>Engadir un nodo ao que conectarse e tentar manter a conexión aberta</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>Cargando moedeiro...</translation>
+ </message>
+ <message>
+ <source>Cannot downgrade wallet</source>
+ <translation>Non se pode desactualizar o moedeiro</translation>
+ </message>
+ <message>
+ <source>Cannot write default address</source>
+ <translation>Non se pode escribir a dirección por defecto</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>Rescaneando...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>Carga completa</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Erro</translation>
+ </message>
+</context>
+</TS> \ No newline at end of file
diff --git a/src/qt/locale/bitcoin_gu_IN.ts b/src/qt/locale/bitcoin_gu_IN.ts
new file mode 100644
index 0000000000..ef99b0dd39
--- /dev/null
+++ b/src/qt/locale/bitcoin_gu_IN.ts
@@ -0,0 +1,110 @@
+<TS language="gu_IN" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ </context>
+<context>
+ <name>AddressTableModel</name>
+ </context>
+<context>
+ <name>AskPassphraseDialog</name>
+ </context>
+<context>
+ <name>BitcoinGUI</name>
+ </context>
+<context>
+ <name>ClientModel</name>
+ </context>
+<context>
+ <name>CoinControlDialog</name>
+ </context>
+<context>
+ <name>EditAddressDialog</name>
+ </context>
+<context>
+ <name>FreespaceChecker</name>
+ </context>
+<context>
+ <name>HelpMessageDialog</name>
+ </context>
+<context>
+ <name>Intro</name>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ </context>
+<context>
+ <name>OptionsDialog</name>
+ </context>
+<context>
+ <name>OverviewPage</name>
+ </context>
+<context>
+ <name>PaymentServer</name>
+ </context>
+<context>
+ <name>PeerTableModel</name>
+ </context>
+<context>
+ <name>QObject</name>
+ </context>
+<context>
+ <name>QRImageWidget</name>
+ </context>
+<context>
+ <name>RPCConsole</name>
+ </context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ </context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ </context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ </context>
+<context>
+ <name>SendCoinsDialog</name>
+ </context>
+<context>
+ <name>SendCoinsEntry</name>
+ </context>
+<context>
+ <name>ShutdownWindow</name>
+ </context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ </context>
+<context>
+ <name>SplashScreen</name>
+ </context>
+<context>
+ <name>TrafficGraphWidget</name>
+ </context>
+<context>
+ <name>TransactionDesc</name>
+ </context>
+<context>
+ <name>TransactionDescDialog</name>
+ </context>
+<context>
+ <name>TransactionTableModel</name>
+ </context>
+<context>
+ <name>TransactionView</name>
+ </context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ </context>
+<context>
+ <name>WalletFrame</name>
+ </context>
+<context>
+ <name>WalletModel</name>
+ </context>
+<context>
+ <name>WalletView</name>
+ </context>
+<context>
+ <name>bitcoin-core</name>
+ </context>
+</TS> \ 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 0000000000..e24d5dd21f
--- /dev/null
+++ b/src/qt/locale/bitcoin_he.ts
@@ -0,0 +1,2926 @@
+<TS language="he" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Create a new address</source>
+ <translation>יצירת כתובת חדשה</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>&amp;חדשה</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>העתקת הכתובת המסומנת ללוח הגזירים</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>ה&amp;עתקה</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>סגירה</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>העתקת כתובת</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>מחיקת הכתובת שנבחרה מהרשימה</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>יצוא הנתונים מהלשונית הנוכחית לקובץ</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>י&amp;צוא</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>מ&amp;חיקה</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>נא לבחור את הכתובת המבוקשת לשליחת המטבעות</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>נא לבחור את הכתובת המבוקשת לקבלת המטבעות</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>בחירה</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>כתובות לשליחה</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>כתובות לקבלה</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>אלה כתובת הביטקוין שלך לצורך שליחת תשלומים. תמיד יש לבדוק את הכמות ואת כתובות מקבלי התשלומים לפני שליחת מטבעות.</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>אלה כתובות הביטקוין שלך לצורך קבלת תשלומים. מומלץ להשתמש בכתובת קבלה חדשה לכל העברה.</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>העתקת &amp;תווית</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>ע&amp;ריכה</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>יצוא רשימת כתובות</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>קובץ מופרד בפסיקים (‎*.csv)</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>היצוא נכשל</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the address list to %1. Please try again.</source>
+ <translation>אירעה שגיאה בעת הניסיון לשמור את רשימת הכתובת אל %1. נא לנסות שוב.</translation>
+ </message>
+</context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>תווית</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>כתובת</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(אין תווית)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Passphrase Dialog</source>
+ <translation>דו־שיח מילת צופן</translation>
+ </message>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>נא להזין מילת צופן</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>מילת צופן חדשה</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>נא לחזור על מילת הצופן החדשה</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>הצפנת הארנק</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>פעולה זו דורשת את מילת הצופן של הארנק שלך כדי לפתוח את הארנק.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>פתיחת ארנק</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>פעולה זו דורשת את מילת הצופן של הארנק שלך כדי לפענח את הארנק.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>פענוח ארנק</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>שינוי מילת צופן</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>אישור הצפנת הארנק</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>אזהרה: הצפנת הארנק ואיבוד מילת הצופן עשויה להוביל &lt;b&gt;לאיבוד כל הביטקוינים שלך&lt;/b&gt;!</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>האם אכן להצפין את הארנק?</translation>
+ </message>
+ <message>
+ <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
+ <translation>לתשומת לבך: כל גיבוי קודם שביצעת לארנק שלך יש להחליף בקובץ הארנק המוצפן שזה עתה נוצר. מטעמי אבטחה, גיבויים קודמים של קובץ הארנק הבלתי-מוצפן יהפכו לחסרי תועלת עם התחלת השימוש בארנק החדש המוצפן.</translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>זהירות: מקש Caps Lock פעיל!</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>הארנק הוצפן</translation>
+ </message>
+ <message>
+ <source>Enter the new passphrase to the wallet.&lt;br/&gt;Please use a passphrase of &lt;b&gt;ten or more random characters&lt;/b&gt;, or &lt;b&gt;eight or more words&lt;/b&gt;.</source>
+ <translation>נא להזין את מילת הצופן החדשה לארנק.&lt;br/&gt;כדאי להשתמש במילת צופן המורכבת מ&lt;b&gt;עשרה תווים אקראיים ומעלה&lt;/b&gt;, או &lt;b&gt;שמונה מילים ומעלה&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>הצפנת הארנק נכשלה</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>הצפנת הארנק נכשלה עקב שגיאה פנימית. הארנק שלך לא הוצפן.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>מילות הצופן שסופקו אינן תואמות.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>פתיחת הארנק נכשלה</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>מילת הצופן שהוכנסה לפענוח הארנק שגויה.</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>פענוח הארנק נכשל</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>מילת הצופן של הארנק שונתה בהצלחה.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>&amp;חתימה על הודעה…</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>בסנכרון עם הרשת…</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;סקירה</translation>
+ </message>
+ <message>
+ <source>Node</source>
+ <translation>מפרק</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>הצגת סקירה כללית של הארנק</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>ה&amp;עברות</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>עיון בהיסטוריית ההעברות</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>י&amp;ציאה</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>יציאה מהתכנית</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>על אודות Qt</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>הצגת מידע על Qt</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;אפשרויות…</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>ה&amp;צפנת הארנק…</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>&amp;גיבוי הארנק…</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>ה&amp;חלפת מילת הצופן…</translation>
+ </message>
+ <message>
+ <source>&amp;Sending addresses...</source>
+ <translation>כתובת ה&amp;שליחה…</translation>
+ </message>
+ <message>
+ <source>&amp;Receiving addresses...</source>
+ <translation>כתובות ה&amp;קבלה…</translation>
+ </message>
+ <message>
+ <source>Open &amp;URI...</source>
+ <translation>פתיחת &amp;כתובת משאב…</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core client</source>
+ <translation>לקוח ליבה של ביטקוין</translation>
+ </message>
+ <message>
+ <source>Importing blocks from disk...</source>
+ <translation>מקטעים מיובאים מהכונן…</translation>
+ </message>
+ <message>
+ <source>Reindexing blocks on disk...</source>
+ <translation>המקטעים נוספים למפתח בכונן…</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>שליחת מטבעות לכתובת ביטקוין</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>גיבוי הארנק למיקום אחר</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>החלפת מילת הצופן להצפנת הארנק</translation>
+ </message>
+ <message>
+ <source>&amp;Debug window</source>
+ <translation>חלון &amp;ניפוי</translation>
+ </message>
+ <message>
+ <source>Open debugging and diagnostic console</source>
+ <translation>פתיחת לוח הבקרה לאבחון ולניפוי</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>&amp;אימות הודעה…</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>ביטקוין</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>ארנק</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>&amp;שליחה</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>&amp;קבלה</translation>
+ </message>
+ <message>
+ <source>Show information about Bitcoin Core</source>
+ <translation>הצגת מידע על ליבת ביטקוין</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>ה&amp;צגה / הסתרה</translation>
+ </message>
+ <message>
+ <source>Show or hide the main Window</source>
+ <translation>הצגה או הסתרה של החלון הראשי</translation>
+ </message>
+ <message>
+ <source>Encrypt the private keys that belong to your wallet</source>
+ <translation>הצפנת המפתחות הפרטיים ששייכים לארנק שלך</translation>
+ </message>
+ <message>
+ <source>Sign messages with your Bitcoin addresses to prove you own them</source>
+ <translation>חתום על הודעות עם כתובות הביטקוין שלך כדי להוכיח שהן בבעלותך</translation>
+ </message>
+ <message>
+ <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source>
+ <translation>אמת הודעות כדי להבטיח שהן נחתמו עם כתובת ביטקוין מסוימות</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;קובץ</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>ה&amp;גדרות</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>ע&amp;זרה</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>סרגל כלים לשוניות</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>ליבת ביטקוין</translation>
+ </message>
+ <message>
+ <source>Request payments (generates QR codes and bitcoin: URIs)</source>
+ <translation>בקשת תשלומים (יצירה של קודים מסוג QR וסכימות כתובות משאב של :bitcoin)</translation>
+ </message>
+ <message>
+ <source>&amp;About Bitcoin Core</source>
+ <translation>על &amp;אודות ליבת ביטקוין</translation>
+ </message>
+ <message>
+ <source>Show the list of used sending addresses and labels</source>
+ <translation>הצג את רשימת הכתובות לשליחה שהיו בשימוש לרבות התוויות</translation>
+ </message>
+ <message>
+ <source>Show the list of used receiving addresses and labels</source>
+ <translation>הצגת רשימת הכתובות והתוויות הנמצאות בשימוש</translation>
+ </message>
+ <message>
+ <source>Open a bitcoin: URI or payment request</source>
+ <translation>פתיחת ביטקוין: כתובת משאב או בקשת תשלום</translation>
+ </message>
+ <message>
+ <source>&amp;Command-line options</source>
+ <translation>אפשרויות &amp;שורת הפקודה</translation>
+ </message>
+ <message>
+ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
+ <translation>הצגת הודעות העזרה של ליבת ביטקוין כדי לקבל רשימה עם אפשרויות שורת הפקודה האפשריות של ביטקוין</translation>
+ </message>
+ <message>
+ <source>No block source available...</source>
+ <translation>אין מקור מקטעים זמין…</translation>
+ </message>
+ <message>
+ <source>%1 and %2</source>
+ <translation>%1 ו%2</translation>
+ </message>
+ <message>
+ <source>Last received block was generated %1 ago.</source>
+ <translation>המקטע האחרון שהתקבל נוצר לפני %1.</translation>
+ </message>
+ <message>
+ <source>Transactions after this will not yet be visible.</source>
+ <translation>ההעברות שבוצעו לאחר העברה זו לא יופיעו.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>שגיאה</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>אזהרה</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>מידע</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>עדכני</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>מתבצע עדכון…</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>העברת שליחה</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>העברת קבלה</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>הארנק &lt;b&gt;מוצפן&lt;/b&gt; ו&lt;b&gt;פתוח&lt;/b&gt; כרגע</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>הארנק &lt;b&gt;מוצפן&lt;/b&gt; ו&lt;b&gt;נעול&lt;/b&gt; כרגע</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <source>Network Alert</source>
+ <translation>אזעקת רשת</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Quantity:</source>
+ <translation>כמות:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>בתים:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>סכום:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>עדיפות:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>עמלה:</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>אבק:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>לאחר עמלה:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>עודף:</translation>
+ </message>
+ <message>
+ <source>(un)select all</source>
+ <translation>ביטול/אישור הבחירה</translation>
+ </message>
+ <message>
+ <source>Tree mode</source>
+ <translation>מצב עץ</translation>
+ </message>
+ <message>
+ <source>List mode</source>
+ <translation>מצב רשימה</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>כמות</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>תאריך</translation>
+ </message>
+ <message>
+ <source>Confirmations</source>
+ <translation>אישורים</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>מאושר</translation>
+ </message>
+ <message>
+ <source>Priority</source>
+ <translation>עדיפות</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>העתקת כתובת</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>העתקת תווית</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>העתקת כמות</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>העתקת מזהה העברה</translation>
+ </message>
+ <message>
+ <source>Lock unspent</source>
+ <translation>נעילת יתרה</translation>
+ </message>
+ <message>
+ <source>Unlock unspent</source>
+ <translation>פתיחת יתרה</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>העתקת כמות</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>העתקת עמלה</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>העתקת אחרי עמלה</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>העתקת בתים</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>העתקת עדיפות</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>העתקת אבק</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>העתקת עודף</translation>
+ </message>
+ <message>
+ <source>highest</source>
+ <translation>הגבוה ביותר</translation>
+ </message>
+ <message>
+ <source>higher</source>
+ <translation>גבוה יותר</translation>
+ </message>
+ <message>
+ <source>high</source>
+ <translation>גבוה</translation>
+ </message>
+ <message>
+ <source>medium-high</source>
+ <translation>בינוני - גבוה</translation>
+ </message>
+ <message>
+ <source>medium</source>
+ <translation>בינוני</translation>
+ </message>
+ <message>
+ <source>low-medium</source>
+ <translation>בינוני - נמוך</translation>
+ </message>
+ <message>
+ <source>low</source>
+ <translation>נמוך</translation>
+ </message>
+ <message>
+ <source>lower</source>
+ <translation>נמוך יותר</translation>
+ </message>
+ <message>
+ <source>lowest</source>
+ <translation>הנמוך ביותר</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>ללא</translation>
+ </message>
+ <message>
+ <source>Can vary +/- %1 satoshi(s) per input.</source>
+ <translation>יכולה להשתנות ב+/- %1 סטושי לקלט.</translation>
+ </message>
+ <message>
+ <source>yes</source>
+ <translation>כן</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>לא</translation>
+ </message>
+ <message>
+ <source>This means a fee of at least %1 per kB is required.</source>
+ <translation>זאת אומרת שנחוצה עמלה של לא פחות מ־%1 לכל קילו בית.</translation>
+ </message>
+ <message>
+ <source>Can vary +/- 1 byte per input.</source>
+ <translation>הערך יכול להיות +/- בית אחד לכל קלט.</translation>
+ </message>
+ <message>
+ <source>Transactions with higher priority are more likely to get included into a block.</source>
+ <translation>העברות עם עדיפות גבוהה, יותר סיכוי שיכנסו לתוך המקטע.</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(אין תווית)</translation>
+ </message>
+ <message>
+ <source>change from %1 (%2)</source>
+ <translation>עודף מ־%1 (%2)</translation>
+ </message>
+ <message>
+ <source>(change)</source>
+ <translation>(עודף)</translation>
+ </message>
+</context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>עריכת כתובת</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>ת&amp;ווית</translation>
+ </message>
+ <message>
+ <source>The label associated with this address list entry</source>
+ <translation>התווית המשויכת לרשומה הזו ברשימת הכתובות</translation>
+ </message>
+ <message>
+ <source>The address associated with this address list entry. This can only be modified for sending addresses.</source>
+ <translation>הכתובת המשויכת עם רשומה זו ברשימת הכתובות. ניתן לשנות זאת רק עבור כתובות לשליחה.</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;כתובת</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>כתובת חדשה לקבלה</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>כתובת חדשה לשליחה</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>עריכת כתובת לקבלה</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>עריכת כתובת לשליחה</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>הכתובת שהוכנסה „%1“ כבר נמצאת בפנקס הכתובות.</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is not a valid Bitcoin address.</source>
+ <translation>הכתובת שהוכנסה „%1“ אינה כתובת ביטקוין תקנית.</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>פתיחת הארנק נכשלה.</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>יצירת מפתח חדש נכשלה.</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ <message>
+ <source>A new data directory will be created.</source>
+ <translation>תיקיית נתונים חדשה תיווצר.</translation>
+ </message>
+ <message>
+ <source>name</source>
+ <translation>שם</translation>
+ </message>
+ <message>
+ <source>Directory already exists. Add %1 if you intend to create a new directory here.</source>
+ <translation>התיקייה כבר קיימת. ניתן להוסיף %1 אם יש ליצור תיקייה חדשה כאן.</translation>
+ </message>
+ <message>
+ <source>Path already exists, and is not a directory.</source>
+ <translation>הנתיב כבר קיים ואינו מצביע על תיקייה.</translation>
+ </message>
+ <message>
+ <source>Cannot create data directory here.</source>
+ <translation>לא ניתן ליצור כאן תיקיית נתונים.</translation>
+ </message>
+</context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>ליבת ביטקוין</translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>גרסה</translation>
+ </message>
+ <message>
+ <source>(%1-bit)</source>
+ <translation>(%1-סיביות)</translation>
+ </message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>על אודות ליבת ביטקוין</translation>
+ </message>
+ <message>
+ <source>Command-line options</source>
+ <translation>אפשרויות שורת פקודה</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>שימוש:</translation>
+ </message>
+ <message>
+ <source>command-line options</source>
+ <translation>אפשרויות שורת פקודה</translation>
+ </message>
+</context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Welcome</source>
+ <translation>ברוך בואך</translation>
+ </message>
+ <message>
+ <source>Welcome to Bitcoin Core.</source>
+ <translation>ברוך בואך לליבת ביטקוין</translation>
+ </message>
+ <message>
+ <source>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</source>
+ <translation>מכיוון שזאת הפעם הראשונה שהתכנית פועלת ניתן לבחור איפה ליבת ביטקוין תאחסן את הנתונים שלה.</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory.</source>
+ <translation>לקוח ביטקוין יוריד וישמור העתק של שרשרת המקטעים של ביטקוין. לפחות %1 ג״ב מהנתונים יאוחסנו בתיקייה זו, והיא תגדל עם הזמן. הארנק גם יאוחסן בתיקייה הזו.</translation>
+ </message>
+ <message>
+ <source>Use the default data directory</source>
+ <translation>שימוש בבררת המחדל של תיקיית הנתונים.</translation>
+ </message>
+ <message>
+ <source>Use a custom data directory:</source>
+ <translation>שימוש בתיקיית נתונים מותאמת אישית:</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>ליבת ביטקוין</translation>
+ </message>
+ <message>
+ <source>Error: Specified data directory "%1" cannot be created.</source>
+ <translation>שגיאה: לא ניתן ליצור את תיקיית הנתונים שצוינה „%1“.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>שגיאה</translation>
+ </message>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ <message>
+ <source>Open URI</source>
+ <translation>פתיחת כתובת משאב</translation>
+ </message>
+ <message>
+ <source>Open payment request from URI or file</source>
+ <translation>פתיחת בקשת תשלום מכתובת משאב או מקובץ</translation>
+ </message>
+ <message>
+ <source>URI:</source>
+ <translation>כתובת משאב:</translation>
+ </message>
+ <message>
+ <source>Select payment request file</source>
+ <translation>בחירת קובץ בקשת תשלום</translation>
+ </message>
+ <message>
+ <source>Select payment request file to open</source>
+ <translation>בחירת קובץ בקשת תשלום לפתיחה</translation>
+ </message>
+</context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>אפשרויות</translation>
+ </message>
+ <message>
+ <source>&amp;Main</source>
+ <translation>&amp;ראשי</translation>
+ </message>
+ <message>
+ <source>Size of &amp;database cache</source>
+ <translation>גודל מ&amp;טמון מסד הנתונים</translation>
+ </message>
+ <message>
+ <source>MB</source>
+ <translation>מ״ב</translation>
+ </message>
+ <message>
+ <source>Number of script &amp;verification threads</source>
+ <translation>מספר תהליכי ה&amp;אימות של הסקריפט</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside</source>
+ <translation>קבלת חיבורים מבחוץ</translation>
+ </message>
+ <message>
+ <source>Allow incoming connections</source>
+ <translation>לאפשר חיבורים נכנסים</translation>
+ </message>
+ <message>
+ <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
+ <translation>כתובת ה־IP של המתווך (לדוגמה IPv4: 127.0.0.1‏ / IPv6: ::1)</translation>
+ </message>
+ <message>
+ <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source>
+ <translation>כתובות צד־שלישי (כגון: סייר מקטעים) שמופיעים בלשונית ההעברות בתור פריטים בתפריט ההקשר. %s בכתובת מוחלף בגיבוב ההעברה. מספר כתובות יופרדו בפס אנכי |.</translation>
+ </message>
+ <message>
+ <source>Third party transaction URLs</source>
+ <translation>כתובות העברה צד־שלישי</translation>
+ </message>
+ <message>
+ <source>Active command-line options that override above options:</source>
+ <translation>אפשרויות פעילות בשורת הפקודה שדורסות את האפשרויות שלהלן:</translation>
+ </message>
+ <message>
+ <source>Reset all client options to default.</source>
+ <translation>איפוס כל אפשרויות התכנית לבררת המחדל.</translation>
+ </message>
+ <message>
+ <source>&amp;Reset Options</source>
+ <translation>&amp;איפוס אפשרויות</translation>
+ </message>
+ <message>
+ <source>&amp;Network</source>
+ <translation>&amp;רשת</translation>
+ </message>
+ <message>
+ <source>(0 = auto, &lt;0 = leave that many cores free)</source>
+ <translation>(0 = אוטומטי, &lt;0 = להשאיר כזאת כמות של ליבות חופשיות)</translation>
+ </message>
+ <message>
+ <source>W&amp;allet</source>
+ <translation>&amp;ארנק</translation>
+ </message>
+ <message>
+ <source>Expert</source>
+ <translation>מומחה</translation>
+ </message>
+ <message>
+ <source>Enable coin &amp;control features</source>
+ <translation>הפעלת תכונות &amp;בקרת מטבעות</translation>
+ </message>
+ <message>
+ <source>If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.</source>
+ <translation>אם אפשרות ההשקעה של עודף בלתי מאושר תנוטרל, לא ניתן יהיה להשתמש בעודף מההעברה עד שלהעברה יהיה לפחות אישור אחד. פעולה זו גם משפיעה על חישוב המאזן שלך.</translation>
+ </message>
+ <message>
+ <source>&amp;Spend unconfirmed change</source>
+ <translation>עודף &amp;בלתי מאושר מההשקעה</translation>
+ </message>
+ <message>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>פתיחת הפתחה של ביטקוין בנתב באופן אוטומטי. עובד רק אם UPnP מופעל ונתמך בנתב.</translation>
+ </message>
+ <message>
+ <source>Map port using &amp;UPnP</source>
+ <translation>מיפוי פתחה באמצעות UPnP</translation>
+ </message>
+ <message>
+ <source>Proxy &amp;IP:</source>
+ <translation>כתובת ה־IP של המ&amp;תווך:</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>&amp;פתחה:</translation>
+ </message>
+ <message>
+ <source>Port of the proxy (e.g. 9050)</source>
+ <translation>הפתחה של המתווך (למשל 9050)</translation>
+ </message>
+ <message>
+ <source>&amp;Window</source>
+ <translation>&amp;חלון</translation>
+ </message>
+ <message>
+ <source>Show only a tray icon after minimizing the window.</source>
+ <translation>הצג סמל מגש בלבד לאחר מזעור החלון.</translation>
+ </message>
+ <message>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>מ&amp;זעור למגש במקום לשורת המשימות</translation>
+ </message>
+ <message>
+ <source>M&amp;inimize on close</source>
+ <translation>מ&amp;זעור עם סגירה</translation>
+ </message>
+ <message>
+ <source>&amp;Display</source>
+ <translation>ת&amp;צוגה</translation>
+ </message>
+ <message>
+ <source>User Interface &amp;language:</source>
+ <translation>&amp;שפת מנשק המשתמש:</translation>
+ </message>
+ <message>
+ <source>&amp;Unit to show amounts in:</source>
+ <translation>י&amp;חידת מידה להצגת כמויות:</translation>
+ </message>
+ <message>
+ <source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
+ <translation>ניתן לבחור את בררת המחדל ליחידת החלוקה שתוצג במנשק ובעת שליחת מטבעות.</translation>
+ </message>
+ <message>
+ <source>Whether to show coin control features or not.</source>
+ <translation>האם להציג תכונות שליטת מטבע או לא.</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>&amp;אישור</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>&amp;ביטול</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>בררת מחדל</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>ללא</translation>
+ </message>
+ <message>
+ <source>Confirm options reset</source>
+ <translation>אישור איפוס האפשרויות</translation>
+ </message>
+ <message>
+ <source>Client restart required to activate changes.</source>
+ <translation>נדרשת הפעלה מחדש של הלקוח כדי להפעיל את השינויים.</translation>
+ </message>
+ <message>
+ <source>This change would require a client restart.</source>
+ <translation>שינוי זה ידרוש הפעלה מחדש של תכנית הלקוח.</translation>
+ </message>
+ <message>
+ <source>The supplied proxy address is invalid.</source>
+ <translation>כתובת המתווך שסופקה אינה תקינה.</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>טופס</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>המידע המוצג עשוי להיות מיושן. הארנק שלך מסתנכרן באופן אוטומטי עם רשת הביטקוין לאחר יצירת החיבור, אך התהליך טרם הסתיים.</translation>
+ </message>
+ <message>
+ <source>Watch-only:</source>
+ <translation>צפייה בלבד:</translation>
+ </message>
+ <message>
+ <source>Available:</source>
+ <translation>זמין:</translation>
+ </message>
+ <message>
+ <source>Your current spendable balance</source>
+ <translation>היתרה הזמינה הנוכחית</translation>
+ </message>
+ <message>
+ <source>Pending:</source>
+ <translation>בהמתנה:</translation>
+ </message>
+ <message>
+ <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source>
+ <translation>הסכום הכולל של העברות שטרם אושרו ועדיין אינן נספרות בחישוב היתרה הזמינה</translation>
+ </message>
+ <message>
+ <source>Immature:</source>
+ <translation>לא בשל:</translation>
+ </message>
+ <message>
+ <source>Mined balance that has not yet matured</source>
+ <translation>מאזן שנכרה וטרם הבשיל</translation>
+ </message>
+ <message>
+ <source>Balances</source>
+ <translation>מאזנים</translation>
+ </message>
+ <message>
+ <source>Total:</source>
+ <translation>סך הכול:</translation>
+ </message>
+ <message>
+ <source>Your current total balance</source>
+ <translation>סך כל היתרה הנוכחית שלך</translation>
+ </message>
+ <message>
+ <source>Your current balance in watch-only addresses</source>
+ <translation>המאזן הנוכחי שלך בכתובות לקריאה בלבד</translation>
+ </message>
+ <message>
+ <source>Recent transactions</source>
+ <translation>העברות אחרונות</translation>
+ </message>
+ <message>
+ <source>Unconfirmed transactions to watch-only addresses</source>
+ <translation>העברות בלתי מאושרות לכתובות לצפייה בלבד</translation>
+ </message>
+ <message>
+ <source>Mined balance in watch-only addresses that has not yet matured</source>
+ <translation>מאזן לאחר כרייה בכתובות לצפייה בלבד שעדיין לא הבשילו</translation>
+ </message>
+ <message>
+ <source>Current total balance in watch-only addresses</source>
+ <translation>המאזן הכולל הנוכחי בכתובות לצפייה בלבד</translation>
+ </message>
+</context>
+<context>
+ <name>PaymentServer</name>
+ <message>
+ <source>URI handling</source>
+ <translation>תפעול כתובות משאב</translation>
+ </message>
+ <message>
+ <source>Invalid payment address %1</source>
+ <translation>כתובת תשלום שגויה %1</translation>
+ </message>
+ <message>
+ <source>Payment request rejected</source>
+ <translation>בקשת התשלום נדחתה</translation>
+ </message>
+ <message>
+ <source>Payment request network doesn't match client network.</source>
+ <translation>רשת בקשת התשלום אינה תואמת לרשת הלקוח.</translation>
+ </message>
+ <message>
+ <source>Payment request is not initialized.</source>
+ <translation>בקשת התשלום לא החלה.</translation>
+ </message>
+ <message>
+ <source>Requested payment amount of %1 is too small (considered dust).</source>
+ <translation>הסכום על סך %1 הנדרש לתשלום קטן מדי (נחשב לאבק)</translation>
+ </message>
+ <message>
+ <source>Payment request error</source>
+ <translation>שגיאה בבקשת תשלום</translation>
+ </message>
+ <message>
+ <source>Cannot start bitcoin: click-to-pay handler</source>
+ <translation>לא ניתן להתחיל את ביטקוין: טיפול בלחיצה–לתשלום </translation>
+ </message>
+ <message>
+ <source>Payment request fetch URL is invalid: %1</source>
+ <translation>כתובת אחזור בקשת התשלום שגויה: %1</translation>
+ </message>
+ <message>
+ <source>URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source>
+ <translation>לא ניתן לנתח את כתובת המשאב! מצב זה יכול לקרות עקב כתובת ביטקוין שגויה או פרמטרים שגויים בכתובת המשאב.</translation>
+ </message>
+ <message>
+ <source>Payment request file handling</source>
+ <translation>טיפול בקובצי בקשות תשלום</translation>
+ </message>
+ <message>
+ <source>Payment request file cannot be read! This can be caused by an invalid payment request file.</source>
+ <translation>לא ניתן לקרוא את קובץ בקשת התשלום! מצב כזה יכול לקרות בעקבות קובץ בקשת תשלום פגום.</translation>
+ </message>
+ <message>
+ <source>Unverified payment requests to custom payment scripts are unsupported.</source>
+ <translation>בקשות תשלום בלתי מאומתות לסקריפטים לתשלום מותאמים אישית אינן נתמכות.</translation>
+ </message>
+ <message>
+ <source>Refund from %1</source>
+ <translation>החזר מ־%1</translation>
+ </message>
+ <message>
+ <source>Error communicating with %1: %2</source>
+ <translation>שגיאה בתקשורת עם %1: %2</translation>
+ </message>
+ <message>
+ <source>Payment request cannot be parsed!</source>
+ <translation>לא ניתן לפענח את בקשת התשלום!</translation>
+ </message>
+ <message>
+ <source>Bad response from server %1</source>
+ <translation>מענה שגוי משרת %1</translation>
+ </message>
+ <message>
+ <source>Payment acknowledged</source>
+ <translation>התשלום התקבל</translation>
+ </message>
+ <message>
+ <source>Network request error</source>
+ <translation>שגיאת בקשת שרת</translation>
+ </message>
+</context>
+<context>
+ <name>PeerTableModel</name>
+ <message>
+ <source>User Agent</source>
+ <translation>סוכן משתמש</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>זמן המענה</translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>כמות</translation>
+ </message>
+ <message>
+ <source>Enter a Bitcoin address (e.g. %1)</source>
+ <translation>נא להזין כתובת ביטקוין (למשל: %1)</translation>
+ </message>
+ <message>
+ <source>%1 d</source>
+ <translation>%1 ימים</translation>
+ </message>
+ <message>
+ <source>%1 h</source>
+ <translation>%1 שעות</translation>
+ </message>
+ <message>
+ <source>%1 m</source>
+ <translation>%1 דקות</translation>
+ </message>
+ <message>
+ <source>%1 s</source>
+ <translation>%1 שניות</translation>
+ </message>
+ <message>
+ <source>None</source>
+ <translation>ללא</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>לא זמין</translation>
+ </message>
+ <message>
+ <source>%1 ms</source>
+ <translation>%1 מילישניות</translation>
+ </message>
+</context>
+<context>
+ <name>QRImageWidget</name>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;שמירת תמונה…</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Image</source>
+ <translation>ה&amp;עתקת תמונה</translation>
+ </message>
+ <message>
+ <source>Save QR Code</source>
+ <translation>שמירת קוד QR</translation>
+ </message>
+ <message>
+ <source>PNG Image (*.png)</source>
+ <translation>תמונת PNG ‏(‎*.png)</translation>
+ </message>
+</context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>Client name</source>
+ <translation>שם לקוח</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>לא זמין</translation>
+ </message>
+ <message>
+ <source>Client version</source>
+ <translation>גרסת מנשק</translation>
+ </message>
+ <message>
+ <source>&amp;Information</source>
+ <translation>מי&amp;דע</translation>
+ </message>
+ <message>
+ <source>Debug window</source>
+ <translation>חלון ניפוי</translation>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>כללי</translation>
+ </message>
+ <message>
+ <source>Using OpenSSL version</source>
+ <translation>שימוש ב־OpenSSL גרסה</translation>
+ </message>
+ <message>
+ <source>Using BerkeleyDB version</source>
+ <translation>שימוש ב־BerkeleyDB גרסה</translation>
+ </message>
+ <message>
+ <source>Startup time</source>
+ <translation>זמן עלייה</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>רשת</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>שם</translation>
+ </message>
+ <message>
+ <source>Number of connections</source>
+ <translation>מספר חיבורים</translation>
+ </message>
+ <message>
+ <source>Block chain</source>
+ <translation>שרשרת מקטעים</translation>
+ </message>
+ <message>
+ <source>Current number of blocks</source>
+ <translation>מספר המקטעים הנוכחי</translation>
+ </message>
+ <message>
+ <source>Received</source>
+ <translation>התקבלו</translation>
+ </message>
+ <message>
+ <source>Sent</source>
+ <translation>נשלחו</translation>
+ </message>
+ <message>
+ <source>&amp;Peers</source>
+ <translation>&amp;עמיתים</translation>
+ </message>
+ <message>
+ <source>Select a peer to view detailed information.</source>
+ <translation>נא לבחור בעמית כדי להציג מידע מפורט.</translation>
+ </message>
+ <message>
+ <source>Direction</source>
+ <translation>כיוון</translation>
+ </message>
+ <message>
+ <source>Version</source>
+ <translation>גרסה</translation>
+ </message>
+ <message>
+ <source>User Agent</source>
+ <translation>סוכן משתמש</translation>
+ </message>
+ <message>
+ <source>Services</source>
+ <translation>שירותים</translation>
+ </message>
+ <message>
+ <source>Starting Height</source>
+ <translation>גובה התחלתי</translation>
+ </message>
+ <message>
+ <source>Sync Height</source>
+ <translation>גובה הסנכרון</translation>
+ </message>
+ <message>
+ <source>Ban Score</source>
+ <translation>דירוג חסימה</translation>
+ </message>
+ <message>
+ <source>Connection Time</source>
+ <translation>זמן החיבור</translation>
+ </message>
+ <message>
+ <source>Last Send</source>
+ <translation>שליחה אחרונה</translation>
+ </message>
+ <message>
+ <source>Last Receive</source>
+ <translation>קבלה אחרונה</translation>
+ </message>
+ <message>
+ <source>Bytes Sent</source>
+ <translation>בתים שנשלחו</translation>
+ </message>
+ <message>
+ <source>Bytes Received</source>
+ <translation>בתים שהתקבלו</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>זמן המענה</translation>
+ </message>
+ <message>
+ <source>Last block time</source>
+ <translation>זמן המקטע האחרון</translation>
+ </message>
+ <message>
+ <source>&amp;Open</source>
+ <translation>&amp;פתיחה</translation>
+ </message>
+ <message>
+ <source>&amp;Console</source>
+ <translation>מ&amp;סוף בקרה</translation>
+ </message>
+ <message>
+ <source>&amp;Network Traffic</source>
+ <translation>&amp;תעבורת רשת</translation>
+ </message>
+ <message>
+ <source>&amp;Clear</source>
+ <translation>&amp;ניקוי</translation>
+ </message>
+ <message>
+ <source>Totals</source>
+ <translation>סכומים</translation>
+ </message>
+ <message>
+ <source>In:</source>
+ <translation>נכנס:</translation>
+ </message>
+ <message>
+ <source>Out:</source>
+ <translation>יוצא:</translation>
+ </message>
+ <message>
+ <source>Build date</source>
+ <translation>תאריך בנייה</translation>
+ </message>
+ <message>
+ <source>Debug log file</source>
+ <translation>קובץ יומן ניפוי</translation>
+ </message>
+ <message>
+ <source>Clear console</source>
+ <translation>ניקוי מסוף הבקרה</translation>
+ </message>
+ <message>
+ <source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
+ <translation>יש להשתמש בחצים למעלה ולמטה כדי לנווט בהיסטוריה, וב־&lt;b&gt;Ctrl-L&lt;/b&gt; כדי לנקות את המסך.</translation>
+ </message>
+ <message>
+ <source>Type &lt;b&gt;help&lt;/b&gt; for an overview of available commands.</source>
+ <translation>ניתן להקליד &lt;b&gt;help&lt;/b&gt; לקבלת סקירה של הפקודות הזמינות.</translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation>%1 ב׳</translation>
+ </message>
+ <message>
+ <source>%1 KB</source>
+ <translation>%1 ק״ב</translation>
+ </message>
+ <message>
+ <source>%1 MB</source>
+ <translation>%1 מ״ב</translation>
+ </message>
+ <message>
+ <source>%1 GB</source>
+ <translation>%1 ג״ב</translation>
+ </message>
+ <message>
+ <source>via %1</source>
+ <translation>דרך %1</translation>
+ </message>
+ <message>
+ <source>never</source>
+ <translation>לעולם לא</translation>
+ </message>
+ <message>
+ <source>Inbound</source>
+ <translation>תעבורה נכנסת</translation>
+ </message>
+ <message>
+ <source>Outbound</source>
+ <translation>תעבורה יוצאת</translation>
+ </message>
+ <message>
+ <source>Unknown</source>
+ <translation>לא ידוע</translation>
+ </message>
+ <message>
+ <source>Fetching...</source>
+ <translation>מתקבל…</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Amount:</source>
+ <translation>&amp;סכום:</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>ת&amp;ווית:</translation>
+ </message>
+ <message>
+ <source>&amp;Message:</source>
+ <translation>הו&amp;דעה:</translation>
+ </message>
+ <message>
+ <source>Reuse one of the previously used receiving addresses. Reusing addresses has security and privacy issues. Do not use this unless re-generating a payment request made before.</source>
+ <translation>ניתן להשתמש שוב באחת מכתובות הקבלה שכבר נעשה בהן שימוש. לשימוש חוזר בכתובות ישנן השלכות אבטחה ופרטיות. מומלץ שלא להשתמש באפשרות זו למעט יצירה מחדש של בקשת תשלום שנוצרה בעבר.</translation>
+ </message>
+ <message>
+ <source>R&amp;euse an existing receiving address (not recommended)</source>
+ <translation>ש&amp;ימוש &amp;חוזר בכתובת קבלה קיימת (לא מומלץ)</translation>
+ </message>
+ <message>
+ <source>An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network.</source>
+ <translation>הודעת רשות לצירוף לבקשת התשלום שתוצג בעת פתיחת הבקשה. לתשומת לבך: ההודעה לא תישלח עם התשלום ברשת ביטקוין.</translation>
+ </message>
+ <message>
+ <source>An optional label to associate with the new receiving address.</source>
+ <translation>תווית רשות לשיוך עם כתובת הקבלה החדשה.</translation>
+ </message>
+ <message>
+ <source>Use this form to request payments. All fields are &lt;b&gt;optional&lt;/b&gt;.</source>
+ <translation>יש להשתמש בטופס זה כדי לבקש תשלומים. כל השדות הם בגדר &lt;b&gt;רשות&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>An optional amount to request. Leave this empty or zero to not request a specific amount.</source>
+ <translation>סכום כרשות לבקשה. ניתן להשאיר זאת ריק כדי לא לבקש סכום מסוים.</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>ניקוי של כל השדות בטופס.</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation>ניקוי</translation>
+ </message>
+ <message>
+ <source>Requested payments history</source>
+ <translation>היסטוריית בקשות תשלום</translation>
+ </message>
+ <message>
+ <source>&amp;Request payment</source>
+ <translation>&amp;בקשת תשלום</translation>
+ </message>
+ <message>
+ <source>Show the selected request (does the same as double clicking an entry)</source>
+ <translation>הצגת בקשות נבחרות (דומה ללחיצה כפולה על רשומה)</translation>
+ </message>
+ <message>
+ <source>Show</source>
+ <translation>הצגה</translation>
+ </message>
+ <message>
+ <source>Remove the selected entries from the list</source>
+ <translation>הסרת הרשומות הנבחרות מהרשימה</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>הסרה</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>העתקת תווית</translation>
+ </message>
+ <message>
+ <source>Copy message</source>
+ <translation>העתקת הודעה</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>העתקת כמות</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>QR Code</source>
+ <translation>קוד QR</translation>
+ </message>
+ <message>
+ <source>Copy &amp;URI</source>
+ <translation>העתקת &amp;כתובת משאב</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Address</source>
+ <translation>העתקת &amp;כתובת</translation>
+ </message>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;שמירת תמונה…</translation>
+ </message>
+ <message>
+ <source>Request payment to %1</source>
+ <translation>בקשת תשלום לטובת %1</translation>
+ </message>
+ <message>
+ <source>Payment information</source>
+ <translation>מידע על תשלום</translation>
+ </message>
+ <message>
+ <source>URI</source>
+ <translation>כתובת משאב</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>כתובת</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>כמות</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>תווית</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>הודעה</translation>
+ </message>
+ <message>
+ <source>Resulting URI too long, try to reduce the text for label / message.</source>
+ <translation>כתובת המשאב המתקבלת ארוכה מדי, כדאי לנסות לצמצם את הטקסט בתווית / הודעה.</translation>
+ </message>
+ <message>
+ <source>Error encoding URI into QR Code.</source>
+ <translation>שגיאה בקידוד כתובת משאב לקוד QR</translation>
+ </message>
+</context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>תאריך</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>תווית</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>הודעה</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>כמות</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(אין תווית)</translation>
+ </message>
+ <message>
+ <source>(no message)</source>
+ <translation>(אין הודעה)</translation>
+ </message>
+ <message>
+ <source>(no amount)</source>
+ <translation>(אין סכום)</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>שליחת מטבעות</translation>
+ </message>
+ <message>
+ <source>Coin Control Features</source>
+ <translation>תכונות בקרת מטבעות</translation>
+ </message>
+ <message>
+ <source>Inputs...</source>
+ <translation>קלטים…</translation>
+ </message>
+ <message>
+ <source>automatically selected</source>
+ <translation>בבחירה אוטומטית</translation>
+ </message>
+ <message>
+ <source>Insufficient funds!</source>
+ <translation>אין מספיק כספים!</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>כמות:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>בתים:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>סכום:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>עדיפות:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>עמלה:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>לאחר עמלה:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>עודף:</translation>
+ </message>
+ <message>
+ <source>If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address.</source>
+ <translation>אם אפשרות זו מופעלת אך כתובת העודף ריקה או שגויה, העודף יישלח לכתובת חדשה שתיווצר.</translation>
+ </message>
+ <message>
+ <source>Custom change address</source>
+ <translation>כתובת לעודף מותאמת אישית</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>שליחה למספר מוטבים בו־זמנית</translation>
+ </message>
+ <message>
+ <source>Add &amp;Recipient</source>
+ <translation>הוספת &amp;מוטב</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>ניקוי של כל השדות בטופס.</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>אבק:</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>&amp;ניקוי הכול</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>מאזן:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>אישור פעולת השליחה</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>&amp;שליחה</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>אישור שליחת מטבעות</translation>
+ </message>
+ <message>
+ <source>%1 to %2</source>
+ <translation>%1 אל %2</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>העתקת כמות</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>העתקת כמות</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>העתקת עמלה</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>העתקת אחרי עמלה</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>העתקת בתים</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>העתקת עדיפות</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>העתקת עודף</translation>
+ </message>
+ <message>
+ <source>or</source>
+ <translation>או</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>הכמות לתשלום חייבת להיות גדולה מ־0.</translation>
+ </message>
+ <message>
+ <source>The amount exceeds your balance.</source>
+ <translation>הכמות עולה על המאזן שלך.</translation>
+ </message>
+ <message>
+ <source>The total exceeds your balance when the %1 transaction fee is included.</source>
+ <translation>הכמות הכוללת, ובכללה עמלת העברה בסך %1, עולה על המאזן שלך.</translation>
+ </message>
+ <message>
+ <source>Transaction creation failed!</source>
+ <translation>יצירת ההעברה נכשלה!</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>ההעברה נדחתה! מצב כזה עשוי לקרות אם חלק מהמטבעות בארנק שלך כבר הושקעו, כמו למשל עקב שימוש בעותק של wallet.dat והמטבעות הושקעו בעותק אבל לא סומנו כאילו הושקעו דרך כאן.</translation>
+ </message>
+ <message>
+ <source>Warning: Invalid Bitcoin address</source>
+ <translation>אזהרה: כתובת ביטקוין שגויה</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(אין תווית)</translation>
+ </message>
+ <message>
+ <source>Warning: Unknown change address</source>
+ <translation>אזהרה: כתובת עודף בלתי ידועה</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>העתקת אבק</translation>
+ </message>
+ <message>
+ <source>Are you sure you want to send?</source>
+ <translation>האם אכן לשלוח?</translation>
+ </message>
+ <message>
+ <source>added as transaction fee</source>
+ <translation>נוסף כעמלת העברה</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>&amp;כמות:</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>לשלם ל&amp;טובת:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>נא להכניס תווית לכתובת הזאת כדי להוסיף לפנקס הכתובות</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>ת&amp;ווית:</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>בחירת כתובת שהייתה בשימוש</translation>
+ </message>
+ <message>
+ <source>This is a normal payment.</source>
+ <translation>זהו תשלום רגיל.</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to send the payment to</source>
+ <translation>כתובת הביטקוין של המוטב</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>הדבקת כתובת מלוח הגזירים</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Remove this entry</source>
+ <translation>הסרת רשומה זו</translation>
+ </message>
+ <message>
+ <source>Message:</source>
+ <translation>הודעה:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to the list of used addresses</source>
+ <translation>יש להזין תווית עבור כתובת זו כדי להוסיף אותה לרשימת הכתובות בשימוש</translation>
+ </message>
+ <message>
+ <source>A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network.</source>
+ <translation>הודעה שצורפה לביטקוין: כתובת שתאוחסן בהעברה לצורך מעקב מצדך. לתשומת לבך: הודעה זו לא תישלח ברשת הביטקוין.</translation>
+ </message>
+ <message>
+ <source>Pay To:</source>
+ <translation>תשלום לטובת:</translation>
+ </message>
+ <message>
+ <source>Memo:</source>
+ <translation>תזכורת:</translation>
+ </message>
+</context>
+<context>
+ <name>ShutdownWindow</name>
+ <message>
+ <source>Bitcoin Core is shutting down...</source>
+ <translation>ליבת ביטקוין נסגרת…</translation>
+ </message>
+ <message>
+ <source>Do not shut down the computer until this window disappears.</source>
+ <translation>אין לכבות את המחשב עד שחלון זה נעלם.</translation>
+ </message>
+</context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Signatures - Sign / Verify a Message</source>
+ <translation>חתימות - חתימה או אימות של הודעה</translation>
+ </message>
+ <message>
+ <source>&amp;Sign Message</source>
+ <translation>חתימה על הו&amp;דעה</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to sign the message with</source>
+ <translation>כתובת הביטקוין אתה לחתום אתה את ההודעה</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>בחירת כתובת שהייתה בשימוש</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>הדבקת כתובת מלוח הגזירים</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Enter the message you want to sign here</source>
+ <translation>יש להוסיף כאן את ההודעה עליה לחתום</translation>
+ </message>
+ <message>
+ <source>Signature</source>
+ <translation>חתימה</translation>
+ </message>
+ <message>
+ <source>Copy the current signature to the system clipboard</source>
+ <translation>העתקת החתימה הנוכחית ללוח הגזירים</translation>
+ </message>
+ <message>
+ <source>Sign the message to prove you own this Bitcoin address</source>
+ <translation>ניתן לחתום על ההודעה כדי להוכיח שכתובת הביטקוין הזו בבעלותך.</translation>
+ </message>
+ <message>
+ <source>Sign &amp;Message</source>
+ <translation>&amp;חתימה על הודעה</translation>
+ </message>
+ <message>
+ <source>Reset all sign message fields</source>
+ <translation>איפוס כל שדות החתימה על הודעה</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>&amp;ניקוי הכול</translation>
+ </message>
+ <message>
+ <source>&amp;Verify Message</source>
+ <translation>&amp;אימות הודעה</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address the message was signed with</source>
+ <translation>כתובת הביטקוין שאתה נחתמה ההודעה</translation>
+ </message>
+ <message>
+ <source>Verify the message to ensure it was signed with the specified Bitcoin address</source>
+ <translation>ניתן לאמת את ההודעה כדי להבטיח שהיא נחתמה עם כתובת הביטקוין הנתונה</translation>
+ </message>
+ <message>
+ <source>Verify &amp;Message</source>
+ <translation>&amp;אימות הודעה</translation>
+ </message>
+ <message>
+ <source>Reset all verify message fields</source>
+ <translation>איפוס כל שדות אימות ההודעה</translation>
+ </message>
+ <message>
+ <source>Click "Sign Message" to generate signature</source>
+ <translation>יש ללחוץ על „חתימה על ההודעה“ כדי לחולל חתימה</translation>
+ </message>
+ <message>
+ <source>The entered address is invalid.</source>
+ <translation>הכתובת שהוכנסה אינה תקינה.</translation>
+ </message>
+ <message>
+ <source>Please check the address and try again.</source>
+ <translation>נא לבדוק את הכתובת לנסות שנית.</translation>
+ </message>
+ <message>
+ <source>The entered address does not refer to a key.</source>
+ <translation>הכתובת שהוכנסה אינה מתייחסת למפתח.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock was cancelled.</source>
+ <translation>פתיחת הארנק בוטלה.</translation>
+ </message>
+ <message>
+ <source>Private key for the entered address is not available.</source>
+ <translation>המפתח הפרטי עבור הכתובת שהוכנסה אינו זמין.</translation>
+ </message>
+ <message>
+ <source>Message signing failed.</source>
+ <translation>החתימה על ההודעה נכשלה.</translation>
+ </message>
+ <message>
+ <source>Message signed.</source>
+ <translation>ההודעה נחתמה.</translation>
+ </message>
+ <message>
+ <source>The signature could not be decoded.</source>
+ <translation>לא ניתן לפענח את החתימה.</translation>
+ </message>
+ <message>
+ <source>Please check the signature and try again.</source>
+ <translation>נא לבדוק את החתימה ולנסות שנית.</translation>
+ </message>
+ <message>
+ <source>The signature did not match the message digest.</source>
+ <translation>החתימה לא תואמת את תקציר ההודעה.</translation>
+ </message>
+ <message>
+ <source>Message verification failed.</source>
+ <translation>אימות ההודעה נכשל.</translation>
+ </message>
+ <message>
+ <source>Message verified.</source>
+ <translation>ההודעה אומתה.</translation>
+ </message>
+</context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>ליבת ביטקוין</translation>
+ </message>
+ <message>
+ <source>The Bitcoin Core developers</source>
+ <translation>מתכנתי ליבת ביטקוין</translation>
+ </message>
+ <message>
+ <source>[testnet]</source>
+ <translation>[רשת-בדיקה]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ <message>
+ <source>KB/s</source>
+ <translation>ק״ב/ש׳</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>פתוחה עד %1</translation>
+ </message>
+ <message>
+ <source>conflicted</source>
+ <translation>מתנגש</translation>
+ </message>
+ <message>
+ <source>%1/offline</source>
+ <translation>%1/מנותק</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/המתנה לאישור</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 אישורים</translation>
+ </message>
+ <message>
+ <source>Status</source>
+ <translation>מצב</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>תאריך</translation>
+ </message>
+ <message>
+ <source>Source</source>
+ <translation>מקור</translation>
+ </message>
+ <message>
+ <source>Generated</source>
+ <translation>נוצר</translation>
+ </message>
+ <message>
+ <source>From</source>
+ <translation>מאת</translation>
+ </message>
+ <message>
+ <source>To</source>
+ <translation>אל</translation>
+ </message>
+ <message>
+ <source>own address</source>
+ <translation>כתובת עצמית</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>צפייה בלבד</translation>
+ </message>
+ <message>
+ <source>label</source>
+ <translation>תווית</translation>
+ </message>
+ <message>
+ <source>Credit</source>
+ <translation>זיכוי</translation>
+ </message>
+ <message>
+ <source>not accepted</source>
+ <translation>לא התקבל</translation>
+ </message>
+ <message>
+ <source>Debit</source>
+ <translation>חיוב</translation>
+ </message>
+ <message>
+ <source>Total debit</source>
+ <translation>סך כל החיוב</translation>
+ </message>
+ <message>
+ <source>Total credit</source>
+ <translation>סך כל האשראי</translation>
+ </message>
+ <message>
+ <source>Transaction fee</source>
+ <translation>עמלת העברה</translation>
+ </message>
+ <message>
+ <source>Net amount</source>
+ <translation>כמות נקייה</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>הודעה</translation>
+ </message>
+ <message>
+ <source>Comment</source>
+ <translation>הערה</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>מזהה העברה</translation>
+ </message>
+ <message>
+ <source>Merchant</source>
+ <translation>סוחר</translation>
+ </message>
+ <message>
+ <source>Generated coins must mature %1 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.</source>
+ <translation>מטבעות חדשים שנוצרו חייבים להבשיל במשך %1 מקטעים לפני שניתן לנצל אותם. כשמקטע זה נוצר הוא משודר ברשת על מנת שייכנס לשרשרת המקטעים. אם הוא לא ייכנס לשרשרת, מצבו ישתנה ל„לא התקבל“ ולא ניתן יהיה לנצלו. מצב כזה יכול לקרות מדי פעם אם במקרה מפרק אחר יצר מקטע בהבדל של שניות בודדות ממך.</translation>
+ </message>
+ <message>
+ <source>Debug information</source>
+ <translation>מידע ניפוי</translation>
+ </message>
+ <message>
+ <source>Transaction</source>
+ <translation>העברה</translation>
+ </message>
+ <message>
+ <source>Inputs</source>
+ <translation>קלטים</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>כמות</translation>
+ </message>
+ <message>
+ <source>true</source>
+ <translation>אמת</translation>
+ </message>
+ <message>
+ <source>false</source>
+ <translation>שקר</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, טרם שודר בהצלחה</translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>לא ידוע</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>פרטי ההעברה</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>חלונית זו מציגה תיאור מפורט של ההעברה</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>תאריך</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>סוג</translation>
+ </message>
+ <message>
+ <source>Immature (%1 confirmations, will be available after %2)</source>
+ <translation>לא בשל (%1 אישורים, יהיו זמינים לאחר %2)</translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>פתוחה עד %1</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>מאושר (%1 אישורים)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>המקטע הזה לא נקלט על ידי אף מפרק אחר, וכנראה לא יתקבל!</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>נוצר אך לא התקבל</translation>
+ </message>
+ <message>
+ <source>Offline</source>
+ <translation>מנותק</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>תווית</translation>
+ </message>
+ <message>
+ <source>Unconfirmed</source>
+ <translation>ללא אישור</translation>
+ </message>
+ <message>
+ <source>Confirming (%1 of %2 recommended confirmations)</source>
+ <translation>מתקבל אישור (%1 מתוך %2 אישורים מומלצים)</translation>
+ </message>
+ <message>
+ <source>Conflicted</source>
+ <translation>מתנגש</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>התקבל עם</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>התקבל מאת</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>נשלח אל</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>תשלום לעצמך</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>נכרה</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>צפייה בלבד</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(לא זמין)</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>מצב ההעברה. יש להמתין עם הסמן מעל שדה זה כדי לראות את מספר האישורים.</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>התאריך והשעה בה ההעברה הזאת התקבלה.</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>סוג ההעברה.</translation>
+ </message>
+ <message>
+ <source>Whether or not a watch-only address is involved in this transaction.</source>
+ <translation>האם כתובות לצפייה בלבד מעורבות בהעברה זאת או שלא.</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>הכמות שהתווספה או הוסרה מהיתרה.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>הכול</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>היום</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>השבוע</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>החודש</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>החודש שעבר</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>השנה</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>טווח…</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>התקבל עם</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>נשלח אל</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>לעצמך</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>נכרה</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>אחר</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>נא להכניס כתובת או תווית לחיפוש</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>כמות מזערית</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>העתקת כתובת</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>העתקת תווית</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>העתקת כמות</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>העתקת מזהה העברה</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>עריכת תווית</translation>
+ </message>
+ <message>
+ <source>Show transaction details</source>
+ <translation>הצגת פרטי העברה</translation>
+ </message>
+ <message>
+ <source>Export Transaction History</source>
+ <translation>יצוא היסטוריית העברות</translation>
+ </message>
+ <message>
+ <source>Watch-only</source>
+ <translation>צפייה בלבד</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>היצוא נכשל</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the transaction history to %1.</source>
+ <translation>אירעה שגיאה בעת ניסיון לשמור את היסטוריית ההעברות אל %1.</translation>
+ </message>
+ <message>
+ <source>Exporting Successful</source>
+ <translation>היצוא בוצע בהצלחה</translation>
+ </message>
+ <message>
+ <source>The transaction history was successfully saved to %1.</source>
+ <translation>היסטוריית ההעברות נשמרה ל־%1 בהצלחה.</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>קובץ מופרד בפסיקים (‎*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>מאושר</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>תאריך</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>סוג</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>תווית</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>כתובת</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>מזהה</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>טווח:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>אל</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ <message>
+ <source>Unit to show amounts in. Click to select another unit.</source>
+ <translation>יחידת המידה להצגת הסכומים. יש ללחוץ כדי לבחור ביחידת מידה אחרת.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletFrame</name>
+ <message>
+ <source>No wallet has been loaded.</source>
+ <translation>לא נטען ארנק</translation>
+ </message>
+</context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>שליחת מטבעות</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>י&amp;צוא</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>יצוא הנתונים מהלשונית הנוכחית לקובץ</translation>
+ </message>
+ <message>
+ <source>Backup Wallet</source>
+ <translation>גיבוי ארנק</translation>
+ </message>
+ <message>
+ <source>Wallet Data (*.dat)</source>
+ <translation>נתוני ארנק (‎*.dat)</translation>
+ </message>
+ <message>
+ <source>Backup Failed</source>
+ <translation>גיבוי נכשל</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the wallet data to %1.</source>
+ <translation>אירעה שגיאה בעת ניסיון לשמירת נתוני הארנק אל %1.</translation>
+ </message>
+ <message>
+ <source>The wallet data was successfully saved to %1.</source>
+ <translation>נתוני הארנק נשמרו בהצלחה אל %1.</translation>
+ </message>
+ <message>
+ <source>Backup Successful</source>
+ <translation>הגיבוי הושלם בהצלחה</translation>
+ </message>
+</context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>אפשרויות:</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>ציון תיקיית נתונים</translation>
+ </message>
+ <message>
+ <source>Connect to a node to retrieve peer addresses, and disconnect</source>
+ <translation>יש להתחבר למפרק כדי לדלות כתובות עמיתים ואז להתנתק</translation>
+ </message>
+ <message>
+ <source>Specify your own public address</source>
+ <translation>נא לציין את הכתובת הפומבית שלך</translation>
+ </message>
+ <message>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>קבלת פקודות משורת הפקודה ומ־JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>ריצה כסוכן ברקע וקבלת פקודות</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>שימוש ברשת הבדיקה</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
+ <translation>קבלת חיבורים מבחוץ (בררת מחדל: 1 ללא ‎-proxy או ‎-connect)</translation>
+ </message>
+ <message>
+ <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
+ <translation>להתאגד לכתובת נתונה להאזין לה תמיד. יש להשתמש בצורה ‎[host]:port עבור IPv6.</translation>
+ </message>
+ <message>
+ <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
+ <translation>מחיקת כל העברות הארנק ולשחזר רק את החלקים המסוימים בשרשרת המקטעים באמצעות ‎-rescan עם ההפעלה</translation>
+ </message>
+ <message>
+ <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
+ <translation>ביצוע פקודה כאשר העברה בארנק משתנה (%s ב־cmd יוחלף ב־TxID)</translation>
+ </message>
+ <message>
+ <source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source>
+ <translation>זוהי בניית ניסיון טרום-שחרור - השימוש בה על אחריותך - אין להשתמש לצורך כריה או יישומי מסחר</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer. Bitcoin Core is probably already running.</source>
+ <translation>לא ניתן להתאגד אל %s במחשב זה. כנראה שליבת ביטקוין כבר פועלת.</translation>
+ </message>
+ <message>
+ <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>אזהרה: ‎-paytxfee נקבע לערך מאד גבוה! זוהי עמלת הפעולה שתשולם בעת העברת שליחה.</translation>
+ </message>
+ <message>
+ <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source>
+ <translation>אזהרה: נראה שלא כל הרשת מסכימה! נראה שישנם כורים שנתקלים בבעיות.</translation>
+ </message>
+ <message>
+ <source>Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.</source>
+ <translation>אזהרה: נראה שישנה אי־הסכמה בינינו לבין שאר העמיתים שלנו! יתכן שעדיף לשדרג או שכל שאר העמיתים צריכים לשדרג.</translation>
+ </message>
+ <message>
+ <source>Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
+ <translation>אזהרה: שגיאה בקריאת wallet.dat! כל המפתחות נקראו באופן תקין, אך נתוני ההעברות או ספר הכתובות עלולים להיות חסרים או שגויים.</translation>
+ </message>
+ <message>
+ <source>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</source>
+ <translation>אזהרה: הקובץ wallet.dat הושחת, המידע חולץ! קובץ ה־wallet.dat המקורי נשמר בשם wallet.{timestamp}.bak במיקום %s; אם המאזן או ההעברות שגויים עליך לשחזר גיבוי.</translation>
+ </message>
+ <message>
+ <source>(default: 1)</source>
+ <translation>(בררת מחדל: 1)</translation>
+ </message>
+ <message>
+ <source>&lt;category&gt; can be:</source>
+ <translation>&lt;קטגוריה&gt; יכולה להיות:</translation>
+ </message>
+ <message>
+ <source>Attempt to recover private keys from a corrupt wallet.dat</source>
+ <translation>נסה לשחזר מפתחות פרטיים מקובץ wallet.dat מושחת.</translation>
+ </message>
+ <message>
+ <source>Block creation options:</source>
+ <translation>אפשרויות יצירת מקטע:</translation>
+ </message>
+ <message>
+ <source>Connect only to the specified node(s)</source>
+ <translation>התחבר רק לצמתים המצוינים</translation>
+ </message>
+ <message>
+ <source>Connection options:</source>
+ <translation>הגדרות חיבור:</translation>
+ </message>
+ <message>
+ <source>Corrupted block database detected</source>
+ <translation>התגלה מסד נתוני מקטעים לא תקין</translation>
+ </message>
+ <message>
+ <source>Debugging/Testing options:</source>
+ <translation>אפשרויות ניפוי/בדיקה:</translation>
+ </message>
+ <message>
+ <source>Do not load the wallet and disable wallet RPC calls</source>
+ <translation>לא לטעון את הארנק ולנטרל קריאות RPC</translation>
+ </message>
+ <message>
+ <source>Do you want to rebuild the block database now?</source>
+ <translation>האם לבנות מחדש את מסד נתוני המקטעים?</translation>
+ </message>
+ <message>
+ <source>Error initializing block database</source>
+ <translation>שגיאה באתחול מסד נתוני המקטעים</translation>
+ </message>
+ <message>
+ <source>Error initializing wallet database environment %s!</source>
+ <translation>שגיאה באתחול סביבת מסד נתוני הארנקים %s!</translation>
+ </message>
+ <message>
+ <source>Error loading block database</source>
+ <translation>שגיאה בטעינת מסד נתוני המקטעים</translation>
+ </message>
+ <message>
+ <source>Error opening block database</source>
+ <translation>שגיאה בטעינת מסד נתוני המקטעים</translation>
+ </message>
+ <message>
+ <source>Error: Disk space is low!</source>
+ <translation>שגיאה: מעט מקום פנוי בכונן!</translation>
+ </message>
+ <message>
+ <source>Failed to listen on any port. Use -listen=0 if you want this.</source>
+ <translation>האזנה נכשלה בכל פורט. השתמש ב- -listen=0 אם ברצונך בכך.</translation>
+ </message>
+ <message>
+ <source>If &lt;category&gt; is not supplied, output all debugging information.</source>
+ <translation>אם לא סופקה &lt;קטגוריה&gt; יש לייצא את כל פרטי הניפוי.</translation>
+ </message>
+ <message>
+ <source>Importing...</source>
+ <translation>מתבצע יבוא…</translation>
+ </message>
+ <message>
+ <source>Incorrect or no genesis block found. Wrong datadir for network?</source>
+ <translation>מקטע הפתיח הוא שגוי או לא נמצא. תיקיית נתונים שגויה עבור הרשת?</translation>
+ </message>
+ <message>
+ <source>Invalid -onion address: '%s'</source>
+ <translation>כתובת onion- שגויה: '%s'</translation>
+ </message>
+ <message>
+ <source>Not enough file descriptors available.</source>
+ <translation>אין מספיק מידע על הקובץ</translation>
+ </message>
+ <message>
+ <source>Only connect to nodes in network &lt;net&gt; (ipv4, ipv6 or onion)</source>
+ <translation>תמיד להתחבר למפרקים ברשת &lt;net&gt;‏ (ipv4,‏ ipv6 או onion)</translation>
+ </message>
+ <message>
+ <source>Set database cache size in megabytes (%d to %d, default: %d)</source>
+ <translation>הגדרת גודל מטמון מסדי הנתונים במגה בתים (%d עד %d, בררת מחדל: %d)</translation>
+ </message>
+ <message>
+ <source>Set maximum block size in bytes (default: %d)</source>
+ <translation>הגדרת קובץ מקטע מרבי בבתים (בררת מחדל: %d)</translation>
+ </message>
+ <message>
+ <source>Specify wallet file (within data directory)</source>
+ <translation>ציון קובץ ארנק (בתוך תיקיית הנתונים)</translation>
+ </message>
+ <message>
+ <source>Verifying blocks...</source>
+ <translation>המקטעים מאומתים…</translation>
+ </message>
+ <message>
+ <source>Verifying wallet...</source>
+ <translation>הארנק מאומת…</translation>
+ </message>
+ <message>
+ <source>Wallet %s resides outside data directory %s</source>
+ <translation>הארנק %s יושב מחוץ לתיקיית הנתונים %s</translation>
+ </message>
+ <message>
+ <source>Wallet options:</source>
+ <translation>אפשרויות הארנק:</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to change -txindex</source>
+ <translation>עליך לבנות מחדש את מסד הנתונים תוך שימוש ב־‎-reindex על מנת לשנות את ‎-txindex</translation>
+ </message>
+ <message>
+ <source>Imports blocks from external blk000??.dat file</source>
+ <translation>מיובאים מקטעים מקובצי blk000??.dat חיצוניים</translation>
+ </message>
+ <message>
+ <source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source>
+ <translation>הרץ פקודה כאשר ההתראה הרלוונטית מתקבלת או כשאנחנו עדים לפיצול ארוך מאוד (%s בשורת הפקודה יוחלף ע"י ההודעה)</translation>
+ </message>
+ <message>
+ <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source>
+ <translation>אזהרה: נא לבדוק שהתאריך והשעה של המחשב שלך נכונים! אם השעון שלך שגוי ליבת ביטקוין לא תעבוד כראוי.</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -whitebind address: '%s'</source>
+ <translation>לא ניתן לפתור את הכתובת ‎-whitebind:‏ '%s'</translation>
+ </message>
+ <message>
+ <source>Choose data directory on startup (default: 0)</source>
+ <translation>בחירת תיקיית נתונים עם ההפעלה (בררת מחדל: 0)</translation>
+ </message>
+ <message>
+ <source>Connect through SOCKS5 proxy</source>
+ <translation>התחברות דרך מתווך SOCKS5</translation>
+ </message>
+ <message>
+ <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source>
+ <translation>כל הזכויות שמורות (C)‏ 2009‏-%i מתכנתי ליבת ביטקוין</translation>
+ </message>
+ <message>
+ <source>Could not parse -rpcbind value %s as network address</source>
+ <translation>לא ניתן לנתח את הערך של ‎-rpcbind שצוין בתור %s ככתובת רשת</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source>
+ <translation>אירעה שגיאה בטעינת wallet.dat: הארנק דורש גרסה חדשה יותר של ליבת ביטקוין</translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -tor found, use -onion.</source>
+ <translation>שגיאה: נמצא ארגומנט בלתי נתמך ‎-tor, יש להשתמש ב־‎-onion.</translation>
+ </message>
+ <message>
+ <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source>
+ <translation>עמלה (ב־BTC/ק״ב) להוספה להעברות שנשלחות ממך (בררת מחדל: %s)</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>מידע</translation>
+ </message>
+ <message>
+ <source>Initialization sanity check failed. Bitcoin Core is shutting down.</source>
+ <translation>בדיקת התקינות ההתחלתית נכשלה. ליבת ביטקוין תיסגר כעת.</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -minrelaytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>כמות לא תקינה עבור -paytxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -mintxfee=&lt;amount&gt;: '%s'</source>
+ <translation>כמות לא תקינה עבור ‎-mintxfee=&lt;amount&gt;‎:‏ '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s' (must be at least %s)</source>
+ <translation>כמות לא תקינה עבור ‎-paytxfee=&lt;amount&gt;‎:‏ '%s' (חייבת להיות לפחות %s)</translation>
+ </message>
+ <message>
+ <source>Invalid netmask specified in -whitelist: '%s'</source>
+ <translation>מסכת הרשת שצוינה עם ‎-whitelist שגויה: '%s'</translation>
+ </message>
+ <message>
+ <source>Need to specify a port with -whitebind: '%s'</source>
+ <translation>עליך לציין פתחה עם ‎-whitebind:‏ '%s'</translation>
+ </message>
+ <message>
+ <source>Node relay options:</source>
+ <translation>אפשרויות ממסר מפרק:</translation>
+ </message>
+ <message>
+ <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source>
+ <translation>אפשרויות RPC SSL: (נא לעיין בוויקי של ביטקוין לקבלת הנחיות על הגדרת SSL)</translation>
+ </message>
+ <message>
+ <source>RPC server options:</source>
+ <translation>הגדרות שרת RPC</translation>
+ </message>
+ <message>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>שלח מידע דיבאג ועקבה לקונסולה במקום לקובץ debug.log</translation>
+ </message>
+ <message>
+ <source>Set SSL root certificates for payment request (default: -system-)</source>
+ <translation>הגדרות אישורי בסיס של SSL לבקשות תשלום (בררת המחדל: -מערכת-)</translation>
+ </message>
+ <message>
+ <source>Set language, for example "de_DE" (default: system locale)</source>
+ <translation>הגדרת שפה, למשל „he_il“ (בררת מחדל: שפת המערכת)</translation>
+ </message>
+ <message>
+ <source>Show all debugging options (usage: --help -help-debug)</source>
+ <translation>הצגת כל אפשרויות הניפוי (שימוש: ‎--help -help-debug)</translation>
+ </message>
+ <message>
+ <source>Show splash screen on startup (default: 1)</source>
+ <translation>הצגת מסך פתיחה בעת הפעלה (בררת מחדל: 1)</translation>
+ </message>
+ <message>
+ <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source>
+ <translation>כיווץ הקובץ debug.log בהפעלת הלקוח (בררת מחדל: 1 ללא ‎-debug)</translation>
+ </message>
+ <message>
+ <source>Signing transaction failed</source>
+ <translation>החתימה על ההעברה נכשלה</translation>
+ </message>
+ <message>
+ <source>Start minimized</source>
+ <translation>התחלה במצב ממוזער</translation>
+ </message>
+ <message>
+ <source>This is experimental software.</source>
+ <translation>זוהי תכנית נסיונית.</translation>
+ </message>
+ <message>
+ <source>Transaction amount too small</source>
+ <translation>סכום ההעברה קטן מדי</translation>
+ </message>
+ <message>
+ <source>Transaction amounts must be positive</source>
+ <translation>סכומי ההעברות חייבים להיות חיוביים</translation>
+ </message>
+ <message>
+ <source>Transaction too large</source>
+ <translation>סכום ההעברה גדול מדי</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer (bind returned error %s)</source>
+ <translation>לא ניתן להתאגד עם הפתחה %s במחשב זה (פעולת האיגוד החזירה את השגיאה %s)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: 1 when listening)</source>
+ <translation>יש להשתמש ב־UPnP כדי למפות את הפתחה להאזנה (בררת מחדל: 1 בעת האזנה)</translation>
+ </message>
+ <message>
+ <source>Username for JSON-RPC connections</source>
+ <translation>שם משתמש לחיבורי JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Wallet needed to be rewritten: restart Bitcoin Core to complete</source>
+ <translation>יש לכתוב את הארנק מחדש: נא להפעיל את ליבת ביטקוין מחדש כדי להשלים את הפעולה</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>אזהרה</translation>
+ </message>
+ <message>
+ <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source>
+ <translation>אזהרה: הארגומנט שאינו נתמך עוד ‎-benchmark לא הופעל, נא להשתמש ב־‎-debug=bench.</translation>
+ </message>
+ <message>
+ <source>Warning: Unsupported argument -debugnet ignored, use -debug=net.</source>
+ <translation>אזהרה: הארגומנט שאינו נתמך עוד ‎-debugnet לא הופעל, נא להשתמש ב־‎-debug=net.</translation>
+ </message>
+ <message>
+ <source>on startup</source>
+ <translation>עם ההפעלה</translation>
+ </message>
+ <message>
+ <source>wallet.dat corrupt, salvage failed</source>
+ <translation>קובץ wallet.dat מושחת, החילוץ נכשל</translation>
+ </message>
+ <message>
+ <source>Password for JSON-RPC connections</source>
+ <translation>ססמה לחיבורי JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
+ <translation>יש לבצע פקודה זו כשהמקטע הטוב ביותר משתנה (%s בפקודה יוחלף בגיבוב המקטע)</translation>
+ </message>
+ <message>
+ <source>Upgrade wallet to latest format</source>
+ <translation>שדרוג הארנק למבנה העדכני</translation>
+ </message>
+ <message>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>יש לסרוק מחדש את שרשרת המקטעים למציאת העברות חסרות בארנק</translation>
+ </message>
+ <message>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>שימוש ב־OpenSSL (https)‎ עבור חיבורי JSON-RPC</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>הודעת העזרה הזו</translation>
+ </message>
+ <message>
+ <source>Allow DNS lookups for -addnode, -seednode and -connect</source>
+ <translation>הפעלת בדיקת DNS עבור ‎-addnode,‏ ‎-seednode ו־‎-connect</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>הכתובות בטעינה…</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>שגיאה בטעינת הקובץ wallet.dat: הארנק מושחת</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>שגיאה בטעינת הקובץ wallet.dat</translation>
+ </message>
+ <message>
+ <source>Invalid -proxy address: '%s'</source>
+ <translation>כתובת ‎-proxy לא תקינה: '%s'</translation>
+ </message>
+ <message>
+ <source>Unknown network specified in -onlynet: '%s'</source>
+ <translation>רשת לא ידועה צוינה דרך ‎-onlynet:‏ '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -bind address: '%s'</source>
+ <translation>לא ניתן לפתור את הכתובת ‎-bind:‏ '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -externalip address: '%s'</source>
+ <translation>לא ניתן לפתור את הכתובת ‎-externalip:‏ '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>כמות לא תקינה עבור ‎-paytxfee=&lt;amount&gt;‎:‏ '%s'</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>אין מספיק כספים</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>מפתח המקטעים נטען…</translation>
+ </message>
+ <message>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>הוספת מפרק להתחברות ולנסות לשמור על החיבור פתוח</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>הארנק בטעינה…</translation>
+ </message>
+ <message>
+ <source>Cannot downgrade wallet</source>
+ <translation>לא ניתן להחזיר את גרסת הארנק</translation>
+ </message>
+ <message>
+ <source>Cannot write default address</source>
+ <translation>לא ניתן לכתוב את כתובת בררת המחדל</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>סריקה מחדש…</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>טעינה הושלמה</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>שגיאה</translation>
+ </message>
+</context>
+</TS> \ No newline at end of file
diff --git a/src/qt/locale/bitcoin_hi_IN.ts b/src/qt/locale/bitcoin_hi_IN.ts
new file mode 100644
index 0000000000..01e074ffc6
--- /dev/null
+++ b/src/qt/locale/bitcoin_hi_IN.ts
@@ -0,0 +1,861 @@
+<TS language="hi_IN" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Create a new address</source>
+ <translation>नया पता लिखिए !</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>चुनिन्दा पते को सिस्टम क्लिपबोर्ड पर कापी करे !</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>&amp;पता कॉपी करे</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;मिटाए !!</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>&amp;लेबल कॉपी करे </translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>&amp;एडिट</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Comma separated file (*.csv)</translation>
+ </message>
+ </context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>लेबल</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>पता</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(कोई लेबल नही !)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>पहचान शब्द/अक्षर डालिए !</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>नया पहचान शब्द/अक्षर डालिए !</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>दोबारा नया पहचान शब्द/अक्षर डालिए !</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>एनक्रिप्ट वॉलेट !</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>वॉलेट खोलने के आपका वॉलेट पहचान शब्द्‌/अक्षर चाईए !</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>वॉलेट खोलिए</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>वॉलेट डीक्रिप्ट( विकोड) करने के लिए आपका वॉलेट पहचान शब्द्‌/अक्षर चाईए !</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation> डीक्रिप्ट वॉलेट</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>पहचान शब्द/अक्षर बदलिये !</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>वॉलेट एनक्रिपशन को प्रमाणित कीजिए !</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>वॉलेट एनक्रिप्ट हो गया !</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>वॉलेट एनक्रिप्ट नही हुआ!</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>वॉलेट एनक्रिपशन नाकाम हो गया इंटर्नल एरर की वजह से! आपका वॉलेट एनक्रीपत नही हुआ है!</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>आपके द्वारा डाले गये पहचान शब्द/अक्षर मिलते नही है !</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>वॉलेट का लॉक नही खुला !</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>वॉलेट डीक्रिप्ट करने के लिए जो पहचान शब्द/अक्षर डाले गये है वो सही नही है!</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>वॉलेट का डीक्रिप्ट-ष्ण असफल !</translation>
+ </message>
+ </context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>नेटवर्क से समकालिक (मिल) रहा है ...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;विवरण</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>वॉलेट का सामानया विवरण दिखाए !</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp; लेन-देन
+</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>देखिए पुराने लेन-देन के विवरण !</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>बाहर जायें</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>अप्लिकेशन से बाहर निकलना !</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;विकल्प</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>&amp;बैकप वॉलेट</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>पहचान शब्द/अक्षर जो वॉलेट एनक्रिपशन के लिए इस्तेमाल किया है उसे बदलिए!</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>बीटकोइन</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>वॉलेट</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;फाइल</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;सेट्टिंग्स</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>&amp;मदद</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>टैबस टूलबार</translation>
+ </message>
+ <message>
+ <source>%1 behind</source>
+ <translation>%1 पीछे</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>भूल</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>चेतावनी</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>जानकारी</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>नवीनतम</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>भेजी ट्रांजक्शन</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>प्राप्त हुई ट्रांजक्शन</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>वॉलेट एन्क्रिप्टेड है तथा अभी लॉक्ड नहीं है</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>वॉलेट एन्क्रिप्टेड है तथा अभी लॉक्ड है</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ </context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Amount:</source>
+ <translation>राशि :</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>राशि</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>taareek</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>पक्का</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>पता कॉपी करे</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>लेबल कॉपी करे </translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>कॉपी राशि</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(कोई लेबल नही !)</translation>
+ </message>
+ </context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>पता एडिट करना</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>&amp;लेबल</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;पता</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>नया स्वीकार्य पता</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>नया भेजने वाला पता</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>एडिट स्वीकार्य पता </translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>एडिट भेजने वाला पता</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>डाला गया पता "%1" एड्रेस बुक में पहले से ही मोजूद है|</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>वॉलेट को unlock नहीं किया जा सकता|</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>नयी कुंजी का निर्माण असफल रहा|</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ </context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>version</source>
+ <translation>संस्करण</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>खपत :</translation>
+ </message>
+ </context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Error</source>
+ <translation>भूल</translation>
+ </message>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ </context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>विकल्प</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>&amp;ओके</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>&amp;कैन्सल</translation>
+ </message>
+ </context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>फार्म</translation>
+ </message>
+ </context>
+<context>
+ <name>PaymentServer</name>
+ </context>
+<context>
+ <name>PeerTableModel</name>
+ </context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>राशि</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>लागू नही
+</translation>
+ </message>
+ </context>
+<context>
+ <name>QRImageWidget</name>
+ </context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>N/A</source>
+ <translation>लागू नही
+</translation>
+ </message>
+ <message>
+ <source>&amp;Information</source>
+ <translation>जानकारी</translation>
+ </message>
+ </context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>लेबल:</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>लेबल कॉपी करे </translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>कॉपी राशि</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>Address</source>
+ <translation>पता</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>राशि</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>लेबल</translation>
+ </message>
+ </context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>taareek</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>लेबल</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>राशि</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(कोई लेबल नही !)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>सिक्के भेजें|</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>राशि :</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>एक साथ कई प्राप्तकर्ताओं को भेजें</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>बाकी रकम :</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>भेजने की पुष्टि करें</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>सिक्के भेजने की पुष्टि करें</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>कॉपी राशि</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>भेजा गया अमाउंट शुन्य से अधिक होना चाहिए|</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(कोई लेबल नही !)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>अमाउंट:</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>प्राप्तकर्ता:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>आपकी एड्रेस बुक में इस एड्रेस के लिए एक लेबल लिखें</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>लेबल:</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt-A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Clipboard से एड्रेस paste करें</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt-P</translation>
+ </message>
+ </context>
+<context>
+ <name>ShutdownWindow</name>
+ </context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt-A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Clipboard से एड्रेस paste करें</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt-P</translation>
+ </message>
+ <message>
+ <source>Signature</source>
+ <translation>हस्ताक्षर</translation>
+ </message>
+ </context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>[testnet]</source>
+ <translation>[टेस्टनेट]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ </context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>खुला है जबतक %1</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/अपुष्ट</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 पुष्टियाँ</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>taareek</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>राशि</translation>
+ </message>
+ <message>
+ <source>true</source>
+ <translation>सही</translation>
+ </message>
+ <message>
+ <source>false</source>
+ <translation>ग़लत</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, अभी तक सफलतापूर्वक प्रसारित नहीं किया गया है</translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>अज्ञात</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>लेन-देन का विवरण</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation> ये खिड़की आपको लेन-देन का विस्तृत विवरण देगी !</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>taareek</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>टाइप</translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>खुला है जबतक %1</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>पक्के ( %1 पक्का करना)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>यह ब्लॉक किसी भी और नोड को मिला नही है ! शायद यह ब्लॉक कोई भी नोड स्वीकारे गा नही !</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>जेनरेट किया गया किंतु स्वीकारा नही गया !</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>लेबल</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>स्वीकार करना</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>स्वीकार्य ओर से</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>भेजा गया</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>भेजा खुद को भुगतान</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>माइंड</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(लागू नहीं)</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>ट्रांसेक्शन स्तिथि| पुष्टियों की संख्या जानने के लिए इस जगह पर माउस लायें|</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>तारीख तथा समय जब ये ट्रांसेक्शन प्राप्त हुई थी|</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>ट्रांसेक्शन का प्रकार|</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>अमाउंट बैलेंस से निकला या जमा किया गया |</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>सभी</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>आज</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>इस हफ्ते</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>इस महीने</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>पिछले महीने</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>इस साल</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>विस्तार...</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>स्वीकार करना</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>भेजा गया</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>अपनेआप को</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>माइंड</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>अन्य</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>ढूँदने के लिए कृपा करके पता या लेबल टाइप करे !</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>लघुत्तम राशि</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>पता कॉपी करे</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>लेबल कॉपी करे </translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>कॉपी राशि</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>एडिट लेबल</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Comma separated file (*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>पक्का</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>taareek</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>टाइप</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>लेबल</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>पता</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>विस्तार:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>तक</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ </context>
+<context>
+ <name>WalletFrame</name>
+ </context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>सिक्के भेजें|</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>Backup Wallet</source>
+ <translation>बैकप वॉलेट</translation>
+ </message>
+ <message>
+ <source>Wallet Data (*.dat)</source>
+ <translation>वॉलेट डेटा (*.dat)</translation>
+ </message>
+ <message>
+ <source>Backup Failed</source>
+ <translation>बैकप असफल</translation>
+ </message>
+ <message>
+ <source>Backup Successful</source>
+ <translation>बैकप सफल</translation>
+ </message>
+</context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>विकल्प:</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>डेटा डायरेक्टरी बताएं </translation>
+ </message>
+ <message>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>बैकग्राउंड में डेमॉन बन कर रन करे तथा कमांड्स स्वीकार करें </translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>टेस्ट नेटवर्क का इस्तेमाल करे </translation>
+ </message>
+ <message>
+ <source>Verifying blocks...</source>
+ <translation>ब्लॉक्स जाँचे जा रहा है...</translation>
+ </message>
+ <message>
+ <source>Verifying wallet...</source>
+ <translation>वॉलेट जाँचा जा रहा है...</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>जानकारी</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>चेतावनी</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>पता पुस्तक आ रही है...</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>ब्लॉक इंडेक्स आ रहा है...</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>वॉलेट आ रहा है...</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>रि-स्केनी-इंग...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>लोड हो गया|</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>भूल</translation>
+ </message>
+</context>
+</TS> \ 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 0000000000..74d380ec2b
--- /dev/null
+++ b/src/qt/locale/bitcoin_hr.ts
@@ -0,0 +1,1904 @@
+<TS language="hr" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Right-click to edit address or label</source>
+ <translation>Desni klik za uređivanje adresa i oznaka</translation>
+ </message>
+ <message>
+ <source>Create a new address</source>
+ <translation>Dodajte novu adresu</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>&amp;Nova</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Kopiraj trenutno odabranu adresu u međuspremnik</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>&amp;Kopiraj</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>&amp;Zatvori</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>&amp;Kopiraj adresu</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>Brisanje trenutno odabrane adrese s popisa.</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Izvoz podataka iz trenutnog lista u datoteku</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Izvozi</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>Iz&amp;briši</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>Odaberi adresu na koju šalješ novac</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>Odaberi adresu na koju primaš novac</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>&amp;Odaberi</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>Adresa za slanje</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>Adresa za primanje</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>Ovo su vaše Bitcoin adrese za slanje novca. Uvijek provjerite iznos i adresu primatelja prije slanja novca.</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>Ovo su vaše Bitcoin adrese za primanje novca. Preporučamo da koristite novu adresu za primanje za svaku transakciju.</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>Kopiraj &amp;oznaku</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>&amp;Uredi</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>Izvezi listu adresa</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Datoteka podataka odvojenih zarezima (*.csv)</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Izvoz neuspješan</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the address list to %1. Please try again.</source>
+ <translation>Došlo je do pogreške kod spremanja liste adresa na %1. Molimo pokušajte ponovno.</translation>
+ </message>
+</context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Oznaka</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adresa</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(bez oznake)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Passphrase Dialog</source>
+ <translation>Dijalog lozinke</translation>
+ </message>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Unesite lozinku</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Nova lozinka</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Ponovite novu lozinku</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>Šifriranje novčanika</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>Ova operacija treba lozinku vašeg novčanika kako bi se novčanik otključao.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Otključaj novčanik</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>Ova operacija treba lozinku vašeg novčanika kako bi se novčanik dešifrirao.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>Dešifriranje novčanika.</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>Promjena lozinke</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>Potvrdi šifriranje novčanika</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>Upozorenje: Ako šifrirate vaš novčanik i izgubite lozinku, &lt;b&gt;IZGUBIT ĆETE SVE SVOJE BITCOINE!&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>Jeste li sigurni da želite šifrirati svoj novčanik?</translation>
+ </message>
+ <message>
+ <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
+ <translation>VAŽNO: Sve prethodne pričuve vašeg novčanika trebale bi biti zamijenjene novo stvorenom, šifriranom datotekom novčanika. Zbog sigurnosnih razloga, prethodne pričuve nešifriranog novčanika će postati beskorisne čim počnete koristiti novi, šifrirani novčanik.</translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>Upozorenje: Tipka Caps Lock je uključena!</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>Novčanik šifriran</translation>
+ </message>
+ <message>
+ <source>Enter the new passphrase to the wallet.&lt;br/&gt;Please use a passphrase of &lt;b&gt;ten or more random characters&lt;/b&gt;, or &lt;b&gt;eight or more words&lt;/b&gt;.</source>
+ <translation>Unesite novu lozinku za novčanik. &lt;br/&gt;Molimo Vas da koristite zaporku od &lt;b&gt;deset ili više slučajnih znakova&lt;/b&gt;, ili &lt;b&gt;osam ili više riječi.&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Enter the old passphrase and new passphrase to the wallet.</source>
+ <translation>Unesite staru i novu lozinku za novčanik.</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>Šifriranje novčanika nije uspjelo</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>Šifriranje novčanika nije uspjelo zbog interne pogreške. Vaš novčanik nije šifriran.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>Priložene lozinke se ne podudaraju.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>Otključavanje novčanika nije uspjelo</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>Lozinka za dešifriranje novčanika nije točna.</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>Dešifriranje novčanika nije uspjelo</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>Lozinka novčanika je uspješno promijenjena.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>P&amp;otpišite poruku...</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>Usklađivanje s mrežom ...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;Pregled</translation>
+ </message>
+ <message>
+ <source>Node</source>
+ <translation>Čvor</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>Prikaži opći pregled novčanika</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Transakcije</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>Pretraži povijest transakcija</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>&amp;Izlaz</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>Izlazak iz programa</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>Više o &amp;Qt</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>Prikaži informacije o Qt</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>Pos&amp;tavke...</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>Ši&amp;friraj novčanik...</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>Spremi &amp;kopiju novčanika...</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>Promjena &amp;lozinke...</translation>
+ </message>
+ <message>
+ <source>&amp;Sending addresses...</source>
+ <translation>Adrese za &amp;slanje</translation>
+ </message>
+ <message>
+ <source>&amp;Receiving addresses...</source>
+ <translation>Adrese za &amp;primanje</translation>
+ </message>
+ <message>
+ <source>Open &amp;URI...</source>
+ <translation>Otvori &amp;URI...</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core client</source>
+ <translation>Bitcoin Core klijent</translation>
+ </message>
+ <message>
+ <source>Importing blocks from disk...</source>
+ <translation>Importiranje blokova sa diska...</translation>
+ </message>
+ <message>
+ <source>Reindexing blocks on disk...</source>
+ <translation>Re-indeksiranje blokova na disku...</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>Slanje novca na bitcoin adresu</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>Napravite sigurnosnu kopiju novčanika na drugoj lokaciji</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Promijenite lozinku za šifriranje novčanika</translation>
+ </message>
+ <message>
+ <source>&amp;Debug window</source>
+ <translation>Konzola za dijagnostiku</translation>
+ </message>
+ <message>
+ <source>Open debugging and diagnostic console</source>
+ <translation>Otvori konzolu za dijagnostiku</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>&amp;Potvrdite poruku...</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>Novčanik</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>&amp;Pošalji</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>Pri&amp;mi</translation>
+ </message>
+ <message>
+ <source>Show information about Bitcoin Core</source>
+ <translation>Prikaži informacije o programu Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>Po&amp;kaži / Sakrij</translation>
+ </message>
+ <message>
+ <source>Show or hide the main Window</source>
+ <translation>Prikaži ili sakrij glavni prozor</translation>
+ </message>
+ <message>
+ <source>Encrypt the private keys that belong to your wallet</source>
+ <translation>Šifriranje privatnih ključeva koji u novčaniku</translation>
+ </message>
+ <message>
+ <source>Sign messages with your Bitcoin addresses to prove you own them</source>
+ <translation>Poruku potpišemo s bitcoin adresom, kako bi dokazali vlasništvo nad tom adresom</translation>
+ </message>
+ <message>
+ <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source>
+ <translation>Provjeravanje poruke, kao dokaz, da je potpisana navedenom bitcoin adresom</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;Datoteka</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;Postavke</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>&amp;Pomoć</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>Traka kartica</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Request payments (generates QR codes and bitcoin: URIs)</source>
+ <translation>Zatraži uplatu (stvara QR kod i bitcoin: URI adresu)</translation>
+ </message>
+ <message>
+ <source>&amp;About Bitcoin Core</source>
+ <translation>&amp;O programu Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Modify configuration options for Bitcoin Core</source>
+ <translation>Promijeni postavke programa</translation>
+ </message>
+ <message>
+ <source>Show the list of used sending addresses and labels</source>
+ <translation>Prikaži popis korištenih adresa i oznaka za slanje novca</translation>
+ </message>
+ <message>
+ <source>Show the list of used receiving addresses and labels</source>
+ <translation>Prikaži popis korištenih adresa i oznaka za primanje novca</translation>
+ </message>
+ <message>
+ <source>Open a bitcoin: URI or payment request</source>
+ <translation>Otvori bitcoin: URI adresu ili zahtjev za uplatu</translation>
+ </message>
+ <message>
+ <source>&amp;Command-line options</source>
+ <translation>Opcije &amp;naredbene linije</translation>
+ </message>
+ <message>
+ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
+ <translation>Ispis svih opcija naredbene linije programa sa kratkim opisom</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n active connection(s) to Bitcoin network</source>
+ <translation><numerusform>%n aktivna veza na Bitcoin mrežu</numerusform><numerusform>%n aktivnih veza na Bitcoin mrežu</numerusform><numerusform>%n aktivnih veza na Bitcoin mrežu</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>Processed %n block(s) of transaction history.</source>
+ <translation><numerusform>Obrađen %n blok povijesti transakcije.</numerusform><numerusform>Obrađeno %n bloka povijesti transakcije.</numerusform><numerusform>Obrađeno %n blokova povijesti transakcije.</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n hour(s)</source>
+ <translation><numerusform>%n sat</numerusform><numerusform>%n sata</numerusform><numerusform>%n sati</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n day(s)</source>
+ <translation><numerusform>%n dan</numerusform><numerusform>%n dana</numerusform><numerusform>%n dana</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n week(s)</source>
+ <translation><numerusform>%n tjedan</numerusform><numerusform>%n tjedna</numerusform><numerusform>%n tjedana</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 and %2</source>
+ <translation>%1 i %2</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n year(s)</source>
+ <translation><numerusform>%n godina</numerusform><numerusform>%n godine</numerusform><numerusform>%n godina</numerusform></translation>
+ </message>
+ <message>
+ <source>Last received block was generated %1 ago.</source>
+ <translation>Zadnji primljeni blok je bio ustvaren prije %1.</translation>
+ </message>
+ <message>
+ <source>Transactions after this will not yet be visible.</source>
+ <translation>Transakcije izvršene za tim blokom nisu još prikazane.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Greška</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Upozorenje</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Informacija</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>Ažurno</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>Ažuriranje...</translation>
+ </message>
+ <message>
+ <source>Date: %1
+</source>
+ <translation>Datum: %1
+</translation>
+ </message>
+ <message>
+ <source>Amount: %1
+</source>
+ <translation>Iznos: %1
+</translation>
+ </message>
+ <message>
+ <source>Type: %1
+</source>
+ <translation>Vrsta: %1
+</translation>
+ </message>
+ <message>
+ <source>Label: %1
+</source>
+ <translation>Oznaka: %1
+</translation>
+ </message>
+ <message>
+ <source>Address: %1
+</source>
+ <translation>Adresa: %1
+</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>Poslana transakcija</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>Dolazna transakcija</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>Novčanik je &lt;b&gt;šifriran&lt;/b&gt; i trenutno &lt;b&gt;otključan&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>Novčanik je &lt;b&gt;šifriran&lt;/b&gt; i trenutno &lt;b&gt;zaključan&lt;/b&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ </context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Coin Selection</source>
+ <translation>Izbor ulaza transakcije</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Količina:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Bajtova:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Iznos:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Prioriteta:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Naknada:</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Prah:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Vraćeno:</translation>
+ </message>
+ <message>
+ <source>(un)select all</source>
+ <translation>Izaberi sve/ništa</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Iznos</translation>
+ </message>
+ <message>
+ <source>Received with label</source>
+ <translation>Primljeno pod oznakom</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>Primljeno na adresu</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Datum</translation>
+ </message>
+ <message>
+ <source>Confirmations</source>
+ <translation>Broj potvrda</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Potvrđeno</translation>
+ </message>
+ <message>
+ <source>Priority</source>
+ <translation>Prioriteta</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Kopiraj adresu</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Kopiraj oznaku</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopiraj iznos</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Kopiraj ID transakcije</translation>
+ </message>
+ <message>
+ <source>highest</source>
+ <translation>najviša</translation>
+ </message>
+ <message>
+ <source>higher</source>
+ <translation>viša</translation>
+ </message>
+ <message>
+ <source>high</source>
+ <translation>visoka</translation>
+ </message>
+ <message>
+ <source>medium-high</source>
+ <translation>srednje visoka</translation>
+ </message>
+ <message>
+ <source>medium</source>
+ <translation>srednja</translation>
+ </message>
+ <message>
+ <source>low-medium</source>
+ <translation>srednje niska</translation>
+ </message>
+ <message>
+ <source>low</source>
+ <translation>niska</translation>
+ </message>
+ <message>
+ <source>lower</source>
+ <translation>niža</translation>
+ </message>
+ <message>
+ <source>lowest</source>
+ <translation>najniža</translation>
+ </message>
+ <message>
+ <source>This label turns red if the transaction size is greater than 1000 bytes.</source>
+ <translation>Oznaka postane crvene boje ako je transakcija veća od 1000 bajtova.</translation>
+ </message>
+ <message>
+ <source>This label turns red if the priority is smaller than "medium".</source>
+ <translation>Oznaka postane crvene boje ako je prioriteta transakcije niža od "srednja"</translation>
+ </message>
+ <message>
+ <source>This label turns red if any recipient receives an amount smaller than %1.</source>
+ <translation>Oznaka postane crvene boje ako je iznos manji od %1</translation>
+ </message>
+ <message>
+ <source>yes</source>
+ <translation>da</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>ne</translation>
+ </message>
+ <message>
+ <source>Transactions with higher priority are more likely to get included into a block.</source>
+ <translation>Transakcije više prioritete imaju veću vjerojatnost da budu prije dodane u novi blok.</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(bez oznake)</translation>
+ </message>
+ </context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>Uredi adresu</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>&amp;Oznaka</translation>
+ </message>
+ <message>
+ <source>The label associated with this address list entry</source>
+ <translation>Oznaka bitcoin adrese</translation>
+ </message>
+ <message>
+ <source>The address associated with this address list entry. This can only be modified for sending addresses.</source>
+ <translation>Bitcoin adresa. Izmjene adrese su moguće samo za adrese za slanje.</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;Adresa</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>Nova adresa za primanje</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>Nova adresa za slanje</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>Uredi adresu za primanje</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>Uredi adresu za slanje</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>Upisana adresa "%1" je već u adresaru.</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is not a valid Bitcoin address.</source>
+ <translation>Upisana adresa "%1" nije valjana bitcoin adresa.</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>Ne mogu otključati novčanik.</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>Stvaranje novog ključa nije uspjelo.</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ <message>
+ <source>A new data directory will be created.</source>
+ <translation>Stvoren će biti novi direktorij za podatke.</translation>
+ </message>
+ <message>
+ <source>name</source>
+ <translation>ime</translation>
+ </message>
+ <message>
+ <source>Cannot create data directory here.</source>
+ <translation>Nije moguće stvoriti direktorij za podatke na tom mjestu.</translation>
+ </message>
+</context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>verzija</translation>
+ </message>
+ <message>
+ <source>(%1-bit)</source>
+ <translation>(%1-bit)</translation>
+ </message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>O programu Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Command-line options</source>
+ <translation>Opcije programa u naredbenoj liniji</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>Upotreba:</translation>
+ </message>
+ <message>
+ <source>command-line options</source>
+ <translation>opcije programa u naredbenoj liniji</translation>
+ </message>
+</context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Welcome</source>
+ <translation>Dobrodošli</translation>
+ </message>
+ <message>
+ <source>Welcome to Bitcoin Core.</source>
+ <translation>Dobrodošli u programu Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Greška</translation>
+ </message>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ <message>
+ <source>Open URI</source>
+ <translation>Otvori URI adresu</translation>
+ </message>
+ <message>
+ <source>Open payment request from URI or file</source>
+ <translation>Otvori zahtjev za plaćanje iz URI adrese ili datoteke</translation>
+ </message>
+ <message>
+ <source>URI:</source>
+ <translation>URI:</translation>
+ </message>
+ <message>
+ <source>Select payment request file</source>
+ <translation>Izaberi datoteku zahtjeva za plaćanje</translation>
+ </message>
+ <message>
+ <source>Select payment request file to open</source>
+ <translation>Izaberi datoteku zahtjeva za plaćanje</translation>
+ </message>
+</context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>Postavke</translation>
+ </message>
+ <message>
+ <source>&amp;Main</source>
+ <translation>&amp;Glavno</translation>
+ </message>
+ <message>
+ <source>Size of &amp;database cache</source>
+ <translation>Veličina predmemorije baze podataka</translation>
+ </message>
+ <message>
+ <source>MB</source>
+ <translation>MB</translation>
+ </message>
+ <message>
+ <source>Number of script &amp;verification threads</source>
+ <translation>Broj CPU niti za verifikaciju transakcija</translation>
+ </message>
+ <message>
+ <source>Allow incoming connections</source>
+ <translation>Dozvoli povezivanje izvana</translation>
+ </message>
+ <message>
+ <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
+ <translation>IP adresa proxy servera (npr. IPv4: 127.0.0.1 / IPv6: ::1)</translation>
+ </message>
+ <message>
+ <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source>
+ <translation>Minimizirati aplikaciju umjesto zatvoriti, kada se zatvori prozor. Kada je ova opcija omogućena, aplikacija će biti zatvorena tek nakon odabira naredbe Izlaz u izborniku.</translation>
+ </message>
+ <message>
+ <source>Reset all client options to default.</source>
+ <translation>Nastavi sve postavke programa na početne vrijednosti.</translation>
+ </message>
+ <message>
+ <source>&amp;Reset Options</source>
+ <translation>Po&amp;nastavi postavke</translation>
+ </message>
+ <message>
+ <source>&amp;Network</source>
+ <translation>&amp;Mreža</translation>
+ </message>
+ <message>
+ <source>Automatically start Bitcoin Core after logging in to the system.</source>
+ <translation>Program se automatski pokrene po prijavi u sustav.</translation>
+ </message>
+ <message>
+ <source>&amp;Start Bitcoin Core on system login</source>
+ <translation>&amp;Pokreni program kod prijave u sustav</translation>
+ </message>
+ <message>
+ <source>W&amp;allet</source>
+ <translation>&amp;Novčanik</translation>
+ </message>
+ <message>
+ <source>&amp;Spend unconfirmed change</source>
+ <translation>&amp;Trošenje nepotvrđenih vraćenih iznosa</translation>
+ </message>
+ <message>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>Automatski otvori port Bitcoin klijenta na ruteru. To radi samo ako ruter podržava UPnP i ako je omogućen.</translation>
+ </message>
+ <message>
+ <source>Map port using &amp;UPnP</source>
+ <translation>Mapiraj port koristeći &amp;UPnP</translation>
+ </message>
+ <message>
+ <source>Proxy &amp;IP:</source>
+ <translation>Proxy &amp;IP:</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>&amp;Vrata:</translation>
+ </message>
+ <message>
+ <source>Port of the proxy (e.g. 9050)</source>
+ <translation>Proxy vrata (npr. 9050)</translation>
+ </message>
+ <message>
+ <source>&amp;Window</source>
+ <translation>&amp;Prozor</translation>
+ </message>
+ <message>
+ <source>Show only a tray icon after minimizing the window.</source>
+ <translation>Prikaži samo ikonu u sistemskoj traci nakon minimiziranja prozora</translation>
+ </message>
+ <message>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>&amp;Minimiziraj u sistemsku traku umjesto u traku programa</translation>
+ </message>
+ <message>
+ <source>M&amp;inimize on close</source>
+ <translation>M&amp;inimiziraj kod zatvaranja</translation>
+ </message>
+ <message>
+ <source>&amp;Display</source>
+ <translation>&amp;Prikaz</translation>
+ </message>
+ <message>
+ <source>User Interface &amp;language:</source>
+ <translation>Jezi&amp;k sučelja:</translation>
+ </message>
+ <message>
+ <source>&amp;Unit to show amounts in:</source>
+ <translation>&amp;Jedinica za prikaz iznosa:</translation>
+ </message>
+ <message>
+ <source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
+ <translation>Izaberite željeni najmanji dio bitcoina koji će biti prikazan u sučelju i koji će se koristiti za plaćanje.</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>&amp;U redu</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>&amp;Odustani</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>standardne vrijednosti</translation>
+ </message>
+ <message>
+ <source>The supplied proxy address is invalid.</source>
+ <translation>Priložena proxy adresa je nevažeća.</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>Oblik</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>Prikazani podatci mogu biti zastarjeli. Vaš novčanik se automatski sinkronizira s Bitcoin mrežom kada je veza uspostavljena, ali taj proces još nije završen.</translation>
+ </message>
+ <message>
+ <source>Total:</source>
+ <translation>Ukupno:</translation>
+ </message>
+ </context>
+<context>
+ <name>PaymentServer</name>
+ <message>
+ <source>URI handling</source>
+ <translation>URI upravljanje</translation>
+ </message>
+ </context>
+<context>
+ <name>PeerTableModel</name>
+ </context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>Iznos</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>N/A</translation>
+ </message>
+ </context>
+<context>
+ <name>QRImageWidget</name>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Spremi sliku...</translation>
+ </message>
+ <message>
+ <source>Save QR Code</source>
+ <translation>Spremi QR kod</translation>
+ </message>
+ </context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>Client name</source>
+ <translation>Ime klijenta</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>N/A</translation>
+ </message>
+ <message>
+ <source>Client version</source>
+ <translation>Verzija klijenta</translation>
+ </message>
+ <message>
+ <source>&amp;Information</source>
+ <translation>&amp;Informacije</translation>
+ </message>
+ <message>
+ <source>Using OpenSSL version</source>
+ <translation>OpenSSL verzija u upotrebi</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Mreža</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>Ime</translation>
+ </message>
+ <message>
+ <source>Number of connections</source>
+ <translation>Broj veza</translation>
+ </message>
+ <message>
+ <source>Block chain</source>
+ <translation>Lanac blokova</translation>
+ </message>
+ <message>
+ <source>Current number of blocks</source>
+ <translation>Trenutni broj blokova</translation>
+ </message>
+ <message>
+ <source>Received</source>
+ <translation>Primljeno</translation>
+ </message>
+ <message>
+ <source>Sent</source>
+ <translation>Poslano</translation>
+ </message>
+ <message>
+ <source>Direction</source>
+ <translation>Smjer</translation>
+ </message>
+ <message>
+ <source>Version</source>
+ <translation>Verzija</translation>
+ </message>
+ <message>
+ <source>Connection Time</source>
+ <translation>Trajanje veze</translation>
+ </message>
+ <message>
+ <source>Bytes Sent</source>
+ <translation>Bajtova poslano</translation>
+ </message>
+ <message>
+ <source>Bytes Received</source>
+ <translation>Bajtova primljeno</translation>
+ </message>
+ <message>
+ <source>Last block time</source>
+ <translation>Posljednje vrijeme bloka</translation>
+ </message>
+ <message>
+ <source>&amp;Open</source>
+ <translation>&amp;Otvori</translation>
+ </message>
+ <message>
+ <source>&amp;Console</source>
+ <translation>&amp;Konzola</translation>
+ </message>
+ <message>
+ <source>&amp;Network Traffic</source>
+ <translation>&amp;Mrežni promet</translation>
+ </message>
+ <message>
+ <source>Totals</source>
+ <translation>Ukupno:</translation>
+ </message>
+ <message>
+ <source>Clear console</source>
+ <translation>Očisti konzolu</translation>
+ </message>
+ <message>
+ <source>Welcome to the Bitcoin Core RPC console.</source>
+ <translation>Dobrodošli u Bitcoin RPC konzolu.</translation>
+ </message>
+ <message>
+ <source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
+ <translation>Koristite tipke gore i dolje za izbor već korištenih naredbi. &lt;b&gt;Ctrl-L&lt;/b&gt; kako bi očistili ekran i povijest naredbi.</translation>
+ </message>
+ <message>
+ <source>Unknown</source>
+ <translation>Nepoznato</translation>
+ </message>
+ </context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Amount:</source>
+ <translation>&amp;Iznos:</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Oznaka:</translation>
+ </message>
+ <message>
+ <source>&amp;Message:</source>
+ <translation>&amp;Poruka:</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Obriši sva polja</translation>
+ </message>
+ <message>
+ <source>&amp;Request payment</source>
+ <translation>&amp;Zatraži plaćanje</translation>
+ </message>
+ <message>
+ <source>Show</source>
+ <translation>Pokaži</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Kopiraj oznaku</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopiraj iznos</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>QR Code</source>
+ <translation>QR kôd</translation>
+ </message>
+ <message>
+ <source>Copy &amp;URI</source>
+ <translation>Kopiraj &amp;URI</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Address</source>
+ <translation>Kopiraj &amp;adresu</translation>
+ </message>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Spremi sliku...</translation>
+ </message>
+ <message>
+ <source>URI</source>
+ <translation>URI</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adresa</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Iznos</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Oznaka</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Poruka</translation>
+ </message>
+ <message>
+ <source>Resulting URI too long, try to reduce the text for label / message.</source>
+ <translation>URI je predug, probajte skratiti tekst za naslov / poruku.</translation>
+ </message>
+ <message>
+ <source>Error encoding URI into QR Code.</source>
+ <translation>Greška kod kodiranja URI adrese u QR kod.</translation>
+ </message>
+</context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Datum</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Oznaka</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Poruka</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Iznos</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(bez oznake)</translation>
+ </message>
+ <message>
+ <source>(no message)</source>
+ <translation>(bez poruke)</translation>
+ </message>
+ <message>
+ <source>(no amount)</source>
+ <translation>(bez iznosa)</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Slanje novca</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Količina:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Bajtova:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Iznos:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Prioriteta:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Naknada:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Vraćeno:</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>Pošalji novce većem broju primatelja u jednoj transakciji</translation>
+ </message>
+ <message>
+ <source>Add &amp;Recipient</source>
+ <translation>&amp;Dodaj primatelja</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Obriši sva polja</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Prah:</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Obriši &amp;sve</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>Stanje:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>Potvrdi akciju slanja</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>&amp;Pošalji</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>Potvrdi slanje novca</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopiraj iznos</translation>
+ </message>
+ <message>
+ <source>or</source>
+ <translation>ili</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>Iznos mora biti veći od 0.</translation>
+ </message>
+ <message>
+ <source>The amount exceeds your balance.</source>
+ <translation>Iznos je veći od raspoložljivog stanja novčanika.</translation>
+ </message>
+ <message>
+ <source>The total exceeds your balance when the %1 transaction fee is included.</source>
+ <translation>Iznos je veći od stanja novčanika kad se doda naknada za transakcije od %1.</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(bez oznake)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>&amp;Iznos:</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>&amp;Primatelj plaćanja:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Unesite oznaku za ovu adresu kako bi ju dodali u vaš adresar</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Oznaka:</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Zalijepi adresu iz međuspremnika</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Message:</source>
+ <translation>Poruka:</translation>
+ </message>
+ <message>
+ <source>Pay To:</source>
+ <translation>Primatelj plaćanja:</translation>
+ </message>
+ </context>
+<context>
+ <name>ShutdownWindow</name>
+ </context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>&amp;Sign Message</source>
+ <translation>&amp;Potpišite poruku</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Zalijepi adresu iz međuspremnika</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Enter the message you want to sign here</source>
+ <translation>Upišite poruku koju želite potpisati ovdje</translation>
+ </message>
+ <message>
+ <source>Signature</source>
+ <translation>Potpis</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Obriši &amp;sve</translation>
+ </message>
+ <message>
+ <source>&amp;Verify Message</source>
+ <translation>&amp;Potvrdite poruku</translation>
+ </message>
+ <message>
+ <source>Wallet unlock was cancelled.</source>
+ <translation>Otključavanje novčanika je otkazano.</translation>
+ </message>
+ <message>
+ <source>Message signed.</source>
+ <translation>Poruka je potpisana.</translation>
+ </message>
+ </context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>[testnet]</source>
+ <translation>[testnet]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ </context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>Otvoren do %1</translation>
+ </message>
+ <message>
+ <source>%1/offline</source>
+ <translation>%1 nije dostupan</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/nepotvrđeno</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 potvrda</translation>
+ </message>
+ <message>
+ <source>Status</source>
+ <translation>Status</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Datum</translation>
+ </message>
+ <message>
+ <source>Source</source>
+ <translation>Izvor</translation>
+ </message>
+ <message>
+ <source>Generated</source>
+ <translation>Generiran</translation>
+ </message>
+ <message>
+ <source>From</source>
+ <translation>Od</translation>
+ </message>
+ <message>
+ <source>To</source>
+ <translation>Za</translation>
+ </message>
+ <message>
+ <source>own address</source>
+ <translation>vlastita adresa</translation>
+ </message>
+ <message>
+ <source>label</source>
+ <translation>oznaka</translation>
+ </message>
+ <message>
+ <source>Credit</source>
+ <translation>Uplaćeno</translation>
+ </message>
+ <message>
+ <source>not accepted</source>
+ <translation>Nije prihvaćeno</translation>
+ </message>
+ <message>
+ <source>Debit</source>
+ <translation>Zaduženje</translation>
+ </message>
+ <message>
+ <source>Transaction fee</source>
+ <translation>Naknada za transakciju</translation>
+ </message>
+ <message>
+ <source>Net amount</source>
+ <translation>Neto iznos</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Poruka</translation>
+ </message>
+ <message>
+ <source>Comment</source>
+ <translation>Komentar</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>ID transakcije</translation>
+ </message>
+ <message>
+ <source>Transaction</source>
+ <translation>Transakcija</translation>
+ </message>
+ <message>
+ <source>Inputs</source>
+ <translation>Unosi</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Iznos</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, još nije bio uspješno emitiran</translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>nepoznato</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>Detalji transakcije</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>Ovaj prozor prikazuje detaljni opis transakcije</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Datum</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Tip</translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>Otvoren do %1</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>Potvrđen (%1 potvrda)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>Ovaj blok nije bio primljen od strane bilo kojeg drugog čvora i vjerojatno neće biti prihvaćen!</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>Generirano, ali nije prihvaćeno</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Oznaka</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Primljeno s</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>Primljeno od</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Poslano za</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>Plaćanje samom sebi</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Rudareno</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(n/d)</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>Status transakcije</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Datum i vrijeme kad je transakcija primljena</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>Vrsta transakcije.</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>Iznos odbijen od ili dodan k saldu.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>Sve</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>Danas</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>Ovaj tjedan</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>Ovaj mjesec</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>Prošli mjesec</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>Ove godine</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>Raspon...</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Primljeno s</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Poslano za</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>Samom sebi</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Rudareno</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>Ostalo</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>Unesite adresu ili oznaku za pretraživanje</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>Min iznos</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Kopiraj adresu</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Kopiraj oznaku</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopiraj iznos</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Kopiraj ID transakcije</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>Izmjeni oznaku</translation>
+ </message>
+ <message>
+ <source>Show transaction details</source>
+ <translation>Prikaži detalje transakcije</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Izvoz neuspješan</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Datoteka podataka odvojenih zarezima (*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Potvrđeno</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Datum</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Tip</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Oznaka</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adresa</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>Raspon:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>za</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ </context>
+<context>
+ <name>WalletFrame</name>
+ </context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Slanje novca</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Izvoz</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Izvoz podataka iz trenutnog taba u datoteku</translation>
+ </message>
+ <message>
+ <source>Backup Wallet</source>
+ <translation>Arhiviranje novčanika</translation>
+ </message>
+ <message>
+ <source>Wallet Data (*.dat)</source>
+ <translation>Podaci novčanika (*.dat)</translation>
+ </message>
+ <message>
+ <source>Backup Failed</source>
+ <translation>Arhiviranje nije uspjelo</translation>
+ </message>
+ </context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>Postavke:</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>Odaberi direktorij za datoteke</translation>
+ </message>
+ <message>
+ <source>Specify your own public address</source>
+ <translation>Odaberi vlastitu javnu adresu</translation>
+ </message>
+ <message>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>Prihvati komande iz tekst moda i JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>Izvršavaj u pozadini kao uslužnik i prihvaćaj komande</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>Koristi test mrežu</translation>
+ </message>
+ <message>
+ <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>Upozorenje: -paytxfee je podešen na preveliki iznos. To je iznos koji ćete platiti za obradu transakcije.</translation>
+ </message>
+ <message>
+ <source>Block creation options:</source>
+ <translation>Opcije za kreiranje bloka:</translation>
+ </message>
+ <message>
+ <source>Connect only to the specified node(s)</source>
+ <translation>Poveži se samo sa određenim čvorom/čvorovima</translation>
+ </message>
+ <message>
+ <source>Error: Disk space is low!</source>
+ <translation>Pogreška: Nema dovoljno prostora na disku!</translation>
+ </message>
+ <message>
+ <source>Imports blocks from external blk000??.dat file</source>
+ <translation>Uvozi blokove sa vanjske blk000??.dat datoteke</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Informacija</translation>
+ </message>
+ <message>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>Šalji trace/debug informacije na konzolu umjesto u debug.log datoteku</translation>
+ </message>
+ <message>
+ <source>Start minimized</source>
+ <translation>Pokreni minimiziran</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: 1 when listening)</source>
+ <translation>Pokušaj koristiti UPnP da otvoriš port za uslugu (default: 1 when listening)</translation>
+ </message>
+ <message>
+ <source>Username for JSON-RPC connections</source>
+ <translation>Korisničko ime za JSON-RPC veze</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Upozorenje</translation>
+ </message>
+ <message>
+ <source>Password for JSON-RPC connections</source>
+ <translation>Lozinka za JSON-RPC veze</translation>
+ </message>
+ <message>
+ <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
+ <translation>Izvršite naredbu kada se najbolji blok promjeni (%s u cmd je zamjenjen sa block hash)</translation>
+ </message>
+ <message>
+ <source>Upgrade wallet to latest format</source>
+ <translation>Nadogradite novčanik u posljednji format.</translation>
+ </message>
+ <message>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>Ponovno pretraži lanac blokova za transakcije koje nedostaju</translation>
+ </message>
+ <message>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>Koristi OpenSSL (https) za JSON-RPC povezivanje</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>Ova poruka za pomoć</translation>
+ </message>
+ <message>
+ <source>Allow DNS lookups for -addnode, -seednode and -connect</source>
+ <translation>Dozvoli DNS upite za -addnode, -seednode i -connect</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>Učitavanje adresa...</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>Greška kod učitavanja datoteke wallet.dat: Novčanik pokvaren</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>Greška kod učitavanja datoteke wallet.dat</translation>
+ </message>
+ <message>
+ <source>Invalid -proxy address: '%s'</source>
+ <translation>Nevaljala -proxy adresa: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Nevaljali iznos za opciju -paytxfee=&lt;iznos&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>Nedovoljna sredstva</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>Učitavanje indeksa blokova...</translation>
+ </message>
+ <message>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>Doda čvor s kojim se želite povezati i nastoji održati vezu otvorenu</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>Učitavanje novčanika...</translation>
+ </message>
+ <message>
+ <source>Cannot downgrade wallet</source>
+ <translation>Nije moguće novčanik vratiti na prijašnju verziju.</translation>
+ </message>
+ <message>
+ <source>Cannot write default address</source>
+ <translation>Nije moguće upisati zadanu adresu.</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>Ponovno pretraživanje...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>Učitavanje gotovo</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Greška</translation>
+ </message>
+</context>
+</TS> \ 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 0000000000..fd476611ee
--- /dev/null
+++ b/src/qt/locale/bitcoin_hu.ts
@@ -0,0 +1,2326 @@
+<TS language="hu" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Right-click to edit address or label</source>
+ <translation>A cím vagy címke szerkeszteséhez kattintson a jobb gombbal</translation>
+ </message>
+ <message>
+ <source>Create a new address</source>
+ <translation>Új cím létrehozása</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>&amp;Új</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>A kiválasztott cím másolása a vágólapra</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>&amp;Másolás</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>&amp;Bezárás</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>&amp;Cím másolása</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>Kiválasztott cím törlése a listából</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Jelenlegi nézet exportálása fájlba</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Exportálás</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;Törlés</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>Válaszd ki a címet, ahová küldesz</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>Válaszd ki a címet, amivel fogadsz</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>&amp;Kiválaszt</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>Küldési címek</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>Fogadó címek</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>Ezekről a címekről küldhetsz bitcoint. Mindig ellenőrizd a fogadó címet és a fizetendő összeget, mielőtt elküldöd.</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>Ezekkel a címekkel fogadhatsz bitcoint. Ajánlott minden tranzakcióhoz egy új fogadó címet használni.</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>&amp;Címke másolása</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>Sz&amp;erkesztés</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>Címjegyzék exportálása</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Vesszővel elválasztott fájl (*.csv)</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Az exportálás sikertelen volt</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the address list to %1. Please try again.</source>
+ <translation>Hiba történt a címjegyzék %1 helyre való mentésekor. Kérlek próbáld újra.</translation>
+ </message>
+</context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Címke</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Cím</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(nincs címke)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Passphrase Dialog</source>
+ <translation>Jelszó párbeszédablak</translation>
+ </message>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Add meg a jelszót</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Új jelszó</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Új jelszó újra</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>Tárca titkosítása</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>A tárca megnyitásához a műveletnek szüksége van a tárcád jelszavára.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Tárca megnyitása</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>A tárca dekódolásához a műveletnek szüksége van a tárcád jelszavára.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>Tárca dekódolása</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>Jelszó megváltoztatása</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>Biztosan titkosítani akarod a tárcát?</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>Figyelem: ha titkosítod a tárcát és elveszted a jelszavad, akkor &lt;b&gt;AZ ÖSSZES BITCOINOD ELVESZIK!&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>Biztosan titkosítani akarod a tárcád?</translation>
+ </message>
+ <message>
+ <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
+ <translation>FONTOS: A tárca-fájl minden korábbi mentését cseréld le ezzel az új, titkosított tárca-fájllal. Biztonsági okokból a tárca-fájl korábbi, titkosítás nélküli mentései használhatatlanná válnak, amint elkezded használni az új, titkosított tárcát.</translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>Vigyázat: a Caps Lock be van kapcsolva!</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>Tárca titkosítva</translation>
+ </message>
+ <message>
+ <source>Enter the new passphrase to the wallet.&lt;br/&gt;Please use a passphrase of &lt;b&gt;ten or more random characters&lt;/b&gt;, or &lt;b&gt;eight or more words&lt;/b&gt;.</source>
+ <translation>Add meg a tárca új jelszavát.&lt;br/&gt;Olyan jelszót válassz, ami &lt;b&gt;legalább tíz véletlenszerű karakterből&lt;/b&gt; vagy &lt;b&gt;legalább 8 véletlenszerű szóból&lt;/b&gt; áll.</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>A tárca titkosítása sikertelen.</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>Tárca titkosítása belső hiba miatt sikertelen. A tárcád nem lett titkosítva.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>A megadott jelszavak nem egyeznek.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>Tárca megnyitása sikertelen</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>Hibás jelszó.</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>Dekódolás sikertelen.</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>Jelszó megváltoztatva.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>Üzenet aláírása...</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>Szinkronizálás a hálózattal...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;Áttekintés</translation>
+ </message>
+ <message>
+ <source>Node</source>
+ <translation>Csomópont</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>Tárca általános áttekintése</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Tranzakciók</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>Tranzakciós előzmények megtekintése</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>&amp;Kilépés</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>Kilépés az alkalmazásból</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>A &amp;Qt-ról</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>Információk a Qt-ról</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;Opciók...</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>Tárca &amp;titkosítása...</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>&amp;Bisztonsági másolat készítése a Tárcáról</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>Jelszó &amp;megváltoztatása...</translation>
+ </message>
+ <message>
+ <source>&amp;Sending addresses...</source>
+ <translation>&amp;Küldési címek...</translation>
+ </message>
+ <message>
+ <source>&amp;Receiving addresses...</source>
+ <translation>&amp;Fogadó címek...</translation>
+ </message>
+ <message>
+ <source>Open &amp;URI...</source>
+ <translation>&amp;URI azonosító megnyitása...</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core client</source>
+ <translation>Bitcoin Core kliens</translation>
+ </message>
+ <message>
+ <source>Importing blocks from disk...</source>
+ <translation>A blokkok importálása lemezről...</translation>
+ </message>
+ <message>
+ <source>Reindexing blocks on disk...</source>
+ <translation>Lemezen lévő blokkok újraindexelése...</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>Bitcoin küldése megadott címre</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>Biztonsági másolat készítése a tárcáról egy másik helyre</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Tárca-titkosító jelszó megváltoztatása</translation>
+ </message>
+ <message>
+ <source>&amp;Debug window</source>
+ <translation>&amp;Debug ablak</translation>
+ </message>
+ <message>
+ <source>Open debugging and diagnostic console</source>
+ <translation>Hibakereső és diagnosztikai konzol megnyitása</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>Üzenet &amp;valódiságának ellenőrzése</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>Tárca</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>&amp;Küldés</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>&amp;Fogadás</translation>
+ </message>
+ <message>
+ <source>Show information about Bitcoin Core</source>
+ <translation>Bitcoin Core információ megjelenítése</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>&amp;Mutat / Elrejt</translation>
+ </message>
+ <message>
+ <source>Show or hide the main Window</source>
+ <translation>Főablakot mutat/elrejt</translation>
+ </message>
+ <message>
+ <source>Encrypt the private keys that belong to your wallet</source>
+ <translation>A tárcádhoz tartozó privát kulcsok titkosítása</translation>
+ </message>
+ <message>
+ <source>Sign messages with your Bitcoin addresses to prove you own them</source>
+ <translation>Üzenetek aláírása a Bitcoin-címmeiddel, amivel bizonyítod, hogy a cím a sajátod</translation>
+ </message>
+ <message>
+ <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source>
+ <translation>Üzenetek ellenőrzése, hogy valóban a megjelölt Bitcoin-címekkel vannak-e aláírva</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;Fájl</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;Beállítások</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>&amp;Súgó</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>Fül eszköztár</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Request payments (generates QR codes and bitcoin: URIs)</source>
+ <translation>Fizetési kérelem (QR-kódot és "bitcoin:" URI azonosítót hoz létre)</translation>
+ </message>
+ <message>
+ <source>&amp;About Bitcoin Core</source>
+ <translation>&amp;A Bitcoin Core-ról</translation>
+ </message>
+ <message>
+ <source>Show the list of used sending addresses and labels</source>
+ <translation>A használt küldési címek és címkék megtekintése</translation>
+ </message>
+ <message>
+ <source>Show the list of used receiving addresses and labels</source>
+ <translation>A használt fogadó címek és címkék megtekintése</translation>
+ </message>
+ <message>
+ <source>Open a bitcoin: URI or payment request</source>
+ <translation>"bitcoin:" URI azonosító vagy fizetési kérelem megnyitása</translation>
+ </message>
+ <message>
+ <source>&amp;Command-line options</source>
+ <translation>Paran&amp;cssor kapcsolók</translation>
+ </message>
+ <message>
+ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
+ <translation>A Bitcoin Core súgóüzenet megjelenítése a Bitcoin lehetséges parancssori kapcsolóival.</translation>
+ </message>
+ <message>
+ <source>No block source available...</source>
+ <translation>Blokk forrása ismeretlen...</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n hour(s)</source>
+ <translation><numerusform>%n óra</numerusform><numerusform>%n óra</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 and %2</source>
+ <translation>%1 és %2</translation>
+ </message>
+ <message>
+ <source>%1 behind</source>
+ <translation>%1 lemaradás</translation>
+ </message>
+ <message>
+ <source>Last received block was generated %1 ago.</source>
+ <translation>Az utolsóként kapott blokk kora: %1.</translation>
+ </message>
+ <message>
+ <source>Transactions after this will not yet be visible.</source>
+ <translation>Ez utáni tranzakciók még nem lesznek láthatóak. </translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Hiba</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Figyelem</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Információ</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>Naprakész</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>Frissítés...</translation>
+ </message>
+ <message>
+ <source>Date: %1
+</source>
+ <translation>Dátum: %1
+</translation>
+ </message>
+ <message>
+ <source>Type: %1
+</source>
+ <translation>Típus: %1
+</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>Tranzakció elküldve.</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>Beérkező tranzakció</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>A tárca &lt;b&gt;titkosítva&lt;/b&gt; és jelenleg &lt;b&gt;nyitva&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>Tárca &lt;b&gt;kódolva&lt;/b&gt; és jelenleg &lt;b&gt;zárva&lt;/b&gt;.</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <source>Network Alert</source>
+ <translation>Hálózati figyelmeztetés</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Quantity:</source>
+ <translation>Mennyiség:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Bájtok:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Összeg:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Prioritás:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Díjak:</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Por-határ:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Utólagos díj:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Visszajáró:</translation>
+ </message>
+ <message>
+ <source>(un)select all</source>
+ <translation>mindent kiválaszt/elvet</translation>
+ </message>
+ <message>
+ <source>Tree mode</source>
+ <translation>Fa nézet</translation>
+ </message>
+ <message>
+ <source>List mode</source>
+ <translation>Lista nézet</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Összeg</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Dátum</translation>
+ </message>
+ <message>
+ <source>Confirmations</source>
+ <translation>Megerősítések</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Megerősítve</translation>
+ </message>
+ <message>
+ <source>Priority</source>
+ <translation>Prioritás</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Cím másolása</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Címke másolása</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Összeg másolása</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Tranzakcióazonosító másolása</translation>
+ </message>
+ <message>
+ <source>Lock unspent</source>
+ <translation>Megmaradt zárolása</translation>
+ </message>
+ <message>
+ <source>Unlock unspent</source>
+ <translation>Zárolás feloldása</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Mennyiség másolása</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Díj másolása</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Utólagos díj másolása</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Byte-ok másolása </translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Prioritás másolása</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Visszajáró másolása</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Visszajáró másolása</translation>
+ </message>
+ <message>
+ <source>highest</source>
+ <translation>legmagasabb</translation>
+ </message>
+ <message>
+ <source>higher</source>
+ <translation>magasabb</translation>
+ </message>
+ <message>
+ <source>high</source>
+ <translation>magas</translation>
+ </message>
+ <message>
+ <source>medium-high</source>
+ <translation>közepesen-magas</translation>
+ </message>
+ <message>
+ <source>medium</source>
+ <translation>közepes</translation>
+ </message>
+ <message>
+ <source>low-medium</source>
+ <translation>alacsony-közepes</translation>
+ </message>
+ <message>
+ <source>low</source>
+ <translation>alacsony</translation>
+ </message>
+ <message>
+ <source>lower</source>
+ <translation>alacsonyabb</translation>
+ </message>
+ <message>
+ <source>lowest</source>
+ <translation>legalacsonyabb</translation>
+ </message>
+ <message>
+ <source>(%1 locked)</source>
+ <translation>(%1 zárolva)</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>semmi</translation>
+ </message>
+ <message>
+ <source>Can vary +/- %1 satoshi(s) per input.</source>
+ <translation>Bemenetenként +/- %1 satoshi-val változhat</translation>
+ </message>
+ <message>
+ <source>yes</source>
+ <translation>igen</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>nem</translation>
+ </message>
+ <message>
+ <source>This means a fee of at least %1 per kB is required.</source>
+ <translation>Legalább %1 díj szüksége kB-onként.</translation>
+ </message>
+ <message>
+ <source>Can vary +/- 1 byte per input.</source>
+ <translation>Bemenetenként +/- 1 byte-al változhat.</translation>
+ </message>
+ <message>
+ <source>Transactions with higher priority are more likely to get included into a block.</source>
+ <translation>Nagyobb prioritású tranzakciók nagyobb valószínűséggel kerülnek be egy blokkba.</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(nincs címke)</translation>
+ </message>
+ <message>
+ <source>change from %1 (%2)</source>
+ <translation>visszajáró %1-ből (%2)</translation>
+ </message>
+ <message>
+ <source>(change)</source>
+ <translation>(visszajáró)</translation>
+ </message>
+</context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>Cím szerkesztése</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>Cím&amp;ke</translation>
+ </message>
+ <message>
+ <source>The label associated with this address list entry</source>
+ <translation>Ehhez a listaelemhez rendelt címke </translation>
+ </message>
+ <message>
+ <source>The address associated with this address list entry. This can only be modified for sending addresses.</source>
+ <translation>Ehhez a címlistaelemhez rendelt cím. Csak a küldő címek módosíthatók.</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;Cím</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>Új fogadó cím</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>Új küldő cím</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>Fogadó cím szerkesztése</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>Küldő cím szerkesztése</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>A megadott "%1" cím már szerepel a címjegyzékben.</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is not a valid Bitcoin address.</source>
+ <translation>A megadott "%1" cím nem egy érvényes Bitcoin-cím.</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>Tárca feloldása sikertelen</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>Új kulcs generálása sikertelen</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ <message>
+ <source>A new data directory will be created.</source>
+ <translation>Új adatkönyvtár lesz létrehozva.</translation>
+ </message>
+ <message>
+ <source>name</source>
+ <translation>Név</translation>
+ </message>
+ <message>
+ <source>Path already exists, and is not a directory.</source>
+ <translation>Az elérési út létezik, de nem egy könyvtáré.</translation>
+ </message>
+ <message>
+ <source>Cannot create data directory here.</source>
+ <translation>Adatkönyvtár nem hozható itt létre.</translation>
+ </message>
+</context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>verzió</translation>
+ </message>
+ <message>
+ <source>(%1-bit)</source>
+ <translation>(%1-bit)</translation>
+ </message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>A Bitcoin Core-ról</translation>
+ </message>
+ <message>
+ <source>Command-line options</source>
+ <translation>Parancssoros opciók</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>Használat:</translation>
+ </message>
+ <message>
+ <source>command-line options</source>
+ <translation>parancssoros opciók</translation>
+ </message>
+</context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Welcome</source>
+ <translation>Üdvözlünk</translation>
+ </message>
+ <message>
+ <source>Welcome to Bitcoin Core.</source>
+ <translation>Üdvözlünk a Bitcoin Core-ban.</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory.</source>
+ <translation>A Bitcoin Core le fogja tölteni és tárolni fogja a Bitcoin blokklánc egy másolatát. Legalább %1GB adat lesz tárolva ebben a mappában, és ez folyamatosan nőni fog. A tárca szintén itt lesz tárolva.</translation>
+ </message>
+ <message>
+ <source>Use the default data directory</source>
+ <translation>Az alapértelmezett adat könyvtár használata</translation>
+ </message>
+ <message>
+ <source>Use a custom data directory:</source>
+ <translation>Saját adatkönyvtár használata:</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Error: Specified data directory "%1" cannot be created.</source>
+ <translation>Hiba: A megadott "%1" adatkönyvtár nem hozható létre. </translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Hiba</translation>
+ </message>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ <message>
+ <source>Open URI</source>
+ <translation>URI megnyitása</translation>
+ </message>
+ <message>
+ <source>Open payment request from URI or file</source>
+ <translation>Fizetési kérelem megnyitása URI azonosítóból vagy fájlból</translation>
+ </message>
+ <message>
+ <source>URI:</source>
+ <translation>URI:</translation>
+ </message>
+ <message>
+ <source>Select payment request file</source>
+ <translation>Fizetési kérelmi fájl kiválasztása</translation>
+ </message>
+ <message>
+ <source>Select payment request file to open</source>
+ <translation>Fizetés kérelmi fájl kiválasztása</translation>
+ </message>
+</context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>Opciók</translation>
+ </message>
+ <message>
+ <source>&amp;Main</source>
+ <translation>&amp;Fő</translation>
+ </message>
+ <message>
+ <source>MB</source>
+ <translation>MB</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside</source>
+ <translation>Külső kapcsolatok elfogadása</translation>
+ </message>
+ <message>
+ <source>Allow incoming connections</source>
+ <translation>Bejövő kapcsolatok engedélyezése</translation>
+ </message>
+ <message>
+ <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
+ <translation>A proxy IP címe (pl.: IPv4: 127.0.0.1 / IPv6: ::1)</translation>
+ </message>
+ <message>
+ <source>Reset all client options to default.</source>
+ <translation>Minden kliensbeállítás alapértelmezettre állítása.</translation>
+ </message>
+ <message>
+ <source>&amp;Reset Options</source>
+ <translation>Beállítások tö&amp;rlése</translation>
+ </message>
+ <message>
+ <source>&amp;Network</source>
+ <translation>&amp;Hálózat</translation>
+ </message>
+ <message>
+ <source>&amp;Start Bitcoin Core on system login</source>
+ <translation>A Bitcoin elindítása bejelentkezéskor</translation>
+ </message>
+ <message>
+ <source>Expert</source>
+ <translation>szakértő</translation>
+ </message>
+ <message>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>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.</translation>
+ </message>
+ <message>
+ <source>Map port using &amp;UPnP</source>
+ <translation>&amp;UPnP port-feltérképezés</translation>
+ </message>
+ <message>
+ <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
+ <translation>Csatlakozás a Bitcoin hálózatához SOCKS5 proxyn keresztül</translation>
+ </message>
+ <message>
+ <source>Proxy &amp;IP:</source>
+ <translation>Proxy &amp;IP:</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>&amp;Port:</translation>
+ </message>
+ <message>
+ <source>Port of the proxy (e.g. 9050)</source>
+ <translation>Proxy portja (pl.: 9050)</translation>
+ </message>
+ <message>
+ <source>&amp;Window</source>
+ <translation>&amp;Ablak</translation>
+ </message>
+ <message>
+ <source>Show only a tray icon after minimizing the window.</source>
+ <translation>Kicsinyítés után csak eszköztár-ikont mutass</translation>
+ </message>
+ <message>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>&amp;Kicsinyítés a tálcára az eszköztár helyett</translation>
+ </message>
+ <message>
+ <source>M&amp;inimize on close</source>
+ <translation>K&amp;icsinyítés záráskor</translation>
+ </message>
+ <message>
+ <source>&amp;Display</source>
+ <translation>&amp;Megjelenítés</translation>
+ </message>
+ <message>
+ <source>User Interface &amp;language:</source>
+ <translation>Felhasználófelület nye&amp;lve:</translation>
+ </message>
+ <message>
+ <source>&amp;Unit to show amounts in:</source>
+ <translation>&amp;Mértékegység:</translation>
+ </message>
+ <message>
+ <source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
+ <translation>Válaszd ki az interfészen és érmék küldésekor megjelenítendő alapértelmezett alegységet.</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>&amp;OK</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>Megszakítás</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>alapértelmezett</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>semmi</translation>
+ </message>
+ <message>
+ <source>Confirm options reset</source>
+ <translation>Beállítások törlésének jóváhagyása.</translation>
+ </message>
+ <message>
+ <source>Client restart required to activate changes.</source>
+ <translation>A változtatások aktiválásahoz újra kell indítani a klienst.</translation>
+ </message>
+ <message>
+ <source>The supplied proxy address is invalid.</source>
+ <translation>A megadott proxy cím nem érvényes.</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>Űrlap</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>A kijelzett információ lehet, hogy elavult. A pénztárcája automatikusan szinkronizálja magát a Bitcoin hálózattal miután a kapcsolat létrejön, de ez e folyamat még nem fejeződött be.</translation>
+ </message>
+ <message>
+ <source>Available:</source>
+ <translation>Elérhető:</translation>
+ </message>
+ <message>
+ <source>Your current spendable balance</source>
+ <translation>Jelenlegi egyenleg</translation>
+ </message>
+ <message>
+ <source>Pending:</source>
+ <translation>Küldés:</translation>
+ </message>
+ <message>
+ <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source>
+ <translation>Még megerősítésre váró, a jelenlegi egyenlegbe be nem számított tranzakciók</translation>
+ </message>
+ <message>
+ <source>Immature:</source>
+ <translation>Éretlen:</translation>
+ </message>
+ <message>
+ <source>Mined balance that has not yet matured</source>
+ <translation>Bányászott egyenleg amely még nem érett be.</translation>
+ </message>
+ <message>
+ <source>Total:</source>
+ <translation>Összesen:</translation>
+ </message>
+ <message>
+ <source>Your current total balance</source>
+ <translation>Aktuális egyenleged</translation>
+ </message>
+ <message>
+ <source>Spendable:</source>
+ <translation>Elkölthető:</translation>
+ </message>
+ <message>
+ <source>Recent transactions</source>
+ <translation>A legutóbbi tranzakciók</translation>
+ </message>
+ </context>
+<context>
+ <name>PaymentServer</name>
+ <message>
+ <source>URI handling</source>
+ <translation>URI kezelés</translation>
+ </message>
+ <message>
+ <source>Cannot start bitcoin: click-to-pay handler</source>
+ <translation>A bitcoint nem lehet elindítani: click-to-pay handler</translation>
+ </message>
+ </context>
+<context>
+ <name>PeerTableModel</name>
+ <message>
+ <source>User Agent</source>
+ <translation>User Agent</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Ping idő</translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>Összeg</translation>
+ </message>
+ <message>
+ <source>%1 d</source>
+ <translation>%1 n</translation>
+ </message>
+ <message>
+ <source>%1 h</source>
+ <translation>%1 ó</translation>
+ </message>
+ <message>
+ <source>%1 m</source>
+ <translation>%1 p</translation>
+ </message>
+ <message>
+ <source>%1 s</source>
+ <translation>%1 mp</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>Nem elérhető</translation>
+ </message>
+ </context>
+<context>
+ <name>QRImageWidget</name>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Kép mentése</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Image</source>
+ <translation>&amp;Kép másolása</translation>
+ </message>
+ <message>
+ <source>Save QR Code</source>
+ <translation>QR kód mentése</translation>
+ </message>
+ <message>
+ <source>PNG Image (*.png)</source>
+ <translation>PNG kép (*.png)</translation>
+ </message>
+</context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>Client name</source>
+ <translation>Kliens néve</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>Nem elérhető</translation>
+ </message>
+ <message>
+ <source>Client version</source>
+ <translation>Kliens verzió</translation>
+ </message>
+ <message>
+ <source>&amp;Information</source>
+ <translation>&amp;Információ</translation>
+ </message>
+ <message>
+ <source>Debug window</source>
+ <translation>Debug ablak</translation>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>Általános</translation>
+ </message>
+ <message>
+ <source>Using OpenSSL version</source>
+ <translation>Használt OpenSSL verzió</translation>
+ </message>
+ <message>
+ <source>Startup time</source>
+ <translation>Bekapcsolás ideje</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Hálózat</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>Név</translation>
+ </message>
+ <message>
+ <source>Number of connections</source>
+ <translation>Kapcsolatok száma</translation>
+ </message>
+ <message>
+ <source>Block chain</source>
+ <translation>Blokklánc</translation>
+ </message>
+ <message>
+ <source>Current number of blocks</source>
+ <translation>Aktuális blokkok száma</translation>
+ </message>
+ <message>
+ <source>Received</source>
+ <translation>Fogadott</translation>
+ </message>
+ <message>
+ <source>Sent</source>
+ <translation>Küldött</translation>
+ </message>
+ <message>
+ <source>&amp;Peers</source>
+ <translation>&amp;Peerek</translation>
+ </message>
+ <message>
+ <source>Version</source>
+ <translation>Verzió</translation>
+ </message>
+ <message>
+ <source>User Agent</source>
+ <translation>User Agent</translation>
+ </message>
+ <message>
+ <source>Services</source>
+ <translation>Szolgáltatások</translation>
+ </message>
+ <message>
+ <source>Last Send</source>
+ <translation>Legutóbbi küldés</translation>
+ </message>
+ <message>
+ <source>Last Receive</source>
+ <translation>Legutóbbi fogadás</translation>
+ </message>
+ <message>
+ <source>Bytes Sent</source>
+ <translation>Küldött bájtok</translation>
+ </message>
+ <message>
+ <source>Bytes Received</source>
+ <translation>Fogadott bájtok</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Ping idő</translation>
+ </message>
+ <message>
+ <source>Last block time</source>
+ <translation>Utolsó blokk ideje</translation>
+ </message>
+ <message>
+ <source>&amp;Open</source>
+ <translation>&amp;Megnyitás</translation>
+ </message>
+ <message>
+ <source>&amp;Console</source>
+ <translation>&amp;Konzol</translation>
+ </message>
+ <message>
+ <source>&amp;Network Traffic</source>
+ <translation>&amp;Hálózati forgalom</translation>
+ </message>
+ <message>
+ <source>Totals</source>
+ <translation>Összesen:</translation>
+ </message>
+ <message>
+ <source>In:</source>
+ <translation>Be:</translation>
+ </message>
+ <message>
+ <source>Out:</source>
+ <translation>Ki:</translation>
+ </message>
+ <message>
+ <source>Build date</source>
+ <translation>Fordítás dátuma</translation>
+ </message>
+ <message>
+ <source>Debug log file</source>
+ <translation>Debug naplófájl</translation>
+ </message>
+ <message>
+ <source>Clear console</source>
+ <translation>Konzol törlése</translation>
+ </message>
+ <message>
+ <source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
+ <translation>Navigálhat a fel és le nyilakkal, és &lt;b&gt;Ctrl-L&lt;/b&gt; -vel törölheti a képernyőt.</translation>
+ </message>
+ <message>
+ <source>Type &lt;b&gt;help&lt;/b&gt; for an overview of available commands.</source>
+ <translation>Írd be azt, hogy &lt;b&gt;help&lt;/b&gt; az elérhető parancsok áttekintéséhez.</translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation>%1 B</translation>
+ </message>
+ <message>
+ <source>%1 KB</source>
+ <translation>%1 KB</translation>
+ </message>
+ <message>
+ <source>%1 MB</source>
+ <translation>%1 MB</translation>
+ </message>
+ <message>
+ <source>%1 GB</source>
+ <translation>%1 GB</translation>
+ </message>
+ <message>
+ <source>never</source>
+ <translation>soha</translation>
+ </message>
+ <message>
+ <source>Unknown</source>
+ <translation>Ismeretlen</translation>
+ </message>
+ </context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>Címke:</translation>
+ </message>
+ <message>
+ <source>&amp;Message:</source>
+ <translation>&amp;Üzenet:</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation>Törlés</translation>
+ </message>
+ <message>
+ <source>Show</source>
+ <translation>Mutat</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>Eltávolítás</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Címke másolása</translation>
+ </message>
+ <message>
+ <source>Copy message</source>
+ <translation>Üzenet másolása</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Összeg másolása</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>QR Code</source>
+ <translation>QR kód</translation>
+ </message>
+ <message>
+ <source>Copy &amp;URI</source>
+ <translation>&amp;URI másolása</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Address</source>
+ <translation>&amp;Cím másolása</translation>
+ </message>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Kép mentése</translation>
+ </message>
+ <message>
+ <source>URI</source>
+ <translation>URI:</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Cím</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Összeg</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Címke</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Üzenet</translation>
+ </message>
+ <message>
+ <source>Resulting URI too long, try to reduce the text for label / message.</source>
+ <translation>A keletkezett URI túl hosszú, próbálja meg csökkenteni a cimkeszöveg / üzenet méretét.</translation>
+ </message>
+ <message>
+ <source>Error encoding URI into QR Code.</source>
+ <translation>Hiba lépett fel az URI QR kóddá alakításakor</translation>
+ </message>
+</context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Dátum</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Címke</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Üzenet</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Összeg</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(nincs címke)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Érmék küldése</translation>
+ </message>
+ <message>
+ <source>Inputs...</source>
+ <translation>Bemenetek...</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Mennyiség:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Bájtok:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Összeg:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Prioritás:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Díjak:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Utólagos díj:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Visszajáró:</translation>
+ </message>
+ <message>
+ <source>Transaction Fee:</source>
+ <translation>Tranzakciós díj</translation>
+ </message>
+ <message>
+ <source>Hide</source>
+ <translation>Elrejtés</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>Küldés több címzettnek egyszerre</translation>
+ </message>
+ <message>
+ <source>Add &amp;Recipient</source>
+ <translation>&amp;Címzett hozzáadása</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Por-határ:</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Mindent &amp;töröl</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>Egyenleg:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>Küldés megerősítése</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>&amp;Küldés</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>Küldés megerősítése</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Mennyiség másolása</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Összeg másolása</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Díj másolása</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Utólagos díj másolása</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Byte-ok másolása </translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Prioritás másolása</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Visszajáró másolása</translation>
+ </message>
+ <message>
+ <source>or</source>
+ <translation>vagy</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>A fizetendő összegnek nagyobbnak kell lennie 0-nál.</translation>
+ </message>
+ <message>
+ <source>The amount exceeds your balance.</source>
+ <translation>Nincs ennyi bitcoin az egyenlegeden.</translation>
+ </message>
+ <message>
+ <source>The total exceeds your balance when the %1 transaction fee is included.</source>
+ <translation>A küldeni kívánt összeg és a %1 tranzakciós díj együtt meghaladja az egyenlegeden rendelkezésedre álló összeget.</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(nincs címke)</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Visszajáró másolása</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>Összeg:</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>Címzett:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Milyen címkével kerüljön be ez a cím a címtáradba?
+</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>Címke:</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Cím beillesztése a vágólapról</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Message:</source>
+ <translation>Üzenet:</translation>
+ </message>
+ <message>
+ <source>Memo:</source>
+ <translation>Jegyzet:</translation>
+ </message>
+</context>
+<context>
+ <name>ShutdownWindow</name>
+ <message>
+ <source>Bitcoin Core is shutting down...</source>
+ <translation>A Bitcoin Core leáll...</translation>
+ </message>
+ </context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Signatures - Sign / Verify a Message</source>
+ <translation>Aláírások - üzenet aláírása/ellenőrzése</translation>
+ </message>
+ <message>
+ <source>&amp;Sign Message</source>
+ <translation>Üzenet aláírása...</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Cím beillesztése a vágólapról</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Enter the message you want to sign here</source>
+ <translation>Ide írja az aláírandó üzenetet</translation>
+ </message>
+ <message>
+ <source>Signature</source>
+ <translation>Aláírás</translation>
+ </message>
+ <message>
+ <source>Copy the current signature to the system clipboard</source>
+ <translation>A jelenleg kiválasztott aláírás másolása a rendszer-vágólapra</translation>
+ </message>
+ <message>
+ <source>Sign the message to prove you own this Bitcoin address</source>
+ <translation>Üzenet </translation>
+ </message>
+ <message>
+ <source>Sign &amp;Message</source>
+ <translation>Üzenet &amp;aláírása</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Mindent &amp;töröl</translation>
+ </message>
+ <message>
+ <source>&amp;Verify Message</source>
+ <translation>Üzenet ellenőrzése</translation>
+ </message>
+ <message>
+ <source>The entered address is invalid.</source>
+ <translation>A megadott cím nem érvényes.</translation>
+ </message>
+ <message>
+ <source>Please check the address and try again.</source>
+ <translation>Ellenőrizze a címet és próbálja meg újra.</translation>
+ </message>
+ <message>
+ <source>Private key for the entered address is not available.</source>
+ <translation>A megadott cím privát kulcsa nem található.</translation>
+ </message>
+ <message>
+ <source>Message signing failed.</source>
+ <translation>Üzenet aláírása nem sikerült.</translation>
+ </message>
+ <message>
+ <source>Message signed.</source>
+ <translation>Üzenet aláírva.</translation>
+ </message>
+ <message>
+ <source>The signature could not be decoded.</source>
+ <translation>Az aláírást nem sikerült dekódolni.</translation>
+ </message>
+ <message>
+ <source>Please check the signature and try again.</source>
+ <translation>Ellenőrizd az aláírást és próbáld újra.</translation>
+ </message>
+ <message>
+ <source>Message verification failed.</source>
+ <translation>Az üzenet ellenőrzése nem sikerült.</translation>
+ </message>
+ <message>
+ <source>Message verified.</source>
+ <translation>Üzenet ellenőrizve.</translation>
+ </message>
+</context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>The Bitcoin Core developers</source>
+ <translation>A Bitcoin Core fejlesztői</translation>
+ </message>
+ <message>
+ <source>[testnet]</source>
+ <translation>[teszthálózat]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ <message>
+ <source>KB/s</source>
+ <translation>KB/s</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>%1-ig megnyitva</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/megerősítetlen</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 megerősítés</translation>
+ </message>
+ <message>
+ <source>Status</source>
+ <translation>Állapot</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Dátum</translation>
+ </message>
+ <message>
+ <source>Source</source>
+ <translation>Forrás</translation>
+ </message>
+ <message>
+ <source>Generated</source>
+ <translation>Legenerálva</translation>
+ </message>
+ <message>
+ <source>From</source>
+ <translation>Űrlap</translation>
+ </message>
+ <message>
+ <source>To</source>
+ <translation>Címzett</translation>
+ </message>
+ <message>
+ <source>own address</source>
+ <translation>saját cím</translation>
+ </message>
+ <message>
+ <source>label</source>
+ <translation>címke</translation>
+ </message>
+ <message>
+ <source>Credit</source>
+ <translation>Jóváírás</translation>
+ </message>
+ <message>
+ <source>not accepted</source>
+ <translation>elutasítva</translation>
+ </message>
+ <message>
+ <source>Debit</source>
+ <translation>Terhelés</translation>
+ </message>
+ <message>
+ <source>Transaction fee</source>
+ <translation>Tranzakciós díj</translation>
+ </message>
+ <message>
+ <source>Net amount</source>
+ <translation>Nettó összeg</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Üzenet</translation>
+ </message>
+ <message>
+ <source>Comment</source>
+ <translation>Megjegyzés</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>Tranzakcióazonosító</translation>
+ </message>
+ <message>
+ <source>Debug information</source>
+ <translation>Debug információ</translation>
+ </message>
+ <message>
+ <source>Transaction</source>
+ <translation>Tranzakció</translation>
+ </message>
+ <message>
+ <source>Inputs</source>
+ <translation>Bemenetek</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Összeg</translation>
+ </message>
+ <message>
+ <source>true</source>
+ <translation>igaz</translation>
+ </message>
+ <message>
+ <source>false</source>
+ <translation>hamis</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, még nem sikerült elküldeni.</translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>ismeretlen</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>Tranzakció részletei</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>Ez a mező a tranzakció részleteit mutatja</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Dátum</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Típus</translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>%1-ig megnyitva</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>Megerősítve (%1 megerősítés)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>Ezt a blokkot egyetlen másik csomópont sem kapta meg, így valószínűleg nem lesz elfogadva!</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>Legenerálva, de még el nem fogadva.</translation>
+ </message>
+ <message>
+ <source>Offline</source>
+ <translation>Offline</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Címke</translation>
+ </message>
+ <message>
+ <source>Unconfirmed</source>
+ <translation>Megerősítetlen:</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Erre a címre</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>Erről az</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Erre a címre</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>Magadnak kifizetve</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Kibányászva</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(nincs)</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>Tranzakció állapota. Húzd ide a kurzort, hogy lásd a megerősítések számát.</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Tranzakció fogadásának dátuma és időpontja.</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>Tranzakció típusa.</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>Az egyenleghez jóváírt vagy ráterhelt összeg.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>Mind</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>Mai</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>Ezen a héten</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>Ebben a hónapban</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>Múlt hónapban</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>Ebben az évben</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>Tartomány ...</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Erre a címre</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Erre a címre</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>Magadnak</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Kibányászva</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>Más</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>Írd be a keresendő címet vagy címkét</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>Minimális összeg</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Cím másolása</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Címke másolása</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Összeg másolása</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Tranzakcióazonosító másolása</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>Címke szerkesztése</translation>
+ </message>
+ <message>
+ <source>Show transaction details</source>
+ <translation>Tranzakciós részletek megjelenítése</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Az exportálás sikertelen volt</translation>
+ </message>
+ <message>
+ <source>Exporting Successful</source>
+ <translation>Sikeres exportálás</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Vesszővel elválasztott fájl (*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Megerősítve</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Dátum</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Típus</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Címke</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Cím</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>Azonosító</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>Tartomány:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>meddig</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ </context>
+<context>
+ <name>WalletFrame</name>
+ </context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Érmék küldése</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Exportálás</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Jelenlegi nézet exportálása fájlba</translation>
+ </message>
+ <message>
+ <source>Backup Wallet</source>
+ <translation>Biztonsági másolat készítése a Tárcáról</translation>
+ </message>
+ <message>
+ <source>Wallet Data (*.dat)</source>
+ <translation>Tárca fájl (*.dat)</translation>
+ </message>
+ <message>
+ <source>Backup Failed</source>
+ <translation>Biztonsági másolat készítése sikertelen</translation>
+ </message>
+ <message>
+ <source>Backup Successful</source>
+ <translation>Sikeres biztonsági mentés</translation>
+ </message>
+</context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>Opciók
+</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>Adatkönyvtár
+</translation>
+ </message>
+ <message>
+ <source>Connect to a node to retrieve peer addresses, and disconnect</source>
+ <translation>Kapcsolódás egy csomóponthoz a peerek címeinek megszerzése miatt, majd szétkapcsolás</translation>
+ </message>
+ <message>
+ <source>Specify your own public address</source>
+ <translation>Adja meg az Ön saját nyilvános címét</translation>
+ </message>
+ <message>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>Parancssoros és JSON-RPC parancsok elfogadása
+</translation>
+ </message>
+ <message>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>Háttérben futtatás daemonként és parancsok elfogadása
+</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>Teszthálózat használata
+</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
+ <translation>Kívülről érkező kapcsolatok elfogadása (alapértelmezett: 1, ha nem használt a -proxy vagy a -connect)</translation>
+ </message>
+ <message>
+ <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
+ <translation>Parancs, amit akkor hajt végre, amikor egy tárca-tranzakció megváltozik (%s a parancsban lecserélődik a blokk TxID-re)</translation>
+ </message>
+ <message>
+ <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>Figyelem: a -paytxfee nagyon magas. Ennyi tranzakciós díjat fogsz fizetni, ha elküldöd a tranzakciót.</translation>
+ </message>
+ <message>
+ <source>Connect only to the specified node(s)</source>
+ <translation>Csatlakozás csak a megadott csomóponthoz</translation>
+ </message>
+ <message>
+ <source>Corrupted block database detected</source>
+ <translation>Sérült blokk-adatbázis észlelve</translation>
+ </message>
+ <message>
+ <source>Do you want to rebuild the block database now?</source>
+ <translation>Újra akarod építeni a blokk adatbázist most?</translation>
+ </message>
+ <message>
+ <source>Error initializing block database</source>
+ <translation>A blokkadatbázis inicializálása nem sikerült</translation>
+ </message>
+ <message>
+ <source>Error initializing wallet database environment %s!</source>
+ <translation>A tárca-adatbázis inicializálása nem sikerült: %s!</translation>
+ </message>
+ <message>
+ <source>Error loading block database</source>
+ <translation>Hiba a blokk adatbázis betöltése közben.</translation>
+ </message>
+ <message>
+ <source>Error opening block database</source>
+ <translation>Hiba a blokk adatbázis megnyitása közben.</translation>
+ </message>
+ <message>
+ <source>Error: Disk space is low!</source>
+ <translation>Hiba: kevés a hely a lemezen!</translation>
+ </message>
+ <message>
+ <source>Failed to listen on any port. Use -listen=0 if you want this.</source>
+ <translation>Egyik hálózati porton sem sikerül hallgatni. Használja a -listen=0 kapcsolót, ha ezt szeretné.</translation>
+ </message>
+ <message>
+ <source>Importing...</source>
+ <translation>Importálás</translation>
+ </message>
+ <message>
+ <source>Incorrect or no genesis block found. Wrong datadir for network?</source>
+ <translation>Helytelen vagy nemlétező genézis blokk. Helytelen hálózati adatkönyvtár?</translation>
+ </message>
+ <message>
+ <source>Not enough file descriptors available.</source>
+ <translation>Nincs elég fájlleíró. </translation>
+ </message>
+ <message>
+ <source>Verifying blocks...</source>
+ <translation>Blokkok ellenőrzése...</translation>
+ </message>
+ <message>
+ <source>Verifying wallet...</source>
+ <translation>Tárca ellenőrzése...</translation>
+ </message>
+ <message>
+ <source>Wallet options:</source>
+ <translation>Tárca beállítások:</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to change -txindex</source>
+ <translation>Az adatbázist újra kell építeni -reindex használatával (módosítás -tindex).</translation>
+ </message>
+ <message>
+ <source>Choose data directory on startup (default: 0)</source>
+ <translation>Adatkönyvtár kiválasztása induláskor (alapbeállítás: 0)</translation>
+ </message>
+ <message>
+ <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source>
+ <translation>Copyright (C) 2009-%i A Bitcoin Core Fejlesztői</translation>
+ </message>
+ <message>
+ <source>Error reading from database, shutting down.</source>
+ <translation>Hiba az adatbázis olvasásakor, leállítás</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Információ</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -minrelaytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Érvénytelen -minrelaytxfee=&lt;amount&gt;: '%s' összeg</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -mintxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Érvénytelen -mintxfee=&lt;amount&gt;: '%s' összeg</translation>
+ </message>
+ <message>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>trace/debug információ küldése a konzolra a debog.log fájl helyett</translation>
+ </message>
+ <message>
+ <source>Set SSL root certificates for payment request (default: -system-)</source>
+ <translation>SLL gyökér-igazolások megadása fizetési kérelmekhez (alapértelmezett: -system-)</translation>
+ </message>
+ <message>
+ <source>Set language, for example "de_DE" (default: system locale)</source>
+ <translation>Nyelvbeállítás, például "de_DE" (alapértelmezett: rendszer nyelve)</translation>
+ </message>
+ <message>
+ <source>Show splash screen on startup (default: 1)</source>
+ <translation>Indítóképernyő mutatása induláskor (alapértelmezett: 1)</translation>
+ </message>
+ <message>
+ <source>Signing transaction failed</source>
+ <translation>Tranzakció aláírása sikertelen</translation>
+ </message>
+ <message>
+ <source>Start minimized</source>
+ <translation>Indítás lekicsinyítve
+</translation>
+ </message>
+ <message>
+ <source>This is experimental software.</source>
+ <translation>Ez egy kísérleti szoftver.</translation>
+ </message>
+ <message>
+ <source>Transaction amount too small</source>
+ <translation>Tranzakció összege túl alacsony</translation>
+ </message>
+ <message>
+ <source>Transaction amounts must be positive</source>
+ <translation>Tranzakció összege pozitív kell legyen</translation>
+ </message>
+ <message>
+ <source>Transaction too large</source>
+ <translation>Túl nagy tranzakció</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: 1 when listening)</source>
+ <translation>UPnP-használat engedélyezése a figyelő port feltérképezésénél (default: 1 when listening)</translation>
+ </message>
+ <message>
+ <source>Username for JSON-RPC connections</source>
+ <translation>Felhasználói név JSON-RPC csatlakozásokhoz
+</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Figyelem</translation>
+ </message>
+ <message>
+ <source>Password for JSON-RPC connections</source>
+ <translation>Jelszó JSON-RPC csatlakozásokhoz
+</translation>
+ </message>
+ <message>
+ <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
+ <translation>Parancs, amit akkor hajt végre, amikor a legjobb blokk megváltozik (%s a cmd-ban lecserélődik a blokk hash-re)</translation>
+ </message>
+ <message>
+ <source>Upgrade wallet to latest format</source>
+ <translation>A Tárca frissítése a legfrissebb formátumra</translation>
+ </message>
+ <message>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>Blokklánc újraszkennelése hiányzó tárca-tranzakciók után
+</translation>
+ </message>
+ <message>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>OpenSSL (https) használata JSON-RPC csatalkozásokhoz
+</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>Ez a súgó-üzenet
+</translation>
+ </message>
+ <message>
+ <source>Allow DNS lookups for -addnode, -seednode and -connect</source>
+ <translation>DNS-kikeresés engedélyezése az addnode-nál és a connect-nél</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>Címek betöltése...</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>Hiba a wallet.dat betöltése közben: meghibásodott tárca</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>Hiba az wallet.dat betöltése közben</translation>
+ </message>
+ <message>
+ <source>Invalid -proxy address: '%s'</source>
+ <translation>Érvénytelen -proxy cím: '%s'</translation>
+ </message>
+ <message>
+ <source>Unknown network specified in -onlynet: '%s'</source>
+ <translation>Ismeretlen hálózat lett megadva -onlynet: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -bind address: '%s'</source>
+ <translation>Csatlakozási cím (-bind address) feloldása nem sikerült: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -externalip address: '%s'</source>
+ <translation>Külső cím (-externalip address) feloldása nem sikerült: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Étvénytelen -paytxfee=&lt;összeg&gt; összeg: '%s'</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>Nincs elég bitcoinod.</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>Blokkindex betöltése...</translation>
+ </message>
+ <message>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>Elérendő csomópont megadása and attempt to keep the connection open</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>Tárca betöltése...</translation>
+ </message>
+ <message>
+ <source>Cannot downgrade wallet</source>
+ <translation>Nem sikerült a Tárca visszaállítása a korábbi verzióra</translation>
+ </message>
+ <message>
+ <source>Cannot write default address</source>
+ <translation>Nem sikerült az alapértelmezett címet írni.</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>Újraszkennelés...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>Betöltés befejezve.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Hiba</translation>
+ </message>
+</context>
+</TS> \ No newline at end of file
diff --git a/src/qt/locale/bitcoin_id_ID.ts b/src/qt/locale/bitcoin_id_ID.ts
new file mode 100644
index 0000000000..5f2c0880fe
--- /dev/null
+++ b/src/qt/locale/bitcoin_id_ID.ts
@@ -0,0 +1,2490 @@
+<TS language="id_ID" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Create a new address</source>
+ <translation>Buat alamat baru</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>&amp;Baru</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Salin alamat yang dipilih ke clipboard</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>&amp;Menyalin</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>T&amp;utup</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>&amp;Salin Alamat</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>Hapus alamat yang sementara dipilih dari daftar</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Ekspor data dalam tab sekarang ke sebuah berkas</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Ekspor</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;Hapus</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>Pilihlah alamat kemana koin Anda akan dikirim </translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>Pilihlah alamat dimana Anda akan menerima koin</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>P&amp;ilihlah</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>Alamat-alamat mengirim</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>Alamat-alamat menerima</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>Alamat-alamat Anda supaya mengirim pembayaran. Periksalah jumlah dan alamat penerima setiap kali Anda mengirim Bitcoin.</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>Alamat-alamat Anda supaya menerima pembayaran. Dianjurkan agar Anda menggunakan alamat menerima yang baru untuk setiap transaksi.</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>Salin &amp;Label</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>&amp;Ubah</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>Ekspor Daftar Alamat</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Berkas CSV (*.csv)</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Proses Ekspor Gagal</translation>
+ </message>
+ </context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Label</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Alamat</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(tidak ada label)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Passphrase Dialog</source>
+ <translation>Dialog Kata kunci</translation>
+ </message>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Masukkan kata kunci</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Kata kunci baru</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Ulangi kata kunci baru</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>Enkripsi dompet</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>Operasi ini memerlukan kata kunci dompet Anda untuk membuka dompet ini.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Buka dompet</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>Operasi ini memerlukan kata kunci dompet Anda untuk mendekripsi dompet ini.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>Dekripsi dompet</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>Ubah kata kunci</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>Konfirmasi enkripsi dompet</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>Perhatian: Jika anda mengenkripsi dompet anda dan lupa kata kuncinya, anda pasti &lt;b&gt;KEHILANGAN SELURUH BITCOIN ANDA&lt;/B&gt;!</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>Apakah kamu yakin ingin mengenkripsi dompet anda?</translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>Perhatian: tombol Caps Lock sementara aktif!</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>Dompet terenkripsi</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>Enkripsi dompet gagal</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>Enkripsi dompet gagal karena kesalahan internal. Dompet Anda tidak dienkripsi.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>Kata kunci yang dimasukkan tidak cocok.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>Gagal buka dompet</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>Kata kunci yang dimasukkan untuk dekripsi dompet tidak cocok.</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>Dekripsi dompet gagal</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>Kata kunci untuk dompet berubah berhasil.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>Pesan &amp;penanda...</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>Sinkronisasi dengan jaringan...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;Kilasan</translation>
+ </message>
+ <message>
+ <source>Node</source>
+ <translation>Node</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>Tampilkan kilasan umum dari dompet</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Transaksi</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>Jelajah sejarah transaksi</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>K&amp;eluar</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>Keluar dari aplikasi</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>Mengenai &amp;Qt</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>Tampilkan informasi mengenai Qt</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;Pilihan...</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>&amp;Cadangkan Dompet...</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>&amp;Ubah Kata Kunci...</translation>
+ </message>
+ <message>
+ <source>&amp;Sending addresses...</source>
+ <translation>Alamat-alamat &amp;Mengirim</translation>
+ </message>
+ <message>
+ <source>&amp;Receiving addresses...</source>
+ <translation>Alamat-alamat &amp;Menerima</translation>
+ </message>
+ <message>
+ <source>Open &amp;URI...</source>
+ <translation>Buka &amp;URI</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core client</source>
+ <translation>Client Bitcoin Inti</translation>
+ </message>
+ <message>
+ <source>Importing blocks from disk...</source>
+ <translation>Blok-blok sedang di-impor dari disk</translation>
+ </message>
+ <message>
+ <source>Reindexing blocks on disk...</source>
+ <translation>Mengindex ulang block di harddisk...</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>Kirim koin ke alamat Bitcoin</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>Cadangkan dompet ke lokasi lain</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Ubah kata kunci yang digunakan untuk enkripsi dompet</translation>
+ </message>
+ <message>
+ <source>&amp;Debug window</source>
+ <translation>&amp;Jendela Debug</translation>
+ </message>
+ <message>
+ <source>Open debugging and diagnostic console</source>
+ <translation>Buka konsol debug dan diagnosa</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>&amp;Verifikasi pesan...</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>Dompet</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>&amp;Kirim</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>&amp;Menerima</translation>
+ </message>
+ <message>
+ <source>Show information about Bitcoin Core</source>
+ <translation>Tampilkan informasi tentang Bitcoin Inti</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>&amp;Sunjukkan / Menyembungi</translation>
+ </message>
+ <message>
+ <source>Show or hide the main Window</source>
+ <translation>Tampilkan atau sembunyikan jendela utama</translation>
+ </message>
+ <message>
+ <source>Encrypt the private keys that belong to your wallet</source>
+ <translation>Mengenkripsi kunci-kunci pribadi yang dipunyai dompetmu</translation>
+ </message>
+ <message>
+ <source>Sign messages with your Bitcoin addresses to prove you own them</source>
+ <translation>Tandalah pesanan dengan alamat-alamat Bitcoin Anda supaya membuktikan pesanan itu dikirim oleh Anda</translation>
+ </message>
+ <message>
+ <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source>
+ <translation>Periksakan pesan-pesan supaya menjaminkan ditandatangani oleh alamat Bitcoin yang terperinci</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;Berkas</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;Pengaturan</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>&amp;Bantuan</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>Baris tab</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Request payments (generates QR codes and bitcoin: URIs)</source>
+ <translation>Permintaan pembayaran (membangkitkan kode QR dan bitcoin: URIs)</translation>
+ </message>
+ <message>
+ <source>&amp;About Bitcoin Core</source>
+ <translation>&amp;Mengenai Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Show the list of used sending addresses and labels</source>
+ <translation>Tampilkan daftar alamat dan label yang terkirim</translation>
+ </message>
+ <message>
+ <source>Show the list of used receiving addresses and labels</source>
+ <translation>Tampilkan daftar alamat dan label yang diterima</translation>
+ </message>
+ <message>
+ <source>Open a bitcoin: URI or payment request</source>
+ <translation>Buka URI bitcoin: atau permintaan pembayaran</translation>
+ </message>
+ <message>
+ <source>&amp;Command-line options</source>
+ <translation>&amp;pilihan Perintah-baris</translation>
+ </message>
+ <message>
+ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
+ <translation>Tampilkan pesan bantuan Bitcoin Core untuk memberikan daftar pilihan perintah-baris yang memungkinkan dalam aplikasi Bitcoin</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n active connection(s) to Bitcoin network</source>
+ <translation><numerusform>%n hubungan aktif ke jaringan Bitcoin</numerusform></translation>
+ </message>
+ <message>
+ <source>No block source available...</source>
+ <translation>Sumber blok tidak tersedia...</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n hour(s)</source>
+ <translation><numerusform>%n jam</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n day(s)</source>
+ <translation><numerusform>%n hari</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n week(s)</source>
+ <translation><numerusform>%n minggu</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 and %2</source>
+ <translation>%1 dan %2</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n year(s)</source>
+ <translation><numerusform>%n tahun</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 behind</source>
+ <translation>kurang %1</translation>
+ </message>
+ <message>
+ <source>Last received block was generated %1 ago.</source>
+ <translation>Blok terakhir dibuat %1 lalu.</translation>
+ </message>
+ <message>
+ <source>Transactions after this will not yet be visible.</source>
+ <translation>Transaksi setelah ini tidak akan ditampilkan</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Gagal</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Peringatan</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Informasi</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>Terbaru</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>Menyusul...</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>Transaksi terkirim</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>Transaksi diterima</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>Dompet saat ini &lt;b&gt;terenkripsi&lt;/b&gt; dan &lt;b&gt;terbuka&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>Dompet saat ini &lt;b&gt;terenkripsi&lt;/b&gt; dan &lt;b&gt;terkunci&lt;/b&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <source>Network Alert</source>
+ <translation>Notifikasi Jaringan</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Quantity:</source>
+ <translation>Kuantitas:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Bytes:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Nilai:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Prioritas:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Biaya:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Dengan Biaya:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Uang Kembali:</translation>
+ </message>
+ <message>
+ <source>(un)select all</source>
+ <translation>(Tidak)memilih semua</translation>
+ </message>
+ <message>
+ <source>Tree mode</source>
+ <translation>mode pohon</translation>
+ </message>
+ <message>
+ <source>List mode</source>
+ <translation>Mode daftar</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Nilai</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Tanggal</translation>
+ </message>
+ <message>
+ <source>Confirmations</source>
+ <translation>Konfirmasi-konfirmasi</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Terkonfirmasi</translation>
+ </message>
+ <message>
+ <source>Priority</source>
+ <translation>Prioritas</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Salin alamat</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Salin label</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Salin nilai</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Menyalinkan ID transaksi</translation>
+ </message>
+ <message>
+ <source>Lock unspent</source>
+ <translation>Kunci terpakai.</translation>
+ </message>
+ <message>
+ <source>Unlock unspent</source>
+ <translation>Membuka kunci terpakai</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Salin kuantitas</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Salin biaya</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Salin dengan biaya</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Salin bytes</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Salin prioritas</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Salin uang kembali</translation>
+ </message>
+ <message>
+ <source>highest</source>
+ <translation>terbesar</translation>
+ </message>
+ <message>
+ <source>higher</source>
+ <translation>lebih besar</translation>
+ </message>
+ <message>
+ <source>high</source>
+ <translation>besar</translation>
+ </message>
+ <message>
+ <source>medium-high</source>
+ <translation>sedang-sampai-besar</translation>
+ </message>
+ <message>
+ <source>medium</source>
+ <translation>sedang</translation>
+ </message>
+ <message>
+ <source>low-medium</source>
+ <translation>sedikit-sampai-sedang</translation>
+ </message>
+ <message>
+ <source>low</source>
+ <translation>sedikit</translation>
+ </message>
+ <message>
+ <source>lower</source>
+ <translation>lebih sedikit</translation>
+ </message>
+ <message>
+ <source>lowest</source>
+ <translation>tersedikit</translation>
+ </message>
+ <message>
+ <source>(%1 locked)</source>
+ <translation>(%1 terkunci)</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>tidak satupun</translation>
+ </message>
+ <message>
+ <source>yes</source>
+ <translation>ya</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>tidak</translation>
+ </message>
+ <message>
+ <source>This means a fee of at least %1 per kB is required.</source>
+ <translation>Berarti perlu biaya lebih dari %1 untuk setiap kB.</translation>
+ </message>
+ <message>
+ <source>Can vary +/- 1 byte per input.</source>
+ <translation>Boleh berbeda +/- 1 byte setiap masukan.</translation>
+ </message>
+ <message>
+ <source>Transactions with higher priority are more likely to get included into a block.</source>
+ <translation>Makin penting transaksinya, makin kemungkinan akan termasuk dalam blok.</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(tidak ada label)</translation>
+ </message>
+ <message>
+ <source>change from %1 (%2)</source>
+ <translation>uang kembali dari %1 (%2)</translation>
+ </message>
+ <message>
+ <source>(change)</source>
+ <translation>(uang kembali)</translation>
+ </message>
+</context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>Ubah Alamat</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>&amp;Label</translation>
+ </message>
+ <message>
+ <source>The label associated with this address list entry</source>
+ <translation>Label yang terkait dengan daftar alamat yang dimasukkan ini</translation>
+ </message>
+ <message>
+ <source>The address associated with this address list entry. This can only be modified for sending addresses.</source>
+ <translation>Alamat yang terkait dengan entri buku alamat ini. Hanya dapat diubah untuk alamat pengirim.</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;Alamat</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>Alamat menerima baru</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>Alamat mengirim baru</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>Ubah alamat menerima</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>Ubah alamat mengirim</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>Alamat yang dimasukkan "%1" sudah ada di dalam buku alamat.</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is not a valid Bitcoin address.</source>
+ <translation>Alamat yang dimasukkan "%1" bukan alamat Bitcoin yang benar.</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>Tidak dapat membuka dompet.</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>Pembuatan kunci baru gagal.</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ <message>
+ <source>A new data directory will be created.</source>
+ <translation>Sebuah data direktori baru telah dibuat.</translation>
+ </message>
+ <message>
+ <source>name</source>
+ <translation>nama</translation>
+ </message>
+ <message>
+ <source>Directory already exists. Add %1 if you intend to create a new directory here.</source>
+ <translation>Direktori masih ada. Tambahlah %1 kalau ingin membuat direktori baru disini.</translation>
+ </message>
+ <message>
+ <source>Path already exists, and is not a directory.</source>
+ <translation>Masih ada Path, dan path itu bukan direktori.</translation>
+ </message>
+ <message>
+ <source>Cannot create data directory here.</source>
+ <translation>Tidak busa membuat direktori untuk data disini.</translation>
+ </message>
+</context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>versi</translation>
+ </message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>Mengenai Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>Penggunaan:</translation>
+ </message>
+ <message>
+ <source>command-line options</source>
+ <translation>pilihan perintah-baris</translation>
+ </message>
+</context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Welcome</source>
+ <translation>Selamat Datang</translation>
+ </message>
+ <message>
+ <source>Welcome to Bitcoin Core.</source>
+ <translation>Selamat Datang ke Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Use the default data directory</source>
+ <translation>Menggunakan direktori untuk data yang biasa.</translation>
+ </message>
+ <message>
+ <source>Use a custom data directory:</source>
+ <translation>Menggunakan direktori data yang dipilih Anda:</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Gagal</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n GB of free space available</source>
+ <translation><numerusform>%n GB dari ruang yang tersedia</numerusform></translation>
+ </message>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ <message>
+ <source>Open URI</source>
+ <translation>Buka URI</translation>
+ </message>
+ <message>
+ <source>Open payment request from URI or file</source>
+ <translation>Buka permintaan pembayaran dari URI atau arsip</translation>
+ </message>
+ <message>
+ <source>URI:</source>
+ <translation>URI:</translation>
+ </message>
+ <message>
+ <source>Select payment request file</source>
+ <translation>Pilihlah arsip permintaan pembayaran</translation>
+ </message>
+ <message>
+ <source>Select payment request file to open</source>
+ <translation>Pilihlah arsip permintaan pembayaran yang Anda ingin membuka</translation>
+ </message>
+</context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>Pilihan</translation>
+ </message>
+ <message>
+ <source>&amp;Main</source>
+ <translation>&amp;Utama</translation>
+ </message>
+ <message>
+ <source>MB</source>
+ <translation>MB</translation>
+ </message>
+ <message>
+ <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
+ <translation>Alamat IP proxy (cth. IPv4: 127.0.0.1 / IPv6: ::1)</translation>
+ </message>
+ <message>
+ <source>Third party transaction URLs</source>
+ <translation>Transaksi URLs pihak ketiga</translation>
+ </message>
+ <message>
+ <source>Active command-line options that override above options:</source>
+ <translation>pilihan perintah-baris aktif menimpa atas pilihan-pilihan: </translation>
+ </message>
+ <message>
+ <source>Reset all client options to default.</source>
+ <translation>Reset setiap pilihan untuk pilihan biasa</translation>
+ </message>
+ <message>
+ <source>&amp;Reset Options</source>
+ <translation>&amp;Reset Pilihan</translation>
+ </message>
+ <message>
+ <source>&amp;Network</source>
+ <translation>&amp;Jaringan</translation>
+ </message>
+ <message>
+ <source>W&amp;allet</source>
+ <translation>D&amp;ompet</translation>
+ </message>
+ <message>
+ <source>Expert</source>
+ <translation>Ahli</translation>
+ </message>
+ <message>
+ <source>Enable coin &amp;control features</source>
+ <translation>Nyalain cara &amp;pengaturan koin</translation>
+ </message>
+ <message>
+ <source>If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.</source>
+ <translation>Jika Anda menonaktifkan perubahan saldo untuk transaksi yang belum dikonfirmasi, perubahan dari transaksi tidak dapat dilakukan sampai transaksi memiliki setidaknya satu konfirmasi. Hal ini juga mempengaruhi bagaimana saldo Anda dihitung.</translation>
+ </message>
+ <message>
+ <source>&amp;Spend unconfirmed change</source>
+ <translation>&amp;Perubahan saldo untuk transaksi yang belum dikonfirmasi</translation>
+ </message>
+ <message>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>Otomatis membuka port client Bitcoin di router. Hanya berjalan apabila router anda mendukung UPnP dan di-enable.</translation>
+ </message>
+ <message>
+ <source>Map port using &amp;UPnP</source>
+ <translation>Petakan port dengan &amp;UPnP</translation>
+ </message>
+ <message>
+ <source>Proxy &amp;IP:</source>
+ <translation>IP Proxy:</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>&amp;Port:</translation>
+ </message>
+ <message>
+ <source>Port of the proxy (e.g. 9050)</source>
+ <translation>Port proxy (cth. 9050)</translation>
+ </message>
+ <message>
+ <source>&amp;Window</source>
+ <translation>&amp;Jendela</translation>
+ </message>
+ <message>
+ <source>Show only a tray icon after minimizing the window.</source>
+ <translation>Hanya tampilkan ikon tray setelah meminilisasi jendela</translation>
+ </message>
+ <message>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>&amp;Meminilisasi ke tray daripada taskbar</translation>
+ </message>
+ <message>
+ <source>M&amp;inimize on close</source>
+ <translation>M&amp;eminilisasi saat tutup</translation>
+ </message>
+ <message>
+ <source>&amp;Display</source>
+ <translation>&amp;Tampilan</translation>
+ </message>
+ <message>
+ <source>User Interface &amp;language:</source>
+ <translation>&amp;Bahasa Antarmuka Pengguna:</translation>
+ </message>
+ <message>
+ <source>&amp;Unit to show amounts in:</source>
+ <translation>&amp;Unit untuk menunjukkan nilai:</translation>
+ </message>
+ <message>
+ <source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
+ <translation>Pilihan standar unit yang ingin ditampilkan pada layar aplikasi dan saat mengirim koin.</translation>
+ </message>
+ <message>
+ <source>Whether to show coin control features or not.</source>
+ <translation>Ingin menunjukkan cara pengaturan koin atau tidak.</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>&amp;YA</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>&amp;Batal</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>standar</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>tidak satupun</translation>
+ </message>
+ <message>
+ <source>Confirm options reset</source>
+ <translation>Memastikan reset pilihan</translation>
+ </message>
+ <message>
+ <source>Client restart required to activate changes.</source>
+ <translation>Restart klien diperlukan untuk mengaktifkan perubahan.</translation>
+ </message>
+ <message>
+ <source>This change would require a client restart.</source>
+ <translation>Perubahan ini akan memerlukan restart klien</translation>
+ </message>
+ <message>
+ <source>The supplied proxy address is invalid.</source>
+ <translation>Alamat proxy yang diisi tidak valid.</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>Formulir</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>Informasi terlampir mungkin sudah kedaluwarsa. Dompet Anda secara otomatis mensinkronisasi dengan jaringan Bitcoin ketika sebuah hubungan terbentuk, namun proses ini belum selesai.</translation>
+ </message>
+ <message>
+ <source>Available:</source>
+ <translation>Tersedia:</translation>
+ </message>
+ <message>
+ <source>Your current spendable balance</source>
+ <translation>Jumlah yang Anda bisa keluarkan sekarang</translation>
+ </message>
+ <message>
+ <source>Pending:</source>
+ <translation>Ditunda</translation>
+ </message>
+ <message>
+ <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source>
+ <translation>Jumlah keseluruhan transaksi yang belum dikonfirmasi, dan belum saatnya dihitung sebagai pengeluaran saldo yang telah dibelanjakan.</translation>
+ </message>
+ <message>
+ <source>Immature:</source>
+ <translation>Terlalu Muda:</translation>
+ </message>
+ <message>
+ <source>Mined balance that has not yet matured</source>
+ <translation>Saldo ditambang yang masih terlalu muda</translation>
+ </message>
+ <message>
+ <source>Total:</source>
+ <translation>Jumlah:</translation>
+ </message>
+ <message>
+ <source>Your current total balance</source>
+ <translation>Jumlah saldo Anda sekarang</translation>
+ </message>
+ </context>
+<context>
+ <name>PaymentServer</name>
+ <message>
+ <source>URI handling</source>
+ <translation>Penanganan URI</translation>
+ </message>
+ <message>
+ <source>Invalid payment address %1</source>
+ <translation>Alamat pembayaran salah %1</translation>
+ </message>
+ <message>
+ <source>Requested payment amount of %1 is too small (considered dust).</source>
+ <translation>Nilai pembayaran %1 yang diminta oleh Anda terlalu sedikit (dianggap debu).</translation>
+ </message>
+ <message>
+ <source>Payment request error</source>
+ <translation>Gagalan permintaan pembayaran</translation>
+ </message>
+ <message>
+ <source>Refund from %1</source>
+ <translation>Pembayaran kembali dari %1</translation>
+ </message>
+ <message>
+ <source>Error communicating with %1: %2</source>
+ <translation>Masalah berkomunikasi dengan %1: %2</translation>
+ </message>
+ <message>
+ <source>Bad response from server %1</source>
+ <translation>Jawaban salah dari server %1</translation>
+ </message>
+ <message>
+ <source>Payment acknowledged</source>
+ <translation>Pembayaran diakui</translation>
+ </message>
+ <message>
+ <source>Network request error</source>
+ <translation>Gagalan permintaan dari jaringan</translation>
+ </message>
+</context>
+<context>
+ <name>PeerTableModel</name>
+ </context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>Nilai</translation>
+ </message>
+ <message>
+ <source>%1 h</source>
+ <translation>%1 Jam</translation>
+ </message>
+ <message>
+ <source>%1 m</source>
+ <translation>%1 menit</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>T/S</translation>
+ </message>
+ </context>
+<context>
+ <name>QRImageWidget</name>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Simpan Gambaran...</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Image</source>
+ <translation>&amp;Salin Gambaran</translation>
+ </message>
+ <message>
+ <source>Save QR Code</source>
+ <translation>Simpan Kode QR</translation>
+ </message>
+ <message>
+ <source>PNG Image (*.png)</source>
+ <translation>Gambar PNG (*.png)</translation>
+ </message>
+</context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>Client name</source>
+ <translation>Nama Klien</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>T/S</translation>
+ </message>
+ <message>
+ <source>Client version</source>
+ <translation>Versi Klien</translation>
+ </message>
+ <message>
+ <source>&amp;Information</source>
+ <translation>&amp;Informasi</translation>
+ </message>
+ <message>
+ <source>Debug window</source>
+ <translation>Jendela debug</translation>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>Umum</translation>
+ </message>
+ <message>
+ <source>Using OpenSSL version</source>
+ <translation>Menggunakan versi OpenSSL</translation>
+ </message>
+ <message>
+ <source>Startup time</source>
+ <translation>Waktu nyala</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Jaringan</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>Nama</translation>
+ </message>
+ <message>
+ <source>Number of connections</source>
+ <translation>Jumlah hubungan</translation>
+ </message>
+ <message>
+ <source>Block chain</source>
+ <translation>Rantai blok</translation>
+ </message>
+ <message>
+ <source>Current number of blocks</source>
+ <translation>Jumlah blok terkini</translation>
+ </message>
+ <message>
+ <source>Last block time</source>
+ <translation>Waktu blok terakhir</translation>
+ </message>
+ <message>
+ <source>&amp;Open</source>
+ <translation>&amp;Buka</translation>
+ </message>
+ <message>
+ <source>&amp;Console</source>
+ <translation>&amp;Konsol</translation>
+ </message>
+ <message>
+ <source>&amp;Network Traffic</source>
+ <translation>Kemacetan &amp;Jaringan </translation>
+ </message>
+ <message>
+ <source>&amp;Clear</source>
+ <translation>&amp;Kosongkan</translation>
+ </message>
+ <message>
+ <source>Totals</source>
+ <translation>Total</translation>
+ </message>
+ <message>
+ <source>In:</source>
+ <translation>Masuk:</translation>
+ </message>
+ <message>
+ <source>Out:</source>
+ <translation>Keluar:</translation>
+ </message>
+ <message>
+ <source>Build date</source>
+ <translation>Tanggal pembuatan</translation>
+ </message>
+ <message>
+ <source>Debug log file</source>
+ <translation>Berkas catatan debug</translation>
+ </message>
+ <message>
+ <source>Clear console</source>
+ <translation>Bersihkan konsol</translation>
+ </message>
+ <message>
+ <source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
+ <translation>Gunakan panah keatas dan kebawah untuk menampilkan sejarah, dan &lt;b&gt;Ctrl-L&lt;/b&gt; untuk bersihkan layar.</translation>
+ </message>
+ <message>
+ <source>Type &lt;b&gt;help&lt;/b&gt; for an overview of available commands.</source>
+ <translation>Ketik &lt;b&gt;help&lt;/b&gt; untuk menampilkan perintah tersedia.</translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation>%1 B</translation>
+ </message>
+ <message>
+ <source>%1 KB</source>
+ <translation>%1 KB</translation>
+ </message>
+ <message>
+ <source>%1 MB</source>
+ <translation>%1 MB</translation>
+ </message>
+ <message>
+ <source>%1 GB</source>
+ <translation>%1 GB</translation>
+ </message>
+ </context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Amount:</source>
+ <translation>&amp;Nilai:</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Label:</translation>
+ </message>
+ <message>
+ <source>&amp;Message:</source>
+ <translation>&amp;Pesan:</translation>
+ </message>
+ <message>
+ <source>R&amp;euse an existing receiving address (not recommended)</source>
+ <translation>Gunakan lagi alamat penerima yang ada (tidak disarankan)</translation>
+ </message>
+ <message>
+ <source>An optional label to associate with the new receiving address.</source>
+ <translation>Label opsional untuk mengasosiasikan dengan alamat penerima baru.</translation>
+ </message>
+ <message>
+ <source>Use this form to request payments. All fields are &lt;b&gt;optional&lt;/b&gt;.</source>
+ <translation>Gunakan form ini untuk meminta pembayaran. Semua bidang adalah &lt;b&gt;opsional&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>An optional amount to request. Leave this empty or zero to not request a specific amount.</source>
+ <translation>Nilai permintaan opsional. Biarkan ini kosong atau nol bila tidak meminta nilai tertentu.</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Hapus informasi dari form.</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation>Hapus</translation>
+ </message>
+ <message>
+ <source>Requested payments history</source>
+ <translation>Riwayat pembayaran yang diminta Anda</translation>
+ </message>
+ <message>
+ <source>&amp;Request payment</source>
+ <translation>&amp;Minta pembayaran</translation>
+ </message>
+ <message>
+ <source>Show the selected request (does the same as double clicking an entry)</source>
+ <translation>Menunjukkan permintaan yang dipilih (sama dengan tekan pilihan dua kali)</translation>
+ </message>
+ <message>
+ <source>Show</source>
+ <translation>Menunjukkan</translation>
+ </message>
+ <message>
+ <source>Remove the selected entries from the list</source>
+ <translation>Menghapus informasi terpilih dari daftar</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>Menghapus</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Salin label</translation>
+ </message>
+ <message>
+ <source>Copy message</source>
+ <translation>Salin Pesan</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Salin nilai</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>QR Code</source>
+ <translation>Kode QR</translation>
+ </message>
+ <message>
+ <source>Copy &amp;URI</source>
+ <translation>Salin &amp;URI</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Address</source>
+ <translation>Salin &amp;Alamat</translation>
+ </message>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Simpan Gambaran...</translation>
+ </message>
+ <message>
+ <source>Request payment to %1</source>
+ <translation>Minta pembayaran ke %1</translation>
+ </message>
+ <message>
+ <source>Payment information</source>
+ <translation>Informasi pembayaran</translation>
+ </message>
+ <message>
+ <source>URI</source>
+ <translation>URI</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Alamat</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Nilai</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Label</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Pesan</translation>
+ </message>
+ <message>
+ <source>Resulting URI too long, try to reduce the text for label / message.</source>
+ <translation>Hasil URI terlalu panjang, coba kurangi label / pesan.</translation>
+ </message>
+ <message>
+ <source>Error encoding URI into QR Code.</source>
+ <translation>Gagal mengubah URI ke kode QR.</translation>
+ </message>
+</context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Tanggal</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Label</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Pesan:</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Nilai</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(tidak ada label)</translation>
+ </message>
+ <message>
+ <source>(no message)</source>
+ <translation>(tidak ada pesan)</translation>
+ </message>
+ <message>
+ <source>(no amount)</source>
+ <translation>(tidak ada nilai)</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Kirim Koin</translation>
+ </message>
+ <message>
+ <source>Coin Control Features</source>
+ <translation>Cara Pengaturan Koin</translation>
+ </message>
+ <message>
+ <source>Inputs...</source>
+ <translation>Masukan...</translation>
+ </message>
+ <message>
+ <source>automatically selected</source>
+ <translation>Pemilihan otomatis</translation>
+ </message>
+ <message>
+ <source>Insufficient funds!</source>
+ <translation>Saldo tidak mencukupi!</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Kuantitas:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Bytes:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Nilai:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Prioritas:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Biaya:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Dengan Biaya:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Uang Kembali:</translation>
+ </message>
+ <message>
+ <source>If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address.</source>
+ <translation>Jiki ini dipilih, tetapi alamat pengembalian uang kosong atau salah, uang kembali akan dikirim ke alamat yang baru dibuat.</translation>
+ </message>
+ <message>
+ <source>Custom change address</source>
+ <translation>Alamat uang kembali yang kustom</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>Kirim ke beberapa penerima sekaligus</translation>
+ </message>
+ <message>
+ <source>Add &amp;Recipient</source>
+ <translation>Tambahlah &amp;Penerima</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Hapus informasi dari form.</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>Saldo:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>Konfirmasi aksi pengiriman</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>K&amp;irim</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>Konfirmasi pengiriman koin</translation>
+ </message>
+ <message>
+ <source>%1 to %2</source>
+ <translation>%1 ke %2</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Salin kuantitas</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Salin nilai</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Salin biaya</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Salin dengan biaya</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Salin bytes</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Salin prioritas</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Salin uang kembali</translation>
+ </message>
+ <message>
+ <source>or</source>
+ <translation>atau</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>Nilai yang dibayar harus lebih besar dari 0.</translation>
+ </message>
+ <message>
+ <source>The amount exceeds your balance.</source>
+ <translation>Nilai melebihi saldo Anda.</translation>
+ </message>
+ <message>
+ <source>The total exceeds your balance when the %1 transaction fee is included.</source>
+ <translation>Jumlah melebihi saldo Anda ketika biaya transaksi %1 ditambahkan.</translation>
+ </message>
+ <message>
+ <source>Transaction creation failed!</source>
+ <translation>Gagal membuat transaksi!</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>Gagal: Transaksi ditolak. Ini mungkin terjadi jika beberapa dari koin dalam dompet Anda telah digunakan, seperti ketika Anda menggunakan salinan wallet.dat dan beberapa koin telah dibelanjakan dalam salinan tersebut tetapi disini tidak tertandai sebagai terpakai.</translation>
+ </message>
+ <message>
+ <source>Warning: Invalid Bitcoin address</source>
+ <translation>Awas: Alamat Bitcoin tidak sah</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(tidak ada label)</translation>
+ </message>
+ <message>
+ <source>Are you sure you want to send?</source>
+ <translation>Apakah Anda yakin ingin kirim?</translation>
+ </message>
+ <message>
+ <source>added as transaction fee</source>
+ <translation>ditambahkan sebagai biaya transaksi</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>J&amp;umlah:</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>Kirim &amp;Ke:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Masukkan label bagi alamat ini untuk menambahkannya ke buku alamat Anda</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Label:</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Pilih alamat yang telah digunakan sebelumnya</translation>
+ </message>
+ <message>
+ <source>This is a normal payment.</source>
+ <translation>Ini adalah pembayaran normal</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+J</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Tempel alamat dari salinan</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+B</translation>
+ </message>
+ <message>
+ <source>Remove this entry</source>
+ <translation>Hapus masukan ini</translation>
+ </message>
+ <message>
+ <source>Message:</source>
+ <translation>Pesan:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to the list of used addresses</source>
+ <translation>Masukkan label untuk alamat ini untuk dimasukan dalam daftar alamat yang pernah digunakan</translation>
+ </message>
+ <message>
+ <source>Pay To:</source>
+ <translation>Kirim Ke:</translation>
+ </message>
+ <message>
+ <source>Memo:</source>
+ <translation>Catatan Peringatan:</translation>
+ </message>
+</context>
+<context>
+ <name>ShutdownWindow</name>
+ <message>
+ <source>Bitcoin Core is shutting down...</source>
+ <translation>Bitcoin Core sementara dimatikan...</translation>
+ </message>
+ <message>
+ <source>Do not shut down the computer until this window disappears.</source>
+ <translation>Kamu tidak dapat mematikan komputer sebelum jendela ini tertutup sendiri.</translation>
+ </message>
+</context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Signatures - Sign / Verify a Message</source>
+ <translation>Tanda Tangan / Verifikasi sebuah Pesan</translation>
+ </message>
+ <message>
+ <source>&amp;Sign Message</source>
+ <translation>&amp;Tandakan Pesan</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Pilih alamat yang telah digunakan sebelumnya</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Tempel alamat dari salinan</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+B</translation>
+ </message>
+ <message>
+ <source>Enter the message you want to sign here</source>
+ <translation>Masukan pesan yang ingin ditandai disini</translation>
+ </message>
+ <message>
+ <source>Signature</source>
+ <translation>Tanda Tangan</translation>
+ </message>
+ <message>
+ <source>Copy the current signature to the system clipboard</source>
+ <translation>Salin tanda tangan terpilih ke sistem klipboard</translation>
+ </message>
+ <message>
+ <source>Sign the message to prove you own this Bitcoin address</source>
+ <translation>Tandai pesan untuk menyetujui kamu pemiliki alamat Bitcoin ini</translation>
+ </message>
+ <message>
+ <source>Sign &amp;Message</source>
+ <translation>Tandakan &amp;Pesan</translation>
+ </message>
+ <message>
+ <source>Reset all sign message fields</source>
+ <translation>Hapus semua bidang penanda pesan</translation>
+ </message>
+ <message>
+ <source>&amp;Verify Message</source>
+ <translation>&amp;Verifikasi Pesan</translation>
+ </message>
+ <message>
+ <source>Verify &amp;Message</source>
+ <translation>Verifikasi &amp;Pesan</translation>
+ </message>
+ <message>
+ <source>Reset all verify message fields</source>
+ <translation>Hapus semua bidang verifikasi pesan</translation>
+ </message>
+ <message>
+ <source>Click "Sign Message" to generate signature</source>
+ <translation>Tekan "Tandatangan Pesan" untuk menghasilan tanda tangan</translation>
+ </message>
+ <message>
+ <source>The entered address is invalid.</source>
+ <translation>Alamat yang dimasukkan tidak sesuai.</translation>
+ </message>
+ <message>
+ <source>Please check the address and try again.</source>
+ <translation>Silahkan periksa alamat dan coba lagi.</translation>
+ </message>
+ <message>
+ <source>The entered address does not refer to a key.</source>
+ <translation>Alamat itu tidak menghubungkan kunci.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock was cancelled.</source>
+ <translation>Membuka kunci dompet dibatalkan.</translation>
+ </message>
+ <message>
+ <source>Private key for the entered address is not available.</source>
+ <translation>Kunci pribadi untuk alamat itu tidak tersedia.</translation>
+ </message>
+ <message>
+ <source>Message signing failed.</source>
+ <translation>Menandai pesan gagal.</translation>
+ </message>
+ <message>
+ <source>Message signed.</source>
+ <translation>Pesan ditandai.</translation>
+ </message>
+ <message>
+ <source>The signature could not be decoded.</source>
+ <translation>Tanda tangan tidak bisa diterjemahkan.</translation>
+ </message>
+ <message>
+ <source>Please check the signature and try again.</source>
+ <translation>Mohon periksa tanda tangan dan coba kembali</translation>
+ </message>
+ <message>
+ <source>The signature did not match the message digest.</source>
+ <translation>Tanda tangan tidak cocok dengan intisari pesan.</translation>
+ </message>
+ <message>
+ <source>Message verification failed.</source>
+ <translation>Verifikasi pesan gagal.</translation>
+ </message>
+ <message>
+ <source>Message verified.</source>
+ <translation>Pesan terverifikasi.</translation>
+ </message>
+</context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>The Bitcoin Core developers</source>
+ <translation>Pembangun Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>[testnet]</source>
+ <translation>[testnet]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ <message>
+ <source>KB/s</source>
+ <translation>KB/s</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>Buka hingga %1</translation>
+ </message>
+ <message>
+ <source>conflicted</source>
+ <translation>Terkonflik</translation>
+ </message>
+ <message>
+ <source>%1/offline</source>
+ <translation>%1/tidak terhubung</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/belum dikonfirmasi</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 konfirmasi</translation>
+ </message>
+ <message>
+ <source>Status</source>
+ <translation>Status</translation>
+ </message>
+ <message numerus="yes">
+ <source>, broadcast through %n node(s)</source>
+ <translation><numerusform>kirim lewat %n node</numerusform></translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Tanggal</translation>
+ </message>
+ <message>
+ <source>Source</source>
+ <translation>Sumber</translation>
+ </message>
+ <message>
+ <source>Generated</source>
+ <translation>Dibuat</translation>
+ </message>
+ <message>
+ <source>From</source>
+ <translation>Dari</translation>
+ </message>
+ <message>
+ <source>To</source>
+ <translation>Untuk</translation>
+ </message>
+ <message>
+ <source>own address</source>
+ <translation>Alamat saya sendiri</translation>
+ </message>
+ <message>
+ <source>label</source>
+ <translation>label</translation>
+ </message>
+ <message>
+ <source>Credit</source>
+ <translation>Kredit</translation>
+ </message>
+ <message numerus="yes">
+ <source>matures in %n more block(s)</source>
+ <translation><numerusform>cukup tua sesudah %n blok lagi</numerusform></translation>
+ </message>
+ <message>
+ <source>not accepted</source>
+ <translation>tidak diterima</translation>
+ </message>
+ <message>
+ <source>Debit</source>
+ <translation>Debet</translation>
+ </message>
+ <message>
+ <source>Transaction fee</source>
+ <translation>Biaya Transaksi</translation>
+ </message>
+ <message>
+ <source>Net amount</source>
+ <translation>Nilai bersih</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Pesan:</translation>
+ </message>
+ <message>
+ <source>Comment</source>
+ <translation>Komentar</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>ID Transaksi</translation>
+ </message>
+ <message>
+ <source>Merchant</source>
+ <translation>Pedagang</translation>
+ </message>
+ <message>
+ <source>Debug information</source>
+ <translation>Informasi debug</translation>
+ </message>
+ <message>
+ <source>Transaction</source>
+ <translation>Transaksi</translation>
+ </message>
+ <message>
+ <source>Inputs</source>
+ <translation>Masukan</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Nilai</translation>
+ </message>
+ <message>
+ <source>true</source>
+ <translation>benar</translation>
+ </message>
+ <message>
+ <source>false</source>
+ <translation>salah</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, belum berhasil disiarkan</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Buka untuk %n blok lagi</numerusform></translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>tidak diketahui</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>Rincian transaksi</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>Jendela ini menampilkan deskripsi rinci dari transaksi tersebut</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Tanggal</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Jenis</translation>
+ </message>
+ <message>
+ <source>Immature (%1 confirmations, will be available after %2)</source>
+ <translation>Terlalu muda (cuma %1 konfirmasi, akan siap sesudah %2) </translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Buka untuk %n blok lagi</numerusform></translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>Buka hingga %1</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>Terkonfirmasi (%1 konfirmasi)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>Blok ini tidak diterima oleh node lainnya dan kemungkinan tidak akan diterima!</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>Terbuat tetapi tidak diterima</translation>
+ </message>
+ <message>
+ <source>Offline</source>
+ <translation>Tidak terhubung</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Label</translation>
+ </message>
+ <message>
+ <source>Unconfirmed</source>
+ <translation>Belum dikonfirmasi</translation>
+ </message>
+ <message>
+ <source>Confirming (%1 of %2 recommended confirmations)</source>
+ <translation>Sedang dikonfirmasi (%1 dari %2 konfirmasi disarankan)</translation>
+ </message>
+ <message>
+ <source>Conflicted</source>
+ <translation>Terkonflik</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Diterima dengan</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>Diterima dari</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Terkirim ke</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>Pembayaran ke Anda sendiri</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Tertambang</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(t/s)</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>Status transaksi. Arahkan ke bagian ini untuk menampilkan jumlah konfrimasi.</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Tanggal dan waktu transaksi tersebut diterima.</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>Jenis transaksi.</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>Nilai dihapus dari atau ditambahkan ke saldo.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>Semua</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>Hari ini</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>Minggu ini</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>Bulan ini</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>Bulan kemarin</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>Tahun ini</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>Jarak...</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>DIterima dengan</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Terkirim ke</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>Ke Anda sendiri</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Ditambang</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>Lainnya</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>Masukkan alamat atau label untuk mencari</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>Nilai min</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Salin alamat</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Salin label</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Salin Nilai</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Menyalinkan ID transaksi</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>Ubah label</translation>
+ </message>
+ <message>
+ <source>Show transaction details</source>
+ <translation>Tampilkan rincian transaksi</translation>
+ </message>
+ <message>
+ <source>Export Transaction History</source>
+ <translation>Expor Histori Transaksi</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Proses Ekspor Gagal</translation>
+ </message>
+ <message>
+ <source>Exporting Successful</source>
+ <translation>Proses Ekspor Berhasil</translation>
+ </message>
+ <message>
+ <source>The transaction history was successfully saved to %1.</source>
+ <translation>Riwayat transaksi berhasil disimpan di %1.</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Berkas CSV (*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Terkonfirmasi</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Tanggal</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Jenis</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Label</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Alamat</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>Jarak:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>ke</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ </context>
+<context>
+ <name>WalletFrame</name>
+ <message>
+ <source>No wallet has been loaded.</source>
+ <translation>Tidak ada dompet yang dibuka</translation>
+ </message>
+</context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Kirim Koin</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Ekspor</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Ekspor data dalam tab sekarang ke sebuah berkas</translation>
+ </message>
+ <message>
+ <source>Backup Wallet</source>
+ <translation>Cadangkan Dompet</translation>
+ </message>
+ <message>
+ <source>Wallet Data (*.dat)</source>
+ <translation>Data Dompet (*.dat)</translation>
+ </message>
+ <message>
+ <source>Backup Failed</source>
+ <translation>Cadangkgan Gagal</translation>
+ </message>
+ <message>
+ <source>The wallet data was successfully saved to %1.</source>
+ <translation>Informasi dalam dompet berhasil disimpan di %1.</translation>
+ </message>
+ <message>
+ <source>Backup Successful</source>
+ <translation>Cadangkan Berhasil </translation>
+ </message>
+</context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>Pilihan:</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>Tentukan direktori data</translation>
+ </message>
+ <message>
+ <source>Connect to a node to retrieve peer addresses, and disconnect</source>
+ <translation>Hubungkan ke node untuk menerima alamat peer, dan putuskan</translation>
+ </message>
+ <message>
+ <source>Specify your own public address</source>
+ <translation>Tentukan alamat publik Anda sendiri</translation>
+ </message>
+ <message>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>Menerima perintah baris perintah dan JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>Berjalan dibelakang sebagai daemin dan menerima perintah</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>Gunakan jaringan uji</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
+ <translation>Terima hubungan dari luar (standar: 1 kalau -proxy atau -connect tidak dipilih)</translation>
+ </message>
+ <message>
+ <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
+ <translation>Jalankan perintah ketika perubahan transaksi dompet (%s di cmd digantikan oleh TxID)</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer. Bitcoin Core is probably already running.</source>
+ <translation>Tidak bisa mengikat dengan %s di computer ini. Kemungkinan Bitcoin Core sudah mulai.</translation>
+ </message>
+ <message>
+ <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>Peringatan: -paytxfee sangat besar! Ini adalah biaya pengiriman yang akan dibayar oleh Anda jika transaksi terkirim.</translation>
+ </message>
+ <message>
+ <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source>
+ <translation>Peringatan: Jaringan tidak semua bersetuju! Beberapa penambang dapat persoalan.</translation>
+ </message>
+ <message>
+ <source>Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.</source>
+ <translation>Peringatan: Kami tidak bersetujuh dengan peer-peer kami! Kemungkinan Anda harus upgrade, atau node-node lain yang harus diupgrade.</translation>
+ </message>
+ <message>
+ <source>Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
+ <translation>Awas: wallet.dat tidak bisa dibaca! Berhasil periksakan kunci-kunci dalam arsipnya, tetapi ada kemungkinan informasi tentang transaksi atau isi-isi buku alamat salah atau terhilang.</translation>
+ </message>
+ <message>
+ <source>(default: 1)</source>
+ <translation>(pengaturan awal: 1)</translation>
+ </message>
+ <message>
+ <source>Attempt to recover private keys from a corrupt wallet.dat</source>
+ <translation>Coba memulihkan kunci-kunci pribadi dari wallet.dat yang rusak</translation>
+ </message>
+ <message>
+ <source>Block creation options:</source>
+ <translation>Pilihan pembuatan blok:</translation>
+ </message>
+ <message>
+ <source>Connect only to the specified node(s)</source>
+ <translation>Jangan menghubungkan node(-node) selain yang di daftar</translation>
+ </message>
+ <message>
+ <source>Connection options:</source>
+ <translation>Pilih koneksi:</translation>
+ </message>
+ <message>
+ <source>Corrupted block database detected</source>
+ <translation>Menemukan database blok yang rusak </translation>
+ </message>
+ <message>
+ <source>Do not load the wallet and disable wallet RPC calls</source>
+ <translation>Jangan memuat dompet dan menonaktifkan panggilan dompet RPC</translation>
+ </message>
+ <message>
+ <source>Do you want to rebuild the block database now?</source>
+ <translation>Apakah Anda ingin coba membangun kembali database blok sekarang?</translation>
+ </message>
+ <message>
+ <source>Error initializing block database</source>
+ <translation>Kesalahan menginisialisasi database blok</translation>
+ </message>
+ <message>
+ <source>Error initializing wallet database environment %s!</source>
+ <translation>Kesalahan menginisialisasi dompet pada database%s!</translation>
+ </message>
+ <message>
+ <source>Error loading block database</source>
+ <translation>Gagal memuat database blok</translation>
+ </message>
+ <message>
+ <source>Error opening block database</source>
+ <translation>Menemukan masalah membukakan database blok</translation>
+ </message>
+ <message>
+ <source>Error: Disk space is low!</source>
+ <translation>Gagal: Hard disk hampir terisi!</translation>
+ </message>
+ <message>
+ <source>Importing...</source>
+ <translation>mengimpor...</translation>
+ </message>
+ <message>
+ <source>Incorrect or no genesis block found. Wrong datadir for network?</source>
+ <translation>Tidak bisa cari blok pertama, atau blok pertama salah. Salah direktori untuk jaringan?</translation>
+ </message>
+ <message>
+ <source>Invalid -onion address: '%s'</source>
+ <translation>Alamat -onion salah: '%s'</translation>
+ </message>
+ <message>
+ <source>Not enough file descriptors available.</source>
+ <translation>Deskripsi berkas tidak tersedia dengan cukup.</translation>
+ </message>
+ <message>
+ <source>Set maximum block size in bytes (default: %d)</source>
+ <translation>Atur ukuran maksimal untuk blok dalam byte (biasanya: %d)</translation>
+ </message>
+ <message>
+ <source>Specify wallet file (within data directory)</source>
+ <translation>Tentukan arsip dompet (dalam direktori data)</translation>
+ </message>
+ <message>
+ <source>Verifying blocks...</source>
+ <translation>Blok-blok sedang diverifikasi...</translation>
+ </message>
+ <message>
+ <source>Verifying wallet...</source>
+ <translation>Dompet sedang diverifikasi...</translation>
+ </message>
+ <message>
+ <source>Wallet %s resides outside data directory %s</source>
+ <translation>Dompet %s ada diluar direktori data %s</translation>
+ </message>
+ <message>
+ <source>Wallet options:</source>
+ <translation>Opsi dompet:</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to change -txindex</source>
+ <translation>Harus membangun ulang database menggunakan -reindex supaya mengubah -txindex</translation>
+ </message>
+ <message>
+ <source>Imports blocks from external blk000??.dat file</source>
+ <translation>Impor blok dari eksternal berkas blk000???.dat</translation>
+ </message>
+ <message>
+ <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source>
+ <translation>Tidak bisa mengunci data directory %s. Kemungkinan Bitcoin Core sudah mulai.</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Informasi</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -minrelaytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Nilai yang salah untuk -minrelaytxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -mintxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Nilai yang salah untuk -mintxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>RPC server options:</source>
+ <translation>Opsi server RPC:</translation>
+ </message>
+ <message>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>Kirim info jejak/debug ke konsol bukan berkas debug.log</translation>
+ </message>
+ <message>
+ <source>Set language, for example "de_DE" (default: system locale)</source>
+ <translation>Atur bahasa, sebagai contoh "id_ID" (standar: system locale)</translation>
+ </message>
+ <message>
+ <source>Show splash screen on startup (default: 1)</source>
+ <translation>Tampilkan layar pembuka saat nyala (standar: 1)</translation>
+ </message>
+ <message>
+ <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source>
+ <translation>Mengecilkan berkas debug.log saat klien berjalan (Standar: 1 jika tidak -debug)</translation>
+ </message>
+ <message>
+ <source>Signing transaction failed</source>
+ <translation>Tandatangani transaksi tergagal</translation>
+ </message>
+ <message>
+ <source>Start minimized</source>
+ <translation>Memulai terminimalisi</translation>
+ </message>
+ <message>
+ <source>Transaction amount too small</source>
+ <translation>Nilai transaksi terlalu kecil</translation>
+ </message>
+ <message>
+ <source>Transaction amounts must be positive</source>
+ <translation>Nilai transaksi harus positif</translation>
+ </message>
+ <message>
+ <source>Transaction too large</source>
+ <translation>Transaksi terlalu besar</translation>
+ </message>
+ <message>
+ <source>Username for JSON-RPC connections</source>
+ <translation>Nama pengguna untuk hubungan JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Peringatan</translation>
+ </message>
+ <message>
+ <source>Zapping all transactions from wallet...</source>
+ <translation>Setiap transaksi dalam dompet sedang di-'Zap'...</translation>
+ </message>
+ <message>
+ <source>wallet.dat corrupt, salvage failed</source>
+ <translation>wallet.dat rusak, tidak bisa diperbaiki</translation>
+ </message>
+ <message>
+ <source>Password for JSON-RPC connections</source>
+ <translation>Kata sandi untuk hubungan JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
+ <translation>Menjalankan perintah ketika perubahan blok terbaik (%s dalam cmd digantikan oleh hash blok)</translation>
+ </message>
+ <message>
+ <source>Upgrade wallet to latest format</source>
+ <translation>Perbarui dompet ke format terbaru</translation>
+ </message>
+ <message>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>Pindai ulang rantai-blok untuk transaksi dompet yang hilang</translation>
+ </message>
+ <message>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>Gunakan OpenSSL (https) untuk hubungan JSON-RPC</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>Pesan bantuan ini</translation>
+ </message>
+ <message>
+ <source>Allow DNS lookups for -addnode, -seednode and -connect</source>
+ <translation>Izinkan peninjauan DNS untuk -addnote, -seednode dan -connect</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>Memuat alamat...</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>Gagal memuat wallet.dat: Dompet rusak</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>Gagal memuat wallet.dat</translation>
+ </message>
+ <message>
+ <source>Invalid -proxy address: '%s'</source>
+ <translation>Alamat -proxy salah: '%s'</translation>
+ </message>
+ <message>
+ <source>Unknown network specified in -onlynet: '%s'</source>
+ <translation>Jaringan tidak diketahui yang ditentukan dalam -onlynet: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -bind address: '%s'</source>
+ <translation>Tidak dapat menyelesaikan alamat -bind: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -externalip address: '%s'</source>
+ <translation>Tidak dapat menyelesaikan alamat -externalip: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Nilai salah untuk -paytxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>Saldo tidak mencukupi</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>Memuat indeks blok...</translation>
+ </message>
+ <message>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>Tambahkan node untuk dihubungkan dan upaya untuk menjaga hubungan tetap terbuka</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>Memuat dompet...</translation>
+ </message>
+ <message>
+ <source>Cannot downgrade wallet</source>
+ <translation>Tidak dapat menurunkan versi dompet</translation>
+ </message>
+ <message>
+ <source>Cannot write default address</source>
+ <translation>Tidak dapat menyimpan alamat standar</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>Memindai ulang...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>Memuat selesai</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Gagal</translation>
+ </message>
+</context>
+</TS> \ 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 0000000000..0aa4ac8f8f
--- /dev/null
+++ b/src/qt/locale/bitcoin_it.ts
@@ -0,0 +1,3568 @@
+<TS language="it" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Right-click to edit address or label</source>
+ <translation>Fare clic con il tasto destro del mouse per modificare l'indirizzo o l'etichetta</translation>
+ </message>
+ <message>
+ <source>Create a new address</source>
+ <translation>Crea un nuovo indirizzo</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>&amp;Nuovo</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Copia negli appunti l'indirizzo attualmente selezionato</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>&amp;Copia</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>C&amp;hiudi</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>&amp;Copia l'indirizzo</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>Rimuove dalla lista l'indirizzo attualmente selezionato</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Esporta su file i dati contenuti nella tabella corrente</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Esporta</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;Elimina</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>Scegli l'indirizzo a cui inviare bitcoin</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>Scegli l'indirizzo con cui ricevere bitcoin</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>Sc&amp;egli</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>Indirizzi d'invio</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>Indirizzi di ricezione</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>Questo è un elenco di indirizzi Bitcoin a cui puoi inviare pagamenti. Controlla sempre l'importo e l'indirizzo del beneficiario prima di inviare bitcoin.</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>Questi sono i tuoi indirizzi Bitcoin che puoi usare per ricevere pagamenti. Si raccomanda di generare un nuovo indirizzo per ogni transazione.</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>Copia &amp;l'etichetta</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>&amp;Modifica</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>Esporta Lista Indirizzi</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Testo CSV (*.csv)</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Esportazione Fallita.</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the address list to %1. Please try again.</source>
+ <translation>Si è verificato un errore tentando di salvare la lista degli indirizzi su %1. Si prega di riprovare.</translation>
+ </message>
+</context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Etichetta</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Indirizzo</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(nessuna etichetta)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Passphrase Dialog</source>
+ <translation>Finestra passphrase</translation>
+ </message>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Inserisci la passphrase</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Nuova passphrase</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Ripeti la nuova passphrase</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>Cifra il portamonete</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>Questa operazione necessita della passphrase per sbloccare il portamonete.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Sblocca il portamonete</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>Quest'operazione necessita della passphrase per decifrare il portamonete,</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>Decifra il portamonete</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>Cambia la passphrase</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>Conferma la cifratura del portamonete</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>Attenzione: perdendo la passphrase di un portamonete cifrato &lt;b&gt;TUTTI I PROPRI BITCOIN ANDRANNO PERSI&lt;/b&gt;!</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>Si è sicuri di voler cifrare il portamonete?</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core 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.</source>
+ <translation>Bitcoin Core si chiuderà per portare a termine il processo di cifratura. Si ricorda che la cifratura del portamonete non garantisce protezione totale contro i furti causati da infezioni malware.</translation>
+ </message>
+ <message>
+ <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
+ <translation>IMPORTANTE: qualsiasi backup del file portamonete effettuato in precedenza dovrà essere sostituito con il file del portamonete cifrato appena generato. Per ragioni di sicurezza, i precedenti backup del file del portamonete non cifrato diventeranno inservibili non appena si inizierà ad utilizzare il nuovo portamonete cifrato.</translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>Attenzione: il tasto Blocco maiuscole è attivo!</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>Portamonete cifrato</translation>
+ </message>
+ <message>
+ <source>Enter the new passphrase to the wallet.&lt;br/&gt;Please use a passphrase of &lt;b&gt;ten or more random characters&lt;/b&gt;, or &lt;b&gt;eight or more words&lt;/b&gt;.</source>
+ <translation>Inserisci la nuova passphrase per il portamonete.&lt;br/&gt;Si consiglia di utilizzare &lt;b&gt;almeno dieci caratteri casuali&lt;/b&gt; oppure &lt;b&gt;otto o più parole&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>Enter the old passphrase and new passphrase to the wallet.</source>
+ <translation>Inserisci la vecchia e la nuova passphrase per il portamonete.</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>Cifratura del portamonete fallita</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>Cifratura del portamonete fallita a causa di un errore interno. Il portamonete non è stato cifrato.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>Le passphrase inserite non corrispondono.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>Sblocco del portamonete fallito</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>La passphrase inserita per la decifrazione del portamonete è errata.</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>Decifrazione del portamonete fallita</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>Passphrase del portamonete modificata con successo.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>Firma &amp;messaggio...</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>Sincronizzazione con la rete in corso...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;Sintesi</translation>
+ </message>
+ <message>
+ <source>Node</source>
+ <translation>Nodo</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>Mostra lo stato generale del portamonete</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Transazioni</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>Mostra la cronologia delle transazioni</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>&amp;Esci</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>Chiudi applicazione</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>Informazioni su &amp;Qt</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>Mostra le informazioni su Qt</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;Opzioni...</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>&amp;Cifra il portamonete...</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>&amp;Backup portamonete...</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>&amp;Cambia passphrase...</translation>
+ </message>
+ <message>
+ <source>&amp;Sending addresses...</source>
+ <translation>&amp;Indirizzi d'invio...</translation>
+ </message>
+ <message>
+ <source>&amp;Receiving addresses...</source>
+ <translation>Indirizzi di &amp;ricezione...</translation>
+ </message>
+ <message>
+ <source>Open &amp;URI...</source>
+ <translation>Apri &amp;URI...</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core client</source>
+ <translation>Bitcoin Core client</translation>
+ </message>
+ <message>
+ <source>Importing blocks from disk...</source>
+ <translation>Importazione blocchi dal disco...</translation>
+ </message>
+ <message>
+ <source>Reindexing blocks on disk...</source>
+ <translation>Re-indicizzazione blocchi su disco...</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>Invia fondi ad un indirizzo Bitcoin</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>Effettua il backup del portamonete</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Cambia la passphrase utilizzata per la cifratura del portamonete</translation>
+ </message>
+ <message>
+ <source>&amp;Debug window</source>
+ <translation>Finestra di &amp;debug</translation>
+ </message>
+ <message>
+ <source>Open debugging and diagnostic console</source>
+ <translation>Apri la console di debugging e diagnostica</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>&amp;Verifica messaggio...</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>Portamonete</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>&amp;Invia</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>&amp;Ricevi</translation>
+ </message>
+ <message>
+ <source>Show information about Bitcoin Core</source>
+ <translation>Mostra le informazioni su Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>&amp;Mostra / Nascondi</translation>
+ </message>
+ <message>
+ <source>Show or hide the main Window</source>
+ <translation>Mostra o nascondi la Finestra principale</translation>
+ </message>
+ <message>
+ <source>Encrypt the private keys that belong to your wallet</source>
+ <translation>Cifra le chiavi private che appartengono al tuo portamonete</translation>
+ </message>
+ <message>
+ <source>Sign messages with your Bitcoin addresses to prove you own them</source>
+ <translation>Firma messaggi con i tuoi indirizzi Bitcoin per dimostrarne il possesso</translation>
+ </message>
+ <message>
+ <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source>
+ <translation>Verifica che i messaggi siano stati firmati con gli indirizzi Bitcoin specificati</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;File</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;Impostazioni</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>&amp;Aiuto</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>Barra degli strumenti</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Request payments (generates QR codes and bitcoin: URIs)</source>
+ <translation>Richiedi pagamenti (genera codici QR e bitcoin: URI)</translation>
+ </message>
+ <message>
+ <source>&amp;About Bitcoin Core</source>
+ <translation>&amp;Informazioni su Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Modify configuration options for Bitcoin Core</source>
+ <translation>Modifica opzioni di configurazione per Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Show the list of used sending addresses and labels</source>
+ <translation>Mostra la lista degli indirizzi di invio utilizzati</translation>
+ </message>
+ <message>
+ <source>Show the list of used receiving addresses and labels</source>
+ <translation>Mostra la lista degli indirizzi di ricezione utilizzati</translation>
+ </message>
+ <message>
+ <source>Open a bitcoin: URI or payment request</source>
+ <translation>Apri un bitcoin: URI o una richiesta di pagamento</translation>
+ </message>
+ <message>
+ <source>&amp;Command-line options</source>
+ <translation>Opzioni della riga di &amp;comando</translation>
+ </message>
+ <message>
+ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
+ <translation>Mostra il messaggio di aiuto di Bitcoin Core per ottenere la lista delle opzioni della riga di comando valide.</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n active connection(s) to Bitcoin network</source>
+ <translation><numerusform>%n connessione attiva alla rete Bitcoin</numerusform><numerusform>%n connessioni alla rete Bitcoin attive</numerusform></translation>
+ </message>
+ <message>
+ <source>No block source available...</source>
+ <translation>Nessuna fonte di blocchi disponibile...</translation>
+ </message>
+ <message numerus="yes">
+ <source>Processed %n block(s) of transaction history.</source>
+ <translation><numerusform>Elaborato %n blocco dello storico transazioni.</numerusform><numerusform>Elaborati %n blocchi dello storico transazioni.</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n hour(s)</source>
+ <translation><numerusform>%n ora</numerusform><numerusform>%n ore</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n day(s)</source>
+ <translation><numerusform>%n giorno</numerusform><numerusform>%n giorni</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n week(s)</source>
+ <translation><numerusform>%n settimana</numerusform><numerusform>%n settimane</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 and %2</source>
+ <translation>%1 e %2</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n year(s)</source>
+ <translation><numerusform>%n anno</numerusform><numerusform>%n anni</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 behind</source>
+ <translation>Indietro di %1</translation>
+ </message>
+ <message>
+ <source>Last received block was generated %1 ago.</source>
+ <translation>L'ultimo blocco ricevuto è stato generato %1 fa.</translation>
+ </message>
+ <message>
+ <source>Transactions after this will not yet be visible.</source>
+ <translation>Le transazioni effettuate successivamente non sono ancora visibili.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Errore</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Attenzione</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Informazioni</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>Aggiornato</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>In aggiornamento...</translation>
+ </message>
+ <message>
+ <source>Date: %1
+</source>
+ <translation>Data: %1
+</translation>
+ </message>
+ <message>
+ <source>Amount: %1
+</source>
+ <translation>Quantità: %1
+</translation>
+ </message>
+ <message>
+ <source>Type: %1
+</source>
+ <translation>Tipo: %1
+</translation>
+ </message>
+ <message>
+ <source>Label: %1
+</source>
+ <translation>Etichetta: %1
+</translation>
+ </message>
+ <message>
+ <source>Address: %1
+</source>
+ <translation>Indirizzo: %1
+</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>Transazione inviata</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>Transazione ricevuta</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>Il portamonete è &lt;b&gt;cifrato&lt;/b&gt; ed attualmente &lt;b&gt;sbloccato&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>Il portamonete è &lt;b&gt;cifrato&lt;/b&gt; ed attualmente &lt;b&gt;bloccato&lt;/b&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <source>Network Alert</source>
+ <translation>Avviso di rete</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Coin Selection</source>
+ <translation>Selezione Input</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Quantità:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Byte:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Importo:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Priorità:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Commissione:</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Trascurabile:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Dopo Commissione:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Resto:</translation>
+ </message>
+ <message>
+ <source>(un)select all</source>
+ <translation>(de)seleziona tutto</translation>
+ </message>
+ <message>
+ <source>Tree mode</source>
+ <translation>Modalità Albero</translation>
+ </message>
+ <message>
+ <source>List mode</source>
+ <translation>Modalità Lista</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Importo</translation>
+ </message>
+ <message>
+ <source>Received with label</source>
+ <translation>Ricevuto con l'etichetta</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>Ricevuto con l'indirizzo</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Confirmations</source>
+ <translation>Conferme</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Confermato</translation>
+ </message>
+ <message>
+ <source>Priority</source>
+ <translation>Priorità</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Copia l'indirizzo</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Copia l'etichetta</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copia importo</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Copia l'ID transazione</translation>
+ </message>
+ <message>
+ <source>Lock unspent</source>
+ <translation>Bloccare non spesi</translation>
+ </message>
+ <message>
+ <source>Unlock unspent</source>
+ <translation>Sbloccare non spesi</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Copia quantità</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Copia commissione</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Copia dopo commissione</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Copia byte</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Copia priorità</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Copia trascurabile</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Copia resto</translation>
+ </message>
+ <message>
+ <source>highest</source>
+ <translation>massima</translation>
+ </message>
+ <message>
+ <source>higher</source>
+ <translation>molto alta</translation>
+ </message>
+ <message>
+ <source>high</source>
+ <translation>alta</translation>
+ </message>
+ <message>
+ <source>medium-high</source>
+ <translation>medio-alta</translation>
+ </message>
+ <message>
+ <source>medium</source>
+ <translation>media</translation>
+ </message>
+ <message>
+ <source>low-medium</source>
+ <translation>medio-bassa</translation>
+ </message>
+ <message>
+ <source>low</source>
+ <translation>bassa</translation>
+ </message>
+ <message>
+ <source>lower</source>
+ <translation>molto bassa</translation>
+ </message>
+ <message>
+ <source>lowest</source>
+ <translation>minima</translation>
+ </message>
+ <message>
+ <source>(%1 locked)</source>
+ <translation>(%1 bloccato)</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>nessuno</translation>
+ </message>
+ <message>
+ <source>This label turns red if the transaction size is greater than 1000 bytes.</source>
+ <translation>Questa etichetta diventerà rossa se la dimensione della transazione supererà i 1000 byte.</translation>
+ </message>
+ <message>
+ <source>This label turns red if the priority is smaller than "medium".</source>
+ <translation>Questa etichetta diventerà rossa se la priorità sarà inferiore a "media".</translation>
+ </message>
+ <message>
+ <source>This label turns red if any recipient receives an amount smaller than %1.</source>
+ <translation>Questa etichetta diventerà rossa se uno qualsiasi dei destinatari riceverà un importo inferiore a %1.</translation>
+ </message>
+ <message>
+ <source>Can vary +/- %1 satoshi(s) per input.</source>
+ <translation>Può variare di +/- %1 satoshi per input.</translation>
+ </message>
+ <message>
+ <source>yes</source>
+ <translation>sì</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>no</translation>
+ </message>
+ <message>
+ <source>This means a fee of at least %1 per kB is required.</source>
+ <translation>In tal caso sarà necessaria una commissione di almeno %1 per ogni kB.</translation>
+ </message>
+ <message>
+ <source>Can vary +/- 1 byte per input.</source>
+ <translation>Può variare di +/- 1 byte per input.</translation>
+ </message>
+ <message>
+ <source>Transactions with higher priority are more likely to get included into a block.</source>
+ <translation>Le transazioni con priorità più alta hanno più probabilità di essere incluse in un blocco.</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(nessuna etichetta)</translation>
+ </message>
+ <message>
+ <source>change from %1 (%2)</source>
+ <translation>resto da %1 (%2)</translation>
+ </message>
+ <message>
+ <source>(change)</source>
+ <translation>(resto)</translation>
+ </message>
+</context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>Modifica l'indirizzo</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>&amp;Etichetta</translation>
+ </message>
+ <message>
+ <source>The label associated with this address list entry</source>
+ <translation>L'etichetta associata con questa voce della lista degli indirizzi</translation>
+ </message>
+ <message>
+ <source>The address associated with this address list entry. This can only be modified for sending addresses.</source>
+ <translation>L'indirizzo associato con questa voce della lista degli indirizzi. Può essere modificato solo per gli indirizzi d'invio.</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;Indirizzo</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>Nuovo indirizzo di ricezione</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>Nuovo indirizzo d'invio</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>Modifica indirizzo di ricezione</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>Modifica indirizzo d'invio</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>L'indirizzo "%1" è già presente in rubrica.</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is not a valid Bitcoin address.</source>
+ <translation>L'indirizzo "%1" non è un indirizzo bitcoin valido.</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>Impossibile sbloccare il portamonete.</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>Generazione della nuova chiave non riuscita.</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ <message>
+ <source>A new data directory will be created.</source>
+ <translation>Sarà creata una nuova cartella dati.</translation>
+ </message>
+ <message>
+ <source>name</source>
+ <translation>nome</translation>
+ </message>
+ <message>
+ <source>Directory already exists. Add %1 if you intend to create a new directory here.</source>
+ <translation>Cartella già esistente. Aggiungi %1 se intendi creare qui una nuova cartella.</translation>
+ </message>
+ <message>
+ <source>Path already exists, and is not a directory.</source>
+ <translation>Il percorso è già esistente e non è una cartella.</translation>
+ </message>
+ <message>
+ <source>Cannot create data directory here.</source>
+ <translation>Impossibile creare una cartella dati qui.</translation>
+ </message>
+</context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>versione</translation>
+ </message>
+ <message>
+ <source>(%1-bit)</source>
+ <translation>(%1-bit)</translation>
+ </message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>Informazioni su Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Command-line options</source>
+ <translation>Opzioni della riga di comando</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>Utilizzo:</translation>
+ </message>
+ <message>
+ <source>command-line options</source>
+ <translation>opzioni della riga di comando</translation>
+ </message>
+</context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Welcome</source>
+ <translation>Benvenuto</translation>
+ </message>
+ <message>
+ <source>Welcome to Bitcoin Core.</source>
+ <translation>Benvenuti su Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</source>
+ <translation>Visto che questa è la prima volta che il programma viene lanciato, puoi scegliere dove Bitcoin Core salverà i propri dati.</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory.</source>
+ <translation>Bitcoin Core scaricherà e salverà una copia della block chain di Bitcoin. Il portamonete ed almeno %1GB di dati saranno salvati in questa cartella. Si ricorda che lo spazio occupato andrà ad aumentare nel tempo.</translation>
+ </message>
+ <message>
+ <source>Use the default data directory</source>
+ <translation>Usa la cartella dati predefinita</translation>
+ </message>
+ <message>
+ <source>Use a custom data directory:</source>
+ <translation>Usa una cartella dati personalizzata:</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Error: Specified data directory "%1" cannot be created.</source>
+ <translation>Errore: La cartella dati "%1" specificata non può essere creata.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Errore</translation>
+ </message>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ <message>
+ <source>Open URI</source>
+ <translation>Apri URI</translation>
+ </message>
+ <message>
+ <source>Open payment request from URI or file</source>
+ <translation>Apri richiesta di pagamento da URI o file</translation>
+ </message>
+ <message>
+ <source>URI:</source>
+ <translation>URI:</translation>
+ </message>
+ <message>
+ <source>Select payment request file</source>
+ <translation>Seleziona il file di richiesta di pagamento</translation>
+ </message>
+ <message>
+ <source>Select payment request file to open</source>
+ <translation>Seleziona il file di richiesta di pagamento da aprire</translation>
+ </message>
+</context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>Opzioni</translation>
+ </message>
+ <message>
+ <source>&amp;Main</source>
+ <translation>&amp;Principale</translation>
+ </message>
+ <message>
+ <source>Size of &amp;database cache</source>
+ <translation>Dimensione della cache del &amp;database.</translation>
+ </message>
+ <message>
+ <source>MB</source>
+ <translation>MB</translation>
+ </message>
+ <message>
+ <source>Number of script &amp;verification threads</source>
+ <translation>Numero di thread di &amp;verifica degli script </translation>
+ </message>
+ <message>
+ <source>Accept connections from outside</source>
+ <translation>Accetta connessioni provenienti dall'esterno</translation>
+ </message>
+ <message>
+ <source>Allow incoming connections</source>
+ <translation>Permetti connessioni in ingresso</translation>
+ </message>
+ <message>
+ <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
+ <translation>Indirizzo IP del proxy (ad es. IPv4: 127.0.0.1 / IPv6: ::1)</translation>
+ </message>
+ <message>
+ <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source>
+ <translation>Riduci ad icona invece di uscire dall'applicazione quando la finestra viene chiusa. Attivando questa opzione l'applicazione terminerà solo dopo aver selezionato Esci dal menu File.</translation>
+ </message>
+ <message>
+ <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source>
+ <translation>La lingua dell'interfaccia utente può essere impostata qui. L'applicazione delle modifiche avrà effetto dopo il riavvio di Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source>
+ <translation>URL di terze parti (ad es. un block explorer) che appaiono nella tabella delle transazioni come voci nel menu contestuale. "%s" nell'URL è sostituito dall'hash della transazione.
+Per specificare più URL separarli con una barra verticale "|".</translation>
+ </message>
+ <message>
+ <source>Third party transaction URLs</source>
+ <translation>URL di transazione di terze parti</translation>
+ </message>
+ <message>
+ <source>Active command-line options that override above options:</source>
+ <translation>Opzioni della riga di comando attive che sostituiscono i settaggi sopra elencati:</translation>
+ </message>
+ <message>
+ <source>Reset all client options to default.</source>
+ <translation>Reimposta tutte le opzioni del client allo stato predefinito.</translation>
+ </message>
+ <message>
+ <source>&amp;Reset Options</source>
+ <translation>&amp;Ripristina Opzioni</translation>
+ </message>
+ <message>
+ <source>&amp;Network</source>
+ <translation>Rete</translation>
+ </message>
+ <message>
+ <source>Automatically start Bitcoin Core after logging in to the system.</source>
+ <translation>Avvia automaticamente Bitcoin Core una volta effettuato l'accesso al sistema.</translation>
+ </message>
+ <message>
+ <source>&amp;Start Bitcoin Core on system login</source>
+ <translation>&amp;Avvia Bitcoin Core all'accesso al sistema</translation>
+ </message>
+ <message>
+ <source>(0 = auto, &lt;0 = leave that many cores free)</source>
+ <translation>(0 = automatico, &lt;0 = lascia questo numero di core liberi)</translation>
+ </message>
+ <message>
+ <source>W&amp;allet</source>
+ <translation>Port&amp;amonete</translation>
+ </message>
+ <message>
+ <source>Expert</source>
+ <translation>Esperti</translation>
+ </message>
+ <message>
+ <source>Enable coin &amp;control features</source>
+ <translation>Abilita le funzionalità di coin &amp;control</translation>
+ </message>
+ <message>
+ <source>If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.</source>
+ <translation>Disabilitando l'uso di resti non confermati, il resto di una transazione non potrà essere speso fino a quando non avrà ottenuto almeno una conferma. Questa impostazione influisce inoltre sul calcolo del saldo.</translation>
+ </message>
+ <message>
+ <source>&amp;Spend unconfirmed change</source>
+ <translation>&amp;Spendi resti non confermati</translation>
+ </message>
+ <message>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>Apri automaticamente la porta del client Bitcoin sul router. Il protocollo UPnP deve essere supportato da parte del router ed attivo.</translation>
+ </message>
+ <message>
+ <source>Map port using &amp;UPnP</source>
+ <translation>Mappa le porte tramite &amp;UPnP</translation>
+ </message>
+ <message>
+ <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
+ <translation>Connessione alla rete Bitcoin attraverso un proxy SOCKS5.</translation>
+ </message>
+ <message>
+ <source>&amp;Connect through SOCKS5 proxy (default proxy):</source>
+ <translation>&amp;Connessione attraverso proxy SOCKS5 (proxy predefinito):</translation>
+ </message>
+ <message>
+ <source>Proxy &amp;IP:</source>
+ <translation>&amp;IP del proxy:</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>&amp;Porta:</translation>
+ </message>
+ <message>
+ <source>Port of the proxy (e.g. 9050)</source>
+ <translation>Porta del proxy (ad es. 9050)</translation>
+ </message>
+ <message>
+ <source>&amp;Window</source>
+ <translation>&amp;Finestra</translation>
+ </message>
+ <message>
+ <source>Show only a tray icon after minimizing the window.</source>
+ <translation>Mostra solo nella tray bar quando si riduce ad icona.</translation>
+ </message>
+ <message>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>&amp;Minimizza nella tray bar invece che sulla barra delle applicazioni</translation>
+ </message>
+ <message>
+ <source>M&amp;inimize on close</source>
+ <translation>M&amp;inimizza alla chiusura</translation>
+ </message>
+ <message>
+ <source>&amp;Display</source>
+ <translation>&amp;Mostra</translation>
+ </message>
+ <message>
+ <source>User Interface &amp;language:</source>
+ <translation>&amp;Lingua Interfaccia Utente:</translation>
+ </message>
+ <message>
+ <source>&amp;Unit to show amounts in:</source>
+ <translation>&amp;Unità di misura con cui visualizzare gli importi:</translation>
+ </message>
+ <message>
+ <source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
+ <translation>Scegli l'unità di suddivisione predefinita da utilizzare per l'interfaccia e per l'invio di bitcoin.</translation>
+ </message>
+ <message>
+ <source>Whether to show coin control features or not.</source>
+ <translation>Specifica se le funzionalita di coin control saranno visualizzate.</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>&amp;OK</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>&amp;Cancella</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>predefinito</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>nessuno</translation>
+ </message>
+ <message>
+ <source>Confirm options reset</source>
+ <translation>Conferma ripristino opzioni</translation>
+ </message>
+ <message>
+ <source>Client restart required to activate changes.</source>
+ <translation>È necessario un riavvio del client per applicare le modifiche.</translation>
+ </message>
+ <message>
+ <source>Client will be shut down. Do you want to proceed?</source>
+ <translation>Il client sarà arrestato. Si desidera procedere?</translation>
+ </message>
+ <message>
+ <source>This change would require a client restart.</source>
+ <translation>Questa modifica richiede un riavvio del client.</translation>
+ </message>
+ <message>
+ <source>The supplied proxy address is invalid.</source>
+ <translation>L'indirizzo proxy che hai fornito non è valido.</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>Modulo</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>Le informazioni visualizzate potrebbero non essere aggiornate. Il portamonete si sincronizza automaticamente con la rete Bitcoin una volta stabilita una connessione, ma questo processo non è ancora stato completato.</translation>
+ </message>
+ <message>
+ <source>Watch-only:</source>
+ <translation>Sola lettura:</translation>
+ </message>
+ <message>
+ <source>Available:</source>
+ <translation>Disponibile:</translation>
+ </message>
+ <message>
+ <source>Your current spendable balance</source>
+ <translation>Il tuo saldo spendibile attuale</translation>
+ </message>
+ <message>
+ <source>Pending:</source>
+ <translation>In attesa:</translation>
+ </message>
+ <message>
+ <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source>
+ <translation>Totale delle transazioni in corso di conferma e che non sono ancora conteggiate nel saldo spendibile</translation>
+ </message>
+ <message>
+ <source>Immature:</source>
+ <translation>Immaturo:</translation>
+ </message>
+ <message>
+ <source>Mined balance that has not yet matured</source>
+ <translation>Importo generato dal mining e non ancora maturato</translation>
+ </message>
+ <message>
+ <source>Balances</source>
+ <translation>Saldo</translation>
+ </message>
+ <message>
+ <source>Total:</source>
+ <translation>Totale:</translation>
+ </message>
+ <message>
+ <source>Your current total balance</source>
+ <translation>Il tuo saldo totale attuale</translation>
+ </message>
+ <message>
+ <source>Your current balance in watch-only addresses</source>
+ <translation>Il tuo saldo attuale negli indirizzi di sola lettura</translation>
+ </message>
+ <message>
+ <source>Spendable:</source>
+ <translation>Spendibile:</translation>
+ </message>
+ <message>
+ <source>Recent transactions</source>
+ <translation>Transazioni recenti</translation>
+ </message>
+ <message>
+ <source>Unconfirmed transactions to watch-only addresses</source>
+ <translation>Transazioni non confermate su indirizzi di sola lettura</translation>
+ </message>
+ <message>
+ <source>Mined balance in watch-only addresses that has not yet matured</source>
+ <translation>Importo generato dal mining su indirizzi di sola lettura e non ancora maturato</translation>
+ </message>
+ <message>
+ <source>Current total balance in watch-only addresses</source>
+ <translation>Saldo corrente totale negli indirizzi di sola lettura</translation>
+ </message>
+</context>
+<context>
+ <name>PaymentServer</name>
+ <message>
+ <source>URI handling</source>
+ <translation>Gestione URI</translation>
+ </message>
+ <message>
+ <source>Invalid payment address %1</source>
+ <translation>Indirizzo di pagamento non valido %1</translation>
+ </message>
+ <message>
+ <source>Payment request rejected</source>
+ <translation>Richiesta di pagamento respinta</translation>
+ </message>
+ <message>
+ <source>Payment request network doesn't match client network.</source>
+ <translation>La rete della richiesta di pagamento non corrisponde alla rete del client.</translation>
+ </message>
+ <message>
+ <source>Payment request is not initialized.</source>
+ <translation>La richiesta di pagamento non è stata inizializzata.</translation>
+ </message>
+ <message>
+ <source>Requested payment amount of %1 is too small (considered dust).</source>
+ <translation>L'importo di pagamento di %1 richiesto è troppo basso (considerato come trascurabile).</translation>
+ </message>
+ <message>
+ <source>Payment request error</source>
+ <translation>Errore di richiesta di pagamento</translation>
+ </message>
+ <message>
+ <source>Cannot start bitcoin: click-to-pay handler</source>
+ <translation>Impossibile avviare bitcoin: gestore click-to-pay</translation>
+ </message>
+ <message>
+ <source>Payment request fetch URL is invalid: %1</source>
+ <translation>URL di recupero della Richiesta di pagamento non valido: %1</translation>
+ </message>
+ <message>
+ <source>URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source>
+ <translation>Impossibile interpretare l'URI! I parametri URI o l'indirizzo Bitcoin potrebbero non essere corretti.</translation>
+ </message>
+ <message>
+ <source>Payment request file handling</source>
+ <translation>Gestione del file di richiesta del pagamento</translation>
+ </message>
+ <message>
+ <source>Payment request file cannot be read! This can be caused by an invalid payment request file.</source>
+ <translation>Impossibile leggere il file della richiesta di pagamento! Il file della richiesta di pagamento potrebbe non essere valido.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>Richiesta di pagamento scaduta.</translation>
+ </message>
+ <message>
+ <source>Unverified payment requests to custom payment scripts are unsupported.</source>
+ <translation>Le richieste di pagamento non verificate verso script di pagamento personalizzati non sono supportate.</translation>
+ </message>
+ <message>
+ <source>Invalid payment request.</source>
+ <translation>Richiesta di pagamento non valida.</translation>
+ </message>
+ <message>
+ <source>Refund from %1</source>
+ <translation>Rimborso da %1</translation>
+ </message>
+ <message>
+ <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source>
+ <translation>La richiesta di pagamento %1 (%2 byte) supera la dimensione massima di %3 byte.</translation>
+ </message>
+ <message>
+ <source>Payment request DoS protection</source>
+ <translation>Protezione DoS per la richiesta di pagamento</translation>
+ </message>
+ <message>
+ <source>Error communicating with %1: %2</source>
+ <translation>Errore di comunicazione con %1: %2</translation>
+ </message>
+ <message>
+ <source>Payment request cannot be parsed!</source>
+ <translation>La richiesta di pagamento non può essere analizzata!</translation>
+ </message>
+ <message>
+ <source>Bad response from server %1</source>
+ <translation>Risposta errata da parte del server %1</translation>
+ </message>
+ <message>
+ <source>Payment acknowledged</source>
+ <translation>Pagamento riconosciuto</translation>
+ </message>
+ <message>
+ <source>Network request error</source>
+ <translation>Errore di richiesta di rete</translation>
+ </message>
+</context>
+<context>
+ <name>PeerTableModel</name>
+ <message>
+ <source>User Agent</source>
+ <translation>User Agent</translation>
+ </message>
+ <message>
+ <source>Node/Service</source>
+ <translation>Nodo/Servizio</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Tempo di ping</translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>Importo</translation>
+ </message>
+ <message>
+ <source>Enter a Bitcoin address (e.g. %1)</source>
+ <translation>Inserisci un indirizzo Bitcoin (ad es. %1)</translation>
+ </message>
+ <message>
+ <source>%1 d</source>
+ <translation>%1 d</translation>
+ </message>
+ <message>
+ <source>%1 h</source>
+ <translation>%1 h</translation>
+ </message>
+ <message>
+ <source>%1 m</source>
+ <translation>%1 m</translation>
+ </message>
+ <message>
+ <source>%1 s</source>
+ <translation>%1 s</translation>
+ </message>
+ <message>
+ <source>None</source>
+ <translation>Nessuno</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>N/D</translation>
+ </message>
+ <message>
+ <source>%1 ms</source>
+ <translation>%1 ms</translation>
+ </message>
+</context>
+<context>
+ <name>QRImageWidget</name>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Salva Immagine...</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Image</source>
+ <translation>&amp;Copia Immagine</translation>
+ </message>
+ <message>
+ <source>Save QR Code</source>
+ <translation>Salva codice QR</translation>
+ </message>
+ <message>
+ <source>PNG Image (*.png)</source>
+ <translation>Immagine PNG (*.png)</translation>
+ </message>
+</context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>Client name</source>
+ <translation>Nome del client</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>N/D</translation>
+ </message>
+ <message>
+ <source>Client version</source>
+ <translation>Versione client</translation>
+ </message>
+ <message>
+ <source>&amp;Information</source>
+ <translation>&amp;Informazioni</translation>
+ </message>
+ <message>
+ <source>Debug window</source>
+ <translation>Finestra di debug</translation>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>Generale</translation>
+ </message>
+ <message>
+ <source>Using OpenSSL version</source>
+ <translation>Versione OpenSSL in uso</translation>
+ </message>
+ <message>
+ <source>Using BerkeleyDB version</source>
+ <translation>Versione BerkeleyDB in uso</translation>
+ </message>
+ <message>
+ <source>Startup time</source>
+ <translation>Ora di avvio</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Rete</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>Nome</translation>
+ </message>
+ <message>
+ <source>Number of connections</source>
+ <translation>Numero di connessioni</translation>
+ </message>
+ <message>
+ <source>Block chain</source>
+ <translation>Block chain</translation>
+ </message>
+ <message>
+ <source>Current number of blocks</source>
+ <translation>Numero attuale di blocchi</translation>
+ </message>
+ <message>
+ <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source>
+ <translation>Apre il file log di debug di Bitcoin Core dalla cartella dati attuale. Questa azione può richiedere alcuni secondi per file log di grandi dimensioni.</translation>
+ </message>
+ <message>
+ <source>Received</source>
+ <translation>Ricevuto</translation>
+ </message>
+ <message>
+ <source>Sent</source>
+ <translation>Inviato</translation>
+ </message>
+ <message>
+ <source>&amp;Peers</source>
+ <translation>&amp;Peer</translation>
+ </message>
+ <message>
+ <source>Select a peer to view detailed information.</source>
+ <translation>Seleziona un peer per visualizzare informazioni più dettagliate.</translation>
+ </message>
+ <message>
+ <source>Direction</source>
+ <translation>Direzione</translation>
+ </message>
+ <message>
+ <source>Version</source>
+ <translation>Versione</translation>
+ </message>
+ <message>
+ <source>User Agent</source>
+ <translation>User Agent</translation>
+ </message>
+ <message>
+ <source>Services</source>
+ <translation>Servizi</translation>
+ </message>
+ <message>
+ <source>Starting Height</source>
+ <translation>Nr. Blocco Iniziale</translation>
+ </message>
+ <message>
+ <source>Sync Height</source>
+ <translation>Nr. Blocco Sincronizzato</translation>
+ </message>
+ <message>
+ <source>Ban Score</source>
+ <translation>Punteggio di Ban</translation>
+ </message>
+ <message>
+ <source>Connection Time</source>
+ <translation>Tempo di Connessione</translation>
+ </message>
+ <message>
+ <source>Last Send</source>
+ <translation>Ultimo Invio</translation>
+ </message>
+ <message>
+ <source>Last Receive</source>
+ <translation>Ultima Ricezione</translation>
+ </message>
+ <message>
+ <source>Bytes Sent</source>
+ <translation>Byte Inviati</translation>
+ </message>
+ <message>
+ <source>Bytes Received</source>
+ <translation>Byte Ricevuti</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Tempo di Ping</translation>
+ </message>
+ <message>
+ <source>Time Offset</source>
+ <translation>Scarto Temporale</translation>
+ </message>
+ <message>
+ <source>Last block time</source>
+ <translation>Ora del blocco più recente</translation>
+ </message>
+ <message>
+ <source>&amp;Open</source>
+ <translation>&amp;Apri</translation>
+ </message>
+ <message>
+ <source>&amp;Console</source>
+ <translation>&amp;Console</translation>
+ </message>
+ <message>
+ <source>&amp;Network Traffic</source>
+ <translation>&amp;Traffico di Rete</translation>
+ </message>
+ <message>
+ <source>&amp;Clear</source>
+ <translation>&amp;Cancella</translation>
+ </message>
+ <message>
+ <source>Totals</source>
+ <translation>Totali</translation>
+ </message>
+ <message>
+ <source>In:</source>
+ <translation>Entrata:</translation>
+ </message>
+ <message>
+ <source>Out:</source>
+ <translation>Uscita:</translation>
+ </message>
+ <message>
+ <source>Build date</source>
+ <translation>Data di creazione</translation>
+ </message>
+ <message>
+ <source>Debug log file</source>
+ <translation>File log del Debug</translation>
+ </message>
+ <message>
+ <source>Clear console</source>
+ <translation>Cancella console</translation>
+ </message>
+ <message>
+ <source>Welcome to the Bitcoin Core RPC console.</source>
+ <translation>Benvenuto nella console RPC di Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
+ <translation>Usa le frecce direzionali per scorrere la cronologia, e &lt;b&gt;Ctrl-L&lt;/b&gt; per cancellarla.</translation>
+ </message>
+ <message>
+ <source>Type &lt;b&gt;help&lt;/b&gt; for an overview of available commands.</source>
+ <translation>Scrivi &lt;b&gt;help&lt;/b&gt; per un riassunto dei comandi disponibili.</translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation>%1 B</translation>
+ </message>
+ <message>
+ <source>%1 KB</source>
+ <translation>%1 KB</translation>
+ </message>
+ <message>
+ <source>%1 MB</source>
+ <translation>%1 MB</translation>
+ </message>
+ <message>
+ <source>%1 GB</source>
+ <translation>%1 GB</translation>
+ </message>
+ <message>
+ <source>via %1</source>
+ <translation>via %1</translation>
+ </message>
+ <message>
+ <source>never</source>
+ <translation>mai</translation>
+ </message>
+ <message>
+ <source>Inbound</source>
+ <translation>In entrata</translation>
+ </message>
+ <message>
+ <source>Outbound</source>
+ <translation>In uscita</translation>
+ </message>
+ <message>
+ <source>Unknown</source>
+ <translation>Sconosciuto</translation>
+ </message>
+ <message>
+ <source>Fetching...</source>
+ <translation>Recuperando...</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Amount:</source>
+ <translation>&amp;Importo:</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Etichetta:</translation>
+ </message>
+ <message>
+ <source>&amp;Message:</source>
+ <translation>&amp;Messaggio:</translation>
+ </message>
+ <message>
+ <source>Reuse one of the previously used receiving addresses. Reusing addresses has security and privacy issues. Do not use this unless re-generating a payment request made before.</source>
+ <translation>Riutilizza uno degli indirizzi di ricezione generati in precedenza. Riutilizzare un indirizzo comporta problemi di sicurezza e privacy. Non selezionare questa opzione a meno che non si stia rigenerando una richiesta di pagamento creata in precedenza.</translation>
+ </message>
+ <message>
+ <source>R&amp;euse an existing receiving address (not recommended)</source>
+ <translation>R&amp;iusa un indirizzo di ricezione (non raccomandato)</translation>
+ </message>
+ <message>
+ <source>An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network.</source>
+ <translation>Un messaggio opzionale da allegare e mostrare all'apertura della richiesta di pagamento. Nota: Il messaggio non sarà inviato con il pagamento sulla rete Bitcoin.</translation>
+ </message>
+ <message>
+ <source>An optional label to associate with the new receiving address.</source>
+ <translation>Un'etichetta opzionale da associare al nuovo indirizzo di ricezione.</translation>
+ </message>
+ <message>
+ <source>Use this form to request payments. All fields are &lt;b&gt;optional&lt;/b&gt;.</source>
+ <translation>Usa questo modulo per richiedere pagamenti. Tutti i campi sono &lt;b&gt;opzionali&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>An optional amount to request. Leave this empty or zero to not request a specific amount.</source>
+ <translation>Un importo opzionale da associare alla richiesta. Lasciare vuoto o a zero per non richiedere un importo specifico.</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Cancellare tutti i campi del modulo.</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation>Cancella</translation>
+ </message>
+ <message>
+ <source>Requested payments history</source>
+ <translation>Cronologia pagamenti richiesti</translation>
+ </message>
+ <message>
+ <source>&amp;Request payment</source>
+ <translation>&amp;Richiedi pagamento</translation>
+ </message>
+ <message>
+ <source>Show the selected request (does the same as double clicking an entry)</source>
+ <translation>Mostra la richiesta selezionata (produce lo stesso effetto di un doppio click su una voce)</translation>
+ </message>
+ <message>
+ <source>Show</source>
+ <translation>Mostra</translation>
+ </message>
+ <message>
+ <source>Remove the selected entries from the list</source>
+ <translation>Rimuovi le voci selezionate dalla lista</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>Rimuovi</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Copia l'etichetta</translation>
+ </message>
+ <message>
+ <source>Copy message</source>
+ <translation>Copia il messaggio</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copia l'importo</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>QR Code</source>
+ <translation>Codice QR</translation>
+ </message>
+ <message>
+ <source>Copy &amp;URI</source>
+ <translation>Copia &amp;URI</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Address</source>
+ <translation>Copia &amp;Indirizzo</translation>
+ </message>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Salva Immagine...</translation>
+ </message>
+ <message>
+ <source>Request payment to %1</source>
+ <translation>Richiesta di pagamento a %1</translation>
+ </message>
+ <message>
+ <source>Payment information</source>
+ <translation>Informazioni pagamento</translation>
+ </message>
+ <message>
+ <source>URI</source>
+ <translation>URI</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Indirizzo</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Importo</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etichetta</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Messaggio</translation>
+ </message>
+ <message>
+ <source>Resulting URI too long, try to reduce the text for label / message.</source>
+ <translation>L'URI risultante è troppo lungo, prova a ridurre il testo nell'etichetta / messaggio.</translation>
+ </message>
+ <message>
+ <source>Error encoding URI into QR Code.</source>
+ <translation>Errore nella codifica dell'URI nel codice QR.</translation>
+ </message>
+</context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etichetta</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Messaggio</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Importo</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(nessuna etichetta)</translation>
+ </message>
+ <message>
+ <source>(no message)</source>
+ <translation>(nessun messaggio)</translation>
+ </message>
+ <message>
+ <source>(no amount)</source>
+ <translation>(nessun importo)</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Invia Bitcoin</translation>
+ </message>
+ <message>
+ <source>Coin Control Features</source>
+ <translation>Funzionalità di Coin Control</translation>
+ </message>
+ <message>
+ <source>Inputs...</source>
+ <translation>Input...</translation>
+ </message>
+ <message>
+ <source>automatically selected</source>
+ <translation>selezionato automaticamente</translation>
+ </message>
+ <message>
+ <source>Insufficient funds!</source>
+ <translation>Fondi insufficienti!</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Quantità:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Byte:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Importo:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Priorità:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Commissione:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Dopo Commissione:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Resto:</translation>
+ </message>
+ <message>
+ <source>If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address.</source>
+ <translation>In caso di abilitazione con indirizzo vuoto o non valido, il resto sarà inviato ad un nuovo indirizzo generato appositamente.</translation>
+ </message>
+ <message>
+ <source>Custom change address</source>
+ <translation>Personalizza indirizzo di resto</translation>
+ </message>
+ <message>
+ <source>Transaction Fee:</source>
+ <translation>Commissione di Transazione:</translation>
+ </message>
+ <message>
+ <source>Choose...</source>
+ <translation>Scegli...</translation>
+ </message>
+ <message>
+ <source>collapse fee-settings</source>
+ <translation>minimizza le impostazioni di commissione</translation>
+ </message>
+ <message>
+ <source>per kilobyte</source>
+ <translation>per kilobyte</translation>
+ </message>
+ <message>
+ <source>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "total at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source>
+ <translation>Se la commissione personalizzata è impostata su 1000 satoshi e la transazione è di soli 250 byte, allora "per kilobyte" paga solo 250 satoshi di commissione, mentre "somma almeno" paga 1000 satoshi. Per transazioni più grandi di un kilobyte, entrambe le opzioni pagano al kilobyte.</translation>
+ </message>
+ <message>
+ <source>Hide</source>
+ <translation>Nascondi</translation>
+ </message>
+ <message>
+ <source>total at least</source>
+ <translation>somma almeno</translation>
+ </message>
+ <message>
+ <source>Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process.</source>
+ <translation>Non vi è alcuna controindicazione a pagare la commissione minima, a patto che il volume delle transazioni sia inferiore allo spazio disponibile nei blocchi. Occorre comunque essere consapevoli che ciò potrebbe impedire la conferma delle transazioni nel caso in cui la rete risultasse satura.</translation>
+ </message>
+ <message>
+ <source>(read the tooltip)</source>
+ <translation>(leggi il suggerimento)</translation>
+ </message>
+ <message>
+ <source>Recommended:</source>
+ <translation>Raccomandata:</translation>
+ </message>
+ <message>
+ <source>Custom:</source>
+ <translation>Personalizzata:</translation>
+ </message>
+ <message>
+ <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source>
+ <translation>(Commissione intelligente non ancora inizializzata. Normalmente richiede un'attesa di alcuni blocchi...)</translation>
+ </message>
+ <message>
+ <source>Confirmation time:</source>
+ <translation>Tempo di conferma:</translation>
+ </message>
+ <message>
+ <source>normal</source>
+ <translation>normale</translation>
+ </message>
+ <message>
+ <source>fast</source>
+ <translation>veloce</translation>
+ </message>
+ <message>
+ <source>Send as zero-fee transaction if possible</source>
+ <translation>Invia come transazione a zero commissioni se possibile</translation>
+ </message>
+ <message>
+ <source>(confirmation may take longer)</source>
+ <translation>(la conferma potrebbe richiedere più tempo)</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>Invia simultaneamente a più beneficiari</translation>
+ </message>
+ <message>
+ <source>Add &amp;Recipient</source>
+ <translation>&amp;Aggiungi beneficiario</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Cancellare tutti i campi del modulo.</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Trascurabile:</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Cancella &amp;tutto</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>Saldo:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>Conferma l'azione di invio</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>&amp;Invia</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>Conferma l'invio di bitcoin</translation>
+ </message>
+ <message>
+ <source>%1 to %2</source>
+ <translation>%1 a %2</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Copia quantità</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copia importo</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Copia commissione</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Copia dopo commissione</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Copia byte</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Copia priorità</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Copia resto</translation>
+ </message>
+ <message>
+ <source>or</source>
+ <translation>o</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>L'importo da pagare deve essere maggiore di 0.</translation>
+ </message>
+ <message>
+ <source>The amount exceeds your balance.</source>
+ <translation>L'importo è superiore al tuo saldo attuale.</translation>
+ </message>
+ <message>
+ <source>The total exceeds your balance when the %1 transaction fee is included.</source>
+ <translation>Il totale è superiore al tuo saldo attuale includendo la commissione di %1.</translation>
+ </message>
+ <message>
+ <source>Transaction creation failed!</source>
+ <translation>Creazione transazione fallita!</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>La transazione è stata respinta! Questo può accadere se alcuni bitcoin nel tuo portamonete sono già stati spesi, come nel caso in cui tu avessi utilizzato una copia del file wallet.dat per spendere bitcoin e questi non fossero stati considerati come spesi dal portamonete corrente.</translation>
+ </message>
+ <message>
+ <source>A fee higher than %1 is considered an absurdly high fee.</source>
+ <translation>Una commissione maggiore di %1 è considerata irragionevolmente elevata.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>Richiesta di pagamento scaduta.</translation>
+ </message>
+ <message>
+ <source>Pay only the minimum fee of %1</source>
+ <translation>Paga solamente la commissione minima di %1</translation>
+ </message>
+ <message>
+ <source>The recipient address is not valid. Please recheck.</source>
+ <translation>L'indirizzo del beneficiario non è valido. Si prega di ricontrollare.</translation>
+ </message>
+ <message>
+ <source>Duplicate address found: addresses should only be used once each.</source>
+ <translation>Rilevato un indirizzo duplicato Ciascun indirizzo dovrebbe essere utilizzato una sola volta.</translation>
+ </message>
+ <message>
+ <source>Warning: Invalid Bitcoin address</source>
+ <translation>Attenzione: Indirizzo Bitcoin non valido</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(nessuna etichetta)</translation>
+ </message>
+ <message>
+ <source>Warning: Unknown change address</source>
+ <translation>Attenzione: Indirizzo per il resto sconosciuto</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Copia trascurabile</translation>
+ </message>
+ <message>
+ <source>Are you sure you want to send?</source>
+ <translation>Sei sicuro di voler inviare?</translation>
+ </message>
+ <message>
+ <source>added as transaction fee</source>
+ <translation>aggiunto come tassa di transazione</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>&amp;Importo:</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>Paga &amp;a:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Inserisci un'etichetta per questo indirizzo, per aggiungerlo alla rubrica</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Etichetta:</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Scegli un indirizzo usato precedentemente</translation>
+ </message>
+ <message>
+ <source>This is a normal payment.</source>
+ <translation>Questo è un normale pagamento.</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to send the payment to</source>
+ <translation>L'indirizzo Bitcoin a cui vuoi inviare il pagamento</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Incollare l'indirizzo dagli appunti</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Remove this entry</source>
+ <translation>Rimuovi questa voce</translation>
+ </message>
+ <message>
+ <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source>
+ <translation>La commissione sarà sottratta dall'importo che si sta inviando. Il beneficiario riceverà un totale di bitcoin inferiore al valore digitato. Nel caso in cui siano stati selezionati più beneficiari la commissione sarà suddivisa in parti uguali.</translation>
+ </message>
+ <message>
+ <source>S&amp;ubtract fee from amount</source>
+ <translation>S&amp;ottrae la commissione dall'importo</translation>
+ </message>
+ <message>
+ <source>Message:</source>
+ <translation>Messaggio:</translation>
+ </message>
+ <message>
+ <source>This is an unauthenticated payment request.</source>
+ <translation>Questa è una richiesta di pagamento non autenticata.</translation>
+ </message>
+ <message>
+ <source>This is an authenticated payment request.</source>
+ <translation>Questa è una richiesta di pagamento autenticata.</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to the list of used addresses</source>
+ <translation>Inserisci un'etichetta per questo indirizzo per aggiungerlo alla lista degli indirizzi utilizzati</translation>
+ </message>
+ <message>
+ <source>A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network.</source>
+ <translation>Messaggio incluso nel bitcoin URI e che sarà memorizzato con la transazione per vostro riferimento. Nota: Questo messaggio non sarà inviato attraverso la rete Bitcoin.</translation>
+ </message>
+ <message>
+ <source>Pay To:</source>
+ <translation>Pagare a:</translation>
+ </message>
+ <message>
+ <source>Memo:</source>
+ <translation>Memo:</translation>
+ </message>
+</context>
+<context>
+ <name>ShutdownWindow</name>
+ <message>
+ <source>Bitcoin Core is shutting down...</source>
+ <translation>Arresto di Bitcoin Core in corso...</translation>
+ </message>
+ <message>
+ <source>Do not shut down the computer until this window disappears.</source>
+ <translation>Non spegnere il computer fino a quando questa finestra non si sarà chiusa.</translation>
+ </message>
+</context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Signatures - Sign / Verify a Message</source>
+ <translation>Firme - Firma / Verifica un messaggio</translation>
+ </message>
+ <message>
+ <source>&amp;Sign Message</source>
+ <translation>&amp;Firma Messaggio</translation>
+ </message>
+ <message>
+ <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source>
+ <translation>È possibile firmare messaggi/accordi con i propri indirizzi in modo da dimostrare di poter ricevere bitcoin attraverso di essi. Si consiglia di prestare attenzione a non firmare dichiarazioni vaghe o casuali, attacchi di phishing potrebbero cercare di indurre ad apporre la firma su di esse. Si raccomanda di firmare esclusivamente dichiarazioni completamente dettagliate e delle quali si condivide in pieno il contenuto.</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to sign the message with</source>
+ <translation>L'indirizzo Bitcoin da utilizzare per firmare il messaggio</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Scegli un indirizzo usato precedentemente</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Incolla l'indirizzo dagli appunti</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Enter the message you want to sign here</source>
+ <translation>Inserisci qui il messaggio che vuoi firmare</translation>
+ </message>
+ <message>
+ <source>Signature</source>
+ <translation>Firma</translation>
+ </message>
+ <message>
+ <source>Copy the current signature to the system clipboard</source>
+ <translation>Copia la firma corrente nella clipboard</translation>
+ </message>
+ <message>
+ <source>Sign the message to prove you own this Bitcoin address</source>
+ <translation>Firma un messaggio per dimostrare di possedere questo indirizzo Bitcoin</translation>
+ </message>
+ <message>
+ <source>Sign &amp;Message</source>
+ <translation>Firma &amp;Messaggio</translation>
+ </message>
+ <message>
+ <source>Reset all sign message fields</source>
+ <translation>Reimposta tutti i campi della firma messaggio</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Cancella &amp;Tutto</translation>
+ </message>
+ <message>
+ <source>&amp;Verify Message</source>
+ <translation>&amp;Verifica Messaggio</translation>
+ </message>
+ <message>
+ <source>Enter the receiver's 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. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source>
+ <translation>Per verificare il messaggio inserire l'indirizzo del firmatario, il messaggio e la firma nei campi sottostanti, assicurandosi di copiare esattamente anche ritorni a capo, spazi, tabulazioni, etc.. Si raccomanda di non lasciarsi fuorviare dalla firma a leggere più di quanto non sia riportato nel testo del messaggio stesso, in modo da evitare di cadere vittima di attacchi di tipo man-in-the-middle. Si ricorda che la verifica della firma dimostra soltanto che il firmatario può ricevere pagamenti con l'indirizzo corrispondente, non prova l'invio di alcuna transazione.</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address the message was signed with</source>
+ <translation>L'indirizzo Bitcoin con cui è stato contrassegnato il messaggio</translation>
+ </message>
+ <message>
+ <source>Verify the message to ensure it was signed with the specified Bitcoin address</source>
+ <translation>Verifica il messaggio per accertare che sia stato firmato con l'indirizzo specificato</translation>
+ </message>
+ <message>
+ <source>Verify &amp;Message</source>
+ <translation>Verifica &amp;Messaggio</translation>
+ </message>
+ <message>
+ <source>Reset all verify message fields</source>
+ <translation>Reimposta tutti i campi della verifica messaggio</translation>
+ </message>
+ <message>
+ <source>Click "Sign Message" to generate signature</source>
+ <translation>Clicca "Firma il messaggio" per ottenere la firma</translation>
+ </message>
+ <message>
+ <source>The entered address is invalid.</source>
+ <translation>L'indirizzo inserito non è valido.</translation>
+ </message>
+ <message>
+ <source>Please check the address and try again.</source>
+ <translation>Per favore controlla l'indirizzo e prova di nuovo.</translation>
+ </message>
+ <message>
+ <source>The entered address does not refer to a key.</source>
+ <translation>L'indirizzo bitcoin inserito non è associato a nessuna chiave.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock was cancelled.</source>
+ <translation>Sblocco del portamonete annullato.</translation>
+ </message>
+ <message>
+ <source>Private key for the entered address is not available.</source>
+ <translation>La chiave privata per l'indirizzo inserito non è disponibile.</translation>
+ </message>
+ <message>
+ <source>Message signing failed.</source>
+ <translation>Firma messaggio fallita.</translation>
+ </message>
+ <message>
+ <source>Message signed.</source>
+ <translation>Messaggio firmato.</translation>
+ </message>
+ <message>
+ <source>The signature could not be decoded.</source>
+ <translation>Non è stato possibile decodificare la firma.</translation>
+ </message>
+ <message>
+ <source>Please check the signature and try again.</source>
+ <translation>Per favore controlla la firma e prova di nuovo.</translation>
+ </message>
+ <message>
+ <source>The signature did not match the message digest.</source>
+ <translation>La firma non corrisponde al digest del messaggio.</translation>
+ </message>
+ <message>
+ <source>Message verification failed.</source>
+ <translation>Verifica messaggio fallita.</translation>
+ </message>
+ <message>
+ <source>Message verified.</source>
+ <translation>Messaggio verificato.</translation>
+ </message>
+</context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>The Bitcoin Core developers</source>
+ <translation>Gli sviluppatori di Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>[testnet]</source>
+ <translation>[testnet]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ <message>
+ <source>KB/s</source>
+ <translation>KB/s</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>Aperto fino a %1</translation>
+ </message>
+ <message>
+ <source>conflicted</source>
+ <translation>in conflitto</translation>
+ </message>
+ <message>
+ <source>%1/offline</source>
+ <translation>%1/offline</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/non confermata</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 conferme</translation>
+ </message>
+ <message>
+ <source>Status</source>
+ <translation>Stato</translation>
+ </message>
+ <message numerus="yes">
+ <source>, broadcast through %n node(s)</source>
+ <translation><numerusform>, trasmesso attraverso %n nodo</numerusform><numerusform>, trasmessa attraverso %n nodi</numerusform></translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Source</source>
+ <translation>Sorgente</translation>
+ </message>
+ <message>
+ <source>Generated</source>
+ <translation>Generato</translation>
+ </message>
+ <message>
+ <source>From</source>
+ <translation>Da</translation>
+ </message>
+ <message>
+ <source>To</source>
+ <translation>A</translation>
+ </message>
+ <message>
+ <source>own address</source>
+ <translation>proprio indirizzo</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>sola lettura</translation>
+ </message>
+ <message>
+ <source>label</source>
+ <translation>etichetta</translation>
+ </message>
+ <message>
+ <source>Credit</source>
+ <translation>Credito</translation>
+ </message>
+ <message numerus="yes">
+ <source>matures in %n more block(s)</source>
+ <translation><numerusform>matura tra %n blocco</numerusform><numerusform>matura tra %n blocchi</numerusform></translation>
+ </message>
+ <message>
+ <source>not accepted</source>
+ <translation>non accettate</translation>
+ </message>
+ <message>
+ <source>Debit</source>
+ <translation>Debito</translation>
+ </message>
+ <message>
+ <source>Total debit</source>
+ <translation>Debito totale</translation>
+ </message>
+ <message>
+ <source>Total credit</source>
+ <translation>Credito totale</translation>
+ </message>
+ <message>
+ <source>Transaction fee</source>
+ <translation>Commissione transazione</translation>
+ </message>
+ <message>
+ <source>Net amount</source>
+ <translation>Importo netto</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Messaggio</translation>
+ </message>
+ <message>
+ <source>Comment</source>
+ <translation>Commento</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>ID della transazione</translation>
+ </message>
+ <message>
+ <source>Merchant</source>
+ <translation>Commerciante</translation>
+ </message>
+ <message>
+ <source>Generated coins must mature %1 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.</source>
+ <translation>È necessario attendere %1 blocchi prima che i bitcoin generati possano essere spesi. Al momento della generazione questo blocco è stato trasmesso alla rete in modo da poter essere aggiunto alla block chain. Se l'inserimento avrà esito negativo lo stato del blocco sarà modificato in "non accettato" ed esso risulterà non spendibile. Ciò può verificarsi occasionalmente nel caso in cui un altro blocco sia stato generato entro pochi secondi dal tuo.</translation>
+ </message>
+ <message>
+ <source>Debug information</source>
+ <translation>Informazione di debug</translation>
+ </message>
+ <message>
+ <source>Transaction</source>
+ <translation>Transazione</translation>
+ </message>
+ <message>
+ <source>Inputs</source>
+ <translation>Input</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Importo</translation>
+ </message>
+ <message>
+ <source>true</source>
+ <translation>vero</translation>
+ </message>
+ <message>
+ <source>false</source>
+ <translation>falso</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, non è ancora stata trasmessa con successo</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Aperto per %n altro blocco</numerusform><numerusform>Aperto per altri %n blocchi</numerusform></translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>sconosciuto</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>Dettagli sulla transazione</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>Questo pannello mostra una descrizione dettagliata della transazione</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Tipo</translation>
+ </message>
+ <message>
+ <source>Immature (%1 confirmations, will be available after %2)</source>
+ <translation>Immaturo (%1 conferme, sarà disponibile fra %2)</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Aperto per %n altro blocco</numerusform><numerusform>Aperto per altri %n blocchi</numerusform></translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>Aperto fino a %1</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>Confermata (%1 conferme)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>Questo blocco non è stato ricevuto da alcun altro nodo e probabilmente non sarà accettato!</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>Generati, ma non accettati</translation>
+ </message>
+ <message>
+ <source>Offline</source>
+ <translation>Offline</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etichetta</translation>
+ </message>
+ <message>
+ <source>Unconfirmed</source>
+ <translation>Non confermata</translation>
+ </message>
+ <message>
+ <source>Confirming (%1 of %2 recommended confirmations)</source>
+ <translation>In conferma (%1 di %2 conferme raccomandate)</translation>
+ </message>
+ <message>
+ <source>Conflicted</source>
+ <translation>In conflitto</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Ricevuto tramite</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>Ricevuto da</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Inviato a</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>Pagamento a te stesso</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Ottenuto dal mining</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>sola lettura</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(n/d)</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>Stato della transazione. Passare con il mouse su questo campo per visualizzare il numero di conferme.</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Data e ora in cui la transazione è stata ricevuta.</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>Tipo di transazione.</translation>
+ </message>
+ <message>
+ <source>Whether or not a watch-only address is involved in this transaction.</source>
+ <translation>Indica se un indirizzo di sola lettura sia o meno coinvolto in questa transazione.</translation>
+ </message>
+ <message>
+ <source>User-defined intent/purpose of the transaction.</source>
+ <translation>Intento/scopo della transazione definito dall'utente.</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>Importo rimosso o aggiunto al saldo.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>Tutti</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>Oggi</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>Questa settimana</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>Questo mese</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>Il mese scorso</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>Quest'anno</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>Intervallo...</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Ricevuto tramite</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Inviato a</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>A te stesso</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Ottenuto dal mining</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>Altro</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>Inserisci un indirizzo o un'etichetta da cercare</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>Importo minimo</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Copia l'indirizzo</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Copia l'etichetta</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copia l'importo</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Copia l'ID transazione</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>Modifica l'etichetta</translation>
+ </message>
+ <message>
+ <source>Show transaction details</source>
+ <translation>Mostra i dettagli della transazione</translation>
+ </message>
+ <message>
+ <source>Export Transaction History</source>
+ <translation>Esporta lo storico delle transazioni</translation>
+ </message>
+ <message>
+ <source>Watch-only</source>
+ <translation>Sola lettura</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Esportazione Fallita.</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the transaction history to %1.</source>
+ <translation>Si è verificato un errore durante il salvataggio dello storico delle transazioni in %1.</translation>
+ </message>
+ <message>
+ <source>Exporting Successful</source>
+ <translation>Esportazione Riuscita</translation>
+ </message>
+ <message>
+ <source>The transaction history was successfully saved to %1.</source>
+ <translation>Lo storico delle transazioni e' stato salvato con successo in %1.</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Testo CSV (*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Confermato</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Tipo</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etichetta</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Indirizzo</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>Intervallo:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>a</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ <message>
+ <source>Unit to show amounts in. Click to select another unit.</source>
+ <translation>Unità con cui visualizzare gli importi. Clicca per selezionare un altra unità.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletFrame</name>
+ <message>
+ <source>No wallet has been loaded.</source>
+ <translation>Non è stato caricato alcun portamonete.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Invia Bitcoin</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Esporta</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Esporta su file i dati contenuti nella tabella corrente</translation>
+ </message>
+ <message>
+ <source>Backup Wallet</source>
+ <translation>Backup Portamonete</translation>
+ </message>
+ <message>
+ <source>Wallet Data (*.dat)</source>
+ <translation>Dati Portamonete (*.dat)</translation>
+ </message>
+ <message>
+ <source>Backup Failed</source>
+ <translation>Backup Fallito</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the wallet data to %1.</source>
+ <translation>Si è verificato un errore durante il salvataggio dei dati del portamonete in %1.</translation>
+ </message>
+ <message>
+ <source>The wallet data was successfully saved to %1.</source>
+ <translation>Il portamonete è stato correttamente salvato in %1.</translation>
+ </message>
+ <message>
+ <source>Backup Successful</source>
+ <translation>Backup eseguito con successo</translation>
+ </message>
+</context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>Opzioni:</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>Specifica la cartella dati</translation>
+ </message>
+ <message>
+ <source>Connect to a node to retrieve peer addresses, and disconnect</source>
+ <translation>Connessione ad un nodo e successiva disconnessione per recuperare gli indirizzi dei peer</translation>
+ </message>
+ <message>
+ <source>Specify your own public address</source>
+ <translation>Specifica il tuo indirizzo pubblico</translation>
+ </message>
+ <message>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>Accetta comandi da riga di comando e JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>Esegui in background come demone ed accetta i comandi</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>Utilizza la rete di prova</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
+ <translation>Accetta connessioni dall'esterno (predefinito: 1 se -proxy o -connect non sono utilizzati)</translation>
+ </message>
+ <message>
+ <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
+ <translation>Associa all'indirizzo indicato e resta permanentemente in ascolto su di esso. Usa la notazione [host]:porta per l'IPv6</translation>
+ </message>
+ <message>
+ <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
+ <translation>Elimina tutte le transazioni dal portamonete e recupera solo quelle che fanno parte della blockchain attraverso il comando -rescan all'avvio.</translation>
+ </message>
+ <message>
+ <source>Distributed under the MIT software license, see the accompanying file COPYING or &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</source>
+ <translation>Distribuito secondo la licenza software MIT, vedi il file COPYING incluso oppure &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</translation>
+ </message>
+ <message>
+ <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
+ <translation>Esegue un comando quando lo stato di una transazione del portamonete cambia (%s in cmd è sostituito da TxID)</translation>
+ </message>
+ <message>
+ <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source>
+ <translation>Commissioni massime totali da includere in una singola transazione dal portamonete. Un'impostazione troppo bassa potrebbe provocare l'annullamento di transazioni di grosse dimensioni (predefinito: %s)</translation>
+ </message>
+ <message>
+ <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, &gt;%u = target size in MiB to use for block files)</source>
+ <translation>Riduce i requisiti di spazio di archiviazione attraverso la rimozione dei vecchi blocchi (pruning). Questa modalità disabilita le funzionalità di portamonete ed è incompatibile con l'opzione -txindex. Attenzione: il ripristinando questa opzione l'intera blockchain dovrà essere riscaricata. (predefinito: 0 = disabilita il pruning, &gt;%u = dimensione desiderata in MiB per i file dei blocchi)</translation>
+ </message>
+ <message>
+ <source>Set the number of script verification threads (%u to %d, 0 = auto, &lt;0 = leave that many cores free, default: %d)</source>
+ <translation>Imposta il numero di thread per la verifica degli script (da %u a %d, 0 = automatico, &lt;0 = lascia questo numero di core liberi, predefinito: %d)</translation>
+ </message>
+ <message>
+ <source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source>
+ <translation>Questa versione è una compilazione pre-rilascio - usala a tuo rischio - non utilizzarla per la generazione o per applicazioni di commercio</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer. Bitcoin Core is probably already running.</source>
+ <translation>Impossibile associarsi a %s su questo computer. Probabilmente Bitcoin Core è già in esecuzione.</translation>
+ </message>
+ <message>
+ <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>ATTENZIONE, il numero di blocchi generati è insolitamente elevato: %d blocchi ricevuti nelle ultime %d ore (%d previsti)</translation>
+ </message>
+ <message>
+ <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>ATTENZIONE, si consiglia di verificare la connessione di rete: %d blocchi ricevuti nelle ultime %d ore (%d previsti)</translation>
+ </message>
+ <message>
+ <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>Attenzione: -paytxfee è impostato su un valore molto elevato. Questa è la commissione che si paga quando si invia una transazione.</translation>
+ </message>
+ <message>
+ <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source>
+ <translation>Attenzione: La rete non sembra trovarsi in pieno consenso! Alcuni minatori sembrano riscontrare problemi.</translation>
+ </message>
+ <message>
+ <source>Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.</source>
+ <translation>Attenzione: Sembra che non vi sia pieno consenso con i nostri peer! Un aggiornamento da parte tua o degli altri nodi potrebbe essere necessario.</translation>
+ </message>
+ <message>
+ <source>Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
+ <translation>Attenzione: errore di lettura di wallet.dat! Tutte le chiavi sono state lette correttamente, ma i dati delle transazioni o della rubrica potrebbero essere mancanti o non corretti.</translation>
+ </message>
+ <message>
+ <source>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</source>
+ <translation>Attenzione: wallet.dat corrotto, dati recuperati! Il wallet.dat originale è stato salvato come wallet.{timestamp}.bak in %s. Se i dati relativi a saldo o transazioni non dovessero risultare corretti si consiglia di procedere al ripristino da un backup.</translation>
+ </message>
+ <message>
+ <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source>
+ <translation>Inserisce in whitelist i peer che si connettono da un dato indirizzo IP o netmask. Può essere specificato più volte.</translation>
+ </message>
+ <message>
+ <source>(default: 1)</source>
+ <translation>(predefinito: 1)</translation>
+ </message>
+ <message>
+ <source>&lt;category&gt; can be:</source>
+ <translation>Valori possibili per &lt;category&gt;:</translation>
+ </message>
+ <message>
+ <source>Attempt to recover private keys from a corrupt wallet.dat</source>
+ <translation>Tenta di recuperare le chiavi private da un wallet.dat corrotto</translation>
+ </message>
+ <message>
+ <source>Block creation options:</source>
+ <translation>Opzioni creazione blocco:</translation>
+ </message>
+ <message>
+ <source>Connect only to the specified node(s)</source>
+ <translation>Connessione ai soli nodi specificati</translation>
+ </message>
+ <message>
+ <source>Connection options:</source>
+ <translation>Opzioni di connessione:</translation>
+ </message>
+ <message>
+ <source>Corrupted block database detected</source>
+ <translation>Rilevato database blocchi corrotto</translation>
+ </message>
+ <message>
+ <source>Debugging/Testing options:</source>
+ <translation>Opzioni di Debug/Test:</translation>
+ </message>
+ <message>
+ <source>Do not load the wallet and disable wallet RPC calls</source>
+ <translation>Disabilita il portamonete e le relative chiamate RPC</translation>
+ </message>
+ <message>
+ <source>Do you want to rebuild the block database now?</source>
+ <translation>Vuoi ricostruire ora il database dei blocchi?</translation>
+ </message>
+ <message>
+ <source>Error initializing block database</source>
+ <translation>Errore durante l'inizializzazione del database dei blocchi</translation>
+ </message>
+ <message>
+ <source>Error initializing wallet database environment %s!</source>
+ <translation>Errore durante l'inizializzazione dell'ambiente del database del portamonete %s!</translation>
+ </message>
+ <message>
+ <source>Error loading block database</source>
+ <translation>Errore durante il caricamento del database blocchi</translation>
+ </message>
+ <message>
+ <source>Error opening block database</source>
+ <translation>Errore durante l'apertura del database blocchi</translation>
+ </message>
+ <message>
+ <source>Error: Disk space is low!</source>
+ <translation>Errore: la spazio libero sul disco è insufficiente!</translation>
+ </message>
+ <message>
+ <source>Failed to listen on any port. Use -listen=0 if you want this.</source>
+ <translation>Nessuna porta disponibile per l'ascolto. Usa -listen=0 se vuoi procedere comunque.</translation>
+ </message>
+ <message>
+ <source>If &lt;category&gt; is not supplied, output all debugging information.</source>
+ <translation>Se &lt;category&gt; non è specificata, mostra tutte le informazioni di debug.</translation>
+ </message>
+ <message>
+ <source>Importing...</source>
+ <translation>Importazione...</translation>
+ </message>
+ <message>
+ <source>Incorrect or no genesis block found. Wrong datadir for network?</source>
+ <translation>Blocco genesi non corretto o non trovato. È possibile che la cartella dati appartenga ad un'altra rete.</translation>
+ </message>
+ <message>
+ <source>Invalid -onion address: '%s'</source>
+ <translation>Indirizzo -onion non valido: '%s'</translation>
+ </message>
+ <message>
+ <source>Not enough file descriptors available.</source>
+ <translation>Non ci sono abbastanza descrittori di file disponibili.</translation>
+ </message>
+ <message>
+ <source>Only connect to nodes in network &lt;net&gt; (ipv4, ipv6 or onion)</source>
+ <translation>Connessione ai soli nodi appartenenti alla rete &lt;net&gt; (ipv4, ipv6 o Tor)</translation>
+ </message>
+ <message>
+ <source>Prune cannot be configured with a negative value.</source>
+ <translation>La modalità prune non può essere configurata con un valore negativo.</translation>
+ </message>
+ <message>
+ <source>Prune mode is incompatible with -txindex.</source>
+ <translation>La modalità prune è incompatibile con l'opzione -txindex.</translation>
+ </message>
+ <message>
+ <source>Set database cache size in megabytes (%d to %d, default: %d)</source>
+ <translation>Imposta la dimensione della cache del database in megabyte (%d a %d, predefinito: %d)</translation>
+ </message>
+ <message>
+ <source>Set maximum block size in bytes (default: %d)</source>
+ <translation>Imposta la dimensione massima del blocco in byte (predefinito: %d)</translation>
+ </message>
+ <message>
+ <source>Specify wallet file (within data directory)</source>
+ <translation>Specifica il file del portamonete (all'interno della cartella dati)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: %u)</source>
+ <translation>Usa UPnP per mappare la porta di ascolto (predefinito: %u)</translation>
+ </message>
+ <message>
+ <source>Verifying blocks...</source>
+ <translation>Verifica blocchi...</translation>
+ </message>
+ <message>
+ <source>Verifying wallet...</source>
+ <translation>Verifica portamonete...</translation>
+ </message>
+ <message>
+ <source>Wallet %s resides outside data directory %s</source>
+ <translation>Il portamonete %s si trova al di fuori dalla cartella dati %s</translation>
+ </message>
+ <message>
+ <source>Wallet options:</source>
+ <translation>Opzioni portamonete:</translation>
+ </message>
+ <message>
+ <source>Warning: This version is obsolete; upgrade required!</source>
+ <translation>Attenzione: questa versione è obsoleta. Aggiornamento necessario!</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to change -txindex</source>
+ <translation>È necessario ricostruire il database usando -reindex per cambiare -txindex</translation>
+ </message>
+ <message>
+ <source>Imports blocks from external blk000??.dat file</source>
+ <translation>Importa blocchi da un file blk000??.dat esterno</translation>
+ </message>
+ <message>
+ <source>Allow JSON-RPC connections from specified source. Valid for &lt;ip&gt; are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times</source>
+ <translation>Permette connessioni JSON-RPC dall'origine specificata. I valori validi per &lt;ip&gt; sono un singolo IP (ad es. 1.2.3.4), una network/netmask (ad es. 1.2.3.4/255.255.255.0) oppure una network/CIDR (ad es. 1.2.3.4/24). Questa opzione può essere specificata più volte.</translation>
+ </message>
+ <message>
+ <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source>
+ <translation>Resta in ascolto sull'indirizzo indicato ed inserisce in whitelist i peer che vi si collegano. Usa la notazione [host]:porta per l'IPv6</translation>
+ </message>
+ <message>
+ <source>Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)</source>
+ <translation>Resta in attesa di connessioni JSON-RPC sull'indirizzo indicato. Usa la notazione [host]:porta per IPv6. Questa opzione può essere specificata più volte (predefinito: associa a tutte le interfacce) </translation>
+ </message>
+ <message>
+ <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source>
+ <translation>Non è possibile ottenere un lock sulla cartella %s. Probabilmente Bitcoin Core è già in esecuzione.</translation>
+ </message>
+ <message>
+ <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
+ <translation>Crea nuovi file con i permessi di default del sistema, invece che con umask 077 (ha effetto solo con funzionalità di portamonete disabilitate)</translation>
+ </message>
+ <message>
+ <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source>
+ <translation>Scopre i propri indirizzi IP (predefinito: 1 se in ascolto ed -externalip o -proxy non sono specificati)</translation>
+ </message>
+ <message>
+ <source>Error: Listening for incoming connections failed (listen returned error %s)</source>
+ <translation>Errore: attesa per connessioni in arrivo fallita (errore riportato %s)</translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source>
+ <translation>Errore: individuato argomento -socks non supportato. Non è più possibile impostare la versione SOCKS, solamente i proxy SOCKS5 sono supportati.</translation>
+ </message>
+ <message>
+ <source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source>
+ <translation>Esegue un comando in caso di ricezione di un allarme pertinente o se si rileva un fork molto lungo (%s in cmd è sostituito dal messaggio)</translation>
+ </message>
+ <message>
+ <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source>
+ <translation>Le commissioni (in BTC/kB) inferiori a questo valore sono considerate pari a zero relativamente alla trasmissione (predefinito: %s)</translation>
+ </message>
+ <message>
+ <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
+ <translation>Nel caso in cui paytxfee non sia impostato, include una commissione tale da ottenere un avvio delle conferme entro una media di n blocchi (predefinito: %u)</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)</source>
+ <translation>Importo non valido per -maxtxfee=&lt;amount&gt;: '%s' (deve essere almeno pari alla commissione 'minrelay fee' di %s per prevenire transazioni bloccate)</translation>
+ </message>
+ <message>
+ <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source>
+ <translation>Dimensione massima dei dati in transazioni di trasporto dati che saranno trasmesse ed incluse nei blocchi (predefinito: %u)</translation>
+ </message>
+ <message>
+ <source>Prune configured below the minimum of %d MB. Please use a higher number.</source>
+ <translation>La modalità prune è configurata al di sotto del minimo di %d MB. Si prega di utilizzare un valore più elevato.</translation>
+ </message>
+ <message>
+ <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source>
+ <translation>Ottiene gli indirizzi dei peer attraverso interrogazioni DNS, in caso di scarsa disponibilità (predefinito: 1 a meno che -connect non sia specificato)</translation>
+ </message>
+ <message>
+ <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source>
+ <translation>Randomizza le credenziali per ogni connessione proxy. Permette la Tor stream isolation (predefinito: %u)</translation>
+ </message>
+ <message>
+ <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
+ <translation>Imposta la dimensione massima in byte delle transazioni ad alta-priorità/basse-commissioni (predefinito: %d)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source>
+ <translation>Specifica il numero di thread per la generazione di bitcoin, se abilitata (-1 = tutti i core, predefinito: %d)</translation>
+ </message>
+ <message>
+ <source>The transaction amount is too small to send after the fee has been deducted</source>
+ <translation>L'importo della transazione risulta troppo basso per l'invio una volta dedotte le commissioni.</translation>
+ </message>
+ <message>
+ <source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit &lt;https://www.openssl.org/&gt; and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source>
+ <translation>Questo prodotto include software sviluppato dal progetto OpenSSL per l'uso del Toolkit OpenSSL &lt;https://www.openssl.org/&gt;, software crittografico scritto da Eric Young e software UPnP scritto da Thomas Bernard.</translation>
+ </message>
+ <message>
+ <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an 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)
+The username and password MUST NOT be the same.
+If the file does not exist, create it with owner-readable-only file permissions.
+It is also recommended to set alertnotify so you are notified of problems;
+for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
+</source>
+ <translation>Per utilizzare bitcoind o l'opzione -server in Bitcoin Core è necessario specificare una rpcpassword nel file di configurazione:
+%s
+Si raccomanda di utilizzare la seguente password casuale:
+rpcuser=bitcoinrpc
+rpcpassword=%s
+(non è necessario ricordare questa password)
+Il nome utente e la password NON DEVONO corrispondere.
+Se il file non esiste si raccomanda di crearlo con permessi di lettura per il solo proprietario.
+Si raccomanda inoltre di configurare alertnotify in modo da ricevere notifiche di eventuali problemi, ad es. alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
+</translation>
+ </message>
+ <message>
+ <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source>
+ <translation>Attenzione: -maxtxfee è impostato su un valore molto elevato. Tali commissioni potrebbero essere pagate anche in una singola transazione.</translation>
+ </message>
+ <message>
+ <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source>
+ <translation>Attenzione: Si prega di verificare che data ed ora del computer siano corrette! Una configurazione errata dell'orologio di sistema potrebbe impedire a Bitcoin Core di funzionare regolarmente.</translation>
+ </message>
+ <message>
+ <source>Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway</source>
+ <translation>I peer inclusi in whitelist non possono subire ban per DoS e le loro transazioni saranno sempre trasmesse, anche nel caso in cui si trovino già nel mempool. Ciò è utile ad es. per i gateway</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source>
+ <translation>Per ritornare alla modalità unpruned sarà necessario ricostruire il database utilizzando l'opzione -reindex. L'intera blockchain sarà riscaricata.</translation>
+ </message>
+ <message>
+ <source>(default: %u)</source>
+ <translation>(default: %u)</translation>
+ </message>
+ <message>
+ <source>Accept public REST requests (default: %u)</source>
+ <translation>Accetta richieste REST pubbliche (predefinito: %u)</translation>
+ </message>
+ <message>
+ <source>Activating best chain...</source>
+ <translation>Attivazione della blockchain migliore...</translation>
+ </message>
+ <message>
+ <source>Can't run with a wallet in prune mode.</source>
+ <translation>Impossibile operare con un portamonete in modalità prune.</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -whitebind address: '%s'</source>
+ <translation>Impossibile risolvere indirizzo -whitebind: '%s'</translation>
+ </message>
+ <message>
+ <source>Choose data directory on startup (default: 0)</source>
+ <translation>Seleziona la cartella dati all'avvio (predefinito: 0)</translation>
+ </message>
+ <message>
+ <source>Connect through SOCKS5 proxy</source>
+ <translation>Connessione attraverso un proxy SOCKS5</translation>
+ </message>
+ <message>
+ <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source>
+ <translation>Copyright (C) 2009-%i Gli sviluppatori di Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Could not parse -rpcbind value %s as network address</source>
+ <translation>Non è stato possibile riconoscere il valore %s di -rpcbind come indirizzo di rete</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source>
+ <translation>Errore durante il caricamento del file wallet.dat: il portamonete richiede una versione di Bitcoin Core più recente</translation>
+ </message>
+ <message>
+ <source>Error reading from database, shutting down.</source>
+ <translation>Errore durante lalettura del database. Arresto in corso.</translation>
+ </message>
+ <message>
+ <source>Error: A fatal internal error occurred, see debug.log for details</source>
+ <translation>Errore: si è presentato un errore interno fatale, consulta il file debug.log per maggiori dettagli</translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -tor found, use -onion.</source>
+ <translation>Errore: Rilevato argomento -tor non supportato, utilizzare -onion.</translation>
+ </message>
+ <message>
+ <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source>
+ <translation>Commissione (in BTC/kB) da aggiungere alle transazioni che invii (predefinito: %s)</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Informazioni</translation>
+ </message>
+ <message>
+ <source>Initialization sanity check failed. Bitcoin Core is shutting down.</source>
+ <translation>Test di integrità iniziale fallito. Bitcoin Core si arresterà.</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Importo non valido per -maxtxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -minrelaytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Importo non valido per -minrelaytxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -mintxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Importo non valido per -mintxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s' (must be at least %s)</source>
+ <translation>Importo non valido per -paytxfee=&lt;amount&gt;: '%s' (deve essere almeno %s)</translation>
+ </message>
+ <message>
+ <source>Invalid netmask specified in -whitelist: '%s'</source>
+ <translation>Netmask non valida specificata in -whitelist: '%s'</translation>
+ </message>
+ <message>
+ <source>Keep at most &lt;n&gt; unconnectable transactions in memory (default: %u)</source>
+ <translation>Mantiene in memoria al massimo &lt;n&gt; transazioni non collegabili (predefinito: %u)</translation>
+ </message>
+ <message>
+ <source>Need to specify a port with -whitebind: '%s'</source>
+ <translation>È necessario specificare una porta con -whitebind: '%s'</translation>
+ </message>
+ <message>
+ <source>Node relay options:</source>
+ <translation>Opzioni trasmissione nodo:</translation>
+ </message>
+ <message>
+ <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source>
+ <translation>Opzioni RPC SSL: (consulta la Bitcoin Wiki per le istruzioni relative alla configurazione SSL)</translation>
+ </message>
+ <message>
+ <source>RPC server options:</source>
+ <translation>Opzioni server RPC:</translation>
+ </message>
+ <message>
+ <source>RPC support for HTTP persistent connections (default: %d)</source>
+ <translation>Supporto RPC per le connessioni HTTP persistenti (predefinito: %d)</translation>
+ </message>
+ <message>
+ <source>Rebuild block chain index from current blk000??.dat files on startup</source>
+ <translation>Ricostruzione dell'indice della block chain dai file blk000??.dat correnti all'avvio</translation>
+ </message>
+ <message>
+ <source>Receive and display P2P network alerts (default: %u)</source>
+ <translation>Ricevi e visualizza gli alerts della rete P2P (default: %u)</translation>
+ </message>
+ <message>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>Invia le informazioni di trace/debug alla console invece che al file debug.log</translation>
+ </message>
+ <message>
+ <source>Send transactions as zero-fee transactions if possible (default: %u)</source>
+ <translation>Invia transazioni a zero commissioni se possibile (predefinito: %u)</translation>
+ </message>
+ <message>
+ <source>Set SSL root certificates for payment request (default: -system-)</source>
+ <translation>Imposta i certificati radice SSL per le richieste di pagamento (predefinito: -system-)</translation>
+ </message>
+ <message>
+ <source>Set language, for example "de_DE" (default: system locale)</source>
+ <translation>Imposta lingua, ad esempio "it_IT" (predefinito: lingua di sistema)</translation>
+ </message>
+ <message>
+ <source>Show all debugging options (usage: --help -help-debug)</source>
+ <translation>Mostra tutte le opzioni di debug (utilizzo: --help -help-debug)</translation>
+ </message>
+ <message>
+ <source>Show splash screen on startup (default: 1)</source>
+ <translation>Mostra finestra di presentazione all'avvio (predefinito: 1)</translation>
+ </message>
+ <message>
+ <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source>
+ <translation>Riduce il file debug.log all'avvio del client (predefinito: 1 se -debug non è impostato)</translation>
+ </message>
+ <message>
+ <source>Signing transaction failed</source>
+ <translation>Firma transazione fallita</translation>
+ </message>
+ <message>
+ <source>Start minimized</source>
+ <translation>Avvia ridotto a icona</translation>
+ </message>
+ <message>
+ <source>The transaction amount is too small to pay the fee</source>
+ <translation>L'importo della transazione è troppo basso per pagare la commissione</translation>
+ </message>
+ <message>
+ <source>This is experimental software.</source>
+ <translation>Questo è un software sperimentale.</translation>
+ </message>
+ <message>
+ <source>Transaction amount too small</source>
+ <translation>Importo transazione troppo piccolo</translation>
+ </message>
+ <message>
+ <source>Transaction amounts must be positive</source>
+ <translation>Gli importi della transazione devono essere positivi</translation>
+ </message>
+ <message>
+ <source>Transaction too large for fee policy</source>
+ <translation>Transazione troppo grande in base alla policy sulle commissioni</translation>
+ </message>
+ <message>
+ <source>Transaction too large</source>
+ <translation>Transazione troppo grande</translation>
+ </message>
+ <message>
+ <source>UI Options:</source>
+ <translation>Opzioni Interfaccia Utente:</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer (bind returned error %s)</source>
+ <translation>Impossibile associarsi a %s su questo computer (l'associazione ha restituito l'errore %s)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: 1 when listening)</source>
+ <translation>Usa UPnP per mappare la porta in ascolto (predefinito: 1 quando in ascolto)</translation>
+ </message>
+ <message>
+ <source>Username for JSON-RPC connections</source>
+ <translation>Nome utente per connessioni JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Wallet needed to be rewritten: restart Bitcoin Core to complete</source>
+ <translation>Il portamonete necessitava di essere riscritto: riavviare Bitcoin Core per completare l'operazione</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Attenzione</translation>
+ </message>
+ <message>
+ <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source>
+ <translation>Attenzione: Argomento -benchmark ignorato in quanto non supportato, usare -debug=bench.</translation>
+ </message>
+ <message>
+ <source>Warning: Unsupported argument -debugnet ignored, use -debug=net.</source>
+ <translation>Attenzione: Argomento -debugnet ignorato in quanto non supportato, usare -debug=net.</translation>
+ </message>
+ <message>
+ <source>Zapping all transactions from wallet...</source>
+ <translation>Eliminazione dal portamonete di tutte le transazioni...</translation>
+ </message>
+ <message>
+ <source>on startup</source>
+ <translation>all'avvio</translation>
+ </message>
+ <message>
+ <source>wallet.dat corrupt, salvage failed</source>
+ <translation>wallet.dat corrotto, recupero fallito</translation>
+ </message>
+ <message>
+ <source>Password for JSON-RPC connections</source>
+ <translation>Password per connessioni JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
+ <translation>Esegue un comando quando il miglior blocco cambia (%s nel cmd è sostituito dall'hash del blocco)</translation>
+ </message>
+ <message>
+ <source>Upgrade wallet to latest format</source>
+ <translation>Aggiorna il wallet all'ultimo formato</translation>
+ </message>
+ <message>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>Ripete la scansione della block chain per individuare le transazioni che mancano dal portamonete</translation>
+ </message>
+ <message>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>Utilizza OpenSSL (https) per le connessioni JSON-RPC</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>Questo messaggio di aiuto</translation>
+ </message>
+ <message>
+ <source>Allow DNS lookups for -addnode, -seednode and -connect</source>
+ <translation>Consente interrogazioni DNS per -addnode, -seednode e -connect</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>Caricamento indirizzi...</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>Errore caricamento wallet.dat: Portamonete corrotto</translation>
+ </message>
+ <message>
+ <source>(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source>
+ <translation>(1 = mantiene metadati tx, ad es. proprietario account ed informazioni di richiesta di pagamento, 2 = scarta metadati tx)</translation>
+ </message>
+ <message>
+ <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
+ <translation>Determina quanto sarà approfondita la verifica da parte di -checkblocks (0-4, predefinito: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
+ <translation>Mantiene l'indice completo delle transazioni usato dalla chiamata rpc getrawtransaction (predefinito: %u)</translation>
+ </message>
+ <message>
+ <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source>
+ <translation>Numero di secondi di sospensione prima della riconnessione per i peer che mostrano un comportamento anomalo (predefinito: %u)</translation>
+ </message>
+ <message>
+ <source>Output debugging information (default: %u, supplying &lt;category&gt; is optional)</source>
+ <translation>Emette informazioni di debug (predefinito: %u, fornire &lt;category&gt; è opzionale)</translation>
+ </message>
+ <message>
+ <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source>
+ <translation>Usa un proxy SOCKS5 a parte per raggiungere i peer attraverso gli hidden services di Tor (predefinito: %s)</translation>
+ </message>
+ <message>
+ <source>(default: %s)</source>
+ <translation>(predefinito: %s)</translation>
+ </message>
+ <message>
+ <source>Acceptable ciphers (default: %s)</source>
+ <translation>Cifrari accettabili (predefinito: %s)</translation>
+ </message>
+ <message>
+ <source>Always query for peer addresses via DNS lookup (default: %u)</source>
+ <translation>Interroga sempre i DNS per ottenere gli indirizzi dei peer (predefinito: %u)</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>Errore caricamento wallet.dat</translation>
+ </message>
+ <message>
+ <source>Generate coins (default: %u)</source>
+ <translation>Genera bitcoin (predefinito: %u)</translation>
+ </message>
+ <message>
+ <source>How many blocks to check at startup (default: %u, 0 = all)</source>
+ <translation>Numero di blocchi da controllare all'avvio (predefinito: %u, 0 = tutti)</translation>
+ </message>
+ <message>
+ <source>Include IP addresses in debug output (default: %u)</source>
+ <translation>Include gli indirizzi IP nell'output del debug (predefinito: %u)</translation>
+ </message>
+ <message>
+ <source>Invalid -proxy address: '%s'</source>
+ <translation>Indirizzo -proxy non valido: '%s'</translation>
+ </message>
+ <message>
+ <source>Listen for JSON-RPC connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>Resta in attesa di connessioni JSON-RPC su &lt;port&gt; (predefinito: %u o testnet: %u)</translation>
+ </message>
+ <message>
+ <source>Listen for connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>Resta in attesa di connessioni su &lt;port&gt; (predefinito: %u o testnet: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain at most &lt;n&gt; connections to peers (default: %u)</source>
+ <translation>Mantiene al massimo &lt;n&gt; connessioni verso i peer (predefinito: %u)</translation>
+ </message>
+ <message>
+ <source>Make the wallet broadcast transactions</source>
+ <translation>Configura il portamonete per la trasmissione di transazioni</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection receive buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>Buffer di ricezione massimo per connessione, &lt;n&gt;*1000 byte (predefinito: %u)</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection send buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>Buffer di invio massimo per connessione, &lt;n&gt;*1000 byte (predefinito: %u)</translation>
+ </message>
+ <message>
+ <source>Prepend debug output with timestamp (default: %u)</source>
+ <translation>Antepone un timestamp all'output del debug (predefinito: %u)</translation>
+ </message>
+ <message>
+ <source>Relay and mine data carrier transactions (default: %u)</source>
+ <translation>Trasmette ed include nei blocchi transazioni di trasporto dati (predefinito: %u)</translation>
+ </message>
+ <message>
+ <source>Relay non-P2SH multisig (default: %u)</source>
+ <translation>Trasmette transazioni non-P2SH multisig (predefinito: %u)</translation>
+ </message>
+ <message>
+ <source>Server certificate file (default: %s)</source>
+ <translation>File del certificato del server (predefinito: %s)</translation>
+ </message>
+ <message>
+ <source>Server private key (default: %s)</source>
+ <translation>Chiave privata del server (predefinito: %s)</translation>
+ </message>
+ <message>
+ <source>Set key pool size to &lt;n&gt; (default: %u)</source>
+ <translation>Imposta la dimensione del pool di chiavi a &lt;n&gt; (predefinito: %u)</translation>
+ </message>
+ <message>
+ <source>Set minimum block size in bytes (default: %u)</source>
+ <translation>Imposta la dimensione minima del blocco in byte (predefinito: %u)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads to service RPC calls (default: %d)</source>
+ <translation>Imposta il numero di thread destinati a rispondere alle chiamate RPC (predefinito %d)</translation>
+ </message>
+ <message>
+ <source>Specify configuration file (default: %s)</source>
+ <translation>Specifica il file di configurazione (predefinito: %s)</translation>
+ </message>
+ <message>
+ <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source>
+ <translation>Specifica il timeout di connessione in millisecondi (minimo:1, predefinito: %d)</translation>
+ </message>
+ <message>
+ <source>Specify pid file (default: %s)</source>
+ <translation>Specifica il file pid (predefinito: %s)</translation>
+ </message>
+ <message>
+ <source>Spend unconfirmed change when sending transactions (default: %u)</source>
+ <translation>Abilita la spesa di resto non confermato quando si inviano transazioni (predefinito: %u)</translation>
+ </message>
+ <message>
+ <source>Threshold for disconnecting misbehaving peers (default: %u)</source>
+ <translation>Soglia di disconnessione per i peer che si comportano in maniera anomala (predefinito: %u)</translation>
+ </message>
+ <message>
+ <source>Unknown network specified in -onlynet: '%s'</source>
+ <translation>Rete sconosciuta specificata in -onlynet: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -bind address: '%s'</source>
+ <translation>Impossibile risolvere indirizzo -bind: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -externalip address: '%s'</source>
+ <translation>Impossibile risolvere indirizzo -externalip: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Importo non valido per -paytxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>Fondi insufficienti</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>Caricamento dell'indice dei blocchi...</translation>
+ </message>
+ <message>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>Aggiunge un nodo a cui connettersi e tenta di mantenere aperta la connessione</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>Caricamento portamonete...</translation>
+ </message>
+ <message>
+ <source>Cannot downgrade wallet</source>
+ <translation>Non è possibile effettuare il downgrade del portamonete</translation>
+ </message>
+ <message>
+ <source>Cannot write default address</source>
+ <translation>Non è possibile scrivere l'indirizzo predefinito</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>Ripetizione scansione...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>Caricamento completato</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Errore</translation>
+ </message>
+</context>
+</TS> \ No newline at end of file
diff --git a/src/qt/locale/bitcoin_ja.ts b/src/qt/locale/bitcoin_ja.ts
new file mode 100644
index 0000000000..2140fe7438
--- /dev/null
+++ b/src/qt/locale/bitcoin_ja.ts
@@ -0,0 +1,3593 @@
+<TS language="ja" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Right-click to edit address or label</source>
+ <translation>右クリックでアドレスまたはラベルを編集します</translation>
+ </message>
+ <message>
+ <source>Create a new address</source>
+ <translation>新規アドレスの作成</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>新規(&amp;N)</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>現在選択されているアドレスをシステムのクリップボードにコピーする</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>コピー(&amp;C)</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>閉じる(&amp;C)</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>アドレスをコピー (&amp;C)</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>選択されたアドレスを一覧から削除する</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>ファイルに現在のタブのデータをエクスポート</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>エクスポート (&amp;E)</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>削除(&amp;D)</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>送信先のアドレスを選択</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>支払いを受け取るアドレスを指定する</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>選択(&amp;C)</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>アドレス送信中</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>アドレス受信中</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>これらは支払いを送信するためのあなたの Bitcoin アドレスです。コインを送信する前に、常に額と受信アドレスを確認してください。</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>これらは支払いを受け取るためのビットコインアドレスです。トランザクションごとに新しい受け取り用アドレスを作成することが推奨されます。</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>ラベルをコピー (&amp;L)</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>編集 (&amp;E)</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>アドレス帳をエクスポート</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>CSVファイル (*.csv)</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>エクスポート失敗</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the address list to %1. Please try again.</source>
+ <translation>トランザクション履歴を %1 へ保存する際にエラーが発生しました。再試行してください。</translation>
+ </message>
+</context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>ラベル</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>アドレス</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(ラベル無し)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Passphrase Dialog</source>
+ <translation>パスフレーズ ダイアログ</translation>
+ </message>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>パスフレーズを入力</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>新しいパスフレーズ</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>新しいパスフレーズをもう一度</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>ウォレットを暗号化する</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>この操作はウォレットをアンロックするためにパスフレーズが必要です。</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>ウォレットをアンロックする</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>この操作はウォレットの暗号化解除のためにパスフレーズが必要です。</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>ウォレットの暗号化を解除する</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>パスフレーズの変更</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>ウォレットの暗号化を確認する</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>警告: もしもあなたのウォレットを暗号化してパスフレーズを失ってしまったなら、&lt;b&gt;あなたの Bitcoin はすべて失われます&lt;/b&gt;!</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>本当にウォレットを暗号化しますか?</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core 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.</source>
+ <translation>暗号化処理を完了させるため Bitcoin Core をいますぐ終了します。ウォレットの暗号化では、コンピュータに感染したマルウェアなどによるビットコインの盗難から完全に守ることはできないことにご注意ください。</translation>
+ </message>
+ <message>
+ <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
+ <translation>重要: 過去のウォレット ファイルのバックアップは、暗号化された新しいウォレット ファイルに取り替える必要があります。セキュリティ上の理由により、暗号化された新しいウォレットを使い始めると、暗号化されていないウォレット ファイルのバックアップはすぐに使えなくなります。</translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>警告: Caps Lock キーがオンになっています!</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>ウォレットは暗号化されました</translation>
+ </message>
+ <message>
+ <source>Enter the new passphrase to the wallet.&lt;br/&gt;Please use a passphrase of &lt;b&gt;ten or more random characters&lt;/b&gt;, or &lt;b&gt;eight or more words&lt;/b&gt;.</source>
+ <translation>ウォレットの新しいパスフレーズを入力してください。&lt;br/&gt;&lt;b&gt;10文字以上のランダムな文字&lt;/b&gt;で構成されたものか、&lt;b&gt;8単語以上の単語&lt;/b&gt;で構成されたパスフレーズを使用してください。</translation>
+ </message>
+ <message>
+ <source>Enter the old passphrase and new passphrase to the wallet.</source>
+ <translation>ウォレットの古いパスフレーズおよび新しいパスフレーズを入力してください。</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>ウォレットの暗号化に失敗しました</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>内部エラーによりウォレットの暗号化が失敗しました。ウォレットは暗号化されませんでした。</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>パスフレーズが同じではありません。</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>ウォレットのアンロックに失敗しました</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>ウォレットの暗号化解除のパスフレーズが正しくありません。</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>ウォレットの暗号化解除に失敗しました</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>ウォレットのパスフレーズの変更が成功しました。</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>メッセージの署名... (&amp;m)</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>ネットワークに同期中……</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>概要(&amp;O)</translation>
+ </message>
+ <message>
+ <source>Node</source>
+ <translation>ノード</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>ウォレットの概要を見る</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>取引(&amp;T)</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>取引履歴を閲覧</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>終了(&amp;E)</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>アプリケーションを終了</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>Qt について(&amp;Q)</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>Qt の情報を表示</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>オプション... (&amp;O)</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>ウォレットの暗号化... (&amp;E)</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>ウォレットのバックアップ... (&amp;B)</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>パスフレーズの変更... (&amp;C)</translation>
+ </message>
+ <message>
+ <source>&amp;Sending addresses...</source>
+ <translation>送金先アドレス一覧 (&amp;S)...</translation>
+ </message>
+ <message>
+ <source>&amp;Receiving addresses...</source>
+ <translation>受け取り用アドレス一覧 (&amp;R)...</translation>
+ </message>
+ <message>
+ <source>Open &amp;URI...</source>
+ <translation>URI を開く (&amp;U)...</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core client</source>
+ <translation>Bitcoinコア クライアント</translation>
+ </message>
+ <message>
+ <source>Importing blocks from disk...</source>
+ <translation>ディスクからブロックをインポートしています...</translation>
+ </message>
+ <message>
+ <source>Reindexing blocks on disk...</source>
+ <translation>ディスク上のブロックのインデックスを再作成中...</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>Bitcoin アドレスにコインを送る</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>ウォレットを他の場所にバックアップ</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>ウォレット暗号化用パスフレーズの変更</translation>
+ </message>
+ <message>
+ <source>&amp;Debug window</source>
+ <translation>デバッグ ウインドウ (&amp;D)</translation>
+ </message>
+ <message>
+ <source>Open debugging and diagnostic console</source>
+ <translation>デバッグと診断コンソールを開く</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>メッセージの検証... (&amp;V)</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>ウォレット</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>送る (&amp;S)</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>受信 (&amp;R)</translation>
+ </message>
+ <message>
+ <source>Show information about Bitcoin Core</source>
+ <translation>Bitcoinコアに関する情報を表示</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>見る/隠す (&amp;S)</translation>
+ </message>
+ <message>
+ <source>Show or hide the main Window</source>
+ <translation>メイン ウインドウを表示または非表示</translation>
+ </message>
+ <message>
+ <source>Encrypt the private keys that belong to your wallet</source>
+ <translation>あなたのウォレットの秘密鍵を暗号化します</translation>
+ </message>
+ <message>
+ <source>Sign messages with your Bitcoin addresses to prove you own them</source>
+ <translation>あなたが所有していることを証明するために、あなたの Bitcoin アドレスでメッセージに署名してください</translation>
+ </message>
+ <message>
+ <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source>
+ <translation>指定された Bitcoin アドレスで署名されたことを確認するためにメッセージを検証します</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>ファイル(&amp;F)</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>設定(&amp;S)</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>ヘルプ(&amp;H)</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>タブツールバー</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin のコア</translation>
+ </message>
+ <message>
+ <source>Request payments (generates QR codes and bitcoin: URIs)</source>
+ <translation>支払いを要求する (QRコードとbitcoin:ではじまるURIを生成する)</translation>
+ </message>
+ <message>
+ <source>&amp;About Bitcoin Core</source>
+ <translation>ビットコインコアについて (&amp;A)</translation>
+ </message>
+ <message>
+ <source>Modify configuration options for Bitcoin Core</source>
+ <translation>Bitcoin Core の設定を編集する</translation>
+ </message>
+ <message>
+ <source>Show the list of used sending addresses and labels</source>
+ <translation>使用済みの送金用アドレスとラベルの一覧を表示する</translation>
+ </message>
+ <message>
+ <source>Show the list of used receiving addresses and labels</source>
+ <translation>支払いを受け取るアドレスとラベルのリストを表示する</translation>
+ </message>
+ <message>
+ <source>Open a bitcoin: URI or payment request</source>
+ <translation>bitcoin: URIまたは支払いリクエストを開く</translation>
+ </message>
+ <message>
+ <source>&amp;Command-line options</source>
+ <translation>コマンドラインオプション (&amp;C)</translation>
+ </message>
+ <message>
+ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
+ <translation>有効な Bitcoin のコマンドライン オプションを見るために Bitcoin Core のヘルプメッセージを表示します。</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n active connection(s) to Bitcoin network</source>
+ <translation><numerusform>%n の Bitcoin ネットワークへのアクティブな接続</numerusform></translation>
+ </message>
+ <message>
+ <source>No block source available...</source>
+ <translation>利用可能なブロックがありません...</translation>
+ </message>
+ <message numerus="yes">
+ <source>Processed %n block(s) of transaction history.</source>
+ <translation><numerusform>トランザクション履歴の %n ブロックを処理しました。</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n hour(s)</source>
+ <translation><numerusform>%n 時間</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n day(s)</source>
+ <translation><numerusform>%n 日</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n week(s)</source>
+ <translation><numerusform>%n 週間</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 and %2</source>
+ <translation>%1 と %2</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n year(s)</source>
+ <translation><numerusform>%n 年</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 behind</source>
+ <translation>%1 遅延</translation>
+ </message>
+ <message>
+ <source>Last received block was generated %1 ago.</source>
+ <translation>最後に受信されたブロックは %1 前に生成されました。</translation>
+ </message>
+ <message>
+ <source>Transactions after this will not yet be visible.</source>
+ <translation>この後の取引はまだ表示されません。</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>エラー</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>警告</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>情報</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>バージョンは最新です</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>追跡中...</translation>
+ </message>
+ <message>
+ <source>Date: %1
+</source>
+ <translation>日付: %1
+</translation>
+ </message>
+ <message>
+ <source>Amount: %1
+</source>
+ <translation>総額: %1
+</translation>
+ </message>
+ <message>
+ <source>Type: %1
+</source>
+ <translation>タイプ: %1
+</translation>
+ </message>
+ <message>
+ <source>Label: %1
+</source>
+ <translation>ラベル: %1
+</translation>
+ </message>
+ <message>
+ <source>Address: %1
+</source>
+ <translation>アドレス: %1
+</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>送金取引</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>着金取引</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>ウォレットは&lt;b&gt;暗号化されて、アンロックされています&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>ウォレットは&lt;b&gt;暗号化されて、ロックされています&lt;/b&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <source>Network Alert</source>
+ <translation>ネットワーク警告</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Coin Selection</source>
+ <translation>コイン選択</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>数量:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>バイト:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>総額:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>優先度:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>手数料:</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>ダスト:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>手数料差引後:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>釣り銭:</translation>
+ </message>
+ <message>
+ <source>(un)select all</source>
+ <translation>すべて選択/選択解除</translation>
+ </message>
+ <message>
+ <source>Tree mode</source>
+ <translation>ツリーモード</translation>
+ </message>
+ <message>
+ <source>List mode</source>
+ <translation>リストモード</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>総額</translation>
+ </message>
+ <message>
+ <source>Received with label</source>
+ <translation>ラベルに対する入金一覧</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>アドレスに対する入金一覧</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>日付</translation>
+ </message>
+ <message>
+ <source>Confirmations</source>
+ <translation>検証数</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>検証済み</translation>
+ </message>
+ <message>
+ <source>Priority</source>
+ <translation>優先度</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>アドレスをコピーする</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>ラベルをコピーする</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>総額のコピー</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>取引 ID をコピー</translation>
+ </message>
+ <message>
+ <source>Lock unspent</source>
+ <translation>未使用トランザクションをロックする</translation>
+ </message>
+ <message>
+ <source>Unlock unspent</source>
+ <translation>未使用トランザクションをアンロックする</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>数量をコピーする</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>手数料をコピーする</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>手数料差引後の値をコピーする</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>バイト数をコピーする</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>優先度をコピーする</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>ダストをコピーする</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>釣り銭をコピー</translation>
+ </message>
+ <message>
+ <source>highest</source>
+ <translation>最高</translation>
+ </message>
+ <message>
+ <source>higher</source>
+ <translation>非常に高</translation>
+ </message>
+ <message>
+ <source>high</source>
+ <translation>高</translation>
+ </message>
+ <message>
+ <source>medium-high</source>
+ <translation>中〜高</translation>
+ </message>
+ <message>
+ <source>medium</source>
+ <translation>中</translation>
+ </message>
+ <message>
+ <source>low-medium</source>
+ <translation>低〜中</translation>
+ </message>
+ <message>
+ <source>low</source>
+ <translation>低</translation>
+ </message>
+ <message>
+ <source>lower</source>
+ <translation>非常に低</translation>
+ </message>
+ <message>
+ <source>lowest</source>
+ <translation>最低</translation>
+ </message>
+ <message>
+ <source>(%1 locked)</source>
+ <translation>(%1 がロック済み)</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>なし</translation>
+ </message>
+ <message>
+ <source>This label turns red if the transaction size is greater than 1000 bytes.</source>
+ <translation>トランザクションのサイズが1000バイトを超える場合にはこのラベルは赤色になります。</translation>
+ </message>
+ <message>
+ <source>This label turns red if the priority is smaller than "medium".</source>
+ <translation>優先度が「中」未満の場合、このラベルは赤色になります。</translation>
+ </message>
+ <message>
+ <source>This label turns red if any recipient receives an amount smaller than %1.</source>
+ <translation>受取人のうち誰かの受取額が %1 未満の場合にこのラベルは赤色になります。</translation>
+ </message>
+ <message>
+ <source>Can vary +/- %1 satoshi(s) per input.</source>
+ <translation>ひとつの入力につき %1 satoshi 前後ずれることがあります。</translation>
+ </message>
+ <message>
+ <source>yes</source>
+ <translation>はい</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>いいえ</translation>
+ </message>
+ <message>
+ <source>This means a fee of at least %1 per kB is required.</source>
+ <translation>これは少なくとも1kBあたり %1 の手数料が必要であることを意味します。</translation>
+ </message>
+ <message>
+ <source>Can vary +/- 1 byte per input.</source>
+ <translation>ひとつの入力につき1バイト程度ずれることがあります。</translation>
+ </message>
+ <message>
+ <source>Transactions with higher priority are more likely to get included into a block.</source>
+ <translation>より高い優先度を持つトランザクションの方がブロックに取り込まれやすくなります。</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(ラベル無し)</translation>
+ </message>
+ <message>
+ <source>change from %1 (%2)</source>
+ <translation>%1 (%2) からのおつり</translation>
+ </message>
+ <message>
+ <source>(change)</source>
+ <translation>(おつり)</translation>
+ </message>
+</context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>アドレスの編集</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>ラベル(&amp;L)</translation>
+ </message>
+ <message>
+ <source>The label associated with this address list entry</source>
+ <translation>このアドレス帳項目に結びつけられているラベル</translation>
+ </message>
+ <message>
+ <source>The address associated with this address list entry. This can only be modified for sending addresses.</source>
+ <translation>このアドレス帳項目に結びつけられているアドレス。この項目は送金用アドレスの場合のみ編集することができます。</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>アドレス帳 (&amp;A)</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>新しい受信アドレス</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>新しい送信アドレス</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>受信アドレスを編集</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>送信アドレスを編集</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>入力されたアドレス "%1" は既にアドレス帳にあります。</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is not a valid Bitcoin address.</source>
+ <translation>入力されたアドレス "%1" は無効な Bitcoin アドレスです。</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>ウォレットをアンロックできませんでした。</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>新しいキーの生成に失敗しました。</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ <message>
+ <source>A new data directory will be created.</source>
+ <translation>新しいデータ ディレクトリが作成されます。</translation>
+ </message>
+ <message>
+ <source>name</source>
+ <translation>name</translation>
+ </message>
+ <message>
+ <source>Directory already exists. Add %1 if you intend to create a new directory here.</source>
+ <translation>ディレクトリがもうあります。 新しいのディレクトリを作るつもりなら%1を書いてください。</translation>
+ </message>
+ <message>
+ <source>Path already exists, and is not a directory.</source>
+ <translation>パスが存在しますがディレクトリではありません。</translation>
+ </message>
+ <message>
+ <source>Cannot create data directory here.</source>
+ <translation>ここにデータ ディレクトリを作成することはできません。</translation>
+ </message>
+</context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin のコア</translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>バージョン</translation>
+ </message>
+ <message>
+ <source>(%1-bit)</source>
+ <translation>(%1ビット)</translation>
+ </message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>Bitcoinコアについて</translation>
+ </message>
+ <message>
+ <source>Command-line options</source>
+ <translation>コマンドライン オプション</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>使用法:</translation>
+ </message>
+ <message>
+ <source>command-line options</source>
+ <translation>コマンドライン オプション</translation>
+ </message>
+</context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Welcome</source>
+ <translation>ようこそ</translation>
+ </message>
+ <message>
+ <source>Welcome to Bitcoin Core.</source>
+ <translation>ようこそ!</translation>
+ </message>
+ <message>
+ <source>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</source>
+ <translation>これはプログラム最初の起動です。Bitcoin Coreがデータを保存する場所を選択して下さい。</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory.</source>
+ <translation>Bitcoin Coreは、ビットコインのブロックチェーンのコピーを、ダウンロードして保存します。少なくとも%1ギガバイトのデータが、このディレクトリに保存されます。そしてそれは時間と共に増加します。またウォレットもこのディレクトリに保存されます。</translation>
+ </message>
+ <message>
+ <source>Use the default data directory</source>
+ <translation>初期値のデータ ディレクトリを使用</translation>
+ </message>
+ <message>
+ <source>Use a custom data directory:</source>
+ <translation>任意のデータ ディレクトリを使用:</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin のコア</translation>
+ </message>
+ <message>
+ <source>Error: Specified data directory "%1" cannot be created.</source>
+ <translation>エラー: 指定のデータディレクトリ "%1" を作成できません。</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>エラー</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n GB of free space available</source>
+ <translation><numerusform>%n GBの空き容量が利用可能</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>(of %n GB needed)</source>
+ <translation><numerusform>(%n GB必要)</numerusform></translation>
+ </message>
+</context>
+<context>
+ <name>OpenURIDialog</name>
+ <message>
+ <source>Open URI</source>
+ <translation>URI を開く</translation>
+ </message>
+ <message>
+ <source>Open payment request from URI or file</source>
+ <translation>URI またはファイルから支払いリクエストを開く</translation>
+ </message>
+ <message>
+ <source>URI:</source>
+ <translation>URI:</translation>
+ </message>
+ <message>
+ <source>Select payment request file</source>
+ <translation>支払いリクエストファイルを選択してください</translation>
+ </message>
+ <message>
+ <source>Select payment request file to open</source>
+ <translation>開きたい支払いリクエストファイルを選択してください</translation>
+ </message>
+</context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>設定</translation>
+ </message>
+ <message>
+ <source>&amp;Main</source>
+ <translation>メイン (&amp;M)</translation>
+ </message>
+ <message>
+ <source>Size of &amp;database cache</source>
+ <translation>データベースキャッシュのサイズ (&amp;D)</translation>
+ </message>
+ <message>
+ <source>MB</source>
+ <translation>MB</translation>
+ </message>
+ <message>
+ <source>Number of script &amp;verification threads</source>
+ <translation>スクリプト検証用スレッド数 (&amp;V)</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside</source>
+ <translation>外部からの接続を許可する</translation>
+ </message>
+ <message>
+ <source>Allow incoming connections</source>
+ <translation>外部からの接続を許可する</translation>
+ </message>
+ <message>
+ <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
+ <translation>プロキシのIPアドレス (例えば IPv4: 127.0.0.1 / IPv6: ::1)</translation>
+ </message>
+ <message>
+ <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source>
+ <translation>ウィンドウを閉じる際にアプリケーションを終了するのではなく、最小化します。このオプションが有効化された場合、メニューから終了を選択した場合にのみアプリケーションは閉じられます。</translation>
+ </message>
+ <message>
+ <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source>
+ <translation>ユーザ・インタフェイス言語はここで設定できます。この設定はBitcoin Coreの再起動後に有効となります。</translation>
+ </message>
+ <message>
+ <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source>
+ <translation>トランザクションタブのコンテキストメニュー項目に表示する、サードパーティURL (例えばブロックエクスプローラ)。URL中の%sはトランザクションのハッシュ値に置き換えられます。垂直バー | で区切ることで、複数のURLを指定できます。</translation>
+ </message>
+ <message>
+ <source>Third party transaction URLs</source>
+ <translation>サードパーティのトランザクションURL</translation>
+ </message>
+ <message>
+ <source>Active command-line options that override above options:</source>
+ <translation>上のオプションを置き換えることのできる、有効なコマンドラインオプションの一覧:</translation>
+ </message>
+ <message>
+ <source>Reset all client options to default.</source>
+ <translation>すべてのオプションを初期値に戻します。</translation>
+ </message>
+ <message>
+ <source>&amp;Reset Options</source>
+ <translation>オプションをリセット (&amp;R)</translation>
+ </message>
+ <message>
+ <source>&amp;Network</source>
+ <translation>ネットワーク (&amp;N)</translation>
+ </message>
+ <message>
+ <source>Automatically start Bitcoin Core after logging in to the system.</source>
+ <translation>システムにログインした際、自動的にBitcoin Coreを起動する。</translation>
+ </message>
+ <message>
+ <source>&amp;Start Bitcoin Core on system login</source>
+ <translation>システムへログインした際にBitcoin Coreを起動する (&amp;S)</translation>
+ </message>
+ <message>
+ <source>(0 = auto, &lt;0 = leave that many cores free)</source>
+ <translation>(0 = 自動、0以上 = 指定した数のコアをフリーにする)</translation>
+ </message>
+ <message>
+ <source>W&amp;allet</source>
+ <translation>ウォレット (&amp;A)</translation>
+ </message>
+ <message>
+ <source>Expert</source>
+ <translation>エクスポート</translation>
+ </message>
+ <message>
+ <source>Enable coin &amp;control features</source>
+ <translation>コインコントロール機能を有効化する (&amp;C)</translation>
+ </message>
+ <message>
+ <source>If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.</source>
+ <translation>未検証のおつりの使用を無効化すると、トランザクションが少なくとも1検証を獲得するまではそのトランザクションのおつりは利用できなくなります。これは残高の計算方法にも影響します。</translation>
+ </message>
+ <message>
+ <source>&amp;Spend unconfirmed change</source>
+ <translation>未検証のおつりを使用する (&amp;S)</translation>
+ </message>
+ <message>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>自動的にルーター上の Bitcoin クライアントのポートを開きます。あなたのルーターが UPnP に対応していて、それが有効になっている場合に作動します。</translation>
+ </message>
+ <message>
+ <source>Map port using &amp;UPnP</source>
+ <translation>UPnP を使ってポートを割り当てる (&amp;U)</translation>
+ </message>
+ <message>
+ <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
+ <translation>SOCKS5 プロキシ経由でBitcoinネットワークに接続する</translation>
+ </message>
+ <message>
+ <source>&amp;Connect through SOCKS5 proxy (default proxy):</source>
+ <translation>SOCKS5 プロキシ経由で接続する (デフォルトプロキシ): (&amp;C)</translation>
+ </message>
+ <message>
+ <source>Proxy &amp;IP:</source>
+ <translation>プロキシの IP (&amp;I) :</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>ポート (&amp;P) :</translation>
+ </message>
+ <message>
+ <source>Port of the proxy (e.g. 9050)</source>
+ <translation>プロキシのポート番号 (例 9050)</translation>
+ </message>
+ <message>
+ <source>&amp;Window</source>
+ <translation>ウインドウ (&amp;W)</translation>
+ </message>
+ <message>
+ <source>Show only a tray icon after minimizing the window.</source>
+ <translation>ウインドウを最小化したあとトレイ アイコンだけを表示する。</translation>
+ </message>
+ <message>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>タスクバーの代わりにトレイに最小化 (&amp;M)</translation>
+ </message>
+ <message>
+ <source>M&amp;inimize on close</source>
+ <translation>閉じる時に最小化 (&amp;i)</translation>
+ </message>
+ <message>
+ <source>&amp;Display</source>
+ <translation>表示 (&amp;D)</translation>
+ </message>
+ <message>
+ <source>User Interface &amp;language:</source>
+ <translation>ユーザインターフェースの言語 (&amp;l) :</translation>
+ </message>
+ <message>
+ <source>&amp;Unit to show amounts in:</source>
+ <translation>額を表示する単位 (&amp;U) :</translation>
+ </message>
+ <message>
+ <source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
+ <translation>インターフェース上の表示とコインの送信で使用する単位を選択します。</translation>
+ </message>
+ <message>
+ <source>Whether to show coin control features or not.</source>
+ <translation>コインコントロール機能を表示するかどうか。</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>&amp;OK</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>キャンセル (&amp;C)</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>初期値</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>なし</translation>
+ </message>
+ <message>
+ <source>Confirm options reset</source>
+ <translation>オプションのリセットの確認</translation>
+ </message>
+ <message>
+ <source>Client restart required to activate changes.</source>
+ <translation>変更を有効化するにはクライアントを再起動する必要があります。</translation>
+ </message>
+ <message>
+ <source>Client will be shut down. Do you want to proceed?</source>
+ <translation>クライアントを終了します。続行してもよろしいですか?</translation>
+ </message>
+ <message>
+ <source>This change would require a client restart.</source>
+ <translation>この変更はクライアントの再起動が必要です。</translation>
+ </message>
+ <message>
+ <source>The supplied proxy address is invalid.</source>
+ <translation>プロキシアドレスが無効です。</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>フォーム</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>表示された情報は古いかもしれません。接続が確立されると、あなたのウォレットは Bitcoin ネットワークと自動的に同期しますが、このプロセスはまだ完了していません。</translation>
+ </message>
+ <message>
+ <source>Watch-only:</source>
+ <translation>監視限定:</translation>
+ </message>
+ <message>
+ <source>Available:</source>
+ <translation>利用可能:</translation>
+ </message>
+ <message>
+ <source>Your current spendable balance</source>
+ <translation>あなたの利用可能残高</translation>
+ </message>
+ <message>
+ <source>Pending:</source>
+ <translation>検証待ち:</translation>
+ </message>
+ <message>
+ <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source>
+ <translation>未検証の取引で利用可能残高に反映されていない数</translation>
+ </message>
+ <message>
+ <source>Immature:</source>
+ <translation>未完成:</translation>
+ </message>
+ <message>
+ <source>Mined balance that has not yet matured</source>
+ <translation>完成していない採掘された残高</translation>
+ </message>
+ <message>
+ <source>Balances</source>
+ <translation>残高</translation>
+ </message>
+ <message>
+ <source>Total:</source>
+ <translation>合計:</translation>
+ </message>
+ <message>
+ <source>Your current total balance</source>
+ <translation>あなたの現在の残高</translation>
+ </message>
+ <message>
+ <source>Your current balance in watch-only addresses</source>
+ <translation>監視限定アドレス内の現在の残高</translation>
+ </message>
+ <message>
+ <source>Spendable:</source>
+ <translation>使用可能:</translation>
+ </message>
+ <message>
+ <source>Recent transactions</source>
+ <translation>最近のトランザクション</translation>
+ </message>
+ <message>
+ <source>Unconfirmed transactions to watch-only addresses</source>
+ <translation>監視限定アドレスに対する未検証のトランザクション</translation>
+ </message>
+ <message>
+ <source>Mined balance in watch-only addresses that has not yet matured</source>
+ <translation>ウォッチオンリーアドレスの採掘された残高のうち、成熟していないもの</translation>
+ </message>
+ <message>
+ <source>Current total balance in watch-only addresses</source>
+ <translation>監視限定アドレス内の現在の全残高</translation>
+ </message>
+</context>
+<context>
+ <name>PaymentServer</name>
+ <message>
+ <source>URI handling</source>
+ <translation>URI の操作</translation>
+ </message>
+ <message>
+ <source>Invalid payment address %1</source>
+ <translation>支払いのアドレス「%1」は無効です</translation>
+ </message>
+ <message>
+ <source>Payment request rejected</source>
+ <translation>支払い要求は拒否されました</translation>
+ </message>
+ <message>
+ <source>Payment request network doesn't match client network.</source>
+ <translation>支払いリクエストのネットワークは現在のクライアントのネットワークに一致しません。</translation>
+ </message>
+ <message>
+ <source>Payment request is not initialized.</source>
+ <translation>支払いリクエストは開始されていません。</translation>
+ </message>
+ <message>
+ <source>Requested payment amount of %1 is too small (considered dust).</source>
+ <translation>要求された支払額 %1 は少なすぎます (ダストとみなされてしまいます)。</translation>
+ </message>
+ <message>
+ <source>Payment request error</source>
+ <translation>支払いのリクエストのエラーです</translation>
+ </message>
+ <message>
+ <source>Cannot start bitcoin: click-to-pay handler</source>
+ <translation>Bitcoin を起動できません: click-to-pay handler</translation>
+ </message>
+ <message>
+ <source>Payment request fetch URL is invalid: %1</source>
+ <translation>支払い要求の取得先URLが無効です: %1</translation>
+ </message>
+ <message>
+ <source>URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source>
+ <translation>URI を解析できません! これは無効な Bitcoin アドレスあるいや不正な形式の URI パラメーターによって引き起こされる場合があります。</translation>
+ </message>
+ <message>
+ <source>Payment request file handling</source>
+ <translation>支払いリクエストファイルを処理しています</translation>
+ </message>
+ <message>
+ <source>Payment request file cannot be read! This can be caused by an invalid payment request file.</source>
+ <translation>支払いリクエストファイルを読み込めませんでした!無効な支払いリクエストファイルにより引き起こされた可能性があります。</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>支払いリクエストの期限が切れました。</translation>
+ </message>
+ <message>
+ <source>Unverified payment requests to custom payment scripts are unsupported.</source>
+ <translation>カスタム支払いスクリプトに対する、検証されていない支払いリクエストはサポートされていません。</translation>
+ </message>
+ <message>
+ <source>Invalid payment request.</source>
+ <translation>無効な支払いリクエスト。</translation>
+ </message>
+ <message>
+ <source>Refund from %1</source>
+ <translation>%1 からの返金</translation>
+ </message>
+ <message>
+ <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source>
+ <translation>支払リクエスト %1 は大きすぎます(%2バイトですが、%3バイトまでが許されています)。</translation>
+ </message>
+ <message>
+ <source>Payment request DoS protection</source>
+ <translation>支払リクエストDoS保護</translation>
+ </message>
+ <message>
+ <source>Error communicating with %1: %2</source>
+ <translation>%1: %2とコミュニケーション・エラーです</translation>
+ </message>
+ <message>
+ <source>Payment request cannot be parsed!</source>
+ <translation>支払リクエストを読み込めませんでした!</translation>
+ </message>
+ <message>
+ <source>Bad response from server %1</source>
+ <translation>サーバーの返事は無効 %1</translation>
+ </message>
+ <message>
+ <source>Payment acknowledged</source>
+ <translation>支払いは確認しました</translation>
+ </message>
+ <message>
+ <source>Network request error</source>
+ <translation>ネットワーク・リクエストのエラーです</translation>
+ </message>
+</context>
+<context>
+ <name>PeerTableModel</name>
+ <message>
+ <source>User Agent</source>
+ <translation>ユーザエージェント</translation>
+ </message>
+ <message>
+ <source>Node/Service</source>
+ <translation>ノード・サービス</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Ping時間</translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>総額</translation>
+ </message>
+ <message>
+ <source>Enter a Bitcoin address (e.g. %1)</source>
+ <translation>Bitcoinアドレスを入力してください (例 %1)</translation>
+ </message>
+ <message>
+ <source>%1 d</source>
+ <translation>%1日</translation>
+ </message>
+ <message>
+ <source>%1 h</source>
+ <translation>%1 h</translation>
+ </message>
+ <message>
+ <source>%1 m</source>
+ <translation>%1 m</translation>
+ </message>
+ <message>
+ <source>%1 s</source>
+ <translation>%1秒</translation>
+ </message>
+ <message>
+ <source>None</source>
+ <translation>なし</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>N/A</translation>
+ </message>
+ <message>
+ <source>%1 ms</source>
+ <translation>%1ミリ秒</translation>
+ </message>
+</context>
+<context>
+ <name>QRImageWidget</name>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>画像を保存(&amp;S)</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Image</source>
+ <translation>画像をコピー(&amp;C)</translation>
+ </message>
+ <message>
+ <source>Save QR Code</source>
+ <translation>QR コードの保存</translation>
+ </message>
+ <message>
+ <source>PNG Image (*.png)</source>
+ <translation>PNG画像ファイル(*.png)</translation>
+ </message>
+</context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>Client name</source>
+ <translation>クライアント名</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>N/A</translation>
+ </message>
+ <message>
+ <source>Client version</source>
+ <translation>クライアントのバージョン</translation>
+ </message>
+ <message>
+ <source>&amp;Information</source>
+ <translation>情報 (&amp;I)</translation>
+ </message>
+ <message>
+ <source>Debug window</source>
+ <translation>デバッグ ウインドウ</translation>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>一般</translation>
+ </message>
+ <message>
+ <source>Using OpenSSL version</source>
+ <translation>使用中の OpenSSL のバージョン</translation>
+ </message>
+ <message>
+ <source>Using BerkeleyDB version</source>
+ <translation>使用中のBerkleyDBバージョン</translation>
+ </message>
+ <message>
+ <source>Startup time</source>
+ <translation>起動した日時</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>ネットワーク</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>名前</translation>
+ </message>
+ <message>
+ <source>Number of connections</source>
+ <translation>接続数</translation>
+ </message>
+ <message>
+ <source>Block chain</source>
+ <translation>ブロック チェーン</translation>
+ </message>
+ <message>
+ <source>Current number of blocks</source>
+ <translation>現在のブロック数</translation>
+ </message>
+ <message>
+ <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source>
+ <translation>現在のデータディレクトリからBitcoin Coreのデバッグ用ログファイルを開きます。ログファイルが巨大な場合、数秒かかることがあります。</translation>
+ </message>
+ <message>
+ <source>Received</source>
+ <translation>受取</translation>
+ </message>
+ <message>
+ <source>Sent</source>
+ <translation>送金</translation>
+ </message>
+ <message>
+ <source>&amp;Peers</source>
+ <translation>ピア (&amp;P)</translation>
+ </message>
+ <message>
+ <source>Select a peer to view detailed information.</source>
+ <translation>詳しい情報を見たいピアを選択してください。</translation>
+ </message>
+ <message>
+ <source>Direction</source>
+ <translation>方向</translation>
+ </message>
+ <message>
+ <source>Version</source>
+ <translation>バージョン</translation>
+ </message>
+ <message>
+ <source>User Agent</source>
+ <translation>ユーザエージェント</translation>
+ </message>
+ <message>
+ <source>Services</source>
+ <translation>サービス</translation>
+ </message>
+ <message>
+ <source>Starting Height</source>
+ <translation>開始時のブロック高</translation>
+ </message>
+ <message>
+ <source>Sync Height</source>
+ <translation>同期済みブロック高</translation>
+ </message>
+ <message>
+ <source>Ban Score</source>
+ <translation>Banスコア</translation>
+ </message>
+ <message>
+ <source>Connection Time</source>
+ <translation>接続時間</translation>
+ </message>
+ <message>
+ <source>Last Send</source>
+ <translation>最終送信</translation>
+ </message>
+ <message>
+ <source>Last Receive</source>
+ <translation>最終受信</translation>
+ </message>
+ <message>
+ <source>Bytes Sent</source>
+ <translation>送信済バイト数</translation>
+ </message>
+ <message>
+ <source>Bytes Received</source>
+ <translation>受信済バイト数</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Ping時間</translation>
+ </message>
+ <message>
+ <source>Time Offset</source>
+ <translation>時間オフセット</translation>
+ </message>
+ <message>
+ <source>Last block time</source>
+ <translation>最終ブロックの日時</translation>
+ </message>
+ <message>
+ <source>&amp;Open</source>
+ <translation>開く (&amp;O)</translation>
+ </message>
+ <message>
+ <source>&amp;Console</source>
+ <translation>コンソール (&amp;C)</translation>
+ </message>
+ <message>
+ <source>&amp;Network Traffic</source>
+ <translation>ネットワーク (&amp;N)</translation>
+ </message>
+ <message>
+ <source>&amp;Clear</source>
+ <translation>クリア(&amp;C)</translation>
+ </message>
+ <message>
+ <source>Totals</source>
+ <translation>合計</translation>
+ </message>
+ <message>
+ <source>In:</source>
+ <translation>入力:</translation>
+ </message>
+ <message>
+ <source>Out:</source>
+ <translation>出力:</translation>
+ </message>
+ <message>
+ <source>Build date</source>
+ <translation>ビルドの日付</translation>
+ </message>
+ <message>
+ <source>Debug log file</source>
+ <translation>デバッグ用ログファイル</translation>
+ </message>
+ <message>
+ <source>Clear console</source>
+ <translation>コンソールをクリア</translation>
+ </message>
+ <message>
+ <source>Welcome to the Bitcoin Core RPC console.</source>
+ <translation>Bitcoin CoreのRPCコンソールへようこそ。</translation>
+ </message>
+ <message>
+ <source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
+ <translation>上下の矢印で履歴をたどれます。 &lt;b&gt;Ctrl-L&lt;/b&gt; でスクリーンを消去できます。</translation>
+ </message>
+ <message>
+ <source>Type &lt;b&gt;help&lt;/b&gt; for an overview of available commands.</source>
+ <translation>使用可能なコマンドを見るには &lt;b&gt;help&lt;/b&gt; と入力します。</translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation>%1 B</translation>
+ </message>
+ <message>
+ <source>%1 KB</source>
+ <translation>%1 KB</translation>
+ </message>
+ <message>
+ <source>%1 MB</source>
+ <translation>%1 MB</translation>
+ </message>
+ <message>
+ <source>%1 GB</source>
+ <translation>%1 GB</translation>
+ </message>
+ <message>
+ <source>via %1</source>
+ <translation>%1経由</translation>
+ </message>
+ <message>
+ <source>never</source>
+ <translation>一度もなし</translation>
+ </message>
+ <message>
+ <source>Inbound</source>
+ <translation>内向き</translation>
+ </message>
+ <message>
+ <source>Outbound</source>
+ <translation>外向き</translation>
+ </message>
+ <message>
+ <source>Unknown</source>
+ <translation>未知</translation>
+ </message>
+ <message>
+ <source>Fetching...</source>
+ <translation>取得中……</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Amount:</source>
+ <translation>総額:(&amp;A)</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>ラベル(&amp;L):</translation>
+ </message>
+ <message>
+ <source>&amp;Message:</source>
+ <translation>メッセージ (&amp;M):</translation>
+ </message>
+ <message>
+ <source>Reuse one of the previously used receiving addresses. Reusing addresses has security and privacy issues. Do not use this unless re-generating a payment request made before.</source>
+ <translation>以前利用した受取用アドレスのどれかを再利用します。アドレスの再利用はセキュリティおよびプライバシーにおいて問題があります。以前作成した支払リクエストを再生成するとき以外は利用しないでください。</translation>
+ </message>
+ <message>
+ <source>R&amp;euse an existing receiving address (not recommended)</source>
+ <translation>既存の受取用アドレスを再利用する (非推奨) (&amp;E)</translation>
+ </message>
+ <message>
+ <source>An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network.</source>
+ <translation>支払リクエストが開始された時に表示される、支払リクエストに添える任意のメッセージです。注意:メッセージはBitcoinネットワークを通じて、支払と共に送られるわけではありません。</translation>
+ </message>
+ <message>
+ <source>An optional label to associate with the new receiving address.</source>
+ <translation>受取用アドレスに紐づく任意のラベル。</translation>
+ </message>
+ <message>
+ <source>Use this form to request payments. All fields are &lt;b&gt;optional&lt;/b&gt;.</source>
+ <translation>このフォームを使用して支払のリクエストを行いましょう。すべての項目は&lt;b&gt;任意入力&lt;/b&gt;です。</translation>
+ </message>
+ <message>
+ <source>An optional amount to request. Leave this empty or zero to not request a specific amount.</source>
+ <translation>リクエストする任意の金額。特定の金額をリクエストするのでない場合には、この欄は空白のままかゼロにしてください。</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>全ての入力項目をクリア</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation>クリア</translation>
+ </message>
+ <message>
+ <source>Requested payments history</source>
+ <translation>支払リクエスト履歴</translation>
+ </message>
+ <message>
+ <source>&amp;Request payment</source>
+ <translation>支払をリクエストする (&amp;R)</translation>
+ </message>
+ <message>
+ <source>Show the selected request (does the same as double clicking an entry)</source>
+ <translation>選択されたリクエストを表示する(項目をダブルクリックすることでも表示できます)</translation>
+ </message>
+ <message>
+ <source>Show</source>
+ <translation>表示</translation>
+ </message>
+ <message>
+ <source>Remove the selected entries from the list</source>
+ <translation>リストから選択項目を削除</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>削除</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>ラベルをコピーする</translation>
+ </message>
+ <message>
+ <source>Copy message</source>
+ <translation>メッセージをコピーする</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>総額のコピー</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>QR Code</source>
+ <translation>QR コード</translation>
+ </message>
+ <message>
+ <source>Copy &amp;URI</source>
+ <translation>URI をコピーする (&amp;U)</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Address</source>
+ <translation>アドレスをコピーする (&amp;A)</translation>
+ </message>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>画像を保存(&amp;S)</translation>
+ </message>
+ <message>
+ <source>Request payment to %1</source>
+ <translation>%1 への支払いリクエストを行う</translation>
+ </message>
+ <message>
+ <source>Payment information</source>
+ <translation>支払い情報</translation>
+ </message>
+ <message>
+ <source>URI</source>
+ <translation>URI</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>アドレス</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>総額</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>ラベル</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>メッセージ</translation>
+ </message>
+ <message>
+ <source>Resulting URI too long, try to reduce the text for label / message.</source>
+ <translation>URI が長くなり過ぎます。ラベルやメッセージのテキストを短くしてください。</translation>
+ </message>
+ <message>
+ <source>Error encoding URI into QR Code.</source>
+ <translation>QR コード用の URI エンコードでエラー。</translation>
+ </message>
+</context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>日付</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>ラベル</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>メッセージ</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>総額</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(ラベル無し)</translation>
+ </message>
+ <message>
+ <source>(no message)</source>
+ <translation>(メッセージなし)</translation>
+ </message>
+ <message>
+ <source>(no amount)</source>
+ <translation>(金額なし)</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>コインを送る</translation>
+ </message>
+ <message>
+ <source>Coin Control Features</source>
+ <translation>コインコントロール機能</translation>
+ </message>
+ <message>
+ <source>Inputs...</source>
+ <translation>入力...</translation>
+ </message>
+ <message>
+ <source>automatically selected</source>
+ <translation>自動選択</translation>
+ </message>
+ <message>
+ <source>Insufficient funds!</source>
+ <translation>残高不足です!</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>数量:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>バイト:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>総額:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>優先度:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>手数料:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>手数料差引後:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>釣り銭:</translation>
+ </message>
+ <message>
+ <source>If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address.</source>
+ <translation>これが有効にもかかわらずおつりアドレスが空欄であったり無効であった場合には、おつりは新しく生成されたアドレスへ送金されます。</translation>
+ </message>
+ <message>
+ <source>Custom change address</source>
+ <translation>カスタムおつりアドレス</translation>
+ </message>
+ <message>
+ <source>Transaction Fee:</source>
+ <translation>トランザクション手数料:</translation>
+ </message>
+ <message>
+ <source>Choose...</source>
+ <translation>選択……</translation>
+ </message>
+ <message>
+ <source>collapse fee-settings</source>
+ <translation>手数料設定を折りたたむ</translation>
+ </message>
+ <message>
+ <source>per kilobyte</source>
+ <translation>1キロバイトあたり手数料</translation>
+ </message>
+ <message>
+ <source>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "total at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source>
+ <translation>カスタム手数料が1000satoshiに設定されている場合、トランザクションサイズが250バイトとすると、「1キロバイトあたり手数料」では250satoshiの手数料のみを支払いますが、「最小手数料」では1000satoshiを支払います。1キロバイトを超えるトランザクションの場合には、どちらの方法を選択したとしても1キロバイトあたりで支払われます。</translation>
+ </message>
+ <message>
+ <source>Hide</source>
+ <translation>隠す</translation>
+ </message>
+ <message>
+ <source>total at least</source>
+ <translation>最小手数料</translation>
+ </message>
+ <message>
+ <source>Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process.</source>
+ <translation>ブロックの容量に比べてトランザクション流量が少ないうちは最小手数料のみの支払で十分です。しかしながらネットワークが処理しきれないほどbitcoinトランザクションの需要がひとたび生まれてしまった場合には、永遠に検証がされないトランザクションになってしまう可能性があることに注意してください。</translation>
+ </message>
+ <message>
+ <source>(read the tooltip)</source>
+ <translation>(ツールチップをお読みください)</translation>
+ </message>
+ <message>
+ <source>Recommended:</source>
+ <translation>推奨:</translation>
+ </message>
+ <message>
+ <source>Custom:</source>
+ <translation>カスタム:</translation>
+ </message>
+ <message>
+ <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source>
+ <translation>(スマート手数料はまだ初期化されていません。これにはおおよそ数ブロックほどかかります……)</translation>
+ </message>
+ <message>
+ <source>Confirmation time:</source>
+ <translation>検証時間:</translation>
+ </message>
+ <message>
+ <source>normal</source>
+ <translation>普通</translation>
+ </message>
+ <message>
+ <source>fast</source>
+ <translation>高速</translation>
+ </message>
+ <message>
+ <source>Send as zero-fee transaction if possible</source>
+ <translation>可能な場合には手数料ゼロのトランザクションとして送金する</translation>
+ </message>
+ <message>
+ <source>(confirmation may take longer)</source>
+ <translation>(検証に長い時間がかかる可能性があります)</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>一度に複数の人に送る</translation>
+ </message>
+ <message>
+ <source>Add &amp;Recipient</source>
+ <translation>受取人を追加 (&amp;R)</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>全ての入力項目をクリア</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>ダスト:</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>すべてクリア (&amp;A)</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>残高:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>送る操作を確認する</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>送る (&amp;e)</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>コインを送る確認</translation>
+ </message>
+ <message>
+ <source>%1 to %2</source>
+ <translation>%1 から %2</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>数量をコピーする</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>総額のコピー</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>手数料をコピーする</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>手数料差引後の値をコピーする</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>バイト数をコピーする</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>優先度をコピーする</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>釣り銭をコピー</translation>
+ </message>
+ <message>
+ <source>or</source>
+ <translation>または</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>支払額は0より大きくないといけません。</translation>
+ </message>
+ <message>
+ <source>The amount exceeds your balance.</source>
+ <translation>額が残高を超えています。</translation>
+ </message>
+ <message>
+ <source>The total exceeds your balance when the %1 transaction fee is included.</source>
+ <translation>%1 の取引手数料を含めると額が残高を超えています。</translation>
+ </message>
+ <message>
+ <source>Transaction creation failed!</source>
+ <translation>トラザクションの作成に失敗しました!</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>トランザクションは拒否されました。wallet.dat のコピーを使い、そしてコピーしたウォレットからコインを使用したことがマークされなかったときなど、ウォレットのいくつかのコインがすでに使用されている場合に、このエラーは起こるかもしれません。</translation>
+ </message>
+ <message>
+ <source>A fee higher than %1 is considered an absurdly high fee.</source>
+ <translation>%1 よりも高い手数料の場合、手数料が高すぎると判断されます。</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>支払いリクエストの期限が切れました。</translation>
+ </message>
+ <message numerus="yes">
+ <source>Estimated to begin confirmation within %n block(s).</source>
+ <translation><numerusform>%n ブロック以内に検証が開始されると予想されます。</numerusform></translation>
+ </message>
+ <message>
+ <source>Pay only the minimum fee of %1</source>
+ <translation>最小手数料 %1 のみを支払う</translation>
+ </message>
+ <message>
+ <source>Total Amount %1&lt;span style='font-size:10pt;font-weight:normal;'&gt;&lt;br /&gt;(=%2)&lt;/span&gt;</source>
+ <translation>総額 %1&lt;span style='font-size:10pt;font-weight:normal;'&gt;&lt;br /&gt;(=%2)&lt;/span&gt;</translation>
+ </message>
+ <message>
+ <source>The recipient address is not valid. Please recheck.</source>
+ <translation>受取アドレスが不正です。再チェックしてください。</translation>
+ </message>
+ <message>
+ <source>Duplicate address found: addresses should only be used once each.</source>
+ <translation>重複したアドレスが見つかりました: アドレスはそれぞれ一度のみ使用することができます。</translation>
+ </message>
+ <message>
+ <source>Warning: Invalid Bitcoin address</source>
+ <translation>警告:無効なBitcoinアドレスです</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(ラベル無し)</translation>
+ </message>
+ <message>
+ <source>Warning: Unknown change address</source>
+ <translation>警告:未知のおつりアドレスです</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>ダストをコピーする</translation>
+ </message>
+ <message>
+ <source>Are you sure you want to send?</source>
+ <translation>送ってよろしいですか?</translation>
+ </message>
+ <message>
+ <source>added as transaction fee</source>
+ <translation>取引手数料として追加された</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>金額(&amp;A):</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>送り先(&amp;T):</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>アドレス帳に追加するには、このアドレスのラベルを入力します</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>ラベル(&amp;L):</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>前に使用したアドレスを選ぶ</translation>
+ </message>
+ <message>
+ <source>This is a normal payment.</source>
+ <translation>これは通常の支払です。</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to send the payment to</source>
+ <translation>支払の送金先Bitcoinアドレス</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>クリップボードからアドレスを貼付ける</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Remove this entry</source>
+ <translation>この項目を削除する</translation>
+ </message>
+ <message>
+ <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source>
+ <translation>送金する金額から手数料が差し引かれます。受取人は数量フィールドで指定した量よりも少ないビットコインを受け取ります。受取人が複数いる場合には、手数料は均等割されます。</translation>
+ </message>
+ <message>
+ <source>S&amp;ubtract fee from amount</source>
+ <translation>送金額から手数料を差し引く (&amp;U)</translation>
+ </message>
+ <message>
+ <source>Message:</source>
+ <translation>メッセージ:</translation>
+ </message>
+ <message>
+ <source>This is an unauthenticated payment request.</source>
+ <translation>これは未認証の支払いリクエストです。</translation>
+ </message>
+ <message>
+ <source>This is an authenticated payment request.</source>
+ <translation>これは認証済みの支払いリクエストです。</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to the list of used addresses</source>
+ <translation>このアドレスに対するラベルを入力することで、使用済みアドレスの一覧に追加することができます</translation>
+ </message>
+ <message>
+ <source>A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network.</source>
+ <translation>bitcoin: URIに添付されていたメッセージです。これは参照用としてトランザクションとともに保存されます。注意:このメッセージはBitcoinネットワークを通して送信されるわけではありません。</translation>
+ </message>
+ <message>
+ <source>Pay To:</source>
+ <translation>支払先:</translation>
+ </message>
+ <message>
+ <source>Memo:</source>
+ <translation>メモ:</translation>
+ </message>
+</context>
+<context>
+ <name>ShutdownWindow</name>
+ <message>
+ <source>Bitcoin Core is shutting down...</source>
+ <translation>Bitcoin Coreをシャットダウンしています。</translation>
+ </message>
+ <message>
+ <source>Do not shut down the computer until this window disappears.</source>
+ <translation>このウィンドウが消えるまでコンピュータをシャットダウンしないで下さい。</translation>
+ </message>
+</context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Signatures - Sign / Verify a Message</source>
+ <translation>署名 - メッセージの署名/検証</translation>
+ </message>
+ <message>
+ <source>&amp;Sign Message</source>
+ <translation>メッセージの署名 (&amp;S)</translation>
+ </message>
+ <message>
+ <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source>
+ <translation>あなたの所有しているアドレスによりメッセージや合意書に署名をすることで、それらアドレスに対して送られたビットコインを受け取ることができることを証明できます。フィッシング攻撃により不正にあなたの識別情報を署名させられてしまうことを防ぐために、不明確なものやランダムなものに対して署名しないよう注意してください。合意することが可能な、よく詳細の記された文言にのみ署名するようにしてください。</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to sign the message with</source>
+ <translation>メッセージを署名するBitcoinアドレス</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>前に使用したアドレスを選ぶ</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>クリップボードからアドレスを貼付ける</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Enter the message you want to sign here</source>
+ <translation>ここにあなたが署名するメッセージを入力します</translation>
+ </message>
+ <message>
+ <source>Signature</source>
+ <translation>署名</translation>
+ </message>
+ <message>
+ <source>Copy the current signature to the system clipboard</source>
+ <translation>現在の署名をシステムのクリップボードにコピーする</translation>
+ </message>
+ <message>
+ <source>Sign the message to prove you own this Bitcoin address</source>
+ <translation>この Bitcoin アドレスを所有していることを証明するためにメッセージに署名</translation>
+ </message>
+ <message>
+ <source>Sign &amp;Message</source>
+ <translation>メッセージの署名 (&amp;M)</translation>
+ </message>
+ <message>
+ <source>Reset all sign message fields</source>
+ <translation>入力項目の内容をすべて消去します</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>すべてクリア (&amp;A)</translation>
+ </message>
+ <message>
+ <source>&amp;Verify Message</source>
+ <translation>メッセージの検証 (&amp;V)</translation>
+ </message>
+ <message>
+ <source>Enter the receiver's 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. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source>
+ <translation>受取人のアドレスとメッセージ(改行やスペース、タブなども完全に一致するよう注意してください)および署名を以下に入力し、メッセージの署名を検証してください。中間者攻撃により騙されるのを防ぐため、署名対象のメッセージに書かれていること以上の意味を署名から読み取ろうとしないよう注意してください。これは署名作成者がこのアドレスで受け取ったことを証明するだけであり、トランザクションの送信権限を証明するものではないことに注意してください!</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address the message was signed with</source>
+ <translation>メッセージの署名に使われたBitcoinアドレス</translation>
+ </message>
+ <message>
+ <source>Verify the message to ensure it was signed with the specified Bitcoin address</source>
+ <translation>指定された Bitcoin アドレスで署名されたことを保証するメッセージを検証</translation>
+ </message>
+ <message>
+ <source>Verify &amp;Message</source>
+ <translation>メッセージの検証 (&amp;M)</translation>
+ </message>
+ <message>
+ <source>Reset all verify message fields</source>
+ <translation>入力項目の内容をすべて消去します</translation>
+ </message>
+ <message>
+ <source>Click "Sign Message" to generate signature</source>
+ <translation>署名を作成するには"メッセージの署名"をクリック</translation>
+ </message>
+ <message>
+ <source>The entered address is invalid.</source>
+ <translation>不正なアドレスが入力されました。</translation>
+ </message>
+ <message>
+ <source>Please check the address and try again.</source>
+ <translation>アドレスを確かめてからもう一度試してください。</translation>
+ </message>
+ <message>
+ <source>The entered address does not refer to a key.</source>
+ <translation>入力されたアドレスに関連するキーがありません。</translation>
+ </message>
+ <message>
+ <source>Wallet unlock was cancelled.</source>
+ <translation>ウォレットのアンロックはキャンセルされました。</translation>
+ </message>
+ <message>
+ <source>Private key for the entered address is not available.</source>
+ <translation>入力されたアドレスのプライベート キーが無効です。</translation>
+ </message>
+ <message>
+ <source>Message signing failed.</source>
+ <translation>メッセージの署名に失敗しました。</translation>
+ </message>
+ <message>
+ <source>Message signed.</source>
+ <translation>メッセージに署名しました。</translation>
+ </message>
+ <message>
+ <source>The signature could not be decoded.</source>
+ <translation>署名がデコードできません。</translation>
+ </message>
+ <message>
+ <source>Please check the signature and try again.</source>
+ <translation>署名を確認してからもう一度試してください。</translation>
+ </message>
+ <message>
+ <source>The signature did not match the message digest.</source>
+ <translation>署名はメッセージ ダイジェストと一致しませんでした。</translation>
+ </message>
+ <message>
+ <source>Message verification failed.</source>
+ <translation>メッセージの検証に失敗しました。</translation>
+ </message>
+ <message>
+ <source>Message verified.</source>
+ <translation>メッセージは検証されました。</translation>
+ </message>
+</context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin のコア</translation>
+ </message>
+ <message>
+ <source>The Bitcoin Core developers</source>
+ <translation>ビットコインコアの開発者</translation>
+ </message>
+ <message>
+ <source>[testnet]</source>
+ <translation>[testnet]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ <message>
+ <source>KB/s</source>
+ <translation>KB/s</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>ユニット %1 を開く</translation>
+ </message>
+ <message>
+ <source>conflicted</source>
+ <translation>衝突</translation>
+ </message>
+ <message>
+ <source>%1/offline</source>
+ <translation>%1/オフライン</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/未検証</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 確認</translation>
+ </message>
+ <message>
+ <source>Status</source>
+ <translation>ステータス</translation>
+ </message>
+ <message numerus="yes">
+ <source>, broadcast through %n node(s)</source>
+ <translation><numerusform>%n ノードにブロードキャスト</numerusform></translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>日付</translation>
+ </message>
+ <message>
+ <source>Source</source>
+ <translation>ソース</translation>
+ </message>
+ <message>
+ <source>Generated</source>
+ <translation>生成された</translation>
+ </message>
+ <message>
+ <source>From</source>
+ <translation>送信</translation>
+ </message>
+ <message>
+ <source>To</source>
+ <translation>受信</translation>
+ </message>
+ <message>
+ <source>own address</source>
+ <translation>自分のアドレス</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>監視限定</translation>
+ </message>
+ <message>
+ <source>label</source>
+ <translation>ラベル</translation>
+ </message>
+ <message>
+ <source>Credit</source>
+ <translation>クレジット</translation>
+ </message>
+ <message numerus="yes">
+ <source>matures in %n more block(s)</source>
+ <translation><numerusform>%n 以上のブロックが満期</numerusform></translation>
+ </message>
+ <message>
+ <source>not accepted</source>
+ <translation>承認されなかった</translation>
+ </message>
+ <message>
+ <source>Debit</source>
+ <translation>引き落とし額</translation>
+ </message>
+ <message>
+ <source>Total debit</source>
+ <translation>総出金額</translation>
+ </message>
+ <message>
+ <source>Total credit</source>
+ <translation>総入金額</translation>
+ </message>
+ <message>
+ <source>Transaction fee</source>
+ <translation>取引手数料</translation>
+ </message>
+ <message>
+ <source>Net amount</source>
+ <translation>正味金額</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>メッセージ</translation>
+ </message>
+ <message>
+ <source>Comment</source>
+ <translation>コメント</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>取引 ID</translation>
+ </message>
+ <message>
+ <source>Merchant</source>
+ <translation>商人</translation>
+ </message>
+ <message>
+ <source>Generated coins must mature %1 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.</source>
+ <translation>生成されたコインは使う前に%1のブロックを完成させる必要があります。あなたが生成した時、このブロックはブロック チェーンに追加されるネットワークにブロードキャストされました。チェーンに追加されるのが失敗した場合、状態が"不承認"に変更されて使えなくなるでしょう。これは、別のノードがあなたの数秒前にブロックを生成する場合に時々起こるかもしれません。</translation>
+ </message>
+ <message>
+ <source>Debug information</source>
+ <translation>デバッグ情報</translation>
+ </message>
+ <message>
+ <source>Transaction</source>
+ <translation>取引</translation>
+ </message>
+ <message>
+ <source>Inputs</source>
+ <translation>入力</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>総額</translation>
+ </message>
+ <message>
+ <source>true</source>
+ <translation>正しい</translation>
+ </message>
+ <message>
+ <source>false</source>
+ <translation>正しくない</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>まだブロードキャストが成功していません</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>%n 以上のブロックを開く</numerusform></translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>未確認</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>取引の詳細</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>ここでは取引の詳細を表示しています</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>日付</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>タイプ</translation>
+ </message>
+ <message>
+ <source>Immature (%1 confirmations, will be available after %2)</source>
+ <translation>未成熟(%1検証。%2検証完了後に使用可能となります)</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>%n 以上のブロックを開く</numerusform></translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>ユニット %1 を開く</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>検証されました (%1 検証済み)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>このブロックは他のどのノードによっても受け取られないで、多分受け入れられないでしょう!</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>生成されましたが承認されませんでした</translation>
+ </message>
+ <message>
+ <source>Offline</source>
+ <translation>オフライン</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>ラベル</translation>
+ </message>
+ <message>
+ <source>Unconfirmed</source>
+ <translation>未検証</translation>
+ </message>
+ <message>
+ <source>Confirming (%1 of %2 recommended confirmations)</source>
+ <translation>検証中(%2の推奨検証数のうち、%1検証が完了)</translation>
+ </message>
+ <message>
+ <source>Conflicted</source>
+ <translation>衝突</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>受信元</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>送り主</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>送り先</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>自分自身への支払い</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>発掘した</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>監視限定</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(n/a)</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>取引の状況。このフィールドの上にカーソルを置くと検証の数を表示します。</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>取引を受信した日時。</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>取引の種類。</translation>
+ </message>
+ <message>
+ <source>Whether or not a watch-only address is involved in this transaction.</source>
+ <translation>監視限定アドレスがこのトランザクションに含まれているかどうか</translation>
+ </message>
+ <message>
+ <source>User-defined intent/purpose of the transaction.</source>
+ <translation>ユーザ定義のトランザクションの意図や目的。</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>残高に追加または削除された総額。</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>すべて</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>今日</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>今週</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>今月</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>先月</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>今年</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>期間...</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>送り主</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>送り先</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>自分自身</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>発掘した</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>その他</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>検索するアドレスまたはラベルを入力</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>最小の額</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>アドレスをコピーする</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>ラベルをコピーする</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>総額のコピー</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>取引 ID をコピー</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>ラベルの編集</translation>
+ </message>
+ <message>
+ <source>Show transaction details</source>
+ <translation>取引の詳細を表示</translation>
+ </message>
+ <message>
+ <source>Export Transaction History</source>
+ <translation>トランザクション履歴をエクスポートする</translation>
+ </message>
+ <message>
+ <source>Watch-only</source>
+ <translation>監視限定</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>エクスポートに失敗しました</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the transaction history to %1.</source>
+ <translation>トランザクション履歴を %1 へ保存する際にエラーが発生しました。</translation>
+ </message>
+ <message>
+ <source>Exporting Successful</source>
+ <translation>エクスポートに成功しました</translation>
+ </message>
+ <message>
+ <source>The transaction history was successfully saved to %1.</source>
+ <translation>トランザクション履歴は正常に%1に保存されました。</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>テキスト CSV (*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>検証済み</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>日付</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>タイプ</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>ラベル</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Helbidea</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>期間:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>から</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ <message>
+ <source>Unit to show amounts in. Click to select another unit.</source>
+ <translation>金額を表示する際の単位。クリックすることで他の単位を選択します。</translation>
+ </message>
+</context>
+<context>
+ <name>WalletFrame</name>
+ <message>
+ <source>No wallet has been loaded.</source>
+ <translation>ウォレットがロードされていません</translation>
+ </message>
+</context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>コインを送る</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>エクスポート (&amp;E)</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>ファイルに現在のタブのデータをエクスポート</translation>
+ </message>
+ <message>
+ <source>Backup Wallet</source>
+ <translation>ウォレットのバックアップ</translation>
+ </message>
+ <message>
+ <source>Wallet Data (*.dat)</source>
+ <translation>ウォレット データ (*.dat)</translation>
+ </message>
+ <message>
+ <source>Backup Failed</source>
+ <translation>バックアップに失敗しました</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the wallet data to %1.</source>
+ <translation>ウォレットデータを%1へ保存する際にエラーが発生しました。</translation>
+ </message>
+ <message>
+ <source>The wallet data was successfully saved to %1.</source>
+ <translation>ウォレット データは正常に%1に保存されました。</translation>
+ </message>
+ <message>
+ <source>Backup Successful</source>
+ <translation>バックアップ成功</translation>
+ </message>
+</context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>オプション:</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>データ ディレクトリの指定</translation>
+ </message>
+ <message>
+ <source>Connect to a node to retrieve peer addresses, and disconnect</source>
+ <translation>ピア アドレスを取得するためにノードに接続し、そして切断します</translation>
+ </message>
+ <message>
+ <source>Specify your own public address</source>
+ <translation>あなた自身のパブリックなアドレスを指定</translation>
+ </message>
+ <message>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>コマンドラインと JSON-RPC コマンドを許可</translation>
+ </message>
+ <message>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>デーモンとしてバックグランドで実行しコマンドを許可</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>テストのためのネットワークを使用</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
+ <translation>外部からの接続を許可 (初期値: -proxy または -connect を使用していない場合は1)</translation>
+ </message>
+ <message>
+ <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
+ <translation>指定のアドレスへバインドし、その上で常にリスンします。IPv6 は [ホスト名]:ポート番号 と表記します</translation>
+ </message>
+ <message>
+ <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
+ <translation>ウォレットの全トランザクションを削除し、これらを-rescanオプションを用いることで起動時にブロックチェインのデータのみからリカバリします。</translation>
+ </message>
+ <message>
+ <source>Distributed under the MIT software license, see the accompanying file COPYING or &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</source>
+ <translation>MITソフトウェアライセンスのもとで配布されています。付属のCOPYINGファイルまたは&lt;http://www.opensource.org/licenses/mit-license.php&gt;を参照してください。</translation>
+ </message>
+ <message>
+ <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
+ <translation>ウォレットの取引を変更する際にコマンドを実行 (cmd の %s は TxID に置換される)</translation>
+ </message>
+ <message>
+ <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source>
+ <translation>ひとつのウォレットトランザクションで使用する合計手数料の最大値。低すぎる値を指定すると巨大なトランザクションの作成ができなくなります (規定値: %s)</translation>
+ </message>
+ <message>
+ <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, &gt;%u = target size in MiB to use for block files)</source>
+ <translation>古いブロックを剪定する(削除する)ことで記憶容量の必要量を削減する。このモードを有効にするとウォレット機能のサポートは無効になり、-txindexとも互換性がなくなります。警告: この設定の再有効化には全ブロックチェインの再ダウンロードが必要となります。(規定値: 0 = ブロックの剪定無効、&gt;%u = ブロックファイルに使用するMiB単位の目標サイズ)</translation>
+ </message>
+ <message>
+ <source>Set the number of script verification threads (%u to %d, 0 = auto, &lt;0 = leave that many cores free, default: %d)</source>
+ <translation>スクリプト検証スレッドを設定 (%uから%dの間, 0 = 自動, &lt;0 = たくさんのコアを自由にしておく, 初期値: %d)</translation>
+ </message>
+ <message>
+ <source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source>
+ <translation>これはリリース前のテストビルドです - 各自の責任で利用すること - 採掘や商取引に使用しないでください</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer. Bitcoin Core is probably already running.</source>
+ <translation>このコンピュータの %s にバインドすることができません。おそらく Bitcoin Core は既に実行されています。</translation>
+ </message>
+ <message>
+ <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>警告:異常に多くの数のブロックが生成されています。%d ブロックが最近 %d 時間以内に受け取られました。(期待値: %d)</translation>
+ </message>
+ <message>
+ <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>警告:ネットワーク接続を確認してください。%d ブロックが最近 %d 時間以内にに受け取られました。(期待値: %d)</translation>
+ </message>
+ <message>
+ <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>警告: -paytxfee が非常に高く設定されています! これは取引を送信する場合に支払う取引手数料です。</translation>
+ </message>
+ <message>
+ <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source>
+ <translation>警告: ネットワークは完全に同意しないみたいです。マイナーは何かの問題を経験してるみたいなんです。</translation>
+ </message>
+ <message>
+ <source>Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.</source>
+ <translation>警告: ピアーと完全に同意しないみたいです!アップグレードは必要かもしれません、それとも他のノードはアップグレードは必要かもしれません。</translation>
+ </message>
+ <message>
+ <source>Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
+ <translation>警告: wallet.dat の読み込みエラー! すべてのキーは正しく読み取れますが、取引データやアドレス帳のエントリが失われたか、正しくない可能性があります。</translation>
+ </message>
+ <message>
+ <source>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</source>
+ <translation>警告: wallet.dat が壊れたのでデータを復旧しました! オリジナルの wallet.dat は wallet.{timestamp}.bak として %s に保存されました; もしもあなたの残高や取引が正しくないならバックアップから復元してください。</translation>
+ </message>
+ <message>
+ <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source>
+ <translation>与えられたネットマスクやIPアドレスから接続を行う、ホワイトリストのピア。複数回指定できます。</translation>
+ </message>
+ <message>
+ <source>(default: 1)</source>
+ <translation>(デフォルト: 1)</translation>
+ </message>
+ <message>
+ <source>&lt;category&gt; can be:</source>
+ <translation>&lt;category&gt;は以下の値を指定できます:</translation>
+ </message>
+ <message>
+ <source>Attempt to recover private keys from a corrupt wallet.dat</source>
+ <translation>壊れた wallet.dat から秘密鍵を復旧することを試す</translation>
+ </message>
+ <message>
+ <source>Block creation options:</source>
+ <translation>ブロック作成オプション:</translation>
+ </message>
+ <message>
+ <source>Connect only to the specified node(s)</source>
+ <translation>指定したノードだけに接続</translation>
+ </message>
+ <message>
+ <source>Connection options:</source>
+ <translation>接続オプション:</translation>
+ </message>
+ <message>
+ <source>Corrupted block database detected</source>
+ <translation>破損したブロック データベースが見つかりました
+</translation>
+ </message>
+ <message>
+ <source>Debugging/Testing options:</source>
+ <translation>デバッグ/テスト用オプション:</translation>
+ </message>
+ <message>
+ <source>Do not load the wallet and disable wallet RPC calls</source>
+ <translation>ウォレットは読み込まず、ウォレットRPCコールを無効化する</translation>
+ </message>
+ <message>
+ <source>Do you want to rebuild the block database now?</source>
+ <translation>ブロック データベースを今すぐ再構築しますか?</translation>
+ </message>
+ <message>
+ <source>Error initializing block database</source>
+ <translation>ブロック データベースの初期化中にエラー</translation>
+ </message>
+ <message>
+ <source>Error initializing wallet database environment %s!</source>
+ <translation>ウォレットのデータベース環境 %s 初期化エラー!</translation>
+ </message>
+ <message>
+ <source>Error loading block database</source>
+ <translation>ブロック データベースの読み込みエラー</translation>
+ </message>
+ <message>
+ <source>Error opening block database</source>
+ <translation>ブロック データベースの開始エラー</translation>
+ </message>
+ <message>
+ <source>Error: Disk space is low!</source>
+ <translation>エラー: ディスク容量不足!</translation>
+ </message>
+ <message>
+ <source>Failed to listen on any port. Use -listen=0 if you want this.</source>
+ <translation>ポートのリスンに失敗しました。必要であれば -listen=0 を使用してください。</translation>
+ </message>
+ <message>
+ <source>If &lt;category&gt; is not supplied, output all debugging information.</source>
+ <translation>&lt;category&gt; が与えられなかった場合には、すべてのデバッグ情報が出力されます。</translation>
+ </message>
+ <message>
+ <source>Importing...</source>
+ <translation>インポートしています……</translation>
+ </message>
+ <message>
+ <source>Incorrect or no genesis block found. Wrong datadir for network?</source>
+ <translation>不正なブロックあるいは、生成されていないブロックが見つかりました。ネットワークの datadir が間違っていませんか?</translation>
+ </message>
+ <message>
+ <source>Invalid -onion address: '%s'</source>
+ <translation>無効な -onion アドレス:'%s'</translation>
+ </message>
+ <message>
+ <source>Not enough file descriptors available.</source>
+ <translation>使用可能なファイルディスクリプタが不足しています。</translation>
+ </message>
+ <message>
+ <source>Only connect to nodes in network &lt;net&gt; (ipv4, ipv6 or onion)</source>
+ <translation>&lt;net&gt; (ipv4, ipv6 または onion) ネットワーク内のノードだけに接続する</translation>
+ </message>
+ <message>
+ <source>Prune cannot be configured with a negative value.</source>
+ <translation>剪定値は負の値に設定できません。</translation>
+ </message>
+ <message>
+ <source>Prune mode is incompatible with -txindex.</source>
+ <translation>剪定モードは-txindexと互換性がありません。</translation>
+ </message>
+ <message>
+ <source>Set database cache size in megabytes (%d to %d, default: %d)</source>
+ <translation>データベースのキャッシュサイズをメガバイトで設定 (%dから%d。初期値: %d)</translation>
+ </message>
+ <message>
+ <source>Set maximum block size in bytes (default: %d)</source>
+ <translation>最大ブロックサイズをバイトで設定 (初期値: %d)</translation>
+ </message>
+ <message>
+ <source>Specify wallet file (within data directory)</source>
+ <translation>ウォレットのファイルを指定 (データ・ディレクトリの中に)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: %u)</source>
+ <translation>リッスンポートの割当に UPnP を使用 (初期値: %u)</translation>
+ </message>
+ <message>
+ <source>Verifying blocks...</source>
+ <translation>ブロックの検証中...</translation>
+ </message>
+ <message>
+ <source>Verifying wallet...</source>
+ <translation>ウォレットの検証中...</translation>
+ </message>
+ <message>
+ <source>Wallet %s resides outside data directory %s</source>
+ <translation>財布 %s はデータ・ディレクトリ%sの外にあります</translation>
+ </message>
+ <message>
+ <source>Wallet options:</source>
+ <translation>ウォレットオプション:</translation>
+ </message>
+ <message>
+ <source>Warning: This version is obsolete; upgrade required!</source>
+ <translation>警告: このバージョンはサポートされません。アップグレードが必要です!</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to change -txindex</source>
+ <translation>-txindex を変更するには -reindex を使用してデータベースを再構築する必要があります</translation>
+ </message>
+ <message>
+ <source>Imports blocks from external blk000??.dat file</source>
+ <translation>外部の blk000??.dat ファイルからブロックをインポート</translation>
+ </message>
+ <message>
+ <source>Allow JSON-RPC connections from specified source. Valid for &lt;ip&gt; are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times</source>
+ <translation>指定したアクセス元からのJSON-RPC接続を許可する。有効な&lt;ip&gt;は、単一のIP (例 1.2.3.4)、ネットワーク/ネットマスク (1.2.3.4/255.255.255.0)、またはネットワーク/CIDR (1.2.3.4/24)です。このオプションは複数回指定できます。</translation>
+ </message>
+ <message>
+ <source>An error occurred while setting up the RPC address %s port %u for listening: %s</source>
+ <translation>リッスンする RPC アドレス %s、ポート %u の設定中にエラーが発生しました: %s</translation>
+ </message>
+ <message>
+ <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source>
+ <translation>指定されたアドレスおよび、そこに接続を行ってきたホワイトリストのピアに対してバインドを行います。IPv6の場合には [host]:port 表記を使用してください</translation>
+ </message>
+ <message>
+ <source>Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)</source>
+ <translation>指定されたアドレスに対して JSON-RPC 接続をリッスンしするようバインドします。IPv6の場合には [host]:port 表記を使用してください。このオプションは複数回指定することが可能です (初期値: すべてのインターフェースに対してバインドする)</translation>
+ </message>
+ <message>
+ <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source>
+ <translation>データ ディレクトリ %s のロックを取得することができません。おそらく Bitcoin Core は実行中です。</translation>
+ </message>
+ <message>
+ <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
+ <translation>umask 077 ではなく、システムのデフォルトパーミッションで新規ファイルを作成する (ウォレット機能が無効化されていた場合にのみ有効)</translation>
+ </message>
+ <message>
+ <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source>
+ <translation>自分のIPアドレスを解決する (規定値: リッスンをしており、-externalipまたは-proxyオプションが指定されていない場合は1)</translation>
+ </message>
+ <message>
+ <source>Error: Listening for incoming connections failed (listen returned error %s)</source>
+ <translation>エラー: 内向きの接続をリッスンするのに失敗しました (エラー %s が返却されました)</translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source>
+ <translation>エラー: サポートされていない引数 -socks が見つかりました。SOCKSバージョンの設定はできないようになりました。SOCKS5プロキシのみがサポートされています。</translation>
+ </message>
+ <message>
+ <source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source>
+ <translation>関連のアラートをもらってもすごく長いのフォークを見てもコマンドを実行 (コマンドの中にあるの%sはメッセージから置き換えさせる)</translation>
+ </message>
+ <message>
+ <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source>
+ <translation>中継の際、この値未満の手数料 (BTC/Kb単位) はゼロであるとみなす (デフォルト: %s)</translation>
+ </message>
+ <message>
+ <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
+ <translation>paytxfee が設定されていなかった場合、平均して n ブロック以内にトランザクションが検証され始めるのに十分な手数料を含める (初期値: %u)</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)</source>
+ <translation>-maxtxfee=&lt;amount&gt; の数量の指定が不正です: '%s' (トランザクションが詰まってしまうのを防ぐため、少なくとも %s の最小中継手数料を指定しなければいけません)</translation>
+ </message>
+ <message>
+ <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source>
+ <translation>中継および採掘を行う際の、データ運送トランザクションの中のデータの最大サイズ (初期値: %u)</translation>
+ </message>
+ <message>
+ <source>Prune configured below the minimum of %d MB. Please use a higher number.</source>
+ <translation>剪定が最小値の %d MB以下に設定されています。もっと大きな値を使用してください。</translation>
+ </message>
+ <message>
+ <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source>
+ <translation>保有するピアアドレスが少ない場合、DNS ルックアップによりピアアドレスを問い合わせる (-connect を使っていない場合の初期値: 1)</translation>
+ </message>
+ <message>
+ <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source>
+ <translation>認証情報をプロキシー接続ごとにランダム化する。これによりTorストリーム分離をすることができます (規定値: %u)</translation>
+ </message>
+ <message>
+ <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
+ <translation>最優先/最低手数料の最大サイズをバイトで指定 (初期値: %d)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source>
+ <translation>コイン生成が有効になっていた場合の利用スレッド数を設定する (-1 = すべてのコア, 初期値: %d)</translation>
+ </message>
+ <message>
+ <source>The transaction amount is too small to send after the fee has been deducted</source>
+ <translation>手数料差引後のトランザクションの金額が小さすぎるため、送金できません。</translation>
+ </message>
+ <message>
+ <source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit &lt;https://www.openssl.org/&gt; and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source>
+ <translation>この製品はOpenSSLプロジェクトにより開発されたソフトウェアをOpenSSLツールキットとして利用しています &lt;https://www.openssl.org/&gt;。また、Eric Young氏により開発された暗号ソフトウェア、Thomas Bernard氏により書かれたUPnPソフトウェアを用いています。</translation>
+ </message>
+ <message>
+ <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an 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)
+The username and password MUST NOT be the same.
+If the file does not exist, create it with owner-readable-only file permissions.
+It is also recommended to set alertnotify so you are notified of problems;
+for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
+</source>
+ <translation>bitcoindを用いる場合や、-server オプションをbitcoin-qtに指定する場合には、設定ファイルにrpcpasswordを設定しなければなりません:
+%s
+以下のランダムなパスワードを用いることが推奨されます:
+rpcuser=bitcoinrpc
+rpcpassword=%s
+(このパスワードを暗記する必要はありません)
+ユーザ名とパスワードは一致してはいけません。
+ファイルが存在しない場合には、所有者のみ読み込み可能なファイルパーミッションでファイルを作成してください。
+またalertnotifyを設定し、問題発生時に通知が行くようにすることをおすすめします;
+例: alertnotify=echo %%s | mail -s "Bitcoinアラート" admin@foo.com
+</translation>
+ </message>
+ <message>
+ <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source>
+ <translation>警告: -maxtxfee が非常に高く設定されています!ひとつのトランザクションでこの量の手数料が支払われてしまうことがあります。</translation>
+ </message>
+ <message>
+ <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source>
+ <translation>警告: あなたのPCの日付と時刻が正しいことを確認して下さい! もしあなたの時計が正しくなければBitcoin Coreが正確に動作しません。</translation>
+ </message>
+ <message>
+ <source>Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway</source>
+ <translation>ホワイトリストのピアはDoSによるアクセス禁止処理が無効化され、トランザクションは例えmempool内に既に存在していたとしても常にリレーされます。これは例えばゲートウェイに対して有用です</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source>
+ <translation>非剪定モードに戻るためには-reindexオプションを使用してデータベースを再構築する必要があります。これによりブロックチェイン全体の再ダウンロードが行われます。</translation>
+ </message>
+ <message>
+ <source>(default: %u)</source>
+ <translation>(規定値: %u)</translation>
+ </message>
+ <message>
+ <source>Accept public REST requests (default: %u)</source>
+ <translation>公開 REST リクエストを許可する (初期値: %u)</translation>
+ </message>
+ <message>
+ <source>Activating best chain...</source>
+ <translation>最優良のチェインを有効化しています...</translation>
+ </message>
+ <message>
+ <source>Can't run with a wallet in prune mode.</source>
+ <translation>剪定モードではウォレット機能付きで起動できません。</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -whitebind address: '%s'</source>
+ <translation>-whitebind アドレス '%s' を解決できません</translation>
+ </message>
+ <message>
+ <source>Choose data directory on startup (default: 0)</source>
+ <translation>起動時にデータ ディレクトリを選ぶ (初期値: 0)</translation>
+ </message>
+ <message>
+ <source>Connect through SOCKS5 proxy</source>
+ <translation>SOCKS5 プロキシ経由で接続する</translation>
+ </message>
+ <message>
+ <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source>
+ <translation>Copyright (C) 2009-%i Bitcoin Core 開発者</translation>
+ </message>
+ <message>
+ <source>Could not parse -rpcbind value %s as network address</source>
+ <translation>-rpcbind の値 %s をネットワークアドレスとして解釈できませんでした</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source>
+ <translation>wallet.dat の読み込みに失敗しました: ウォレットの読み込みにはより新しいバージョンの Bitcoin Core が必要です</translation>
+ </message>
+ <message>
+ <source>Error reading from database, shutting down.</source>
+ <translation>データベースの読み込みエラー。シャットダウンします。</translation>
+ </message>
+ <message>
+ <source>Error: A fatal internal error occurred, see debug.log for details</source>
+ <translation>エラー:致命的な内部エラーが発生しました。詳細はdebug.logを参照してください</translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -tor found, use -onion.</source>
+ <translation>エラー: サポートされていない引数 -tor が見つかりました。-onion を使用してください。</translation>
+ </message>
+ <message>
+ <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source>
+ <translation>送信するトランザクションに付加する手数料 (BTC/kB単位) (初期値: %s)</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>情報</translation>
+ </message>
+ <message>
+ <source>Initialization sanity check failed. Bitcoin Core is shutting down.</source>
+ <translation>初期化時の健全性チェックに失敗しました。Bitcoin Coreを終了します。</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s'</source>
+ <translation>-maxtxfee=&lt;amount&gt; に対する無効な数量です: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -minrelaytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>不正な額 -minrelaytxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -mintxfee=&lt;amount&gt;: '%s'</source>
+ <translation>不正な額 -minrelaytxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s' (must be at least %s)</source>
+ <translation>-paytxfee=&lt;amount&gt; に対する無効な数量です: '%s' (少なくとも %s でなければいけません)</translation>
+ </message>
+ <message>
+ <source>Invalid netmask specified in -whitelist: '%s'</source>
+ <translation>-whitelist に対する無効なネットマスクです: '%s'</translation>
+ </message>
+ <message>
+ <source>Keep at most &lt;n&gt; unconnectable transactions in memory (default: %u)</source>
+ <translation>最大で &lt;n&gt; 個の孤立したトランザクションをメモリの中に保持する (初期値: %u)</translation>
+ </message>
+ <message>
+ <source>Need to specify a port with -whitebind: '%s'</source>
+ <translation>-whitebind を用いてポートを指定する必要があります: '%s'</translation>
+ </message>
+ <message>
+ <source>Node relay options:</source>
+ <translation>ノード中継オプション:</translation>
+ </message>
+ <message>
+ <source>Pruning blockstore...</source>
+ <translation>ブロックデータを剪定しています……</translation>
+ </message>
+ <message>
+ <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source>
+ <translation>RPC SSL オプション: (SSLのセットアップ手順はビットコインWikiを参照してください)</translation>
+ </message>
+ <message>
+ <source>RPC server options:</source>
+ <translation>RPCサーバのオプション:</translation>
+ </message>
+ <message>
+ <source>RPC support for HTTP persistent connections (default: %d)</source>
+ <translation>RPCにおけるHTTPの持続的接続のサポート (初期値: %d)</translation>
+ </message>
+ <message>
+ <source>Rebuild block chain index from current blk000??.dat files on startup</source>
+ <translation>起動時に現在の blk000??.dat ファイルからブロック チェーンのインデックスを再構築</translation>
+ </message>
+ <message>
+ <source>Receive and display P2P network alerts (default: %u)</source>
+ <translation>P2Pネットワークのアラートの受け取りと表示を行う (デフォルト: %u)</translation>
+ </message>
+ <message>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>トレース/デバッグ情報を debug.log ファイルの代わりにコンソールへ送る</translation>
+ </message>
+ <message>
+ <source>Send transactions as zero-fee transactions if possible (default: %u)</source>
+ <translation>可能な場合には手数料ゼロのトランザクションとしてトランザクションを送信する (初期値: %u)</translation>
+ </message>
+ <message>
+ <source>Set SSL root certificates for payment request (default: -system-)</source>
+ <translation>支払いリクエスト用にSSLルート証明書を設定する(デフォルト:-system-)</translation>
+ </message>
+ <message>
+ <source>Set language, for example "de_DE" (default: system locale)</source>
+ <translation>言語設定 例: "de_DE" (初期値: システムの言語)</translation>
+ </message>
+ <message>
+ <source>Show all debugging options (usage: --help -help-debug)</source>
+ <translation>すべてのデバッグオプションを表示する (使い方: --help -help-debug)</translation>
+ </message>
+ <message>
+ <source>Show splash screen on startup (default: 1)</source>
+ <translation>起動時にスプラッシュ画面を表示する (初期値: 1)</translation>
+ </message>
+ <message>
+ <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source>
+ <translation>クライアント起動時に debug.log ファイルを縮小 (初期値: -debug オプションを指定しない場合は1)</translation>
+ </message>
+ <message>
+ <source>Signing transaction failed</source>
+ <translation>取引の署名に失敗しました</translation>
+ </message>
+ <message>
+ <source>Start minimized</source>
+ <translation>最小化された状態で起動する</translation>
+ </message>
+ <message>
+ <source>The transaction amount is too small to pay the fee</source>
+ <translation>トランザクションの金額が小さすぎて手数料を支払えません</translation>
+ </message>
+ <message>
+ <source>This is experimental software.</source>
+ <translation>これは実験的なソフトウェアです。</translation>
+ </message>
+ <message>
+ <source>Transaction amount too small</source>
+ <translation>取引の額が小さ過ぎます</translation>
+ </message>
+ <message>
+ <source>Transaction amounts must be positive</source>
+ <translation>取引の額は0より大きくしてください</translation>
+ </message>
+ <message>
+ <source>Transaction too large for fee policy</source>
+ <translation>手数料ポリシーに対してトランザクションが大きすぎます</translation>
+ </message>
+ <message>
+ <source>Transaction too large</source>
+ <translation>取引が大き過ぎます</translation>
+ </message>
+ <message>
+ <source>UI Options:</source>
+ <translation>UIオプション:</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer (bind returned error %s)</source>
+ <translation>このコンピュータの %s にバインドすることができません (バインドが返したエラーは %s)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: 1 when listening)</source>
+ <translation>リスン ポートの割当に UPnP を使用 (初期値: リスン中は1)</translation>
+ </message>
+ <message>
+ <source>Username for JSON-RPC connections</source>
+ <translation>JSON-RPC 接続のユーザー名</translation>
+ </message>
+ <message>
+ <source>Wallet needed to be rewritten: restart Bitcoin Core to complete</source>
+ <translation>ウォレットが書き直される必要がありました: 完了するために Bitcoin Core を再起動します</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>警告</translation>
+ </message>
+ <message>
+ <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source>
+ <translation>警告: サポートされていない引数 -benchmark は無視されました。-debug=bench を使用してください。</translation>
+ </message>
+ <message>
+ <source>Warning: Unsupported argument -debugnet ignored, use -debug=net.</source>
+ <translation>警告: サポートされていない引数 -debugnet は無視されました。-debug=net を使用してください。</translation>
+ </message>
+ <message>
+ <source>Zapping all transactions from wallet...</source>
+ <translation>ウォレットからすべてのトランザクションを消去しています...</translation>
+ </message>
+ <message>
+ <source>on startup</source>
+ <translation>起動時</translation>
+ </message>
+ <message>
+ <source>wallet.dat corrupt, salvage failed</source>
+ <translation>wallet.dat が壊れ、復旧に失敗しました</translation>
+ </message>
+ <message>
+ <source>Password for JSON-RPC connections</source>
+ <translation>JSON-RPC 接続のパスワード</translation>
+ </message>
+ <message>
+ <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
+ <translation>最良のブロックに変更する際にコマンドを実行 (cmd の %s はブロック ハッシュに置換される)</translation>
+ </message>
+ <message>
+ <source>Upgrade wallet to latest format</source>
+ <translation>ウォレットを最新のフォーマットにアップグレード</translation>
+ </message>
+ <message>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>失ったウォレットの取引のブロック チェーンを再スキャン</translation>
+ </message>
+ <message>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>JSON-RPC 接続に OpenSSL (https) を使用</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>このヘルプ メッセージ</translation>
+ </message>
+ <message>
+ <source>Allow DNS lookups for -addnode, -seednode and -connect</source>
+ <translation>-addnode, -seednode と -connect で DNS ルックアップを許可する</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>アドレスを読み込んでいます...</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>wallet.dat 読み込みエラー: ウォレットが壊れました</translation>
+ </message>
+ <message>
+ <source>(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source>
+ <translation>(1 = トランザクションのメタデータ、例えばアカウントの所有者や支払リクエストの内容を保持する, 2 = トランザクションのメタデータを破棄する)</translation>
+ </message>
+ <message>
+ <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
+ <translation>-checkblocks のブロックの検証レベル (0-4, 初期値: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
+ <translation>getrawtransaction rpc 呼び出し時に用いる、完全なトランザクションインデックスを保持する (初期値: %u)</translation>
+ </message>
+ <message>
+ <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source>
+ <translation>不正なピアを再接続するまでの秒数 (初期値: %u)</translation>
+ </message>
+ <message>
+ <source>Output debugging information (default: %u, supplying &lt;category&gt; is optional)</source>
+ <translation>デバッグ情報を出力する (初期値: %u, &lt;category&gt; の指定は任意です)</translation>
+ </message>
+ <message>
+ <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source>
+ <translation>Tor 秘匿サービスを通し、別々の SOCKS5 プロキシを用いることでピアに到達する (初期値: %s)</translation>
+ </message>
+ <message>
+ <source>(default: %s)</source>
+ <translation>(デフォルト: %s)</translation>
+ </message>
+ <message>
+ <source>Acceptable ciphers (default: %s)</source>
+ <translation>受付可能な暗号化方式 (初期値: %s)</translation>
+ </message>
+ <message>
+ <source>Always query for peer addresses via DNS lookup (default: %u)</source>
+ <translation>DNS ルックアップを通してピアアドレスを常に問い合わせる (初期値: %u)</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>wallet.dat 読み込みエラー</translation>
+ </message>
+ <message>
+ <source>Generate coins (default: %u)</source>
+ <translation>コインを生成 (初期値: %u)</translation>
+ </message>
+ <message>
+ <source>How many blocks to check at startup (default: %u, 0 = all)</source>
+ <translation>起動時に点検するブロック数 (初期値: %u, 0=すべて)</translation>
+ </message>
+ <message>
+ <source>Include IP addresses in debug output (default: %u)</source>
+ <translation>デバッグ出力にIPアドレスを含める (初期値: %u)</translation>
+ </message>
+ <message>
+ <source>Invalid -proxy address: '%s'</source>
+ <translation>無効な -proxy アドレス: '%s'</translation>
+ </message>
+ <message>
+ <source>Listen for JSON-RPC connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>&lt;port&gt; で JSON-RPC 接続をリスン (初期値: %u、testnet は %u)</translation>
+ </message>
+ <message>
+ <source>Listen for connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>接続のリッスンを &lt;port&gt; で行う (初期値: %u、testnet: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain at most &lt;n&gt; connections to peers (default: %u)</source>
+ <translation>ピアの接続数を最大でも &lt;n&gt; 個に維持する (初期値: %u)</translation>
+ </message>
+ <message>
+ <source>Make the wallet broadcast transactions</source>
+ <translation>ウォレットのトランザクションをブロードキャストする</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection receive buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>接続毎の最大受信バッファ &lt;n&gt;*1000 バイト (初期値: %u)</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection send buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>接続毎の最大送信バッファ &lt;n&gt;*1000 バイト (初期値: %u)</translation>
+ </message>
+ <message>
+ <source>Prepend debug output with timestamp (default: %u)</source>
+ <translation>デバッグ出力にタイムスタンプを付ける (初期値: %u)</translation>
+ </message>
+ <message>
+ <source>Relay and mine data carrier transactions (default: %u)</source>
+ <translation>データ運送トランザクションのリレーおよび採掘を行う (初期値: %u)</translation>
+ </message>
+ <message>
+ <source>Relay non-P2SH multisig (default: %u)</source>
+ <translation>P2SHでないマルチシグトランザクションをリレーする (初期値: %u)</translation>
+ </message>
+ <message>
+ <source>Server certificate file (default: %s)</source>
+ <translation>サーバ証明書ファイル (初期値: %s)</translation>
+ </message>
+ <message>
+ <source>Server private key (default: %s)</source>
+ <translation>サーバの秘密鍵 (初期値: %s)</translation>
+ </message>
+ <message>
+ <source>Set key pool size to &lt;n&gt; (default: %u)</source>
+ <translation>key pool のサイズを &lt;n&gt; (初期値: %u) にセット</translation>
+ </message>
+ <message>
+ <source>Set minimum block size in bytes (default: %u)</source>
+ <translation>最小ブロックサイズをバイトで設定 (初期値: %u)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads to service RPC calls (default: %d)</source>
+ <translation>RPC サービスのスレッド数を設定 (初期値: %d)</translation>
+ </message>
+ <message>
+ <source>Specify configuration file (default: %s)</source>
+ <translation>設定ファイルの指定 (初期値: %s)</translation>
+ </message>
+ <message>
+ <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source>
+ <translation>接続のタイムアウトをミリセコンドで指定 (最小値: 1, 初期値: %d)</translation>
+ </message>
+ <message>
+ <source>Specify pid file (default: %s)</source>
+ <translation>pid ファイルの指定 (初期値: %s)</translation>
+ </message>
+ <message>
+ <source>Spend unconfirmed change when sending transactions (default: %u)</source>
+ <translation>トランザクション送信時に未検証のおつりを使用する (デフォルト: %u)</translation>
+ </message>
+ <message>
+ <source>Threshold for disconnecting misbehaving peers (default: %u)</source>
+ <translation>不正なピアを切断するためのしきい値 (初期値: %u)</translation>
+ </message>
+ <message>
+ <source>Unknown network specified in -onlynet: '%s'</source>
+ <translation>-onlynet で指定された '%s' は未知のネットワークです</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -bind address: '%s'</source>
+ <translation>-bind のアドレス '%s' を解決できません</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -externalip address: '%s'</source>
+ <translation>-externalip のアドレス '%s' を解決できません</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>-paytxfee=&lt;amount&gt; の額 '%s' が無効です</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>残高不足</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>ブロック インデックスを読み込んでいます...</translation>
+ </message>
+ <message>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>接続するノードを追加し接続を持続するように試します</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>ウォレットを読み込んでいます...</translation>
+ </message>
+ <message>
+ <source>Cannot downgrade wallet</source>
+ <translation>ウォレットのダウングレードはできません</translation>
+ </message>
+ <message>
+ <source>Cannot write default address</source>
+ <translation>初期値のアドレスを書き込むことができません</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>再スキャン中...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>読み込み完了</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>エラー</translation>
+ </message>
+</context>
+</TS> \ No newline at end of file
diff --git a/src/qt/locale/bitcoin_ka.ts b/src/qt/locale/bitcoin_ka.ts
new file mode 100644
index 0000000000..7a0c382a83
--- /dev/null
+++ b/src/qt/locale/bitcoin_ka.ts
@@ -0,0 +1,2518 @@
+<TS language="ka" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Create a new address</source>
+ <translation>ახალი მისამართის შექმნა</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>შექმ&amp;ნა</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>მონიშნული მისამართის კოპირება სისტემურ კლიპბორდში</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>&amp;კოპირება</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>&amp;დახურვა</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>&amp;მისამართის კოპირება</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>მონიშნული მისამართის წაშლა სიიდან</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>ამ ბარათიდან მონაცემების ექსპორტი ფაილში</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;ექსპორტი</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;წაშლა</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>აირჩიეთ მონეტების გაგზავნის მისამართი</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>აირჩიეთ მონეტების მიღების მისამართი</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>&amp;არჩევა</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>გაგზავნის მისამართი</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>მიღების მისამართი</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>ეს არის თქვენი Bitcoin-მისამართები გადახდების შესასრულებლად. მონეტების გაგზავნამდე ყოველთვის შეამოწმეთ თანხა და მიმღების მისამართი.</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>ეს არის თქვენი Bitcoin-მისამართები გადახდების მისაღებად. რეკომენდებულია ყოველი ტრანსაქციისათვის ახალი მიღების მისამართის გამოყენება.</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>ნიშნუ&amp;ლის კოპირება</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>რ&amp;ედაქტირება</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>მისამართების სიის ექსპორტი</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>CSV-ფაილი (*.csv)</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>ექსპორტი ვერ განხორციელდა</translation>
+ </message>
+ </context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>ნიშნული</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>მისამართი</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(არ არის ნიშნული)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Passphrase Dialog</source>
+ <translation>ფრაზა-პაროლის დიალოგი</translation>
+ </message>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>შეიყვანეთ ფრაზა-პაროლი</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>ახალი ფრაზა-პაროლი</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>გაიმეორეთ ახალი ფრაზა-პაროლი</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>საფულის დაშიფრვა</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>ეს ოპერაცია მოითხოვს თქვენი საფულის ფრაზა-პაროლს საფულის განსაბლოკად.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>საფულის განბლოკვა</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>ეს ოპერაცია მოითხოვს თქვენი საფულის ფრაზა-პაროლს საფულის გასაშიფრად.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>საფულის გაშიფრვა</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>ფრაზა-პაროლის შეცვლა</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>დაადასტურეთ საფულის დაშიფრვა</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>ყურადღება: საფულის დაშიფრვის შემდეგ თუ თქვენ დაკარგავთ ფრაზა-პაროლს, &lt;b&gt;ყველა ბიტქოინი დაგეკარგებათ&lt;/b&gt;!</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>დარწმუნებული ხართ, რომ გინდათ საფულის დაშიფრვა?</translation>
+ </message>
+ <message>
+ <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
+ <translation>მნიშვნელოვანია: თქვენი საფულის ყველა ადრინდელი არქივი შეიცვლება ახლადგენერირებული დაშიფრული საფულის ფაილით. უსაფრთხოების მოსაზრებებით დაუშიფრავი საფულის ძველი არქივები ძალას დაკარგავს, როგორც კი დაიწყებთ ახალი, დაშიფრული საფულის გამოყენებას.</translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>ყურადღება: ჩართულია Caps Lock რეჟიმი!</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>საფულე დაშიფრულია</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>ვერ მოხერხდა საფულის დაშიფრვა</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>საფულის დაშიფრვა ვერ მოხერხდა სისტემაში შეცდომის გამო. თქვენი საფულე არ არის დაშფრული.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>ფრაზა-პაროლები არ ემთხვევა ერთმანეთს.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>საფულის განბლოკვა ვერ მოხერხდა</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>საფულის განშიფრვის ფრაზა-პაროლი არაწორია</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>საფულის განშიფრვა ვერ მოხერხდა</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>საფულის ფრაზა-პაროლი შეცვლილია.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>ხელ&amp;მოწერა</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>ქსელთან სინქრონიზება...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>მიმ&amp;ოხილვა</translation>
+ </message>
+ <message>
+ <source>Node</source>
+ <translation>კვანძი</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>საფულის ზოგადი მიმოხილვა</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;ტრანსაქციები</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>ტრანსაქციების ისტორიის დათვალიერება</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>&amp;გასვლა</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>გასვლა</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>&amp;Qt-ს შესახებ</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>ინფორმაცია Qt-ს შესახებ</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;ოპციები</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>საფულის &amp;დაშიფრვა</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>საფულის &amp;არქივირება</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>ფრაზა-პაროლის შე&amp;ცვლა</translation>
+ </message>
+ <message>
+ <source>&amp;Sending addresses...</source>
+ <translation>გაგზავნის მი&amp;სამართი</translation>
+ </message>
+ <message>
+ <source>&amp;Receiving addresses...</source>
+ <translation>მიღების მისამა&amp;რთი</translation>
+ </message>
+ <message>
+ <source>Open &amp;URI...</source>
+ <translation>&amp;URI-ის გახსნა...</translation>
+ </message>
+ <message>
+ <source>Importing blocks from disk...</source>
+ <translation>ბლოკების იმპორტი დისკიდან...</translation>
+ </message>
+ <message>
+ <source>Reindexing blocks on disk...</source>
+ <translation>დისკზე ბლოკების რეინდექსაცია...</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>მონეტების გაგზავნა Bitcoin-მისამართზე</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>საფულის არქივირება სხვა ადგილზე</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>საფულის დაშიფრვის ფრაზა-პაროლის შეცვლა</translation>
+ </message>
+ <message>
+ <source>&amp;Debug window</source>
+ <translation>და&amp;ხვეწის ფანჯარა</translation>
+ </message>
+ <message>
+ <source>Open debugging and diagnostic console</source>
+ <translation>დახვეწისა და გიაგნოსტიკის კონსოლის გაშვება</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>&amp;ვერიფიკაცია</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>საფულე</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>&amp;გაგზავნა</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>&amp;მიღება</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>&amp;ჩვენება/დაფარვა</translation>
+ </message>
+ <message>
+ <source>Show or hide the main Window</source>
+ <translation>მთავარი ფანჯრის ჩვენება/დაფარვა</translation>
+ </message>
+ <message>
+ <source>Encrypt the private keys that belong to your wallet</source>
+ <translation>თქვენი საფულის პირადი გასაღებების დაშიფრვა</translation>
+ </message>
+ <message>
+ <source>Sign messages with your Bitcoin addresses to prove you own them</source>
+ <translation>მესიჯებზე ხელმოწერა თქვენი Bitcoin-მისამართებით იმის დასტურად, რომ ის თქვენია</translation>
+ </message>
+ <message>
+ <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source>
+ <translation>შეამოწმეთ, რომ მესიჯები ხელმოწერილია მითითებული Bitcoin-მისამართით</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;ფაილი</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;პარამეტრები</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>&amp;დახმარება</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>ბარათების პანელი</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Request payments (generates QR codes and bitcoin: URIs)</source>
+ <translation>გადახდის მოთხოვნა (შეიქმნება QR-კოდები და bitcoin: ბმულები)</translation>
+ </message>
+ <message>
+ <source>&amp;About Bitcoin Core</source>
+ <translation>Bitcoin Core-ს შეს&amp;ახებ</translation>
+ </message>
+ <message>
+ <source>Show the list of used sending addresses and labels</source>
+ <translation>გამოყენებული გაგზავნის მისამართებისა და ნიშნულების სიის ჩვენება</translation>
+ </message>
+ <message>
+ <source>Show the list of used receiving addresses and labels</source>
+ <translation>გამოყენებული მიღების მისამართებისა და ნიშნულების სიის ჩვენება</translation>
+ </message>
+ <message>
+ <source>Open a bitcoin: URI or payment request</source>
+ <translation>bitcoin: URI-ის ან გადახდის მოთხოვნის გახსნა</translation>
+ </message>
+ <message>
+ <source>&amp;Command-line options</source>
+ <translation>საკომანდო სტრიქონის ოპ&amp;ციები</translation>
+ </message>
+ <message>
+ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
+ <translation>Bitcoin Core-ს დახმარების ჩვენება Bitcoin-ის საკომანდო სტრიქონის დასაშვები ოპციების სანახავად</translation>
+ </message>
+ <message>
+ <source>No block source available...</source>
+ <translation>ბლოკების წყარო მიუწვდომელია...</translation>
+ </message>
+ <message>
+ <source>%1 and %2</source>
+ <translation>%1 და %2</translation>
+ </message>
+ <message>
+ <source>%1 behind</source>
+ <translation>%1 გავლილია</translation>
+ </message>
+ <message>
+ <source>Last received block was generated %1 ago.</source>
+ <translation>ბოლო მიღებული ბლოკის გენერირებიდან გასულია %1</translation>
+ </message>
+ <message>
+ <source>Transactions after this will not yet be visible.</source>
+ <translation>შემდგომი ტრანსაქციები ნაჩვენები ჯერ არ იქნება.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>შეცდომა</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>გაფრთხილება</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>ინფორმაცია</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>განახლებულია</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>ჩართვა...</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>გაგზავნილი ტრანსაქციები</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>მიღებული ტრანსაქციები</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>საფულე &lt;b&gt;დაშიფრულია&lt;/b&gt; და ამჟამად &lt;b&gt;განბლოკილია&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>საფულე &lt;b&gt;დაშიფრულია&lt;/b&gt; და ამჟამად &lt;b&gt;დაბლოკილია&lt;/b&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <source>Network Alert</source>
+ <translation>ქსელური განგაში</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Quantity:</source>
+ <translation>რაოდენობა:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>ბაიტები:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>თანხა:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>პრიორიტეტი:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>საკომისიო:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>დამატებითი საკომისიო:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>ხურდა:</translation>
+ </message>
+ <message>
+ <source>(un)select all</source>
+ <translation>ყველას მონიშვნა/(მოხსნა)</translation>
+ </message>
+ <message>
+ <source>Tree mode</source>
+ <translation>განტოტვილი</translation>
+ </message>
+ <message>
+ <source>List mode</source>
+ <translation>სია</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>თანხა</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>თარიღი</translation>
+ </message>
+ <message>
+ <source>Confirmations</source>
+ <translation>დადასტურება</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>დადასტურებულია</translation>
+ </message>
+ <message>
+ <source>Priority</source>
+ <translation>პრიორიტეტი</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>მისამართის კოპირება</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>ნიშნულის კოპირება</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>თანხის კოპირება</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>ტრანსაქციის ID-ს კოპირება</translation>
+ </message>
+ <message>
+ <source>Lock unspent</source>
+ <translation>დაუხარჯავის დაბლოკვა</translation>
+ </message>
+ <message>
+ <source>Unlock unspent</source>
+ <translation>დაუხარჯავის განბლოკვა</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>რაოდენობის კოპირება</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>საკომისიოს კოპირება</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>დამატებითი საკომისიოს კოპირება</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>ბაიტების კოპირება</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>პრიორიტეტის კოპირება</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>ხურდის კოპირება</translation>
+ </message>
+ <message>
+ <source>highest</source>
+ <translation>უმაღლესი</translation>
+ </message>
+ <message>
+ <source>higher</source>
+ <translation>უფრო მაღალი</translation>
+ </message>
+ <message>
+ <source>high</source>
+ <translation>მაღალი</translation>
+ </message>
+ <message>
+ <source>medium-high</source>
+ <translation>საშუალოზე მაღალი</translation>
+ </message>
+ <message>
+ <source>medium</source>
+ <translation>საშუალო</translation>
+ </message>
+ <message>
+ <source>low-medium</source>
+ <translation>საშუალოზე დაბალი</translation>
+ </message>
+ <message>
+ <source>low</source>
+ <translation>დაბალი</translation>
+ </message>
+ <message>
+ <source>lower</source>
+ <translation>უფრო დაბალი</translation>
+ </message>
+ <message>
+ <source>lowest</source>
+ <translation>უდაბლესი</translation>
+ </message>
+ <message>
+ <source>(%1 locked)</source>
+ <translation>(%1 დაბლოკილია)</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>ცარიელი</translation>
+ </message>
+ <message>
+ <source>yes</source>
+ <translation>კი</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>არა</translation>
+ </message>
+ <message>
+ <source>This means a fee of at least %1 per kB is required.</source>
+ <translation>ეს ნიშნავს, რომ კილობაიტზე საკომისიო იქნება მინიმუმ %1</translation>
+ </message>
+ <message>
+ <source>Can vary +/- 1 byte per input.</source>
+ <translation>შეიძლება იყოს +/- 1 ბაიტი ყოველ შესავალზე.</translation>
+ </message>
+ <message>
+ <source>Transactions with higher priority are more likely to get included into a block.</source>
+ <translation>მეტი პრიორიტეტის ტრანსაქციებს მეტი შანსი აქვს მოხვდეს ბლოკში.</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(არ არის ნიშნული)</translation>
+ </message>
+ <message>
+ <source>change from %1 (%2)</source>
+ <translation>ხურდა %1-დან (%2)</translation>
+ </message>
+ <message>
+ <source>(change)</source>
+ <translation>(ხურდა)</translation>
+ </message>
+</context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>მისამართის შეცვლა</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>ნიშნუ&amp;ლი</translation>
+ </message>
+ <message>
+ <source>The label associated with this address list entry</source>
+ <translation>მისამართების სიის ამ ჩანაწერთან ასოცირებული ნიშნული</translation>
+ </message>
+ <message>
+ <source>The address associated with this address list entry. This can only be modified for sending addresses.</source>
+ <translation>მისამართების სიის ამ ჩანაწერთან მისამართი ასოცირებული. მისი შეცვლა შეიძლება მხოლოდ გაგზავნის მისამართის შემთხვევაში.</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>მის&amp;ამართი</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>ახალი მიღების მისამართი</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>ახალი გაგზავნის მისამართი</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>მიღების მისამართის შეცვლა</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>გაგზავნის მისამართის შეცვლა</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>მისამართი "%1" უკვე არის მისამართების წიგნში.</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is not a valid Bitcoin address.</source>
+ <translation>შეყვანილი მისამართი "%1" არ არის ვალიდური Bitcoin-მისამართი.</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>საფულის განბლოკვა ვერ მოხერხდა.</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>ახალი გასაღების გენერირება ვერ მოხერხდა</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ <message>
+ <source>A new data directory will be created.</source>
+ <translation>შეიქმნება ახალი მონაცემთა კატალოგი.</translation>
+ </message>
+ <message>
+ <source>name</source>
+ <translation>სახელი</translation>
+ </message>
+ <message>
+ <source>Directory already exists. Add %1 if you intend to create a new directory here.</source>
+ <translation>კატალოგი უკვე არსებობს. დაამატეთ %1 თუ გინდათ ახალი კატალოგის აქვე შექმნა.</translation>
+ </message>
+ <message>
+ <source>Path already exists, and is not a directory.</source>
+ <translation>მისამართი უკვე არსებობს და არ წარმოადგენს კატალოგს.</translation>
+ </message>
+ <message>
+ <source>Cannot create data directory here.</source>
+ <translation>კატალოგის აქ შექმნა შეუძლებელია.</translation>
+ </message>
+</context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>ვერსია</translation>
+ </message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>Bitcoin Core-ს შესახებ</translation>
+ </message>
+ <message>
+ <source>Command-line options</source>
+ <translation>კომანდების ზოლის ოპციები</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>გამოყენება:</translation>
+ </message>
+ <message>
+ <source>command-line options</source>
+ <translation>კომანდების ზოლის ოპციები</translation>
+ </message>
+</context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Welcome</source>
+ <translation>მოგესალმებით</translation>
+ </message>
+ <message>
+ <source>Welcome to Bitcoin Core.</source>
+ <translation>მოგესალმებათ Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</source>
+ <translation>ეს პროგრამის პირველი გაშვებაა; შეგიძლიათ მიუთითოთ, სად შეინახოს მონაცემები Bitcoin Core-მ.</translation>
+ </message>
+ <message>
+ <source>Use the default data directory</source>
+ <translation>ნაგულისხმევი კატალოგის გამოყენება</translation>
+ </message>
+ <message>
+ <source>Use a custom data directory:</source>
+ <translation>მითითებული კატალოგის გამოყენება:</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>შეცდომა</translation>
+ </message>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ <message>
+ <source>Open URI</source>
+ <translation>URI-ის გახსნა</translation>
+ </message>
+ <message>
+ <source>Open payment request from URI or file</source>
+ <translation>გადახდის მოთხოვნის შექმნა URI-იდან ან ფაილიდან</translation>
+ </message>
+ <message>
+ <source>URI:</source>
+ <translation>URI:</translation>
+ </message>
+ <message>
+ <source>Select payment request file</source>
+ <translation>გადახდის მოთხოვნის ფაილის არჩევა</translation>
+ </message>
+ <message>
+ <source>Select payment request file to open</source>
+ <translation>გადახდის მოთხოვნის ფაილის არჩევა გასახსნელად</translation>
+ </message>
+</context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>ოპციები</translation>
+ </message>
+ <message>
+ <source>&amp;Main</source>
+ <translation>&amp;მთავარი</translation>
+ </message>
+ <message>
+ <source>Size of &amp;database cache</source>
+ <translation>მონაცემთა ბაზის კეშის სი&amp;დიდე</translation>
+ </message>
+ <message>
+ <source>MB</source>
+ <translation>MB</translation>
+ </message>
+ <message>
+ <source>Number of script &amp;verification threads</source>
+ <translation>სკრიპტის &amp;ვერიფიცირების ნაკადების რაოდენობა</translation>
+ </message>
+ <message>
+ <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
+ <translation>პროქსის IP-მისამართი (მაგ.: IPv4: 127.0.0.1 / IPv6: ::1)</translation>
+ </message>
+ <message>
+ <source>Active command-line options that override above options:</source>
+ <translation>საკომანდო სტრიქონის აქტიური ოპციები, რომლებიც გადაფარავენ ზემოთნაჩვენებს:</translation>
+ </message>
+ <message>
+ <source>Reset all client options to default.</source>
+ <translation>კლიენტის ყველა პარამეტრის დაბრუნება ნაგულისხმევ მნიშვნელობებზე.</translation>
+ </message>
+ <message>
+ <source>&amp;Reset Options</source>
+ <translation>დაბ&amp;რუნების ოპციები</translation>
+ </message>
+ <message>
+ <source>&amp;Network</source>
+ <translation>&amp;ქსელი</translation>
+ </message>
+ <message>
+ <source>W&amp;allet</source>
+ <translation>ს&amp;აფულე</translation>
+ </message>
+ <message>
+ <source>If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.</source>
+ <translation>დაუდასტურებელი ხურდის გამოყენების აკრძალვის შემდეგ მათი გამოყენება შეუძლებელი იქნება, სანამ ტრანსაქციას არ ექნება ერთი დასტური მაინც. ეს აისახება თქვენი ნაშთის დათვლაზეც.</translation>
+ </message>
+ <message>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>როუტერში Bitcoin-კლიენტის პორტის ავტომატური გახსნა. მუშაობს, თუ თქვენს როუტერს ჩართული აქვს UPnP.</translation>
+ </message>
+ <message>
+ <source>Map port using &amp;UPnP</source>
+ <translation>პორტის გადამისამართება &amp;UPnP-ით</translation>
+ </message>
+ <message>
+ <source>Proxy &amp;IP:</source>
+ <translation>პროქსის &amp;IP:</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>&amp;პორტი</translation>
+ </message>
+ <message>
+ <source>Port of the proxy (e.g. 9050)</source>
+ <translation>პროქსის პორტი (მაგ.: 9050)</translation>
+ </message>
+ <message>
+ <source>&amp;Window</source>
+ <translation>&amp;ფანჯარა</translation>
+ </message>
+ <message>
+ <source>Show only a tray icon after minimizing the window.</source>
+ <translation>ფანჯრის მინიმიზებისას მხოლოდ იკონა სისტემურ ზონაში</translation>
+ </message>
+ <message>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>&amp;მინიმიზება სისტემურ ზონაში პროგრამების პანელის ნაცვლად</translation>
+ </message>
+ <message>
+ <source>M&amp;inimize on close</source>
+ <translation>მ&amp;ინიმიზება დახურვისას</translation>
+ </message>
+ <message>
+ <source>&amp;Display</source>
+ <translation>&amp;ჩვენება</translation>
+ </message>
+ <message>
+ <source>User Interface &amp;language:</source>
+ <translation>სამომხმარებ&amp;ლო ენა:</translation>
+ </message>
+ <message>
+ <source>&amp;Unit to show amounts in:</source>
+ <translation>ერთეუ&amp;ლი:</translation>
+ </message>
+ <message>
+ <source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
+ <translation>აირჩიეთ გასაგზავნი თანხის ნაგულისხმევი ერთეული.</translation>
+ </message>
+ <message>
+ <source>Whether to show coin control features or not.</source>
+ <translation>ვაჩვენოთ თუ არა მონეტების მართვის პარამეტრები.</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>&amp;OK</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>&amp;გაუქმება</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>ნაგულისხმევი</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>ცარიელი</translation>
+ </message>
+ <message>
+ <source>Confirm options reset</source>
+ <translation>დაადასტურეთ პარამეტრების დაბრუნება ნაგულისხმევზე</translation>
+ </message>
+ <message>
+ <source>Client restart required to activate changes.</source>
+ <translation>ცვლილებები ძალაში შევა კლიენტის ხელახალი გაშვების შემდეგ.</translation>
+ </message>
+ <message>
+ <source>This change would require a client restart.</source>
+ <translation>ამ ცვლილებების ძალაში შესასვლელად საჭიროა კლიენტის დახურვა და ხელახალი გაშვება.</translation>
+ </message>
+ <message>
+ <source>The supplied proxy address is invalid.</source>
+ <translation>პროქსის მისამართი არასწორია.</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>ფორმა</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>ნაჩვენები ინფორმაცია შეიძლება მოძველებული იყოს. თქვენი საფულე ავტომატურად სინქრონიზდება Bitcoin-ის ქსელთან კავშირის დამყარების შემდეგ, ეს პროცესი ჯერ არ არის დასრულებული.</translation>
+ </message>
+ <message>
+ <source>Available:</source>
+ <translation>ხელმისაწვდომია:</translation>
+ </message>
+ <message>
+ <source>Your current spendable balance</source>
+ <translation>თქვენი ხელმისაწვდომი ნაშთი</translation>
+ </message>
+ <message>
+ <source>Pending:</source>
+ <translation>იგზავნება:</translation>
+ </message>
+ <message>
+ <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source>
+ <translation>დასადასტურებელი ტრანსაქციების საერთო რაოდენობა, რომლებიც ჯერ არ არის ასახული ბალანსში</translation>
+ </message>
+ <message>
+ <source>Immature:</source>
+ <translation>მოუმზადებელია:</translation>
+ </message>
+ <message>
+ <source>Mined balance that has not yet matured</source>
+ <translation>მოპოვებული თანხა, რომელიც ჯერ არ არის მზადყოფნაში</translation>
+ </message>
+ <message>
+ <source>Total:</source>
+ <translation>სულ:</translation>
+ </message>
+ <message>
+ <source>Your current total balance</source>
+ <translation>თქვენი სრული მიმდინარე ბალანსი</translation>
+ </message>
+ </context>
+<context>
+ <name>PaymentServer</name>
+ <message>
+ <source>URI handling</source>
+ <translation>URI-ების დამუშავება</translation>
+ </message>
+ <message>
+ <source>Invalid payment address %1</source>
+ <translation>გადახდის მისამართი არასწორია: %1</translation>
+ </message>
+ <message>
+ <source>Requested payment amount of %1 is too small (considered dust).</source>
+ <translation>მოთხოვნილი გადახდის %1 მოცულობა ძალიან მცირეა (ითვლება "მტვრად")</translation>
+ </message>
+ <message>
+ <source>Payment request error</source>
+ <translation>გადახდის მოთხოვნის შეცდომა</translation>
+ </message>
+ <message>
+ <source>Cannot start bitcoin: click-to-pay handler</source>
+ <translation>ვერ გაიშვა bitcoin: click-to-pay</translation>
+ </message>
+ <message>
+ <source>Payment request fetch URL is invalid: %1</source>
+ <translation>არასწორია გადახდის მოთხოვნის URL: %1</translation>
+ </message>
+ <message>
+ <source>Payment request file handling</source>
+ <translation>გადახდის მოთხოვნის ფაილის დამუშავება</translation>
+ </message>
+ <message>
+ <source>Unverified payment requests to custom payment scripts are unsupported.</source>
+ <translation>არავერიფიცირებული გადახდის მოთხოვნები გადახდის სამომხმარებლო სკრიპტებისათვის არ არის მხარდაჭერილი.</translation>
+ </message>
+ <message>
+ <source>Refund from %1</source>
+ <translation>დაბრუნება %1-საგან</translation>
+ </message>
+ <message>
+ <source>Error communicating with %1: %2</source>
+ <translation>ვერ გამოდის კავშირზე %1: %2</translation>
+ </message>
+ <message>
+ <source>Bad response from server %1</source>
+ <translation>ცუდი პასუხი სერვერისაგან %1</translation>
+ </message>
+ <message>
+ <source>Payment acknowledged</source>
+ <translation>გადახდა მიღებულია</translation>
+ </message>
+ <message>
+ <source>Network request error</source>
+ <translation>ქსელური მოთხოვნის შეცდომა</translation>
+ </message>
+</context>
+<context>
+ <name>PeerTableModel</name>
+ </context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>თანხა</translation>
+ </message>
+ <message>
+ <source>%1 h</source>
+ <translation>%1 სთ</translation>
+ </message>
+ <message>
+ <source>%1 m</source>
+ <translation>%1 წთ</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>მიუწვდ.</translation>
+ </message>
+ </context>
+<context>
+ <name>QRImageWidget</name>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>გამო&amp;სახულების შენახვა...</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Image</source>
+ <translation>გამოსახულების &amp;კოპირება</translation>
+ </message>
+ <message>
+ <source>Save QR Code</source>
+ <translation>QR-კოდის შენახვა</translation>
+ </message>
+ <message>
+ <source>PNG Image (*.png)</source>
+ <translation>PNG სურათი (*.png)</translation>
+ </message>
+</context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>Client name</source>
+ <translation>კლიენტი</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>მიუწვდ.</translation>
+ </message>
+ <message>
+ <source>Client version</source>
+ <translation>კლიენტის ვერსია</translation>
+ </message>
+ <message>
+ <source>&amp;Information</source>
+ <translation>&amp;ინფორმაცია</translation>
+ </message>
+ <message>
+ <source>Debug window</source>
+ <translation>დახვეწის ფანჯარა</translation>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>საერთო</translation>
+ </message>
+ <message>
+ <source>Using OpenSSL version</source>
+ <translation>OpenSSL-ის ვერსია</translation>
+ </message>
+ <message>
+ <source>Startup time</source>
+ <translation>სტარტის დრო</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>ქსელი</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>სახელი</translation>
+ </message>
+ <message>
+ <source>Number of connections</source>
+ <translation>შეერთებების რაოდენობა</translation>
+ </message>
+ <message>
+ <source>Block chain</source>
+ <translation>ბლოკთა ჯაჭვი</translation>
+ </message>
+ <message>
+ <source>Current number of blocks</source>
+ <translation>ბლოკების მიმდინარე რაოდენობა</translation>
+ </message>
+ <message>
+ <source>Last block time</source>
+ <translation>ბოლო ბლოკის დრო</translation>
+ </message>
+ <message>
+ <source>&amp;Open</source>
+ <translation>&amp;შექმნა</translation>
+ </message>
+ <message>
+ <source>&amp;Console</source>
+ <translation>&amp;კონსოლი</translation>
+ </message>
+ <message>
+ <source>&amp;Network Traffic</source>
+ <translation>&amp;ქსელის ტრაფიკი</translation>
+ </message>
+ <message>
+ <source>&amp;Clear</source>
+ <translation>&amp;წაშლა</translation>
+ </message>
+ <message>
+ <source>Totals</source>
+ <translation>სულ:</translation>
+ </message>
+ <message>
+ <source>In:</source>
+ <translation>შემომავალი:</translation>
+ </message>
+ <message>
+ <source>Out:</source>
+ <translation>გამავალი:</translation>
+ </message>
+ <message>
+ <source>Build date</source>
+ <translation>შექმნის დრო</translation>
+ </message>
+ <message>
+ <source>Debug log file</source>
+ <translation>დახვეწის ლოგ-ფაილი</translation>
+ </message>
+ <message>
+ <source>Clear console</source>
+ <translation>კონსოლის გასუფთავება</translation>
+ </message>
+ <message>
+ <source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
+ <translation>კლავიშები "ზევით" და "ქვევით" - ისტორიაში მოძრაობა, &lt;b&gt;Ctrl-L&lt;/b&gt; - ეკრანის გასუფთავება.</translation>
+ </message>
+ <message>
+ <source>Type &lt;b&gt;help&lt;/b&gt; for an overview of available commands.</source>
+ <translation>აკრიფეთ &lt;b&gt;help&lt;/b&gt; ფაშვებული ბრძანებების სანახავად.</translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation>%1 B</translation>
+ </message>
+ <message>
+ <source>%1 KB</source>
+ <translation>%1 KB</translation>
+ </message>
+ <message>
+ <source>%1 MB</source>
+ <translation>%1 MB</translation>
+ </message>
+ <message>
+ <source>%1 GB</source>
+ <translation>%1 GB</translation>
+ </message>
+ </context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Amount:</source>
+ <translation>თ&amp;ანხა:</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>ნიშნუ&amp;ლი:</translation>
+ </message>
+ <message>
+ <source>&amp;Message:</source>
+ <translation>&amp;მესიჯი:</translation>
+ </message>
+ <message>
+ <source>Reuse one of the previously used receiving addresses. Reusing addresses has security and privacy issues. Do not use this unless re-generating a payment request made before.</source>
+ <translation>რომელიმე ადრე გამოყენებული მიღების მისამართის გამოყენება. ეს ამცირებს უსაფრთხოებასა და პრივატულობას. ნუ გამოიყენებთ ამ ოპციას, თუ არ ახდენთ ადრე მოთხოვნილი გადახდის ხელახლა გენერირებას.</translation>
+ </message>
+ <message>
+ <source>R&amp;euse an existing receiving address (not recommended)</source>
+ <translation>ად&amp;რე გამოყენებული მიღების მისამართის გამოყენება (არ არის რეკომენდებული)</translation>
+ </message>
+ <message>
+ <source>An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network.</source>
+ <translation>არააუცილებელი მესიჯი, რომელიც ერთვის გადახდის მოთხოვნას და ნაჩვენები იქნება მოთხოვნის გახსნისას. შენიშვნა: მესიჯი არ გაყვება გადახდას ბითქოინის ქსელში.</translation>
+ </message>
+ <message>
+ <source>An optional label to associate with the new receiving address.</source>
+ <translation>არააუცილებელი ნიშნული ახალ მიღების მისამართთან ასოცირებისათვის.</translation>
+ </message>
+ <message>
+ <source>Use this form to request payments. All fields are &lt;b&gt;optional&lt;/b&gt;.</source>
+ <translation>გამოიყენეთ ეს ფორმა გადახდის მოთხოვნისათვის. ყველა ველი &lt;b&gt;არააუცილებელია&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>An optional amount to request. Leave this empty or zero to not request a specific amount.</source>
+ <translation>მოთხოვნის მოცულობა. არააუცილებელია. ჩაწერეთ 0 ან დატოვეთ ცარიელი, თუ არ მოითხოვება კონკრეტული მოცულობა.</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>ფორმის ყველა ველის წაშლა</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation>წაშლა</translation>
+ </message>
+ <message>
+ <source>Requested payments history</source>
+ <translation>მოთხოვნილი გადახდების ისტორია</translation>
+ </message>
+ <message>
+ <source>&amp;Request payment</source>
+ <translation>&amp;გადახდის მოთხოვნა</translation>
+ </message>
+ <message>
+ <source>Show the selected request (does the same as double clicking an entry)</source>
+ <translation>არჩეული მოთხოვნის ჩვენება (იგივეა, რაც ჩანაწერზე ორჯერ ჩხვლეტა)</translation>
+ </message>
+ <message>
+ <source>Show</source>
+ <translation>ჩვენება</translation>
+ </message>
+ <message>
+ <source>Remove the selected entries from the list</source>
+ <translation>მონიშნული ჩანაწერების წაშლა სიიდან</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>წაშლა</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>ნიშნულის კოპირება</translation>
+ </message>
+ <message>
+ <source>Copy message</source>
+ <translation>მესიჯის კოპირება</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>თანხის კოპირება</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>QR Code</source>
+ <translation>QR-კოდი</translation>
+ </message>
+ <message>
+ <source>Copy &amp;URI</source>
+ <translation>&amp;URI-ის კოპირება</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Address</source>
+ <translation>მის&amp;ამართის კოპირება</translation>
+ </message>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>გამო&amp;სახულების შენახვა...</translation>
+ </message>
+ <message>
+ <source>Request payment to %1</source>
+ <translation>%1-ის გადაზდის მოთხოვნა</translation>
+ </message>
+ <message>
+ <source>Payment information</source>
+ <translation>ინფორმაცია გადახდის შესახებ</translation>
+ </message>
+ <message>
+ <source>URI</source>
+ <translation>URI</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>მისამართი</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>თანხა</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>ნიშნული</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>მესიჯი</translation>
+ </message>
+ <message>
+ <source>Resulting URI too long, try to reduce the text for label / message.</source>
+ <translation>URI ძალიან გრძელი გამოდის, შეამოკლეთ ნიშნულის/მესიჯის ტექსტი.</translation>
+ </message>
+ <message>
+ <source>Error encoding URI into QR Code.</source>
+ <translation>შედომა URI-ის QR-კოდში გადაყვანისას.</translation>
+ </message>
+</context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>თარიღი</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>ნიშნული</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>მესიჯი</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>თანხა</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(არ არის ნიშნული)</translation>
+ </message>
+ <message>
+ <source>(no message)</source>
+ <translation>(მესიჯები არ არის)</translation>
+ </message>
+ <message>
+ <source>(no amount)</source>
+ <translation>(თანხა არ არის)</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>მონეტების გაგზავნა</translation>
+ </message>
+ <message>
+ <source>Coin Control Features</source>
+ <translation>მონეტების კონტროლის პარამეტრები</translation>
+ </message>
+ <message>
+ <source>Inputs...</source>
+ <translation>ხარჯები...</translation>
+ </message>
+ <message>
+ <source>automatically selected</source>
+ <translation>არჩეულია ავტომატურად</translation>
+ </message>
+ <message>
+ <source>Insufficient funds!</source>
+ <translation>არ არის საკმარისი თანხა!</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>რაოდენობა:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>ბაიტები:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>თანხა:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>პრიორიტეტი:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>საკომისიო:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>დამატებითი საკომისიო:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>ხურდა:</translation>
+ </message>
+ <message>
+ <source>If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address.</source>
+ <translation>ამის გააქტიურებისას თუ ხურდის მისამართი ცარიელია ან არასწორია, ხურდა გაიგზავნება ახლად გენერირებულ მისამართებზე.</translation>
+ </message>
+ <message>
+ <source>Custom change address</source>
+ <translation>ხურდის მისამართი</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>გაგზავნა რამდენიმე რეციპიენტთან ერთდროულად</translation>
+ </message>
+ <message>
+ <source>Add &amp;Recipient</source>
+ <translation>&amp;რეციპიენტის დამატება</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>ფორმის ყველა ველის წაშლა</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>გ&amp;ასუფთავება</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>ბალანსი:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>გაგზავნის დადასტურება</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>გაგ&amp;ზავნა</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>მონეტების გაგზავნის დადასტურება</translation>
+ </message>
+ <message>
+ <source>%1 to %2</source>
+ <translation>%1-დან %2-ში</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>რაოდენობის კოპირება</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>თანხის კოპირება</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>საკომისიოს კოპირება</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>დამატებითი საკომისიოს კოპირება</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>ბაიტების კოპირება</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>პრიორიტეტის კოპირება</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>ხურდის კოპირება</translation>
+ </message>
+ <message>
+ <source>or</source>
+ <translation>ან</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>გადახდის მოცულობა 0-ზე მეტი უნდა იყოს</translation>
+ </message>
+ <message>
+ <source>The amount exceeds your balance.</source>
+ <translation>თანხა აღემატება თქვენს ბალანსს</translation>
+ </message>
+ <message>
+ <source>Transaction creation failed!</source>
+ <translation>შეცდომა ტრანსაქციის შექმნისას!</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>ტრანსაქცია უარყოფილია! შესაძლოა მონეტების ნაწილი თქვენი საფულიდან უკვე გამოყენებულია, რაც შეიძლება მოხდეს wallet.dat-ის ასლის გამოყენებისას, როცა მონეტები გაიგზავნა სხვა ასლიდან, აქ კი არ არის გაგზავნილად მონიშნული.</translation>
+ </message>
+ <message>
+ <source>Warning: Invalid Bitcoin address</source>
+ <translation>ყურადღება: არასწორია Bitcoin-მისამართი</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(არ არის ნიშნული)</translation>
+ </message>
+ <message>
+ <source>Warning: Unknown change address</source>
+ <translation>ყურადღება: უცნობია ხურდის მისამართი</translation>
+ </message>
+ <message>
+ <source>Are you sure you want to send?</source>
+ <translation>დარწმუნებული ხართ, რომ გინდათ გაგზავნა?</translation>
+ </message>
+ <message>
+ <source>added as transaction fee</source>
+ <translation>დამატებულია საკომისიო</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>&amp;რაოდენობა</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>ადრესა&amp;ტი:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>შეიყვანეთ ამ მისამართის ნიშნული მისამართების წიგნში დასამატებლად</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>ნიშნუ&amp;ლი:</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>აირჩიეთ ადრე გამოყენებული მისამართი</translation>
+ </message>
+ <message>
+ <source>This is a normal payment.</source>
+ <translation>ეს არის ჩვეულებრივი გადახდა.</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>მისამართის ჩასმა კლიპბორდიდან</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Remove this entry</source>
+ <translation>ჩანაწერის წაშლა</translation>
+ </message>
+ <message>
+ <source>Message:</source>
+ <translation>მესიჯი:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to the list of used addresses</source>
+ <translation>შეიყვანეთ ამ მისამართის ნიშნული გამოყენებული მისამართების სიაში დასამატებლად</translation>
+ </message>
+ <message>
+ <source>A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network.</source>
+ <translation>მესიჯი, რომელიც თან ერთვის მონეტებს: URI, რომელიც შეინახება ტრანსაქციასთან ერთად თქვენთვის. შენიშვნა: მესიჯი არ გაყვება გადახდას ბითქოინის ქსელში.</translation>
+ </message>
+ <message>
+ <source>Pay To:</source>
+ <translation>ადრესატი:</translation>
+ </message>
+ <message>
+ <source>Memo:</source>
+ <translation>შენიშვნა:</translation>
+ </message>
+</context>
+<context>
+ <name>ShutdownWindow</name>
+ <message>
+ <source>Bitcoin Core is shutting down...</source>
+ <translation>Bitcoin Core იხურება...</translation>
+ </message>
+ <message>
+ <source>Do not shut down the computer until this window disappears.</source>
+ <translation>არ გამორთოთ კომპიუტერი ამ ფანჯრის გაქრობამდე.</translation>
+ </message>
+</context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Signatures - Sign / Verify a Message</source>
+ <translation>ხელმოწერები - მესიჯის ხელმოწერა/ვერიფიკაცია</translation>
+ </message>
+ <message>
+ <source>&amp;Sign Message</source>
+ <translation>მე&amp;სიჯის ხელმოწერა</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>აირჩიეთ ადრე გამოყენებული მისამართი</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>მისამართის ჩასმა კლიპბორდიდან</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Enter the message you want to sign here</source>
+ <translation>აკრიფეთ ხელმოსაწერი მესიჯი</translation>
+ </message>
+ <message>
+ <source>Signature</source>
+ <translation>ხელმოწერა</translation>
+ </message>
+ <message>
+ <source>Copy the current signature to the system clipboard</source>
+ <translation>მიმდინარე ხელმოწერის კოპირება კლიპბორდში</translation>
+ </message>
+ <message>
+ <source>Sign the message to prove you own this Bitcoin address</source>
+ <translation>მოაწერეთ ხელი იმის დასადასტურებლად, რომ ეს მისამართი თქვენია</translation>
+ </message>
+ <message>
+ <source>Sign &amp;Message</source>
+ <translation>&amp;მესიჯის ხელმოწერა</translation>
+ </message>
+ <message>
+ <source>Reset all sign message fields</source>
+ <translation>ხელმოწერის ყველა ველის წაშლა</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>გ&amp;ასუფთავება</translation>
+ </message>
+ <message>
+ <source>&amp;Verify Message</source>
+ <translation>მესიჯის &amp;ვერიფიკაცია</translation>
+ </message>
+ <message>
+ <source>Verify the message to ensure it was signed with the specified Bitcoin address</source>
+ <translation>შეამოწმეთ, რომ მესიჯი ხელმოწერილია მითითებული Bitcoin-მისამართით</translation>
+ </message>
+ <message>
+ <source>Verify &amp;Message</source>
+ <translation>&amp;მესიჯის ვერიფიკაცია</translation>
+ </message>
+ <message>
+ <source>Reset all verify message fields</source>
+ <translation>ვერიფიკაციის ყველა ველის წაშლა</translation>
+ </message>
+ <message>
+ <source>Click "Sign Message" to generate signature</source>
+ <translation>ხელმოწერის გენერირებისათვის დააჭირეთ "მესიჯის ხელმოწერა"-ს</translation>
+ </message>
+ <message>
+ <source>The entered address is invalid.</source>
+ <translation>შეყვანილი მისამართი არასწორია.</translation>
+ </message>
+ <message>
+ <source>Please check the address and try again.</source>
+ <translation>შეამოწმეთ მისამართი და სცადეთ ხელახლა.</translation>
+ </message>
+ <message>
+ <source>The entered address does not refer to a key.</source>
+ <translation>შეყვანილი მისამართი არ არის კავშირში გასაღებთან.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock was cancelled.</source>
+ <translation>საფულის განბლოკვა შეწყვეტილია.</translation>
+ </message>
+ <message>
+ <source>Private key for the entered address is not available.</source>
+ <translation>ამ მისამართისათვის პირადი გასაღები მიუწვდომელია.</translation>
+ </message>
+ <message>
+ <source>Message signing failed.</source>
+ <translation>ვერ მოხერხდა მესიჯის ხელმოწერა.</translation>
+ </message>
+ <message>
+ <source>Message signed.</source>
+ <translation>მესიჯი ხელმოწერილია.</translation>
+ </message>
+ <message>
+ <source>The signature could not be decoded.</source>
+ <translation>ხელმოწერის დეკოდირება ვერ ხერხდება.</translation>
+ </message>
+ <message>
+ <source>Please check the signature and try again.</source>
+ <translation>შეამოწმეთ ხელმოწერა და სცადეთ ხელახლა.</translation>
+ </message>
+ <message>
+ <source>The signature did not match the message digest.</source>
+ <translation>ხელმოწერა არ შეესაბამება მესიჯის დაიჯესტს.</translation>
+ </message>
+ <message>
+ <source>Message verification failed.</source>
+ <translation>მესიჯის ვერიფიკაცია ვერ მოხერხდა.</translation>
+ </message>
+ <message>
+ <source>Message verified.</source>
+ <translation>მესიჯი ვერიფიცირებულია.</translation>
+ </message>
+</context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>The Bitcoin Core developers</source>
+ <translation>Bitcoin Core-ს ავტორები</translation>
+ </message>
+ <message>
+ <source>[testnet]</source>
+ <translation>[testnet]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ <message>
+ <source>KB/s</source>
+ <translation>KB/s</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>ღია იქნება სანამ %1</translation>
+ </message>
+ <message>
+ <source>conflicted</source>
+ <translation>კონფლიქტშია</translation>
+ </message>
+ <message>
+ <source>%1/offline</source>
+ <translation>%1/გათიშულია</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/დაუდასტურებელია</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 დადასტურებულია</translation>
+ </message>
+ <message>
+ <source>Status</source>
+ <translation>სტატუსი</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>თარიღი</translation>
+ </message>
+ <message>
+ <source>Source</source>
+ <translation>წყარო</translation>
+ </message>
+ <message>
+ <source>Generated</source>
+ <translation>გენერირებულია</translation>
+ </message>
+ <message>
+ <source>From</source>
+ <translation>გამგზავნი</translation>
+ </message>
+ <message>
+ <source>To</source>
+ <translation>მიმღები</translation>
+ </message>
+ <message>
+ <source>own address</source>
+ <translation>საკუთარი მისამართი</translation>
+ </message>
+ <message>
+ <source>label</source>
+ <translation>ნიშნული</translation>
+ </message>
+ <message>
+ <source>Credit</source>
+ <translation>კრედიტი</translation>
+ </message>
+ <message>
+ <source>not accepted</source>
+ <translation>უარყოფილია</translation>
+ </message>
+ <message>
+ <source>Debit</source>
+ <translation>დებიტი</translation>
+ </message>
+ <message>
+ <source>Transaction fee</source>
+ <translation>ტრანსაქციის საფასური - საკომისიო</translation>
+ </message>
+ <message>
+ <source>Net amount</source>
+ <translation>სუფთა თანხა</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>მესიჯი</translation>
+ </message>
+ <message>
+ <source>Comment</source>
+ <translation>შენიშვნა</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>ტრანსაქციის ID</translation>
+ </message>
+ <message>
+ <source>Merchant</source>
+ <translation>გამყიდველი</translation>
+ </message>
+ <message>
+ <source>Generated coins must mature %1 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.</source>
+ <translation>გენერირებული მონეტები გასაგზავნად მომწიფდება %1 ბლოკის შემდეგ. ეს ბლოკი გენერირების შემდეგ გავრცელებულ იქნა ქსელში ბლოკთა ჯაჭვზე დასამატებლად. თუ ის ვერ ჩაჯდა ჯაჭვში, მიეცემა სტატუსი "უარყოფილია" და ამ მონეტებს ვერ გამოიყენებთ. ასეთი რამ შეიძლება მოხდეს, თუ რომელიმე კვანძმა რამდენიმე წამით დაგასწროთ ბლოკის გენერირება.</translation>
+ </message>
+ <message>
+ <source>Debug information</source>
+ <translation>დახვეწის ინფორმაცია</translation>
+ </message>
+ <message>
+ <source>Transaction</source>
+ <translation>ტრანსაქცია</translation>
+ </message>
+ <message>
+ <source>Inputs</source>
+ <translation>ხარჯები</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>თანხა</translation>
+ </message>
+ <message>
+ <source>true</source>
+ <translation>ჭეშმარიტი</translation>
+ </message>
+ <message>
+ <source>false</source>
+ <translation>მცდარი</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, დაგზავნა არ არის წარმატებით დასრულებული</translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>უცნობია</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>ტრანსაქციის დეტალები</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>ტრანსაქციის დაწვრილებითი აღწერილობა</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>თარიღი</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>ტიპი</translation>
+ </message>
+ <message>
+ <source>Immature (%1 confirmations, will be available after %2)</source>
+ <translation>არ არის მომწიფებული (%1 დასტური, საჭიროა სულ %2)</translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>ღია იქნება სანამ %1</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>დადასტურებულია (%1დასტური)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>ეს ბლოკი არ არის მიღებული არცერთი კვანძის მიერ და სავარაუდოდ უარყოფილია!</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>გენერირებულია, მაგრამ უარყოფილია</translation>
+ </message>
+ <message>
+ <source>Offline</source>
+ <translation>ოფლაინშია</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>ნიშნული</translation>
+ </message>
+ <message>
+ <source>Unconfirmed</source>
+ <translation>დაუდასტურებელია</translation>
+ </message>
+ <message>
+ <source>Confirming (%1 of %2 recommended confirmations)</source>
+ <translation>დადასტურებულია (%1, რეკომენდებულია %2)</translation>
+ </message>
+ <message>
+ <source>Conflicted</source>
+ <translation>კონფლიქტშია</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>შემოსულია</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>გამომგზავნი</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>გაგზავნილია</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>გადახდილია საკუთარი თავისათვის</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>მოპოვებულია</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(მიუწვდ.)</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>ტრანსაქციის სტატუსი. ველზე კურსორის შეყვანისას გამოჩნდება დასტურების რაოდენობა.</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>ტრანსაქციის მიღების თარიღი და დრო.</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>ტრანსაქციის ტიპი.</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>ბალანსიდან მოხსნილი ან დამატებული თანხა.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>ყველა</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>დღეს</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>ამ კვირის</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>ამ თვის</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>ბოლო თვის</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>ამ წლის</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>შუალედი...</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>შემოსულია</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>გაგზავნილია</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>საკუთარი თავისათვის</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>მოპოვებულია</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>სხვა</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>შეიყვანეთ საძებნი მისამართი ან ნიშნული</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>მინ. თანხა</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>მისამართის კოპირება</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>ნიშნულის კოპირება</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>თანხის კოპირება</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>ტრანსაქციის ID-ს კოპირება</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>ნიშნულის რედაქტირება</translation>
+ </message>
+ <message>
+ <source>Show transaction details</source>
+ <translation>ტრანსაქციის დეტალების ჩვენება</translation>
+ </message>
+ <message>
+ <source>Export Transaction History</source>
+ <translation>ტრანსაქციების ისტორიის ექსპორტი</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>ექსპორტი ვერ განხორციელდა</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the transaction history to %1.</source>
+ <translation>შეცდომა %1-ში ტრანსაქციების შენახვის მცდელობისას.</translation>
+ </message>
+ <message>
+ <source>Exporting Successful</source>
+ <translation>ეხპორტი განხორციელებულია</translation>
+ </message>
+ <message>
+ <source>The transaction history was successfully saved to %1.</source>
+ <translation>ტრანსაქციების ისტორია შენახულია %1-ში.</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>CSV-ფაილი (*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>დადასტურებულია</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>თარიღი</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>ტიპი</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>ნიშნული</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>მისამართი</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>შუალედი:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>-</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ </context>
+<context>
+ <name>WalletFrame</name>
+ <message>
+ <source>No wallet has been loaded.</source>
+ <translation>არ არის ჩატვირთული საფულე.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>მონეტების გაგზავნა</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;ექსპორტი</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>ამ ბარათიდან მონაცემების ექსპორტი ფაილში</translation>
+ </message>
+ <message>
+ <source>Backup Wallet</source>
+ <translation>საფულის არქივირება</translation>
+ </message>
+ <message>
+ <source>Wallet Data (*.dat)</source>
+ <translation>საფულის მონაცემები (*.dat)</translation>
+ </message>
+ <message>
+ <source>Backup Failed</source>
+ <translation>არქივირება ვერ მოხერხდა</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the wallet data to %1.</source>
+ <translation>შეცდომა %1-ში საფულის მონაცემების შენახვის მცდელობისას.</translation>
+ </message>
+ <message>
+ <source>The wallet data was successfully saved to %1.</source>
+ <translation>საფულის მონაცემები შენახულია %1-ში.</translation>
+ </message>
+ <message>
+ <source>Backup Successful</source>
+ <translation>არქივირება შესრულებულია</translation>
+ </message>
+</context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>ოპციები:</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>მიუთითეთ მონაცემთა კატალოგი</translation>
+ </message>
+ <message>
+ <source>Connect to a node to retrieve peer addresses, and disconnect</source>
+ <translation>მიერთება კვანძთან, პირების მისამართების მიღება და გათიშვა</translation>
+ </message>
+ <message>
+ <source>Specify your own public address</source>
+ <translation>მიუთითეთ თქვენი საჯარო მისამართი</translation>
+ </message>
+ <message>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>საკომანდო სტრიქონისა და JSON-RPC-კომამდების ნებართვა</translation>
+ </message>
+ <message>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>რეზიდენტულად გაშვება და კომანდების მიღება</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>სატესტო ქსელის გამოყენება</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
+ <translation>გარედან შეერთებების დაშვება (ნაგულისხმევი: 1 თუ არ გამოიყენება -proxy ან -connect)</translation>
+ </message>
+ <message>
+ <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
+ <translation>მოცემულ მისამართზე მიჯაჭვა მუდმივად მასზე მიყურადებით. გამოიყენეთ [host]:port ფორმა IPv6-სათვის</translation>
+ </message>
+ <message>
+ <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
+ <translation>კომანდის შესრულება საფულის ტრანსაქციის ცვლილებისას (%s კომანდაში ჩანაცვლდება TxID-ით)</translation>
+ </message>
+ <message>
+ <source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source>
+ <translation>ეს არის წინასწარი სატესტო ვერსია - გამოიყენეთ საკუთარი რისკით - არ გამოიყენოთ მოპოვებისა ან კომერციული მიზნებისათვის</translation>
+ </message>
+ <message>
+ <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>ყურადღება: ძალიან მაღალია -paytxfee - საკომისო, რომელსაც თქვენ გადაიხდით ამ ტრანსაქციის გაგზავნის საფასურად.</translation>
+ </message>
+ <message>
+ <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source>
+ <translation>ყურადღება: ქსელში შეუთანხმებლობაა. შესაძლოა ცალკეულ მომპოვებლებს პრობლემები ექმნებათ!</translation>
+ </message>
+ <message>
+ <source>Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.</source>
+ <translation>ყურადღება: ჩვენ არ ვეთანხმებით ყველა პირს. შესაძლოა თქვენ ან სხვა კვანძებს განახლება გჭირდებათ.</translation>
+ </message>
+ <message>
+ <source>Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
+ <translation>ყურადღება: არ იკითხება wallet.dat! ყველა გასაღები წაკითხულია, მაგრამ გამორჩენილი ან არასწორია ტრანსაქციის თარიღი ან ჩანაწერები მისამართების წიგნში.</translation>
+ </message>
+ <message>
+ <source>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</source>
+ <translation>ყურადღება: wallet.dat დაზიანებულია! ორიგინალური wallet.dat შენახულია როგორც wallet.{timestamp}.bak %s-ში; თუ შეამჩნიეთ უზუსტობა ნაშთში ან ტრანსაქციებში, აღადგინეთ არქივიდან.</translation>
+ </message>
+ <message>
+ <source>&lt;category&gt; can be:</source>
+ <translation>&lt;category&gt; შეიძლება იყოს:</translation>
+ </message>
+ <message>
+ <source>Attempt to recover private keys from a corrupt wallet.dat</source>
+ <translation>პირადი გასაღებების აღდგენის მცდელობა wallet.dat-იდან</translation>
+ </message>
+ <message>
+ <source>Block creation options:</source>
+ <translation>ბლოკის შექმნის ოპციები:</translation>
+ </message>
+ <message>
+ <source>Connect only to the specified node(s)</source>
+ <translation>შეერთება მხოლოდ მითითებულ კვანძ(ებ)თან</translation>
+ </message>
+ <message>
+ <source>Corrupted block database detected</source>
+ <translation>შენიშნულია ბლოკთა ბაზის დაზიანება</translation>
+ </message>
+ <message>
+ <source>Do not load the wallet and disable wallet RPC calls</source>
+ <translation>არ ჩაიტვირთოს საფულე და აიკრძალოს საფულისადმი RPC-მიმართვები</translation>
+ </message>
+ <message>
+ <source>Do you want to rebuild the block database now?</source>
+ <translation>გავუშვათ ბლოკთა ბაზის ხელახლა აგება ეხლა?</translation>
+ </message>
+ <message>
+ <source>Error initializing block database</source>
+ <translation>ვერ ინიციალიზდება ბლოკების ბაზა</translation>
+ </message>
+ <message>
+ <source>Error initializing wallet database environment %s!</source>
+ <translation>ვერ ინიციალიზდება საფულის ბაზის გარემო %s!</translation>
+ </message>
+ <message>
+ <source>Error loading block database</source>
+ <translation>არ იტვირთება ბლოკების ბაზა</translation>
+ </message>
+ <message>
+ <source>Error opening block database</source>
+ <translation>ბლოკთა ბაზის შექმნა ვერ მოხერხდა</translation>
+ </message>
+ <message>
+ <source>Error: Disk space is low!</source>
+ <translation>შეცდომა: დისზე არ არის ადგილი!</translation>
+ </message>
+ <message>
+ <source>Failed to listen on any port. Use -listen=0 if you want this.</source>
+ <translation>ვერ ხერხდება პორტების მიყურადება. თუ გსურთ, გამოიყენეთ -listen=0.</translation>
+ </message>
+ <message>
+ <source>If &lt;category&gt; is not supplied, output all debugging information.</source>
+ <translation>თუ &lt;category&gt; არ არის მითითებული, ნაჩვენები იქნება სრული დახვეწის ინფორმაცია.</translation>
+ </message>
+ <message>
+ <source>Incorrect or no genesis block found. Wrong datadir for network?</source>
+ <translation>საწყისი ბლოკი არ არსებობს ან არასწორია. ქსელის მონაცემთა კატალოგი datadir ხომ არის არასწორი?</translation>
+ </message>
+ <message>
+ <source>Invalid -onion address: '%s'</source>
+ <translation>არასწორია მისამართი -onion: '%s'</translation>
+ </message>
+ <message>
+ <source>Not enough file descriptors available.</source>
+ <translation>არ არის საკმარისი ფაილ-დესკრიპტორები.</translation>
+ </message>
+ <message>
+ <source>Set maximum block size in bytes (default: %d)</source>
+ <translation>ბლოკის მაქსიმალური ზომის განსაზღვრა ბაიტებში (ნადულისხმევი: %d)</translation>
+ </message>
+ <message>
+ <source>Specify wallet file (within data directory)</source>
+ <translation>მიუთითეთ საფულის ფაილი (კატალოგში)</translation>
+ </message>
+ <message>
+ <source>Verifying blocks...</source>
+ <translation>ბლოკების ვერიფიკაცია...</translation>
+ </message>
+ <message>
+ <source>Verifying wallet...</source>
+ <translation>საფულის ვერიფიკაცია...</translation>
+ </message>
+ <message>
+ <source>Wallet %s resides outside data directory %s</source>
+ <translation>საფულე %s მდებარეობს მონაცემთა კატალოგის %s გარეთ</translation>
+ </message>
+ <message>
+ <source>Wallet options:</source>
+ <translation>სფულის ოპციები:</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to change -txindex</source>
+ <translation>საჭიროა ბაზის ხელახალი აგება, გამოიყენეთ -reindex რათა შეცვალოთ -txindex</translation>
+ </message>
+ <message>
+ <source>Imports blocks from external blk000??.dat file</source>
+ <translation>ბლოკების იმპორტი გარე blk000??.dat ფაილიდან</translation>
+ </message>
+ <message>
+ <source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source>
+ <translation>ბრძანების შესრულება შესაბამისი უწყების მიღებისას ან როცა შეინიშნება საგრძნობი გახლეჩა (cmd-ში %s შეიცვლება მესიჯით)</translation>
+ </message>
+ <message>
+ <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
+ <translation>მაღალპრიორიტეტული/დაბალსაკომისიოიანი ტრანსაქციების მაქსიმალური ზომა ბაიტებში (ნაგულისხმევი: %d)</translation>
+ </message>
+ <message>
+ <source>Choose data directory on startup (default: 0)</source>
+ <translation>მონაცემთა კატალოგის მითითება ყოველი გაშვებისას (ნაგულისხმევი: 0)</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>ინფორმაცია</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -minrelaytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>დაუშვებელი მნიშვნელობა -minrelaytxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -mintxfee=&lt;amount&gt;: '%s'</source>
+ <translation>დაუშვებელი მნიშვნელობა -mintxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>ტრასირების/დახვეწის ინფოს გაგზავნა კონსოლზე debug.log ფაილის ნაცვლად</translation>
+ </message>
+ <message>
+ <source>Set language, for example "de_DE" (default: system locale)</source>
+ <translation>აირჩიეთ ენა, მაგალითად "de_DE" (ნაგულისხმევია სისტემური ლოკალი)</translation>
+ </message>
+ <message>
+ <source>Show splash screen on startup (default: 1)</source>
+ <translation>მისალმების ეკრანის ჩვენება გაშვებისას (ნაგულისხმევი:1)</translation>
+ </message>
+ <message>
+ <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source>
+ <translation>debug.log ფაილის შეკუმშვა გაშვებისას (ნაგულისხმევია: 1 როცა არ აყენია -debug)</translation>
+ </message>
+ <message>
+ <source>Signing transaction failed</source>
+ <translation>ტრანსაქციების ხელმოწერა ვერ მოხერხდა</translation>
+ </message>
+ <message>
+ <source>Start minimized</source>
+ <translation>გაშვება მინიმიზებული ეკრანით</translation>
+ </message>
+ <message>
+ <source>Transaction amount too small</source>
+ <translation>ტრანსაქციების რაოდენობა ძალიან ცოტაა</translation>
+ </message>
+ <message>
+ <source>Transaction amounts must be positive</source>
+ <translation>ტრანსაქციების რაოდენობა დადებითი რიცხვი უნდა იყოს</translation>
+ </message>
+ <message>
+ <source>Transaction too large</source>
+ <translation>ტრანსაქცია ძალიან დიდია</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: 1 when listening)</source>
+ <translation>გამოიყენეთ UPnP მისაყურადებელი პორტის გადასამისამართებლად (ნაგულისხმევი: 1 როცა ჩართულია მიყურადება)</translation>
+ </message>
+ <message>
+ <source>Username for JSON-RPC connections</source>
+ <translation>მომხმარებლის სახელი JSON-RPC-შეერთებისათვის</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>გაფრთხილება</translation>
+ </message>
+ <message>
+ <source>Zapping all transactions from wallet...</source>
+ <translation>ტრანსაქციების ჩახსნა საფულიდან...</translation>
+ </message>
+ <message>
+ <source>wallet.dat corrupt, salvage failed</source>
+ <translation>wallet.dat დაზიანებულია, აღდგენა ვერ მოხერხდა</translation>
+ </message>
+ <message>
+ <source>Password for JSON-RPC connections</source>
+ <translation>პაროლი JSON-RPC-შეერთებისათვის</translation>
+ </message>
+ <message>
+ <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
+ <translation>კომანდის შესრულება უკეთესი ბლოკის გამოჩენისას (%s კომანდაში ჩანაცვლდება ბლოკის ჰეშით)</translation>
+ </message>
+ <message>
+ <source>Upgrade wallet to latest format</source>
+ <translation>საფულის ფორმატის განახლება</translation>
+ </message>
+ <message>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>ბლოკების ჯაჭვის გადამოწმება საფულეში გამორჩენილ ტრანსაქციებზე</translation>
+ </message>
+ <message>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>OpenSSL-ის (https) გამოყენება JSON-RPC-შეერთებებისათვის</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>ეს ტექსტი</translation>
+ </message>
+ <message>
+ <source>Allow DNS lookups for -addnode, -seednode and -connect</source>
+ <translation>DNS-ძებნის დაშვება -addnode, -seednode და -connect-სათვის</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>მისამართების ჩატვირთვა...</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>არ იტვირთება wallet.dat: საფულე დაზიანებულია</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>არ იტვირთება wallet.dat</translation>
+ </message>
+ <message>
+ <source>Invalid -proxy address: '%s'</source>
+ <translation>არასწორია მისამართი -proxy: '%s'</translation>
+ </message>
+ <message>
+ <source>Unknown network specified in -onlynet: '%s'</source>
+ <translation>-onlynet-ში მითითებულია უცნობი ქსელი: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -bind address: '%s'</source>
+ <translation>ვერ ხერხდება -bind მისამართის გარკვევა: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -externalip address: '%s'</source>
+ <translation>ვერ ხერხდება -externalip მისამართის გარკვევა: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>დაუშვებელი მნიშვნელობა -paytxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>არ არის საკმარისი თანხა</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>ბლოკების ინდექსის ჩატვირთვა...</translation>
+ </message>
+ <message>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>მისაერთებელი კვანძის დამატება და მიერთების შეძლებისდაგვარად შენარჩუნება</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>საფულის ჩატვირთვა...</translation>
+ </message>
+ <message>
+ <source>Cannot downgrade wallet</source>
+ <translation>საფულის ძველ ვერსიაზე გადაყვანა შეუძლებელია</translation>
+ </message>
+ <message>
+ <source>Cannot write default address</source>
+ <translation>ვერ ხერხდება ნაგულისხმევი მისამართის ჩაწერა</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>სკანირება...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>ჩატვირთვა დასრულებულია</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>შეცდომა</translation>
+ </message>
+</context>
+</TS> \ No newline at end of file
diff --git a/src/qt/locale/bitcoin_kk_KZ.ts b/src/qt/locale/bitcoin_kk_KZ.ts
new file mode 100644
index 0000000000..5ee9040633
--- /dev/null
+++ b/src/qt/locale/bitcoin_kk_KZ.ts
@@ -0,0 +1,442 @@
+<TS language="kk_KZ" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Create a new address</source>
+ <translation>Жаңа адрес енгізу</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>Жаңа</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Таңдаған адресті тізімнен жою</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>Жабу</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>Экспорт</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>Жою</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Үтірмен бөлінген текст (*.csv)</translation>
+ </message>
+ </context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>таңба</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Адрес</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(таңбасыз)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Құпия сөзді енгізу</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Жаңа құпия сөзі</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Жаңа құпия сөзді қайта енгізу</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>Әмиянді шифрлау</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>Бұл операциясы бойынша сіздің әмиянізді қоршаудан шығару үшін әмиянның құпия сөзі керек</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Әмиянізді қоршаудан шығару</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>Бұл операциясы бойынша сіздің әмиянізді шифрлап тастау үшін әмиянның құпия сөзі керек</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>Әмиянізді шифрлап тастау</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>Құпия сөзді өзгерту</translation>
+ </message>
+ </context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Транзакциялар</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>Шығу</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>Параметрлері</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>Әмиянды жасыру</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>Құпия сөзді өзгерту</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Биткоин</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>Әмиян</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>Жіберу</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>Алу</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>Файл</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>Көмек</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n hour(s)</source>
+ <translation><numerusform>%n сағат</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n day(s)</source>
+ <translation><numerusform>%n күн</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n week(s)</source>
+ <translation><numerusform>%n апта</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 and %2</source>
+ <translation>%1 немесе %2</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n year(s)</source>
+ <translation><numerusform>%n жыл</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 behind</source>
+ <translation>%1 қалмады</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>қате</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Ескерту</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Информация</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>Жаңартылған</translation>
+ </message>
+ </context>
+<context>
+ <name>ClientModel</name>
+ </context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Amount:</source>
+ <translation>Саны</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Басымдық</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Комиссия</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Шаң</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Комиссия алу кейін</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Саны</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Күні</translation>
+ </message>
+ <message>
+ <source>Confirmations</source>
+ <translation>Растау саны</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Растық</translation>
+ </message>
+ <message>
+ <source>Priority</source>
+ <translation>Басымдық</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>жоқ</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(таңбасыз)</translation>
+ </message>
+ </context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>&amp;Address</source>
+ <translation>Адрес</translation>
+ </message>
+ </context>
+<context>
+ <name>FreespaceChecker</name>
+ </context>
+<context>
+ <name>HelpMessageDialog</name>
+ </context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Error</source>
+ <translation>қате</translation>
+ </message>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ </context>
+<context>
+ <name>OptionsDialog</name>
+ </context>
+<context>
+ <name>OverviewPage</name>
+ </context>
+<context>
+ <name>PaymentServer</name>
+ </context>
+<context>
+ <name>PeerTableModel</name>
+ </context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>Саны</translation>
+ </message>
+ </context>
+<context>
+ <name>QRImageWidget</name>
+ </context>
+<context>
+ <name>RPCConsole</name>
+ </context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ </context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>Address</source>
+ <translation>Адрес</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Саны</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>таңба</translation>
+ </message>
+ </context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Күні</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>таңба</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Саны</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(таңбасыз)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Amount:</source>
+ <translation>Саны</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Басымдық</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Комиссия:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Комиссия алу кейін:</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Шаң</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(таңбасыз)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsEntry</name>
+ </context>
+<context>
+ <name>ShutdownWindow</name>
+ </context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ </context>
+<context>
+ <name>SplashScreen</name>
+ </context>
+<context>
+ <name>TrafficGraphWidget</name>
+ </context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Date</source>
+ <translation>Күні</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Саны</translation>
+ </message>
+ </context>
+<context>
+ <name>TransactionDescDialog</name>
+ </context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Күні</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>таңба</translation>
+ </message>
+ </context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Үтірмен бөлінген файл (*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Растық</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Күні</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>таңба</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Адрес</translation>
+ </message>
+ </context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ </context>
+<context>
+ <name>WalletFrame</name>
+ </context>
+<context>
+ <name>WalletModel</name>
+ </context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>Экспорт</translation>
+ </message>
+ </context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Information</source>
+ <translation>Информация</translation>
+ </message>
+ <message>
+ <source>Transaction amount too small</source>
+ <translation>Транзакция өте кішкентай</translation>
+ </message>
+ <message>
+ <source>Transaction too large</source>
+ <translation>Транзакция өте үлкен</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Ескерту</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>қате</translation>
+ </message>
+</context>
+</TS> \ No newline at end of file
diff --git a/src/qt/locale/bitcoin_ko_KR.ts b/src/qt/locale/bitcoin_ko_KR.ts
new file mode 100644
index 0000000000..089e5afbb9
--- /dev/null
+++ b/src/qt/locale/bitcoin_ko_KR.ts
@@ -0,0 +1,2624 @@
+<TS language="ko_KR" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Right-click to edit address or label</source>
+ <translation>지갑 주소나 이름을 수정하려면 우클릭하세요.</translation>
+ </message>
+ <message>
+ <source>Create a new address</source>
+ <translation>새 주소 만들기</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>새 항목(N)</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>현재 선택한 주소를 시스템 클립보드로 복사하기</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>복사</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>닫기 (L)</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>계좌 복사(&amp;C)</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>현재 목록에 선택한 주소 삭제</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>현재 탭에 있는 데이터를 파일로 내보내기</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;내보내기</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;삭제</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>코인을 보내실 주소를 선택하세요</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>코인을 받으실 주소를 선택하세요</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>선택하기 (H)</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>보내는 주소들</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>받은 주소들</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>비트코인을 받는 계좌 주소입니다. 코인을 보내기 전에 잔고와 받는 주소를 항상 확인하세요.</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>비트코인을 받을 수 있는 계좌 주소입니다. 매 거래마다 새로운 주소 사용을 권장합니다. </translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>표 복사</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>편집&amp;</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>주소 목록 내보내기</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>각각의 파일에 쉼표하기(*.csv)</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>내보내기 실패</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the address list to %1. Please try again.</source>
+ <translation>%1으로 주소 리스트를 저장하는 동안 오류가 발생했습니다. 다시 시도해주세요.</translation>
+ </message>
+</context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>표</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>주소</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(표 없음)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Passphrase Dialog</source>
+ <translation>암호문 대화상자</translation>
+ </message>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>암호 입력하기</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>새로운 암호</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>새 암호 반복</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>지갑 암호화</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>이 작업을 실행하려면 사용자 지갑의 암호가 필요합니다.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>지갑 열기</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>이 작업은 지갑을 해독하기 위해 사용자 지갑의 암호가 필요합니다.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>지갑 해독</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>암호 변경</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>지갑의 암호화를 확정</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>경고: 만약 암호화된 지갑의 비밀번호를 잃어버릴 경우, 모든 비트코인들을 잃어버릴 수 있습니다!</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>지갑 암호화를 허용하시겠습니까?</translation>
+ </message>
+ <message>
+ <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
+ <translation>중요: 본인 지갑파일에서 만든 예전 백업들은 새로 생성한 암화화된 지갑 파일로 교체됩니다. 보안상 이유로 이전에 암호화 하지 않은 지갑 파일 백업은 사용할 수 없게 되니 빠른 시일 내로 새로 암화화된 지갑을 사용하시기 바랍니다.</translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>경고: 캡스록 키가 켜져있습니다!</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>지갑 암호화 완료</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>지갑 암호화 실패</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>지갑 암호화는 내부 에러로 인해 실패했습니다. 당신의 지갑은 암호화 되지 않았습니다.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>지정한 암호가 일치하지 않습니다.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>지갑을 열지 못했습니다.</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>지갑 해독을 위한 암호가 틀렸습니다.</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>지갑 해독에 실패하였습니다.</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>지갑 비밀번호가 성공적으로 변경되었습니다.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>메시지 서명&amp;...</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>네트워크와 동기화중...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;개요</translation>
+ </message>
+ <message>
+ <source>Node</source>
+ <translation>노드</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>지갑의 일반적 개요를 보여줍니다.</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;거래</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>거래내역을 검색합니다.</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>나가기(&amp;X)</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>적용 중단</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>Qt 정보(&amp;Q)</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>Qt 정보를 표시합니다</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;옵션</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>지갑 암호화&amp;...</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>지갑 백업&amp;...</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>암호문 변경&amp;...</translation>
+ </message>
+ <message>
+ <source>&amp;Sending addresses...</source>
+ <translation>&amp;주소 보내는 중</translation>
+ </message>
+ <message>
+ <source>&amp;Receiving addresses...</source>
+ <translation>&amp; 주소 받는 중</translation>
+ </message>
+ <message>
+ <source>Open &amp;URI...</source>
+ <translation>URI&amp;열기...</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core client</source>
+ <translation>비트코인 코어 클라이언트</translation>
+ </message>
+ <message>
+ <source>Importing blocks from disk...</source>
+ <translation>디스크에서 블록 가져오는 중...</translation>
+ </message>
+ <message>
+ <source>Reindexing blocks on disk...</source>
+ <translation>디스크에서 블록 다시 색인중...</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>비트코인 주소로 코인 전송</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>지갑을 다른장소에 백업</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>지갑 암호화에 사용되는 암호를 변경합니다</translation>
+ </message>
+ <message>
+ <source>&amp;Debug window</source>
+ <translation>디버그 창&amp;</translation>
+ </message>
+ <message>
+ <source>Open debugging and diagnostic console</source>
+ <translation>디버깅 및 진단 콘솔을 엽니다</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>메시지 확인&amp;...</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>비트코인</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>지갑</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>보내기(&amp;S)</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>받기(&amp;R)</translation>
+ </message>
+ <message>
+ <source>Show information about Bitcoin Core</source>
+ <translation>비트코인 코어에 관한 정보입니다.</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>보이기/숨기기(&amp;S)</translation>
+ </message>
+ <message>
+ <source>Show or hide the main Window</source>
+ <translation>메인창 보이기 또는 숨기기</translation>
+ </message>
+ <message>
+ <source>Encrypt the private keys that belong to your wallet</source>
+ <translation>지갑에 포함된 개인키 암호화하기</translation>
+ </message>
+ <message>
+ <source>Sign messages with your Bitcoin addresses to prove you own them</source>
+ <translation>지갑 주소가 본인 소유인지 증명하기 위해 비트코인 주소에 서명할 수 있습니다.</translation>
+ </message>
+ <message>
+ <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source>
+ <translation>비트코인 주소의 전자 서명 확인을 위해 첨부된 메시지가 있을 경우 이를 검증할 수 있습니다.</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;파일</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;설정</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>&amp;도움말</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>툴바 색인표</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>비트코인 코어</translation>
+ </message>
+ <message>
+ <source>Request payments (generates QR codes and bitcoin: URIs)</source>
+ <translation>지불 요청하기 (QR코드와 비트코인이 생성됩니다: URIs)</translation>
+ </message>
+ <message>
+ <source>&amp;About Bitcoin Core</source>
+ <translation>&amp;비트코인 코어 소개</translation>
+ </message>
+ <message>
+ <source>Show the list of used sending addresses and labels</source>
+ <translation>한번 이상 사용된 보내는 주소와 주소 제목의 목록을 보여줍니다.</translation>
+ </message>
+ <message>
+ <source>Show the list of used receiving addresses and labels</source>
+ <translation>한번 이상 사용된 받는 주소와 주소 제목의 목록을 보여줍니다.</translation>
+ </message>
+ <message>
+ <source>Open a bitcoin: URI or payment request</source>
+ <translation>bitcoin: URI 또는 지불요청 열기</translation>
+ </message>
+ <message>
+ <source>&amp;Command-line options</source>
+ <translation>명령어-라인 옵션</translation>
+ </message>
+ <message>
+ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
+ <translation>사용할 수 있는 비트코인 명령어 옵션 목록을 가져오기 위해 Bitcoin-Qt 도움말 메시지를 표시합니다.</translation>
+ </message>
+ <message>
+ <source>No block source available...</source>
+ <translation>사용 가능한 블록이 없습니다...</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n hour(s)</source>
+ <translation><numerusform>%n시간</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n day(s)</source>
+ <translation><numerusform>%n일</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n week(s)</source>
+ <translation><numerusform>%n주</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 and %2</source>
+ <translation>%1 그리고 %2</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n year(s)</source>
+ <translation><numerusform>%n년</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 behind</source>
+ <translation>%1 뒤에</translation>
+ </message>
+ <message>
+ <source>Last received block was generated %1 ago.</source>
+ <translation>최근에 받은 블록은 %1 전에 생성되었습니다.</translation>
+ </message>
+ <message>
+ <source>Transactions after this will not yet be visible.</source>
+ <translation>이 후의 거래들은 아직 보이지 않을 것입니다.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>오류</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>경고</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>정보</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>현재까지</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>블록 따라잡기...</translation>
+ </message>
+ <message>
+ <source>Date: %1
+</source>
+ <translation>날짜: %1
+</translation>
+ </message>
+ <message>
+ <source>Amount: %1
+</source>
+ <translation>금액: %1
+</translation>
+ </message>
+ <message>
+ <source>Type: %1
+</source>
+ <translation>종류: %1
+</translation>
+ </message>
+ <message>
+ <source>Label: %1
+</source>
+ <translation>라벨: %1
+</translation>
+ </message>
+ <message>
+ <source>Address: %1
+</source>
+ <translation>주소: %1
+</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>거래 보내기</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>들어오고 있는 거래</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>지갑이 암호화 되었고 현재 차단해제 되었습니다</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>지갑이 암호화 되었고 현재 잠겨져 있습니다</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <source>Network Alert</source>
+ <translation>네트워크 경고</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Coin Selection</source>
+ <translation>코인 선택</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>수량:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>바이트:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>금액:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>우선순위:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>수수료:</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>더스트:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>수수료 이후:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>체인지:</translation>
+ </message>
+ <message>
+ <source>(un)select all</source>
+ <translation>모두 선택(하지 않음)</translation>
+ </message>
+ <message>
+ <source>Tree mode</source>
+ <translation>트리 모드</translation>
+ </message>
+ <message>
+ <source>List mode</source>
+ <translation>리스트 모드</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>거래량</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>날짜</translation>
+ </message>
+ <message>
+ <source>Confirmations</source>
+ <translation>확인</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>확인됨</translation>
+ </message>
+ <message>
+ <source>Priority</source>
+ <translation>우선순위</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>주소 복사하기</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>표 복사하기</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>거래량 복사</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>거래 아이디 복사</translation>
+ </message>
+ <message>
+ <source>Lock unspent</source>
+ <translation>비트코인이 사용되지 않은 주소를 잠금 처리합니다.</translation>
+ </message>
+ <message>
+ <source>Unlock unspent</source>
+ <translation>비트코인이 사용되지 않은 주소를 잠금 해제합니다. </translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>수량 복사</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>수수료 복사</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>수수료 이후 복사</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>bytes 복사</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>우선도 복사</translation>
+ </message>
+ <message>
+ <source>highest</source>
+ <translation>아주 높음</translation>
+ </message>
+ <message>
+ <source>higher</source>
+ <translation>보다 높음</translation>
+ </message>
+ <message>
+ <source>high</source>
+ <translation>높음</translation>
+ </message>
+ <message>
+ <source>medium-high</source>
+ <translation>약간 높음</translation>
+ </message>
+ <message>
+ <source>medium</source>
+ <translation>보통</translation>
+ </message>
+ <message>
+ <source>low-medium</source>
+ <translation>약간 낮음</translation>
+ </message>
+ <message>
+ <source>low</source>
+ <translation>낮음</translation>
+ </message>
+ <message>
+ <source>lower</source>
+ <translation>보다 낮음</translation>
+ </message>
+ <message>
+ <source>lowest</source>
+ <translation>아주 낮음</translation>
+ </message>
+ <message>
+ <source>(%1 locked)</source>
+ <translation>(%1 잠금)</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>없음</translation>
+ </message>
+ <message>
+ <source>yes</source>
+ <translation>예</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>아니요</translation>
+ </message>
+ <message>
+ <source>This means a fee of at least %1 per kB is required.</source>
+ <translation>이 의미는 수수료가 최소한 %1 per 키로바이트 필요합니다</translation>
+ </message>
+ <message>
+ <source>Transactions with higher priority are more likely to get included into a block.</source>
+ <translation>우선 순위가 높은 거래의 경우 블럭에 포함될 가능성이 더 많습니다.</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(표 없음)</translation>
+ </message>
+ <message>
+ <source>change from %1 (%2)</source>
+ <translation>~로부터 변경 %1 (%2)</translation>
+ </message>
+ </context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>주소 편집</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>&amp;표</translation>
+ </message>
+ <message>
+ <source>The label associated with this address list entry</source>
+ <translation>현재 선택된 주소 필드의 제목입니다. </translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;주소</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>새로 받는 주소</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>새로 보내는 주소</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>받는 주소 편집</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>보내는 주소 편집</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>입력된 주소는"%1" 이미 주소록에 있습니다.</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is not a valid Bitcoin address.</source>
+ <translation>입력한 "%1" 주소는 올바른 비트코인 주소가 아닙니다.</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>지갑을 열 수 없습니다.</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>새로운 키 생성이 실패하였습니다</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ <message>
+ <source>A new data directory will be created.</source>
+ <translation>새로운 데이터 폴더가 생성됩니다.</translation>
+ </message>
+ <message>
+ <source>name</source>
+ <translation>이름</translation>
+ </message>
+ <message>
+ <source>Directory already exists. Add %1 if you intend to create a new directory here.</source>
+ <translation>폴더가 이미 존재합니다. 새로운 폴더 생성을 원한다면 %1 명령어를 추가하세요. </translation>
+ </message>
+ <message>
+ <source>Path already exists, and is not a directory.</source>
+ <translation>경로가 이미 존재합니다. 그리고 그것은 폴더가 아닙니다.</translation>
+ </message>
+ <message>
+ <source>Cannot create data directory here.</source>
+ <translation>데이터 폴더를 여기 생성할 수 없습니다.</translation>
+ </message>
+</context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>비트코인 코어</translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>버전</translation>
+ </message>
+ <message>
+ <source>(%1-bit)</source>
+ <translation>(%1-비트)</translation>
+ </message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>비트코인 코어 소개</translation>
+ </message>
+ <message>
+ <source>Command-line options</source>
+ <translation>명령줄 옵션</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>사용법:</translation>
+ </message>
+ <message>
+ <source>command-line options</source>
+ <translation>명령줄 옵션</translation>
+ </message>
+</context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Welcome</source>
+ <translation>환영합니다</translation>
+ </message>
+ <message>
+ <source>Welcome to Bitcoin Core.</source>
+ <translation>비트코인 코어에 오신것을 환영합니.</translation>
+ </message>
+ <message>
+ <source>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</source>
+ <translation>프로그램이 처음으로 실행되고 있습니다. 비트코인 코어가 어디에 데이터를 저장할지 선택할 수 있습니다. </translation>
+ </message>
+ <message>
+ <source>Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory.</source>
+ <translation>비트코인 코어가 블럭체인의 복사본을 다운로드 저장합니다. 적어도 %1GB의 데이터가 이 폴더에 저장되며 시간이 경과할수록 점차 증가합니다. 그리고 지갑 또한 이 폴더에 저장됩니다. </translation>
+ </message>
+ <message>
+ <source>Use the default data directory</source>
+ <translation>기본 데이터 폴더를 사용하기</translation>
+ </message>
+ <message>
+ <source>Use a custom data directory:</source>
+ <translation>커스텀 데이터 폴더 사용:</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>비트코인 코어</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>오류</translation>
+ </message>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ <message>
+ <source>Open URI</source>
+ <translation>URI 열기</translation>
+ </message>
+ <message>
+ <source>Open payment request from URI or file</source>
+ <translation>지급 요청 URI 또는 파일 열기</translation>
+ </message>
+ <message>
+ <source>URI:</source>
+ <translation>URI:</translation>
+ </message>
+ <message>
+ <source>Select payment request file</source>
+ <translation>지불 요청 파일을 선택하세요</translation>
+ </message>
+ <message>
+ <source>Select payment request file to open</source>
+ <translation>지불 요청 파일을 열기 위해서 선택하세요</translation>
+ </message>
+</context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>선택들</translation>
+ </message>
+ <message>
+ <source>&amp;Main</source>
+ <translation>메인(&amp;M)</translation>
+ </message>
+ <message>
+ <source>Size of &amp;database cache</source>
+ <translation>데이터베이스 캐시 크기</translation>
+ </message>
+ <message>
+ <source>MB</source>
+ <translation>메가바이트</translation>
+ </message>
+ <message>
+ <source>Number of script &amp;verification threads</source>
+ <translation>스크립트 인증 쓰레드의 개수</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside</source>
+ <translation>외부로부터의 연결을 승인합니다.</translation>
+ </message>
+ <message>
+ <source>Allow incoming connections</source>
+ <translation>연결 요청을 허용합니다.</translation>
+ </message>
+ <message>
+ <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
+ <translation>프록시 아이피 주소(예. IPv4:127.0.0.1 / IPv6: ::1)</translation>
+ </message>
+ <message>
+ <source>Third party transaction URLs</source>
+ <translation>제 3자 거래 URLs</translation>
+ </message>
+ <message>
+ <source>Active command-line options that override above options:</source>
+ <translation>명령어 라인 옵션을 활성화해서 옵션을 우회하시오</translation>
+ </message>
+ <message>
+ <source>Reset all client options to default.</source>
+ <translation>모든 클라이언트 옵션을 기본값으로 재설정</translation>
+ </message>
+ <message>
+ <source>&amp;Reset Options</source>
+ <translation>옵션 재설정(&amp;R)</translation>
+ </message>
+ <message>
+ <source>&amp;Network</source>
+ <translation>네트워크(&amp;N)</translation>
+ </message>
+ <message>
+ <source>W&amp;allet</source>
+ <translation>지갑</translation>
+ </message>
+ <message>
+ <source>Expert</source>
+ <translation>전문가</translation>
+ </message>
+ <message>
+ <source>Enable coin &amp;control features</source>
+ <translation>코인 상세 제어기능을 활성화합니다 - &amp;C</translation>
+ </message>
+ <message>
+ <source>&amp;Spend unconfirmed change</source>
+ <translation>&amp;확인되지 않은 돈을 쓰다</translation>
+ </message>
+ <message>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>라우터의 비트코인 클라이언트 포트를 자동으로 엽니다. 라우터에서 UPnP를 지원하고 활성화 했을 경우에만 동작합니다.</translation>
+ </message>
+ <message>
+ <source>Map port using &amp;UPnP</source>
+ <translation>사용중인 UPnP 포트 매핑(&amp;U)</translation>
+ </message>
+ <message>
+ <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
+ <translation>SOCKS5 프록시를 통해 비트코인 네트워크 연결</translation>
+ </message>
+ <message>
+ <source>&amp;Connect through SOCKS5 proxy (default proxy):</source>
+ <translation>SOCKS5 프록시를 거쳐 연결합니다 (기본값 프록시):</translation>
+ </message>
+ <message>
+ <source>Proxy &amp;IP:</source>
+ <translation>프록시 IP(&amp;I):</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>포트(&amp;P):</translation>
+ </message>
+ <message>
+ <source>Port of the proxy (e.g. 9050)</source>
+ <translation>프록시의 포트번호입니다(예: 9050)</translation>
+ </message>
+ <message>
+ <source>&amp;Window</source>
+ <translation>창(&amp;W)</translation>
+ </message>
+ <message>
+ <source>Show only a tray icon after minimizing the window.</source>
+ <translation>창을 최소화 하면 트레이에 아이콘만 표시합니다.</translation>
+ </message>
+ <message>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>작업 표시줄 대신 트레이로 최소화(&amp;M)</translation>
+ </message>
+ <message>
+ <source>M&amp;inimize on close</source>
+ <translation>닫을때 최소화(&amp;I)</translation>
+ </message>
+ <message>
+ <source>&amp;Display</source>
+ <translation>표시(&amp;D)</translation>
+ </message>
+ <message>
+ <source>User Interface &amp;language:</source>
+ <translation>사용자 인터페이스 언어(&amp;L):</translation>
+ </message>
+ <message>
+ <source>&amp;Unit to show amounts in:</source>
+ <translation>거래액을 표시할 단위(&amp;U):</translation>
+ </message>
+ <message>
+ <source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
+ <translation>인터페이스에 표시하고 코인을 보낼때 사용할 기본 최소화 단위를 선택하십시오.</translation>
+ </message>
+ <message>
+ <source>Whether to show coin control features or not.</source>
+ <translation>코인 상세 제어기능에 대한 표시 여부를 선택할 수 있습니다.</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>확인(&amp;O)</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>취소(&amp;C)</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>기본값</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>없음</translation>
+ </message>
+ <message>
+ <source>Confirm options reset</source>
+ <translation>옵션 초기화를 확인</translation>
+ </message>
+ <message>
+ <source>Client restart required to activate changes.</source>
+ <translation>변경 사항을 적용하기 위해서는 프로그램이 종료 후 재시작되어야 합니다.</translation>
+ </message>
+ <message>
+ <source>This change would require a client restart.</source>
+ <translation>이 변경 사항 적용을 위해 프로그램 재시작이 필요합니다. </translation>
+ </message>
+ <message>
+ <source>The supplied proxy address is invalid.</source>
+ <translation>지정한 프록시 주소가 잘못되었습니다.</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>유형</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>표시한 정보가 오래된 것 같습니다. 비트코인 네트워크에 연결하고 난 다음에 지갑을 자동으로 동기화 하지만, 아직 과정이 끝나지는 않았습니다.</translation>
+ </message>
+ <message>
+ <source>Watch-only:</source>
+ <translation>모니터링 지갑:</translation>
+ </message>
+ <message>
+ <source>Available:</source>
+ <translation>사용 가능</translation>
+ </message>
+ <message>
+ <source>Your current spendable balance</source>
+ <translation>당신의 현재 사용 가능한 잔액</translation>
+ </message>
+ <message>
+ <source>Pending:</source>
+ <translation>미확정</translation>
+ </message>
+ <message>
+ <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source>
+ <translation>전체 거래들은 아직 확인되지 않았고, 그리고 현재 잔액에 아직 반영되지 않았습니다.</translation>
+ </message>
+ <message>
+ <source>Immature:</source>
+ <translation>아직 사용 불가능:</translation>
+ </message>
+ <message>
+ <source>Mined balance that has not yet matured</source>
+ <translation>아직 사용 가능하지 않은 채굴된 잔액</translation>
+ </message>
+ <message>
+ <source>Total:</source>
+ <translation>총액:</translation>
+ </message>
+ <message>
+ <source>Your current total balance</source>
+ <translation>당신의 현재 총액</translation>
+ </message>
+ <message>
+ <source>Your current balance in watch-only addresses</source>
+ <translation>모니터링 지갑의 현재 잔액</translation>
+ </message>
+ </context>
+<context>
+ <name>PaymentServer</name>
+ <message>
+ <source>URI handling</source>
+ <translation>URI 조작중</translation>
+ </message>
+ <message>
+ <source>Invalid payment address %1</source>
+ <translation>잘못된 지불 주소입니다 %1</translation>
+ </message>
+ <message>
+ <source>Requested payment amount of %1 is too small (considered dust).</source>
+ <translation>요청한 금액 %1의 양이 너무 적습니다. (스팸성 거래로 간주)</translation>
+ </message>
+ <message>
+ <source>Payment request error</source>
+ <translation>지불 요청 애러</translation>
+ </message>
+ <message>
+ <source>Cannot start bitcoin: click-to-pay handler</source>
+ <translation>비트코인을 시작할 수 없습니다: 지급제어기를 클릭하시오</translation>
+ </message>
+ <message>
+ <source>Payment request fetch URL is invalid: %1</source>
+ <translation>대금 청구서의 URL이 올바르지 않습니다: %1</translation>
+ </message>
+ <message>
+ <source>Payment request file handling</source>
+ <translation>지불이 파일 처리를 요청합니다</translation>
+ </message>
+ <message>
+ <source>Unverified payment requests to custom payment scripts are unsupported.</source>
+ <translation>임의로 변경한 결제 스크립트 기반의 대금 청구서 양식은 검증되기 전까지는 지원되지 않습니다.</translation>
+ </message>
+ <message>
+ <source>Refund from %1</source>
+ <translation>%1 으로부터의 환불</translation>
+ </message>
+ <message>
+ <source>Error communicating with %1: %2</source>
+ <translation>%1과 소통하는데 애러: %2</translation>
+ </message>
+ <message>
+ <source>Bad response from server %1</source>
+ <translation>서버로 부터 반응이 없습니다 %1</translation>
+ </message>
+ <message>
+ <source>Payment acknowledged</source>
+ <translation>지불이 승인됨</translation>
+ </message>
+ <message>
+ <source>Network request error</source>
+ <translation>네트워크 요청 애러</translation>
+ </message>
+</context>
+<context>
+ <name>PeerTableModel</name>
+ </context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>거래량</translation>
+ </message>
+ <message>
+ <source>Enter a Bitcoin address (e.g. %1)</source>
+ <translation>비트코인 주소를 입력하기 (예. %1)</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>없음</translation>
+ </message>
+ </context>
+<context>
+ <name>QRImageWidget</name>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>이미지 저장(&amp;S)...</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Image</source>
+ <translation>이미지 복사(&amp;C)</translation>
+ </message>
+ <message>
+ <source>Save QR Code</source>
+ <translation>QR코드 저장</translation>
+ </message>
+ <message>
+ <source>PNG Image (*.png)</source>
+ <translation>PNG 이미지(*.png)</translation>
+ </message>
+</context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>Client name</source>
+ <translation>클라이언트 이름</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>없음</translation>
+ </message>
+ <message>
+ <source>Client version</source>
+ <translation>클라이언트 버전</translation>
+ </message>
+ <message>
+ <source>&amp;Information</source>
+ <translation>정보</translation>
+ </message>
+ <message>
+ <source>Debug window</source>
+ <translation>디버그 창</translation>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>일반</translation>
+ </message>
+ <message>
+ <source>Using OpenSSL version</source>
+ <translation>오픈SSL 버전을 사용합니다</translation>
+ </message>
+ <message>
+ <source>Startup time</source>
+ <translation>시작 시간</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>네트워크</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>이름</translation>
+ </message>
+ <message>
+ <source>Number of connections</source>
+ <translation>연결 수</translation>
+ </message>
+ <message>
+ <source>Block chain</source>
+ <translation>블럭 체인</translation>
+ </message>
+ <message>
+ <source>Current number of blocks</source>
+ <translation>현재 블럭 수</translation>
+ </message>
+ <message>
+ <source>Last block time</source>
+ <translation>최종 블럭 시각</translation>
+ </message>
+ <message>
+ <source>&amp;Open</source>
+ <translation>열기(&amp;O)</translation>
+ </message>
+ <message>
+ <source>&amp;Console</source>
+ <translation>콘솔(&amp;C)</translation>
+ </message>
+ <message>
+ <source>&amp;Network Traffic</source>
+ <translation>&amp;네트워크 트래픽</translation>
+ </message>
+ <message>
+ <source>&amp;Clear</source>
+ <translation>&amp;지우기</translation>
+ </message>
+ <message>
+ <source>Totals</source>
+ <translation>총액</translation>
+ </message>
+ <message>
+ <source>In:</source>
+ <translation>In:</translation>
+ </message>
+ <message>
+ <source>Out:</source>
+ <translation>Out:</translation>
+ </message>
+ <message>
+ <source>Build date</source>
+ <translation>빌드 날짜</translation>
+ </message>
+ <message>
+ <source>Debug log file</source>
+ <translation>로그 파일 디버그</translation>
+ </message>
+ <message>
+ <source>Clear console</source>
+ <translation>콘솔 초기화</translation>
+ </message>
+ <message>
+ <source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
+ <translation>기록을 찾아보려면 위 아래 화살표 키를, 화면을 지우려면 &lt;b&gt;Ctrl-L&lt;/b&gt;키를 사용하십시오.</translation>
+ </message>
+ <message>
+ <source>Type &lt;b&gt;help&lt;/b&gt; for an overview of available commands.</source>
+ <translation>사용할 수 있는 명령을 둘러보려면 &lt;b&gt;help&lt;/b&gt;를 입력하십시오.</translation>
+ </message>
+ </context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Amount:</source>
+ <translation>&amp;거래량:</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>표:</translation>
+ </message>
+ <message>
+ <source>&amp;Message:</source>
+ <translation>&amp;메시지:</translation>
+ </message>
+ <message>
+ <source>Reuse one of the previously used receiving addresses. Reusing addresses has security and privacy issues. Do not use this unless re-generating a payment request made before.</source>
+ <translation>이전에 사용된 수취용 주소를 사용할려고 합니다. 주소의 재사용은 보안과 개인정보 보호 측면에서 문제를 초래할 수 있습니다. 이전 지불 요청을 재생성하는 경우가 아니라면 주소 재사용을 권하지 않습니다. </translation>
+ </message>
+ <message>
+ <source>R&amp;euse an existing receiving address (not recommended)</source>
+ <translation>현재의 수취용 주소를 재사용합니다만 권장하지는 않습니다. (R&amp;)</translation>
+ </message>
+ <message>
+ <source>An optional label to associate with the new receiving address.</source>
+ <translation>임의의 라벨이 새로운 받기 주소와 결합</translation>
+ </message>
+ <message>
+ <source>Use this form to request payments. All fields are &lt;b&gt;optional&lt;/b&gt;.</source>
+ <translation>지급을 요청하기 위해 아래 형식을 사용하세요. 입력값은 &lt;b&gt;선택 사항&lt;/b&gt; 입니다.</translation>
+ </message>
+ <message>
+ <source>An optional amount to request. Leave this empty or zero to not request a specific amount.</source>
+ <translation>요청할 금액 입력칸으로 선택 사항입니다. 빈 칸으로 두거나 특정 금액이 필요하지 않는 경우 0을 입력하세요. </translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>양식의 모든 필드를 지웁니다</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation>지우기</translation>
+ </message>
+ <message>
+ <source>Requested payments history</source>
+ <translation>지출기록 확인</translation>
+ </message>
+ <message>
+ <source>&amp;Request payment</source>
+ <translation>지불 요청(&amp;R)</translation>
+ </message>
+ <message>
+ <source>Show</source>
+ <translation>보기</translation>
+ </message>
+ <message>
+ <source>Remove the selected entries from the list</source>
+ <translation>목록에서 삭제할 항목을 선택하시오</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>삭제</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>표 복사하기</translation>
+ </message>
+ <message>
+ <source>Copy message</source>
+ <translation>메시지 복사</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>거래량 복사</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>QR Code</source>
+ <translation>QR 코드</translation>
+ </message>
+ <message>
+ <source>Copy &amp;URI</source>
+ <translation>URI 복사(&amp;U)</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Address</source>
+ <translation>주소 복사(&amp;A)</translation>
+ </message>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>이미지 저장(&amp;S)...</translation>
+ </message>
+ <message>
+ <source>Request payment to %1</source>
+ <translation>%1에 지불을 요청했습니다</translation>
+ </message>
+ <message>
+ <source>Payment information</source>
+ <translation>지불 정보</translation>
+ </message>
+ <message>
+ <source>URI</source>
+ <translation>URI</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>주소</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>거래량</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>표</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>메시지</translation>
+ </message>
+ <message>
+ <source>Resulting URI too long, try to reduce the text for label / message.</source>
+ <translation>URI 결과가 너무 길음, 표/메세지의 글을 줄이도록 하세요.</translation>
+ </message>
+ <message>
+ <source>Error encoding URI into QR Code.</source>
+ <translation>QR코드 인코딩 오류</translation>
+ </message>
+</context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>날짜</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>표</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>메시지</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>거래량</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(표 없음)</translation>
+ </message>
+ <message>
+ <source>(no message)</source>
+ <translation>(메세지가 없습니다)</translation>
+ </message>
+ <message>
+ <source>(no amount)</source>
+ <translation>(거래량 없음)</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>코인들 보내기</translation>
+ </message>
+ <message>
+ <source>Coin Control Features</source>
+ <translation>코인 컨트롤 기능들</translation>
+ </message>
+ <message>
+ <source>Inputs...</source>
+ <translation>입력...</translation>
+ </message>
+ <message>
+ <source>automatically selected</source>
+ <translation>자동 선택</translation>
+ </message>
+ <message>
+ <source>Insufficient funds!</source>
+ <translation>자금이 부족합니다!</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>수량:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>바이트:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>거래량:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>우선순위:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>수수료:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>수수료 이후:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>체인지:</translation>
+ </message>
+ <message>
+ <source>Custom change address</source>
+ <translation>주소변경</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>다수의 수령인들에게 한번에 보내기</translation>
+ </message>
+ <message>
+ <source>Add &amp;Recipient</source>
+ <translation>수령인 추가하기</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>양식의 모든 필드를 지웁니다</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>더스트:</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>모두 지우기(&amp;A)</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>잔액:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>전송 기능 확인</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>보내기(&amp;E)</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>코인 전송을 확인</translation>
+ </message>
+ <message>
+ <source>%1 to %2</source>
+ <translation>%1을(를) %2(으)로</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>수량 복사</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>거래량 복사</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>수수료 복사</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>수수료 이후 복사</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>bytes 복사</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>우선도 복사</translation>
+ </message>
+ <message>
+ <source>or</source>
+ <translation>또는</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>지불하는 금액은 0 보다 커야 합니다.</translation>
+ </message>
+ <message>
+ <source>The amount exceeds your balance.</source>
+ <translation>잔고를 초과하였습니다.</translation>
+ </message>
+ <message>
+ <source>The total exceeds your balance when the %1 transaction fee is included.</source>
+ <translation>%1 의 거래수수료를 포함하면 잔고를 초과합니다.</translation>
+ </message>
+ <message>
+ <source>Transaction creation failed!</source>
+ <translation>거래를 생성하는 것을 실패하였습니다</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>거래가 거부되었습니다. 몇몇 코인들이 지갑에서 이미 사용된 경우, 예를 들어 코인을 이미 사용한 wallet.dat를 복사해서 사용한 경우 지금 지갑에 기록이 안되있어 이런 일이 생길 수 있습니다.</translation>
+ </message>
+ <message>
+ <source>Warning: Invalid Bitcoin address</source>
+ <translation>경고: 잘못된 비트코인주소입니다</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(표 없음)</translation>
+ </message>
+ <message>
+ <source>Warning: Unknown change address</source>
+ <translation>경고: 알려지지 않은 주소변경입니다</translation>
+ </message>
+ <message>
+ <source>Are you sure you want to send?</source>
+ <translation>정말로 보내시겠습니까?</translation>
+ </message>
+ <message>
+ <source>added as transaction fee</source>
+ <translation>거래 수수료로 추가됨</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>금액:</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>지급&amp;수신:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>당신의 주소록에 이 주소를 추가하기 위하여 표를 입역하세요 </translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>표:</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>이전에 사용한 주소를 선택하십시오</translation>
+ </message>
+ <message>
+ <source>This is a normal payment.</source>
+ <translation>평균지급입니다</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>클립보드로 부터 주소를 붙이세요</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Remove this entry</source>
+ <translation>항목을 지우시오</translation>
+ </message>
+ <message>
+ <source>Message:</source>
+ <translation>메시지:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to the list of used addresses</source>
+ <translation>사용된 주소 목록에 새 주소를 추가하기 위해 제목을 입력합니다. </translation>
+ </message>
+ <message>
+ <source>A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network.</source>
+ <translation>비트코인에 첨부된 메시지: 참고용으로 거래와 함께 저장될 URI. 메모: 이 메시지는 비트코인 네트워크로 전송되지 않습니다.</translation>
+ </message>
+ <message>
+ <source>Pay To:</source>
+ <translation>송금할 대상 : </translation>
+ </message>
+ <message>
+ <source>Memo:</source>
+ <translation>메모:</translation>
+ </message>
+</context>
+<context>
+ <name>ShutdownWindow</name>
+ <message>
+ <source>Bitcoin Core is shutting down...</source>
+ <translation>비트코인코어가 닫아지고 있습니다</translation>
+ </message>
+ <message>
+ <source>Do not shut down the computer until this window disappears.</source>
+ <translation>창이 사라지기 전까지 컴퓨터를 끄지마시오.</translation>
+ </message>
+</context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Signatures - Sign / Verify a Message</source>
+ <translation>서명 - 싸인 / 메시지 확인</translation>
+ </message>
+ <message>
+ <source>&amp;Sign Message</source>
+ <translation>메시지 서명(&amp;S)</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>이전에 사용한 주소를 선택하십시오</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>클립보드로 부터 주소를 붙이세요</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Enter the message you want to sign here</source>
+ <translation>여기에 서명하려는 메시지를 입력하십시오</translation>
+ </message>
+ <message>
+ <source>Signature</source>
+ <translation>서명</translation>
+ </message>
+ <message>
+ <source>Copy the current signature to the system clipboard</source>
+ <translation>현재 서명을 시스템 클립보드에 복사</translation>
+ </message>
+ <message>
+ <source>Sign the message to prove you own this Bitcoin address</source>
+ <translation>여러분의 비트코인 주소를 증명하려면 메시지 서명하십시오</translation>
+ </message>
+ <message>
+ <source>Sign &amp;Message</source>
+ <translation>메시지에 서명(&amp;M)</translation>
+ </message>
+ <message>
+ <source>Reset all sign message fields</source>
+ <translation>메시지 필드의 모든 서명 재설정</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>모두 지우기(&amp;A)</translation>
+ </message>
+ <message>
+ <source>&amp;Verify Message</source>
+ <translation>메시지 검증(&amp;V)</translation>
+ </message>
+ <message>
+ <source>Verify the message to ensure it was signed with the specified Bitcoin address</source>
+ <translation>정확한 비트코인주소가 입력됬는지 메시지를 확인하시오</translation>
+ </message>
+ <message>
+ <source>Verify &amp;Message</source>
+ <translation>메시지 검증(&amp;M)</translation>
+ </message>
+ <message>
+ <source>Reset all verify message fields</source>
+ <translation>모든 검증 메시지 필드 재설정</translation>
+ </message>
+ <message>
+ <source>Click "Sign Message" to generate signature</source>
+ <translation>서명을 만들려면 "메시지 서명"을 누르십시오</translation>
+ </message>
+ <message>
+ <source>The entered address is invalid.</source>
+ <translation>입력한 주소가 잘못되었습니다.</translation>
+ </message>
+ <message>
+ <source>Please check the address and try again.</source>
+ <translation>주소를 확인하고 다시 시도하십시오.</translation>
+ </message>
+ <message>
+ <source>The entered address does not refer to a key.</source>
+ <translation>입력한 주소는 키에서 참조하지 않습니다.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock was cancelled.</source>
+ <translation>지갑 잠금 해제를 취소했습니다.</translation>
+ </message>
+ <message>
+ <source>Private key for the entered address is not available.</source>
+ <translation>입력한 주소에 대한 개인키가 없습니다.</translation>
+ </message>
+ <message>
+ <source>Message signing failed.</source>
+ <translation>메시지 서명에 실패했습니다.</translation>
+ </message>
+ <message>
+ <source>Message signed.</source>
+ <translation>메시지를 서명했습니다.</translation>
+ </message>
+ <message>
+ <source>The signature could not be decoded.</source>
+ <translation>서명을 해독할 수 없습니다.</translation>
+ </message>
+ <message>
+ <source>Please check the signature and try again.</source>
+ <translation>서명을 확인하고 다시 시도하십시오.</translation>
+ </message>
+ <message>
+ <source>The signature did not match the message digest.</source>
+ <translation>메시지 다이제스트와 서명이 일치하지 않습니다.</translation>
+ </message>
+ <message>
+ <source>Message verification failed.</source>
+ <translation>메시지 검증에 실패했습니다.</translation>
+ </message>
+ <message>
+ <source>Message verified.</source>
+ <translation>메시지를 검증했습니다.</translation>
+ </message>
+</context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>비트코인 코어</translation>
+ </message>
+ <message>
+ <source>The Bitcoin Core developers</source>
+ <translation>비트코인코어 개발자들</translation>
+ </message>
+ <message>
+ <source>[testnet]</source>
+ <translation>[테스트넷]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ <message>
+ <source>KB/s</source>
+ <translation>KB/s</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>%1 까지 열림</translation>
+ </message>
+ <message>
+ <source>conflicted</source>
+ <translation>충돌</translation>
+ </message>
+ <message>
+ <source>%1/offline</source>
+ <translation>%1/오프라인</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/미확인</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 확인됨</translation>
+ </message>
+ <message>
+ <source>Status</source>
+ <translation>상태</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>날짜</translation>
+ </message>
+ <message>
+ <source>Source</source>
+ <translation>소스</translation>
+ </message>
+ <message>
+ <source>Generated</source>
+ <translation>생성하다</translation>
+ </message>
+ <message>
+ <source>From</source>
+ <translation>으로부터</translation>
+ </message>
+ <message>
+ <source>To</source>
+ <translation>에게</translation>
+ </message>
+ <message>
+ <source>own address</source>
+ <translation>자신의 주소</translation>
+ </message>
+ <message>
+ <source>label</source>
+ <translation>라벨</translation>
+ </message>
+ <message>
+ <source>Credit</source>
+ <translation>예금</translation>
+ </message>
+ <message>
+ <source>not accepted</source>
+ <translation>허용되지 않는다</translation>
+ </message>
+ <message>
+ <source>Debit</source>
+ <translation>차변</translation>
+ </message>
+ <message>
+ <source>Transaction fee</source>
+ <translation>송금 수수료</translation>
+ </message>
+ <message>
+ <source>Net amount</source>
+ <translation>총액</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>메시지</translation>
+ </message>
+ <message>
+ <source>Comment</source>
+ <translation>설명</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>아이디</translation>
+ </message>
+ <message>
+ <source>Merchant</source>
+ <translation>상인</translation>
+ </message>
+ <message>
+ <source>Generated coins must mature %1 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.</source>
+ <translation>신규 채굴된 코인이 사용되기 위해서는 %1 개의 블럭이 경과되어야 합니다. 블럭을 생성할 때 블럭체인에 추가되도록 네트워크에 전파되는 과정을 거치는데, 블럭체인에 포함되지 못하고 실패한다면 해당 블럭의 상태는 '미승인'으로 표현되고 비트코인 또한 사용될 수 없습니다. 이 현상은 다른 노드가 비슷한 시간대에 동시에 블럭을 생성할 때 종종 발생할 수 있습니다. </translation>
+ </message>
+ <message>
+ <source>Debug information</source>
+ <translation>디버깅 정보</translation>
+ </message>
+ <message>
+ <source>Transaction</source>
+ <translation>송금</translation>
+ </message>
+ <message>
+ <source>Inputs</source>
+ <translation>입력</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>거래량</translation>
+ </message>
+ <message>
+ <source>true</source>
+ <translation>참</translation>
+ </message>
+ <message>
+ <source>false</source>
+ <translation>거짓</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>. 아직 성공적으로 통보하지 않음</translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>알수없음</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>거래 세부 내역</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>이 창은 거래의 세부내역을 보여줍니다</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>날짜</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>종류</translation>
+ </message>
+ <message>
+ <source>Immature (%1 confirmations, will be available after %2)</source>
+ <translation>충분히 숙성되지 않은 상태 (%1 승인, %2 후에 사용 가능합니다)</translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>%1 까지 열림</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>확인됨(%1 확인됨)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>이 블럭은 다른 노드로부터 받지 않아 허용되지 않을 것임.</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>생성되었으나 거절됨</translation>
+ </message>
+ <message>
+ <source>Offline</source>
+ <translation>오프라인</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>표</translation>
+ </message>
+ <message>
+ <source>Unconfirmed</source>
+ <translation>미확인</translation>
+ </message>
+ <message>
+ <source>Confirming (%1 of %2 recommended confirmations)</source>
+ <translation>승인 중 (권장되는 승인 회수 %2 대비 현재 승인 수 %1)</translation>
+ </message>
+ <message>
+ <source>Conflicted</source>
+ <translation>충돌</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>보낸 주소</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>보낸 주소</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>받는 주소</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>자신에게 지불</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>채굴</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(없음)</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>거래상황. 마우스를 올리면 승인횟수가 표시됩니다.</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>거래가 이루어진 날짜와 시각.</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>거래의 종류.</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>변경된 잔고.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>전체</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>오늘</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>이번주</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>이번 달</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>지난 달</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>올 해</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>범위...</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>보낸 주소</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>받는 주소</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>자기거래</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>채굴</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>기타</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>검색하기 위한 주소 또는 표 입력</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>최소 거래량</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>주소 복사하기</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>표 복사하기</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>거래량 복사</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>거래 아이디 복사</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>표 수정하기</translation>
+ </message>
+ <message>
+ <source>Show transaction details</source>
+ <translation>거래 내역 확인</translation>
+ </message>
+ <message>
+ <source>Export Transaction History</source>
+ <translation>거래 기록 내보내기</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>내보내기 실패</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the transaction history to %1.</source>
+ <translation>%1으로 거래 기록을 저장하는데 애러가 있었습니다.</translation>
+ </message>
+ <message>
+ <source>Exporting Successful</source>
+ <translation>내보내기 성공</translation>
+ </message>
+ <message>
+ <source>The transaction history was successfully saved to %1.</source>
+ <translation>거래 기록이 성공적으로 %1에 저장되었습니다.</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>각각의 파일에 쉼표하기(*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>확인됨</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>날짜</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>종류</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>표</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>주소</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>아이디</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>범위:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>상대방</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ </context>
+<context>
+ <name>WalletFrame</name>
+ <message>
+ <source>No wallet has been loaded.</source>
+ <translation>지갑 불러오기가 안됩니다</translation>
+ </message>
+</context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>코인들 보내기</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;내보내기</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>현재 탭에 있는 데이터를 파일로 내보내기</translation>
+ </message>
+ <message>
+ <source>Backup Wallet</source>
+ <translation>지갑 백업</translation>
+ </message>
+ <message>
+ <source>Wallet Data (*.dat)</source>
+ <translation>지갑 데이터(*.dat)</translation>
+ </message>
+ <message>
+ <source>Backup Failed</source>
+ <translation>백업 실패</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the wallet data to %1.</source>
+ <translation>지갑 데이터를 %1 폴더에 저장하는 동안 오류가 발생했습니다. </translation>
+ </message>
+ <message>
+ <source>The wallet data was successfully saved to %1.</source>
+ <translation>지갑 정보가 %1에 성공적으로 저장되었습니다</translation>
+ </message>
+ <message>
+ <source>Backup Successful</source>
+ <translation>백업 성공</translation>
+ </message>
+</context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>옵션:</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>데이터 폴더 지정</translation>
+ </message>
+ <message>
+ <source>Connect to a node to retrieve peer addresses, and disconnect</source>
+ <translation>피어 주소를 받기 위해 노드에 연결하고, 받은 후에 연결을 끊습니다</translation>
+ </message>
+ <message>
+ <source>Specify your own public address</source>
+ <translation>공인 주소를 지정하십시오</translation>
+ </message>
+ <message>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>명령줄과 JSON-RPC 명령 수락</translation>
+ </message>
+ <message>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>데몬으로 백그라운드에서 실행하고 명령을 허용</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>테스트 네트워크 사용</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
+ <translation>외부 접속을 승인합니다</translation>
+ </message>
+ <message>
+ <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
+ <translation>선택된 주소로 고정하며 항상 리슨(Listen)합니다. IPv6 프로토콜인 경우 [host]:port 방식의 명령어 표기법을 사용합니다.</translation>
+ </message>
+ <message>
+ <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
+ <translation>지갑 거래가 바뀌면 명령을 실행합니다.(%s 안의 명령어가 TxID로 바뀝니다)</translation>
+ </message>
+ <message>
+ <source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source>
+ <translation>이 빌드 버전은 정식 출시 전 테스트의 목적이며, 예기치 않은 위험과 오류가 발생할 수 있습니다. 채굴과 상점용 소프트웨어로 사용하는 것을 권하지 않습니다.</translation>
+ </message>
+ <message>
+ <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>경고: -paytxfee값이 너무 큽니다! 이 값은 송금할때 지불할 송금 수수료입니다.</translation>
+ </message>
+ <message>
+ <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source>
+ <translation>경고 : 모든 네트워크가 동의해야 하나, 일부 채굴자들에게 문제가 있는 것으로 보입니다. </translation>
+ </message>
+ <message>
+ <source>Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.</source>
+ <translation>경고: 현재 비트코인 버전이 다른 네트워크 참여자들과 동일하지 않는 것 같습니다. 당신 또는 다른 참여자들이 동일한 비트코인 버전으로 업그레이드 할 필요가 있습니다.</translation>
+ </message>
+ <message>
+ <source>Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
+ <translation>경고 : wallet.dat 파일을 읽는 중 에러가 발생했습니다. 주소 키는 모두 정확하게 로딩되었으나 거래 데이터와 주소록 필드에서 누락이나 오류가 존재할 수 있습니다. </translation>
+ </message>
+ <message>
+ <source>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</source>
+ <translation>경고 : wallet.dat가 손상되어 데이터가 복구되었습니다. 원래의 wallet.dat 파일은 %s 후에 wallet.{timestamp}.bak 이름으로 저장됩니다. 잔액과 거래 내역이 정확하지 않다면 백업 파일로 부터 복원해야 합니다. </translation>
+ </message>
+ <message>
+ <source>(default: 1)</source>
+ <translation>(기본값: 1)</translation>
+ </message>
+ <message>
+ <source>Attempt to recover private keys from a corrupt wallet.dat</source>
+ <translation>손상된 wallet.dat에서 개인키 복원을 시도합니다</translation>
+ </message>
+ <message>
+ <source>Block creation options:</source>
+ <translation>블록 생성 옵션:</translation>
+ </message>
+ <message>
+ <source>Connect only to the specified node(s)</source>
+ <translation>지정된 노드에만 연결하기</translation>
+ </message>
+ <message>
+ <source>Connection options:</source>
+ <translation>연결 설정 : </translation>
+ </message>
+ <message>
+ <source>Corrupted block database detected</source>
+ <translation>손상된 블록 데이터베이스가 감지되었습니다</translation>
+ </message>
+ <message>
+ <source>Debugging/Testing options:</source>
+ <translation>디버그 및 테스트 설정</translation>
+ </message>
+ <message>
+ <source>Do not load the wallet and disable wallet RPC calls</source>
+ <translation>지갑 불러오기를 하지마시오 또한 지갑 RPC 연결을 차단하십시오</translation>
+ </message>
+ <message>
+ <source>Do you want to rebuild the block database now?</source>
+ <translation>블락 데이터베이스를 다시 생성하시겠습니까?</translation>
+ </message>
+ <message>
+ <source>Error initializing block database</source>
+ <translation>블록 데이터베이스를 초기화하는데 오류</translation>
+ </message>
+ <message>
+ <source>Error loading block database</source>
+ <translation>블록 데이터베이스를 불러오는데 오류</translation>
+ </message>
+ <message>
+ <source>Error opening block database</source>
+ <translation>블록 데이터베이스를 여는데 오류</translation>
+ </message>
+ <message>
+ <source>Error: Disk space is low!</source>
+ <translation>오류: 디스크 공간이 부족합니다!</translation>
+ </message>
+ <message>
+ <source>Failed to listen on any port. Use -listen=0 if you want this.</source>
+ <translation>어떤 포트도 반응하지 않습니다. 사용자 반응=0 만약 원한다면</translation>
+ </message>
+ <message>
+ <source>If &lt;category&gt; is not supplied, output all debugging information.</source>
+ <translation>&lt;카테고리&gt;가 제공되지 않을 경우, 모든 디버깅 정보를 출력</translation>
+ </message>
+ <message>
+ <source>Importing...</source>
+ <translation>들여오기 중...</translation>
+ </message>
+ <message>
+ <source>Incorrect or no genesis block found. Wrong datadir for network?</source>
+ <translation>올바르지 않거나 생성된 블록을 찾을 수 없습니다. 잘못된 네트워크 자료 디렉토리?</translation>
+ </message>
+ <message>
+ <source>Invalid -onion address: '%s'</source>
+ <translation>잘못된 -onion 주소입니다: '%s'</translation>
+ </message>
+ <message>
+ <source>Not enough file descriptors available.</source>
+ <translation>사용 가능한 파일 디스크립터-File Descriptor-가 부족합니다. </translation>
+ </message>
+ <message>
+ <source>Set database cache size in megabytes (%d to %d, default: %d)</source>
+ <translation>데이터베이스 케시 크기를 메가바이트로 설정(%d 부터 %d, 기본값: %d)</translation>
+ </message>
+ <message>
+ <source>Set maximum block size in bytes (default: %d)</source>
+ <translation>최대 블락 크기를 Bytes로 지정하세요 (기본: %d)</translation>
+ </message>
+ <message>
+ <source>Specify wallet file (within data directory)</source>
+ <translation>데이터 폴더 안에 지갑 파일을 선택하세요.</translation>
+ </message>
+ <message>
+ <source>Verifying blocks...</source>
+ <translation>블록 검증중...</translation>
+ </message>
+ <message>
+ <source>Verifying wallet...</source>
+ <translation>지갑 검증중...</translation>
+ </message>
+ <message>
+ <source>Wallet %s resides outside data directory %s</source>
+ <translation>지갑 %s는 데이터 디렉토리 %s 밖에 위치합니다.</translation>
+ </message>
+ <message>
+ <source>Wallet options:</source>
+ <translation>지갑 옵션:</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to change -txindex</source>
+ <translation>-txindex를 바꾸기 위해서는 -reindex를 사용해서 데이터베이스를 재구성해야 합니다. </translation>
+ </message>
+ <message>
+ <source>Imports blocks from external blk000??.dat file</source>
+ <translation>외부 blk000??.dat 파일에서 블록을 가져옵니다.</translation>
+ </message>
+ <message>
+ <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source>
+ <translation>데이터 디렉토리 %s에 락을 걸 수 없었습니다. 비트코인 코어가 이미 실행 중인 것으로 보입니다.</translation>
+ </message>
+ <message>
+ <source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source>
+ <translation>이 사항과 관련있는 경고가 발생하거나 아주 긴 포크가 발생했을 때 명령어를 실행해 주세요. (cmd 명령어 목록에서 %s는 메시지로 대체됩니다) </translation>
+ </message>
+ <message>
+ <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
+ <translation>최대 크기를 최우선으로 설정 / 바이트당 최소 수수료로 거래(기본값: %d)</translation>
+ </message>
+ <message>
+ <source>Choose data directory on startup (default: 0)</source>
+ <translation>파일목록을 선택하여 시작하시오(기본값: 0)</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>정보</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -minrelaytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>노드로 전달하기 위한 최저 거래 수수료가 부족합니다. - minrelaytxfee=&lt;amount&gt;: '%s' -</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -mintxfee=&lt;amount&gt;: '%s'</source>
+ <translation>최저 거래 수수료가 부족합니다. -mintxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source>
+ <translation>RPC SSL 옵션: (비트코인 위키의 SSL 설정 설명서 참고)</translation>
+ </message>
+ <message>
+ <source>RPC server options:</source>
+ <translation>RPC 서버 설정</translation>
+ </message>
+ <message>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>추적오류 정보를 degug.log 자료로 보내는 대신 콘솔로 보내기</translation>
+ </message>
+ <message>
+ <source>Set SSL root certificates for payment request (default: -system-)</source>
+ <translation>지불 요청을 위해 SSL 최상위 인증을 설정합니다. (기본값: -system-)</translation>
+ </message>
+ <message>
+ <source>Set language, for example "de_DE" (default: system locale)</source>
+ <translation>"de_DE"와 같이 언어를 설정하십시오 (기본값: 시스템 로캘)</translation>
+ </message>
+ <message>
+ <source>Show all debugging options (usage: --help -help-debug)</source>
+ <translation>모든 디버그 설정 보기(설정: --help -help-debug)</translation>
+ </message>
+ <message>
+ <source>Show splash screen on startup (default: 1)</source>
+ <translation>시작시 시작 화면 표시 (기본값: 1)</translation>
+ </message>
+ <message>
+ <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source>
+ <translation>클라이언트 시작시 debug.log 파일 비우기(기본값: 디버그 안할때 1)</translation>
+ </message>
+ <message>
+ <source>Signing transaction failed</source>
+ <translation>거래를 서명하는것을 실패하였습니다.</translation>
+ </message>
+ <message>
+ <source>Start minimized</source>
+ <translation>최소화 상태에서 시작</translation>
+ </message>
+ <message>
+ <source>Transaction amount too small</source>
+ <translation>거래량이 너무 적습니다</translation>
+ </message>
+ <message>
+ <source>Transaction amounts must be positive</source>
+ <translation>거래량은 반드시 정수여야합니다.</translation>
+ </message>
+ <message>
+ <source>Transaction too large</source>
+ <translation>너무 큰 거래</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: 1 when listening)</source>
+ <translation>UPnP사용하여 지도에서 포트 반응기다리는 중 (기본값: 1 반응이 생기면)</translation>
+ </message>
+ <message>
+ <source>Username for JSON-RPC connections</source>
+ <translation>JSON-RPC 연결에 사용할 사용자 이름</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>경고</translation>
+ </message>
+ <message>
+ <source>Zapping all transactions from wallet...</source>
+ <translation>지갑의 모든거래내역 건너뛰기...</translation>
+ </message>
+ <message>
+ <source>on startup</source>
+ <translation>구동 중</translation>
+ </message>
+ <message>
+ <source>wallet.dat corrupt, salvage failed</source>
+ <translation>wallet.dat 파일이 손상되었고 복구가 실패하였습니다.</translation>
+ </message>
+ <message>
+ <source>Password for JSON-RPC connections</source>
+ <translation>JSON-RPC 연결에 사용할 암호</translation>
+ </message>
+ <message>
+ <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
+ <translation>최고의 블럭이 변하면 명령을 실행(cmd 에 있는 %s 는 블럭 해시에 의해 대체되어 짐)</translation>
+ </message>
+ <message>
+ <source>Upgrade wallet to latest format</source>
+ <translation>지갑을 최근 형식으로 개선하시오</translation>
+ </message>
+ <message>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>누락된 지갑 송금에 대한 블록 체인 다시 검색</translation>
+ </message>
+ <message>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>JSON-RPC 연결에 OpenSSL(https) 사용</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>도움말 메시지입니다</translation>
+ </message>
+ <message>
+ <source>Allow DNS lookups for -addnode, -seednode and -connect</source>
+ <translation>-addnode, -seednode, -connect 옵션에 대해 DNS 탐색 허용</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>주소를 불러오는 중...</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>wallet.dat 불러오기 에러: 지갑 오류</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>wallet.dat 불러오기 에러</translation>
+ </message>
+ <message>
+ <source>Invalid -proxy address: '%s'</source>
+ <translation>잘못된 -proxy 주소입니다: '%s'</translation>
+ </message>
+ <message>
+ <source>Unknown network specified in -onlynet: '%s'</source>
+ <translation>-onlynet에 지정한 네트워크를 알 수 없습니다: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -bind address: '%s'</source>
+ <translation>-bind 주소를 확인할 수 없습니다: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -externalip address: '%s'</source>
+ <translation>-externalip 주소를 확인할 수 없습니다: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>-paytxfee=&lt;amount&gt;에 대한 양이 잘못되었습니다: '%s'</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>자금 부족</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>블럭 인덱스를 불러오는 중...</translation>
+ </message>
+ <message>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>노드를 추가하여 연결하고 연결상태를 계속 유지하려고 시도합니다.</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>지갑을 불러오는 중...</translation>
+ </message>
+ <message>
+ <source>Cannot downgrade wallet</source>
+ <translation>지갑을 다운그레이드 할 수 없습니다</translation>
+ </message>
+ <message>
+ <source>Cannot write default address</source>
+ <translation>기본 계좌에 기록할 수 없습니다</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>재검색 중...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>로딩 완료</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>오류</translation>
+ </message>
+</context>
+</TS> \ No newline at end of file
diff --git a/src/qt/locale/bitcoin_ky.ts b/src/qt/locale/bitcoin_ky.ts
new file mode 100644
index 0000000000..442d7c5d52
--- /dev/null
+++ b/src/qt/locale/bitcoin_ky.ts
@@ -0,0 +1,330 @@
+<TS language="ky" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Create a new address</source>
+ <translation>Жаң даректи жасоо</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>Ө&amp;чүрүү</translation>
+ </message>
+ </context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Address</source>
+ <translation>Дарек</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(аты жок)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ </context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Транзакциялар</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>Билдирүүнү &amp;текшерүү...</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>Капчык</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;Файл</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>&amp;Жардам</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Ката</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Эскертүү</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Маалымат</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>Жаңыланган</translation>
+ </message>
+ </context>
+<context>
+ <name>ClientModel</name>
+ </context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Date</source>
+ <translation>Дата</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>жок</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(аты жок)</translation>
+ </message>
+ </context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;Дарек</translation>
+ </message>
+ </context>
+<context>
+ <name>FreespaceChecker</name>
+ </context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>version</source>
+ <translation>версия</translation>
+ </message>
+ </context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Error</source>
+ <translation>Ката</translation>
+ </message>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ </context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>MB</source>
+ <translation>МБ</translation>
+ </message>
+ <message>
+ <source>&amp;Network</source>
+ <translation>&amp;Тармак</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>&amp;Порт:</translation>
+ </message>
+ <message>
+ <source>&amp;Window</source>
+ <translation>&amp;Терезе</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>&amp;Жарайт</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>&amp;Жокко чыгаруу</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>жарыяланбаган</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>жок</translation>
+ </message>
+ </context>
+<context>
+ <name>OverviewPage</name>
+ </context>
+<context>
+ <name>PaymentServer</name>
+ </context>
+<context>
+ <name>PeerTableModel</name>
+ </context>
+<context>
+ <name>QObject</name>
+ </context>
+<context>
+ <name>QRImageWidget</name>
+ </context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>&amp;Information</source>
+ <translation>Маалымат</translation>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>Жалпы</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>Аты</translation>
+ </message>
+ <message>
+ <source>&amp;Open</source>
+ <translation>&amp;Ачуу</translation>
+ </message>
+ <message>
+ <source>&amp;Console</source>
+ <translation>&amp;Консоль</translation>
+ </message>
+ <message>
+ <source>Clear console</source>
+ <translation>Консолду тазалоо</translation>
+ </message>
+ </context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ </context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>Address</source>
+ <translation>Дарек</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Билдирүү</translation>
+ </message>
+ </context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Дата</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Билдирүү</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(аты жок)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>&amp;Бардыгын тазалоо</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>&amp;Жөнөтүү</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(аты жок)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Даректи алмашуу буферинен коюу</translation>
+ </message>
+ <message>
+ <source>Message:</source>
+ <translation>Билдирүү:</translation>
+ </message>
+ </context>
+<context>
+ <name>ShutdownWindow</name>
+ </context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Даректи алмашуу буферинен коюу</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>&amp;Бардыгын тазалоо</translation>
+ </message>
+ </context>
+<context>
+ <name>SplashScreen</name>
+ </context>
+<context>
+ <name>TrafficGraphWidget</name>
+ </context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>%1/offline</source>
+ <translation>%1/тармакта эмес</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Дата</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Билдирүү</translation>
+ </message>
+ </context>
+<context>
+ <name>TransactionDescDialog</name>
+ </context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Дата</translation>
+ </message>
+ </context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>Date</source>
+ <translation>Дата</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Дарек</translation>
+ </message>
+ </context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ </context>
+<context>
+ <name>WalletFrame</name>
+ </context>
+<context>
+ <name>WalletModel</name>
+ </context>
+<context>
+ <name>WalletView</name>
+ </context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Information</source>
+ <translation>Маалымат</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Эскертүү</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Ката</translation>
+ </message>
+</context>
+</TS> \ No newline at end of file
diff --git a/src/qt/locale/bitcoin_la.ts b/src/qt/locale/bitcoin_la.ts
new file mode 100644
index 0000000000..b1a69c9a9e
--- /dev/null
+++ b/src/qt/locale/bitcoin_la.ts
@@ -0,0 +1,1642 @@
+<TS language="la" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Create a new address</source>
+ <translation>Crea novam inscriptionem</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Copia inscriptionem iam selectam in latibulum systematis</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>&amp;Copia Inscriptionem</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>Dele active selectam inscriptionem ex enumeratione</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Exporta data in hac tabella in plicam</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Exporta</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;Dele</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>Hae sunt inscriptiones mittendi pensitationes. Semper inspice quantitatem et inscriptionem accipiendi antequam nummos mittis.</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>Copia &amp;Titulum</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>&amp;Muta</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Comma Separata Plica (*.csv)</translation>
+ </message>
+ </context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Titulus</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Inscriptio</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(nullus titulus)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Passphrase Dialog</source>
+ <translation>Dialogus Tesserae</translation>
+ </message>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Insere tesseram</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Nova tessera</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Itera novam tesseram</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>Cifra cassidile</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>Huic operationi necesse est tessera cassidili tuo ut cassidile reseret.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Resera cassidile</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>Huic operationi necesse est tessera cassidili tuo ut cassidile decifret.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>Decifra cassidile</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>Muta tesseram</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>Confirma cifrationem cassidilis</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>Monitio: Si cassidile tuum cifras et tesseram amittis, tu &lt;b&gt;AMITTES OMNES TUOS NUMMOS BITOS&lt;/b&gt;!</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>Certusne es te velle tuum cassidile cifrare?</translation>
+ </message>
+ <message>
+ <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
+ <translation>GRAVE: Oportet ulla prioria conservata quae fecisti de plica tui cassidilis reponi a nove generata cifrata plica cassidilis. Propter securitatem, prioria conservata de plica non cifrata cassidilis inutilia fiet simul atque incipis uti novo cifrato cassidili.</translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>Monitio: Litterae ut capitales seratae sunt!</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>Cassidile cifratum</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>Cassidile cifrare abortum est</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>Cassidile cifrare abortum est propter internum errorem. Tuum cassidile cifratum non est.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>Tesserae datae non eaedem sunt.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>Cassidile reserare abortum est.</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>Tessera inserta pro cassidilis decifrando prava erat.</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>Cassidile decifrare abortum est.</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>Tessera cassidilis successa est in mutando.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>Signa &amp;nuntium...</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>Synchronizans cum rete...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;Summarium</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>Monstra generale summarium cassidilis</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Transactiones</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>Inspicio historiam transactionum</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>E&amp;xi</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>Exi applicatione</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>Informatio de &amp;Qt</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>Monstra informationem de Qt</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;Optiones</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>&amp;Cifra Cassidile...</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>&amp;Conserva Cassidile...</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>&amp;Muta tesseram...</translation>
+ </message>
+ <message>
+ <source>Importing blocks from disk...</source>
+ <translation>Importans frusta ab disco...</translation>
+ </message>
+ <message>
+ <source>Reindexing blocks on disk...</source>
+ <translation>Recreans indicem frustorum in disco...</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>Mitte nummos ad inscriptionem Bitcoin</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>Conserva cassidile in locum alium</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Muta tesseram utam pro cassidilis cifrando</translation>
+ </message>
+ <message>
+ <source>&amp;Debug window</source>
+ <translation>Fenestra &amp;Debug</translation>
+ </message>
+ <message>
+ <source>Open debugging and diagnostic console</source>
+ <translation>Aperi terminalem debug et diagnosticalem</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>&amp;Verifica nuntium...</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>Cassidile</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>&amp;Mitte</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>&amp;Accipe</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>&amp;Monstra/Occulta</translation>
+ </message>
+ <message>
+ <source>Show or hide the main Window</source>
+ <translation>Monstra vel occulta Fenestram principem</translation>
+ </message>
+ <message>
+ <source>Encrypt the private keys that belong to your wallet</source>
+ <translation>Cifra claves privatas quae cassidili tui sunt</translation>
+ </message>
+ <message>
+ <source>Sign messages with your Bitcoin addresses to prove you own them</source>
+ <translation>Signa nuntios cum tuis inscriptionibus Bitcoin ut demonstres te eas possidere</translation>
+ </message>
+ <message>
+ <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source>
+ <translation>Verifica nuntios ut certus sis eos signatos esse cum specificatis inscriptionibus Bitcoin</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;Plica</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;Configuratio</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>&amp;Auxilium</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>Tabella instrumentorum "Tabs"</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Nucleus</translation>
+ </message>
+ <message>
+ <source>No block source available...</source>
+ <translation>Nulla fons frustorum absens...</translation>
+ </message>
+ <message>
+ <source>%1 behind</source>
+ <translation>%1 post</translation>
+ </message>
+ <message>
+ <source>Last received block was generated %1 ago.</source>
+ <translation>Postremum acceptum frustum generatum est %1 abhinc.</translation>
+ </message>
+ <message>
+ <source>Transactions after this will not yet be visible.</source>
+ <translation>Transactiones post hoc nondum visibiles erunt.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Error</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Monitio</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Informatio</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>Recentissimo</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>Persequens...</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>Transactio missa</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>Transactio incipiens</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>Cassidile &lt;b&gt;cifratum&lt;/b&gt; est et iam nunc &lt;b&gt;reseratum&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>Cassidile &lt;b&gt;cifratum&lt;/b&gt; est et iam nunc &lt;b&gt;seratum&lt;/b&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <source>Network Alert</source>
+ <translation>Monitio Retis</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Amount:</source>
+ <translation>Quantitas:</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Quantitas</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Dies</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Confirmatum</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Copia inscriptionem</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Copia titulum</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copia quantitatem</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Copia transactionis ID</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(nullus titulus)</translation>
+ </message>
+ </context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>Muta Inscriptionem</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>&amp;Titulus</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;Inscriptio</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>Nova inscriptio accipiendi</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>Nova inscriptio mittendi</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>Muta inscriptionem accipiendi</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>Muta inscriptionem mittendi</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>Inserta inscriptio "%1" iam in libro inscriptionum est.</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is not a valid Bitcoin address.</source>
+ <translation>Inscriptio inserta "%1" non valida inscriptio Bitcoin est.</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>Non potuisse cassidile reserare</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>Generare novam clavem abortum est.</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ </context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Nucleus</translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>versio</translation>
+ </message>
+ <message>
+ <source>Command-line options</source>
+ <translation>Optiones mandati initiantis</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>Usus:</translation>
+ </message>
+ <message>
+ <source>command-line options</source>
+ <translation>Optiones mandati intiantis</translation>
+ </message>
+</context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Nucleus</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Error</translation>
+ </message>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ </context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>Optiones</translation>
+ </message>
+ <message>
+ <source>&amp;Main</source>
+ <translation>&amp;Princeps</translation>
+ </message>
+ <message>
+ <source>Reset all client options to default.</source>
+ <translation>Reconstitue omnes optiones clientis ad praedefinita.</translation>
+ </message>
+ <message>
+ <source>&amp;Reset Options</source>
+ <translation>&amp;Reconstitue Optiones</translation>
+ </message>
+ <message>
+ <source>&amp;Network</source>
+ <translation>&amp;Rete</translation>
+ </message>
+ <message>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>Aperi per se portam clientis Bitcoin in itineratore. Hoc tantum effectivum est si itineratrum tuum supportat UPnP et id activum est.</translation>
+ </message>
+ <message>
+ <source>Map port using &amp;UPnP</source>
+ <translation>Designa portam utendo &amp;UPnP</translation>
+ </message>
+ <message>
+ <source>Proxy &amp;IP:</source>
+ <translation>&amp;IP vicarii:</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>&amp;Porta:</translation>
+ </message>
+ <message>
+ <source>Port of the proxy (e.g. 9050)</source>
+ <translation>Porta vicarii (e.g. 9050)</translation>
+ </message>
+ <message>
+ <source>&amp;Window</source>
+ <translation>&amp;Fenestra</translation>
+ </message>
+ <message>
+ <source>Show only a tray icon after minimizing the window.</source>
+ <translation>Monstra tantum iconem in tabella systematis postquam fenestram minifactam est.</translation>
+ </message>
+ <message>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>&amp;Minifac in tabellam systematis potius quam applicationum</translation>
+ </message>
+ <message>
+ <source>M&amp;inimize on close</source>
+ <translation>M&amp;inifac ad claudendum</translation>
+ </message>
+ <message>
+ <source>&amp;Display</source>
+ <translation>&amp;UI</translation>
+ </message>
+ <message>
+ <source>User Interface &amp;language:</source>
+ <translation>&amp;Lingua monstranda utenti:</translation>
+ </message>
+ <message>
+ <source>&amp;Unit to show amounts in:</source>
+ <translation>&amp;Unita qua quantitates monstrare:</translation>
+ </message>
+ <message>
+ <source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
+ <translation>Selige praedefinitam unitam subdivisionis monstrare in interfacie et quando nummos mittere</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>&amp;OK</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>&amp;Cancella</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>praedefinitum</translation>
+ </message>
+ <message>
+ <source>Confirm options reset</source>
+ <translation>Confirma optionum reconstituere</translation>
+ </message>
+ <message>
+ <source>The supplied proxy address is invalid.</source>
+ <translation>Inscriptio vicarii tradita non valida est.</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>Schema</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>Monstrata informatio fortasse non recentissima est. Tuum cassidile per se synchronizat cum rete Bitcoin postquam conexio constabilita est, sed hoc actio nondum perfecta est.</translation>
+ </message>
+ <message>
+ <source>Immature:</source>
+ <translation>Immatura:</translation>
+ </message>
+ <message>
+ <source>Mined balance that has not yet matured</source>
+ <translation>Fossum pendendum quod nondum maturum est</translation>
+ </message>
+ </context>
+<context>
+ <name>PaymentServer</name>
+ <message>
+ <source>URI handling</source>
+ <translation>Tractatio URI</translation>
+ </message>
+ <message>
+ <source>Cannot start bitcoin: click-to-pay handler</source>
+ <translation>Bitcoin incipere non potest: cliccare-ad-pensandum handler</translation>
+ </message>
+ </context>
+<context>
+ <name>PeerTableModel</name>
+ </context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>Quantitas</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>N/A</translation>
+ </message>
+ </context>
+<context>
+ <name>QRImageWidget</name>
+ <message>
+ <source>Save QR Code</source>
+ <translation>Salva codicem QR</translation>
+ </message>
+ </context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>Client name</source>
+ <translation>Nomen clientis</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>N/A</translation>
+ </message>
+ <message>
+ <source>Client version</source>
+ <translation>Versio clientis</translation>
+ </message>
+ <message>
+ <source>&amp;Information</source>
+ <translation>&amp;Informatio</translation>
+ </message>
+ <message>
+ <source>Using OpenSSL version</source>
+ <translation>Utens OpenSSL versione</translation>
+ </message>
+ <message>
+ <source>Startup time</source>
+ <translation>Tempus initiandi</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Rete</translation>
+ </message>
+ <message>
+ <source>Number of connections</source>
+ <translation>Numerus conexionum</translation>
+ </message>
+ <message>
+ <source>Block chain</source>
+ <translation>Catena frustorum</translation>
+ </message>
+ <message>
+ <source>Current number of blocks</source>
+ <translation>Numerus frustorum iam nunc</translation>
+ </message>
+ <message>
+ <source>Last block time</source>
+ <translation>Hora postremi frusti</translation>
+ </message>
+ <message>
+ <source>&amp;Open</source>
+ <translation>&amp;Aperi</translation>
+ </message>
+ <message>
+ <source>&amp;Console</source>
+ <translation>&amp;Terminale</translation>
+ </message>
+ <message>
+ <source>Build date</source>
+ <translation>Dies aedificandi</translation>
+ </message>
+ <message>
+ <source>Debug log file</source>
+ <translation>Debug catalogi plica</translation>
+ </message>
+ <message>
+ <source>Clear console</source>
+ <translation>Vacuefac terminale</translation>
+ </message>
+ <message>
+ <source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
+ <translation>Utere sagittis sursum deorsumque ut per historiam naviges, et &lt;b&gt;Ctrl+L&lt;/b&gt; ut scrinium vacuefacias.</translation>
+ </message>
+ <message>
+ <source>Type &lt;b&gt;help&lt;/b&gt; for an overview of available commands.</source>
+ <translation>Scribe &lt;b&gt;help&lt;/b&gt; pro summario possibilium mandatorum.</translation>
+ </message>
+ </context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Titulus:</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Copia titulum</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copia quantitatem</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>Address</source>
+ <translation>Inscriptio</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Quantitas</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Titulus</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Nuntius</translation>
+ </message>
+ <message>
+ <source>Resulting URI too long, try to reduce the text for label / message.</source>
+ <translation>Resultato URI nimis longo, conare minuere verba pro titulo / nuntio.</translation>
+ </message>
+ <message>
+ <source>Error encoding URI into QR Code.</source>
+ <translation>Error codificandi URI in codicem QR.</translation>
+ </message>
+</context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Dies</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Titulus</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Nuntius</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Quantitas</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(nullus titulus)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Mitte Nummos</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Quantitas:</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>Mitte pluribus accipientibus simul</translation>
+ </message>
+ <message>
+ <source>Add &amp;Recipient</source>
+ <translation>Adde &amp;Accipientem</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Vacuefac &amp;Omnia</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>Pendendum:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>Confirma actionem mittendi</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>&amp;Mitte</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>Confirma mittendum nummorum</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copia quantitatem</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>Oportet quantitatem ad pensandum maiorem quam 0 esse.</translation>
+ </message>
+ <message>
+ <source>The amount exceeds your balance.</source>
+ <translation>Quantitas est ultra quod habes.</translation>
+ </message>
+ <message>
+ <source>The total exceeds your balance when the %1 transaction fee is included.</source>
+ <translation>Quantitas est ultra quod habes cum merces transactionis %1 includitur.</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(nullus titulus)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>&amp;Quantitas:</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>Pensa &amp;Ad:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Insero titulum huic inscriptioni ut eam in tuum librum inscriptionum addas.</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Titulus:</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Glutina inscriptionem ex latibulo</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Message:</source>
+ <translation>Nuntius:</translation>
+ </message>
+ </context>
+<context>
+ <name>ShutdownWindow</name>
+ </context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Signatures - Sign / Verify a Message</source>
+ <translation>Signationes - Signa / Verifica nuntium</translation>
+ </message>
+ <message>
+ <source>&amp;Sign Message</source>
+ <translation>&amp;Signa Nuntium</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Glutina inscriptionem ex latibulo</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Enter the message you want to sign here</source>
+ <translation>Insere hic nuntium quod vis signare</translation>
+ </message>
+ <message>
+ <source>Signature</source>
+ <translation>Signatio</translation>
+ </message>
+ <message>
+ <source>Copy the current signature to the system clipboard</source>
+ <translation>Copia signationem in latibulum systematis</translation>
+ </message>
+ <message>
+ <source>Sign the message to prove you own this Bitcoin address</source>
+ <translation>Signa nuntium ut demonstres hanc inscriptionem Bitcoin a te possessa esse</translation>
+ </message>
+ <message>
+ <source>Sign &amp;Message</source>
+ <translation>Signa &amp;Nuntium</translation>
+ </message>
+ <message>
+ <source>Reset all sign message fields</source>
+ <translation>Reconstitue omnes campos signandi nuntii</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Vacuefac &amp;Omnia</translation>
+ </message>
+ <message>
+ <source>&amp;Verify Message</source>
+ <translation>&amp;Verifica Nuntium</translation>
+ </message>
+ <message>
+ <source>Verify the message to ensure it was signed with the specified Bitcoin address</source>
+ <translation>Verifica nuntium ut cures signatum esse cum specifica inscriptione Bitcoin</translation>
+ </message>
+ <message>
+ <source>Verify &amp;Message</source>
+ <translation>Verifica &amp;Nuntium</translation>
+ </message>
+ <message>
+ <source>Reset all verify message fields</source>
+ <translation>Reconstitue omnes campos verificandi nuntii</translation>
+ </message>
+ <message>
+ <source>Click "Sign Message" to generate signature</source>
+ <translation>Clicca "Signa Nuntium" ut signatio generetur</translation>
+ </message>
+ <message>
+ <source>The entered address is invalid.</source>
+ <translation>Inscriptio inserta non valida est.</translation>
+ </message>
+ <message>
+ <source>Please check the address and try again.</source>
+ <translation>Sodes inscriptionem proba et rursus conare.</translation>
+ </message>
+ <message>
+ <source>The entered address does not refer to a key.</source>
+ <translation>Inserta inscriptio clavem non refert.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock was cancelled.</source>
+ <translation>Cassidilis reserare cancellatum est.</translation>
+ </message>
+ <message>
+ <source>Private key for the entered address is not available.</source>
+ <translation>Clavis privata absens est pro inserta inscriptione.</translation>
+ </message>
+ <message>
+ <source>Message signing failed.</source>
+ <translation>Nuntium signare abortum est.</translation>
+ </message>
+ <message>
+ <source>Message signed.</source>
+ <translation>Nuntius signatus.</translation>
+ </message>
+ <message>
+ <source>The signature could not be decoded.</source>
+ <translation>Signatio decodificari non potuit.</translation>
+ </message>
+ <message>
+ <source>Please check the signature and try again.</source>
+ <translation>Sodes signationem proba et rursus conare.</translation>
+ </message>
+ <message>
+ <source>The signature did not match the message digest.</source>
+ <translation>Signatio non convenit digesto nuntii</translation>
+ </message>
+ <message>
+ <source>Message verification failed.</source>
+ <translation>Nuntium verificare abortum est.</translation>
+ </message>
+ <message>
+ <source>Message verified.</source>
+ <translation>Nuntius verificatus.</translation>
+ </message>
+</context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Nucleus</translation>
+ </message>
+ <message>
+ <source>[testnet]</source>
+ <translation>[testnet]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ </context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>Apertum donec %1</translation>
+ </message>
+ <message>
+ <source>%1/offline</source>
+ <translation>%1/non conecto</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/non confirmata</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 confirmationes</translation>
+ </message>
+ <message>
+ <source>Status</source>
+ <translation>Status</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Dies</translation>
+ </message>
+ <message>
+ <source>Source</source>
+ <translation>Fons</translation>
+ </message>
+ <message>
+ <source>Generated</source>
+ <translation>Generatum</translation>
+ </message>
+ <message>
+ <source>From</source>
+ <translation>Ab</translation>
+ </message>
+ <message>
+ <source>To</source>
+ <translation>Ad</translation>
+ </message>
+ <message>
+ <source>own address</source>
+ <translation>inscriptio propria</translation>
+ </message>
+ <message>
+ <source>label</source>
+ <translation>titulus</translation>
+ </message>
+ <message>
+ <source>Credit</source>
+ <translation>Creditum</translation>
+ </message>
+ <message>
+ <source>not accepted</source>
+ <translation>non acceptum</translation>
+ </message>
+ <message>
+ <source>Debit</source>
+ <translation>Debitum</translation>
+ </message>
+ <message>
+ <source>Transaction fee</source>
+ <translation>Transactionis merces</translation>
+ </message>
+ <message>
+ <source>Net amount</source>
+ <translation>Cuncta quantitas</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Nuntius</translation>
+ </message>
+ <message>
+ <source>Comment</source>
+ <translation>Annotatio</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>ID transactionis</translation>
+ </message>
+ <message>
+ <source>Debug information</source>
+ <translation>Informatio de debug</translation>
+ </message>
+ <message>
+ <source>Transaction</source>
+ <translation>Transactio</translation>
+ </message>
+ <message>
+ <source>Inputs</source>
+ <translation>Lectenda</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Quantitas</translation>
+ </message>
+ <message>
+ <source>true</source>
+ <translation>verum</translation>
+ </message>
+ <message>
+ <source>false</source>
+ <translation>falsum</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, nondum prospere disseminatum est</translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>ignotum</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>Particularia transactionis</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>Haec tabula monstrat descriptionem verbosam transactionis</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Dies</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Typus</translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>Apertum donec %1</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>Confirmatum (%1 confirmationes)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>Hoc frustum non acceptum est ab ulla alia nodis et probabiliter non acceptum erit!</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>Generatum sed non acceptum</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Titulus</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Acceptum cum</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>Acceptum ab</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Missum ad</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>Pensitatio ad te ipsum</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Fossa</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(n/a)</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>Status transactionis. Supervola cum mure ut monstretur numerus confirmationum.</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Dies et tempus quando transactio accepta est.</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>Typus transactionis.</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>Quantitas remota ex pendendo aut addita ei.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>Omne</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>Hodie</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>Hac hebdomade</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>Hoc mense</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>Postremo mense</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>Hoc anno</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>Intervallum...</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Acceptum cum</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Missum ad</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>Ad te ipsum</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Fossa</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>Alia</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>Insere inscriptionem vel titulum ut quaeras</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>Quantitas minima</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Copia inscriptionem</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Copia titulum</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copia quantitatem</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Copia transactionis ID</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>Muta titulum</translation>
+ </message>
+ <message>
+ <source>Show transaction details</source>
+ <translation>Monstra particularia transactionis</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Comma Separata Plica (*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Confirmatum</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Dies</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Typus</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Titulus</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Inscriptio</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>Intervallum:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>ad</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ </context>
+<context>
+ <name>WalletFrame</name>
+ </context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Mitte Nummos</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Exporta</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Exporta data in hac tabella in plicam</translation>
+ </message>
+ <message>
+ <source>Backup Wallet</source>
+ <translation>Conserva cassidile</translation>
+ </message>
+ <message>
+ <source>Wallet Data (*.dat)</source>
+ <translation>Data cassidilis (*.dat)</translation>
+ </message>
+ <message>
+ <source>Backup Failed</source>
+ <translation>Conservare abortum est.</translation>
+ </message>
+ <message>
+ <source>Backup Successful</source>
+ <translation>Successum in conservando</translation>
+ </message>
+</context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>Optiones:</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>Specifica indicem datorum</translation>
+ </message>
+ <message>
+ <source>Connect to a node to retrieve peer addresses, and disconnect</source>
+ <translation>Conecta ad nodum acceptare inscriptiones parium, et disconecte</translation>
+ </message>
+ <message>
+ <source>Specify your own public address</source>
+ <translation>Specifica tuam propriam publicam inscriptionem</translation>
+ </message>
+ <message>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>Accipe terminalis et JSON-RPC mandata.</translation>
+ </message>
+ <message>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>Operare infere sicut daemon et mandata accipe</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>Utere rete experimentale</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
+ <translation>Accipe conexiones externas (praedefinitum: 1 nisi -proxy neque -connect)</translation>
+ </message>
+ <message>
+ <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
+ <translation>Conglutina ad inscriptionem datam et semper in eam ausculta. Utere [moderatrum]:porta notationem pro IPv6</translation>
+ </message>
+ <message>
+ <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
+ <translation>Facere mandatum quotiescumque cassidilis transactio mutet (%s in mandato sbstituitur ab TxID)</translation>
+ </message>
+ <message>
+ <source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source>
+ <translation>Hoc est prae-dimittum experimentala aedes - utere eo periculo tuo proprio - nolite utere fodendo vel applicationibus mercatoriis</translation>
+ </message>
+ <message>
+ <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>Monitio: -paytxfee constitutum valde magnum! Hoc est merces transactionis solves si mittis transactionem.</translation>
+ </message>
+ <message>
+ <source>Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
+ <translation>Monitio: error legendo wallet.dat! Omnes claves recte lectae, sed data transactionum vel libri inscriptionum fortasse desint vel prava sint.</translation>
+ </message>
+ <message>
+ <source>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</source>
+ <translation>Monitio: wallet.data corrupta, data salvata! Originalis wallet.dat salvata ut wallet.{timestamp}.bak in %s; si pendendum tuum vel transactiones pravae sunt, oportet ab conservato restituere.</translation>
+ </message>
+ <message>
+ <source>Attempt to recover private keys from a corrupt wallet.dat</source>
+ <translation>Conare recipere claves privatas de corrupto wallet.dat</translation>
+ </message>
+ <message>
+ <source>Block creation options:</source>
+ <translation>Optiones creandi frustorum:</translation>
+ </message>
+ <message>
+ <source>Connect only to the specified node(s)</source>
+ <translation>Conecte sole ad nodos specificatos (vel nodum specificatum)</translation>
+ </message>
+ <message>
+ <source>Corrupted block database detected</source>
+ <translation>Corruptum databasum frustorum invenitur</translation>
+ </message>
+ <message>
+ <source>Do you want to rebuild the block database now?</source>
+ <translation>Visne reficere databasum frustorum iam?</translation>
+ </message>
+ <message>
+ <source>Error initializing block database</source>
+ <translation>Error initiando databasem frustorum</translation>
+ </message>
+ <message>
+ <source>Error initializing wallet database environment %s!</source>
+ <translation>Error initiando systematem databasi cassidilis %s!</translation>
+ </message>
+ <message>
+ <source>Error loading block database</source>
+ <translation>Error legendo frustorum databasem</translation>
+ </message>
+ <message>
+ <source>Error opening block database</source>
+ <translation>Error aperiendo databasum frustorum</translation>
+ </message>
+ <message>
+ <source>Error: Disk space is low!</source>
+ <translation>Error: Inopia spatii disci!</translation>
+ </message>
+ <message>
+ <source>Failed to listen on any port. Use -listen=0 if you want this.</source>
+ <translation>Non potuisse auscultare in ulla porta. Utere -listen=0 si hoc vis.</translation>
+ </message>
+ <message>
+ <source>Not enough file descriptors available.</source>
+ <translation>Inopia descriptorum plicarum.</translation>
+ </message>
+ <message>
+ <source>Verifying blocks...</source>
+ <translation>Verificante frusta...</translation>
+ </message>
+ <message>
+ <source>Verifying wallet...</source>
+ <translation>Verificante cassidilem...</translation>
+ </message>
+ <message>
+ <source>Imports blocks from external blk000??.dat file</source>
+ <translation>Importat frusta ab externa plica blk000??.dat</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Informatio</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -minrelaytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Quantitas non valida pro -minrelaytxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -mintxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Quantitas non valida pro -mintxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>Mitte informationem vestigii/debug ad terminale potius quam plicam debug.log</translation>
+ </message>
+ <message>
+ <source>Set language, for example "de_DE" (default: system locale)</source>
+ <translation>Constitue linguam, exempli gratia "de_DE" (praedefinitum: lingua systematis)</translation>
+ </message>
+ <message>
+ <source>Show splash screen on startup (default: 1)</source>
+ <translation>Monstra principem imaginem ad initium (praedefinitum: 1)</translation>
+ </message>
+ <message>
+ <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source>
+ <translation>Diminue plicam debug.log ad initium clientis (praedefinitum: 1 nisi -debug)</translation>
+ </message>
+ <message>
+ <source>Signing transaction failed</source>
+ <translation>Signandum transactionis abortum est</translation>
+ </message>
+ <message>
+ <source>Start minimized</source>
+ <translation>Incipe minifactum ut icon</translation>
+ </message>
+ <message>
+ <source>Transaction amount too small</source>
+ <translation>Magnitudo transactionis nimis parva</translation>
+ </message>
+ <message>
+ <source>Transaction amounts must be positive</source>
+ <translation>Necesse est magnitudines transactionum positivas esse.</translation>
+ </message>
+ <message>
+ <source>Transaction too large</source>
+ <translation>Transactio nimis magna</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: 1 when listening)</source>
+ <translation>Utere UPnP designare portam auscultandi (praedefinitum: 1 quando auscultans)</translation>
+ </message>
+ <message>
+ <source>Username for JSON-RPC connections</source>
+ <translation>Nomen utentis pro conexionibus JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Monitio</translation>
+ </message>
+ <message>
+ <source>wallet.dat corrupt, salvage failed</source>
+ <translation>wallet.dat corrupta, salvare abortum est</translation>
+ </message>
+ <message>
+ <source>Password for JSON-RPC connections</source>
+ <translation>Tessera pro conexionibus JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
+ <translation>Pelle mandatum quando optissimum frustum mutat (%s in mandato substituitur ab hash frusti)</translation>
+ </message>
+ <message>
+ <source>Upgrade wallet to latest format</source>
+ <translation>Progredere cassidile ad formam recentissimam</translation>
+ </message>
+ <message>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>Iterum perlege catenam frustorum propter absentes cassidilis transactiones</translation>
+ </message>
+ <message>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>Utere OpenSSL (https) pro conexionibus JSON-RPC</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>Hic nuntius auxilii</translation>
+ </message>
+ <message>
+ <source>Allow DNS lookups for -addnode, -seednode and -connect</source>
+ <translation>Permitte quaerenda DNS pro -addnode, -seednode, et -connect</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>Legens inscriptiones...</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>Error legendi wallet.dat: Cassidile corruptum</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>Error legendi wallet.dat</translation>
+ </message>
+ <message>
+ <source>Invalid -proxy address: '%s'</source>
+ <translation>Inscriptio -proxy non valida: '%s'</translation>
+ </message>
+ <message>
+ <source>Unknown network specified in -onlynet: '%s'</source>
+ <translation>Ignotum rete specificatum in -onlynet: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -bind address: '%s'</source>
+ <translation>Non posse resolvere -bind inscriptonem: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -externalip address: '%s'</source>
+ <translation>Non posse resolvere -externalip inscriptionem: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Quantitas non valida pro -paytxfee=&lt;quantitas&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>Inopia nummorum</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>Legens indicem frustorum...</translation>
+ </message>
+ <message>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>Adice nodum cui conectere et conare sustinere conexionem apertam</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>Legens cassidile...</translation>
+ </message>
+ <message>
+ <source>Cannot downgrade wallet</source>
+ <translation>Non posse cassidile regredi</translation>
+ </message>
+ <message>
+ <source>Cannot write default address</source>
+ <translation>Non posse scribere praedefinitam inscriptionem</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>Iterum perlegens...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>Completo lengendi</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Error</translation>
+ </message>
+</context>
+</TS> \ 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 0000000000..4e468911dc
--- /dev/null
+++ b/src/qt/locale/bitcoin_lt.ts
@@ -0,0 +1,1746 @@
+<TS language="lt" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Right-click to edit address or label</source>
+ <translation>Spustelėkite dešinįjį klaviša norint keisti adresą arba etiketę</translation>
+ </message>
+ <message>
+ <source>Create a new address</source>
+ <translation>Sukurti naują adresą</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>&amp;Naujas</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Kopijuoti esamą adresą į mainų atmintį</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>&amp;Kopijuoti</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>&amp;Užverti</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>&amp;Kopijuoti adresą</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>Ištrinti pasirinktą adresą iš sąrašo</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Eksportuoti</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;Trinti</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>Pasirinkite adresą kuriam siūsite monetas</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>P&amp;asirinkti</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>Siunčiami adresai</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>Gaunami adresai</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>Kopijuoti ž&amp;ymę</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>&amp;Keisti</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>Eksportuoti adresų sąrašą</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Kableliais atskirtų duomenų failas (*.csv)</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Eksportavimas nepavyko</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the address list to %1. Please try again.</source>
+ <translation>Bandant išsaugoti adresų sąrašą - įvyko klaida keliant į %1. Prašome bandyti dar kartą.</translation>
+ </message>
+</context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Žymė</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adresas</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(nėra žymės)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Passphrase Dialog</source>
+ <translation>Slaptafrazės dialogas</translation>
+ </message>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Įvesti slaptafrazę</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Nauja slaptafrazė</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Pakartokite naują slaptafrazę</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>Užšifruoti piniginę</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>Ši operacija reikalauja jūsų piniginės slaptafrazės jai atrakinti.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Atrakinti piniginę</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>Ši operacija reikalauja jūsų piniginės slaptafrazės jai iššifruoti.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>Iššifruoti piniginę</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>Pakeisti slaptafrazę</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>Patvirtinkite piniginės užšifravimą</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>Dėmesio: jei užšifruosite savo piniginę ir pamesite slaptafrazę, jūs&lt;b&gt;PRARASITE VISUS SAVO BITCOINUS&lt;/b&gt;! </translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>Ar tikrai norite šifruoti savo piniginę?</translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>Įspėjimas: įjungtas Caps Lock klavišas!</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>Piniginė užšifruota</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>Nepavyko užšifruoti piniginę</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>Dėl vidinės klaidos nepavyko užšifruoti piniginę.Piniginė neužšifruota.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>Įvestos slaptafrazės nesutampa.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>Nepavyko atrakinti piniginę</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>Neteisingai įvestas slaptažodis piniginės iššifravimui.</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>Nepavyko iššifruoti piniginės</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>Piniginės slaptažodis sėkmingai pakeistas.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>Pasirašyti ži&amp;nutę...</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>Sinchronizavimas su tinklu ...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;Apžvalga</translation>
+ </message>
+ <message>
+ <source>Node</source>
+ <translation>Taškas</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>Rodyti piniginės bendrą apžvalgą</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Sandoriai</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>Apžvelgti sandorių istoriją</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>&amp;Išeiti</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>Išjungti programą</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>Apie &amp;Qt</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>Rodyti informaciją apie Qt</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;Parinktys...</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>&amp;Užšifruoti piniginę...</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>&amp;Backup piniginę...</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>&amp;Keisti slaptafrazę...</translation>
+ </message>
+ <message>
+ <source>&amp;Sending addresses...</source>
+ <translation>&amp;Siunčiami adresai...</translation>
+ </message>
+ <message>
+ <source>&amp;Receiving addresses...</source>
+ <translation>&amp;Gaunami adresai...</translation>
+ </message>
+ <message>
+ <source>Open &amp;URI...</source>
+ <translation>Atidaryti &amp;URI...</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core client</source>
+ <translation>Bitcoin Core klientas</translation>
+ </message>
+ <message>
+ <source>Importing blocks from disk...</source>
+ <translation>Blokai importuojami iš disko...</translation>
+ </message>
+ <message>
+ <source>Reindexing blocks on disk...</source>
+ <translation>Blokai iš naujo indeksuojami...</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>Siųsti monetas Bitcoin adresui</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>Daryti piniginės atsarginę kopiją</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Pakeisti slaptafrazę naudojamą piniginės užšifravimui</translation>
+ </message>
+ <message>
+ <source>&amp;Debug window</source>
+ <translation>&amp;Derinimo langas</translation>
+ </message>
+ <message>
+ <source>Open debugging and diagnostic console</source>
+ <translation>Atverti derinimo ir diagnostikos konsolę</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>&amp;Tikrinti žinutę...</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>Piniginė</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>&amp;Siųsti</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>&amp;Gauti</translation>
+ </message>
+ <message>
+ <source>Show information about Bitcoin Core</source>
+ <translation>Rodyti informaciją apie Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>&amp;Rodyti / Slėpti</translation>
+ </message>
+ <message>
+ <source>Show or hide the main Window</source>
+ <translation>Rodyti arba slėpti pagrindinį langą</translation>
+ </message>
+ <message>
+ <source>Encrypt the private keys that belong to your wallet</source>
+ <translation>Užšifruoti privačius raktus, kurie priklauso jūsų piniginei</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;Failas</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;Nustatymai</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>&amp;Pagalba</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>Kortelių įrankinė</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin branduolys</translation>
+ </message>
+ <message>
+ <source>&amp;About Bitcoin Core</source>
+ <translation>&amp;Apie Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Klaida</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Įspėjimas</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Informacija</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>Atnaujinta</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>Vejamasi...</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>Sandoris nusiųstas</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>Ateinantis sandoris</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>Piniginė &lt;b&gt;užšifruota&lt;/b&gt; ir šiuo metu &lt;b&gt;atrakinta&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>Piniginė &lt;b&gt;užšifruota&lt;/b&gt; ir šiuo metu &lt;b&gt;užrakinta&lt;/b&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <source>Network Alert</source>
+ <translation>Tinklo įspėjimas</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Coin Selection</source>
+ <translation>Monetų pasirinkimas</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Kiekis:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Baitai:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Suma:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Pirmumas:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Mokestis:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Po mokesčio:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Graža:</translation>
+ </message>
+ <message>
+ <source>(un)select all</source>
+ <translation>(ne)pasirinkti viską</translation>
+ </message>
+ <message>
+ <source>Tree mode</source>
+ <translation>Medžio režimas</translation>
+ </message>
+ <message>
+ <source>List mode</source>
+ <translation>Sąrašo režimas</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Suma</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Confirmations</source>
+ <translation>Patvirtinimai</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Patvirtintas</translation>
+ </message>
+ <message>
+ <source>Priority</source>
+ <translation>Pirmumas</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Kopijuoti adresą</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Kopijuoti žymę</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopijuoti sumą</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Kopijuoti kiekį</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Kopijuoti mokestį</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Kopijuoti po mokesčio</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Kopijuoti baitus</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Kopijuoti pirmumą</translation>
+ </message>
+ <message>
+ <source>highest</source>
+ <translation>auksčiausias</translation>
+ </message>
+ <message>
+ <source>higher</source>
+ <translation>aukštesnis</translation>
+ </message>
+ <message>
+ <source>high</source>
+ <translation>aukštas</translation>
+ </message>
+ <message>
+ <source>medium-high</source>
+ <translation>vidutiniškai aukštas</translation>
+ </message>
+ <message>
+ <source>medium</source>
+ <translation>vidutiniškai</translation>
+ </message>
+ <message>
+ <source>low-medium</source>
+ <translation>žemai-vidutiniškas</translation>
+ </message>
+ <message>
+ <source>low</source>
+ <translation>žemas</translation>
+ </message>
+ <message>
+ <source>lower</source>
+ <translation>žemesnis</translation>
+ </message>
+ <message>
+ <source>lowest</source>
+ <translation>žemiausias</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>niekas</translation>
+ </message>
+ <message>
+ <source>yes</source>
+ <translation>taip</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>ne</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(nėra žymės)</translation>
+ </message>
+ </context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>Keisti adresą</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>Ž&amp;ymė</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;Adresas</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>Naujas gavimo adresas</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>Naujas siuntimo adresas</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>Keisti gavimo adresą</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>Keisti siuntimo adresą</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>Įvestas adresas „%1“ jau yra adresų knygelėje.</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is not a valid Bitcoin address.</source>
+ <translation>Įvestas adresas „%1“ nėra galiojantis Bitcoin adresas.</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>Nepavyko atrakinti piniginės.</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>Naujo rakto generavimas nepavyko.</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ <message>
+ <source>name</source>
+ <translation>pavadinimas</translation>
+ </message>
+ </context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin branduolys</translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>versija</translation>
+ </message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>Apie Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Command-line options</source>
+ <translation>Komandinės eilutės parametrai</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>Naudojimas:</translation>
+ </message>
+ <message>
+ <source>command-line options</source>
+ <translation>komandinės eilutės parametrai</translation>
+ </message>
+</context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Welcome</source>
+ <translation>Sveiki</translation>
+ </message>
+ <message>
+ <source>Welcome to Bitcoin Core.</source>
+ <translation>Sveiki atvykę į Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin branduolys</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Klaida</translation>
+ </message>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ </context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>Parinktys</translation>
+ </message>
+ <message>
+ <source>&amp;Main</source>
+ <translation>&amp;Pagrindinės</translation>
+ </message>
+ <message>
+ <source>&amp;Network</source>
+ <translation>&amp;Tinklas</translation>
+ </message>
+ <message>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>Automatiškai atidaryti Bitcoin kliento prievadą maršrutizatoriuje. Tai veikia tik tada, kai jūsų maršrutizatorius palaiko UPnP ir ji įjungta.</translation>
+ </message>
+ <message>
+ <source>Map port using &amp;UPnP</source>
+ <translation>Persiųsti prievadą naudojant &amp;UPnP</translation>
+ </message>
+ <message>
+ <source>Proxy &amp;IP:</source>
+ <translation>Tarpinio serverio &amp;IP:</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>&amp;Prievadas:</translation>
+ </message>
+ <message>
+ <source>Port of the proxy (e.g. 9050)</source>
+ <translation>Tarpinio serverio preivadas (pvz, 9050)</translation>
+ </message>
+ <message>
+ <source>&amp;Window</source>
+ <translation>&amp;Langas</translation>
+ </message>
+ <message>
+ <source>Show only a tray icon after minimizing the window.</source>
+ <translation>Po programos lango sumažinimo rodyti tik programos ikoną.</translation>
+ </message>
+ <message>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>&amp;M sumažinti langą bet ne užduočių juostą</translation>
+ </message>
+ <message>
+ <source>M&amp;inimize on close</source>
+ <translation>&amp;Sumažinti uždarant</translation>
+ </message>
+ <message>
+ <source>&amp;Display</source>
+ <translation>&amp;Rodymas</translation>
+ </message>
+ <message>
+ <source>User Interface &amp;language:</source>
+ <translation>Naudotojo sąsajos &amp;kalba:</translation>
+ </message>
+ <message>
+ <source>&amp;Unit to show amounts in:</source>
+ <translation>&amp;Vienetai, kuriais rodyti sumas:</translation>
+ </message>
+ <message>
+ <source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
+ <translation>Rodomų ir siunčiamų monetų kiekio matavimo vienetai</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>&amp;Gerai</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>&amp;Atšaukti</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>numatyta</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>niekas</translation>
+ </message>
+ <message>
+ <source>Confirm options reset</source>
+ <translation>Patvirtinti nustatymų atstatymą</translation>
+ </message>
+ <message>
+ <source>The supplied proxy address is invalid.</source>
+ <translation>Nurodytas tarpinio serverio adresas negalioja.</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>Forma</translation>
+ </message>
+ <message>
+ <source>Available:</source>
+ <translation>Galimi:</translation>
+ </message>
+ <message>
+ <source>Pending:</source>
+ <translation>Laukiantys:</translation>
+ </message>
+ <message>
+ <source>Immature:</source>
+ <translation>Nepribrendę:</translation>
+ </message>
+ <message>
+ <source>Total:</source>
+ <translation>Viso:</translation>
+ </message>
+ <message>
+ <source>Your current total balance</source>
+ <translation>Jūsų balansas</translation>
+ </message>
+ </context>
+<context>
+ <name>PaymentServer</name>
+ <message>
+ <source>URI handling</source>
+ <translation>URI apdorojimas</translation>
+ </message>
+ <message>
+ <source>Payment request rejected</source>
+ <translation>Mokėjimo siuntimas atmestas</translation>
+ </message>
+ <message>
+ <source>Network request error</source>
+ <translation>Tinklo užklausos klaida</translation>
+ </message>
+</context>
+<context>
+ <name>PeerTableModel</name>
+ </context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>Suma</translation>
+ </message>
+ <message>
+ <source>%1 h</source>
+ <translation>%1 h</translation>
+ </message>
+ <message>
+ <source>%1 m</source>
+ <translation>%1 m</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>nėra</translation>
+ </message>
+ </context>
+<context>
+ <name>QRImageWidget</name>
+ <message>
+ <source>Save QR Code</source>
+ <translation>Įrašyti QR kodą</translation>
+ </message>
+ </context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>Client name</source>
+ <translation>Kliento pavadinimas</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>nėra</translation>
+ </message>
+ <message>
+ <source>Client version</source>
+ <translation>Kliento versija</translation>
+ </message>
+ <message>
+ <source>&amp;Information</source>
+ <translation>&amp;Informacija</translation>
+ </message>
+ <message>
+ <source>Using OpenSSL version</source>
+ <translation>Naudojama OpenSSL versija</translation>
+ </message>
+ <message>
+ <source>Startup time</source>
+ <translation>Paleidimo laikas</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Tinklas</translation>
+ </message>
+ <message>
+ <source>Number of connections</source>
+ <translation>Prisijungimų kiekis</translation>
+ </message>
+ <message>
+ <source>Block chain</source>
+ <translation>Blokų grandinė</translation>
+ </message>
+ <message>
+ <source>Current number of blocks</source>
+ <translation>Dabartinis blokų skaičius</translation>
+ </message>
+ <message>
+ <source>Received</source>
+ <translation>Gauta</translation>
+ </message>
+ <message>
+ <source>Direction</source>
+ <translation>Kryptis</translation>
+ </message>
+ <message>
+ <source>Version</source>
+ <translation>Versija</translation>
+ </message>
+ <message>
+ <source>Bytes Sent</source>
+ <translation>Nusiųsti baitai</translation>
+ </message>
+ <message>
+ <source>Bytes Received</source>
+ <translation>Gauti baitai</translation>
+ </message>
+ <message>
+ <source>Last block time</source>
+ <translation>Paskutinio bloko laikas</translation>
+ </message>
+ <message>
+ <source>&amp;Open</source>
+ <translation>&amp;Atverti</translation>
+ </message>
+ <message>
+ <source>&amp;Console</source>
+ <translation>&amp;Konsolė</translation>
+ </message>
+ <message>
+ <source>Totals</source>
+ <translation>Viso:</translation>
+ </message>
+ <message>
+ <source>Build date</source>
+ <translation>Kompiliavimo data</translation>
+ </message>
+ <message>
+ <source>Debug log file</source>
+ <translation>Derinimo žurnalo failas</translation>
+ </message>
+ <message>
+ <source>Clear console</source>
+ <translation>Išvalyti konsolę</translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation>%1 B</translation>
+ </message>
+ <message>
+ <source>%1 KB</source>
+ <translation>%1 KB</translation>
+ </message>
+ <message>
+ <source>%1 MB</source>
+ <translation>%1 MB</translation>
+ </message>
+ <message>
+ <source>%1 GB</source>
+ <translation>%1 GB</translation>
+ </message>
+ <message>
+ <source>never</source>
+ <translation>Niekada</translation>
+ </message>
+ </context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>Ž&amp;ymė:</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation>Išvalyti</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Kopijuoti žymę</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopijuoti sumą</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>QR Code</source>
+ <translation>QR kodas</translation>
+ </message>
+ <message>
+ <source>Payment information</source>
+ <translation>Mokėjimo informacija</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adresas</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Suma</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Žymė</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Žinutė</translation>
+ </message>
+ <message>
+ <source>Error encoding URI into QR Code.</source>
+ <translation>Klaida, koduojant URI į QR kodą.</translation>
+ </message>
+</context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Žymė</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Žinutė</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Suma</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(nėra žymės)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Siųsti monetas</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Kiekis:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Baitai:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Suma:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Pirmumas:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Mokestis:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Po mokesčio:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Graža:</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>Siųsti keliems gavėjams vienu metu</translation>
+ </message>
+ <message>
+ <source>Add &amp;Recipient</source>
+ <translation>&amp;A Pridėti gavėją</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Išvalyti &amp;viską</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>Balansas:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>Patvirtinti siuntimo veiksmą</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>&amp;Siųsti</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>Patvirtinti monetų siuntimą</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Kopijuoti kiekį</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopijuoti sumą</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Kopijuoti mokestį</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Kopijuoti po mokesčio</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Kopijuoti baitus</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Kopijuoti pirmumą</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>Apmokėjimo suma turi būti didesnė nei 0.</translation>
+ </message>
+ <message>
+ <source>The amount exceeds your balance.</source>
+ <translation>Suma viršija jūsų balansą.</translation>
+ </message>
+ <message>
+ <source>The total exceeds your balance when the %1 transaction fee is included.</source>
+ <translation>Jei pridedame sandorio mokestį %1 bendra suma viršija jūsų balansą.</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(nėra žymės)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>Su&amp;ma:</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>Mokėti &amp;gavėjui:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Įveskite žymę šiam adresui kad galėtumėte įtraukti ją į adresų knygelę</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>Ž&amp;ymė:</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Įvesti adresą iš mainų atminties</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Message:</source>
+ <translation>Žinutė:</translation>
+ </message>
+ </context>
+<context>
+ <name>ShutdownWindow</name>
+ </context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>&amp;Sign Message</source>
+ <translation>&amp;Pasirašyti žinutę</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Įvesti adresą iš mainų atminties</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Enter the message you want to sign here</source>
+ <translation>Įveskite pranešimą, kurį norite pasirašyti čia</translation>
+ </message>
+ <message>
+ <source>Sign the message to prove you own this Bitcoin address</source>
+ <translation>Registruotis žinute įrodymuii, kad turite šį adresą</translation>
+ </message>
+ <message>
+ <source>Sign &amp;Message</source>
+ <translation>Registruoti praneši&amp;mą</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Išvalyti &amp;viską</translation>
+ </message>
+ <message>
+ <source>&amp;Verify Message</source>
+ <translation>&amp;Patikrinti žinutę</translation>
+ </message>
+ <message>
+ <source>Verify the message to ensure it was signed with the specified Bitcoin address</source>
+ <translation>Patikrinkite žinutę, jog įsitikintumėte, kad ją pasirašė nurodytas Bitcoin adresas</translation>
+ </message>
+ <message>
+ <source>Click "Sign Message" to generate signature</source>
+ <translation>Spragtelėkite "Registruotis žinutę" tam, kad gauti parašą</translation>
+ </message>
+ <message>
+ <source>The entered address is invalid.</source>
+ <translation>Įvestas adresas negalioja.</translation>
+ </message>
+ <message>
+ <source>Please check the address and try again.</source>
+ <translation>Prašom patikrinti adresą ir bandyti iš naujo.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock was cancelled.</source>
+ <translation>Piniginės atrakinimas atšauktas.</translation>
+ </message>
+ <message>
+ <source>Message signing failed.</source>
+ <translation>Žinutės pasirašymas nepavyko.</translation>
+ </message>
+ <message>
+ <source>Message signed.</source>
+ <translation>Žinutė pasirašyta.</translation>
+ </message>
+ <message>
+ <source>The signature could not be decoded.</source>
+ <translation>Nepavyko iškoduoti parašo.</translation>
+ </message>
+ <message>
+ <source>Please check the signature and try again.</source>
+ <translation>Prašom patikrinti parašą ir bandyti iš naujo.</translation>
+ </message>
+ <message>
+ <source>The signature did not match the message digest.</source>
+ <translation>Parašas neatitinka žinutės.</translation>
+ </message>
+ <message>
+ <source>Message verification failed.</source>
+ <translation>Žinutės tikrinimas nepavyko.</translation>
+ </message>
+ <message>
+ <source>Message verified.</source>
+ <translation>Žinutė patikrinta.</translation>
+ </message>
+</context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin branduolys</translation>
+ </message>
+ <message>
+ <source>[testnet]</source>
+ <translation>[testavimotinklas]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ <message>
+ <source>KB/s</source>
+ <translation>KB/s</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>Atidaryta iki %1</translation>
+ </message>
+ <message>
+ <source>%1/offline</source>
+ <translation>%1/neprisijungęs</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/nepatvirtintas</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 patvirtinimų</translation>
+ </message>
+ <message>
+ <source>Status</source>
+ <translation>Būsena</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Source</source>
+ <translation>Šaltinis</translation>
+ </message>
+ <message>
+ <source>Generated</source>
+ <translation>Sugeneruotas</translation>
+ </message>
+ <message>
+ <source>From</source>
+ <translation>Nuo</translation>
+ </message>
+ <message>
+ <source>To</source>
+ <translation>Kam</translation>
+ </message>
+ <message>
+ <source>own address</source>
+ <translation>savo adresas</translation>
+ </message>
+ <message>
+ <source>label</source>
+ <translation>žymė</translation>
+ </message>
+ <message>
+ <source>Credit</source>
+ <translation>Kreditas</translation>
+ </message>
+ <message>
+ <source>not accepted</source>
+ <translation>nepriimta</translation>
+ </message>
+ <message>
+ <source>Debit</source>
+ <translation>Debitas</translation>
+ </message>
+ <message>
+ <source>Transaction fee</source>
+ <translation>Sandorio mokestis</translation>
+ </message>
+ <message>
+ <source>Net amount</source>
+ <translation>Neto suma</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Žinutė</translation>
+ </message>
+ <message>
+ <source>Comment</source>
+ <translation>Komentaras</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>Sandorio ID</translation>
+ </message>
+ <message>
+ <source>Debug information</source>
+ <translation>Derinimo informacija</translation>
+ </message>
+ <message>
+ <source>Transaction</source>
+ <translation>Sandoris</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Suma</translation>
+ </message>
+ <message>
+ <source>true</source>
+ <translation>tiesa</translation>
+ </message>
+ <message>
+ <source>false</source>
+ <translation>netiesa</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, transliavimas dar nebuvo sėkmingas</translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>nežinomas</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>Sandorio detelės</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>Šis langas sandorio detalų aprašymą</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Tipas</translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>Atidaryta iki %1</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>Patvirtinta (%1 patvirtinimai)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>Šis blokas negautas nė vienu iš mazgų ir matomai nepriimtas</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>Išgauta bet nepriimta</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Žymė</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Gauta su</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>Gauta iš</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Išsiųsta</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>Mokėjimas sau</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Išgauta</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>nepasiekiama</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>Sandorio būklė. Užvedus pelės žymeklį ant šios srities matysite patvirtinimų skaičių.</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Sandorio gavimo data ir laikas</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>Sandorio tipas.</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>Suma pridėta ar išskaičiuota iš balanso</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>Visi</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>Šiandien</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>Šią savaitę</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>Šį mėnesį</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>Paskutinį mėnesį</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>Šiais metais</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>Intervalas...</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Gauta su</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Išsiųsta</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>Skirta sau</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Išgauta</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>Kita</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>Įveskite adresą ar žymę į paiešką</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>Minimali suma</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Kopijuoti adresą</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Kopijuoti žymę</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopijuoti sumą</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>Taisyti žymę</translation>
+ </message>
+ <message>
+ <source>Show transaction details</source>
+ <translation>Rodyti sandėrio detales</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Eksportavimas nepavyko</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Kableliais atskirtų duomenų failas (*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Patvirtintas</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Tipas</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Žymė</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adresas</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>Grupė:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>skirta</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ </context>
+<context>
+ <name>WalletFrame</name>
+ </context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Siųsti monetas</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Eksportuoti</translation>
+ </message>
+ <message>
+ <source>Backup Wallet</source>
+ <translation>Backup piniginę</translation>
+ </message>
+ <message>
+ <source>Wallet Data (*.dat)</source>
+ <translation>Piniginės duomenys (*.dat)</translation>
+ </message>
+ <message>
+ <source>Backup Failed</source>
+ <translation>Nepavyko padaryti atsarginės kopijos</translation>
+ </message>
+ <message>
+ <source>Backup Successful</source>
+ <translation>Atsarginė kopija sėkmingai padaryta</translation>
+ </message>
+</context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>Parinktys:</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>Nustatyti duomenų aplanką</translation>
+ </message>
+ <message>
+ <source>Specify your own public address</source>
+ <translation>Nurodykite savo nuosavą viešą adresą</translation>
+ </message>
+ <message>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>Priimti komandinę eilutę ir JSON-RPC komandas</translation>
+ </message>
+ <message>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>Dirbti fone kaip šešėlyje ir priimti komandas</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>Naudoti testavimo tinklą</translation>
+ </message>
+ <message>
+ <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>Įspėjimas: -paytxfee yra nustatytas per didelis. Tai sandorio mokestis, kurį turėsite mokėti, jei siųsite sandorį.</translation>
+ </message>
+ <message>
+ <source>Connect only to the specified node(s)</source>
+ <translation>Prisijungti tik prie nurodyto mazgo</translation>
+ </message>
+ <message>
+ <source>Error opening block database</source>
+ <translation>Klaida atveriant blokų duombazę</translation>
+ </message>
+ <message>
+ <source>Verifying blocks...</source>
+ <translation>Tikrinami blokai...</translation>
+ </message>
+ <message>
+ <source>Verifying wallet...</source>
+ <translation>Tikrinama piniginė...</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Informacija</translation>
+ </message>
+ <message>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>Siųsti atsekimo/derinimo info į konsolę vietoj debug.log failo</translation>
+ </message>
+ <message>
+ <source>Set language, for example "de_DE" (default: system locale)</source>
+ <translation>Nustatyti kalbą, pavyzdžiui "lt_LT" (numatyta: sistemos kalba)</translation>
+ </message>
+ <message>
+ <source>Start minimized</source>
+ <translation>Paleisti sumažintą</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: 1 when listening)</source>
+ <translation>Bandymas naudoti UPnP struktūra klausymosi prievadui (default: 1 when listening)</translation>
+ </message>
+ <message>
+ <source>Username for JSON-RPC connections</source>
+ <translation>Vartotojo vardas JSON-RPC jungimuisi</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Įspėjimas</translation>
+ </message>
+ <message>
+ <source>Password for JSON-RPC connections</source>
+ <translation>Slaptažodis JSON-RPC sujungimams</translation>
+ </message>
+ <message>
+ <source>Upgrade wallet to latest format</source>
+ <translation>Atnaujinti piniginę į naujausią formatą</translation>
+ </message>
+ <message>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>Ieškoti prarastų piniginės sandorių blokų grandinėje</translation>
+ </message>
+ <message>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>Naudoti OpenSSL (https) jungimuisi JSON-RPC </translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>Pagelbos žinutė</translation>
+ </message>
+ <message>
+ <source>Allow DNS lookups for -addnode, -seednode and -connect</source>
+ <translation>Leisti DNS paiešką sujungimui ir mazgo pridėjimui</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>Užkraunami adresai...</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation> wallet.dat pakrovimo klaida, wallet.dat sugadintas</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation> wallet.dat pakrovimo klaida</translation>
+ </message>
+ <message>
+ <source>Invalid -proxy address: '%s'</source>
+ <translation>Neteisingas proxy adresas: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Neteisinga suma -paytxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>Nepakanka lėšų</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>Įkeliamas blokų indeksas...</translation>
+ </message>
+ <message>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>Pridėti mazgą prie sujungti su and attempt to keep the connection open</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>Užkraunama piniginė...</translation>
+ </message>
+ <message>
+ <source>Cannot write default address</source>
+ <translation>Negalima parašyti įprasto adreso</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>Peržiūra</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>Įkėlimas baigtas</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Klaida</translation>
+ </message>
+</context>
+</TS> \ No newline at end of file
diff --git a/src/qt/locale/bitcoin_lv_LV.ts b/src/qt/locale/bitcoin_lv_LV.ts
new file mode 100644
index 0000000000..fcdacfac55
--- /dev/null
+++ b/src/qt/locale/bitcoin_lv_LV.ts
@@ -0,0 +1,2290 @@
+<TS language="lv_LV" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Create a new address</source>
+ <translation>Izveidot jaunu adresi</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>&amp;Jauns</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Kopēt iezīmēto adresi uz starpliktuvi</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>&amp;Kopēt</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>&amp;Aizvērt</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>&amp;Kopēt adresi</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>Izdzēst iezīmētās adreses no saraksta</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Datus no tekošā ieliktņa eksportēt uz failu</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Eksportēt</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;Dzēst</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>Izvēlies adresi uz kuru sūtīt bitcoins</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>Izvēlies adresi ar kuru saņemt bitcoins</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>&amp;Izvēlēties</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>Sūtīšanas adreses</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>Saņemšanas adreses</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>Kopēt &amp;Nosaukumu</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>&amp;Rediģēt</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>Eksportēt Adrešu Sarakstu</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Fails ar komatu kā atdalītāju (*.csv)</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Eksportēšana Neizdevās</translation>
+ </message>
+ </context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Nosaukums</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adrese</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(bez nosaukuma)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Passphrase Dialog</source>
+ <translation>Paroles dialogs</translation>
+ </message>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Ierakstiet paroli</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Jauna parole</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Jaunā parole vēlreiz</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>Šifrēt maciņu</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>Lai veikto šo darbību, maciņš jāatslēdz ar paroli.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Atslēgt maciņu</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>Šai darbībai maciņš jāatšifrē ar maciņa paroli.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>Atšifrēt maciņu</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>Mainīt paroli</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>Apstiprināt maciņa šifrēšanu</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>Brīdinājums: Ja tu nošifrē savu maciņu un pazaudē paroli, tu &lt;b&gt;PAZAUDĒSI VISAS SAVAS BITCOINS&lt;/b&gt;!</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>Vai tu tiešām vēlies šifrēt savu maciņu?</translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>Brīdinājums: Caps Lock ir ieslēgts!</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>Maciņš nošifrēts</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>Maciņa šifrēšana neizdevās</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>Maciņa šifrēšana neizdevās programmas kļūdas dēļ. Jūsu maciņš netika šifrēts.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>Ievadītās paroles nav vienādas.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>Maciņu atšifrēt neizdevās</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>Maciņa atšifrēšanai ievadītā parole nav pareiza.</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>Maciņu neizdevās atšifrēt</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>Maciņa parole tika veiksmīgi nomainīta.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>Parakstīt &amp;ziņojumu...</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>Sinhronizācija ar tīklu...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;Pārskats</translation>
+ </message>
+ <message>
+ <source>Node</source>
+ <translation>Node</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>Rādīt vispārēju maciņa pārskatu</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Transakcijas</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>Skatīt transakciju vēsturi</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>&amp;Iziet</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>Aizvērt programmu</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>Par &amp;Qt</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>Parādīt informāciju par Qt</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;Iespējas...</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>Šifrēt &amp;maciņu...</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>&amp;Maciņa Rezerves Kopija...</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>Mainīt &amp;Paroli...</translation>
+ </message>
+ <message>
+ <source>&amp;Sending addresses...</source>
+ <translation>&amp;Sūtīšanas adreses...</translation>
+ </message>
+ <message>
+ <source>&amp;Receiving addresses...</source>
+ <translation>Saņemšanas &amp;adreses...</translation>
+ </message>
+ <message>
+ <source>Open &amp;URI...</source>
+ <translation>Atvērt &amp;URI...</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core client</source>
+ <translation>Bitcoin Core klients</translation>
+ </message>
+ <message>
+ <source>Importing blocks from disk...</source>
+ <translation>Importē blokus no diska...</translation>
+ </message>
+ <message>
+ <source>Reindexing blocks on disk...</source>
+ <translation>Bloku reindeksēšana no diska...</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>Nosūtīt bitkoinus uz Bitcoin adresi</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>Izveidot maciņa rezerves kopiju citur</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Mainīt maciņa šifrēšanas paroli</translation>
+ </message>
+ <message>
+ <source>&amp;Debug window</source>
+ <translation>&amp;Atkļūdošanas logs</translation>
+ </message>
+ <message>
+ <source>Open debugging and diagnostic console</source>
+ <translation>Atvērt atkļūdošanas un diagnostikas konsoli</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>&amp;Pārbaudīt ziņojumu...</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>Maciņš</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>&amp;Sūtīt</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>&amp;Saņemt</translation>
+ </message>
+ <message>
+ <source>Show information about Bitcoin Core</source>
+ <translation>Parādīt informāciju par Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>&amp;Rādīt / Paslēpt</translation>
+ </message>
+ <message>
+ <source>Show or hide the main Window</source>
+ <translation>Parādīt vai paslēpt galveno Logu</translation>
+ </message>
+ <message>
+ <source>Encrypt the private keys that belong to your wallet</source>
+ <translation>Šifrēt privātās atslēgas kuras pieder tavam maciņam</translation>
+ </message>
+ <message>
+ <source>Sign messages with your Bitcoin addresses to prove you own them</source>
+ <translation>Parakstīt ziņojumus ar savām Bitcoin adresēm lai pierādītu ka tās pieder tev</translation>
+ </message>
+ <message>
+ <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source>
+ <translation>Pārbaudīt ziņojumus lai pārliecinātos, ka tie tika parakstīti ar norādītajām Bitcoin adresēm</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;Fails</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;Uzstādījumi</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>&amp;Palīdzība</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>Ciļņu rīkjosla</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Request payments (generates QR codes and bitcoin: URIs)</source>
+ <translation>Pieprasīt maksājumus (izveido QR kodu un bitcoin: URIs)</translation>
+ </message>
+ <message>
+ <source>&amp;About Bitcoin Core</source>
+ <translation>Par &amp;Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Open a bitcoin: URI or payment request</source>
+ <translation>Atvērt bitcoin URI vai maksājuma pieprasījumu</translation>
+ </message>
+ <message>
+ <source>&amp;Command-line options</source>
+ <translation>&amp;Komandrindas iespējas</translation>
+ </message>
+ <message>
+ <source>No block source available...</source>
+ <translation>Nav pieejams neviens bloku avots...</translation>
+ </message>
+ <message>
+ <source>%1 and %2</source>
+ <translation>%1 un %2</translation>
+ </message>
+ <message>
+ <source>%1 behind</source>
+ <translation>%1 aizmugurē</translation>
+ </message>
+ <message>
+ <source>Transactions after this will not yet be visible.</source>
+ <translation>Transakcijas pēc šī vel nebūs redzamas</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Kļūda</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Brīdinājums</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Informācija</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>Sinhronizēts</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>Sinhronizējos...</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>Transakcija nosūtīta</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>Ienākoša transakcija</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>Maciņš ir &lt;b&gt;šifrēts&lt;/b&gt; un pašlaik &lt;b&gt;atslēgts&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>Maciņš ir &lt;b&gt;šifrēts&lt;/b&gt; un pašlaik &lt;b&gt;slēgts&lt;/b&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <source>Network Alert</source>
+ <translation>Tīkla brīdinājums</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Quantity:</source>
+ <translation>Daudzums:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Baiti:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Daudzums:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Prioritāte:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Maksa:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Pēc Maksas:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Atlikums:</translation>
+ </message>
+ <message>
+ <source>(un)select all</source>
+ <translation>iezīmēt visus</translation>
+ </message>
+ <message>
+ <source>Tree mode</source>
+ <translation>Koka režīms</translation>
+ </message>
+ <message>
+ <source>List mode</source>
+ <translation>Saraksta režīms</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Daudzums</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Datums</translation>
+ </message>
+ <message>
+ <source>Confirmations</source>
+ <translation>Apstiprinājumi</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Apstiprināts</translation>
+ </message>
+ <message>
+ <source>Priority</source>
+ <translation>Prioritāte</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Kopēt adresi</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Kopēt nosaukumu</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopēt daudzumu</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Kopēt transakcijas ID</translation>
+ </message>
+ <message>
+ <source>Lock unspent</source>
+ <translation>Aizslēgt neiztērēto</translation>
+ </message>
+ <message>
+ <source>Unlock unspent</source>
+ <translation>Atslēgt neiztērēto</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Kopēt daudzumu</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Kopēt maksu</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Kopēt pēc maksas</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Kopēt baitus</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Kopēt prioritāti</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Kopēt atlikumu</translation>
+ </message>
+ <message>
+ <source>highest</source>
+ <translation>augstākais</translation>
+ </message>
+ <message>
+ <source>higher</source>
+ <translation>augstāks</translation>
+ </message>
+ <message>
+ <source>high</source>
+ <translation>augsts</translation>
+ </message>
+ <message>
+ <source>medium-high</source>
+ <translation>vidēji-augsts</translation>
+ </message>
+ <message>
+ <source>medium</source>
+ <translation>vidējs</translation>
+ </message>
+ <message>
+ <source>low-medium</source>
+ <translation>zemi-vidējs</translation>
+ </message>
+ <message>
+ <source>low</source>
+ <translation>zems</translation>
+ </message>
+ <message>
+ <source>lower</source>
+ <translation>zemāks</translation>
+ </message>
+ <message>
+ <source>lowest</source>
+ <translation>zemākais</translation>
+ </message>
+ <message>
+ <source>(%1 locked)</source>
+ <translation>(%1 aizslēgts)</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>neviena</translation>
+ </message>
+ <message>
+ <source>yes</source>
+ <translation>jā</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>nē</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(bez nosaukuma)</translation>
+ </message>
+ <message>
+ <source>change from %1 (%2)</source>
+ <translation>atlikums no %1 (%2)</translation>
+ </message>
+ <message>
+ <source>(change)</source>
+ <translation>(atlikums)</translation>
+ </message>
+</context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>Mainīt adrese</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>&amp;Nosaukums</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;Adrese</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>Jauna saņemšanas adrese</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>Jauna nosūtīšanas adrese</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>Mainīt saņemšanas adresi</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>Mainīt nosūtīšanas adresi</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>Nupat ierakstītā adrese "%1" jau atrodas adrešu grāmatā.</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is not a valid Bitcoin address.</source>
+ <translation>Ierakstītā adrese "%1" nav derīga Bitcoin adrese.</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>Nav iespējams atslēgt maciņu.</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>Neizdevās ģenerēt jaunu atslēgu.</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ <message>
+ <source>A new data directory will be created.</source>
+ <translation>Tiks izveidota jauna datu mape.</translation>
+ </message>
+ <message>
+ <source>name</source>
+ <translation>vārds</translation>
+ </message>
+ <message>
+ <source>Path already exists, and is not a directory.</source>
+ <translation>Šāds ceļš jau pastāv un tā nav mape.</translation>
+ </message>
+ <message>
+ <source>Cannot create data directory here.</source>
+ <translation>Šeit nevar izveidot datu mapi.</translation>
+ </message>
+</context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>versija</translation>
+ </message>
+ <message>
+ <source>(%1-bit)</source>
+ <translation>(%1-biti)</translation>
+ </message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>Par Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>Lietojums:</translation>
+ </message>
+ <message>
+ <source>command-line options</source>
+ <translation>komandrindas izvēles</translation>
+ </message>
+</context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Welcome</source>
+ <translation>Sveiciens</translation>
+ </message>
+ <message>
+ <source>Welcome to Bitcoin Core.</source>
+ <translation>Sveicināts Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Use the default data directory</source>
+ <translation>Izmantot noklusēto datu mapi</translation>
+ </message>
+ <message>
+ <source>Use a custom data directory:</source>
+ <translation>Izmantot pielāgotu datu mapi:</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Kļūda</translation>
+ </message>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ <message>
+ <source>Open URI</source>
+ <translation>Atvērt URI</translation>
+ </message>
+ <message>
+ <source>Open payment request from URI or file</source>
+ <translation>Atvērt maksājuma pieprasījumu no URI vai datnes</translation>
+ </message>
+ <message>
+ <source>URI:</source>
+ <translation>URI:</translation>
+ </message>
+ <message>
+ <source>Select payment request file</source>
+ <translation>Izvēlies maksājuma pieprasījuma datni</translation>
+ </message>
+ <message>
+ <source>Select payment request file to open</source>
+ <translation>Izvēlies maksājuma pieprasījuma datni lai atvēru</translation>
+ </message>
+</context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>Iespējas</translation>
+ </message>
+ <message>
+ <source>&amp;Main</source>
+ <translation>&amp;Galvenais</translation>
+ </message>
+ <message>
+ <source>Size of &amp;database cache</source>
+ <translation>&amp;Datubāzes kešatmiņas izmērs</translation>
+ </message>
+ <message>
+ <source>MB</source>
+ <translation>MB</translation>
+ </message>
+ <message>
+ <source>Number of script &amp;verification threads</source>
+ <translation>Skriptu &amp;pārbaudes pavedienu skaits</translation>
+ </message>
+ <message>
+ <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
+ <translation>Starpniekservera IP adrese (piem. IPv4: 127.0.0.1 / IPv6: ::1)</translation>
+ </message>
+ <message>
+ <source>Third party transaction URLs</source>
+ <translation>Trešo personu transakciju URLs</translation>
+ </message>
+ <message>
+ <source>Active command-line options that override above options:</source>
+ <translation>Aktīvās komandrindas opcijas, kuras pārspēko šos iestatījumus:</translation>
+ </message>
+ <message>
+ <source>Reset all client options to default.</source>
+ <translation>Atiestatīt visus klienta iestatījumus uz noklusējumu.</translation>
+ </message>
+ <message>
+ <source>&amp;Reset Options</source>
+ <translation>&amp;Atiestatīt Iestatījumus.</translation>
+ </message>
+ <message>
+ <source>&amp;Network</source>
+ <translation>&amp;Tīkls</translation>
+ </message>
+ <message>
+ <source>W&amp;allet</source>
+ <translation>&amp;Maciņš</translation>
+ </message>
+ <message>
+ <source>Expert</source>
+ <translation>Eksperts</translation>
+ </message>
+ <message>
+ <source>Enable coin &amp;control features</source>
+ <translation>Ieslēgt bitcoin &amp;kontroles funkcijas</translation>
+ </message>
+ <message>
+ <source>&amp;Spend unconfirmed change</source>
+ <translation>&amp;Tērēt neapstiprinātu atlikumu</translation>
+ </message>
+ <message>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>Uz rūtera automātiski atvērt Bitcoin klienta portu. Tas strādā tikai tad, ja rūteris atbalsta UPnP un tas ir ieslēgts.</translation>
+ </message>
+ <message>
+ <source>Map port using &amp;UPnP</source>
+ <translation>Kartēt portu, izmantojot &amp;UPnP</translation>
+ </message>
+ <message>
+ <source>Proxy &amp;IP:</source>
+ <translation>Starpniekservera &amp;IP:</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>&amp;Ports:</translation>
+ </message>
+ <message>
+ <source>Port of the proxy (e.g. 9050)</source>
+ <translation>Starpniekservera ports (piem. 9050)</translation>
+ </message>
+ <message>
+ <source>&amp;Window</source>
+ <translation>&amp;Logs</translation>
+ </message>
+ <message>
+ <source>Show only a tray icon after minimizing the window.</source>
+ <translation>Pēc loga minimizācijas rādīt tikai ikonu sistēmas teknē.</translation>
+ </message>
+ <message>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>&amp;Minimizēt uz sistēmas tekni, nevis rīkjoslu</translation>
+ </message>
+ <message>
+ <source>M&amp;inimize on close</source>
+ <translation>M&amp;inimizēt aizverot</translation>
+ </message>
+ <message>
+ <source>&amp;Display</source>
+ <translation>&amp;Izskats</translation>
+ </message>
+ <message>
+ <source>User Interface &amp;language:</source>
+ <translation>Lietotāja interfeiss un &amp;valoda:</translation>
+ </message>
+ <message>
+ <source>&amp;Unit to show amounts in:</source>
+ <translation>&amp;Vienības, kurās attēlot daudzumus:</translation>
+ </message>
+ <message>
+ <source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
+ <translation>Izvēlēties dalījuma vienību pēc noklusēšanas, ko izmantot interfeisā un nosūtot bitkoinus.</translation>
+ </message>
+ <message>
+ <source>Whether to show coin control features or not.</source>
+ <translation>Vai rādīt Bitcoin kontroles funkcijas vai nē.</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>&amp;Labi</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>&amp;Atcelt</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>pēc noklusēšanas</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>neviena</translation>
+ </message>
+ <message>
+ <source>Confirm options reset</source>
+ <translation>Apstiprināt iestatījumu atiestatīšanu</translation>
+ </message>
+ <message>
+ <source>The supplied proxy address is invalid.</source>
+ <translation>Norādītā starpniekservera adrese nav derīga.</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>Forma</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>Attēlotā informācija var būt novecojusi. Jūsu maciņš pēc savienojuma izveides automātiski sinhronizējas ar Bitcoin tīklu, taču šis process vēl nav beidzies.</translation>
+ </message>
+ <message>
+ <source>Available:</source>
+ <translation>Pieejams:</translation>
+ </message>
+ <message>
+ <source>Your current spendable balance</source>
+ <translation>Tava pašreizējā tērējamā bilance</translation>
+ </message>
+ <message>
+ <source>Pending:</source>
+ <translation>Neizšķirts:</translation>
+ </message>
+ <message>
+ <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source>
+ <translation>Kopējā apstiprināmo transakciju vērtība, vēl nav ieskaitīta tērējamajā bilancē</translation>
+ </message>
+ <message>
+ <source>Immature:</source>
+ <translation>Nenobriedušu:</translation>
+ </message>
+ <message>
+ <source>Total:</source>
+ <translation>Kopsumma:</translation>
+ </message>
+ <message>
+ <source>Your current total balance</source>
+ <translation>Jūsu kopējā tekošā bilance</translation>
+ </message>
+ </context>
+<context>
+ <name>PaymentServer</name>
+ <message>
+ <source>URI handling</source>
+ <translation>URI apstrāde</translation>
+ </message>
+ <message>
+ <source>Invalid payment address %1</source>
+ <translation>Nederīga maksājuma adrese %1</translation>
+ </message>
+ <message>
+ <source>Payment request error</source>
+ <translation>Maksājumu pieprasījuma kļūda</translation>
+ </message>
+ <message>
+ <source>Cannot start bitcoin: click-to-pay handler</source>
+ <translation>Nevar palaist Bitcoin: nospied-lai-maksātu apstrādātāju</translation>
+ </message>
+ <message>
+ <source>Refund from %1</source>
+ <translation>Atmaksa no %1</translation>
+ </message>
+ <message>
+ <source>Payment acknowledged</source>
+ <translation>Maksājums atzīts</translation>
+ </message>
+ <message>
+ <source>Network request error</source>
+ <translation>Tīkla pieprasījuma kļūda</translation>
+ </message>
+</context>
+<context>
+ <name>PeerTableModel</name>
+ </context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>Daudzums</translation>
+ </message>
+ <message>
+ <source>%1 h</source>
+ <translation>%1 st</translation>
+ </message>
+ <message>
+ <source>%1 m</source>
+ <translation>%1 m</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>N/A</translation>
+ </message>
+ </context>
+<context>
+ <name>QRImageWidget</name>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Saglabāt Attēlu...</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Image</source>
+ <translation>&amp;Kopēt Attēlu</translation>
+ </message>
+ <message>
+ <source>Save QR Code</source>
+ <translation>Saglabāt QR kodu</translation>
+ </message>
+ <message>
+ <source>PNG Image (*.png)</source>
+ <translation>PNG Attēls (*.png)</translation>
+ </message>
+</context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>Client name</source>
+ <translation>Klienta vārds</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>N/A</translation>
+ </message>
+ <message>
+ <source>Client version</source>
+ <translation>Klienta versija</translation>
+ </message>
+ <message>
+ <source>&amp;Information</source>
+ <translation>&amp;Informācija</translation>
+ </message>
+ <message>
+ <source>Debug window</source>
+ <translation>Atkļūdošanas logs</translation>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>Vispārējs</translation>
+ </message>
+ <message>
+ <source>Using OpenSSL version</source>
+ <translation>Izmantotā OpenSSL versija</translation>
+ </message>
+ <message>
+ <source>Startup time</source>
+ <translation>Sākuma laiks</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Tīkls</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>Vārds</translation>
+ </message>
+ <message>
+ <source>Number of connections</source>
+ <translation>Savienojumu skaits</translation>
+ </message>
+ <message>
+ <source>Block chain</source>
+ <translation>Bloku virkne</translation>
+ </message>
+ <message>
+ <source>Current number of blocks</source>
+ <translation>Pašreizējais bloku skaits</translation>
+ </message>
+ <message>
+ <source>Last block time</source>
+ <translation>Pēdējā bloka laiks</translation>
+ </message>
+ <message>
+ <source>&amp;Open</source>
+ <translation>&amp;Atvērt</translation>
+ </message>
+ <message>
+ <source>&amp;Console</source>
+ <translation>&amp;Konsole</translation>
+ </message>
+ <message>
+ <source>&amp;Network Traffic</source>
+ <translation>&amp;Tīkla Satiksme</translation>
+ </message>
+ <message>
+ <source>&amp;Clear</source>
+ <translation>&amp;Notīrīt</translation>
+ </message>
+ <message>
+ <source>Totals</source>
+ <translation>Kopsummas</translation>
+ </message>
+ <message>
+ <source>In:</source>
+ <translation>Ie.:</translation>
+ </message>
+ <message>
+ <source>Out:</source>
+ <translation>Iz.:</translation>
+ </message>
+ <message>
+ <source>Build date</source>
+ <translation>Kompilācijas datums</translation>
+ </message>
+ <message>
+ <source>Debug log file</source>
+ <translation>Atkļūdošanas žurnāla datne</translation>
+ </message>
+ <message>
+ <source>Clear console</source>
+ <translation>Notīrīt konsoli</translation>
+ </message>
+ <message>
+ <source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
+ <translation>Izmantojiet bultiņas uz augšu un leju, lai pārvietotos pa vēsturi, un &lt;b&gt;Ctrl-L&lt;/b&gt; ekrāna notīrīšanai.</translation>
+ </message>
+ <message>
+ <source>Type &lt;b&gt;help&lt;/b&gt; for an overview of available commands.</source>
+ <translation>Ierakstiet &lt;b&gt;help&lt;/b&gt; lai iegūtu pieejamo komandu sarakstu.</translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation>%1 B</translation>
+ </message>
+ <message>
+ <source>%1 KB</source>
+ <translation>%1 KB</translation>
+ </message>
+ <message>
+ <source>%1 MB</source>
+ <translation>%1 MB</translation>
+ </message>
+ <message>
+ <source>%1 GB</source>
+ <translation>%1 GB</translation>
+ </message>
+ </context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Amount:</source>
+ <translation>&amp;Daudzums:</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Nosaukums:</translation>
+ </message>
+ <message>
+ <source>&amp;Message:</source>
+ <translation>&amp;Ziņojums:</translation>
+ </message>
+ <message>
+ <source>R&amp;euse an existing receiving address (not recommended)</source>
+ <translation>&amp;Atkārtoti izmantot esošo saņemšanas adresi (nav ieteicams)</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Notīrīt visus laukus formā.</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation>Notīrīt</translation>
+ </message>
+ <message>
+ <source>Requested payments history</source>
+ <translation>Pieprasīto maksājumu vēsture</translation>
+ </message>
+ <message>
+ <source>&amp;Request payment</source>
+ <translation>&amp;Pieprasīt maksājumu</translation>
+ </message>
+ <message>
+ <source>Show the selected request (does the same as double clicking an entry)</source>
+ <translation>Parādīt atlasītos pieprasījumus (tas pats, kas dubultklikšķis uz ieraksta)</translation>
+ </message>
+ <message>
+ <source>Show</source>
+ <translation>Rādīt</translation>
+ </message>
+ <message>
+ <source>Remove the selected entries from the list</source>
+ <translation>Noņemt atlasītos ierakstus no saraksta.</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>Noņemt</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Kopēt nosaukumu</translation>
+ </message>
+ <message>
+ <source>Copy message</source>
+ <translation>Kopēt ziņojumu</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopēt daudzumu</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>QR Code</source>
+ <translation>QR Kods</translation>
+ </message>
+ <message>
+ <source>Copy &amp;URI</source>
+ <translation>Kopēt &amp;URI</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Address</source>
+ <translation>Kopēt &amp;Adresi</translation>
+ </message>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Saglabāt Attēlu...</translation>
+ </message>
+ <message>
+ <source>Request payment to %1</source>
+ <translation>Pieprasīt maksājumu uz %1</translation>
+ </message>
+ <message>
+ <source>Payment information</source>
+ <translation>Maksājuma informācija</translation>
+ </message>
+ <message>
+ <source>URI</source>
+ <translation>URI</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adrese</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Daudzums</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Nosaukums</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Ziņojums</translation>
+ </message>
+ <message>
+ <source>Resulting URI too long, try to reduce the text for label / message.</source>
+ <translation>Rezultāta URI pārāk garš, mēģiniet saīsināt nosaukumu vai ziņojumu. </translation>
+ </message>
+ <message>
+ <source>Error encoding URI into QR Code.</source>
+ <translation>Kļūda kodējot URI QR kodā.</translation>
+ </message>
+</context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Datums</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Nosaukums</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Ziņojums</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Daudzums</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(bez nosaukuma)</translation>
+ </message>
+ <message>
+ <source>(no message)</source>
+ <translation>(nav ziņojuma)</translation>
+ </message>
+ <message>
+ <source>(no amount)</source>
+ <translation>(nav summas)</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Sūtīt Bitkoinus</translation>
+ </message>
+ <message>
+ <source>Coin Control Features</source>
+ <translation>Bitcoin Kontroles Funkcijas</translation>
+ </message>
+ <message>
+ <source>Inputs...</source>
+ <translation>Ieejas...</translation>
+ </message>
+ <message>
+ <source>automatically selected</source>
+ <translation>automātiski atlasīts</translation>
+ </message>
+ <message>
+ <source>Insufficient funds!</source>
+ <translation>Nepietiekami līdzekļi!</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Daudzums:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Baiti:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Daudzums:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Prioritāte:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Maksa:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Pēc Maksas:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Atlikums:</translation>
+ </message>
+ <message>
+ <source>Custom change address</source>
+ <translation>Pielāgota atlikuma adrese</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>Sūtīt vairākiem saņēmējiem uzreiz</translation>
+ </message>
+ <message>
+ <source>Add &amp;Recipient</source>
+ <translation>&amp;Pievienot Saņēmēju</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Notīrīt visus laukus formā.</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>&amp;Notīrīt visu</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>Bilance:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>Apstiprināt nosūtīšanu</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>&amp;Sūtīt</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>Apstiprināt bitkoinu sūtīšanu</translation>
+ </message>
+ <message>
+ <source>%1 to %2</source>
+ <translation>%1 līdz %2</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Kopēt daudzumu</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopēt daudzumu</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Kopēt maksu</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Kopēt pēc maksas</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Kopēt baitus</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Kopēt prioritāti</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Kopēt atlikumu</translation>
+ </message>
+ <message>
+ <source>or</source>
+ <translation>vai</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>Nosūtāmajai summai jābūt lielākai par 0.</translation>
+ </message>
+ <message>
+ <source>The amount exceeds your balance.</source>
+ <translation>Daudzums pārsniedz pieejamo.</translation>
+ </message>
+ <message>
+ <source>The total exceeds your balance when the %1 transaction fee is included.</source>
+ <translation>Kopsumma pārsniedz pieejamo, ja pieskaitīta %1 transakcijas maksa.</translation>
+ </message>
+ <message>
+ <source>Transaction creation failed!</source>
+ <translation>Transakcijas izveidošana neizdevās!</translation>
+ </message>
+ <message>
+ <source>Warning: Invalid Bitcoin address</source>
+ <translation>Brīdinājums: Nederīga Bitcoin adrese</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(bez nosaukuma)</translation>
+ </message>
+ <message>
+ <source>Warning: Unknown change address</source>
+ <translation>Brīdinājums: Nezināma atlikuma adrese</translation>
+ </message>
+ <message>
+ <source>added as transaction fee</source>
+ <translation>pievienots kā transakcijas maksa</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>Apjo&amp;ms</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>&amp;Saņēmējs:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Lai pievienotu adresi adrešu grāmatai, tai jādod nosaukums</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Nosaukums:</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Izvēlies iepriekš izmantoto adresi</translation>
+ </message>
+ <message>
+ <source>This is a normal payment.</source>
+ <translation>Šis ir parasts maksājums.</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>ielīmēt adresi no starpliktuves</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Remove this entry</source>
+ <translation>Noņem šo ierakstu</translation>
+ </message>
+ <message>
+ <source>Message:</source>
+ <translation>Ziņojums:</translation>
+ </message>
+ <message>
+ <source>Pay To:</source>
+ <translation>Maksāt:</translation>
+ </message>
+ <message>
+ <source>Memo:</source>
+ <translation>Memo:</translation>
+ </message>
+</context>
+<context>
+ <name>ShutdownWindow</name>
+ <message>
+ <source>Bitcoin Core is shutting down...</source>
+ <translation>Bitcoin Core tiek izslēgta...</translation>
+ </message>
+ <message>
+ <source>Do not shut down the computer until this window disappears.</source>
+ <translation>Neizslēdziet datoru kamēr šis logs nepazūd.</translation>
+ </message>
+</context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Signatures - Sign / Verify a Message</source>
+ <translation>Paraksti - Parakstīt / Pabaudīt Ziņojumu</translation>
+ </message>
+ <message>
+ <source>&amp;Sign Message</source>
+ <translation>Parakstīt &amp;Ziņojumu</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Izvēlies iepriekš izmantoto adresi</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>ielīmēt adresi no starpliktuves</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Enter the message you want to sign here</source>
+ <translation>Šeit ievadi ziņojumu kuru vēlies parakstīt</translation>
+ </message>
+ <message>
+ <source>Signature</source>
+ <translation>Paraksts</translation>
+ </message>
+ <message>
+ <source>Copy the current signature to the system clipboard</source>
+ <translation>Kopēt parakstu uz sistēmas starpliktuvi</translation>
+ </message>
+ <message>
+ <source>Sign the message to prove you own this Bitcoin address</source>
+ <translation>Parakstīt ziņojumu lai pierādītu, ka esi šīs Bitcoin adreses īpašnieks.</translation>
+ </message>
+ <message>
+ <source>Sign &amp;Message</source>
+ <translation>Parakstīt &amp;Ziņojumu</translation>
+ </message>
+ <message>
+ <source>Reset all sign message fields</source>
+ <translation>Atiestatīt visus laukus</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>&amp;Notīrīt visu</translation>
+ </message>
+ <message>
+ <source>&amp;Verify Message</source>
+ <translation>&amp;Pārbaudīt Ziņojumu</translation>
+ </message>
+ <message>
+ <source>Verify &amp;Message</source>
+ <translation>&amp;Pārbaudīt Ziņojumu</translation>
+ </message>
+ <message>
+ <source>Reset all verify message fields</source>
+ <translation>Atiestatīt visus laukus</translation>
+ </message>
+ <message>
+ <source>Click "Sign Message" to generate signature</source>
+ <translation>Nospied "Parakstīt Ziņojumu" lai ģenerētu parakstu</translation>
+ </message>
+ <message>
+ <source>The entered address is invalid.</source>
+ <translation>Ievadītā adrese ir nederīga.</translation>
+ </message>
+ <message>
+ <source>Please check the address and try again.</source>
+ <translation>Lūdzu pārbaudi adresi un mēģini vēlreiz.</translation>
+ </message>
+ <message>
+ <source>The entered address does not refer to a key.</source>
+ <translation>Ievadītā adrese neattiecas uz atslēgu.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock was cancelled.</source>
+ <translation>Maciņa atslēgšana tika atcelta.</translation>
+ </message>
+ <message>
+ <source>Private key for the entered address is not available.</source>
+ <translation>Privātā atslēga priekš ievadītās adreses nav pieejama.</translation>
+ </message>
+ <message>
+ <source>Message signing failed.</source>
+ <translation>Neizdevās parakstīt ziņojumu.</translation>
+ </message>
+ <message>
+ <source>Message signed.</source>
+ <translation>Ziņojums parakstīts.</translation>
+ </message>
+ <message>
+ <source>The signature could not be decoded.</source>
+ <translation>Paraksts nevarēja tikt dekodēts.</translation>
+ </message>
+ <message>
+ <source>Please check the signature and try again.</source>
+ <translation>Lūdzu pārbaudi parakstu un mēģini vēlreiz.</translation>
+ </message>
+ <message>
+ <source>The signature did not match the message digest.</source>
+ <translation>Paraksts neatbilda ziņojuma apkopojumam.</translation>
+ </message>
+ <message>
+ <source>Message verification failed.</source>
+ <translation>Ziņojumu neizdevās pārbaudīt.</translation>
+ </message>
+ <message>
+ <source>Message verified.</source>
+ <translation>Ziņojums pārbaudīts.</translation>
+ </message>
+</context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>The Bitcoin Core developers</source>
+ <translation>Bitcoin Core izstrādātāji</translation>
+ </message>
+ <message>
+ <source>[testnet]</source>
+ <translation>[testnets]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ <message>
+ <source>KB/s</source>
+ <translation>KB/s</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>Atvērts līdz %1</translation>
+ </message>
+ <message>
+ <source>conflicted</source>
+ <translation>pretrunā</translation>
+ </message>
+ <message>
+ <source>%1/offline</source>
+ <translation>%1/bezsaistē</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/neapstiprinātas</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 apstiprinājumu</translation>
+ </message>
+ <message>
+ <source>Status</source>
+ <translation>Status</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Datums</translation>
+ </message>
+ <message>
+ <source>Source</source>
+ <translation>Avots</translation>
+ </message>
+ <message>
+ <source>Generated</source>
+ <translation>Ģenerēts</translation>
+ </message>
+ <message>
+ <source>From</source>
+ <translation>No</translation>
+ </message>
+ <message>
+ <source>To</source>
+ <translation>Uz</translation>
+ </message>
+ <message>
+ <source>own address</source>
+ <translation>paša adrese</translation>
+ </message>
+ <message>
+ <source>label</source>
+ <translation>etiķete</translation>
+ </message>
+ <message>
+ <source>Credit</source>
+ <translation>Kredīts</translation>
+ </message>
+ <message>
+ <source>not accepted</source>
+ <translation>nav pieņemts</translation>
+ </message>
+ <message>
+ <source>Debit</source>
+ <translation>Debets</translation>
+ </message>
+ <message>
+ <source>Transaction fee</source>
+ <translation>Transakcijas maksa</translation>
+ </message>
+ <message>
+ <source>Net amount</source>
+ <translation>Neto summa</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Ziņojums</translation>
+ </message>
+ <message>
+ <source>Comment</source>
+ <translation>Komentārs</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>Transakcijas ID</translation>
+ </message>
+ <message>
+ <source>Merchant</source>
+ <translation>Tirgotājs</translation>
+ </message>
+ <message>
+ <source>Debug information</source>
+ <translation>Atkļūdošanas informācija</translation>
+ </message>
+ <message>
+ <source>Transaction</source>
+ <translation>Transakcija</translation>
+ </message>
+ <message>
+ <source>Inputs</source>
+ <translation>Ieejas</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Daudzums</translation>
+ </message>
+ <message>
+ <source>true</source>
+ <translation>patiess</translation>
+ </message>
+ <message>
+ <source>false</source>
+ <translation>nepatiess</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, vēl nav veiksmīgi izziņots</translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>nav zināms</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>Transakcijas detaļas</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>Šis panelis parāda transakcijas detaļas</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Datums</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Tips</translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>Atvērts līdz %1</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>Apstiprināts (%1 apstiprinājumu)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>Neviens cits mezgls šo bloku nav saņēmis un droši vien netiks akceptēts!</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>Ģenerēts, taču nav akceptēts</translation>
+ </message>
+ <message>
+ <source>Offline</source>
+ <translation>Bezsaitē</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Nosaukums</translation>
+ </message>
+ <message>
+ <source>Unconfirmed</source>
+ <translation>Neapstiprināts</translation>
+ </message>
+ <message>
+ <source>Conflicted</source>
+ <translation>Pretrunā</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Saņemts ar</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>Saņemts no</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Nosūtīts</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>Maksājums sev</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Atrasts</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(nav pieejams)</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>Transakcijas statuss. Turiet peli virs šī lauka, lai redzētu apstiprinājumu skaitu.</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Transakcijas saņemšanas datums un laiks.</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>Transakcijas tips.</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>Bilancei pievienotais vai atņemtais daudzums.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>Visi</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>Šodien</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>Šonedēļ</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>Šomēnes</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>Pēdējais mēnesis</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>Šogad</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>Diapazons...</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Saņemts ar</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Nosūtīts</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>Sev</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Atrasts</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>Cits</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>Ierakstiet meklējamo nosaukumu vai adresi</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>Minimālais daudzums</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Kopēt adresi</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Kopēt nosaukumu</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopēt daudzumu</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Kopēt transakcijas ID</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>Mainīt nosaukumu</translation>
+ </message>
+ <message>
+ <source>Show transaction details</source>
+ <translation>Rādīt transakcijas detaļas</translation>
+ </message>
+ <message>
+ <source>Export Transaction History</source>
+ <translation>Eksportēt Transakciju Vēsturi</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Eksportēšana Neizdevās</translation>
+ </message>
+ <message>
+ <source>Exporting Successful</source>
+ <translation>Eksportēšana Veiksmīga</translation>
+ </message>
+ <message>
+ <source>The transaction history was successfully saved to %1.</source>
+ <translation>Transakciju vēsture tika veiksmīgi saglabāta uz %1.</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Fails ar komatu kā atdalītāju (*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Apstiprināts</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Datums</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Tips</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Nosaukums</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adrese</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>Diapazons:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>uz</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ </context>
+<context>
+ <name>WalletFrame</name>
+ <message>
+ <source>No wallet has been loaded.</source>
+ <translation>Neviens maciņš nav ielādēts.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Sūtīt Bitkoinus</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Eksportēt</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Datus no tekošā ieliktņa eksportēt uz failu</translation>
+ </message>
+ <message>
+ <source>Backup Wallet</source>
+ <translation>Izveidot maciņa rezerves kopiju</translation>
+ </message>
+ <message>
+ <source>Wallet Data (*.dat)</source>
+ <translation>Maciņa dati (*.dat)</translation>
+ </message>
+ <message>
+ <source>Backup Failed</source>
+ <translation>Rezerves kopēšana neizdevās</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the wallet data to %1.</source>
+ <translation>Notikusi kļūme mēģinot saglabāt maciņa datus uz %1.</translation>
+ </message>
+ <message>
+ <source>The wallet data was successfully saved to %1.</source>
+ <translation>Maciņa dati tika veiksmīgi saglabāti uz %1.</translation>
+ </message>
+ <message>
+ <source>Backup Successful</source>
+ <translation>Dublēšana Veiksmīga</translation>
+ </message>
+</context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>Iespējas:</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>Norādiet datu direktoriju</translation>
+ </message>
+ <message>
+ <source>Connect to a node to retrieve peer addresses, and disconnect</source>
+ <translation>Pievienoties mezglam, lai iegūtu citu mezglu adreses, un atvienoties</translation>
+ </message>
+ <message>
+ <source>Specify your own public address</source>
+ <translation>Norādiet savu publisko adresi</translation>
+ </message>
+ <message>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>Pieņemt komandrindas un JSON-RPC komandas</translation>
+ </message>
+ <message>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>Darbināt fonā kā servisu un pieņemt komandas</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>Izmantot testa tīklu</translation>
+ </message>
+ <message>
+ <source>(default: 1)</source>
+ <translation>(noklusējums: 1)</translation>
+ </message>
+ <message>
+ <source>&lt;category&gt; can be:</source>
+ <translation>&lt;category&gt; var būt:</translation>
+ </message>
+ <message>
+ <source>Attempt to recover private keys from a corrupt wallet.dat</source>
+ <translation>Mēģināt atgūt privātās atslēgas no bojāta wallet.dat</translation>
+ </message>
+ <message>
+ <source>Block creation options:</source>
+ <translation>Bloka izveidošanas iestatījumi:</translation>
+ </message>
+ <message>
+ <source>Connect only to the specified node(s)</source>
+ <translation>Savienoties tikai ar norādītajām nodēm.</translation>
+ </message>
+ <message>
+ <source>Connection options:</source>
+ <translation>Savienojuma iestatījumi:</translation>
+ </message>
+ <message>
+ <source>Debugging/Testing options:</source>
+ <translation>Atkļūdošanas/Testēšanas iestatījumi:</translation>
+ </message>
+ <message>
+ <source>Error loading block database</source>
+ <translation>Kļūda ielādējot bloku datubāzi</translation>
+ </message>
+ <message>
+ <source>Error: Disk space is low!</source>
+ <translation>Kļūda: Zema diska vieta!</translation>
+ </message>
+ <message>
+ <source>If &lt;category&gt; is not supplied, output all debugging information.</source>
+ <translation>Ja &lt;category&gt; nav norādīta, izvadīt visu atkļūdošanas informāciju.</translation>
+ </message>
+ <message>
+ <source>Importing...</source>
+ <translation>Importē...</translation>
+ </message>
+ <message>
+ <source>Verifying blocks...</source>
+ <translation>Pārbauda blokus...</translation>
+ </message>
+ <message>
+ <source>Verifying wallet...</source>
+ <translation>Pārbauda maciņu...</translation>
+ </message>
+ <message>
+ <source>Wallet options:</source>
+ <translation>Maciņa iespējas:</translation>
+ </message>
+ <message>
+ <source>Imports blocks from external blk000??.dat file</source>
+ <translation>Importēt blokus no ārējās blk000??.dat datnes</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Informācija</translation>
+ </message>
+ <message>
+ <source>RPC server options:</source>
+ <translation>RPC servera iestatījumi:</translation>
+ </message>
+ <message>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>Debug/trace informāciju izvadīt konsolē, nevis debug.log failā</translation>
+ </message>
+ <message>
+ <source>Set language, for example "de_DE" (default: system locale)</source>
+ <translation>Uzstādiet valodu, piemēram "de_DE" (pēc noklusēšanas: sistēmas lokāle)</translation>
+ </message>
+ <message>
+ <source>Show splash screen on startup (default: 1)</source>
+ <translation>Uzsākot, parādīt programmas informācijas logu (pēc noklusēšanas: 1)</translation>
+ </message>
+ <message>
+ <source>Signing transaction failed</source>
+ <translation>Transakcijas parakstīšana neizdevās</translation>
+ </message>
+ <message>
+ <source>Start minimized</source>
+ <translation>Sākt minimizētu</translation>
+ </message>
+ <message>
+ <source>Transaction amount too small</source>
+ <translation>Transakcijas summa ir pārāk maza</translation>
+ </message>
+ <message>
+ <source>Transaction amounts must be positive</source>
+ <translation>Transakcijas summai ir jābūt pozitīvai</translation>
+ </message>
+ <message>
+ <source>Transaction too large</source>
+ <translation>Transakcija ir pārāk liela</translation>
+ </message>
+ <message>
+ <source>Username for JSON-RPC connections</source>
+ <translation>JSON-RPC savienojumu lietotājvārds</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Brīdinājums</translation>
+ </message>
+ <message>
+ <source>on startup</source>
+ <translation>startēšanas laikā</translation>
+ </message>
+ <message>
+ <source>wallet.dat corrupt, salvage failed</source>
+ <translation>wallet.dat ir bojāts, glābšana neizdevās</translation>
+ </message>
+ <message>
+ <source>Password for JSON-RPC connections</source>
+ <translation>JSON-RPC savienojumu parole</translation>
+ </message>
+ <message>
+ <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
+ <translation>Izpildīt komandu, kad labāk atbilstošais bloks izmainās (%s cmd aizvieto ar bloka hešu)</translation>
+ </message>
+ <message>
+ <source>Upgrade wallet to latest format</source>
+ <translation>Atjaunot maciņa formātu uz jaunāko</translation>
+ </message>
+ <message>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>Atkārtoti skanēt bloku virkni, meklējot trūkstošās maciņa transakcijas</translation>
+ </message>
+ <message>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>JSON-RPC savienojumiem izmantot OpenSSL (https)</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>Šis palīdzības paziņojums</translation>
+ </message>
+ <message>
+ <source>Allow DNS lookups for -addnode, -seednode and -connect</source>
+ <translation>Atļaut DNS uzmeklēšanu priekš -addnode, -seednode un -connect</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>Ielādē adreses...</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>Nevar ielādēt wallet.dat: maciņš bojāts</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>Kļūda ielādējot wallet.dat</translation>
+ </message>
+ <message>
+ <source>Invalid -proxy address: '%s'</source>
+ <translation>Nederīga -proxy adrese: '%s'</translation>
+ </message>
+ <message>
+ <source>Unknown network specified in -onlynet: '%s'</source>
+ <translation>-onlynet komandā norādīts nepazīstams tīkls: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -bind address: '%s'</source>
+ <translation>Nevar uzmeklēt -bind adresi: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -externalip address: '%s'</source>
+ <translation>Nevar atrisināt -externalip adresi: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Nederīgs daudzums priekš -paytxfree=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>Nepietiek bitkoinu</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>Ielādē bloku indeksu...</translation>
+ </message>
+ <message>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>Pievienot mezglu, kam pievienoties un turēt savienojumu atvērtu</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>Ielādē maciņu...</translation>
+ </message>
+ <message>
+ <source>Cannot downgrade wallet</source>
+ <translation>Nevar maciņa formātu padarīt vecāku</translation>
+ </message>
+ <message>
+ <source>Cannot write default address</source>
+ <translation>Nevar ierakstīt adresi pēc noklusēšanas</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>Skanēju no jauna...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>Ielāde pabeigta</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Kļūda</translation>
+ </message>
+</context>
+</TS> \ No newline at end of file
diff --git a/src/qt/locale/bitcoin_mn.ts b/src/qt/locale/bitcoin_mn.ts
new file mode 100644
index 0000000000..699031270f
--- /dev/null
+++ b/src/qt/locale/bitcoin_mn.ts
@@ -0,0 +1,1078 @@
+<TS language="mn" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Create a new address</source>
+ <translation>Шинэ хаяг нээх</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>&amp;Шинэ</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Одоогоор сонгогдсон байгаа хаягуудыг сануулах</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>&amp;Хуулах</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>&amp;Хаах</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>Хаягийг &amp;Хуулбарлах</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>Одоо сонгогдсон байгаа хаягуудыг жагсаалтаас устгах</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Сонгогдсон таб дээрхи дата-г экспортлох</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Экспортдлох</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;Устгах</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>Зооснуудыг илгээх хаягийг сонгоно уу</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>Зооснуудыг хүлээн авах хаягийг сонгоно уу</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>Илгээх хаягууд</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>Хүлээн авах хаяг</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>Эдгээр Биткойн хаягууд нь илгээх хаягууд. Хүлээн авах хаяг болон тоо хэмжээг илгээхээсээ өмнө сайн нягталж үзэж байна уу</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>Эдгээр Биткойн хаягууд нь хүлээн авах хаягууд. Гүйлгээ болгонд шинээр хаяг үүсгэхийг бид санал болгож байна.</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>&amp;Шошгыг хуулбарлах</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>&amp;Ѳѳрчлѳх</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>Экспорт хийх хаягуудын жагсаалт</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Таслалаар тусгаарлагдсан хүснэгтэн файл (.csv)</translation>
+ </message>
+ </context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Шошго</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Хаяг</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(шошгогүй)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Нууц үгийг оруул</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Шинэ нууц үг</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Шинэ нууц үгийг давтана уу</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>Түрүйвчийг цоожлох</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>Энэ үйлдэлийг гүйцэтгэхийн тулд та нууц үгээрээ түрүйвчийн цоожийг тайлах хэрэгтэй</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Түрүйвчийн цоожийг тайлах</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>Энэ үйлдэлийг гүйцэтгэхийн тулд та эхлээд түрүйвчийн нууц үгийг оруулж цоожийг тайлах шаардлагтай.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>Түрүйвчийн цоожийг устгах</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>Нууц үгийг солих</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>Түрүйвчийн цоожийг баталгаажуулах</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>Түрүйвч цоожлогдлоо</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>Түрүйвчийн цоожлол амжилттай болсонгүй</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>Түрүйвчийн цоожлол дотоод алдаанаас үүдэн амжилттай болсонгүй. Түрүйвч цоожлогдоогүй байна.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>Таны оруулсан нууц үг таарсангүй</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>Түрүйвчийн цоож тайлагдсангүй</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>Таны оруулсан түрүйвчийн цоожийг тайлах нууц үг буруу байна</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>Түрүйвчийн цоож амжилттай устгагдсангүй</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>Түрүйвчийн нууц үг амжилттай ѳѳр</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>&amp;Зурвас хавсаргах...</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>Сүлжээтэй тааруулж байна...</translation>
+ </message>
+ <message>
+ <source>Node</source>
+ <translation>Нод</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>Гүйлгээнүүд</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>Гүйлгээнүүдийн түүхийг харах</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>Гарах</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>Програмаас Гарах</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>&amp;Клиентийн тухай</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>Клиентийн тухай мэдээллийг харуул</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;Сонголтууд...</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>&amp;Түрүйвчийг цоожлох...</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>&amp;Түрүйвчийг Жоорлох...</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>&amp;Нууц Үгийг Солих...</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Түрүйвчийг цоожлох нууц үгийг солих</translation>
+ </message>
+ <message>
+ <source>Open debugging and diagnostic console</source>
+ <translation>Оношилгоо ба засварын консолыг онгойлго</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Биткойн</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>Түрүйвч</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>&amp;Харуул / Нуу</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;Файл</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;Тохиргоо</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>&amp;Тусламж</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Алдаа</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>Шинэчлэгдсэн</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>Гадагшаа гүйлгээ</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>Дотогшоо гүйлгээ</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>Түрүйвч &lt;b&gt;цоожтой&lt;/b&gt; ба одоогоор цоож &lt;b&gt;онгорхой&lt;/b&gt; байна</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>Түрүйвч &lt;b&gt;цоожтой&lt;/b&gt; ба одоогоор цоож &lt;b&gt;хаалттай&lt;/b&gt; байна</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ </context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Amount:</source>
+ <translation>Хэмжээ:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Тѳлбѳр:</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Хэмжээ</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Огноо</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Баталгаажлаа</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Хаягийг санах</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Шошгыг санах</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Хэмжээг санах</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Ѳѳрчлѳлтийг санах</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(шошгогүй)</translation>
+ </message>
+ <message>
+ <source>(change)</source>
+ <translation>(ѳѳрчлѳх)</translation>
+ </message>
+</context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>Хаягийг ѳѳрчлѳх</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>&amp;Шошго</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;Хаяг</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>Шинэ хүлээн авах хаяг</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>Шинэ явуулах хаяг</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>Хүлээн авах хаягийг ѳѳрчлѳх</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>Явуулах хаягийг ѳѳрчлѳх</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>Таны оруулсан хаяг "%1" нь хаягийн бүртгэлд ѳмнѳ нь орсон байна</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>Түрүйвчийн цоожийг тайлж чадсангүй</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>Шинэ түлхүүр амжилттай гарсангүй</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ </context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>version</source>
+ <translation>хувилбар</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>Хэрэглээ:</translation>
+ </message>
+ </context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Error</source>
+ <translation>Алдаа</translation>
+ </message>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ </context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>Сонголтууд</translation>
+ </message>
+ <message>
+ <source>MB</source>
+ <translation>МБ</translation>
+ </message>
+ <message>
+ <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
+ <translation>проксигийн IP хаяг (жишээ нь: IPv4: 127.0.0.1 / IPv6: ::1)</translation>
+ </message>
+ <message>
+ <source>Client restart required to activate changes.</source>
+ <translation>Ѳѳрчлѳлтүүдийг идэвхижүүлхийн тулд клиентийг ахин эхлүүлэх шаардлагтай</translation>
+ </message>
+ <message>
+ <source>This change would require a client restart.</source>
+ <translation>Энэ ѳѳрчлѳлтийг оруулахын тулд кли1нт програмыг ахин эхлүүлэх шаардлагтай</translation>
+ </message>
+ </context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Available:</source>
+ <translation>Хэрэглэж болох хэмжээ:</translation>
+ </message>
+ </context>
+<context>
+ <name>PaymentServer</name>
+ </context>
+<context>
+ <name>PeerTableModel</name>
+ </context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>Хэмжээ</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>Алга Байна</translation>
+ </message>
+ </context>
+<context>
+ <name>QRImageWidget</name>
+ <message>
+ <source>PNG Image (*.png)</source>
+ <translation>PNG форматын зураг (*.png)</translation>
+ </message>
+</context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>Client name</source>
+ <translation>Клиентийн нэр</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>Алга Байна</translation>
+ </message>
+ <message>
+ <source>Client version</source>
+ <translation>Клиентийн хувилбар</translation>
+ </message>
+ <message>
+ <source>&amp;Information</source>
+ <translation>&amp;Мэдээллэл</translation>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>Ерѳнхий</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Сүлжээ</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>Нэр</translation>
+ </message>
+ <message>
+ <source>Number of connections</source>
+ <translation>Холболтын тоо</translation>
+ </message>
+ <message>
+ <source>Block chain</source>
+ <translation>Блокийн цуваа</translation>
+ </message>
+ <message>
+ <source>Current number of blocks</source>
+ <translation>Одоогийн блокийн тоо</translation>
+ </message>
+ <message>
+ <source>Last block time</source>
+ <translation>Сүүлийн блокийн хугацаа</translation>
+ </message>
+ <message>
+ <source>&amp;Open</source>
+ <translation>&amp;Нээх</translation>
+ </message>
+ <message>
+ <source>&amp;Console</source>
+ <translation>&amp;Консол</translation>
+ </message>
+ <message>
+ <source>Clear console</source>
+ <translation>Консолыг цэвэрлэх</translation>
+ </message>
+ </context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Шошго:</translation>
+ </message>
+ <message>
+ <source>Show</source>
+ <translation>Харуул</translation>
+ </message>
+ <message>
+ <source>Remove the selected entries from the list</source>
+ <translation>Сонгогдсон ѳгѳгдлүүдийг устгах</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>Устгах</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Шошгыг санах</translation>
+ </message>
+ <message>
+ <source>Copy message</source>
+ <translation>Зурвасыг санах</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Хэмжээг санах</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>Address</source>
+ <translation>Хаяг</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Хэмжээ</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Шошго</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Зурвас</translation>
+ </message>
+ </context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Огноо</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Шошго</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Зурвас</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Хэмжээ</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(шошгогүй)</translation>
+ </message>
+ <message>
+ <source>(no message)</source>
+ <translation>(зурвас алга)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Зоос явуулах</translation>
+ </message>
+ <message>
+ <source>automatically selected</source>
+ <translation>автоматаар сонгогдсон</translation>
+ </message>
+ <message>
+ <source>Insufficient funds!</source>
+ <translation>Таны дансны үлдэгдэл хүрэлцэхгүй байна!</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Хэмжээ:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Тѳлбѳр:</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>Нэгэн зэрэг олон хүлээн авагчруу явуулах</translation>
+ </message>
+ <message>
+ <source>Add &amp;Recipient</source>
+ <translation>&amp;Хүлээн авагчийг Нэмэх</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>&amp;Бүгдийг Цэвэрлэ</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>Баланс:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>Явуулах үйлдлийг баталгаажуулна уу</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>Яв&amp;уул</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>Зоос явуулахыг баталгаажуулна уу</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Хэмжээг санах</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Ѳѳрчлѳлтийг санах</translation>
+ </message>
+ <message>
+ <source>or</source>
+ <translation>эсвэл</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>Тѳлѳх хэмжээ 0.-оос их байх ёстой</translation>
+ </message>
+ <message>
+ <source>The amount exceeds your balance.</source>
+ <translation>Энэ хэмжээ таны балансаас хэтэрсэн байна.</translation>
+ </message>
+ <message>
+ <source>The total exceeds your balance when the %1 transaction fee is included.</source>
+ <translation>Гүйлгээний тѳлбѳр %1-ийг тооцхоор нийт дүн нь таны балансаас хэтрээд байна.</translation>
+ </message>
+ <message>
+ <source>Warning: Invalid Bitcoin address</source>
+ <translation>Анхаар:Буруу Биткойны хаяг байна</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(шошгогүй)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>Дүн:</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>Тѳлѳх &amp;хаяг:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Энэ хаягийг ѳѳрийн бүртгэлдээ авахын тулд шошго оруул</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Шошго:</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Копидсон хаягийг буулгах</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Message:</source>
+ <translation>Зурвас:</translation>
+ </message>
+ </context>
+<context>
+ <name>ShutdownWindow</name>
+ <message>
+ <source>Bitcoin Core is shutting down...</source>
+ <translation>Биткойны цѳм хаагдаж байна...</translation>
+ </message>
+ <message>
+ <source>Do not shut down the computer until this window disappears.</source>
+ <translation>Энэ цонхыг хаагдтал компьютерээ бүү унтраагаарай</translation>
+ </message>
+</context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Копидсон хаягийг буулгах</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>&amp;Бүгдийг Цэвэрлэ</translation>
+ </message>
+ </context>
+<context>
+ <name>SplashScreen</name>
+ </context>
+<context>
+ <name>TrafficGraphWidget</name>
+ </context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>%1 хүртэл нээлттэй</translation>
+ </message>
+ <message>
+ <source>conflicted</source>
+ <translation>зѳрчилдлѳѳ</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/баталгаажаагүй</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 баталгаажилтууд</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Огноо</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Зурвас</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>Тодорхойлолт</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Хэмжээ</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, хараахан амжилттай цацагдаагүй байна</translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>үл мэдэгдэх</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>Гүйлгээний мэдээллэл</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>Гүйлгээний дэлгэрэнгүйг энэ бичил цонх харуулж байна</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Огноо</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Тѳрѳл</translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>%1 хүртэл нээлттэй</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>Баталгаажлаа (%1 баталгаажилт)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>Энэ блокийг аль ч нод хүлээн авсангүй ба ер нь зѳвшѳѳрѳгдѳхгүй байж мэднэ!</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>Үүсгэгдсэн гэхдээ хүлээн авагдаагүй</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Шошго</translation>
+ </message>
+ <message>
+ <source>Unconfirmed</source>
+ <translation>Баталгаажаагүй</translation>
+ </message>
+ <message>
+ <source>Conflicted</source>
+ <translation>Зѳрчилдлѳѳ</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Хүлээн авсан хаяг</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>Хүлээн авагдсан хаяг</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Явуулсан хаяг</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>Ѳѳрлүүгээ хийсэн тѳлбѳр</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Олборлогдсон</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(алга байна)</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>Гүйлгээний байдал. Энд хулганыг авчирч баталгаажуулалтын тоог харна уу.</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Гүйлгээг хүлээн авсан огноо ба цаг.</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>Гүйлгээний тѳрѳл</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>Балансаас авагдсан болон нэмэгдсэн хэмжээ.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>Бүгд</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>Ѳнѳѳдѳр</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>Энэ долоо хоног</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>Энэ сар</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>Ѳнгѳрсѳн сар</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>Энэ жил</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Хүлээн авсан хаяг</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Явуулсан хаяг</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>Ѳѳрлүүгээ</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Олборлогдсон</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>Бусад</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>Хайлт хийхийн тулд хаяг эсвэл шошгыг оруул</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>Хамгийн бага хэмжээ</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Хаягийг санах</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Шошгыг санах</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Хэмжээг санах</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>Шошгыг ѳѳрчлѳх</translation>
+ </message>
+ <message>
+ <source>Show transaction details</source>
+ <translation>Гүйлгээний дэлгэрэнгүйг харуул</translation>
+ </message>
+ <message>
+ <source>The transaction history was successfully saved to %1.</source>
+ <translation>Гүйлгээнүй түүхийг %1-д амжилттай хадгаллаа.</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Таслалаар тусгаарлагдсан хүснэгтэн файл (.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Баталгаажлаа</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Огноо</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Тѳрѳл</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Шошго</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Хаяг</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>Тодорхойлолт</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>-рүү/руу</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ </context>
+<context>
+ <name>WalletFrame</name>
+ <message>
+ <source>No wallet has been loaded.</source>
+ <translation>Ямар ч түрүйвч ачааллагдсангүй.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Зоос явуулах</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Экспортдлох</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Сонгогдсон таб дээрхи дата-г экспортлох</translation>
+ </message>
+ </context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>Сонголтууд:</translation>
+ </message>
+ <message>
+ <source>Wallet options:</source>
+ <translation>Түрүйвчийн сонголтууд:</translation>
+ </message>
+ <message>
+ <source>Upgrade wallet to latest format</source>
+ <translation>Түрүйвчийг хамгийн сүүлийн үеийн форматруу шинэчлэх</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>Хаягуудыг ачааллаж байна...</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>wallet.dat-ыг ачааллахад алдаа гарлаа: Түрүйвч эвдэрсэн байна</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>wallet.dat-ыг ачааллахад алдаа гарлаа</translation>
+ </message>
+ <message>
+ <source>Invalid -proxy address: '%s'</source>
+ <translation>Эдгээр прокси хаягнууд буруу байна: '%s'</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>Таны дансны үлдэгдэл хүрэлцэхгүй байна</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>Блокийн индексүүдийг ачааллаж байна...</translation>
+ </message>
+ <message>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>Холболт хийхийн тулд мѳн холболтой онгорхой хадгалхын тулд шинэ нод нэм</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>Түрүйвчийг ачааллаж байна...</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>Ахин уншиж байна...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>Ачааллаж дууслаа</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Алдаа</translation>
+ </message>
+</context>
+</TS> \ No newline at end of file
diff --git a/src/qt/locale/bitcoin_ms_MY.ts b/src/qt/locale/bitcoin_ms_MY.ts
new file mode 100644
index 0000000000..5e10c80aff
--- /dev/null
+++ b/src/qt/locale/bitcoin_ms_MY.ts
@@ -0,0 +1,190 @@
+<TS language="ms_MY" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Create a new address</source>
+ <translation>Cipta alamat baru</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>&amp;Baru</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Salin alamat terpilih ke dalam sistem papan klip</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>&amp;Salin</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>&amp;Salin Alamat</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Eksport</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;Padam</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>Pilih alamat untuk menghantar syiling</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>Pilih alamat untuk menerima syiling</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>&amp;Pilih</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Fail yang dipisahkan dengan koma</translation>
+ </message>
+ </context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Address</source>
+ <translation>Alamat</translation>
+ </message>
+ </context>
+<context>
+ <name>AskPassphraseDialog</name>
+ </context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>Pilihan</translation>
+ </message>
+ </context>
+<context>
+ <name>ClientModel</name>
+ </context>
+<context>
+ <name>CoinControlDialog</name>
+ </context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>Alamat</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>Alamat</translation>
+ </message>
+ </context>
+<context>
+ <name>FreespaceChecker</name>
+ </context>
+<context>
+ <name>HelpMessageDialog</name>
+ </context>
+<context>
+ <name>Intro</name>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ </context>
+<context>
+ <name>OptionsDialog</name>
+ </context>
+<context>
+ <name>OverviewPage</name>
+ </context>
+<context>
+ <name>PaymentServer</name>
+ </context>
+<context>
+ <name>PeerTableModel</name>
+ </context>
+<context>
+ <name>QObject</name>
+ </context>
+<context>
+ <name>QRImageWidget</name>
+ </context>
+<context>
+ <name>RPCConsole</name>
+ </context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ </context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>Address</source>
+ <translation>Alamat</translation>
+ </message>
+ </context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ </context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Balance:</source>
+ <translation>Baki</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsEntry</name>
+ </context>
+<context>
+ <name>ShutdownWindow</name>
+ </context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ </context>
+<context>
+ <name>SplashScreen</name>
+ </context>
+<context>
+ <name>TrafficGraphWidget</name>
+ </context>
+<context>
+ <name>TransactionDesc</name>
+ </context>
+<context>
+ <name>TransactionDescDialog</name>
+ </context>
+<context>
+ <name>TransactionTableModel</name>
+ </context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Fail yang dipisahkan dengan koma</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Alamat</translation>
+ </message>
+ </context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ </context>
+<context>
+ <name>WalletFrame</name>
+ </context>
+<context>
+ <name>WalletModel</name>
+ </context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Eksport</translation>
+ </message>
+ </context>
+<context>
+ <name>bitcoin-core</name>
+ </context>
+</TS> \ 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 0000000000..13bf4bd19e
--- /dev/null
+++ b/src/qt/locale/bitcoin_nb.ts
@@ -0,0 +1,3592 @@
+<TS language="nb" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Right-click to edit address or label</source>
+ <translation>Høyreklikk for å redigere adressen eller merkelappen</translation>
+ </message>
+ <message>
+ <source>Create a new address</source>
+ <translation>Opprett en ny addresse</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>&amp;Ny</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Kopier den valgte adressen til systemets utklippstavle</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>&amp;Kopier</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>&amp;Lukk</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>&amp;Kopier Adresse</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>Slett den valgte adressen fra listen.</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Eksporter data fra nåværende fane til fil</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Eksporter</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;Slett</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>Velg adressen å sende mynter til</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>Velg adressen til å motta mynter med</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>&amp;Velg</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>Utsendingsadresser</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>Mottaksadresser</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>Dette er dine Bitcoin-adresser for å sende betalinger. Alltid sjekk beløp og mottakeradresse før sending av mynter.</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>Dette er dine Bitcoin-adresser for å sende betalinger. Det er anbefalt å bruk en ny mottaksadresse for hver transaksjon.</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>Kopier &amp;Merkelapp</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>&amp;Rediger</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>Ekporter Adresseliste</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Kommaseparert fil (*.csv)</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Eksportering feilet</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the address list to %1. Please try again.</source>
+ <translation>Det oppstod en feil under lagring av adresselisten til %1. Vennligst prøv på nytt.</translation>
+ </message>
+</context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Merkelapp</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adresse</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(ingen merkelapp)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Passphrase Dialog</source>
+ <translation>Dialog for Adgangsfrase</translation>
+ </message>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Angi adgangsfrase</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Ny adgangsfrase</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Gjenta ny adgangsfrase</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>Krypter lommebok</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>Denne operasjonen krever adgangsfrasen til lommeboken for å låse den opp.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Lås opp lommebok</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>Denne operasjonen krever adgangsfrasen til lommeboken for å dekryptere den.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>Dekrypter lommebok</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>Endre adgangsfrase</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>Bekreft kryptering av lommebok</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>Advarsel: Hvis du krypterer lommeboken og mister adgangsfrasen, så vil du &lt;b&gt;MISTE ALLE DINE BITCOINS&lt;/b&gt;!</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>Er du sikker på at du vil kryptere lommeboken?</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core 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.</source>
+ <translation>Bitcoin Core vil nå avslutte for å fullføre krypteringsprosessen. Husk at kryptering av lommeboken ikke kan beskytte fullstendig mot tyveri av dine bitcoins hvis datamaskinen din er infisert av skadevare.</translation>
+ </message>
+ <message>
+ <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
+ <translation>VIKTIG: Tidligere sikkerhetskopier av din lommebokfil bør erstattes med den nylig genererte og krypterte filen, da de blir ugyldiggjort av sikkerhetshensyn så snart du begynner å bruke den nye krypterte lommeboken.</translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>Advarsel: Caps Lock er på!</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>Lommebok kryptert</translation>
+ </message>
+ <message>
+ <source>Enter the new passphrase to the wallet.&lt;br/&gt;Please use a passphrase of &lt;b&gt;ten or more random characters&lt;/b&gt;, or &lt;b&gt;eight or more words&lt;/b&gt;.</source>
+ <translation>Oppgi adgangsfrasen til lommeboken.&lt;br/&gt;Vennligst bruk en adgangsfrase med &lt;b&gt;ti eller flere tilfeldige tegn&lt;/b&gt;, eller &lt;b&gt;åtte eller flere ord&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>Enter the old passphrase and new passphrase to the wallet.</source>
+ <translation>Oppgi gammel og ny adgangsfrase til lommeboken.</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>Kryptering av lommebok feilet</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>Kryptering av lommebok feilet på grunn av en intern feil. Din lommebok ble ikke kryptert.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>De angitte adgangsfrasene er ulike.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>Opplåsing av lommebok feilet</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>Adgangsfrasen angitt for dekryptering av lommeboken var feil.</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>Dekryptering av lommebok feilet</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>Adgangsfrase for lommebok endret.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>Signer &amp;melding...</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>Synkroniserer med nettverk...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;Oversikt</translation>
+ </message>
+ <message>
+ <source>Node</source>
+ <translation>Node</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>Vis generell oversikt over lommeboken</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Transaksjoner</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>Vis transaksjonshistorikk</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>&amp;Avslutt</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>Avslutt applikasjonen</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>Om &amp;Qt</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>Vis informasjon om Qt</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;Innstillinger...</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>&amp;Krypter Lommebok...</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>Lag &amp;Sikkerhetskopi av Lommebok...</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>&amp;Endre Adgangsfrase...</translation>
+ </message>
+ <message>
+ <source>&amp;Sending addresses...</source>
+ <translation>&amp;Utsendingsadresser...</translation>
+ </message>
+ <message>
+ <source>&amp;Receiving addresses...</source>
+ <translation>&amp;Mottaksadresser...</translation>
+ </message>
+ <message>
+ <source>Open &amp;URI...</source>
+ <translation>Åpne &amp;URI...</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core client</source>
+ <translation>Bitcoin Core-klient</translation>
+ </message>
+ <message>
+ <source>Importing blocks from disk...</source>
+ <translation>Importere blokker...</translation>
+ </message>
+ <message>
+ <source>Reindexing blocks on disk...</source>
+ <translation>Reindekserer blokker på harddisk...</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>Send til en Bitcoin-adresse</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>Sikkerhetskopier lommebok til annet sted</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Endre adgangsfrasen brukt for kryptering av lommebok</translation>
+ </message>
+ <message>
+ <source>&amp;Debug window</source>
+ <translation>&amp;Feilsøkingsvindu</translation>
+ </message>
+ <message>
+ <source>Open debugging and diagnostic console</source>
+ <translation>Åpne konsoll for feilsøk og diagnostikk</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>&amp;Verifiser melding...</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>Lommebok</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>&amp;Send</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>&amp;Motta</translation>
+ </message>
+ <message>
+ <source>Show information about Bitcoin Core</source>
+ <translation>Vis informasjon om Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>&amp;Vis / Skjul</translation>
+ </message>
+ <message>
+ <source>Show or hide the main Window</source>
+ <translation>Vis eller skjul hovedvinduet</translation>
+ </message>
+ <message>
+ <source>Encrypt the private keys that belong to your wallet</source>
+ <translation>Krypter de private nøklene som tilhører lommeboken din</translation>
+ </message>
+ <message>
+ <source>Sign messages with your Bitcoin addresses to prove you own them</source>
+ <translation>Signer en melding med Bitcoin-adressene dine for å bevise at du eier dem</translation>
+ </message>
+ <message>
+ <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source>
+ <translation>Bekreft meldinger for å være sikker på at de ble signert av en angitt Bitcoin-adresse</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;Fil</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;Innstillinger</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>&amp;Hjelp</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>Verktøylinje for faner</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Request payments (generates QR codes and bitcoin: URIs)</source>
+ <translation>Forespør betalinger (genererer QR-koder og bitcoin: URIer)</translation>
+ </message>
+ <message>
+ <source>&amp;About Bitcoin Core</source>
+ <translation>&amp;Om Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Modify configuration options for Bitcoin Core</source>
+ <translation>Endre konfigurasjonsvalg for Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Show the list of used sending addresses and labels</source>
+ <translation>Vis listen av brukte utsendingsadresser og merkelapper</translation>
+ </message>
+ <message>
+ <source>Show the list of used receiving addresses and labels</source>
+ <translation>Vis listen over bruke mottaksadresser og merkelapper</translation>
+ </message>
+ <message>
+ <source>Open a bitcoin: URI or payment request</source>
+ <translation>Åpne en Bitcoin: URI eller betalingsetterspørring</translation>
+ </message>
+ <message>
+ <source>&amp;Command-line options</source>
+ <translation>&amp;Kommandolinjevalg</translation>
+ </message>
+ <message>
+ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
+ <translation>Vis Bitcoin Core hjelpemeldingen for å få en liste med mulige kommandolinjevalg</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n active connection(s) to Bitcoin network</source>
+ <translation><numerusform>%n aktiv forbindelse til Bitcoin-nettverket</numerusform><numerusform>%n aktive forbindelser til Bitcoin-nettverket</numerusform></translation>
+ </message>
+ <message>
+ <source>No block source available...</source>
+ <translation>Ingen kilde for blokker tilgjengelig...</translation>
+ </message>
+ <message numerus="yes">
+ <source>Processed %n block(s) of transaction history.</source>
+ <translation><numerusform>Lastet %n blokk med transaksjonshistorikk.</numerusform><numerusform>Lastet %n blokker med transaksjonshistorikk.</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n hour(s)</source>
+ <translation><numerusform>%n time</numerusform><numerusform>%n timer</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n day(s)</source>
+ <translation><numerusform>%n dag</numerusform><numerusform>%n dager</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n week(s)</source>
+ <translation><numerusform>%n uke</numerusform><numerusform>%n uker</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 and %2</source>
+ <translation>%1 og %2</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n year(s)</source>
+ <translation><numerusform>%n år</numerusform><numerusform>%n år</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 behind</source>
+ <translation>%1 bak</translation>
+ </message>
+ <message>
+ <source>Last received block was generated %1 ago.</source>
+ <translation>Siste mottatte blokk ble generert for %1 siden.</translation>
+ </message>
+ <message>
+ <source>Transactions after this will not yet be visible.</source>
+ <translation>Transaksjoner etter dette vil ikke være synlige enda.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Feil</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Advarsel</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Informasjon</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>Oppdatert</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>Laster ned...</translation>
+ </message>
+ <message>
+ <source>Date: %1
+</source>
+ <translation>Dato: %1
+</translation>
+ </message>
+ <message>
+ <source>Amount: %1
+</source>
+ <translation>Beløp: %1:
+</translation>
+ </message>
+ <message>
+ <source>Type: %1
+</source>
+ <translation>Type: %1
+</translation>
+ </message>
+ <message>
+ <source>Label: %1
+</source>
+ <translation>Merkelapp: %1
+</translation>
+ </message>
+ <message>
+ <source>Address: %1
+</source>
+ <translation>Adresse: %1
+</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>Sendt transaksjon</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>Innkommende transaksjon</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>Lommeboken er &lt;b&gt;kryptert&lt;/b&gt; og for tiden &lt;b&gt;låst opp&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>Lommeboken er &lt;b&gt;kryptert&lt;/b&gt; og for tiden &lt;b&gt;låst&lt;/b&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <source>Network Alert</source>
+ <translation>Nettverksvarsel</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Coin Selection</source>
+ <translation>Mynt Valg</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Mengde:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Bytes:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Beløp:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Prioritet:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Avgift:</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Støv:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Totalt:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Veksel:</translation>
+ </message>
+ <message>
+ <source>(un)select all</source>
+ <translation>velg (fjern) alle</translation>
+ </message>
+ <message>
+ <source>Tree mode</source>
+ <translation>Trevisning</translation>
+ </message>
+ <message>
+ <source>List mode</source>
+ <translation>Listevisning</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Beløp</translation>
+ </message>
+ <message>
+ <source>Received with label</source>
+ <translation>Mottatt med merkelapp</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>Mottatt med adresse</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Dato</translation>
+ </message>
+ <message>
+ <source>Confirmations</source>
+ <translation>Bekreftelser</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Bekreftet</translation>
+ </message>
+ <message>
+ <source>Priority</source>
+ <translation>Prioritet</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Kopier adresse</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Kopier merkelapp</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopier beløp</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Kopier transaksjons-ID</translation>
+ </message>
+ <message>
+ <source>Lock unspent</source>
+ <translation>Lås ubrukte</translation>
+ </message>
+ <message>
+ <source>Unlock unspent</source>
+ <translation>Lås opp ubrukte</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Kopier mengde</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Kopier gebyr</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Kopier totalt</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Kopier bytes</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Kopier prioritet</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Kopier støv</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Kopier veksel</translation>
+ </message>
+ <message>
+ <source>highest</source>
+ <translation>høyest</translation>
+ </message>
+ <message>
+ <source>higher</source>
+ <translation>høyere</translation>
+ </message>
+ <message>
+ <source>high</source>
+ <translation>høy</translation>
+ </message>
+ <message>
+ <source>medium-high</source>
+ <translation>medium-høy</translation>
+ </message>
+ <message>
+ <source>medium</source>
+ <translation>medium</translation>
+ </message>
+ <message>
+ <source>low-medium</source>
+ <translation>lav-medium</translation>
+ </message>
+ <message>
+ <source>low</source>
+ <translation>lav</translation>
+ </message>
+ <message>
+ <source>lower</source>
+ <translation>lavere</translation>
+ </message>
+ <message>
+ <source>lowest</source>
+ <translation>lavest</translation>
+ </message>
+ <message>
+ <source>(%1 locked)</source>
+ <translation>(%1 låst)</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>ingen</translation>
+ </message>
+ <message>
+ <source>This label turns red if the transaction size is greater than 1000 bytes.</source>
+ <translation>Denne teksten blir rød hvis transaksjonsstørrelsen er større enn 1000 bytes.</translation>
+ </message>
+ <message>
+ <source>This label turns red if the priority is smaller than "medium".</source>
+ <translation>Denne teksten blir rød hvis prioriteten er lavere enn "medium".</translation>
+ </message>
+ <message>
+ <source>This label turns red if any recipient receives an amount smaller than %1.</source>
+ <translation>Denne teksten blir rød dersom en mottaker mottar et beløp mindre enn %1.</translation>
+ </message>
+ <message>
+ <source>Can vary +/- %1 satoshi(s) per input.</source>
+ <translation>Kan variere +/- %1 satoshi(er) per input.</translation>
+ </message>
+ <message>
+ <source>yes</source>
+ <translation>ja</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>nei</translation>
+ </message>
+ <message>
+ <source>This means a fee of at least %1 per kB is required.</source>
+ <translation>Dette betyr at et gebyr på minst %1 per KB er påkrevd.</translation>
+ </message>
+ <message>
+ <source>Can vary +/- 1 byte per input.</source>
+ <translation>Kan variere +/- 1 byte per input.</translation>
+ </message>
+ <message>
+ <source>Transactions with higher priority are more likely to get included into a block.</source>
+ <translation>Transaksjoner med høyere prioritet har mer sannsynlighet for å bli inkludert i en blokk.</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(ingen merkelapp)</translation>
+ </message>
+ <message>
+ <source>change from %1 (%2)</source>
+ <translation>veksel fra %1 (%2)</translation>
+ </message>
+ <message>
+ <source>(change)</source>
+ <translation>(veksel)</translation>
+ </message>
+</context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>Rediger adresse</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>&amp;Merkelapp</translation>
+ </message>
+ <message>
+ <source>The label associated with this address list entry</source>
+ <translation>Merkelappen koblet til denne adresseliste oppføringen</translation>
+ </message>
+ <message>
+ <source>The address associated with this address list entry. This can only be modified for sending addresses.</source>
+ <translation>Adressen til denne oppføringen i adresseboken. Denne kan kun endres for utsendingsadresser.</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;Adresse</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>Ny mottaksadresse</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>Ny utsendingsadresse</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>Rediger mottaksadresse</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>Rediger utsendingsadresse</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>Den oppgitte adressen "%1" er allerede i adresseboken.</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is not a valid Bitcoin address.</source>
+ <translation>Den angitte adressed "%1" er ikke en gyldig Bitcoin-adresse.</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>Kunne ikke låse opp lommeboken.</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>Generering av ny nøkkel feilet.</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ <message>
+ <source>A new data directory will be created.</source>
+ <translation>En ny datamappe vil bli laget.</translation>
+ </message>
+ <message>
+ <source>name</source>
+ <translation>navn</translation>
+ </message>
+ <message>
+ <source>Directory already exists. Add %1 if you intend to create a new directory here.</source>
+ <translation>Mappe finnes allerede. Legg til %1 hvis du vil lage en ny mappe her.</translation>
+ </message>
+ <message>
+ <source>Path already exists, and is not a directory.</source>
+ <translation>Snarvei finnes allerede, og er ikke en mappe.</translation>
+ </message>
+ <message>
+ <source>Cannot create data directory here.</source>
+ <translation>Kan ikke lage datamappe her.</translation>
+ </message>
+</context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>versjon</translation>
+ </message>
+ <message>
+ <source>(%1-bit)</source>
+ <translation> (%1-bit)</translation>
+ </message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>Om Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Command-line options</source>
+ <translation>Kommandolinjevalg</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>Bruk:</translation>
+ </message>
+ <message>
+ <source>command-line options</source>
+ <translation>kommandolinjevalg</translation>
+ </message>
+</context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Welcome</source>
+ <translation>Velkommen</translation>
+ </message>
+ <message>
+ <source>Welcome to Bitcoin Core.</source>
+ <translation>Velkommen til Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</source>
+ <translation>Siden dette er første gang programmet starter, kan du nå velge hvor Bitcoin Core skal lagre sine data.</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory.</source>
+ <translation>Bitcoin Core vil laste ned og lagre en kopi av Bitcoin sin blokkjede. Minst %1GB av data vil bli lagret i denne mappen, og det vil vokse over tid. Lommeboken vil også bli lagret i denne mappen.</translation>
+ </message>
+ <message>
+ <source>Use the default data directory</source>
+ <translation>Bruk standard datamappe</translation>
+ </message>
+ <message>
+ <source>Use a custom data directory:</source>
+ <translation>Bruk en egendefinert datamappe:</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Error: Specified data directory "%1" cannot be created.</source>
+ <translation>Feil: Den oppgitte datamappen "%1" kan ikke opprettes.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Feil</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n GB of free space available</source>
+ <translation><numerusform>%n GB med ledig lagringsplass</numerusform><numerusform>%n GB med ledig lagringsplass</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>(of %n GB needed)</source>
+ <translation><numerusform>(av %n GB som trengs)</numerusform><numerusform>(av %n GB som trengs)</numerusform></translation>
+ </message>
+</context>
+<context>
+ <name>OpenURIDialog</name>
+ <message>
+ <source>Open URI</source>
+ <translation>Åpne URI</translation>
+ </message>
+ <message>
+ <source>Open payment request from URI or file</source>
+ <translation>Åpne betalingsetterspørring fra URI eller fil</translation>
+ </message>
+ <message>
+ <source>URI:</source>
+ <translation>URI:</translation>
+ </message>
+ <message>
+ <source>Select payment request file</source>
+ <translation>Velg fil for betalingsetterspørring</translation>
+ </message>
+ <message>
+ <source>Select payment request file to open</source>
+ <translation>Velg fil for betalingsetterspørring å åpne</translation>
+ </message>
+</context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>Innstillinger</translation>
+ </message>
+ <message>
+ <source>&amp;Main</source>
+ <translation>&amp;Hoved</translation>
+ </message>
+ <message>
+ <source>Size of &amp;database cache</source>
+ <translation>Størrelse på &amp;database hurtigbuffer</translation>
+ </message>
+ <message>
+ <source>MB</source>
+ <translation>MB</translation>
+ </message>
+ <message>
+ <source>Number of script &amp;verification threads</source>
+ <translation>Antall script &amp;verifikasjonstråder</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside</source>
+ <translation>Tillat tilkoblinger fra utsiden</translation>
+ </message>
+ <message>
+ <source>Allow incoming connections</source>
+ <translation>Tillatt innkommende tilkoblinger</translation>
+ </message>
+ <message>
+ <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
+ <translation>IP-adressen til proxyen (f.eks. IPv4: 127.0.0.1 / IPv6: ::1)</translation>
+ </message>
+ <message>
+ <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source>
+ <translation>Minimer i stedet for å avslutte applikasjonen når vinduet lukkes. Når dette er valgt, vil applikasjonen avsluttes kun etter at Avslutte er valgt i menyen.</translation>
+ </message>
+ <message>
+ <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source>
+ <translation>Språk for brukergrensesnittet kan velges her. Denne innstillingen trer i kraft etter omstart av Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source>
+ <translation>Tredjepart URLer (f. eks. en blokkutforsker) som dukker opp i transaksjonsfanen som kontekst meny elementer. %s i URLen er erstattet med transaksjonen sin hash. Flere URLer er separert av en vertikal linje |.</translation>
+ </message>
+ <message>
+ <source>Third party transaction URLs</source>
+ <translation>Tredjepart transaksjon URLer</translation>
+ </message>
+ <message>
+ <source>Active command-line options that override above options:</source>
+ <translation>Aktive kommandolinjevalg som overstyrer valgene ovenfor:</translation>
+ </message>
+ <message>
+ <source>Reset all client options to default.</source>
+ <translation>Tilbakestill alle klient valg til standard</translation>
+ </message>
+ <message>
+ <source>&amp;Reset Options</source>
+ <translation>&amp;Tilbakestill Instillinger</translation>
+ </message>
+ <message>
+ <source>&amp;Network</source>
+ <translation>&amp;Nettverk</translation>
+ </message>
+ <message>
+ <source>Automatically start Bitcoin Core after logging in to the system.</source>
+ <translation>Start Bitcoin Core automatisk ved oppstart av datamaskinen.</translation>
+ </message>
+ <message>
+ <source>&amp;Start Bitcoin Core on system login</source>
+ <translation>&amp;Start Bitcoin Core ved oppstart av datamaskinen</translation>
+ </message>
+ <message>
+ <source>(0 = auto, &lt;0 = leave that many cores free)</source>
+ <translation>(0 = automatisk, &lt;0 = la så mange kjerner være ledig)</translation>
+ </message>
+ <message>
+ <source>W&amp;allet</source>
+ <translation>L&amp;ommebok</translation>
+ </message>
+ <message>
+ <source>Expert</source>
+ <translation>Ekspert</translation>
+ </message>
+ <message>
+ <source>Enable coin &amp;control features</source>
+ <translation>Aktiver &amp;myntkontroll funksjoner</translation>
+ </message>
+ <message>
+ <source>If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.</source>
+ <translation>Hvis du sperrer for bruk av ubekreftet veksel, kan ikke vekselen fra transaksjonen bli brukt før transaksjonen har minimum en bekreftelse. Dette påvirker også hvordan balansen din blir beregnet.</translation>
+ </message>
+ <message>
+ <source>&amp;Spend unconfirmed change</source>
+ <translation>&amp;Bruk ubekreftet veksel</translation>
+ </message>
+ <message>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>Åpne automatisk Bitcoin klientporten på ruteren. Dette virker kun om din ruter støtter UPnP og dette er påslått.</translation>
+ </message>
+ <message>
+ <source>Map port using &amp;UPnP</source>
+ <translation>Sett opp port ved hjelp av &amp;UPnP</translation>
+ </message>
+ <message>
+ <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
+ <translation>Koble til Bitcoin-nettverket gjennom en SOCKS5 proxy.</translation>
+ </message>
+ <message>
+ <source>&amp;Connect through SOCKS5 proxy (default proxy):</source>
+ <translation>&amp;Koble til gjennom SOCKS5 proxy (standardvalg proxy):</translation>
+ </message>
+ <message>
+ <source>Proxy &amp;IP:</source>
+ <translation>Proxy &amp;IP:</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>&amp;Port:</translation>
+ </message>
+ <message>
+ <source>Port of the proxy (e.g. 9050)</source>
+ <translation>Proxyens port (f.eks. 9050)</translation>
+ </message>
+ <message>
+ <source>&amp;Window</source>
+ <translation>&amp;Vindu</translation>
+ </message>
+ <message>
+ <source>Show only a tray icon after minimizing the window.</source>
+ <translation>Vis kun ikon i systemkurv etter minimering av vinduet.</translation>
+ </message>
+ <message>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>&amp;Minimer til systemkurv istedenfor oppgavelinjen</translation>
+ </message>
+ <message>
+ <source>M&amp;inimize on close</source>
+ <translation>M&amp;inimer ved lukking</translation>
+ </message>
+ <message>
+ <source>&amp;Display</source>
+ <translation>&amp;Visning</translation>
+ </message>
+ <message>
+ <source>User Interface &amp;language:</source>
+ <translation>&amp;Språk for brukergrensesnitt</translation>
+ </message>
+ <message>
+ <source>&amp;Unit to show amounts in:</source>
+ <translation>&amp;Enhet for visning av beløper:</translation>
+ </message>
+ <message>
+ <source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
+ <translation>Velg standard delt enhet for visning i grensesnittet og for sending av bitcoins.</translation>
+ </message>
+ <message>
+ <source>Whether to show coin control features or not.</source>
+ <translation>Skal myntkontroll funksjoner vises eller ikke.</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>&amp;OK</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>&amp;Avbryt</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>standardverdi</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>ingen</translation>
+ </message>
+ <message>
+ <source>Confirm options reset</source>
+ <translation>Bekreft tilbakestilling av innstillinger</translation>
+ </message>
+ <message>
+ <source>Client restart required to activate changes.</source>
+ <translation>Omstart av klienten er nødvendig for å aktivere endringene.</translation>
+ </message>
+ <message>
+ <source>Client will be shut down. Do you want to proceed?</source>
+ <translation>Klienten vil bli lukket. Ønsker du å gå videre?</translation>
+ </message>
+ <message>
+ <source>This change would require a client restart.</source>
+ <translation>Denne endringen krever omstart av klienten.</translation>
+ </message>
+ <message>
+ <source>The supplied proxy address is invalid.</source>
+ <translation>Angitt proxyadresse er ugyldig.</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>Skjema</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>Informasjonen som vises kan være foreldet. Din lommebok synkroniseres automatisk med Bitcoin-nettverket etter at tilkobling er opprettet, men denne prosessen er ikke ferdig enda.</translation>
+ </message>
+ <message>
+ <source>Watch-only:</source>
+ <translation>Kun observerbar:</translation>
+ </message>
+ <message>
+ <source>Available:</source>
+ <translation>Tilgjengelig:</translation>
+ </message>
+ <message>
+ <source>Your current spendable balance</source>
+ <translation>Din nåværende saldo</translation>
+ </message>
+ <message>
+ <source>Pending:</source>
+ <translation>Under behandling:</translation>
+ </message>
+ <message>
+ <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source>
+ <translation>Totalt antall ubekreftede transaksjoner som ikke teller med i saldo</translation>
+ </message>
+ <message>
+ <source>Immature:</source>
+ <translation>Umoden:</translation>
+ </message>
+ <message>
+ <source>Mined balance that has not yet matured</source>
+ <translation>Minet saldo har ikke modnet enda</translation>
+ </message>
+ <message>
+ <source>Balances</source>
+ <translation>Saldoer</translation>
+ </message>
+ <message>
+ <source>Total:</source>
+ <translation>Totalt:</translation>
+ </message>
+ <message>
+ <source>Your current total balance</source>
+ <translation>Din nåværende saldo</translation>
+ </message>
+ <message>
+ <source>Your current balance in watch-only addresses</source>
+ <translation>Din nåværende balanse i kun observerbare adresser</translation>
+ </message>
+ <message>
+ <source>Spendable:</source>
+ <translation>Kan brukes:</translation>
+ </message>
+ <message>
+ <source>Recent transactions</source>
+ <translation>Nylige transaksjoner</translation>
+ </message>
+ <message>
+ <source>Unconfirmed transactions to watch-only addresses</source>
+ <translation>Ubekreftede transaksjoner til kun observerbare adresser</translation>
+ </message>
+ <message>
+ <source>Mined balance in watch-only addresses that has not yet matured</source>
+ <translation>Utvunnet balanse i kun observerbare adresser som ennå ikke har modnet</translation>
+ </message>
+ <message>
+ <source>Current total balance in watch-only addresses</source>
+ <translation>Nåværende totale balanse i kun observerbare adresser</translation>
+ </message>
+</context>
+<context>
+ <name>PaymentServer</name>
+ <message>
+ <source>URI handling</source>
+ <translation>URI-håndtering</translation>
+ </message>
+ <message>
+ <source>Invalid payment address %1</source>
+ <translation>Ugyldig betalingsadresse %1</translation>
+ </message>
+ <message>
+ <source>Payment request rejected</source>
+ <translation>Betalingsetterspørring avvist</translation>
+ </message>
+ <message>
+ <source>Payment request network doesn't match client network.</source>
+ <translation>Nettverk for betalingsetterspørring er ikke i overensstemmelse med klientnettverket.</translation>
+ </message>
+ <message>
+ <source>Payment request is not initialized.</source>
+ <translation>Betalingsetterspørringen er ikke initialisert.</translation>
+ </message>
+ <message>
+ <source>Requested payment amount of %1 is too small (considered dust).</source>
+ <translation>Forespurt betalingsmengde på %1 er for liten (betraktet som støv).</translation>
+ </message>
+ <message>
+ <source>Payment request error</source>
+ <translation>Betalingsetterspørringsfeil</translation>
+ </message>
+ <message>
+ <source>Cannot start bitcoin: click-to-pay handler</source>
+ <translation>Kan ikke starte Bitcoin: klikk-og-betal håndterer</translation>
+ </message>
+ <message>
+ <source>Payment request fetch URL is invalid: %1</source>
+ <translation>Hentelenke for betalingsetterspørring er ugyldig: %1</translation>
+ </message>
+ <message>
+ <source>URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source>
+ <translation>URI kan ikke fortolkes! Dette kan være forårsaket av en ugyldig Bitcoin-adresse eller feilformede URI-parametre.</translation>
+ </message>
+ <message>
+ <source>Payment request file handling</source>
+ <translation>Filhåndtering for betalingsetterspørring</translation>
+ </message>
+ <message>
+ <source>Payment request file cannot be read! This can be caused by an invalid payment request file.</source>
+ <translation>Betalingsetterspørringsfil kan ikke leses! Dette kan være forårsaket av en ugyldig betalingsetterspørringsfil.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>Betalingsetterspørringen har utløpt.</translation>
+ </message>
+ <message>
+ <source>Unverified payment requests to custom payment scripts are unsupported.</source>
+ <translation>Uverifiserte betalingsforespørsler til egentilpassede betalingscript er ikke støttet.</translation>
+ </message>
+ <message>
+ <source>Invalid payment request.</source>
+ <translation>Ugyldig betalingsetterspørring.</translation>
+ </message>
+ <message>
+ <source>Refund from %1</source>
+ <translation>Refundering fra %1</translation>
+ </message>
+ <message>
+ <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source>
+ <translation>Betalingsforespørsel %1 er for stor (%2 bytes, tillatt %3 bytes).</translation>
+ </message>
+ <message>
+ <source>Payment request DoS protection</source>
+ <translation>Betalingsforespørsel DoS-beskyttelse</translation>
+ </message>
+ <message>
+ <source>Error communicating with %1: %2</source>
+ <translation>Feil i kommunikasjonen med %1: %2</translation>
+ </message>
+ <message>
+ <source>Payment request cannot be parsed!</source>
+ <translation>Betaingsetterspørrelse kan ikke fortolkes!</translation>
+ </message>
+ <message>
+ <source>Bad response from server %1</source>
+ <translation>Dårlig svar fra server %1</translation>
+ </message>
+ <message>
+ <source>Payment acknowledged</source>
+ <translation>Betaling erkjent</translation>
+ </message>
+ <message>
+ <source>Network request error</source>
+ <translation>Nettverksforespørsel feil</translation>
+ </message>
+</context>
+<context>
+ <name>PeerTableModel</name>
+ <message>
+ <source>User Agent</source>
+ <translation>Brukeragent</translation>
+ </message>
+ <message>
+ <source>Node/Service</source>
+ <translation>Node/Tjeneste</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Ping-tid</translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>Beløp</translation>
+ </message>
+ <message>
+ <source>Enter a Bitcoin address (e.g. %1)</source>
+ <translation>Oppgi en Bitcoin-adresse (f.eks. %1)</translation>
+ </message>
+ <message>
+ <source>%1 d</source>
+ <translation>%1 d</translation>
+ </message>
+ <message>
+ <source>%1 h</source>
+ <translation>%1 t</translation>
+ </message>
+ <message>
+ <source>%1 m</source>
+ <translation>%1 m</translation>
+ </message>
+ <message>
+ <source>%1 s</source>
+ <translation>%1 s</translation>
+ </message>
+ <message>
+ <source>None</source>
+ <translation>Ingen</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>-</translation>
+ </message>
+ <message>
+ <source>%1 ms</source>
+ <translation>%1 ms</translation>
+ </message>
+</context>
+<context>
+ <name>QRImageWidget</name>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Lagre Bilde...</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Image</source>
+ <translation>&amp;Kopier Bilde</translation>
+ </message>
+ <message>
+ <source>Save QR Code</source>
+ <translation>Lagre QR-kode</translation>
+ </message>
+ <message>
+ <source>PNG Image (*.png)</source>
+ <translation>PNG-bilde (*.png)</translation>
+ </message>
+</context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>Client name</source>
+ <translation>Klientnavn</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>-</translation>
+ </message>
+ <message>
+ <source>Client version</source>
+ <translation>Klientversjon</translation>
+ </message>
+ <message>
+ <source>&amp;Information</source>
+ <translation>&amp;Informasjon</translation>
+ </message>
+ <message>
+ <source>Debug window</source>
+ <translation>Feilsøkingsvindu</translation>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>Generelt</translation>
+ </message>
+ <message>
+ <source>Using OpenSSL version</source>
+ <translation>Bruker OpenSSL versjon</translation>
+ </message>
+ <message>
+ <source>Using BerkeleyDB version</source>
+ <translation>Bruker BerkeleyDB versjon</translation>
+ </message>
+ <message>
+ <source>Startup time</source>
+ <translation>Oppstartstidspunkt</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Nettverk</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>Navn</translation>
+ </message>
+ <message>
+ <source>Number of connections</source>
+ <translation>Antall tilkoblinger</translation>
+ </message>
+ <message>
+ <source>Block chain</source>
+ <translation>Blokkjeden</translation>
+ </message>
+ <message>
+ <source>Current number of blocks</source>
+ <translation>Nåværende antall blokker</translation>
+ </message>
+ <message>
+ <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source>
+ <translation>Åpne Bitcoin Core sin loggfil for feilsøk fra gjeldende datamappe. Dette kan ta noen sekunder for store loggfiler.</translation>
+ </message>
+ <message>
+ <source>Received</source>
+ <translation>Mottatt</translation>
+ </message>
+ <message>
+ <source>Sent</source>
+ <translation>Sendt</translation>
+ </message>
+ <message>
+ <source>&amp;Peers</source>
+ <translation>&amp;Noder</translation>
+ </message>
+ <message>
+ <source>Select a peer to view detailed information.</source>
+ <translation>Velg en node for å vise detaljert informasjon.</translation>
+ </message>
+ <message>
+ <source>Direction</source>
+ <translation>Retning</translation>
+ </message>
+ <message>
+ <source>Version</source>
+ <translation>Versjon</translation>
+ </message>
+ <message>
+ <source>User Agent</source>
+ <translation>Brukeragent</translation>
+ </message>
+ <message>
+ <source>Services</source>
+ <translation>Tjenester</translation>
+ </message>
+ <message>
+ <source>Starting Height</source>
+ <translation>Starthøyde</translation>
+ </message>
+ <message>
+ <source>Sync Height</source>
+ <translation>Synkroniseringshøyde</translation>
+ </message>
+ <message>
+ <source>Ban Score</source>
+ <translation>Ban Poengsum</translation>
+ </message>
+ <message>
+ <source>Connection Time</source>
+ <translation>Tilkoblingstid</translation>
+ </message>
+ <message>
+ <source>Last Send</source>
+ <translation>Siste Sendte</translation>
+ </message>
+ <message>
+ <source>Last Receive</source>
+ <translation>Siste Mottatte</translation>
+ </message>
+ <message>
+ <source>Bytes Sent</source>
+ <translation>Byte Sendt</translation>
+ </message>
+ <message>
+ <source>Bytes Received</source>
+ <translation>Byte Mottatt</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Ping-tid</translation>
+ </message>
+ <message>
+ <source>Time Offset</source>
+ <translation>Tidsforskyvning</translation>
+ </message>
+ <message>
+ <source>Last block time</source>
+ <translation>Tidspunkt for siste blokk</translation>
+ </message>
+ <message>
+ <source>&amp;Open</source>
+ <translation>&amp;Åpne</translation>
+ </message>
+ <message>
+ <source>&amp;Console</source>
+ <translation>&amp;Konsoll</translation>
+ </message>
+ <message>
+ <source>&amp;Network Traffic</source>
+ <translation>&amp;Nettverkstrafikk</translation>
+ </message>
+ <message>
+ <source>&amp;Clear</source>
+ <translation>&amp;Fjern</translation>
+ </message>
+ <message>
+ <source>Totals</source>
+ <translation>Totalt</translation>
+ </message>
+ <message>
+ <source>In:</source>
+ <translation>Inn:</translation>
+ </message>
+ <message>
+ <source>Out:</source>
+ <translation>Ut:</translation>
+ </message>
+ <message>
+ <source>Build date</source>
+ <translation>Byggedato</translation>
+ </message>
+ <message>
+ <source>Debug log file</source>
+ <translation>Loggfil for feilsøk</translation>
+ </message>
+ <message>
+ <source>Clear console</source>
+ <translation>Tøm konsoll</translation>
+ </message>
+ <message>
+ <source>Welcome to the Bitcoin Core RPC console.</source>
+ <translation>Velkommen til Bitcoin Core sin RPC-konsoll.</translation>
+ </message>
+ <message>
+ <source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
+ <translation>Bruk opp og ned pil for å navigere historikken, og &lt;b&gt;Ctrl-L&lt;/b&gt; for å tømme skjermen.</translation>
+ </message>
+ <message>
+ <source>Type &lt;b&gt;help&lt;/b&gt; for an overview of available commands.</source>
+ <translation>Skriv &lt;b&gt;help&lt;/b&gt; for en oversikt over kommandoer.</translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation>%1 B</translation>
+ </message>
+ <message>
+ <source>%1 KB</source>
+ <translation>%1 KB</translation>
+ </message>
+ <message>
+ <source>%1 MB</source>
+ <translation>%1 MB</translation>
+ </message>
+ <message>
+ <source>%1 GB</source>
+ <translation>%1 GB</translation>
+ </message>
+ <message>
+ <source>via %1</source>
+ <translation>via %1</translation>
+ </message>
+ <message>
+ <source>never</source>
+ <translation>aldri</translation>
+ </message>
+ <message>
+ <source>Inbound</source>
+ <translation>Innkommende</translation>
+ </message>
+ <message>
+ <source>Outbound</source>
+ <translation>Utgående</translation>
+ </message>
+ <message>
+ <source>Unknown</source>
+ <translation>Ukjent</translation>
+ </message>
+ <message>
+ <source>Fetching...</source>
+ <translation>Henter …</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Amount:</source>
+ <translation>&amp;Beløp:</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Merkelapp:</translation>
+ </message>
+ <message>
+ <source>&amp;Message:</source>
+ <translation>&amp;Melding:</translation>
+ </message>
+ <message>
+ <source>Reuse one of the previously used receiving addresses. Reusing addresses has security and privacy issues. Do not use this unless re-generating a payment request made before.</source>
+ <translation>Gjenbruk en av de tidligere brukte mottaksadressene. Gjenbruk av adresser har sikkerhets- og personvernsutfordringer. Ikke bruk dette med unntak for å gjennopprette en betalingsetterspørring som ble gjort tidligere.</translation>
+ </message>
+ <message>
+ <source>R&amp;euse an existing receiving address (not recommended)</source>
+ <translation>Gj&amp;enbruk en eksisterende mottaksadresse (ikke anbefalt)</translation>
+ </message>
+ <message>
+ <source>An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network.</source>
+ <translation>En valgfri melding å tilknytte betalingsetterspørringen, som vil bli vist når forespørselen er åpnet. Meldingen vil ikke bli sendt med betalingen over Bitcoin-nettverket.</translation>
+ </message>
+ <message>
+ <source>An optional label to associate with the new receiving address.</source>
+ <translation>En valgfri merkelapp å tilknytte den nye mottakeradressen.</translation>
+ </message>
+ <message>
+ <source>Use this form to request payments. All fields are &lt;b&gt;optional&lt;/b&gt;.</source>
+ <translation>Bruk dette skjemaet til betalingsforespørsler. Alle felt er &lt;b&gt;valgfrie&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>An optional amount to request. Leave this empty or zero to not request a specific amount.</source>
+ <translation>Et valgfritt beløp å etterspørre. La stå tomt eller null for ikke å etterspørre et spesifikt beløp.</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Fjern alle felter fra skjemaet.</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation>Fjern</translation>
+ </message>
+ <message>
+ <source>Requested payments history</source>
+ <translation>Etterspurt betalingshistorikk</translation>
+ </message>
+ <message>
+ <source>&amp;Request payment</source>
+ <translation>&amp;Etterspør betaling</translation>
+ </message>
+ <message>
+ <source>Show the selected request (does the same as double clicking an entry)</source>
+ <translation>Vis den valgte etterspørringen (gjør det samme som å dobbelklikke på en oppføring)</translation>
+ </message>
+ <message>
+ <source>Show</source>
+ <translation>Vis</translation>
+ </message>
+ <message>
+ <source>Remove the selected entries from the list</source>
+ <translation>Fjern de valgte oppføringene fra listen</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>Fjern</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Kopier merkelapp</translation>
+ </message>
+ <message>
+ <source>Copy message</source>
+ <translation>Kopier melding</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopier beløp</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>QR Code</source>
+ <translation>QR-kode</translation>
+ </message>
+ <message>
+ <source>Copy &amp;URI</source>
+ <translation>Kopier &amp;URI</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Address</source>
+ <translation>Kopier &amp;Adresse</translation>
+ </message>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Lagre Bilde...</translation>
+ </message>
+ <message>
+ <source>Request payment to %1</source>
+ <translation>Etterspør betaling til %1</translation>
+ </message>
+ <message>
+ <source>Payment information</source>
+ <translation>Betalingsinformasjon</translation>
+ </message>
+ <message>
+ <source>URI</source>
+ <translation>URI</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adresse</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Beløp</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Merkelapp</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Melding</translation>
+ </message>
+ <message>
+ <source>Resulting URI too long, try to reduce the text for label / message.</source>
+ <translation>Resultat URI for lang, prøv å redusere teksten for merkelapp / melding.</translation>
+ </message>
+ <message>
+ <source>Error encoding URI into QR Code.</source>
+ <translation>Feil ved koding av URI til QR-kode.</translation>
+ </message>
+</context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Dato</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Merkelapp</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Melding</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Beløp</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(ingen merkelapp)</translation>
+ </message>
+ <message>
+ <source>(no message)</source>
+ <translation>(ingen melding)</translation>
+ </message>
+ <message>
+ <source>(no amount)</source>
+ <translation>(intet beløp)</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Send Bitcoins</translation>
+ </message>
+ <message>
+ <source>Coin Control Features</source>
+ <translation>Myntkontroll Funksjoner</translation>
+ </message>
+ <message>
+ <source>Inputs...</source>
+ <translation>Inndata...</translation>
+ </message>
+ <message>
+ <source>automatically selected</source>
+ <translation>automatisk valgte</translation>
+ </message>
+ <message>
+ <source>Insufficient funds!</source>
+ <translation>Utilstrekkelige midler!</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Mengde:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Bytes:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Beløp:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Prioritet:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Gebyr:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Etter Gebyr:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Veksel:</translation>
+ </message>
+ <message>
+ <source>If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address.</source>
+ <translation>Hvis dette er aktivert, men adressen for veksel er tom eller ugyldig, vil veksel bli sendt til en nylig generert adresse.</translation>
+ </message>
+ <message>
+ <source>Custom change address</source>
+ <translation>Egendefinert adresse for veksel</translation>
+ </message>
+ <message>
+ <source>Transaction Fee:</source>
+ <translation>Transaksjonsgebyr:</translation>
+ </message>
+ <message>
+ <source>Choose...</source>
+ <translation>Velg...</translation>
+ </message>
+ <message>
+ <source>collapse fee-settings</source>
+ <translation>Legg ned gebyrinnstillinger</translation>
+ </message>
+ <message>
+ <source>per kilobyte</source>
+ <translation>per kilobyte</translation>
+ </message>
+ <message>
+ <source>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "total at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source>
+ <translation>Hvis den egendefinerte avgiften er satt til 1000 satoshis og transaksjonen bare er 250 bytes, da vil "per kilobyte" bare betale 250 satoshis i gebyr, mens "minstebeløp" betaler 1000 satoshis. For transaksjoner større enn en kilobyte vil begge betale for antall kilobyte.</translation>
+ </message>
+ <message>
+ <source>Hide</source>
+ <translation>Skjul</translation>
+ </message>
+ <message>
+ <source>total at least</source>
+ <translation>minstebeløp</translation>
+ </message>
+ <message>
+ <source>Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process.</source>
+ <translation>Betaling av bare minimumsavgiften går helt fint så lenge det er mindre transaksjonsvolum enn plass i blokkene. Men vær klar over at dette kan ende opp i en transaksjon som aldri blir bekreftet når det er mer etterspørsel etter Bitcoin-transaksjoner enn nettverket kan behandle.</translation>
+ </message>
+ <message>
+ <source>(read the tooltip)</source>
+ <translation>(les verktøytipset)</translation>
+ </message>
+ <message>
+ <source>Recommended:</source>
+ <translation>Anbefalt:</translation>
+ </message>
+ <message>
+ <source>Custom:</source>
+ <translation>Egendefinert:</translation>
+ </message>
+ <message>
+ <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source>
+ <translation>(Smartgebyr ikke innført ennå. Dette tar vanligvis noen blokker...)</translation>
+ </message>
+ <message>
+ <source>Confirmation time:</source>
+ <translation>Bekreftelsestid:</translation>
+ </message>
+ <message>
+ <source>normal</source>
+ <translation>normal</translation>
+ </message>
+ <message>
+ <source>fast</source>
+ <translation>rask</translation>
+ </message>
+ <message>
+ <source>Send as zero-fee transaction if possible</source>
+ <translation>Send uten transaksjonsgebyr hvis mulig</translation>
+ </message>
+ <message>
+ <source>(confirmation may take longer)</source>
+ <translation>(bekreftelse kan ta lengre tid)</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>Send til flere enn en mottaker</translation>
+ </message>
+ <message>
+ <source>Add &amp;Recipient</source>
+ <translation>Legg til &amp;Mottaker</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Fjern alle felter fra skjemaet.</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Støv:</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Fjern &amp;Alt</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>Saldo:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>Bekreft sending</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>S&amp;end</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>Bekreft sending av bitcoins</translation>
+ </message>
+ <message>
+ <source>%1 to %2</source>
+ <translation>%1 til %2</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Kopier mengde</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopier beløp</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Kopier gebyr</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Kopier fra gebyr</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Kopier bytes</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Kopier prioritet</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Kopier veksel</translation>
+ </message>
+ <message>
+ <source>or</source>
+ <translation>eller</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>Beløpet som skal betales må være over 0.</translation>
+ </message>
+ <message>
+ <source>The amount exceeds your balance.</source>
+ <translation>Beløpet overstiger saldo.</translation>
+ </message>
+ <message>
+ <source>The total exceeds your balance when the %1 transaction fee is included.</source>
+ <translation>Totalbeløpet overstiger saldo etter at %1 transaksjonsgebyr er lagt til.</translation>
+ </message>
+ <message>
+ <source>Transaction creation failed!</source>
+ <translation>Opprettelse av transaksjon feilet!</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>Transaksjonen ble avvist! Dette kan skje hvis noen av myntene i lommeboken allerede er brukt, som hvis du kopierte wallet.dat og mynter ble brukt i kopien uten å bli markert som brukt her.</translation>
+ </message>
+ <message>
+ <source>A fee higher than %1 is considered an absurdly high fee.</source>
+ <translation>Et gebyr høyere enn %1 er ansett som et absurd høyt gebyr.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>Betalingsetterspørringen har utløpt.</translation>
+ </message>
+ <message numerus="yes">
+ <source>Estimated to begin confirmation within %n block(s).</source>
+ <translation><numerusform>Anslått til å begynne bekreftelse innen %n blokk.</numerusform><numerusform>Anslått til å begynne bekreftelse innen %n blokker.</numerusform></translation>
+ </message>
+ <message>
+ <source>Pay only the minimum fee of %1</source>
+ <translation>Betal kun minimumsgebyret på %1</translation>
+ </message>
+ <message>
+ <source>Total Amount %1&lt;span style='font-size:10pt;font-weight:normal;'&gt;&lt;br /&gt;(=%2)&lt;/span&gt;</source>
+ <translation>Totalt Beløp %1&lt;span style='font-size:10pt;font-weight:normal;'&gt;&lt;br /&gt;(=%2)&lt;/span&gt;</translation>
+ </message>
+ <message>
+ <source>The recipient address is not valid. Please recheck.</source>
+ <translation>Mottakeradressen er ikke gyldig. Vennligst kontroller på nytt.</translation>
+ </message>
+ <message>
+ <source>Duplicate address found: addresses should only be used once each.</source>
+ <translation>Gjenbruk av adresse funnet: adresser skal bare brukes en gang hver.</translation>
+ </message>
+ <message>
+ <source>Warning: Invalid Bitcoin address</source>
+ <translation>Advarsel: Ugyldig Bitcoin-adresse</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(ingen merkelapp)</translation>
+ </message>
+ <message>
+ <source>Warning: Unknown change address</source>
+ <translation>Advarsel: Ukjent adresse for veksel</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Kopier støv</translation>
+ </message>
+ <message>
+ <source>Are you sure you want to send?</source>
+ <translation>Er du sikker på at du vil sende?</translation>
+ </message>
+ <message>
+ <source>added as transaction fee</source>
+ <translation>lagt til som transaksjonsgebyr</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>&amp;Beløp:</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>Betal &amp;Til:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Skriv inn en merkelapp for denne adressen for å legge den til i din adressebok</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Merkelapp:</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Velg tidligere brukt adresse</translation>
+ </message>
+ <message>
+ <source>This is a normal payment.</source>
+ <translation>Dette er en normal betaling.</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to send the payment to</source>
+ <translation>Bitcoin-adressen betalingen skal sendes til</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Lim inn adresse fra utklippstavlen</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Remove this entry</source>
+ <translation>Fjern denne oppføringen</translation>
+ </message>
+ <message>
+ <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source>
+ <translation>Gebyret vil bli trukket fra beløpet som blir sendt. Mottakeren vil motta mindre bitcoins enn det du skriver inn i beløpsfeltet. Hvis det er valgt flere mottakere, deles gebyret likt.</translation>
+ </message>
+ <message>
+ <source>S&amp;ubtract fee from amount</source>
+ <translation>T&amp;rekk fra gebyr fra beløp</translation>
+ </message>
+ <message>
+ <source>Message:</source>
+ <translation>Melding:</translation>
+ </message>
+ <message>
+ <source>This is an unauthenticated payment request.</source>
+ <translation>Dette er en uautorisert betalingsetterspørring.</translation>
+ </message>
+ <message>
+ <source>This is an authenticated payment request.</source>
+ <translation>Dette er en autorisert betalingsetterspørring.</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to the list of used addresses</source>
+ <translation>Skriv inn en merkelapp for denne adressen for å legge den til listen av brukte adresser</translation>
+ </message>
+ <message>
+ <source>A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network.</source>
+ <translation>En melding som var tilknyttet bitcoinen: URI vil bli lagret med transaksjonen for din oversikt. Denne meldingen vil ikke bli sendt over Bitcoin-nettverket.</translation>
+ </message>
+ <message>
+ <source>Pay To:</source>
+ <translation>Betal Til:</translation>
+ </message>
+ <message>
+ <source>Memo:</source>
+ <translation>Memo:</translation>
+ </message>
+</context>
+<context>
+ <name>ShutdownWindow</name>
+ <message>
+ <source>Bitcoin Core is shutting down...</source>
+ <translation>Bitcoin Core lukker...</translation>
+ </message>
+ <message>
+ <source>Do not shut down the computer until this window disappears.</source>
+ <translation>Slå ikke av datamaskinen før dette vinduet forsvinner.</translation>
+ </message>
+</context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Signatures - Sign / Verify a Message</source>
+ <translation>Signaturer - Signer / Verifiser en Melding</translation>
+ </message>
+ <message>
+ <source>&amp;Sign Message</source>
+ <translation>&amp;Signer Melding</translation>
+ </message>
+ <message>
+ <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source>
+ <translation>Du kan signere meldinger/avtaler med adresser for å bevise at du kan motta bitcoins sendt til dem. Vær forsiktig med å signere noe vagt eller tilfeldig, siden phishing-angrep kan prøve å lure deg til å signere din identitet over til dem. Bare signer fullt detaljerte utsagn som du er enig i.</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to sign the message with</source>
+ <translation>Bitcoin-adressen meldingen skal signeres med</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Velg tidligere brukt adresse</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Lim inn adresse fra utklippstavlen</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Enter the message you want to sign here</source>
+ <translation>Skriv inn meldingen du vil signere her</translation>
+ </message>
+ <message>
+ <source>Signature</source>
+ <translation>Signatur</translation>
+ </message>
+ <message>
+ <source>Copy the current signature to the system clipboard</source>
+ <translation>Kopier valgt signatur til utklippstavle</translation>
+ </message>
+ <message>
+ <source>Sign the message to prove you own this Bitcoin address</source>
+ <translation>Signer meldingen for å bevise at du eier denne Bitcoin-adressen</translation>
+ </message>
+ <message>
+ <source>Sign &amp;Message</source>
+ <translation>Signer &amp;Melding</translation>
+ </message>
+ <message>
+ <source>Reset all sign message fields</source>
+ <translation>Tilbakestill alle felter for meldingssignering</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Fjern &amp;Alt</translation>
+ </message>
+ <message>
+ <source>&amp;Verify Message</source>
+ <translation>&amp;Verifiser Melding</translation>
+ </message>
+ <message>
+ <source>Enter the receiver's 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. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source>
+ <translation>Skriv inn mottakerens adresse, melding (forsikre deg om at du kopier linjeskift, mellomrom, faner osv. nøyaktig) og underskrift nedenfor for å bekrefte meldingen. Vær forsiktig så du ikke leser mer ut av signaturen enn hva som er i den signerte meldingen i seg selv, for å unngå å bli lurt av et man-in-the-middle-angrep. Merk at dette bare beviser at den som signerer kan motta med adressen, dette beviser ikke hvem som har sendt transaksjoner!</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address the message was signed with</source>
+ <translation>Bitcoin-adressen meldingen ble signert med</translation>
+ </message>
+ <message>
+ <source>Verify the message to ensure it was signed with the specified Bitcoin address</source>
+ <translation>Verifiser meldingen for å være sikker på at den ble signert av den angitte Bitcoin-adressen</translation>
+ </message>
+ <message>
+ <source>Verify &amp;Message</source>
+ <translation>Verifiser &amp;Melding</translation>
+ </message>
+ <message>
+ <source>Reset all verify message fields</source>
+ <translation>Tilbakestill alle felter for meldingsverifikasjon</translation>
+ </message>
+ <message>
+ <source>Click "Sign Message" to generate signature</source>
+ <translation>Klikk "Signer Melding" for å generere signatur</translation>
+ </message>
+ <message>
+ <source>The entered address is invalid.</source>
+ <translation>Angitt adresse er ugyldig.</translation>
+ </message>
+ <message>
+ <source>Please check the address and try again.</source>
+ <translation>Vennligst sjekk adressen og prøv igjen.</translation>
+ </message>
+ <message>
+ <source>The entered address does not refer to a key.</source>
+ <translation>Angitt adresse refererer ikke til en nøkkel.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock was cancelled.</source>
+ <translation>Opplåsing av lommebok ble avbrutt.</translation>
+ </message>
+ <message>
+ <source>Private key for the entered address is not available.</source>
+ <translation>Privat nøkkel for den angitte adressen er ikke tilgjengelig.</translation>
+ </message>
+ <message>
+ <source>Message signing failed.</source>
+ <translation>Signering av melding feilet.</translation>
+ </message>
+ <message>
+ <source>Message signed.</source>
+ <translation>Melding signert.</translation>
+ </message>
+ <message>
+ <source>The signature could not be decoded.</source>
+ <translation>Signaturen kunne ikke dekodes.</translation>
+ </message>
+ <message>
+ <source>Please check the signature and try again.</source>
+ <translation>Vennligst sjekk signaturen og prøv igjen.</translation>
+ </message>
+ <message>
+ <source>The signature did not match the message digest.</source>
+ <translation>Signaturen passer ikke til meldingen.</translation>
+ </message>
+ <message>
+ <source>Message verification failed.</source>
+ <translation>Verifikasjon av melding feilet.</translation>
+ </message>
+ <message>
+ <source>Message verified.</source>
+ <translation>Melding verifisert.</translation>
+ </message>
+</context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>The Bitcoin Core developers</source>
+ <translation>Bitcoin Core utviklerne</translation>
+ </message>
+ <message>
+ <source>[testnet]</source>
+ <translation>[testnett]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ <message>
+ <source>KB/s</source>
+ <translation>KB/s</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>Åpen til %1</translation>
+ </message>
+ <message>
+ <source>conflicted</source>
+ <translation>konflikt</translation>
+ </message>
+ <message>
+ <source>%1/offline</source>
+ <translation>%1/frakoblet</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/ubekreftet</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 bekreftelser</translation>
+ </message>
+ <message>
+ <source>Status</source>
+ <translation>Status</translation>
+ </message>
+ <message numerus="yes">
+ <source>, broadcast through %n node(s)</source>
+ <translation><numerusform>, kringkast gjennom %n node</numerusform><numerusform>, kringkast gjennom %n noder</numerusform></translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Dato</translation>
+ </message>
+ <message>
+ <source>Source</source>
+ <translation>Kilde</translation>
+ </message>
+ <message>
+ <source>Generated</source>
+ <translation>Generert</translation>
+ </message>
+ <message>
+ <source>From</source>
+ <translation>Fra</translation>
+ </message>
+ <message>
+ <source>To</source>
+ <translation>Til</translation>
+ </message>
+ <message>
+ <source>own address</source>
+ <translation>egen adresse</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>kun observerbar</translation>
+ </message>
+ <message>
+ <source>label</source>
+ <translation>merkelapp</translation>
+ </message>
+ <message>
+ <source>Credit</source>
+ <translation>Kredit</translation>
+ </message>
+ <message numerus="yes">
+ <source>matures in %n more block(s)</source>
+ <translation><numerusform>blir moden om %n blokk</numerusform><numerusform>blir moden om %n blokker</numerusform></translation>
+ </message>
+ <message>
+ <source>not accepted</source>
+ <translation>ikke akseptert</translation>
+ </message>
+ <message>
+ <source>Debit</source>
+ <translation>Debet</translation>
+ </message>
+ <message>
+ <source>Total debit</source>
+ <translation>Total debet</translation>
+ </message>
+ <message>
+ <source>Total credit</source>
+ <translation>Total kredit</translation>
+ </message>
+ <message>
+ <source>Transaction fee</source>
+ <translation>Transaksjonsgebyr</translation>
+ </message>
+ <message>
+ <source>Net amount</source>
+ <translation>Nettobeløp</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Melding</translation>
+ </message>
+ <message>
+ <source>Comment</source>
+ <translation>Kommentar</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>Transaksjons-ID</translation>
+ </message>
+ <message>
+ <source>Merchant</source>
+ <translation>Forhandler</translation>
+ </message>
+ <message>
+ <source>Generated coins must mature %1 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.</source>
+ <translation>Genererte bitcoins må modnes %1 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.</translation>
+ </message>
+ <message>
+ <source>Debug information</source>
+ <translation>Informasjon for feilsøk</translation>
+ </message>
+ <message>
+ <source>Transaction</source>
+ <translation>Transaksjon</translation>
+ </message>
+ <message>
+ <source>Inputs</source>
+ <translation>Inndata</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Beløp</translation>
+ </message>
+ <message>
+ <source>true</source>
+ <translation>sann</translation>
+ </message>
+ <message>
+ <source>false</source>
+ <translation>usann</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, har ikke blitt kringkastet med hell enda</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Åpen for %n blokk til</numerusform><numerusform>Åpen for %n blokker til</numerusform></translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>ukjent</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>Transaksjonsdetaljer</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>Her vises en detaljert beskrivelse av transaksjonen</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Dato</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Type</translation>
+ </message>
+ <message>
+ <source>Immature (%1 confirmations, will be available after %2)</source>
+ <translation>Umoden (%1 bekreftelser, vil være tilgjengelig etter %2)</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Åpen for %n blokk til</numerusform><numerusform>Åpen for %n blokker til</numerusform></translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>Åpen til %1</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>Bekreftet (%1 bekreftelser)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>Denne blokken har ikke blitt mottatt av noen andre noder og vil sannsynligvis ikke bli akseptert!</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>Generert men ikke akseptert</translation>
+ </message>
+ <message>
+ <source>Offline</source>
+ <translation>Frakoblet</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Merkelapp</translation>
+ </message>
+ <message>
+ <source>Unconfirmed</source>
+ <translation>Ubekreftet</translation>
+ </message>
+ <message>
+ <source>Confirming (%1 of %2 recommended confirmations)</source>
+ <translation>Bekrefter (%1 av %2 anbefalte bekreftelser)</translation>
+ </message>
+ <message>
+ <source>Conflicted</source>
+ <translation>Konflikt</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Mottatt med</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>Mottatt fra</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Sendt til</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>Betaling til deg selv</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Utvunnet</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>kun observerbar</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>-</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>Transaksjonsstatus. Hold muspekeren over dette feltet for å se antall bekreftelser.</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Dato og tid for da transaksjonen ble mottat.</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>Type transaksjon.</translation>
+ </message>
+ <message>
+ <source>Whether or not a watch-only address is involved in this transaction.</source>
+ <translation>Hvorvidt en kun observerbar adresse er involvert i denne transaksjonen.</translation>
+ </message>
+ <message>
+ <source>User-defined intent/purpose of the transaction.</source>
+ <translation>Brukerdefinert intensjon/hensikt med transaksjonen.</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>Beløp fjernet eller lagt til saldo.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>Alle</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>I dag</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>Denne uken</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>Denne måneden</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>Forrige måned</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>Dette året</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>Intervall...</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Mottatt med</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Sendt til</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>Til deg selv</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Utvunnet</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>Andre</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>Skriv inn adresse eller merkelapp for søk</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>Minimumsbeløp</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Kopier adresse</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Kopier merkelapp</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopier beløp</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Kopier transaksjons-ID</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>Rediger merkelapp</translation>
+ </message>
+ <message>
+ <source>Show transaction details</source>
+ <translation>Vis transaksjonsdetaljer</translation>
+ </message>
+ <message>
+ <source>Export Transaction History</source>
+ <translation>Eksporter Transaksjonshistorikk</translation>
+ </message>
+ <message>
+ <source>Watch-only</source>
+ <translation>Kun observer</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Ekport Feilet</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the transaction history to %1.</source>
+ <translation>En feil oppstod ved lagring av transaksjonshistorikken til %1.</translation>
+ </message>
+ <message>
+ <source>Exporting Successful</source>
+ <translation>Ekport Fullført</translation>
+ </message>
+ <message>
+ <source>The transaction history was successfully saved to %1.</source>
+ <translation>Transaksjonshistorikken ble lagret til %1.</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Kommaseparert fil (*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Bekreftet</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Dato</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Type</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Merkelapp</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adresse</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>Intervall:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>til</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ <message>
+ <source>Unit to show amounts in. Click to select another unit.</source>
+ <translation>Enhet å vise beløper i. Klikk for å velge en annen enhet.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletFrame</name>
+ <message>
+ <source>No wallet has been loaded.</source>
+ <translation>Ingen lommebok har blitt lastet.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Send Bitcoins</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Eksporter</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Eksporter data fra nåværende fane til fil</translation>
+ </message>
+ <message>
+ <source>Backup Wallet</source>
+ <translation>Sikkerhetskopier Lommebok</translation>
+ </message>
+ <message>
+ <source>Wallet Data (*.dat)</source>
+ <translation>Lommebokdata (*.dat)</translation>
+ </message>
+ <message>
+ <source>Backup Failed</source>
+ <translation>Sikkerhetskopiering Feilet</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the wallet data to %1.</source>
+ <translation>En feil oppstod ved lagring av lommebok til %1.</translation>
+ </message>
+ <message>
+ <source>The wallet data was successfully saved to %1.</source>
+ <translation>Lommeboken ble lagret til %1.</translation>
+ </message>
+ <message>
+ <source>Backup Successful</source>
+ <translation>Sikkerhetskopiering Fullført</translation>
+ </message>
+</context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>Innstillinger:</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>Angi mappe for datafiler</translation>
+ </message>
+ <message>
+ <source>Connect to a node to retrieve peer addresses, and disconnect</source>
+ <translation>Koble til node for å hente adresser til andre noder, koble så fra igjen</translation>
+ </message>
+ <message>
+ <source>Specify your own public address</source>
+ <translation>Angi din egen offentlige adresse</translation>
+ </message>
+ <message>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>Ta imot kommandolinje- og JSON-RPC-kommandoer</translation>
+ </message>
+ <message>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>Kjør i bakgrunnen som daemon og ta imot kommandoer</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>Bruk testnettverket</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
+ <translation>Ta imot tilkoblinger fra utsiden (standardverdi: 1 hvis uten -proxy eller -connect)</translation>
+ </message>
+ <message>
+ <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
+ <translation>Bind til angitt adresse. Bruk [vertsmaskin]:port notasjon for IPv6</translation>
+ </message>
+ <message>
+ <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
+ <translation>Slett alle transaksjoner i lommeboken og gjenopprett kun de delene av blokkjeden gjennom -rescan ved oppstart</translation>
+ </message>
+ <message>
+ <source>Distributed under the MIT software license, see the accompanying file COPYING or &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</source>
+ <translation>Distribuert under MIT programvarelisensen, se medfølgende fil COPYING eller &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</translation>
+ </message>
+ <message>
+ <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
+ <translation>Kjør kommando når en lommeboktransaksjon endres (%s i kommando er erstattet med TxID)</translation>
+ </message>
+ <message>
+ <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source>
+ <translation>Maksimalt samlede gebyrer til å bruke i en enkelt lommeboktransaksjon; settes dette for lavt kan store transaksjoner kanskje avbrytes (standardverdi: %s)</translation>
+ </message>
+ <message>
+ <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, &gt;%u = target size in MiB to use for block files)</source>
+ <translation>Reduser lagringsbehovet ved beskjæring (slette) gamle blokker. Denne modusen deaktiverer støtte for lommebok og er ikke kompatibel med -txindex. Advarsel: Tilbakestilling av denne innstillingen krever at hele blokkjeden må lastes ned på nytt. (Standardverdi: 0 = deaktiver beskjæringsblokker, &gt;%u = mål for størrelse i MiB å bruke for blokkfiler)</translation>
+ </message>
+ <message>
+ <source>Set the number of script verification threads (%u to %d, 0 = auto, &lt;0 = leave that many cores free, default: %d)</source>
+ <translation>Angi antall tråder for skriptverifisering (%u til %d, 0 = auto, &lt;0 = la det antallet kjerner være ledig, standard: %d)</translation>
+ </message>
+ <message>
+ <source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source>
+ <translation>Dette er en forhåndssluppet testversjon - bruk på egen risiko - ikke for bruk til blokkutvinning eller bedriftsapplikasjoner</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer. Bitcoin Core is probably already running.</source>
+ <translation>Ute av stand til å binde til %s på denne datamaskinen. Bitcoin Core kjører sannsynligvis allerede.</translation>
+ </message>
+ <message>
+ <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>ADVARSEL: unormalt høyt antall blokker generert, %d blokker mottatt de siste %d timene (%d forventet)</translation>
+ </message>
+ <message>
+ <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>ADVARSEL: kontroller nettverkstilkoblingen, mottok %d blokker i de siste %d timene (%d forventet)</translation>
+ </message>
+ <message>
+ <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>Advarsel: -paytxfee er satt veldig høyt! Dette er transaksjonsgebyret du betaler når du sender transaksjoner.</translation>
+ </message>
+ <message>
+ <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source>
+ <translation>Advarsel: Nettverket ser ikke ut til å være enig! Noen minere ser ut til å ha problemer.</translation>
+ </message>
+ <message>
+ <source>Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.</source>
+ <translation>Advarsel: Vi ser ikke ut til å være enige med våre noder! Du må oppgradere, eller andre noder må oppgradere.</translation>
+ </message>
+ <message>
+ <source>Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
+ <translation>Advarsel: Feil ved lesing av wallet.dat! Alle nøkler lest riktig, men transaksjonsdataene eller oppføringer i adresseboken mangler kanskje eller er feil.</translation>
+ </message>
+ <message>
+ <source>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</source>
+ <translation>Advarsel: wallet.dat korrupt, data reddet! Original wallet.dat lagret som wallet.{timestamp}.bak i %s; hvis din saldo eller dine transaksjoner ikke er korrekte bør du gjenopprette fra en backup.</translation>
+ </message>
+ <message>
+ <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source>
+ <translation>Hvitelist noder som kobler til fra den oppgitte nettmasken eller IP-adressen. Kan oppgis flere ganger.</translation>
+ </message>
+ <message>
+ <source>(default: 1)</source>
+ <translation>(standardverdi: 1)</translation>
+ </message>
+ <message>
+ <source>&lt;category&gt; can be:</source>
+ <translation>&lt;category&gt; kan være:</translation>
+ </message>
+ <message>
+ <source>Attempt to recover private keys from a corrupt wallet.dat</source>
+ <translation>Forsøk å berge private nøkler fra en korrupt wallet.dat</translation>
+ </message>
+ <message>
+ <source>Block creation options:</source>
+ <translation>Valg for opprettelse av blokker:</translation>
+ </message>
+ <message>
+ <source>Connect only to the specified node(s)</source>
+ <translation>Koble kun til angitt(e) node(r)</translation>
+ </message>
+ <message>
+ <source>Connection options:</source>
+ <translation>Innstillinger for tilkobling:</translation>
+ </message>
+ <message>
+ <source>Corrupted block database detected</source>
+ <translation>Oppdaget korrupt blokkdatabase</translation>
+ </message>
+ <message>
+ <source>Debugging/Testing options:</source>
+ <translation>Valg for feilsøking/testing:</translation>
+ </message>
+ <message>
+ <source>Do not load the wallet and disable wallet RPC calls</source>
+ <translation>Ikke last inn lommeboken og deaktiver RPC-kall</translation>
+ </message>
+ <message>
+ <source>Do you want to rebuild the block database now?</source>
+ <translation>Ønsker du å gjenopprette blokkdatabasen nå?</translation>
+ </message>
+ <message>
+ <source>Error initializing block database</source>
+ <translation>Feil under initialisering av blokkdatabase</translation>
+ </message>
+ <message>
+ <source>Error initializing wallet database environment %s!</source>
+ <translation>Feil under oppstart av lommeboken sitt databasemiljø %s!</translation>
+ </message>
+ <message>
+ <source>Error loading block database</source>
+ <translation>Feil ved lasting av blokkdatabase</translation>
+ </message>
+ <message>
+ <source>Error opening block database</source>
+ <translation>Feil under åpning av blokkdatabase</translation>
+ </message>
+ <message>
+ <source>Error: Disk space is low!</source>
+ <translation>Feil: Lite ledig lagringsplass!</translation>
+ </message>
+ <message>
+ <source>Failed to listen on any port. Use -listen=0 if you want this.</source>
+ <translation>Kunne ikke lytte på noen port. Bruk -listen=0 hvis det er dette du vil.</translation>
+ </message>
+ <message>
+ <source>If &lt;category&gt; is not supplied, output all debugging information.</source>
+ <translation>Hvis &lt;category&gt; ikke er oppgitt, ta ut all informasjon om feilsøking.</translation>
+ </message>
+ <message>
+ <source>Importing...</source>
+ <translation>Importerer...</translation>
+ </message>
+ <message>
+ <source>Incorrect or no genesis block found. Wrong datadir for network?</source>
+ <translation>Ugyldig eller ingen skaperblokk funnet. Feil datamappe for nettverk?</translation>
+ </message>
+ <message>
+ <source>Invalid -onion address: '%s'</source>
+ <translation>Ugyldig -onion adresse: '%s'</translation>
+ </message>
+ <message>
+ <source>Not enough file descriptors available.</source>
+ <translation>For få fildeskriptorer tilgjengelig.</translation>
+ </message>
+ <message>
+ <source>Only connect to nodes in network &lt;net&gt; (ipv4, ipv6 or onion)</source>
+ <translation>Bare koble til noder i nettverket &lt;net&gt; (IPv4, IPv6 eller onion)</translation>
+ </message>
+ <message>
+ <source>Prune cannot be configured with a negative value.</source>
+ <translation>Beskjæringsmodus kan ikke konfigureres med en negativ verdi.</translation>
+ </message>
+ <message>
+ <source>Prune mode is incompatible with -txindex.</source>
+ <translation>Beskjæringsmodus er ikke kompatibel med -txindex.</translation>
+ </message>
+ <message>
+ <source>Set database cache size in megabytes (%d to %d, default: %d)</source>
+ <translation>Sett databasen sin størrelse på hurtigbufferen i megabytes (%d til %d, standardverdi: %d)</translation>
+ </message>
+ <message>
+ <source>Set maximum block size in bytes (default: %d)</source>
+ <translation>Sett maks blokkstørrelse i bytes (standardverdi: %d)</translation>
+ </message>
+ <message>
+ <source>Specify wallet file (within data directory)</source>
+ <translation>Angi lommebokfil (inne i datamappe)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: %u)</source>
+ <translation>Bruk UPnP for å sette opp lytteport (standardverdi: %u)</translation>
+ </message>
+ <message>
+ <source>Verifying blocks...</source>
+ <translation>Verifiserer blokker...</translation>
+ </message>
+ <message>
+ <source>Verifying wallet...</source>
+ <translation>Verifiserer lommebok...</translation>
+ </message>
+ <message>
+ <source>Wallet %s resides outside data directory %s</source>
+ <translation>Lommebok %s befinner seg utenfor datamappe %s</translation>
+ </message>
+ <message>
+ <source>Wallet options:</source>
+ <translation>Valg for lommebok:</translation>
+ </message>
+ <message>
+ <source>Warning: This version is obsolete; upgrade required!</source>
+ <translation>Advarsel: Denne versjonen er utdatert; oppgradering er påkrevd!</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to change -txindex</source>
+ <translation>Du må gjenoppbygge databasen med å bruke -reindex for å endre -txindex</translation>
+ </message>
+ <message>
+ <source>Imports blocks from external blk000??.dat file</source>
+ <translation>Importerer blokker fra ekstern fil blk000??.dat</translation>
+ </message>
+ <message>
+ <source>Allow JSON-RPC connections from specified source. Valid for &lt;ip&gt; are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times</source>
+ <translation>Tillat JSON-RPC-tilkoblinger fra angitt kilde. Gyldig for &lt;ip&gt; er en enkelt IP (f. eks. 1.2.3.4), et nettverk/nettmaske (f. eks. 1.2.3.4/255.255.255.0) eller et nettverk/CIDR (f. eks. 1.2.3.4/24). Dette alternativet kan angis flere ganger</translation>
+ </message>
+ <message>
+ <source>An error occurred while setting up the RPC address %s port %u for listening: %s</source>
+ <translation>En feil oppstod under oppsett av RPC-adressen %s port %u for lytting: %s</translation>
+ </message>
+ <message>
+ <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source>
+ <translation>Bind til gitt adresse og hvitlist peers som kobler seg til den. Bruk [host]:port notasjon for IPv6</translation>
+ </message>
+ <message>
+ <source>Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)</source>
+ <translation>Bind til gitt adresse for å lytte for JSON-RPC-tilkoblinger. Bruk [host]:port notasjon for IPv6. Dette alternativet kan angis flere ganger (standardverdi: bind til alle grensesnitt)</translation>
+ </message>
+ <message>
+ <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source>
+ <translation>Ute av stand til å låse datamappen %s. Bitcoin Core kjører sannsynligvis allerede.</translation>
+ </message>
+ <message>
+ <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
+ <translation>Opprett nye filer med standardtillatelser i systemet, i stedet for umask 077 (kun virksom med lommebokfunksjonalitet slått av)</translation>
+ </message>
+ <message>
+ <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source>
+ <translation>Oppdag egne IP-adresser (standardverdi: 1 ved lytting og ingen -externalip eller -proxy)</translation>
+ </message>
+ <message>
+ <source>Error: Listening for incoming connections failed (listen returned error %s)</source>
+ <translation>Feil: Lytting etter innkommende tilkoblinger feilet (lytting returnerte feil %s)</translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source>
+ <translation>Feil: Argumentet -socks er ikke støttet. Det er ikke lenger mulig å sette SOCKS-versjon; bare SOCKS5-proxyer er støttet.</translation>
+ </message>
+ <message>
+ <source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source>
+ <translation>Utfør kommando når et relevant varsel er mottatt eller vi ser en veldig lang gaffel (%s i kommando er erstattet med melding)</translation>
+ </message>
+ <message>
+ <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source>
+ <translation>Gebyrer (i BTC/Kb) mindre enn dette anses som null gebyr for videresending (standardverdi: %s)</translation>
+ </message>
+ <message>
+ <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
+ <translation>Hvis paytxfee ikke er angitt, inkluderer da nok i gebyr til at transaksjoner gjennomsnittligt bekreftes innen n blokker (standardverdi: %u)</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)</source>
+ <translation>Ugyldig beløp for -maxtxfee=&lt;amount&gt;: '%s' (må være minst minimum relé gebyr på %s for å hindre fastlåste transaksjoner)</translation>
+ </message>
+ <message>
+ <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source>
+ <translation>Maksimal størrelse på data i databærende transaksjoner vi videresender og ufører graving på (standardverdi: %u)</translation>
+ </message>
+ <message>
+ <source>Prune configured below the minimum of %d MB. Please use a higher number.</source>
+ <translation>Beskjæringsmodus er konfigurert under minimum på %d MB. Vennligst bruk et høyere nummer.</translation>
+ </message>
+ <message>
+ <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source>
+ <translation>Søk etter nodeadresser via DNS-oppslag, hvis vi har få adresser å koble til (standard: 1 med mindre -connect)</translation>
+ </message>
+ <message>
+ <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source>
+ <translation>Bruk tilfeldig identitet for hver proxytilkobling. Dette muliggjør TOR stream isolasjon (standardverdi: %u)</translation>
+ </message>
+ <message>
+ <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
+ <translation>Sett maksimum størrelse for transaksjoner med høy prioritet / lavt gebyr, i bytes (standardverdi: %d)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source>
+ <translation>Angi antall tråder for mynt generering hvis aktivert (-1 = alle kjerner, standardverdi: %d)</translation>
+ </message>
+ <message>
+ <source>The transaction amount is too small to send after the fee has been deducted</source>
+ <translation>Transaksjonsbeløpet er for lite til å sendes etter at gebyret er fratrukket</translation>
+ </message>
+ <message>
+ <source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit &lt;https://www.openssl.org/&gt; and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source>
+ <translation>Dette produktet inneholder programvare utviklet av OpenSSL Project for bruk i OpenSSL Toolkit &lt;https://www.openssl.org/&gt; og kryptografisk programvare skrevet av Eric Young og UPnP-programvare skrevet av Thomas Bernard.</translation>
+ </message>
+ <message>
+ <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an 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)
+The username and password MUST NOT be the same.
+If the file does not exist, create it with owner-readable-only file permissions.
+It is also recommended to set alertnotify so you are notified of problems;
+for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
+</source>
+ <translation>For å bruke bitcoind, eller -server valget til bitcoin-qt, må du angi et rpcpassord i konfigurasjonsfilen:
+%s
+Det anbefales at du bruker det følgende tilfeldige passordet:
+rpcuser=bitcoinrpc
+rpcpassword=%s
+(du behøver ikke å huske passordet)
+Brukernavnet og passordet MÅ IKKE være like.
+Om filen ikke eksisterer, opprett den med eier-kun-les filrettigheter.
+Det er også anbefalt at å sette varselsmelding slik du får melding om problemer;
+for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
+</translation>
+ </message>
+ <message>
+ <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source>
+ <translation>Advarsel: -paytxfee er satt veldig høyt! Så stort gebyr kan bli betalt ved en enkelt transaksjon.</translation>
+ </message>
+ <message>
+ <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source>
+ <translation>Advarsel: Vennligst undersøk at din datamaskin har riktig dato og klokkeslett! Hvis klokken er stilt feil vil ikke Bitcoin Core fungere riktig.</translation>
+ </message>
+ <message>
+ <source>Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway</source>
+ <translation>Hvitlistede noder kan ikke DoS-blokkeres, og deres transaksjoner videresendes alltid, selv om de allerede er i minnelageret. Nyttig f.eks. for en gateway.</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source>
+ <translation>Du må gjenoppbygge databasen ved hjelp av -reindex for å gå tilbake til ubeskåret modus. Dette vil laste ned hele blokkjeden på nytt.</translation>
+ </message>
+ <message>
+ <source>(default: %u)</source>
+ <translation>(standardverdi: %u)</translation>
+ </message>
+ <message>
+ <source>Accept public REST requests (default: %u)</source>
+ <translation>Godta offentlige REST forespørsler (standardverdi: %u)</translation>
+ </message>
+ <message>
+ <source>Activating best chain...</source>
+ <translation>Aktiverer beste kjede...</translation>
+ </message>
+ <message>
+ <source>Can't run with a wallet in prune mode.</source>
+ <translation>Kan ikke kjøre med en lommebok i beskjæringsmodus.</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -whitebind address: '%s'</source>
+ <translation>Kan ikke løse -whitebind-adresse: '%s'</translation>
+ </message>
+ <message>
+ <source>Choose data directory on startup (default: 0)</source>
+ <translation>Velg datamappe ved oppstart (standard: 0)</translation>
+ </message>
+ <message>
+ <source>Connect through SOCKS5 proxy</source>
+ <translation>Koble til via SOCKS5-proxy</translation>
+ </message>
+ <message>
+ <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source>
+ <translation>Copyright (C) 2009-%i utviklerne av Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Could not parse -rpcbind value %s as network address</source>
+ <translation>Kunne ikke tolke -rpcbind-verdi %s som en nettverksadresse</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source>
+ <translation>Feil ved lasting av wallet.dat: Lommeboken krever en nyere versjon av Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Error reading from database, shutting down.</source>
+ <translation>Feil ved lesing fra database, stenger ned.</translation>
+ </message>
+ <message>
+ <source>Error: A fatal internal error occurred, see debug.log for details</source>
+ <translation>Feil: En fatal intern feil oppstod, se debug.log for detaljer</translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -tor found, use -onion.</source>
+ <translation>Feil: Argumentet -tor er ikke støttet, bruk -onion.</translation>
+ </message>
+ <message>
+ <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source>
+ <translation>Gebyr (i BTC/kB) for å legge til i transaksjoner du sender (standardverdi: %s)</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Informasjon</translation>
+ </message>
+ <message>
+ <source>Initialization sanity check failed. Bitcoin Core is shutting down.</source>
+ <translation>Sunnhetssjekk ved oppstart feilet. Bitcoin Core stenges ned.</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Ugyldig beløp for -maxtxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -minrelaytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Ugyldig mengde for -minrelaytxfee=&lt;beløp&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -mintxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Ugyldig mengde for -mintxfee=&lt;beløp&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s' (must be at least %s)</source>
+ <translation>Ugyldig beløp for -paytxfee=&lt;amount&gt;: '%s' (må være minst %s)</translation>
+ </message>
+ <message>
+ <source>Invalid netmask specified in -whitelist: '%s'</source>
+ <translation>Ugyldig nettmaske spesifisert i -whitelist: '%s'</translation>
+ </message>
+ <message>
+ <source>Keep at most &lt;n&gt; unconnectable transactions in memory (default: %u)</source>
+ <translation>Hold på det meste &lt;n&gt; transaksjoner som ikke kobles i minnet (standardverdi: %u)</translation>
+ </message>
+ <message>
+ <source>Need to specify a port with -whitebind: '%s'</source>
+ <translation>Må oppgi en port med -whitebind: '%s'</translation>
+ </message>
+ <message>
+ <source>Node relay options:</source>
+ <translation>Node alternativer for videresending:</translation>
+ </message>
+ <message>
+ <source>Pruning blockstore...</source>
+ <translation>Beskjærer blokklageret...</translation>
+ </message>
+ <message>
+ <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source>
+ <translation>RPC SSL-valg: (se Bitcoin Wiki for oppsettsinstruksjoner for SSL)</translation>
+ </message>
+ <message>
+ <source>RPC server options:</source>
+ <translation>Innstillinger for RPC-server:</translation>
+ </message>
+ <message>
+ <source>RPC support for HTTP persistent connections (default: %d)</source>
+ <translation>RPC-støtte for persistente HTTP-forbindelser (standardverdi: %d)</translation>
+ </message>
+ <message>
+ <source>Rebuild block chain index from current blk000??.dat files on startup</source>
+ <translation>Gjenopprett blokkjedeindeks fra gjeldende blk000??.dat filer ved oppstart</translation>
+ </message>
+ <message>
+ <source>Receive and display P2P network alerts (default: %u)</source>
+ <translation>Motta og vis P2P nettverksvarsler (standardvalg: %u)</translation>
+ </message>
+ <message>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>Send spor-/feilsøkingsinformasjon til konsollen istedenfor filen debug.log</translation>
+ </message>
+ <message>
+ <source>Send transactions as zero-fee transactions if possible (default: %u)</source>
+ <translation>Send transaksjoner uten transaksjonsgebyr hvis mulig (standardverdi: %u)</translation>
+ </message>
+ <message>
+ <source>Set SSL root certificates for payment request (default: -system-)</source>
+ <translation>Sett SSL-rotsertifikat for betalingsetterspørring (standard: -system-)</translation>
+ </message>
+ <message>
+ <source>Set language, for example "de_DE" (default: system locale)</source>
+ <translation>Sett språk, for eksempel "nb_NO" (standardverdi: fra operativsystem)</translation>
+ </message>
+ <message>
+ <source>Show all debugging options (usage: --help -help-debug)</source>
+ <translation>Vis alle feilsøkingsvalg (bruk: --help -help-debug)</translation>
+ </message>
+ <message>
+ <source>Show splash screen on startup (default: 1)</source>
+ <translation>Vis splashskjerm ved oppstart (standardverdi: 1)</translation>
+ </message>
+ <message>
+ <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source>
+ <translation>Krymp filen debug.log når klienten starter (standardverdi: 1 hvis uten -debug)</translation>
+ </message>
+ <message>
+ <source>Signing transaction failed</source>
+ <translation>Signering av transaksjon feilet</translation>
+ </message>
+ <message>
+ <source>Start minimized</source>
+ <translation>Start minimert</translation>
+ </message>
+ <message>
+ <source>The transaction amount is too small to pay the fee</source>
+ <translation>Transaksjonsbeløpet er for lite til å betale gebyr</translation>
+ </message>
+ <message>
+ <source>This is experimental software.</source>
+ <translation>Dette er eksperimentell programvare.</translation>
+ </message>
+ <message>
+ <source>Transaction amount too small</source>
+ <translation>Transaksjonen er for liten</translation>
+ </message>
+ <message>
+ <source>Transaction amounts must be positive</source>
+ <translation>Transaksjonsbeløpet må være positivt</translation>
+ </message>
+ <message>
+ <source>Transaction too large for fee policy</source>
+ <translation>Transaksjon for stor for gebyrpolitikken</translation>
+ </message>
+ <message>
+ <source>Transaction too large</source>
+ <translation>Transaksjonen er for stor</translation>
+ </message>
+ <message>
+ <source>UI Options:</source>
+ <translation>Innstillinger for Brukergrensesnitt:</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer (bind returned error %s)</source>
+ <translation>Kan ikke binde til %s på denne datamaskinen (binding returnerte feilen %s)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: 1 when listening)</source>
+ <translation>Bruk UPnP for lytteport (standardverdi: 1 ved lytting)</translation>
+ </message>
+ <message>
+ <source>Username for JSON-RPC connections</source>
+ <translation>Brukernavn for JSON-RPC forbindelser</translation>
+ </message>
+ <message>
+ <source>Wallet needed to be rewritten: restart Bitcoin Core to complete</source>
+ <translation>Lommeboken måtte skrives på nytt: start Bitcoin Core på nytt for å fullføre</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Advarsel</translation>
+ </message>
+ <message>
+ <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source>
+ <translation>Advarsel: Argumentet -benchmark er ikke støttet og ble ignorert, bruk -debug=bench.</translation>
+ </message>
+ <message>
+ <source>Warning: Unsupported argument -debugnet ignored, use -debug=net.</source>
+ <translation>Advarsel: Argumentet -debugnet er ikke støttet og ble ignorert, bruk -debug=net.</translation>
+ </message>
+ <message>
+ <source>Zapping all transactions from wallet...</source>
+ <translation>Zapper alle transaksjoner fra lommeboken...</translation>
+ </message>
+ <message>
+ <source>on startup</source>
+ <translation>ved oppstart</translation>
+ </message>
+ <message>
+ <source>wallet.dat corrupt, salvage failed</source>
+ <translation>wallet.dat korrupt, bergning feilet</translation>
+ </message>
+ <message>
+ <source>Password for JSON-RPC connections</source>
+ <translation>Passord for JSON-RPC forbindelser</translation>
+ </message>
+ <message>
+ <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
+ <translation>Utfør kommando når beste blokk endrer seg (%s i kommandoen erstattes med blokkens hash)</translation>
+ </message>
+ <message>
+ <source>Upgrade wallet to latest format</source>
+ <translation>Oppgrader lommebok til nyeste format</translation>
+ </message>
+ <message>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>Se gjennom blokkjeden etter manglende lommeboktransaksjoner</translation>
+ </message>
+ <message>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>Bruk OpenSSL (https) for JSON-RPC forbindelser</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>Denne hjelpemeldingen</translation>
+ </message>
+ <message>
+ <source>Allow DNS lookups for -addnode, -seednode and -connect</source>
+ <translation>Tillat oppslag i DNS for -addnode, -seednode og -connect</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>Laster adresser...</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>Feil ved lasting av wallet.dat: Lommeboken er skadet</translation>
+ </message>
+ <message>
+ <source>(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source>
+ <translation>(1 = behold metadata for transaksjon som f. eks. kontoeier og informasjon om betalingsanmodning, 2 = dropp metadata for transaksjon)</translation>
+ </message>
+ <message>
+ <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
+ <translation>Hvor grundig blokkverifiseringen til -checkblocks er (0-4, standardverdi: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
+ <translation>Oppretthold en full transaksjonsindeks, brukt av getrawtransaction RPC-kall (standardverdi: %u)</translation>
+ </message>
+ <message>
+ <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source>
+ <translation>Antall sekunder noder med dårlig oppførsel hindres fra å koble til på nytt (standardverdi: %u)</translation>
+ </message>
+ <message>
+ <source>Output debugging information (default: %u, supplying &lt;category&gt; is optional)</source>
+ <translation>Ta ut feilsøkingsinformasjon (standardverdi: %u, bruk av &lt;category&gt; er valgfritt)</translation>
+ </message>
+ <message>
+ <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source>
+ <translation>Bruk separate SOCKS5 proxyer for å nå noder via Tor skjulte tjenester (standardverdi: %s)</translation>
+ </message>
+ <message>
+ <source>(default: %s)</source>
+ <translation>(standardverdi: %s)</translation>
+ </message>
+ <message>
+ <source>Acceptable ciphers (default: %s)</source>
+ <translation>Akseptable sifre (standardverdi: %s)</translation>
+ </message>
+ <message>
+ <source>Always query for peer addresses via DNS lookup (default: %u)</source>
+ <translation>Alltid søk etter nodeadresser via DNS-oppslag (standardverdi: %u)</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>Feil ved lasting av wallet.dat</translation>
+ </message>
+ <message>
+ <source>Generate coins (default: %u)</source>
+ <translation>Generer mynter (standardverdi: %u)</translation>
+ </message>
+ <message>
+ <source>How many blocks to check at startup (default: %u, 0 = all)</source>
+ <translation>Hvor mange blokker skal sjekkes ved oppstart (standardverdi: %u, 0 = alle)</translation>
+ </message>
+ <message>
+ <source>Include IP addresses in debug output (default: %u)</source>
+ <translation>Inkludere IP-adresser i feilsøkingslogg (standardverdi: %u)</translation>
+ </message>
+ <message>
+ <source>Invalid -proxy address: '%s'</source>
+ <translation>Ugyldig -proxy adresse: '%s'</translation>
+ </message>
+ <message>
+ <source>Listen for JSON-RPC connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>Lytt etter JSON-RPC tilkoblinger på &lt;port&gt; (standardverdi: %u eller testnett: %u)</translation>
+ </message>
+ <message>
+ <source>Listen for connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>Lytt etter tilkoblinger på &lt;port&gt; (standardverdi: %u eller testnett: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain at most &lt;n&gt; connections to peers (default: %u)</source>
+ <translation>Hold maks &lt;n&gt; koblinger åpne til andre noder (standardverdi: %u)</translation>
+ </message>
+ <message>
+ <source>Make the wallet broadcast transactions</source>
+ <translation>Få lommeboken til å kringkaste transaksjoner</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection receive buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>Maks mottaksbuffer per forbindelse, &lt;n&gt;*1000 bytes (standardverdi: %u)</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection send buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>Maks sendebuffer per forbindelse, &lt;n&gt;*1000 bytes (standardverdi: %u)</translation>
+ </message>
+ <message>
+ <source>Prepend debug output with timestamp (default: %u)</source>
+ <translation>Sett inn tidsstempel i front av feilsøkingsdata (standardverdi: %u)</translation>
+ </message>
+ <message>
+ <source>Relay and mine data carrier transactions (default: %u)</source>
+ <translation>Videresend og ufør graving av databærende transaksjoner (standardverdi: %u)</translation>
+ </message>
+ <message>
+ <source>Relay non-P2SH multisig (default: %u)</source>
+ <translation>Videresend ikke-P2SH multisig (standardverdi: %u)</translation>
+ </message>
+ <message>
+ <source>Server certificate file (default: %s)</source>
+ <translation>Fil for tjenersertifikat (standardverdi: %s)</translation>
+ </message>
+ <message>
+ <source>Server private key (default: %s)</source>
+ <translation>Privat nøkkel for tjener (standardverdi: %s) </translation>
+ </message>
+ <message>
+ <source>Set key pool size to &lt;n&gt; (default: %u)</source>
+ <translation>Angi størrelse på nøkkel-lager til &lt;n&gt; (standardverdi: %u)</translation>
+ </message>
+ <message>
+ <source>Set minimum block size in bytes (default: %u)</source>
+ <translation>Sett minimum blokkstørrelse i bytes (standardverdi: %u)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads to service RPC calls (default: %d)</source>
+ <translation>Sett antall tråder til betjening av RPC-kall (standardverdi: %d)</translation>
+ </message>
+ <message>
+ <source>Specify configuration file (default: %s)</source>
+ <translation>Angi konfigurasjonsfil (standardverdi: %s)</translation>
+ </message>
+ <message>
+ <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source>
+ <translation>Angi tidsavbrudd for forbindelse i millisekunder (minimum: 1, standardverdi: %d)</translation>
+ </message>
+ <message>
+ <source>Specify pid file (default: %s)</source>
+ <translation>Angi pid-fil (standardverdi: %s)</translation>
+ </message>
+ <message>
+ <source>Spend unconfirmed change when sending transactions (default: %u)</source>
+ <translation>Bruk ubekreftet veksel ved sending av transaksjoner (standardverdi: %u)</translation>
+ </message>
+ <message>
+ <source>Threshold for disconnecting misbehaving peers (default: %u)</source>
+ <translation>Grenseverdi for å koble fra noder med dårlig oppførsel (standardverdi: %u)</translation>
+ </message>
+ <message>
+ <source>Unknown network specified in -onlynet: '%s'</source>
+ <translation>Ukjent nettverk angitt i -onlynet '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -bind address: '%s'</source>
+ <translation>Kunne ikke slå opp -bind adresse: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -externalip address: '%s'</source>
+ <translation>Kunne ikke slå opp -externalip adresse: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Ugyldig beløp for -paytxfee=&lt;beløp&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>Utilstrekkelige midler</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>Laster blokkindeks...</translation>
+ </message>
+ <message>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>Legg til node for tilkobling og hold forbindelsen åpen</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>Laster lommebok...</translation>
+ </message>
+ <message>
+ <source>Cannot downgrade wallet</source>
+ <translation>Kan ikke nedgradere lommebok</translation>
+ </message>
+ <message>
+ <source>Cannot write default address</source>
+ <translation>Kan ikke skrive standardadresse</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>Leser gjennom...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>Ferdig med lasting</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Feil</translation>
+ </message>
+</context>
+</TS> \ 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 0000000000..0487a7e130
--- /dev/null
+++ b/src/qt/locale/bitcoin_nl.ts
@@ -0,0 +1,3496 @@
+<TS language="nl" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Right-click to edit address or label</source>
+ <translation>Klik met de rechtermuisknop om het adres of label te wijzigen</translation>
+ </message>
+ <message>
+ <source>Create a new address</source>
+ <translation>Maak een nieuw adres</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>&amp;Nieuw</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Kopieer het geselecteerde adres naar het klembord</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>&amp;Kopieer</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>S&amp;luiten</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>&amp;Kopiëer Adres</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>Verwijder het geselecteerde adres van de lijst</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Exporteer de data in de huidige tab naar een bestand</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Exporteer</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;Verwijder</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>Kies het adres om munten naar te versturen</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>Kies het adres om munten op te ontvangen</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>K&amp;iezen</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>Verstuur adressen</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>Ontvang adressen</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>Dit zijn uw Bitcoinadressen om betalingen mee te verzenden. Controleer altijd het bedrag en het ontvang adres voordat u uw bitcoins verzendt.</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>Dit zijn uw Bitcoin-adressen waarmee u kunt betalen. We raden u aan om een nieuw ontvangstadres voor elke transactie te gebruiken.</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>Kopiëer &amp;Label</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>&amp;Bewerk</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>Exporteer adreslijst</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Kommagescheiden bestand (*.csv)</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Export Mislukt</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the address list to %1. Please try again.</source>
+ <translation>Een fout is opgetreden tijdens het opslaan van deze adreslijst naar %1. Probeer het nogmaals.</translation>
+ </message>
+</context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Label</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adres</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(geen label)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Passphrase Dialog</source>
+ <translation>Wachtwoorddialoog</translation>
+ </message>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Voer wachtwoord in</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Nieuw wachtwoord</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Herhaal nieuw wachtwoord</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>Versleutel portemonnee</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>Deze operatie vereist uw portemonneewachtwoord om de portemonnee te openen.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Open portemonnee</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>Deze operatie vereist uw portemonneewachtwoord om de portemonnee te ontsleutelen</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>Ontsleutel portemonnee</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>Wijzig wachtwoord</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>Bevestig versleuteling van de portemonnee</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>Waarschuwing: Als u uw portemonnee versleutelt en uw wachtwoord vergeet, zult u &lt;b&gt;AL UW BITCOINS VERLIEZEN&lt;/b&gt;!</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>Weet u zeker dat u uw portemonnee wilt versleutelen?</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core 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.</source>
+ <translation>Bitcoin Core zal nu afsluiten om het versleutelingsproces te voltooien. Hou er rekening mee dat versleuteling van je portemonnee je niet volledig beschermt tegen diefstal van jouw bitcoins door malware op je computer.</translation>
+ </message>
+ <message>
+ <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
+ <translation>BELANGRIJK: Elke eerder gemaakte backup van uw portemonneebestand dient u te vervangen door het nieuw gegenereerde, versleutelde portemonneebestand. Om veiligheidsredenen zullen eerdere backups van het niet-versleutelde portemonneebestand onbruikbaar worden zodra u uw nieuwe, versleutelde, portemonnee begint te gebruiken.</translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>Waarschuwing: De Caps-Lock-toets staat aan!</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>Portemonnee versleuteld</translation>
+ </message>
+ <message>
+ <source>Enter the new passphrase to the wallet.&lt;br/&gt;Please use a passphrase of &lt;b&gt;ten or more random characters&lt;/b&gt;, or &lt;b&gt;eight or more words&lt;/b&gt;.</source>
+ <translation>Voer een nieuw wachtwoord in voor uw portemonnee.&lt;br/&gt;Gebruik een wachtwoord van &lt;b&gt;tien of meer willekeurige karakters&lt;/b&gt;, of &lt;b&gt;acht of meer woorden&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>Enter the old passphrase and new passphrase to the wallet.</source>
+ <translation>Voer het oude en nieuwe wachtwoord in voor uw portemonnee.</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>Portemonneeversleuteling mislukt</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>Portemonneeversleuteling mislukt door een interne fout. Uw portemonnee is niet versleuteld.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>De opgegeven wachtwoorden komen niet overeen</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>Portemonnee openen mislukt</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>Het opgegeven wachtwoord voor de portemonnee-ontsleuteling is niet correct.</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>Portemonnee-ontsleuteling mislukt</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>Portemonneewachtwoord is met succes gewijzigd.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>&amp;Onderteken bericht...</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>Synchroniseren met netwerk...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;Overzicht</translation>
+ </message>
+ <message>
+ <source>Node</source>
+ <translation>Node</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>Toon algemeen overzicht van uw portemonnee</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Transacties</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>Blader door transactieverleden</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>&amp;Afsluiten</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>Programma afsluiten</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>Over &amp;Qt</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>Toon informatie over Qt</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>O&amp;pties...</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>&amp;Versleutel Portemonnee...</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>&amp;Backup Portemonnee...</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>&amp;Wijzig Wachtwoord</translation>
+ </message>
+ <message>
+ <source>&amp;Sending addresses...</source>
+ <translation>V&amp;erstuur adressen...</translation>
+ </message>
+ <message>
+ <source>&amp;Receiving addresses...</source>
+ <translation>O&amp;ntvang adressen...</translation>
+ </message>
+ <message>
+ <source>Open &amp;URI...</source>
+ <translation>Open &amp;URI...</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core client</source>
+ <translation>Bitcoin Kern applicatie</translation>
+ </message>
+ <message>
+ <source>Importing blocks from disk...</source>
+ <translation>Blokken aan het importeren vanaf harde schijf...</translation>
+ </message>
+ <message>
+ <source>Reindexing blocks on disk...</source>
+ <translation>Bezig met herindexeren van blokken op harde schijf...</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>Verstuur munten naar een Bitcoinadres</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>Backup portemonnee naar een andere locatie</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Wijzig het wachtwoord voor uw portemonneversleuteling</translation>
+ </message>
+ <message>
+ <source>&amp;Debug window</source>
+ <translation>&amp;Debugscherm</translation>
+ </message>
+ <message>
+ <source>Open debugging and diagnostic console</source>
+ <translation>Open debugging en diagnostische console</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>&amp;Verifiëer bericht...</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>Portemonnee</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>&amp;Versturen</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>&amp;Ontvangen</translation>
+ </message>
+ <message>
+ <source>Show information about Bitcoin Core</source>
+ <translation>Toon informatie over bitcoin kern</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>&amp;Toon / Verberg</translation>
+ </message>
+ <message>
+ <source>Show or hide the main Window</source>
+ <translation>Toon of verberg het hoofdvenster</translation>
+ </message>
+ <message>
+ <source>Encrypt the private keys that belong to your wallet</source>
+ <translation>Versleutel de geheime sleutels die bij uw portemonnee horen</translation>
+ </message>
+ <message>
+ <source>Sign messages with your Bitcoin addresses to prove you own them</source>
+ <translation>Onderteken berichten met uw Bitcoinadressen om te bewijzen dat u deze adressen bezit</translation>
+ </message>
+ <message>
+ <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source>
+ <translation>Verifiëer handtekeningen om zeker te zijn dat de berichten zijn ondertekend met de gespecificeerde Bitcoinadressen</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;Bestand</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;Instellingen</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>&amp;Hulp</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>Tab-werkbalk</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Kern</translation>
+ </message>
+ <message>
+ <source>Request payments (generates QR codes and bitcoin: URIs)</source>
+ <translation>Vraag betaling aan (genereert QR codes en bitcoin: URIs)</translation>
+ </message>
+ <message>
+ <source>&amp;About Bitcoin Core</source>
+ <translation>&amp;Over Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Modify configuration options for Bitcoin Core</source>
+ <translation>Wijzig configuratieopties voor Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Show the list of used sending addresses and labels</source>
+ <translation>Toon de lijst met gebruikt verzend adressen en labels</translation>
+ </message>
+ <message>
+ <source>Show the list of used receiving addresses and labels</source>
+ <translation>Toon de lijst met gebruikte ontvangst adressen en labels</translation>
+ </message>
+ <message>
+ <source>Open a bitcoin: URI or payment request</source>
+ <translation>Open een bitcoin: URI of betalingsverzoek</translation>
+ </message>
+ <message>
+ <source>&amp;Command-line options</source>
+ <translation>&amp;Commandoregel-opties</translation>
+ </message>
+ <message>
+ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
+ <translation>Toon het Bitcoin Core hulpbericht om een lijst te krijgen met mogelijke Bitcoin commandoregelopties</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n active connection(s) to Bitcoin network</source>
+ <translation><numerusform>%n actieve connectie naar Bitcoin netwerk</numerusform><numerusform>%n actieve connecties naar Bitcoin netwerk</numerusform></translation>
+ </message>
+ <message>
+ <source>No block source available...</source>
+ <translation>Geen bron voor blokken beschikbaar...</translation>
+ </message>
+ <message numerus="yes">
+ <source>Processed %n block(s) of transaction history.</source>
+ <translation><numerusform>%n blok aan transactie geschiedenis verwerkt.</numerusform><numerusform>%n blokken aan transactie geschiedenis verwerkt.</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n hour(s)</source>
+ <translation><numerusform>%n uur</numerusform><numerusform>%n uur</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n day(s)</source>
+ <translation><numerusform>%n dag</numerusform><numerusform>%n dagen</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n week(s)</source>
+ <translation><numerusform>%n week</numerusform><numerusform>%n weken</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 and %2</source>
+ <translation>%1 en %2</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n year(s)</source>
+ <translation><numerusform>%n jaar</numerusform><numerusform>%n jaar</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 behind</source>
+ <translation>%1 achter</translation>
+ </message>
+ <message>
+ <source>Last received block was generated %1 ago.</source>
+ <translation>Laatst ontvangen blok was %1 geleden gegenereerd.</translation>
+ </message>
+ <message>
+ <source>Transactions after this will not yet be visible.</source>
+ <translation>Transacties na dit moment zullen nu nog niet zichtbaar zijn.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Fout</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Waarschuwing</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Informatie</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>Bijgewerkt</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>Aan het bijwerken...</translation>
+ </message>
+ <message>
+ <source>Date: %1
+</source>
+ <translation>Datum: %1
+</translation>
+ </message>
+ <message>
+ <source>Amount: %1
+</source>
+ <translation>Aantal: %1
+</translation>
+ </message>
+ <message>
+ <source>Type: %1
+</source>
+ <translation>Type: %1
+</translation>
+ </message>
+ <message>
+ <source>Label: %1
+</source>
+ <translation>Label: %1
+</translation>
+ </message>
+ <message>
+ <source>Address: %1
+</source>
+ <translation>Adres: %1
+</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>Verzonden transactie</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>Binnenkomende transactie</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>Portemonnee is &lt;b&gt;versleuteld&lt;/b&gt; en momenteel &lt;b&gt;geopend&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>Portemonnee is &lt;b&gt;versleuteld&lt;/b&gt; en momenteel &lt;b&gt;gesloten&lt;/b&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <source>Network Alert</source>
+ <translation>Netwerkwaarschuwing</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Coin Selection</source>
+ <translation>Munt Selectie</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Kwantiteit</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Bytes:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Bedrag:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Prioriteit:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Vergoeding:</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Stof:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Na vergoeding:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Wisselgeld:</translation>
+ </message>
+ <message>
+ <source>(un)select all</source>
+ <translation>(de)selecteer alles</translation>
+ </message>
+ <message>
+ <source>Tree mode</source>
+ <translation>Boom modus</translation>
+ </message>
+ <message>
+ <source>List mode</source>
+ <translation>Lijst modus</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Bedrag</translation>
+ </message>
+ <message>
+ <source>Received with label</source>
+ <translation>Ontvangen met label</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>Ontvangen met adres</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Datum</translation>
+ </message>
+ <message>
+ <source>Confirmations</source>
+ <translation>Bevestigingen</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Bevestigd</translation>
+ </message>
+ <message>
+ <source>Priority</source>
+ <translation>Prioriteit</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Kopieer adres</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Kopieer label</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopieer bedrag</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Kopieer transactie-ID</translation>
+ </message>
+ <message>
+ <source>Lock unspent</source>
+ <translation>Blokeer ongebruikte</translation>
+ </message>
+ <message>
+ <source>Unlock unspent</source>
+ <translation>Deblokkeer ongebruikte</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Kopieer aantal</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Kopieer vergoeding</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Kopieer na vergoeding</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Kopieer bytes</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Kopieer prioriteit</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Kopieër stof</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Kopieer wisselgeld</translation>
+ </message>
+ <message>
+ <source>highest</source>
+ <translation>hoogste</translation>
+ </message>
+ <message>
+ <source>higher</source>
+ <translation>hoger</translation>
+ </message>
+ <message>
+ <source>high</source>
+ <translation>hoog</translation>
+ </message>
+ <message>
+ <source>medium-high</source>
+ <translation>gemiddeld hoog</translation>
+ </message>
+ <message>
+ <source>medium</source>
+ <translation>gemiddeld</translation>
+ </message>
+ <message>
+ <source>low-medium</source>
+ <translation>laag gemiddeld</translation>
+ </message>
+ <message>
+ <source>low</source>
+ <translation>laag</translation>
+ </message>
+ <message>
+ <source>lower</source>
+ <translation>lager</translation>
+ </message>
+ <message>
+ <source>lowest</source>
+ <translation>laagste</translation>
+ </message>
+ <message>
+ <source>(%1 locked)</source>
+ <translation>(%1 geblokeerd)</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>geen</translation>
+ </message>
+ <message>
+ <source>This label turns red if the transaction size is greater than 1000 bytes.</source>
+ <translation>Dit label wordt rood als de transactie groter is dan 1000 bytes.</translation>
+ </message>
+ <message>
+ <source>This label turns red if the priority is smaller than "medium".</source>
+ <translation>Dit label wordt rood als de prioriteit lager is dan "gemiddeld".</translation>
+ </message>
+ <message>
+ <source>This label turns red if any recipient receives an amount smaller than %1.</source>
+ <translation>Dit label wordt rood wanneer een ontvanger minder dan %1 krijgt.</translation>
+ </message>
+ <message>
+ <source>Can vary +/- %1 satoshi(s) per input.</source>
+ <translation>Kan per input +/- %1 satoshi(s) variëren.</translation>
+ </message>
+ <message>
+ <source>yes</source>
+ <translation>ja</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>nee</translation>
+ </message>
+ <message>
+ <source>This means a fee of at least %1 per kB is required.</source>
+ <translation>Dit betekent dat een vergoeding van minimaal %1 per kB nodig is.</translation>
+ </message>
+ <message>
+ <source>Can vary +/- 1 byte per input.</source>
+ <translation>Kan +/- byte per invoer variëren.</translation>
+ </message>
+ <message>
+ <source>Transactions with higher priority are more likely to get included into a block.</source>
+ <translation>Transacties met een hogere prioriteit zullen eerder in een block gezet worden.</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(geen label)</translation>
+ </message>
+ <message>
+ <source>change from %1 (%2)</source>
+ <translation>wijzig van %1 (%2)</translation>
+ </message>
+ <message>
+ <source>(change)</source>
+ <translation>(wijzig)</translation>
+ </message>
+</context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>Bewerk Adres</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>&amp;Label</translation>
+ </message>
+ <message>
+ <source>The label associated with this address list entry</source>
+ <translation>Het label dat bij dit adres item hoort</translation>
+ </message>
+ <message>
+ <source>The address associated with this address list entry. This can only be modified for sending addresses.</source>
+ <translation>Het adres dat bij dit adres item hoort. Dit kan alleen bewerkt worden voor verstuur adressen.</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;Adres</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>Nieuw ontvangstadres</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>Nieuw adres om naar te verzenden</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>Bewerk ontvangstadres</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>Bewerk adres om naar te verzenden</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>Het opgegeven adres "%1" bestaat al in uw adresboek.</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is not a valid Bitcoin address.</source>
+ <translation>Het opgegeven adres "%1" is een ongeldig Bitcoinadres</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>Kon de portemonnee niet openen.</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>Genereren nieuwe sleutel mislukt.</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ <message>
+ <source>A new data directory will be created.</source>
+ <translation>Een nieuwe gegevensmap wordt aangemaakt.</translation>
+ </message>
+ <message>
+ <source>name</source>
+ <translation>naam</translation>
+ </message>
+ <message>
+ <source>Directory already exists. Add %1 if you intend to create a new directory here.</source>
+ <translation>Map bestaat al. Voeg %1 toe als u van plan bent hier een nieuwe map aan te maken.</translation>
+ </message>
+ <message>
+ <source>Path already exists, and is not a directory.</source>
+ <translation>Communicatiepad bestaat al, en is geen folder.</translation>
+ </message>
+ <message>
+ <source>Cannot create data directory here.</source>
+ <translation>Kan hier geen gegevensmap aanmaken.</translation>
+ </message>
+</context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Kern</translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>versie</translation>
+ </message>
+ <message>
+ <source>(%1-bit)</source>
+ <translation>(%1-bit)</translation>
+ </message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>Over Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Command-line options</source>
+ <translation>Commandoregel-opties</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>Gebruik:</translation>
+ </message>
+ <message>
+ <source>command-line options</source>
+ <translation>commandoregel-opties</translation>
+ </message>
+</context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Welcome</source>
+ <translation>Welkom</translation>
+ </message>
+ <message>
+ <source>Welcome to Bitcoin Core.</source>
+ <translation>Welkom bij Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</source>
+ <translation>Omdat dit de eerste keer is dat het programma gestart is, kunt u nu kiezen waar Bitcoin Core de data moet opslaan.</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory.</source>
+ <translation>Bitcoin Core zal een kopie van de Bitcoin blokketen downloaden en opslaan. Tenminste %1 GB aan data wordt opgeslagen in deze map en het zal groeien in de tijd. De portemonnee wordt ook in deze map opgeslagen.</translation>
+ </message>
+ <message>
+ <source>Use the default data directory</source>
+ <translation>Gebruik de standaard gegevensmap</translation>
+ </message>
+ <message>
+ <source>Use a custom data directory:</source>
+ <translation>Gebruik een persoonlijke gegevensmap:</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Kern</translation>
+ </message>
+ <message>
+ <source>Error: Specified data directory "%1" cannot be created.</source>
+ <translation>Fout: De gespecificeerde directory "%1" kan niet worden gecreëerd.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Fout</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n GB of free space available</source>
+ <translation><numerusform>%n GB aan vrije oplsagruimte beschikbaar</numerusform><numerusform>%n GB aan vrije oplsagruimte beschikbaar</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>(of %n GB needed)</source>
+ <translation><numerusform>(van %n GB nodig)</numerusform><numerusform>(van %n GB nodig)</numerusform></translation>
+ </message>
+</context>
+<context>
+ <name>OpenURIDialog</name>
+ <message>
+ <source>Open URI</source>
+ <translation>Open URI</translation>
+ </message>
+ <message>
+ <source>Open payment request from URI or file</source>
+ <translation>Open betalingsverzoek via URI of bestand</translation>
+ </message>
+ <message>
+ <source>URI:</source>
+ <translation>URI:</translation>
+ </message>
+ <message>
+ <source>Select payment request file</source>
+ <translation>Selecteer betalingsverzoek bestand</translation>
+ </message>
+ <message>
+ <source>Select payment request file to open</source>
+ <translation>Selecteer betalingsverzoek bestand om te openen</translation>
+ </message>
+</context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>Opties</translation>
+ </message>
+ <message>
+ <source>&amp;Main</source>
+ <translation>&amp;Algemeen</translation>
+ </message>
+ <message>
+ <source>Size of &amp;database cache</source>
+ <translation>Grootte van de &amp;database cache</translation>
+ </message>
+ <message>
+ <source>MB</source>
+ <translation>MB</translation>
+ </message>
+ <message>
+ <source>Number of script &amp;verification threads</source>
+ <translation>Aantal threads voor &amp;scriptverificatie</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside</source>
+ <translation>Accepteer binnenkomende verbindingen</translation>
+ </message>
+ <message>
+ <source>Allow incoming connections</source>
+ <translation>Sta inkomende verbindingen toe</translation>
+ </message>
+ <message>
+ <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
+ <translation>IP-adres van de proxy (bijv. IPv4: 127.0.0.1 / IPv6: ::1)</translation>
+ </message>
+ <message>
+ <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source>
+ <translation>Minimaliseren in plaats van de applicatie af te sluiten wanneer het venster is afgesloten. Als deze optie is ingeschakeld, zal de toepassing pas worden afgesloten na het selecteren van Exit in het menu.</translation>
+ </message>
+ <message>
+ <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source>
+ <translation>Stel hier de taal van de applicatie in. Deze instelling zal van kracht worden na het herstarten van de applicatie.</translation>
+ </message>
+ <message>
+ <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source>
+ <translation>Derde partijen URL's (bijvoorbeeld block explorer) dat in de transacties tab verschijnen als contextmenu elementen. %s in de URL is vervangen door transactie hash. Verscheidene URL's zijn gescheiden door een verticale streep |. </translation>
+ </message>
+ <message>
+ <source>Third party transaction URLs</source>
+ <translation>Transactie-URLs van derde partijen</translation>
+ </message>
+ <message>
+ <source>Active command-line options that override above options:</source>
+ <translation>Actieve commandoregelopties die bovenstaande opties overschrijven:</translation>
+ </message>
+ <message>
+ <source>Reset all client options to default.</source>
+ <translation>Reset alle clientopties naar de standaardinstellingen.</translation>
+ </message>
+ <message>
+ <source>&amp;Reset Options</source>
+ <translation>&amp;Reset Opties</translation>
+ </message>
+ <message>
+ <source>&amp;Network</source>
+ <translation>&amp;Netwerk</translation>
+ </message>
+ <message>
+ <source>Automatically start Bitcoin Core after logging in to the system.</source>
+ <translation>Bitcoin Kern automatisch starten bij inloggen.</translation>
+ </message>
+ <message>
+ <source>&amp;Start Bitcoin Core on system login</source>
+ <translation>&amp;Start Bitcoin Kern tijdens login.</translation>
+ </message>
+ <message>
+ <source>(0 = auto, &lt;0 = leave that many cores free)</source>
+ <translation>(0 = auto, &lt;0 = laat dit aantal kernen vrij)</translation>
+ </message>
+ <message>
+ <source>W&amp;allet</source>
+ <translation>W&amp;allet</translation>
+ </message>
+ <message>
+ <source>Expert</source>
+ <translation>Expert</translation>
+ </message>
+ <message>
+ <source>Enable coin &amp;control features</source>
+ <translation>Coin &amp;Control activeren</translation>
+ </message>
+ <message>
+ <source>If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.</source>
+ <translation>Indien het uitgeven van onbevestigd wisselgeld uitgeschakeld wordt dan kan het wisselgeld van een transactie niet worden gebruikt totdat de transactie ten minste een bevestiging heeft. Dit heeft ook invloed op de manier waarop uw saldo wordt berekend.</translation>
+ </message>
+ <message>
+ <source>&amp;Spend unconfirmed change</source>
+ <translation>&amp;Spendeer onbevestigd wisselgeld</translation>
+ </message>
+ <message>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>Open de Bitcoin-poort automatisch op de router. Dit werkt alleen als de router UPnP ondersteunt en het aanstaat.</translation>
+ </message>
+ <message>
+ <source>Map port using &amp;UPnP</source>
+ <translation>Portmapping via &amp;UPnP</translation>
+ </message>
+ <message>
+ <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
+ <translation>Verbind met het Bitcoin netwerk via een SOCKS5 proxy.</translation>
+ </message>
+ <message>
+ <source>&amp;Connect through SOCKS5 proxy (default proxy):</source>
+ <translation>&amp;Verbind via een SOCKS5-proxy (standaardproxy):</translation>
+ </message>
+ <message>
+ <source>Proxy &amp;IP:</source>
+ <translation>Proxy &amp;IP:</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>&amp;Poort:</translation>
+ </message>
+ <message>
+ <source>Port of the proxy (e.g. 9050)</source>
+ <translation>Poort van de proxy (bijv. 9050)</translation>
+ </message>
+ <message>
+ <source>&amp;Window</source>
+ <translation>&amp;Scherm</translation>
+ </message>
+ <message>
+ <source>Show only a tray icon after minimizing the window.</source>
+ <translation>Laat alleen een systeemvak-icoon zien wanneer het venster geminimaliseerd is</translation>
+ </message>
+ <message>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>&amp;Minimaliseer naar het systeemvak in plaats van de taakbalk</translation>
+ </message>
+ <message>
+ <source>M&amp;inimize on close</source>
+ <translation>Minimaliseer bij sluiten van het &amp;venster</translation>
+ </message>
+ <message>
+ <source>&amp;Display</source>
+ <translation>&amp;Interface</translation>
+ </message>
+ <message>
+ <source>User Interface &amp;language:</source>
+ <translation>Taal &amp;Gebruikersinterface:</translation>
+ </message>
+ <message>
+ <source>&amp;Unit to show amounts in:</source>
+ <translation>&amp;Eenheid om bedrag in te tonen:</translation>
+ </message>
+ <message>
+ <source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
+ <translation>Kies de standaard onderverdelingseenheid om weer te geven in uw programma, en voor het versturen van munten</translation>
+ </message>
+ <message>
+ <source>Whether to show coin control features or not.</source>
+ <translation>Munt controle functies weergeven of niet.</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>&amp;OK</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>Ann&amp;uleren</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>standaard</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>geen</translation>
+ </message>
+ <message>
+ <source>Confirm options reset</source>
+ <translation>Bevestig reset opties</translation>
+ </message>
+ <message>
+ <source>Client restart required to activate changes.</source>
+ <translation>Herstart van de client is vereist om veranderingen door te voeren.</translation>
+ </message>
+ <message>
+ <source>Client will be shut down. Do you want to proceed?</source>
+ <translation>Applicatie zal worden afgesloten. Wilt u doorgaan?</translation>
+ </message>
+ <message>
+ <source>This change would require a client restart.</source>
+ <translation>Om dit aan te passen moet de client opnieuw gestart worden.</translation>
+ </message>
+ <message>
+ <source>The supplied proxy address is invalid.</source>
+ <translation>Het opgegeven proxyadres is ongeldig.</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>Vorm</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>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.</translation>
+ </message>
+ <message>
+ <source>Watch-only:</source>
+ <translation>Alleen-bekijkbaar:</translation>
+ </message>
+ <message>
+ <source>Available:</source>
+ <translation>Beschikbaar:</translation>
+ </message>
+ <message>
+ <source>Your current spendable balance</source>
+ <translation>Uw beschikbare saldo</translation>
+ </message>
+ <message>
+ <source>Pending:</source>
+ <translation>Afwachtend:</translation>
+ </message>
+ <message>
+ <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source>
+ <translation>De som van de transacties die nog bevestigd moeten worden, en nog niet meetellen in uw beschikbare saldo</translation>
+ </message>
+ <message>
+ <source>Immature:</source>
+ <translation>Immatuur:</translation>
+ </message>
+ <message>
+ <source>Mined balance that has not yet matured</source>
+ <translation>Gedolven saldo dat nog niet tot wasdom is gekomen</translation>
+ </message>
+ <message>
+ <source>Balances</source>
+ <translation>Saldi</translation>
+ </message>
+ <message>
+ <source>Total:</source>
+ <translation>Totaal:</translation>
+ </message>
+ <message>
+ <source>Your current total balance</source>
+ <translation>Uw totale saldo</translation>
+ </message>
+ <message>
+ <source>Your current balance in watch-only addresses</source>
+ <translation>Uw huidige balans in alleen-bekijkbare adressen</translation>
+ </message>
+ <message>
+ <source>Spendable:</source>
+ <translation>Besteedbaar:</translation>
+ </message>
+ <message>
+ <source>Recent transactions</source>
+ <translation>Recente transacties</translation>
+ </message>
+ <message>
+ <source>Unconfirmed transactions to watch-only addresses</source>
+ <translation>Onbevestigde transacties naar alleen-bekijkbare adressen</translation>
+ </message>
+ <message>
+ <source>Mined balance in watch-only addresses that has not yet matured</source>
+ <translation>Ontgonnen saldo dat nog niet tot wasdom is gekomen</translation>
+ </message>
+ <message>
+ <source>Current total balance in watch-only addresses</source>
+ <translation>Huidige balans in alleen-bekijkbare adressen.</translation>
+ </message>
+</context>
+<context>
+ <name>PaymentServer</name>
+ <message>
+ <source>URI handling</source>
+ <translation>URI-behandeling</translation>
+ </message>
+ <message>
+ <source>Invalid payment address %1</source>
+ <translation>Ongeldig betalingsadres %1</translation>
+ </message>
+ <message>
+ <source>Payment request rejected</source>
+ <translation>Betalingsverzoek geweigerd</translation>
+ </message>
+ <message>
+ <source>Payment request network doesn't match client network.</source>
+ <translation>Betalingsaanvraagnetwerk komt niet overeen met klantennetwerk.</translation>
+ </message>
+ <message>
+ <source>Payment request is not initialized.</source>
+ <translation>Betalingsaanvraag is niet geïnitialiseerd.</translation>
+ </message>
+ <message>
+ <source>Requested payment amount of %1 is too small (considered dust).</source>
+ <translation>Het gevraagde betalingsbedrag van %1 is te weinig (beschouwd als stof).</translation>
+ </message>
+ <message>
+ <source>Payment request error</source>
+ <translation>Fout bij betalingsverzoek</translation>
+ </message>
+ <message>
+ <source>Cannot start bitcoin: click-to-pay handler</source>
+ <translation>Kan bitcoin niet starten: click-to-pay handler</translation>
+ </message>
+ <message>
+ <source>Payment request fetch URL is invalid: %1</source>
+ <translation>URL om betalingsverzoek te verkrijgen is ongeldig: %1</translation>
+ </message>
+ <message>
+ <source>URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source>
+ <translation>URI kan niet verwerkt worden! Dit kan het gevolg zijn van een ongeldig Bitcoin adres of misvormde URI parameters.</translation>
+ </message>
+ <message>
+ <source>Payment request file handling</source>
+ <translation>Betalingsverzoek bestandsafhandeling</translation>
+ </message>
+ <message>
+ <source>Payment request file cannot be read! This can be caused by an invalid payment request file.</source>
+ <translation>Betalingsverzoek-bestand kan niet gelezen of verwerkt worden! Dit kan veroorzaakt worden door een ongeldig betalingsverzoek-bestand.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>Betalingsverzoek verlopen.</translation>
+ </message>
+ <message>
+ <source>Unverified payment requests to custom payment scripts are unsupported.</source>
+ <translation>Niet-geverifieerde betalingsverzoeken naar aangepaste betaling scripts worden niet ondersteund.</translation>
+ </message>
+ <message>
+ <source>Invalid payment request.</source>
+ <translation>Ongeldig betalingsverzoek.</translation>
+ </message>
+ <message>
+ <source>Refund from %1</source>
+ <translation>Restitutie van %1</translation>
+ </message>
+ <message>
+ <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source>
+ <translation>Betalingsverzoek %1 is te groot (%2 bytes, toegestaan ​​%3 bytes).</translation>
+ </message>
+ <message>
+ <source>Payment request DoS protection</source>
+ <translation>Betalingsaanvraag DoS bescherming</translation>
+ </message>
+ <message>
+ <source>Error communicating with %1: %2</source>
+ <translation>Fout bij communiceren met %1: %2</translation>
+ </message>
+ <message>
+ <source>Payment request cannot be parsed!</source>
+ <translation>Betalingsverzoek kan niet juist worden ontleed of verwerkt!</translation>
+ </message>
+ <message>
+ <source>Bad response from server %1</source>
+ <translation>Ongeldige respons van server %1</translation>
+ </message>
+ <message>
+ <source>Payment acknowledged</source>
+ <translation>Betaling bevestigd</translation>
+ </message>
+ <message>
+ <source>Network request error</source>
+ <translation>Netwerkfout bij verzoek</translation>
+ </message>
+</context>
+<context>
+ <name>PeerTableModel</name>
+ <message>
+ <source>User Agent</source>
+ <translation>User Agent</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Ping tijd</translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>Bedrag</translation>
+ </message>
+ <message>
+ <source>Enter a Bitcoin address (e.g. %1)</source>
+ <translation>Voer een Bitcoin-adres in (bijv. %1)</translation>
+ </message>
+ <message>
+ <source>%1 d</source>
+ <translation>%1d</translation>
+ </message>
+ <message>
+ <source>%1 h</source>
+ <translation>%1 uur</translation>
+ </message>
+ <message>
+ <source>%1 m</source>
+ <translation>%1 m</translation>
+ </message>
+ <message>
+ <source>%1 s</source>
+ <translation>%1s</translation>
+ </message>
+ <message>
+ <source>None</source>
+ <translation>Geen</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>N.v.t.</translation>
+ </message>
+ <message>
+ <source>%1 ms</source>
+ <translation>%1 ms</translation>
+ </message>
+</context>
+<context>
+ <name>QRImageWidget</name>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Afbeelding opslaan...</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Image</source>
+ <translation>&amp;Afbeelding kopiëren</translation>
+ </message>
+ <message>
+ <source>Save QR Code</source>
+ <translation>Sla QR-code op</translation>
+ </message>
+ <message>
+ <source>PNG Image (*.png)</source>
+ <translation>PNG afbeelding (*.png)</translation>
+ </message>
+</context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>Client name</source>
+ <translation>Clientnaam</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>N.v.t.</translation>
+ </message>
+ <message>
+ <source>Client version</source>
+ <translation>Clientversie</translation>
+ </message>
+ <message>
+ <source>&amp;Information</source>
+ <translation>&amp;Informatie</translation>
+ </message>
+ <message>
+ <source>Debug window</source>
+ <translation>Debug venster</translation>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>Algemeen</translation>
+ </message>
+ <message>
+ <source>Using OpenSSL version</source>
+ <translation>Gebruikt OpenSSL versie</translation>
+ </message>
+ <message>
+ <source>Using BerkeleyDB version</source>
+ <translation>Gebruikt BerkeleyDB versie</translation>
+ </message>
+ <message>
+ <source>Startup time</source>
+ <translation>Opstarttijd</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Netwerk</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>Naam</translation>
+ </message>
+ <message>
+ <source>Number of connections</source>
+ <translation>Aantal connecties</translation>
+ </message>
+ <message>
+ <source>Block chain</source>
+ <translation>Blokketen</translation>
+ </message>
+ <message>
+ <source>Current number of blocks</source>
+ <translation>Huidig aantal blokken</translation>
+ </message>
+ <message>
+ <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source>
+ <translation>Open het Bitcoin Core debug logbestand van de huidige gegevens directory. Dit kan enkele seconden duren voor grote logbestanden.</translation>
+ </message>
+ <message>
+ <source>Received</source>
+ <translation>Ontvangen</translation>
+ </message>
+ <message>
+ <source>Sent</source>
+ <translation>Verstuurd</translation>
+ </message>
+ <message>
+ <source>&amp;Peers</source>
+ <translation>&amp;Peers</translation>
+ </message>
+ <message>
+ <source>Select a peer to view detailed information.</source>
+ <translation>Selecteer een peer om gedetailleerde informatie te bekijken.</translation>
+ </message>
+ <message>
+ <source>Direction</source>
+ <translation>Directie</translation>
+ </message>
+ <message>
+ <source>Version</source>
+ <translation>Versie</translation>
+ </message>
+ <message>
+ <source>User Agent</source>
+ <translation>User Agent</translation>
+ </message>
+ <message>
+ <source>Services</source>
+ <translation>Services</translation>
+ </message>
+ <message>
+ <source>Starting Height</source>
+ <translation>Aanvangshoogte</translation>
+ </message>
+ <message>
+ <source>Sync Height</source>
+ <translation>Synchronisatiehoogte</translation>
+ </message>
+ <message>
+ <source>Ban Score</source>
+ <translation>Ban score</translation>
+ </message>
+ <message>
+ <source>Connection Time</source>
+ <translation>Connectie tijd</translation>
+ </message>
+ <message>
+ <source>Last Send</source>
+ <translation>Laatst verstuurd</translation>
+ </message>
+ <message>
+ <source>Last Receive</source>
+ <translation>Laatst ontvangen</translation>
+ </message>
+ <message>
+ <source>Bytes Sent</source>
+ <translation>Bytes Verzonden</translation>
+ </message>
+ <message>
+ <source>Bytes Received</source>
+ <translation>Bytes Ontvangen</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Ping Tijd</translation>
+ </message>
+ <message>
+ <source>Last block time</source>
+ <translation>Tijd laatste blok</translation>
+ </message>
+ <message>
+ <source>&amp;Open</source>
+ <translation>&amp;Open</translation>
+ </message>
+ <message>
+ <source>&amp;Console</source>
+ <translation>&amp;Console</translation>
+ </message>
+ <message>
+ <source>&amp;Network Traffic</source>
+ <translation>&amp;Netwerkverkeer</translation>
+ </message>
+ <message>
+ <source>&amp;Clear</source>
+ <translation>&amp;Wissen</translation>
+ </message>
+ <message>
+ <source>Totals</source>
+ <translation>Totalen</translation>
+ </message>
+ <message>
+ <source>In:</source>
+ <translation>In;</translation>
+ </message>
+ <message>
+ <source>Out:</source>
+ <translation>Uit:</translation>
+ </message>
+ <message>
+ <source>Build date</source>
+ <translation>Bouwdatum</translation>
+ </message>
+ <message>
+ <source>Debug log file</source>
+ <translation>Debug-logbestand</translation>
+ </message>
+ <message>
+ <source>Clear console</source>
+ <translation>Maak console leeg</translation>
+ </message>
+ <message>
+ <source>Welcome to the Bitcoin Core RPC console.</source>
+ <translation>Welkom op de Bitcoin Core RPC console.</translation>
+ </message>
+ <message>
+ <source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
+ <translation>Gebruik de pijltjestoetsen om door de geschiedenis te navigeren, en &lt;b&gt;Ctrl-L&lt;/b&gt; om het scherm leeg te maken.</translation>
+ </message>
+ <message>
+ <source>Type &lt;b&gt;help&lt;/b&gt; for an overview of available commands.</source>
+ <translation>Typ &lt;b&gt;help&lt;/b&gt; voor een overzicht van de beschikbare commando's.</translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation>%1 B</translation>
+ </message>
+ <message>
+ <source>%1 KB</source>
+ <translation>%1 Kb</translation>
+ </message>
+ <message>
+ <source>%1 MB</source>
+ <translation>%1 MB</translation>
+ </message>
+ <message>
+ <source>%1 GB</source>
+ <translation>%1 Gb</translation>
+ </message>
+ <message>
+ <source>via %1</source>
+ <translation>via %1</translation>
+ </message>
+ <message>
+ <source>never</source>
+ <translation>nooit</translation>
+ </message>
+ <message>
+ <source>Inbound</source>
+ <translation>Inkomend</translation>
+ </message>
+ <message>
+ <source>Outbound</source>
+ <translation>Uitgaand</translation>
+ </message>
+ <message>
+ <source>Unknown</source>
+ <translation>Onbekend</translation>
+ </message>
+ <message>
+ <source>Fetching...</source>
+ <translation>Ophalen...</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Amount:</source>
+ <translation>&amp;Bedrag</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Label:</translation>
+ </message>
+ <message>
+ <source>&amp;Message:</source>
+ <translation>&amp;Bericht</translation>
+ </message>
+ <message>
+ <source>Reuse one of the previously used receiving addresses. Reusing addresses has security and privacy issues. Do not use this unless re-generating a payment request made before.</source>
+ <translation>Gebruik een van de eerder gebruikte ontvangstadressen opnieuw. Het opnieuw gebruiken van adressen heeft beveiliging- en privacy problemen. Gebruik dit niet, behalve als er eerder een betalingsverzoek opnieuw gegenereerd is.</translation>
+ </message>
+ <message>
+ <source>R&amp;euse an existing receiving address (not recommended)</source>
+ <translation>H&amp;ergebruik en bestaand ontvangstadres (niet aanbevolen)</translation>
+ </message>
+ <message>
+ <source>An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network.</source>
+ <translation>Een optioneel bericht om bij te voegen aan het betalingsverzoek, dewelke zal getoond worden wanneer het verzoek is geopend. Opermerking: Het bericht zal niet worden verzonden met de betaling over het Bitcoin netwerk.</translation>
+ </message>
+ <message>
+ <source>An optional label to associate with the new receiving address.</source>
+ <translation>Een optioneel label om te associëren met het nieuwe ontvangende adres</translation>
+ </message>
+ <message>
+ <source>Use this form to request payments. All fields are &lt;b&gt;optional&lt;/b&gt;.</source>
+ <translation>Gebruik dit formulier om te verzoeken tot betaling. Alle velden zijn &lt;b&gt;optioneel&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>An optional amount to request. Leave this empty or zero to not request a specific amount.</source>
+ <translation>Een optioneel te verzoeken bedrag. Laat dit leeg, of nul, om geen specifiek bedrag aan te vragen.</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Wis alle velden op het formulier.</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation>Wissen</translation>
+ </message>
+ <message>
+ <source>Requested payments history</source>
+ <translation>Geschiedenis van de betalingsverzoeken</translation>
+ </message>
+ <message>
+ <source>&amp;Request payment</source>
+ <translation>&amp;Betalingsverzoek</translation>
+ </message>
+ <message>
+ <source>Show the selected request (does the same as double clicking an entry)</source>
+ <translation>Toon het geselecteerde verzoek (doet hetzelfde als dubbelklikken)</translation>
+ </message>
+ <message>
+ <source>Show</source>
+ <translation>Toon</translation>
+ </message>
+ <message>
+ <source>Remove the selected entries from the list</source>
+ <translation>Verwijder de geselecteerde items van de lijst</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>Verwijder</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Kopieer label</translation>
+ </message>
+ <message>
+ <source>Copy message</source>
+ <translation>Kopieer bericht</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopieer bedrag</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>QR Code</source>
+ <translation>QR-code</translation>
+ </message>
+ <message>
+ <source>Copy &amp;URI</source>
+ <translation>Kopieer &amp;URI</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Address</source>
+ <translation>Kopieer &amp;adres</translation>
+ </message>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Sla afbeelding op...</translation>
+ </message>
+ <message>
+ <source>Request payment to %1</source>
+ <translation>Betalingsverzoek tot %1</translation>
+ </message>
+ <message>
+ <source>Payment information</source>
+ <translation>Betalingsinformatie</translation>
+ </message>
+ <message>
+ <source>URI</source>
+ <translation>URI</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adres</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Bedrag</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Label</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Bericht</translation>
+ </message>
+ <message>
+ <source>Resulting URI too long, try to reduce the text for label / message.</source>
+ <translation>Resulterende URI te lang, probeer de tekst korter te maken voor het label/bericht.</translation>
+ </message>
+ <message>
+ <source>Error encoding URI into QR Code.</source>
+ <translation>Fout tijdens encoderen URI in QR-code</translation>
+ </message>
+</context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Datum</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Label</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Bericht</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Bedrag</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(geen label)</translation>
+ </message>
+ <message>
+ <source>(no message)</source>
+ <translation>(geen bericht)</translation>
+ </message>
+ <message>
+ <source>(no amount)</source>
+ <translation>(geen bedrag)</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Verstuur munten</translation>
+ </message>
+ <message>
+ <source>Coin Control Features</source>
+ <translation>Coin controle opties</translation>
+ </message>
+ <message>
+ <source>Inputs...</source>
+ <translation>Invoer...</translation>
+ </message>
+ <message>
+ <source>automatically selected</source>
+ <translation>automatisch geselecteerd</translation>
+ </message>
+ <message>
+ <source>Insufficient funds!</source>
+ <translation>Onvoldoende fonds!</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Kwantiteit</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Bytes:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Bedrag:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Prioriteit:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Vergoeding:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Na vergoeding:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Wisselgeld:</translation>
+ </message>
+ <message>
+ <source>If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address.</source>
+ <translation>Als dit is geactiveerd, maar het wisselgeldadres is leeg of ongeldig, dan wordt het wisselgeld verzonden naar een nieuw gegenereerd adres.</translation>
+ </message>
+ <message>
+ <source>Custom change address</source>
+ <translation>Aangepast wisselgeldadres</translation>
+ </message>
+ <message>
+ <source>Transaction Fee:</source>
+ <translation>Transactiekosten:</translation>
+ </message>
+ <message>
+ <source>Choose...</source>
+ <translation>Kies...</translation>
+ </message>
+ <message>
+ <source>collapse fee-settings</source>
+ <translation>Transactiekosteninstellingen verbergen</translation>
+ </message>
+ <message>
+ <source>per kilobyte</source>
+ <translation>per kilobyte</translation>
+ </message>
+ <message>
+ <source>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "total at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source>
+ <translation>Als de aangepaste toeslag is ingesteld op 1000 satoshis en de transactie is maar 250 bytes, dan wordt bij "per kilobyte" 250 satoshis aan toeslag berekend, terwijl er bij "totaal tenminste" 1000 satoshis worden berekend. Voor transacties die groter zijn dan een kilobyte, wordt in beide gevallen per kilobyte de toeslag berekend.</translation>
+ </message>
+ <message>
+ <source>Hide</source>
+ <translation>Verbergen</translation>
+ </message>
+ <message>
+ <source>total at least</source>
+ <translation>totaal ten minste</translation>
+ </message>
+ <message>
+ <source>Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process.</source>
+ <translation>De minimale toeslag betalen is prima mits het transactievolume kleiner is dan de ruimte in de blokken. Let wel op dat dit tot gevolg kan hebben dat een transactie nooit wordt bevestigd als er meer vraag is naar bitcointransacties dan het netwerk kan verwerken.</translation>
+ </message>
+ <message>
+ <source>(read the tooltip)</source>
+ <translation>(lees de tooltip)</translation>
+ </message>
+ <message>
+ <source>Recommended:</source>
+ <translation>Aanbevolen:</translation>
+ </message>
+ <message>
+ <source>Custom:</source>
+ <translation>Handmatig:</translation>
+ </message>
+ <message>
+ <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source>
+ <translation>(Slimme vergoeding is nog niet geïnitialiseerd. Dit duurt meestal een paar blokken...)</translation>
+ </message>
+ <message>
+ <source>Confirmation time:</source>
+ <translation>Bevestigings tijd:</translation>
+ </message>
+ <message>
+ <source>normal</source>
+ <translation>normaal</translation>
+ </message>
+ <message>
+ <source>fast</source>
+ <translation>snel</translation>
+ </message>
+ <message>
+ <source>Send as zero-fee transaction if possible</source>
+ <translation>Verstuur als transactie zonder verzendkosten indien mogelijk</translation>
+ </message>
+ <message>
+ <source>(confirmation may take longer)</source>
+ <translation>(bevestiging kan langer duren)</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>Verstuur aan verschillende ontvangers ineens</translation>
+ </message>
+ <message>
+ <source>Add &amp;Recipient</source>
+ <translation>Voeg &amp;Ontvanger Toe</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Wis alle velden van het formulier.</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Stof:</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Verwijder &amp;Alles</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>Saldo:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>Bevestig de verstuuractie</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>&amp;Verstuur</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>Bevestig versturen munten</translation>
+ </message>
+ <message>
+ <source>%1 to %2</source>
+ <translation>%1 tot %2</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Kopieer aantal</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopieer bedrag</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Kopieer vergoeding</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Kopieer na vergoeding</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Kopieer bytes</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Kopieer prioriteit</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Kopieer wijziging</translation>
+ </message>
+ <message>
+ <source>or</source>
+ <translation>of</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>Het ingevoerde bedrag moet groter zijn dan 0.</translation>
+ </message>
+ <message>
+ <source>The amount exceeds your balance.</source>
+ <translation>Bedrag is hoger dan uw huidige saldo</translation>
+ </message>
+ <message>
+ <source>The total exceeds your balance when the %1 transaction fee is included.</source>
+ <translation>Totaal overschrijdt uw huidige saldo wanneer de %1 transactiekosten worden meegerekend</translation>
+ </message>
+ <message>
+ <source>Transaction creation failed!</source>
+ <translation>Transactie creatie niet gelukt!</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>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.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>Betalingsverzoek verlopen.</translation>
+ </message>
+ <message>
+ <source>Pay only the minimum fee of %1</source>
+ <translation>Betaal alleen de minimale transactiekosten van %1</translation>
+ </message>
+ <message>
+ <source>The recipient address is not valid. Please recheck.</source>
+ <translation>Het adres van de ontvanger is niet geldig. Gelieve opnieuw te controleren..</translation>
+ </message>
+ <message>
+ <source>Duplicate address found: addresses should only be used once each.</source>
+ <translation>Dubbel adres gevonden: adressen mogen maar één keer worden gebruikt worden.</translation>
+ </message>
+ <message>
+ <source>Warning: Invalid Bitcoin address</source>
+ <translation>Waarschuwing: Ongeldig Bitcoin adres</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(geen label)</translation>
+ </message>
+ <message>
+ <source>Warning: Unknown change address</source>
+ <translation>Waarschuwing: Onbekend wisselgeldadres</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Kopieër stof</translation>
+ </message>
+ <message>
+ <source>Are you sure you want to send?</source>
+ <translation>Weet u zeker dat u wilt verzenden?</translation>
+ </message>
+ <message>
+ <source>added as transaction fee</source>
+ <translation>toegevoegd als transactiekosten</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>Bedra&amp;g:</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>Betaal &amp;Aan:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Vul een label in voor dit adres om het toe te voegen aan uw adresboek</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Label:</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Kies een eerder gebruikt adres</translation>
+ </message>
+ <message>
+ <source>This is a normal payment.</source>
+ <translation>Dit is een normale betaling.</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to send the payment to</source>
+ <translation>Het Bitcoin adres om betaling aan te voldoen</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Plak adres vanuit klembord</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Remove this entry</source>
+ <translation>Verwijder deze toevoeging</translation>
+ </message>
+ <message>
+ <source>Message:</source>
+ <translation>Bericht:</translation>
+ </message>
+ <message>
+ <source>This is an unauthenticated payment request.</source>
+ <translation>Dit is een niet-geverifieerd betalingsverzoek.</translation>
+ </message>
+ <message>
+ <source>This is an authenticated payment request.</source>
+ <translation>Dit is een geverifieerd betalingsverzoek.</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to the list of used addresses</source>
+ <translation>Vul een label voor dit adres in om het aan de lijst met gebruikte adressen toe te voegen</translation>
+ </message>
+ <message>
+ <source>A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network.</source>
+ <translation>Een bericht dat werd toegevoegd aan de bitcoin: URI dewelke wordt opgeslagen met de transactie ter referentie. Opmerking: Dit bericht zal niet worden verzonden over het Bitcoin netwerk.</translation>
+ </message>
+ <message>
+ <source>Pay To:</source>
+ <translation>Betaal Aan:</translation>
+ </message>
+ <message>
+ <source>Memo:</source>
+ <translation>Memo:</translation>
+ </message>
+</context>
+<context>
+ <name>ShutdownWindow</name>
+ <message>
+ <source>Bitcoin Core is shutting down...</source>
+ <translation>Bitcoin Core is aan het afsluiten...</translation>
+ </message>
+ <message>
+ <source>Do not shut down the computer until this window disappears.</source>
+ <translation>Sluit de computer niet af totdat dit venster verdwenen is.</translation>
+ </message>
+</context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Signatures - Sign / Verify a Message</source>
+ <translation>Handtekeningen - Onderteken een bericht / Verifiëer een handtekening</translation>
+ </message>
+ <message>
+ <source>&amp;Sign Message</source>
+ <translation>O&amp;nderteken Bericht</translation>
+ </message>
+ <message>
+ <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source>
+ <translation>U kunt berichten/overeenkomsten ondertekenen met uw adres om te bewijzen dat u Bitcoins kunt versturen. Wees voorzichtig met het ondertekenen van iets vaags of willekeurigs, omdat phishing-aanvallen u kunnen proberen te misleiden tot het ondertekenen van overeenkomsten om uw identiteit aan hen toe te vertrouwen. Onderteken alleen volledig gedetailleerde verklaringen voordat u akkoord gaat.</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to sign the message with</source>
+ <translation>Het Bitcoin adres om bericht mee te ondertekenen</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Kies een eerder gebruikt adres</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Plak adres vanuit klembord</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Enter the message you want to sign here</source>
+ <translation>Typ hier het bericht dat u wilt ondertekenen</translation>
+ </message>
+ <message>
+ <source>Signature</source>
+ <translation>Handtekening</translation>
+ </message>
+ <message>
+ <source>Copy the current signature to the system clipboard</source>
+ <translation>Kopieer de huidige handtekening naar het systeemklembord</translation>
+ </message>
+ <message>
+ <source>Sign the message to prove you own this Bitcoin address</source>
+ <translation>Onderteken een bericht om te bewijzen dat u een bepaald Bitcoinadres bezit</translation>
+ </message>
+ <message>
+ <source>Sign &amp;Message</source>
+ <translation>Onderteken &amp;Bericht</translation>
+ </message>
+ <message>
+ <source>Reset all sign message fields</source>
+ <translation>Verwijder alles in de invulvelden</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Verwijder &amp;Alles</translation>
+ </message>
+ <message>
+ <source>&amp;Verify Message</source>
+ <translation>&amp;Verifiëer Bericht</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address the message was signed with</source>
+ <translation>Het Bitcoin adres waarmee het bericht ondertekend is</translation>
+ </message>
+ <message>
+ <source>Verify the message to ensure it was signed with the specified Bitcoin address</source>
+ <translation>Controleer een bericht om te verifiëren dat het gespecificeerde Bitcoinadres het bericht heeft ondertekend.</translation>
+ </message>
+ <message>
+ <source>Verify &amp;Message</source>
+ <translation>Verifiëer &amp;Bericht</translation>
+ </message>
+ <message>
+ <source>Reset all verify message fields</source>
+ <translation>Verwijder alles in de invulvelden</translation>
+ </message>
+ <message>
+ <source>Click "Sign Message" to generate signature</source>
+ <translation>Klik "Onderteken Bericht" om de handtekening te genereren</translation>
+ </message>
+ <message>
+ <source>The entered address is invalid.</source>
+ <translation>Het opgegeven adres is ongeldig.</translation>
+ </message>
+ <message>
+ <source>Please check the address and try again.</source>
+ <translation>Controleer s.v.p. het adres en probeer het opnieuw.</translation>
+ </message>
+ <message>
+ <source>The entered address does not refer to a key.</source>
+ <translation>Het opgegeven adres verwijst niet naar een sleutel.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock was cancelled.</source>
+ <translation>Portemonnee-ontsleuteling is geannuleerd</translation>
+ </message>
+ <message>
+ <source>Private key for the entered address is not available.</source>
+ <translation>Geheime sleutel voor het ingevoerde adres is niet beschikbaar.</translation>
+ </message>
+ <message>
+ <source>Message signing failed.</source>
+ <translation>Ondertekenen van het bericht is mislukt.</translation>
+ </message>
+ <message>
+ <source>Message signed.</source>
+ <translation>Bericht ondertekend.</translation>
+ </message>
+ <message>
+ <source>The signature could not be decoded.</source>
+ <translation>De handtekening kon niet worden gedecodeerd.</translation>
+ </message>
+ <message>
+ <source>Please check the signature and try again.</source>
+ <translation>Controleer s.v.p. de handtekening en probeer het opnieuw.</translation>
+ </message>
+ <message>
+ <source>The signature did not match the message digest.</source>
+ <translation>De handtekening hoort niet bij het bericht.</translation>
+ </message>
+ <message>
+ <source>Message verification failed.</source>
+ <translation>Berichtverificatie mislukt.</translation>
+ </message>
+ <message>
+ <source>Message verified.</source>
+ <translation>Bericht correct geverifiëerd.</translation>
+ </message>
+</context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Kern</translation>
+ </message>
+ <message>
+ <source>The Bitcoin Core developers</source>
+ <translation>De Bitcoin Core ontwikkelaars</translation>
+ </message>
+ <message>
+ <source>[testnet]</source>
+ <translation>[testnetwerk]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ <message>
+ <source>KB/s</source>
+ <translation>KB/s</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>Openen totdat %1</translation>
+ </message>
+ <message>
+ <source>conflicted</source>
+ <translation>conflicterend</translation>
+ </message>
+ <message>
+ <source>%1/offline</source>
+ <translation>%1/offline</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/onbevestigd</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 bevestigingen</translation>
+ </message>
+ <message>
+ <source>Status</source>
+ <translation>Status</translation>
+ </message>
+ <message numerus="yes">
+ <source>, broadcast through %n node(s)</source>
+ <translation><numerusform>, uitgezonden naar %n node</numerusform><numerusform>, uitgezonden naar %n nodes</numerusform></translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Datum</translation>
+ </message>
+ <message>
+ <source>Source</source>
+ <translation>Bron</translation>
+ </message>
+ <message>
+ <source>Generated</source>
+ <translation>Gegenereerd</translation>
+ </message>
+ <message>
+ <source>From</source>
+ <translation>Van</translation>
+ </message>
+ <message>
+ <source>To</source>
+ <translation>Aan</translation>
+ </message>
+ <message>
+ <source>own address</source>
+ <translation>eigen adres</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>alleen-bekijkbaar</translation>
+ </message>
+ <message>
+ <source>label</source>
+ <translation>label</translation>
+ </message>
+ <message>
+ <source>Credit</source>
+ <translation>Credit</translation>
+ </message>
+ <message numerus="yes">
+ <source>matures in %n more block(s)</source>
+ <translation><numerusform>komt tot wasdom na %n nieuw blok</numerusform><numerusform>komt tot wasdom na %n nieuwe blokken</numerusform></translation>
+ </message>
+ <message>
+ <source>not accepted</source>
+ <translation>niet geaccepteerd</translation>
+ </message>
+ <message>
+ <source>Debit</source>
+ <translation>Debet</translation>
+ </message>
+ <message>
+ <source>Total debit</source>
+ <translation>Totaal debit</translation>
+ </message>
+ <message>
+ <source>Total credit</source>
+ <translation>Totaal credit</translation>
+ </message>
+ <message>
+ <source>Transaction fee</source>
+ <translation>Transactiekosten</translation>
+ </message>
+ <message>
+ <source>Net amount</source>
+ <translation>Netto bedrag</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Bericht</translation>
+ </message>
+ <message>
+ <source>Comment</source>
+ <translation>Opmerking</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>Transactie-ID:</translation>
+ </message>
+ <message>
+ <source>Merchant</source>
+ <translation>Handelaar</translation>
+ </message>
+ <message>
+ <source>Generated coins must mature %1 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.</source>
+ <translation>Gegenereerde munten moeten %1 blokken rijpen voordat ze kunnen worden besteed. Toen dit blok gegenereerd werd, werd het uitgezonden naar het netwerk om aan de blokketen toegevoegd te worden. Als het niet lukt om in de keten toegevoegd te worden, zal de status te veranderen naar "niet geaccepteerd" en het zal deze niet besteedbaar zijn. Dit kan soms gebeuren als een ander knooppunt een blok genereert binnen een paar seconden na die van u.</translation>
+ </message>
+ <message>
+ <source>Debug information</source>
+ <translation>Debug-informatie</translation>
+ </message>
+ <message>
+ <source>Transaction</source>
+ <translation>Transactie</translation>
+ </message>
+ <message>
+ <source>Inputs</source>
+ <translation>Inputs</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Bedrag</translation>
+ </message>
+ <message>
+ <source>true</source>
+ <translation>waar</translation>
+ </message>
+ <message>
+ <source>false</source>
+ <translation>onwaar</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, is nog niet met succes uitgezonden</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Open voor nog %n blok</numerusform><numerusform>Open voor nog %n blokken</numerusform></translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>onbekend</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>Transactiedetails</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>Dit venster laat een uitgebreide beschrijving van de transactie zien</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Datum</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Type</translation>
+ </message>
+ <message>
+ <source>Immature (%1 confirmations, will be available after %2)</source>
+ <translation>immatuur (%1 bevestigingen, zal beschikbaar zijn na %2)</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Open voor nog %n blok</numerusform><numerusform>Open voor nog %n blokken</numerusform></translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>Open tot %1</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>Bevestigd (%1 bevestigingen)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>Dit blok is niet ontvangen bij andere nodes en zal waarschijnlijk niet worden geaccepteerd!</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>Gegenereerd maar niet geaccepteerd</translation>
+ </message>
+ <message>
+ <source>Offline</source>
+ <translation>Niet verbonden</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Label</translation>
+ </message>
+ <message>
+ <source>Unconfirmed</source>
+ <translation>Onbevestigd</translation>
+ </message>
+ <message>
+ <source>Confirming (%1 of %2 recommended confirmations)</source>
+ <translation>Bevestigen (%1 van %2 aanbevolen bevestigingen)</translation>
+ </message>
+ <message>
+ <source>Conflicted</source>
+ <translation>Conflicterend</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Ontvangen met</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>Ontvangen van</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Verzonden aan</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>Betaling aan uzelf</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Gedolven</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>alleen-bekijkbaar</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(nvt)</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>Transactiestatus. Houd de muiscursor boven dit veld om het aantal bevestigingen te laten zien.</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Datum en tijd waarop deze transactie is ontvangen.</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>Type transactie.</translation>
+ </message>
+ <message>
+ <source>Whether or not a watch-only address is involved in this transaction.</source>
+ <translation>Of er een alleen-bekijken adres is betrokken bij deze transactie.</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>Bedrag verwijderd van of toegevoegd aan saldo</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>Alles</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>Vandaag</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>Deze week</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>Deze maand</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>Vorige maand</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>Dit jaar</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>Bereik...</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Ontvangen met</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Verzonden aan</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>Aan uzelf</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Gedolven</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>Anders</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>Vul adres of label in om te zoeken</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>Min. bedrag</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Kopieer adres</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Kopieer label</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopieer bedrag</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Kopieer transactie-ID</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>Bewerk label</translation>
+ </message>
+ <message>
+ <source>Show transaction details</source>
+ <translation>Toon transactiedetails</translation>
+ </message>
+ <message>
+ <source>Export Transaction History</source>
+ <translation>Exporteer Transactieverleden</translation>
+ </message>
+ <message>
+ <source>Watch-only</source>
+ <translation>Alleen-bekijkbaar</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Export Mislukt</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the transaction history to %1.</source>
+ <translation>Er is een fout opgetreden bij het opslaan van het transactieverleden naar %1.</translation>
+ </message>
+ <message>
+ <source>Exporting Successful</source>
+ <translation>Export Succesvol</translation>
+ </message>
+ <message>
+ <source>The transaction history was successfully saved to %1.</source>
+ <translation>Het transactieverleden was succesvol bewaard in %1.</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Kommagescheiden bestand (*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Bevestigd</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Datum</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Type</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Label</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adres</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>Bereik:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>naar</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ <message>
+ <source>Unit to show amounts in. Click to select another unit.</source>
+ <translation>Eenheid om bedragen uit te drukken. Klik om een andere eenheid te selecteren.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletFrame</name>
+ <message>
+ <source>No wallet has been loaded.</source>
+ <translation>Portemonnee werd niet geladen.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Verstuur munten</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Exporteer</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Exporteer de data in de huidige tab naar een bestand</translation>
+ </message>
+ <message>
+ <source>Backup Wallet</source>
+ <translation>Portemonnee backuppen</translation>
+ </message>
+ <message>
+ <source>Wallet Data (*.dat)</source>
+ <translation>Portemonnee-data (*.dat)</translation>
+ </message>
+ <message>
+ <source>Backup Failed</source>
+ <translation>Backup Mislukt</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the wallet data to %1.</source>
+ <translation>Er is een fout opgetreden bij het wegschrijven van de portemonnee-data naar %1.</translation>
+ </message>
+ <message>
+ <source>The wallet data was successfully saved to %1.</source>
+ <translation>De portemonneedata is succesvol opgeslagen in %1.</translation>
+ </message>
+ <message>
+ <source>Backup Successful</source>
+ <translation>Backup Succesvol</translation>
+ </message>
+</context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>Opties:</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>Stel datamap in</translation>
+ </message>
+ <message>
+ <source>Connect to a node to retrieve peer addresses, and disconnect</source>
+ <translation>Verbind naar een node om adressen van anderen op te halen, en verbreek vervolgens de verbinding</translation>
+ </message>
+ <message>
+ <source>Specify your own public address</source>
+ <translation>Specificeer uw eigen publieke adres</translation>
+ </message>
+ <message>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>Aanvaard commandoregel- en JSON-RPC-commando's</translation>
+ </message>
+ <message>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>Draai in de achtergrond als daemon en aanvaard commando's</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>Gebruik het testnetwerk</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
+ <translation>Accepteer verbindingen van buitenaf (standaard: 1 als geen -proxy of -connect is opgegeven)</translation>
+ </message>
+ <message>
+ <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
+ <translation>Bind aan opgegeven adres en luister er altijd op. Gebruik [host]:port notatie voor IPv6</translation>
+ </message>
+ <message>
+ <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
+ <translation>Verwijder alle transacties van de portemonnee en herstel alleen de delen van de blockchain door -rescan tijdens het opstarten</translation>
+ </message>
+ <message>
+ <source>Distributed under the MIT software license, see the accompanying file COPYING or &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</source>
+ <translation>Uitgegeven onder de MIT software licentie, zie het bijgevoegde bestand COPYING of &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</translation>
+ </message>
+ <message>
+ <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
+ <translation>Voer opdracht uit zodra een portemonneetransactie verandert (%s in cmd wordt vervangen door TxID)</translation>
+ </message>
+ <message>
+ <source>Set the number of script verification threads (%u to %d, 0 = auto, &lt;0 = leave that many cores free, default: %d)</source>
+ <translation>Kies het aantal script verificatie processen (%u tot %d, 0 = auto, &lt;0 = laat dit aantal kernen vrij, standaard: %d)</translation>
+ </message>
+ <message>
+ <source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source>
+ <translation>Dit is een pre-release testversie - gebruik op eigen risico! Gebruik deze niet voor het delven van munten of handelsdoeleinden</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer. Bitcoin Core is probably already running.</source>
+ <translation>Niet in staat om %s te verbinden op deze computer. Bitcoin Core draait waarschijnlijk al.</translation>
+ </message>
+ <message>
+ <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>WAARSCHUWING: controleer uw netwerkverbinding, %d blokken ontvangen in de laatste %d uren (%d verwacht)</translation>
+ </message>
+ <message>
+ <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>Waarschuwing: -paytxfee is zeer hoog ingesteld. Dit zijn de transactiekosten die u betaalt bij het versturen van een transactie.</translation>
+ </message>
+ <message>
+ <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source>
+ <translation>Waarschuwing: Het lijkt erop dat het netwerk geen consensus kan vinden! Sommige delvers lijken problemen te ondervinden.</translation>
+ </message>
+ <message>
+ <source>Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.</source>
+ <translation>Waarschuwing: Het lijkt erop dat we geen consensus kunnen vinden met onze peers! Mogelijk dient u te upgraden, of andere nodes moeten wellicht upgraden.</translation>
+ </message>
+ <message>
+ <source>Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
+ <translation>Waarschuwing: Fout bij het lezen van wallet.dat! Alle sleutels zijn in goede orde uitgelezen, maar transactiedata of adresboeklemma's zouden kunnen ontbreken of fouten bevatten.</translation>
+ </message>
+ <message>
+ <source>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</source>
+ <translation>Waarschuwing: wallet.dat is corrupt, data is veiliggesteld! Originele wallet.dat is opgeslagen als wallet.{tijdstip}.bak in %s; als uw balans of transacties incorrect zijn dient u een backup terug te zetten.</translation>
+ </message>
+ <message>
+ <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source>
+ <translation>Goedgekeurde peers die verbinden van het ingegeven netmask of IP adres. Kan meerdere keren gespecificeerd worden.</translation>
+ </message>
+ <message>
+ <source>(default: 1)</source>
+ <translation>(standaard: 1)</translation>
+ </message>
+ <message>
+ <source>&lt;category&gt; can be:</source>
+ <translation>&lt;category&gt; kan zijn:</translation>
+ </message>
+ <message>
+ <source>Attempt to recover private keys from a corrupt wallet.dat</source>
+ <translation>Poog de geheime sleutels uit een corrupt wallet.dat bestand terug te halen</translation>
+ </message>
+ <message>
+ <source>Block creation options:</source>
+ <translation>Blokcreatie-opties:</translation>
+ </message>
+ <message>
+ <source>Connect only to the specified node(s)</source>
+ <translation>Verbind alleen naar de gespecificeerde node(s)</translation>
+ </message>
+ <message>
+ <source>Connection options:</source>
+ <translation>Verbindingsopties:</translation>
+ </message>
+ <message>
+ <source>Corrupted block database detected</source>
+ <translation>Corrupte blokkendatabase gedetecteerd</translation>
+ </message>
+ <message>
+ <source>Debugging/Testing options:</source>
+ <translation>Foutopsporing/Testopties:</translation>
+ </message>
+ <message>
+ <source>Do not load the wallet and disable wallet RPC calls</source>
+ <translation>Laad de wallet niet en schakel wallet RPC oproepen uit</translation>
+ </message>
+ <message>
+ <source>Do you want to rebuild the block database now?</source>
+ <translation>Wilt u de blokkendatabase nu herbouwen?</translation>
+ </message>
+ <message>
+ <source>Error initializing block database</source>
+ <translation>Fout bij intialisatie blokkendatabase</translation>
+ </message>
+ <message>
+ <source>Error initializing wallet database environment %s!</source>
+ <translation>Probleem met initializeren van de database-omgeving %s!</translation>
+ </message>
+ <message>
+ <source>Error loading block database</source>
+ <translation>Fout bij het laden van blokkendatabase</translation>
+ </message>
+ <message>
+ <source>Error opening block database</source>
+ <translation>Fout bij openen blokkendatabase</translation>
+ </message>
+ <message>
+ <source>Error: Disk space is low!</source>
+ <translation>Fout: Weinig vrije diskruimte!</translation>
+ </message>
+ <message>
+ <source>Failed to listen on any port. Use -listen=0 if you want this.</source>
+ <translation>Mislukt om op welke poort dan ook te luisteren. Gebruik -listen=0 as u dit wilt.</translation>
+ </message>
+ <message>
+ <source>If &lt;category&gt; is not supplied, output all debugging information.</source>
+ <translation>Als er geen &lt;category&gt; is opgegeven, laat dan alle debugging informatie zien.</translation>
+ </message>
+ <message>
+ <source>Importing...</source>
+ <translation>Importeren...</translation>
+ </message>
+ <message>
+ <source>Incorrect or no genesis block found. Wrong datadir for network?</source>
+ <translation>Incorrect of geen genesis-blok gevonden. Verkeerde datamap voor het netwerk?</translation>
+ </message>
+ <message>
+ <source>Invalid -onion address: '%s'</source>
+ <translation>Ongeldig -onion adres '%s'</translation>
+ </message>
+ <message>
+ <source>Not enough file descriptors available.</source>
+ <translation>Niet genoeg file descriptors beschikbaar.</translation>
+ </message>
+ <message>
+ <source>Only connect to nodes in network &lt;net&gt; (ipv4, ipv6 or onion)</source>
+ <translation>Verbind alleen met nodes in netwerk &lt;net&gt; (ipv4, ipv6 of onion)</translation>
+ </message>
+ <message>
+ <source>Set database cache size in megabytes (%d to %d, default: %d)</source>
+ <translation>Zet database cache grootte in megabytes (%d tot %d, standaard: %d)</translation>
+ </message>
+ <message>
+ <source>Set maximum block size in bytes (default: %d)</source>
+ <translation>Stel maximum blokgrootte in in bytes (standaard: %d)</translation>
+ </message>
+ <message>
+ <source>Specify wallet file (within data directory)</source>
+ <translation>Specificeer het portemonnee bestand (vanuit de gegevensmap)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: %u)</source>
+ <translation>Gebruik UPnP om de luisterende poort te mappen (standaard: %u)</translation>
+ </message>
+ <message>
+ <source>Verifying blocks...</source>
+ <translation>Blokken aan het controleren...</translation>
+ </message>
+ <message>
+ <source>Verifying wallet...</source>
+ <translation>Portemonnee aan het controleren...</translation>
+ </message>
+ <message>
+ <source>Wallet %s resides outside data directory %s</source>
+ <translation>Portemonnee %s bevindt zich buiten de gegevensmap %s</translation>
+ </message>
+ <message>
+ <source>Wallet options:</source>
+ <translation>Portemonnee instellingen:</translation>
+ </message>
+ <message>
+ <source>Warning: This version is obsolete; upgrade required!</source>
+ <translation>Waarschuwing: Deze versie is verouderd; upgraden verplicht!</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to change -txindex</source>
+ <translation>Om -txindex te kunnen veranderen dient u de database opnieuw te bouwen met gebruik van -reindex.</translation>
+ </message>
+ <message>
+ <source>Imports blocks from external blk000??.dat file</source>
+ <translation>Importeert blokken van extern blk000??.dat bestand</translation>
+ </message>
+ <message>
+ <source>Allow JSON-RPC connections from specified source. Valid for &lt;ip&gt; are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times</source>
+ <translation>Sta JSON-RPC verbindingen toe vanuit een gespecificeerde bron. Geldig voor &lt;ip&gt; zijn een enkel IP (bijv. 1.2.3.4), een netwerk/netmask (bijv. 1.2.3.4/255.255.255.0) of een netwerk/CIDR (bijv. 1.2.3.4/24). Deze optie kan meerdere keren gespecificeerd worden.</translation>
+ </message>
+ <message>
+ <source>An error occurred while setting up the RPC address %s port %u for listening: %s</source>
+ <translation>Er is een fout opgetreden tijdens het opzetten van het RPC adres %s poort %u voor luisteren: %s</translation>
+ </message>
+ <message>
+ <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source>
+ <translation>Bind aan opgegeven adres en keur peers die ermee verbinden goed. Gebruik [host]:poort notatie voor IPv6</translation>
+ </message>
+ <message>
+ <source>Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)</source>
+ <translation>Bind aan gegeven adres om te luisteren voor JSON-RPC verbindingen. Gebruik [host]:poort notatie voor IPv6. Deze optie kan meerdere keren gespecificeerd worden (standaard: bind aan alle interfaces.</translation>
+ </message>
+ <message>
+ <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source>
+ <translation>Kan geen lock verkrijgen op gegevensmap %s. Bitcoin Core draait waarschijnlijk al.</translation>
+ </message>
+ <message>
+ <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
+ <translation>Creër nieuwe bestanden met standaard systeem bestandsrechten in plaats van umask 077 (alleen effectief met uitgeschakelde portemonnee functionaliteit)</translation>
+ </message>
+ <message>
+ <source>Error: Listening for incoming connections failed (listen returned error %s)</source>
+ <translation>Fout: luisteren naar binnenkomende verbindingen mislukt (luisteren gaf foutmelding %s)</translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source>
+ <translation>Fout: er is een niet-ondersteund argument -socks aangetroffen. Het instellen van de SOCKS-versie is niet langer mogelijk. Alleen SOCKS5-proxy's worden ondersteund.</translation>
+ </message>
+ <message>
+ <source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source>
+ <translation>Voer commando uit zodra een waarschuwing is ontvangen of wanneer we een erg lange fork detecteren (%s in commando wordt vervangen door bericht)</translation>
+ </message>
+ <message>
+ <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source>
+ <translation>Toeslagen (in BTC/Kb) kleiner dan dit worden beschouwd als geen vergoeding (voor doorgeven) (standaard: %s)</translation>
+ </message>
+ <message>
+ <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
+ <translation>Als paytxfee niet is ingesteld, het pakket voldoende vergoeding zodat transacties beginnen bevestiging gemiddeld binnen in blokken (default: %u)</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)</source>
+ <translation>ongeldig bedrag voor -maxtxfee=&lt;amount&gt;: '%s' (moet ten minste de minrelay vergoeding van %s het voorkomen geplakt transacties voorkomen)</translation>
+ </message>
+ <message>
+ <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source>
+ <translation>Maximale grootte va n de gegevens in gegevensdrager transacties we relais en de mijnen
+(default: %u)</translation>
+ </message>
+ <message>
+ <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source>
+ <translation>Query voor peer- adressen via DNS- lookup , als laag op adressen (default: 1 unless -connect)</translation>
+ </message>
+ <message>
+ <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
+ <translation>Stel maximumgrootte in bytes in voor hoge-prioriteits-/lage-transactiekosten-transacties (standaard: %d)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source>
+ <translation>Stel het aantal threads in voor het genereren van coins indien ingesteld (-1 = alle kernen, standaard: %d)</translation>
+ </message>
+ <message>
+ <source>The transaction amount is too small to send after the fee has been deducted</source>
+ <translation>Het transactiebedrag is te klein om te versturen nadat de vergoeding in mindering is gebracht</translation>
+ </message>
+ <message>
+ <source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit &lt;https://www.openssl.org/&gt; and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source>
+ <translation>Dit product bevat software dat ontwikkeld is door het OpenSSL Project voor gebruik in de OpenSSL Toolkit &lt;https://www.openssl.org/&gt; en cryptografische software geschreven door Eric Young en UPnP software geschreven door Thomas Bernard.</translation>
+ </message>
+ <message>
+ <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an 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)
+The username and password MUST NOT be the same.
+If the file does not exist, create it with owner-readable-only file permissions.
+It is also recommended to set alertnotify so you are notified of problems;
+for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
+</source>
+ <translation>Om bitcoind of de -server optie naar bitcoin-gt te gebruiken, dient u een rpcwachtwoord in te stellen in het configuratiebestand:
+ %s
+Wij raden u aan om het volgende wachtwoord willekeurig te gebruiken:
+rpcuser=bitcoinrpc
+rpcpassword=%s
+(u hoeft dit wachtwoord niet te onthouden)
+De gebruikersnaam en het wachtwoorden moeten NIET hetzelfde zijn.
+Indien het bestand niet bestaat, maak het bestand aan met bestandsrechten: alleen lezen voor eigenaar.
+Het is ook aan te raden om een alarmnotificatie in te stellen, zodat u op de hoogte bent van de problemen;
+Voorbeeld: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</translation>
+ </message>
+ <message>
+ <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source>
+ <translation>Let op: -maxtxfee is erg hoog ingesteld! Transactiekosten van dergelijke groottes kunnen in een enkele transactie worden betaald.</translation>
+ </message>
+ <message>
+ <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source>
+ <translation>Waarschuwing: Controleer dat de datum en tijd van uw computer correct zijn ingesteld! Bij een onjuist ingestelde klok zal Bitcoin Core niet goed werken.</translation>
+ </message>
+ <message>
+ <source>Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway</source>
+ <translation>Goedgekeurde peers kunnen niet ge-DoS-banned worden en hun transacties worden altijd doorgestuurd, zelfs als ze reeds in de mempool aanwezig zijn, nuttig voor bijv. een gateway</translation>
+ </message>
+ <message>
+ <source>(default: %u)</source>
+ <translation>(standaard: %u)</translation>
+ </message>
+ <message>
+ <source>Accept public REST requests (default: %u)</source>
+ <translation>Accepteer publieke REST-requests (standaard: %u)</translation>
+ </message>
+ <message>
+ <source>Activating best chain...</source>
+ <translation>Beste reeks activeren...</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -whitebind address: '%s'</source>
+ <translation>Kan -whitebind adres niet herleiden: '%s'</translation>
+ </message>
+ <message>
+ <source>Choose data directory on startup (default: 0)</source>
+ <translation>Kies de gegevensmap tijdens het opstarten (standaard: 0)</translation>
+ </message>
+ <message>
+ <source>Connect through SOCKS5 proxy</source>
+ <translation>Verbind door SOCKS5 proxy</translation>
+ </message>
+ <message>
+ <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source>
+ <translation>Auteursrecht (C) 2009-%i De Bitcoin Core Ontwikkelaars</translation>
+ </message>
+ <message>
+ <source>Could not parse -rpcbind value %s as network address</source>
+ <translation>Niet mogelijk om -rpcbind waarde %s te verwerken als netwerk adres</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source>
+ <translation>Fout bij laden wallet.dat: Portemonnee vereist een nieuwere versie van Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Error reading from database, shutting down.</source>
+ <translation>Fout bij het lezen van de database, afsluiten. </translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -tor found, use -onion.</source>
+ <translation>Fout: Niet ondersteund argument -tor gevonden, gebruik -onion.</translation>
+ </message>
+ <message>
+ <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source>
+ <translation>Transactiekosten (in BTC/kB) om toe te voegen aan transacties die u verstuurd (standaard: %s)</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Informatie</translation>
+ </message>
+ <message>
+ <source>Initialization sanity check failed. Bitcoin Core is shutting down.</source>
+ <translation>Initialisatie sanity check mislukt. Bitcoin Core is aan het afsluiten.</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Ongeldig bedrag voor -maxtxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -minrelaytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Ongeldig bedrag voor -minrelaytxfee=&lt;bedrag&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -mintxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Ongeldig bedrag voor -mintxfee=&lt;bedrag&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s' (must be at least %s)</source>
+ <translation>Ongeldig bedrag voor -paytxfee=&lt;bedrag&gt;: '%s' (Minimum %s)</translation>
+ </message>
+ <message>
+ <source>Invalid netmask specified in -whitelist: '%s'</source>
+ <translation>Ongeldig netmask gespecificeerd in -whitelist: '%s'</translation>
+ </message>
+ <message>
+ <source>Keep at most &lt;n&gt; unconnectable transactions in memory (default: %u)</source>
+ <translation>Houd maximaal &lt;n&gt; onverbonden transacties in geheugen (standaard: %u)</translation>
+ </message>
+ <message>
+ <source>Need to specify a port with -whitebind: '%s'</source>
+ <translation>Verplicht een poort met -whitebind op te geven: '%s'</translation>
+ </message>
+ <message>
+ <source>Node relay options:</source>
+ <translation>Node relay opties:</translation>
+ </message>
+ <message>
+ <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source>
+ <translation>RPC SSL opties: (zie de Bitcoin Wiki voor SSL installatie-instructies)</translation>
+ </message>
+ <message>
+ <source>RPC server options:</source>
+ <translation>RPC server opties:</translation>
+ </message>
+ <message>
+ <source>RPC support for HTTP persistent connections (default: %d)</source>
+ <translation>RPC ondersteuning voor HTTP persisten verbindingen (default: %d)</translation>
+ </message>
+ <message>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>Stuur trace/debug-info naar de console in plaats van het debug.log bestand</translation>
+ </message>
+ <message>
+ <source>Send transactions as zero-fee transactions if possible (default: %u)</source>
+ <translation>Verstuur transacties zonder verzendkosten indien mogelijk (standaard: %u)</translation>
+ </message>
+ <message>
+ <source>Set SSL root certificates for payment request (default: -system-)</source>
+ <translation>Zet SSL root certificaten voor betalingsverzoek (standaard: -sytem-)</translation>
+ </message>
+ <message>
+ <source>Set language, for example "de_DE" (default: system locale)</source>
+ <translation>Stel taal in, bijvoorbeeld ''de_DE" (standaard: systeeminstellingen)</translation>
+ </message>
+ <message>
+ <source>Show all debugging options (usage: --help -help-debug)</source>
+ <translation>Toon alle foutopsporingsopties (gebruik: --help -help-debug)</translation>
+ </message>
+ <message>
+ <source>Show splash screen on startup (default: 1)</source>
+ <translation>Laat laadscherm zien bij het opstarten. (standaard: 1)</translation>
+ </message>
+ <message>
+ <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source>
+ <translation>Verklein debug.log-bestand bij het opstarten van de client (standaard: 1 als geen -debug)</translation>
+ </message>
+ <message>
+ <source>Signing transaction failed</source>
+ <translation>Ondertekenen van transactie mislukt</translation>
+ </message>
+ <message>
+ <source>Start minimized</source>
+ <translation>Geminimaliseerd starten</translation>
+ </message>
+ <message>
+ <source>The transaction amount is too small to pay the fee</source>
+ <translation>Het transactiebedrag is te klein om de vergoeding te betalen</translation>
+ </message>
+ <message>
+ <source>This is experimental software.</source>
+ <translation>Dit is experimentele software.</translation>
+ </message>
+ <message>
+ <source>Transaction amount too small</source>
+ <translation>Transactiebedrag te klein</translation>
+ </message>
+ <message>
+ <source>Transaction amounts must be positive</source>
+ <translation>Transactiebedragen moeten positief zijn</translation>
+ </message>
+ <message>
+ <source>Transaction too large for fee policy</source>
+ <translation>De transactie is te groot voor het toeslagenbeleid</translation>
+ </message>
+ <message>
+ <source>Transaction too large</source>
+ <translation>Transactie te groot</translation>
+ </message>
+ <message>
+ <source>UI Options:</source>
+ <translation>UI Opties:</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer (bind returned error %s)</source>
+ <translation>Niet in staat om aan %s te binden op deze computer (bind gaf error %s)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: 1 when listening)</source>
+ <translation>Gebruik UPnP om de luisterende poort te mappen (standaard: 1 als er wordt geluisterd)</translation>
+ </message>
+ <message>
+ <source>Username for JSON-RPC connections</source>
+ <translation>Gebruikersnaam voor JSON-RPC-verbindingen</translation>
+ </message>
+ <message>
+ <source>Wallet needed to be rewritten: restart Bitcoin Core to complete</source>
+ <translation>Portemonnee moest herschreven worden: Herstart Bitcoin Core om te voltooien</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Waarschuwing</translation>
+ </message>
+ <message>
+ <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source>
+ <translation>Waarschuwing: Niet ondersteund argument -benchmark genegeerd, gebruik -debug=bench.</translation>
+ </message>
+ <message>
+ <source>Warning: Unsupported argument -debugnet ignored, use -debug=net.</source>
+ <translation>Waarschuwing: Niet ondersteund argument -debugnet genegeerd, gebruik -debug=net.</translation>
+ </message>
+ <message>
+ <source>Zapping all transactions from wallet...</source>
+ <translation>Bezig met het zappen van alle transacties van de portemonnee...</translation>
+ </message>
+ <message>
+ <source>on startup</source>
+ <translation>bij opstarten</translation>
+ </message>
+ <message>
+ <source>wallet.dat corrupt, salvage failed</source>
+ <translation>wallet.dat corrupt, veiligstellen mislukt</translation>
+ </message>
+ <message>
+ <source>Password for JSON-RPC connections</source>
+ <translation>Wachtwoord voor JSON-RPC-verbindingen</translation>
+ </message>
+ <message>
+ <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
+ <translation>Voer commando uit zodra het beste blok verandert (%s in cmd wordt vervangen door blockhash)</translation>
+ </message>
+ <message>
+ <source>Upgrade wallet to latest format</source>
+ <translation>Vernieuw portemonnee naar nieuwste versie</translation>
+ </message>
+ <message>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>Doorzoek de blokketen op ontbrekende portemonnee-transacties</translation>
+ </message>
+ <message>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>Gebruik OpenSSL (https) voor JSON-RPC-verbindingen</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>Dit helpbericht</translation>
+ </message>
+ <message>
+ <source>Allow DNS lookups for -addnode, -seednode and -connect</source>
+ <translation>Sta DNS-naslag toe voor -addnode, -seednode en -connect</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>Adressen aan het laden...</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>Fout bij laden wallet.dat: Portemonnee corrupt</translation>
+ </message>
+ <message>
+ <source>(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source>
+ <translation>(1 = behoudt tx meta data bijv. account eigenaar en betalingsverzoek informatie, 2. sla tx meta data niet op)</translation>
+ </message>
+ <message>
+ <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
+ <translation>Hoe grondig de blokverificatie van -checkblocks is (0-4, standaard: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
+ <translation>Onderhoud een volledige transactieindex, gebruikt door de getrawtransaction rpc call (standaard: %u)</translation>
+ </message>
+ <message>
+ <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source>
+ <translation>Aantal seconden dat zich misdragende peers niet opnieuw kunnen verbinden (standaard: %u)</translation>
+ </message>
+ <message>
+ <source>Output debugging information (default: %u, supplying &lt;category&gt; is optional)</source>
+ <translation>Output extra debugginginformatie (standaard: %u, het leveren van &lt;category&gt; is optioneel)</translation>
+ </message>
+ <message>
+ <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source>
+ <translation>Gebruik een aparte SOCKS5 proxy om 'Tor hidden services' te bereiken (standaard: %s)</translation>
+ </message>
+ <message>
+ <source>Acceptable ciphers (default: %s)</source>
+ <translation>Geaccepteerde versleutelingen (standaard: %s)</translation>
+ </message>
+ <message>
+ <source>Always query for peer addresses via DNS lookup (default: %u)</source>
+ <translation>Vind anderen door middel van een DNS-naslag (standaard: %u)</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>Fout bij laden wallet.dat</translation>
+ </message>
+ <message>
+ <source>Generate coins (default: %u)</source>
+ <translation>Genereer munten (standaard: %u)</translation>
+ </message>
+ <message>
+ <source>How many blocks to check at startup (default: %u, 0 = all)</source>
+ <translation>Aantal te checken blokken bij het opstarten (standaard: %u, 0 = allemaal)</translation>
+ </message>
+ <message>
+ <source>Include IP addresses in debug output (default: %u)</source>
+ <translation>IP-adressen toevoegen in de debuguitvoer (standaard: %u)</translation>
+ </message>
+ <message>
+ <source>Invalid -proxy address: '%s'</source>
+ <translation>Ongeldig -proxy adres: '%s'</translation>
+ </message>
+ <message>
+ <source>Listen for JSON-RPC connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>Luister naar JSON-RPC-verbindingen op poort &lt;port&gt; (standaard: %u of testnet: %u)</translation>
+ </message>
+ <message>
+ <source>Listen for connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>Luister naar verbindingen op &lt;poort&gt; (standaard: %u of testnet: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain at most &lt;n&gt; connections to peers (default: %u)</source>
+ <translation>Onderhoud maximaal &lt;n&gt; verbindingen naar peers (standaard: %u)</translation>
+ </message>
+ <message>
+ <source>Make the wallet broadcast transactions</source>
+ <translation>Laat de portemonnee transacties uitsturen</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection receive buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>Maximum per-connectie ontvangstbuffer, &lt;n&gt;*1000 bytes (standaard: %u)</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection send buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>Maximum per-connectie zendbuffer, &lt;n&gt;*1000 bytes (standaard: %u)</translation>
+ </message>
+ <message>
+ <source>Prepend debug output with timestamp (default: %u)</source>
+ <translation>Prepend debug output met tijdstempel (standaard: %u)</translation>
+ </message>
+ <message>
+ <source>Relay and mine data carrier transactions (default: %u)</source>
+ <translation>Gegevensdrager transacties relay en de mijnen (default: %u)</translation>
+ </message>
+ <message>
+ <source>Relay non-P2SH multisig (default: %u)</source>
+ <translation>Relay non-P2SH multisig (default: %u)</translation>
+ </message>
+ <message>
+ <source>Server certificate file (default: %s)</source>
+ <translation>Certificaat-bestand voor server (standaard: %s)</translation>
+ </message>
+ <message>
+ <source>Server private key (default: %s)</source>
+ <translation>Geheime sleutel voor server (standaard: %s)</translation>
+ </message>
+ <message>
+ <source>Set key pool size to &lt;n&gt; (default: %u)</source>
+ <translation>Stel sleutelpoelgrootte in op &lt;&amp;&gt; (standaard: %u)</translation>
+ </message>
+ <message>
+ <source>Set minimum block size in bytes (default: %u)</source>
+ <translation>Stel minimum blokgrootte in in bytes (standaard: %u)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads to service RPC calls (default: %d)</source>
+ <translation>Stel het aantal threads in om RPC-aanvragen mee te bedienen (standaard: %d)</translation>
+ </message>
+ <message>
+ <source>Specify configuration file (default: %s)</source>
+ <translation>Specificeer configuratie bestand (standaard: %s)</translation>
+ </message>
+ <message>
+ <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source>
+ <translation>Specificeer de time-out tijd in milliseconden (minimum: 1, standaard: %d)</translation>
+ </message>
+ <message>
+ <source>Specify pid file (default: %s)</source>
+ <translation>Specificeer pid-bestand (standaard: %s)</translation>
+ </message>
+ <message>
+ <source>Spend unconfirmed change when sending transactions (default: %u)</source>
+ <translation>Besteed onbevestigd wisselgeld bij het versturen van transacties (standaard: %u)</translation>
+ </message>
+ <message>
+ <source>Threshold for disconnecting misbehaving peers (default: %u)</source>
+ <translation>Drempel om verbinding te verbreken naar zich misdragende peers (standaard: %u)</translation>
+ </message>
+ <message>
+ <source>Unknown network specified in -onlynet: '%s'</source>
+ <translation>Onbekend netwerk gespecificeerd in -onlynet: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -bind address: '%s'</source>
+ <translation>Kan -bind adres niet herleiden: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -externalip address: '%s'</source>
+ <translation>Kan -externlip adres niet herleiden: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Ongeldig bedrag voor -paytxfee=&lt;bedrag&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>Ontoereikend saldo</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>Blokindex aan het laden...</translation>
+ </message>
+ <message>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>Voeg een node om naar te verbinden toe en probeer de verbinding open te houden</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>Portemonnee aan het laden...</translation>
+ </message>
+ <message>
+ <source>Cannot downgrade wallet</source>
+ <translation>Kan portemonnee niet downgraden</translation>
+ </message>
+ <message>
+ <source>Cannot write default address</source>
+ <translation>Kan standaardadres niet schrijven</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>Blokketen aan het doorzoeken...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>Klaar met laden</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Fout</translation>
+ </message>
+</context>
+</TS> \ No newline at end of file
diff --git a/src/qt/locale/bitcoin_pam.ts b/src/qt/locale/bitcoin_pam.ts
new file mode 100644
index 0000000000..4939dff4b0
--- /dev/null
+++ b/src/qt/locale/bitcoin_pam.ts
@@ -0,0 +1,1502 @@
+<TS language="pam" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Right-click to edit address or label</source>
+ <translation>I-right click ban alilan ing address o libel</translation>
+ </message>
+ <message>
+ <source>Create a new address</source>
+ <translation>Maglalang kang bayung address</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>&amp;Bayu</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Kopyan me ing salukuyan at makipiling address keng system clipboard</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>&amp;Kopyan</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>I&amp;sara</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>&amp;Kopyan ing address</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>Ilako ya ing kasalungsungan makapiling address keng listahan</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;Ilako</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>Pilinan ing address a magpadalang coins kang</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>Pilinan ing address a tumanggap coins a atin</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>P&amp;ilinan</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>Address king pamag-Send</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>Address king pamag-Tanggap</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>Reni reng kekang Bitcoin address king pamagpadalang kabayaran. Lawan mulang masalese reng alaga ampo ing address na ning tumanggap bayu ka magpadalang barya.</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>Reni reng kekang Bitcoin addresses keng pamananggap bayad. Rerekomenda mi na gumamit kang bayung address keng balang transaksiyon.</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>Kopyan ing &amp;Label</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>&amp;Alilan</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Comma separated file (*.csv)</translation>
+ </message>
+ </context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Label</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Address</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(alang label)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Passphrase Dialog</source>
+ <translation>Dialogo ning Passphrase</translation>
+ </message>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Mamalub kang passphrase</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Panibayung passphrase</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Pasibayuan ya ing bayung passphrase</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>I-encrypt ye ing wallet</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>Ing operasyun a ini kailangan ne ing kekayung wallet passphrase, ban a-unlock ya ing wallet</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Unlock ya ing wallet</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>Ing operasyun a ini kailangan ne ing kekang wallet passphrase ban a-decrypt ne ing wallet.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>I-decrypt ya ing wallet</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>Alilan ya ing passphrase</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>Kumpirman ya ing wallet encryption</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>Kapabaluan: Istung in-encrypt me ing kekang wallet at meala ya ing passphrase na, ma-&lt;b&gt;ALA NO NGAN RING KEKANG BITCOINS&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>Siguradu na kang buri meng i-encrypt ing kekang wallet?</translation>
+ </message>
+ <message>
+ <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
+ <translation>Mayalaga: Reng milabas a backups a gewa mu gamit ing wallet file mu dapat lamung mialilan bayung gawang encrypted wallet file. Para keng seguridad , reng milabas a backups dareng ali maka encrypt a wallet file ma-ala nala istung inumpisan mu nalang gamitan reng bayu, at me encrypt a wallet. </translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>Kapabaluan: Makabuklat ya ing Caps Lock key!</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>Me-encrypt ne ing wallet</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>Memali ya ing pamag-encrypt king wallet </translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>Memali ya ing encryption uli na ning ausan dang internal error. E ya me-encrypt ing wallet yu.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>E la mitutugma ring mibieng passphrase</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>Memali ya ing pamag-unlock king wallet </translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>E ya istu ing passphrase a pepalub da para king wallet decryption</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>Me-mali ya ing pamag-decrypt king wallet</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>Mi-alilan ne ing passphrase na ning wallet.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>I-sign ing &amp;mensayi</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>Mag-sychronize ne king network...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;Overview</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>Ipakit ing kabuuang lawe ning wallet</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Transaksion</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>Lawan ing kasalesayan ning transaksion</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>L&amp;umwal</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>Tuknangan ing aplikasyon</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>Tungkul &amp;Qt</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>Magpakit impormasion tungkul king Qt</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;Pipamilian...</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>I-&amp;Encrypt in Wallet...</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>I-&amp;Backup ing Wallet...</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>&amp;Alilan ing Passphrase...</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>Magpadalang barya king Bitcoin address</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>I-backup ing wallet king aliwang lugal</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Alilan ya ing passphrase a gagamitan para king wallet encryption</translation>
+ </message>
+ <message>
+ <source>&amp;Debug window</source>
+ <translation>I-&amp;Debug ing awang</translation>
+ </message>
+ <message>
+ <source>Open debugging and diagnostic console</source>
+ <translation>Ibuklat ing debugging at diagnostic console</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>&amp;Beripikan ing message...</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>Wallet</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>&amp;Ipalto / Isalikut</translation>
+ </message>
+ <message>
+ <source>Show or hide the main Window</source>
+ <translation>Ipalto o isalikut ing pun a awang</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;File</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;Pamag-ayus</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>&amp;Saup</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>Gamit para king Tabs</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Kapilubluban ning Bitcoin</translation>
+ </message>
+ <message>
+ <source>Last received block was generated %1 ago.</source>
+ <translation>Ing tatauling block a metanggap, me-generate ya %1 ing milabas</translation>
+ </message>
+ <message>
+ <source>Transactions after this will not yet be visible.</source>
+ <translation>Ing transaksion kaibat na nini ali yapa magsilbing ipakit.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Mali</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Kapabaluan</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>&amp;Impormasion</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>Makatuki ya king aldo</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>Catching up...</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>Mipadalang transaksion</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>Paparatang a transaksion</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>Maka-&lt;b&gt;encrypt&lt;/b&gt; ya ing wallet at kasalukuyan yang maka-&lt;b&gt;unlocked&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>Maka-&lt;b&gt;encrypt&lt;/b&gt; ya ing wallet at kasalukuyan yang maka-&lt;b&gt;locked&lt;/b&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <source>Network Alert</source>
+ <translation>Alertu ning Network</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Amount</source>
+ <translation>Alaga</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Kaaldauan</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Me-kumpirma</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Kopyan ing address</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Kopyan ing label</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopyan ing alaga</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(alang label)</translation>
+ </message>
+ </context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>Alilan ing Address</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>&amp;Label</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;Address</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>Bayung address king pamagtanggap</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>Bayung address king pamagpadala</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>Alilan ya ing address king pamagpadala</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>Alilan ya ing address king pamagpadala</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>Ing pepalub yung address "%1" ati na yu king aklat dareng address</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is not a valid Bitcoin address.</source>
+ <translation>Ing pepalub yung address "%1" ali ya katanggap-tanggap a Bitcoin address.</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>Ali ya bisang mag-unlock ing wallet</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>Memali ya ing pamangaua king key</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ </context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Kapilubluban ning Bitcoin</translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>bersion</translation>
+ </message>
+ <message>
+ <source>Command-line options</source>
+ <translation>Pipamilian command-line</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>Pamanggamit:</translation>
+ </message>
+ <message>
+ <source>command-line options</source>
+ <translation>pipamilian command-line</translation>
+ </message>
+</context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Welcome</source>
+ <translation>Malaus ka</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Kapilubluban ning Bitcoin</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Mali</translation>
+ </message>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ </context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>Pipamilian</translation>
+ </message>
+ <message>
+ <source>&amp;Main</source>
+ <translation>&amp;Pun</translation>
+ </message>
+ <message>
+ <source>&amp;Network</source>
+ <translation>&amp;Network</translation>
+ </message>
+ <message>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>Ibuklat yang antimanu ing Bitcoin client port king router. Gagana yamu ini istung ing router mu susuporta yang UPnP at magsilbi ya.</translation>
+ </message>
+ <message>
+ <source>Map port using &amp;UPnP</source>
+ <translation>Mapa ng ning port gamit ing &amp;UPnP</translation>
+ </message>
+ <message>
+ <source>Proxy &amp;IP:</source>
+ <translation>Proxy &amp;IP:</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>&amp;Port:</translation>
+ </message>
+ <message>
+ <source>Port of the proxy (e.g. 9050)</source>
+ <translation>Port na ning proxy(e.g. 9050)</translation>
+ </message>
+ <message>
+ <source>&amp;Window</source>
+ <translation>&amp;Awang</translation>
+ </message>
+ <message>
+ <source>Show only a tray icon after minimizing the window.</source>
+ <translation>Ipakit mu ing tray icon kaibat meng pelatian ing awang.</translation>
+ </message>
+ <message>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>&amp;Latian ya ing tray kesa king taskbar</translation>
+ </message>
+ <message>
+ <source>M&amp;inimize on close</source>
+ <translation>P&amp;alatian istung isara</translation>
+ </message>
+ <message>
+ <source>&amp;Display</source>
+ <translation>&amp;Ipalto</translation>
+ </message>
+ <message>
+ <source>User Interface &amp;language:</source>
+ <translation>Amanu na ning user interface:</translation>
+ </message>
+ <message>
+ <source>&amp;Unit to show amounts in:</source>
+ <translation>Ing &amp;Unit a ipakit king alaga ning:</translation>
+ </message>
+ <message>
+ <source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
+ <translation>Pilinan ing default subdivision unit a ipalto o ipakit king interface at istung magpadala kang barya.</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>&amp;OK</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>I-&amp;Cancel</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>default</translation>
+ </message>
+ <message>
+ <source>The supplied proxy address is invalid.</source>
+ <translation>Ing milageng proxy address eya katanggap-tanggap.</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>Form</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>Ing makaltong impormasion mapalyaring luma ne. Ing kekang wallet otomatiku yang mag-synchronize keng Bitcoin network istung mekakonekta ne king network, oneng ing prosesung ini ali ya pa kumpletu.</translation>
+ </message>
+ <message>
+ <source>Your current spendable balance</source>
+ <translation>Ing kekang kasalungsungan balanse a malyari mung gastusan</translation>
+ </message>
+ <message>
+ <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source>
+ <translation>Ing kabuuan dareng transaksion a kasalungsungan ali pa me-kumpirma, at kasalungsungan ali pa mebilang kareng kekang balanseng malyari mung gastusan</translation>
+ </message>
+ <message>
+ <source>Immature:</source>
+ <translation>Immature:</translation>
+ </message>
+ <message>
+ <source>Mined balance that has not yet matured</source>
+ <translation>Reng me-minang balanse a epa meg-matured</translation>
+ </message>
+ <message>
+ <source>Total:</source>
+ <translation>Kabuuan:</translation>
+ </message>
+ <message>
+ <source>Your current total balance</source>
+ <translation>Ing kekang kasalungsungan kabuuang balanse</translation>
+ </message>
+ </context>
+<context>
+ <name>PaymentServer</name>
+ </context>
+<context>
+ <name>PeerTableModel</name>
+ </context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>Alaga</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>N/A</translation>
+ </message>
+ </context>
+<context>
+ <name>QRImageWidget</name>
+ </context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>Client name</source>
+ <translation>Lagyu ning kliente</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>N/A</translation>
+ </message>
+ <message>
+ <source>Client version</source>
+ <translation>Bersion ning Cliente</translation>
+ </message>
+ <message>
+ <source>&amp;Information</source>
+ <translation>&amp;Impormasion</translation>
+ </message>
+ <message>
+ <source>Using OpenSSL version</source>
+ <translation>Gagamit bersion na ning OpenSSL</translation>
+ </message>
+ <message>
+ <source>Startup time</source>
+ <translation>Oras ning umpisa</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Network</translation>
+ </message>
+ <message>
+ <source>Number of connections</source>
+ <translation>Bilang dareng koneksion</translation>
+ </message>
+ <message>
+ <source>Block chain</source>
+ <translation>Block chain</translation>
+ </message>
+ <message>
+ <source>Current number of blocks</source>
+ <translation>Kasalungsungan bilang dareng blocks</translation>
+ </message>
+ <message>
+ <source>Last block time</source>
+ <translation>Tatauling oras na ning block</translation>
+ </message>
+ <message>
+ <source>&amp;Open</source>
+ <translation>&amp;Ibuklat</translation>
+ </message>
+ <message>
+ <source>&amp;Console</source>
+ <translation>&amp;Console</translation>
+ </message>
+ <message>
+ <source>Totals</source>
+ <translation>Kabuuan:</translation>
+ </message>
+ <message>
+ <source>Build date</source>
+ <translation>Kaaldauan ning pamaglalang</translation>
+ </message>
+ <message>
+ <source>Debug log file</source>
+ <translation>Debug log file</translation>
+ </message>
+ <message>
+ <source>Clear console</source>
+ <translation>I-Clear ing console</translation>
+ </message>
+ <message>
+ <source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
+ <translation>Gamitan me ing patas at pababang arrow para alibut me ing kasalesayan, at &lt;b&gt;Ctrl-L&lt;/b&gt; ban I-clear ya ing screen.</translation>
+ </message>
+ <message>
+ <source>Type &lt;b&gt;help&lt;/b&gt; for an overview of available commands.</source>
+ <translation>I-type ing &lt;b&gt;help&lt;/b&gt; ban akit la reng ati at magsilbing commands.</translation>
+ </message>
+ </context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Label:</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Kopyan ing label</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopyan ing alaga</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>Address</source>
+ <translation>Address</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Alaga</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Label</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Mensayi</translation>
+ </message>
+ </context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Kaaldauan</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Label</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Mensayi</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Alaga</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(alang label)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Magpadalang Barya</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>Misanang magpadala kareng alialiuang tumanggap</translation>
+ </message>
+ <message>
+ <source>Add &amp;Recipient</source>
+ <translation>Maglage &amp;Tumanggap</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>I-Clear &amp;Eganagana</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>Balanse:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>Kumpirman ing aksion king pamagpadala</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>Ipadala</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>Kumpirman ing pamagpadalang barya</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopyan ing alaga</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>Ing alaga na ning bayaran dapat mung mas matas ya king 0.</translation>
+ </message>
+ <message>
+ <source>The amount exceeds your balance.</source>
+ <translation>Ing alaga mipasobra ya king kekang balanse.</translation>
+ </message>
+ <message>
+ <source>The total exceeds your balance when the %1 transaction fee is included.</source>
+ <translation>Ing kabuuan mipasobra ya king kekang balanse istung inabe ya ing %1 a bayad king transaksion </translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(alang label)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>A&amp;laga:</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>Ibayad &amp;kang:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Magpalub kang label para king address a ini ban a-iabe me king aklat dareng address</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Label:</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Idikit ing address menibat king clipboard</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ </context>
+<context>
+ <name>ShutdownWindow</name>
+ </context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Signatures - Sign / Verify a Message</source>
+ <translation>Pirma - Pirman / I-beripika ing mensayi</translation>
+ </message>
+ <message>
+ <source>&amp;Sign Message</source>
+ <translation>&amp;Pirman ing Mensayi</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Idikit ing address menibat king clipboard</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Enter the message you want to sign here</source>
+ <translation>Ipalub ing mensayi a buri mung pirman keni</translation>
+ </message>
+ <message>
+ <source>Signature</source>
+ <translation>Pirma</translation>
+ </message>
+ <message>
+ <source>Copy the current signature to the system clipboard</source>
+ <translation>Kopyan ing kasalungsungan pirma king system clipboard</translation>
+ </message>
+ <message>
+ <source>Sign the message to prove you own this Bitcoin address</source>
+ <translation>Pirman ing mensayi ban patune na keka ya ining Bitcoin address</translation>
+ </message>
+ <message>
+ <source>Sign &amp;Message</source>
+ <translation>Pirman ing &amp;Mensayi</translation>
+ </message>
+ <message>
+ <source>Reset all sign message fields</source>
+ <translation>Ibalik keng dati reng ngan fields keng pamamirmang mensayi</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>I-Clear &amp;Eganagana</translation>
+ </message>
+ <message>
+ <source>&amp;Verify Message</source>
+ <translation>&amp;Beripikan ing Mensayi</translation>
+ </message>
+ <message>
+ <source>Verify the message to ensure it was signed with the specified Bitcoin address</source>
+ <translation>Beripikan ing mensayi ban asiguradu a me pirma ya ini gamit ing mepiling Bitcoin address</translation>
+ </message>
+ <message>
+ <source>Verify &amp;Message</source>
+ <translation>Beripikan ing &amp;Mensayi</translation>
+ </message>
+ <message>
+ <source>Reset all verify message fields</source>
+ <translation>Ibalik king dati reng ngan fields na ning pamag beripikang mensayi</translation>
+ </message>
+ <message>
+ <source>Click "Sign Message" to generate signature</source>
+ <translation>I-click ing "Pirman ing Mensayi" ban agawa ya ing metung a pirma</translation>
+ </message>
+ <message>
+ <source>The entered address is invalid.</source>
+ <translation>Ing milub a address e ya katanggap-tanggap.</translation>
+ </message>
+ <message>
+ <source>Please check the address and try again.</source>
+ <translation>Maliaring pakilawe pasibayu ing address at pasibayuan ya iti.</translation>
+ </message>
+ <message>
+ <source>The entered address does not refer to a key.</source>
+ <translation>Ing milub a address ali ya mag-refer king metung a key.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock was cancelled.</source>
+ <translation>Me-kansela ya ing pamag-unlock king wallet.</translation>
+ </message>
+ <message>
+ <source>Private key for the entered address is not available.</source>
+ <translation>Ing private key para king milub a address, ala ya.</translation>
+ </message>
+ <message>
+ <source>Message signing failed.</source>
+ <translation>Me-mali ya ing pamag-pirma king mensayi .</translation>
+ </message>
+ <message>
+ <source>Message signed.</source>
+ <translation>Me-pirman ne ing mensayi.</translation>
+ </message>
+ <message>
+ <source>The signature could not be decoded.</source>
+ <translation>Ing pirma ali ya bisang ma-decode.</translation>
+ </message>
+ <message>
+ <source>Please check the signature and try again.</source>
+ <translation>Maliaring pakilawe pasibayu ing pirma kaibat pasibayuan ya iti.</translation>
+ </message>
+ <message>
+ <source>The signature did not match the message digest.</source>
+ <translation>Ing pirma ali ya makatugma king message digest.</translation>
+ </message>
+ <message>
+ <source>Message verification failed.</source>
+ <translation>Me-mali ya ing pamag-beripika king mensayi.</translation>
+ </message>
+ <message>
+ <source>Message verified.</source>
+ <translation>Me-beripika ne ing mensayi.</translation>
+ </message>
+</context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Kapilubluban ning Bitcoin</translation>
+ </message>
+ <message>
+ <source>[testnet]</source>
+ <translation>[testnet]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ </context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>Makabuklat anggang %1</translation>
+ </message>
+ <message>
+ <source>%1/offline</source>
+ <translation>%1/offline</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/ali me-kumpirma</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 kumpirmasion</translation>
+ </message>
+ <message>
+ <source>Status</source>
+ <translation>Kabilian</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Kaaldauan</translation>
+ </message>
+ <message>
+ <source>Source</source>
+ <translation>Pikuanan</translation>
+ </message>
+ <message>
+ <source>Generated</source>
+ <translation>Megawa</translation>
+ </message>
+ <message>
+ <source>From</source>
+ <translation>Menibat</translation>
+ </message>
+ <message>
+ <source>To</source>
+ <translation>Para kang</translation>
+ </message>
+ <message>
+ <source>own address</source>
+ <translation>sariling address</translation>
+ </message>
+ <message>
+ <source>label</source>
+ <translation>label</translation>
+ </message>
+ <message>
+ <source>Credit</source>
+ <translation>Credit</translation>
+ </message>
+ <message>
+ <source>not accepted</source>
+ <translation>ali metanggap</translation>
+ </message>
+ <message>
+ <source>Debit</source>
+ <translation>Debit</translation>
+ </message>
+ <message>
+ <source>Transaction fee</source>
+ <translation>Bayad king Transaksion</translation>
+ </message>
+ <message>
+ <source>Net amount</source>
+ <translation>Alaga dareng eganagana</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Mensayi</translation>
+ </message>
+ <message>
+ <source>Comment</source>
+ <translation>Komentu</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>Debug information</source>
+ <translation>Impormasion ning Debug</translation>
+ </message>
+ <message>
+ <source>Transaction</source>
+ <translation>Transaksion</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Alaga</translation>
+ </message>
+ <message>
+ <source>true</source>
+ <translation>tutu</translation>
+ </message>
+ <message>
+ <source>false</source>
+ <translation>e tutu</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, eya matagumpeng mibalita</translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>e miya balu</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>Detalye ning Transaksion</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>Ining pane a ini magpakit yang detalyadung description ning transaksion</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Kaaldauan</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Klase</translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>Makabuklat anggang %1</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>Me-kumpirma(%1 kumpirmasion)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>Ing block a ini ali de atanggap deng aliwa pang nodes ania ali ya magsilbing tanggapan</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>Me-generate ya oneng ali ya metanggap</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Label</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Atanggap kayabe ning</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>Atanggap menibat kang</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Mipadala kang</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>Kabayaran keka</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Me-mina</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(n/a)</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>Status ning Transaksion: Itapat me babo na ning field a ini ban ipakit dala reng bilang dareng me-kumpirma na</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Aldo at oras nung kapilan me tanggap ya ing transaksion</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>Klase ning transaksion</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>Alagang milako o miragdag king balanse.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>Eganagana</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>Aldo iti</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>Paruminggung iti</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>Bulan a iti</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>Milabas a bulan</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>Banuang iti</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>Angganan...</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Atanggap kayabe ning</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Mipadala kang</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>Keng sarili mu</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Me-mina</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>Aliwa</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>Magpalub kang address o label para pantunan</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>Pekaditak a alaga</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Kopyan ing address</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Kopyan ing label</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopyan ing alaga</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>Alilan ing label</translation>
+ </message>
+ <message>
+ <source>Show transaction details</source>
+ <translation>Ipakit ing detalye ning transaksion</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Comma separated file (*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Me-kumpirma</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Kaaldauan</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Klase</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Label</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Address</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>Angga:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>para kang</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ </context>
+<context>
+ <name>WalletFrame</name>
+ </context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Magpadalang Barya</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ </context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>Pipamilian:</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>Pilinan ing data directory</translation>
+ </message>
+ <message>
+ <source>Connect to a node to retrieve peer addresses, and disconnect</source>
+ <translation>Kumunekta king note ban ayakua mula reng peer address, at mako king panga konekta</translation>
+ </message>
+ <message>
+ <source>Specify your own public address</source>
+ <translation>Sabyan me ing kekang pampublikong address</translation>
+ </message>
+ <message>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>Tumanggap command line at JSON-RPC commands</translation>
+ </message>
+ <message>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>Gumana king gulut bilang daemon at tumanggap commands</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>Gamitan ing test network</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
+ <translation>Tumanggap koneksion menibat king kilwal (default: 1 if no -proxy or -connect)</translation>
+ </message>
+ <message>
+ <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>Kapabaluan: Sobra ya katas ing makalage king -paytxfee. Ini ing maging bayad mu para king bayad na ning transaksion istung pepadala me ing transaksion a ini.</translation>
+ </message>
+ <message>
+ <source>Block creation options:</source>
+ <translation>Pipamilian king pamag-gawang block:</translation>
+ </message>
+ <message>
+ <source>Connect only to the specified node(s)</source>
+ <translation>Kumunekta mu king mepiling node(s)</translation>
+ </message>
+ <message>
+ <source>Corrupted block database detected</source>
+ <translation>Mekapansin lang me-corrupt a block database</translation>
+ </message>
+ <message>
+ <source>Do you want to rebuild the block database now?</source>
+ <translation>Buri meng buuan pasibayu ing block database ngene?</translation>
+ </message>
+ <message>
+ <source>Error initializing block database</source>
+ <translation>Kamalian king pamag-initialize king block na ning database</translation>
+ </message>
+ <message>
+ <source>Error opening block database</source>
+ <translation>Kamalian king pamag buklat king block database</translation>
+ </message>
+ <message>
+ <source>Error: Disk space is low!</source>
+ <translation>Kamalian: Mababa ne ing espasyu king disk!</translation>
+ </message>
+ <message>
+ <source>Failed to listen on any port. Use -listen=0 if you want this.</source>
+ <translation>Memali ya ing pamakiramdam kareng gang nanung port. Gamita me ini -listen=0 nung buri me ini.</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>&amp;Impormasion</translation>
+ </message>
+ <message>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>Magpadalang trace/debug info okeng console kesa keng debug.log file</translation>
+ </message>
+ <message>
+ <source>Set language, for example "de_DE" (default: system locale)</source>
+ <translation>Mamiling Amanu, alimbawa "de_DE"(default: system locale)</translation>
+ </message>
+ <message>
+ <source>Show splash screen on startup (default: 1)</source>
+ <translation>Ipalto ing splash screen keng umpisa (default: 1)</translation>
+ </message>
+ <message>
+ <source>Start minimized</source>
+ <translation>Umpisan ing pamaglati</translation>
+ </message>
+ <message>
+ <source>Transaction too large</source>
+ <translation>Maragul yang masiadu ing transaksion</translation>
+ </message>
+ <message>
+ <source>Username for JSON-RPC connections</source>
+ <translation>Username para king JSON-RPC koneksion</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Kapabaluan</translation>
+ </message>
+ <message>
+ <source>Password for JSON-RPC connections</source>
+ <translation>Password para king JSON-RPC koneksion</translation>
+ </message>
+ <message>
+ <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
+ <translation>I-execute ing command istung mialilan ya ing best block (%s in cmd is replaced by block hash)</translation>
+ </message>
+ <message>
+ <source>Upgrade wallet to latest format</source>
+ <translation>I-upgrade ing wallet king pekabayung porma</translation>
+ </message>
+ <message>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>I-scan pasibayu ing block chain para kareng mauaualang transaksion</translation>
+ </message>
+ <message>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>Gumamit OpenSSL(https) para king JSON-RPC koneksion</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>Ining saup a mensayi</translation>
+ </message>
+ <message>
+ <source>Allow DNS lookups for -addnode, -seednode and -connect</source>
+ <translation>Payagan ing pamaglawe DNS para king -addnode, -seednode and -connect</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>Lo-load da ne ing address...</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>Me-mali ya ing pamag-load king wallet.dat: Me-corrupt ya ing wallet</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>Me-mali ya ing pamag-load king wallet.dat</translation>
+ </message>
+ <message>
+ <source>Invalid -proxy address: '%s'</source>
+ <translation>Ali katanggap-tanggap a -proxy addresss: '%s'</translation>
+ </message>
+ <message>
+ <source>Unknown network specified in -onlynet: '%s'</source>
+ <translation>E kilalang network ing mepili king -onlynet: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -bind address: '%s'</source>
+ <translation>Eya me-resolve ing -bind address: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -externalip address: '%s'</source>
+ <translation>Eya me-resolve ing -externalip address: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Eya maliari ing alaga keng -paytxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>Kulang a pondo</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>Lo-load dane ing block index...</translation>
+ </message>
+ <message>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>Magdagdag a node ban kumunekta at subuknan apanatili yang makabuklat ing koneksion</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>Lo-load dane ing wallet...</translation>
+ </message>
+ <message>
+ <source>Cannot downgrade wallet</source>
+ <translation>Ali ya magsilbing i-downgrade ing wallet</translation>
+ </message>
+ <message>
+ <source>Cannot write default address</source>
+ <translation>Eya misulat ing default address</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>I-scan deng pasibayu...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>Yari ne ing pamag-load</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Mali</translation>
+ </message>
+</context>
+</TS> \ 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 0000000000..8e4ee84965
--- /dev/null
+++ b/src/qt/locale/bitcoin_pl.ts
@@ -0,0 +1,3564 @@
+<TS language="pl" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Right-click to edit address or label</source>
+ <translation>Kliknij prawy przycisk aby edytować adres lub etykietę</translation>
+ </message>
+ <message>
+ <source>Create a new address</source>
+ <translation>Utwórz nowy adres</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>&amp;Nowy</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Skopiuj aktualnie wybrany adres do schowka</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>&amp;Kopiuj</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>Z&amp;amknij</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>&amp;Kopiuj adres</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>Usuń zaznaczony adres z listy</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Eksportuj dane z aktywnej karty do pliku</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Eksportuj</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;Usuń</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>Wybierz adres, na który chcesz wysłać monety</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>Wybierz adres, na który chcesz otrzymać monety</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>W&amp;ybierz</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>Adres wysyłania</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>Adres odbiorczy</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>Tutaj znajdują się adresy Bitcoin na które wysyłasz płatności. Zawsze sprawdzaj ilość i adres odbiorcy przed wysyłką monet.</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>To twoje adresy Bitcoin, na które otrzymujesz płatności. Zaleca się używanie nowych adresów odbiorczych dla każdej transakcji.</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>Kopiuj &amp;Etykietę</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>&amp;Modyfikuj</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>Eksportuj listę adresową</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>CSV (rozdzielany przecinkami)</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Błąd przy próbie eksportu</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the address list to %1. Please try again.</source>
+ <translation>Wystąpił błąd podczas próby zapisu listy adresów %1. Proszę spróbować ponownie.</translation>
+ </message>
+</context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Etykieta</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adres</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(brak etykiety)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Passphrase Dialog</source>
+ <translation>Okienko Hasła</translation>
+ </message>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Wpisz hasło</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Nowe hasło</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Powtórz nowe hasło</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>Zaszyfruj portfel</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>Ta operacja wymaga hasła do portfela ażeby odblokować portfel.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Odblokuj portfel</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>Ta operacja wymaga hasła do portfela ażeby odszyfrować portfel.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>Odszyfruj portfel</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>Zmień hasło</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>Potwierdź szyfrowanie portfela</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>Uwaga: Jeśli zaszyfrujesz swój portfel i zgubisz hasło to &lt;b&gt;STRACISZ WSZYSTKIE SWOJE BITCOIN'Y&lt;/b&gt;!</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>Jesteś pewien, że chcesz zaszyfrować swój portfel?</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core 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.</source>
+ <translation>Program Bitcoin Core 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.</translation>
+ </message>
+ <message>
+ <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
+ <translation>WAŻNE: Wszystkie wykonane wcześniej kopie pliku portfela powinny być zamienione na nowe, szyfrowane pliki. Z powodów bezpieczeństwa, poprzednie kopie nieszyfrowanych plików portfela staną się bezużyteczne jak tylko zaczniesz korzystać z nowego, szyfrowanego portfela.</translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>Uwaga: Klawisz Caps Lock jest włączony!</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>Portfel zaszyfrowany</translation>
+ </message>
+ <message>
+ <source>Enter the new passphrase to the wallet.&lt;br/&gt;Please use a passphrase of &lt;b&gt;ten or more random characters&lt;/b&gt;, or &lt;b&gt;eight or more words&lt;/b&gt;.</source>
+ <translation>Wprowadź nowe hasło do portfela.&lt;br/&gt;Proszę używać hasła złożonego z &lt;b&gt;10 lub więcej losowych znaków&lt;/b&gt; lub &lt;b&gt;ośmiu lub więcej słów.&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Enter the old passphrase and new passphrase to the wallet.</source>
+ <translation>Podaj stare i nowe hasło do portfela.</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>Szyfrowanie portfela nie powiodło się</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>Szyfrowanie portfela nie powiodło się z powodu wewnętrznego błędu. Twój portfel nie został zaszyfrowany.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>Podane hasła nie są takie same.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>Odblokowanie portfela nie powiodło się</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>Wprowadzone hasło do odszyfrowania portfela jest niepoprawne.</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>Odszyfrowanie portfela nie powiodło się</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>Hasło portfela zostało pomyślnie zmienione.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>Podpisz wiado&amp;mość...</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>Synchronizacja z siecią...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>P&amp;odsumowanie</translation>
+ </message>
+ <message>
+ <source>Node</source>
+ <translation>Węzeł</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>Pokazuje ogólny widok portfela</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Transakcje</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>Przeglądaj historię transakcji</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>&amp;Zakończ</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>Zamknij program</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>O &amp;Qt</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>Pokazuje informacje o Qt</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;Opcje...</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>Zaszyfruj Portf&amp;el</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>Wykonaj kopię zapasową...</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>&amp;Zmień hasło...</translation>
+ </message>
+ <message>
+ <source>&amp;Sending addresses...</source>
+ <translation>Adresy wysyłania...</translation>
+ </message>
+ <message>
+ <source>&amp;Receiving addresses...</source>
+ <translation>Adresy odbioru...</translation>
+ </message>
+ <message>
+ <source>Open &amp;URI...</source>
+ <translation>Otwórz URI...</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core client</source>
+ <translation>Rdzeń klienta Bitcoin</translation>
+ </message>
+ <message>
+ <source>Importing blocks from disk...</source>
+ <translation>Importowanie bloków z dysku...</translation>
+ </message>
+ <message>
+ <source>Reindexing blocks on disk...</source>
+ <translation>Ponowne indeksowanie bloków na dysku...</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>Wyślij monety na adres Bitcoin</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>Zapasowy portfel w innej lokalizacji</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Zmień hasło użyte do szyfrowania portfela</translation>
+ </message>
+ <message>
+ <source>&amp;Debug window</source>
+ <translation>&amp;Okno debugowania</translation>
+ </message>
+ <message>
+ <source>Open debugging and diagnostic console</source>
+ <translation>Otwórz konsolę debugowania i diagnostyki</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>&amp;Zweryfikuj wiadomość...</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>Portfel</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>Wyślij</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>Odbie&amp;rz</translation>
+ </message>
+ <message>
+ <source>Show information about Bitcoin Core</source>
+ <translation>Pokaż informacje o Rdzeniu Bitcoin</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>&amp;Pokaż / Ukryj</translation>
+ </message>
+ <message>
+ <source>Show or hide the main Window</source>
+ <translation>Pokazuje lub ukrywa główne okno</translation>
+ </message>
+ <message>
+ <source>Encrypt the private keys that belong to your wallet</source>
+ <translation>Szyfruj klucze prywatne, które są w Twoim portfelu</translation>
+ </message>
+ <message>
+ <source>Sign messages with your Bitcoin addresses to prove you own them</source>
+ <translation>Podpisz wiadomości swoim adresem aby udowodnić jego posiadanie</translation>
+ </message>
+ <message>
+ <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source>
+ <translation>Zweryfikuj wiadomość, aby upewnić się, że została podpisana podanym adresem Bitcoin.</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;Plik</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>P&amp;referencje</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>Pomo&amp;c</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>Pasek zakładek</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Rdzeń Bitcoin</translation>
+ </message>
+ <message>
+ <source>Request payments (generates QR codes and bitcoin: URIs)</source>
+ <translation>Żądaj płatności (generuje kod QR oraz bitcoin URI)</translation>
+ </message>
+ <message>
+ <source>&amp;About Bitcoin Core</source>
+ <translation>&amp;O Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Modify configuration options for Bitcoin Core</source>
+ <translation>Zmień opcje konfiguracji dla Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Show the list of used sending addresses and labels</source>
+ <translation>Pokaż listę adresów i etykiet użytych do wysyłania</translation>
+ </message>
+ <message>
+ <source>Show the list of used receiving addresses and labels</source>
+ <translation>Pokaż listę adresów i etykiet użytych do odbierania</translation>
+ </message>
+ <message>
+ <source>Open a bitcoin: URI or payment request</source>
+ <translation>Otwórz URI bitcoin: lub żądanie zapłaty</translation>
+ </message>
+ <message>
+ <source>&amp;Command-line options</source>
+ <translation>&amp;Opcje linii komend</translation>
+ </message>
+ <message>
+ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
+ <translation>Pokaż pomoc Rdzenia Bitcoin, aby zobaczyć listę wszystkich opcji linii poleceń</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n active connection(s) to Bitcoin network</source>
+ <translation><numerusform>%n aktywnych połączeń do sieci Bitcoin</numerusform><numerusform>%n aktywnych połączeń do sieci Bitcoin</numerusform><numerusform>%n aktywnych połączeń do sieci Bitcoin</numerusform></translation>
+ </message>
+ <message>
+ <source>No block source available...</source>
+ <translation>Brak dostępnych źródeł bloków...</translation>
+ </message>
+ <message numerus="yes">
+ <source>Processed %n block(s) of transaction history.</source>
+ <translation><numerusform>Przetworzono %n bloków historii transakcji.</numerusform><numerusform>Przetworzono %n bloków historii transakcji.</numerusform><numerusform>Przetworzono %n bloków historii transakcji.</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n hour(s)</source>
+ <translation><numerusform>%n godzin</numerusform><numerusform>%n godzin</numerusform><numerusform>%n godzin</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n week(s)</source>
+ <translation><numerusform>%n tygodni</numerusform><numerusform>%n tygodni</numerusform><numerusform>%n tygodni</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 and %2</source>
+ <translation>%1 i %2</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n year(s)</source>
+ <translation><numerusform>%n lat</numerusform><numerusform>%n lat</numerusform><numerusform>%n lat</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 behind</source>
+ <translation>%1 wstecz</translation>
+ </message>
+ <message>
+ <source>Last received block was generated %1 ago.</source>
+ <translation>Ostatni otrzymany blok został wygenerowany %1 temu.</translation>
+ </message>
+ <message>
+ <source>Transactions after this will not yet be visible.</source>
+ <translation>Transakcje po tym momencie nie będą jeszcze widoczne.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Błąd</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Ostrzeżenie</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Informacja</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>Aktualny</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>Synchronizuję się...</translation>
+ </message>
+ <message>
+ <source>Date: %1
+</source>
+ <translation>Data: %1
+</translation>
+ </message>
+ <message>
+ <source>Amount: %1
+</source>
+ <translation>Kwota: %1
+</translation>
+ </message>
+ <message>
+ <source>Type: %1
+</source>
+ <translation>Typ: %1
+</translation>
+ </message>
+ <message>
+ <source>Label: %1
+</source>
+ <translation>Etykieta: %1
+</translation>
+ </message>
+ <message>
+ <source>Address: %1
+</source>
+ <translation>Adres: %1
+</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>Transakcja wysłana</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>Transakcja przychodząca</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>Portfel jest &lt;b&gt;zaszyfrowany&lt;/b&gt; i obecnie &lt;b&gt;odblokowany&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>Portfel jest &lt;b&gt;zaszyfrowany&lt;/b&gt; i obecnie &lt;b&gt;zablokowany&lt;/b&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <source>Network Alert</source>
+ <translation>Komunikat Sieci</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Coin Selection</source>
+ <translation>Wybór monet</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Ilość:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Bajtów:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Kwota:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Priorytet:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Opłata:</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Pył:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Po opłacie:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Reszta:</translation>
+ </message>
+ <message>
+ <source>(un)select all</source>
+ <translation>Zaznacz/Odznacz wszystko</translation>
+ </message>
+ <message>
+ <source>Tree mode</source>
+ <translation>Widok drzewa</translation>
+ </message>
+ <message>
+ <source>List mode</source>
+ <translation>Widok listy</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Kwota</translation>
+ </message>
+ <message>
+ <source>Received with label</source>
+ <translation>Otrzymano z opisem</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>Otrzymano z adresem</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Confirmations</source>
+ <translation>Potwierdzenia</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Potwierdzony</translation>
+ </message>
+ <message>
+ <source>Priority</source>
+ <translation>Priorytet</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Kopiuj adres</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Kopiuj etykietę</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopiuj kwotę</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Skopiuj ID transakcji</translation>
+ </message>
+ <message>
+ <source>Lock unspent</source>
+ <translation>Zablokuj niewydane</translation>
+ </message>
+ <message>
+ <source>Unlock unspent</source>
+ <translation>Odblokuj niewydane</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Skopiuj ilość</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Skopiuj opłatę</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Skopiuj ilość po opłacie</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Skopiuj ilość bajtów</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Skopiuj priorytet</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Kopiuj kurz</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Skopiuj resztę</translation>
+ </message>
+ <message>
+ <source>highest</source>
+ <translation>najwyższa</translation>
+ </message>
+ <message>
+ <source>higher</source>
+ <translation>wyższa</translation>
+ </message>
+ <message>
+ <source>high</source>
+ <translation>wysoka</translation>
+ </message>
+ <message>
+ <source>medium-high</source>
+ <translation>średnio wysoki</translation>
+ </message>
+ <message>
+ <source>medium</source>
+ <translation>średnia</translation>
+ </message>
+ <message>
+ <source>low-medium</source>
+ <translation>średnio niski</translation>
+ </message>
+ <message>
+ <source>low</source>
+ <translation>niski</translation>
+ </message>
+ <message>
+ <source>lower</source>
+ <translation>niższy</translation>
+ </message>
+ <message>
+ <source>lowest</source>
+ <translation>najniższy</translation>
+ </message>
+ <message>
+ <source>(%1 locked)</source>
+ <translation>(%1 zablokowane)</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>żaden</translation>
+ </message>
+ <message>
+ <source>This label turns red if the transaction size is greater than 1000 bytes.</source>
+ <translation>Ta etykieta staje się czerwona, kiedy transakcja jest większa niż 1000 bajtów.</translation>
+ </message>
+ <message>
+ <source>This label turns red if the priority is smaller than "medium".</source>
+ <translation>Ta etykieta jest czerwona, jeżeli priorytet jest mniejszy niż "średni"</translation>
+ </message>
+ <message>
+ <source>This label turns red if any recipient receives an amount smaller than %1.</source>
+ <translation>Etykieta staje się czerwona kiedy którykolwiek odbiorca otrzymuje kwotę mniejszą niż %1.</translation>
+ </message>
+ <message>
+ <source>Can vary +/- %1 satoshi(s) per input.</source>
+ <translation>Waha się +/- %1 satoshi na wejście.</translation>
+ </message>
+ <message>
+ <source>yes</source>
+ <translation>tak</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>nie</translation>
+ </message>
+ <message>
+ <source>This means a fee of at least %1 per kB is required.</source>
+ <translation>Oznacza to wymaganą opłatę minimum %1 na kB.</translation>
+ </message>
+ <message>
+ <source>Can vary +/- 1 byte per input.</source>
+ <translation>Waha się +/- 1 bajt na wejście.</translation>
+ </message>
+ <message>
+ <source>Transactions with higher priority are more likely to get included into a block.</source>
+ <translation>Transakcje o wyższym priorytecie zwykle szybciej zostają dołączone do bloku.</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(brak etykiety)</translation>
+ </message>
+ <message>
+ <source>change from %1 (%2)</source>
+ <translation>reszta z %1 (%2)</translation>
+ </message>
+ <message>
+ <source>(change)</source>
+ <translation>(reszta)</translation>
+ </message>
+</context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>Zmień adres</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>&amp;Etykieta</translation>
+ </message>
+ <message>
+ <source>The label associated with this address list entry</source>
+ <translation>Etykieta skojarzona z tym wpisem na liście adresów</translation>
+ </message>
+ <message>
+ <source>The address associated with this address list entry. This can only be modified for sending addresses.</source>
+ <translation>Ten adres jest skojarzony z wpisem na liście adresów. Może być zmodyfikowany jedynie dla adresów wysyłających.</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;Adres</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>Nowy adres otrzymywania</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>Nowy adres wysyłania</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>Zmień adres odbioru</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>Zmień adres wysyłania</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>Wprowadzony adres "%1" już istnieje w książce adresowej.</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is not a valid Bitcoin address.</source>
+ <translation>Wprowadzony adres "%1" nie jest poprawnym adresem Bitcoin.</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>Nie można było odblokować portfela.</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>Tworzenie nowego klucza nie powiodło się.</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ <message>
+ <source>A new data directory will be created.</source>
+ <translation>Będzie utworzony nowy folder danych.</translation>
+ </message>
+ <message>
+ <source>name</source>
+ <translation>nazwa</translation>
+ </message>
+ <message>
+ <source>Directory already exists. Add %1 if you intend to create a new directory here.</source>
+ <translation>Katalog już istnieje. Dodaj %1 jeśli masz zamiar utworzyć tutaj nowy katalog.</translation>
+ </message>
+ <message>
+ <source>Path already exists, and is not a directory.</source>
+ <translation>Ścieżka już istnieje i nie jest katalogiem.</translation>
+ </message>
+ <message>
+ <source>Cannot create data directory here.</source>
+ <translation>Nie można było tutaj utworzyć folderu.</translation>
+ </message>
+</context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Rdzeń Bitcoin</translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>wersja</translation>
+ </message>
+ <message>
+ <source>(%1-bit)</source>
+ <translation>(%1-bit)</translation>
+ </message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>O Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Command-line options</source>
+ <translation>Opcje konsoli</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>Użycie:</translation>
+ </message>
+ <message>
+ <source>command-line options</source>
+ <translation>opcje konsoli</translation>
+ </message>
+</context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Welcome</source>
+ <translation>Witaj</translation>
+ </message>
+ <message>
+ <source>Welcome to Bitcoin Core.</source>
+ <translation>Witam w Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</source>
+ <translation>Ponieważ jest to pierwsze uruchomienie programu, możesz wybrać gdzie Bitcoin Core będzie przechowywał swoje dane.</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory.</source>
+ <translation>Program pobierze i będzie przechowywał kopię łańcucha bloków Bitcoin. W wybranym katalogu musi być przynajmniej %1GB miejsca, a z czasem ilość danych będzie rosła. Portfel będzie przechowywany w tym samym katalogu.</translation>
+ </message>
+ <message>
+ <source>Use the default data directory</source>
+ <translation>Użyj domyślnego folderu danych</translation>
+ </message>
+ <message>
+ <source>Use a custom data directory:</source>
+ <translation>Użyj wybranego folderu dla danych</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Rdzeń Bitcoin</translation>
+ </message>
+ <message>
+ <source>Error: Specified data directory "%1" cannot be created.</source>
+ <translation>Błąd: Określony folder danych "%1" nie mógł zostać utworzony.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Błąd</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n GB of free space available</source>
+ <translation><numerusform>%n GB dostępnego wolnego miejsca</numerusform><numerusform>%n GB dostępnego wolnego miejsca</numerusform><numerusform>%n GB dostępnego wolnego miejsca</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>(of %n GB needed)</source>
+ <translation><numerusform>(z %n GB potrzebnych)</numerusform><numerusform>(z %n GB potrzebnych)</numerusform><numerusform>(z %n GB potrzebnych)</numerusform></translation>
+ </message>
+</context>
+<context>
+ <name>OpenURIDialog</name>
+ <message>
+ <source>Open URI</source>
+ <translation>Otwórz URI</translation>
+ </message>
+ <message>
+ <source>Open payment request from URI or file</source>
+ <translation>Otwórz żądanie zapłaty z URI lub pliku</translation>
+ </message>
+ <message>
+ <source>URI:</source>
+ <translation>URI:</translation>
+ </message>
+ <message>
+ <source>Select payment request file</source>
+ <translation>Otwórz żądanie zapłaty z pliku</translation>
+ </message>
+ <message>
+ <source>Select payment request file to open</source>
+ <translation>Wybierz plik żądania zapłaty do otwarcia</translation>
+ </message>
+</context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>Opcje</translation>
+ </message>
+ <message>
+ <source>&amp;Main</source>
+ <translation>Główne</translation>
+ </message>
+ <message>
+ <source>Size of &amp;database cache</source>
+ <translation>Wielkość bufora bazy &amp;danych</translation>
+ </message>
+ <message>
+ <source>MB</source>
+ <translation>MB</translation>
+ </message>
+ <message>
+ <source>Number of script &amp;verification threads</source>
+ <translation>Liczba wątków &amp;weryfikacji skryptu</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside</source>
+ <translation>Akceptuj połączenia z zewnątrz</translation>
+ </message>
+ <message>
+ <source>Allow incoming connections</source>
+ <translation>Zezwól na połączenia przychodzące</translation>
+ </message>
+ <message>
+ <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
+ <translation>Adres IP serwera proxy (np. IPv4: 127.0.0.1 / IPv6: ::1)</translation>
+ </message>
+ <message>
+ <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source>
+ <translation>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.</translation>
+ </message>
+ <message>
+ <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source>
+ <translation>Można tu ustawić język interfejsu uzytkownika. Żeby ustawienie przyniosło skutek trzeba uruchomić ponownie Bitcoin.</translation>
+ </message>
+ <message>
+ <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source>
+ <translation>Zewnętrzne URL podglądu transakcji (np. eksplorator bloków), które będą wyświetlały się w menu kontekstowym, w zakładce transakcji. %s będzie zamieniany w adresie na hash transakcji. Oddziel wiele adresów pionową kreską |.</translation>
+ </message>
+ <message>
+ <source>Third party transaction URLs</source>
+ <translation>Zewnętrzny URL podglądu transakcji</translation>
+ </message>
+ <message>
+ <source>Active command-line options that override above options:</source>
+ <translation>Aktywne opcje linii komend, które nadpisują powyższe opcje:</translation>
+ </message>
+ <message>
+ <source>Reset all client options to default.</source>
+ <translation>Przywróć wszystkie domyślne ustawienia klienta.</translation>
+ </message>
+ <message>
+ <source>&amp;Reset Options</source>
+ <translation>Z&amp;resetuj Ustawienia</translation>
+ </message>
+ <message>
+ <source>&amp;Network</source>
+ <translation>&amp;Sieć</translation>
+ </message>
+ <message>
+ <source>Automatically start Bitcoin Core after logging in to the system.</source>
+ <translation>Automatycznie uruchamia Bitcoin po zalogowaniu do systemu.</translation>
+ </message>
+ <message>
+ <source>&amp;Start Bitcoin Core on system login</source>
+ <translation>Uruchamiaj Bitcoin wraz z zalogowaniem do &amp;systemu</translation>
+ </message>
+ <message>
+ <source>(0 = auto, &lt;0 = leave that many cores free)</source>
+ <translation>(0 = automatycznie, &lt;0 = zostaw tyle wolnych rdzeni)</translation>
+ </message>
+ <message>
+ <source>W&amp;allet</source>
+ <translation>Portfel</translation>
+ </message>
+ <message>
+ <source>Expert</source>
+ <translation>Ekspert</translation>
+ </message>
+ <message>
+ <source>Enable coin &amp;control features</source>
+ <translation>Włącz funk&amp;cje kontoli monet</translation>
+ </message>
+ <message>
+ <source>If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.</source>
+ <translation>Jeżeli wyłączysz możliwość wydania niezatwierdzonej wydanej reszty, reszta z transakcji nie będzie mogła zostać wykorzystana, dopóki ta transakcja nie będzie miała przynajmniej jednego potwierdzenia. To także ma wpływ na obliczanie Twojego salda.</translation>
+ </message>
+ <message>
+ <source>&amp;Spend unconfirmed change</source>
+ <translation>Wydaj niepotwierdzoną re&amp;sztę</translation>
+ </message>
+ <message>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>Automatycznie otwiera port klienta Bitcoin na routerze. Ta opcja dzieła tylko jeśli twój router wspiera UPnP i jest ono włączone.</translation>
+ </message>
+ <message>
+ <source>Map port using &amp;UPnP</source>
+ <translation>Mapuj port używając &amp;UPnP</translation>
+ </message>
+ <message>
+ <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
+ <translation>Połącz się z siecią Bitcoin poprzez proxy SOCKS5.</translation>
+ </message>
+ <message>
+ <source>&amp;Connect through SOCKS5 proxy (default proxy):</source>
+ <translation>Połącz przez proxy SO&amp;CKS5 (domyślne proxy):</translation>
+ </message>
+ <message>
+ <source>Proxy &amp;IP:</source>
+ <translation>Proxy &amp;IP: </translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>&amp;Port:</translation>
+ </message>
+ <message>
+ <source>Port of the proxy (e.g. 9050)</source>
+ <translation>Port proxy (np. 9050)</translation>
+ </message>
+ <message>
+ <source>&amp;Window</source>
+ <translation>&amp;Okno</translation>
+ </message>
+ <message>
+ <source>Show only a tray icon after minimizing the window.</source>
+ <translation>Pokazuj tylko ikonę przy zegarku po zminimalizowaniu okna.</translation>
+ </message>
+ <message>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>&amp;Minimalizuj do paska przy zegarku zamiast do paska zadań</translation>
+ </message>
+ <message>
+ <source>M&amp;inimize on close</source>
+ <translation>M&amp;inimalizuj przy zamknięciu</translation>
+ </message>
+ <message>
+ <source>&amp;Display</source>
+ <translation>&amp;Wyświetlanie</translation>
+ </message>
+ <message>
+ <source>User Interface &amp;language:</source>
+ <translation>Język &amp;Użytkownika:</translation>
+ </message>
+ <message>
+ <source>&amp;Unit to show amounts in:</source>
+ <translation>&amp;Jednostka pokazywana przy kwocie:</translation>
+ </message>
+ <message>
+ <source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
+ <translation>Wybierz podział jednostki pokazywany w interfejsie oraz podczas wysyłania monet</translation>
+ </message>
+ <message>
+ <source>Whether to show coin control features or not.</source>
+ <translation>Wybierz pokazywanie lub nie funkcji kontroli monet.</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>&amp;OK</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>&amp;Anuluj</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>domyślny</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>żaden</translation>
+ </message>
+ <message>
+ <source>Confirm options reset</source>
+ <translation>Potwierdź reset ustawień</translation>
+ </message>
+ <message>
+ <source>Client restart required to activate changes.</source>
+ <translation>Wymagany restart programu, aby uaktywnić zmiany.</translation>
+ </message>
+ <message>
+ <source>Client will be shut down. Do you want to proceed?</source>
+ <translation>Program zostanie wyłączony. Czy chcesz kontynuować?</translation>
+ </message>
+ <message>
+ <source>This change would require a client restart.</source>
+ <translation>Ta zmiana może wymagać ponownego uruchomienia klienta.</translation>
+ </message>
+ <message>
+ <source>The supplied proxy address is invalid.</source>
+ <translation>Adres podanego proxy jest nieprawidłowy</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>Formularz</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>Wyświetlana informacja może być nieaktualna. Twój portfel synchronizuje się automatycznie z siecią bitcoin, zaraz po tym jak uzyskano połączenie, ale proces ten nie został jeszcze ukończony.</translation>
+ </message>
+ <message>
+ <source>Watch-only:</source>
+ <translation>Tylko podglądaj:</translation>
+ </message>
+ <message>
+ <source>Available:</source>
+ <translation>Dostępne:</translation>
+ </message>
+ <message>
+ <source>Your current spendable balance</source>
+ <translation>Twoje obecne saldo</translation>
+ </message>
+ <message>
+ <source>Pending:</source>
+ <translation>W toku:</translation>
+ </message>
+ <message>
+ <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source>
+ <translation>Suma transakcji, które nie zostały jeszcze potwierdzone, a które nie zostały wliczone do twojego obecnego salda</translation>
+ </message>
+ <message>
+ <source>Immature:</source>
+ <translation>Niedojrzały: </translation>
+ </message>
+ <message>
+ <source>Mined balance that has not yet matured</source>
+ <translation>Balans wydobytych monet, które jeszcze nie dojrzały</translation>
+ </message>
+ <message>
+ <source>Balances</source>
+ <translation>Salda</translation>
+ </message>
+ <message>
+ <source>Total:</source>
+ <translation>Wynosi ogółem:</translation>
+ </message>
+ <message>
+ <source>Your current total balance</source>
+ <translation>Twoje obecne saldo</translation>
+ </message>
+ <message>
+ <source>Your current balance in watch-only addresses</source>
+ <translation>Twoje obecne saldo na podglądanym adresie </translation>
+ </message>
+ <message>
+ <source>Spendable:</source>
+ <translation>Możliwe do wydania:</translation>
+ </message>
+ <message>
+ <source>Recent transactions</source>
+ <translation>Ostatnie transakcje</translation>
+ </message>
+ <message>
+ <source>Unconfirmed transactions to watch-only addresses</source>
+ <translation>Niepotwierdzone transakcje na podglądanych adresach</translation>
+ </message>
+ <message>
+ <source>Mined balance in watch-only addresses that has not yet matured</source>
+ <translation>Wykopane monety na podglądanych adresach które jeszcze nie dojrzały</translation>
+ </message>
+ <message>
+ <source>Current total balance in watch-only addresses</source>
+ <translation>Łączna kwota na podglądanych adresach</translation>
+ </message>
+</context>
+<context>
+ <name>PaymentServer</name>
+ <message>
+ <source>URI handling</source>
+ <translation>Obsługa URI</translation>
+ </message>
+ <message>
+ <source>Invalid payment address %1</source>
+ <translation>błędny adres płatności %1</translation>
+ </message>
+ <message>
+ <source>Payment request rejected</source>
+ <translation>Żądanie płatności odrzucone</translation>
+ </message>
+ <message>
+ <source>Payment request network doesn't match client network.</source>
+ <translation>Sieć żądania płatności nie odpowiada sieci klienta.</translation>
+ </message>
+ <message>
+ <source>Payment request is not initialized.</source>
+ <translation>Żądanie płatności nie jest zainicjowane.</translation>
+ </message>
+ <message>
+ <source>Requested payment amount of %1 is too small (considered dust).</source>
+ <translation>Żądana kwota %1 jest za niska (uznano za kurz).</translation>
+ </message>
+ <message>
+ <source>Payment request error</source>
+ <translation>Błąd żądania płatności</translation>
+ </message>
+ <message>
+ <source>Cannot start bitcoin: click-to-pay handler</source>
+ <translation>Nie można uruchomić protokołu bitcoin: kliknij-by-zapłacić</translation>
+ </message>
+ <message>
+ <source>Payment request fetch URL is invalid: %1</source>
+ <translation>URL pobrania żądania zapłaty jest nieprawidłowe: %1</translation>
+ </message>
+ <message>
+ <source>URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source>
+ <translation>URI nie może zostać przetworzony! Może to być spowodowane nieprawidłowym adresem Bitcoin lub uszkodzonymi parametrami URI.</translation>
+ </message>
+ <message>
+ <source>Payment request file handling</source>
+ <translation>Przechwytywanie plików żądania płatności</translation>
+ </message>
+ <message>
+ <source>Payment request file cannot be read! This can be caused by an invalid payment request file.</source>
+ <translation>Plików żądania płatności nie może zostać odczytany. Mogło to być spowodowane nieprawidłowym plikiem żądania płatności.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>Żądanie płatności upłynęło.</translation>
+ </message>
+ <message>
+ <source>Unverified payment requests to custom payment scripts are unsupported.</source>
+ <translation>Niezweryfikowane żądania płatności do własnych skryptów płatności są niewspierane.</translation>
+ </message>
+ <message>
+ <source>Invalid payment request.</source>
+ <translation>Nieprawidłowe żądanie płatności</translation>
+ </message>
+ <message>
+ <source>Refund from %1</source>
+ <translation>Zwrot z %1</translation>
+ </message>
+ <message>
+ <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source>
+ <translation>Żądanie płatności %1 jest zbyt duże (%2 bajtów, dozwolone %3 bajtów).</translation>
+ </message>
+ <message>
+ <source>Payment request DoS protection</source>
+ <translation>Zabezpieczenie żądania płatności przed atakiem DoS</translation>
+ </message>
+ <message>
+ <source>Error communicating with %1: %2</source>
+ <translation>Błąd komunikacji z %1 : %2</translation>
+ </message>
+ <message>
+ <source>Payment request cannot be parsed!</source>
+ <translation>Żądanie płatności nie może zostać przetworzone.</translation>
+ </message>
+ <message>
+ <source>Bad response from server %1</source>
+ <translation>Błędna odpowiedź z serwera %1</translation>
+ </message>
+ <message>
+ <source>Payment acknowledged</source>
+ <translation>Płatność potwierdzona</translation>
+ </message>
+ <message>
+ <source>Network request error</source>
+ <translation>Błąd żądania sieci</translation>
+ </message>
+</context>
+<context>
+ <name>PeerTableModel</name>
+ <message>
+ <source>User Agent</source>
+ <translation>Aplikacja kliencka</translation>
+ </message>
+ <message>
+ <source>Node/Service</source>
+ <translation>Węzeł/Usługi</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Czas odpowiedzi</translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>Kwota</translation>
+ </message>
+ <message>
+ <source>Enter a Bitcoin address (e.g. %1)</source>
+ <translation>Wprowadź adres Bitcoin (np. %1)</translation>
+ </message>
+ <message>
+ <source>%1 d</source>
+ <translation>%1 d</translation>
+ </message>
+ <message>
+ <source>%1 h</source>
+ <translation>%1 h</translation>
+ </message>
+ <message>
+ <source>%1 m</source>
+ <translation>%1 m</translation>
+ </message>
+ <message>
+ <source>%1 s</source>
+ <translation>%1 s</translation>
+ </message>
+ <message>
+ <source>None</source>
+ <translation>Żaden</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>NIEDOSTĘPNE</translation>
+ </message>
+ <message>
+ <source>%1 ms</source>
+ <translation>%1 ms</translation>
+ </message>
+</context>
+<context>
+ <name>QRImageWidget</name>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Zapisz obraz...</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Image</source>
+ <translation>&amp;Kopiuj obraz</translation>
+ </message>
+ <message>
+ <source>Save QR Code</source>
+ <translation>Zapisz Kod QR</translation>
+ </message>
+ <message>
+ <source>PNG Image (*.png)</source>
+ <translation>Obraz PNG (*.png)</translation>
+ </message>
+</context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>Client name</source>
+ <translation>Nazwa klienta</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>NIEDOSTĘPNE</translation>
+ </message>
+ <message>
+ <source>Client version</source>
+ <translation>Wersja klienta</translation>
+ </message>
+ <message>
+ <source>&amp;Information</source>
+ <translation>&amp;Informacje</translation>
+ </message>
+ <message>
+ <source>Debug window</source>
+ <translation>Okno debugowania</translation>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>Ogólne</translation>
+ </message>
+ <message>
+ <source>Using OpenSSL version</source>
+ <translation>Używana wersja OpenSSL</translation>
+ </message>
+ <message>
+ <source>Using BerkeleyDB version</source>
+ <translation>Używana wersja BerkeleyDB </translation>
+ </message>
+ <message>
+ <source>Startup time</source>
+ <translation>Czas uruchomienia</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Sieć</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>Nazwa</translation>
+ </message>
+ <message>
+ <source>Number of connections</source>
+ <translation>Liczba połączeń</translation>
+ </message>
+ <message>
+ <source>Block chain</source>
+ <translation>Łańcuch bloków</translation>
+ </message>
+ <message>
+ <source>Current number of blocks</source>
+ <translation>Aktualna liczba bloków</translation>
+ </message>
+ <message>
+ <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source>
+ <translation>Otwórz plik logowania debugowania Bitcoin Core z obecnego katalogu z danymi. Może to potrwać kilka sekund przy większych plikach.</translation>
+ </message>
+ <message>
+ <source>Received</source>
+ <translation>Otrzymane</translation>
+ </message>
+ <message>
+ <source>Sent</source>
+ <translation>Wysłane</translation>
+ </message>
+ <message>
+ <source>&amp;Peers</source>
+ <translation>&amp;Węzły</translation>
+ </message>
+ <message>
+ <source>Select a peer to view detailed information.</source>
+ <translation>Wybierz węzeł żeby zobaczyć szczegóły.</translation>
+ </message>
+ <message>
+ <source>Direction</source>
+ <translation>Kierunek</translation>
+ </message>
+ <message>
+ <source>Version</source>
+ <translation>Wersja</translation>
+ </message>
+ <message>
+ <source>User Agent</source>
+ <translation>Aplikacja kliencka</translation>
+ </message>
+ <message>
+ <source>Services</source>
+ <translation>Usługi</translation>
+ </message>
+ <message>
+ <source>Starting Height</source>
+ <translation>Początkowa wysokość</translation>
+ </message>
+ <message>
+ <source>Sync Height</source>
+ <translation>Zsynchronizowana wysokość</translation>
+ </message>
+ <message>
+ <source>Ban Score</source>
+ <translation>Punkty karne</translation>
+ </message>
+ <message>
+ <source>Connection Time</source>
+ <translation>Czas połączenia</translation>
+ </message>
+ <message>
+ <source>Last Send</source>
+ <translation>Ostatnio wysłano</translation>
+ </message>
+ <message>
+ <source>Last Receive</source>
+ <translation>Ostatnio odebrano</translation>
+ </message>
+ <message>
+ <source>Bytes Sent</source>
+ <translation>Bajtów wysłano</translation>
+ </message>
+ <message>
+ <source>Bytes Received</source>
+ <translation>Bajtów pobrano</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Czas odpowiedzi</translation>
+ </message>
+ <message>
+ <source>Time Offset</source>
+ <translation>Przesunięcie czasu</translation>
+ </message>
+ <message>
+ <source>Last block time</source>
+ <translation>Czas ostatniego bloku</translation>
+ </message>
+ <message>
+ <source>&amp;Open</source>
+ <translation>&amp;Otwórz</translation>
+ </message>
+ <message>
+ <source>&amp;Console</source>
+ <translation>&amp;Konsola</translation>
+ </message>
+ <message>
+ <source>&amp;Network Traffic</source>
+ <translation>$Ruch sieci</translation>
+ </message>
+ <message>
+ <source>&amp;Clear</source>
+ <translation>&amp;Wyczyść</translation>
+ </message>
+ <message>
+ <source>Totals</source>
+ <translation>Kwota ogólna</translation>
+ </message>
+ <message>
+ <source>In:</source>
+ <translation>Wejście:</translation>
+ </message>
+ <message>
+ <source>Out:</source>
+ <translation>Wyjście:</translation>
+ </message>
+ <message>
+ <source>Build date</source>
+ <translation>Data kompilacji</translation>
+ </message>
+ <message>
+ <source>Debug log file</source>
+ <translation>Plik logowania debugowania</translation>
+ </message>
+ <message>
+ <source>Clear console</source>
+ <translation>Wyczyść konsolę</translation>
+ </message>
+ <message>
+ <source>Welcome to the Bitcoin Core RPC console.</source>
+ <translation>Witaj w konsoli Bitcoin Core RPC.</translation>
+ </message>
+ <message>
+ <source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
+ <translation>Użyj strzałek do przewijania historii i &lt;b&gt;Ctrl-L&lt;/b&gt; aby wyczyścić ekran</translation>
+ </message>
+ <message>
+ <source>Type &lt;b&gt;help&lt;/b&gt; for an overview of available commands.</source>
+ <translation>Wpisz &lt;b&gt;help&lt;/b&gt; aby uzyskać listę dostępnych komend</translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation>%1 B</translation>
+ </message>
+ <message>
+ <source>%1 KB</source>
+ <translation>%1 KB</translation>
+ </message>
+ <message>
+ <source>%1 MB</source>
+ <translation>%1 MB</translation>
+ </message>
+ <message>
+ <source>%1 GB</source>
+ <translation>%1 GB</translation>
+ </message>
+ <message>
+ <source>via %1</source>
+ <translation>przez %1</translation>
+ </message>
+ <message>
+ <source>never</source>
+ <translation>nigdy</translation>
+ </message>
+ <message>
+ <source>Inbound</source>
+ <translation>Wejściowy</translation>
+ </message>
+ <message>
+ <source>Outbound</source>
+ <translation>Wyjściowy</translation>
+ </message>
+ <message>
+ <source>Unknown</source>
+ <translation>Nieznany</translation>
+ </message>
+ <message>
+ <source>Fetching...</source>
+ <translation>Pobieram...</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Amount:</source>
+ <translation>&amp;Ilość:</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Etykieta:</translation>
+ </message>
+ <message>
+ <source>&amp;Message:</source>
+ <translation>&amp;Wiadomość:</translation>
+ </message>
+ <message>
+ <source>Reuse one of the previously used receiving addresses. Reusing addresses has security and privacy issues. Do not use this unless re-generating a payment request made before.</source>
+ <translation>Użyj jednego z poprzednio użytych adresów odbiorczych. Podczas ponownego używania adresów występują problemy z bezpieczeństwem i prywatnością. Nie korzystaj z tej opcji, chyba że odtwarzasz żądanie płatności wykonane już wcześniej.</translation>
+ </message>
+ <message>
+ <source>An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network.</source>
+ <translation>Opcjonalna wiadomość do dołączenia do żądania płatności, która będzie wyświetlana, gdy żądanie zostanie otwarte. Uwaga: wiadomość ta nie zostanie wysłana wraz z płatnością w sieci Bitcoin.</translation>
+ </message>
+ <message>
+ <source>An optional label to associate with the new receiving address.</source>
+ <translation>Opcjonalna etykieta do skojarzenia z nowym adresem odbiorczym.</translation>
+ </message>
+ <message>
+ <source>Use this form to request payments. All fields are &lt;b&gt;optional&lt;/b&gt;.</source>
+ <translation>Użyj tego formularza do zażądania płatności. Wszystkie pola są &lt;b&gt;opcjonalne&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>An optional amount to request. Leave this empty or zero to not request a specific amount.</source>
+ <translation>Opcjonalna kwota by zażądać. Zostaw puste lub zero by nie zażądać konkretnej kwoty.</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Wyczyść wszystkie pola formularza.</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation>Wyczyść</translation>
+ </message>
+ <message>
+ <source>Requested payments history</source>
+ <translation>Żądanie historii płatności</translation>
+ </message>
+ <message>
+ <source>&amp;Request payment</source>
+ <translation>&amp;Żądaj płatności</translation>
+ </message>
+ <message>
+ <source>Show the selected request (does the same as double clicking an entry)</source>
+ <translation>Pokaż wybrane żądanie (robi to samo co dwukrotne kliknięcie pozycji)</translation>
+ </message>
+ <message>
+ <source>Show</source>
+ <translation>Pokaż</translation>
+ </message>
+ <message>
+ <source>Remove the selected entries from the list</source>
+ <translation>Usuń zaznaczone z listy</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>Usuń</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Kopiuj etykietę</translation>
+ </message>
+ <message>
+ <source>Copy message</source>
+ <translation>Kopiuj wiadomość</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopiuj kwotę</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>QR Code</source>
+ <translation>Kod QR</translation>
+ </message>
+ <message>
+ <source>Copy &amp;URI</source>
+ <translation>Kopiuj &amp;URI</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Address</source>
+ <translation>Kopiuj &amp;adres</translation>
+ </message>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Zapisz obraz...</translation>
+ </message>
+ <message>
+ <source>Request payment to %1</source>
+ <translation>Zażądaj płatności do %1</translation>
+ </message>
+ <message>
+ <source>Payment information</source>
+ <translation>Informacje o płatności</translation>
+ </message>
+ <message>
+ <source>URI</source>
+ <translation>URI</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adres</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Kwota</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etykieta</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Wiadomość</translation>
+ </message>
+ <message>
+ <source>Resulting URI too long, try to reduce the text for label / message.</source>
+ <translation>Wynikowy URI jest zbyt długi, spróbuj zmniejszyć tekst etykiety / wiadomości</translation>
+ </message>
+ <message>
+ <source>Error encoding URI into QR Code.</source>
+ <translation>Błąd kodowania URI w Kodzie QR.</translation>
+ </message>
+</context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etykieta</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Wiadomość</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Kwota</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(brak etykiety)</translation>
+ </message>
+ <message>
+ <source>(no message)</source>
+ <translation>(brak wiadomości)</translation>
+ </message>
+ <message>
+ <source>(no amount)</source>
+ <translation>(brak kwoty)</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Wyślij monety</translation>
+ </message>
+ <message>
+ <source>Coin Control Features</source>
+ <translation>Funkcje kontroli monet</translation>
+ </message>
+ <message>
+ <source>Inputs...</source>
+ <translation>Wejścia...</translation>
+ </message>
+ <message>
+ <source>automatically selected</source>
+ <translation>zaznaczone automatycznie</translation>
+ </message>
+ <message>
+ <source>Insufficient funds!</source>
+ <translation>Niewystarczające środki!</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Ilość:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Bajtów:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Kwota:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Priorytet:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Opłata:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Po opłacie:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Reszta:</translation>
+ </message>
+ <message>
+ <source>If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address.</source>
+ <translation>Kiedy ta opcja jest wybrana, to jeżeli adres reszty jest pusty lub nieprawidłowy, to reszta będzie wysyłana na nowo wygenerowany adres, </translation>
+ </message>
+ <message>
+ <source>Custom change address</source>
+ <translation>Niestandardowe zmiany adresu</translation>
+ </message>
+ <message>
+ <source>Transaction Fee:</source>
+ <translation>Opłata transakcyjna:</translation>
+ </message>
+ <message>
+ <source>Choose...</source>
+ <translation>Wybierz...</translation>
+ </message>
+ <message>
+ <source>collapse fee-settings</source>
+ <translation>zwiń opcje opłaty</translation>
+ </message>
+ <message>
+ <source>per kilobyte</source>
+ <translation>za kilobajt</translation>
+ </message>
+ <message>
+ <source>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "total at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source>
+ <translation>Jeżeli własna opłata zostanie ustawiona na 1000 satoshi, a transakcja będzie miała tylko 250 bajtów, to "za kilobajt" płaci tylko 250 satoshi, podczas gdy, "razem przynajmniej" płaci 1000 satoshi. Przy transakcjach większych niż kilobajt, w obu przypadkach płaci za każdy kilobajt.</translation>
+ </message>
+ <message>
+ <source>Hide</source>
+ <translation>Ukryj</translation>
+ </message>
+ <message>
+ <source>total at least</source>
+ <translation>razem przynajmniej</translation>
+ </message>
+ <message>
+ <source>Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process.</source>
+ <translation>Zapłacenie tylko minimalnej opłaty jest nadal wystarczające, dopóki jest mniejszy wolumen transakcji niż miejsca w blokach. Należy jednak mieć świadomość, że może skończyć się to niezatwierdzeniem nigdy transakcji, gdy jest większe zapotrzebowanie na transakcje bitcoina niż sieć może przetworzyć.</translation>
+ </message>
+ <message>
+ <source>(read the tooltip)</source>
+ <translation>(przeczytaj podpowiedź)</translation>
+ </message>
+ <message>
+ <source>Recommended:</source>
+ <translation>Zalecane:</translation>
+ </message>
+ <message>
+ <source>Custom:</source>
+ <translation>Własna:</translation>
+ </message>
+ <message>
+ <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source>
+ <translation>(Sprytne opłaty nie są jeszcze zainicjowane. Trwa to zwykle kilka bloków...)</translation>
+ </message>
+ <message>
+ <source>Confirmation time:</source>
+ <translation>Czas potwierdzenia:</translation>
+ </message>
+ <message>
+ <source>normal</source>
+ <translation>normalnie</translation>
+ </message>
+ <message>
+ <source>fast</source>
+ <translation>szybko</translation>
+ </message>
+ <message>
+ <source>Send as zero-fee transaction if possible</source>
+ <translation>Wyślij bez opłaty jeżeli to możliwe</translation>
+ </message>
+ <message>
+ <source>(confirmation may take longer)</source>
+ <translation>(potwierdzenie może potrwać dłużej)</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>Wyślij do wielu odbiorców na raz</translation>
+ </message>
+ <message>
+ <source>Add &amp;Recipient</source>
+ <translation>Dodaj Odbio&amp;rcę</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Wyczyść wszystkie pola formularza.</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Pył:</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Wyczyść &amp;wszystko</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>Saldo:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>Potwierdź akcję wysyłania</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>Wy&amp;syłka</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>Potwierdź wysyłanie monet</translation>
+ </message>
+ <message>
+ <source>%1 to %2</source>
+ <translation>%1 do %2</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Skopiuj ilość</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopiuj kwotę</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Skopiuj opłatę</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Skopiuj ilość po opłacie</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Skopiuj ilość bajtów</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Skopiuj priorytet</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Skopiuj resztę</translation>
+ </message>
+ <message>
+ <source>or</source>
+ <translation>lub</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>Kwota do zapłacenia musi być większa od 0.</translation>
+ </message>
+ <message>
+ <source>The amount exceeds your balance.</source>
+ <translation>Kwota przekracza twoje saldo.</translation>
+ </message>
+ <message>
+ <source>The total exceeds your balance when the %1 transaction fee is included.</source>
+ <translation>Suma przekracza twoje saldo, gdy doliczymy %1 prowizji transakcyjnej.</translation>
+ </message>
+ <message>
+ <source>Transaction creation failed!</source>
+ <translation>Utworzenie transakcji nie powiodło się!</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>Transakcja została odrzucona! Może się to zdarzyć jeśli część monet z portfela została już wydana używając kopii pliku wallet.dat i nie zostało to tutaj uwzględnione.</translation>
+ </message>
+ <message>
+ <source>A fee higher than %1 is considered an absurdly high fee.</source>
+ <translation>Opłata wyższa niż %1 jest uważana za szalenie wysoką.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>Żądanie płatności upłynęło.</translation>
+ </message>
+ <message numerus="yes">
+ <source>Estimated to begin confirmation within %n block(s).</source>
+ <translation><numerusform>Przybliżony czas zatwierdzenia: %n bloków.</numerusform><numerusform>Przybliżony czas zatwierdzenia: %n bloków.</numerusform><numerusform>Przybliżony czas zatwierdzenia: %n bloków.</numerusform></translation>
+ </message>
+ <message>
+ <source>Pay only the minimum fee of %1</source>
+ <translation>Płac tylko minimalna opłatę %1</translation>
+ </message>
+ <message>
+ <source>Total Amount %1&lt;span style='font-size:10pt;font-weight:normal;'&gt;&lt;br /&gt;(=%2)&lt;/span&gt;</source>
+ <translation>Całkowita kwota %1&lt;span style='font-size:10pt;font-weight:normal;'&gt;&lt;br /&gt;(=%2)&lt;/span&gt;</translation>
+ </message>
+ <message>
+ <source>The recipient address is not valid. Please recheck.</source>
+ <translation>Adres odbiorcy jest nieprawidłowy, proszę sprawić ponownie.</translation>
+ </message>
+ <message>
+ <source>Duplicate address found: addresses should only be used once each.</source>
+ <translation>Znaleziono powtórzony adres, można wysłać tylko raz na każdy adres podczas jednej operacji wysyłania.</translation>
+ </message>
+ <message>
+ <source>Warning: Invalid Bitcoin address</source>
+ <translation>Ostrzeżenie: nieprawidłowy adres Bitcoin</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(brak etykiety)</translation>
+ </message>
+ <message>
+ <source>Warning: Unknown change address</source>
+ <translation>Ostrzeżenie: Nieznany adres reszty</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Kopiuj kurz</translation>
+ </message>
+ <message>
+ <source>Are you sure you want to send?</source>
+ <translation>Czy na pewno chcesz wysłać?</translation>
+ </message>
+ <message>
+ <source>added as transaction fee</source>
+ <translation>dodano jako opłata transakcyjna</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>Su&amp;ma:</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>Zapłać &amp;dla:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Wprowadź etykietę dla tego adresu by dodać go do książki adresowej</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Etykieta:</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Wybierz wcześniej użyty adres</translation>
+ </message>
+ <message>
+ <source>This is a normal payment.</source>
+ <translation>To jest standardowa płatność</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to send the payment to</source>
+ <translation>Adres Bitcoin gdzie wysłać płatność</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Wklej adres ze schowka</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Remove this entry</source>
+ <translation>Usuń ten wpis</translation>
+ </message>
+ <message>
+ <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source>
+ <translation>Opłata zostanie odjęta od kwoty wysyłane.Odbiorca otrzyma mniej niż bitcoins wpisz w polu kwoty. Jeśli wybrano kilku odbiorców, opłata jest podzielona równo.</translation>
+ </message>
+ <message>
+ <source>S&amp;ubtract fee from amount</source>
+ <translation>Odejmij od wysokości opłaty</translation>
+ </message>
+ <message>
+ <source>Message:</source>
+ <translation>Wiadomość:</translation>
+ </message>
+ <message>
+ <source>This is an unauthenticated payment request.</source>
+ <translation>To żądanie zapłaty nie zostało zweryfikowane.</translation>
+ </message>
+ <message>
+ <source>This is an authenticated payment request.</source>
+ <translation>To żądanie zapłaty jest zweryfikowane.</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to the list of used addresses</source>
+ <translation>Wprowadź etykietę dla tego adresu by dodać go do listy użytych adresów</translation>
+ </message>
+ <message>
+ <source>A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network.</source>
+ <translation>Wiadomość, która została dołączona do URI bitcoin:, która będzie przechowywana wraz z transakcją w celach informacyjnych. Uwaga: Ta wiadomość nie będzie rozsyłana w sieci Bitcoin.</translation>
+ </message>
+ <message>
+ <source>Pay To:</source>
+ <translation>Wpłać do:</translation>
+ </message>
+ <message>
+ <source>Memo:</source>
+ <translation>Notatka:</translation>
+ </message>
+</context>
+<context>
+ <name>ShutdownWindow</name>
+ <message>
+ <source>Bitcoin Core is shutting down...</source>
+ <translation>Bitcoin Core się zamyka...</translation>
+ </message>
+ <message>
+ <source>Do not shut down the computer until this window disappears.</source>
+ <translation>Nie wyłączaj komputera dopóki to okno nie zniknie.</translation>
+ </message>
+</context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Signatures - Sign / Verify a Message</source>
+ <translation>Podpisy - Podpisz / zweryfikuj wiadomość</translation>
+ </message>
+ <message>
+ <source>&amp;Sign Message</source>
+ <translation>Podpi&amp;sz Wiadomość</translation>
+ </message>
+ <message>
+ <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source>
+ <translation>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.</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to sign the message with</source>
+ <translation>Adres Bitcoin, za pomocą którego podpisać wiadomość</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Wybierz wcześniej użyty adres</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Wklej adres ze schowka</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Enter the message you want to sign here</source>
+ <translation>Tutaj wprowadź wiadomość, którą chcesz podpisać</translation>
+ </message>
+ <message>
+ <source>Signature</source>
+ <translation>Podpis</translation>
+ </message>
+ <message>
+ <source>Copy the current signature to the system clipboard</source>
+ <translation>Kopiuje aktualny podpis do schowka systemowego</translation>
+ </message>
+ <message>
+ <source>Sign the message to prove you own this Bitcoin address</source>
+ <translation>Podpisz wiadomość aby dowieść, że ten adres jest twój</translation>
+ </message>
+ <message>
+ <source>Sign &amp;Message</source>
+ <translation>Podpisz Wiado&amp;mość</translation>
+ </message>
+ <message>
+ <source>Reset all sign message fields</source>
+ <translation>Zresetuj wszystkie pola podpisanej wiadomości</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Wyczyść &amp;wszystko</translation>
+ </message>
+ <message>
+ <source>&amp;Verify Message</source>
+ <translation>&amp;Zweryfikuj wiadomość</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address the message was signed with</source>
+ <translation>Adres Bitcoin, którym została podpisana wiadomość</translation>
+ </message>
+ <message>
+ <source>Verify the message to ensure it was signed with the specified Bitcoin address</source>
+ <translation>Zweryfikuj wiadomość, aby upewnić się, że została podpisana odpowiednim adresem Bitcoin.</translation>
+ </message>
+ <message>
+ <source>Verify &amp;Message</source>
+ <translation>Zweryfikuj Wiado&amp;mość</translation>
+ </message>
+ <message>
+ <source>Reset all verify message fields</source>
+ <translation>Resetuje wszystkie pola weryfikacji wiadomości</translation>
+ </message>
+ <message>
+ <source>Click "Sign Message" to generate signature</source>
+ <translation>Kliknij "Podpisz Wiadomość" żeby uzyskać podpis</translation>
+ </message>
+ <message>
+ <source>The entered address is invalid.</source>
+ <translation>Podany adres jest nieprawidłowy.</translation>
+ </message>
+ <message>
+ <source>Please check the address and try again.</source>
+ <translation>Proszę sprawdzić adres i spróbować ponownie.</translation>
+ </message>
+ <message>
+ <source>The entered address does not refer to a key.</source>
+ <translation>Wprowadzony adres nie odnosi się do klucza.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock was cancelled.</source>
+ <translation>Odblokowanie portfela zostało anulowane.</translation>
+ </message>
+ <message>
+ <source>Private key for the entered address is not available.</source>
+ <translation>Klucz prywatny dla podanego adresu nie jest dostępny.</translation>
+ </message>
+ <message>
+ <source>Message signing failed.</source>
+ <translation>Podpisanie wiadomości nie powiodło się.</translation>
+ </message>
+ <message>
+ <source>Message signed.</source>
+ <translation>Wiadomość podpisana.</translation>
+ </message>
+ <message>
+ <source>The signature could not be decoded.</source>
+ <translation>Podpis nie może zostać zdekodowany.</translation>
+ </message>
+ <message>
+ <source>Please check the signature and try again.</source>
+ <translation>Sprawdź podpis i spróbuj ponownie.</translation>
+ </message>
+ <message>
+ <source>The signature did not match the message digest.</source>
+ <translation>Podpis nie odpowiada skrótowi wiadomości.</translation>
+ </message>
+ <message>
+ <source>Message verification failed.</source>
+ <translation>Weryfikacja wiadomości nie powiodła się.</translation>
+ </message>
+ <message>
+ <source>Message verified.</source>
+ <translation>Wiadomość zweryfikowana.</translation>
+ </message>
+</context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Rdzeń Bitcoin</translation>
+ </message>
+ <message>
+ <source>The Bitcoin Core developers</source>
+ <translation>Deweloperzy Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>[testnet]</source>
+ <translation>[testnet]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ <message>
+ <source>KB/s</source>
+ <translation>KB/s</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>Otwórz do %1</translation>
+ </message>
+ <message>
+ <source>conflicted</source>
+ <translation>konflikt</translation>
+ </message>
+ <message>
+ <source>%1/offline</source>
+ <translation>%1/offline</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/niezatwierdzone</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 potwierdzeń</translation>
+ </message>
+ <message>
+ <source>Status</source>
+ <translation>Status</translation>
+ </message>
+ <message numerus="yes">
+ <source>, broadcast through %n node(s)</source>
+ <translation><numerusform>, przekazywany przez %n węzłów</numerusform><numerusform>, przekazywany przez %n węzłów</numerusform><numerusform>, przekazywany przez %n węzłów</numerusform></translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Source</source>
+ <translation>Źródło</translation>
+ </message>
+ <message>
+ <source>Generated</source>
+ <translation>Wygenerowano</translation>
+ </message>
+ <message>
+ <source>From</source>
+ <translation>Od</translation>
+ </message>
+ <message>
+ <source>To</source>
+ <translation>Do</translation>
+ </message>
+ <message>
+ <source>own address</source>
+ <translation>własny adres</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>tylko-obserwowany</translation>
+ </message>
+ <message>
+ <source>label</source>
+ <translation>etykieta</translation>
+ </message>
+ <message>
+ <source>Credit</source>
+ <translation>Przypisy</translation>
+ </message>
+ <message numerus="yes">
+ <source>matures in %n more block(s)</source>
+ <translation><numerusform>potwierdzona przy %n blokach więcej</numerusform><numerusform>potwierdzona przy %n blokach więcej</numerusform><numerusform>potwierdzona przy %n blokach więcej</numerusform></translation>
+ </message>
+ <message>
+ <source>not accepted</source>
+ <translation>niezaakceptowane</translation>
+ </message>
+ <message>
+ <source>Debit</source>
+ <translation>Debet</translation>
+ </message>
+ <message>
+ <source>Total debit</source>
+ <translation>Razem wychodzących</translation>
+ </message>
+ <message>
+ <source>Total credit</source>
+ <translation>Razem przychodzących</translation>
+ </message>
+ <message>
+ <source>Transaction fee</source>
+ <translation>Opłata transakcyjna</translation>
+ </message>
+ <message>
+ <source>Net amount</source>
+ <translation>Kwota netto</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Wiadomość</translation>
+ </message>
+ <message>
+ <source>Comment</source>
+ <translation>Komentarz</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>ID transakcji</translation>
+ </message>
+ <message>
+ <source>Merchant</source>
+ <translation>Kupiec</translation>
+ </message>
+ <message>
+ <source>Generated coins must mature %1 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.</source>
+ <translation>Wygenerowane monety muszą dojrzeć przez %1 bloków zanim będzie można je wydać. Gdy wygenerowałeś ten blok został on ogłoszony w sieci i dodany do łańcucha bloków. Jeżeli nie uda mu się wejść do łańcucha jego status zostanie zmieniony na "nie zaakceptowano" i nie będzie można go wydać. To czasem zdarza się gdy inny węzeł wygeneruje blok w kilka sekund od twojego.</translation>
+ </message>
+ <message>
+ <source>Debug information</source>
+ <translation>Informacje debugowania</translation>
+ </message>
+ <message>
+ <source>Transaction</source>
+ <translation>Transakcja</translation>
+ </message>
+ <message>
+ <source>Inputs</source>
+ <translation>Wejścia</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Kwota</translation>
+ </message>
+ <message>
+ <source>true</source>
+ <translation>prawda</translation>
+ </message>
+ <message>
+ <source>false</source>
+ <translation>fałsz</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, nie został jeszcze pomyślnie rozesłany</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Otwórz dla %n następnych bloków</numerusform><numerusform>Otwórz dla %n następnych bloków</numerusform><numerusform>Otwórz dla %n następnych bloków</numerusform></translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>nieznany</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>Szczegóły transakcji</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>Ten panel pokazuje szczegółowy opis transakcji</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Typ</translation>
+ </message>
+ <message>
+ <source>Immature (%1 confirmations, will be available after %2)</source>
+ <translation>Niedojrzała (%1 potwierdzeń, będzie dostępna po %2)</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Otwórz dla %n następnych bloków</numerusform><numerusform>Otwórz dla %n następnych bloków</numerusform><numerusform>Otwórz dla %n następnych bloków</numerusform></translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>Otwórz do %1</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>Zatwierdzony (%1 potwierdzeń)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>Ten blok nie został odebrany przez jakikolwiek inny węzeł i prawdopodobnie nie zostanie zaakceptowany!</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>Wygenerowano ale nie zaakceptowano</translation>
+ </message>
+ <message>
+ <source>Offline</source>
+ <translation>Offline</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etykieta</translation>
+ </message>
+ <message>
+ <source>Unconfirmed</source>
+ <translation>Niepotwierdzone:</translation>
+ </message>
+ <message>
+ <source>Confirming (%1 of %2 recommended confirmations)</source>
+ <translation>Potwierdzanie (%1 z %2 rekomendowanych potwierdzeń)</translation>
+ </message>
+ <message>
+ <source>Conflicted</source>
+ <translation>Konflikt</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Otrzymane przez</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>Odebrano od</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Wysłano do</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>Płatność do siebie</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Wydobyto</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>tylko-obserwowany</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(brak)</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>Status transakcji. Najedź na pole, aby zobaczyć liczbę potwierdzeń.</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Data i czas odebrania transakcji.</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>Rodzaj transakcji.</translation>
+ </message>
+ <message>
+ <source>Whether or not a watch-only address is involved in this transaction.</source>
+ <translation>Czy adres tylko-obserwowany jest lub nie użyty w tej transakcji.</translation>
+ </message>
+ <message>
+ <source>User-defined intent/purpose of the transaction.</source>
+ <translation>Zdefiniowana przez użytkownika intencja/cel transakcji.</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>Kwota usunięta z lub dodana do konta.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>Wszystko</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>Dzisiaj</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>W tym tygodniu</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>W tym miesiącu</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>W zeszłym miesiącu</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>W tym roku</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>Zakres...</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Otrzymane przez</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Wysłano do</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>Do siebie</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Wydobyto</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>Inne</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>Wprowadź adres albo etykietę żeby wyszukać</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>Min suma</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Kopiuj adres</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Kopiuj etykietę</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopiuj kwotę</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Skopiuj ID transakcji</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>Zmień etykietę</translation>
+ </message>
+ <message>
+ <source>Show transaction details</source>
+ <translation>Pokaż szczegóły transakcji</translation>
+ </message>
+ <message>
+ <source>Export Transaction History</source>
+ <translation>Eksport historii transakcji</translation>
+ </message>
+ <message>
+ <source>Watch-only</source>
+ <translation>Tylko obserwowany</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Błąd przy próbie eksportu</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the transaction history to %1.</source>
+ <translation>Wystąpił błąd przy próbie zapisu historii transakcji do %1.</translation>
+ </message>
+ <message>
+ <source>Exporting Successful</source>
+ <translation>Eksport powiódł się</translation>
+ </message>
+ <message>
+ <source>The transaction history was successfully saved to %1.</source>
+ <translation>Historia transakcji została zapisana do %1.</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>CSV (rozdzielany przecinkami)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Potwierdzony</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Typ</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etykieta</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adres</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>Zakres:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>do</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ <message>
+ <source>Unit to show amounts in. Click to select another unit.</source>
+ <translation>Jednostka w jakiej pokazywane są kwoty. Kliknij aby wybrać inną.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletFrame</name>
+ <message>
+ <source>No wallet has been loaded.</source>
+ <translation>Nie załadowano żadnego portfela.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Wyślij monety</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Eksportuj</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Eksportuj dane z aktywnej karty do pliku</translation>
+ </message>
+ <message>
+ <source>Backup Wallet</source>
+ <translation>Kopia Zapasowa Portfela</translation>
+ </message>
+ <message>
+ <source>Wallet Data (*.dat)</source>
+ <translation>Dane Portfela (*.dat)</translation>
+ </message>
+ <message>
+ <source>Backup Failed</source>
+ <translation>Nie udało się wykonać kopii zapasowej</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the wallet data to %1.</source>
+ <translation>Wystąpił błąd przy próbie zapisu pliku portfela do %1.</translation>
+ </message>
+ <message>
+ <source>The wallet data was successfully saved to %1.</source>
+ <translation>Plik portfela został zapisany do %1.</translation>
+ </message>
+ <message>
+ <source>Backup Successful</source>
+ <translation>Wykonano Kopię Zapasową</translation>
+ </message>
+</context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>Opcje:</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>Wskaż folder danych</translation>
+ </message>
+ <message>
+ <source>Connect to a node to retrieve peer addresses, and disconnect</source>
+ <translation>Podłącz się do węzła aby otrzymać adresy peerów i rozłącz</translation>
+ </message>
+ <message>
+ <source>Specify your own public address</source>
+ <translation>Podaj swój publiczny adres</translation>
+ </message>
+ <message>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>Akceptuj linię poleceń oraz polecenia JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>Uruchom w tle jako daemon i przyjmuj polecenia</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>Użyj sieci testowej</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
+ <translation>Akceptuj połączenia z zewnątrz (domyślnie: 1 jeśli nie ustawiono -proxy lub -connect)</translation>
+ </message>
+ <message>
+ <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
+ <translation>Skojarz z podanym adresem i nasłuchuj na nim. Użyj formatu [host]:port dla IPv6</translation>
+ </message>
+ <message>
+ <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
+ <translation>Usuwa wszystkie transakcje w portfelu i tylko odtwarza te części z łańcucha bloków poprzez -rescan przy starcie</translation>
+ </message>
+ <message>
+ <source>Distributed under the MIT software license, see the accompanying file COPYING or &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</source>
+ <translation>Rozprowadzane na licencji MIT, zobacz dołączony plik COPYING lub &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</translation>
+ </message>
+ <message>
+ <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
+ <translation>Wykonaj polecenie, kiedy transakcja portfela ulegnie zmianie (%s w poleceniu zostanie zastąpione przez TxID)</translation>
+ </message>
+ <message>
+ <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source>
+ <translation>Maksymalna całkowita opłata użyta na każdą pojedynczą transakcję portfela; ustawienie jej za nisko może przerwać większe transakcje (domyślnie: %s)</translation>
+ </message>
+ <message>
+ <source>Set the number of script verification threads (%u to %d, 0 = auto, &lt;0 = leave that many cores free, default: %d)</source>
+ <translation>Ustaw liczbę wątków skryptu weryfikacyjnego (%u do %d, 0 = auto, &lt;0 = zostaw tyle rdzeni wolnych, domyślnie: %d)</translation>
+ </message>
+ <message>
+ <source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source>
+ <translation>To jest testowa wersja - używaj na własne ryzyko - nie używaj do wykopywania oraz przy aplikacjach kupieckich</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer. Bitcoin Core is probably already running.</source>
+ <translation>Nie można przywiązać z portem %s na tym komputerze. Bitcoin Core prawdopodobnie już działa.</translation>
+ </message>
+ <message>
+ <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>UWAGA: nienaturalnie duża liczba wygenerowanych bloków, %d bloków otrzymano w ostatnich %d godzinach (%d oczekiwanych)</translation>
+ </message>
+ <message>
+ <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>UWAGA: sprawdź swoje połączenie sieciowe, %d bloków otrzymano w ostatnich %d godzinach (%d oczekiwanych)</translation>
+ </message>
+ <message>
+ <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>Ostrzeżenie: -paytxfee jest bardzo duże! Jest to prowizja za transakcje, którą płacisz, gdy wysyłasz monety.</translation>
+ </message>
+ <message>
+ <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source>
+ <translation>Ostrzeżenie: Sieć nie wydaje się w pełni zgodna! Niektórzy górnicy wydają się doświadczać problemów.</translation>
+ </message>
+ <message>
+ <source>Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.</source>
+ <translation>Uwaga: Wygląda na to, że nie ma pełnej zgodności z naszymi peerami! Możliwe, że potrzebujesz aktualizacji bądź inne węzły jej potrzebują</translation>
+ </message>
+ <message>
+ <source>Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
+ <translation>Ostrzeżenie: błąd odczytu wallet.dat! Wszystkie klucze zostały odczytane, ale może brakować pewnych danych transakcji lub wpisów w książce adresowej lub mogą one być nieprawidłowe.</translation>
+ </message>
+ <message>
+ <source>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</source>
+ <translation>Ostrzeżenie: Odtworzono dane z uszkodzonego pliku wallet.dat! Oryginalny wallet.dat został zapisany jako wallet.{timestamp}.bak w %s; jeśli twoje saldo lub transakcje są niepoprawne powinieneś odtworzyć kopię zapasową.</translation>
+ </message>
+ <message>
+ <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source>
+ <translation>Dodawaj do białej listy węzły łączące się z podanej maski sieciowej lub adresu IP. Może być określona kilka razy.</translation>
+ </message>
+ <message>
+ <source>(default: 1)</source>
+ <translation>(domyślnie: 1)</translation>
+ </message>
+ <message>
+ <source>&lt;category&gt; can be:</source>
+ <translation>&lt;category&gt; mogą być:</translation>
+ </message>
+ <message>
+ <source>Attempt to recover private keys from a corrupt wallet.dat</source>
+ <translation>Próbuj odzyskać klucze prywatne z uszkodzonego wallet.dat</translation>
+ </message>
+ <message>
+ <source>Block creation options:</source>
+ <translation>Opcje tworzenia bloku:</translation>
+ </message>
+ <message>
+ <source>Connect only to the specified node(s)</source>
+ <translation>Łącz się tylko do wskazanego węzła/węzłów</translation>
+ </message>
+ <message>
+ <source>Connection options:</source>
+ <translation>Opcje połączenia:</translation>
+ </message>
+ <message>
+ <source>Corrupted block database detected</source>
+ <translation>Wykryto uszkodzoną bazę bloków</translation>
+ </message>
+ <message>
+ <source>Debugging/Testing options:</source>
+ <translation>Opcje debugowania/testowania:</translation>
+ </message>
+ <message>
+ <source>Do not load the wallet and disable wallet RPC calls</source>
+ <translation>Nie ładuj portfela i wyłącz wywołania RPC portfela</translation>
+ </message>
+ <message>
+ <source>Do you want to rebuild the block database now?</source>
+ <translation>Czy chcesz teraz przebudować bazę bloków?</translation>
+ </message>
+ <message>
+ <source>Error initializing block database</source>
+ <translation>Błąd inicjowania bazy danych bloków</translation>
+ </message>
+ <message>
+ <source>Error initializing wallet database environment %s!</source>
+ <translation>Błąd inicjowania środowiska bazy portfela %s!</translation>
+ </message>
+ <message>
+ <source>Error loading block database</source>
+ <translation>Błąd ładowania bazy bloków</translation>
+ </message>
+ <message>
+ <source>Error opening block database</source>
+ <translation>Błąd otwierania bazy bloków</translation>
+ </message>
+ <message>
+ <source>Error: Disk space is low!</source>
+ <translation>Błąd: Mało miejsca na dysku!</translation>
+ </message>
+ <message>
+ <source>Failed to listen on any port. Use -listen=0 if you want this.</source>
+ <translation>Próba nasłuchiwania na jakimkolwiek porcie nie powiodła się. Użyj -listen=0 jeśli tego chcesz.</translation>
+ </message>
+ <message>
+ <source>If &lt;category&gt; is not supplied, output all debugging information.</source>
+ <translation>Jeżeli &lt;category&gt; nie zostanie określona, wyświetl wszystkie informacje debugowania.</translation>
+ </message>
+ <message>
+ <source>Importing...</source>
+ <translation>Importowanie…</translation>
+ </message>
+ <message>
+ <source>Incorrect or no genesis block found. Wrong datadir for network?</source>
+ <translation>Nieprawidłowy lub brak bloku genezy. Błędny folder_danych dla sieci?</translation>
+ </message>
+ <message>
+ <source>Invalid -onion address: '%s'</source>
+ <translation>Nieprawidłowy adres -onion: '%s'</translation>
+ </message>
+ <message>
+ <source>Not enough file descriptors available.</source>
+ <translation>Brak wystarczającej liczby deskryptorów plików. </translation>
+ </message>
+ <message>
+ <source>Only connect to nodes in network &lt;net&gt; (ipv4, ipv6 or onion)</source>
+ <translation>Łącz z węzłami tylko w sieci &lt;net&gt; (ipv4, piv6 lub onion)</translation>
+ </message>
+ <message>
+ <source>Prune cannot be configured with a negative value.</source>
+ <translation>Przycinanie nie może być skonfigurowane z negatywną wartością.</translation>
+ </message>
+ <message>
+ <source>Prune mode is incompatible with -txindex.</source>
+ <translation>Tryb ograniczony jest niekompatybilny z -txindex.</translation>
+ </message>
+ <message>
+ <source>Set database cache size in megabytes (%d to %d, default: %d)</source>
+ <translation>Ustaw wielkość pamięci podręcznej w megabajtach (%d do %d, domyślnie: %d)</translation>
+ </message>
+ <message>
+ <source>Set maximum block size in bytes (default: %d)</source>
+ <translation>Ustaw maksymalną wielkość bloku w bajtach (domyślnie: %d)</translation>
+ </message>
+ <message>
+ <source>Specify wallet file (within data directory)</source>
+ <translation>Określ plik portfela (w obrębie folderu danych)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: %u)</source>
+ <translation>Użyj UPnP do przekazania portu nasłuchu (domyślnie : %u)</translation>
+ </message>
+ <message>
+ <source>Verifying blocks...</source>
+ <translation>Weryfikacja bloków...</translation>
+ </message>
+ <message>
+ <source>Verifying wallet...</source>
+ <translation>Weryfikacja portfela...</translation>
+ </message>
+ <message>
+ <source>Wallet %s resides outside data directory %s</source>
+ <translation>Portfel %s znajduje się poza folderem danych %s</translation>
+ </message>
+ <message>
+ <source>Wallet options:</source>
+ <translation>Opcje portfela:</translation>
+ </message>
+ <message>
+ <source>Warning: This version is obsolete; upgrade required!</source>
+ <translation>Uwaga: Ta wersja jest przestarzała, wymagana jest aktualizacja!</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to change -txindex</source>
+ <translation>Musisz przebudować bazę używając parametru -reindex aby zmienić -txindex</translation>
+ </message>
+ <message>
+ <source>Imports blocks from external blk000??.dat file</source>
+ <translation>Importuj bloki z zewnętrznego pliku blk000??.dat</translation>
+ </message>
+ <message>
+ <source>Allow JSON-RPC connections from specified source. Valid for &lt;ip&gt; are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times</source>
+ <translation>Pozwól na połączenia JSON-RPC z podanego źródła. Jako &lt;ip&gt; prawidłowe jest pojedyncze IP (np. 1.2.3.4), podsieć/maska (np. 1.2.3.4/255.255.255.0) lub sieć/CIDR (np. 1.2.3.4/24). Opcja ta może być użyta wiele razy.</translation>
+ </message>
+ <message>
+ <source>An error occurred while setting up the RPC address %s port %u for listening: %s</source>
+ <translation>Napotkano błąd podczas ustawiania adres RPC %s port %u dla nasłuchiwania: %s</translation>
+ </message>
+ <message>
+ <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source>
+ <translation>Podepnij się do podanego adresu i dodawaj do białej listy węzły łączące się z nim. Użyj notacji [host]:port dla IPv6</translation>
+ </message>
+ <message>
+ <source>Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)</source>
+ <translation>Powiąż się z podanym adresem, aby nasłuchiwać połączenia JSON-RPC. Użyj notacji [host]:port dla IPv6. Ta opcja może być określona kilka razy (domyślnie: powiąż ze wszystkimi interfejsami)</translation>
+ </message>
+ <message>
+ <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source>
+ <translation>Nie można uzyskać blokady na katalogu z danymi %s. Rdzeń Bitcoin najprawdopodobniej jest już uruchomiony.</translation>
+ </message>
+ <message>
+ <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
+ <translation>Twórz nowe pliki z domyślnymi dla systemu uprawnieniami, zamiast umask 077 (skuteczne tylko przy wyłączonej funkcjonalności portfela)</translation>
+ </message>
+ <message>
+ <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source>
+ <translation>Odkryj własny adres IP (domyślnie: 1 kiedy w trybie nasłuchu i brak -externalip lub -proxy)</translation>
+ </message>
+ <message>
+ <source>Error: Listening for incoming connections failed (listen returned error %s)</source>
+ <translation>Błąd: Nasłuchiwanie połączeń przychodzących nie powiodło się (nasłuch zwrócił błąd %s)</translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source>
+ <translation>Błąd: Znaleziono niewspierany argument -socks . Ustawienie wersji SOCKS nie jest już możliwe, tylko serwery proxy SOCKS5 są wspierane.</translation>
+ </message>
+ <message>
+ <source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source>
+ <translation>Uruchom polecenie przy otrzymaniu odpowiedniego powiadomienia lub gdy zobaczymy naprawdę długie rozgałęzienie (%s w poleceniu jest podstawiane za komunikat)</translation>
+ </message>
+ <message>
+ <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source>
+ <translation>Opłaty (w BTC/Kb) mniejsze niż ta będą traktowane jako bez opłaty przy propagowaniu (domyślnie: %s)</translation>
+ </message>
+ <message>
+ <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
+ <translation>Jeżeli nie ustawiono paytxfee, dołącz wystarczająca opłatę, aby transakcja mogła zostać zatwierdzona w ciągu średniej ilości n bloków (domyślnie: %u)</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)</source>
+ <translation>Niewłaściwa ilość dla -maxtxfee=&lt;ilość&gt;: '%s' (musi wynosić przynajmniej minimalną wielkość %s aby zapobiec utknięciu transakcji)</translation>
+ </message>
+ <message>
+ <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source>
+ <translation>Maksymalny rozmiar danych w transakcji przekazującej dane które przekazujemy i wydobywamy (domyślnie: %u)</translation>
+ </message>
+ <message>
+ <source>Prune configured below the minimum of %d MB. Please use a higher number.</source>
+ <translation>Przycinanie skonfigurowano poniżej minimalnych %d MB. Proszę użyć wyższej liczby.</translation>
+ </message>
+ <message>
+ <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source>
+ <translation>Wyszukaj adresy węzłów wykorzystując zapytanie DNS, jeżeli masz mało adresów (domyślnie: 1 jeśli nie użyto -connect)</translation>
+ </message>
+ <message>
+ <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
+ <translation>Ustaw maksymalny rozmiar transakcji o wysokim priorytecie/niskiej prowizji w bajtach (domyślnie: %d)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source>
+ <translation>Ustaw liczbę wątków dla generowania monet (-1 = wszystkie rdzenie, domyślnie: %d)</translation>
+ </message>
+ <message>
+ <source>The transaction amount is too small to send after the fee has been deducted</source>
+ <translation>Zbyt niska kwota transakcji do wysłania po odjęciu opłaty</translation>
+ </message>
+ <message>
+ <source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit &lt;https://www.openssl.org/&gt; and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source>
+ <translation>Program ten zawiera oprogramowanie stworzone przez OpenSSL Project do użycia w OpensSSL Toolkit &lt;https://www.openssl.org/&gt;, oprogramowanie kryptograficzne napisane przez Eric Young oraz oprogramowanie UPnP napisane przez Thomas Bernard.</translation>
+ </message>
+ <message>
+ <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an 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)
+The username and password MUST NOT be the same.
+If the file does not exist, create it with owner-readable-only file permissions.
+It is also recommended to set alertnotify so you are notified of problems;
+for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
+</source>
+ <translation>Aby korzystać z bitcoind, lub opcji -server w bitcoin-qt, musisz ustawić opcję rpcpassword w pliku konfiguracyjnym:
+%s
+Zalecane jest użycie poniższego losowego hasła:
+rpcuser=bitcoinrpc
+rpcpassword=%s
+(nie musisz pamiętać tego hasła)
+Nazwa użytkownika i hasło NIE MOGĄ być takie same.
+Jeżeli ten plik nie istnieje, utwórz go z uprawnieniami tylko-do-odczytu przez właściciela.
+Zalecane jest także ustawienie opcji alertnotify, dzięki której będziesz powiadamiany o problemach;
+na przykład: alertnotify=echo %%s | mail -s "Alarm Bitcoin" admin@foo.com
+</translation>
+ </message>
+ <message>
+ <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source>
+ <translation>Ostrzeżenie: -matxfee jest ustawione bardzo wysokie! Tak wysokie opłaty mogą być zapłacone w jednej transakcji.</translation>
+ </message>
+ <message>
+ <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source>
+ <translation>Ostrzeżenie: Proszę sprawdzić czy data i czas na Twoim komputerze są poprawne! Jeżeli ustawienia zegara będą złe, Bitcoin Core nie będzie działał prawidłowo.</translation>
+ </message>
+ <message>
+ <source>Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway</source>
+ <translation>Węzły z białej listy nie mogą zostać zbanowane za ataki DoS, a ich transakcje będą zawsze przekazywane, nawet jeżeli będą znajdywać się już w pamięci, przydatne np. dla bramek płatniczych</translation>
+ </message>
+ <message>
+ <source>(default: %u)</source>
+ <translation>(domyślnie: %u)</translation>
+ </message>
+ <message>
+ <source>Accept public REST requests (default: %u)</source>
+ <translation>Akceptuj publiczne żądania REST (domyślnie: %u)</translation>
+ </message>
+ <message>
+ <source>Activating best chain...</source>
+ <translation>Aktywuje najlepszy łańcuch</translation>
+ </message>
+ <message>
+ <source>Can't run with a wallet in prune mode.</source>
+ <translation>Nie można uruchomić z portfela w trybie ograniczonym.</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -whitebind address: '%s'</source>
+ <translation>Nie można rozwiązać adresu -whitebind: '%s'</translation>
+ </message>
+ <message>
+ <source>Choose data directory on startup (default: 0)</source>
+ <translation>Wybierz folder danych przy starcie (domyślnie: 0)</translation>
+ </message>
+ <message>
+ <source>Connect through SOCKS5 proxy</source>
+ <translation>Połącz przez SOCKS5 proxy</translation>
+ </message>
+ <message>
+ <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source>
+ <translation>Copyright (C) 2009-%i The Bitcoin Core Developers</translation>
+ </message>
+ <message>
+ <source>Could not parse -rpcbind value %s as network address</source>
+ <translation>Nie można przetworzyć wartości -rpcbind %s jako adresu sieciowego</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source>
+ <translation>Błąd ładowania wallet.dat: Portfel wymaga nowszej wersji Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Error reading from database, shutting down.</source>
+ <translation>Błąd odczytu z bazy danych, wyłączam się.</translation>
+ </message>
+ <message>
+ <source>Error: A fatal internal error occurred, see debug.log for details</source>
+ <translation>Błąd: Wystąpił fatalny błąd wewnętrzny, sprawdź szczegóły w debug.log</translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -tor found, use -onion.</source>
+ <translation>Błąd: Znaleziono nieprawidłowy argument -tor, użyj -onion.</translation>
+ </message>
+ <message>
+ <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source>
+ <translation>Prowizja (w BTC za kB) dodawana do wysyłanej transakcji (domyślnie: %s)</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Informacja</translation>
+ </message>
+ <message>
+ <source>Initialization sanity check failed. Bitcoin Core is shutting down.</source>
+ <translation>Wstępna kontrola poprawności nie powiodła się. Bitcoin Core wyłącza się.</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Nieprawidłowa kwota dla -maxtxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -minrelaytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Nieprawidłowa kwota dla -minrelaytxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -mintxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Nieprawidłowa kwota dla -mintxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s' (must be at least %s)</source>
+ <translation>Nieprawidłowa kwota dla -paytxfee=&lt;amount&gt;: '%s' (musi być co najmniej %s)</translation>
+ </message>
+ <message>
+ <source>Invalid netmask specified in -whitelist: '%s'</source>
+ <translation>Nieprawidłowa maska sieci określona w -whitelist: '%s'</translation>
+ </message>
+ <message>
+ <source>Keep at most &lt;n&gt; unconnectable transactions in memory (default: %u)</source>
+ <translation>Przechowuj w pamięci maksymalnie &lt;n&gt; transakcji nie możliwych do połączenia (domyślnie: %u)</translation>
+ </message>
+ <message>
+ <source>Node relay options:</source>
+ <translation>Opcje przekaźnikowe węzła:</translation>
+ </message>
+ <message>
+ <source>Pruning blockstore...</source>
+ <translation>Przycinanie zapisu bloków...</translation>
+ </message>
+ <message>
+ <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source>
+ <translation>Opcje RPC SSL: (odwiedź Bitcoin Wiki w celu uzyskania instrukcji)</translation>
+ </message>
+ <message>
+ <source>RPC server options:</source>
+ <translation>Opcje serwera RPC:</translation>
+ </message>
+ <message>
+ <source>RPC support for HTTP persistent connections (default: %d)</source>
+ <translation>Wsparcie RPC dla ciągłych połączeń HTTP (domyślnie: %d)</translation>
+ </message>
+ <message>
+ <source>Rebuild block chain index from current blk000??.dat files on startup</source>
+ <translation>Odbuduj indeks łańcucha bloków z obecnych plików blk000??.dat podczas ponownego uruchomienia</translation>
+ </message>
+ <message>
+ <source>Receive and display P2P network alerts (default: %u)</source>
+ <translation>Odbieranie i wyświetlanie alertów sieci P2P (domyślnie: %u)</translation>
+ </message>
+ <message>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>Wyślij informację/raport do konsoli zamiast do pliku debug.log.</translation>
+ </message>
+ <message>
+ <source>Send transactions as zero-fee transactions if possible (default: %u)</source>
+ <translation>Wyślij bez opłaty jeżeli to możliwe (domyślnie: %u)</translation>
+ </message>
+ <message>
+ <source>Set SSL root certificates for payment request (default: -system-)</source>
+ <translation>Ustaw certyfikaty główne SSL dla żądań płatności (domyślnie: -system-)</translation>
+ </message>
+ <message>
+ <source>Set language, for example "de_DE" (default: system locale)</source>
+ <translation>Ustaw Język, na przykład "pl_PL" (domyślnie: systemowy)</translation>
+ </message>
+ <message>
+ <source>Show all debugging options (usage: --help -help-debug)</source>
+ <translation>Pokaż wszystkie opcje odpluskwiania (użycie: --help -help-debug)</translation>
+ </message>
+ <message>
+ <source>Show splash screen on startup (default: 1)</source>
+ <translation>Pokazuj okno powitalne przy starcie (domyślnie: 1)</translation>
+ </message>
+ <message>
+ <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source>
+ <translation>Zmniejsz plik debug.log przy starcie programu (domyślnie: 1 jeśli nie użyto -debug)</translation>
+ </message>
+ <message>
+ <source>Signing transaction failed</source>
+ <translation>Podpisywanie transakcji nie powiodło się</translation>
+ </message>
+ <message>
+ <source>Start minimized</source>
+ <translation>Uruchom zminimalizowany</translation>
+ </message>
+ <message>
+ <source>The transaction amount is too small to pay the fee</source>
+ <translation>Zbyt niska kwota transakcji by zapłacić opłatę</translation>
+ </message>
+ <message>
+ <source>This is experimental software.</source>
+ <translation>To oprogramowanie eksperymentalne.</translation>
+ </message>
+ <message>
+ <source>Transaction amount too small</source>
+ <translation>Zbyt niska kwota transakcji </translation>
+ </message>
+ <message>
+ <source>Transaction amounts must be positive</source>
+ <translation>Kwota transakcji musi być dodatnia</translation>
+ </message>
+ <message>
+ <source>Transaction too large for fee policy</source>
+ <translation>Transakcja jest zbyt duża dla tej opłaty</translation>
+ </message>
+ <message>
+ <source>Transaction too large</source>
+ <translation>Transakcja zbyt duża</translation>
+ </message>
+ <message>
+ <source>UI Options:</source>
+ <translation>Opcje UI</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer (bind returned error %s)</source>
+ <translation>Nie można przywiązać do %s na tym komputerze (bind zwrócił błąd %s)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: 1 when listening)</source>
+ <translation>Używaj UPnP do mapowania portu nasłuchu (domyślnie: 1 gdy nasłuchuje)</translation>
+ </message>
+ <message>
+ <source>Username for JSON-RPC connections</source>
+ <translation>Nazwa użytkownika dla połączeń JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Wallet needed to be rewritten: restart Bitcoin Core to complete</source>
+ <translation>Portfel wymaga przepisania: zrestartuj Bitcoina aby ukończyć</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Ostrzeżenie</translation>
+ </message>
+ <message>
+ <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source>
+ <translation>Uwaga: Zignorowano nieprawidłowy argument -benchmark, użyj -debug=bench.</translation>
+ </message>
+ <message>
+ <source>Warning: Unsupported argument -debugnet ignored, use -debug=net.</source>
+ <translation>Uwaga: Zignorowano nieprawidłowy argument -debugnet , użyj -debug=net.</translation>
+ </message>
+ <message>
+ <source>Zapping all transactions from wallet...</source>
+ <translation>Usuwam wszystkie transakcje z portfela...</translation>
+ </message>
+ <message>
+ <source>on startup</source>
+ <translation>podczas uruchamiania</translation>
+ </message>
+ <message>
+ <source>wallet.dat corrupt, salvage failed</source>
+ <translation>wallet.dat uszkodzony, odtworzenie się nie powiodło</translation>
+ </message>
+ <message>
+ <source>Password for JSON-RPC connections</source>
+ <translation>Hasło do połączeń JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
+ <translation>Wykonaj polecenie kiedy najlepszy blok ulegnie zmianie (%s w komendzie zastanie zastąpione przez hash bloku)</translation>
+ </message>
+ <message>
+ <source>Upgrade wallet to latest format</source>
+ <translation>Zaktualizuj portfel do najnowszego formatu.</translation>
+ </message>
+ <message>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>Przeskanuj łańcuch bloków w poszukiwaniu zaginionych transakcji portfela</translation>
+ </message>
+ <message>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>Użyj OpenSSL (https) do połączeń JSON-RPC</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>Ta wiadomość pomocy</translation>
+ </message>
+ <message>
+ <source>Allow DNS lookups for -addnode, -seednode and -connect</source>
+ <translation>Zezwól -addnode, -seednode i -connect na łączenie się z serwerem DNS</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>Wczytywanie adresów...</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>Błąd ładowania wallet.dat: Uszkodzony portfel</translation>
+ </message>
+ <message>
+ <source>(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source>
+ <translation>(1 = zachowaj wysłane metadane np. właściciel konta i informacje o żądaniach płatności, 2 = porzuć wysłane metadane)</translation>
+ </message>
+ <message>
+ <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
+ <translation>Jak dokładna jest weryfikacja bloków przy -checkblocks (0-4, domyślnie: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
+ <translation>Utrzymuj pełny indeks transakcji, używany przy wywołaniu RPC getrawtransaction (domyślnie: %u)</translation>
+ </message>
+ <message>
+ <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source>
+ <translation>Czas w sekundach, przez jaki nietrzymające się zasad węzły nie będą mogły ponownie się podłączyć (domyślnie: %u)</translation>
+ </message>
+ <message>
+ <source>Output debugging information (default: %u, supplying &lt;category&gt; is optional)</source>
+ <translation>Wypuść informacje debugowania (domyślnie: %u, podanie &lt;category&gt; jest opcjonalne)</translation>
+ </message>
+ <message>
+ <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source>
+ <translation>Użyj oddzielnego prozy SOCKS5 aby osiągnąć węzły w ukrytych usługach Tor (domyślnie: %s)</translation>
+ </message>
+ <message>
+ <source>(default: %s)</source>
+ <translation>(domyślnie: %s)</translation>
+ </message>
+ <message>
+ <source>Acceptable ciphers (default: %s)</source>
+ <translation>Akceptowane szyfry (domyślne: %s)</translation>
+ </message>
+ <message>
+ <source>Always query for peer addresses via DNS lookup (default: %u)</source>
+ <translation>Zawsze wypytuj o adresy węzłów poprzez podejrzenie DNS (domyślnie: %u)</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>Błąd ładowania wallet.dat</translation>
+ </message>
+ <message>
+ <source>Generate coins (default: %u)</source>
+ <translation>Generuj monety (domyślnie: %u)</translation>
+ </message>
+ <message>
+ <source>How many blocks to check at startup (default: %u, 0 = all)</source>
+ <translation>Ile bloków sprawdzić przy starcie (domyślnie: %u, 0 = wszystkie)</translation>
+ </message>
+ <message>
+ <source>Include IP addresses in debug output (default: %u)</source>
+ <translation>Dołącz adresy IP do logowania (domyślnie: %u)</translation>
+ </message>
+ <message>
+ <source>Invalid -proxy address: '%s'</source>
+ <translation>Nieprawidłowy adres -proxy: '%s'</translation>
+ </message>
+ <message>
+ <source>Listen for JSON-RPC connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>Nasłuchuj połączeń JSON-RPC na &lt;port&gt; (domyślnie: %u lub testnet: %u)</translation>
+ </message>
+ <message>
+ <source>Listen for connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>Nasłuchuj połączeń na &lt;port&gt; (domyślnie: %u lub testnet: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain at most &lt;n&gt; connections to peers (default: %u)</source>
+ <translation>Utrzymuj maksymalnie &lt;n&gt; połączeń z węzłami (domyślnie: %u)</translation>
+ </message>
+ <message>
+ <source>Make the wallet broadcast transactions</source>
+ <translation>Spraw by portfel dokonał transmisji transakcji</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection receive buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>Maksymalny bufor odbioru na połączenie, &lt;n&gt;*1000 bajtów (domyślnie: %u)</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection send buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>Maksymalny bufor wysyłania na połączenie, &lt;n&gt;*1000 bajtów (domyślnie: %u)</translation>
+ </message>
+ <message>
+ <source>Prepend debug output with timestamp (default: %u)</source>
+ <translation>Dołączaj znacznik czasu do logowania (domyślnie: %u)</translation>
+ </message>
+ <message>
+ <source>Relay and mine data carrier transactions (default: %u)</source>
+ <translation>Przekazuj i wydobywaj transakcje zawierające dane (domyślnie: %u)</translation>
+ </message>
+ <message>
+ <source>Relay non-P2SH multisig (default: %u)</source>
+ <translation>Przekazuj transakcje multisig inne niż P2SH (domyślnie: %u)</translation>
+ </message>
+ <message>
+ <source>Server certificate file (default: %s)</source>
+ <translation>Plik certyfikatu serwera (domyślnie: %s)</translation>
+ </message>
+ <message>
+ <source>Server private key (default: %s)</source>
+ <translation>Klucz prywatny serwera (domyślnie: %s)</translation>
+ </message>
+ <message>
+ <source>Set key pool size to &lt;n&gt; (default: %u)</source>
+ <translation>Ustaw rozmiar puli kluczy na &lt;n&gt; (domyślnie: %u)</translation>
+ </message>
+ <message>
+ <source>Set minimum block size in bytes (default: %u)</source>
+ <translation>Ustaw minimalny rozmiar bloku w bajtach (domyślnie: %u)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads to service RPC calls (default: %d)</source>
+ <translation>Ustaw liczbę wątków do obsługi RPC (domyślnie: %d)</translation>
+ </message>
+ <message>
+ <source>Specify configuration file (default: %s)</source>
+ <translation>Wskaż plik konfiguracyjny (domyślnie: %s)</translation>
+ </message>
+ <message>
+ <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source>
+ <translation>Wskaż czas oczekiwania na połączenie w milisekundach (minimum: 1, domyślnie: %d)</translation>
+ </message>
+ <message>
+ <source>Specify pid file (default: %s)</source>
+ <translation>Wskaż plik pid (domyślnie: %s)</translation>
+ </message>
+ <message>
+ <source>Spend unconfirmed change when sending transactions (default: %u)</source>
+ <translation>Wydawaj niepotwierdzoną resztę podczas wysyłania transakcji (domyślnie: %u)</translation>
+ </message>
+ <message>
+ <source>Threshold for disconnecting misbehaving peers (default: %u)</source>
+ <translation>Próg, po którym nastąpi rozłączenie węzłów nietrzymających się zasad (domyślnie: %u)</translation>
+ </message>
+ <message>
+ <source>Unknown network specified in -onlynet: '%s'</source>
+ <translation>Nieznana sieć w -onlynet: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -bind address: '%s'</source>
+ <translation>Nie można uzyskać adresu -bind: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -externalip address: '%s'</source>
+ <translation>Nie można uzyskać adresu -externalip: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Nieprawidłowa kwota dla -paytxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>Niewystarczające środki</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>Ładowanie indeksu bloku...</translation>
+ </message>
+ <message>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>Dodaj węzeł do podłączenia się i próbuj utrzymać to połączenie</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>Wczytywanie portfela...</translation>
+ </message>
+ <message>
+ <source>Cannot downgrade wallet</source>
+ <translation>Nie można dezaktualizować portfela</translation>
+ </message>
+ <message>
+ <source>Cannot write default address</source>
+ <translation>Nie można zapisać domyślnego adresu</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>Ponowne skanowanie...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>Wczytywanie zakończone</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Błąd</translation>
+ </message>
+</context>
+</TS> \ 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 0000000000..112b894898
--- /dev/null
+++ b/src/qt/locale/bitcoin_pt_BR.ts
@@ -0,0 +1,3380 @@
+<TS language="pt_BR" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Right-click to edit address or label</source>
+ <translation>Clique com o botão direito para editar o endereço ou rótulo </translation>
+ </message>
+ <message>
+ <source>Create a new address</source>
+ <translation>Criar novo endereço</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>&amp;Novo</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Copie o endereço selecionado para a área de transferência do sistema</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>&amp;Copiar</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>&amp;Fechar</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>&amp;Copiar Endereço</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>Excluir os endereços selecionados da lista</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Exportar os dados na aba atual para um arquivo</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Exportar</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;Excluir</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>Escolha o endereço para enviar moedas</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>Escolha o endereço para receber moedas</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>Escol&amp;ha</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>Endereços para envios</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>Endereços de recebimento</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>Esses são seus endereços Bitcoin para enviar pagamentos. Certifique-se sempre da quantia e do destinatário antes de enviar moedas.</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>Estes são os seus endereços Bitcoin para receber pagamentos. Recomenda-se a utilização de um novo endereço de recebimento para cada transação.</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>Copiar &amp;Rótulo</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>&amp;Editar</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>Exportar lista de endereços</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Arquivo separado por vírgulas (*. csv)</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Exportação Falhou</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the address list to %1. Please try again.</source>
+ <translation>Ocorreu um erro ao tentar salvar a lista de endereço em %1.. Por favor tente novamente.</translation>
+ </message>
+</context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Rótulo</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Endereço</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(Sem rótulo)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Passphrase Dialog</source>
+ <translation>Janela da Frase de Segurança</translation>
+ </message>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Digite a frase de segurança</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Nova frase de segurança</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Repita a nova frase de segurança</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>Criptografar carteira</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>Esta operação precisa de sua frase de segurança para desbloquear a carteira.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Desbloquear carteira</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>Esta operação precisa de sua frase de segurança para descriptografar a carteira.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>Descriptografar carteira</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>Alterar frase de segurança</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>Confirmar criptografia da carteira</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>Atenção: Se você criptografar sua carteira e perder sua frase, você vai &lt;b&gt;perder todos os seus BITCOINS!&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>Tem certeza de que deseja criptografar sua carteira?</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core 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.</source>
+ <translation>O Bitcoin irá fechar agora para terminar o processo de criptografia. Lembre-se que criptografando sua carteira não te protege totalmente de ter seus bitcoins roubados por um malware que infectar seu computador.</translation>
+ </message>
+ <message>
+ <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
+ <translation>IMPORTANTE: Qualquer backup prévio que você tenha feito do seu arquivo wallet deve ser substituído pelo novo e encriptado arquivo wallet gerado. Por razões de segurança, qualquer backup do arquivo wallet não criptografado se tornará inútil assim que você começar a usar uma nova carteira criptografada.</translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>Atenção: A tecla Caps Lock está ligada!</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>Carteira criptografada</translation>
+ </message>
+ <message>
+ <source>Enter the new passphrase to the wallet.&lt;br/&gt;Please use a passphrase of &lt;b&gt;ten or more random characters&lt;/b&gt;, or &lt;b&gt;eight or more words&lt;/b&gt;.</source>
+ <translation>Digite a nova frase da carteira. &lt;br/&gt;Por favor utilize uma senha com &lt;b&gt;dez ou mais caracteres aleartórios&lt;/b&gt;, ou &lt;b&gt;oito ou mais palavras&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>Enter the old passphrase and new passphrase to the wallet.</source>
+ <translation>Insira a frase antiga e a nova da carteira.</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>A criptografia da carteira falhou</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>A criptografia da carteira falhou devido a um erro interno. Sua carteira não estava criptografada.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>A frase de segurança fornecida não confere.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>O desbloqueio da carteira falhou</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>A frase de segurança digitada para a descriptografia da carteira estava incorreta.</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>A descriptografia da carteira falhou</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>A frase de segurança da carteira foi alterada com êxito.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>&amp;Assinar mensagem...</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>Sincronizando com a rede...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;Visão geral</translation>
+ </message>
+ <message>
+ <source>Node</source>
+ <translation>Nó</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>Mostrar visão geral da carteira</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Transações</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>Navegar pelo histórico de transações</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>S&amp;air</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>Sair da aplicação</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>Sobre &amp;Qt</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>Mostrar informações sobre o Qt</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;Opções...</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>&amp;Criptografar Carteira...</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>&amp;Backup da carteira...</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>&amp;Mudar frase de segurança...</translation>
+ </message>
+ <message>
+ <source>&amp;Sending addresses...</source>
+ <translation>Endereço&amp;s de envio...</translation>
+ </message>
+ <message>
+ <source>&amp;Receiving addresses...</source>
+ <translation>Endereços de &amp;recebimento...</translation>
+ </message>
+ <message>
+ <source>Open &amp;URI...</source>
+ <translation>Abrir &amp;URI...</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core client</source>
+ <translation>Cliente Bitcoin</translation>
+ </message>
+ <message>
+ <source>Importing blocks from disk...</source>
+ <translation>Importando blocos do disco...</translation>
+ </message>
+ <message>
+ <source>Reindexing blocks on disk...</source>
+ <translation>Reindexando blocos no disco...</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>Enviar moedas para um endereço bitcoin</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>Fazer cópia de segurança da carteira para uma outra localização</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Mudar a frase de segurança utilizada na criptografia da carteira</translation>
+ </message>
+ <message>
+ <source>&amp;Debug window</source>
+ <translation>Janela de &amp;Depuração</translation>
+ </message>
+ <message>
+ <source>Open debugging and diagnostic console</source>
+ <translation>Abrir console de depuração e diagnóstico</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>&amp;Verificar mensagem...</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>Carteira</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>&amp;Enviar</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>&amp;Receber</translation>
+ </message>
+ <message>
+ <source>Show information about Bitcoin Core</source>
+ <translation>Mostrar informações sobre Bitcoin</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>&amp;Exibir/Ocultar</translation>
+ </message>
+ <message>
+ <source>Show or hide the main Window</source>
+ <translation>Mostrar ou esconder a Janela Principal.</translation>
+ </message>
+ <message>
+ <source>Encrypt the private keys that belong to your wallet</source>
+ <translation>Criptografar as chaves privadas que pertencem à sua carteira</translation>
+ </message>
+ <message>
+ <source>Sign messages with your Bitcoin addresses to prove you own them</source>
+ <translation>Assine mensagens com seus endereços Bitcoin para provar que você é dono delas</translation>
+ </message>
+ <message>
+ <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source>
+ <translation>Verificar mensagens para se assegurar que elas foram assinadas pelo dono de Endereços Bitcoin específicos</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;Arquivo</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;Configurações</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>A&amp;juda</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>Barra de ferramentas</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <source>Request payments (generates QR codes and bitcoin: URIs)</source>
+ <translation>Solicitações de pagamentos (gera códigos QR e bitcoin: URIs)</translation>
+ </message>
+ <message>
+ <source>&amp;About Bitcoin Core</source>
+ <translation>&amp;Sobre Bitcoin</translation>
+ </message>
+ <message>
+ <source>Modify configuration options for Bitcoin Core</source>
+ <translation>Modificar opções de configuração do Bitcoin</translation>
+ </message>
+ <message>
+ <source>Show the list of used sending addresses and labels</source>
+ <translation>Mostrar a lista de endereços de envio e rótulos usados</translation>
+ </message>
+ <message>
+ <source>Show the list of used receiving addresses and labels</source>
+ <translation>Mostrar a lista de endereços de recebimento usados ​​e rótulos</translation>
+ </message>
+ <message>
+ <source>Open a bitcoin: URI or payment request</source>
+ <translation>Abrir um bitcoin: URI ou cobrança</translation>
+ </message>
+ <message>
+ <source>&amp;Command-line options</source>
+ <translation>Opções de linha de &amp;comando</translation>
+ </message>
+ <message>
+ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
+ <translation>Mostra a mensagem de ajuda do Bitcoin para pegar a lista com os comandos possíveis</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n active connection(s) to Bitcoin network</source>
+ <translation><numerusform>%n conexão ativa na rede Bitcoin</numerusform><numerusform>%n conexões ativas na rede Bitcoin</numerusform></translation>
+ </message>
+ <message>
+ <source>No block source available...</source>
+ <translation>Nenhum servidor disponível...</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n hour(s)</source>
+ <translation><numerusform>%n hora</numerusform><numerusform>%n horas</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n day(s)</source>
+ <translation><numerusform>%n dia</numerusform><numerusform>%n dias</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n week(s)</source>
+ <translation><numerusform>%n semana</numerusform><numerusform>%n semanas</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 and %2</source>
+ <translation>%1 e %2</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n year(s)</source>
+ <translation><numerusform>%n ano</numerusform><numerusform>%n anos</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 behind</source>
+ <translation>%1 atrás</translation>
+ </message>
+ <message>
+ <source>Last received block was generated %1 ago.</source>
+ <translation>Último bloco recebido foi gerado %1 atrás.</translation>
+ </message>
+ <message>
+ <source>Transactions after this will not yet be visible.</source>
+ <translation>Transações após isso ainda não estão visíveis.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Erro</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Atenção</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Informação</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>Atualizado</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>Recuperando o atraso ...</translation>
+ </message>
+ <message>
+ <source>Date: %1
+</source>
+ <translation>Data: %1
+</translation>
+ </message>
+ <message>
+ <source>Amount: %1
+</source>
+ <translation>Quantidade: %1
+</translation>
+ </message>
+ <message>
+ <source>Type: %1
+</source>
+ <translation>Tipo: %1
+</translation>
+ </message>
+ <message>
+ <source>Label: %1
+</source>
+ <translation>Rótulo: %1
+</translation>
+ </message>
+ <message>
+ <source>Address: %1
+</source>
+ <translation>Endereço: %1
+</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>Transação enviada</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>Transação recebida</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>Carteira está &lt;b&gt;criptografada&lt;/b&gt; e atualmente &lt;b&gt;desbloqueada&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>Carteira está &lt;b&gt;criptografada&lt;/b&gt; e atualmente &lt;b&gt;bloqueada&lt;/b&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <source>Network Alert</source>
+ <translation>Alerta da Rede</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Coin Selection</source>
+ <translation>Selecionar Moeda</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Quantidade:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Bytes:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Quantia:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Prioridade:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Taxa:</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Poeira:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Depois da taxa:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>trocar</translation>
+ </message>
+ <message>
+ <source>(un)select all</source>
+ <translation>(de)selecionar tudo</translation>
+ </message>
+ <message>
+ <source>Tree mode</source>
+ <translation>Modo árvore</translation>
+ </message>
+ <message>
+ <source>List mode</source>
+ <translation>Modo lista</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Quantidade</translation>
+ </message>
+ <message>
+ <source>Received with label</source>
+ <translation>Recebido com rótulo</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>Recebido com endereço </translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Confirmations</source>
+ <translation>Confirmações</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Confirmado</translation>
+ </message>
+ <message>
+ <source>Priority</source>
+ <translation>Prioridade</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Copiar endereço</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Copiar rótulo</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copiar quantia</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Copiar ID da transação</translation>
+ </message>
+ <message>
+ <source>Lock unspent</source>
+ <translation>Travar não gasto</translation>
+ </message>
+ <message>
+ <source>Unlock unspent</source>
+ <translation>Destravar não gasto</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Copiar quantidade</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Copiar taxa</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Copia pós-taxa</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Copiar bytes</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Copia prioridade</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Copiar poeira</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Copia alteração</translation>
+ </message>
+ <message>
+ <source>highest</source>
+ <translation>mais alta possível</translation>
+ </message>
+ <message>
+ <source>higher</source>
+ <translation>muito alta</translation>
+ </message>
+ <message>
+ <source>high</source>
+ <translation>alta</translation>
+ </message>
+ <message>
+ <source>medium-high</source>
+ <translation>média-alta</translation>
+ </message>
+ <message>
+ <source>medium</source>
+ <translation>média</translation>
+ </message>
+ <message>
+ <source>low-medium</source>
+ <translation>média-baixa</translation>
+ </message>
+ <message>
+ <source>low</source>
+ <translation>baixa</translation>
+ </message>
+ <message>
+ <source>lower</source>
+ <translation>muito baixa</translation>
+ </message>
+ <message>
+ <source>lowest</source>
+ <translation>a mais baixa possível</translation>
+ </message>
+ <message>
+ <source>(%1 locked)</source>
+ <translation>(%1 travado)</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>nenhum</translation>
+ </message>
+ <message>
+ <source>This label turns red if the transaction size is greater than 1000 bytes.</source>
+ <translation>Este texto fica vermelho se o tamanho da transação for maior que 1000 bytes.</translation>
+ </message>
+ <message>
+ <source>This label turns red if the priority is smaller than "medium".</source>
+ <translation>Este texto fica vermelho se a prioridade é menor que "medio".</translation>
+ </message>
+ <message>
+ <source>This label turns red if any recipient receives an amount smaller than %1.</source>
+ <translation>Este texto fica vermelho se qualquer destinatário receber uma quantidade menor que %1.</translation>
+ </message>
+ <message>
+ <source>Can vary +/- %1 satoshi(s) per input.</source>
+ <translation>Pode variar +/- %1 satoshi(s) por entrada.</translation>
+ </message>
+ <message>
+ <source>yes</source>
+ <translation>sim</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>não</translation>
+ </message>
+ <message>
+ <source>This means a fee of at least %1 per kB is required.</source>
+ <translation>Isso significa que uma taxa de pelo menos %1 por kB é necessária.</translation>
+ </message>
+ <message>
+ <source>Can vary +/- 1 byte per input.</source>
+ <translation>Pode variar +/- 1 byte por entrada.</translation>
+ </message>
+ <message>
+ <source>Transactions with higher priority are more likely to get included into a block.</source>
+ <translation>Transações de alta prioridade são mais propensas a serem incluídas em um bloco.</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(Sem rótulo)</translation>
+ </message>
+ <message>
+ <source>change from %1 (%2)</source>
+ <translation>troco de %1 (%2)</translation>
+ </message>
+ <message>
+ <source>(change)</source>
+ <translation>(troco)</translation>
+ </message>
+</context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>Editar Endereço</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>&amp;Rótulo</translation>
+ </message>
+ <message>
+ <source>The label associated with this address list entry</source>
+ <translation>O rótulo associado a esta entrada na lista de endereços</translation>
+ </message>
+ <message>
+ <source>The address associated with this address list entry. This can only be modified for sending addresses.</source>
+ <translation>O endereço associado a esta lista de endereços de entrada. Isso só pode ser modificado para o envio de endereços.</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;Endereço</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>Novo endereço de recebimento</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>Novo endereço de envio</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>Editar endereço de recebimento</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>Editar endereço de envio</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>O endereço digitado "%1" já se encontra no catálogo de endereços.</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is not a valid Bitcoin address.</source>
+ <translation>O endereço digitado "%1" não é um endereço Bitcoin válido.</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>Não foi possível desbloquear a carteira.</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>A geração de nova chave falhou.</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ <message>
+ <source>A new data directory will be created.</source>
+ <translation>Um novo diretório de dados será criado.</translation>
+ </message>
+ <message>
+ <source>name</source>
+ <translation>nome</translation>
+ </message>
+ <message>
+ <source>Directory already exists. Add %1 if you intend to create a new directory here.</source>
+ <translation>O diretório já existe. Adicione %1 se você pretende criar um novo diretório aqui.</translation>
+ </message>
+ <message>
+ <source>Path already exists, and is not a directory.</source>
+ <translation>Esta pasta já existe, e não é um diretório.</translation>
+ </message>
+ <message>
+ <source>Cannot create data directory here.</source>
+ <translation>Não é possível criar um diretório de dados aqui.</translation>
+ </message>
+</context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>versão</translation>
+ </message>
+ <message>
+ <source>(%1-bit)</source>
+ <translation>(%1-bit)</translation>
+ </message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>Sobre o Bitcoin</translation>
+ </message>
+ <message>
+ <source>Command-line options</source>
+ <translation>Opções da linha de comando</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>Uso:</translation>
+ </message>
+ <message>
+ <source>command-line options</source>
+ <translation>opções da linha de comando</translation>
+ </message>
+</context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Welcome</source>
+ <translation>Bem-vindo</translation>
+ </message>
+ <message>
+ <source>Welcome to Bitcoin Core.</source>
+ <translation>Bem vindo ao Bitcoin.</translation>
+ </message>
+ <message>
+ <source>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</source>
+ <translation>A primeira vez que o programa é aberto você pode escolher onde o Bitcoin vai guardar os dados.</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory.</source>
+ <translation>O Bitcoin vai fazer download e salvar uma cópia da cadeia de blocos do Bitcoin: Blockchain. Pelo menos %1 GB de dados serão armazenados nesse diretório e isso aumentará ao longo do tempo. Sua carteira também será armazenada nesse diretório.</translation>
+ </message>
+ <message>
+ <source>Use the default data directory</source>
+ <translation>Use o diretório de dados padrão</translation>
+ </message>
+ <message>
+ <source>Use a custom data directory:</source>
+ <translation>Use um diretório de dados personalizado:</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <source>Error: Specified data directory "%1" cannot be created.</source>
+ <translation>Erro: Diretório de dados "%1" não pode ser criado.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Erro</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n GB of free space available</source>
+ <translation><numerusform>%n GB de espaço livre disponível</numerusform><numerusform>%n GB de espaço livre disponível</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>(of %n GB needed)</source>
+ <translation><numerusform>(de %n GB necessário)</numerusform><numerusform>(de %n GB necessário)</numerusform></translation>
+ </message>
+</context>
+<context>
+ <name>OpenURIDialog</name>
+ <message>
+ <source>Open URI</source>
+ <translation>Abrir URI</translation>
+ </message>
+ <message>
+ <source>Open payment request from URI or file</source>
+ <translation>Cobrança aberta de URI ou arquivo</translation>
+ </message>
+ <message>
+ <source>URI:</source>
+ <translation>URI:</translation>
+ </message>
+ <message>
+ <source>Select payment request file</source>
+ <translation>Selecione o arquivo de cobrança</translation>
+ </message>
+ <message>
+ <source>Select payment request file to open</source>
+ <translation>Selecione o arquivo de cobrança para ser aberto</translation>
+ </message>
+</context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>Opções</translation>
+ </message>
+ <message>
+ <source>&amp;Main</source>
+ <translation>Principal</translation>
+ </message>
+ <message>
+ <source>Size of &amp;database cache</source>
+ <translation>Tamanho do banco de &amp;dados do cache</translation>
+ </message>
+ <message>
+ <source>MB</source>
+ <translation>MB</translation>
+ </message>
+ <message>
+ <source>Number of script &amp;verification threads</source>
+ <translation>Número de threads do script de &amp;verificação</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside</source>
+ <translation>Aceitar conexões externas</translation>
+ </message>
+ <message>
+ <source>Allow incoming connections</source>
+ <translation>Permitir conexões de entrada</translation>
+ </message>
+ <message>
+ <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
+ <translation>Endereço de IP do proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</translation>
+ </message>
+ <message>
+ <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source>
+ <translation>Minimizar em vez de fechar o programa quando a janela for fechada. Quando essa opção estiver ativa, o programa só será fechado somente pela opção Sair no menu Arquivo.</translation>
+ </message>
+ <message>
+ <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source>
+ <translation>A linguagem da interface do usuário pode ser alterada aqui. A mudança ocorrerá após o reinício do Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source>
+ <translation>URLs de terceiros (exemplo: explorador de blocos) que aparecem na aba de transações como itens do menu de contexto. %s na URL é substituido pela hash da transação. Múltiplas URLs são separadas pela barra vertical |.</translation>
+ </message>
+ <message>
+ <source>Third party transaction URLs</source>
+ <translation>URLs de transação de terceiros:</translation>
+ </message>
+ <message>
+ <source>Active command-line options that override above options:</source>
+ <translation>Ativa as opções de linha de comando que sobrescreve as opções acima:</translation>
+ </message>
+ <message>
+ <source>Reset all client options to default.</source>
+ <translation>Redefinir todas as opções do cliente para opções padrão.</translation>
+ </message>
+ <message>
+ <source>&amp;Reset Options</source>
+ <translation>&amp;Redefinir opções</translation>
+ </message>
+ <message>
+ <source>&amp;Network</source>
+ <translation>Rede</translation>
+ </message>
+ <message>
+ <source>Automatically start Bitcoin Core after logging in to the system.</source>
+ <translation>Inicar automaticamente o Bitcoin ao logar no sistema.</translation>
+ </message>
+ <message>
+ <source>&amp;Start Bitcoin Core on system login</source>
+ <translation>&amp;Iniciar Bitcoin no login do sistema</translation>
+ </message>
+ <message>
+ <source>(0 = auto, &lt;0 = leave that many cores free)</source>
+ <translation>(0 = automático, &lt;0 = número de cores deixados livres)</translation>
+ </message>
+ <message>
+ <source>W&amp;allet</source>
+ <translation>C&amp;arteira</translation>
+ </message>
+ <message>
+ <source>Expert</source>
+ <translation>Avançado</translation>
+ </message>
+ <message>
+ <source>Enable coin &amp;control features</source>
+ <translation>Habilitar opções de &amp;controle de moedas</translation>
+ </message>
+ <message>
+ <source>If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.</source>
+ <translation>Se você desabilitar o gasto de um troco não confirmado, o troco da transação não poderá ser utilizado até a transação ter pelo menos uma confirmação. Isso também afeta seu saldo computado.</translation>
+ </message>
+ <message>
+ <source>&amp;Spend unconfirmed change</source>
+ <translation>Ga&amp;star mudança não confirmada</translation>
+ </message>
+ <message>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>Abrir as portas do cliente Bitcoin automaticamente no roteador. Isto só funcionará se seu roteador suportar UPnP e esta função estiver habilitada.</translation>
+ </message>
+ <message>
+ <source>Map port using &amp;UPnP</source>
+ <translation>Mapear porta usando &amp;UPnP</translation>
+ </message>
+ <message>
+ <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
+ <translation>Conectar na rede Bitcoin através de um proxy SOCKS5.</translation>
+ </message>
+ <message>
+ <source>&amp;Connect through SOCKS5 proxy (default proxy):</source>
+ <translation>&amp;Conectar usando proxy SOCKS5 (proxy pradrão):</translation>
+ </message>
+ <message>
+ <source>Proxy &amp;IP:</source>
+ <translation>&amp;IP do proxy:</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>&amp;Porta:</translation>
+ </message>
+ <message>
+ <source>Port of the proxy (e.g. 9050)</source>
+ <translation>Porta do serviço de proxy (ex. 9050)</translation>
+ </message>
+ <message>
+ <source>&amp;Window</source>
+ <translation>&amp;Janela</translation>
+ </message>
+ <message>
+ <source>Show only a tray icon after minimizing the window.</source>
+ <translation>Mostrar apenas um ícone na bandeja ao minimizar a janela.</translation>
+ </message>
+ <message>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>&amp;Minimizar para a bandeja em vez da barra de tarefas.</translation>
+ </message>
+ <message>
+ <source>M&amp;inimize on close</source>
+ <translation>M&amp;inimizar ao sair</translation>
+ </message>
+ <message>
+ <source>&amp;Display</source>
+ <translation>&amp;Mostrar</translation>
+ </message>
+ <message>
+ <source>User Interface &amp;language:</source>
+ <translation>&amp;Linguagem da interface:</translation>
+ </message>
+ <message>
+ <source>&amp;Unit to show amounts in:</source>
+ <translation>&amp;Unidade usada para mostrar quantidades:</translation>
+ </message>
+ <message>
+ <source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
+ <translation>Escolha a unidade padrão de subdivisão para interface mostrar quando enviar bitcoins.</translation>
+ </message>
+ <message>
+ <source>Whether to show coin control features or not.</source>
+ <translation>Mostrar ou não opções de controle da moeda.</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>&amp;OK</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>&amp;Cancelar</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>padrão</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>nenhum</translation>
+ </message>
+ <message>
+ <source>Confirm options reset</source>
+ <translation>Confirmar redefinição de opções</translation>
+ </message>
+ <message>
+ <source>Client restart required to activate changes.</source>
+ <translation>Reinicialização do aplicativo necessária para efetivar alterações.</translation>
+ </message>
+ <message>
+ <source>Client will be shut down. Do you want to proceed?</source>
+ <translation>O programa será encerrado. Deseja continuar?</translation>
+ </message>
+ <message>
+ <source>This change would require a client restart.</source>
+ <translation>Essa mudança requer uma reinicialização do aplicativo.</translation>
+ </message>
+ <message>
+ <source>The supplied proxy address is invalid.</source>
+ <translation>O endereço proxy fornecido é inválido.</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>Formulário</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>A informação mostrada pode estar desatualizada. Sua carteira sincroniza automaticamente com a rede Bitcoin depois que a conexão é estabelecida, mas este processo pode não estar completo ainda.</translation>
+ </message>
+ <message>
+ <source>Watch-only:</source>
+ <translation>Monitorados:</translation>
+ </message>
+ <message>
+ <source>Available:</source>
+ <translation>Disponível:</translation>
+ </message>
+ <message>
+ <source>Your current spendable balance</source>
+ <translation>Seu saldo atual spendable</translation>
+ </message>
+ <message>
+ <source>Pending:</source>
+ <translation>Pendente:</translation>
+ </message>
+ <message>
+ <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source>
+ <translation>Total de transações que ainda têm de ser confirmados, e ainda não contam para o equilíbrio spendable</translation>
+ </message>
+ <message>
+ <source>Immature:</source>
+ <translation>Imaturo:</translation>
+ </message>
+ <message>
+ <source>Mined balance that has not yet matured</source>
+ <translation>Saldo minerado que ainda não maturou</translation>
+ </message>
+ <message>
+ <source>Balances</source>
+ <translation>Saldos</translation>
+ </message>
+ <message>
+ <source>Total:</source>
+ <translation>Total:</translation>
+ </message>
+ <message>
+ <source>Your current total balance</source>
+ <translation>Seu saldo total atual</translation>
+ </message>
+ <message>
+ <source>Your current balance in watch-only addresses</source>
+ <translation>Sua balança atual em endereços apenas visualizados</translation>
+ </message>
+ <message>
+ <source>Spendable:</source>
+ <translation>Disponível: </translation>
+ </message>
+ <message>
+ <source>Recent transactions</source>
+ <translation>Transações recentes</translation>
+ </message>
+ <message>
+ <source>Unconfirmed transactions to watch-only addresses</source>
+ <translation>Transações não confirmadas de um endereço monitorado</translation>
+ </message>
+ <message>
+ <source>Mined balance in watch-only addresses that has not yet matured</source>
+ <translation>Saldo minerado de endereço monitorado ainda não foi implementado</translation>
+ </message>
+ <message>
+ <source>Current total balance in watch-only addresses</source>
+ <translation>Balanço total em endereços monitorados</translation>
+ </message>
+</context>
+<context>
+ <name>PaymentServer</name>
+ <message>
+ <source>URI handling</source>
+ <translation>Manipulação de URI</translation>
+ </message>
+ <message>
+ <source>Invalid payment address %1</source>
+ <translation>Endereço de pagamento inválido %1</translation>
+ </message>
+ <message>
+ <source>Payment request rejected</source>
+ <translation>Solicitação de pagamento rejeitada</translation>
+ </message>
+ <message>
+ <source>Payment request is not initialized.</source>
+ <translation>Pedido de pagamento não é inicializado.</translation>
+ </message>
+ <message>
+ <source>Requested payment amount of %1 is too small (considered dust).</source>
+ <translation>Valor do pagamento solicitado de %1 é muito pequeno (Considerado poeira).</translation>
+ </message>
+ <message>
+ <source>Payment request error</source>
+ <translation>Erro no pedido de pagamento</translation>
+ </message>
+ <message>
+ <source>Cannot start bitcoin: click-to-pay handler</source>
+ <translation>Não foi possível iniciar bitcoin: manipulador clique-para-pagar</translation>
+ </message>
+ <message>
+ <source>Payment request fetch URL is invalid: %1</source>
+ <translation>URL de cobrança é inválida: %1</translation>
+ </message>
+ <message>
+ <source>Payment request file handling</source>
+ <translation>Manipulação de arquivo de cobrança</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>Pedido de pagamento expirado.</translation>
+ </message>
+ <message>
+ <source>Unverified payment requests to custom payment scripts are unsupported.</source>
+ <translation>Cobrança não verificada para scripts de pagamento personalizados não é suportado.</translation>
+ </message>
+ <message>
+ <source>Invalid payment request.</source>
+ <translation>Pedido de pagamento inválido.</translation>
+ </message>
+ <message>
+ <source>Refund from %1</source>
+ <translation>Reembolso de %1</translation>
+ </message>
+ <message>
+ <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source>
+ <translation>Pedido de pagamento %1 é muito grande (%2 bytes, permitido %3 bytes).</translation>
+ </message>
+ <message>
+ <source>Payment request DoS protection</source>
+ <translation>Pagamento requer proteção DoS</translation>
+ </message>
+ <message>
+ <source>Error communicating with %1: %2</source>
+ <translation>Erro na comunicação com %1: %2</translation>
+ </message>
+ <message>
+ <source>Payment request cannot be parsed!</source>
+ <translation>Requisição de pagamento não pode ser analisado!</translation>
+ </message>
+ <message>
+ <source>Bad response from server %1</source>
+ <translation>Resposta incorreta do servidor %1</translation>
+ </message>
+ <message>
+ <source>Payment acknowledged</source>
+ <translation>Pagamento reconhecido</translation>
+ </message>
+ <message>
+ <source>Network request error</source>
+ <translation>Erro de solicitação de rede</translation>
+ </message>
+</context>
+<context>
+ <name>PeerTableModel</name>
+ <message>
+ <source>User Agent</source>
+ <translation>User Agent</translation>
+ </message>
+ <message>
+ <source>Node/Service</source>
+ <translation>Nó/Serviço</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Ping</translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>Quantidade</translation>
+ </message>
+ <message>
+ <source>Enter a Bitcoin address (e.g. %1)</source>
+ <translation>Informe um endereço Bitcoin (ex: %1)</translation>
+ </message>
+ <message>
+ <source>%1 d</source>
+ <translation>%1 d</translation>
+ </message>
+ <message>
+ <source>%1 h</source>
+ <translation>%1 h</translation>
+ </message>
+ <message>
+ <source>%1 m</source>
+ <translation>%1 m</translation>
+ </message>
+ <message>
+ <source>%1 s</source>
+ <translation>%1 s</translation>
+ </message>
+ <message>
+ <source>None</source>
+ <translation>Nenhum</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>N/A</translation>
+ </message>
+ <message>
+ <source>%1 ms</source>
+ <translation>%1 ms</translation>
+ </message>
+</context>
+<context>
+ <name>QRImageWidget</name>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Salvar imagem</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Image</source>
+ <translation>&amp;Copiar Imagem</translation>
+ </message>
+ <message>
+ <source>Save QR Code</source>
+ <translation>Salvar código QR</translation>
+ </message>
+ <message>
+ <source>PNG Image (*.png)</source>
+ <translation>PNG Imagem (*.png)</translation>
+ </message>
+</context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>Client name</source>
+ <translation>Nome do cliente</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>N/A</translation>
+ </message>
+ <message>
+ <source>Client version</source>
+ <translation>Versão do cliente</translation>
+ </message>
+ <message>
+ <source>&amp;Information</source>
+ <translation>&amp;Informação</translation>
+ </message>
+ <message>
+ <source>Debug window</source>
+ <translation>Janela de depuração</translation>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>Geral</translation>
+ </message>
+ <message>
+ <source>Using OpenSSL version</source>
+ <translation>Versão do OpenSSL</translation>
+ </message>
+ <message>
+ <source>Using BerkeleyDB version</source>
+ <translation>Versão do BerkeleyDB</translation>
+ </message>
+ <message>
+ <source>Startup time</source>
+ <translation>Horário de inicialização</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Rede</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>Nome</translation>
+ </message>
+ <message>
+ <source>Number of connections</source>
+ <translation>Número de conexões</translation>
+ </message>
+ <message>
+ <source>Block chain</source>
+ <translation>Corrente de blocos</translation>
+ </message>
+ <message>
+ <source>Current number of blocks</source>
+ <translation>Quantidade atual de blocos</translation>
+ </message>
+ <message>
+ <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source>
+ <translation>Abrir o arquivo de log de depuração do Bitcoin na pasta de dados atual. Isso pode demorar para arquivos grandes.</translation>
+ </message>
+ <message>
+ <source>Received</source>
+ <translation>Recebido</translation>
+ </message>
+ <message>
+ <source>Sent</source>
+ <translation>Enviado</translation>
+ </message>
+ <message>
+ <source>&amp;Peers</source>
+ <translation>&amp;Pares</translation>
+ </message>
+ <message>
+ <source>Select a peer to view detailed information.</source>
+ <translation>Selecione um cliente para ver informações detalhadas.</translation>
+ </message>
+ <message>
+ <source>Direction</source>
+ <translation>Direção</translation>
+ </message>
+ <message>
+ <source>Version</source>
+ <translation>Versão</translation>
+ </message>
+ <message>
+ <source>User Agent</source>
+ <translation>User Agent</translation>
+ </message>
+ <message>
+ <source>Services</source>
+ <translation>Serviços</translation>
+ </message>
+ <message>
+ <source>Starting Height</source>
+ <translation>Altura inicial</translation>
+ </message>
+ <message>
+ <source>Sync Height</source>
+ <translation>Altura sincronizada</translation>
+ </message>
+ <message>
+ <source>Ban Score</source>
+ <translation>Banir pontuação</translation>
+ </message>
+ <message>
+ <source>Connection Time</source>
+ <translation>Tempo de conexão </translation>
+ </message>
+ <message>
+ <source>Last Send</source>
+ <translation>Ultimo Envio</translation>
+ </message>
+ <message>
+ <source>Last Receive</source>
+ <translation>Ultimo Recebido</translation>
+ </message>
+ <message>
+ <source>Bytes Sent</source>
+ <translation>Bytes Enviados</translation>
+ </message>
+ <message>
+ <source>Bytes Received</source>
+ <translation>Bytes recebidos</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Ping</translation>
+ </message>
+ <message>
+ <source>Last block time</source>
+ <translation>Horário do último bloco</translation>
+ </message>
+ <message>
+ <source>&amp;Open</source>
+ <translation>&amp;Abrir</translation>
+ </message>
+ <message>
+ <source>&amp;Console</source>
+ <translation>&amp;Console</translation>
+ </message>
+ <message>
+ <source>&amp;Network Traffic</source>
+ <translation>Tráfico de Rede</translation>
+ </message>
+ <message>
+ <source>&amp;Clear</source>
+ <translation>&amp;Limpar</translation>
+ </message>
+ <message>
+ <source>Totals</source>
+ <translation>Totais</translation>
+ </message>
+ <message>
+ <source>In:</source>
+ <translation>Entrada:</translation>
+ </message>
+ <message>
+ <source>Out:</source>
+ <translation>Saída:</translation>
+ </message>
+ <message>
+ <source>Build date</source>
+ <translation>Data do 'build'</translation>
+ </message>
+ <message>
+ <source>Debug log file</source>
+ <translation>Arquivo de log de Depuração</translation>
+ </message>
+ <message>
+ <source>Clear console</source>
+ <translation>Limpar console</translation>
+ </message>
+ <message>
+ <source>Welcome to the Bitcoin Core RPC console.</source>
+ <translation>Bem vindo ao console de RPC do Bitcoin.</translation>
+ </message>
+ <message>
+ <source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
+ <translation>Use as setas para cima e para baixo para navegar pelo histórico, e &lt;b&gt;Ctrl-L&lt;/b&gt; para limpar a tela.</translation>
+ </message>
+ <message>
+ <source>Type &lt;b&gt;help&lt;/b&gt; for an overview of available commands.</source>
+ <translation>Digite &lt;b&gt;help&lt;/b&gt; para uma visão geral dos comandos disponíveis.</translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation>%1 B</translation>
+ </message>
+ <message>
+ <source>%1 KB</source>
+ <translation>%1 KB</translation>
+ </message>
+ <message>
+ <source>%1 MB</source>
+ <translation>%1 MB</translation>
+ </message>
+ <message>
+ <source>%1 GB</source>
+ <translation>%1 GB</translation>
+ </message>
+ <message>
+ <source>via %1</source>
+ <translation>por %1</translation>
+ </message>
+ <message>
+ <source>never</source>
+ <translation>nunca</translation>
+ </message>
+ <message>
+ <source>Inbound</source>
+ <translation>Entrada</translation>
+ </message>
+ <message>
+ <source>Outbound</source>
+ <translation>Saída</translation>
+ </message>
+ <message>
+ <source>Unknown</source>
+ <translation>Desconhecido</translation>
+ </message>
+ <message>
+ <source>Fetching...</source>
+ <translation>Buscando...</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Amount:</source>
+ <translation>Qu&amp;antia:</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Rótulo:</translation>
+ </message>
+ <message>
+ <source>&amp;Message:</source>
+ <translation>&amp;Mensagem</translation>
+ </message>
+ <message>
+ <source>Reuse one of the previously used receiving addresses. Reusing addresses has security and privacy issues. Do not use this unless re-generating a payment request made before.</source>
+ <translation>Reutilize um dos endereços de recebimento anteriormente utilizados. Reutilizar um endereço implica em problemas com segurança e privacidade. Não reutilize a menos que esteja refazendo uma cobrança já feita anteriormente.</translation>
+ </message>
+ <message>
+ <source>R&amp;euse an existing receiving address (not recommended)</source>
+ <translation>R&amp;eutilize um endereço de recebimento (não recomendado)</translation>
+ </message>
+ <message>
+ <source>An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network.</source>
+ <translation>Uma mensagem opcional que será anexada na cobrança e será mostrada quando ela for aberta. Nota: A mensagem não será enviada com o pagamento pela rede Bitcoin.</translation>
+ </message>
+ <message>
+ <source>An optional label to associate with the new receiving address.</source>
+ <translation>Um marcador opcional para associar ao novo endereço de recebimento.</translation>
+ </message>
+ <message>
+ <source>Use this form to request payments. All fields are &lt;b&gt;optional&lt;/b&gt;.</source>
+ <translation>Use esse formulário para fazer cobranças. Todos os campos são &lt;b&gt;opcionais&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>An optional amount to request. Leave this empty or zero to not request a specific amount.</source>
+ <translation>Uma quantia opcional para cobrar. Deixe vazio ou em branco se o pagador puder especificar a quantia.</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Limpa todos os campos do formulário.</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation>Limpar</translation>
+ </message>
+ <message>
+ <source>Requested payments history</source>
+ <translation>Histórico de cobranças</translation>
+ </message>
+ <message>
+ <source>&amp;Request payment</source>
+ <translation>&amp;Requisitar Pagamento</translation>
+ </message>
+ <message>
+ <source>Show the selected request (does the same as double clicking an entry)</source>
+ <translation>Mostra a cobrança selecionada (o mesmo que clicar duas vezes em um registro)</translation>
+ </message>
+ <message>
+ <source>Show</source>
+ <translation>Mostrar</translation>
+ </message>
+ <message>
+ <source>Remove the selected entries from the list</source>
+ <translation>Remove o registro selecionado da lista</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>Remover</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Copiar rótulo</translation>
+ </message>
+ <message>
+ <source>Copy message</source>
+ <translation>Copiar mensagem</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copiar quantia</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>QR Code</source>
+ <translation>Código QR</translation>
+ </message>
+ <message>
+ <source>Copy &amp;URI</source>
+ <translation>Copiar &amp;URI</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Address</source>
+ <translation>&amp;Copiar Endereço</translation>
+ </message>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Salvar Imagem...</translation>
+ </message>
+ <message>
+ <source>Request payment to %1</source>
+ <translation>Requisitar pagamento para %1</translation>
+ </message>
+ <message>
+ <source>Payment information</source>
+ <translation>Informação de pagamento</translation>
+ </message>
+ <message>
+ <source>URI</source>
+ <translation>URI</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Endereço</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Quantidade</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Rótulo</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Mensagem</translation>
+ </message>
+ <message>
+ <source>Resulting URI too long, try to reduce the text for label / message.</source>
+ <translation>URI resultante muito longa. Tente reduzir o texto do rótulo ou da mensagem.</translation>
+ </message>
+ <message>
+ <source>Error encoding URI into QR Code.</source>
+ <translation>Erro ao codigicar o URI em código QR</translation>
+ </message>
+</context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Rótulo</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Mensagem</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Quantidade</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(Sem rótulo)</translation>
+ </message>
+ <message>
+ <source>(no message)</source>
+ <translation>(sem mensagem)</translation>
+ </message>
+ <message>
+ <source>(no amount)</source>
+ <translation>(sem quantia especificada)</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Enviar moedas</translation>
+ </message>
+ <message>
+ <source>Coin Control Features</source>
+ <translation>Opções de controle de moeda</translation>
+ </message>
+ <message>
+ <source>Inputs...</source>
+ <translation>Entradas...</translation>
+ </message>
+ <message>
+ <source>automatically selected</source>
+ <translation>automaticamente selecionado</translation>
+ </message>
+ <message>
+ <source>Insufficient funds!</source>
+ <translation>Saldo insuficiente!</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Quantidade:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Bytes:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Quantia:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Prioridade:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Taxa:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Depois da taxa:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>troco</translation>
+ </message>
+ <message>
+ <source>If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address.</source>
+ <translation>Se isso estiver ativo e o endereço de troco estiver vazio ou inválido, o troco será enviado a um novo endereço gerado na hora.</translation>
+ </message>
+ <message>
+ <source>Custom change address</source>
+ <translation>Endereço específico de troco</translation>
+ </message>
+ <message>
+ <source>Transaction Fee:</source>
+ <translation>Taxa de transação: </translation>
+ </message>
+ <message>
+ <source>Choose...</source>
+ <translation>Escolher</translation>
+ </message>
+ <message>
+ <source>collapse fee-settings</source>
+ <translation>colapso Taxa de definições</translation>
+ </message>
+ <message>
+ <source>per kilobyte</source>
+ <translation>por kilobyte</translation>
+ </message>
+ <message>
+ <source>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "total at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source>
+ <translation>Se a taxa personalizada for definida em 1000 satoshis e a transação tiver somente 250 bytes, então "por kilobyte" somente paga 250 satoshis de taxa, enquanto "pelo menos" paga 1000 satoshis. Se a transação for maior que 1 kilobyte, ambos pagam por kilobyte.</translation>
+ </message>
+ <message>
+ <source>Hide</source>
+ <translation>Ocultar</translation>
+ </message>
+ <message>
+ <source>total at least</source>
+ <translation>pelo menos</translation>
+ </message>
+ <message>
+ <source>Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process.</source>
+ <translation>Pagando apenas a taxa mínima é bom, desde que haja pouco volume de transações. Mas esteja ciente de que isso pode acabar em uma transação nunca confirmanda uma vez que há mais demanda por transações do que a rede pode processar.</translation>
+ </message>
+ <message>
+ <source>(read the tooltip)</source>
+ <translation>(Leia o popup)</translation>
+ </message>
+ <message>
+ <source>Recommended:</source>
+ <translation>Recomendado:</translation>
+ </message>
+ <message>
+ <source>Custom:</source>
+ <translation>Personalizado:</translation>
+ </message>
+ <message>
+ <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source>
+ <translation>(Smart fee não iniciado. Isso requer alguns blocos...)</translation>
+ </message>
+ <message>
+ <source>Confirmation time:</source>
+ <translation>Tempo de confirmação:</translation>
+ </message>
+ <message>
+ <source>normal</source>
+ <translation>normal</translation>
+ </message>
+ <message>
+ <source>fast</source>
+ <translation>rápido </translation>
+ </message>
+ <message>
+ <source>Send as zero-fee transaction if possible</source>
+ <translation>Enviar sem taxa de transação se possível </translation>
+ </message>
+ <message>
+ <source>(confirmation may take longer)</source>
+ <translation>(confirmação pode demorar)</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>Enviar para vários destinatários de uma só vez</translation>
+ </message>
+ <message>
+ <source>Add &amp;Recipient</source>
+ <translation>Adicionar destinatário</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Limpar todos os campos do formulário.</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Poeira:</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Limpar Tudo</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>Saldo:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>Confirmar o envio</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>Enviar</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>Confirmar envio de moedas</translation>
+ </message>
+ <message>
+ <source>%1 to %2</source>
+ <translation>%1 para %2</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Copiar quantidade</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copiar quantia</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Copiar taxa</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Copia pós-taxa</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Copiar bytes</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Copia prioridade</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Copia alteração</translation>
+ </message>
+ <message>
+ <source>or</source>
+ <translation>ou</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>A quantidade a ser paga precisa ser maior que 0.</translation>
+ </message>
+ <message>
+ <source>The amount exceeds your balance.</source>
+ <translation>A quantidade excede seu saldo.</translation>
+ </message>
+ <message>
+ <source>The total exceeds your balance when the %1 transaction fee is included.</source>
+ <translation>O total excede seu saldo quando uma taxa de transação de %1 é incluída.</translation>
+ </message>
+ <message>
+ <source>Transaction creation failed!</source>
+ <translation>A criação de transação falhou!</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>A transação foi rejeitada! Isso pode acontecer se alguns bitcoins na sua carteira já foram gastos em outro local, por exemplo se você tiver uma cópia do wallet.dat e os bitcoins tiverem sido gastos na cópia mas não marcados como gastos aqui ainda.</translation>
+ </message>
+ <message>
+ <source>A fee higher than %1 is considered an absurdly high fee.</source>
+ <translation>Uma taxa maior que %1 é considerada uma taxa absurdamente alto.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>Pedido de pagamento expirado.</translation>
+ </message>
+ <message numerus="yes">
+ <source>Estimated to begin confirmation within %n block(s).</source>
+ <translation><numerusform>Confirmação estimada em %n bloco.</numerusform><numerusform>Confirmação estimada em %n blocos.</numerusform></translation>
+ </message>
+ <message>
+ <source>Pay only the minimum fee of %1</source>
+ <translation>Pagar somente a taxa mínima de %1</translation>
+ </message>
+ <message>
+ <source>The recipient address is not valid. Please recheck.</source>
+ <translation>O endereço do destinatário é inválido. Favor confirmar.</translation>
+ </message>
+ <message>
+ <source>Duplicate address found: addresses should only be used once each.</source>
+ <translation>Endereço duplicado encontrado: Endereços devem ser usados somente uma vez cada.</translation>
+ </message>
+ <message>
+ <source>Warning: Invalid Bitcoin address</source>
+ <translation>Atenção: endereço de Bitcoin inválido</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(Sem rótulo)</translation>
+ </message>
+ <message>
+ <source>Warning: Unknown change address</source>
+ <translation>Atenção: endereço de troco desconhecido</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Copiar poeira</translation>
+ </message>
+ <message>
+ <source>Are you sure you want to send?</source>
+ <translation>Tem certeza que quer enviar?</translation>
+ </message>
+ <message>
+ <source>added as transaction fee</source>
+ <translation>Adicionado como taxa de transação</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>Q&amp;uantidade:</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>Pagar &amp;Para:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Digite um rótulo para este endereço para adicioná-lo ao catálogo de endereços</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Rótulo:</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Escolher endereço usado anteriormente</translation>
+ </message>
+ <message>
+ <source>This is a normal payment.</source>
+ <translation>Este é um pagamento normal.</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to send the payment to</source>
+ <translation>Endereço que enviará o pagamento</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Colar o endereço da área de transferência</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Remove this entry</source>
+ <translation>Remover esta entrada</translation>
+ </message>
+ <message>
+ <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source>
+ <translation>A taxa será deduzida da quantia sendo enviada. O destinatário receberá menos bitcoins do que você colocou no campo de quantidade. Se varios destinatários estão selecionados, a taxa é dividida igualmente.</translation>
+ </message>
+ <message>
+ <source>S&amp;ubtract fee from amount</source>
+ <translation>&amp;Retirar taxa da quantia</translation>
+ </message>
+ <message>
+ <source>Message:</source>
+ <translation>Mensagem:</translation>
+ </message>
+ <message>
+ <source>This is an unauthenticated payment request.</source>
+ <translation>Esta é uma cobrança não autenticada.</translation>
+ </message>
+ <message>
+ <source>This is an authenticated payment request.</source>
+ <translation>Esta é uma cobrança autenticada.</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to the list of used addresses</source>
+ <translation>Digite um rótulo para este endereço para adicioná-lo no catálogo</translation>
+ </message>
+ <message>
+ <source>A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network.</source>
+ <translation>A mensagem que foi anexada ao bitcoin: URI na qual será gravada na transação para sua referência. Nota: Essa mensagem não será gravada publicamente na rede Bitcoin.</translation>
+ </message>
+ <message>
+ <source>Pay To:</source>
+ <translation>Pague Para:</translation>
+ </message>
+ <message>
+ <source>Memo:</source>
+ <translation>Memorizar:</translation>
+ </message>
+</context>
+<context>
+ <name>ShutdownWindow</name>
+ <message>
+ <source>Bitcoin Core is shutting down...</source>
+ <translation>Bitcoin está desligando...</translation>
+ </message>
+ <message>
+ <source>Do not shut down the computer until this window disappears.</source>
+ <translation>Não desligue o computador até que esta janela desapareça.</translation>
+ </message>
+</context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Signatures - Sign / Verify a Message</source>
+ <translation>Assinaturas - Assinar / Verificar uma mensagem</translation>
+ </message>
+ <message>
+ <source>&amp;Sign Message</source>
+ <translation>&amp;Assinar mensagem</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to sign the message with</source>
+ <translation>O enderesso Bitcoin que assinará a mensagem</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Escolha um endereço usado anteriormente</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Colar o endereço da área de transferência</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Enter the message you want to sign here</source>
+ <translation>Entre a mensagem que você quer assinar aqui</translation>
+ </message>
+ <message>
+ <source>Signature</source>
+ <translation>Assinatura</translation>
+ </message>
+ <message>
+ <source>Copy the current signature to the system clipboard</source>
+ <translation>Copiar a assinatura para a área de transferência do sistema</translation>
+ </message>
+ <message>
+ <source>Sign the message to prove you own this Bitcoin address</source>
+ <translation>Assinar mensagem para provar que você é dono deste endereço Bitcoin</translation>
+ </message>
+ <message>
+ <source>Sign &amp;Message</source>
+ <translation>Assinar &amp;mensagem</translation>
+ </message>
+ <message>
+ <source>Reset all sign message fields</source>
+ <translation>Limpar todos os campos de assinatura da mensagem</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Limpar Tudo</translation>
+ </message>
+ <message>
+ <source>&amp;Verify Message</source>
+ <translation>&amp;Verificar mensagem</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address the message was signed with</source>
+ <translation>O enderesso Bitcoin que assionou a mesnagem</translation>
+ </message>
+ <message>
+ <source>Verify the message to ensure it was signed with the specified Bitcoin address</source>
+ <translation>Verificar mensagem para se assegurar que ela foi assinada pelo dono de um endereço Bitcoin específico.</translation>
+ </message>
+ <message>
+ <source>Verify &amp;Message</source>
+ <translation>Verificar &amp;mensagem</translation>
+ </message>
+ <message>
+ <source>Reset all verify message fields</source>
+ <translation>Limpar todos os campos de assinatura da mensagem</translation>
+ </message>
+ <message>
+ <source>Click "Sign Message" to generate signature</source>
+ <translation>Clique em "Assinar mensagem" para gerar a assinatura</translation>
+ </message>
+ <message>
+ <source>The entered address is invalid.</source>
+ <translation>O endereço fornecido é inválido.</translation>
+ </message>
+ <message>
+ <source>Please check the address and try again.</source>
+ <translation>Por favor, verifique o endereço e tente novamente.</translation>
+ </message>
+ <message>
+ <source>The entered address does not refer to a key.</source>
+ <translation>O endereço fornecido não se refere a uma chave.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock was cancelled.</source>
+ <translation>Desbloqueamento da Carteira foi cancelado.</translation>
+ </message>
+ <message>
+ <source>Private key for the entered address is not available.</source>
+ <translation>A chave privada para o endereço fornecido não está disponível.</translation>
+ </message>
+ <message>
+ <source>Message signing failed.</source>
+ <translation>Assinatura da mensagem falhou.</translation>
+ </message>
+ <message>
+ <source>Message signed.</source>
+ <translation>Mensagem assinada.</translation>
+ </message>
+ <message>
+ <source>The signature could not be decoded.</source>
+ <translation>A assinatura não pode ser decodificada.</translation>
+ </message>
+ <message>
+ <source>Please check the signature and try again.</source>
+ <translation>Por favor, verifique a assinatura e tente novamente.</translation>
+ </message>
+ <message>
+ <source>The signature did not match the message digest.</source>
+ <translation>A assinatura não corresponde ao "resumo da mensagem".</translation>
+ </message>
+ <message>
+ <source>Message verification failed.</source>
+ <translation>Verificação da mensagem falhou.</translation>
+ </message>
+ <message>
+ <source>Message verified.</source>
+ <translation>Mensagem verificada.</translation>
+ </message>
+</context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <source>The Bitcoin Core developers</source>
+ <translation>Programadores do Bitcoin</translation>
+ </message>
+ <message>
+ <source>[testnet]</source>
+ <translation>[testnet]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ <message>
+ <source>KB/s</source>
+ <translation>KB/s</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>Aberto até %1</translation>
+ </message>
+ <message>
+ <source>conflicted</source>
+ <translation>em conflito</translation>
+ </message>
+ <message>
+ <source>%1/offline</source>
+ <translation>%1/offline</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/não confirmadas</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 confirmações</translation>
+ </message>
+ <message>
+ <source>Status</source>
+ <translation>Status</translation>
+ </message>
+ <message numerus="yes">
+ <source>, broadcast through %n node(s)</source>
+ <translation><numerusform>, difundir atráves de %n nó</numerusform><numerusform>, difundir atráves de %n nós</numerusform></translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Source</source>
+ <translation>Fonte</translation>
+ </message>
+ <message>
+ <source>Generated</source>
+ <translation>Gerados</translation>
+ </message>
+ <message>
+ <source>From</source>
+ <translation>De</translation>
+ </message>
+ <message>
+ <source>To</source>
+ <translation>Para</translation>
+ </message>
+ <message>
+ <source>own address</source>
+ <translation>seu próprio endereço</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>monitorado</translation>
+ </message>
+ <message>
+ <source>label</source>
+ <translation>rótulo</translation>
+ </message>
+ <message>
+ <source>Credit</source>
+ <translation>Crédito</translation>
+ </message>
+ <message numerus="yes">
+ <source>matures in %n more block(s)</source>
+ <translation><numerusform>matura em mais %n bloco</numerusform><numerusform>matura em mais %n blocos</numerusform></translation>
+ </message>
+ <message>
+ <source>not accepted</source>
+ <translation>não aceito</translation>
+ </message>
+ <message>
+ <source>Debit</source>
+ <translation>Débito</translation>
+ </message>
+ <message>
+ <source>Total debit</source>
+ <translation>Débito total</translation>
+ </message>
+ <message>
+ <source>Total credit</source>
+ <translation>Credito total</translation>
+ </message>
+ <message>
+ <source>Transaction fee</source>
+ <translation>Taxa de transação</translation>
+ </message>
+ <message>
+ <source>Net amount</source>
+ <translation>Valor líquido</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Mensagem</translation>
+ </message>
+ <message>
+ <source>Comment</source>
+ <translation>Comentário</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>ID da transação</translation>
+ </message>
+ <message>
+ <source>Merchant</source>
+ <translation>Mercador</translation>
+ </message>
+ <message>
+ <source>Generated coins must mature %1 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.</source>
+ <translation>Bitcoins recém minerados precisam aguardar %1 blocos antes de serem gastos. Quando o bloco foi gerado, ele foi disseminado pela rede para ser adicionado à blockchain. Se ele falhar em ser inserido na cadeia, seu estado será modificado para "não aceito" e ele não poderá ser gasto. Isso pode acontecer eventualmente quando blocos são gerados quase que simultaneamente.</translation>
+ </message>
+ <message>
+ <source>Debug information</source>
+ <translation>Informação de depuração</translation>
+ </message>
+ <message>
+ <source>Transaction</source>
+ <translation>Transação</translation>
+ </message>
+ <message>
+ <source>Inputs</source>
+ <translation>Entradas</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Quantidade</translation>
+ </message>
+ <message>
+ <source>true</source>
+ <translation>verdadeiro</translation>
+ </message>
+ <message>
+ <source>false</source>
+ <translation>falso</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, ainda não foi propagada na rede com sucesso.</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Abrir para mais %n bloco</numerusform><numerusform>Abrir para mais %n blocos</numerusform></translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>desconhecido</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>Detalhes da transação</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>Este painel mostra uma descrição detalhada da transação</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Tipo</translation>
+ </message>
+ <message>
+ <source>Immature (%1 confirmations, will be available after %2)</source>
+ <translation>Recém-criado (%1 confirmações, disponível somente após %2)</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Abrir para mais %n bloco</numerusform><numerusform>Abrir para mais %n blocos</numerusform></translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>Aberto até %1</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>Confirmado (%1 confirmações)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>Este bloco não foi recebido por nenhum outro participante da rede e provavelmente não será aceito!</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>Gerado mas não aceito</translation>
+ </message>
+ <message>
+ <source>Offline</source>
+ <translation>Offline</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Rótulo</translation>
+ </message>
+ <message>
+ <source>Unconfirmed</source>
+ <translation>Não confirmado</translation>
+ </message>
+ <message>
+ <source>Confirming (%1 of %2 recommended confirmations)</source>
+ <translation>Confirmando (%1 de %2 confirmações recomendadas)</translation>
+ </message>
+ <message>
+ <source>Conflicted</source>
+ <translation>Conflitou</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Recebido</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>Recebido</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Enviado</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>Pagamento para você mesmo</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Minerado</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>monitorado</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(n/a)</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>Status da transação. Passe o mouse sobre este campo para mostrar o número de confirmações.</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Data e hora em que a transação foi recebida.</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>Tipo de transação.</translation>
+ </message>
+ <message>
+ <source>Whether or not a watch-only address is involved in this transaction.</source>
+ <translation>Mostrar ou não endereços Bitcoin na lista de transações.</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>Quantidade debitada ou creditada ao saldo.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>Todos</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>Hoje</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>Esta semana</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>Este mês</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>Mês passado</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>Este ano</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>Intervalo...</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Recebido</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Enviado</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>Para você mesmo</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Minerado</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>Outro</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>Procure um endereço ou rótulo</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>Quantidade mínima</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Copiar endereço</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Copiar rótulo</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copiar quantia</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Copiar ID da transação</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>Editar rótulo</translation>
+ </message>
+ <message>
+ <source>Show transaction details</source>
+ <translation>Mostrar detalhes da transação</translation>
+ </message>
+ <message>
+ <source>Export Transaction History</source>
+ <translation>Exportar Histórico de Transação</translation>
+ </message>
+ <message>
+ <source>Watch-only</source>
+ <translation>Monitorado</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Exportação Falhou</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the transaction history to %1.</source>
+ <translation>Ocorreu um erro ao tentar salvar o histórico de transação em %1.</translation>
+ </message>
+ <message>
+ <source>Exporting Successful</source>
+ <translation>Exportação feita com sucesso</translation>
+ </message>
+ <message>
+ <source>The transaction history was successfully saved to %1.</source>
+ <translation>O histórico de transação foi gravado com sucesso em %1.</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Arquivo separado por vírgulas (*. csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Confirmado</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Tipo</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Rótulo</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Endereço</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>Intervalo: </translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>para</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ <message>
+ <source>Unit to show amounts in. Click to select another unit.</source>
+ <translation>Unidade para mostrar. Clique para selecionar outra unidade.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletFrame</name>
+ <message>
+ <source>No wallet has been loaded.</source>
+ <translation>Nenhuma carteira foi carregada.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Send Coins</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Exportar</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Exportar os dados na aba atual para um arquivo</translation>
+ </message>
+ <message>
+ <source>Backup Wallet</source>
+ <translation>Fazer cópia de segurança da Carteira</translation>
+ </message>
+ <message>
+ <source>Wallet Data (*.dat)</source>
+ <translation>Dados da Carteira (*.dat)</translation>
+ </message>
+ <message>
+ <source>Backup Failed</source>
+ <translation>Cópia de segurança Falhou</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the wallet data to %1.</source>
+ <translation>Ocorreu um erro ao tentar salvar os dados da carteira em %1.</translation>
+ </message>
+ <message>
+ <source>The wallet data was successfully saved to %1.</source>
+ <translation>Os dados da carteira foram salvos com sucesso em %1.</translation>
+ </message>
+ <message>
+ <source>Backup Successful</source>
+ <translation>Backup feito com sucesso</translation>
+ </message>
+</context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>Opções:</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>Especificar o diretório de dados</translation>
+ </message>
+ <message>
+ <source>Connect to a node to retrieve peer addresses, and disconnect</source>
+ <translation>Conectar a um nó para receber endereços de participantes, e desconectar.</translation>
+ </message>
+ <message>
+ <source>Specify your own public address</source>
+ <translation>Especificar seu próprio endereço público</translation>
+ </message>
+ <message>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>Aceitar linha de comando e comandos JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>Rodar em segundo plano como serviço e aceitar comandos</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>Usar rede de teste</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
+ <translation>Aceitar conexões externas (padrão: 1 se opções -proxy ou -connect não estiverem presentes)</translation>
+ </message>
+ <message>
+ <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
+ <translation>Vincular ao endereço fornecido e sempre escutar nele. Use a notação [host]:port para IPv6</translation>
+ </message>
+ <message>
+ <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
+ <translation>Apaga todas as transações da carteira e somente recupera essas partes da blockchain usando o comando -rescan na inicialização</translation>
+ </message>
+ <message>
+ <source>Distributed under the MIT software license, see the accompanying file COPYING or &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</source>
+ <translation>Distribuido sob a licença MIT software license. Veja os termos em &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</translation>
+ </message>
+ <message>
+ <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
+ <translation>Executa um comando quando uma transação da carteira mudar (%s no comando será substituído por TxID)</translation>
+ </message>
+ <message>
+ <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, &gt;%u = target size in MiB to use for block files)</source>
+ <translation>Reduz o armazenamento requerido prunando (apagando) blocos antigos. Este modo desativa o suporte a carteira e é incompatível com -txindex. Aviso: Reverter essa opção requer re-baixar o blockchain inteiro. (padrão: 0 = desativado, &gt;%u = Tamanho em mega para os arquivos de bloco)</translation>
+ </message>
+ <message>
+ <source>Set the number of script verification threads (%u to %d, 0 = auto, &lt;0 = leave that many cores free, default: %d)</source>
+ <translation>Define o número de threads de verificação de script (%u a %d, 0 = automático, &lt;0 = número de cores deixados livres, padrão: %d)</translation>
+ </message>
+ <message>
+ <source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source>
+ <translation>Este pode ser um build de teste pré-lançamento - use por sua conta e risco - não use para mineração ou aplicações de comércio.</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer. Bitcoin Core is probably already running.</source>
+ <translation>Impossível ouvir em %s neste computador. Provavelmente o Bitcoin já está sendo executado.</translation>
+ </message>
+ <message>
+ <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>Atenção: valor de -paytxfee escolhido é muito alto! Este é o valor da taxa de transação que você irá pagar se enviar a transação.</translation>
+ </message>
+ <message>
+ <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source>
+ <translation>Atenção: A rede não parecem concordar plenamente! Alguns mineiros parecem estar enfrentando problemas.</translation>
+ </message>
+ <message>
+ <source>Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.</source>
+ <translation>Atenção: Nós não parecemos concordar plenamente com nossos colegas! Você pode precisar atualizar ou outros nós podem precisar atualizar.</translation>
+ </message>
+ <message>
+ <source>Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
+ <translation>Atenção: erro ao ler arquivo wallet.dat! Todas as chaves foram lidas corretamente, mas dados de transações e do catálogo de endereços podem estar faltando ou incorretos.</translation>
+ </message>
+ <message>
+ <source>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</source>
+ <translation>Atenção: wallet.dat corrompido, dados recuperados! Arquivo wallet.dat original salvo como wallet.{timestamp}.bak em %s; se seu saldo ou transações estiverem incorretos, você deve restaurar o backup.</translation>
+ </message>
+ <message>
+ <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source>
+ <translation>Lista Branca pares de ligação da máscara de rede dado ou o endereço IP . Pode ser especificado várias vezes.</translation>
+ </message>
+ <message>
+ <source>(default: 1)</source>
+ <translation>(padrão: 1)</translation>
+ </message>
+ <message>
+ <source>&lt;category&gt; can be:</source>
+ <translation>&lt;category&gt; pode ser:</translation>
+ </message>
+ <message>
+ <source>Attempt to recover private keys from a corrupt wallet.dat</source>
+ <translation>Tentar recuperar chaves privadas de um arquivo wallet.dat corrompido</translation>
+ </message>
+ <message>
+ <source>Block creation options:</source>
+ <translation>Opções de criação de blocos:</translation>
+ </message>
+ <message>
+ <source>Connect only to the specified node(s)</source>
+ <translation>Conectar apenas a cliente(s) específico(s)</translation>
+ </message>
+ <message>
+ <source>Connection options:</source>
+ <translation>Opções de conexão:</translation>
+ </message>
+ <message>
+ <source>Corrupted block database detected</source>
+ <translation>Detectado Banco de dados de blocos corrompido</translation>
+ </message>
+ <message>
+ <source>Debugging/Testing options:</source>
+ <translation>Opções de depuração/teste:</translation>
+ </message>
+ <message>
+ <source>Do not load the wallet and disable wallet RPC calls</source>
+ <translation>Não carrega a carteira e desabilita as chamadas RPC para a carteira</translation>
+ </message>
+ <message>
+ <source>Do you want to rebuild the block database now?</source>
+ <translation>Você quer reconstruir o banco de dados de blocos agora?</translation>
+ </message>
+ <message>
+ <source>Error initializing block database</source>
+ <translation>Erro ao inicializar banco de dados de blocos</translation>
+ </message>
+ <message>
+ <source>Error initializing wallet database environment %s!</source>
+ <translation>Erro ao inicializar ambiente de banco de dados de carteira %s!</translation>
+ </message>
+ <message>
+ <source>Error loading block database</source>
+ <translation>Erro ao carregar banco de dados de blocos</translation>
+ </message>
+ <message>
+ <source>Error opening block database</source>
+ <translation>Erro ao abrir banco de dados de blocos</translation>
+ </message>
+ <message>
+ <source>Error: Disk space is low!</source>
+ <translation>Erro: Espaço em disco insuficiente!</translation>
+ </message>
+ <message>
+ <source>Failed to listen on any port. Use -listen=0 if you want this.</source>
+ <translation>Falha ao escutar em qualquer porta. Use -listen=0 se você quiser isso.</translation>
+ </message>
+ <message>
+ <source>If &lt;category&gt; is not supplied, output all debugging information.</source>
+ <translation>Se &lt;category&gt; não for informada, registrar toda informação de depuração.</translation>
+ </message>
+ <message>
+ <source>Importing...</source>
+ <translation>Importando...</translation>
+ </message>
+ <message>
+ <source>Incorrect or no genesis block found. Wrong datadir for network?</source>
+ <translation>Bloco gênese incorreto ou não encontrado. Datadir errado para a rede?</translation>
+ </message>
+ <message>
+ <source>Invalid -onion address: '%s'</source>
+ <translation>Endereço -onion inválido: '%s'</translation>
+ </message>
+ <message>
+ <source>Not enough file descriptors available.</source>
+ <translation>Decriptadores de arquivos disponíveis insuficientes.</translation>
+ </message>
+ <message>
+ <source>Only connect to nodes in network &lt;net&gt; (ipv4, ipv6 or onion)</source>
+ <translation>Somente conectar a clientes na rede &lt;net&gt; (ipv4, ipv6 ou onion)</translation>
+ </message>
+ <message>
+ <source>Prune cannot be configured with a negative value.</source>
+ <translation>O modo Prune não pode ser configurado com um valor negativo.</translation>
+ </message>
+ <message>
+ <source>Prune mode is incompatible with -txindex.</source>
+ <translation>O modo Prune é incompatível com -txindex.</translation>
+ </message>
+ <message>
+ <source>Set database cache size in megabytes (%d to %d, default: %d)</source>
+ <translation>Define o tamanho do cache do banco de dados em megabytes (%d para %d, padrão: %d)</translation>
+ </message>
+ <message>
+ <source>Set maximum block size in bytes (default: %d)</source>
+ <translation>Define o tamanho máximo de cada bloco em bytes (padrão: %d)</translation>
+ </message>
+ <message>
+ <source>Specify wallet file (within data directory)</source>
+ <translation>Especifique o arquivo da carteira (dentro do diretório de dados)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: %u)</source>
+ <translation>Use UPnP para mapear a porta de entrada (padrão: %u)</translation>
+ </message>
+ <message>
+ <source>Verifying blocks...</source>
+ <translation>Verificando blocos...</translation>
+ </message>
+ <message>
+ <source>Verifying wallet...</source>
+ <translation>Verificando carteira...</translation>
+ </message>
+ <message>
+ <source>Wallet %s resides outside data directory %s</source>
+ <translation>Carteira %s reside fora do diretório de dados %s</translation>
+ </message>
+ <message>
+ <source>Wallet options:</source>
+ <translation>Opções da carteira:</translation>
+ </message>
+ <message>
+ <source>Warning: This version is obsolete; upgrade required!</source>
+ <translation>Atenção: Essa versão está obsoleta, atualização necessária!</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to change -txindex</source>
+ <translation>Você precisa reconstruir o banco de dados utilizando -reindex</translation>
+ </message>
+ <message>
+ <source>Imports blocks from external blk000??.dat file</source>
+ <translation>Importar blocos de um arquivo externo blk000??.dat</translation>
+ </message>
+ <message>
+ <source>Allow JSON-RPC connections from specified source. Valid for &lt;ip&gt; are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times</source>
+ <translation>Permitir conexões JSON-RPC de uma fonte específica. Válido para um único ip (ex. 1.2.3.4), até uma rede/máscara (ex. 1.2.3.4/255.255.255.0) ou uma rede/CIDR (ex. 1.2.3.4/24). Esta opção pode ser usada múltiplas vezes</translation>
+ </message>
+ <message>
+ <source>An error occurred while setting up the RPC address %s port %u for listening: %s</source>
+ <translation>Um erro ocorreu enquanto configurando o endereço RPC %s porta %u para escuta: %s</translation>
+ </message>
+ <message>
+ <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source>
+ <translation>Vincular ao endereço fornecido e sempre escutar nele. Use a notação [host]:port para IPv6</translation>
+ </message>
+ <message>
+ <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source>
+ <translation>Não foi possível obter acesso exclusivo ao diretório de dados %s. Provavelmente Bitcoin já está sendo executado.</translation>
+ </message>
+ <message>
+ <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source>
+ <translation>Descobrir o próprio IP (padrão: 1 enquanto aguardando conexões e sem -externalip ou -proxy)</translation>
+ </message>
+ <message>
+ <source>Error: Listening for incoming connections failed (listen returned error %s)</source>
+ <translation>Erro: Aceitar conexões de entrada falhou (retornou erro %s)</translation>
+ </message>
+ <message>
+ <source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source>
+ <translation>Executa um comando quando um alerta relevante é recebido ou vemos uma longa segregação (%s em cmd é substituído pela mensagem)</translation>
+ </message>
+ <message>
+ <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source>
+ <translation>Taxas (em BTC/Kb) menores do que este valor são consideradas inexistentes para divulgação (padrão: %s)</translation>
+ </message>
+ <message>
+ <source>Prune configured below the minimum of %d MB. Please use a higher number.</source>
+ <translation>Prunagem configurada abaixo do mínimo de %d MB. Use um número maior.</translation>
+ </message>
+ <message>
+ <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
+ <translation>Define o tamanho máximo de alta-prioridade por taxa baixa nas transações em bytes (padrão: %d)</translation>
+ </message>
+ <message>
+ <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an 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)
+The username and password MUST NOT be the same.
+If the file does not exist, create it with owner-readable-only file permissions.
+It is also recommended to set alertnotify so you are notified of problems;
+for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
+</source>
+ <translation>Para usar o bitcoind, ou a opção -server do bitcoin-qt, você deve definir rpcpassword no arquivo de configuração:
+%s
+É recomendado que use a seguinte senha randômica:
+rpcuser=bitcoinrpc
+rpcpassword=%s
+(você não precisa lembrar esta senha)
+O usuário e senha NÃO DEVEM ser os mesmos.
+Se o arquivo não existir, crie com permissão de proprietário criador somente.
+É também recomendado definir a opção alertnotify se deseja ser notificado de problemas;
+por exemplo: alertnotify=echo %%s | mail -s "Alerta do Bitcoin" admin@foo.com.br
+</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source>
+ <translation>Você precisa reconstruir o banco de dados usando -reindex para sair do modo prune. Isso irá rebaixar todo o blockchain.</translation>
+ </message>
+ <message>
+ <source>(default: %u)</source>
+ <translation>(padrão: %u)</translation>
+ </message>
+ <message>
+ <source>Activating best chain...</source>
+ <translation>Ativando a melhor sequência...</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -whitebind address: '%s'</source>
+ <translation>Impossível resolver endereço -whitebind: '%s'</translation>
+ </message>
+ <message>
+ <source>Choose data directory on startup (default: 0)</source>
+ <translation>Escolha o diretório de dados na inicialização (padrão: 0)</translation>
+ </message>
+ <message>
+ <source>Connect through SOCKS5 proxy</source>
+ <translation>Connecte-se através de um proxy SOCKS5</translation>
+ </message>
+ <message>
+ <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source>
+ <translation>Copyright (C) 2009-%i Desenvolvedores Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Could not parse -rpcbind value %s as network address</source>
+ <translation>Impossível interpretar o valor -rpcbind %s como um endereço da rede</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source>
+ <translation>Erro ao carregar wallet.dat: A carteira requer a nova versão do Bitcoin</translation>
+ </message>
+ <message>
+ <source>Error reading from database, shutting down.</source>
+ <translation>Erro ao ler o banco de dados. Finalizando.</translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -tor found, use -onion.</source>
+ <translation>Erro: Argumento não suportado -tor, use -onion.</translation>
+ </message>
+ <message>
+ <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source>
+ <translation>Taxa (em BTC/kB) a adicionar nas transações que você envia (padrão: %s)</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Informação</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Quantidade inválida para -maxtxfee=&lt;quantidade&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -minrelaytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Quantidade inválida para -minrelaytxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -mintxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Valor inválido para -mintxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s' (must be at least %s)</source>
+ <translation>Valor inválido para -paytxfee=&lt;amount&gt;: '%s' (precisa ser no mínimo %s)</translation>
+ </message>
+ <message>
+ <source>Invalid netmask specified in -whitelist: '%s'</source>
+ <translation>Máscara de rede especificada em -whitelist: '%s' é inválida</translation>
+ </message>
+ <message>
+ <source>Need to specify a port with -whitebind: '%s'</source>
+ <translation>Necessário informar uma porta com -whitebind: '%s'</translation>
+ </message>
+ <message>
+ <source>Node relay options:</source>
+ <translation>Opções de relé nó :</translation>
+ </message>
+ <message>
+ <source>Pruning blockstore...</source>
+ <translation>Prunando os blocos existentes...</translation>
+ </message>
+ <message>
+ <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source>
+ <translation>Opções RPC SSL: (veja o Bitcoin Wiki para instruções de configuração SSL)</translation>
+ </message>
+ <message>
+ <source>RPC server options:</source>
+ <translation>Opções do servidor RPC:</translation>
+ </message>
+ <message>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>Mandar informação de trace/debug para o console em vez de para o arquivo debug.log</translation>
+ </message>
+ <message>
+ <source>Send transactions as zero-fee transactions if possible (default: %u)</source>
+ <translation>Enviar transação sem taxa, se possível (padrão: %u)</translation>
+ </message>
+ <message>
+ <source>Set SSL root certificates for payment request (default: -system-)</source>
+ <translation>Define certificados SSL root para requisição de pagamento (padrão: -system-)</translation>
+ </message>
+ <message>
+ <source>Set language, for example "de_DE" (default: system locale)</source>
+ <translation>Escolher língua, por exemplo "de_DE" (padrão: localização do sistema)</translation>
+ </message>
+ <message>
+ <source>Show all debugging options (usage: --help -help-debug)</source>
+ <translation>Exibir todas opções de depuração (uso: --help -help-debug)</translation>
+ </message>
+ <message>
+ <source>Show splash screen on startup (default: 1)</source>
+ <translation>Mostrar tela inicial ao ligar (padrão: 1)</translation>
+ </message>
+ <message>
+ <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source>
+ <translation>Encolher arquivo debug.log ao iniciar o cliente (padrão 1 se opção -debug não estiver presente)</translation>
+ </message>
+ <message>
+ <source>Signing transaction failed</source>
+ <translation>Assinatura de transação falhou</translation>
+ </message>
+ <message>
+ <source>Start minimized</source>
+ <translation>Inicializar minimizado</translation>
+ </message>
+ <message>
+ <source>The transaction amount is too small to pay the fee</source>
+ <translation>A quantidade da transação é pequena demais para pagar a taxa</translation>
+ </message>
+ <message>
+ <source>This is experimental software.</source>
+ <translation>Este é um software experimental.</translation>
+ </message>
+ <message>
+ <source>Transaction amount too small</source>
+ <translation>Quantidade da transação muito pequena.</translation>
+ </message>
+ <message>
+ <source>Transaction amounts must be positive</source>
+ <translation>As quantidades das transações devem ser positivas.</translation>
+ </message>
+ <message>
+ <source>Transaction too large for fee policy</source>
+ <translation>Transação muito grande para enviar sem taxa</translation>
+ </message>
+ <message>
+ <source>Transaction too large</source>
+ <translation>Transação muito larga</translation>
+ </message>
+ <message>
+ <source>UI Options:</source>
+ <translation>Opções da interface:</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer (bind returned error %s)</source>
+ <translation>Impossível se ligar a %s neste computador (bind retornou erro %s)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: 1 when listening)</source>
+ <translation>Usar UPnP para mapear porta de escuta (padrão: 1 quando estiver escutando)</translation>
+ </message>
+ <message>
+ <source>Username for JSON-RPC connections</source>
+ <translation>Nome de usuário para conexões JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Wallet needed to be rewritten: restart Bitcoin Core to complete</source>
+ <translation>Sua carteira precisou ser reescrita: favor reiniciar o Bitcoin para completar</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Atenção</translation>
+ </message>
+ <message>
+ <source>Zapping all transactions from wallet...</source>
+ <translation>Aniquilando todas as transações da carteira...</translation>
+ </message>
+ <message>
+ <source>on startup</source>
+ <translation>ao iniciar</translation>
+ </message>
+ <message>
+ <source>wallet.dat corrupt, salvage failed</source>
+ <translation>wallet.dat corrompido, recuperação falhou</translation>
+ </message>
+ <message>
+ <source>Password for JSON-RPC connections</source>
+ <translation>Senha para conexões JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
+ <translation>Executa um comando quando o melhor bloco mudar (%s no comando será substituído pelo hash do bloco)</translation>
+ </message>
+ <message>
+ <source>Upgrade wallet to latest format</source>
+ <translation>Atualizar carteira para o formato mais recente</translation>
+ </message>
+ <message>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>Re-escanear blocos procurando por transações perdidas da carteira</translation>
+ </message>
+ <message>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>Usar OpenSSL (https) para conexões JSON-RPC</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>Exibe esta mensagem de ajuda</translation>
+ </message>
+ <message>
+ <source>Allow DNS lookups for -addnode, -seednode and -connect</source>
+ <translation>Permitir consultas DNS para -addnode, -seednode e -connect</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>Carregando endereços...</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>Erro ao carregar wallet.dat: Carteira corrompida</translation>
+ </message>
+ <message>
+ <source>(default: %s)</source>
+ <translation>(padrão: %s)</translation>
+ </message>
+ <message>
+ <source>Acceptable ciphers (default: %s)</source>
+ <translation>Cífras aceitas (padrão: %s)</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>Erro ao carregar wallet.dat</translation>
+ </message>
+ <message>
+ <source>Generate coins (default: %u)</source>
+ <translation>Gerar moedas (padrão: %u)</translation>
+ </message>
+ <message>
+ <source>How many blocks to check at startup (default: %u, 0 = all)</source>
+ <translation>Quantos blocos devem ser checados ao iniciar (padrão: %u, 0 = todos)</translation>
+ </message>
+ <message>
+ <source>Include IP addresses in debug output (default: %u)</source>
+ <translation>Incluir endereço IP na saída de depuração (padrão: %u)</translation>
+ </message>
+ <message>
+ <source>Invalid -proxy address: '%s'</source>
+ <translation>Endereço -proxy inválido: '%s'</translation>
+ </message>
+ <message>
+ <source>Listen for connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>Aguardar por conexões na porta &lt;port&gt; (padrão: %u ou testnet: %u)</translation>
+ </message>
+ <message>
+ <source>Prepend debug output with timestamp (default: %u)</source>
+ <translation>Adiciona timestamp como prefixo no debug (default: %u)</translation>
+ </message>
+ <message>
+ <source>Relay non-P2SH multisig (default: %u)</source>
+ <translation>Retransmitir P2SH não multisig (default: %u)</translation>
+ </message>
+ <message>
+ <source>Server certificate file (default: %s)</source>
+ <translation>Arquivo de certificado do servidor (padrão: %s)</translation>
+ </message>
+ <message>
+ <source>Server private key (default: %s)</source>
+ <translation>Chave privada do servidor (padrão: %s)</translation>
+ </message>
+ <message>
+ <source>Set minimum block size in bytes (default: %u)</source>
+ <translation>Definir tamanho mínimo do bloco, em bytes (padrão: %u)</translation>
+ </message>
+ <message>
+ <source>Specify configuration file (default: %s)</source>
+ <translation>Especificar arquivo de configuração (padrão: %s)</translation>
+ </message>
+ <message>
+ <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source>
+ <translation>Especificar tempo para desistência de conexões, em mili segundos (mínimo: 1, padrão: %d)</translation>
+ </message>
+ <message>
+ <source>Specify pid file (default: %s)</source>
+ <translation>Especificar aqrquivo pid (default: %s)</translation>
+ </message>
+ <message>
+ <source>Unknown network specified in -onlynet: '%s'</source>
+ <translation>Rede desconhecida especificada em -onlynet: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -bind address: '%s'</source>
+ <translation>Impossível encontrar o endereço -bind: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -externalip address: '%s'</source>
+ <translation>Impossível encontrar endereço -externalip: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Quantidade inválida para -paytxfee=&lt;quantidade&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>Saldo insuficiente</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>Carregando índice de blocos...</translation>
+ </message>
+ <message>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>Adicionar um cliente para se conectar e tentar manter a conexão ativa</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>Carregando carteira...</translation>
+ </message>
+ <message>
+ <source>Cannot downgrade wallet</source>
+ <translation>Não é possível fazer downgrade da carteira</translation>
+ </message>
+ <message>
+ <source>Cannot write default address</source>
+ <translation>Não foi possível escrever no endereço padrão</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>Re-escaneando...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>Carregamento terminado</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Erro</translation>
+ </message>
+</context>
+</TS> \ 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 0000000000..cfbaff7b3b
--- /dev/null
+++ b/src/qt/locale/bitcoin_pt_PT.ts
@@ -0,0 +1,3217 @@
+<TS language="pt_PT" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Right-click to edit address or label</source>
+ <translation>Clique á direita para editar endereço ou rótulo</translation>
+ </message>
+ <message>
+ <source>Create a new address</source>
+ <translation>Criar um novo endereço</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>&amp;Novo</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Copiar o endereço selecionado para a área de transferência</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>&amp;Copiar</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>F&amp;echar</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>&amp;Copiar Endereço</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>Apagar o endereço selecionado da lista</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Exportar os dados no separador actual para um ficheiro</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Exportar</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;Eliminar\</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>Escolha o endereço para o qual pretende enviar moedas</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>Escolha o endereço com o qual pretende receber moedas</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>Escol&amp;her</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>Endereços de envio</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>Endereços de depósito</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>Estes são os seus endereços Bitcoin para enviar pagamentos. Verifique sempre o valor e o endereço de envio antes de enviar moedas.</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>Estes são os seus endereços Bitcoin para receber pagamentos. É recomendado que utilize um endereço novo para cada transacção.</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>Copiar &amp;Rótulo</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>&amp;Editar</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>Exportar Lista de Endereços</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Ficheiro separado por vírgulas (*.csv)</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>A Exportação Falhou</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the address list to %1. Please try again.</source>
+ <translation>Houve um erro ao tentar a guardar a lista de endereços em %1. Por favor tente novamente.</translation>
+ </message>
+</context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Rótulo</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Endereço</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(sem rótulo)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Passphrase Dialog</source>
+ <translation>Diálogo de frase de segurança</translation>
+ </message>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Insira a frase de segurança</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Nova frase de segurança</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Repita a nova frase de segurança</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>Encriptar carteira</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>A sua frase de segurança é necessária para desbloquear a carteira.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Desbloquear carteira</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>A sua frase de segurança é necessária para desencriptar a carteira.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>Desencriptar carteira</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>Alterar frase de segurança</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>Confirmar encriptação da carteira</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>Atenção: Se encriptar a carteira e perder a sua senha irá &lt;b&gt;PERDER TODOS OS SEUS BITCOINS&lt;/b&gt;!</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>Tem a certeza que deseja encriptar a carteira?</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core 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.</source>
+ <translation>O cliente Bitcoin Core 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.</translation>
+ </message>
+ <message>
+ <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
+ <translation>IMPORTANTE: Qualquer cópia de segurança da carteira anterior deverá ser substituída com o novo ficheiro de carteira, agora encriptado. Por razões de segurança, cópias de segurança não encriptadas tornar-se-ão inúteis assim que começar a usar a nova carteira encriptada.</translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>Atenção: A tecla Caps Lock está activa!</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>Carteira encriptada</translation>
+ </message>
+ <message>
+ <source>Enter the new passphrase to the wallet.&lt;br/&gt;Please use a passphrase of &lt;b&gt;ten or more random characters&lt;/b&gt;, or &lt;b&gt;eight or more words&lt;/b&gt;.</source>
+ <translation>Escreva a nova frase de seguraça da sua carteira. &lt;br/&gt; Por favor, use uma frase de &lt;b&gt;10 ou mais caracteres aleatórios,&lt;/b&gt; ou &lt;b&gt;oito ou mais palavras&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>Enter the old passphrase and new passphrase to the wallet.</source>
+ <translation>Escreva a antiga frase de segurança da carteira, seguida da nova.</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>A encriptação da carteira falhou</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>A encriptação da carteira falhou devido a um erro interno. A carteira não foi encriptada.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>As frases de segurança fornecidas não coincidem.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>O desbloqueio da carteira falhou</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>A frase de segurança introduzida para a desencriptação da carteira estava incorreta.</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>A desencriptação da carteira falhou</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>A frase de segurança da carteira foi alterada com êxito.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>Assinar &amp;mensagem...</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>A sincronizar com a rede...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>Visã&amp;o geral</translation>
+ </message>
+ <message>
+ <source>Node</source>
+ <translation>Nó</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>Mostrar visão geral da carteira</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Transações</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>Navegar pelo histórico de transações</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>Fec&amp;har</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>Sair da aplicação</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>Sobre &amp;Qt</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>Mostrar informação sobre Qt</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;Opções...</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>E&amp;ncriptar Carteira...</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>&amp;Guardar Carteira...</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>Mudar &amp;Palavra-passe...</translation>
+ </message>
+ <message>
+ <source>&amp;Sending addresses...</source>
+ <translation>A &amp;enviar endereços...</translation>
+ </message>
+ <message>
+ <source>&amp;Receiving addresses...</source>
+ <translation>A &amp;receber endereços...</translation>
+ </message>
+ <message>
+ <source>Open &amp;URI...</source>
+ <translation>Abrir &amp;URI...</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core client</source>
+ <translation>Cliente Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Importing blocks from disk...</source>
+ <translation>A importar blocos do disco...</translation>
+ </message>
+ <message>
+ <source>Reindexing blocks on disk...</source>
+ <translation>A reindexar blocos no disco...</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>Enviar moedas para um endereço bitcoin</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>Faça uma cópia de segurança da carteira para outra localização</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Mudar a frase de segurança utilizada na encriptação da carteira</translation>
+ </message>
+ <message>
+ <source>&amp;Debug window</source>
+ <translation>Janela de &amp;depuração</translation>
+ </message>
+ <message>
+ <source>Open debugging and diagnostic console</source>
+ <translation>Abrir consola de diagnóstico e depuração</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>&amp;Verificar mensagem...</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>Carteira</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>&amp;Enviar</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>&amp;Receber</translation>
+ </message>
+ <message>
+ <source>Show information about Bitcoin Core</source>
+ <translation>Mostrar informação sobre Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>Mo&amp;strar / Ocultar</translation>
+ </message>
+ <message>
+ <source>Show or hide the main Window</source>
+ <translation>Mostrar ou esconder a janela principal</translation>
+ </message>
+ <message>
+ <source>Encrypt the private keys that belong to your wallet</source>
+ <translation>Encriptar as chaves privadas que pertencem à sua carteira</translation>
+ </message>
+ <message>
+ <source>Sign messages with your Bitcoin addresses to prove you own them</source>
+ <translation>Assine mensagens com os seus endereços Bitcoin para provar que os controla</translation>
+ </message>
+ <message>
+ <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source>
+ <translation>Verifique mensagens para assegurar que foram assinadas com o endereço Bitcoin especificado</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;Ficheiro</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;Configurações</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>&amp;Ajuda</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>Barra de separadores</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Request payments (generates QR codes and bitcoin: URIs)</source>
+ <translation>Solicitar pagamentos (gera códigos QR e URIs bitcoin:)</translation>
+ </message>
+ <message>
+ <source>&amp;About Bitcoin Core</source>
+ <translation>&amp;Sobre o Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Modify configuration options for Bitcoin Core</source>
+ <translation>Modificar opções de configuração de Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Show the list of used sending addresses and labels</source>
+ <translation>Mostrar a lista de rótulos e endereços de envio usados</translation>
+ </message>
+ <message>
+ <source>Show the list of used receiving addresses and labels</source>
+ <translation>Mostrar a lista de rótulos e endereços de receção usados</translation>
+ </message>
+ <message>
+ <source>Open a bitcoin: URI or payment request</source>
+ <translation>Abrir URI bitcoin: ou pedido de pagamento</translation>
+ </message>
+ <message>
+ <source>&amp;Command-line options</source>
+ <translation>&amp;Opções da linha de &amp;comandos</translation>
+ </message>
+ <message>
+ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
+ <translation>Mostrar a mensagem de ajuda do Bitcoin Core para obter uma lista com possíveis opções de linha de comandos</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n active connection(s) to Bitcoin network</source>
+ <translation><numerusform>%n ligação ativa à rede Bitcoin</numerusform><numerusform>%n ligações ativas à rede Bitcoin</numerusform></translation>
+ </message>
+ <message>
+ <source>No block source available...</source>
+ <translation>Nenhuma fonte de blocos disponível...</translation>
+ </message>
+ <message numerus="yes">
+ <source>Processed %n block(s) of transaction history.</source>
+ <translation><numerusform>Processado %n bloco do histórico de transações.</numerusform><numerusform>Processados %n blocos do histórico de transações.</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n hour(s)</source>
+ <translation><numerusform>%n hora</numerusform><numerusform>%n horas</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n day(s)</source>
+ <translation><numerusform>%n dia</numerusform><numerusform>%n dias</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n week(s)</source>
+ <translation><numerusform>%n semana</numerusform><numerusform>%n semanas</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 and %2</source>
+ <translation>%1 e %2</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n year(s)</source>
+ <translation><numerusform>%n ano</numerusform><numerusform>%n anos</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 behind</source>
+ <translation>%1 em atraso</translation>
+ </message>
+ <message>
+ <source>Last received block was generated %1 ago.</source>
+ <translation>O último bloco recebido foi gerado %1 atrás.</translation>
+ </message>
+ <message>
+ <source>Transactions after this will not yet be visible.</source>
+ <translation>Transações posteriores não serão visíveis por enquanto.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Erro</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Aviso</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Informação</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>Atualizado</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>Recuperando o atraso...</translation>
+ </message>
+ <message>
+ <source>Date: %1
+</source>
+ <translation>Data: %1
+</translation>
+ </message>
+ <message>
+ <source>Amount: %1
+</source>
+ <translation>Quantia: %1
+</translation>
+ </message>
+ <message>
+ <source>Type: %1
+</source>
+ <translation>Tipo: %1
+</translation>
+ </message>
+ <message>
+ <source>Label: %1
+</source>
+ <translation>Rótulo: %1
+</translation>
+ </message>
+ <message>
+ <source>Address: %1
+</source>
+ <translation>Endereço: %1
+</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>Transação enviada</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>Transação recebida</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>A carteira está &lt;b&gt;encriptada&lt;/b&gt; e atualmente &lt;b&gt;desbloqueada&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>A carteira está &lt;b&gt;encriptada&lt;/b&gt; e atualmente &lt;b&gt;bloqueada&lt;/b&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <source>Network Alert</source>
+ <translation>Alerta da Rede</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Coin Selection</source>
+ <translation>Seleção de moeda</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Quantidade:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Bytes:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Quantia:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Prioridade:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Taxa:</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Lixo:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Depois da Taxa:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Troco:</translation>
+ </message>
+ <message>
+ <source>(un)select all</source>
+ <translation>(des)seleccionar todos</translation>
+ </message>
+ <message>
+ <source>Tree mode</source>
+ <translation>Modo árvore</translation>
+ </message>
+ <message>
+ <source>List mode</source>
+ <translation>Modo lista</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Quantia</translation>
+ </message>
+ <message>
+ <source>Received with label</source>
+ <translation>Recebido com rótulo</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>Recebido com endereço</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Confirmations</source>
+ <translation>Confirmados</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Confirmada</translation>
+ </message>
+ <message>
+ <source>Priority</source>
+ <translation>Prioridade</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Copiar endereço</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Copiar rótulo</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copiar quantia</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Copiar ID da transação</translation>
+ </message>
+ <message>
+ <source>Lock unspent</source>
+ <translation>Bloquear não gastos</translation>
+ </message>
+ <message>
+ <source>Unlock unspent</source>
+ <translation>Desbloquear não gastos</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Copiar quantidade</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Copiar taxa</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Copiar valor após taxa</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Copiar bytes</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Copiar prioridade</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Copiar lixo</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Copiar alteração</translation>
+ </message>
+ <message>
+ <source>highest</source>
+ <translation>muito alta</translation>
+ </message>
+ <message>
+ <source>higher</source>
+ <translation>mais alta</translation>
+ </message>
+ <message>
+ <source>high</source>
+ <translation>alta</translation>
+ </message>
+ <message>
+ <source>medium-high</source>
+ <translation>média-alta</translation>
+ </message>
+ <message>
+ <source>medium</source>
+ <translation>média</translation>
+ </message>
+ <message>
+ <source>low-medium</source>
+ <translation>média-baixa</translation>
+ </message>
+ <message>
+ <source>low</source>
+ <translation>baixa</translation>
+ </message>
+ <message>
+ <source>lower</source>
+ <translation>mais baixa</translation>
+ </message>
+ <message>
+ <source>lowest</source>
+ <translation>muito alta</translation>
+ </message>
+ <message>
+ <source>(%1 locked)</source>
+ <translation>(%1 bloqueados)</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>nenhum</translation>
+ </message>
+ <message>
+ <source>This label turns red if the transaction size is greater than 1000 bytes.</source>
+ <translation>Este rótulo fica vermelho se o tamanho da transacção exceder os 1000 bytes.</translation>
+ </message>
+ <message>
+ <source>This label turns red if the priority is smaller than "medium".</source>
+ <translation>Esta legenda fica vermelha se a prioridade for menor que "média".</translation>
+ </message>
+ <message>
+ <source>This label turns red if any recipient receives an amount smaller than %1.</source>
+ <translation>Este rótulo fica vermelho se algum recipiente receber uma quantia menor que %1.</translation>
+ </message>
+ <message>
+ <source>Can vary +/- %1 satoshi(s) per input.</source>
+ <translation>Pode variar +/- %1 satoshi(s) por entrada</translation>
+ </message>
+ <message>
+ <source>yes</source>
+ <translation>sim</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>não</translation>
+ </message>
+ <message>
+ <source>This means a fee of at least %1 per kB is required.</source>
+ <translation>Isto significa que uma taxa de pelo menos %1 por kB é necessária.</translation>
+ </message>
+ <message>
+ <source>Can vary +/- 1 byte per input.</source>
+ <translation>Pode variar +/- 1 byte por input.</translation>
+ </message>
+ <message>
+ <source>Transactions with higher priority are more likely to get included into a block.</source>
+ <translation>Transacções com uma prioridade mais alta têm uma maior probabilidade de serem incluídas num bloco.</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(sem rótulo)</translation>
+ </message>
+ <message>
+ <source>change from %1 (%2)</source>
+ <translation>troco de %1 (%2)</translation>
+ </message>
+ <message>
+ <source>(change)</source>
+ <translation>(troco)</translation>
+ </message>
+</context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>Editar Endereço</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>&amp;Rótulo</translation>
+ </message>
+ <message>
+ <source>The label associated with this address list entry</source>
+ <translation>O rótulo associado com esta entrada no livro de endereços</translation>
+ </message>
+ <message>
+ <source>The address associated with this address list entry. This can only be modified for sending addresses.</source>
+ <translation>O endereço associado com o esta entrada no livro de endereços. Isto só pode ser modificado para endereços de saída.</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>E&amp;ndereço</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>Novo endereço de entrada</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>Novo endereço de saída</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>Editar endereço de entrada</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>Editar endereço de saída</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>O endereço introduzido "%1" já se encontra no livro de endereços.</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is not a valid Bitcoin address.</source>
+ <translation>O endereço introduzido "%1" não é um endereço bitcoin válido.</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>Impossível desbloquear carteira.</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>Falha ao gerar nova chave.</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ <message>
+ <source>A new data directory will be created.</source>
+ <translation>Uma nova pasta de dados será criada.</translation>
+ </message>
+ <message>
+ <source>name</source>
+ <translation>nome</translation>
+ </message>
+ <message>
+ <source>Directory already exists. Add %1 if you intend to create a new directory here.</source>
+ <translation>A pasta já existe. Adicione %1 se pretender criar aqui uma nova pasta.</translation>
+ </message>
+ <message>
+ <source>Path already exists, and is not a directory.</source>
+ <translation>Caminho já existe, e não é uma pasta.</translation>
+ </message>
+ <message>
+ <source>Cannot create data directory here.</source>
+ <translation>Não pode ser criada uma pasta de dados aqui.</translation>
+ </message>
+</context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>versão</translation>
+ </message>
+ <message>
+ <source>(%1-bit)</source>
+ <translation>(%1-bit)</translation>
+ </message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>Sobre o Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Command-line options</source>
+ <translation>Opções de linha de comandos</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>Utilização:</translation>
+ </message>
+ <message>
+ <source>command-line options</source>
+ <translation>opções da linha de comandos</translation>
+ </message>
+</context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Welcome</source>
+ <translation>Bem-vindo</translation>
+ </message>
+ <message>
+ <source>Welcome to Bitcoin Core.</source>
+ <translation>Bem-vindo ao Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</source>
+ <translation>Sendo esta a primeira vez que o programa é iniciado, poderá escolher onde o Bitcoin Core irá guardar os seus dados.</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory.</source>
+ <translation>O Bitcoin Core vai transferir e armazenar uma cópia do "block chain" (cadeia de blocos). Pelo menos %1GB de dados serão armazenados nesta pasta, e vão crescer ao longo do tempo. A sua carteira também irá ser armazenada nesta pasta.</translation>
+ </message>
+ <message>
+ <source>Use the default data directory</source>
+ <translation>Utilizar a pasta de dados padrão</translation>
+ </message>
+ <message>
+ <source>Use a custom data directory:</source>
+ <translation>Utilizar uma pasta de dados personalizada:</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Error: Specified data directory "%1" cannot be created.</source>
+ <translation>Erro: Pasta de dados especificada como "%1, não pode ser criada.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Erro</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n GB of free space available</source>
+ <translation><numerusform>%n GB de espaço livre disponível </numerusform><numerusform>%n GB de espaço livre disponível </numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>(of %n GB needed)</source>
+ <translation><numerusform>(de %n GB necessários)</numerusform><numerusform>(de %n GB necessário)</numerusform></translation>
+ </message>
+</context>
+<context>
+ <name>OpenURIDialog</name>
+ <message>
+ <source>Open URI</source>
+ <translation>Abir URI</translation>
+ </message>
+ <message>
+ <source>Open payment request from URI or file</source>
+ <translation>Abrir pedido de pagamento de um URI ou ficheiro</translation>
+ </message>
+ <message>
+ <source>URI:</source>
+ <translation>URI:</translation>
+ </message>
+ <message>
+ <source>Select payment request file</source>
+ <translation>Seleccione o ficheiro de pedido de pagamento</translation>
+ </message>
+ <message>
+ <source>Select payment request file to open</source>
+ <translation>Seleccione o ficheiro de pedido de pagamento a abrir</translation>
+ </message>
+</context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>Opções</translation>
+ </message>
+ <message>
+ <source>&amp;Main</source>
+ <translation>&amp;Principal</translation>
+ </message>
+ <message>
+ <source>Size of &amp;database cache</source>
+ <translation>Tamanho da cache da base de &amp;dados</translation>
+ </message>
+ <message>
+ <source>MB</source>
+ <translation>MB</translation>
+ </message>
+ <message>
+ <source>Number of script &amp;verification threads</source>
+ <translation>Número de processos de &amp;verificação de scripts</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside</source>
+ <translation>Aceitar conceções externas</translation>
+ </message>
+ <message>
+ <source>Allow incoming connections</source>
+ <translation>Permitir conexão</translation>
+ </message>
+ <message>
+ <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
+ <translation>Endereço IP do proxy (p.ex. IPv4: 127.0.0.1 / IPv6: ::1)</translation>
+ </message>
+ <message>
+ <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source>
+ <translation>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ú.</translation>
+ </message>
+ <message>
+ <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source>
+ <translation>A linguagem da interface do utilizador pode ser definida aqui. Esta definição entrará em efeito após reiniciar o Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source>
+ <translation>URLs de outrem (ex. um explorador de blocos) que aparece no separador de transações como itens do menu de contexto.
+%s do URL é substituído por hash de transação. Vários URLs são separados por barra vertical |.</translation>
+ </message>
+ <message>
+ <source>Third party transaction URLs</source>
+ <translation>URLs de transação de outrem</translation>
+ </message>
+ <message>
+ <source>Active command-line options that override above options:</source>
+ <translation>Opções de linha de comandos ativas que se sobrepõem ás opções anteriores:</translation>
+ </message>
+ <message>
+ <source>Reset all client options to default.</source>
+ <translation>Repor todas as opções do cliente.</translation>
+ </message>
+ <message>
+ <source>&amp;Reset Options</source>
+ <translation>&amp;Repor Opções</translation>
+ </message>
+ <message>
+ <source>&amp;Network</source>
+ <translation>&amp;Rede</translation>
+ </message>
+ <message>
+ <source>Automatically start Bitcoin Core after logging in to the system.</source>
+ <translation>Começar o Bitcoin Core automaticamente ao iniciar sessão no sistema.</translation>
+ </message>
+ <message>
+ <source>&amp;Start Bitcoin Core on system login</source>
+ <translation>&amp;Começar o Bitcoin Core ao iniciar o sistema</translation>
+ </message>
+ <message>
+ <source>(0 = auto, &lt;0 = leave that many cores free)</source>
+ <translation>(0 = auto, &lt;0 = Deixar essa quantidade de núcleos livre)</translation>
+ </message>
+ <message>
+ <source>W&amp;allet</source>
+ <translation>C&amp;arteira</translation>
+ </message>
+ <message>
+ <source>Expert</source>
+ <translation>Especialista</translation>
+ </message>
+ <message>
+ <source>Enable coin &amp;control features</source>
+ <translation>Ativar funcionalidades de controlo de transação.</translation>
+ </message>
+ <message>
+ <source>If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.</source>
+ <translation>No caso de desativar o gasto de troco não confirmado, o troco de uma transação não poderá ser utilizado até que essa transação tenha pelo menos uma confirmação. Isto também afeta o cálculo do seu saldo.</translation>
+ </message>
+ <message>
+ <source>&amp;Spend unconfirmed change</source>
+ <translation>&amp;Gastar troco não confirmado</translation>
+ </message>
+ <message>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>Abrir a porta do cliente bitcoin automaticamente no seu router. Isto apenas funciona se o seu router suportar UPnP e este se encontrar ligado.</translation>
+ </message>
+ <message>
+ <source>Map port using &amp;UPnP</source>
+ <translation>Mapear porta usando &amp;UPnP</translation>
+ </message>
+ <message>
+ <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
+ <translation>Conectar à rede da Bitcoin através dum proxy SOCLS5.</translation>
+ </message>
+ <message>
+ <source>&amp;Connect through SOCKS5 proxy (default proxy):</source>
+ <translation>&amp;Ligar através dum proxy SOCKS5 (proxy por defeito):</translation>
+ </message>
+ <message>
+ <source>Proxy &amp;IP:</source>
+ <translation>&amp;IP do proxy:</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>&amp;Porto:</translation>
+ </message>
+ <message>
+ <source>Port of the proxy (e.g. 9050)</source>
+ <translation>Porto do proxy (p.ex. 9050)</translation>
+ </message>
+ <message>
+ <source>&amp;Window</source>
+ <translation>&amp;Janela</translation>
+ </message>
+ <message>
+ <source>Show only a tray icon after minimizing the window.</source>
+ <translation>Apenas mostrar o ícone da bandeja de sistema após minimizar a janela.</translation>
+ </message>
+ <message>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>&amp;Minimizar para a bandeja de sistema e não para a barra de ferramentas</translation>
+ </message>
+ <message>
+ <source>M&amp;inimize on close</source>
+ <translation>M&amp;inimizar ao fechar</translation>
+ </message>
+ <message>
+ <source>&amp;Display</source>
+ <translation>&amp;Visualização</translation>
+ </message>
+ <message>
+ <source>User Interface &amp;language:</source>
+ <translation>&amp;Linguagem da interface de utilizador:</translation>
+ </message>
+ <message>
+ <source>&amp;Unit to show amounts in:</source>
+ <translation>&amp;Unidade para mostrar quantias:</translation>
+ </message>
+ <message>
+ <source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
+ <translation>Escolha a subdivisão unitária a ser mostrada por defeito na aplicação e ao enviar moedas.</translation>
+ </message>
+ <message>
+ <source>Whether to show coin control features or not.</source>
+ <translation>Escolha para mostrar funcionalidades de Coin Control ou não.</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>&amp;OK</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>&amp;Cancelar</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>padrão</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>nenhum</translation>
+ </message>
+ <message>
+ <source>Confirm options reset</source>
+ <translation>Confirme a reposição de opções</translation>
+ </message>
+ <message>
+ <source>Client restart required to activate changes.</source>
+ <translation>É necessário reiniciar o cliente para ativar as alterações.</translation>
+ </message>
+ <message>
+ <source>Client will be shut down. Do you want to proceed?</source>
+ <translation>O cliente será desligado. Deseja continuar?</translation>
+ </message>
+ <message>
+ <source>This change would require a client restart.</source>
+ <translation>Esta alteração requer um reinício do cliente.</translation>
+ </message>
+ <message>
+ <source>The supplied proxy address is invalid.</source>
+ <translation>O endereço de proxy introduzido é inválido. </translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>Formulário</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>A informação mostrada poderá estar desatualizada. A sua carteira sincroniza automaticamente com a rede Bitcoin depois de estabelecer ligação, mas este processo ainda não está completo.</translation>
+ </message>
+ <message>
+ <source>Watch-only:</source>
+ <translation>Modo-verificação:</translation>
+ </message>
+ <message>
+ <source>Available:</source>
+ <translation>Disponível:</translation>
+ </message>
+ <message>
+ <source>Your current spendable balance</source>
+ <translation>O seu saldo (gastável) disponível</translation>
+ </message>
+ <message>
+ <source>Pending:</source>
+ <translation>Pendente:</translation>
+ </message>
+ <message>
+ <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source>
+ <translation>Total de transações por confirmar, que ainda não estão contabilizadas no seu saldo gastável</translation>
+ </message>
+ <message>
+ <source>Immature:</source>
+ <translation>Imaturo:</translation>
+ </message>
+ <message>
+ <source>Mined balance that has not yet matured</source>
+ <translation>O saldo minado ainda não amadureceu</translation>
+ </message>
+ <message>
+ <source>Balances</source>
+ <translation>Balanços</translation>
+ </message>
+ <message>
+ <source>Total:</source>
+ <translation>Total:</translation>
+ </message>
+ <message>
+ <source>Your current total balance</source>
+ <translation>O seu saldo total actual</translation>
+ </message>
+ <message>
+ <source>Your current balance in watch-only addresses</source>
+ <translation>O seu balanço atual em endereços de apenas observação</translation>
+ </message>
+ <message>
+ <source>Spendable:</source>
+ <translation>Dispensável:</translation>
+ </message>
+ <message>
+ <source>Recent transactions</source>
+ <translation>transações recentes</translation>
+ </message>
+ <message>
+ <source>Unconfirmed transactions to watch-only addresses</source>
+ <translation>Transações não confirmadas para endereços modo-verificação</translation>
+ </message>
+ <message>
+ <source>Mined balance in watch-only addresses that has not yet matured</source>
+ <translation>Saldo minado ainda não disponivél de endereços modo-verificação</translation>
+ </message>
+ <message>
+ <source>Current total balance in watch-only addresses</source>
+ <translation>Saldo disponivél em enderços modo-verificação</translation>
+ </message>
+</context>
+<context>
+ <name>PaymentServer</name>
+ <message>
+ <source>URI handling</source>
+ <translation>Manuseamento de URI</translation>
+ </message>
+ <message>
+ <source>Invalid payment address %1</source>
+ <translation>Endereço de pagamento inválido %1</translation>
+ </message>
+ <message>
+ <source>Payment request rejected</source>
+ <translation>Pedido de pagamento rejeitado</translation>
+ </message>
+ <message>
+ <source>Payment request network doesn't match client network.</source>
+ <translation>Rede de requisição de pagamento não corresponde com a rede do cliente.</translation>
+ </message>
+ <message>
+ <source>Payment request is not initialized.</source>
+ <translation>Requisição de pagamento não iniciou.</translation>
+ </message>
+ <message>
+ <source>Requested payment amount of %1 is too small (considered dust).</source>
+ <translation>Quantia solicitada para pagamento de %1 é muito pequena (considerada "pó").</translation>
+ </message>
+ <message>
+ <source>Payment request error</source>
+ <translation>Erro de pedido de pagamento</translation>
+ </message>
+ <message>
+ <source>Cannot start bitcoin: click-to-pay handler</source>
+ <translation>Impossível iniciar o controlador de bitcoin: click-to-pay</translation>
+ </message>
+ <message>
+ <source>Payment request fetch URL is invalid: %1</source>
+ <translation>O URL de pedido de pagamento é inválido: %1</translation>
+ </message>
+ <message>
+ <source>URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source>
+ <translation>URI não foi lido correctamente! Isto pode ser causado por um endereço Bitcoin inválido ou por parâmetros URI malformados.</translation>
+ </message>
+ <message>
+ <source>Payment request file handling</source>
+ <translation>Controlo de pedidos de pagamento.</translation>
+ </message>
+ <message>
+ <source>Payment request file cannot be read! This can be caused by an invalid payment request file.</source>
+ <translation>O ficheiro de pedido de pagamento não pôde ser lido! Isto pode ter sido causado por um ficheiro de pedido de pagamento inválido.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>Pedido de pagamento expirou.</translation>
+ </message>
+ <message>
+ <source>Unverified payment requests to custom payment scripts are unsupported.</source>
+ <translation>Pedidos de pagamento não-verificados para scripts de pagamento personalizados não são suportados.</translation>
+ </message>
+ <message>
+ <source>Invalid payment request.</source>
+ <translation>Pedido de pagamento inválido.</translation>
+ </message>
+ <message>
+ <source>Refund from %1</source>
+ <translation>Reembolsar de %1</translation>
+ </message>
+ <message>
+ <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source>
+ <translation>Pedido de pagamento %1 excede o tamanho (%2 bytes, permitido %3 bytes).</translation>
+ </message>
+ <message>
+ <source>Payment request DoS protection</source>
+ <translation>Pedido de pagamento proteção DdS</translation>
+ </message>
+ <message>
+ <source>Error communicating with %1: %2</source>
+ <translation>Erro ao comunicar com %1: %2</translation>
+ </message>
+ <message>
+ <source>Payment request cannot be parsed!</source>
+ <translation>O pedido de pagamento não pode ser lido ou processado!</translation>
+ </message>
+ <message>
+ <source>Bad response from server %1</source>
+ <translation>Má resposta do servidor %1</translation>
+ </message>
+ <message>
+ <source>Payment acknowledged</source>
+ <translation>Pagamento confirmado</translation>
+ </message>
+ <message>
+ <source>Network request error</source>
+ <translation>Erro de pedido de rede</translation>
+ </message>
+</context>
+<context>
+ <name>PeerTableModel</name>
+ <message>
+ <source>User Agent</source>
+ <translation>Agente Usuário</translation>
+ </message>
+ <message>
+ <source>Node/Service</source>
+ <translation>Nó/Serviço</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Tempo de Latência</translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>Quantia</translation>
+ </message>
+ <message>
+ <source>Enter a Bitcoin address (e.g. %1)</source>
+ <translation>Entre um endereço Bitcoin (ex. %1)</translation>
+ </message>
+ <message>
+ <source>%1 d</source>
+ <translation>%1 d</translation>
+ </message>
+ <message>
+ <source>%1 h</source>
+ <translation>%1 h</translation>
+ </message>
+ <message>
+ <source>%1 m</source>
+ <translation>%1 m</translation>
+ </message>
+ <message>
+ <source>%1 s</source>
+ <translation>%1 s</translation>
+ </message>
+ <message>
+ <source>None</source>
+ <translation>Nenhum</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>N/D</translation>
+ </message>
+ <message>
+ <source>%1 ms</source>
+ <translation>%1 ms</translation>
+ </message>
+</context>
+<context>
+ <name>QRImageWidget</name>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Salvar Imagem...</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Image</source>
+ <translation>&amp;Copiar Imagem</translation>
+ </message>
+ <message>
+ <source>Save QR Code</source>
+ <translation>Guardar Código QR</translation>
+ </message>
+ <message>
+ <source>PNG Image (*.png)</source>
+ <translation>Imagem PNG (*.png)</translation>
+ </message>
+</context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>Client name</source>
+ <translation>Nome do Cliente</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>N/D</translation>
+ </message>
+ <message>
+ <source>Client version</source>
+ <translation>Versão do Cliente</translation>
+ </message>
+ <message>
+ <source>&amp;Information</source>
+ <translation>&amp;Informação</translation>
+ </message>
+ <message>
+ <source>Debug window</source>
+ <translation>Janela de depuração</translation>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>Geral</translation>
+ </message>
+ <message>
+ <source>Using OpenSSL version</source>
+ <translation>Usando versão OpenSSL</translation>
+ </message>
+ <message>
+ <source>Using BerkeleyDB version</source>
+ <translation>Versão BerkeleyDB em uso</translation>
+ </message>
+ <message>
+ <source>Startup time</source>
+ <translation>Hora de inicialização</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Rede</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>Nome</translation>
+ </message>
+ <message>
+ <source>Number of connections</source>
+ <translation>Número de ligações</translation>
+ </message>
+ <message>
+ <source>Block chain</source>
+ <translation>Cadeia de blocos</translation>
+ </message>
+ <message>
+ <source>Current number of blocks</source>
+ <translation>Número actual de blocos</translation>
+ </message>
+ <message>
+ <source>Received</source>
+ <translation>Recebido</translation>
+ </message>
+ <message>
+ <source>Sent</source>
+ <translation>Enviado</translation>
+ </message>
+ <message>
+ <source>&amp;Peers</source>
+ <translation>&amp;Conexção</translation>
+ </message>
+ <message>
+ <source>Select a peer to view detailed information.</source>
+ <translation>Selecione uma conexação para ver informação em detalhe.</translation>
+ </message>
+ <message>
+ <source>Direction</source>
+ <translation>Direcção</translation>
+ </message>
+ <message>
+ <source>Version</source>
+ <translation>Versão</translation>
+ </message>
+ <message>
+ <source>User Agent</source>
+ <translation>Agente Usuário</translation>
+ </message>
+ <message>
+ <source>Services</source>
+ <translation>Serviços</translation>
+ </message>
+ <message>
+ <source>Starting Height</source>
+ <translation>Iniciando Altura</translation>
+ </message>
+ <message>
+ <source>Sync Height</source>
+ <translation>Sincronização da Altura</translation>
+ </message>
+ <message>
+ <source>Ban Score</source>
+ <translation>Resultado da Suspensão</translation>
+ </message>
+ <message>
+ <source>Connection Time</source>
+ <translation>Tempo de Conexção</translation>
+ </message>
+ <message>
+ <source>Last Send</source>
+ <translation>Ultimo Envio</translation>
+ </message>
+ <message>
+ <source>Last Receive</source>
+ <translation>Ultimo Recebimento</translation>
+ </message>
+ <message>
+ <source>Bytes Sent</source>
+ <translation>Bytes Enviados</translation>
+ </message>
+ <message>
+ <source>Bytes Received</source>
+ <translation>Bytes Recebidos</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Tempo de Latência</translation>
+ </message>
+ <message>
+ <source>Last block time</source>
+ <translation>Data do último bloco</translation>
+ </message>
+ <message>
+ <source>&amp;Open</source>
+ <translation>&amp;Abrir</translation>
+ </message>
+ <message>
+ <source>&amp;Console</source>
+ <translation>&amp;Consola</translation>
+ </message>
+ <message>
+ <source>&amp;Network Traffic</source>
+ <translation>&amp;Tráfego de Rede</translation>
+ </message>
+ <message>
+ <source>&amp;Clear</source>
+ <translation>&amp;Limpar</translation>
+ </message>
+ <message>
+ <source>Totals</source>
+ <translation>Totais</translation>
+ </message>
+ <message>
+ <source>In:</source>
+ <translation>Entrada:</translation>
+ </message>
+ <message>
+ <source>Out:</source>
+ <translation>Saída:</translation>
+ </message>
+ <message>
+ <source>Build date</source>
+ <translation>Data de compilação</translation>
+ </message>
+ <message>
+ <source>Debug log file</source>
+ <translation>Ficheiro de registo de depuração</translation>
+ </message>
+ <message>
+ <source>Clear console</source>
+ <translation>Limpar consola</translation>
+ </message>
+ <message>
+ <source>Welcome to the Bitcoin Core RPC console.</source>
+ <translation>Bem-vindo à consola RPC do Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
+ <translation>Use as setas para cima e para baixo para navegar no histórico e &lt;b&gt;Ctrl-L&lt;/b&gt; para limpar o ecrã.</translation>
+ </message>
+ <message>
+ <source>Type &lt;b&gt;help&lt;/b&gt; for an overview of available commands.</source>
+ <translation>Insira &lt;b&gt;help&lt;/b&gt; para visualizar os comandos disponíveis.</translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation>%1 B</translation>
+ </message>
+ <message>
+ <source>%1 KB</source>
+ <translation>%1 KB</translation>
+ </message>
+ <message>
+ <source>%1 MB</source>
+ <translation>%1 MB</translation>
+ </message>
+ <message>
+ <source>%1 GB</source>
+ <translation>%1 GB</translation>
+ </message>
+ <message>
+ <source>via %1</source>
+ <translation>via %1</translation>
+ </message>
+ <message>
+ <source>never</source>
+ <translation>nunca</translation>
+ </message>
+ <message>
+ <source>Inbound</source>
+ <translation>Entrada</translation>
+ </message>
+ <message>
+ <source>Outbound</source>
+ <translation>Saída</translation>
+ </message>
+ <message>
+ <source>Unknown</source>
+ <translation>Desconhecido</translation>
+ </message>
+ <message>
+ <source>Fetching...</source>
+ <translation>Em busca...</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Amount:</source>
+ <translation>&amp;Quantia:</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Rótulo:</translation>
+ </message>
+ <message>
+ <source>&amp;Message:</source>
+ <translation>&amp;Mensagem:</translation>
+ </message>
+ <message>
+ <source>Reuse one of the previously used receiving addresses. Reusing addresses has security and privacy issues. Do not use this unless re-generating a payment request made before.</source>
+ <translation>Reutilize um dos endereços de entrada usados anteriormente. Reutilizar endereços pode levar a riscos de segurança e de privacidade. Não use esta função a não ser que esteja a gerar novamente uma requisição de pagamento feita anteriormente.</translation>
+ </message>
+ <message>
+ <source>R&amp;euse an existing receiving address (not recommended)</source>
+ <translation>Reutilizar um endereço de receção existente (não recomendado)</translation>
+ </message>
+ <message>
+ <source>An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network.</source>
+ <translation>Uma mensagem opcional para anexar ao pedido de pagamento, que será exibida quando o pedido for aberto. Nota: A mensagem não será enviada com o pagamento através da rede Bitcoin.</translation>
+ </message>
+ <message>
+ <source>An optional label to associate with the new receiving address.</source>
+ <translation>Um rótulo opcional a associar ao novo endereço de receção.</translation>
+ </message>
+ <message>
+ <source>Use this form to request payments. All fields are &lt;b&gt;optional&lt;/b&gt;.</source>
+ <translation>Utilize este formulário para solicitar pagamentos. Todos os campos são &lt;b&gt;opcionais&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>An optional amount to request. Leave this empty or zero to not request a specific amount.</source>
+ <translation>Uma quantia opcional a solicitar. Deixe em branco ou zero para não solicitar uma quantidade específica.</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Limpar todos os campos do formulário.</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation>Limpar</translation>
+ </message>
+ <message>
+ <source>Requested payments history</source>
+ <translation>Histórico de pagamentos solicitados</translation>
+ </message>
+ <message>
+ <source>&amp;Request payment</source>
+ <translation>&amp;Requisitar Pagamento</translation>
+ </message>
+ <message>
+ <source>Show the selected request (does the same as double clicking an entry)</source>
+ <translation>Mostrar o pedido seleccionado (faz o mesmo que clicar 2 vezes numa entrada)</translation>
+ </message>
+ <message>
+ <source>Show</source>
+ <translation>Mostrar</translation>
+ </message>
+ <message>
+ <source>Remove the selected entries from the list</source>
+ <translation>Remover as entradas seleccionadas da lista</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>Remover</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Copiar rótulo</translation>
+ </message>
+ <message>
+ <source>Copy message</source>
+ <translation>Copiar mensagem</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copiar quantia</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>QR Code</source>
+ <translation>Código QR</translation>
+ </message>
+ <message>
+ <source>Copy &amp;URI</source>
+ <translation>Copiar &amp;URI</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Address</source>
+ <translation>Copi&amp;ar Endereço</translation>
+ </message>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Salvar Imagem...</translation>
+ </message>
+ <message>
+ <source>Request payment to %1</source>
+ <translation>Requisitar Pagamento para %1</translation>
+ </message>
+ <message>
+ <source>Payment information</source>
+ <translation>Informação de Pagamento</translation>
+ </message>
+ <message>
+ <source>URI</source>
+ <translation>URI</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Endereço</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Quantia</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Rótulo</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Mensagem</translation>
+ </message>
+ <message>
+ <source>Resulting URI too long, try to reduce the text for label / message.</source>
+ <translation>URI resultante muito longo. Tente reduzir o texto do rótulo / mensagem.</translation>
+ </message>
+ <message>
+ <source>Error encoding URI into QR Code.</source>
+ <translation>Erro ao codificar URI em Código QR.</translation>
+ </message>
+</context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Rótulo</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Mensagem</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Quantia</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(sem rótulo)</translation>
+ </message>
+ <message>
+ <source>(no message)</source>
+ <translation>(sem mensagem)</translation>
+ </message>
+ <message>
+ <source>(no amount)</source>
+ <translation>(sem quantia)</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Enviar Moedas</translation>
+ </message>
+ <message>
+ <source>Coin Control Features</source>
+ <translation>Funcionalidades de Coin Control:</translation>
+ </message>
+ <message>
+ <source>Inputs...</source>
+ <translation>Entradas...</translation>
+ </message>
+ <message>
+ <source>automatically selected</source>
+ <translation>selecionadas automáticamente</translation>
+ </message>
+ <message>
+ <source>Insufficient funds!</source>
+ <translation>Fundos insuficientes!</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Quantidade:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Bytes:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Quantia:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Prioridade:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Taxa:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Depois da taxa:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Troco:</translation>
+ </message>
+ <message>
+ <source>If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address.</source>
+ <translation>Se isto estiver ativo, mas o endereço de troco estiver vazio ou for inválido, o troco irá ser enviado para um novo endereço.</translation>
+ </message>
+ <message>
+ <source>Custom change address</source>
+ <translation>Endereço de troco personalizado</translation>
+ </message>
+ <message>
+ <source>Transaction Fee:</source>
+ <translation>Custo da Transação:</translation>
+ </message>
+ <message>
+ <source>Choose...</source>
+ <translation>Escolha...</translation>
+ </message>
+ <message>
+ <source>collapse fee-settings</source>
+ <translation>fechar definições-de custos</translation>
+ </message>
+ <message>
+ <source>per kilobyte</source>
+ <translation>por kilobyte</translation>
+ </message>
+ <message>
+ <source>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "total at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source>
+ <translation>Se a taxa fixa for 1000 satoshis e a transação for somente 250 bytes, pagará somente 250 satoshis "por kilobyte" em custos se trasacionar "pelo menos" 1000 satoshis. Transações superiores a um kilobyte são cobradas por kilobyte.</translation>
+ </message>
+ <message>
+ <source>Hide</source>
+ <translation>Esconder</translation>
+ </message>
+ <message>
+ <source>total at least</source>
+ <translation>total minimo</translation>
+ </message>
+ <message>
+ <source>Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process.</source>
+ <translation>Pode pagar somente a taxa minima desde que haja um volume de transações inferior ao espaço nos blocos. No entanto tenha em atenção que esta opção poderá acabar em uma transação nunca confirmada assim que os pedidos de transações excedam a capacidade de processamento da rede.</translation>
+ </message>
+ <message>
+ <source>(read the tooltip)</source>
+ <translation>(leia a dica)</translation>
+ </message>
+ <message>
+ <source>Recommended:</source>
+ <translation>Recomendado:</translation>
+ </message>
+ <message>
+ <source>Custom:</source>
+ <translation>Uso:</translation>
+ </message>
+ <message>
+ <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source>
+ <translation>(Taxa inteligente ainda não foi acionada. Normalmente demora alguns blocos...)</translation>
+ </message>
+ <message>
+ <source>Confirmation time:</source>
+ <translation>Tempo de confirmação:</translation>
+ </message>
+ <message>
+ <source>normal</source>
+ <translation>normal</translation>
+ </message>
+ <message>
+ <source>fast</source>
+ <translation>rapido</translation>
+ </message>
+ <message>
+ <source>Send as zero-fee transaction if possible</source>
+ <translation>Enviar como uma transação a custo zero se possivél</translation>
+ </message>
+ <message>
+ <source>(confirmation may take longer)</source>
+ <translation>(confirmação poderá demorar mais)</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>Enviar para múltiplos destinatários de uma vez</translation>
+ </message>
+ <message>
+ <source>Add &amp;Recipient</source>
+ <translation>Adicionar &amp;Destinatário</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Limpar todos os campos do formulário.</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Lixo:</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Limpar &amp;Tudo</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>Saldo:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>Confirme ação de envio</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>E&amp;nviar</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>Confirme envio de moedas</translation>
+ </message>
+ <message>
+ <source>%1 to %2</source>
+ <translation>%1 para %2</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Copiar quantidade</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copiar quantia</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Copiar taxa</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Copiar valor após taxa</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Copiar bytes</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Copiar prioridade</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Copiar alteração</translation>
+ </message>
+ <message>
+ <source>or</source>
+ <translation>ou</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>A quantia a pagar deverá ser maior que 0.</translation>
+ </message>
+ <message>
+ <source>The amount exceeds your balance.</source>
+ <translation>A quantia excede o seu saldo.</translation>
+ </message>
+ <message>
+ <source>The total exceeds your balance when the %1 transaction fee is included.</source>
+ <translation>O total excede o seu saldo quando a taxa de transação de %1 for incluída.</translation>
+ </message>
+ <message>
+ <source>Transaction creation failed!</source>
+ <translation>Erro: A criação da transação falhou! </translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>A transação foi rejeitada! Isto poderá acontecer se algumas das moedas na sua carteira já tiverem sido gastas, se por exemplo tiver usado uma cópia do ficheiro wallet.dat e as moedas tiverem sido gastas na cópia mas não tiverem sido marcadas como gastas aqui.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>Pedido de pagamento expirou.</translation>
+ </message>
+ <message>
+ <source>Pay only the minimum fee of %1</source>
+ <translation>Pagar somente a taxa minima de %1</translation>
+ </message>
+ <message>
+ <source>Warning: Invalid Bitcoin address</source>
+ <translation>Aviso: Endereço Bitcoin inválido</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(sem rótulo)</translation>
+ </message>
+ <message>
+ <source>Warning: Unknown change address</source>
+ <translation>Aviso: Endereço de troco desconhecido</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Copiar lixo</translation>
+ </message>
+ <message>
+ <source>Are you sure you want to send?</source>
+ <translation>Tem a certeza que deseja enviar?</translation>
+ </message>
+ <message>
+ <source>added as transaction fee</source>
+ <translation>adicionados como taxa de transação</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>Qu&amp;antia:</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>&amp;Pagar A:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Escreva um rótulo para este endereço para o adicionar ao seu livro de endereços</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>Rótu&amp;lo:</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Escolher endereço usado previamente</translation>
+ </message>
+ <message>
+ <source>This is a normal payment.</source>
+ <translation>Este é um pagamento normal.</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to send the payment to</source>
+ <translation>O endereço Bitcoin para enviar o pagamento</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Cole endereço da área de transferência</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Remove this entry</source>
+ <translation>Remover esta entrada</translation>
+ </message>
+ <message>
+ <source>Message:</source>
+ <translation>Mensagem:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to the list of used addresses</source>
+ <translation>Introduza um rótulo para este endereço para o adicionar à sua lista de endereços usados</translation>
+ </message>
+ <message>
+ <source>A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network.</source>
+ <translation>Uma mensagem que estava anexada ao URI bitcoin: que será armazenada com a transação para sua referência. Nota: Esta mensagem não será enviada através da rede Bitcoin.</translation>
+ </message>
+ <message>
+ <source>Pay To:</source>
+ <translation>Pagar a:</translation>
+ </message>
+ <message>
+ <source>Memo:</source>
+ <translation>Memorando:</translation>
+ </message>
+</context>
+<context>
+ <name>ShutdownWindow</name>
+ <message>
+ <source>Bitcoin Core is shutting down...</source>
+ <translation>O Bitcoin Core está a encerrar...</translation>
+ </message>
+ <message>
+ <source>Do not shut down the computer until this window disappears.</source>
+ <translation>Não desligue o computador enquanto esta janela não desaparecer.</translation>
+ </message>
+</context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Signatures - Sign / Verify a Message</source>
+ <translation>Assinaturas - Assinar / Verificar uma Mensagem</translation>
+ </message>
+ <message>
+ <source>&amp;Sign Message</source>
+ <translation>&amp;Assinar Mensagem</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to sign the message with</source>
+ <translation>O endereço Bitcoin para designar a mensagem</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Escolher endereço usado previamente</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Colar endereço da área de transferência</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Enter the message you want to sign here</source>
+ <translation>Escreva aqui a mensagem que deseja assinar</translation>
+ </message>
+ <message>
+ <source>Signature</source>
+ <translation>Assinatura</translation>
+ </message>
+ <message>
+ <source>Copy the current signature to the system clipboard</source>
+ <translation>Copiar a assinatura actual para a área de transferência</translation>
+ </message>
+ <message>
+ <source>Sign the message to prove you own this Bitcoin address</source>
+ <translation>Assine uma mensagem para provar que é dono deste endereço Bitcoin</translation>
+ </message>
+ <message>
+ <source>Sign &amp;Message</source>
+ <translation>Assinar &amp;Mensagem</translation>
+ </message>
+ <message>
+ <source>Reset all sign message fields</source>
+ <translation>Repor todos os campos de assinatura de mensagem</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Limpar &amp;Tudo</translation>
+ </message>
+ <message>
+ <source>&amp;Verify Message</source>
+ <translation>&amp;Verificar Mensagem</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address the message was signed with</source>
+ <translation>O endereço Bitcoin com que a mensagem foi designada</translation>
+ </message>
+ <message>
+ <source>Verify the message to ensure it was signed with the specified Bitcoin address</source>
+ <translation>Verifique a mensagem para assegurar que foi assinada com o endereço Bitcoin especificado</translation>
+ </message>
+ <message>
+ <source>Verify &amp;Message</source>
+ <translation>Verificar &amp;Mensagem</translation>
+ </message>
+ <message>
+ <source>Reset all verify message fields</source>
+ <translation>Repor todos os campos de verificação de mensagem</translation>
+ </message>
+ <message>
+ <source>Click "Sign Message" to generate signature</source>
+ <translation>Clique "Assinar mensagem" para gerar a assinatura</translation>
+ </message>
+ <message>
+ <source>The entered address is invalid.</source>
+ <translation>O endereço introduzido é inválido.</translation>
+ </message>
+ <message>
+ <source>Please check the address and try again.</source>
+ <translation>Por favor verifique o endereço e tente de novo.</translation>
+ </message>
+ <message>
+ <source>The entered address does not refer to a key.</source>
+ <translation>O endereço introduzido não refere a nenhuma chave.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock was cancelled.</source>
+ <translation>O desbloqueio da carteira foi cancelado.</translation>
+ </message>
+ <message>
+ <source>Private key for the entered address is not available.</source>
+ <translation>A chave privada para o endereço introduzido não está disponível.</translation>
+ </message>
+ <message>
+ <source>Message signing failed.</source>
+ <translation>Assinatura de mensagem falhou.</translation>
+ </message>
+ <message>
+ <source>Message signed.</source>
+ <translation>Mensagem assinada.</translation>
+ </message>
+ <message>
+ <source>The signature could not be decoded.</source>
+ <translation>A assinatura não pôde ser descodificada.</translation>
+ </message>
+ <message>
+ <source>Please check the signature and try again.</source>
+ <translation>Por favor verifique a assinatura e tente de novo.</translation>
+ </message>
+ <message>
+ <source>The signature did not match the message digest.</source>
+ <translation>A assinatura não condiz com o conteúdo da mensagem.</translation>
+ </message>
+ <message>
+ <source>Message verification failed.</source>
+ <translation>Verificação da mensagem falhou.</translation>
+ </message>
+ <message>
+ <source>Message verified.</source>
+ <translation>Mensagem verificada.</translation>
+ </message>
+</context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>The Bitcoin Core developers</source>
+ <translation>Os programadores do Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>[testnet]</source>
+ <translation>[rede de testes]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ <message>
+ <source>KB/s</source>
+ <translation>KB/s</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>Aberto até %1</translation>
+ </message>
+ <message>
+ <source>conflicted</source>
+ <translation>em conflito:</translation>
+ </message>
+ <message>
+ <source>%1/offline</source>
+ <translation>%1/desligado</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/não confirmada</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 confirmações</translation>
+ </message>
+ <message>
+ <source>Status</source>
+ <translation>Estado</translation>
+ </message>
+ <message numerus="yes">
+ <source>, broadcast through %n node(s)</source>
+ <translation><numerusform>, transmitida através de %n nó</numerusform><numerusform>, transmitida através de %n nós</numerusform></translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Source</source>
+ <translation>Origem</translation>
+ </message>
+ <message>
+ <source>Generated</source>
+ <translation>Gerado</translation>
+ </message>
+ <message>
+ <source>From</source>
+ <translation>De</translation>
+ </message>
+ <message>
+ <source>To</source>
+ <translation>Para</translation>
+ </message>
+ <message>
+ <source>own address</source>
+ <translation>endereço próprio</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>modo-verificação</translation>
+ </message>
+ <message>
+ <source>label</source>
+ <translation>rótulo</translation>
+ </message>
+ <message>
+ <source>Credit</source>
+ <translation>Crédito</translation>
+ </message>
+ <message numerus="yes">
+ <source>matures in %n more block(s)</source>
+ <translation><numerusform>matura em %n bloco</numerusform><numerusform>matura em %n blocos</numerusform></translation>
+ </message>
+ <message>
+ <source>not accepted</source>
+ <translation>não aceite</translation>
+ </message>
+ <message>
+ <source>Debit</source>
+ <translation>Débito</translation>
+ </message>
+ <message>
+ <source>Total debit</source>
+ <translation>Total a debitar</translation>
+ </message>
+ <message>
+ <source>Total credit</source>
+ <translation>Total a creditar</translation>
+ </message>
+ <message>
+ <source>Transaction fee</source>
+ <translation>Taxa de transação</translation>
+ </message>
+ <message>
+ <source>Net amount</source>
+ <translation>Valor líquido</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Mensagem</translation>
+ </message>
+ <message>
+ <source>Comment</source>
+ <translation>Comentário</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>ID da Transação</translation>
+ </message>
+ <message>
+ <source>Merchant</source>
+ <translation>Comerciante</translation>
+ </message>
+ <message>
+ <source>Generated coins must mature %1 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.</source>
+ <translation>Moedas geradas deverão maturar por %1 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, o seu estado irá ser alterado 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.</translation>
+ </message>
+ <message>
+ <source>Debug information</source>
+ <translation>Informação de depuração</translation>
+ </message>
+ <message>
+ <source>Transaction</source>
+ <translation>Transação</translation>
+ </message>
+ <message>
+ <source>Inputs</source>
+ <translation>Entradas</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Quantia</translation>
+ </message>
+ <message>
+ <source>true</source>
+ <translation>verdadeiro</translation>
+ </message>
+ <message>
+ <source>false</source>
+ <translation>falso</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, ainda não foi transmitida com sucesso</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Aberta por mais %n bloco</numerusform><numerusform>Aberta por mais %n blocos</numerusform></translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>desconhecido</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>Detalhes da transação</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>Esta janela mostra uma descrição detalhada da transação</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Tipo</translation>
+ </message>
+ <message>
+ <source>Immature (%1 confirmations, will be available after %2)</source>
+ <translation>Imaturo (%1 confirmações, estará disponível após %2)</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Aberta por mais %n bloco</numerusform><numerusform>Aberta por mais %n blocos</numerusform></translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>Aberto até %1</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>Confirmada (%1 confirmações)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>Este bloco não foi recebido por outros nós e provavelmente não será aceite pela rede!</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>Gerado mas não aceite</translation>
+ </message>
+ <message>
+ <source>Offline</source>
+ <translation>Offline</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Rótulo</translation>
+ </message>
+ <message>
+ <source>Unconfirmed</source>
+ <translation>Não confirmado:</translation>
+ </message>
+ <message>
+ <source>Confirming (%1 of %2 recommended confirmations)</source>
+ <translation>A confirmar (%1 de %2 confirmações recomendadas)</translation>
+ </message>
+ <message>
+ <source>Conflicted</source>
+ <translation>Em Conflito:</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Recebido com</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>Recebido de</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Enviado para</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>Pagamento a si mesmo</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Minadas</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>modo-verificação</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(n/d)</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>Estado da transação. Passar o cursor por cima deste campo para mostrar o número de confirmações.</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Data e hora em que a transação foi recebida.</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>Tipo de transação.</translation>
+ </message>
+ <message>
+ <source>Whether or not a watch-only address is involved in this transaction.</source>
+ <translation>Desde que um endereço de modo-verificação faça parte ou não desta transação</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>Quantia retirada ou adicionada ao saldo.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>Todas</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>Hoje</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>Esta semana</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>Este mês</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>Mês passado</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>Este ano</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>Período...</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Recebida com</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Enviada para</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>Para si mesmo</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Minadas</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>Outras</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>Escreva endereço ou rótulo a procurar</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>Quantia mínima</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Copiar endereço</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Copiar rótulo</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copiar quantia</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Copiar ID da Transação</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>Editar rótulo</translation>
+ </message>
+ <message>
+ <source>Show transaction details</source>
+ <translation>Mostrar detalhes da transação</translation>
+ </message>
+ <message>
+ <source>Export Transaction History</source>
+ <translation>Exportar Histórico de Transacções</translation>
+ </message>
+ <message>
+ <source>Watch-only</source>
+ <translation>Modo-verificação</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>A Exportação Falhou</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the transaction history to %1.</source>
+ <translation>Ocorreu um erro ao tentar guardar o histórico de transações em %1.</translation>
+ </message>
+ <message>
+ <source>Exporting Successful</source>
+ <translation>Exportação Bem Sucedida</translation>
+ </message>
+ <message>
+ <source>The transaction history was successfully saved to %1.</source>
+ <translation>O histórico de transacções foi com guardado com sucesso em %1.</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Ficheiro separado por vírgulas (*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Confirmada</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Tipo</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Rótulo</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Endereço</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>Período:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>até</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ <message>
+ <source>Unit to show amounts in. Click to select another unit.</source>
+ <translation>Unidade de valores recebidos. Clique para selecionar outra unidade.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletFrame</name>
+ <message>
+ <source>No wallet has been loaded.</source>
+ <translation>Nenhuma carteira foi carregada.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Enviar Moedas</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Exportar</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Exportar os dados no separador actual para um ficheiro</translation>
+ </message>
+ <message>
+ <source>Backup Wallet</source>
+ <translation>Cópia de Segurança da Carteira</translation>
+ </message>
+ <message>
+ <source>Wallet Data (*.dat)</source>
+ <translation>Dados da Carteira (*.dat)</translation>
+ </message>
+ <message>
+ <source>Backup Failed</source>
+ <translation>Cópia de Segurança Falhou</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the wallet data to %1.</source>
+ <translation>Ocorreu um erro ao tentar guardar os dados da carteira em %1.</translation>
+ </message>
+ <message>
+ <source>The wallet data was successfully saved to %1.</source>
+ <translation>Os dados da carteira foram guardados com sucesso em %1.</translation>
+ </message>
+ <message>
+ <source>Backup Successful</source>
+ <translation>Cópia de Segurança Bem Sucedida</translation>
+ </message>
+</context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>Opções:</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>Especificar pasta de dados</translation>
+ </message>
+ <message>
+ <source>Connect to a node to retrieve peer addresses, and disconnect</source>
+ <translation>Ligar a um nó para recuperar endereços de pares, e desligar</translation>
+ </message>
+ <message>
+ <source>Specify your own public address</source>
+ <translation>Especifique o seu endereço público</translation>
+ </message>
+ <message>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>Aceitar comandos de linha de comandos e JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>Correr o processo em segundo plano e aceitar comandos</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>Utilizar a rede de testes</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
+ <translation>Aceitar ligações externas (padrão: 1 sem -proxy ou -connect)</translation>
+ </message>
+ <message>
+ <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
+ <translation>Associar a endereço específico e escutar sempre nele. Use a notação [anfitrião]:porta para IPv6</translation>
+ </message>
+ <message>
+ <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
+ <translation>Apague todas as transações da carteira e somente restore aquelas que façam parte do blockchain através de re-scan ao reiniciar o programa</translation>
+ </message>
+ <message>
+ <source>Distributed under the MIT software license, see the accompanying file COPYING or &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</source>
+ <translation>Distribuido através da licença de software MIT, verifique o ficheiro anexado COPYING ou &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</translation>
+ </message>
+ <message>
+ <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
+ <translation>Executar comando quando uma das transações na carteira mudar (no comando, %s é substituído pelo ID da Transação)</translation>
+ </message>
+ <message>
+ <source>Set the number of script verification threads (%u to %d, 0 = auto, &lt;0 = leave that many cores free, default: %d)</source>
+ <translation>Defina o número de processos de verificação (%u até %d, 0 = automático, &lt;0 = ldisponibiliza esse número de núcleos livres, por defeito: %d)</translation>
+ </message>
+ <message>
+ <source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source>
+ <translation>Esta é uma versão de testes pré-lançamento - use à sua responsabilidade - não usar para minar ou aplicações comerciais</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer. Bitcoin Core is probably already running.</source>
+ <translation>Incapaz de vincular à porta %s neste computador. O Bitcoin Core provavelmente já está a correr.</translation>
+ </message>
+ <message>
+ <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>Atenção: -paytxfee está definida com um valor muito alto! Esta é a taxa que irá pagar se enviar uma transação.</translation>
+ </message>
+ <message>
+ <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source>
+ <translation>Aviso: A rede não parece estar completamente de acordo! Parece que alguns mineiros estão com dificuldades técnicas.</translation>
+ </message>
+ <message>
+ <source>Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.</source>
+ <translation>Atenção: Parecemos não estar de acordo com os nossos pares! Poderá ter que atualizar o seu cliente, ou outros nós poderão ter que atualizar os seus clientes.</translation>
+ </message>
+ <message>
+ <source>Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
+ <translation>Atenção: erro ao ler wallet.dat! Todas as chaves foram lidas correctamente, mas dados de transação ou do livro de endereços podem estar em falta ou incorrectos.</translation>
+ </message>
+ <message>
+ <source>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</source>
+ <translation>Atenção: wallet.dat corrompido, dados recuperados! wallet.dat original salvo como wallet.{timestamp}.bak em %s; se o seu saldo ou transações estiverem incorrectos deverá recuperar uma cópia de segurança.</translation>
+ </message>
+ <message>
+ <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source>
+ <translation>Ligações na lista branca conectam desde a seguinte netmask ou endereço IP. Posse ser especificado varias vezes.</translation>
+ </message>
+ <message>
+ <source>(default: 1)</source>
+ <translation>(padrão: 1)</translation>
+ </message>
+ <message>
+ <source>&lt;category&gt; can be:</source>
+ <translation>&lt;categoria&gt; pode ser:</translation>
+ </message>
+ <message>
+ <source>Attempt to recover private keys from a corrupt wallet.dat</source>
+ <translation>Tentar recuperar chaves privadas de um wallet.dat corrupto</translation>
+ </message>
+ <message>
+ <source>Block creation options:</source>
+ <translation>Opções de criação de bloco:</translation>
+ </message>
+ <message>
+ <source>Connect only to the specified node(s)</source>
+ <translation>Apenas ligar ao(s) nó(s) especificado(s)</translation>
+ </message>
+ <message>
+ <source>Connection options:</source>
+ <translation>Opcões de conexção:</translation>
+ </message>
+ <message>
+ <source>Corrupted block database detected</source>
+ <translation>Cadeia de blocos corrompida detectada</translation>
+ </message>
+ <message>
+ <source>Debugging/Testing options:</source>
+ <translation>Depuração/Opções teste:</translation>
+ </message>
+ <message>
+ <source>Do not load the wallet and disable wallet RPC calls</source>
+ <translation>Não carregar a carteira e desativar chamadas RPC de carteira.</translation>
+ </message>
+ <message>
+ <source>Do you want to rebuild the block database now?</source>
+ <translation>Deseja reconstruir agora a base de dados de blocos.</translation>
+ </message>
+ <message>
+ <source>Error initializing block database</source>
+ <translation>Erro ao inicializar a cadeia de blocos</translation>
+ </message>
+ <message>
+ <source>Error initializing wallet database environment %s!</source>
+ <translation>Erro ao inicializar o ambiente %s da base de dados da carteira</translation>
+ </message>
+ <message>
+ <source>Error loading block database</source>
+ <translation>Erro ao carregar base de dados de blocos</translation>
+ </message>
+ <message>
+ <source>Error opening block database</source>
+ <translation>Erro ao abrir a base de dados de blocos</translation>
+ </message>
+ <message>
+ <source>Error: Disk space is low!</source>
+ <translation>Erro: Pouco espaço em disco!</translation>
+ </message>
+ <message>
+ <source>Failed to listen on any port. Use -listen=0 if you want this.</source>
+ <translation>Falhou a escutar em qualquer porta. Use -listen=0 se quiser isto.</translation>
+ </message>
+ <message>
+ <source>If &lt;category&gt; is not supplied, output all debugging information.</source>
+ <translation>Se uma &lt;categoria&gt; não é fornecida, imprimir toda a informação de depuração.</translation>
+ </message>
+ <message>
+ <source>Importing...</source>
+ <translation>A importar...</translation>
+ </message>
+ <message>
+ <source>Incorrect or no genesis block found. Wrong datadir for network?</source>
+ <translation>Bloco génese incorreto ou nenhum bloco génese encontrado. Pasta de dados errada para a rede?</translation>
+ </message>
+ <message>
+ <source>Invalid -onion address: '%s'</source>
+ <translation>Endereço -onion inválido: '%s'</translation>
+ </message>
+ <message>
+ <source>Not enough file descriptors available.</source>
+ <translation>Os descritores de ficheiros disponíveis são insuficientes.</translation>
+ </message>
+ <message>
+ <source>Only connect to nodes in network &lt;net&gt; (ipv4, ipv6 or onion)</source>
+ <translation>Somente conectar aos nodes na rede &lt;net&gt; (ipv4, ipv6 ou onion)</translation>
+ </message>
+ <message>
+ <source>Set database cache size in megabytes (%d to %d, default: %d)</source>
+ <translation>Definir o tamanho da cache de base de dados em megabytes (%d a %d, padrão: %d)</translation>
+ </message>
+ <message>
+ <source>Set maximum block size in bytes (default: %d)</source>
+ <translation>Definir tamanho máximo por bloco em bytes (por defeito: %d)</translation>
+ </message>
+ <message>
+ <source>Specify wallet file (within data directory)</source>
+ <translation>Especifique ficheiro de carteira (dentro da pasta de dados)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: %u)</source>
+ <translation>Use UPnP para mapear a porto de escuta (default: %u)</translation>
+ </message>
+ <message>
+ <source>Verifying blocks...</source>
+ <translation>A verificar blocos...</translation>
+ </message>
+ <message>
+ <source>Verifying wallet...</source>
+ <translation>A verificar carteira...</translation>
+ </message>
+ <message>
+ <source>Wallet %s resides outside data directory %s</source>
+ <translation>A carteira %s reside fora da pasta de dados %s</translation>
+ </message>
+ <message>
+ <source>Wallet options:</source>
+ <translation>Opções da carteira:</translation>
+ </message>
+ <message>
+ <source>Warning: This version is obsolete; upgrade required!</source>
+ <translation>Aviso: Esta versão está desatualizada; atualização necessária!</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to change -txindex</source>
+ <translation>É necessário reconstruir as bases de dados usando -reindex para mudar o -txindex</translation>
+ </message>
+ <message>
+ <source>Imports blocks from external blk000??.dat file</source>
+ <translation>Importar blocos de um ficheiro blk000??.dat externo</translation>
+ </message>
+ <message>
+ <source>Allow JSON-RPC connections from specified source. Valid for &lt;ip&gt; are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times</source>
+ <translation>Permitir conexções JSON-RPC de fontes especificas. Valido para &lt;ip&gt; um unico IP (ex. 1.2.3.4), uma rede/netmask (ex. 1.2.3.4/255.255.255.0) ou uma rede/CIDR (ex. 1.2.3.4/24). Esta opção pode ser especificada varias vezes</translation>
+ </message>
+ <message>
+ <source>An error occurred while setting up the RPC address %s port %u for listening: %s</source>
+ <translation>Um erro ocorreu durante a definição do endereço RPC %s porto %u para escutar: %s</translation>
+ </message>
+ <message>
+ <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source>
+ <translation>Vincualar o endereço dado e listar as ligações conectadas ao mesmo na lista branca. Use a notação [anfitrião]:porta para IPv6</translation>
+ </message>
+ <message>
+ <source>Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)</source>
+ <translation>Vinculado para dar o endereço para atender as ligações JSON-RPC. Use [host]: Notação de porta para IPv6. Esta opção pode ser especificada várias vezes (padrão: ligam-se a todas as interfaces)</translation>
+ </message>
+ <message>
+ <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source>
+ <translation>Impossível trancar a pasta de dados %s. Provavelmente o Bitcoin Core já está a ser executado.</translation>
+ </message>
+ <message>
+ <source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source>
+ <translation>Executar comando quando um alerta relevante for recebido ou em caso de uma divisão longa da cadeia de blocos (no comando, %s é substituído pela mensagem)</translation>
+ </message>
+ <message>
+ <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
+ <translation>Definir tamanho máximo de transações com alta-prioridade/baixa-taxa em bytes (por defeito: %d)</translation>
+ </message>
+ <message>
+ <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source>
+ <translation>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 Core não irá funcionar correctamente.</translation>
+ </message>
+ <message>
+ <source>(default: %u)</source>
+ <translation>(por defeito: %u)</translation>
+ </message>
+ <message>
+ <source>Choose data directory on startup (default: 0)</source>
+ <translation>Escolha a pasta de dados ao iniciar (por defeito: 0)</translation>
+ </message>
+ <message>
+ <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source>
+ <translation>Copyright (C) 2009-%i Os Programadores do Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source>
+ <translation>Erro ao carregar wallet.dat: A Carteira requer uma versão mais recente do Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Informação</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -minrelaytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Quantia inválida para -minrelaytxfee=&lt;quantidade&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -mintxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Quantia inválida para -mintxfee=&lt;quantidade&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>Enviar informação de rastreio/depuração para a consola e não para o ficheiro debug.log</translation>
+ </message>
+ <message>
+ <source>Set SSL root certificates for payment request (default: -system-)</source>
+ <translation>Configurar certificados SSL root para pedido de pagamento (default: -system-)</translation>
+ </message>
+ <message>
+ <source>Set language, for example "de_DE" (default: system locale)</source>
+ <translation>Definir linguagem, por exemplo "pt_PT" (por defeito: linguagem do sistema)</translation>
+ </message>
+ <message>
+ <source>Show splash screen on startup (default: 1)</source>
+ <translation>Mostrar imagem ao iniciar (por defeito: 1)</translation>
+ </message>
+ <message>
+ <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source>
+ <translation>Encolher ficheiro debug.log ao iniciar o cliente (por defeito: 1 sem -debug definido)</translation>
+ </message>
+ <message>
+ <source>Signing transaction failed</source>
+ <translation>Falhou assinatura da transação</translation>
+ </message>
+ <message>
+ <source>Start minimized</source>
+ <translation>Iniciar minimizado</translation>
+ </message>
+ <message>
+ <source>Transaction amount too small</source>
+ <translation>Quantia da transação é muito baixa</translation>
+ </message>
+ <message>
+ <source>Transaction amounts must be positive</source>
+ <translation>Quantia da transação deverá ser positiva</translation>
+ </message>
+ <message>
+ <source>Transaction too large</source>
+ <translation>Transação grande demais</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: 1 when listening)</source>
+ <translation>Usar UPnP para mapear a porta de escuta (padrão: 1 ao escutar)</translation>
+ </message>
+ <message>
+ <source>Username for JSON-RPC connections</source>
+ <translation>Nome de utilizador para ligações JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Wallet needed to be rewritten: restart Bitcoin Core to complete</source>
+ <translation>A Carteira precisou de ser reescrita: reinicie o Bitcoin Core para completar o processo</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Aviso</translation>
+ </message>
+ <message>
+ <source>Zapping all transactions from wallet...</source>
+ <translation>A limpar todas as transações da carteira...</translation>
+ </message>
+ <message>
+ <source>wallet.dat corrupt, salvage failed</source>
+ <translation>wallet.dat corrompido, recuperação falhou</translation>
+ </message>
+ <message>
+ <source>Password for JSON-RPC connections</source>
+ <translation>Palavra-passe para ligações JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
+ <translation>Executar comando quando o melhor bloco mudar (no comando, %s é substituído pela hash do bloco)</translation>
+ </message>
+ <message>
+ <source>Upgrade wallet to latest format</source>
+ <translation>Atualize a carteira para o formato mais recente</translation>
+ </message>
+ <message>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>Procurar transações em falta na cadeia de blocos</translation>
+ </message>
+ <message>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>Usar OpenSSL (https) para ligações JSON-RPC</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>Esta mensagem de ajuda</translation>
+ </message>
+ <message>
+ <source>Allow DNS lookups for -addnode, -seednode and -connect</source>
+ <translation>Permitir procuras DNS para -addnode, -seednode e -connect</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>A carregar endereços...</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>Erro ao carregar wallet.dat: Carteira danificada</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>Erro ao carregar wallet.dat</translation>
+ </message>
+ <message>
+ <source>Invalid -proxy address: '%s'</source>
+ <translation>Endereço -proxy inválido: '%s'</translation>
+ </message>
+ <message>
+ <source>Listen for JSON-RPC connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>Escutar por ligações JSON-RPC na porta &lt;port&gt; (por defeito: %u ou rede de testes: %u)</translation>
+ </message>
+ <message>
+ <source>Listen for connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>Escute ligações na porta &lt;port&gt; (por defeito: %u ou testnet: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain at most &lt;n&gt; connections to peers (default: %u)</source>
+ <translation>Manter no máximo &lt;n&gt; ligações a outros nós da rede (por defeito: %u)</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection receive buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>Maximo armazenamento intermédio de recepção por ligação, &lt;n&gt;*1000 bytes (por defeito: %u)</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection send buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>Maximo armazenamento intermédio de envio por ligação, &lt;n&gt;*1000 bytes (por defeito: %u)</translation>
+ </message>
+ <message>
+ <source>Prepend debug output with timestamp (default: %u)</source>
+ <translation>Adicionar data e hora à informação de depuração (por defeito: %u)</translation>
+ </message>
+ <message>
+ <source>Server certificate file (default: %s)</source>
+ <translation>Ficheiro de certificado do servidor (por defeito: %s)</translation>
+ </message>
+ <message>
+ <source>Server private key (default: %s)</source>
+ <translation>Chave privada do servidor (por defeito: %s)</translation>
+ </message>
+ <message>
+ <source>Set key pool size to &lt;n&gt; (default: %u)</source>
+ <translation>Definir o tamanho da memória de chaves para &lt;n&gt; (por defeito: %u)</translation>
+ </message>
+ <message>
+ <source>Set minimum block size in bytes (default: %u)</source>
+ <translation>Definir tamanho minímo de um bloco em bytes (por defeito: %u)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads to service RPC calls (default: %d)</source>
+ <translation>Defina o número de processos para servir as chamadas RPC (por defeito: %d)</translation>
+ </message>
+ <message>
+ <source>Specify configuration file (default: %s)</source>
+ <translation>Especificar ficheiro de configuração (por defeito: %s)</translation>
+ </message>
+ <message>
+ <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source>
+ <translation>Especificar tempo de espera da ligação em milissegundos (mínimo 1, por defeito: %d)</translation>
+ </message>
+ <message>
+ <source>Unknown network specified in -onlynet: '%s'</source>
+ <translation>Rede desconhecida especificada em -onlynet: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -bind address: '%s'</source>
+ <translation>Não foi possível resolver o endereço -bind: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -externalip address: '%s'</source>
+ <translation>Não foi possível resolver o endereço -externalip: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Quantia inválida para -paytxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>Fundos insuficientes</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>A carregar índice de blocos...</translation>
+ </message>
+ <message>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>Adicionar um nó para se ligar e tentar manter a ligação aberta</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>A carregar carteira...</translation>
+ </message>
+ <message>
+ <source>Cannot downgrade wallet</source>
+ <translation>Impossível mudar a carteira para uma versão anterior</translation>
+ </message>
+ <message>
+ <source>Cannot write default address</source>
+ <translation>Impossível escrever endereço por defeito</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>Reexaminando...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>Carregamento completo</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Erro</translation>
+ </message>
+</context>
+</TS> \ 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 0000000000..76fd8e5ebd
--- /dev/null
+++ b/src/qt/locale/bitcoin_ro_RO.ts
@@ -0,0 +1,3204 @@
+<TS language="ro_RO" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Right-click to edit address or label</source>
+ <translation>Click-dreapta pentru a edita adresa sau eticheta</translation>
+ </message>
+ <message>
+ <source>Create a new address</source>
+ <translation>Creează o adresă nouă</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>&amp;Nou</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Copiază adresa selectată în clipboard</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>&amp;Copiază</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>Închide</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>&amp;Copiază adresa</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>Şterge adresele curent selectate din listă</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Exportă datele din tab-ul curent într-un fişier</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Exportă</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>Şterge</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>Alegeţi adresa unde vreţi să trimiteţi monezile</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>Alegeţi adresa unde vreţi să primiţi monezile</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>&amp;Alegeţi</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>Adresa destinatarului</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>Adresa de primire</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>Acestea sînt adresele dumneavoastră Bitcoin pentru efectuarea plăţilor. Verificaţi întotdeauna cantitatea şi adresa de primire înainte de a trimite monezi.</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>Acestea sînt adresele dumneavoastră Bitcoin folosite pentru a primi plati. Este recomandat să folosiţi o adresă nouă de primire pentru fiecare tranzacţie în parte.</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>Copiază &amp;eticheta</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>&amp;Editare</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>Exportă listă de adrese</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Fişier text cu valori separate prin virgulă (*.csv)</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Export nereuşit</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the address list to %1. Please try again.</source>
+ <translation>A apărut o eroare la salvarea listei de adrese la %1. Vă rugăm să încercaţi din nou.</translation>
+ </message>
+</context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Etichetă</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adresă</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(fără etichetă)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Passphrase Dialog</source>
+ <translation>Dialogul pentru fraza de acces</translation>
+ </message>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Introduceţi fraza de acces</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Frază de acces nouă</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Repetaţi noua frază de acces</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>Criptare portofel</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>Această acţiune necesită fraza dvs. de acces pentru deblocarea portofelului.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Deblocare portofel</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>Această acţiune necesită fraza dvs. de acces pentru decriptarea portofelului.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>Decriptare portofel</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>Schimbare frază de acces</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>Confirmaţi criptarea portofelului</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>Atenţie: Dacă pierdeţi parola portofelului electronic după criptare, &lt;b&gt;VEŢI PIERDE ÎNTREAGA SUMĂ DE BITCOIN ACUMULATĂ&lt;/b&gt;!</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>Sigur doriţi să criptaţi portofelul dvs.?</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core 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.</source>
+ <translation>Bitcoin se va închide acum pentru a termina procesul de criptare. Ţineţi minte că criptarea portofelului nu vă poate proteja în totalitate de furtul monedelor de către programe dăunătoare care vă infectează calculatorul.</translation>
+ </message>
+ <message>
+ <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
+ <translation>IMPORTANT: Orice copie de siguranţă făcută anterior portofelului dumneavoastră ar trebui înlocuită cu cea generată cel mai recent, fişier criptat al portofelului. Pentru siguranţă, copiile de siguranţă vechi ale portofelului ne-criptat vor deveni inutile imediat ce veţi începe folosirea noului fişier criptat al portofelului.</translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>Atenţie! Caps Lock este pornit!</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>Portofel criptat</translation>
+ </message>
+ <message>
+ <source>Enter the new passphrase to the wallet.&lt;br/&gt;Please use a passphrase of &lt;b&gt;ten or more random characters&lt;/b&gt;, or &lt;b&gt;eight or more words&lt;/b&gt;.</source>
+ <translation>Introduceţi noua parolă a portofelului electronic.&lt;br/&gt;Vă rugăm să folosiţi o parolă de&lt;b&gt;minimum 10 caractere aleatoare&lt;/b&gt;, sau &lt;b&gt;minimum 8 cuvinte&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>Enter the old passphrase and new passphrase to the wallet.</source>
+ <translation>Introduceţi vechea şi noua parolă pentru portofel.</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>Criptarea portofelului nu a reuşit</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>Criptarea portofelului nu a reuşit din cauza unei erori interne. Portofelul dvs. nu a fost criptat.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>Frazele de acces introduse nu se potrivesc.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>Deblocarea portofelului nu a reuşit</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>Fraza de acces introdusă pentru decriptarea portofelului a fost incorectă.</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>Decriptarea portofelului nu a reuşit</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>Parola portofelului electronic a fost schimbată.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>Semnează &amp;mesaj...</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>Se sincronizează cu reţeaua...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;Imagine de ansamblu</translation>
+ </message>
+ <message>
+ <source>Node</source>
+ <translation>Nod</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>Arată o stare generală de ansamblu a portofelului</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Tranzacţii</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>Răsfoire istoric tranzacţii</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>Ieşire</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>Închide aplicaţia</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>Despre &amp;Qt</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>Arată informaţii despre Qt</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;Opţiuni...</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>Cript&amp;ează portofelul...</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>Face o copie de siguranţă a portofelului...</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>S&amp;chimbă parola...</translation>
+ </message>
+ <message>
+ <source>&amp;Sending addresses...</source>
+ <translation>Adrese de trimitere...</translation>
+ </message>
+ <message>
+ <source>&amp;Receiving addresses...</source>
+ <translation>Adrese de p&amp;rimire...</translation>
+ </message>
+ <message>
+ <source>Open &amp;URI...</source>
+ <translation>Deschide &amp;URI...</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core client</source>
+ <translation>Clientul Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Importing blocks from disk...</source>
+ <translation>Import blocuri de pe disk...</translation>
+ </message>
+ <message>
+ <source>Reindexing blocks on disk...</source>
+ <translation>Se reindexează blocurile pe disc...</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>Trimite monede către o adresă Bitcoin</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>Creează o copie de rezervă a portofelului într-o locaţie diferită</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Schimbă fraza de acces folosită pentru criptarea portofelului</translation>
+ </message>
+ <message>
+ <source>&amp;Debug window</source>
+ <translation>Fereastra de &amp;depanare</translation>
+ </message>
+ <message>
+ <source>Open debugging and diagnostic console</source>
+ <translation>Deschide consola de depanare şi diagnosticare</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>&amp;Verifică mesaj...</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>Portofel</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>Trimite</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>P&amp;rimeşte</translation>
+ </message>
+ <message>
+ <source>Show information about Bitcoin Core</source>
+ <translation>Arată informaţii despre Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>Arată/Ascunde</translation>
+ </message>
+ <message>
+ <source>Show or hide the main Window</source>
+ <translation>Arată sau ascunde fereastra principală</translation>
+ </message>
+ <message>
+ <source>Encrypt the private keys that belong to your wallet</source>
+ <translation>Criptează cheile private ale portofelului dvs.</translation>
+ </message>
+ <message>
+ <source>Sign messages with your Bitcoin addresses to prove you own them</source>
+ <translation>Semnaţi mesaje cu adresa dvs. Bitcoin pentru a dovedi că vă aparţin</translation>
+ </message>
+ <message>
+ <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source>
+ <translation>Verificaţi mesaje pentru a vă asigura că au fost semnate cu adresa Bitcoin specificată</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;Fişier</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;Setări</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>A&amp;jutor</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>Bara de unelte</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Nucleul Bitcoin</translation>
+ </message>
+ <message>
+ <source>Request payments (generates QR codes and bitcoin: URIs)</source>
+ <translation>Cereţi plăţi (generează coduri QR şi bitcoin-uri: URls)</translation>
+ </message>
+ <message>
+ <source>&amp;About Bitcoin Core</source>
+ <translation>&amp;Despre Nucleul Bitcoin</translation>
+ </message>
+ <message>
+ <source>Modify configuration options for Bitcoin Core</source>
+ <translation>Modifică opţiunile de configurare pentru Bitcoin</translation>
+ </message>
+ <message>
+ <source>Show the list of used sending addresses and labels</source>
+ <translation>Arată lista de adrese trimise şi etichetele folosite.</translation>
+ </message>
+ <message>
+ <source>Show the list of used receiving addresses and labels</source>
+ <translation>Arată lista de adrese pentru primire şi etichetele</translation>
+ </message>
+ <message>
+ <source>Open a bitcoin: URI or payment request</source>
+ <translation>Deschidere bitcoin: o adresa URI sau o cerere de plată</translation>
+ </message>
+ <message>
+ <source>&amp;Command-line options</source>
+ <translation>Opţiuni linie de &amp;comandă</translation>
+ </message>
+ <message>
+ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
+ <translation>Arată mesajul de ajutor Bitcoin Core pentru a obţine o listă cu opţiunile posibile de linii de comandă Bitcoin</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n active connection(s) to Bitcoin network</source>
+ <translation><numerusform>%n conexiune activă către reţeaua Bitcoin</numerusform><numerusform>%n conexiuni active către reţeaua Bitcoin</numerusform><numerusform>%n de conexiuni active către reţeaua Bitcoin</numerusform></translation>
+ </message>
+ <message>
+ <source>No block source available...</source>
+ <translation>Nici o sursă de bloc disponibilă...</translation>
+ </message>
+ <message numerus="yes">
+ <source>Processed %n block(s) of transaction history.</source>
+ <translation><numerusform>S-a procesat %n bloc din istoricul tranzacţiilor.</numerusform><numerusform>S-au procesat %n blocuri din istoricul tranzacţiilor.</numerusform><numerusform>S-au procesat %n de blocuri din istoricul tranzacţiilor.</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n hour(s)</source>
+ <translation><numerusform>%n oră</numerusform><numerusform>%n ore</numerusform><numerusform>%n ore</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n day(s)</source>
+ <translation><numerusform>%n zi</numerusform><numerusform>%n zile</numerusform><numerusform>%n de zile</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n week(s)</source>
+ <translation><numerusform>%n săptămână</numerusform><numerusform>%n săptămâni</numerusform><numerusform>%n de săptămâni</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 and %2</source>
+ <translation>%1 şi %2</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n year(s)</source>
+ <translation><numerusform>%n an</numerusform><numerusform>%n ani</numerusform><numerusform>%n de ani</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 behind</source>
+ <translation>%1 în urmă</translation>
+ </message>
+ <message>
+ <source>Last received block was generated %1 ago.</source>
+ <translation>Ultimul bloc recepţionat a fost generat acum %1.</translation>
+ </message>
+ <message>
+ <source>Transactions after this will not yet be visible.</source>
+ <translation>Tranzacţiile după aceasta nu vor fi vizibile încă.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Eroare</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Avertisment</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Informaţie</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>Actualizat</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>Se actualizează...</translation>
+ </message>
+ <message>
+ <source>Date: %1
+</source>
+ <translation>Data: %1
+</translation>
+ </message>
+ <message>
+ <source>Amount: %1
+</source>
+ <translation>Sumă: %1
+</translation>
+ </message>
+ <message>
+ <source>Type: %1
+</source>
+ <translation>Tip: %1
+</translation>
+ </message>
+ <message>
+ <source>Label: %1
+</source>
+ <translation>Etichetă: %1
+</translation>
+ </message>
+ <message>
+ <source>Address: %1
+</source>
+ <translation>Adresă: %1
+</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>Tranzacţie expediată</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>Tranzacţie recepţionată</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>Portofelul este &lt;b&gt;criptat&lt;/b&gt; iar în momentul de faţă este &lt;b&gt;deblocat&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>Portofelul este &lt;b&gt;criptat&lt;/b&gt; iar în momentul de faţă este &lt;b&gt;blocat&lt;/b&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <source>Network Alert</source>
+ <translation>Alertă reţea</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Coin Selection</source>
+ <translation>Selectarea monezii</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Cantitate:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Octeţi:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Sumă:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Prioritate:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Taxă:</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Praf:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>După taxă:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Schimb:</translation>
+ </message>
+ <message>
+ <source>(un)select all</source>
+ <translation>(de)selectare tot</translation>
+ </message>
+ <message>
+ <source>Tree mode</source>
+ <translation>Mod arbore</translation>
+ </message>
+ <message>
+ <source>List mode</source>
+ <translation>Mod listă</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Sumă</translation>
+ </message>
+ <message>
+ <source>Received with label</source>
+ <translation>Primite cu eticheta</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>Primite cu adresa</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Confirmations</source>
+ <translation>Confirmări</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Confirmat</translation>
+ </message>
+ <message>
+ <source>Priority</source>
+ <translation>Prioritate</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Copiază adresa</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Copiază eticheta</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copiază suma</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Copiază ID tranzacţie</translation>
+ </message>
+ <message>
+ <source>Lock unspent</source>
+ <translation>Blocare necheltuiţi</translation>
+ </message>
+ <message>
+ <source>Unlock unspent</source>
+ <translation>Deblocare necheltuiţi</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Copiază cantitea</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Copiază taxa</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Copiază după taxă</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Copiază octeţi</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Copiază prioritatea</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Copiază praf</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Copiază rest</translation>
+ </message>
+ <message>
+ <source>highest</source>
+ <translation>cea mai mare</translation>
+ </message>
+ <message>
+ <source>higher</source>
+ <translation>mai mare</translation>
+ </message>
+ <message>
+ <source>high</source>
+ <translation>mare</translation>
+ </message>
+ <message>
+ <source>medium-high</source>
+ <translation>medie-mare</translation>
+ </message>
+ <message>
+ <source>medium</source>
+ <translation>medie</translation>
+ </message>
+ <message>
+ <source>low-medium</source>
+ <translation>medie-scăzută</translation>
+ </message>
+ <message>
+ <source>low</source>
+ <translation>scazută</translation>
+ </message>
+ <message>
+ <source>lower</source>
+ <translation>mai scăzută</translation>
+ </message>
+ <message>
+ <source>lowest</source>
+ <translation>cea mai scăzută</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>nimic</translation>
+ </message>
+ <message>
+ <source>This label turns red if the transaction size is greater than 1000 bytes.</source>
+ <translation>Această etichetă devine roşie în cazul în care dimensiunea tranzacţiei este mai mare de 1000 de octeţi.</translation>
+ </message>
+ <message>
+ <source>This label turns red if the priority is smaller than "medium".</source>
+ <translation>Această etichetă devine roşie dacă prioritatea e mai mică decît "medie".</translation>
+ </message>
+ <message>
+ <source>This label turns red if any recipient receives an amount smaller than %1.</source>
+ <translation>Această etichetă devine roşie, dacă orice beneficiar primeşte o sumă mai mică decât %1.</translation>
+ </message>
+ <message>
+ <source>Can vary +/- %1 satoshi(s) per input.</source>
+ <translation>Poate varia +/- %1 satoshi pentru fiecare intrare.</translation>
+ </message>
+ <message>
+ <source>yes</source>
+ <translation>da</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>nu</translation>
+ </message>
+ <message>
+ <source>Can vary +/- 1 byte per input.</source>
+ <translation>Poate varia +/- 1 octet pentru fiecare intrare.</translation>
+ </message>
+ <message>
+ <source>Transactions with higher priority are more likely to get included into a block.</source>
+ <translation>Tranzacţiile cu prioritate mai mare sînt mai susceptibile de fi incluse într-un bloc.</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(fără etichetă)</translation>
+ </message>
+ <message>
+ <source>change from %1 (%2)</source>
+ <translation>restul de la %1 (%2)</translation>
+ </message>
+ <message>
+ <source>(change)</source>
+ <translation>(rest)</translation>
+ </message>
+</context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>Editează adresa</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>&amp;Etichetă</translation>
+ </message>
+ <message>
+ <source>The label associated with this address list entry</source>
+ <translation>Eticheta asociată cu această intrare din listă.</translation>
+ </message>
+ <message>
+ <source>The address associated with this address list entry. This can only be modified for sending addresses.</source>
+ <translation>Adresa asociată cu această adresă din listă. Aceasta poate fi modificată doar pentru adresele de trimitere.</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;Adresă</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>Noua adresă de primire</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>Noua adresă de trimitere</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>Editează adresa de primire</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>Editează adresa de trimitere</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>Adresa introdusă "%1" se află deja în lista de adrese.</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is not a valid Bitcoin address.</source>
+ <translation>Adresa introdusă "%1" nu este o adresă bitcoin validă.</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>Portofelul nu a putut fi deblocat.</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>Generarea noii chei nu a reuşit.</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ <message>
+ <source>A new data directory will be created.</source>
+ <translation>Va fi creat un nou dosar de date.</translation>
+ </message>
+ <message>
+ <source>name</source>
+ <translation>nume</translation>
+ </message>
+ <message>
+ <source>Directory already exists. Add %1 if you intend to create a new directory here.</source>
+ <translation>Dosarul deja există. Adaugă %1 dacă intenţionaţi să creaţi un nou dosar aici.</translation>
+ </message>
+ <message>
+ <source>Path already exists, and is not a directory.</source>
+ <translation>Calea deja există şi nu este un dosar.</translation>
+ </message>
+ <message>
+ <source>Cannot create data directory here.</source>
+ <translation>Nu se poate crea un dosar de date aici.</translation>
+ </message>
+</context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Nucleul Bitcoin</translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>versiunea</translation>
+ </message>
+ <message>
+ <source>(%1-bit)</source>
+ <translation>(%1-bit)</translation>
+ </message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>Despre Nucleul Bitcoin</translation>
+ </message>
+ <message>
+ <source>Command-line options</source>
+ <translation>Opţiuni linie de comandă</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>Uz:</translation>
+ </message>
+ <message>
+ <source>command-line options</source>
+ <translation>Opţiuni linie de comandă</translation>
+ </message>
+</context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Welcome</source>
+ <translation>Bun venit</translation>
+ </message>
+ <message>
+ <source>Welcome to Bitcoin Core.</source>
+ <translation>Bine aţi venit la Nucleul Bitcoin.</translation>
+ </message>
+ <message>
+ <source>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</source>
+ <translation>Dacă aceasta este prima dată cînd programul este lansat, puteţi alege unde Nucleul Bitcoin va stoca datele.</translation>
+ </message>
+ <message>
+ <source>Use the default data directory</source>
+ <translation>Foloseşte dosarul de date implicit</translation>
+ </message>
+ <message>
+ <source>Use a custom data directory:</source>
+ <translation>Foloseşte un dosar de date personalizat:</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Nucleul Bitcoin</translation>
+ </message>
+ <message>
+ <source>Error: Specified data directory "%1" cannot be created.</source>
+ <translation>Eroare: Directorul datelor specificate "%1" nu poate fi creat.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Eroare</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n GB of free space available</source>
+ <translation><numerusform>%n GB de spaţiu liber disponibil</numerusform><numerusform>%n GB de spaţiu liber disponibil</numerusform><numerusform>%n GB de spaţiu liber disponibil</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>(of %n GB needed)</source>
+ <translation><numerusform>(din %n GB necesar)</numerusform><numerusform>(din %n GB necesari)</numerusform><numerusform>(din %n GB necesari)</numerusform></translation>
+ </message>
+</context>
+<context>
+ <name>OpenURIDialog</name>
+ <message>
+ <source>Open URI</source>
+ <translation>Deschide URI</translation>
+ </message>
+ <message>
+ <source>Open payment request from URI or file</source>
+ <translation>Deschideţi cerere de plată prin intermediul adresei URI sau a fişierului</translation>
+ </message>
+ <message>
+ <source>URI:</source>
+ <translation>URI:</translation>
+ </message>
+ <message>
+ <source>Select payment request file</source>
+ <translation>Selectaţi fişierul cerere de plată</translation>
+ </message>
+ <message>
+ <source>Select payment request file to open</source>
+ <translation>Selectaţi fişierul cerere de plată pentru deschidere</translation>
+ </message>
+</context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>Opţiuni</translation>
+ </message>
+ <message>
+ <source>&amp;Main</source>
+ <translation>Principal</translation>
+ </message>
+ <message>
+ <source>Size of &amp;database cache</source>
+ <translation>Mărimea bazei de &amp;date cache</translation>
+ </message>
+ <message>
+ <source>MB</source>
+ <translation>MB</translation>
+ </message>
+ <message>
+ <source>Number of script &amp;verification threads</source>
+ <translation>Numărul de thread-uri de &amp;verificare</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside</source>
+ <translation>Acceptă conexiuni din exterior</translation>
+ </message>
+ <message>
+ <source>Allow incoming connections</source>
+ <translation>Permite conexiuni de intrare</translation>
+ </message>
+ <message>
+ <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
+ <translation>Adresa IP a serverului proxy (de exemplu: IPv4: 127.0.0.1 / IPv6: ::1)</translation>
+ </message>
+ <message>
+ <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source>
+ <translation>Minimizează 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 'Închide aplicaţia' din menu.</translation>
+ </message>
+ <message>
+ <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source>
+ <translation>Limba interfeţei utilizatorului poate fi setată aici. Această setare va avea efect după repornirea Nucleului Bitcoin.</translation>
+ </message>
+ <message>
+ <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source>
+ <translation>URL-uri terţe părţi (de exemplu, un explorator de bloc), care apar în tab-ul tranzacţiilor ca elemente de meniu contextual. %s în URL este înlocuit cu hash de tranzacţie. URL-urile multiple sînt separate prin bară verticală |.</translation>
+ </message>
+ <message>
+ <source>Third party transaction URLs</source>
+ <translation>URL-uri tranzacţii terţe părţi</translation>
+ </message>
+ <message>
+ <source>Active command-line options that override above options:</source>
+ <translation>Opţiuni linie de comandă active care oprimă opţiunile de mai sus:</translation>
+ </message>
+ <message>
+ <source>Reset all client options to default.</source>
+ <translation>Resetează toate setările clientului la valorile implicite.</translation>
+ </message>
+ <message>
+ <source>&amp;Reset Options</source>
+ <translation>&amp;Resetează opţiunile</translation>
+ </message>
+ <message>
+ <source>&amp;Network</source>
+ <translation>Reţea</translation>
+ </message>
+ <message>
+ <source>&amp;Start Bitcoin Core on system login</source>
+ <translation>Porneşte Nucleul Bitcoin la pornirea sistemului</translation>
+ </message>
+ <message>
+ <source>(0 = auto, &lt;0 = leave that many cores free)</source>
+ <translation>(0 = automat, &lt;0 = lasă atîtea nuclee libere)</translation>
+ </message>
+ <message>
+ <source>W&amp;allet</source>
+ <translation>Portofel</translation>
+ </message>
+ <message>
+ <source>Expert</source>
+ <translation>Expert</translation>
+ </message>
+ <message>
+ <source>Enable coin &amp;control features</source>
+ <translation>Activare caracteristici de control ale monedei</translation>
+ </message>
+ <message>
+ <source>If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.</source>
+ <translation>Dacă dezactivaţi cheltuirea restului neconfirmat, restul dintr-o tranzacţie nu poate fi folosit pînă cînd tranzacţia are cel puţin o confirmare. Aceasta afectează de asemenea calcularea soldului.</translation>
+ </message>
+ <message>
+ <source>&amp;Spend unconfirmed change</source>
+ <translation>Cheltuire rest neconfirmat</translation>
+ </message>
+ <message>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>Deschide automat în router portul aferent clientului Bitcoin. Funcţionează doar dacă routerul duportă UPnP şi e activat.</translation>
+ </message>
+ <message>
+ <source>Map port using &amp;UPnP</source>
+ <translation>Mapare port folosind &amp;UPnP</translation>
+ </message>
+ <message>
+ <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
+ <translation>Conectare la reţeaua Bitcoin printr-un proxy SOCKS.</translation>
+ </message>
+ <message>
+ <source>&amp;Connect through SOCKS5 proxy (default proxy):</source>
+ <translation>&amp;Conectare printr-un proxy SOCKS (implicit proxy):</translation>
+ </message>
+ <message>
+ <source>Proxy &amp;IP:</source>
+ <translation>Proxy &amp;IP:</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>&amp;Port:</translation>
+ </message>
+ <message>
+ <source>Port of the proxy (e.g. 9050)</source>
+ <translation>Portul proxy (de exemplu: 9050)</translation>
+ </message>
+ <message>
+ <source>&amp;Window</source>
+ <translation>&amp;Fereastră</translation>
+ </message>
+ <message>
+ <source>Show only a tray icon after minimizing the window.</source>
+ <translation>Arată doar un icon în tray la ascunderea ferestrei</translation>
+ </message>
+ <message>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>&amp;Minimizare în tray în loc de taskbar</translation>
+ </message>
+ <message>
+ <source>M&amp;inimize on close</source>
+ <translation>M&amp;inimizare fereastră în locul închiderii programului</translation>
+ </message>
+ <message>
+ <source>&amp;Display</source>
+ <translation>&amp;Afişare</translation>
+ </message>
+ <message>
+ <source>User Interface &amp;language:</source>
+ <translation>&amp;Limbă interfaţă utilizator</translation>
+ </message>
+ <message>
+ <source>&amp;Unit to show amounts in:</source>
+ <translation>&amp;Unitatea de măsură pentru afişarea sumelor:</translation>
+ </message>
+ <message>
+ <source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
+ <translation>Alegeţi subdiviziunea folosită la afişarea interfeţei şi la trimiterea de bitcoin.</translation>
+ </message>
+ <message>
+ <source>Whether to show coin control features or not.</source>
+ <translation>Arată controlul caracteristicilor monedei sau nu.</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>&amp;OK</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>Renunţă</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>iniţial</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>nimic</translation>
+ </message>
+ <message>
+ <source>Confirm options reset</source>
+ <translation>Confirmă resetarea opţiunilor</translation>
+ </message>
+ <message>
+ <source>Client restart required to activate changes.</source>
+ <translation>Este necesară repornirea clientului pentru a activa schimbările.</translation>
+ </message>
+ <message>
+ <source>Client will be shut down. Do you want to proceed?</source>
+ <translation>Clientul va fi închis. Doriţi să continuaţi?</translation>
+ </message>
+ <message>
+ <source>This change would require a client restart.</source>
+ <translation>Această schimbare necesită o repornire a clientului.</translation>
+ </message>
+ <message>
+ <source>The supplied proxy address is invalid.</source>
+ <translation>Adresa bitcoin pe care aţi specificat-o nu este validă.</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>Form</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>Informaţiile afişate pot fi neactualizate. Portofelul dvs. se sincronizează automat cu reţeaua Bitcoin după ce o conexiune este stabilită, dar acest proces nu a fost finalizat încă.</translation>
+ </message>
+ <message>
+ <source>Watch-only:</source>
+ <translation>Doar-supraveghere:</translation>
+ </message>
+ <message>
+ <source>Available:</source>
+ <translation>Disponibil:</translation>
+ </message>
+ <message>
+ <source>Your current spendable balance</source>
+ <translation>Balanţa dvs. curentă de cheltuieli</translation>
+ </message>
+ <message>
+ <source>Pending:</source>
+ <translation>În aşteptare:</translation>
+ </message>
+ <message>
+ <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source>
+ <translation>Totalul tranzacţiilor care nu sunt confirmate încă şi care nu sunt încă adunate la balanţa de cheltuieli</translation>
+ </message>
+ <message>
+ <source>Immature:</source>
+ <translation>Nematurizat:</translation>
+ </message>
+ <message>
+ <source>Mined balance that has not yet matured</source>
+ <translation>Balanţa minertită care nu s-a maturizat încă</translation>
+ </message>
+ <message>
+ <source>Balances</source>
+ <translation>Balanţă</translation>
+ </message>
+ <message>
+ <source>Total:</source>
+ <translation>Total:</translation>
+ </message>
+ <message>
+ <source>Your current total balance</source>
+ <translation>Balanţa totală curentă</translation>
+ </message>
+ <message>
+ <source>Your current balance in watch-only addresses</source>
+ <translation>Soldul dvs. curent în adresele doar-supraveghere</translation>
+ </message>
+ <message>
+ <source>Spendable:</source>
+ <translation>Cheltuibil:</translation>
+ </message>
+ <message>
+ <source>Recent transactions</source>
+ <translation>Tranzacţii recente</translation>
+ </message>
+ <message>
+ <source>Unconfirmed transactions to watch-only addresses</source>
+ <translation>Tranzacţii neconfirmate la adresele doar-supraveghere</translation>
+ </message>
+ <message>
+ <source>Mined balance in watch-only addresses that has not yet matured</source>
+ <translation>Balanţă minată în adresele doar-supraveghere care nu s-a maturizat încă</translation>
+ </message>
+ <message>
+ <source>Current total balance in watch-only addresses</source>
+ <translation>Soldul dvs. total în adresele doar-supraveghere</translation>
+ </message>
+</context>
+<context>
+ <name>PaymentServer</name>
+ <message>
+ <source>URI handling</source>
+ <translation>Gestionare URI</translation>
+ </message>
+ <message>
+ <source>Invalid payment address %1</source>
+ <translation>Adresă pentru plată nevalidă %1</translation>
+ </message>
+ <message>
+ <source>Payment request rejected</source>
+ <translation>Cerere de plată refuzată</translation>
+ </message>
+ <message>
+ <source>Payment request network doesn't match client network.</source>
+ <translation>Cererea de plată din reţea nu se potriveşte cu clientul din reţea</translation>
+ </message>
+ <message>
+ <source>Payment request is not initialized.</source>
+ <translation>Cererea de plată nu este iniţializată.</translation>
+ </message>
+ <message>
+ <source>Requested payment amount of %1 is too small (considered dust).</source>
+ <translation>Suma cerută de plată de %1 este prea mică (considerată praf).</translation>
+ </message>
+ <message>
+ <source>Payment request error</source>
+ <translation>Eroare la cererea de plată</translation>
+ </message>
+ <message>
+ <source>Cannot start bitcoin: click-to-pay handler</source>
+ <translation>Nu poate porni bitcoin: manipulator clic-pentru-plată</translation>
+ </message>
+ <message>
+ <source>Payment request fetch URL is invalid: %1</source>
+ <translation>URL-ul cererii de plată preluat nu este valid: %1</translation>
+ </message>
+ <message>
+ <source>URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source>
+ <translation>URI nu poate fi analizat! Acest lucru poate fi cauzat de o adresă Bitcoin nevalidă sau parametri URI deformaţi.</translation>
+ </message>
+ <message>
+ <source>Payment request file handling</source>
+ <translation>Manipulare fişier cerere de plată</translation>
+ </message>
+ <message>
+ <source>Payment request file cannot be read! This can be caused by an invalid payment request file.</source>
+ <translation>Fişierul cerere de plată nu poate fi citit! Cauza poate fi un fişier cerere de plată nevalid.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>Cererea de plată a expirat.</translation>
+ </message>
+ <message>
+ <source>Unverified payment requests to custom payment scripts are unsupported.</source>
+ <translation>Cererile de plată neverificate prin script-uri personalizate de plată nu sînt suportate.</translation>
+ </message>
+ <message>
+ <source>Invalid payment request.</source>
+ <translation>Cerere de plată nevalidă.</translation>
+ </message>
+ <message>
+ <source>Refund from %1</source>
+ <translation>Rambursare de la %1</translation>
+ </message>
+ <message>
+ <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source>
+ <translation>Cererea de plată %1 este prea mare (%2 octeţi, permis %3 octeţi).</translation>
+ </message>
+ <message>
+ <source>Payment request DoS protection</source>
+ <translation>Protecţie DoS cerere de plată</translation>
+ </message>
+ <message>
+ <source>Error communicating with %1: %2</source>
+ <translation>Eroare la comunicarea cu %1: %2</translation>
+ </message>
+ <message>
+ <source>Payment request cannot be parsed!</source>
+ <translation>Cererea de plată nu poate fi analizată!</translation>
+ </message>
+ <message>
+ <source>Bad response from server %1</source>
+ <translation>Răspuns greşit de la server %1</translation>
+ </message>
+ <message>
+ <source>Payment acknowledged</source>
+ <translation>Plată acceptată</translation>
+ </message>
+ <message>
+ <source>Network request error</source>
+ <translation>Eroare în cererea de reţea</translation>
+ </message>
+</context>
+<context>
+ <name>PeerTableModel</name>
+ <message>
+ <source>User Agent</source>
+ <translation>Agent utilizator</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Timp ping</translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>Cantitate</translation>
+ </message>
+ <message>
+ <source>Enter a Bitcoin address (e.g. %1)</source>
+ <translation>Introduceţi o adresă Bitcoin (de exemplu %1)</translation>
+ </message>
+ <message>
+ <source>%1 d</source>
+ <translation>%1 z</translation>
+ </message>
+ <message>
+ <source>%1 h</source>
+ <translation>%1 h</translation>
+ </message>
+ <message>
+ <source>%1 m</source>
+ <translation>%1 m</translation>
+ </message>
+ <message>
+ <source>%1 s</source>
+ <translation>%1 s</translation>
+ </message>
+ <message>
+ <source>None</source>
+ <translation>Niciuna</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>N/A</translation>
+ </message>
+ <message>
+ <source>%1 ms</source>
+ <translation>%1 ms</translation>
+ </message>
+</context>
+<context>
+ <name>QRImageWidget</name>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Salvează imagine...</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Image</source>
+ <translation>&amp;Copiază imaginea</translation>
+ </message>
+ <message>
+ <source>Save QR Code</source>
+ <translation>Salvează codul QR</translation>
+ </message>
+ <message>
+ <source>PNG Image (*.png)</source>
+ <translation>Imagine de tip PNG (*.png)</translation>
+ </message>
+</context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>Client name</source>
+ <translation>Nume client</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>indisponibil</translation>
+ </message>
+ <message>
+ <source>Client version</source>
+ <translation>Versiune client</translation>
+ </message>
+ <message>
+ <source>&amp;Information</source>
+ <translation>&amp;Informaţii</translation>
+ </message>
+ <message>
+ <source>Debug window</source>
+ <translation>Fereastra de depanare</translation>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>General</translation>
+ </message>
+ <message>
+ <source>Using OpenSSL version</source>
+ <translation>Foloseşte OpenSSL versiunea</translation>
+ </message>
+ <message>
+ <source>Using BerkeleyDB version</source>
+ <translation>Foloseşte BerkeleyDB versiunea</translation>
+ </message>
+ <message>
+ <source>Startup time</source>
+ <translation>Durata pornirii</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Reţea</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>Nume</translation>
+ </message>
+ <message>
+ <source>Number of connections</source>
+ <translation>Numărul de conexiuni</translation>
+ </message>
+ <message>
+ <source>Block chain</source>
+ <translation>Lanţ de blocuri</translation>
+ </message>
+ <message>
+ <source>Current number of blocks</source>
+ <translation>Numărul curent de blocuri</translation>
+ </message>
+ <message>
+ <source>Received</source>
+ <translation>Recepţionat</translation>
+ </message>
+ <message>
+ <source>Sent</source>
+ <translation>Trimis</translation>
+ </message>
+ <message>
+ <source>&amp;Peers</source>
+ <translation>&amp;Parteneri</translation>
+ </message>
+ <message>
+ <source>Select a peer to view detailed information.</source>
+ <translation>Selectaţi un partener pentru a vedea informaţiile detaliate.</translation>
+ </message>
+ <message>
+ <source>Direction</source>
+ <translation>Direcţie</translation>
+ </message>
+ <message>
+ <source>Version</source>
+ <translation>Versiune</translation>
+ </message>
+ <message>
+ <source>User Agent</source>
+ <translation>Agent utilizator</translation>
+ </message>
+ <message>
+ <source>Services</source>
+ <translation>Servicii</translation>
+ </message>
+ <message>
+ <source>Connection Time</source>
+ <translation>Timp conexiune</translation>
+ </message>
+ <message>
+ <source>Last Send</source>
+ <translation>Ultima trimitere</translation>
+ </message>
+ <message>
+ <source>Last Receive</source>
+ <translation>Ultima primire</translation>
+ </message>
+ <message>
+ <source>Bytes Sent</source>
+ <translation>Octeţi trimişi</translation>
+ </message>
+ <message>
+ <source>Bytes Received</source>
+ <translation>Octeţi primiţi</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Timp ping</translation>
+ </message>
+ <message>
+ <source>Last block time</source>
+ <translation>Data ultimului bloc</translation>
+ </message>
+ <message>
+ <source>&amp;Open</source>
+ <translation>&amp;Deschide</translation>
+ </message>
+ <message>
+ <source>&amp;Console</source>
+ <translation>&amp;Consolă</translation>
+ </message>
+ <message>
+ <source>&amp;Network Traffic</source>
+ <translation>Trafic reţea</translation>
+ </message>
+ <message>
+ <source>&amp;Clear</source>
+ <translation>&amp;Curăţă</translation>
+ </message>
+ <message>
+ <source>Totals</source>
+ <translation>Totaluri</translation>
+ </message>
+ <message>
+ <source>In:</source>
+ <translation>Intrare:</translation>
+ </message>
+ <message>
+ <source>Out:</source>
+ <translation>Ieşire:</translation>
+ </message>
+ <message>
+ <source>Build date</source>
+ <translation>Construit la data</translation>
+ </message>
+ <message>
+ <source>Debug log file</source>
+ <translation>Fişier jurnal depanare</translation>
+ </message>
+ <message>
+ <source>Clear console</source>
+ <translation>Curăţă consola</translation>
+ </message>
+ <message>
+ <source>Welcome to the Bitcoin Core RPC console.</source>
+ <translation>Bun venit la consola Nucleului Bitcoin RPC.</translation>
+ </message>
+ <message>
+ <source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
+ <translation>Folosiţi săgetile sus şi jos pentru a naviga în istoric şi &lt;b&gt;Ctrl-L&lt;/b&gt; pentru a curăţa.</translation>
+ </message>
+ <message>
+ <source>Type &lt;b&gt;help&lt;/b&gt; for an overview of available commands.</source>
+ <translation>Scrieţi &lt;b&gt;help&lt;/b&gt; pentru a vedea comenzile disponibile.</translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation>%1 B</translation>
+ </message>
+ <message>
+ <source>%1 KB</source>
+ <translation>%1 KB</translation>
+ </message>
+ <message>
+ <source>%1 MB</source>
+ <translation>%1 MB</translation>
+ </message>
+ <message>
+ <source>%1 GB</source>
+ <translation>%1 GB</translation>
+ </message>
+ <message>
+ <source>via %1</source>
+ <translation>via %1</translation>
+ </message>
+ <message>
+ <source>never</source>
+ <translation>niciodată</translation>
+ </message>
+ <message>
+ <source>Inbound</source>
+ <translation>Intrare</translation>
+ </message>
+ <message>
+ <source>Outbound</source>
+ <translation>Ieşire</translation>
+ </message>
+ <message>
+ <source>Unknown</source>
+ <translation>Necunoscut</translation>
+ </message>
+ <message>
+ <source>Fetching...</source>
+ <translation>Preluare...</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Amount:</source>
+ <translation>Sum&amp;a:</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Etichetă:</translation>
+ </message>
+ <message>
+ <source>&amp;Message:</source>
+ <translation>&amp;Mesaj:</translation>
+ </message>
+ <message>
+ <source>Reuse one of the previously used receiving addresses. Reusing addresses has security and privacy issues. Do not use this unless re-generating a payment request made before.</source>
+ <translation>Refoloseşte una din adresele de primire folosite anterior. Refolosirea adreselor poate crea probleme de securitate şi confidenţialitate. Nu folosiţi această opţiune decît dacă o cerere de regenerare a plăţii a fost făcută anterior.</translation>
+ </message>
+ <message>
+ <source>R&amp;euse an existing receiving address (not recommended)</source>
+ <translation>R&amp;efoloseşte o adresă de primire (nu este recomandat)</translation>
+ </message>
+ <message>
+ <source>An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network.</source>
+ <translation>Un mesaj opţional de ataşat la cererea de plată, care va fi afişat cînd cererea este deschisă. Notă: Acest mesaj nu va fi trimis cu plata către reţeaua Bitcoin.</translation>
+ </message>
+ <message>
+ <source>An optional label to associate with the new receiving address.</source>
+ <translation>O etichetă opţională de asociat cu adresa de primire.</translation>
+ </message>
+ <message>
+ <source>Use this form to request payments. All fields are &lt;b&gt;optional&lt;/b&gt;.</source>
+ <translation>Foloseşte acest formular pentru a solicita plăţi. Toate cîmpurile sînt &lt;b&gt;opţionale&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>An optional amount to request. Leave this empty or zero to not request a specific amount.</source>
+ <translation>O sumă opţională de cerut. Lăsaţi gol sau zero pentru a nu cere o sumă anume.</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Curăţă toate cîmpurile formularului.</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation>Curăţă</translation>
+ </message>
+ <message>
+ <source>Requested payments history</source>
+ <translation>Istoricul plăţilor cerute</translation>
+ </message>
+ <message>
+ <source>&amp;Request payment</source>
+ <translation>&amp;Cerere plată</translation>
+ </message>
+ <message>
+ <source>Show the selected request (does the same as double clicking an entry)</source>
+ <translation>Arată cererea selectată (acelaşi lucru ca şi dublu-clic pe o înregistrare)</translation>
+ </message>
+ <message>
+ <source>Show</source>
+ <translation>Arată</translation>
+ </message>
+ <message>
+ <source>Remove the selected entries from the list</source>
+ <translation>Înlătură intrările selectate din listă</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>Înlătură</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Copiază eticheta</translation>
+ </message>
+ <message>
+ <source>Copy message</source>
+ <translation>Copiază mesajul</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copiază suma</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>QR Code</source>
+ <translation>Cod QR</translation>
+ </message>
+ <message>
+ <source>Copy &amp;URI</source>
+ <translation>Copiază &amp;URl</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Address</source>
+ <translation>Copiază &amp;adresa</translation>
+ </message>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Salvează imaginea...</translation>
+ </message>
+ <message>
+ <source>Request payment to %1</source>
+ <translation>Cere plata pentru %1</translation>
+ </message>
+ <message>
+ <source>Payment information</source>
+ <translation>Informaţiile plăţii</translation>
+ </message>
+ <message>
+ <source>URI</source>
+ <translation>URI</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adresă</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Sumă</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etichetă</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Mesaj</translation>
+ </message>
+ <message>
+ <source>Resulting URI too long, try to reduce the text for label / message.</source>
+ <translation>URI rezultat este prea lung, încearcaţi să reduceţi textul pentru etichetă / mesaj.</translation>
+ </message>
+ <message>
+ <source>Error encoding URI into QR Code.</source>
+ <translation>Eroare la codarea URl-ului în cod QR.</translation>
+ </message>
+</context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etichetă</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Mesaj</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Sumă</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(fără etichetă)</translation>
+ </message>
+ <message>
+ <source>(no message)</source>
+ <translation>(nici un mesaj)</translation>
+ </message>
+ <message>
+ <source>(no amount)</source>
+ <translation>(sumă nulă)</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Trimite monede</translation>
+ </message>
+ <message>
+ <source>Coin Control Features</source>
+ <translation>Caracteristici de control ale monedei</translation>
+ </message>
+ <message>
+ <source>Inputs...</source>
+ <translation>Intrări...</translation>
+ </message>
+ <message>
+ <source>automatically selected</source>
+ <translation>selecţie automată</translation>
+ </message>
+ <message>
+ <source>Insufficient funds!</source>
+ <translation>Fonduri insuficiente!</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Cantitate:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Octeţi:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Sumă:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Prioritate:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Taxă:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>După taxă:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Rest:</translation>
+ </message>
+ <message>
+ <source>If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address.</source>
+ <translation>Dacă este activat, dar adresa de rest este goală sau nevalidă, restul va fi trimis la o adresă nou generată.</translation>
+ </message>
+ <message>
+ <source>Custom change address</source>
+ <translation>Adresă personalizată de rest</translation>
+ </message>
+ <message>
+ <source>Transaction Fee:</source>
+ <translation>Taxă tranzacţie:</translation>
+ </message>
+ <message>
+ <source>Choose...</source>
+ <translation>Alegeţi...</translation>
+ </message>
+ <message>
+ <source>per kilobyte</source>
+ <translation>per kilooctet</translation>
+ </message>
+ <message>
+ <source>Hide</source>
+ <translation>Ascunde</translation>
+ </message>
+ <message>
+ <source>total at least</source>
+ <translation>total cel puţin</translation>
+ </message>
+ <message>
+ <source>Recommended:</source>
+ <translation>Recomandat:</translation>
+ </message>
+ <message>
+ <source>Custom:</source>
+ <translation>Personalizat:</translation>
+ </message>
+ <message>
+ <source>Confirmation time:</source>
+ <translation>Timp confirmare:</translation>
+ </message>
+ <message>
+ <source>normal</source>
+ <translation>normal</translation>
+ </message>
+ <message>
+ <source>fast</source>
+ <translation>rapid</translation>
+ </message>
+ <message>
+ <source>Send as zero-fee transaction if possible</source>
+ <translation>Trimite ca taxă zero dacă este posibil</translation>
+ </message>
+ <message>
+ <source>(confirmation may take longer)</source>
+ <translation>(confirmarea poate dura mai mult)</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>Trimite simultan către mai mulţi destinatari</translation>
+ </message>
+ <message>
+ <source>Add &amp;Recipient</source>
+ <translation>Adaugă destinata&amp;r</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Şterge toate cîmpurile formularului.</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Praf:</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Curăţă to&amp;ate</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>Balanţă:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>Confirmă operaţiunea de trimitere</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>Trimit&amp;e</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>Confirmă trimiterea de monede</translation>
+ </message>
+ <message>
+ <source>%1 to %2</source>
+ <translation>%1 la %2</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Copiază cantitea</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copiază suma</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Copiază taxa</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Copiază după taxă</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Copiază octeţi</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Copiază prioritatea</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Copiază rest</translation>
+ </message>
+ <message>
+ <source>or</source>
+ <translation>sau</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>Suma de plată trebuie să fie mai mare decît 0.</translation>
+ </message>
+ <message>
+ <source>The amount exceeds your balance.</source>
+ <translation>Suma depăşeşte soldul contului.</translation>
+ </message>
+ <message>
+ <source>The total exceeds your balance when the %1 transaction fee is included.</source>
+ <translation>Totalul depăşeşte soldul contului dacă se include şi plata taxei de %1.</translation>
+ </message>
+ <message>
+ <source>Transaction creation failed!</source>
+ <translation>Creare tranzacţie nereuşită!</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>Tranzacţia a fost respinsă! Acest lucru se poate întîmpla dacă o parte din monedele tale din portofel au fost deja cheltuite, la fel ca şi cum aţi fi folosit o copie a wallet.dat şi monedele au fost cheltuite în copie, dar nu au fost marcate ca şi cheltuite şi aici.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>Cererea de plată a expirat.</translation>
+ </message>
+ <message>
+ <source>Pay only the minimum fee of %1</source>
+ <translation>Plăteşte doar taxa minimă de %1</translation>
+ </message>
+ <message>
+ <source>The recipient address is not valid. Please recheck.</source>
+ <translation>Adresa destinatarului nu este validă, vă rugăm să o verificaţi.</translation>
+ </message>
+ <message>
+ <source>Warning: Invalid Bitcoin address</source>
+ <translation>Atenţie: Adresa bitcoin nevalidă!</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(fără etichetă)</translation>
+ </message>
+ <message>
+ <source>Warning: Unknown change address</source>
+ <translation>Atenţie: Adresă de rest necunoscută</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Copiază praf</translation>
+ </message>
+ <message>
+ <source>Are you sure you want to send?</source>
+ <translation>Sigur doriţi să trimiteţi?</translation>
+ </message>
+ <message>
+ <source>added as transaction fee</source>
+ <translation>adăugat ca taxă de tranzacţie</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>Su&amp;mă:</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>Plăteşte că&amp;tre:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Introduceţi o etichetă pentru această adresă pentru a fi adăugată în lista dvs. de adrese</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Etichetă:</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Alegeţi adrese folosite anterior</translation>
+ </message>
+ <message>
+ <source>This is a normal payment.</source>
+ <translation>Aceasta este o tranzacţie normală.</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to send the payment to</source>
+ <translation>Adresa bitcoin către care se face plata</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Lipeşte adresa din clipboard</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Remove this entry</source>
+ <translation>Înlătură această intrare</translation>
+ </message>
+ <message>
+ <source>Message:</source>
+ <translation>Mesaj:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to the list of used addresses</source>
+ <translation>Introduceţi eticheta pentru ca această adresa să fie introdusă în lista de adrese folosite</translation>
+ </message>
+ <message>
+ <source>A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network.</source>
+ <translation>un mesaj a fost ataşat la bitcoin: URI care va fi stocat cu tranzacţia pentru referinţa dvs. Notă: Acest mesaj nu va fi trimis către reţeaua bitcoin.</translation>
+ </message>
+ <message>
+ <source>Pay To:</source>
+ <translation>Plăteşte către:</translation>
+ </message>
+ <message>
+ <source>Memo:</source>
+ <translation>Memo:</translation>
+ </message>
+</context>
+<context>
+ <name>ShutdownWindow</name>
+ <message>
+ <source>Bitcoin Core is shutting down...</source>
+ <translation>Nucleul Bitcoin se închide...</translation>
+ </message>
+ <message>
+ <source>Do not shut down the computer until this window disappears.</source>
+ <translation>Nu închide calculatorul pînă ce această fereastră nu dispare.</translation>
+ </message>
+</context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Signatures - Sign / Verify a Message</source>
+ <translation>Semnaturi - Semnează/verifică un mesaj</translation>
+ </message>
+ <message>
+ <source>&amp;Sign Message</source>
+ <translation>&amp;Semnează mesaj</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to sign the message with</source>
+ <translation>Adresa cu care semnaţi mesajul</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Alegeţi adrese folosite anterior</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Lipeşte adresa copiată din clipboard</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Enter the message you want to sign here</source>
+ <translation>Introduceţi mesajul pe care vreţi să-l semnaţi, aici</translation>
+ </message>
+ <message>
+ <source>Signature</source>
+ <translation>Semnătură</translation>
+ </message>
+ <message>
+ <source>Copy the current signature to the system clipboard</source>
+ <translation>Copiază semnatura curentă în clipboard-ul sistemului</translation>
+ </message>
+ <message>
+ <source>Sign the message to prove you own this Bitcoin address</source>
+ <translation>Semnează mesajul pentru a dovedi ca deţineţi acestă adresă Bitcoin</translation>
+ </message>
+ <message>
+ <source>Sign &amp;Message</source>
+ <translation>Semnează &amp;mesaj</translation>
+ </message>
+ <message>
+ <source>Reset all sign message fields</source>
+ <translation>Resetează toate cîmpurile mesajelor semnate</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Curăţă to&amp;ate</translation>
+ </message>
+ <message>
+ <source>&amp;Verify Message</source>
+ <translation>&amp;Verifică mesaj</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address the message was signed with</source>
+ <translation>Introduceţi o adresă Bitcoin</translation>
+ </message>
+ <message>
+ <source>Verify the message to ensure it was signed with the specified Bitcoin address</source>
+ <translation>Verificaţi mesajul pentru a vă asigura că a fost semnat cu adresa Bitcoin specificată</translation>
+ </message>
+ <message>
+ <source>Verify &amp;Message</source>
+ <translation>Verifică &amp;mesaj</translation>
+ </message>
+ <message>
+ <source>Reset all verify message fields</source>
+ <translation>Resetează toate cîmpurile mesajelor semnate</translation>
+ </message>
+ <message>
+ <source>Click "Sign Message" to generate signature</source>
+ <translation>Faceţi clic pe "Semneaza msaj" pentru a genera semnătura</translation>
+ </message>
+ <message>
+ <source>The entered address is invalid.</source>
+ <translation>Adresa introdusă nu este validă</translation>
+ </message>
+ <message>
+ <source>Please check the address and try again.</source>
+ <translation>Vă rugăm verificaţi adresa şi încercaţi din nou.</translation>
+ </message>
+ <message>
+ <source>The entered address does not refer to a key.</source>
+ <translation>Adresa introdusă nu se referă la o cheie.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock was cancelled.</source>
+ <translation>Blocarea portofelului a fost întreruptă.</translation>
+ </message>
+ <message>
+ <source>Private key for the entered address is not available.</source>
+ <translation>Cheia privată pentru adresa introdusă nu este validă.</translation>
+ </message>
+ <message>
+ <source>Message signing failed.</source>
+ <translation>Semnarea mesajului nu a reuşit.</translation>
+ </message>
+ <message>
+ <source>Message signed.</source>
+ <translation>Mesaj semnat.</translation>
+ </message>
+ <message>
+ <source>The signature could not be decoded.</source>
+ <translation>Această semnatură nu a putut fi decodată.</translation>
+ </message>
+ <message>
+ <source>Please check the signature and try again.</source>
+ <translation>Vă rugăm verificaţi semnătura şi încercaţi din nou.</translation>
+ </message>
+ <message>
+ <source>The signature did not match the message digest.</source>
+ <translation>Semnatura nu se potriveşte cu mesajul.</translation>
+ </message>
+ <message>
+ <source>Message verification failed.</source>
+ <translation>Verificarea mesajului nu a reuşit.</translation>
+ </message>
+ <message>
+ <source>Message verified.</source>
+ <translation>Mesaj verificat.</translation>
+ </message>
+</context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Nucleul Bitcoin</translation>
+ </message>
+ <message>
+ <source>The Bitcoin Core developers</source>
+ <translation>Dezvoltatorii Nucleului Bitcoin</translation>
+ </message>
+ <message>
+ <source>[testnet]</source>
+ <translation>[testnet]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ <message>
+ <source>KB/s</source>
+ <translation>KB/s</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>Deschis pînă la %1</translation>
+ </message>
+ <message>
+ <source>conflicted</source>
+ <translation>în conflict</translation>
+ </message>
+ <message>
+ <source>%1/offline</source>
+ <translation>%1/deconectat</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/neconfirmat</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 confirmări</translation>
+ </message>
+ <message>
+ <source>Status</source>
+ <translation>Stare</translation>
+ </message>
+ <message numerus="yes">
+ <source>, broadcast through %n node(s)</source>
+ <translation><numerusform>, distribuit prin %n nod</numerusform><numerusform>, distribuit prin %n noduri</numerusform><numerusform>, distribuit prin %n de noduri</numerusform></translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Source</source>
+ <translation>Sursa</translation>
+ </message>
+ <message>
+ <source>Generated</source>
+ <translation>Generat</translation>
+ </message>
+ <message>
+ <source>From</source>
+ <translation>De la</translation>
+ </message>
+ <message>
+ <source>To</source>
+ <translation>Către</translation>
+ </message>
+ <message>
+ <source>own address</source>
+ <translation>adresa proprie</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>doar-supraveghere</translation>
+ </message>
+ <message>
+ <source>label</source>
+ <translation>etichetă</translation>
+ </message>
+ <message>
+ <source>Credit</source>
+ <translation>Credit</translation>
+ </message>
+ <message numerus="yes">
+ <source>matures in %n more block(s)</source>
+ <translation><numerusform>se maturizează în încă %n bloc</numerusform><numerusform>se maturizează în încă %n blocuri</numerusform><numerusform>se maturizează în încă %n de blocuri</numerusform></translation>
+ </message>
+ <message>
+ <source>not accepted</source>
+ <translation>neacceptat</translation>
+ </message>
+ <message>
+ <source>Debit</source>
+ <translation>Debit</translation>
+ </message>
+ <message>
+ <source>Total debit</source>
+ <translation>Total debit</translation>
+ </message>
+ <message>
+ <source>Total credit</source>
+ <translation>Total credit</translation>
+ </message>
+ <message>
+ <source>Transaction fee</source>
+ <translation>Taxă tranzacţie</translation>
+ </message>
+ <message>
+ <source>Net amount</source>
+ <translation>Suma netă</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Mesaj</translation>
+ </message>
+ <message>
+ <source>Comment</source>
+ <translation>Comentariu</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>ID-ul tranzacţie</translation>
+ </message>
+ <message>
+ <source>Merchant</source>
+ <translation>Comerciant</translation>
+ </message>
+ <message>
+ <source>Generated coins must mature %1 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.</source>
+ <translation>Monezile generate trebuie să crească %1 blocuri înainte să poată fi cheltuite. Cînd aţi generat acest bloc, a fost transmis reţelei pentru a fi adaugat la lanţul de blocuri. Aceasta se poate întîmpla ocazional dacă alt nod generează un bloc la numai cîteva secunde de al dvs.</translation>
+ </message>
+ <message>
+ <source>Debug information</source>
+ <translation>Informaţii pentru depanare</translation>
+ </message>
+ <message>
+ <source>Transaction</source>
+ <translation>Tranzacţie</translation>
+ </message>
+ <message>
+ <source>Inputs</source>
+ <translation>Intrări</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Sumă</translation>
+ </message>
+ <message>
+ <source>true</source>
+ <translation>adevărat</translation>
+ </message>
+ <message>
+ <source>false</source>
+ <translation>fals</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, nu s-a propagat încă</translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>necunoscut</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>Detaliile tranzacţiei</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>Acest panou arată o descriere detaliată a tranzacţiei</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Tip</translation>
+ </message>
+ <message>
+ <source>Immature (%1 confirmations, will be available after %2)</source>
+ <translation>Imatur (%1 confirmări, va fi disponibil după %2)</translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>Deschis până la %1</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>Confirmat (%1 confirmări)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>Acest bloc nu a fost recepţionat de nici un alt nod şi probabil nu va fi acceptat!</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>Generat dar neacceptat</translation>
+ </message>
+ <message>
+ <source>Offline</source>
+ <translation>Deconectat</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etichetă</translation>
+ </message>
+ <message>
+ <source>Unconfirmed</source>
+ <translation>Neconfirmat</translation>
+ </message>
+ <message>
+ <source>Confirming (%1 of %2 recommended confirmations)</source>
+ <translation>Confirmare (%1 din %2 confirmări recomandate)</translation>
+ </message>
+ <message>
+ <source>Conflicted</source>
+ <translation>În conflict</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Recepţionat cu</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>Primit de la</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Trimis către</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>Plată către dvs.</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Minerit</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>doar-supraveghere</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>indisponibil</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>Starea tranzacţiei. Treceţi cu mouse-ul peste acest cîmp pentru afişarea numărului de confirmări.</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Data şi ora la care a fost recepţionată tranzacţia.</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>Tipul tranzacţiei.</translation>
+ </message>
+ <message>
+ <source>Whether or not a watch-only address is involved in this transaction.</source>
+ <translation>Indiferent dacă sau nu o adresă doar-suăpraveghere este implicată în această tranzacţie.</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>Suma extrasă sau adăugată la sold.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>Toate</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>Astăzi</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>Săptămîna aceasta</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>Luna aceasta</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>Luna trecută</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>Anul acesta</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>Interval...</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Recepţionat cu</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Trimis către</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>Către dvs.</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Minerit</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>Altele</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>Introduceţi adresa sau eticheta pentru căutare</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>Suma minimă</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Copiază adresa</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Copiază eticheta</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Copiază suma</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Copiază ID tranzacţie</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>Editează eticheta</translation>
+ </message>
+ <message>
+ <source>Show transaction details</source>
+ <translation>Arată detaliile tranzacţiei</translation>
+ </message>
+ <message>
+ <source>Export Transaction History</source>
+ <translation>Export istoric tranzacţii</translation>
+ </message>
+ <message>
+ <source>Watch-only</source>
+ <translation>Doar-supraveghere</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Export nereuşit</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the transaction history to %1.</source>
+ <translation>S-a produs o eroare la salvarea istoricului tranzacţiilor la %1.</translation>
+ </message>
+ <message>
+ <source>Exporting Successful</source>
+ <translation>Export reuşit</translation>
+ </message>
+ <message>
+ <source>The transaction history was successfully saved to %1.</source>
+ <translation>Istoricul tranzacţiilor a fost salvat cu succes la %1.</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Fişier text cu valori separate prin virgulă (*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Confirmat</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Tip</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etichetă</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adresă</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>Interval:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>către</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ <message>
+ <source>Unit to show amounts in. Click to select another unit.</source>
+ <translation>Unitatea în care sînt arătate sumele. Faceţi clic pentru a selecta o altă unitate.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletFrame</name>
+ <message>
+ <source>No wallet has been loaded.</source>
+ <translation>Nu a fost încărcat nici un portofel.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Trimitere bitcoin</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Export</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Exportă datele din tab-ul curent într-un fişier</translation>
+ </message>
+ <message>
+ <source>Backup Wallet</source>
+ <translation>Copie de siguranţă portofel</translation>
+ </message>
+ <message>
+ <source>Wallet Data (*.dat)</source>
+ <translation>Date portofel (*.dat)</translation>
+ </message>
+ <message>
+ <source>Backup Failed</source>
+ <translation>Copierea de siguranţă nu a reuşit</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the wallet data to %1.</source>
+ <translation>S-a produs o eroare la salvarea datelor portofelului la %1.</translation>
+ </message>
+ <message>
+ <source>The wallet data was successfully saved to %1.</source>
+ <translation>Datele portofelului s-au salvat cu succes la %1.</translation>
+ </message>
+ <message>
+ <source>Backup Successful</source>
+ <translation>Copie de siguranţă efectuată cu succes</translation>
+ </message>
+</context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>Opţiuni:</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>Specificaţi dosarul de date</translation>
+ </message>
+ <message>
+ <source>Connect to a node to retrieve peer addresses, and disconnect</source>
+ <translation>Se conectează la un nod pentru a obţine adresele partenerilor, şi apoi se deconectează</translation>
+ </message>
+ <message>
+ <source>Specify your own public address</source>
+ <translation>Specificaţi adresa dvs. publică</translation>
+ </message>
+ <message>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>Acceptă comenzi din linia de comandă şi comenzi JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>Rulează în fundal ca un demon şi acceptă comenzi</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>Utilizează reţeaua de test</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
+ <translation>Acceptă conexiuni din afară (implicit: 1 dacă nu se foloseşte -proxy sau -connect)</translation>
+ </message>
+ <message>
+ <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
+ <translation>Ataşaţi adresei date şi ascultaţi totdeauna pe ea. Folosiţi notaţia [host]:port pentru IPv6</translation>
+ </message>
+ <message>
+ <source>Distributed under the MIT software license, see the accompanying file COPYING or &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</source>
+ <translation>Distribuit sub licenţa de programe MIT/X11, vezi fişierul însoţitor COPYING sau &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</translation>
+ </message>
+ <message>
+ <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
+ <translation>Execută comanda cînd o tranzacţie a portofelului se schimbă (%s în cmd este înlocuit de TxID)</translation>
+ </message>
+ <message>
+ <source>Set the number of script verification threads (%u to %d, 0 = auto, &lt;0 = leave that many cores free, default: %d)</source>
+ <translation>Setează numărul de thread-uri de verificare a script-urilor (%u la %d, 0 = auto, &lt;0 = lasă atîtea nuclee libere, implicit: %d)</translation>
+ </message>
+ <message>
+ <source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source>
+ <translation>Aceasta este o versiune de test preliminară - vă asumaţi riscul folosind-o - nu folosiţi pentru minerit sau aplicaţiile comercianţilor</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer. Bitcoin Core is probably already running.</source>
+ <translation>Nu se poate lega la %s pe acest calculator. Nucleul Bitcoin probabil deja rulează.</translation>
+ </message>
+ <message>
+ <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>Atenţie: setarea -paytxfee este foarte mare! Aceasta este taxa tranzacţiei pe care o veţi plăti dacă trimiteţi o tranzacţie.</translation>
+ </message>
+ <message>
+ <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source>
+ <translation>Atenţie: Reţeaua nu pare să fie de acord în totalitate! Aparent nişte mineri au probleme.</translation>
+ </message>
+ <message>
+ <source>Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.</source>
+ <translation>Atenţie: Aparent, nu sîntem de acord cu toţi partenerii noştri! Va trebui să faceţi o actualizare, sau alte noduri necesită actualizare.</translation>
+ </message>
+ <message>
+ <source>Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
+ <translation>Atenţie: eroare la citirea fişierului wallet.dat! Toate cheile sînt citite corect, dar datele tranzactiei sau anumite intrări din agenda sînt incorecte sau lipsesc.</translation>
+ </message>
+ <message>
+ <source>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</source>
+ <translation>Atenţie: fişierul wallet.dat este corupt, date salvate! Fişierul original wallet.dat a fost salvat ca wallet.{timestamp}.bak in %s; dacă balansul sau tranzactiile sînt incorecte ar trebui să restauraţi dintr-o copie de siguranţă.</translation>
+ </message>
+ <message>
+ <source>(default: 1)</source>
+ <translation>(iniţial: 1)</translation>
+ </message>
+ <message>
+ <source>&lt;category&gt; can be:</source>
+ <translation>&lt;category&gt; poate fi:</translation>
+ </message>
+ <message>
+ <source>Attempt to recover private keys from a corrupt wallet.dat</source>
+ <translation>Încercare de recuperare a cheilor private dintr-un wallet.dat corupt</translation>
+ </message>
+ <message>
+ <source>Block creation options:</source>
+ <translation>Opţiuni creare bloc:</translation>
+ </message>
+ <message>
+ <source>Connect only to the specified node(s)</source>
+ <translation>Conectare doar la nod(urile) specificate</translation>
+ </message>
+ <message>
+ <source>Connection options:</source>
+ <translation>Opţiuni conexiune:</translation>
+ </message>
+ <message>
+ <source>Corrupted block database detected</source>
+ <translation>Bloc defect din baza de date detectat</translation>
+ </message>
+ <message>
+ <source>Debugging/Testing options:</source>
+ <translation>Opţiuni Depanare/Test:</translation>
+ </message>
+ <message>
+ <source>Do not load the wallet and disable wallet RPC calls</source>
+ <translation>Nu încarcă portofelul şi dezactivează solicitările portofel RPC</translation>
+ </message>
+ <message>
+ <source>Do you want to rebuild the block database now?</source>
+ <translation>Doriţi să reconstruiţi baza de date blocuri acum?</translation>
+ </message>
+ <message>
+ <source>Error initializing block database</source>
+ <translation>Eroare la iniţializarea bazei de date de blocuri</translation>
+ </message>
+ <message>
+ <source>Error initializing wallet database environment %s!</source>
+ <translation>Eroare la iniţializarea mediului de bază de date a portofelului %s!</translation>
+ </message>
+ <message>
+ <source>Error loading block database</source>
+ <translation>Eroare la încărcarea bazei de date de blocuri</translation>
+ </message>
+ <message>
+ <source>Error opening block database</source>
+ <translation>Eroare la deschiderea bazei de date de blocuri</translation>
+ </message>
+ <message>
+ <source>Error: Disk space is low!</source>
+ <translation>Eroare: Spaţiu pe disc redus!</translation>
+ </message>
+ <message>
+ <source>Failed to listen on any port. Use -listen=0 if you want this.</source>
+ <translation>Nu s-a reuşit ascultarea pe orice port. Folosiţi -listen=0 dacă vreţi asta.</translation>
+ </message>
+ <message>
+ <source>If &lt;category&gt; is not supplied, output all debugging information.</source>
+ <translation>Dacă &lt;category&gt; nu este furnizat, produce toate informaţiile de depanare.</translation>
+ </message>
+ <message>
+ <source>Importing...</source>
+ <translation>Import...</translation>
+ </message>
+ <message>
+ <source>Incorrect or no genesis block found. Wrong datadir for network?</source>
+ <translation>Incorect sau nici un bloc de geneza găsit. Directorul de retea greşit?</translation>
+ </message>
+ <message>
+ <source>Invalid -onion address: '%s'</source>
+ <translation>Adresa -onion nevalidă: '%s'</translation>
+ </message>
+ <message>
+ <source>Not enough file descriptors available.</source>
+ <translation>Nu sînt destule descriptoare disponibile.</translation>
+ </message>
+ <message>
+ <source>Only connect to nodes in network &lt;net&gt; (ipv4, ipv6 or onion)</source>
+ <translation>Se conectează doar la noduri în reţeaua &lt;net&gt; (ipv4, ipv6 sau onion)</translation>
+ </message>
+ <message>
+ <source>Set database cache size in megabytes (%d to %d, default: %d)</source>
+ <translation>Setează mărimea bazei de date cache în megaocteţi (%d la %d, implicit: %d)</translation>
+ </message>
+ <message>
+ <source>Set maximum block size in bytes (default: %d)</source>
+ <translation>Setaţi dimensiunea maximă a unui bloc în bytes (implicit: %d)</translation>
+ </message>
+ <message>
+ <source>Specify wallet file (within data directory)</source>
+ <translation>Specifică fişierul portofel (în dosarul de date)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: %u)</source>
+ <translation>Foloseşte mapare UPnP pentru asculatere port (implicit: %u)</translation>
+ </message>
+ <message>
+ <source>Verifying blocks...</source>
+ <translation>Se verifică blocurile...</translation>
+ </message>
+ <message>
+ <source>Verifying wallet...</source>
+ <translation>Se verifică portofelul...</translation>
+ </message>
+ <message>
+ <source>Wallet %s resides outside data directory %s</source>
+ <translation>Portofelul %s se află în afara dosarului de date %s</translation>
+ </message>
+ <message>
+ <source>Wallet options:</source>
+ <translation>Opţiuni portofel:</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to change -txindex</source>
+ <translation>Trebuie să reconstruiţi baza de date folosind -reindex pentru a schimba -txindex</translation>
+ </message>
+ <message>
+ <source>Imports blocks from external blk000??.dat file</source>
+ <translation>Importă blocuri dintr-un fişier extern blk000??.dat</translation>
+ </message>
+ <message>
+ <source>Allow JSON-RPC connections from specified source. Valid for &lt;ip&gt; are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times</source>
+ <translation>Permite conexiunile JSON-RPC din sursa specificată. Valid pentru &lt;ip&gt; sînt IP singulare (ex. 1.2.3.4), o reţea/mască-reţea (ex. 1.2.3.4/255.255.255.0) sau o reţea/CIDR (ex. 1.2.3.4/24). Această opţiune poate fi specificată de mai multe ori</translation>
+ </message>
+ <message>
+ <source>An error occurred while setting up the RPC address %s port %u for listening: %s</source>
+ <translation>A apărut o eroare la setarea adresei RPC %s portul %u pentru ascultare: %s</translation>
+ </message>
+ <message>
+ <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source>
+ <translation>Nu se poate obţine blocarea folderului cu date %s. Nucleul Bitcoin probabil deja rulează.</translation>
+ </message>
+ <message>
+ <source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source>
+ <translation>Execută comanda cînd o alertă relevantă este primită sau vedem o bifurcaţie foarte lungă (%s în cmd este înlocuit de mesaj)</translation>
+ </message>
+ <message>
+ <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
+ <translation>Setează mărimea pentru tranzacţiile prioritare/taxe mici în octeţi (implicit: %d)</translation>
+ </message>
+ <message>
+ <source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit &lt;https://www.openssl.org/&gt; and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source>
+ <translation>Acest produs include programe dezvoltate de către Proiectul OpenSSL pentru a fi folosite în OpenSSL Toolkit &lt;https://www.openssl.org/&gt; şi programe criptografice scrise de către Eric Young şi programe UPnP scrise de către Thomas Bernard.</translation>
+ </message>
+ <message>
+ <source>Accept public REST requests (default: %u)</source>
+ <translation>Acceptă cererile publice REST (implicit: %u)</translation>
+ </message>
+ <message>
+ <source>Choose data directory on startup (default: 0)</source>
+ <translation>Alege dosarul de date la pornire (implicit: 0)</translation>
+ </message>
+ <message>
+ <source>Connect through SOCKS5 proxy</source>
+ <translation>Conectare prin proxy SOCKS5</translation>
+ </message>
+ <message>
+ <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source>
+ <translation>Copyright (C) 2009-%i Dezvoltatorii Bitcoin</translation>
+ </message>
+ <message>
+ <source>Error reading from database, shutting down.</source>
+ <translation>Eroare la citirea bazei de date. Oprire.</translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -tor found, use -onion.</source>
+ <translation>Eroare: Argument nesuportat -tor găsit, folosiţi -onion.</translation>
+ </message>
+ <message>
+ <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source>
+ <translation>Taxa (în BTC/kB) de adăugat la tranzacţiile pe care le trimiteţi(implicit: %s)</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Informaţie</translation>
+ </message>
+ <message>
+ <source>Initialization sanity check failed. Bitcoin Core is shutting down.</source>
+ <translation>Nu s-a reuşit iniţierea verificării sănătăţii. Nucleul Bitcoin se opreşte.</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Sumă nevalidă pentru -maxtxfee=&lt;suma&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -minrelaytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Sumă nevalidă pentru -minrelaytxfee=&lt;suma&gt;:'%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -mintxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Sumă nevalidă pentru -mintxfee=&lt;suma&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s' (must be at least %s)</source>
+ <translation>Sumă nevalidă pentru -paytxfee=&lt;suma&gt;: '%s' (trebuie să fie cel puţin %s)</translation>
+ </message>
+ <message>
+ <source>Invalid netmask specified in -whitelist: '%s'</source>
+ <translation>Mască reţea nevalidă specificată în -whitelist: '%s'</translation>
+ </message>
+ <message>
+ <source>Need to specify a port with -whitebind: '%s'</source>
+ <translation>Trebuie să specificaţi un port cu -whitebind: '%s'</translation>
+ </message>
+ <message>
+ <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source>
+ <translation>Opţiuni RPC SSL: (vedeţi Wiki Bitcoin pentru intrucţiunile de setare SSL)</translation>
+ </message>
+ <message>
+ <source>RPC server options:</source>
+ <translation>Opţiuni server RPC:</translation>
+ </message>
+ <message>
+ <source>RPC support for HTTP persistent connections (default: %d)</source>
+ <translation>RPC suportă pentru HTTP conexiuni persistente (implicit: %d)</translation>
+ </message>
+ <message>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>Trimite informaţiile trace/debug la consolă în locul fişierului debug.log</translation>
+ </message>
+ <message>
+ <source>Send transactions as zero-fee transactions if possible (default: %u)</source>
+ <translation>Trimitere tranzacţii ca tranzacţii taxă-zero dacă este posibil (implicit: %u)</translation>
+ </message>
+ <message>
+ <source>Set SSL root certificates for payment request (default: -system-)</source>
+ <translation>Setare rădăcină certificat SSL pentru cerere de plată (implicit: -sistem- )</translation>
+ </message>
+ <message>
+ <source>Set language, for example "de_DE" (default: system locale)</source>
+ <translation>Setează limba, de exemplu: "de_DE" (implicit: sistem local)</translation>
+ </message>
+ <message>
+ <source>Show all debugging options (usage: --help -help-debug)</source>
+ <translation>Arată toate opţiunile de depanare (uz: --help -help-debug)</translation>
+ </message>
+ <message>
+ <source>Show splash screen on startup (default: 1)</source>
+ <translation>Afişează pe ecran splash la pornire (implicit: 1)</translation>
+ </message>
+ <message>
+ <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source>
+ <translation>Micşorează fişierul debug.log la pornirea clientului (implicit: 1 cînd nu se foloseşte -debug)</translation>
+ </message>
+ <message>
+ <source>Signing transaction failed</source>
+ <translation>Nu s-a reuşit semnarea tranzacţiei</translation>
+ </message>
+ <message>
+ <source>Start minimized</source>
+ <translation>Începe minimizat</translation>
+ </message>
+ <message>
+ <source>This is experimental software.</source>
+ <translation>Acesta este un program experimental.</translation>
+ </message>
+ <message>
+ <source>Transaction amount too small</source>
+ <translation>Suma tranzacţionată este prea mică</translation>
+ </message>
+ <message>
+ <source>Transaction amounts must be positive</source>
+ <translation>Sumele tranzacţionate trebuie să fie pozitive</translation>
+ </message>
+ <message>
+ <source>Transaction too large for fee policy</source>
+ <translation>Tranzacţie prea mare pentru politică gratis</translation>
+ </message>
+ <message>
+ <source>Transaction too large</source>
+ <translation>Tranzacţie prea mare</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer (bind returned error %s)</source>
+ <translation>Nu se poate lega la %s pe acest calculator. (Legarea a întors eroarea %s)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: 1 when listening)</source>
+ <translation>Foloseşte UPnP pentru a vedea porturile (implicit: 1 cînd ascultă)</translation>
+ </message>
+ <message>
+ <source>Username for JSON-RPC connections</source>
+ <translation>Utilizator pentru conexiunile JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Wallet needed to be rewritten: restart Bitcoin Core to complete</source>
+ <translation>Portofelul necesită rescrierea: reporniţi Nucleul Bitcoin pentru completare</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Avertisment</translation>
+ </message>
+ <message>
+ <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source>
+ <translation>Avertisment: Argument nesuportat -benchmark ignorat, folosiţi -debug=bench.</translation>
+ </message>
+ <message>
+ <source>Warning: Unsupported argument -debugnet ignored, use -debug=net.</source>
+ <translation>Avertisment: Argument nesuportat -debugnet ignorat, folosiţi -debug=net.</translation>
+ </message>
+ <message>
+ <source>Zapping all transactions from wallet...</source>
+ <translation>Şterge toate tranzacţiile din portofel...</translation>
+ </message>
+ <message>
+ <source>on startup</source>
+ <translation>la pornire</translation>
+ </message>
+ <message>
+ <source>wallet.dat corrupt, salvage failed</source>
+ <translation>wallet.dat corupt, salvare nereuşită</translation>
+ </message>
+ <message>
+ <source>Password for JSON-RPC connections</source>
+ <translation>Parola pentru conexiunile JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
+ <translation>Execută comanda cînd cel mai bun bloc se modifică (%s în cmd este înlocuit cu hash-ul blocului)</translation>
+ </message>
+ <message>
+ <source>Upgrade wallet to latest format</source>
+ <translation>Actualizează portofelul la ultimul format</translation>
+ </message>
+ <message>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>Rescanează lanţul de bloc pentru tranzacţiile portofel lipsă</translation>
+ </message>
+ <message>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>Foloseşte OpenSSL (https) pentru conexiunile JSON-RPC</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>Acest mesaj de ajutor</translation>
+ </message>
+ <message>
+ <source>Allow DNS lookups for -addnode, -seednode and -connect</source>
+ <translation>Permite căutări DNS pentru -addnode, -seednode şi -connect</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>Încărcare adrese...</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>Eroare la încărcarea wallet.dat: Portofel corupt</translation>
+ </message>
+ <message>
+ <source>Output debugging information (default: %u, supplying &lt;category&gt; is optional)</source>
+ <translation>Produce toate informaţiile de depanare (implicit: %u &lt;category&gt; furnizată este opţională)</translation>
+ </message>
+ <message>
+ <source>(default: %s)</source>
+ <translation>(implicit: %s)</translation>
+ </message>
+ <message>
+ <source>Acceptable ciphers (default: %s)</source>
+ <translation>Cifruri acceptabile (implicit: %s)</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>Eroare la încărcarea wallet.dat</translation>
+ </message>
+ <message>
+ <source>Generate coins (default: %u)</source>
+ <translation>Generează monede (implicit: %u)</translation>
+ </message>
+ <message>
+ <source>How many blocks to check at startup (default: %u, 0 = all)</source>
+ <translation>Cîte blocuri verifică la pornire (implicit: %u, 0 = toate)</translation>
+ </message>
+ <message>
+ <source>Invalid -proxy address: '%s'</source>
+ <translation>Adresa -proxy nevalidă: '%s'</translation>
+ </message>
+ <message>
+ <source>Server certificate file (default: %s)</source>
+ <translation>Fişierul certificat al serverului (implicit: %s)</translation>
+ </message>
+ <message>
+ <source>Server private key (default: %s)</source>
+ <translation>Cheia privată a serverului (implicit: %s)</translation>
+ </message>
+ <message>
+ <source>Set minimum block size in bytes (default: %u)</source>
+ <translation>Setare mărime minimă bloc în octeţi (implicit: %u)</translation>
+ </message>
+ <message>
+ <source>Specify configuration file (default: %s)</source>
+ <translation>Specificaţi fişierul configuraţie (implicit: %s)</translation>
+ </message>
+ <message>
+ <source>Specify pid file (default: %s)</source>
+ <translation>Specifică fişierul pid (implicit: %s)</translation>
+ </message>
+ <message>
+ <source>Unknown network specified in -onlynet: '%s'</source>
+ <translation>Reţeaua specificată în -onlynet este necunoscută: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -bind address: '%s'</source>
+ <translation>Nu se poate rezolva adresa -bind: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -externalip address: '%s'</source>
+ <translation>Nu se poate rezolva adresa -externalip: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Suma nevalidă pentru -paytxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>Fonduri insuficiente</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>Încărcare index bloc...</translation>
+ </message>
+ <message>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>Adaugă un nod la care te poţi conecta pentru a menţine conexiunea deschisă</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>Încărcare portofel...</translation>
+ </message>
+ <message>
+ <source>Cannot downgrade wallet</source>
+ <translation>Nu se poate retrograda portofelul</translation>
+ </message>
+ <message>
+ <source>Cannot write default address</source>
+ <translation>Nu se poate scrie adresa implicită</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>Rescanare...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>Încărcare terminată</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Eroare</translation>
+ </message>
+</context>
+</TS> \ 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 0000000000..592c972666
--- /dev/null
+++ b/src/qt/locale/bitcoin_ru.ts
@@ -0,0 +1,3528 @@
+<TS language="ru" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Right-click to edit address or label</source>
+ <translation>Клик правой кнопкой для редактирования адреса или метки</translation>
+ </message>
+ <message>
+ <source>Create a new address</source>
+ <translation>Создать новый адрес</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>&amp;Новый</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Копировать текущий выделенный адрес в буфер обмена</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>&amp;Копировать</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>&amp;Закрыть</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>&amp;Копировать адрес</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>Удалить выбранный адрес из списка</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Экспортировать данные из вкладки в файл</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Экспорт</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;Удалить</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>Выберите адрес для отправки на него монет</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>Выберите адрес для получения монет</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>&amp;Выбрать</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>Адреса отправки</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>Адреса получения</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>Это ваши адреса Bitcoin для отправки платежей. Всегда проверяйте количество и адрес получателя перед отправкой перевода.</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>Это ваши адреса Bitcoin для приёма платежей. Рекомендуется использовать новый адрес получения для каждой транзакции.</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>Копировать &amp;метку</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>&amp;Правка</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>Экспортировать список адресов</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Текст, разделённый запятыми (*.csv)</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Экспорт не удался</translation>
+ </message>
+ </context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Метка</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Адрес</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>[нет метки]</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Passphrase Dialog</source>
+ <translation>Диалог ввода пароля</translation>
+ </message>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Введите пароль</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Новый пароль</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Повторите новый пароль</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>Зашифровать бумажник</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>Для выполнения операции требуется пароль вашего бумажника.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Разблокировать бумажник</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>Для выполнения операции требуется пароль вашего бумажника.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>Расшифровать бумажник</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>Сменить пароль</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>Подтвердите шифрование бумажника</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>Внимание: если вы зашифруете бумажник и потеряете пароль, вы &lt;b&gt;ПОТЕРЯЕТЕ ВСЕ ВАШИ БИТКОЙНЫ&lt;/b&gt;!</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>Вы уверены, что хотите зашифровать ваш бумажник?</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core 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.</source>
+ <translation>Сейчас программа закроется для завершения процесса шифрования. Помните, что шифрование вашего бумажника не может полностью защитить ваши биткоины от кражи с помощью инфицирования вашего компьютера вредоносным ПО.</translation>
+ </message>
+ <message>
+ <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
+ <translation>ВАЖНО: все предыдущие резервные копии вашего бумажника должны быть заменены новым зашифрованным файлом. В целях безопасности предыдущие резервные копии незашифрованного бумажника станут бесполезны, как только вы начнёте использовать новый зашифрованный бумажник.</translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>Внимание: Caps Lock включен!</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>Бумажник зашифрован</translation>
+ </message>
+ <message>
+ <source>Enter the new passphrase to the wallet.&lt;br/&gt;Please use a passphrase of &lt;b&gt;ten or more random characters&lt;/b&gt;, or &lt;b&gt;eight or more words&lt;/b&gt;.</source>
+ <translation>Введите новый пароль бумажника.&lt;br/&gt;Используйте пароль, состоящий из &lt;b&gt;десяти или более случайных символов&lt;/b&gt;, или &lt;b&gt;восьми или более слов&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>Enter the old passphrase and new passphrase to the wallet.</source>
+ <translation>Введите старый и новый пароль для кошелька.</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>Не удалось зашифровать бумажник</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>Шифрование бумажника не удалось из-за внутренней ошибки. Ваш бумажник не был зашифрован.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>Введённые пароли не совпадают.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>Разблокировка бумажника не удалась</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>Указанный пароль не подходит.</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>Расшифрование бумажника не удалось</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>Пароль бумажника успешно изменён.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>&amp;Подписать сообщение...</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>Синхронизация с сетью...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;Обзор</translation>
+ </message>
+ <message>
+ <source>Node</source>
+ <translation>Узел</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>Показать общий обзор действий с бумажником</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Транзакции</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>Показать историю транзакций</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>В&amp;ыход</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>Закрыть приложение</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>О &amp;Qt</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>Показать информацию о Qt</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;Параметры</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>&amp;Зашифровать бумажник...</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>&amp;Сделать резервную копию бумажника...</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>&amp;Изменить пароль...</translation>
+ </message>
+ <message>
+ <source>&amp;Sending addresses...</source>
+ <translation>&amp;Адреса отправки...</translation>
+ </message>
+ <message>
+ <source>&amp;Receiving addresses...</source>
+ <translation>Адреса &amp;получения...</translation>
+ </message>
+ <message>
+ <source>Open &amp;URI...</source>
+ <translation>Открыть &amp;URI...</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core client</source>
+ <translation>Bitcoin Core клиент</translation>
+ </message>
+ <message>
+ <source>Importing blocks from disk...</source>
+ <translation>Импортируются блоки с диска...</translation>
+ </message>
+ <message>
+ <source>Reindexing blocks on disk...</source>
+ <translation>Идёт переиндексация блоков на диске...</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>Отправить монеты на указанный адрес Bitcoin</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>Сделать резервную копию бумажника в другом месте</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Изменить пароль шифрования бумажника</translation>
+ </message>
+ <message>
+ <source>&amp;Debug window</source>
+ <translation>&amp;Окно отладки</translation>
+ </message>
+ <message>
+ <source>Open debugging and diagnostic console</source>
+ <translation>Открыть консоль отладки и диагностики</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>&amp;Проверить сообщение...</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>Бумажник</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>&amp;Отправить</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>&amp;Получить</translation>
+ </message>
+ <message>
+ <source>Show information about Bitcoin Core</source>
+ <translation>Показать информацию о Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>&amp;Показать / Скрыть</translation>
+ </message>
+ <message>
+ <source>Show or hide the main Window</source>
+ <translation>Показать или скрыть главное окно</translation>
+ </message>
+ <message>
+ <source>Encrypt the private keys that belong to your wallet</source>
+ <translation>Зашифровать приватные ключи, принадлежащие вашему бумажнику</translation>
+ </message>
+ <message>
+ <source>Sign messages with your Bitcoin addresses to prove you own them</source>
+ <translation>Подписать сообщения вашим адресом Bitcoin, чтобы доказать, что вы им владеете</translation>
+ </message>
+ <message>
+ <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source>
+ <translation>Проверить сообщения, чтобы удостовериться, что они были подписаны определённым адресом Bitcoin</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;Файл</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;Настройки</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>&amp;Помощь</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>Панель вкладок</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Request payments (generates QR codes and bitcoin: URIs)</source>
+ <translation>Запросить платежи (создаёт QR-коды и bitcoin: ссылки)</translation>
+ </message>
+ <message>
+ <source>&amp;About Bitcoin Core</source>
+ <translation>&amp;О Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Modify configuration options for Bitcoin Core</source>
+ <translation>Изменить опции конфигурации Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Show the list of used sending addresses and labels</source>
+ <translation>Показать список использованных адресов и меток отправки</translation>
+ </message>
+ <message>
+ <source>Show the list of used receiving addresses and labels</source>
+ <translation>Показать список использованных адресов и меток получения</translation>
+ </message>
+ <message>
+ <source>Open a bitcoin: URI or payment request</source>
+ <translation>Открыть bitcoin: URI или запрос платежа</translation>
+ </message>
+ <message>
+ <source>&amp;Command-line options</source>
+ <translation>&amp;Параметры командной строки</translation>
+ </message>
+ <message>
+ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
+ <translation>Показать помощь по Bitcoin Core и получить список доступных параметров командной строки.</translation>
+ </message>
+ <message>
+ <source>No block source available...</source>
+ <translation>Источник блоков недоступен...</translation>
+ </message>
+ <message numerus="yes">
+ <source>Processed %n block(s) of transaction history.</source>
+ <translation><numerusform>Обработан %n блок истории транзакций.</numerusform><numerusform>Обработано %n блока истории транзакций.</numerusform><numerusform>Обработано %n блоков истории транзакций.</numerusform><numerusform>Обработано %n блоков истории транзакций.</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 and %2</source>
+ <translation>%1 и %2</translation>
+ </message>
+ <message>
+ <source>%1 behind</source>
+ <translation>%1 позади</translation>
+ </message>
+ <message>
+ <source>Last received block was generated %1 ago.</source>
+ <translation>Последний полученный блок был сгенерирован %1 назад.</translation>
+ </message>
+ <message>
+ <source>Transactions after this will not yet be visible.</source>
+ <translation>Транзакции после него пока не будут видны.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Ошибка</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Внимание</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Информация</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>Синхронизировано</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>Синхронизируется...</translation>
+ </message>
+ <message>
+ <source>Date: %1
+</source>
+ <translation>Дата: %1
+</translation>
+ </message>
+ <message>
+ <source>Amount: %1
+</source>
+ <translation>Количество: %1
+</translation>
+ </message>
+ <message>
+ <source>Type: %1
+</source>
+ <translation>Тип: %1
+</translation>
+ </message>
+ <message>
+ <source>Label: %1
+</source>
+ <translation>Метка: %1
+</translation>
+ </message>
+ <message>
+ <source>Address: %1
+</source>
+ <translation>Адрес: %1
+</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>Исходящая транзакция</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>Входящая транзакция</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>Бумажник &lt;b&gt;зашифрован&lt;/b&gt; и в настоящее время &lt;b&gt;разблокирован&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>Бумажник &lt;b&gt;зашифрован&lt;/b&gt; и в настоящее время &lt;b&gt;заблокирован&lt;/b&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <source>Network Alert</source>
+ <translation>Сетевая Тревога</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Coin Selection</source>
+ <translation>Выбор монет</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Количество:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Байт:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Сумма:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Приоритет:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Комиссия:</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Пыль:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>После комиссии:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Сдача:</translation>
+ </message>
+ <message>
+ <source>(un)select all</source>
+ <translation>Отменить выбор всего</translation>
+ </message>
+ <message>
+ <source>Tree mode</source>
+ <translation>Режим дерева</translation>
+ </message>
+ <message>
+ <source>List mode</source>
+ <translation>Режим списка</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Сумма</translation>
+ </message>
+ <message>
+ <source>Received with label</source>
+ <translation>Получено с пометкой</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>Получено с адреса</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Дата</translation>
+ </message>
+ <message>
+ <source>Confirmations</source>
+ <translation>Подтверждений</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Подтверждено</translation>
+ </message>
+ <message>
+ <source>Priority</source>
+ <translation>Приоритет</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Копировать адрес</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Копировать метку</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Скопировать сумму</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Скопировать ID транзакции</translation>
+ </message>
+ <message>
+ <source>Lock unspent</source>
+ <translation>Заблокировать непотраченное</translation>
+ </message>
+ <message>
+ <source>Unlock unspent</source>
+ <translation>Разблокировать непотраченное</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Копировать количество</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Копировать комиссию</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Копировать после комиссии</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Копировать байты</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Копировать приоритет</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Копировать пыль</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Копировать сдачу</translation>
+ </message>
+ <message>
+ <source>highest</source>
+ <translation>самый высокий</translation>
+ </message>
+ <message>
+ <source>higher</source>
+ <translation>выше</translation>
+ </message>
+ <message>
+ <source>high</source>
+ <translation>высокий</translation>
+ </message>
+ <message>
+ <source>medium-high</source>
+ <translation>выше среднего</translation>
+ </message>
+ <message>
+ <source>medium</source>
+ <translation>средний</translation>
+ </message>
+ <message>
+ <source>low-medium</source>
+ <translation>ниже среднего</translation>
+ </message>
+ <message>
+ <source>low</source>
+ <translation>низкий</translation>
+ </message>
+ <message>
+ <source>lower</source>
+ <translation>ниже</translation>
+ </message>
+ <message>
+ <source>lowest</source>
+ <translation>самый низкий</translation>
+ </message>
+ <message>
+ <source>(%1 locked)</source>
+ <translation>(%1 заблокировано)</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>ничего</translation>
+ </message>
+ <message>
+ <source>This label turns red if the transaction size is greater than 1000 bytes.</source>
+ <translation>Эта метка становится красной, если размер транзакции будет больше, чем 1000 байт.</translation>
+ </message>
+ <message>
+ <source>This label turns red if the priority is smaller than "medium".</source>
+ <translation>Эта метка становится красной, если приоритет меньше, чем "среднее".</translation>
+ </message>
+ <message>
+ <source>This label turns red if any recipient receives an amount smaller than %1.</source>
+ <translation>Эта метка становится красной, если любой из получателей принимает количество меньше, чем %1.</translation>
+ </message>
+ <message>
+ <source>Can vary +/- %1 satoshi(s) per input.</source>
+ <translation>Может отличаться на +/- %1 сатоши на вход.</translation>
+ </message>
+ <message>
+ <source>yes</source>
+ <translation>да</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>нет</translation>
+ </message>
+ <message>
+ <source>This means a fee of at least %1 per kB is required.</source>
+ <translation>Это значит, что требуется комиссия как минимум %1 на КБ.</translation>
+ </message>
+ <message>
+ <source>Can vary +/- 1 byte per input.</source>
+ <translation>Может отличаться на +/- 1 байт на вход.</translation>
+ </message>
+ <message>
+ <source>Transactions with higher priority are more likely to get included into a block.</source>
+ <translation>Транзакции с более высоким приоритетом будут вероятнее других включены в блок.</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>[нет метки]</translation>
+ </message>
+ <message>
+ <source>change from %1 (%2)</source>
+ <translation>сдача с %1 (%2)</translation>
+ </message>
+ <message>
+ <source>(change)</source>
+ <translation>(размен)</translation>
+ </message>
+</context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>Изменить адрес</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>&amp;Метка</translation>
+ </message>
+ <message>
+ <source>The label associated with this address list entry</source>
+ <translation>Метка, связанная с этой записью списка адресов</translation>
+ </message>
+ <message>
+ <source>The address associated with this address list entry. This can only be modified for sending addresses.</source>
+ <translation>Адрес, связанный с этой записью списка адресов. Он может быть изменён только для адресов отправки.</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;Адрес</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>Новый адрес для получения</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>Новый адрес для отправки</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>Изменение адреса для получения</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>Изменение адреса для отправки</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>Введённый адрес «%1» уже находится в адресной книге.</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is not a valid Bitcoin address.</source>
+ <translation>Введённый адрес "%1" не является правильным Bitcoin-адресом.</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>Не удается разблокировать бумажник.</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>Генерация нового ключа не удалась.</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ <message>
+ <source>A new data directory will be created.</source>
+ <translation>Будет создан новый каталог данных.</translation>
+ </message>
+ <message>
+ <source>name</source>
+ <translation>имя</translation>
+ </message>
+ <message>
+ <source>Directory already exists. Add %1 if you intend to create a new directory here.</source>
+ <translation>Каталог уже существует. Добавьте %1, если вы хотите создать здесь новый каталог.</translation>
+ </message>
+ <message>
+ <source>Path already exists, and is not a directory.</source>
+ <translation>Путь уже существует и не является каталогом.</translation>
+ </message>
+ <message>
+ <source>Cannot create data directory here.</source>
+ <translation>Не удаётся создать здесь каталог данных.</translation>
+ </message>
+</context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>версия</translation>
+ </message>
+ <message>
+ <source>(%1-bit)</source>
+ <translation>(%1-бит)</translation>
+ </message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>О Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Command-line options</source>
+ <translation>Параметры командной строки</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>Использование:</translation>
+ </message>
+ <message>
+ <source>command-line options</source>
+ <translation>параметры командной строки</translation>
+ </message>
+</context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Welcome</source>
+ <translation>Добро пожаловать</translation>
+ </message>
+ <message>
+ <source>Welcome to Bitcoin Core.</source>
+ <translation>Добро пожаловать в Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</source>
+ <translation>Так как вы впервые запустили программу, вы можете выбрать, где Bitcoin Core будет хранить данные.</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory.</source>
+ <translation>Bitcoin Core скачает и сохранит копию цепи блоков. Как минимум, %1ГБ данных будет храниться в этом каталоге, и со временем он будет расти. Бумажник будет также сохранён в этом каталоге.</translation>
+ </message>
+ <message>
+ <source>Use the default data directory</source>
+ <translation>Использовать каталог данных по умолчанию</translation>
+ </message>
+ <message>
+ <source>Use a custom data directory:</source>
+ <translation>Использовать другой каталог данных:</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Error: Specified data directory "%1" cannot be created.</source>
+ <translation>Ошибка: не удалось создать указанный каталог данных "%1".</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Ошибка</translation>
+ </message>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ <message>
+ <source>Open URI</source>
+ <translation>Открыть URI</translation>
+ </message>
+ <message>
+ <source>Open payment request from URI or file</source>
+ <translation>Открыть запрос платежа из URI или файла</translation>
+ </message>
+ <message>
+ <source>URI:</source>
+ <translation>URI:</translation>
+ </message>
+ <message>
+ <source>Select payment request file</source>
+ <translation>Выбрать файл запроса платежа</translation>
+ </message>
+ <message>
+ <source>Select payment request file to open</source>
+ <translation>Выберите файл запроса платежа</translation>
+ </message>
+</context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>Параметры</translation>
+ </message>
+ <message>
+ <source>&amp;Main</source>
+ <translation>&amp;Главная</translation>
+ </message>
+ <message>
+ <source>Size of &amp;database cache</source>
+ <translation>Размер кэша &amp;БД</translation>
+ </message>
+ <message>
+ <source>MB</source>
+ <translation>МБ</translation>
+ </message>
+ <message>
+ <source>Number of script &amp;verification threads</source>
+ <translation>Число потоков проверки &amp;сценария</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside</source>
+ <translation>Разрешать соединения извне</translation>
+ </message>
+ <message>
+ <source>Allow incoming connections</source>
+ <translation>Разрешить входящие подключения</translation>
+ </message>
+ <message>
+ <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
+ <translation>IP-адрес прокси (например IPv4: 127.0.0.1 / IPv6: ::1)</translation>
+ </message>
+ <message>
+ <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source>
+ <translation>Сворачивать вместо закрытия. Если данная опция будет выбрана — приложение закроется только после выбора соответствующего пункта в меню.</translation>
+ </message>
+ <message>
+ <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source>
+ <translation>Здесь можно выбрать язык интерфейса. Настройки вступят в силу после перезапуска Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source>
+ <translation>Сторонние URL (например, block explorer), которые отображаются на вкладке транзакций как пункты контекстного меню. %s в URL заменяется хэшем транзакции. URL отделяются друг от друга вертикальной чертой |.</translation>
+ </message>
+ <message>
+ <source>Third party transaction URLs</source>
+ <translation>Сторонние URL транзакций.</translation>
+ </message>
+ <message>
+ <source>Active command-line options that override above options:</source>
+ <translation>Активные опции командной строки, которые перекрывают вышеуказанные опции:</translation>
+ </message>
+ <message>
+ <source>Reset all client options to default.</source>
+ <translation>Сбросить все настройки клиента на значения по умолчанию.</translation>
+ </message>
+ <message>
+ <source>&amp;Reset Options</source>
+ <translation>&amp;Сбросить параметры</translation>
+ </message>
+ <message>
+ <source>&amp;Network</source>
+ <translation>&amp;Сеть</translation>
+ </message>
+ <message>
+ <source>Automatically start Bitcoin Core after logging in to the system.</source>
+ <translation>Автоматически запускать Bitcoin Core после входа в систему</translation>
+ </message>
+ <message>
+ <source>&amp;Start Bitcoin Core on system login</source>
+ <translation>&amp;Запускать Bitcoin Core при входе в систему</translation>
+ </message>
+ <message>
+ <source>(0 = auto, &lt;0 = leave that many cores free)</source>
+ <translation>(0 = автоматически, &lt;0 = оставить столько незагруженных ядер)</translation>
+ </message>
+ <message>
+ <source>W&amp;allet</source>
+ <translation>Б&amp;умажник</translation>
+ </message>
+ <message>
+ <source>Expert</source>
+ <translation>Эксперт</translation>
+ </message>
+ <message>
+ <source>Enable coin &amp;control features</source>
+ <translation>Включить управление входами</translation>
+ </message>
+ <message>
+ <source>If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.</source>
+ <translation>При отключении траты неподтверждённой сдачи, сдача от транзакции не может быть использована до тех пор пока у этой транзакции не будет хотя бы одно подтверждение. Это также влияет как ваш баланс рассчитывается.</translation>
+ </message>
+ <message>
+ <source>&amp;Spend unconfirmed change</source>
+ <translation>&amp;Тратить неподтверждённую сдачу</translation>
+ </message>
+ <message>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>Автоматически открыть порт для Bitcoin-клиента на роутере. Работает только если Ваш роутер поддерживает UPnP, и данная функция включена.</translation>
+ </message>
+ <message>
+ <source>Map port using &amp;UPnP</source>
+ <translation>Пробросить порт через &amp;UPnP</translation>
+ </message>
+ <message>
+ <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
+ <translation>Подключаться к сети Bitcoin через прокси SOCKS5</translation>
+ </message>
+ <message>
+ <source>&amp;Connect through SOCKS5 proxy (default proxy):</source>
+ <translation>&amp;Подключаться к сети Bitcoin через прокси SOCKS5 (прокси по умолчанию):</translation>
+ </message>
+ <message>
+ <source>Proxy &amp;IP:</source>
+ <translation>&amp;IP Прокси: </translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>По&amp;рт: </translation>
+ </message>
+ <message>
+ <source>Port of the proxy (e.g. 9050)</source>
+ <translation>Порт прокси-сервера (например, 9050)</translation>
+ </message>
+ <message>
+ <source>&amp;Window</source>
+ <translation>&amp;Окно</translation>
+ </message>
+ <message>
+ <source>Show only a tray icon after minimizing the window.</source>
+ <translation>Показывать только иконку в системном лотке после сворачивания окна.</translation>
+ </message>
+ <message>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>&amp;Cворачивать в системный лоток вместо панели задач</translation>
+ </message>
+ <message>
+ <source>M&amp;inimize on close</source>
+ <translation>С&amp;ворачивать при закрытии</translation>
+ </message>
+ <message>
+ <source>&amp;Display</source>
+ <translation>О&amp;тображение</translation>
+ </message>
+ <message>
+ <source>User Interface &amp;language:</source>
+ <translation>&amp;Язык интерфейса:</translation>
+ </message>
+ <message>
+ <source>&amp;Unit to show amounts in:</source>
+ <translation>&amp;Отображать суммы в единицах: </translation>
+ </message>
+ <message>
+ <source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
+ <translation>Выберите единицу измерения монет при отображении и отправке.</translation>
+ </message>
+ <message>
+ <source>Whether to show coin control features or not.</source>
+ <translation>Показывать ли функции контроля монет или нет.</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>&amp;OK</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>&amp;Отмена</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>по умолчанию</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>ничего</translation>
+ </message>
+ <message>
+ <source>Confirm options reset</source>
+ <translation>Подтвердите сброс параметров</translation>
+ </message>
+ <message>
+ <source>Client restart required to activate changes.</source>
+ <translation>Для применения изменений требуется перезапуск клиента.</translation>
+ </message>
+ <message>
+ <source>Client will be shut down. Do you want to proceed?</source>
+ <translation>Клиент будет выключен. Желаете продолжить?</translation>
+ </message>
+ <message>
+ <source>This change would require a client restart.</source>
+ <translation>Это изменение потребует перезапуска клиента.</translation>
+ </message>
+ <message>
+ <source>The supplied proxy address is invalid.</source>
+ <translation>Адрес прокси неверен.</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>Форма</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>Отображаемая информация может быть устаревшей. Ваш бумажник автоматически синхронизируется с сетью Bitcoin после подключения, но этот процесс пока не завершён.</translation>
+ </message>
+ <message>
+ <source>Watch-only:</source>
+ <translation>Только наблюдение:</translation>
+ </message>
+ <message>
+ <source>Available:</source>
+ <translation>Доступно:</translation>
+ </message>
+ <message>
+ <source>Your current spendable balance</source>
+ <translation>Ваш текущий расходный баланс</translation>
+ </message>
+ <message>
+ <source>Pending:</source>
+ <translation>В ожидании:</translation>
+ </message>
+ <message>
+ <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source>
+ <translation>Общая сумма всех транзакций, которые до сих пор не подтверждены, и до сих пор не учитываются в расходном балансе</translation>
+ </message>
+ <message>
+ <source>Immature:</source>
+ <translation>Незрелые:</translation>
+ </message>
+ <message>
+ <source>Mined balance that has not yet matured</source>
+ <translation>Баланс добытых монет, который ещё не созрел</translation>
+ </message>
+ <message>
+ <source>Balances</source>
+ <translation>Балансы</translation>
+ </message>
+ <message>
+ <source>Total:</source>
+ <translation>Итого:</translation>
+ </message>
+ <message>
+ <source>Your current total balance</source>
+ <translation>Ваш текущий общий баланс</translation>
+ </message>
+ <message>
+ <source>Your current balance in watch-only addresses</source>
+ <translation>Ваш текущий баланс в адресах наблюдения</translation>
+ </message>
+ <message>
+ <source>Spendable:</source>
+ <translation>Доступно:</translation>
+ </message>
+ <message>
+ <source>Recent transactions</source>
+ <translation>Последние транзакции</translation>
+ </message>
+ <message>
+ <source>Unconfirmed transactions to watch-only addresses</source>
+ <translation>Неподтверждённые транзакции на адреса наблюдения</translation>
+ </message>
+ <message>
+ <source>Mined balance in watch-only addresses that has not yet matured</source>
+ <translation>Баланс добытых монет на адресах наблюдения, который ещё не созрел</translation>
+ </message>
+ <message>
+ <source>Current total balance in watch-only addresses</source>
+ <translation>Текущий общий баланс на адресах наблюдения</translation>
+ </message>
+</context>
+<context>
+ <name>PaymentServer</name>
+ <message>
+ <source>URI handling</source>
+ <translation>Обработка URI</translation>
+ </message>
+ <message>
+ <source>Invalid payment address %1</source>
+ <translation>Неверный адрес платежа %1</translation>
+ </message>
+ <message>
+ <source>Payment request rejected</source>
+ <translation>Запрос платежа отклонён</translation>
+ </message>
+ <message>
+ <source>Payment request network doesn't match client network.</source>
+ <translation>Сеть запроса платежа не совпадает с сетью клиента.</translation>
+ </message>
+ <message>
+ <source>Payment request is not initialized.</source>
+ <translation>Запрос платежа не инициализирован.</translation>
+ </message>
+ <message>
+ <source>Requested payment amount of %1 is too small (considered dust).</source>
+ <translation>Запрошенная сумма платежа %1 слишком мала (считается пылью).</translation>
+ </message>
+ <message>
+ <source>Payment request error</source>
+ <translation>Ошибка запроса платежа</translation>
+ </message>
+ <message>
+ <source>Cannot start bitcoin: click-to-pay handler</source>
+ <translation>Не удаётся запустить bitcoin: обработчик click-to-pay</translation>
+ </message>
+ <message>
+ <source>Payment request fetch URL is invalid: %1</source>
+ <translation>Неверный URL запроса платежа: %1</translation>
+ </message>
+ <message>
+ <source>URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source>
+ <translation>Не удалось обработать URI! Это может быть связано с неверным адресом Bitcoin или неправильными параметрами URI.</translation>
+ </message>
+ <message>
+ <source>Payment request file handling</source>
+ <translation>Обработка файла запроса платежа</translation>
+ </message>
+ <message>
+ <source>Payment request file cannot be read! This can be caused by an invalid payment request file.</source>
+ <translation>Файл запроса платежа не может быть прочитан! Обычно это происходит из-за неверного файла запроса платежа.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>Запрос платежа просрочен.</translation>
+ </message>
+ <message>
+ <source>Unverified payment requests to custom payment scripts are unsupported.</source>
+ <translation>Непроверенные запросы платежей с нестандартными платёжными сценариями не поддерживаются.</translation>
+ </message>
+ <message>
+ <source>Invalid payment request.</source>
+ <translation>Неверный запрос платежа.</translation>
+ </message>
+ <message>
+ <source>Refund from %1</source>
+ <translation>Возврат от %1</translation>
+ </message>
+ <message>
+ <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source>
+ <translation>Запрос платежа %1 слишком большой (%2 байтов, разрешено %3 байтов).</translation>
+ </message>
+ <message>
+ <source>Payment request DoS protection</source>
+ <translation>DoS-защита запроса платежа</translation>
+ </message>
+ <message>
+ <source>Error communicating with %1: %2</source>
+ <translation>Ошибка связи с %1: %2</translation>
+ </message>
+ <message>
+ <source>Payment request cannot be parsed!</source>
+ <translation>Запрос платежа не может быть разобран!</translation>
+ </message>
+ <message>
+ <source>Bad response from server %1</source>
+ <translation>Плохой ответ от сервера %1</translation>
+ </message>
+ <message>
+ <source>Payment acknowledged</source>
+ <translation>Платёж принят</translation>
+ </message>
+ <message>
+ <source>Network request error</source>
+ <translation>Ошибка сетевого запроса</translation>
+ </message>
+</context>
+<context>
+ <name>PeerTableModel</name>
+ <message>
+ <source>User Agent</source>
+ <translation>Юзер-агент</translation>
+ </message>
+ <message>
+ <source>Node/Service</source>
+ <translation>Узел/сервис</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Время задержки</translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>Сумма</translation>
+ </message>
+ <message>
+ <source>Enter a Bitcoin address (e.g. %1)</source>
+ <translation>Введите адрес Bitcoin (например, %1)</translation>
+ </message>
+ <message>
+ <source>%1 d</source>
+ <translation>%1 д</translation>
+ </message>
+ <message>
+ <source>%1 h</source>
+ <translation>%1 ч</translation>
+ </message>
+ <message>
+ <source>%1 m</source>
+ <translation>%1 мин</translation>
+ </message>
+ <message>
+ <source>%1 s</source>
+ <translation>%1 с</translation>
+ </message>
+ <message>
+ <source>None</source>
+ <translation>Ничего</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>Н/Д</translation>
+ </message>
+ <message>
+ <source>%1 ms</source>
+ <translation>%1 мс</translation>
+ </message>
+</context>
+<context>
+ <name>QRImageWidget</name>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Сохранить изображение...</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Image</source>
+ <translation>&amp;Копировать изображение</translation>
+ </message>
+ <message>
+ <source>Save QR Code</source>
+ <translation>Сохранить QR-код</translation>
+ </message>
+ <message>
+ <source>PNG Image (*.png)</source>
+ <translation>Изображение PNG (*.png)</translation>
+ </message>
+</context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>Client name</source>
+ <translation>Имя клиента</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>Н/Д</translation>
+ </message>
+ <message>
+ <source>Client version</source>
+ <translation>Версия клиента</translation>
+ </message>
+ <message>
+ <source>&amp;Information</source>
+ <translation>&amp;Информация</translation>
+ </message>
+ <message>
+ <source>Debug window</source>
+ <translation>Окно отладки</translation>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>Общие</translation>
+ </message>
+ <message>
+ <source>Using OpenSSL version</source>
+ <translation>Используется версия OpenSSL</translation>
+ </message>
+ <message>
+ <source>Using BerkeleyDB version</source>
+ <translation>Используется версия BerkeleyDB</translation>
+ </message>
+ <message>
+ <source>Startup time</source>
+ <translation>Время запуска</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Сеть</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>Имя</translation>
+ </message>
+ <message>
+ <source>Number of connections</source>
+ <translation>Число подключений</translation>
+ </message>
+ <message>
+ <source>Block chain</source>
+ <translation>Цепь блоков</translation>
+ </message>
+ <message>
+ <source>Current number of blocks</source>
+ <translation>Текущее число блоков</translation>
+ </message>
+ <message>
+ <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source>
+ <translation>Открыть отладочный лог-файл Bitcoin Core из текущего каталога данных. Это может занять несколько секунд для больших лог-файлов.</translation>
+ </message>
+ <message>
+ <source>Received</source>
+ <translation>Получено</translation>
+ </message>
+ <message>
+ <source>Sent</source>
+ <translation>Отправлено</translation>
+ </message>
+ <message>
+ <source>&amp;Peers</source>
+ <translation>&amp;Участники</translation>
+ </message>
+ <message>
+ <source>Select a peer to view detailed information.</source>
+ <translation>Выберите участника для просмотра подробностей.</translation>
+ </message>
+ <message>
+ <source>Direction</source>
+ <translation>Направление</translation>
+ </message>
+ <message>
+ <source>Version</source>
+ <translation>Версия</translation>
+ </message>
+ <message>
+ <source>User Agent</source>
+ <translation>Юзер-агент</translation>
+ </message>
+ <message>
+ <source>Services</source>
+ <translation>Сервисы</translation>
+ </message>
+ <message>
+ <source>Starting Height</source>
+ <translation>Начальная высота</translation>
+ </message>
+ <message>
+ <source>Sync Height</source>
+ <translation>Высота синхронизации</translation>
+ </message>
+ <message>
+ <source>Ban Score</source>
+ <translation>Очков бана</translation>
+ </message>
+ <message>
+ <source>Connection Time</source>
+ <translation>Время соединения</translation>
+ </message>
+ <message>
+ <source>Last Send</source>
+ <translation>Последняя отправка</translation>
+ </message>
+ <message>
+ <source>Last Receive</source>
+ <translation>Последний раз получено</translation>
+ </message>
+ <message>
+ <source>Bytes Sent</source>
+ <translation>Байт передано</translation>
+ </message>
+ <message>
+ <source>Bytes Received</source>
+ <translation>Байт получено</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Время задержки</translation>
+ </message>
+ <message>
+ <source>Time Offset</source>
+ <translation>Смещение времени</translation>
+ </message>
+ <message>
+ <source>Last block time</source>
+ <translation>Время последнего блока</translation>
+ </message>
+ <message>
+ <source>&amp;Open</source>
+ <translation>&amp;Открыть</translation>
+ </message>
+ <message>
+ <source>&amp;Console</source>
+ <translation>Консоль</translation>
+ </message>
+ <message>
+ <source>&amp;Network Traffic</source>
+ <translation>Сетевой &amp;трафик</translation>
+ </message>
+ <message>
+ <source>&amp;Clear</source>
+ <translation>&amp;Очистить</translation>
+ </message>
+ <message>
+ <source>Totals</source>
+ <translation>Всего</translation>
+ </message>
+ <message>
+ <source>In:</source>
+ <translation>Вход:</translation>
+ </message>
+ <message>
+ <source>Out:</source>
+ <translation>Выход:</translation>
+ </message>
+ <message>
+ <source>Build date</source>
+ <translation>Дата сборки</translation>
+ </message>
+ <message>
+ <source>Debug log file</source>
+ <translation>Отладочный лог-файл</translation>
+ </message>
+ <message>
+ <source>Clear console</source>
+ <translation>Очистить консоль</translation>
+ </message>
+ <message>
+ <source>Welcome to the Bitcoin Core RPC console.</source>
+ <translation>Добро пожаловать в RPC-консоль Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
+ <translation>Используйте стрелки вверх и вниз для просмотра истории и &lt;b&gt;Ctrl-L&lt;/b&gt; для очистки экрана.</translation>
+ </message>
+ <message>
+ <source>Type &lt;b&gt;help&lt;/b&gt; for an overview of available commands.</source>
+ <translation>Напишите &lt;b&gt;help&lt;/b&gt; для просмотра доступных команд.</translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation>%1 Б</translation>
+ </message>
+ <message>
+ <source>%1 KB</source>
+ <translation>%1 КБ</translation>
+ </message>
+ <message>
+ <source>%1 MB</source>
+ <translation>%1 МБ</translation>
+ </message>
+ <message>
+ <source>%1 GB</source>
+ <translation>%1 ГБ</translation>
+ </message>
+ <message>
+ <source>via %1</source>
+ <translation>через %1</translation>
+ </message>
+ <message>
+ <source>never</source>
+ <translation>никогда</translation>
+ </message>
+ <message>
+ <source>Inbound</source>
+ <translation>Входящие</translation>
+ </message>
+ <message>
+ <source>Outbound</source>
+ <translation>Исходящие</translation>
+ </message>
+ <message>
+ <source>Unknown</source>
+ <translation>Неизвестно</translation>
+ </message>
+ <message>
+ <source>Fetching...</source>
+ <translation>Получение...</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Amount:</source>
+ <translation>&amp;Сумма:</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Метка:</translation>
+ </message>
+ <message>
+ <source>&amp;Message:</source>
+ <translation>&amp;Сообщение</translation>
+ </message>
+ <message>
+ <source>Reuse one of the previously used receiving addresses. Reusing addresses has security and privacy issues. Do not use this unless re-generating a payment request made before.</source>
+ <translation>Повторно использовать один из ранее использованных адресов. Повторное использование адресов несёт риски безопасности и приватности. Не используйте эту опцию, если вы не создаёте повторно ранее сделанный запрос платежа.</translation>
+ </message>
+ <message>
+ <source>R&amp;euse an existing receiving address (not recommended)</source>
+ <translation>&amp;Повторно использовать существующий адрес получения (не рекомендуется)</translation>
+ </message>
+ <message>
+ <source>An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network.</source>
+ <translation>Необязательное сообщение для запроса платежа, которое будет показано при открытии запроса. Заметьте: сообщение не будет отправлено вместе с платежом через сеть Bitcoin.</translation>
+ </message>
+ <message>
+ <source>An optional label to associate with the new receiving address.</source>
+ <translation>Необязательная метка для нового адреса получения.</translation>
+ </message>
+ <message>
+ <source>Use this form to request payments. All fields are &lt;b&gt;optional&lt;/b&gt;.</source>
+ <translation>Заполните форму для запроса платежей. Все поля &lt;b&gt;необязательны&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>An optional amount to request. Leave this empty or zero to not request a specific amount.</source>
+ <translation>Необязательная сумма для запроса. Оставьте пустым или укажите ноль, чтобы запросить неопределённую сумму.</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Очистить все поля формы.</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation>Очистить</translation>
+ </message>
+ <message>
+ <source>Requested payments history</source>
+ <translation>История запрошенных платежей</translation>
+ </message>
+ <message>
+ <source>&amp;Request payment</source>
+ <translation>&amp;Запросить платёж</translation>
+ </message>
+ <message>
+ <source>Show the selected request (does the same as double clicking an entry)</source>
+ <translation>Показать выбранный запрос (то же самое, что и двойной клик по записи)</translation>
+ </message>
+ <message>
+ <source>Show</source>
+ <translation>Показать</translation>
+ </message>
+ <message>
+ <source>Remove the selected entries from the list</source>
+ <translation>Удалить выбранные записи из списка</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>Удалить</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Копировать метку</translation>
+ </message>
+ <message>
+ <source>Copy message</source>
+ <translation>Копировать сообщение</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Скопировать сумму</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>QR Code</source>
+ <translation>QR код</translation>
+ </message>
+ <message>
+ <source>Copy &amp;URI</source>
+ <translation>Копировать &amp;URI</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Address</source>
+ <translation>Копировать &amp;адрес</translation>
+ </message>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Сохранить изображение...</translation>
+ </message>
+ <message>
+ <source>Request payment to %1</source>
+ <translation>Запросить платёж на %1</translation>
+ </message>
+ <message>
+ <source>Payment information</source>
+ <translation>Информация платежа</translation>
+ </message>
+ <message>
+ <source>URI</source>
+ <translation>URI</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Адрес</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Сумма</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Метка</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Сообщение</translation>
+ </message>
+ <message>
+ <source>Resulting URI too long, try to reduce the text for label / message.</source>
+ <translation>Получившийся URI слишком длинный, попробуйте сократить текст метки / сообщения.</translation>
+ </message>
+ <message>
+ <source>Error encoding URI into QR Code.</source>
+ <translation>Ошибка кодирования URI в QR-код</translation>
+ </message>
+</context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Дата</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Метка</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Сообщение</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Сумма</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>[нет метки]</translation>
+ </message>
+ <message>
+ <source>(no message)</source>
+ <translation>(нет сообщения)</translation>
+ </message>
+ <message>
+ <source>(no amount)</source>
+ <translation>(нет суммы)</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Отправка</translation>
+ </message>
+ <message>
+ <source>Coin Control Features</source>
+ <translation>Функции Контроля Монет</translation>
+ </message>
+ <message>
+ <source>Inputs...</source>
+ <translation>Входы...</translation>
+ </message>
+ <message>
+ <source>automatically selected</source>
+ <translation>автоматически выбрано</translation>
+ </message>
+ <message>
+ <source>Insufficient funds!</source>
+ <translation>Недостаточно средств!</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Количество:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Байт:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Сумма:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Приоритет:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Комиссия:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>После комиссии:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Размен:</translation>
+ </message>
+ <message>
+ <source>If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address.</source>
+ <translation>Если это выбрано, но адрес сдачи пустой или неверный, сдача будет отправлена на новый сгенерированный адрес.</translation>
+ </message>
+ <message>
+ <source>Custom change address</source>
+ <translation>Свой адрес для сдачи</translation>
+ </message>
+ <message>
+ <source>Transaction Fee:</source>
+ <translation>Комиссия</translation>
+ </message>
+ <message>
+ <source>Choose...</source>
+ <translation>Выберите...</translation>
+ </message>
+ <message>
+ <source>collapse fee-settings</source>
+ <translation>Свернуть настройки комиссии</translation>
+ </message>
+ <message>
+ <source>per kilobyte</source>
+ <translation>за килобайт</translation>
+ </message>
+ <message>
+ <source>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "total at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source>
+ <translation>Если комиссия установлена в 1000 сатоши, а транзакция составляет лишь 250 байт, тогда комиссия "на килобайт" составит 250 сатоши, а "всего как минимум" — 1000 сатоши. Для транзакций крупнее килобайта в обоих случаях будет использоваться платёж "на килобайт".</translation>
+ </message>
+ <message>
+ <source>Hide</source>
+ <translation>Скрыть</translation>
+ </message>
+ <message>
+ <source>total at least</source>
+ <translation>Итого как минимум</translation>
+ </message>
+ <message>
+ <source>Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process.</source>
+ <translation>Уплата минимальной комиссии — не проблема, пока объём транзакций меньше, чем свободное место в блоках. Учтите, однако, что такая транзакция может никогда не подтвердиться, если спрос на транзакции превышает возможности сети по их обработке.</translation>
+ </message>
+ <message>
+ <source>(read the tooltip)</source>
+ <translation>(прочтите подсказку)</translation>
+ </message>
+ <message>
+ <source>Recommended:</source>
+ <translation>Рекомендовано:</translation>
+ </message>
+ <message>
+ <source>Custom:</source>
+ <translation>Выборочно:</translation>
+ </message>
+ <message>
+ <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source>
+ <translation>(Умная комиссия пока не инициализирована. Обычно для этого требуется несколько блоков...)</translation>
+ </message>
+ <message>
+ <source>Confirmation time:</source>
+ <translation>Время подтверждения:</translation>
+ </message>
+ <message>
+ <source>normal</source>
+ <translation>обычный</translation>
+ </message>
+ <message>
+ <source>fast</source>
+ <translation>ускоренный</translation>
+ </message>
+ <message>
+ <source>Send as zero-fee transaction if possible</source>
+ <translation>Осуществить транзакцию бесплатно, если возможно</translation>
+ </message>
+ <message>
+ <source>(confirmation may take longer)</source>
+ <translation>(подтверждение может занять больше времени)</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>Отправить нескольким получателям одновременно</translation>
+ </message>
+ <message>
+ <source>Add &amp;Recipient</source>
+ <translation>&amp;Добавить получателя</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Очистить все поля формы</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Пыль:</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Очистить &amp;всё</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>Баланс:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>Подтвердить отправку</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>&amp;Отправить</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>Подтвердите отправку монет</translation>
+ </message>
+ <message>
+ <source>%1 to %2</source>
+ <translation>С %1 на %2</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Копировать количество</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Скопировать сумму</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Копировать комиссию</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Копировать после комиссии</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Копировать байты</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Копировать приоритет</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Копировать размен</translation>
+ </message>
+ <message>
+ <source>or</source>
+ <translation>или</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>Сумма для отправки должно быть больше 0.</translation>
+ </message>
+ <message>
+ <source>The amount exceeds your balance.</source>
+ <translation>Сумма превышает Ваш баланс</translation>
+ </message>
+ <message>
+ <source>The total exceeds your balance when the %1 transaction fee is included.</source>
+ <translation>Сумма превысит Ваш баланс, если комиссия в размере %1 будет добавлена к транзакции</translation>
+ </message>
+ <message>
+ <source>Transaction creation failed!</source>
+ <translation>Не удалось создать транзакцию!</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>Транзакция была отклонена! Такое может произойти, если некоторые монеты уже были потрачены, например, если Вы используете одну копию бумажника (wallet.dat), а монеты были потрачены из другой копии, но не были отмечены как потраченные в этой.</translation>
+ </message>
+ <message>
+ <source>A fee higher than %1 is considered an absurdly high fee.</source>
+ <translation>Комиссия больше, чем %1, считается невероятно большой.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>Запрос платежа просрочен.</translation>
+ </message>
+ <message>
+ <source>Total Amount %1&lt;span style='font-size:10pt;font-weight:normal;'&gt;&lt;br /&gt;(=%2)&lt;/span&gt;</source>
+ <translation>Всего %1&lt;span style='font-size:10pt;font-weight:normal;'&gt;&lt;br /&gt;(=%2)&lt;/span&gt;</translation>
+ </message>
+ <message>
+ <source>The recipient address is not valid. Please recheck.</source>
+ <translation>Адрес получателя неверный. Пожалуйста, перепроверьте.</translation>
+ </message>
+ <message>
+ <source>Duplicate address found: addresses should only be used once each.</source>
+ <translation>Обнаружен дублирующийся адрес: используйте каждый адрес только один раз.</translation>
+ </message>
+ <message>
+ <source>Warning: Invalid Bitcoin address</source>
+ <translation>Внимание: неверный адрес Bitcoin</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>[нет метки]</translation>
+ </message>
+ <message>
+ <source>Warning: Unknown change address</source>
+ <translation>Внимание: неизвестный адрес для сдачи</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Копировать пыль</translation>
+ </message>
+ <message>
+ <source>Are you sure you want to send?</source>
+ <translation>Вы уверены, что хотите отправить?</translation>
+ </message>
+ <message>
+ <source>added as transaction fee</source>
+ <translation>добавлено как комиссия</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>Ко&amp;личество:</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>Полу&amp;чатель:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Введите метку для данного адреса (для добавления в адресную книгу)</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Метка:</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Выберите ранее использованный адрес</translation>
+ </message>
+ <message>
+ <source>This is a normal payment.</source>
+ <translation>Это нормальный платёж.</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to send the payment to</source>
+ <translation>Адрес Bitcoin, на который отправить платёж</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Вставить адрес из буфера обмена</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Remove this entry</source>
+ <translation>Удалить эту запись</translation>
+ </message>
+ <message>
+ <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source>
+ <translation>С отправляемой суммы будет удержана комиссия. Получателю придёт меньше биткоинов, чем вы вводите в поле количества. Если выбрано несколько получателей, комиссия распределяется поровну.</translation>
+ </message>
+ <message>
+ <source>S&amp;ubtract fee from amount</source>
+ <translation>Вычесть комиссию из суммы</translation>
+ </message>
+ <message>
+ <source>Message:</source>
+ <translation>Сообщение:</translation>
+ </message>
+ <message>
+ <source>This is an unauthenticated payment request.</source>
+ <translation>Это неавторизованный запрос платежа.</translation>
+ </message>
+ <message>
+ <source>This is an authenticated payment request.</source>
+ <translation>Это авторизованный запрос платежа.</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to the list of used addresses</source>
+ <translation>Введите метку для этого адреса, чтобы добавить его в список использованных</translation>
+ </message>
+ <message>
+ <source>A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network.</source>
+ <translation>К bitcoin: URI было прикреплено сообщение, которое будет сохранено вместе с транзакцией для вашего сведения. Заметьте: сообщение не будет отправлено через сеть Bitcoin.</translation>
+ </message>
+ <message>
+ <source>Pay To:</source>
+ <translation>Получатель:</translation>
+ </message>
+ <message>
+ <source>Memo:</source>
+ <translation>Примечание:</translation>
+ </message>
+</context>
+<context>
+ <name>ShutdownWindow</name>
+ <message>
+ <source>Bitcoin Core is shutting down...</source>
+ <translation>Bitcoin Core выключается...</translation>
+ </message>
+ <message>
+ <source>Do not shut down the computer until this window disappears.</source>
+ <translation>Не выключайте компьютер, пока это окно не исчезнет.</translation>
+ </message>
+</context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Signatures - Sign / Verify a Message</source>
+ <translation>Подписи - подписать/проверить сообщение</translation>
+ </message>
+ <message>
+ <source>&amp;Sign Message</source>
+ <translation>&amp;Подписать сообщение</translation>
+ </message>
+ <message>
+ <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source>
+ <translation>Вы можете подписывать сообщения/соглашения своими адресами, чтобы доказать свою возможность получать биткоины на них. Будьте осторожны, не подписывайте что-то неопределённое или случайное, так как фишинговые атаки могут обманным путём заставить вас подписать нежелательные сообщения. Подписывайте только те сообщения, с которыми вы согласны вплоть до мелочей.</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to sign the message with</source>
+ <translation>Адрес Bitcoin, которым подписать сообщение</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Выберите ранее использованный адрес</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Вставить адрес из буфера обмена</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Enter the message you want to sign here</source>
+ <translation>Введите сообщение для подписи</translation>
+ </message>
+ <message>
+ <source>Signature</source>
+ <translation>Подпись</translation>
+ </message>
+ <message>
+ <source>Copy the current signature to the system clipboard</source>
+ <translation>Скопировать текущую подпись в системный буфер обмена</translation>
+ </message>
+ <message>
+ <source>Sign the message to prove you own this Bitcoin address</source>
+ <translation>Подписать сообщение, чтобы доказать владение адресом Bitcoin</translation>
+ </message>
+ <message>
+ <source>Sign &amp;Message</source>
+ <translation>Подписать &amp;Сообщение</translation>
+ </message>
+ <message>
+ <source>Reset all sign message fields</source>
+ <translation>Сбросить значения всех полей подписывания сообщений</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Очистить &amp;всё</translation>
+ </message>
+ <message>
+ <source>&amp;Verify Message</source>
+ <translation>&amp;Проверить сообщение</translation>
+ </message>
+ <message>
+ <source>Enter the receiver's 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. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source>
+ <translation>Введите ниже адрес получателя, сообщение (убедитесь, что переводы строк, пробелы, табы и т.п. в точности скопированы) и подпись, чтобы проверить сообщение. Убедитесь, что не скопировали лишнего в подпись, по сравнению с самим подписываемым сообщением, чтобы не стать жертвой атаки "man-in-the-middle". Заметьте, что эта операция удостоверяет лишь авторство подписавшего, но не может удостоверить отправителя транзакции.</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address the message was signed with</source>
+ <translation>Адрес Bitcoin, которым было подписано сообщение</translation>
+ </message>
+ <message>
+ <source>Verify the message to ensure it was signed with the specified Bitcoin address</source>
+ <translation>Проверить сообщение, чтобы убедиться, что оно было подписано указанным адресом Bitcoin</translation>
+ </message>
+ <message>
+ <source>Verify &amp;Message</source>
+ <translation>Проверить &amp;Сообщение</translation>
+ </message>
+ <message>
+ <source>Reset all verify message fields</source>
+ <translation>Сбросить все поля проверки сообщения</translation>
+ </message>
+ <message>
+ <source>Click "Sign Message" to generate signature</source>
+ <translation>Нажмите "Подписать сообщение" для создания подписи</translation>
+ </message>
+ <message>
+ <source>The entered address is invalid.</source>
+ <translation>Введённый адрес неверен</translation>
+ </message>
+ <message>
+ <source>Please check the address and try again.</source>
+ <translation>Пожалуйста, проверьте адрес и попробуйте ещё раз.</translation>
+ </message>
+ <message>
+ <source>The entered address does not refer to a key.</source>
+ <translation>Введённый адрес не связан с ключом</translation>
+ </message>
+ <message>
+ <source>Wallet unlock was cancelled.</source>
+ <translation>Разблокировка бумажника была отменена.</translation>
+ </message>
+ <message>
+ <source>Private key for the entered address is not available.</source>
+ <translation>Для введённого адреса недоступен закрытый ключ</translation>
+ </message>
+ <message>
+ <source>Message signing failed.</source>
+ <translation>Не удалось подписать сообщение</translation>
+ </message>
+ <message>
+ <source>Message signed.</source>
+ <translation>Сообщение подписано</translation>
+ </message>
+ <message>
+ <source>The signature could not be decoded.</source>
+ <translation>Подпись не может быть раскодирована.</translation>
+ </message>
+ <message>
+ <source>Please check the signature and try again.</source>
+ <translation>Пожалуйста, проверьте подпись и попробуйте ещё раз.</translation>
+ </message>
+ <message>
+ <source>The signature did not match the message digest.</source>
+ <translation>Подпись не соответствует отпечатку сообщения.</translation>
+ </message>
+ <message>
+ <source>Message verification failed.</source>
+ <translation>Проверка сообщения не удалась.</translation>
+ </message>
+ <message>
+ <source>Message verified.</source>
+ <translation>Сообщение проверено.</translation>
+ </message>
+</context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>The Bitcoin Core developers</source>
+ <translation>Разработчики Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>[testnet]</source>
+ <translation>[тестовая сеть]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ <message>
+ <source>KB/s</source>
+ <translation>КБ/сек</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>Открыто до %1</translation>
+ </message>
+ <message>
+ <source>conflicted</source>
+ <translation>в противоречии</translation>
+ </message>
+ <message>
+ <source>%1/offline</source>
+ <translation>%1/отключен</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/не подтверждено</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 подтверждений</translation>
+ </message>
+ <message>
+ <source>Status</source>
+ <translation>Статус</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Дата</translation>
+ </message>
+ <message>
+ <source>Source</source>
+ <translation>Источник</translation>
+ </message>
+ <message>
+ <source>Generated</source>
+ <translation>Сгенерированно</translation>
+ </message>
+ <message>
+ <source>From</source>
+ <translation>От</translation>
+ </message>
+ <message>
+ <source>To</source>
+ <translation>Для</translation>
+ </message>
+ <message>
+ <source>own address</source>
+ <translation>свой адрес</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>только наблюдение</translation>
+ </message>
+ <message>
+ <source>label</source>
+ <translation>метка</translation>
+ </message>
+ <message>
+ <source>Credit</source>
+ <translation>Кредит</translation>
+ </message>
+ <message>
+ <source>not accepted</source>
+ <translation>не принято</translation>
+ </message>
+ <message>
+ <source>Debit</source>
+ <translation>Дебет</translation>
+ </message>
+ <message>
+ <source>Total debit</source>
+ <translation>Всего дебет</translation>
+ </message>
+ <message>
+ <source>Total credit</source>
+ <translation>Всего кредит</translation>
+ </message>
+ <message>
+ <source>Transaction fee</source>
+ <translation>Комиссия</translation>
+ </message>
+ <message>
+ <source>Net amount</source>
+ <translation>Чистая сумма</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Сообщение</translation>
+ </message>
+ <message>
+ <source>Comment</source>
+ <translation>Комментарий:</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>ID транзакции</translation>
+ </message>
+ <message>
+ <source>Merchant</source>
+ <translation>Продавец</translation>
+ </message>
+ <message>
+ <source>Generated coins must mature %1 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.</source>
+ <translation>Сгенерированные монеты должны подождать %1 блоков, прежде чем они могут быть потрачены. Когда Вы сгенерировали этот блок, он был отправлен в сеть для добавления в цепочку блоков. Если он не попадёт в цепь, его статус изменится на "не принят", и монеты будут недействительны. Это иногда происходит в случае, если другой узел сгенерирует блок на несколько секунд раньше вас.</translation>
+ </message>
+ <message>
+ <source>Debug information</source>
+ <translation>Отладочная информация</translation>
+ </message>
+ <message>
+ <source>Transaction</source>
+ <translation>Транзакция</translation>
+ </message>
+ <message>
+ <source>Inputs</source>
+ <translation>Входы</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Сумма</translation>
+ </message>
+ <message>
+ <source>true</source>
+ <translation>истина</translation>
+ </message>
+ <message>
+ <source>false</source>
+ <translation>ложь</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, ещё не было успешно разослано</translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>неизвестно</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>Детали транзакции</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>Эта панель отображает детальное описание транзакции.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Дата</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Тип</translation>
+ </message>
+ <message>
+ <source>Immature (%1 confirmations, will be available after %2)</source>
+ <translation>Незрелый (%1 подтверждений, будет доступен после %2)</translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>Открыто до %1</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>Подтверждено (%1 подтверждений)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>Этот блок не был получен другими узлами и, возможно, не будет принят!</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>Сгенерированно, но не подтверждено</translation>
+ </message>
+ <message>
+ <source>Offline</source>
+ <translation>Нет активных соединений с сетью</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Метка</translation>
+ </message>
+ <message>
+ <source>Unconfirmed</source>
+ <translation>Неподтверждено</translation>
+ </message>
+ <message>
+ <source>Conflicted</source>
+ <translation>В противоречии</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Получено</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>Получено от</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Отправлено</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>Отправлено себе</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Добыто</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>только наблюдение</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>[не доступно]</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>Статус транзакции. Подведите курсор к нужному полю для того, чтобы увидеть количество подтверждений.</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Дата и время, когда транзакция была получена.</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>Тип транзакции.</translation>
+ </message>
+ <message>
+ <source>Whether or not a watch-only address is involved in this transaction.</source>
+ <translation>Использовался ли в транзакции адрес для наблюдения.</translation>
+ </message>
+ <message>
+ <source>User-defined intent/purpose of the transaction.</source>
+ <translation>Определяемое пользователем намерение/цель транзакции.</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>Сумма, добавленная, или снятая с баланса.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>Все</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>Сегодня</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>На этой неделе</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>В этом месяце</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>В прошлом месяце</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>В этом году</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>Промежуток...</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Получено на</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Отправлено на</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>Отправленные себе</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Добытые</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>Другое</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>Введите адрес или метку для поиска</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>Мин. сумма</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Копировать адрес</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Копировать метку</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Скопировать сумму</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Скопировать ID транзакции</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>Изменить метку</translation>
+ </message>
+ <message>
+ <source>Show transaction details</source>
+ <translation>Показать подробности транзакции</translation>
+ </message>
+ <message>
+ <source>Export Transaction History</source>
+ <translation>Экспортировать историю транзакций</translation>
+ </message>
+ <message>
+ <source>Watch-only</source>
+ <translation>Для наблюдения</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Экспорт не удался</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the transaction history to %1.</source>
+ <translation>Произошла ошибка при сохранении истории транзакций в %1.</translation>
+ </message>
+ <message>
+ <source>Exporting Successful</source>
+ <translation>Экспорт успешно завершён</translation>
+ </message>
+ <message>
+ <source>The transaction history was successfully saved to %1.</source>
+ <translation>История транзакций была успешно сохранена в %1.</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Текст, разделённый запятыми (*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Подтверждено</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Дата</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Тип</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Метка</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Адрес</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>Промежуток от:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>до</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ <message>
+ <source>Unit to show amounts in. Click to select another unit.</source>
+ <translation>Единица измерения количества монет. Щёлкните для выбора другой единицы.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletFrame</name>
+ <message>
+ <source>No wallet has been loaded.</source>
+ <translation>Не был загружен ни один бумажник.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Отправка</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Экспорт</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Экспортировать данные из вкладки в файл</translation>
+ </message>
+ <message>
+ <source>Backup Wallet</source>
+ <translation>Сделать резервную копию бумажника</translation>
+ </message>
+ <message>
+ <source>Wallet Data (*.dat)</source>
+ <translation>Данные бумажника (*.dat)</translation>
+ </message>
+ <message>
+ <source>Backup Failed</source>
+ <translation>Резервное копирование не удалось</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the wallet data to %1.</source>
+ <translation>Произошла ошибка при сохранении данных бумажника в %1.</translation>
+ </message>
+ <message>
+ <source>The wallet data was successfully saved to %1.</source>
+ <translation>Данные бумажника были успешно сохранены в %1.</translation>
+ </message>
+ <message>
+ <source>Backup Successful</source>
+ <translation>Резервное копирование успешно завершено</translation>
+ </message>
+</context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>Параметры:</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>Задать каталог данных</translation>
+ </message>
+ <message>
+ <source>Connect to a node to retrieve peer addresses, and disconnect</source>
+ <translation>Подключиться к участнику, чтобы получить список адресов других участников и отключиться</translation>
+ </message>
+ <message>
+ <source>Specify your own public address</source>
+ <translation>Укажите ваш собственный публичный адрес</translation>
+ </message>
+ <message>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>Принимать командную строку и команды JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>Запускаться в фоне как демон и принимать команды</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>Использовать тестовую сеть</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
+ <translation>Принимать подключения извне (по умолчанию: 1, если не используется -proxy или -connect)</translation>
+ </message>
+ <message>
+ <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
+ <translation>Привязаться к указанному адресу и всегда прослушивать только его. Используйте [хост]:порт для IPv6</translation>
+ </message>
+ <message>
+ <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
+ <translation>Удалить все транзакции бумажника с возможностью восстановить эти части цепи блоков с помощью -rescan при запуске</translation>
+ </message>
+ <message>
+ <source>Distributed under the MIT software license, see the accompanying file COPYING or &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</source>
+ <translation>Распространяется под лицензией MIT, см. приложенный файл COPYING или &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</translation>
+ </message>
+ <message>
+ <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
+ <translation>Выполнить команду, когда меняется транзакция в бумажнике (%s в команде заменяется на TxID)</translation>
+ </message>
+ <message>
+ <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source>
+ <translation>Максимальная сумма комиссий для одной транзакции в бумажнике; слишком низкое значение может вызвать прерывание больших транзакций (по умолчанию: %s)</translation>
+ </message>
+ <message>
+ <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, &gt;%u = target size in MiB to use for block files)</source>
+ <translation>Уменьшить размер хранилища за счёт удаления (обрезания) старых блоков. Этот режим отключает поддержку бумажника и несовместим с -txindex. Внимание: переключение этой опции обратно потребует полной загрузки цепи блоков. (по умолчанию: 0 = отключить удаление блоков, &gt;%u = целевой размер в Мб для файлов блоков)</translation>
+ </message>
+ <message>
+ <source>Set the number of script verification threads (%u to %d, 0 = auto, &lt;0 = leave that many cores free, default: %d)</source>
+ <translation>Задать число потоков проверки скрипта (от %u до %d, 0=авто, &lt;0 = оставить столько ядер свободными, по умолчанию: %d)</translation>
+ </message>
+ <message>
+ <source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source>
+ <translation>Это пре-релизная тестовая сборка - используйте на свой страх и риск - не используйте для добычи или торговых приложений</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer. Bitcoin Core is probably already running.</source>
+ <translation>Не удалось забиндиться на %s на этом компьютере. Возможно, Bitcoin Core уже запущен.</translation>
+ </message>
+ <message>
+ <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>ВНИМАНИЕ: сгенерировано ненормально большое число блоков, %d блоков получено за последние %d часов (ожидалось %d)</translation>
+ </message>
+ <message>
+ <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>ВНИМАНИЕ: проверьте сетевое подключение, получено %d блоков за последние %d часов (ожидалось %d)</translation>
+ </message>
+ <message>
+ <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>Внимание: установлено очень большое значение -paytxfee. Это комиссия, которую вы заплатите при проведении транзакции.</translation>
+ </message>
+ <message>
+ <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source>
+ <translation>Внимание: похоже, в сети нет полного согласия! Некоторый майнеры, возможно, испытывают проблемы.</translation>
+ </message>
+ <message>
+ <source>Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.</source>
+ <translation>Внимание: мы не полностью согласны с подключенными участниками! Вам или другим участникам, возможно, следует обновиться.</translation>
+ </message>
+ <message>
+ <source>Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
+ <translation>Внимание: ошибка чтения wallet.dat! Все ключи прочитаны верно, но данные транзакций или записи адресной книги могут отсутствовать или быть неправильными.</translation>
+ </message>
+ <message>
+ <source>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</source>
+ <translation>Внимание: wallet.dat повреждён, данные спасены! Оригинальный wallet.dat сохранён как wallet.{timestamp}.bak в %s; если ваш баланс или транзакции некорректны, вы должны восстановить файл из резервной копии.</translation>
+ </message>
+ <message>
+ <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source>
+ <translation>Вносить в белый список участников, подключающихся с указанной маски сети или IP. Можно использовать многократно.</translation>
+ </message>
+ <message>
+ <source>(default: 1)</source>
+ <translation>(по умолчанию: 1)</translation>
+ </message>
+ <message>
+ <source>&lt;category&gt; can be:</source>
+ <translation>&lt;category&gt; может быть:</translation>
+ </message>
+ <message>
+ <source>Attempt to recover private keys from a corrupt wallet.dat</source>
+ <translation>Попытаться восстановить приватные ключи из повреждённого wallet.dat</translation>
+ </message>
+ <message>
+ <source>Block creation options:</source>
+ <translation>Параметры создания блоков:</translation>
+ </message>
+ <message>
+ <source>Connect only to the specified node(s)</source>
+ <translation>Подключаться только к указанному узлу(ам)</translation>
+ </message>
+ <message>
+ <source>Connection options:</source>
+ <translation>Параметры подключения:</translation>
+ </message>
+ <message>
+ <source>Corrupted block database detected</source>
+ <translation>БД блоков повреждена</translation>
+ </message>
+ <message>
+ <source>Debugging/Testing options:</source>
+ <translation>Параметры отладки/тестирования:</translation>
+ </message>
+ <message>
+ <source>Do not load the wallet and disable wallet RPC calls</source>
+ <translation>Не загружать бумажник и запретить обращения к нему через RPC</translation>
+ </message>
+ <message>
+ <source>Do you want to rebuild the block database now?</source>
+ <translation>Пересобрать БД блоков прямо сейчас?</translation>
+ </message>
+ <message>
+ <source>Error initializing block database</source>
+ <translation>Ошибка инициализации БД блоков</translation>
+ </message>
+ <message>
+ <source>Error initializing wallet database environment %s!</source>
+ <translation>Ошибка инициализации окружения БД бумажника %s!</translation>
+ </message>
+ <message>
+ <source>Error loading block database</source>
+ <translation>Ошибка чтения базы данных блоков</translation>
+ </message>
+ <message>
+ <source>Error opening block database</source>
+ <translation>Не удалось открыть БД блоков</translation>
+ </message>
+ <message>
+ <source>Error: Disk space is low!</source>
+ <translation>Ошибка: мало места на диске!</translation>
+ </message>
+ <message>
+ <source>Failed to listen on any port. Use -listen=0 if you want this.</source>
+ <translation>Не удалось начать прослушивание на порту. Используйте -listen=0 если вас это устраивает.</translation>
+ </message>
+ <message>
+ <source>If &lt;category&gt; is not supplied, output all debugging information.</source>
+ <translation>Если &lt;category&gt; не предоставлена, выводить всю отладочную информацию.</translation>
+ </message>
+ <message>
+ <source>Importing...</source>
+ <translation>Импорт ...</translation>
+ </message>
+ <message>
+ <source>Incorrect or no genesis block found. Wrong datadir for network?</source>
+ <translation>Неверный или отсутствующий начальный блок. Неправильный каталог данных для сети?</translation>
+ </message>
+ <message>
+ <source>Invalid -onion address: '%s'</source>
+ <translation>Неверный -onion адрес: '%s'</translation>
+ </message>
+ <message>
+ <source>Not enough file descriptors available.</source>
+ <translation>Недостаточно файловых дескрипторов.</translation>
+ </message>
+ <message>
+ <source>Only connect to nodes in network &lt;net&gt; (ipv4, ipv6 or onion)</source>
+ <translation>Соединяться только по сети &lt;net&gt; (ipv4, ipv6 или onion)</translation>
+ </message>
+ <message>
+ <source>Prune cannot be configured with a negative value.</source>
+ <translation>Удаление блоков не может использовать отрицательное значение.</translation>
+ </message>
+ <message>
+ <source>Prune mode is incompatible with -txindex.</source>
+ <translation>Режим удаления блоков несовместим с -txindex.</translation>
+ </message>
+ <message>
+ <source>Set database cache size in megabytes (%d to %d, default: %d)</source>
+ <translation>Установить размер кэша БД в мегабайтах(от %d до %d, по умолчанию: %d)</translation>
+ </message>
+ <message>
+ <source>Set maximum block size in bytes (default: %d)</source>
+ <translation>Задать максимальный размер блока в байтах (по умолчанию: %d)</translation>
+ </message>
+ <message>
+ <source>Specify wallet file (within data directory)</source>
+ <translation>Укажите файл бумажника (внутри каталога данных)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: %u)</source>
+ <translation>Использовать UPnP для проброса порта (по умолчанию: %u)</translation>
+ </message>
+ <message>
+ <source>Verifying blocks...</source>
+ <translation>Проверка блоков...</translation>
+ </message>
+ <message>
+ <source>Verifying wallet...</source>
+ <translation>Проверка бумажника...</translation>
+ </message>
+ <message>
+ <source>Wallet %s resides outside data directory %s</source>
+ <translation>Бумажник %s располагается вне каталога данных %s</translation>
+ </message>
+ <message>
+ <source>Wallet options:</source>
+ <translation>Настройки бумажника:</translation>
+ </message>
+ <message>
+ <source>Warning: This version is obsolete; upgrade required!</source>
+ <translation>Внимание: эта версия устарела; требуется обновление!</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to change -txindex</source>
+ <translation>Вам необходимо пересобрать базы данных с помощью -reindex, чтобы изменить -txindex</translation>
+ </message>
+ <message>
+ <source>Imports blocks from external blk000??.dat file</source>
+ <translation>Импортировать блоки из внешнего файла blk000??.dat</translation>
+ </message>
+ <message>
+ <source>Allow JSON-RPC connections from specified source. Valid for &lt;ip&gt; are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times</source>
+ <translation>Разрешить подключения JSON-RPC с указанного источника. Разрешённые значения для &lt;ip&gt; — отдельный IP (например, 1.2.3.4), сеть/маска сети (например, 1.2.3.4/255.255.255.0) или сеть/CIDR (например, 1.2.3.4/24). Эту опцию можно использовать многократно</translation>
+ </message>
+ <message>
+ <source>An error occurred while setting up the RPC address %s port %u for listening: %s</source>
+ <translation>Произошла ошибка в процессе открытия RPC адреса %s порта %u для прослушивания: %s</translation>
+ </message>
+ <message>
+ <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source>
+ <translation>Привязаться к указанному адресу и внести в белый список подключающихся к нему участников. Используйте [хост]:порт для IPv6</translation>
+ </message>
+ <message>
+ <source>Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)</source>
+ <translation>Привязаться к указанному адресу для прослушивания JSON-RPC подключений. Используйте запись [хост]:порт для IPv6. Эту опцию можно использовать многократно (по умолчанию: привязываться ко всем интерфейсам)</translation>
+ </message>
+ <message>
+ <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source>
+ <translation>Не удалось установить блокировку на каталог данных %s. Возможно, Bitcoin Core уже запущен.</translation>
+ </message>
+ <message>
+ <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
+ <translation>Создавать новые файлы с системными правами по умолчанию вместо umask 077 (эффективно только при отключенном бумажнике)</translation>
+ </message>
+ <message>
+ <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source>
+ <translation>Обнаруживать собственный IP адрес (по умолчанию: 1 при прослушивании и без -externalip или -proxy)</translation>
+ </message>
+ <message>
+ <source>Error: Listening for incoming connections failed (listen returned error %s)</source>
+ <translation>Ошибка: не удалось начать прослушивание входящих подключений (прослушивание вернуло ошибку %s)</translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source>
+ <translation>Ошибка: обнаружен неподдерживаемый аргумент -socks. Выбор версии SOCKS более невозможен, поддерживаются только прокси SOCKS5.</translation>
+ </message>
+ <message>
+ <source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source>
+ <translation>Выполнить команду, когда приходит соответствующее сообщение о тревоге или наблюдается очень длинное расщепление цепи (%s в команде заменяется на сообщение)</translation>
+ </message>
+ <message>
+ <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source>
+ <translation>Комиссии (в BTC/Кб) меньшие этого значения считаются нулевыми для трансляции (по умолчанию: %s)</translation>
+ </message>
+ <message>
+ <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
+ <translation>Если paytxfee не задан, включить достаточную комиссию для подтверждения транзакции в среднем за n блоков (по умолчанию: %u)</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)</source>
+ <translation>Неверное значение для -maxtxfee=&lt;amount&gt;: '%s' (минимальная комиссия трансляции %s для предотвращения зависания транзакций)</translation>
+ </message>
+ <message>
+ <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source>
+ <translation>Наибольший размер данных в носителе данных транзакций, которые мы передаем и генерируем (по умолчанию: %u)</translation>
+ </message>
+ <message>
+ <source>Prune configured below the minimum of %d MB. Please use a higher number.</source>
+ <translation>Удаление блоков выставлено ниже, чем минимум в %d Мб. Пожалуйста, используйте большее значение.</translation>
+ </message>
+ <message>
+ <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source>
+ <translation>Запрашивать адреса участников с помощью DNS, если адресов мало (по умолчанию: 1, если не указан -connect)</translation>
+ </message>
+ <message>
+ <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source>
+ <translation>Использовать случайные учётные данные для каждого прокси-подключения. Эта функция позволяет изолировать потоки Tor (по умолчанию: %u)</translation>
+ </message>
+ <message>
+ <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
+ <translation>Задать максимальный размер высокоприоритетных/низкокомиссионных транзакций в байтах (по умолчанию: %d)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source>
+ <translation>Задать число потоков генерации монет, если она включена (-1 = все ядра процессора, по умолчанию: %d)</translation>
+ </message>
+ <message>
+ <source>The transaction amount is too small to send after the fee has been deducted</source>
+ <translation>Сумма транзакции за вычетом комиссии слишком мала</translation>
+ </message>
+ <message>
+ <source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit &lt;https://www.openssl.org/&gt; and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source>
+ <translation>Этот продукт включает ПО, разработанное OpenSSL Project для использования в OpenSSL Toolkit &lt;https://www.openssl.org/&gt; и криптографическое ПО, написанное Eric Young и ПО для работы с UPnP, написанное Thomas Bernard.</translation>
+ </message>
+ <message>
+ <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an 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)
+The username and password MUST NOT be the same.
+If the file does not exist, create it with owner-readable-only file permissions.
+It is also recommended to set alertnotify so you are notified of problems;
+for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
+</source>
+ <translation>Для использования bitcoind или опции bitcoin-qt -server, вы должны установить опцию rpcpassword в конфигурационном файле:
+ %s
+Рекомендуется использовать следующий случайный пароль:
+rpcuser=bitcoinrpc
+rpcpassword=%s
+(вам не нужно запоминать этот пароль)
+Имя и пароль ДОЛЖНЫ различаться.
+Если файл не существует, создайте его и установите право доступа только для чтения только для владельца.
+Также рекомендуется включить alertnotify для оповещения о проблемах;
+Например: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
+</translation>
+ </message>
+ <message>
+ <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source>
+ <translation>Внимание: установлено очень большое значение -paytxfee. Такие большие комиссии могут быть уплачены в отдельной транзакции.</translation>
+ </message>
+ <message>
+ <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source>
+ <translation>Внимание: убедитесь, что дата и время на Вашем компьютере выставлены верно. Если Ваши часы идут неправильно, Bitcoin Core будет работать некорректно.</translation>
+ </message>
+ <message>
+ <source>Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway</source>
+ <translation>Участники из белого списка не могуть быть забанены за DoS, и их транзакции всегда транслируются, даже если они уже содержатся в памяти. Полезно, например, для шлюза.</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source>
+ <translation>Вам необходимо пересобрать базу данных с помощью -reindex, чтобы вернуться к полному режиму. Это приведёт к перезагрузке всей цепи блоков</translation>
+ </message>
+ <message>
+ <source>(default: %u)</source>
+ <translation>(по умолчанию: %u)</translation>
+ </message>
+ <message>
+ <source>Accept public REST requests (default: %u)</source>
+ <translation>Принимать публичные REST-запросы (по умолчанию: %u)</translation>
+ </message>
+ <message>
+ <source>Activating best chain...</source>
+ <translation>Активируется лучшая цепь...</translation>
+ </message>
+ <message>
+ <source>Can't run with a wallet in prune mode.</source>
+ <translation>Нельзя работать с бумажником в режиме с удалением блоков.</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -whitebind address: '%s'</source>
+ <translation>Не удаётся разрешить адрес в параметре -whitebind: '%s'</translation>
+ </message>
+ <message>
+ <source>Choose data directory on startup (default: 0)</source>
+ <translation>Выбрать каталог данных при запуске (по умолчанию: 0)</translation>
+ </message>
+ <message>
+ <source>Connect through SOCKS5 proxy</source>
+ <translation>Подключаться через SOCKS5 прокси</translation>
+ </message>
+ <message>
+ <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source>
+ <translation>Все права защищены © 2009-%i Разработчики Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Could not parse -rpcbind value %s as network address</source>
+ <translation>Не удалось разобрать значение %s параметра -rpcbind как сетевой адрес</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source>
+ <translation>Ошибка загрузки wallet.dat: бумажник требует более новую версию Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Error reading from database, shutting down.</source>
+ <translation>Ошибка чтения базы данных, работа завершается.</translation>
+ </message>
+ <message>
+ <source>Error: A fatal internal error occurred, see debug.log for details</source>
+ <translation>Ошибка: произошла неустранимая ошибка, подробности в debug.log</translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -tor found, use -onion.</source>
+ <translation>Ошибка: обнаружен неподдерживаемый параметр -tor, используйте -onion.</translation>
+ </message>
+ <message>
+ <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source>
+ <translation>Комиссия (в BTC/Кб) для добавления к вашим транзакциям (по умолчанию: %s)</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Информация</translation>
+ </message>
+ <message>
+ <source>Initialization sanity check failed. Bitcoin Core is shutting down.</source>
+ <translation>Не удалось проверить чистоту. Bitcoin Core выключается.</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Неверное значение -maxtxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -minrelaytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Неверная сумма в параметре -minrelaytxfee=&lt;кол-во&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -mintxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Неверная сумма в параметре -mintxfee=&lt;кол-во&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s' (must be at least %s)</source>
+ <translation>Неверное количество в параметре -paytxfee=&lt;кол-во&gt;: '%s' (должно быть как минимум %s)</translation>
+ </message>
+ <message>
+ <source>Invalid netmask specified in -whitelist: '%s'</source>
+ <translation>Указана неверная сетевая маска в -whitelist: '%s'</translation>
+ </message>
+ <message>
+ <source>Keep at most &lt;n&gt; unconnectable transactions in memory (default: %u)</source>
+ <translation>Держать в памяти до &lt;n&gt; несвязных транзакций (по умолчанию: %u)</translation>
+ </message>
+ <message>
+ <source>Need to specify a port with -whitebind: '%s'</source>
+ <translation>Необходимо указать порт с помощью -whitebind: '%s'</translation>
+ </message>
+ <message>
+ <source>Node relay options:</source>
+ <translation>Параметры трансляции узла:</translation>
+ </message>
+ <message>
+ <source>Pruning blockstore...</source>
+ <translation>Очистка хранилища блоков...</translation>
+ </message>
+ <message>
+ <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source>
+ <translation>Параметры RPC SSL: (см. Bitcoin вики для инструкций по настройке SSL)</translation>
+ </message>
+ <message>
+ <source>RPC server options:</source>
+ <translation>Параметры сервера RPC:</translation>
+ </message>
+ <message>
+ <source>RPC support for HTTP persistent connections (default: %d)</source>
+ <translation>Поддержка RPC постоянных HTTP подключений (по умолчанию: %d)</translation>
+ </message>
+ <message>
+ <source>Rebuild block chain index from current blk000??.dat files on startup</source>
+ <translation>Перестроить при запуске индекс цепи блоков из текущих файлов blk000??.dat</translation>
+ </message>
+ <message>
+ <source>Receive and display P2P network alerts (default: %u)</source>
+ <translation>Получать и отображать P2P сетевые тревоги (по умолчанию: %u)</translation>
+ </message>
+ <message>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>Выводить информацию трассировки/отладки на консоль вместо файла debug.log</translation>
+ </message>
+ <message>
+ <source>Send transactions as zero-fee transactions if possible (default: %u)</source>
+ <translation>Осуществить транзакцию бесплатно, если возможно (по умолчанию: %u)</translation>
+ </message>
+ <message>
+ <source>Set SSL root certificates for payment request (default: -system-)</source>
+ <translation>Указать корневые SSL-сертификаты для запроса платежа (по умолчанию: -system-)</translation>
+ </message>
+ <message>
+ <source>Set language, for example "de_DE" (default: system locale)</source>
+ <translation>Выберите язык, например "de_DE" (по умолчанию: как в системе)</translation>
+ </message>
+ <message>
+ <source>Show all debugging options (usage: --help -help-debug)</source>
+ <translation>Показать все отладочные параметры (использование: --help -help-debug)</translation>
+ </message>
+ <message>
+ <source>Show splash screen on startup (default: 1)</source>
+ <translation>Показывать сплэш при запуске (по умолчанию: 1)</translation>
+ </message>
+ <message>
+ <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source>
+ <translation>Сжимать файл debug.log при запуске клиента (по умолчанию: 1, если нет -debug)</translation>
+ </message>
+ <message>
+ <source>Signing transaction failed</source>
+ <translation>Не удалось подписать транзакцию</translation>
+ </message>
+ <message>
+ <source>Start minimized</source>
+ <translation>Запускать свёрнутым</translation>
+ </message>
+ <message>
+ <source>The transaction amount is too small to pay the fee</source>
+ <translation>Сумма транзакции слишком мала для уплаты комиссии</translation>
+ </message>
+ <message>
+ <source>This is experimental software.</source>
+ <translation>Это экспериментальное ПО.</translation>
+ </message>
+ <message>
+ <source>Transaction amount too small</source>
+ <translation>Сумма транзакции слишком мала</translation>
+ </message>
+ <message>
+ <source>Transaction amounts must be positive</source>
+ <translation>Сумма транзакции должна быть положительна</translation>
+ </message>
+ <message>
+ <source>Transaction too large for fee policy</source>
+ <translation>Транзакция слишком большая для правил комиссии.</translation>
+ </message>
+ <message>
+ <source>Transaction too large</source>
+ <translation>Транзакция слишком большая</translation>
+ </message>
+ <message>
+ <source>UI Options:</source>
+ <translation>Настройки интерфейса:</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer (bind returned error %s)</source>
+ <translation>Невозможно привязаться к %s на этом компьютере (bind вернул ошибку %s)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: 1 when listening)</source>
+ <translation>Использовать UPnP для проброса порта (по умолчанию: 1, если используется прослушивание)</translation>
+ </message>
+ <message>
+ <source>Username for JSON-RPC connections</source>
+ <translation>Имя для подключений JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Wallet needed to be rewritten: restart Bitcoin Core to complete</source>
+ <translation>Необходимо перезаписать бумажник, перезапустите Bitcoin Core для завершения операции.</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Внимание</translation>
+ </message>
+ <message>
+ <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source>
+ <translation>Внимание: неподдерживаемый аргумент -benchmark проигнорирован, используйте -debug=bench.</translation>
+ </message>
+ <message>
+ <source>Warning: Unsupported argument -debugnet ignored, use -debug=net.</source>
+ <translation>Внимание: неподдерживаемый аргумент -debugnet проигнорирован, используйте -debug=net.</translation>
+ </message>
+ <message>
+ <source>Zapping all transactions from wallet...</source>
+ <translation>Стираем все транзакции из кошелька...</translation>
+ </message>
+ <message>
+ <source>on startup</source>
+ <translation>при запуске</translation>
+ </message>
+ <message>
+ <source>wallet.dat corrupt, salvage failed</source>
+ <translation>wallet.dat повреждён, спасение данных не удалось</translation>
+ </message>
+ <message>
+ <source>Password for JSON-RPC connections</source>
+ <translation>Пароль для подключений JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
+ <translation>Выполнить команду, когда появляется новый блок (%s в команде заменяется на хэш блока)</translation>
+ </message>
+ <message>
+ <source>Upgrade wallet to latest format</source>
+ <translation>Обновить бумажник до последнего формата</translation>
+ </message>
+ <message>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>Перепроверить цепь блоков на предмет отсутствующих в бумажнике транзакций</translation>
+ </message>
+ <message>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>Использовать OpenSSL (https) для подключений JSON-RPC</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>Эта справка</translation>
+ </message>
+ <message>
+ <source>Allow DNS lookups for -addnode, -seednode and -connect</source>
+ <translation>Разрешить поиск в DNS для -addnode, -seednode и -connect</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>Загрузка адресов...</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>Ошибка загрузки wallet.dat: Бумажник поврежден</translation>
+ </message>
+ <message>
+ <source>(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source>
+ <translation>(1 = сохранять метаданные транзакции: например, владельца аккаунта и информацию запроса платежа; 2 = отбросить метаданные)</translation>
+ </message>
+ <message>
+ <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
+ <translation>Насколько тщательна проверка контрольных блоков -checkblocks (0-4, по умолчанию: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
+ <translation>Держать полный индекс транзакций, используемый RPC-запросом getrawtransaction (по умолчанию: %u)</translation>
+ </message>
+ <message>
+ <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source>
+ <translation>Число секунд блокирования неправильно ведущих себя узлов (по умолчанию: %u)</translation>
+ </message>
+ <message>
+ <source>Output debugging information (default: %u, supplying &lt;category&gt; is optional)</source>
+ <translation>Выводить отладочную информацию (по умолчанию: %u, указание &lt;category&gt; необязательно)</translation>
+ </message>
+ <message>
+ <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source>
+ <translation>Использовать отдельный прокси SOCKS5 для соединения с участниками через скрытые сервисы Tor (по умолчанию: %s)</translation>
+ </message>
+ <message>
+ <source>(default: %s)</source>
+ <translation>(по умолчанию: %s)</translation>
+ </message>
+ <message>
+ <source>Acceptable ciphers (default: %s)</source>
+ <translation>Допустимые шифры (по умолчанию: %s)</translation>
+ </message>
+ <message>
+ <source>Always query for peer addresses via DNS lookup (default: %u)</source>
+ <translation>Всегда запрашивать адреса участников с помощью DNS (по умолчанию: %u)</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>Ошибка при загрузке wallet.dat</translation>
+ </message>
+ <message>
+ <source>Generate coins (default: %u)</source>
+ <translation>Включить добычу монет (по умолчанию: %u)</translation>
+ </message>
+ <message>
+ <source>How many blocks to check at startup (default: %u, 0 = all)</source>
+ <translation>Сколько блоков проверять при запуске (по умолчанию: %u, 0 = все)</translation>
+ </message>
+ <message>
+ <source>Include IP addresses in debug output (default: %u)</source>
+ <translation>Включить IP-адреса в отладочный вывод (по умолчанию: %u)</translation>
+ </message>
+ <message>
+ <source>Invalid -proxy address: '%s'</source>
+ <translation>Неверный адрес -proxy: '%s'</translation>
+ </message>
+ <message>
+ <source>Listen for JSON-RPC connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>Прослушивать подключения JSON-RPC на &lt;порту&gt; (по умолчанию: %u или %u в тестовой сети)</translation>
+ </message>
+ <message>
+ <source>Listen for connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>Принимать входящие подключения на &lt;port&gt; (по умолчанию: %u или %u в тестовой сети)</translation>
+ </message>
+ <message>
+ <source>Maintain at most &lt;n&gt; connections to peers (default: %u)</source>
+ <translation>Поддерживать не более &lt;n&gt; подключений к узлам (по умолчанию: %u)</translation>
+ </message>
+ <message>
+ <source>Make the wallet broadcast transactions</source>
+ <translation>Рассылать транзакции из бумажника</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection receive buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>Максимальный размер буфера приёма на соединение, &lt;n&gt;*1000 байт (по умолчанию: %u)</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection send buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>Максимальный размер буфера отправки на соединение, &lt;n&gt;*1000 байт (по умолчанию: %u)</translation>
+ </message>
+ <message>
+ <source>Prepend debug output with timestamp (default: %u)</source>
+ <translation>Дописывать отметки времени к отладочному выводу (по умолчанию: %u)</translation>
+ </message>
+ <message>
+ <source>Relay and mine data carrier transactions (default: %u)</source>
+ <translation>Транслировать и генерировать транзакции носителей данных (по умолчанию: %u)</translation>
+ </message>
+ <message>
+ <source>Relay non-P2SH multisig (default: %u)</source>
+ <translation>Транслировать не-P2SH мультиподпись (по умолчанию: %u)</translation>
+ </message>
+ <message>
+ <source>Server certificate file (default: %s)</source>
+ <translation>Файл сертификата сервера (по умолчанию: %s)</translation>
+ </message>
+ <message>
+ <source>Server private key (default: %s)</source>
+ <translation>Закрытый ключ сервера (по умолчанию: %s)</translation>
+ </message>
+ <message>
+ <source>Set key pool size to &lt;n&gt; (default: %u)</source>
+ <translation>Установить размер пула ключей в &lt;n&gt; (по умолчанию: %u)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads to service RPC calls (default: %d)</source>
+ <translation>Задать число потоков выполнения запросов RPC (по умолчанию: %d)</translation>
+ </message>
+ <message>
+ <source>Specify configuration file (default: %s)</source>
+ <translation>Указать конфигурационный файл (по умолчанию: %s)</translation>
+ </message>
+ <message>
+ <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source>
+ <translation>Указать тайм-аут соединения в миллисекундах (минимум: 1, по умолчанию: %d)</translation>
+ </message>
+ <message>
+ <source>Specify pid file (default: %s)</source>
+ <translation>Указать pid-файл (по умолчанию: %s)</translation>
+ </message>
+ <message>
+ <source>Spend unconfirmed change when sending transactions (default: %u)</source>
+ <translation>Тратить неподтвержденную сдачу при отправке транзакций (по умолчанию: %u)</translation>
+ </message>
+ <message>
+ <source>Threshold for disconnecting misbehaving peers (default: %u)</source>
+ <translation>Порог для отключения неправильно ведущих себя узлов (по умолчанию: %u)</translation>
+ </message>
+ <message>
+ <source>Unknown network specified in -onlynet: '%s'</source>
+ <translation>В параметре -onlynet указана неизвестная сеть: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -bind address: '%s'</source>
+ <translation>Не удаётся разрешить адрес в параметре -bind: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -externalip address: '%s'</source>
+ <translation>Не удаётся разрешить адрес в параметре -externalip: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Неверная сумма в параметре -paytxfee=&lt;кол-во&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>Недостаточно монет</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>Загрузка индекса блоков...</translation>
+ </message>
+ <message>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>Добавить узел для подключения и пытаться поддерживать соединение открытым</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>Загрузка бумажника...</translation>
+ </message>
+ <message>
+ <source>Cannot downgrade wallet</source>
+ <translation>Не удаётся понизить версию бумажника</translation>
+ </message>
+ <message>
+ <source>Cannot write default address</source>
+ <translation>Не удаётся записать адрес по умолчанию</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>Сканирование...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>Загрузка завершена</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Ошибка</translation>
+ </message>
+</context>
+</TS> \ No newline at end of file
diff --git a/src/qt/locale/bitcoin_sah.ts b/src/qt/locale/bitcoin_sah.ts
new file mode 100644
index 0000000000..9ca08ee7da
--- /dev/null
+++ b/src/qt/locale/bitcoin_sah.ts
@@ -0,0 +1,110 @@
+<TS language="sah" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ </context>
+<context>
+ <name>AddressTableModel</name>
+ </context>
+<context>
+ <name>AskPassphraseDialog</name>
+ </context>
+<context>
+ <name>BitcoinGUI</name>
+ </context>
+<context>
+ <name>ClientModel</name>
+ </context>
+<context>
+ <name>CoinControlDialog</name>
+ </context>
+<context>
+ <name>EditAddressDialog</name>
+ </context>
+<context>
+ <name>FreespaceChecker</name>
+ </context>
+<context>
+ <name>HelpMessageDialog</name>
+ </context>
+<context>
+ <name>Intro</name>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ </context>
+<context>
+ <name>OptionsDialog</name>
+ </context>
+<context>
+ <name>OverviewPage</name>
+ </context>
+<context>
+ <name>PaymentServer</name>
+ </context>
+<context>
+ <name>PeerTableModel</name>
+ </context>
+<context>
+ <name>QObject</name>
+ </context>
+<context>
+ <name>QRImageWidget</name>
+ </context>
+<context>
+ <name>RPCConsole</name>
+ </context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ </context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ </context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ </context>
+<context>
+ <name>SendCoinsDialog</name>
+ </context>
+<context>
+ <name>SendCoinsEntry</name>
+ </context>
+<context>
+ <name>ShutdownWindow</name>
+ </context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ </context>
+<context>
+ <name>SplashScreen</name>
+ </context>
+<context>
+ <name>TrafficGraphWidget</name>
+ </context>
+<context>
+ <name>TransactionDesc</name>
+ </context>
+<context>
+ <name>TransactionDescDialog</name>
+ </context>
+<context>
+ <name>TransactionTableModel</name>
+ </context>
+<context>
+ <name>TransactionView</name>
+ </context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ </context>
+<context>
+ <name>WalletFrame</name>
+ </context>
+<context>
+ <name>WalletModel</name>
+ </context>
+<context>
+ <name>WalletView</name>
+ </context>
+<context>
+ <name>bitcoin-core</name>
+ </context>
+</TS> \ 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 0000000000..cce8f2a09b
--- /dev/null
+++ b/src/qt/locale/bitcoin_sk.ts
@@ -0,0 +1,3446 @@
+<TS language="sk" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Right-click to edit address or label</source>
+ <translation>Kliknutím pravým tlačidlom upravte adresu alebo popis</translation>
+ </message>
+ <message>
+ <source>Create a new address</source>
+ <translation>Vytvoriť novú adresu</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>&amp;Nové</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Kopírovať práve zvolenú adresu do systémového klipbordu</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>&amp;Kopírovať</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>Zatvoriť</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>&amp;Kopírovať adresu</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>Vymaž vybranú adresu zo zoznamu</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Exportovať tento náhľad do súboru</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Exportovať...</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;Zmazať</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>Zvoľte adresu kam poslať coins</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>Zvoľte adresu na ktorú prijať coins</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>Vybrať</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>Adresa odoslania</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>Adresa prijatia</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>Toto sú Vaše Bitcoin adresy pre posielanie platieb. Vždy skontrolujte množstvo a prijímaciu adresu pred poslaním coins.</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>Toto sú vaše Bitcoin adresy pre prijímanie platieb. Odporúča sa použiť novú prijímaciu adresu pre každú transakciu.</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>Kopírovať &amp;popis</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>&amp;Upraviť</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>Exportovať zoznam adries</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Čiarkou oddelovaný súbor (*.csv)</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Export zlyhal</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the address list to %1. Please try again.</source>
+ <translation>Nastala chyba pri pokuse uložiť zoznam adries do %1. Skúste znovu.</translation>
+ </message>
+</context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Popis</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adresa</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(bez popisu)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Passphrase Dialog</source>
+ <translation>Dialóg hesla</translation>
+ </message>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Zadajte heslo</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Nové heslo</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Zopakujte nové heslo</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>Zašifrovať peňaženku</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>Táto operácia potrebuje heslo k vašej peňaženke aby ju mohla dešifrovať.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Odomknúť peňaženku</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>Táto operácia potrebuje heslo k vašej peňaženke na dešifrovanie peňaženky.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>Dešifrovať peňaženku</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>Zmena hesla</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>Potvrďte šifrovanie peňaženky</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>Varovanie: Ak zašifrujete peňaženku a stratíte heslo, &lt;b&gt;STRATÍTE VŠETKY VAŠE BITCOINY&lt;/b&gt;!⏎</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>Ste si istí, že si želáte zašifrovať peňaženku?</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core 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.</source>
+ <translation>Jadro Bitcoin sa teraz ukončí pre dokončenie procesu šifrovania. Pamätaj, že šifrovanie peňaženky Ťa nemôže úplne ochrániť pred krádežou bitcoinov pomocou škodlivého software.</translation>
+ </message>
+ <message>
+ <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
+ <translation>DÔLEŽITÉ: Všetky doterajšie záložné kópie peňaženky ktoré ste zhotovili by mali byť nahradené novým zašifrovaným súborom s peňaženkou. Z bezpečnostných dôvodov sa predchádzajúce kópie nezašifrovanej peňaženky stanú neužitočné keď začnete používať novú zašifrovanú peňaženku.</translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>Varovanie: Caps Lock je zapnutý</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>Peňaženka zašifrovaná</translation>
+ </message>
+ <message>
+ <source>Enter the new passphrase to the wallet.&lt;br/&gt;Please use a passphrase of &lt;b&gt;ten or more random characters&lt;/b&gt;, or &lt;b&gt;eight or more words&lt;/b&gt;.</source>
+ <translation>Zadajte nové heslo k peňaženke.&lt;br/&gt;Prosím použite heslo s dĺžkou aspoň &lt;b&gt;10 alebo viac náhodných znakov&lt;/b&gt;, alebo &lt;b&gt;8 alebo viac slov&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>Enter the old passphrase and new passphrase to the wallet.</source>
+ <translation>Zadajte staré a nové heslo k peňaženke.</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>Šifrovanie peňaženky zlyhalo</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>Šifrovanie peňaženky zlyhalo kôli internej chybe. Vaša peňaženka nebola zašifrovaná.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>Zadané heslá nesúhlasia.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>Odomykanie peňaženky zlyhalo</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>Zadané heslo pre dešifrovanie peňaženky bolo nesprávne.</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>Zlyhalo šifrovanie peňaženky.</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>Heslo k peňaženke bolo úspešne zmenené.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>Podpísať &amp;správu...</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>Synchronizácia so sieťou...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;Prehľad</translation>
+ </message>
+ <message>
+ <source>Node</source>
+ <translation>Uzol</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>Zobraziť celkový prehľad o peňaženke</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Transakcie</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>Prechádzať históriu transakcií</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>U&amp;končiť</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>Ukončiť program</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>O &amp;Qt</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>Zobrazit informácie o Qt</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;Možnosti...</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>&amp;Zašifrovať Peňaženku...</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>&amp;Zálohovať peňaženku...</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>&amp;Zmena Hesla...</translation>
+ </message>
+ <message>
+ <source>&amp;Sending addresses...</source>
+ <translation>&amp;Odosielajúce adresy ...</translation>
+ </message>
+ <message>
+ <source>&amp;Receiving addresses...</source>
+ <translation>&amp;Prijímajúce adresy...</translation>
+ </message>
+ <message>
+ <source>Open &amp;URI...</source>
+ <translation>Otvoriť &amp;URI...</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core client</source>
+ <translation>Bitcoin Core klient</translation>
+ </message>
+ <message>
+ <source>Importing blocks from disk...</source>
+ <translation>Importujem bloky z disku...</translation>
+ </message>
+ <message>
+ <source>Reindexing blocks on disk...</source>
+ <translation>Preindexúvam bloky na disku...</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>Poslať bitcoins na adresu</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>Zálohovať peňaženku na iné miesto</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Zmeniť heslo použité na šifrovanie peňaženky</translation>
+ </message>
+ <message>
+ <source>&amp;Debug window</source>
+ <translation>&amp;Okno pre ladenie</translation>
+ </message>
+ <message>
+ <source>Open debugging and diagnostic console</source>
+ <translation>Otvor konzolu pre ladenie a diagnostiku</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>O&amp;veriť správu...</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>Peňaženka</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>&amp;Odoslať</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>&amp;Prijať</translation>
+ </message>
+ <message>
+ <source>Show information about Bitcoin Core</source>
+ <translation>Zobraziť informácie o Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>Zobraziť / skryť</translation>
+ </message>
+ <message>
+ <source>Show or hide the main Window</source>
+ <translation>Zobraziť alebo skryť hlavné okno</translation>
+ </message>
+ <message>
+ <source>Encrypt the private keys that belong to your wallet</source>
+ <translation>Zašifruj súkromné kľúče ktoré patria do vašej peňaženky</translation>
+ </message>
+ <message>
+ <source>Sign messages with your Bitcoin addresses to prove you own them</source>
+ <translation>Podpísať správu s vašou adresou Bitcoin aby ste preukázali že ju vlastníte</translation>
+ </message>
+ <message>
+ <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source>
+ <translation>Overiť či správa bola podpísaná uvedenou Bitcoin adresou</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;Súbor</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;Nastavenia</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>&amp;Pomoc</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>Lišta záložiek</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Jadro Bitcoin</translation>
+ </message>
+ <message>
+ <source>Request payments (generates QR codes and bitcoin: URIs)</source>
+ <translation>Vyžiadať platby (vygeneruje QR kódy a bitcoin: URI)</translation>
+ </message>
+ <message>
+ <source>&amp;About Bitcoin Core</source>
+ <translation>O jadre Bitcoin</translation>
+ </message>
+ <message>
+ <source>Modify configuration options for Bitcoin Core</source>
+ <translation>Upraviť možnosti nastavenia pre Jadro Bitcoin</translation>
+ </message>
+ <message>
+ <source>Show the list of used sending addresses and labels</source>
+ <translation>Zobraziť zoznam použitých adries odosielateľa a ich popisy</translation>
+ </message>
+ <message>
+ <source>Show the list of used receiving addresses and labels</source>
+ <translation>Zobraziť zoznam použitých prijímacích adries a ich popisov</translation>
+ </message>
+ <message>
+ <source>Open a bitcoin: URI or payment request</source>
+ <translation>Otvoriť bitcoin URI alebo výzvu k platbe</translation>
+ </message>
+ <message>
+ <source>&amp;Command-line options</source>
+ <translation>Možnosti príkazového riadku</translation>
+ </message>
+ <message>
+ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
+ <translation>Zobraziť pomocnú správu od Bitcoin Jadra pre získanie zoznamu dostupných možností príkazového riadku</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n active connection(s) to Bitcoin network</source>
+ <translation><numerusform>%n aktívne pripojenie do siete Bitcoin</numerusform><numerusform>%n aktívne pripojenia do siete Bitcoin</numerusform><numerusform>%n aktívnych pripojení do siete Bitcoin</numerusform></translation>
+ </message>
+ <message>
+ <source>No block source available...</source>
+ <translation>Nedostupný zdroj blokov...</translation>
+ </message>
+ <message numerus="yes">
+ <source>Processed %n block(s) of transaction history.</source>
+ <translation><numerusform>Spracovaných %n blok transakčnej histórie.</numerusform><numerusform>Spracovaných %n bloky transakčnej histórie.</numerusform><numerusform>Spracovaných %n blokov transakčnej histórie.</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n hour(s)</source>
+ <translation><numerusform>%n hodina</numerusform><numerusform>%n hodiny</numerusform><numerusform>%n hodín</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n day(s)</source>
+ <translation><numerusform>%n deň</numerusform><numerusform>%n dni</numerusform><numerusform>%n dní</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n week(s)</source>
+ <translation><numerusform>%n týždeň</numerusform><numerusform>%n týždne</numerusform><numerusform>%n týždňov</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 and %2</source>
+ <translation> %1 a %2</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n year(s)</source>
+ <translation><numerusform>%n rok</numerusform><numerusform>%n roky</numerusform><numerusform>%n rokov</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 behind</source>
+ <translation>%1 pozadu</translation>
+ </message>
+ <message>
+ <source>Last received block was generated %1 ago.</source>
+ <translation>Posledný prijatý blok bol vygenerovaný pred %1.</translation>
+ </message>
+ <message>
+ <source>Transactions after this will not yet be visible.</source>
+ <translation>Transakcie po tomto čase ešte nebudú viditeľné.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Chyba</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Upozornenie</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Informácia</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>Aktualizovaný</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>Sťahujem...</translation>
+ </message>
+ <message>
+ <source>Date: %1
+</source>
+ <translation>Dátum: %1
+</translation>
+ </message>
+ <message>
+ <source>Amount: %1
+</source>
+ <translation>Suma: %1
+</translation>
+ </message>
+ <message>
+ <source>Type: %1
+</source>
+ <translation>Typ: %1
+</translation>
+ </message>
+ <message>
+ <source>Label: %1
+</source>
+ <translation>Popis: %1
+</translation>
+ </message>
+ <message>
+ <source>Address: %1
+</source>
+ <translation>Adresa: %1
+</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>Odoslané transakcie</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>Prijatá transakcia</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>Peňaženka je &lt;b&gt;zašifrovaná&lt;/b&gt; a momentálne &lt;b&gt;odomknutá&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>Peňaženka je &lt;b&gt;zašifrovaná&lt;/b&gt; a momentálne &lt;b&gt;zamknutá&lt;/b&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <source>Network Alert</source>
+ <translation>Výstraha siete</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Coin Selection</source>
+ <translation>Výber mince</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Množstvo:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Bajtov:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Suma:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Priorita:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Poplatok:</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Prach:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Po poplatku:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Zmena:</translation>
+ </message>
+ <message>
+ <source>(un)select all</source>
+ <translation>(ne)vybrať všetko</translation>
+ </message>
+ <message>
+ <source>Tree mode</source>
+ <translation>Stromový režim</translation>
+ </message>
+ <message>
+ <source>List mode</source>
+ <translation>Zoznamový režim</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Suma</translation>
+ </message>
+ <message>
+ <source>Received with label</source>
+ <translation>Prijaté s označením</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>Prijaté s adresou</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Dátum</translation>
+ </message>
+ <message>
+ <source>Confirmations</source>
+ <translation>Potvrdenia</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Potvrdené</translation>
+ </message>
+ <message>
+ <source>Priority</source>
+ <translation>Priorita</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Kopírovať adresu</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Kopírovať popis</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopírovať sumu</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Kopírovať ID transakcie</translation>
+ </message>
+ <message>
+ <source>Lock unspent</source>
+ <translation>Uzamknúť neminuté</translation>
+ </message>
+ <message>
+ <source>Unlock unspent</source>
+ <translation>Odomknúť neminuté</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Kopírovať množstvo</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Kopírovať poplatok</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Kopírovať za poplatok</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Kopírovať bajty</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Kopírovať prioritu</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Kopírovať prach</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Kopírovať zmenu</translation>
+ </message>
+ <message>
+ <source>highest</source>
+ <translation>najvyššie</translation>
+ </message>
+ <message>
+ <source>higher</source>
+ <translation>vyššie</translation>
+ </message>
+ <message>
+ <source>high</source>
+ <translation>vysoké</translation>
+ </message>
+ <message>
+ <source>medium-high</source>
+ <translation>stredne vysoké</translation>
+ </message>
+ <message>
+ <source>medium</source>
+ <translation>stredné</translation>
+ </message>
+ <message>
+ <source>low-medium</source>
+ <translation>stredne nízke</translation>
+ </message>
+ <message>
+ <source>low</source>
+ <translation>nízke</translation>
+ </message>
+ <message>
+ <source>lower</source>
+ <translation>nižšie</translation>
+ </message>
+ <message>
+ <source>lowest</source>
+ <translation>najnižšie</translation>
+ </message>
+ <message>
+ <source>(%1 locked)</source>
+ <translation>(%1 zamknutých)</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>žiadne</translation>
+ </message>
+ <message>
+ <source>This label turns red if the transaction size is greater than 1000 bytes.</source>
+ <translation>Tento popis sčervenie ak veľkosť transakcie presiahne 1000 bajtov.</translation>
+ </message>
+ <message>
+ <source>This label turns red if the priority is smaller than "medium".</source>
+ <translation>Tento popis sčervenie ak je priorita nižšia ako "stredná".</translation>
+ </message>
+ <message>
+ <source>This label turns red if any recipient receives an amount smaller than %1.</source>
+ <translation>Tento popis sčervenie ak ktorýkoľvek príjemca dostane sumu menšiu ako %1.</translation>
+ </message>
+ <message>
+ <source>Can vary +/- %1 satoshi(s) per input.</source>
+ <translation>Môže sa líšiť o +/- %1 satoshi pre každý vstup</translation>
+ </message>
+ <message>
+ <source>yes</source>
+ <translation>áno</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>nie</translation>
+ </message>
+ <message>
+ <source>This means a fee of at least %1 per kB is required.</source>
+ <translation>To znamená že požadovaný poplatok je aspoň %1 za kB.</translation>
+ </message>
+ <message>
+ <source>Can vary +/- 1 byte per input.</source>
+ <translation>Môže sa pohybovať +/- 1 bajt pre vstup.</translation>
+ </message>
+ <message>
+ <source>Transactions with higher priority are more likely to get included into a block.</source>
+ <translation>Transakcie s vysokou prioritou sa pravdepodobnejsie dostanú do bloku.</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(bez popisu)</translation>
+ </message>
+ <message>
+ <source>change from %1 (%2)</source>
+ <translation>zmena od %1 (%2)</translation>
+ </message>
+ <message>
+ <source>(change)</source>
+ <translation>(zmena)</translation>
+ </message>
+</context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>Upraviť adresu</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>&amp;Popis</translation>
+ </message>
+ <message>
+ <source>The label associated with this address list entry</source>
+ <translation>Popis tejto položký v zozname adries je prázdny</translation>
+ </message>
+ <message>
+ <source>The address associated with this address list entry. This can only be modified for sending addresses.</source>
+ <translation>Adresa spojená s týmto záznamom v adresári. Možno upravovať len pre odosielajúce adresy.</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;Adresa</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>Nová adresa pre prijímanie</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>Nová adresa pre odoslanie</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>Upraviť prijímacie adresy</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>Upraviť odosielaciu adresu</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>Vložená adresa "%1" sa už nachádza v adresári.</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is not a valid Bitcoin address.</source>
+ <translation>Vložená adresa "%1" nieje platnou adresou bitcoin.</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>Nepodarilo sa odomknúť peňaženku.</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>Generovanie nového kľúča zlyhalo.</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ <message>
+ <source>A new data directory will be created.</source>
+ <translation>Bude vytvorený nový dátový adresár.</translation>
+ </message>
+ <message>
+ <source>name</source>
+ <translation>názov</translation>
+ </message>
+ <message>
+ <source>Directory already exists. Add %1 if you intend to create a new directory here.</source>
+ <translation>Priečinok už existuje. Pridajte "%1" ak chcete vytvoriť nový priečinok tu.</translation>
+ </message>
+ <message>
+ <source>Path already exists, and is not a directory.</source>
+ <translation>Cesta už existuje a nie je to adresár.</translation>
+ </message>
+ <message>
+ <source>Cannot create data directory here.</source>
+ <translation>Tu nemôžem vytvoriť dátový adresár.</translation>
+ </message>
+</context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Jadro Bitcoin</translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>verzia</translation>
+ </message>
+ <message>
+ <source>(%1-bit)</source>
+ <translation>(%1-bit)</translation>
+ </message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>O jadre Bitcoin</translation>
+ </message>
+ <message>
+ <source>Command-line options</source>
+ <translation>Voľby príkazového riadku</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>Použitie:</translation>
+ </message>
+ <message>
+ <source>command-line options</source>
+ <translation>voľby príkazového riadku</translation>
+ </message>
+</context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Welcome</source>
+ <translation>Vitajte</translation>
+ </message>
+ <message>
+ <source>Welcome to Bitcoin Core.</source>
+ <translation>Vitajte v jadre Bitcoin.</translation>
+ </message>
+ <message>
+ <source>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</source>
+ <translation>Keďže spúštate program prvý krát, môžte si vybrať kde bude Bitcoin Jadro ukladať svoje dáta.</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory.</source>
+ <translation>Jadro Bitcoin stiahne zo siete a uloží kópiu Bitcoin blockchain. Aspoň %1GB dát bude uložených v tomto priečinku a časom porastie. Peňaženka bude tiež uložená v tomto priečinku.</translation>
+ </message>
+ <message>
+ <source>Use the default data directory</source>
+ <translation>Použiť predvolený dátový adresár</translation>
+ </message>
+ <message>
+ <source>Use a custom data directory:</source>
+ <translation>Použiť vlastný dátový adresár:</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Jadro Bitcoin</translation>
+ </message>
+ <message>
+ <source>Error: Specified data directory "%1" cannot be created.</source>
+ <translation>Chyba: Zadaný priečinok pre dáta "%1" nemôže byť vytvorený.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Chyba</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n GB of free space available</source>
+ <translation><numerusform>%n GB voľného miesta</numerusform><numerusform>%n GB voľného miesta</numerusform><numerusform>%n GB voľného miesta</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>(of %n GB needed)</source>
+ <translation><numerusform>(z %n GB potrebného)</numerusform><numerusform>(z %n GB potrebných)</numerusform><numerusform>(z %n GB potrebných)</numerusform></translation>
+ </message>
+</context>
+<context>
+ <name>OpenURIDialog</name>
+ <message>
+ <source>Open URI</source>
+ <translation>Otvoriť URI</translation>
+ </message>
+ <message>
+ <source>Open payment request from URI or file</source>
+ <translation>Otvoriť požiadavku na zaplatenie z URI alebo súboru</translation>
+ </message>
+ <message>
+ <source>URI:</source>
+ <translation>URI:</translation>
+ </message>
+ <message>
+ <source>Select payment request file</source>
+ <translation>Vyberte súbor s výzvou k platbe</translation>
+ </message>
+ <message>
+ <source>Select payment request file to open</source>
+ <translation>Vyberte ktorý súbor s výzvou k platbe otvoriť</translation>
+ </message>
+</context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>Možnosti</translation>
+ </message>
+ <message>
+ <source>&amp;Main</source>
+ <translation>&amp;Hlavné</translation>
+ </message>
+ <message>
+ <source>Size of &amp;database cache</source>
+ <translation>Veľkosť vyrovnávacej pamäti &amp;databázy</translation>
+ </message>
+ <message>
+ <source>MB</source>
+ <translation>MB</translation>
+ </message>
+ <message>
+ <source>Number of script &amp;verification threads</source>
+ <translation>Počet &amp;vlákien overujúcich skript</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside</source>
+ <translation>Prijať spojenia zvonku</translation>
+ </message>
+ <message>
+ <source>Allow incoming connections</source>
+ <translation>Povoliť prichádzajúce spojenia</translation>
+ </message>
+ <message>
+ <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
+ <translation>IP adresy proxy (napr. IPv4: 127.0.0.1 / IPv6: ::1)</translation>
+ </message>
+ <message>
+ <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source>
+ <translation>Minimalizovať 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.</translation>
+ </message>
+ <message>
+ <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source>
+ <translation>Tu sa dá nastaviť jazyk užívateľského rozhrania. Toto nastavenie bude účinné po reštartovaní Jadra Bitcoin.</translation>
+ </message>
+ <message>
+ <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source>
+ <translation>URL tretích strán (napr. prehliadač blockchain) ktoré sa zobrazujú v záložke transakcií ako položky kontextového menu. %s v URL je nahradené hash-om transakcie. Viaceré URL sú oddelené zvislou čiarou |.</translation>
+ </message>
+ <message>
+ <source>Third party transaction URLs</source>
+ <translation>URL transakcií s tretími stranami</translation>
+ </message>
+ <message>
+ <source>Active command-line options that override above options:</source>
+ <translation>Aktívne možnosti príkazového riadku ktoré prepíšu možnosti vyššie:</translation>
+ </message>
+ <message>
+ <source>Reset all client options to default.</source>
+ <translation>Vynulovať všetky voľby klienta na predvolené.</translation>
+ </message>
+ <message>
+ <source>&amp;Reset Options</source>
+ <translation>Vynulovať voľby</translation>
+ </message>
+ <message>
+ <source>&amp;Network</source>
+ <translation>Sieť</translation>
+ </message>
+ <message>
+ <source>Automatically start Bitcoin Core after logging in to the system.</source>
+ <translation>Automaticky spustiť Jadro Bitcoin po prihlásení do systému</translation>
+ </message>
+ <message>
+ <source>&amp;Start Bitcoin Core on system login</source>
+ <translation>&amp;Spustiť Bitcoin pri spustení systému správy okien</translation>
+ </message>
+ <message>
+ <source>(0 = auto, &lt;0 = leave that many cores free)</source>
+ <translation>(0 = auto, &lt;0 = nechať toľko jadier voľných)</translation>
+ </message>
+ <message>
+ <source>W&amp;allet</source>
+ <translation>Peňaženka</translation>
+ </message>
+ <message>
+ <source>Expert</source>
+ <translation>Expert</translation>
+ </message>
+ <message>
+ <source>Enable coin &amp;control features</source>
+ <translation>Povoliť možnosti "&amp;coin control"</translation>
+ </message>
+ <message>
+ <source>If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.</source>
+ <translation>Ak vypnete míňanie nepotvrdeného výdavku tak výdavok z transakcie bude možné použiť až keď daná transakcia bude mať aspoň jedno potvrdenie. Toto má vplyv aj na výpočet vášho zostatku.</translation>
+ </message>
+ <message>
+ <source>&amp;Spend unconfirmed change</source>
+ <translation>Minúť nepotvrdený výdavok</translation>
+ </message>
+ <message>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>Automaticky otvorit port pre Bitcoin na routeri. Toto funguje len ak router podporuje UPnP a je táto podpora aktivovaná.</translation>
+ </message>
+ <message>
+ <source>Map port using &amp;UPnP</source>
+ <translation>Mapovať port pomocou &amp;UPnP</translation>
+ </message>
+ <message>
+ <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
+ <translation>Pripojiť do siete Bitcoin cez proxy server SOCKS5.</translation>
+ </message>
+ <message>
+ <source>&amp;Connect through SOCKS5 proxy (default proxy):</source>
+ <translation>&amp;Pripojiť cez proxy server SOCKS5 (predvolený proxy).</translation>
+ </message>
+ <message>
+ <source>Proxy &amp;IP:</source>
+ <translation>Proxy &amp;IP:</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>&amp;Port:</translation>
+ </message>
+ <message>
+ <source>Port of the proxy (e.g. 9050)</source>
+ <translation>Port proxy (napr. 9050)</translation>
+ </message>
+ <message>
+ <source>&amp;Window</source>
+ <translation>Okno</translation>
+ </message>
+ <message>
+ <source>Show only a tray icon after minimizing the window.</source>
+ <translation>Zobraziť len ikonu na lište po minimalizovaní okna.</translation>
+ </message>
+ <message>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>Zobraziť len ikonu na lište po minimalizovaní okna.</translation>
+ </message>
+ <message>
+ <source>M&amp;inimize on close</source>
+ <translation>M&amp;inimalizovať pri zavretí</translation>
+ </message>
+ <message>
+ <source>&amp;Display</source>
+ <translation>&amp;Displej</translation>
+ </message>
+ <message>
+ <source>User Interface &amp;language:</source>
+ <translation>Jazyk užívateľského rozhrania:</translation>
+ </message>
+ <message>
+ <source>&amp;Unit to show amounts in:</source>
+ <translation>&amp;Zobrazovať hodnoty v jednotkách:</translation>
+ </message>
+ <message>
+ <source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
+ <translation>Zvoľte ako deliť bitcoin pri zobrazovaní pri platbách a užívateľskom rozhraní.</translation>
+ </message>
+ <message>
+ <source>Whether to show coin control features or not.</source>
+ <translation>Či zobrazovať možnosti "Coin control" alebo nie.</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>&amp;OK</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>Zrušiť</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>predvolené</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>žiadne</translation>
+ </message>
+ <message>
+ <source>Confirm options reset</source>
+ <translation>Potvrdiť obnovenie možností</translation>
+ </message>
+ <message>
+ <source>Client restart required to activate changes.</source>
+ <translation>Reštart klienta potrebný pre aktivovanie zmien.</translation>
+ </message>
+ <message>
+ <source>Client will be shut down. Do you want to proceed?</source>
+ <translation>Klient bude vypnutý, chcete pokračovať?</translation>
+ </message>
+ <message>
+ <source>This change would require a client restart.</source>
+ <translation>Táto zmena by vyžadovala reštart klienta.</translation>
+ </message>
+ <message>
+ <source>The supplied proxy address is invalid.</source>
+ <translation>Zadaná proxy adresa je neplatná.</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>Forma</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>Zobrazené informácie môžu byť neaktuálne. Vaša peňaženka sa automaticky synchronizuje so sieťou Bitcoin po nadviazaní spojenia, ale tento proces ešte nie je ukončený.</translation>
+ </message>
+ <message>
+ <source>Watch-only:</source>
+ <translation>Iba sledované:</translation>
+ </message>
+ <message>
+ <source>Available:</source>
+ <translation>Disponibilné:</translation>
+ </message>
+ <message>
+ <source>Your current spendable balance</source>
+ <translation>Váš aktuálny disponibilný zostatok</translation>
+ </message>
+ <message>
+ <source>Pending:</source>
+ <translation>Čakajúce potvrdenie:</translation>
+ </message>
+ <message>
+ <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source>
+ <translation>Suma transakcií ktoré ešte neboli potvrdené a ešte sa nepočítajú do disponibilného zostatku</translation>
+ </message>
+ <message>
+ <source>Immature:</source>
+ <translation>Nezrelé:</translation>
+ </message>
+ <message>
+ <source>Mined balance that has not yet matured</source>
+ <translation>Vytvorený zostatok ktorý ešte nedosiahol zrelosť</translation>
+ </message>
+ <message>
+ <source>Balances</source>
+ <translation>Stav účtu</translation>
+ </message>
+ <message>
+ <source>Total:</source>
+ <translation>Celkovo:</translation>
+ </message>
+ <message>
+ <source>Your current total balance</source>
+ <translation>Váš súčasný celkový zostatok</translation>
+ </message>
+ <message>
+ <source>Your current balance in watch-only addresses</source>
+ <translation>Váš celkový zostatok pre adresy ktoré sa iba sledujú</translation>
+ </message>
+ <message>
+ <source>Spendable:</source>
+ <translation>Použiteľné:</translation>
+ </message>
+ <message>
+ <source>Recent transactions</source>
+ <translation>Nedávne transakcie</translation>
+ </message>
+ <message>
+ <source>Unconfirmed transactions to watch-only addresses</source>
+ <translation>Nepotvrdené transakcie pre adresy ktoré sa iba sledujú</translation>
+ </message>
+ <message>
+ <source>Mined balance in watch-only addresses that has not yet matured</source>
+ <translation>Vyťažená suma pre adresy ktoré sa iba sledujú ale ešte nie je dozretá</translation>
+ </message>
+ <message>
+ <source>Current total balance in watch-only addresses</source>
+ <translation>Aktuálny celkový zostatok pre adries ktoré sa iba sledujú</translation>
+ </message>
+</context>
+<context>
+ <name>PaymentServer</name>
+ <message>
+ <source>URI handling</source>
+ <translation>Spracovanie URI</translation>
+ </message>
+ <message>
+ <source>Invalid payment address %1</source>
+ <translation>Neplatná adresa platby %1</translation>
+ </message>
+ <message>
+ <source>Payment request rejected</source>
+ <translation>Požiadavka na platbu zamietnutá</translation>
+ </message>
+ <message>
+ <source>Payment request network doesn't match client network.</source>
+ <translation>Sieť požiadavky na platbu nie je zhodná so sieťou klienta.</translation>
+ </message>
+ <message>
+ <source>Payment request is not initialized.</source>
+ <translation>Požiadavka na platbu nie je inicializovaná</translation>
+ </message>
+ <message>
+ <source>Requested payment amount of %1 is too small (considered dust).</source>
+ <translation>Požadovaná platba sumy %1 je príliš malá (považovaná za prach).</translation>
+ </message>
+ <message>
+ <source>Payment request error</source>
+ <translation>Chyba pri vyžiadaní platby</translation>
+ </message>
+ <message>
+ <source>Cannot start bitcoin: click-to-pay handler</source>
+ <translation>Nedá sa spustiť obslužný program bitcoin: click-to-pay zaplatiť kliknutím</translation>
+ </message>
+ <message>
+ <source>Payment request fetch URL is invalid: %1</source>
+ <translation>URL pre stiahnutie výzvy na zaplatenie je neplatné: %1</translation>
+ </message>
+ <message>
+ <source>URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source>
+ <translation>URI sa nedá analyzovať! To môže byť spôsobené neplatnou Bitcoin adresou alebo zle upravenými vlastnosťami URI.</translation>
+ </message>
+ <message>
+ <source>Payment request file handling</source>
+ <translation>Obsluha súboru s požiadavkou na platbu</translation>
+ </message>
+ <message>
+ <source>Payment request file cannot be read! This can be caused by an invalid payment request file.</source>
+ <translation>Súbor s výzvou na zaplatenie sa nedá čítať alebo spracovať! To môže byť spôsobené aj neplatným súborom s výzvou.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>Vypršala platnosť požiadavky na platbu.</translation>
+ </message>
+ <message>
+ <source>Unverified payment requests to custom payment scripts are unsupported.</source>
+ <translation>Program nepodporuje neoverené platobné výzvy na vlastná skripty.</translation>
+ </message>
+ <message>
+ <source>Invalid payment request.</source>
+ <translation>Chybná požiadavka na platbu.</translation>
+ </message>
+ <message>
+ <source>Refund from %1</source>
+ <translation>Vrátenie z %1</translation>
+ </message>
+ <message>
+ <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source>
+ <translation>Požiadavka na platbu %1 je príliš veľká (%2 bajtov, povolené je %3 bajtov).</translation>
+ </message>
+ <message>
+ <source>Payment request DoS protection</source>
+ <translation>Ochrana pred zahltením požiadavkami na platbu</translation>
+ </message>
+ <message>
+ <source>Error communicating with %1: %2</source>
+ <translation>Chyba komunikácie s %1: %2 </translation>
+ </message>
+ <message>
+ <source>Payment request cannot be parsed!</source>
+ <translation>Požiadavka na platbu nemôže byť analyzovaná!</translation>
+ </message>
+ <message>
+ <source>Bad response from server %1</source>
+ <translation>Zlá odpoveď zo servera %1</translation>
+ </message>
+ <message>
+ <source>Payment acknowledged</source>
+ <translation>Platba potvrdená</translation>
+ </message>
+ <message>
+ <source>Network request error</source>
+ <translation>Chyba požiadavky siete</translation>
+ </message>
+</context>
+<context>
+ <name>PeerTableModel</name>
+ <message>
+ <source>User Agent</source>
+ <translation>Aplikácia</translation>
+ </message>
+ <message>
+ <source>Node/Service</source>
+ <translation>Uzol/Služba</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Čas odozvy</translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>Suma</translation>
+ </message>
+ <message>
+ <source>Enter a Bitcoin address (e.g. %1)</source>
+ <translation>Zadajte bitcoin adresu (napr. %1)</translation>
+ </message>
+ <message>
+ <source>%1 d</source>
+ <translation>%1 d</translation>
+ </message>
+ <message>
+ <source>%1 h</source>
+ <translation>%1 h</translation>
+ </message>
+ <message>
+ <source>%1 m</source>
+ <translation>%1 m</translation>
+ </message>
+ <message>
+ <source>%1 s</source>
+ <translation>%1 s</translation>
+ </message>
+ <message>
+ <source>None</source>
+ <translation>Žiadne</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>nie je k dispozícii</translation>
+ </message>
+ <message>
+ <source>%1 ms</source>
+ <translation>%1 ms</translation>
+ </message>
+</context>
+<context>
+ <name>QRImageWidget</name>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>Uložiť obrázok...</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Image</source>
+ <translation>Kopírovať obrázok</translation>
+ </message>
+ <message>
+ <source>Save QR Code</source>
+ <translation>Ukladanie QR kódu</translation>
+ </message>
+ <message>
+ <source>PNG Image (*.png)</source>
+ <translation>PNG obrázok (*.png)</translation>
+ </message>
+</context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>Client name</source>
+ <translation>Meno klienta</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>nie je k dispozícii</translation>
+ </message>
+ <message>
+ <source>Client version</source>
+ <translation>Verzia klienta</translation>
+ </message>
+ <message>
+ <source>&amp;Information</source>
+ <translation>&amp;Informácia</translation>
+ </message>
+ <message>
+ <source>Debug window</source>
+ <translation>Okno pre ladenie</translation>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>Všeobecné</translation>
+ </message>
+ <message>
+ <source>Using OpenSSL version</source>
+ <translation>Používa OpenSSL verziu</translation>
+ </message>
+ <message>
+ <source>Using BerkeleyDB version</source>
+ <translation>Používa BerkeleyDB verziu</translation>
+ </message>
+ <message>
+ <source>Startup time</source>
+ <translation>Čas spustenia</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Sieť</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>Názov</translation>
+ </message>
+ <message>
+ <source>Number of connections</source>
+ <translation>Počet pripojení</translation>
+ </message>
+ <message>
+ <source>Block chain</source>
+ <translation>Reťazec blokov</translation>
+ </message>
+ <message>
+ <source>Current number of blocks</source>
+ <translation>Aktuálny počet blokov</translation>
+ </message>
+ <message>
+ <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source>
+ <translation>Otvoriť Bitcoin log súbor pre ladenie z aktuálneho dátového adresára. Toto môže trvať niekoľko sekúnd pre veľké súbory.</translation>
+ </message>
+ <message>
+ <source>Received</source>
+ <translation>Prijaté</translation>
+ </message>
+ <message>
+ <source>Sent</source>
+ <translation>Odoslané</translation>
+ </message>
+ <message>
+ <source>&amp;Peers</source>
+ <translation>&amp;Partneri</translation>
+ </message>
+ <message>
+ <source>Select a peer to view detailed information.</source>
+ <translation>Vyberte počítač pre zobrazenie podrobností.</translation>
+ </message>
+ <message>
+ <source>Direction</source>
+ <translation>Smer</translation>
+ </message>
+ <message>
+ <source>Version</source>
+ <translation>Verzia</translation>
+ </message>
+ <message>
+ <source>User Agent</source>
+ <translation>Aplikácia</translation>
+ </message>
+ <message>
+ <source>Services</source>
+ <translation>Služby</translation>
+ </message>
+ <message>
+ <source>Starting Height</source>
+ <translation>Počiatočná výška</translation>
+ </message>
+ <message>
+ <source>Sync Height</source>
+ <translation>Synchronizovaná výška</translation>
+ </message>
+ <message>
+ <source>Ban Score</source>
+ <translation>Skóre zákazu</translation>
+ </message>
+ <message>
+ <source>Connection Time</source>
+ <translation>Dĺžka spojenia</translation>
+ </message>
+ <message>
+ <source>Last Send</source>
+ <translation>Posledné odoslanie</translation>
+ </message>
+ <message>
+ <source>Last Receive</source>
+ <translation>Posledné prijatie</translation>
+ </message>
+ <message>
+ <source>Bytes Sent</source>
+ <translation>Odoslaných bajtov</translation>
+ </message>
+ <message>
+ <source>Bytes Received</source>
+ <translation>Prijatých bajtov</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Čas odozvy</translation>
+ </message>
+ <message>
+ <source>Time Offset</source>
+ <translation>Časový posun</translation>
+ </message>
+ <message>
+ <source>Last block time</source>
+ <translation>Čas posledného bloku</translation>
+ </message>
+ <message>
+ <source>&amp;Open</source>
+ <translation>&amp;Otvoriť</translation>
+ </message>
+ <message>
+ <source>&amp;Console</source>
+ <translation>&amp;Konzola</translation>
+ </message>
+ <message>
+ <source>&amp;Network Traffic</source>
+ <translation>&amp;Sieťová prevádzka</translation>
+ </message>
+ <message>
+ <source>&amp;Clear</source>
+ <translation>&amp;Vyčistiť</translation>
+ </message>
+ <message>
+ <source>Totals</source>
+ <translation>Celkovo:</translation>
+ </message>
+ <message>
+ <source>In:</source>
+ <translation>Dnu:</translation>
+ </message>
+ <message>
+ <source>Out:</source>
+ <translation>Von:</translation>
+ </message>
+ <message>
+ <source>Build date</source>
+ <translation>Dátum zostavenia</translation>
+ </message>
+ <message>
+ <source>Debug log file</source>
+ <translation>Súbor záznamu ladenia</translation>
+ </message>
+ <message>
+ <source>Clear console</source>
+ <translation>Vymazať konzolu</translation>
+ </message>
+ <message>
+ <source>Welcome to the Bitcoin Core RPC console.</source>
+ <translation>Vitajte v RPC konzole pre Jadro Bitcoin.</translation>
+ </message>
+ <message>
+ <source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
+ <translation>Použi šípky hore a dolu pre navigáciu históriou a &lt;b&gt;Ctrl-L&lt;/b&gt; pre vyčistenie obrazovky.</translation>
+ </message>
+ <message>
+ <source>Type &lt;b&gt;help&lt;/b&gt; for an overview of available commands.</source>
+ <translation>Napíš &lt;b&gt;help&lt;/b&gt; pre prehľad dostupných príkazov.</translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation>%1 B</translation>
+ </message>
+ <message>
+ <source>%1 KB</source>
+ <translation>%1 KB</translation>
+ </message>
+ <message>
+ <source>%1 MB</source>
+ <translation>%1 MB</translation>
+ </message>
+ <message>
+ <source>%1 GB</source>
+ <translation>%1 GB</translation>
+ </message>
+ <message>
+ <source>via %1</source>
+ <translation>cez %1</translation>
+ </message>
+ <message>
+ <source>never</source>
+ <translation>nikdy</translation>
+ </message>
+ <message>
+ <source>Inbound</source>
+ <translation>Prichádzajúce</translation>
+ </message>
+ <message>
+ <source>Outbound</source>
+ <translation>Odchádzajúce</translation>
+ </message>
+ <message>
+ <source>Unknown</source>
+ <translation>neznámy</translation>
+ </message>
+ <message>
+ <source>Fetching...</source>
+ <translation>Získava sa...</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Amount:</source>
+ <translation>&amp;Suma:</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Popis:</translation>
+ </message>
+ <message>
+ <source>&amp;Message:</source>
+ <translation>&amp;Správa:</translation>
+ </message>
+ <message>
+ <source>Reuse one of the previously used receiving addresses. Reusing addresses has security and privacy issues. Do not use this unless re-generating a payment request made before.</source>
+ <translation>Znovu použiť jednu z už použitých adries pre prijímanie. Znovu používanie adries je sporná otázka bezpečnosti aj súkromia. Používajte to len v prípade ak znovu generujete výzvu na zaplatenie ktorú ste už vyrobili v minulosti.</translation>
+ </message>
+ <message>
+ <source>R&amp;euse an existing receiving address (not recommended)</source>
+ <translation>Znovu použiť jestvujúcu prijímaciu adresu (neodporúča sa)</translation>
+ </message>
+ <message>
+ <source>An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network.</source>
+ <translation>Pridať voliteľnú správu k výzve na zaplatenie, ktorá sa zobrazí keď bude výzva otvorená. Poznámka: Správa nebude poslaná s platbou cez sieť Bitcoin.</translation>
+ </message>
+ <message>
+ <source>An optional label to associate with the new receiving address.</source>
+ <translation>Voliteľný popis ktorý sa pridá k tejto novej prijímajúcej adrese.</translation>
+ </message>
+ <message>
+ <source>Use this form to request payments. All fields are &lt;b&gt;optional&lt;/b&gt;.</source>
+ <translation>Použite tento formulár pre vyžiadanie platby. Všetky polia sú &lt;b&gt;voliteľné&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>An optional amount to request. Leave this empty or zero to not request a specific amount.</source>
+ <translation>Voliteľná požadovaná suma. Nechajte prázdne alebo nulu ak nepožadujete určitú sumu.</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Vyčistiť všetky polia formulára.</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation>Vyčistiť</translation>
+ </message>
+ <message>
+ <source>Requested payments history</source>
+ <translation>História vyžiadaných platieb</translation>
+ </message>
+ <message>
+ <source>&amp;Request payment</source>
+ <translation>Vyžiadať platbu</translation>
+ </message>
+ <message>
+ <source>Show the selected request (does the same as double clicking an entry)</source>
+ <translation>Zobraz zvolenú požiadavku (urobí to isté ako dvoj-klik na záznam)</translation>
+ </message>
+ <message>
+ <source>Show</source>
+ <translation>Zobraziť</translation>
+ </message>
+ <message>
+ <source>Remove the selected entries from the list</source>
+ <translation>Odstrániť zvolené záznamy zo zoznamu</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>Odstrániť</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Kopírovať popis</translation>
+ </message>
+ <message>
+ <source>Copy message</source>
+ <translation>Kopírovať správu</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopírovať sumu</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>QR Code</source>
+ <translation>QR kód</translation>
+ </message>
+ <message>
+ <source>Copy &amp;URI</source>
+ <translation>Kopírovať &amp;URI</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Address</source>
+ <translation>Kopírovať adresu</translation>
+ </message>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>Uložiť obrázok...</translation>
+ </message>
+ <message>
+ <source>Request payment to %1</source>
+ <translation>Vyžiadať platbu pre %1</translation>
+ </message>
+ <message>
+ <source>Payment information</source>
+ <translation>Informácia o platbe</translation>
+ </message>
+ <message>
+ <source>URI</source>
+ <translation>URI</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adresa</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Suma</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Popis</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Správa</translation>
+ </message>
+ <message>
+ <source>Resulting URI too long, try to reduce the text for label / message.</source>
+ <translation>Výsledné URI príliš dlhé, skráť text pre názov / správu.</translation>
+ </message>
+ <message>
+ <source>Error encoding URI into QR Code.</source>
+ <translation>Chyba v zakódovaní URI do QR kódu</translation>
+ </message>
+</context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Dátum</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Popis</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Správa</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Suma</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(bez popisu)</translation>
+ </message>
+ <message>
+ <source>(no message)</source>
+ <translation>(žiadna správa)</translation>
+ </message>
+ <message>
+ <source>(no amount)</source>
+ <translation>(žiadna suma)</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Poslať Bitcoins</translation>
+ </message>
+ <message>
+ <source>Coin Control Features</source>
+ <translation>Možnosti "Coin Control"</translation>
+ </message>
+ <message>
+ <source>Inputs...</source>
+ <translation>Vstupy...</translation>
+ </message>
+ <message>
+ <source>automatically selected</source>
+ <translation>automaticky vybrané</translation>
+ </message>
+ <message>
+ <source>Insufficient funds!</source>
+ <translation>Nedostatok prostriedkov!</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Množstvo:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Bajtov:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Suma:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Priorita:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Poplatok:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Po poplatku:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Zmena:</translation>
+ </message>
+ <message>
+ <source>If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address.</source>
+ <translation>Ak aktivované ale adresa pre výdavok je prázdna alebo neplatná, výdavok bude poslaný na novovytvorenú adresu.</translation>
+ </message>
+ <message>
+ <source>Custom change address</source>
+ <translation>Vlastná adresa zmeny</translation>
+ </message>
+ <message>
+ <source>Transaction Fee:</source>
+ <translation>Poplatok za transakciu:</translation>
+ </message>
+ <message>
+ <source>Choose...</source>
+ <translation>Zvoliť...</translation>
+ </message>
+ <message>
+ <source>collapse fee-settings</source>
+ <translation>zbaliť nastavenia poplatkov</translation>
+ </message>
+ <message>
+ <source>per kilobyte</source>
+ <translation>za kilobajt</translation>
+ </message>
+ <message>
+ <source>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "total at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source>
+ <translation>Ak je poplatok nastavený na 1000 satoshi a transakcia je veľká len 250 bajtov, potom "za kilobajt" zaplatí poplatok 250 satoshi, ale "spolu aspoň" zaplatí 1000 satoshi. Pre transakcie väčšie ako kilobajt platia oba spôsoby za každý kilobajt.</translation>
+ </message>
+ <message>
+ <source>Hide</source>
+ <translation>Skryť</translation>
+ </message>
+ <message>
+ <source>total at least</source>
+ <translation>spolu aspoň</translation>
+ </message>
+ <message>
+ <source>Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process.</source>
+ <translation>Zaplatenie len minimálneho poplatku je v poriadku, pokiaľ existuje menej transakcií ako miesta v blokoch. Uvedomte si však, že ak bude vyšší dopyt po transakciách ako dokáže sieť spracovať, môže byť vaša transakcia odsúvaná a nepotvrdená donekonečna.</translation>
+ </message>
+ <message>
+ <source>(read the tooltip)</source>
+ <translation>(prečítajte si nápovedu pod kurzorom)</translation>
+ </message>
+ <message>
+ <source>Recommended:</source>
+ <translation>Odporúčaný:</translation>
+ </message>
+ <message>
+ <source>Custom:</source>
+ <translation>Vlastný:</translation>
+ </message>
+ <message>
+ <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source>
+ <translation>(Automatický poplatok ešte nebol aktivovaný. Toto zvyčajne trvá niekoľko blokov...)</translation>
+ </message>
+ <message>
+ <source>Confirmation time:</source>
+ <translation>Čas potvrdenia:</translation>
+ </message>
+ <message>
+ <source>normal</source>
+ <translation>normálne</translation>
+ </message>
+ <message>
+ <source>fast</source>
+ <translation>rýchle</translation>
+ </message>
+ <message>
+ <source>Send as zero-fee transaction if possible</source>
+ <translation>Poslať ako transakciu bez poplatku, ak je to možné</translation>
+ </message>
+ <message>
+ <source>(confirmation may take longer)</source>
+ <translation>(potvrdenie môže trvať dlhšie)</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>Poslať viacerým príjemcom naraz</translation>
+ </message>
+ <message>
+ <source>Add &amp;Recipient</source>
+ <translation>&amp;Pridať príjemcu</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Vyčistiť všetky polia formulára.</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Prach:</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>&amp;Zmazať všetko</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>Zostatok:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>Potvrďte odoslanie</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>&amp;Odoslať</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>Potvrdiť odoslanie bitcoins</translation>
+ </message>
+ <message>
+ <source>%1 to %2</source>
+ <translation>%1 do %2</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Kopírovať množstvo</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopírovať sumu</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Kopírovať poplatok</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Kopírovať za poplatok</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Kopírovať bajty</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Kopírovať prioritu</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Kopírovať zmenu</translation>
+ </message>
+ <message>
+ <source>or</source>
+ <translation>alebo</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>Suma na úhradu musí byť väčšia ako 0.</translation>
+ </message>
+ <message>
+ <source>The amount exceeds your balance.</source>
+ <translation>Suma je vyššia ako Váš zostatok.</translation>
+ </message>
+ <message>
+ <source>The total exceeds your balance when the %1 transaction fee is included.</source>
+ <translation>Suma celkom prevyšuje Váš zostatok ak sú započítané %1 transakčné poplatky.</translation>
+ </message>
+ <message>
+ <source>Transaction creation failed!</source>
+ <translation>Vytvorenie transakcie zlyhalo!</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>Transakcia bola zamietnutá! Toto sa môže stať ak niektoré coins vo vašej peňaženke už boli minuté, ako keď použijete kópiu wallet.dat a coins boli minuté z kópie ale neoznačené ako minuté tu.</translation>
+ </message>
+ <message>
+ <source>A fee higher than %1 is considered an absurdly high fee.</source>
+ <translation>Poplatok vyšší ako %1 je považovaný za šialene vysoký.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>Vypršala platnosť požiadavky na platbu.</translation>
+ </message>
+ <message>
+ <source>Pay only the minimum fee of %1</source>
+ <translation>Zaplatiť minimálny poplatok %1</translation>
+ </message>
+ <message>
+ <source>The recipient address is not valid. Please recheck.</source>
+ <translation>Adresa príjemcu je neplatná. Prosím, overte ju.</translation>
+ </message>
+ <message>
+ <source>Duplicate address found: addresses should only be used once each.</source>
+ <translation>Našla sa duplicitná adresa: každú adresu je možné použiť len raz.</translation>
+ </message>
+ <message>
+ <source>Warning: Invalid Bitcoin address</source>
+ <translation>Varovanie: Nesprávna Bitcoin adresa</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(bez popisu)</translation>
+ </message>
+ <message>
+ <source>Warning: Unknown change address</source>
+ <translation>Varovanie: Neznáma adresa pre výdavok</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Kopírovať prach</translation>
+ </message>
+ <message>
+ <source>Are you sure you want to send?</source>
+ <translation>Určite to chcete odoslať?</translation>
+ </message>
+ <message>
+ <source>added as transaction fee</source>
+ <translation>pridané ako transakčný poplatok</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>Su&amp;ma:</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>Zapla&amp;tiť:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Vložte popis pre túto adresu aby sa pridala do adresára</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Popis:</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Vybrať predtým použitú adresu</translation>
+ </message>
+ <message>
+ <source>This is a normal payment.</source>
+ <translation>Toto je normálna platba.</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to send the payment to</source>
+ <translation>Zvoľte adresu kam poslať platbu</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Vložte adresu z klipbordu</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Remove this entry</source>
+ <translation>Odstrániť túto položku</translation>
+ </message>
+ <message>
+ <source>S&amp;ubtract fee from amount</source>
+ <translation>Odpočítať poplatok od s&amp;umy</translation>
+ </message>
+ <message>
+ <source>Message:</source>
+ <translation>Správa:</translation>
+ </message>
+ <message>
+ <source>This is an unauthenticated payment request.</source>
+ <translation>Toto je neoverená výzva k platbe.</translation>
+ </message>
+ <message>
+ <source>This is an authenticated payment request.</source>
+ <translation>Toto je overená výzva k platbe.</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to the list of used addresses</source>
+ <translation>Vložte popis pre túto adresu aby sa uložila do zoznamu použitých adries</translation>
+ </message>
+ <message>
+ <source>A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network.</source>
+ <translation>Správa ktorá bola pripojená k bitcoin: URI a ktorá bude uložená s transakcou pre Vaše potreby. Poznámka: Táto správa nebude poslaná cez sieť Bitcoin.</translation>
+ </message>
+ <message>
+ <source>Pay To:</source>
+ <translation>Platba pre:</translation>
+ </message>
+ <message>
+ <source>Memo:</source>
+ <translation>Poznámka:</translation>
+ </message>
+</context>
+<context>
+ <name>ShutdownWindow</name>
+ <message>
+ <source>Bitcoin Core is shutting down...</source>
+ <translation>Jadro Bitcoin sa ukončuje...</translation>
+ </message>
+ <message>
+ <source>Do not shut down the computer until this window disappears.</source>
+ <translation>Nevypínajte počítač kým toto okno nezmizne.</translation>
+ </message>
+</context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Signatures - Sign / Verify a Message</source>
+ <translation>Podpisy - Podpísať / Overiť správu</translation>
+ </message>
+ <message>
+ <source>&amp;Sign Message</source>
+ <translation>&amp;Podpísať Správu</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Vybrať predtým použitú adresu</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Vložte adresu z klipbordu</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Enter the message you want to sign here</source>
+ <translation>Sem vložte správu ktorú chcete podpísať</translation>
+ </message>
+ <message>
+ <source>Signature</source>
+ <translation>Podpis</translation>
+ </message>
+ <message>
+ <source>Copy the current signature to the system clipboard</source>
+ <translation>Kopírovať práve zvolenú adresu do systémového klipbordu</translation>
+ </message>
+ <message>
+ <source>Sign the message to prove you own this Bitcoin address</source>
+ <translation>Podpíšte správu aby ste dokázali že vlastníte túto adresu</translation>
+ </message>
+ <message>
+ <source>Sign &amp;Message</source>
+ <translation>Podpísať &amp;správu</translation>
+ </message>
+ <message>
+ <source>Reset all sign message fields</source>
+ <translation>Vynulovať všetky polia podpisu správy</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>&amp;Zmazať všetko</translation>
+ </message>
+ <message>
+ <source>&amp;Verify Message</source>
+ <translation>O&amp;veriť správu...</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address the message was signed with</source>
+ <translation>Adresa Bitcoin, ktorou bola podpísaná správa</translation>
+ </message>
+ <message>
+ <source>Verify the message to ensure it was signed with the specified Bitcoin address</source>
+ <translation>Overím správy sa uistiť že bola podpísaná označenou Bitcoin adresou</translation>
+ </message>
+ <message>
+ <source>Verify &amp;Message</source>
+ <translation>&amp;Overiť správu</translation>
+ </message>
+ <message>
+ <source>Reset all verify message fields</source>
+ <translation>Obnoviť všetky polia v overiť správu</translation>
+ </message>
+ <message>
+ <source>Click "Sign Message" to generate signature</source>
+ <translation>Kliknite "Podpísať Správu" na získanie podpisu</translation>
+ </message>
+ <message>
+ <source>The entered address is invalid.</source>
+ <translation>Zadaná adresa je neplatná.</translation>
+ </message>
+ <message>
+ <source>Please check the address and try again.</source>
+ <translation>Prosím skontrolujte adresu a skúste znova.</translation>
+ </message>
+ <message>
+ <source>The entered address does not refer to a key.</source>
+ <translation>Vložená adresa nezodpovedá žiadnemu kľúcu.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock was cancelled.</source>
+ <translation>Odomknutie peňaženky bolo zrušené.</translation>
+ </message>
+ <message>
+ <source>Private key for the entered address is not available.</source>
+ <translation>Súkromný kľúč pre vložená adresu nieje k dispozícii.</translation>
+ </message>
+ <message>
+ <source>Message signing failed.</source>
+ <translation>Podpísanie správy zlyhalo.</translation>
+ </message>
+ <message>
+ <source>Message signed.</source>
+ <translation>Správa podpísaná.</translation>
+ </message>
+ <message>
+ <source>The signature could not be decoded.</source>
+ <translation>Podpis nie je možné dekódovať.</translation>
+ </message>
+ <message>
+ <source>Please check the signature and try again.</source>
+ <translation>Prosím skontrolujte podpis a skúste znova.</translation>
+ </message>
+ <message>
+ <source>The signature did not match the message digest.</source>
+ <translation>Podpis sa nezhoduje so zhrnutím správy</translation>
+ </message>
+ <message>
+ <source>Message verification failed.</source>
+ <translation>Overenie správy zlyhalo.</translation>
+ </message>
+ <message>
+ <source>Message verified.</source>
+ <translation>Správa overená.</translation>
+ </message>
+</context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Jadro Bitcoin</translation>
+ </message>
+ <message>
+ <source>The Bitcoin Core developers</source>
+ <translation>Vývojári jadra Bitcoin</translation>
+ </message>
+ <message>
+ <source>[testnet]</source>
+ <translation>[testovacia sieť]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ <message>
+ <source>KB/s</source>
+ <translation>KB/s</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>Otvorené do %1</translation>
+ </message>
+ <message>
+ <source>conflicted</source>
+ <translation>sporné</translation>
+ </message>
+ <message>
+ <source>%1/offline</source>
+ <translation>%1/offline</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/nepotvrdené</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 potvrdení</translation>
+ </message>
+ <message>
+ <source>Status</source>
+ <translation>Stav</translation>
+ </message>
+ <message numerus="yes">
+ <source>, broadcast through %n node(s)</source>
+ <translation><numerusform>, vysielať cez %n uzol</numerusform><numerusform>, vysielať cez %n uzle</numerusform><numerusform>, vysielať cez %n uzolov</numerusform></translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Dátum</translation>
+ </message>
+ <message>
+ <source>Source</source>
+ <translation>Zdroj</translation>
+ </message>
+ <message>
+ <source>Generated</source>
+ <translation>Vygenerované</translation>
+ </message>
+ <message>
+ <source>From</source>
+ <translation>od</translation>
+ </message>
+ <message>
+ <source>To</source>
+ <translation>Pre</translation>
+ </message>
+ <message>
+ <source>own address</source>
+ <translation>vlastná adresa</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>Iba sledovanie</translation>
+ </message>
+ <message>
+ <source>label</source>
+ <translation>popis</translation>
+ </message>
+ <message>
+ <source>Credit</source>
+ <translation>Kredit</translation>
+ </message>
+ <message>
+ <source>not accepted</source>
+ <translation>neprijaté</translation>
+ </message>
+ <message>
+ <source>Debit</source>
+ <translation>Debet</translation>
+ </message>
+ <message>
+ <source>Total debit</source>
+ <translation>Debit spolu</translation>
+ </message>
+ <message>
+ <source>Total credit</source>
+ <translation>Kredit spolu</translation>
+ </message>
+ <message>
+ <source>Transaction fee</source>
+ <translation>Transakčný poplatok</translation>
+ </message>
+ <message>
+ <source>Net amount</source>
+ <translation>Suma netto</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Správa</translation>
+ </message>
+ <message>
+ <source>Comment</source>
+ <translation>Komentár</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>ID transakcie</translation>
+ </message>
+ <message>
+ <source>Merchant</source>
+ <translation>Kupec</translation>
+ </message>
+ <message>
+ <source>Generated coins must mature %1 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.</source>
+ <translation>Vygenerované mince musia dospieť %1 blokov kým môžu byť minuté. Keď vytvoríte tento blok, bude rozoslaný do siete aby bol akceptovaný do reťaze blokov. Ak sa nedostane do reťazca, jeho stav sa zmení na "zamietnutý" a nebude sa dať minúť. Toto sa môže občas stať ak iný uzol vytvorí blok približne v rovnakom čase.</translation>
+ </message>
+ <message>
+ <source>Debug information</source>
+ <translation>Ladiace informácie</translation>
+ </message>
+ <message>
+ <source>Transaction</source>
+ <translation>Transakcie</translation>
+ </message>
+ <message>
+ <source>Inputs</source>
+ <translation>Vstupy</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Suma</translation>
+ </message>
+ <message>
+ <source>true</source>
+ <translation>pravda</translation>
+ </message>
+ <message>
+ <source>false</source>
+ <translation>nepravda</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, ešte nebola úspešne odoslaná</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Otvorené pre %n ďalší blok</numerusform><numerusform>Otvorené pre %n ďalšie bloky</numerusform><numerusform>Otvorené pre %n ďalších blokov</numerusform></translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>neznámy</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>Detaily transakcie</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>Táto časť obrazovky zobrazuje detailný popis transakcie</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Dátum</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Typ</translation>
+ </message>
+ <message>
+ <source>Immature (%1 confirmations, will be available after %2)</source>
+ <translation>Nezrelé (%1 potvrdení, bude k dispozícii po %2)</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Otvorené pre %n ďalší blok</numerusform><numerusform>Otvorené pre %n ďalšie bloky</numerusform><numerusform>Otvorené pre %n ďalších blokov</numerusform></translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>Otvorené do %1</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>Potvrdené (%1 potvrdení)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>Ten blok nebol prijatý žiadnou inou nódou a pravdepodobne nebude akceptovaný!</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>Vygenerované ale neakceptované</translation>
+ </message>
+ <message>
+ <source>Offline</source>
+ <translation>Offline</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Popis</translation>
+ </message>
+ <message>
+ <source>Unconfirmed</source>
+ <translation>Nepotvrdené</translation>
+ </message>
+ <message>
+ <source>Confirming (%1 of %2 recommended confirmations)</source>
+ <translation> Potvrdzuje sa ( %1 z %2 odporúčaných potvrdení)</translation>
+ </message>
+ <message>
+ <source>Conflicted</source>
+ <translation>V rozpore</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Prijaté s</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>Prijaté od:</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Odoslané na</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>Platba sebe samému</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Vyťažené</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>Iba sledovanie</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(n/a)</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>Status transakcie. Pohybujte myšou nad týmto poľom a zjaví sa počet potvrdení.</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Dátum a čas prijatia transakcie.</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>Typ transakcie.</translation>
+ </message>
+ <message>
+ <source>Whether or not a watch-only address is involved in this transaction.</source>
+ <translation>Či sú ale nie sú, adresy iba na sledovanie zahrnuté v tejto transakcii.</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>Suma pridaná alebo odobraná k zostatku.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>Všetko</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>Dnes</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>Tento týždeň</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>Tento mesiac</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>Minulý mesiac</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>Tento rok</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>Rozsah...</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Prijaté s</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Odoslané na</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>Samému sebe</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Vyťažené</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>Iné</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>Vložte adresu alebo popis pre vyhľadávanie</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>Min množstvo</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Kopírovať adresu</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Kopírovať popis</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopírovať sumu</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Kopírovať ID transakcie</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>Editovať popis</translation>
+ </message>
+ <message>
+ <source>Show transaction details</source>
+ <translation>Zobraziť podrobnosti transakcie</translation>
+ </message>
+ <message>
+ <source>Export Transaction History</source>
+ <translation>Exportovať históriu transakcií</translation>
+ </message>
+ <message>
+ <source>Watch-only</source>
+ <translation>Iba sledovanie</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Export zlyhal</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the transaction history to %1.</source>
+ <translation>Vyskytla sa chyba pri pokuse o uloženie histórie transakcií do %1.</translation>
+ </message>
+ <message>
+ <source>Exporting Successful</source>
+ <translation>Export úspešný</translation>
+ </message>
+ <message>
+ <source>The transaction history was successfully saved to %1.</source>
+ <translation>História transakciá bola úspešne uložená do %1.</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Čiarkou oddelovaný súbor (*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Potvrdené</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Dátum</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Typ</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Popis</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adresa</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>Rozsah:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>do</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ <message>
+ <source>Unit to show amounts in. Click to select another unit.</source>
+ <translation>Jednotka pre zobrazovanie súm. Kliknite pre zvolenie inej jednotky.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletFrame</name>
+ <message>
+ <source>No wallet has been loaded.</source>
+ <translation>Nie je načítaná peňaženka.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Poslať Bitcoins</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Exportovať...</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Exportovať tento náhľad do súboru</translation>
+ </message>
+ <message>
+ <source>Backup Wallet</source>
+ <translation>Zálohovať peňaženku</translation>
+ </message>
+ <message>
+ <source>Wallet Data (*.dat)</source>
+ <translation>Údaje peňaženky (*.dat)</translation>
+ </message>
+ <message>
+ <source>Backup Failed</source>
+ <translation>Záloha zlyhala</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the wallet data to %1.</source>
+ <translation>Vyskytla sa chyba pri pokuse o uloženie dát peňaženky do %1.</translation>
+ </message>
+ <message>
+ <source>The wallet data was successfully saved to %1.</source>
+ <translation>Dáta peňaženky boli úspešne uložené do %1.</translation>
+ </message>
+ <message>
+ <source>Backup Successful</source>
+ <translation>Záloha úspešná</translation>
+ </message>
+</context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>Možnosti:</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>Určiť priečinok s dátami</translation>
+ </message>
+ <message>
+ <source>Connect to a node to retrieve peer addresses, and disconnect</source>
+ <translation>Pripojiť sa k uzlu, získať adresy ďalších počítačov v sieti a odpojiť sa</translation>
+ </message>
+ <message>
+ <source>Specify your own public address</source>
+ <translation>Určite vašu vlastnú verejnú adresu</translation>
+ </message>
+ <message>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>Prijímať príkazy z príkazového riadku a JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>Bežať na pozadí ako démon a prijímať príkazy</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>Použiť testovaciu sieť</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
+ <translation>Prijať spojenia zvonku (predvolené: 1 ak žiadne -proxy alebo -connect)</translation>
+ </message>
+ <message>
+ <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
+ <translation>Spojiť s danou adresou a vždy na nej počúvať. Použite zápis [host]:port pre IPv6</translation>
+ </message>
+ <message>
+ <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
+ <translation>Vymazať všetky transakcie z peňaženky a pri spustení znova získať z reťazca blokov iba tie získané pomocou -rescan</translation>
+ </message>
+ <message>
+ <source>Distributed under the MIT software license, see the accompanying file COPYING or &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</source>
+ <translation>Distribuované pod softvérovou licenciou MIT, viď sprievodný súbor COPYING alebo &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</translation>
+ </message>
+ <message>
+ <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
+ <translation>Vykonaj príkaz keď sa zmení transakcia peňaženky (%s v príkaze je nahradená TxID)</translation>
+ </message>
+ <message>
+ <source>Set the number of script verification threads (%u to %d, 0 = auto, &lt;0 = leave that many cores free, default: %d)</source>
+ <translation>Nastaviť počeť vlákien overujúcich skripty (%u až %d, 0 = auto, &lt;0 = nechať toľkoto jadier voľných, prednastavené: %d)</translation>
+ </message>
+ <message>
+ <source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source>
+ <translation>Toto je pred-testovacia verzia - použitie je na vlastné riziko - nepoužívajte na tvorbu bitcoin ani obchodovanie.</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer. Bitcoin Core is probably already running.</source>
+ <translation>Nepodarilo sa pripojiť na %s na tomto počítači. Bitcoin Jadro je už pravdepodobne spustené.</translation>
+ </message>
+ <message>
+ <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>Varovanie: -paytxfee je nastavené veľmi vysoko. Toto sú transakčné poplatky ktoré zaplatíte ak odošlete transakciu.</translation>
+ </message>
+ <message>
+ <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source>
+ <translation>Varovanie: Javí sa že sieť sieť úplne nesúhlasí! Niektorí mineri zjavne majú ťažkosti.
+
+The network does not appear to fully agree! Some miners appear to be experiencing issues.</translation>
+ </message>
+ <message>
+ <source>Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.</source>
+ <translation>Varovanie: Zjavne sa úplne nezhodujeme s našimi peer-mi! Možno potrebujete prejsť na novšiu verziu alebo ostatné uzly potrebujú vyššiu verziu.</translation>
+ </message>
+ <message>
+ <source>Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
+ <translation>Varovanie: chyba pri čítaní wallet.dad! Všetky kľúče sú čitateľné ale transakčné dáta alebo záznamy v adresári môžu byť nesprávne.</translation>
+ </message>
+ <message>
+ <source>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</source>
+ <translation>Varovanie: wallet.dat je poškodený, údaje úspešne získané! Pôvodný wallet.dat uložený ako wallet.{timestamp}.bak v %s; ak váš zostatok alebo transakcie niesu správne, mali by ste súbor obnoviť zo zálohy.</translation>
+ </message>
+ <message>
+ <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source>
+ <translation>Uzle na zoznam povolených, ktoré sa pripájajú z danej netmask alebo IP adresy. Môže byť zadané viac krát.</translation>
+ </message>
+ <message>
+ <source>(default: 1)</source>
+ <translation>(predvolené: 1)</translation>
+ </message>
+ <message>
+ <source>&lt;category&gt; can be:</source>
+ <translation>&lt;category&gt; môže byť:</translation>
+ </message>
+ <message>
+ <source>Attempt to recover private keys from a corrupt wallet.dat</source>
+ <translation>Pokus zachrániť súkromné kľúče z poškodeného wallet.dat</translation>
+ </message>
+ <message>
+ <source>Block creation options:</source>
+ <translation>Voľby vytvorenia bloku:</translation>
+ </message>
+ <message>
+ <source>Connect only to the specified node(s)</source>
+ <translation>Pripojiť sa len k určenej nóde</translation>
+ </message>
+ <message>
+ <source>Connection options:</source>
+ <translation>Možnosti pripojenia:</translation>
+ </message>
+ <message>
+ <source>Corrupted block database detected</source>
+ <translation>Zistená poškodená databáza blokov</translation>
+ </message>
+ <message>
+ <source>Debugging/Testing options:</source>
+ <translation>Možnosti ladenia/testovania:</translation>
+ </message>
+ <message>
+ <source>Do not load the wallet and disable wallet RPC calls</source>
+ <translation>Nenahrat peňaženku a zablokovať volania RPC.</translation>
+ </message>
+ <message>
+ <source>Do you want to rebuild the block database now?</source>
+ <translation>Chcete znovu zostaviť databázu blokov?</translation>
+ </message>
+ <message>
+ <source>Error initializing block database</source>
+ <translation>Chyba inicializácie databázy blokov</translation>
+ </message>
+ <message>
+ <source>Error initializing wallet database environment %s!</source>
+ <translation>Chyba spustenia databázového prostredia peňaženky %s!</translation>
+ </message>
+ <message>
+ <source>Error loading block database</source>
+ <translation>Chyba načítania databázy blokov</translation>
+ </message>
+ <message>
+ <source>Error opening block database</source>
+ <translation>Chyba otvárania databázy blokov</translation>
+ </message>
+ <message>
+ <source>Error: Disk space is low!</source>
+ <translation>Chyba: Málo miesta na disku!</translation>
+ </message>
+ <message>
+ <source>Failed to listen on any port. Use -listen=0 if you want this.</source>
+ <translation>Chyba počúvania na ktoromkoľvek porte. Použi -listen=0 ak toto chcete.</translation>
+ </message>
+ <message>
+ <source>If &lt;category&gt; is not supplied, output all debugging information.</source>
+ <translation>Ak nie je uvedená &lt;category&gt;, na výstupe zobrazuj všetky informácie pre ladenie.</translation>
+ </message>
+ <message>
+ <source>Importing...</source>
+ <translation>Prebieha import ...</translation>
+ </message>
+ <message>
+ <source>Incorrect or no genesis block found. Wrong datadir for network?</source>
+ <translation>Nesprávny alebo žiadny genesis blok nájdený. Nesprávny dátový priečinok alebo sieť?</translation>
+ </message>
+ <message>
+ <source>Invalid -onion address: '%s'</source>
+ <translation>Neplatná -onion adresa: '%s'</translation>
+ </message>
+ <message>
+ <source>Not enough file descriptors available.</source>
+ <translation>Nedostatok kľúčových slov súboru.</translation>
+ </message>
+ <message>
+ <source>Only connect to nodes in network &lt;net&gt; (ipv4, ipv6 or onion)</source>
+ <translation>Pripojiť iba k uzlom v sieti &lt;net&gt; (ipv4, ipv6, alebo onion)</translation>
+ </message>
+ <message>
+ <source>Set database cache size in megabytes (%d to %d, default: %d)</source>
+ <translation>Nastaviť veľkosť pomocnej pamäti databázy v megabajtoch (%d do %d, prednastavené: %d)</translation>
+ </message>
+ <message>
+ <source>Set maximum block size in bytes (default: %d)</source>
+ <translation>Nastaviť najväčšiu veľkosť bloku v bytoch (predvolené: %d)</translation>
+ </message>
+ <message>
+ <source>Specify wallet file (within data directory)</source>
+ <translation>Označ súbor peňaženky (v priečinku s dátami)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: %u)</source>
+ <translation>Použiť UPnP pre mapovanie počúvajúceho portu (predvolené: %u)</translation>
+ </message>
+ <message>
+ <source>Verifying blocks...</source>
+ <translation>Overujem bloky...</translation>
+ </message>
+ <message>
+ <source>Verifying wallet...</source>
+ <translation>Overujem peňaženku...</translation>
+ </message>
+ <message>
+ <source>Wallet %s resides outside data directory %s</source>
+ <translation>Peňaženka %s sa nachádza mimo dátového priečinka %s </translation>
+ </message>
+ <message>
+ <source>Wallet options:</source>
+ <translation>Voľby peňaženky:</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to change -txindex</source>
+ <translation>Potrebujete prebudovať databázu použitím -reindex zmeniť -txindex</translation>
+ </message>
+ <message>
+ <source>Imports blocks from external blk000??.dat file</source>
+ <translation>Importuje bloky z externého súboru blk000??.dat</translation>
+ </message>
+ <message>
+ <source>Allow JSON-RPC connections from specified source. Valid for &lt;ip&gt; are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times</source>
+ <translation>Povoliť JSON-RPC pripojenia zo zadaného zdroja. Pre &lt;ip&gt; sú platné jednoduché IP (napr. 1.2.3.4), sieť/netmask (napr. 1.2.3.4/255.255.255.0) alebo sieť/CIDR (napr. 1.2.3.4/24). Táto možnosť môže byť zadaná niekoľko krát</translation>
+ </message>
+ <message>
+ <source>An error occurred while setting up the RPC address %s port %u for listening: %s</source>
+ <translation>Pri nastavovaní RPC adresy %s na porte %u pre počúvanie došlo k chybe: %s</translation>
+ </message>
+ <message>
+ <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source>
+ <translation>Spojiť s danou adresou a povolenými partnerskými zariadeniami ktoré sa tam pripájajú. Použite zápis [host]:port pre IPv6</translation>
+ </message>
+ <message>
+ <source>Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)</source>
+ <translation>Spojiť s danou adresou pre počúvanie JSON-RPC spojení. Použite zápis [host]:port pre IPv6. Táto možnosť môže byt zadaná niekoľko krát (predvolené: spojiť so všetkými rozhraniami)</translation>
+ </message>
+ <message>
+ <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source>
+ <translation>Neviem uzamknúť data adresár %s. Jadro Bitcoin je pravdepodobne už spustené.</translation>
+ </message>
+ <message>
+ <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
+ <translation>Vytvoriť nové súbory z predvolenými systémovými právami, namiesto umask 077 (funguje iba z vypnutou funkcionalitou peňaženky)</translation>
+ </message>
+ <message>
+ <source>Error: Listening for incoming connections failed (listen returned error %s)</source>
+ <translation>Chyba: Počúvanie prichádzajúcich spojení zlyhalo (vrátená chyba je %s)</translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source>
+ <translation>Chyba: Nájdený nepodporovaný argument -socks. Nastavenie SOCKS verzie nie je už možné, podporované sú už iba proxy SOCKS5.</translation>
+ </message>
+ <message>
+ <source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source>
+ <translation>Vykonať príkaz po prijatí patričného varovania alebo uvidíme veľmi dlhé rozdvojenie siete (%s v cmd je nahradené správou)</translation>
+ </message>
+ <message>
+ <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source>
+ <translation>Poplatky (v BTC/Kb) nižšie ako toľkoto sa považujú za nulové pri postupovaní transakcií (predvolené: %s)</translation>
+ </message>
+ <message>
+ <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
+ <translation>Ak nie je nastavené paytxfee, pridať dostatočný poplatok aby sa transakcia začala potvrdzovať priemerne v rámci bloku (predvolené: %u)</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)</source>
+ <translation>Neplatná suma pre -maxtxfee=&lt;amount&gt;: '%s' (aby sa transakcia nezasekla, minimálny prenosový poplatok musí byť aspoň %s)</translation>
+ </message>
+ <message>
+ <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source>
+ <translation>Maximálna veľkosť dát v transakciách nosných dát, ktoré prenášame a ťažíme (predvolené: %u)</translation>
+ </message>
+ <message>
+ <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source>
+ <translation>Dotaz na partnerské adresy pomocou vyhľadávania DNS v prípade nedostatku adries (predvolené: 1, pokiaľ -connect)</translation>
+ </message>
+ <message>
+ <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
+ <translation>Nastaviť najväčšiu veľkosť vysoká-dôležitosť/nízke-poplatky transakcií v bajtoch (prednastavené: %d)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source>
+ <translation>Nastaviť počet vlákien pre generáciu mincí (-1 = všetky jadrá, predvolené: %d)</translation>
+ </message>
+ <message>
+ <source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit &lt;https://www.openssl.org/&gt; and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source>
+ <translation>Tento produkt obsahuje softvér vyvinutý projektom OpenSSL pre použitie sady nástrojov OpenSSL &lt;https://www.openssl.org/&gt; a kryptografického softvéru napísaného Eric Young a UPnP softvér napísaný Thomas Bernard.</translation>
+ </message>
+ <message>
+ <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source>
+ <translation>Upozornenie: -maxtxfee je nastavené príliš vysoko! Takto vysoké poplatky by mali byť zaplatené za jednu transakciu.</translation>
+ </message>
+ <message>
+ <source>Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway</source>
+ <translation>Uzle na zoznam povolených nemôžu byť DoS zakázané a ich transakcie vždy postúpené ďalej, aj v prípade, ak sú už pamäťovej fronte. Užitočné napr. pre brány</translation>
+ </message>
+ <message>
+ <source>(default: %u)</source>
+ <translation>(predvolené: %u)</translation>
+ </message>
+ <message>
+ <source>Accept public REST requests (default: %u)</source>
+ <translation>Akceptovať verejné REST žiadosti (predvolené: %u)</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -whitebind address: '%s'</source>
+ <translation>Nedá sa vyriešiť -whitebind adresa: '%s'</translation>
+ </message>
+ <message>
+ <source>Choose data directory on startup (default: 0)</source>
+ <translation>Zvoľte dátový priečinok pri štarte (prednastavené: 0)</translation>
+ </message>
+ <message>
+ <source>Connect through SOCKS5 proxy</source>
+ <translation>Pripojiť cez proxy server SOCKS5</translation>
+ </message>
+ <message>
+ <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source>
+ <translation>Autorské práva (C) 2009-%i Vývojári jadra Bitcoin</translation>
+ </message>
+ <message>
+ <source>Could not parse -rpcbind value %s as network address</source>
+ <translation>Nedá sa analyzovať -rpcbind hodnota %s ako sieťová adresa</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source>
+ <translation>Chyba pri čítaní wallet.dat: Peňaženka vyžaduje vyššiu verziu Jadra Bitcoin</translation>
+ </message>
+ <message>
+ <source>Error reading from database, shutting down.</source>
+ <translation>Chyba pri načítaní z databázy, ukončuje sa.</translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -tor found, use -onion.</source>
+ <translation>Chyba: nájdený nepodporovaný argument -tor, použite -onion.</translation>
+ </message>
+ <message>
+ <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source>
+ <translation>Poplatok (v BTC/kB), ktorý sa pridá k transakciám, ktoré odosielate (predvolený: %s)</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Informácia</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Neplatná suma pre -maxtxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -minrelaytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Neplatná suma pre -minrelaytxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -mintxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Neplatná suma pre -mintxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s' (must be at least %s)</source>
+ <translation>Neplatná suma pre -paytxfee=&lt;amount&gt;: '%s' (musí byť aspoň %s)</translation>
+ </message>
+ <message>
+ <source>Invalid netmask specified in -whitelist: '%s'</source>
+ <translation>Nadaná neplatná netmask vo -whitelist: '%s'</translation>
+ </message>
+ <message>
+ <source>Keep at most &lt;n&gt; unconnectable transactions in memory (default: %u)</source>
+ <translation>V pamäti udržiavať najviac &lt;n&gt; nepotvrdených transakcií (predvolené: %u)</translation>
+ </message>
+ <message>
+ <source>Need to specify a port with -whitebind: '%s'</source>
+ <translation>Je potrebné zadať port s -whitebind: '%s'</translation>
+ </message>
+ <message>
+ <source>Node relay options:</source>
+ <translation>Prenosové možnosti uzla:</translation>
+ </message>
+ <message>
+ <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source>
+ <translation>Možnosti RPC SSL: (Pozri v Bitcoin Wiki pokyny pre SSL nastavenie)</translation>
+ </message>
+ <message>
+ <source>RPC server options:</source>
+ <translation>Možnosti servra RPC:</translation>
+ </message>
+ <message>
+ <source>RPC support for HTTP persistent connections (default: %d)</source>
+ <translation>Podpora RPC pre trvalé HTTP spojenia (predvolené: %d)</translation>
+ </message>
+ <message>
+ <source>Receive and display P2P network alerts (default: %u)</source>
+ <translation>Obdržať a zobraziť sieťové P2P varovania (predvolené: %u)</translation>
+ </message>
+ <message>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>Odoslať trace/debug informácie na konzolu namiesto debug.info žurnálu</translation>
+ </message>
+ <message>
+ <source>Send transactions as zero-fee transactions if possible (default: %u)</source>
+ <translation>Poslať ako transakcie bez poplatku, ak je to možné (predvolené: %u)</translation>
+ </message>
+ <message>
+ <source>Set SSL root certificates for payment request (default: -system-)</source>
+ <translation>Nastaviť koreňový certifikát pre výzvy na platbu (prednastavené: -system-)</translation>
+ </message>
+ <message>
+ <source>Set language, for example "de_DE" (default: system locale)</source>
+ <translation>Nastaviť jazyk, napríklad "sk_SK" (predvolené: systémový)</translation>
+ </message>
+ <message>
+ <source>Show all debugging options (usage: --help -help-debug)</source>
+ <translation>Zobraziť všetky možnosti ladenia (použitie: --help --help-debug)</translation>
+ </message>
+ <message>
+ <source>Show splash screen on startup (default: 1)</source>
+ <translation>Zobraziť splash screen pri spustení (predvolené: 1)</translation>
+ </message>
+ <message>
+ <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source>
+ <translation>Zmenšiť debug.log pri spustení klienta (predvolené: 1 ak bez -debug)</translation>
+ </message>
+ <message>
+ <source>Signing transaction failed</source>
+ <translation>Podpísanie správy zlyhalo</translation>
+ </message>
+ <message>
+ <source>Start minimized</source>
+ <translation>Spustiť minimalizované</translation>
+ </message>
+ <message>
+ <source>This is experimental software.</source>
+ <translation>Toto je experimentálny softvér.</translation>
+ </message>
+ <message>
+ <source>Transaction amount too small</source>
+ <translation>Suma transakcie príliš malá</translation>
+ </message>
+ <message>
+ <source>Transaction amounts must be positive</source>
+ <translation>Hodnoty transakcie musia byť väčšie ako nula (pozitívne)</translation>
+ </message>
+ <message>
+ <source>Transaction too large for fee policy</source>
+ <translation>Transakcia je príliš veľká pre aktuálne podmienky poplatkov</translation>
+ </message>
+ <message>
+ <source>Transaction too large</source>
+ <translation>Transakcia príliš veľká</translation>
+ </message>
+ <message>
+ <source>UI Options:</source>
+ <translation>Možnosti používateľského rozhrania:</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer (bind returned error %s)</source>
+ <translation>Na tomto počítači sa nedá vytvoriť väzba %s (vytvorenie väzby vrátilo chybu %s)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: 1 when listening)</source>
+ <translation>Skúsiť použiť UPnP pre mapovanie počúvajúceho portu (default: 1 when listening)</translation>
+ </message>
+ <message>
+ <source>Username for JSON-RPC connections</source>
+ <translation>Užívateľské meno pre JSON-RPC spojenia</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Upozornenie</translation>
+ </message>
+ <message>
+ <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source>
+ <translation>Upozornenie: Nepodporovaný argument -benchmark bol ignorovaný, použite -debug=bench.</translation>
+ </message>
+ <message>
+ <source>Warning: Unsupported argument -debugnet ignored, use -debug=net.</source>
+ <translation>Upozornenie: Nepodporovaný argument -debugnet bol ignorovaný, použite -debug=net.</translation>
+ </message>
+ <message>
+ <source>Zapping all transactions from wallet...</source>
+ <translation>Zmazať všetky transakcie z peňaženky...</translation>
+ </message>
+ <message>
+ <source>on startup</source>
+ <translation>pri štarte</translation>
+ </message>
+ <message>
+ <source>wallet.dat corrupt, salvage failed</source>
+ <translation>wallet.dat je poškodený, záchrana zlyhala</translation>
+ </message>
+ <message>
+ <source>Password for JSON-RPC connections</source>
+ <translation>Heslo pre JSON-rPC spojenia</translation>
+ </message>
+ <message>
+ <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
+ <translation>Vykonaj príkaz, ak zmeny v najlepšom bloku (%s v príkaze nahradí blok hash)</translation>
+ </message>
+ <message>
+ <source>Upgrade wallet to latest format</source>
+ <translation>Aktualizuj peňaženku na najnovší formát.</translation>
+ </message>
+ <message>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>Znovu skenovať reťaz blokov pre chýbajúce transakcie</translation>
+ </message>
+ <message>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>Použiť OpenSSL (https) pre JSON-RPC spojenia</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>Táto pomocná správa</translation>
+ </message>
+ <message>
+ <source>Allow DNS lookups for -addnode, -seednode and -connect</source>
+ <translation>Povoliť vyhľadávanie DNS pre pridanie nódy a spojenie</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>Načítavanie adries...</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>Chyba načítania wallet.dat: Peňaženka je poškodená</translation>
+ </message>
+ <message>
+ <source>(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source>
+ <translation>(1 = zachovať metaúdaje tx napr. vlastníka účtu a informácie o platobných príkazoch, 2 = zahodiť metaúdaje tx)</translation>
+ </message>
+ <message>
+ <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
+ <translation>Ako dôkladné je -checkblocks overenie blokov (0-4, predvolené: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
+ <translation>Udržiavať kompletný transakčný index, využíva getrawtransaction rpc volanie (predvolené: %u)</translation>
+ </message>
+ <message>
+ <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source>
+ <translation>Počet sekúnd, počas ktorých nepripájať zle správajúce sa uzle (predvolené: %u)</translation>
+ </message>
+ <message>
+ <source>Output debugging information (default: %u, supplying &lt;category&gt; is optional)</source>
+ <translation>Výstupné ladiace informácie (predvolené: %u, dodanie &lt;category&gt; je voliteľné)</translation>
+ </message>
+ <message>
+ <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source>
+ <translation>Použiť samostatný SOCKS5 proxy server na dosiahnutie počítačov cez skryté služby Tor (predvolené: %s)</translation>
+ </message>
+ <message>
+ <source>(default: %s)</source>
+ <translation>(predvolené: %s)</translation>
+ </message>
+ <message>
+ <source>Acceptable ciphers (default: %s)</source>
+ <translation>Prijateľné šifry (predvolené: %s)</translation>
+ </message>
+ <message>
+ <source>Always query for peer addresses via DNS lookup (default: %u)</source>
+ <translation>Vždy sa dotazovať adresy partnerských uzlov cez vyhľadávanie DNS (predvolené: %u)</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>Chyba načítania wallet.dat</translation>
+ </message>
+ <message>
+ <source>How many blocks to check at startup (default: %u, 0 = all)</source>
+ <translation>Koľko blokov overiť pri spustení (predvolené: %u, 0 = všetky)</translation>
+ </message>
+ <message>
+ <source>Include IP addresses in debug output (default: %u)</source>
+ <translation>Zahrnúť IP adresy v ladiacom výstupe (predvolené: %u)</translation>
+ </message>
+ <message>
+ <source>Invalid -proxy address: '%s'</source>
+ <translation>Neplatná adresa proxy: '%s'</translation>
+ </message>
+ <message>
+ <source>Listen for JSON-RPC connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>Počúvať JSON-RPC pripojenia na &lt;port&gt; (predvolené: %u alebo testovacia sieť: %u)</translation>
+ </message>
+ <message>
+ <source>Listen for connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>Počúvať pripojenia na &lt;port&gt; (predvolené: %u alebo testovacia sieť: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain at most &lt;n&gt; connections to peers (default: %u)</source>
+ <translation>Udržiavať najviac &lt;n&gt; spojení s inými počítačmi (predvolené: %u)</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection receive buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>Maximálna prijímajúca medzipamäť pre pripojenie, &lt;n&gt;*1000 bajtov (predvolené: %u)</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection send buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>Maximálna odosielajúca medzipamäť pre pripojenie, &lt;n&gt;*1000 bajtov (predvolené: %u)</translation>
+ </message>
+ <message>
+ <source>Prepend debug output with timestamp (default: %u)</source>
+ <translation>Na začiatok pripojiť časovú známku k ladiacemu výstupu (predvolené: %u)</translation>
+ </message>
+ <message>
+ <source>Relay and mine data carrier transactions (default: %u)</source>
+ <translation>Prenášať a ťažiť transakcie nosných dát (predvolené: %u)</translation>
+ </message>
+ <message>
+ <source>Relay non-P2SH multisig (default: %u)</source>
+ <translation>Prenášať non-P2SH multi-podpis (predvolené: %u)</translation>
+ </message>
+ <message>
+ <source>Server certificate file (default: %s)</source>
+ <translation>Certifikačný súbor servera (predvolené: %s)</translation>
+ </message>
+ <message>
+ <source>Server private key (default: %s)</source>
+ <translation>Privátny kľúč servera (predvolené: %s)</translation>
+ </message>
+ <message>
+ <source>Set key pool size to &lt;n&gt; (default: %u)</source>
+ <translation>Nastaviť veľkosť kľúča fronty na &lt;n&gt; (predvolené: %u)</translation>
+ </message>
+ <message>
+ <source>Set minimum block size in bytes (default: %u)</source>
+ <translation>Nastaviť minimálnu veľkosť bloku v bajtoch (predvolené: %u)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads to service RPC calls (default: %d)</source>
+ <translation>Nastaviť počet vlákien na obsluhu RPC volaní (predvolené: %d)</translation>
+ </message>
+ <message>
+ <source>Specify configuration file (default: %s)</source>
+ <translation>Zadať konfiguračný súbor (predvolené: %s)</translation>
+ </message>
+ <message>
+ <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source>
+ <translation>Zadajte časový limit pripojenia v milisekundách (minimum: 1, predvolené: %d)</translation>
+ </message>
+ <message>
+ <source>Specify pid file (default: %s)</source>
+ <translation>Zadať pid súbor (predvolené: %s)</translation>
+ </message>
+ <message>
+ <source>Spend unconfirmed change when sending transactions (default: %u)</source>
+ <translation>Minúť nepotvrdené zmenu pri posielaní transakcií (predvolené: %u)</translation>
+ </message>
+ <message>
+ <source>Threshold for disconnecting misbehaving peers (default: %u)</source>
+ <translation>Hranica pre odpájanie zle sa správajúcim partnerským uzlom (predvolené: %u)</translation>
+ </message>
+ <message>
+ <source>Unknown network specified in -onlynet: '%s'</source>
+ <translation>Neznáma sieť upresnená v -onlynet: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -bind address: '%s'</source>
+ <translation>Nemožno rozriešiť -bind adress: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -externalip address: '%s'</source>
+ <translation>Nemožno rozriešiť -externalip address: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Neplatná suma pre -paytxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>Nedostatok prostriedkov</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>Načítavanie zoznamu blokov...</translation>
+ </message>
+ <message>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>Pridať nód na pripojenie a pokus o udržanie pripojenia otvoreného</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>Načítavam peňaženku...</translation>
+ </message>
+ <message>
+ <source>Cannot downgrade wallet</source>
+ <translation>Nie je možné prejsť na nižšiu verziu peňaženky</translation>
+ </message>
+ <message>
+ <source>Cannot write default address</source>
+ <translation>Nie je možné zapísať predvolenú adresu.</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>Nové prehľadávanie...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>Dokončené načítavanie</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Chyba</translation>
+ </message>
+</context>
+</TS> \ No newline at end of file
diff --git a/src/qt/locale/bitcoin_sl_SI.ts b/src/qt/locale/bitcoin_sl_SI.ts
new file mode 100644
index 0000000000..4c3427e47b
--- /dev/null
+++ b/src/qt/locale/bitcoin_sl_SI.ts
@@ -0,0 +1,3312 @@
+<TS language="sl_SI" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Right-click to edit address or label</source>
+ <translation>Desni klik za urejanje naslovov ali oznak</translation>
+ </message>
+ <message>
+ <source>Create a new address</source>
+ <translation>Ustvari nov naslov</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>&amp;Novo</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Kopiraj trenutno izbrani naslov v odložišče</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>&amp;Kopiraj</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>&amp;Zapri</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>&amp;Kopiraj naslov</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>Izbriši trenutno označeni naslov iz seznama</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Izvozi podatke v trenutnem zavihku v datoteko</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Izvozi</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>I&amp;zbriši</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>Izbira naslova, na katerega pošiljate plačilo</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>Izbira naslova za prejem plačila</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>&amp;Izberi</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>Imenik naslovov za pošiljanje</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>Imenik naslovov za prejemanje</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>To je vaš imenik shranjenih naslovov Bitcoin, na katere lahko pošiljate plačila. Pred vsakim odlivom vedno preverite, če sta znesek in prejemnikov naslov pravilna.</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>To je imenik vaših ustvarjenih naslovov Bitcoin, na katere lahko prejemate plačila. Priporočljivo je, da za vsak nov priliv ustvarite nov prejemni naslov.</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>Kopiraj &amp;oznako</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>&amp;Uredi</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>Izvozi seznam naslovov</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Datoteka s podatki, ločenimi z vejico (*.csv)</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Seznama naslovov ni bilo mogoče izvoziti.</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the address list to %1. Please try again.</source>
+ <translation>Napaka pri shranjevanju seznama naslovov v datoteko %1. Prosimo, poskusite znova.</translation>
+ </message>
+</context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Oznaka</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Naslov</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(brez oznake)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Passphrase Dialog</source>
+ <translation>Vnos gesla</translation>
+ </message>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Vnesite geslo</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Novo geslo</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Ponovite novo geslo</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>Šifriraj denarnico</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>To dejanje zahteva geslo za odklepanje vaše denarnice.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Odkleni denarnico</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>To dejanje zahteva geslo za dešifriranje vaše denarnice.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>Dešifriraj denarnico</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>Zamenjaj geslo</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>Potrditev šifriranja denarnice</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>Opozorilo: V primeru izgube gesla šifrirane denarnice, boste &lt;b&gt;IZGUBILI VSE BITCOINE V DENARNICI&lt;/b&gt;!</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>Ali ste prepričani, da želite šifrirati vašo denarnico?</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core 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.</source>
+ <translation>Program se bo zaprl, da dokonča proces šifriranja. Zapomnite si, da šifriranje ne more popolnoma zaščititi vaše denarnice pred krajami in zlonamernimi programi, ki bi lahko bili nameščeni na vašem računalniku.</translation>
+ </message>
+ <message>
+ <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
+ <translation>POMEMBNO: Vse starejše obstoječe varnostne kopije denarnice je potrebno zamenjati s to novo, šifrirano varnostno kopijo. Iz varnostnih razlogov bodo stare varnostne kopije postale neuporabne takoj, ko začnete uporabljati novo, šifrirano denarnico.</translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>Opozorilo: imate vklopljene velike črke (Caps Lock)</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>Denarnica je šifrirana</translation>
+ </message>
+ <message>
+ <source>Enter the new passphrase to the wallet.&lt;br/&gt;Please use a passphrase of &lt;b&gt;ten or more random characters&lt;/b&gt;, or &lt;b&gt;eight or more words&lt;/b&gt;.</source>
+ <translation>Vnesite novo geslo. Prosimo, da uporabite geslo sestavljeno iz &lt;b&gt;deset ali več&lt;/b&gt; naključnih znakov, ali &lt;b&gt;osem ali več&lt;/b&gt; besed.</translation>
+ </message>
+ <message>
+ <source>Enter the old passphrase and new passphrase to the wallet.</source>
+ <translation>Vnesite staro in novo geslo denarnice.</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>Denarnice ni bilo mogoče šifrirati.</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>Prišlo je do napake. Denarnice ni bilo mogoče šifrirati.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>Vnešeni gesli se ne ujemata</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>Denarnice ni bilo mogoče odkleniti.</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>Vnesli ste napačno geslo za dešifriranje denarnice.</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>Denarnice ni bilo mogoče dešifrirati.</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>Geslo za dostop do denarnice je bilo uspešno zamenjano.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>Podpiši &amp;sporočilo ...</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>Dohitevam omrežje ...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>Pre&amp;gled</translation>
+ </message>
+ <message>
+ <source>Node</source>
+ <translation>Vozlišče</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>Oglejte si splošne informacije o vaši denarnici</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Transakcije</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>Brskajte po zgodovini transakcij</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>I&amp;zhod</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>Ustavite program</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>O &amp;Qt</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>Oglejte si informacije o Qt</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;Možnosti ...</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>&amp;Šifriraj denarnico ...</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>Shrani &amp;varnostno kopijo denarnice ...</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>&amp;Spremeni geslo ...</translation>
+ </message>
+ <message>
+ <source>&amp;Sending addresses...</source>
+ <translation>Naslovi za po&amp;šiljanje ...</translation>
+ </message>
+ <message>
+ <source>&amp;Receiving addresses...</source>
+ <translation>Naslovi za &amp;prejemanje...</translation>
+ </message>
+ <message>
+ <source>Open &amp;URI...</source>
+ <translation>Odpri &amp;URI ...</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core client</source>
+ <translation>Odjemalec Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Importing blocks from disk...</source>
+ <translation>Uvažam bloke z diska ...</translation>
+ </message>
+ <message>
+ <source>Reindexing blocks on disk...</source>
+ <translation>Poustvarjam kazalo blokov na disku ...</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>Izvedite plačilo na naslov Bitcoin</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>Shranite varnostno kopijo svoje denarnice na drugo lokacijo</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Spremenite geslo za šifriranje denarnice</translation>
+ </message>
+ <message>
+ <source>&amp;Debug window</source>
+ <translation>&amp;Razhroščevalno okno</translation>
+ </message>
+ <message>
+ <source>Open debugging and diagnostic console</source>
+ <translation>Odprite razhroščevalno in diagnostično konzolo</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>&amp;Preveri sporočilo ...</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>Denarnica</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>&amp;Pošlji</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>P&amp;rejmi</translation>
+ </message>
+ <message>
+ <source>Show information about Bitcoin Core</source>
+ <translation>Oglejte si informacije o programu</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>&amp;Prikaži / Skrij</translation>
+ </message>
+ <message>
+ <source>Show or hide the main Window</source>
+ <translation>Prikaži ali skrij glavno okno</translation>
+ </message>
+ <message>
+ <source>Encrypt the private keys that belong to your wallet</source>
+ <translation>Šifrirajte zasebne ključe, ki se nahajajo v denarnici</translation>
+ </message>
+ <message>
+ <source>Sign messages with your Bitcoin addresses to prove you own them</source>
+ <translation>Podpišite poljubno sporočilo z enim svojih naslovov Bitcoin, da prejemniku sporočila dokažete, da je ta naslov v vaši lasti.</translation>
+ </message>
+ <message>
+ <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source>
+ <translation>Preverite, če je bilo prejeto sporočilo podpisano z določenim naslovom Bitcoin</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;Datoteka</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;Nastavitve</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>&amp;Pomoč</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>Orodna vrstica zavihkov</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Request payments (generates QR codes and bitcoin: URIs)</source>
+ <translation>Zahtevajte plačilo (ustvarite zahtevek s kodo QR in URI tipa bitcoin:)</translation>
+ </message>
+ <message>
+ <source>&amp;About Bitcoin Core</source>
+ <translation>&amp;O programu</translation>
+ </message>
+ <message>
+ <source>Modify configuration options for Bitcoin Core</source>
+ <translation>Spremenite programske nastavitve</translation>
+ </message>
+ <message>
+ <source>Show the list of used sending addresses and labels</source>
+ <translation>Preglejte in uredite seznam naslovov, na katere ste kdaj poslali plačila</translation>
+ </message>
+ <message>
+ <source>Show the list of used receiving addresses and labels</source>
+ <translation>Preglejte in uredite seznam naslovov, na katere ste kdaj prejeli plačila</translation>
+ </message>
+ <message>
+ <source>Open a bitcoin: URI or payment request</source>
+ <translation>Izvedite plačilo iz zahtevka v datoteki ali iz URI tipa bitcoin:</translation>
+ </message>
+ <message>
+ <source>&amp;Command-line options</source>
+ <translation>Opcije &amp;ukazne vrstice</translation>
+ </message>
+ <message>
+ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
+ <translation>Oglejte si seznam in kratek opis vseh opcij pri zagonu programa iz ukazne vrstice</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n active connection(s) to Bitcoin network</source>
+ <translation><numerusform>%n aktivna povezava v bitcoin omrežje</numerusform><numerusform>%n aktivni povezavi v bitcoin omrežje</numerusform><numerusform>%n aktivne povezave v bitcoin omrežje</numerusform><numerusform>%n aktivnih povezav v bitcoin omrežje</numerusform></translation>
+ </message>
+ <message>
+ <source>No block source available...</source>
+ <translation>Ni virov za prenos blokov ...</translation>
+ </message>
+ <message numerus="yes">
+ <source>Processed %n block(s) of transaction history.</source>
+ <translation><numerusform>%n obdelan blok zgodovine transakcij.</numerusform><numerusform>%n obdelana bloka zgodovine transakcij.</numerusform><numerusform>%n obdelani bloki zgodovine transakcij.</numerusform><numerusform>%n obdelanih blokov zgodovine transakcij.</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n hour(s)</source>
+ <translation><numerusform>%n ura</numerusform><numerusform>%n uri</numerusform><numerusform>%n ure</numerusform><numerusform>%n ur</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n day(s)</source>
+ <translation><numerusform>%n dan</numerusform><numerusform>%n dneva</numerusform><numerusform>%n dni</numerusform><numerusform>%n dni</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n week(s)</source>
+ <translation><numerusform>%n teden</numerusform><numerusform>%n tedna</numerusform><numerusform>%n tedne</numerusform><numerusform>%n tednov</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 and %2</source>
+ <translation>%1 in %2</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n year(s)</source>
+ <translation><numerusform>%n leto</numerusform><numerusform>%n leti</numerusform><numerusform>%n leta</numerusform><numerusform>%n let</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 behind</source>
+ <translation>imam še %1 zaostanka</translation>
+ </message>
+ <message>
+ <source>Last received block was generated %1 ago.</source>
+ <translation>Zadnji prejeti blok je bil ustvarjen %1 nazaj.</translation>
+ </message>
+ <message>
+ <source>Transactions after this will not yet be visible.</source>
+ <translation>Novejše transakcije še ne bodo vidne.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Napaka</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Opozorilo</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Informacije</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>Posodobljeno</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>Dohitevam omrežje ...</translation>
+ </message>
+ <message>
+ <source>Date: %1
+</source>
+ <translation>Datum: %1
+</translation>
+ </message>
+ <message>
+ <source>Amount: %1
+</source>
+ <translation>Znesek: %1
+</translation>
+ </message>
+ <message>
+ <source>Type: %1
+</source>
+ <translation>Vrsta: %1
+</translation>
+ </message>
+ <message>
+ <source>Label: %1
+</source>
+ <translation>Oznaka: %1
+</translation>
+ </message>
+ <message>
+ <source>Address: %1
+</source>
+ <translation>Naslov: %1
+</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>Odlivi</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>Prilivi</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>Denarnica je &lt;b&gt;šifrirana&lt;/b&gt; in trenutno &lt;b&gt;odklenjena&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>Denarnica je &lt;b&gt;šifrirana&lt;/b&gt; in trenutno &lt;b&gt;zaklenjena&lt;/b&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <source>Network Alert</source>
+ <translation>Omrežno opozorilo</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Coin Selection</source>
+ <translation>Izbira vhodnih kovancev</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Št.vhodov:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Št.bajtov:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Znesek:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Prioriteta:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Provizija:</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Prah:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Po proviziji:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Vračilo:</translation>
+ </message>
+ <message>
+ <source>(un)select all</source>
+ <translation>izberi vse/nič</translation>
+ </message>
+ <message>
+ <source>Tree mode</source>
+ <translation>Drevesni prikaz</translation>
+ </message>
+ <message>
+ <source>List mode</source>
+ <translation>Seznam</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Znesek</translation>
+ </message>
+ <message>
+ <source>Received with label</source>
+ <translation>Oznaka priliva</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>Naslov priliva</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Datum</translation>
+ </message>
+ <message>
+ <source>Confirmations</source>
+ <translation>Potrditve</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Potrjeno</translation>
+ </message>
+ <message>
+ <source>Priority</source>
+ <translation>Prioriteta</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Kopiraj naslov</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Kopiraj oznako</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopiraj znesek</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Kopiraj ID transakcije</translation>
+ </message>
+ <message>
+ <source>Lock unspent</source>
+ <translation>Zakleni neporabljeno</translation>
+ </message>
+ <message>
+ <source>Unlock unspent</source>
+ <translation>Odkleni neporabljeno</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Kopiraj število vhodov</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Kopiraj znesek provizije</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Kopiraj končni znesek</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Kopiraj število bajtov</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Kopiraj prioriteto</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Kopiraj prah</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Kopiraj znesek vračila</translation>
+ </message>
+ <message>
+ <source>highest</source>
+ <translation>najvišja</translation>
+ </message>
+ <message>
+ <source>higher</source>
+ <translation>višja</translation>
+ </message>
+ <message>
+ <source>high</source>
+ <translation>visoka</translation>
+ </message>
+ <message>
+ <source>medium-high</source>
+ <translation>srednje visoka</translation>
+ </message>
+ <message>
+ <source>medium</source>
+ <translation>srednja</translation>
+ </message>
+ <message>
+ <source>low-medium</source>
+ <translation>srednje nizka</translation>
+ </message>
+ <message>
+ <source>low</source>
+ <translation>nizka</translation>
+ </message>
+ <message>
+ <source>lower</source>
+ <translation>nižja</translation>
+ </message>
+ <message>
+ <source>lowest</source>
+ <translation>najnižja</translation>
+ </message>
+ <message>
+ <source>(%1 locked)</source>
+ <translation>(%1 zaklenjeno)</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>nič</translation>
+ </message>
+ <message>
+ <source>This label turns red if the transaction size is greater than 1000 bytes.</source>
+ <translation>Oznaka postane rdeča, če je transakcije večja od 1000 bajtov.</translation>
+ </message>
+ <message>
+ <source>This label turns red if the priority is smaller than "medium".</source>
+ <translation>Oznaka postane rdeča, če je prioriteta transakcije manjša kot "srednja".</translation>
+ </message>
+ <message>
+ <source>This label turns red if any recipient receives an amount smaller than %1.</source>
+ <translation>Oznaka postane rdeča, če je znesek manjši od %1.</translation>
+ </message>
+ <message>
+ <source>Can vary +/- %1 satoshi(s) per input.</source>
+ <translation>Lahko variira +/- %1 satoshijev na vhod.</translation>
+ </message>
+ <message>
+ <source>yes</source>
+ <translation>da</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>ne</translation>
+ </message>
+ <message>
+ <source>This means a fee of at least %1 per kB is required.</source>
+ <translation>To pomeni, da je zahtevana provizija v višini vsaj %1 na KiB.</translation>
+ </message>
+ <message>
+ <source>Can vary +/- 1 byte per input.</source>
+ <translation>Lahko variira +/-1 bajt na vhod.</translation>
+ </message>
+ <message>
+ <source>Transactions with higher priority are more likely to get included into a block.</source>
+ <translation>Transakcije z višjo prioriteto imajo boljše možnosti za vključitev v blok.</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(brez oznake)</translation>
+ </message>
+ <message>
+ <source>change from %1 (%2)</source>
+ <translation>vračilo od %1 (%2)</translation>
+ </message>
+ <message>
+ <source>(change)</source>
+ <translation>(vračilo)</translation>
+ </message>
+</context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>Uredi naslov</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>&amp;Oznaka</translation>
+ </message>
+ <message>
+ <source>The label associated with this address list entry</source>
+ <translation>Oznaka, pod katero je spodnji naslov naveden v vašem imeniku naslovov.</translation>
+ </message>
+ <message>
+ <source>The address associated with this address list entry. This can only be modified for sending addresses.</source>
+ <translation>Naslov tega vnosa v imeniku. Spremeniti ga je mogoče le pri vnosih iz imenika naslovov za pošiljanje.</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;Naslov</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>Nov naslov za prilive</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>Nov naslov za odlive</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>Uredi naslov za prilive</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>Uredi naslov za odlive</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>Vnešeni naslov %1 je že v imeniku.</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is not a valid Bitcoin address.</source>
+ <translation>Vnešeni naslov %1 ni veljaven naslov Bitcoin.</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>Denarnice ni bilo mogoče odkleniti.</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>Novega ključa ni bilo mogoče ustvariti.</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ <message>
+ <source>A new data directory will be created.</source>
+ <translation>Ustvarjena bo nova podatkovna mapa.</translation>
+ </message>
+ <message>
+ <source>name</source>
+ <translation>ime</translation>
+ </message>
+ <message>
+ <source>Directory already exists. Add %1 if you intend to create a new directory here.</source>
+ <translation>Mapa že obstaja. Dodajte %1, če tu želite ustvariti novo mapo.</translation>
+ </message>
+ <message>
+ <source>Path already exists, and is not a directory.</source>
+ <translation>Pot že obstaja, vendar ni mapa.</translation>
+ </message>
+ <message>
+ <source>Cannot create data directory here.</source>
+ <translation>Na tem mestu ni mogoče ustvariti nove mape.</translation>
+ </message>
+</context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>različica</translation>
+ </message>
+ <message>
+ <source>(%1-bit)</source>
+ <translation>(%1-bit)</translation>
+ </message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>O programu Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Command-line options</source>
+ <translation>Možnosti ukazne vrstice</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>Uporaba:</translation>
+ </message>
+ <message>
+ <source>command-line options</source>
+ <translation>možnosti ukazne vrstice</translation>
+ </message>
+</context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Welcome</source>
+ <translation>Dobrodošli</translation>
+ </message>
+ <message>
+ <source>Welcome to Bitcoin Core.</source>
+ <translation>Dobrodošli v programu Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</source>
+ <translation>To je prvi zagon programa, zato lahko izberete mapo, v katero bo program shranjeval podatke.</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory.</source>
+ <translation>Program bo prenesel in shranil kopijo verige blokov. V izbrani podatkovni mapi bo shranjenih vsaj %1 GiB podatkov, ta količina pa bo sčasoma še naraščala. V tej mapi bo shranjena tudi denarnica.</translation>
+ </message>
+ <message>
+ <source>Use the default data directory</source>
+ <translation>Uporabi privzeto podatkovno mapo</translation>
+ </message>
+ <message>
+ <source>Use a custom data directory:</source>
+ <translation>Uporabi to podatkovno mapo:</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Error: Specified data directory "%1" cannot be created.</source>
+ <translation>Napaka: Ni mogoče ustvariti mape "%1".</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Napaka</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n GB of free space available</source>
+ <translation><numerusform>%n GiB prostega prostora na voljo</numerusform><numerusform>%n GiB prostega prostora na voljo</numerusform><numerusform>%n GiB prostega prostora na voljo</numerusform><numerusform>%n GiB prostega prostora na voljo</numerusform></translation>
+ </message>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ <message>
+ <source>Open URI</source>
+ <translation>Odpri URl</translation>
+ </message>
+ <message>
+ <source>Open payment request from URI or file</source>
+ <translation>Vnesite zahtevek za plačilo iz URI ali pa ga naložite iz datoteke</translation>
+ </message>
+ <message>
+ <source>URI:</source>
+ <translation>URI:</translation>
+ </message>
+ <message>
+ <source>Select payment request file</source>
+ <translation>Izbiranje datoteke z zahtevkom za plačilo</translation>
+ </message>
+ <message>
+ <source>Select payment request file to open</source>
+ <translation>Izberite datoteko, ki vsebuje zahtevek za plačilo</translation>
+ </message>
+</context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>Možnosti</translation>
+ </message>
+ <message>
+ <source>&amp;Main</source>
+ <translation>&amp;Glavno</translation>
+ </message>
+ <message>
+ <source>Size of &amp;database cache</source>
+ <translation>Velikost &amp;predpomnilnika podatkovne baze</translation>
+ </message>
+ <message>
+ <source>MB</source>
+ <translation>MiB</translation>
+ </message>
+ <message>
+ <source>Number of script &amp;verification threads</source>
+ <translation>Število programskih &amp;niti za preverjanje</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside</source>
+ <translation>Sprejemaj zunanje povezave</translation>
+ </message>
+ <message>
+ <source>Allow incoming connections</source>
+ <translation>Dovoli dohodne povezave</translation>
+ </message>
+ <message>
+ <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
+ <translation>Naslov IP posredniškega strežnika (npr. IPv4: 127.0.0.1 ali IPv6: ::1)</translation>
+ </message>
+ <message>
+ <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source>
+ <translation>Ko zaprete glavno okno programa, bo program tekel še naprej, okno pa bo zgolj minimirano. Program v tem primeru ustavite tako, da v meniju izberete ukaz Izhod.</translation>
+ </message>
+ <message>
+ <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source>
+ <translation>Nastavitev jezika uporabniškega vmesnika programa. Nova nastavitev jezika bo uporabljena šele, ko boste znova zagnali program.</translation>
+ </message>
+ <message>
+ <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source>
+ <translation>Naslovi URL tretjih oseb (npr. raziskovalec blokov), ki bodo navedeni v kontekstnem meniju seznama transakcij. Niz %s iz naslova URL je nadomeščen s hash vrednostjo transakcije. Več zaporednih naslovov URL je med seboj ločenih z znakom |.</translation>
+ </message>
+ <message>
+ <source>Third party transaction URLs</source>
+ <translation>Zunanje povezave za transakcije</translation>
+ </message>
+ <message>
+ <source>Active command-line options that override above options:</source>
+ <translation>Aktivne opcije iz ukazne vrstice, ki preglasijo zgornje opcije:</translation>
+ </message>
+ <message>
+ <source>Reset all client options to default.</source>
+ <translation>Ponastavi vse nastavitve programa na privzete vrednosti.</translation>
+ </message>
+ <message>
+ <source>&amp;Reset Options</source>
+ <translation>&amp;Ponastavi nastavitve</translation>
+ </message>
+ <message>
+ <source>&amp;Network</source>
+ <translation>&amp;Omrežje</translation>
+ </message>
+ <message>
+ <source>Automatically start Bitcoin Core after logging in to the system.</source>
+ <translation>Ob uporabnikovi prijavi v sistem se bo program samodejno zagnal</translation>
+ </message>
+ <message>
+ <source>&amp;Start Bitcoin Core on system login</source>
+ <translation>&amp;Zaženi program ob prijavi v sistem</translation>
+ </message>
+ <message>
+ <source>(0 = auto, &lt;0 = leave that many cores free)</source>
+ <translation>(0 = samodejno, &lt;0 = toliko procesorskih jeder naj ostane prostih)</translation>
+ </message>
+ <message>
+ <source>W&amp;allet</source>
+ <translation>&amp;Denarnica</translation>
+ </message>
+ <message>
+ <source>Expert</source>
+ <translation>Napredne možnosti</translation>
+ </message>
+ <message>
+ <source>Enable coin &amp;control features</source>
+ <translation>Omogoči upravljanje s kovanci</translation>
+ </message>
+ <message>
+ <source>If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.</source>
+ <translation>Če onemogočite trošenje drobiža iz še nepotrjenih transakcij, potem vrnjenega drobiža ne morete uporabiti, dokler plačilo ni vsaj enkrat potrjeno. Ta opcija vpliva tudi na izračun stanja sredstev.</translation>
+ </message>
+ <message>
+ <source>&amp;Spend unconfirmed change</source>
+ <translation>Omogoči &amp;trošenje drobiža iz še nepotrjenih plačil</translation>
+ </message>
+ <message>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>Program samodejno odpre ustrezna vrata na usmerjevalniku. To deluje samo, če vaš usmerjevalnik podpira in ima omogočen UPnP.</translation>
+ </message>
+ <message>
+ <source>Map port using &amp;UPnP</source>
+ <translation>Preslikaj vrata z uporabo &amp;UPnP</translation>
+ </message>
+ <message>
+ <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
+ <translation>Poveži se v omrežje Bitcoin preko posredniškega strežnika SOCKS5.</translation>
+ </message>
+ <message>
+ <source>&amp;Connect through SOCKS5 proxy (default proxy):</source>
+ <translation>&amp;Poveži se preko posredniškega strežnika SOCKS5 (privzeti strežnik):</translation>
+ </message>
+ <message>
+ <source>Proxy &amp;IP:</source>
+ <translation>Naslov &amp;IP posredniškega strežnika:</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>&amp;Vrata:</translation>
+ </message>
+ <message>
+ <source>Port of the proxy (e.g. 9050)</source>
+ <translation>Vrata posredniškega strežnika (npr. 9050)</translation>
+ </message>
+ <message>
+ <source>&amp;Window</source>
+ <translation>O&amp;kno</translation>
+ </message>
+ <message>
+ <source>Show only a tray icon after minimizing the window.</source>
+ <translation>Po minimiranju okna samo prikaži ikono programa v pladnju.</translation>
+ </message>
+ <message>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>&amp;Minimiraj na pladenj namesto na opravilno vrstico</translation>
+ </message>
+ <message>
+ <source>M&amp;inimize on close</source>
+ <translation>Ob zapiranju okno zgolj m&amp;inimiraj</translation>
+ </message>
+ <message>
+ <source>&amp;Display</source>
+ <translation>&amp;Prikaz</translation>
+ </message>
+ <message>
+ <source>User Interface &amp;language:</source>
+ <translation>&amp;Jezik uporabniškega vmesnika:</translation>
+ </message>
+ <message>
+ <source>&amp;Unit to show amounts in:</source>
+ <translation>&amp;Enota za prikaz zneskov:</translation>
+ </message>
+ <message>
+ <source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
+ <translation>Izberite privzeto mersko enoto za prikaz v uporabniškem vmesniku in pri pošiljanju kovancev.</translation>
+ </message>
+ <message>
+ <source>Whether to show coin control features or not.</source>
+ <translation>Omogoči dodatno možnost podrobnega nadzora nad posameznimi kovanci v transakcijah.</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>&amp;Potrdi</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>&amp;Prekliči</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>privzeto</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>nič</translation>
+ </message>
+ <message>
+ <source>Confirm options reset</source>
+ <translation>Potrditev ponastavitve</translation>
+ </message>
+ <message>
+ <source>Client restart required to activate changes.</source>
+ <translation>Za uveljavitev sprememb je potreben ponoven zagon programa.</translation>
+ </message>
+ <message>
+ <source>Client will be shut down. Do you want to proceed?</source>
+ <translation>Program bo zaustavljen. Želite nadaljevati z izhodom?</translation>
+ </message>
+ <message>
+ <source>This change would require a client restart.</source>
+ <translation>Ta sprememba zahteva ponoven zagon programa.</translation>
+ </message>
+ <message>
+ <source>The supplied proxy address is invalid.</source>
+ <translation>Vnešeni naslov posredniškega strežnika ni veljaven.</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>Oblika</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>Prikazani podatki so morda zastareli. Program ob vzpostavitvi povezave samodejno sinhronizira denarnico z omrežjem Bitcoin, a trenutno ta proces še ni zaključen.</translation>
+ </message>
+ <message>
+ <source>Watch-only:</source>
+ <translation>Opazovano:</translation>
+ </message>
+ <message>
+ <source>Available:</source>
+ <translation>Na voljo:</translation>
+ </message>
+ <message>
+ <source>Your current spendable balance</source>
+ <translation>Skupni znesek vaših sredstev, s katerimi lahko prosto razpolagate</translation>
+ </message>
+ <message>
+ <source>Pending:</source>
+ <translation>Nepotrjeno:</translation>
+ </message>
+ <message>
+ <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source>
+ <translation>Skupni znesek sredstev s katerimi še ne razpolagate prosto, ker so del še nepotrjenih transakcij.</translation>
+ </message>
+ <message>
+ <source>Immature:</source>
+ <translation>Nedozorelo:</translation>
+ </message>
+ <message>
+ <source>Mined balance that has not yet matured</source>
+ <translation>Nedozorel narudarjeni znesek</translation>
+ </message>
+ <message>
+ <source>Balances</source>
+ <translation>Stanje sredstev</translation>
+ </message>
+ <message>
+ <source>Total:</source>
+ <translation>Skupaj:</translation>
+ </message>
+ <message>
+ <source>Your current total balance</source>
+ <translation>Trenutna vsota vseh vaših sredstev</translation>
+ </message>
+ <message>
+ <source>Your current balance in watch-only addresses</source>
+ <translation>Trenutno stanje vaših sredstev na opazovanih naslovih</translation>
+ </message>
+ <message>
+ <source>Spendable:</source>
+ <translation>Na voljo:</translation>
+ </message>
+ <message>
+ <source>Recent transactions</source>
+ <translation>Nedavne transakcije</translation>
+ </message>
+ <message>
+ <source>Unconfirmed transactions to watch-only addresses</source>
+ <translation>Nepotrjene transakcije na opazovanih naslovih</translation>
+ </message>
+ <message>
+ <source>Mined balance in watch-only addresses that has not yet matured</source>
+ <translation>Nedozoreli narudarjeni znesek na opazovanih naslovih</translation>
+ </message>
+ <message>
+ <source>Current total balance in watch-only addresses</source>
+ <translation>Trenutno skupno stanje sredstev na opazovanih naslovih</translation>
+ </message>
+</context>
+<context>
+ <name>PaymentServer</name>
+ <message>
+ <source>URI handling</source>
+ <translation>Rokovanje z URI</translation>
+ </message>
+ <message>
+ <source>Invalid payment address %1</source>
+ <translation>Neveljaven naslov plačila %1</translation>
+ </message>
+ <message>
+ <source>Payment request rejected</source>
+ <translation>Zahtevek za plačilo je bil zavrnjen.</translation>
+ </message>
+ <message>
+ <source>Payment request network doesn't match client network.</source>
+ <translation>Zahtevek za plačilo in vaš odjemalec se nahajata na dveh različnih omrežjih.</translation>
+ </message>
+ <message>
+ <source>Payment request is not initialized.</source>
+ <translation>Zahtevek za plačilo ni inicializiran.</translation>
+ </message>
+ <message>
+ <source>Requested payment amount of %1 is too small (considered dust).</source>
+ <translation>Znesek %1 v zahtevku za plačilo je prenizek (smatran za prah.)</translation>
+ </message>
+ <message>
+ <source>Payment request error</source>
+ <translation>Napaka pri zahtevku za plačilo</translation>
+ </message>
+ <message>
+ <source>Cannot start bitcoin: click-to-pay handler</source>
+ <translation>Ni mogoče zagnati rokovalca plačilnih povezav tipa bitcoin:.</translation>
+ </message>
+ <message>
+ <source>Payment request fetch URL is invalid: %1</source>
+ <translation>Naslov URL za pridobitev zahtevka za plačilo ni veljaven: %1</translation>
+ </message>
+ <message>
+ <source>URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source>
+ <translation>URI je neprepoznaven! Možno je, da je naslov Bitcoin neveljaven, ali da so parametri v URI napačno oblikovani.</translation>
+ </message>
+ <message>
+ <source>Payment request file handling</source>
+ <translation>Rokovanje z datoteko z zahtevkom za plačilo</translation>
+ </message>
+ <message>
+ <source>Payment request file cannot be read! This can be caused by an invalid payment request file.</source>
+ <translation>Datoteke z zahtevkom za plačilo ni mogoče prebrati! Možno je, da datoteka ni veljavna.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>Zahtevek za plačilo je potekel.</translation>
+ </message>
+ <message>
+ <source>Unverified payment requests to custom payment scripts are unsupported.</source>
+ <translation>Nepreverjeni zahtevki za plačilo, namenjeni plačilni skripti po meri, niso podprti.</translation>
+ </message>
+ <message>
+ <source>Invalid payment request.</source>
+ <translation>Neveljaven zahtevek za plačilo.</translation>
+ </message>
+ <message>
+ <source>Refund from %1</source>
+ <translation>Povračilo od %1</translation>
+ </message>
+ <message>
+ <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source>
+ <translation>Zahtevek za plačilo %1 je prevelik (%2 bajtov, dovoljenih je %3 bajtov.)</translation>
+ </message>
+ <message>
+ <source>Payment request DoS protection</source>
+ <translation>Zaščita pred napadom denial-of-service zahtevka za plačilo</translation>
+ </message>
+ <message>
+ <source>Error communicating with %1: %2</source>
+ <translation>Napaka pri povezavi z %1: %2</translation>
+ </message>
+ <message>
+ <source>Payment request cannot be parsed!</source>
+ <translation>Zahtevek za plačilo je neprepoznaven!</translation>
+ </message>
+ <message>
+ <source>Bad response from server %1</source>
+ <translation>Napačen odziv strežnika %1</translation>
+ </message>
+ <message>
+ <source>Payment acknowledged</source>
+ <translation>Plačilo priznano</translation>
+ </message>
+ <message>
+ <source>Network request error</source>
+ <translation>Napaka omrežne zahteve</translation>
+ </message>
+</context>
+<context>
+ <name>PeerTableModel</name>
+ <message>
+ <source>User Agent</source>
+ <translation>Ime agenta</translation>
+ </message>
+ <message>
+ <source>Node/Service</source>
+ <translation>Vozlišče/Storitev</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Odzivni čas</translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>Znesek</translation>
+ </message>
+ <message>
+ <source>Enter a Bitcoin address (e.g. %1)</source>
+ <translation>Vnesite naslov Bitcoin (npr. %1):</translation>
+ </message>
+ <message>
+ <source>%1 d</source>
+ <translation>%1 d</translation>
+ </message>
+ <message>
+ <source>%1 h</source>
+ <translation>%1 h</translation>
+ </message>
+ <message>
+ <source>%1 m</source>
+ <translation>%1 m</translation>
+ </message>
+ <message>
+ <source>%1 s</source>
+ <translation>%1 s</translation>
+ </message>
+ <message>
+ <source>None</source>
+ <translation>Nič</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>Neznano</translation>
+ </message>
+ <message>
+ <source>%1 ms</source>
+ <translation>%1 ms</translation>
+ </message>
+</context>
+<context>
+ <name>QRImageWidget</name>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Shrani sliko ...</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Image</source>
+ <translation>&amp;Kopiraj sliko</translation>
+ </message>
+ <message>
+ <source>Save QR Code</source>
+ <translation>Shrani kodo QR</translation>
+ </message>
+ <message>
+ <source>PNG Image (*.png)</source>
+ <translation>PNG slika (*.png)</translation>
+ </message>
+</context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>Client name</source>
+ <translation>Ime odjemalca</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>Neznano</translation>
+ </message>
+ <message>
+ <source>Client version</source>
+ <translation>Različica odjemalca</translation>
+ </message>
+ <message>
+ <source>&amp;Information</source>
+ <translation>&amp;Informacije</translation>
+ </message>
+ <message>
+ <source>Debug window</source>
+ <translation>Razhroščevalno okno</translation>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>Splošno</translation>
+ </message>
+ <message>
+ <source>Using OpenSSL version</source>
+ <translation>OpenSSL različica v rabi</translation>
+ </message>
+ <message>
+ <source>Using BerkeleyDB version</source>
+ <translation>BerkeleyDB različica v rabi</translation>
+ </message>
+ <message>
+ <source>Startup time</source>
+ <translation>Čas zagona</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Omrežje</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>Ime</translation>
+ </message>
+ <message>
+ <source>Number of connections</source>
+ <translation>Število povezav</translation>
+ </message>
+ <message>
+ <source>Block chain</source>
+ <translation>Veriga blokov</translation>
+ </message>
+ <message>
+ <source>Current number of blocks</source>
+ <translation>Trenutno število blokov</translation>
+ </message>
+ <message>
+ <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source>
+ <translation>Odpre razhroščevalni dnevnik debug.log, ki se nahaja v trenutni podatkovni mapi. Če je datoteka velika, lahko postopek traja nekaj sekund.</translation>
+ </message>
+ <message>
+ <source>Received</source>
+ <translation>Prejeto</translation>
+ </message>
+ <message>
+ <source>Sent</source>
+ <translation>Oddano</translation>
+ </message>
+ <message>
+ <source>&amp;Peers</source>
+ <translation>&amp;Soležniki</translation>
+ </message>
+ <message>
+ <source>Select a peer to view detailed information.</source>
+ <translation>Izberite soležnika, o katerem si želite ogledati podrobnejše informacije.</translation>
+ </message>
+ <message>
+ <source>Direction</source>
+ <translation>Smer povezave</translation>
+ </message>
+ <message>
+ <source>Version</source>
+ <translation>Različica</translation>
+ </message>
+ <message>
+ <source>User Agent</source>
+ <translation>Ime agenta</translation>
+ </message>
+ <message>
+ <source>Services</source>
+ <translation>Storitve</translation>
+ </message>
+ <message>
+ <source>Starting Height</source>
+ <translation>Začetna višina</translation>
+ </message>
+ <message>
+ <source>Sync Height</source>
+ <translation>Trenutna višina</translation>
+ </message>
+ <message>
+ <source>Ban Score</source>
+ <translation>Kazenske točke</translation>
+ </message>
+ <message>
+ <source>Connection Time</source>
+ <translation>Trajanje povezave</translation>
+ </message>
+ <message>
+ <source>Last Send</source>
+ <translation>Nazadje oddano</translation>
+ </message>
+ <message>
+ <source>Last Receive</source>
+ <translation>Nazadnje prejeto</translation>
+ </message>
+ <message>
+ <source>Bytes Sent</source>
+ <translation>Oddanih bajtov</translation>
+ </message>
+ <message>
+ <source>Bytes Received</source>
+ <translation>Prejetih bajtov</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Odzivni čas</translation>
+ </message>
+ <message>
+ <source>Time Offset</source>
+ <translation>Časovni odklon</translation>
+ </message>
+ <message>
+ <source>Last block time</source>
+ <translation>Čas zadnjega bloka</translation>
+ </message>
+ <message>
+ <source>&amp;Open</source>
+ <translation>&amp;Odpri</translation>
+ </message>
+ <message>
+ <source>&amp;Console</source>
+ <translation>&amp;Konzola</translation>
+ </message>
+ <message>
+ <source>&amp;Network Traffic</source>
+ <translation>&amp;Omrežni promet</translation>
+ </message>
+ <message>
+ <source>&amp;Clear</source>
+ <translation>&amp;Počisti</translation>
+ </message>
+ <message>
+ <source>Totals</source>
+ <translation>Promet</translation>
+ </message>
+ <message>
+ <source>In:</source>
+ <translation>Dohodnih:</translation>
+ </message>
+ <message>
+ <source>Out:</source>
+ <translation>Odhodnih:</translation>
+ </message>
+ <message>
+ <source>Build date</source>
+ <translation>Datum izgradnje</translation>
+ </message>
+ <message>
+ <source>Debug log file</source>
+ <translation>Razhroščevalni dnevnik</translation>
+ </message>
+ <message>
+ <source>Clear console</source>
+ <translation>Počisti konzolo</translation>
+ </message>
+ <message>
+ <source>Welcome to the Bitcoin Core RPC console.</source>
+ <translation>Dobrodošli v konzoli RPC programa Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
+ <translation>Uporabite tipki gor in dol za navigacijo po zgodovini ukazov. Uporabite &lt;b&gt;Ctrl-L&lt;/b&gt; za izbris zaslona in zgodovine ukazov.</translation>
+ </message>
+ <message>
+ <source>Type &lt;b&gt;help&lt;/b&gt; for an overview of available commands.</source>
+ <translation>Vtipkajte &lt;b&gt;help&lt;/b&gt; za pregled razpoložljivih ukazov.</translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation>%1 B</translation>
+ </message>
+ <message>
+ <source>%1 KB</source>
+ <translation>%1 KiB</translation>
+ </message>
+ <message>
+ <source>%1 MB</source>
+ <translation>%1 MiB</translation>
+ </message>
+ <message>
+ <source>%1 GB</source>
+ <translation>%1 GiB</translation>
+ </message>
+ <message>
+ <source>via %1</source>
+ <translation>preko %1</translation>
+ </message>
+ <message>
+ <source>never</source>
+ <translation>nikoli</translation>
+ </message>
+ <message>
+ <source>Inbound</source>
+ <translation>Dohodna</translation>
+ </message>
+ <message>
+ <source>Outbound</source>
+ <translation>Odhodna</translation>
+ </message>
+ <message>
+ <source>Unknown</source>
+ <translation>Neznano</translation>
+ </message>
+ <message>
+ <source>Fetching...</source>
+ <translation>Pridobivam ...</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Amount:</source>
+ <translation>&amp;Znesek:</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Oznaka:</translation>
+ </message>
+ <message>
+ <source>&amp;Message:</source>
+ <translation>&amp;Sporočilo:</translation>
+ </message>
+ <message>
+ <source>Reuse one of the previously used receiving addresses. Reusing addresses has security and privacy issues. Do not use this unless re-generating a payment request made before.</source>
+ <translation>Ponovno uporabite enega od že uporabljenih naslovov za prejemanje. Večkratna uporaba istih naslovov za prejemanje negativno vpliva na varnost in zasebnost. To opcijo uporabite samo v primeru, da poustvarjate obstoječ zahtevek za plačilo.</translation>
+ </message>
+ <message>
+ <source>R&amp;euse an existing receiving address (not recommended)</source>
+ <translation>P&amp;onovno uporabite obstoječ naslov za prejemanje. (Ni priporočeno.)</translation>
+ </message>
+ <message>
+ <source>An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network.</source>
+ <translation>Neobvezno sporočilo kot priponka zahtevku za plačilo, ki bo prikazano, ko bo zahtevek odprt. Opomba: Opravljeno plačilo.prek omrežja Bitcoin tega sporočila ne bo vsebovalo.</translation>
+ </message>
+ <message>
+ <source>An optional label to associate with the new receiving address.</source>
+ <translation>Oznaka novega sprejemnega naslova.</translation>
+ </message>
+ <message>
+ <source>Use this form to request payments. All fields are &lt;b&gt;optional&lt;/b&gt;.</source>
+ <translation>S tem obrazcem ustvarite nov zahtevek za plačilo. Vsa polja so &lt;b&gt;neobvezna&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>An optional amount to request. Leave this empty or zero to not request a specific amount.</source>
+ <translation>Zahtevani znesek. Če ne zahtevate določenega zneska, pustite prazno ali nastavite vrednost na 0.</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Počisti vsa polja.</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation>Počisti</translation>
+ </message>
+ <message>
+ <source>Requested payments history</source>
+ <translation>Zgodovina zahtevkov za plačilo</translation>
+ </message>
+ <message>
+ <source>&amp;Request payment</source>
+ <translation>&amp;Zahtevaj plačilo</translation>
+ </message>
+ <message>
+ <source>Show the selected request (does the same as double clicking an entry)</source>
+ <translation>Prikaz izbranega zahtevka. (Isto funkcijo opravi dvojni klik na zapis.)</translation>
+ </message>
+ <message>
+ <source>Show</source>
+ <translation>Pokaži</translation>
+ </message>
+ <message>
+ <source>Remove the selected entries from the list</source>
+ <translation>Odstrani označene vnose iz seznama</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>Odstrani</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Kopiraj oznako</translation>
+ </message>
+ <message>
+ <source>Copy message</source>
+ <translation>Kopiraj sporočilo</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopiraj znesek</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>QR Code</source>
+ <translation>QR Koda</translation>
+ </message>
+ <message>
+ <source>Copy &amp;URI</source>
+ <translation>Kopiraj &amp;URl</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Address</source>
+ <translation>Kopiraj &amp;naslov</translation>
+ </message>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Shrani sliko ...</translation>
+ </message>
+ <message>
+ <source>Request payment to %1</source>
+ <translation>Zahtevek za plačilo z oznako: %1</translation>
+ </message>
+ <message>
+ <source>Payment information</source>
+ <translation>Informacije o plačilu</translation>
+ </message>
+ <message>
+ <source>URI</source>
+ <translation>URI</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Naslov</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Znesek</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Oznaka</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Sporočilo</translation>
+ </message>
+ <message>
+ <source>Resulting URI too long, try to reduce the text for label / message.</source>
+ <translation>Nastali URI je predolg. Skušajte skrajšati besedilo v oznaki/sporočilu.</translation>
+ </message>
+ <message>
+ <source>Error encoding URI into QR Code.</source>
+ <translation>Napaka pri pretvorbi URI v kodo QR.</translation>
+ </message>
+</context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Datum</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Oznaka</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Sporočilo</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Znesek</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(brez oznake)</translation>
+ </message>
+ <message>
+ <source>(no message)</source>
+ <translation>(brez sporočila)</translation>
+ </message>
+ <message>
+ <source>(no amount)</source>
+ <translation>(brez zneska)</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Pošlji</translation>
+ </message>
+ <message>
+ <source>Coin Control Features</source>
+ <translation>Upravljanje s kovanci</translation>
+ </message>
+ <message>
+ <source>Inputs...</source>
+ <translation>Vhodi ...</translation>
+ </message>
+ <message>
+ <source>automatically selected</source>
+ <translation>samodejno izbrani</translation>
+ </message>
+ <message>
+ <source>Insufficient funds!</source>
+ <translation>Premalo sredstev!</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Št.vhodov:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Št.bajtov:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Znesek:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Prioriteta:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Provizija:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Po proviziji:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Vračilo:</translation>
+ </message>
+ <message>
+ <source>If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address.</source>
+ <translation>Če to vključite, nato pa vnesete neveljaven naslov, ali pa pustite polje prazno, bo vrnjen drobiž poslan na novo ustvarjen naslov.</translation>
+ </message>
+ <message>
+ <source>Custom change address</source>
+ <translation>Naslov za vračilo drobiža po meri</translation>
+ </message>
+ <message>
+ <source>Transaction Fee:</source>
+ <translation>Provizija:</translation>
+ </message>
+ <message>
+ <source>Choose...</source>
+ <translation>Izberi ...</translation>
+ </message>
+ <message>
+ <source>collapse fee-settings</source>
+ <translation>Skrije nastavitve provizije</translation>
+ </message>
+ <message>
+ <source>per kilobyte</source>
+ <translation>na KiB</translation>
+ </message>
+ <message>
+ <source>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "total at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source>
+ <translation>Če je nastavitev zneska provizije po meri enaka 1000 satoshijev, transakcija pa je velika samo 250 bajtov, je obračunani znesek provizije pri nastavitvi "za KiB" samo 250 satoshijev, medtem ko je pri nastavitvi "skupno vsaj" ta znesek 1000 satoshijev. Za transakcije, večje od 1 KiB, se končni znesek pri obeh nastavitvah obračuna na KiB.</translation>
+ </message>
+ <message>
+ <source>Hide</source>
+ <translation>Skrij</translation>
+ </message>
+ <message>
+ <source>total at least</source>
+ <translation>skupno vsaj</translation>
+ </message>
+ <message>
+ <source>Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process.</source>
+ <translation>Dokler bo v blokih še dovolj prostora za vse nastajajoče transakcije, zadostuje, če plačate samo minimalno provizijo. Ko pa se bo količina vseh transakcij povečala do meja zmogljivosti omrežja, se lahko zgodi, da vaša transakcija brez večje provizije nikoli ne bo potrjena.</translation>
+ </message>
+ <message>
+ <source>(read the tooltip)</source>
+ <translation>(oglejte si namig)</translation>
+ </message>
+ <message>
+ <source>Recommended:</source>
+ <translation>Priporočena:</translation>
+ </message>
+ <message>
+ <source>Custom:</source>
+ <translation>Po meri:</translation>
+ </message>
+ <message>
+ <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source>
+ <translation>(Samodejni obračun provizije še ni pripravljen. Po navadi izračun traja nekaj blokov ...)</translation>
+ </message>
+ <message>
+ <source>Confirmation time:</source>
+ <translation>Čas do potrditve:</translation>
+ </message>
+ <message>
+ <source>normal</source>
+ <translation>navadno</translation>
+ </message>
+ <message>
+ <source>fast</source>
+ <translation>hitro</translation>
+ </message>
+ <message>
+ <source>Send as zero-fee transaction if possible</source>
+ <translation>Pošlji brez provizije, če je mogoče</translation>
+ </message>
+ <message>
+ <source>(confirmation may take longer)</source>
+ <translation>(čas do potrditve je lahko daljši)</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>Pošlji več prejemnikom hkrati</translation>
+ </message>
+ <message>
+ <source>Add &amp;Recipient</source>
+ <translation>Dodaj &amp;prejemnika</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Počisti vsa polja.</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Prah:</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Počisti &amp;vse </translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>Stanje:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>Potrdi pošiljanje</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>&amp;Pošlji</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>Potrdi pošiljanje</translation>
+ </message>
+ <message>
+ <source>%1 to %2</source>
+ <translation>%1 na %2</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Kopiraj število vhodov</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopiraj znesek</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Kopiraj provizijo</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Kopiraj Po proviziji</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Kopiraj bajte</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Kopiraj prioriteto</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Kopiraj vračilo</translation>
+ </message>
+ <message>
+ <source>or</source>
+ <translation>ali</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>Znesek za plačilo mora biti večji od 0.</translation>
+ </message>
+ <message>
+ <source>The amount exceeds your balance.</source>
+ <translation>Znesek je večji od stanja sredstev, s katerimi razpolagate.</translation>
+ </message>
+ <message>
+ <source>The total exceeds your balance when the %1 transaction fee is included.</source>
+ <translation>Celotni znesek z vključeno provizijo %1 je večji od stanja sredstev, s katerimi razpolagate.</translation>
+ </message>
+ <message>
+ <source>Transaction creation failed!</source>
+ <translation>Transakcije ni bilo mogoče ustvariti!</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>Transakcija je bila zavrnjena! To se lahko zgodi, če so bili kateri od kovancev iz denarnice že porabljeni, kot v primeru, da ste kje uporabili kopijo datoteke wallet.dat in kovance tam že porabili, lokalno pa ti še niso bili označeni kot porabljeni.</translation>
+ </message>
+ <message>
+ <source>A fee higher than %1 is considered an absurdly high fee.</source>
+ <translation>Provizija, višja od %1, velja za nesmiselno visoko.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>Zahtevek za plačilo je potekel.</translation>
+ </message>
+ <message numerus="yes">
+ <source>Estimated to begin confirmation within %n block(s).</source>
+ <translation><numerusform>Predviden začetek potrditev po %n najdenem bloku.</numerusform><numerusform>Predviden začetek potrditev po %n najdenih blokih.</numerusform><numerusform>Predviden začetek potrditev po %n najdenih blokih.</numerusform><numerusform>Predviden začetek potrditev po %n najdenih blokih.</numerusform></translation>
+ </message>
+ <message>
+ <source>Pay only the minimum fee of %1</source>
+ <translation>Plačilo samo minimalne provizije v znesku %1</translation>
+ </message>
+ <message>
+ <source>The recipient address is not valid. Please recheck.</source>
+ <translation>Naslov prejemnika je neveljaven. Prosimo, preverite.</translation>
+ </message>
+ <message>
+ <source>Duplicate address found: addresses should only be used once each.</source>
+ <translation>Naslov je že bil uporabljen. Vsak naslov naj bi se uporabil samo enkrat.</translation>
+ </message>
+ <message>
+ <source>Warning: Invalid Bitcoin address</source>
+ <translation>Opozorilo: Neveljaven bitcoin naslov</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(brez oznake)</translation>
+ </message>
+ <message>
+ <source>Warning: Unknown change address</source>
+ <translation>Opozorilo: Neznan naslov za vračilo drobiža</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Kopiraj prah</translation>
+ </message>
+ <message>
+ <source>Are you sure you want to send?</source>
+ <translation>Ali ste prepričani, da želite izvesti plačilo?</translation>
+ </message>
+ <message>
+ <source>added as transaction fee</source>
+ <translation>dodano kot provizija transakcije</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>&amp;Znesek:</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>Prejemnik &amp;plačila:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Vnesite oznako, pod katero bo zgornji naslov shranjen v imenik</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Oznaka:</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Izberite enega od že uporabljenih naslovov</translation>
+ </message>
+ <message>
+ <source>This is a normal payment.</source>
+ <translation>Plačilo je navadne vrste.</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to send the payment to</source>
+ <translation>Naslov Bitcoin, na katerega bo plačilo poslano</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Prilepite naslov iz odložišča</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Remove this entry</source>
+ <translation>Izpraznite vsebino polja</translation>
+ </message>
+ <message>
+ <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source>
+ <translation>Znesek plačila bo zmanjšan za znesek provizije. Prejemnik bo prejel manjše število kovancev, kot je bil vnešeni znesek. Če je prejemnikov več, bo provizija med njih enakomerno porazdeljena.</translation>
+ </message>
+ <message>
+ <source>S&amp;ubtract fee from amount</source>
+ <translation>O&amp;dštej provizijo od zneska</translation>
+ </message>
+ <message>
+ <source>Message:</source>
+ <translation>Sporočilo:</translation>
+ </message>
+ <message>
+ <source>This is an unauthenticated payment request.</source>
+ <translation>Zahtevek za plačilo je neoverjen.</translation>
+ </message>
+ <message>
+ <source>This is an authenticated payment request.</source>
+ <translation>Zahtevek za plačilo je overjen.</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to the list of used addresses</source>
+ <translation>Če vnesete oznako za zgornji naslov, se bo skupaj z naslovom shranila v imenk že uporabljenih naslovov</translation>
+ </message>
+ <message>
+ <source>A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network.</source>
+ <translation>Sporočilo, ki ste ga pripeli na URI tipa bitcoin:. Shranjeno bo skupaj s podatki o transakciji. Opomba: Sporočilo ne bo poslano preko omrežja Bitcoin.</translation>
+ </message>
+ <message>
+ <source>Pay To:</source>
+ <translation>Prejemnik:</translation>
+ </message>
+ <message>
+ <source>Memo:</source>
+ <translation>Opomba:</translation>
+ </message>
+</context>
+<context>
+ <name>ShutdownWindow</name>
+ <message>
+ <source>Bitcoin Core is shutting down...</source>
+ <translation>Program se ustavlja ...</translation>
+ </message>
+ <message>
+ <source>Do not shut down the computer until this window disappears.</source>
+ <translation>Dokler to okno ne izgine, ne zaustavljajte računalnika.</translation>
+ </message>
+</context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Signatures - Sign / Verify a Message</source>
+ <translation>Podpiši / preveri sporočilo</translation>
+ </message>
+ <message>
+ <source>&amp;Sign Message</source>
+ <translation>&amp;Podpiši sporočilo</translation>
+ </message>
+ <message>
+ <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source>
+ <translation>S svojimi naslovi lahko podpisujete sporočila ali pogodbe in s tem dokazujete, da na teh naslovih lahko prejemate kovance. Bodite previdni in ne podpisujte ničesar nejasnega ali naključnega, ker vas zlikovci preko ribarjenja (phishing) lahko prelisičijo, da na njih prepišete svojo identiteto. Podpisujte samo podrobno opisane izjave, s katerimi se strinjate.</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to sign the message with</source>
+ <translation>Naslov Bitcoin, s katerim podpisujete sporočilo</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Izberite enega od že uporabljenih naslovov</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Prilepite naslov iz odložišča</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Enter the message you want to sign here</source>
+ <translation>Vnesite sporočilo, ki ga želite podpisati</translation>
+ </message>
+ <message>
+ <source>Signature</source>
+ <translation>Podpis</translation>
+ </message>
+ <message>
+ <source>Copy the current signature to the system clipboard</source>
+ <translation>Kopiranje trenutnega podpisa na sistemsko odložišče.</translation>
+ </message>
+ <message>
+ <source>Sign the message to prove you own this Bitcoin address</source>
+ <translation>Podpišite sporočilo, da dokažete lastništvo nad zgornjim naslovom.</translation>
+ </message>
+ <message>
+ <source>Sign &amp;Message</source>
+ <translation>Podpiši &amp;sporočilo</translation>
+ </message>
+ <message>
+ <source>Reset all sign message fields</source>
+ <translation>Počisti vsa polja za vnos v oknu za podpisovanje</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Počisti &amp;vse </translation>
+ </message>
+ <message>
+ <source>&amp;Verify Message</source>
+ <translation>&amp;Preveri sporočilo</translation>
+ </message>
+ <message>
+ <source>Enter the receiver's 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. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source>
+ <translation>Da preverite verodostojnost sporočila, spodaj vnesite: prejemnikov naslov, prejeto sporočilo (pazljivo skopirajte vse prelome vrstic, presledke, tabulatorje ipd.,) in prejeti podpis. Da se izognete napadom tipa man-in-the-middle, vedite, da iz veljavnega podpisa ne sledi nič drugega, kot tisto, kar je navedeno v sporočilu. Podpis samo potrjuje dejstvo, da ima podpisnik v lasti prejemni naslov, ne more pa dokazati vira nobene transakcije!</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address the message was signed with</source>
+ <translation>Naslov Bitcoin, s katerim je bilo sporočilo podpisano</translation>
+ </message>
+ <message>
+ <source>Verify the message to ensure it was signed with the specified Bitcoin address</source>
+ <translation>Preverite, ali je bilo sporočilo v resnici podpisano z navedenim naslovom Bitcoin.</translation>
+ </message>
+ <message>
+ <source>Verify &amp;Message</source>
+ <translation>Preveri &amp;sporočilo</translation>
+ </message>
+ <message>
+ <source>Reset all verify message fields</source>
+ <translation>Počisti vsa polja za vnos v oknu za preverjanje</translation>
+ </message>
+ <message>
+ <source>Click "Sign Message" to generate signature</source>
+ <translation>Kliknite "Podpiši sporočilo" da ustvarite podpis</translation>
+ </message>
+ <message>
+ <source>The entered address is invalid.</source>
+ <translation>Vnešeni naslov ni veljaven.</translation>
+ </message>
+ <message>
+ <source>Please check the address and try again.</source>
+ <translation>Prosimo preverite naslov in poskusite znova.</translation>
+ </message>
+ <message>
+ <source>The entered address does not refer to a key.</source>
+ <translation>Vnešeni naslov se ne nanaša na noben ključ.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock was cancelled.</source>
+ <translation>Odklepanje denarnice je bilo preklicano.</translation>
+ </message>
+ <message>
+ <source>Private key for the entered address is not available.</source>
+ <translation>Zasebni ključ vnešenega naslova ni na voljo.</translation>
+ </message>
+ <message>
+ <source>Message signing failed.</source>
+ <translation>Podpisa ni bilo mogoče ustvariti.</translation>
+ </message>
+ <message>
+ <source>Message signed.</source>
+ <translation>Podpis je bil ustvarjen.</translation>
+ </message>
+ <message>
+ <source>The signature could not be decoded.</source>
+ <translation>Podpisa ni bilo mogoče razbrati.</translation>
+ </message>
+ <message>
+ <source>Please check the signature and try again.</source>
+ <translation>Prosimo preverite podpis in poskusite znova.</translation>
+ </message>
+ <message>
+ <source>The signature did not match the message digest.</source>
+ <translation>Podpis se ne ujema z rezultatom funkcije preverjanja.</translation>
+ </message>
+ <message>
+ <source>Message verification failed.</source>
+ <translation>Podpis ni veljaven za to sporočilo.</translation>
+ </message>
+ <message>
+ <source>Message verified.</source>
+ <translation>Podpis sporočila je veljaven.</translation>
+ </message>
+</context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>The Bitcoin Core developers</source>
+ <translation>Bitcoin Core razvijalci</translation>
+ </message>
+ <message>
+ <source>[testnet]</source>
+ <translation>[testnet]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ <message>
+ <source>KB/s</source>
+ <translation>KiB/s</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>Odprto do %1</translation>
+ </message>
+ <message>
+ <source>conflicted</source>
+ <translation>v konfliktu</translation>
+ </message>
+ <message>
+ <source>%1/offline</source>
+ <translation>%1/brez povezave</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/nepotrjeno</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 potrdil</translation>
+ </message>
+ <message>
+ <source>Status</source>
+ <translation>Status</translation>
+ </message>
+ <message numerus="yes">
+ <source>, broadcast through %n node(s)</source>
+ <translation><numerusform>, posredovano %n vozlišču</numerusform><numerusform>, posredovano %n vozliščema</numerusform><numerusform>, posredovano %n vozliščem</numerusform><numerusform>, posredovano %n vozliščem</numerusform></translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Datum</translation>
+ </message>
+ <message>
+ <source>Source</source>
+ <translation>Izvor</translation>
+ </message>
+ <message>
+ <source>Generated</source>
+ <translation>Generirano</translation>
+ </message>
+ <message>
+ <source>From</source>
+ <translation>Pošiljatelj</translation>
+ </message>
+ <message>
+ <source>To</source>
+ <translation>Prejemnik</translation>
+ </message>
+ <message>
+ <source>own address</source>
+ <translation>lasten naslov</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>opazovano</translation>
+ </message>
+ <message>
+ <source>label</source>
+ <translation>oznaka</translation>
+ </message>
+ <message>
+ <source>Credit</source>
+ <translation>V dobro</translation>
+ </message>
+ <message numerus="yes">
+ <source>matures in %n more block(s)</source>
+ <translation><numerusform>dozori po %n najdenem bloku</numerusform><numerusform>dozori po %n najdenih blokih</numerusform><numerusform>dozori po %n najdenih blokih</numerusform><numerusform>dozori po %n najdenih blokih</numerusform></translation>
+ </message>
+ <message>
+ <source>not accepted</source>
+ <translation>ni bilo sprejeto</translation>
+ </message>
+ <message>
+ <source>Debit</source>
+ <translation>Debit</translation>
+ </message>
+ <message>
+ <source>Total debit</source>
+ <translation>Skupaj v breme</translation>
+ </message>
+ <message>
+ <source>Total credit</source>
+ <translation>Skupaj v dobro</translation>
+ </message>
+ <message>
+ <source>Transaction fee</source>
+ <translation>Provizija transakcije</translation>
+ </message>
+ <message>
+ <source>Net amount</source>
+ <translation>Neto znesek</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Sporočilo</translation>
+ </message>
+ <message>
+ <source>Comment</source>
+ <translation>Opomba</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>ID transakcije</translation>
+ </message>
+ <message>
+ <source>Merchant</source>
+ <translation>Trgovec</translation>
+ </message>
+ <message>
+ <source>Generated coins must mature %1 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.</source>
+ <translation>Ustvarjeni kovanci morajo zoreti %1 blokov, preden jih lahko porabite. Ko ste ta blok zgenerirali, je bil posredovan v omrežje, da bo dodan v verigo. Če se bloku ni uspelo uvrstiti v verigo, se bo njegovo stanje spremenilo v "ni bilo sprejeto" in kovancev ne bo mogoče porabiti. To se včasih zgodi, če kak drug rudar v roku nekaj sekund hkrati z vami odkrije drug blok.</translation>
+ </message>
+ <message>
+ <source>Debug information</source>
+ <translation>Razhroščevalne informacije</translation>
+ </message>
+ <message>
+ <source>Transaction</source>
+ <translation>Transakcija</translation>
+ </message>
+ <message>
+ <source>Inputs</source>
+ <translation>Vhodi</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Znesek</translation>
+ </message>
+ <message>
+ <source>true</source>
+ <translation>pravilno</translation>
+ </message>
+ <message>
+ <source>false</source>
+ <translation>nepravilno</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, še ni bila uspešno raznešena</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Odprto še %n blok</numerusform><numerusform>Odprto še %n bloka</numerusform><numerusform>Odprto še %n bloke</numerusform><numerusform>Odprto še %n blokov</numerusform></translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>neznano</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>Podrobnosti transakcije</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>V tem podoknu so prikazane podrobnosti o transakciji</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Datum</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Vrsta</translation>
+ </message>
+ <message>
+ <source>Immature (%1 confirmations, will be available after %2)</source>
+ <translation>Nedozorelo (št. potrditev: %1, na voljo šele po: %2)</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Odprto še %n blok</numerusform><numerusform>Odprto še %n bloka</numerusform><numerusform>Odprto še %n bloke</numerusform><numerusform>Odprto še %n blokov</numerusform></translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>Odprto do %1</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>Potrjeno (%1 potrdil)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>Ta blok ni prejelo še nobeno vozlišče. Najverjetneje ne bo sprejet!</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>Generirano, toda ne sprejeto</translation>
+ </message>
+ <message>
+ <source>Offline</source>
+ <translation>Brez povezave</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Oznaka</translation>
+ </message>
+ <message>
+ <source>Unconfirmed</source>
+ <translation>Nepotrjeno</translation>
+ </message>
+ <message>
+ <source>Confirming (%1 of %2 recommended confirmations)</source>
+ <translation>V potrjevanju (št. potrditev: %1 od priporočenih %2)</translation>
+ </message>
+ <message>
+ <source>Conflicted</source>
+ <translation>V konfliktu</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Prejemek</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>Prejemek</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Izdatek</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>Nakazilo sebi</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Narudarjeno</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>opazovano</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(ni na voljo)</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>Stanje transakcije. Zapeljite z miško čez to polje za prikaz števila potrdil. </translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Datum in čas, ko je transakcija bila prejeta.</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>Vrsta transakcije.</translation>
+ </message>
+ <message>
+ <source>Whether or not a watch-only address is involved in this transaction.</source>
+ <translation>Ali je v transakciji udeležen kateri od opazovanih naslovov.</translation>
+ </message>
+ <message>
+ <source>User-defined intent/purpose of the transaction.</source>
+ <translation>Uporabniško določen namen transakcije.</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>Znesek spremembe stanja sredstev.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>Vse</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>Danes</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>Ta teden</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>Ta mesec</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>Prejšnji mesec</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>To leto</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>Območje ...</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Prejemek</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Izdatek</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>Nakazilo sebi</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Narudarjeno</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>Drugo</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>Iščite po naslovu ali oznaki</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>Minimalni znesek</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Kopiraj naslov</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Kopiraj oznako</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopiraj znesek</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Kopiraj ID transakcije</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>Uredi oznako</translation>
+ </message>
+ <message>
+ <source>Show transaction details</source>
+ <translation>Prikaži podrobnosti transakcije</translation>
+ </message>
+ <message>
+ <source>Export Transaction History</source>
+ <translation>Izvoz zgodovine transakcij</translation>
+ </message>
+ <message>
+ <source>Watch-only</source>
+ <translation>Opazovano</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Seznama transakcij ni bilo mogoče izvoziti.</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the transaction history to %1.</source>
+ <translation>Prišlo je do napake med shranjevanjem zgodovine transakcij v datoteko %1.</translation>
+ </message>
+ <message>
+ <source>Exporting Successful</source>
+ <translation>Uspešen izvoz</translation>
+ </message>
+ <message>
+ <source>The transaction history was successfully saved to %1.</source>
+ <translation>Zgodovina poteklih transakcij je bila uspešno shranjena v datoteko %1.</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Datoteka s podatki, ločenimi z vejico (*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Potrjeno</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Datum</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Vrsta</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Oznaka</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Naslov</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>Območje:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>za</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ <message>
+ <source>Unit to show amounts in. Click to select another unit.</source>
+ <translation>Merska enota za prikaz zneskov. Kliknite za izbiro druge enote.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletFrame</name>
+ <message>
+ <source>No wallet has been loaded.</source>
+ <translation>Denarnica ni bila naložena.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Pošlji</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Izvozi</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Izvozi podatke iz trenutnega zavihka v datoteko</translation>
+ </message>
+ <message>
+ <source>Backup Wallet</source>
+ <translation>Izdelava varnostne kopije denarnice</translation>
+ </message>
+ <message>
+ <source>Wallet Data (*.dat)</source>
+ <translation>Podatki denarnice (*.dat)</translation>
+ </message>
+ <message>
+ <source>Backup Failed</source>
+ <translation>Varnostne kopije ni bilo mogoče izdelati.</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the wallet data to %1.</source>
+ <translation>Prišlo je do napake pri shranjevanju podatkov denarnice v datoteko %1.</translation>
+ </message>
+ <message>
+ <source>The wallet data was successfully saved to %1.</source>
+ <translation>Podatki iz denarnice so bili uspešno shranjeni v datoteko %1.</translation>
+ </message>
+ <message>
+ <source>Backup Successful</source>
+ <translation>Varnostna kopija je bila uspešno izdelana</translation>
+ </message>
+</context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>Možnosti:</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>Izberite podatkovno mapo</translation>
+ </message>
+ <message>
+ <source>Connect to a node to retrieve peer addresses, and disconnect</source>
+ <translation>Povežite se z vozliščem za pridobitev naslovov soležnikov in nato prekinite povezavo.</translation>
+ </message>
+ <message>
+ <source>Specify your own public address</source>
+ <translation>Določite vaš lasten javni naslov</translation>
+ </message>
+ <message>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>Sprejemaj ukaze iz ukazne vrstice in preko JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>Teci v ozadju in sprejemaj ukaze</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>Uporabi testno omrežje</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
+ <translation>Sprejemaj zunanje povezave (privzeto: 1, razen če ste vklopili opciji -proxy ali -connect)</translation>
+ </message>
+ <message>
+ <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
+ <translation>Veži dani naslov in tam vedno poslušaj. Za naslove protokola IPv6 uporabite zapis [gostitelj]:vrata.</translation>
+ </message>
+ <message>
+ <source>Distributed under the MIT software license, see the accompanying file COPYING or &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</source>
+ <translation>Distribuirano v okviru programske licence MIT. Podrobnosti so navedene v priloženi datoteki COPYING ali na naslovu &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</translation>
+ </message>
+ <message>
+ <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
+ <translation>Izvedi ukaz, ko bo transakcija denarnice se spremenila (V cmd je bil TxID zamenjan za %s)</translation>
+ </message>
+ <message>
+ <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source>
+ <translation>Največji še veljavni skupni znesek provizij pri transakcijah z uporabo ene denarnice. Prenizka nastavitev lahko povzroči izločitev večjih transakcij (privzeto %s)</translation>
+ </message>
+ <message>
+ <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, &gt;%u = target size in MiB to use for block files)</source>
+ <translation>Omogoči obrezovanje (brisanje) starejših blokov in s tem prihrani pri prostoru za shranjevanje. Ta način delovanja onemogoči uporabo denarnice in ni združljivo z opcijo -txindex. Opozorilo: Če kasneje to opcijo povrnete na privzeto vrednost, boste morali ponovno prenesti celotno verigo. (privzeto: 0 = onemogoči obrezovanje, &gt;%u = ciljna velikost datotek blokov v MiB)</translation>
+ </message>
+ <message>
+ <source>Set the number of script verification threads (%u to %d, 0 = auto, &lt;0 = leave that many cores free, default: %d)</source>
+ <translation>Nastavi število niti za preverjanje skript (%u do %d, 0 = samodejno, &lt;0 toliko procesorskih jeder naj ostane prostih, privzeto: %d)</translation>
+ </message>
+ <message>
+ <source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source>
+ <translation>To je preizkusna različica še neizdanega programa. Uporabljate jo na lastno odgovornost. Programa ne uporabljajte je za rudarjenje ali trgovske aplikacije.</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer. Bitcoin Core is probably already running.</source>
+ <translation>Na tem računalniku ni bilo mogoče vezati naslova %s. Odjemalec Bitcoin Core je verjetno že zagnan.</translation>
+ </message>
+ <message>
+ <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>OPOZORILO: Generirano je bilo nenavadno veliko število blokov. Št. prejetih blokov: %d v št. ur: %d (pričakovanih je %d blokov)</translation>
+ </message>
+ <message>
+ <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>OPOZORILO: Preverite vašo omrežno povezavo. Št. prejetih blokov: %d v št. ur: %d (pričakovanih je %d blokov)</translation>
+ </message>
+ <message>
+ <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>Opozorilo: Vrednost opcije -paytxfee je zelo visoka. To je provizija, ki jo boste plačali, če izvedete plačilo.</translation>
+ </message>
+ <message>
+ <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source>
+ <translation>Opozorilo: Trenutno na omrežju ni videti konsenza! Videti je, kot da bi imeli nekateri rudarji težave.</translation>
+ </message>
+ <message>
+ <source>Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.</source>
+ <translation>Opozorilo: Trenutno se s soležniki ne strinjam v popolnosti! Mogoče bi morali vi ali drugi udeleženci posodobiti odjemalce.</translation>
+ </message>
+ <message>
+ <source>Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
+ <translation>Opozorilo: napaka pri branju datoteke wallet.dat! Vsi ključi so bili pravilno prebrani, podatki o transakciji ali imenik vnešenih naslovov so morda izgubljeni ali nepravilni.</translation>
+ </message>
+ <message>
+ <source>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</source>
+ <translation>Opozorilo: Datoteka wallet.dat je bila okvarjena, podatki pa so bili kljub temu rešeni! Originalna datoteka je bila shranjena kot wallet.{čas.oznaka}.bak v mapo %s. Če sta skupno stanje ali seznam transakcij napačna, morate datoteko restavrirati iz varnostne kopije.</translation>
+ </message>
+ <message>
+ <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source>
+ <translation>Sprejemaj povezave samo od soležnikov, ki so na naslovih, ki ustrezajo navedeni omrežni maski ali naslovu. Opcijo lahko navedete večkrat.</translation>
+ </message>
+ <message>
+ <source>(default: 1)</source>
+ <translation>(privzeto: 1)</translation>
+ </message>
+ <message>
+ <source>&lt;category&gt; can be:</source>
+ <translation>&lt;category&gt; je lahko:</translation>
+ </message>
+ <message>
+ <source>Attempt to recover private keys from a corrupt wallet.dat</source>
+ <translation>Skušaj obnoviti zasebne ključe iz okvarjene datoteke wallet.dat</translation>
+ </message>
+ <message>
+ <source>Block creation options:</source>
+ <translation>Možnosti ustvarjanja blokov:</translation>
+ </message>
+ <message>
+ <source>Connect only to the specified node(s)</source>
+ <translation>Poveži se samo z (enim ali več) navedenimi vozlišči</translation>
+ </message>
+ <message>
+ <source>Connection options:</source>
+ <translation>Izbire povezave:</translation>
+ </message>
+ <message>
+ <source>Corrupted block database detected</source>
+ <translation>Podatkovna baza blokov je okvarjena</translation>
+ </message>
+ <message>
+ <source>Debugging/Testing options:</source>
+ <translation>Možnosti razhroščevanja in testiranja:</translation>
+ </message>
+ <message>
+ <source>Do not load the wallet and disable wallet RPC calls</source>
+ <translation>Ne naloži denarnice in onemogoči s tem povezane klice RPC</translation>
+ </message>
+ <message>
+ <source>Do you want to rebuild the block database now?</source>
+ <translation>Želite zdaj obnoviti podatkovno bazo blokov?</translation>
+ </message>
+ <message>
+ <source>Error initializing block database</source>
+ <translation>Napaka pri inicializaciji podatkovne baze blokov</translation>
+ </message>
+ <message>
+ <source>Error initializing wallet database environment %s!</source>
+ <translation>Napaka pri inicializaciji okolja podatkovne baze denarnice %s!</translation>
+ </message>
+ <message>
+ <source>Error loading block database</source>
+ <translation>Napaka pri nalaganju podatkovne baze blokov</translation>
+ </message>
+ <message>
+ <source>Error opening block database</source>
+ <translation>Napaka pri odpiranju podatkovne baze blokov</translation>
+ </message>
+ <message>
+ <source>Error: Disk space is low!</source>
+ <translation>Opozorilo: Premalo prostora na disku!</translation>
+ </message>
+ <message>
+ <source>Failed to listen on any port. Use -listen=0 if you want this.</source>
+ <translation>Ni mogoče poslušati na nobenih vratih. Če to zares želite, uporabite opcijo -listen=0.</translation>
+ </message>
+ <message>
+ <source>If &lt;category&gt; is not supplied, output all debugging information.</source>
+ <translation>Če element &lt;category&gt; ni naveden, izpisuje vse informacije za razhroščevanje.</translation>
+ </message>
+ <message>
+ <source>Importing...</source>
+ <translation>Uvažam ...</translation>
+ </message>
+ <message>
+ <source>Incorrect or no genesis block found. Wrong datadir for network?</source>
+ <translation>Izvornega bloka ni mogoče najti ali pa je neveljaven. Preverite, če ste izbrali pravo podatkovno mapo za izbrano omrežje.</translation>
+ </message>
+ <message>
+ <source>Invalid -onion address: '%s'</source>
+ <translation>Neveljaven naslov tipa -onion: '%s'</translation>
+ </message>
+ <message>
+ <source>Not enough file descriptors available.</source>
+ <translation>Na voljo ni dovolj deskriptorjev datotek.</translation>
+ </message>
+ <message>
+ <source>Only connect to nodes in network &lt;net&gt; (ipv4, ipv6 or onion)</source>
+ <translation>Povezuj se samo z vozlišči na omrežju tipa &lt;net&gt; (IPv4, IPv6 ali onion)</translation>
+ </message>
+ <message>
+ <source>Prune cannot be configured with a negative value.</source>
+ <translation>Negativne vrednosti parametra funkcije obrezovanja niso sprejemljive.</translation>
+ </message>
+ <message>
+ <source>Prune mode is incompatible with -txindex.</source>
+ <translation>Funkcija obrezovanja ni združljiva z opcijo -txindex.</translation>
+ </message>
+ <message>
+ <source>Set database cache size in megabytes (%d to %d, default: %d)</source>
+ <translation>Nastavitev velikosti predpomnilnik podatkovne baze v MiB (%d do %d, privzeto: %d)</translation>
+ </message>
+ <message>
+ <source>Set maximum block size in bytes (default: %d)</source>
+ <translation>Nastavitev maksimalne velikosti bloka v bajtih (privzeto: %d)</translation>
+ </message>
+ <message>
+ <source>Specify wallet file (within data directory)</source>
+ <translation>Ime datoteke z denarnico (znotraj podatkovne mape)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: %u)</source>
+ <translation>Uporabi protokol UPnP za preslikavo vrat za poslušanje (privzeto: %u)</translation>
+ </message>
+ <message>
+ <source>Verifying blocks...</source>
+ <translation>Preverjam celovitost blokov ...</translation>
+ </message>
+ <message>
+ <source>Verifying wallet...</source>
+ <translation>Preverjam celovitost denarnice ...</translation>
+ </message>
+ <message>
+ <source>Wallet %s resides outside data directory %s</source>
+ <translation>Datoteka %s z denarnico se nahaja izven podatkovne mape %s</translation>
+ </message>
+ <message>
+ <source>Wallet options:</source>
+ <translation>Izbire denarnice:</translation>
+ </message>
+ <message>
+ <source>Warning: This version is obsolete; upgrade required!</source>
+ <translation>Opozorilo: Različica vašega odjemalca je zastarela. Potrebna je nadgradnja!</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to change -txindex</source>
+ <translation>Ob spremembi vrednosti opcije -txindex boste morali obnoviti bazo podatkov z uporabo opcije -reindex</translation>
+ </message>
+ <message>
+ <source>Imports blocks from external blk000??.dat file</source>
+ <translation>Uvozi bloke iz zunanje datoteke blk000??.dat</translation>
+ </message>
+ <message>
+ <source>Allow JSON-RPC connections from specified source. Valid for &lt;ip&gt; are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times</source>
+ <translation>Iz navedenega vira dovoli povezave na JSON-RPC. Veljavne oblike vrednosti parametra &lt;ip&gt; so: edinstven naslov IP (npr.: 1.2.3.4), kombinacija omrežje/netmask (npr.: 1.2.3.4/255.255.255.0), ali pa kombinacija omrežje/CIDR (1.2.3.4/24). To opcijo lahko navedete večkrat.</translation>
+ </message>
+ <message>
+ <source>An error occurred while setting up the RPC address %s port %u for listening: %s</source>
+ <translation>Prišlo je do napake med zagonom poslušalca RPC na naslovu %s in vratih %u: %s</translation>
+ </message>
+ <message>
+ <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source>
+ <translation>Veži dani naslov in sprejemaj povezave samo od navedenih soležnikov. Za naslove protokola IPv6 uporabite zapis [gostitelj]:vrata.</translation>
+ </message>
+ <message>
+ <source>Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)</source>
+ <translation>Veži dani naslov in sprejemaj povezave na JSON-RPC. Za naslove protokola IPv6 uporabite zapis [gostitelj]:vrata. To opcijo lahko navedete večkrat. (privzeto: veži vse omrežne vmesnike)</translation>
+ </message>
+ <message>
+ <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source>
+ <translation>Ne morem zakleniti podatkovne mape %s. Bitcoin Core je verjetno že zagnan.</translation>
+ </message>
+ <message>
+ <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
+ <translation>Ustvarjaj nove datoteke s privzetimi sistemskimi dovoljenji, namesto z umask 077. (To pride v poštev samo, kadar imate izklopljeno funkcijo denarnice.)</translation>
+ </message>
+ <message>
+ <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source>
+ <translation>Odkrij svoj naslov IP (privzeto: 1, če poslušate in sta opciji -externalip in -proxy neaktivni)</translation>
+ </message>
+ <message>
+ <source>Error: Listening for incoming connections failed (listen returned error %s)</source>
+ <translation>Napaka: Ni mogoče sprejemati dohodnih povezav (vrnjena napaka: %s)</translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source>
+ <translation>Napaka: Navedli ste nepodprto vrednost opcije -socks. Različice protokola SOCKS ni več mogoče navesti, podprti so samo posredniški strežniki tipa SOCKS5.</translation>
+ </message>
+ <message>
+ <source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source>
+ <translation>Ko bo prejeto ustrezno opozorilo, ali ko bo opažena zelo dolga razvejitev, izvedi navedeni ukazni niz. (Niz %s bo nadomeščen z vsebino sporočila.)</translation>
+ </message>
+ <message>
+ <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source>
+ <translation>Provizije (v BTC/KiB), ki so manjše od te vrednosti, se pri posredovanju smatrajo za nične (privzeto: %s)</translation>
+ </message>
+ <message>
+ <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
+ <translation>Če opcija -paytxfee ni nastavljena, nastavi znesek provizije tako visoko, da bodo transakcije potrjene v povprečno n blokih. (privzeto: %u)</translation>
+ </message>
+ <message>
+ <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source>
+ <translation>Na vsak posredniški strežnik se prijavi z drugimi naključnimi podatki. Tako je omogočena osamitev tokov v omrežju Tor (privzeto: %u)</translation>
+ </message>
+ <message>
+ <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source>
+ <translation>Opozorilo: Preverite, če sta datum in ura na vašem računalniku točna! Bitcoin Core ne bo dobro deloval, če je nastavljeni čas nepravilen.</translation>
+ </message>
+ <message>
+ <source>(default: %u)</source>
+ <translation>(privzeto: %u)</translation>
+ </message>
+ <message>
+ <source>Activating best chain...</source>
+ <translation>Preklapljam na najboljšo verigo ...</translation>
+ </message>
+ <message>
+ <source>Can't run with a wallet in prune mode.</source>
+ <translation>Če je omogočena funkcija obrezovanja, ni mogoče uporabljati denarnice.</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -whitebind address: '%s'</source>
+ <translation>Naslova %s, podanega pri opciji -whitebind ni mogoče razrešiti.</translation>
+ </message>
+ <message>
+ <source>Choose data directory on startup (default: 0)</source>
+ <translation>Ob zagonu pozovi uporabnika, naj izbere podatkovno mapo (privzeto: 0)</translation>
+ </message>
+ <message>
+ <source>Connect through SOCKS5 proxy</source>
+ <translation>Poveži se preko posredniškega strežnika SOCKS5</translation>
+ </message>
+ <message>
+ <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source>
+ <translation>Copyright (C) 2009-%i The Bitcoin Core Developers</translation>
+ </message>
+ <message>
+ <source>Could not parse -rpcbind value %s as network address</source>
+ <translation>Vrednost %s opcije -rpcbind ni prepoznaven omrežni naslov</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Informacije</translation>
+ </message>
+ <message>
+ <source>Need to specify a port with -whitebind: '%s'</source>
+ <translation>Pri opciji -whitebind morate navesti vrata: %s</translation>
+ </message>
+ <message>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>Pošilja sledilne/razhroščevalne informacije na konzolo namesto v datoteko debug.log</translation>
+ </message>
+ <message>
+ <source>Set SSL root certificates for payment request (default: -system-)</source>
+ <translation>Nastavi korenske certifikate SSL za preverjanje zahtevkov za plačilo (privzeto: -system-)</translation>
+ </message>
+ <message>
+ <source>Set language, for example "de_DE" (default: system locale)</source>
+ <translation>Nastavi jezik, npr. "sl_SI" (privzeto: jezik sistema)</translation>
+ </message>
+ <message>
+ <source>Show splash screen on startup (default: 1)</source>
+ <translation>Ob zagonu prikaži uvodni zaslon (privzeto: 1)</translation>
+ </message>
+ <message>
+ <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source>
+ <translation>Ob zagonu skrajšaj datoteko debug.log (privzeto: 1, če ni vklopljena opcija -debug)</translation>
+ </message>
+ <message>
+ <source>Signing transaction failed</source>
+ <translation>Transakcije ni bilo mogoče podpisati.</translation>
+ </message>
+ <message>
+ <source>Start minimized</source>
+ <translation>Zaženi v minimiranem oknu</translation>
+ </message>
+ <message>
+ <source>This is experimental software.</source>
+ <translation>Program je eksperimentalne narave.</translation>
+ </message>
+ <message>
+ <source>Transaction amount too small</source>
+ <translation>Znesek je pramajhen</translation>
+ </message>
+ <message>
+ <source>Transaction amounts must be positive</source>
+ <translation>Znesek mora biti pozitiven</translation>
+ </message>
+ <message>
+ <source>Transaction too large</source>
+ <translation>Transkacija je prevelika</translation>
+ </message>
+ <message>
+ <source>UI Options:</source>
+ <translation>Možnosti uporabniškega vmesnika:</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer (bind returned error %s)</source>
+ <translation>Na tem računalniku ni bilo mogoče vezati naslova %s (vrnjena napaka: %s)</translation>
+ </message>
+ <message>
+ <source>Username for JSON-RPC connections</source>
+ <translation>Uporabniško ime za povezave na JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Opozorilo</translation>
+ </message>
+ <message>
+ <source>Zapping all transactions from wallet...</source>
+ <translation>Brišem vse transakcije iz denarnice ...</translation>
+ </message>
+ <message>
+ <source>on startup</source>
+ <translation>ob zagonu</translation>
+ </message>
+ <message>
+ <source>wallet.dat corrupt, salvage failed</source>
+ <translation>Datoteka wallet.dat je poškodovana in je ni bilo mogoče obnoviti.</translation>
+ </message>
+ <message>
+ <source>Password for JSON-RPC connections</source>
+ <translation>Geslo za povezave na JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
+ <translation>Izvedi ukaz, ko je najden najboljši blok (niz %s v ukazu bo zamenjan s hash vrednostjo bloka)</translation>
+ </message>
+ <message>
+ <source>Upgrade wallet to latest format</source>
+ <translation>Nadgradi denarnico na najnovejšo različico</translation>
+ </message>
+ <message>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>S ponovnim pregledom verige blokov poišči manjkajoče transakcije iz denarnice</translation>
+ </message>
+ <message>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>Uporabi OpenSSL (https) za povezave na JSON-RPC</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>To sporočilo pomoči</translation>
+ </message>
+ <message>
+ <source>Allow DNS lookups for -addnode, -seednode and -connect</source>
+ <translation>Omogoči poizvedbe DNS za opcije -addnode, -seednode in -connect.</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>Nalagam naslove ...</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>Napaka pri nalaganju wallet.dat: denarnica pokvarjena</translation>
+ </message>
+ <message>
+ <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source>
+ <translation>Za dostop do soležnikov preko skritih storitev Tor uporabi drug posredniški strežnik SOCKS5 (privzeto: %s)</translation>
+ </message>
+ <message>
+ <source>(default: %s)</source>
+ <translation>(privzeto: %s)</translation>
+ </message>
+ <message>
+ <source>Acceptable ciphers (default: %s)</source>
+ <translation>Sprejemljivi tipi šifriranja (privzeto: %s)</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>Napaka pri nalaganju wallet.dat</translation>
+ </message>
+ <message>
+ <source>Invalid -proxy address: '%s'</source>
+ <translation>Neveljaven naslov -proxy: '%s'</translation>
+ </message>
+ <message>
+ <source>Relay non-P2SH multisig (default: %u)</source>
+ <translation>Posreduj transakcije tipa multisig, ki niso hkrati tipa P2SH. (privzeto: %u)</translation>
+ </message>
+ <message>
+ <source>Specify configuration file (default: %s)</source>
+ <translation>Za shranjevanje konfiguracije uporabi navedeno datoteko. (privzeto: %s)</translation>
+ </message>
+ <message>
+ <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source>
+ <translation>Vzpostavljanje nove povezave poteče po navedenem št. pretečenih milisekund. (najmanj: 1, privzeto: %d)</translation>
+ </message>
+ <message>
+ <source>Specify pid file (default: %s)</source>
+ <translation>Za shranjevanje PID uporabi navedeno datoteko. (privzeto: %s)</translation>
+ </message>
+ <message>
+ <source>Spend unconfirmed change when sending transactions (default: %u)</source>
+ <translation>Pri odlivnih transakcijah omogoči trošenje drobiža iz še nepotrjenih plačil (privzeto: %u)</translation>
+ </message>
+ <message>
+ <source>Threshold for disconnecting misbehaving peers (default: %u)</source>
+ <translation>Prekini povezavo s soležnikom, ko št. njegovih kazenskih točk preseže navedeni prag. (privzeto: %u)</translation>
+ </message>
+ <message>
+ <source>Unknown network specified in -onlynet: '%s'</source>
+ <translation>Neznano omrežje določeno v -onlynet: '%s'.</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -bind address: '%s'</source>
+ <translation>Naslova %s, podanega pri opciji -bind ni mogoče razrešiti.</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -externalip address: '%s'</source>
+ <translation>Naslova "%s", podanega pri opciji -externalip ni mogoče razrešiti.</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Neveljavna količina za -paytxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>Premalo sredstev</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>Nalagam kazalo blokov ...</translation>
+ </message>
+ <message>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>Dodaj povezavo na vozlišče in jo skušaj držati odprto</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>Nalagam denarnico ...</translation>
+ </message>
+ <message>
+ <source>Cannot downgrade wallet</source>
+ <translation>Ne morem </translation>
+ </message>
+ <message>
+ <source>Cannot write default address</source>
+ <translation>Ni mogoče zapisati privzetega naslova</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>Ponovno pregledujem verigo ...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>Nalaganje končano</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Napaka</translation>
+ </message>
+</context>
+</TS> \ No newline at end of file
diff --git a/src/qt/locale/bitcoin_sq.ts b/src/qt/locale/bitcoin_sq.ts
new file mode 100644
index 0000000000..6ed9856889
--- /dev/null
+++ b/src/qt/locale/bitcoin_sq.ts
@@ -0,0 +1,774 @@
+<TS language="sq" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Right-click to edit address or label</source>
+ <translation>Kliko me të djathtën për të ndryshuar adresën ose etiketen.</translation>
+ </message>
+ <message>
+ <source>Create a new address</source>
+ <translation>Krijo një adresë të re</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>&amp;E re</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Kopjo adresën e zgjedhur në memorjen e sistemit </translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>&amp;Kopjo</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>&amp;Kopjo adresen</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>Fshi adresen e selektuar nga lista</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;Fshi</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>Zgjidh adresen ku do te dergoni monedhat</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>Duke derguar adresen</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>Duke marr adresen</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>Këto janë Bitcoin adresat e juaja për të dërguar pagesa. Gjithmon kontrolloni shumën dhe adresën pranuese para se të dërgoni monedha.</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>Këto janë Bitcoin adresat e juaja për të pranuar pagesa. Rekomandohet që gjithmon të përdorni një adresë të re për çdo transaksion.</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>Kopjo &amp;Etiketë</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>&amp;Ndrysho</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>Eksporto listën e adresave</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Skedar i ndarë me pikëpresje(*.csv)</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Eksportimi dështoj</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the address list to %1. Please try again.</source>
+ <translation>Gabim gjatë ruajtjes së listës së adresave në %1. Ju lutem provoni prapë.</translation>
+ </message>
+</context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Etiketë</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adresë</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(pa etiketë)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Futni frazkalimin</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Frazkalim i ri</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Përsërisni frazkalimin e ri</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>Kripto portofolin</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>Ky veprim ka nevojë per frazkalimin e portofolit tuaj që të ç'kyç portofolin.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>ç'kyç portofolin.</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>Ky veprim kërkon frazkalimin e portofolit tuaj që të dekriptoj portofolin.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>Dekripto portofolin</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>Ndrysho frazkalimin</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>Konfirmoni enkriptimin e portofolit</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>Jeni te sigurt te enkriptoni portofolin tuaj?</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>Portofoli u enkriptua</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>Enkriptimi i portofolit dështoi</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>Enkriptimi i portofolit dështoi për shkak të një gabimi të brëndshëm. portofoli juaj nuk u enkriptua.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>Frazkalimet e plotësuara nuk përputhen.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>ç'kyçja e portofolit dështoi</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>Frazkalimi i futur për dekriptimin e portofolit nuk ishte i saktë.</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>Dekriptimi i portofolit dështoi</translation>
+ </message>
+ </context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>Duke u sinkronizuar me rrjetin...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;Përmbledhje</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>Trego një përmbledhje te përgjithshme të portofolit</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Transaksionet</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>Shfleto historinë e transaksioneve</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>Mbyllni aplikacionin</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;Opsione</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Ndrysho frazkalimin e përdorur per enkriptimin e portofolit</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>Portofol</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>&amp;Dergo</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>&amp;Merr</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>&amp;Shfaq / Fsheh</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;Skedar</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;Konfigurimet</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>&amp;Ndihmë</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>Shiriti i mjeteve</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Berthama Bitcoin</translation>
+ </message>
+ <message>
+ <source>&amp;About Bitcoin Core</source>
+ <translation>Rreth Berthames Bitkoin</translation>
+ </message>
+ <message>
+ <source>%1 and %2</source>
+ <translation>%1 dhe %2</translation>
+ </message>
+ <message>
+ <source>%1 behind</source>
+ <translation>%1 Pas</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Problem</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Informacion</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>I azhornuar</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>Duke u azhornuar...</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>Dërgo transaksionin</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>Transaksion në ardhje</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>Portofoli po &lt;b&gt; enkriptohet&lt;/b&gt; dhe është &lt;b&gt; i ç'kyçur&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>Portofoli po &lt;b&gt; enkriptohet&lt;/b&gt; dhe është &lt;b&gt; i kyçur&lt;/b&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ </context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Coin Selection</source>
+ <translation>Zgjedhja e monedhes</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Shuma:</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Sasia</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Kopjo adresën</translation>
+ </message>
+ <message>
+ <source>yes</source>
+ <translation>po</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>jo</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(pa etiketë)</translation>
+ </message>
+ </context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>Ndrysho Adresën</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>&amp;Etiketë</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;Adresa</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>Adresë e re pritëse</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>Adresë e re dërgimi</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>Ndrysho adresën pritëse</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>ndrysho adresën dërguese</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>Adresa e dhënë "%1" është e zënë në librin e adresave. </translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>Nuk mund të ç'kyçet portofoli.</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>Krijimi i çelësit të ri dështoi.</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ <message>
+ <source>name</source>
+ <translation>emri</translation>
+ </message>
+ </context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Berthama Bitcoin</translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>versioni</translation>
+ </message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>Rreth Berthames Bitkoin</translation>
+ </message>
+ </context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Welcome</source>
+ <translation>Miresevini</translation>
+ </message>
+ <message>
+ <source>Welcome to Bitcoin Core.</source>
+ <translation>Miresevini ne Berthamen Bitcoin</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Berthama Bitcoin</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Problem</translation>
+ </message>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ </context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>Opsionet</translation>
+ </message>
+ </context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>Formilarë</translation>
+ </message>
+ </context>
+<context>
+ <name>PaymentServer</name>
+ </context>
+<context>
+ <name>PeerTableModel</name>
+ </context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>Sasia</translation>
+ </message>
+ </context>
+<context>
+ <name>QRImageWidget</name>
+ </context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>&amp;Open</source>
+ <translation>&amp;Hap</translation>
+ </message>
+ <message>
+ <source>&amp;Clear</source>
+ <translation>&amp;Pastro</translation>
+ </message>
+ <message>
+ <source>never</source>
+ <translation>asnjehere</translation>
+ </message>
+ <message>
+ <source>Unknown</source>
+ <translation>i/e panjohur</translation>
+ </message>
+ </context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Etiketë:</translation>
+ </message>
+ </context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>Address</source>
+ <translation>Adresë</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Sasia</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiketë</translation>
+ </message>
+ </context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiketë</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Sasia</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(pa etiketë)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Dërgo Monedha</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Shuma:</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>Dërgo marrësve të ndryshëm njëkohësisht</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>Balanca:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>Konfirmo veprimin e dërgimit</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>konfirmo dërgimin e monedhave</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>Shuma e paguar duhet të jetë më e madhe se 0.</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(pa etiketë)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>Sh&amp;uma:</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>Paguaj &amp;drejt:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Krijoni një etiketë për këtë adresë që t'ja shtoni librit të adresave</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Etiketë:</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Ngjit nga memorja e sistemit</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ </context>
+<context>
+ <name>ShutdownWindow</name>
+ </context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Ngjit nga memorja e sistemit</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ </context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Berthama Bitcoin</translation>
+ </message>
+ <message>
+ <source>[testnet]</source>
+ <translation>[testo rrjetin]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ </context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>Hapur deri më %1</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/I pakonfirmuar</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 konfirmimet</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Sasia</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, nuk është transmetuar me sukses deri tani</translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>i/e panjohur</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>Detajet e transaksionit</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>Ky panel tregon një përshkrim të detajuar të transaksionit</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Lloji</translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>Hapur deri më %1</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>I/E konfirmuar(%1 konfirmime)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>Ky bllok është marrë nga ndonjë nyje dhe ka shumë mundësi të mos pranohet! </translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>I krijuar por i papranuar</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiketë</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Marrë me</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Dërguar drejt</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>Pagesë ndaj vetvetes</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Minuar</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(p/a)</translation>
+ </message>
+ </context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>Received with</source>
+ <translation>Marrë me</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Dërguar drejt</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Minuar</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Kopjo adresën</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Eksportimi dështoj</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Skedar i ndarë me pikëpresje(*.csv)</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Lloji</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiketë</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adresë</translation>
+ </message>
+ </context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ </context>
+<context>
+ <name>WalletFrame</name>
+ </context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Dërgo Monedha</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ </context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Information</source>
+ <translation>Informacion</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>Fonde te pamjaftueshme</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>Rikerkim</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Problem</translation>
+ </message>
+</context>
+</TS> \ 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 0000000000..ddaab9ab2b
--- /dev/null
+++ b/src/qt/locale/bitcoin_sr.ts
@@ -0,0 +1,806 @@
+<TS language="sr" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Create a new address</source>
+ <translation>Napravite novu adresu</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>Novo</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Kopirajte trenutno izabranu adresu</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>Kopirajte</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>Kopirajte adresu</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>Izbrisite trenutno izabranu adresu sa liste</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;Избриши</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Зарезом одвојене вредности (*.csv)</translation>
+ </message>
+ </context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Етикета</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Адреса</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(без етикете)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Унесите лозинку</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Нова лозинка</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Поновите нову лозинку</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>Шифровање новчаника</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>Ова акција захтева лозинку Вашег новчаника да би га откључала.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Откључавање новчаника</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>Ова акција захтева да унесете лозинку да би дешифловала новчаник.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>Дешифровање новчаника</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>Промена лозинке</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>Одобрите шифровање новчаника</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>Упозорење: Ако се ваш новчаник шифрује а потом изгубите лозинкзу, ви ћете &lt;b&gt;ИЗГУБИТИ СВЕ BITCOIN-Е&lt;/b&gt;!</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>Да ли сте сигурни да желите да се новчаник шифује?</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>Новчаник је шифрован</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>Неуспело шифровање новчаника</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>Настала је унутрашња грешка током шифровања новчаника. Ваш новчаник није шифрован.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>Лозинке које сте унели се не подударају.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>Неуспело откључавање новчаника</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>Лозинка коју сте унели за откључавање новчаника је нетачна.</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>Неуспело дешифровање новчаника</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>Лозинка за приступ новчанику је успешно промењена.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>Синхронизација са мрежом у току...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;Општи преглед</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>Погледајте општи преглед новчаника</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Трансакције</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>Претражите историјат трансакција</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>I&amp;zlaz</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>Напустите програм</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>О &amp;Qt-у</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>Прегледајте информације о Qt-у</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>П&amp;оставке...</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>&amp;Шифровање новчаника...</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>&amp;Backup новчаника</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>Промени &amp;лозинку...</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>Пошаљите новац на bitcoin адресу</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Мењање лозинке којом се шифрује новчаник</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>новчаник</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>&amp;Пошаљи</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;Фајл</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;Подешавања</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>П&amp;омоћ</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>Трака са картицама</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>Ажурно</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>Ажурирање у току...</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>Послана трансакција</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>Придошла трансакција</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>Новчаник јс &lt;b&gt;шифрован&lt;/b&gt; и тренутно &lt;b&gt;откључан&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>Новчаник јс &lt;b&gt;шифрован&lt;/b&gt; и тренутно &lt;b&gt;закључан&lt;/b&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ </context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Amount:</source>
+ <translation>Iznos:</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>iznos</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>datum</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Potvrdjen</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>kopiraj adresu</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>kopiraj naziv</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>kopiraj iznos</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(без етикете)</translation>
+ </message>
+ </context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>Измени адресу</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>&amp;Етикета</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;Адреса</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>Унешена адреса "%1" се већ налази у адресару.</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>Немогуће откључати новчаник.</translation>
+ </message>
+ </context>
+<context>
+ <name>FreespaceChecker</name>
+ </context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>version</source>
+ <translation>верзија</translation>
+ </message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>O Bitcoin Coru</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>Korišćenje:</translation>
+ </message>
+ </context>
+<context>
+ <name>Intro</name>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ </context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>Поставке</translation>
+ </message>
+ <message>
+ <source>&amp;Unit to show amounts in:</source>
+ <translation>&amp;Јединица за приказивање износа:</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>&amp;OK</translation>
+ </message>
+ </context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>Форма</translation>
+ </message>
+ </context>
+<context>
+ <name>PaymentServer</name>
+ </context>
+<context>
+ <name>PeerTableModel</name>
+ </context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>iznos</translation>
+ </message>
+ </context>
+<context>
+ <name>QRImageWidget</name>
+ </context>
+<context>
+ <name>RPCConsole</name>
+ </context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Етикета</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>kopiraj naziv</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>kopiraj iznos</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>Address</source>
+ <translation>Адреса</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>iznos</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Етикета</translation>
+ </message>
+ </context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>datum</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Етикета</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>iznos</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(без етикете)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Слање новца</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Iznos:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>Потврди акцију слања</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>&amp;Пошаљи</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>kopiraj iznos</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(без етикете)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Етикета</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+П</translation>
+ </message>
+ <message>
+ <source>Message:</source>
+ <translation>Poruka:</translation>
+ </message>
+ </context>
+<context>
+ <name>ShutdownWindow</name>
+ </context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+П</translation>
+ </message>
+ </context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>[testnet]</source>
+ <translation>[testnet]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ </context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>Otvoreno do %1</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/nepotvrdjeno</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 potvrde</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>datum</translation>
+ </message>
+ <message>
+ <source>label</source>
+ <translation>етикета</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>iznos</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, nije još uvek uspešno emitovan</translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>nepoznato</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>detalji transakcije</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>Ovaj odeljak pokazuje detaljan opis transakcije</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>datum</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>tip</translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>Otvoreno do %1</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>Potvrdjena (%1 potvrdjenih)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>Ovaj blok nije primljen od ostalih čvorova (nodova) i verovatno neće biti prihvaćen!</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>Generisan ali nije prihvaćen</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Етикета</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Primljen sa</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>Primljeno od</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Poslat ka</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>Isplata samom sebi</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Minirano</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(n/a)</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>Status vaše transakcije. Predjite mišem preko ovog polja da bi ste videli broj konfirmacija</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Datum i vreme primljene transakcije.</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>Tip transakcije</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>Iznos odbijen ili dodat balansu.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>Sve</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>Danas</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>ove nedelje</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>Ovog meseca</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>Prošlog meseca</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>Ove godine</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>Opseg...</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Primljen sa</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Poslat ka</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>Vama - samom sebi</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Minirano</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>Drugi</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>Navedite adresu ili naziv koji bi ste potražili</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>Min iznos</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>kopiraj adresu</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>kopiraj naziv</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>kopiraj iznos</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>promeni naziv</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Зарезом одвојене вредности (*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Potvrdjen</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>datum</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>tip</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Етикета</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Адреса</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>Opseg:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>do</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ </context>
+<context>
+ <name>WalletFrame</name>
+ </context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Слање новца</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>Backup Wallet</source>
+ <translation>Backup новчаника</translation>
+ </message>
+ </context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>Opcije</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>Gde je konkretni data direktorijum </translation>
+ </message>
+ <message>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>Prihvati komandnu liniju i JSON-RPC komande</translation>
+ </message>
+ <message>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>Radi u pozadini kao daemon servis i prihvati komande</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>Koristi testnu mrežu</translation>
+ </message>
+ <message>
+ <source>Username for JSON-RPC connections</source>
+ <translation>Korisničko ime za JSON-RPC konekcije</translation>
+ </message>
+ <message>
+ <source>Password for JSON-RPC connections</source>
+ <translation>Lozinka za JSON-RPC konekcije</translation>
+ </message>
+ <message>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>Ponovo skeniraj lanac blokova za nedostajuće transakcije iz novčanika</translation>
+ </message>
+ <message>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>Koristi OpenSSL (https) za JSON-RPC konekcije</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>Ova poruka Pomoći</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>učitavam adrese....</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>Грешка током учитавања wallet.dat: Новчаник је покварен </translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>Грешка током учитавања wallet.dat </translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>Učitavam blok indeksa...</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>Новчаник се учитава...</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>Ponovo skeniram...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>Završeno učitavanje</translation>
+ </message>
+ </context>
+</TS> \ 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 0000000000..f589383f9b
--- /dev/null
+++ b/src/qt/locale/bitcoin_sv.ts
@@ -0,0 +1,3577 @@
+<TS language="sv" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Right-click to edit address or label</source>
+ <translation>Högerklicka för att ändra adressen eller etiketten.</translation>
+ </message>
+ <message>
+ <source>Create a new address</source>
+ <translation>Skapa ny adress</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>&amp;Ny</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Kopiera den markerade adressen till systemets Urklipp</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>&amp;Kopiera</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>S&amp;täng</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>&amp;Kopiera adress</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>Ta bort den valda adressen från listan</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Exportera informationen i den nuvarande fliken till en fil</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Exportera</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;Radera</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>Välj en adress att sända betalning till</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>Välj en adress att ta emot betalning till</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>V&amp;älj</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>Avsändaradresser</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>Mottagaradresser</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>Detta är dina Bitcoin-adresser för att skicka betalningar. Kolla alltid summan och den mottagande adressen innan du skickar Bitcoins.</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>Detta är dina Bitcoin-adresser för att ta emot betalningar. Det rekommenderas att använda en ny mottagningsadress för varje transaktion.</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>Kopiera &amp;etikett</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>&amp;Ändra</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>Exportera adresslistan</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Kommaseparerad fil (*.csv)</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Exporteringen misslyckades</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the address list to %1. Please try again.</source>
+ <translation>Det inträffade ett fel när adresslistan skulle sparas till %1.
+Var vänlig och försök igen.</translation>
+ </message>
+</context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Etikett</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adress</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(ingen etikett)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Passphrase Dialog</source>
+ <translation>Lösenordsdialog</translation>
+ </message>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Ange lösenord</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Nytt lösenord</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Upprepa nytt lösenord</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>Kryptera plånbok</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>Denna operation behöver din plånboks lösenord för att låsa upp plånboken.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Lås upp plånbok</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>Denna operation behöver din plånboks lösenord för att dekryptera plånboken.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>Dekryptera plånbok</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>Ändra lösenord</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>Bekräfta kryptering av plånbok</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>VARNING: Om du krypterar din plånbok och glömmer ditt lösenord, kommer du att &lt;b&gt;FÖRLORA ALLA DINA TILLGÅNGAR&lt;/b&gt;!</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>Är du säker på att du vill kryptera din plånbok?</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core 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.</source>
+ <translation>Bitcoin Core kommer att stängas för att slutföra krypteringsprocessen. Kom ihåg att plånbokskryptering inte garanterar fullt skydd mot skadlig kod på din dator.</translation>
+ </message>
+ <message>
+ <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
+ <translation>VIKTIGT: Alla tidigare säkerhetskopior du har gjort av plånbokens fil ska ersättas med den nya genererade, krypterade plånboks filen. Av säkerhetsskäl kommer tidigare säkerhetskopior av den okrypterade plånboks filen blir oanvändbara när du börjar använda en ny, krypterad plånbok.</translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>Varning: Caps Lock är påslaget!</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>Plånboken är krypterad</translation>
+ </message>
+ <message>
+ <source>Enter the new passphrase to the wallet.&lt;br/&gt;Please use a passphrase of &lt;b&gt;ten or more random characters&lt;/b&gt;, or &lt;b&gt;eight or more words&lt;/b&gt;.</source>
+ <translation>Ange plånbokens nya lösenord. &lt;br/&gt; Använd ett lösenord på &lt;b&gt;tio eller fler slumpmässiga tecken,&lt;/b&gt; eller &lt;b&gt;åtta eller fler ord.&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>Enter the old passphrase and new passphrase to the wallet.</source>
+ <translation>Ge det gamla lösenordet och det nya lösenordet för plånboken.</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>Kryptering av plånbok misslyckades</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>Kryptering av plånbok misslyckades på grund av ett internt fel. Din plånbok blev inte krypterad.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>De angivna lösenorden överensstämmer inte.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>Upplåsning av plånbok misslyckades</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>Lösenordet för dekryptering av plånbok var felaktig.</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>Dekryptering av plånbok misslyckades</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>Plånbokens lösenord har ändrats.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>Signera &amp;meddelande...</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>Synkroniserar med nätverk...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;Översikt</translation>
+ </message>
+ <message>
+ <source>Node</source>
+ <translation>Nod</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>Visa generell översikt av plånboken</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Transaktioner</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>Bläddra i transaktionshistorik</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>&amp;Avsluta</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>Avsluta programmet</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>Om &amp;Qt</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>Visa information om Qt</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;Alternativ...</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>&amp;Kryptera plånbok...</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>&amp;Säkerhetskopiera plånbok...</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>&amp;Byt lösenord...</translation>
+ </message>
+ <message>
+ <source>&amp;Sending addresses...</source>
+ <translation>Av&amp;sändaradresser...</translation>
+ </message>
+ <message>
+ <source>&amp;Receiving addresses...</source>
+ <translation>Mottaga&amp;radresser...</translation>
+ </message>
+ <message>
+ <source>Open &amp;URI...</source>
+ <translation>Öppna &amp;URI...</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core client</source>
+ <translation>Bitcoin Core-klient</translation>
+ </message>
+ <message>
+ <source>Importing blocks from disk...</source>
+ <translation>Importerar block från disk...</translation>
+ </message>
+ <message>
+ <source>Reindexing blocks on disk...</source>
+ <translation>Återindexerar block på disken...</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>Skicka bitcoins till en Bitcoin-adress</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>Säkerhetskopiera plånboken till en annan plats</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Byt lösenfras för kryptering av plånbok</translation>
+ </message>
+ <message>
+ <source>&amp;Debug window</source>
+ <translation>&amp;Debug-fönster</translation>
+ </message>
+ <message>
+ <source>Open debugging and diagnostic console</source>
+ <translation>Öppna debug- och diagnostikkonsolen</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>&amp;Verifiera meddelande...</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>Plånbok</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>&amp;Skicka</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>&amp;Ta emot</translation>
+ </message>
+ <message>
+ <source>Show information about Bitcoin Core</source>
+ <translation>Visa information om Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>&amp;Visa / Göm</translation>
+ </message>
+ <message>
+ <source>Show or hide the main Window</source>
+ <translation>Visa eller göm huvudfönstret</translation>
+ </message>
+ <message>
+ <source>Encrypt the private keys that belong to your wallet</source>
+ <translation>Kryptera de privata nycklar som tillhör din plånbok</translation>
+ </message>
+ <message>
+ <source>Sign messages with your Bitcoin addresses to prove you own them</source>
+ <translation>Signera meddelanden med din Bitcoin-adress för att bevisa att du äger dem</translation>
+ </message>
+ <message>
+ <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source>
+ <translation>Verifiera meddelanden för att vara säker på att de var signerade med specificerade Bitcoin-adresser</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;Arkiv</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;Inställningar</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>&amp;Hjälp</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>Verktygsfält för tabbar</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Request payments (generates QR codes and bitcoin: URIs)</source>
+ <translation>Begär betalning (genererar QR-koder och bitcoin-URI)</translation>
+ </message>
+ <message>
+ <source>&amp;About Bitcoin Core</source>
+ <translation>&amp;Om Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Modify configuration options for Bitcoin Core</source>
+ <translation>Ändra konfigurationsalternativ för Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Show the list of used sending addresses and labels</source>
+ <translation>Visa listan av använda avsändaradresser och etiketter</translation>
+ </message>
+ <message>
+ <source>Show the list of used receiving addresses and labels</source>
+ <translation>Visa listan av använda mottagningsadresser och etiketter</translation>
+ </message>
+ <message>
+ <source>Open a bitcoin: URI or payment request</source>
+ <translation>Öppna en bitcoin: URI eller betalningsbegäran</translation>
+ </message>
+ <message>
+ <source>&amp;Command-line options</source>
+ <translation>&amp;Kommandoradsalternativ</translation>
+ </message>
+ <message>
+ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
+ <translation>Visa Bitcoin Cores hjälpmeddelande för att få en lista med möjliga Bitcoin-kommandoradsalternativ.</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n active connection(s) to Bitcoin network</source>
+ <translation><numerusform>%n aktiva anslutningar till Bitcoin-nätverket.</numerusform><numerusform>%n aktiva anslutningar till Bitcoin-nätverket.</numerusform></translation>
+ </message>
+ <message>
+ <source>No block source available...</source>
+ <translation>Ingen block-källa tillgänglig...</translation>
+ </message>
+ <message numerus="yes">
+ <source>Processed %n block(s) of transaction history.</source>
+ <translation><numerusform>Bearbetade %n block av transaktionshistoriken.</numerusform><numerusform>Bearbetade %n block av transaktionshistoriken.</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n hour(s)</source>
+ <translation><numerusform>%n timme</numerusform><numerusform>%n timmar</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n day(s)</source>
+ <translation><numerusform>%n dag</numerusform><numerusform>%n dagar</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n week(s)</source>
+ <translation><numerusform>%n vecka</numerusform><numerusform>%n veckor</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 and %2</source>
+ <translation>%1 och %2</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n year(s)</source>
+ <translation><numerusform>%n år</numerusform><numerusform>%n år</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 behind</source>
+ <translation>%1 efter</translation>
+ </message>
+ <message>
+ <source>Last received block was generated %1 ago.</source>
+ <translation>Senast mottagna block genererades för %1 sen.</translation>
+ </message>
+ <message>
+ <source>Transactions after this will not yet be visible.</source>
+ <translation>Transaktioner efter denna kommer inte ännu vara synliga.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Fel</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Varning</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Information</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>Uppdaterad</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>Hämtar senaste...</translation>
+ </message>
+ <message>
+ <source>Date: %1
+</source>
+ <translation>Datum: %1
+</translation>
+ </message>
+ <message>
+ <source>Amount: %1
+</source>
+ <translation>Belopp: %1
+</translation>
+ </message>
+ <message>
+ <source>Type: %1
+</source>
+ <translation>Typ: %1
+</translation>
+ </message>
+ <message>
+ <source>Label: %1
+</source>
+ <translation>Etikett: %1
+</translation>
+ </message>
+ <message>
+ <source>Address: %1
+</source>
+ <translation>Adress: %1
+</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>Transaktion skickad</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>Inkommande transaktion</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>Denna plånbok är &lt;b&gt;krypterad&lt;/b&gt; och för närvarande &lt;b&gt;olåst&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>Denna plånbok är &lt;b&gt;krypterad&lt;/b&gt; och för närvarande &lt;b&gt;låst&lt;/b&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <source>Network Alert</source>
+ <translation>Nätverkslarm</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Coin Selection</source>
+ <translation>Myntval</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Kvantitet:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Antal byte:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Belopp:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Prioritet:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Avgift:</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Damm:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Efter avgift:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Växel:</translation>
+ </message>
+ <message>
+ <source>(un)select all</source>
+ <translation>(av)markera allt</translation>
+ </message>
+ <message>
+ <source>Tree mode</source>
+ <translation>Trädvy</translation>
+ </message>
+ <message>
+ <source>List mode</source>
+ <translation>Listvy</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Mängd</translation>
+ </message>
+ <message>
+ <source>Received with label</source>
+ <translation>Mottagen med etikett</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>Mottagen med adress</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Datum</translation>
+ </message>
+ <message>
+ <source>Confirmations</source>
+ <translation>Bekräftelser</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Bekräftad</translation>
+ </message>
+ <message>
+ <source>Priority</source>
+ <translation>Prioritet</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Kopiera adress</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Kopiera etikett</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopiera belopp</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Kopiera transaktions ID</translation>
+ </message>
+ <message>
+ <source>Lock unspent</source>
+ <translation>Lås ospenderat</translation>
+ </message>
+ <message>
+ <source>Unlock unspent</source>
+ <translation>Lås upp ospenderat</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Kopiera kvantitet</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Kopiera avgift</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Kopiera efter avgift</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Kopiera byte</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Kopiera prioritet</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Kopiera damm</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Kopiera växel</translation>
+ </message>
+ <message>
+ <source>highest</source>
+ <translation>högst</translation>
+ </message>
+ <message>
+ <source>higher</source>
+ <translation>högre</translation>
+ </message>
+ <message>
+ <source>high</source>
+ <translation>hög</translation>
+ </message>
+ <message>
+ <source>medium-high</source>
+ <translation>medelhög</translation>
+ </message>
+ <message>
+ <source>medium</source>
+ <translation>medel</translation>
+ </message>
+ <message>
+ <source>low-medium</source>
+ <translation>lågmedel</translation>
+ </message>
+ <message>
+ <source>low</source>
+ <translation>låg</translation>
+ </message>
+ <message>
+ <source>lower</source>
+ <translation>lägre</translation>
+ </message>
+ <message>
+ <source>lowest</source>
+ <translation>lägst</translation>
+ </message>
+ <message>
+ <source>(%1 locked)</source>
+ <translation>(%1 låst)</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>ingen</translation>
+ </message>
+ <message>
+ <source>This label turns red if the transaction size is greater than 1000 bytes.</source>
+ <translation>Denna etikett blir röd om transaktionens storlek är större än 1000 bytes.</translation>
+ </message>
+ <message>
+ <source>This label turns red if the priority is smaller than "medium".</source>
+ <translation>Denna etikett blir röd om prioriteten är lägre än "medium".</translation>
+ </message>
+ <message>
+ <source>This label turns red if any recipient receives an amount smaller than %1.</source>
+ <translation>Denna etikett blir röd om någon mottagare får ett belopp mindre än %1.</translation>
+ </message>
+ <message>
+ <source>yes</source>
+ <translation>ja</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>nej</translation>
+ </message>
+ <message>
+ <source>This means a fee of at least %1 per kB is required.</source>
+ <translation>Detta betyder att en avgift på minst %1 per kB behövs.</translation>
+ </message>
+ <message>
+ <source>Can vary +/- 1 byte per input.</source>
+ <translation>Kan variera +/- 1 byte per inmatning.</translation>
+ </message>
+ <message>
+ <source>Transactions with higher priority are more likely to get included into a block.</source>
+ <translation>Transaktioner med högre prioritet har större sannolikhet att inkluderas i ett block.</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(Ingen etikett)</translation>
+ </message>
+ <message>
+ <source>change from %1 (%2)</source>
+ <translation>växel från %1 (%2)</translation>
+ </message>
+ <message>
+ <source>(change)</source>
+ <translation>(växel)</translation>
+ </message>
+</context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>Redigera adress</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>&amp;Etikett</translation>
+ </message>
+ <message>
+ <source>The label associated with this address list entry</source>
+ <translation>Etiketten associerad med denna adresslistas post</translation>
+ </message>
+ <message>
+ <source>The address associated with this address list entry. This can only be modified for sending addresses.</source>
+ <translation>Adressen associerad med denna adresslistas post. Detta kan bara ändras för sändningsadresser.</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;Adress</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>Ny mottagaradress</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>Ny avsändaradress</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>Redigera mottagaradress</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>Redigera avsändaradress</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>Den angivna adressen "%1" finns redan i adressboken.</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is not a valid Bitcoin address.</source>
+ <translation>Den angivna adressen "%1" är inte en giltig Bitcoin-adress.</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>Plånboken kunde inte låsas upp.</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>Misslyckades med generering av ny nyckel.</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ <message>
+ <source>A new data directory will be created.</source>
+ <translation>En ny datakatalog kommer att skapas.</translation>
+ </message>
+ <message>
+ <source>name</source>
+ <translation>namn</translation>
+ </message>
+ <message>
+ <source>Directory already exists. Add %1 if you intend to create a new directory here.</source>
+ <translation>Katalogen finns redan. Läggtill %1 om du vill skapa en ny katalog här.</translation>
+ </message>
+ <message>
+ <source>Path already exists, and is not a directory.</source>
+ <translation>Sökvägen finns redan, och är inte en katalog.</translation>
+ </message>
+ <message>
+ <source>Cannot create data directory here.</source>
+ <translation>Kan inte skapa datakatalog här.</translation>
+ </message>
+</context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>version</translation>
+ </message>
+ <message>
+ <source>(%1-bit)</source>
+ <translation>(%1-bit)</translation>
+ </message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>Om Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Command-line options</source>
+ <translation>Kommandoradsalternativ</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>Användning:</translation>
+ </message>
+ <message>
+ <source>command-line options</source>
+ <translation>kommandoradsalternativ</translation>
+ </message>
+</context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Welcome</source>
+ <translation>Välkommen</translation>
+ </message>
+ <message>
+ <source>Welcome to Bitcoin Core.</source>
+ <translation>Välkommen till Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</source>
+ <translation>Eftersom detta är första gången programmet startas får du välja var Bitcoin Core skall lagra sina data.</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory.</source>
+ <translation>Bitcoin Core kommer att ladda ner och spara en kopia av Bitcoin-blockkedjan. Åtminstone %1GB av data kommer att sparas i denna katalog, och den kommer att växa över tiden. Plånboken kommer också att sparas i denna katalog.</translation>
+ </message>
+ <message>
+ <source>Use the default data directory</source>
+ <translation>Använd den förvalda datakatalogen</translation>
+ </message>
+ <message>
+ <source>Use a custom data directory:</source>
+ <translation>Använd en anpassad datakatalog:</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Error: Specified data directory "%1" cannot be created.</source>
+ <translation>Fel: Den angivna datakatalogen "%1" kan inte skapas.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Fel</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n GB of free space available</source>
+ <translation><numerusform>%n GB fritt utrymme kvar</numerusform><numerusform>%n GB fritt utrymme kvar</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>(of %n GB needed)</source>
+ <translation><numerusform>(av %n GB behövs)</numerusform><numerusform>(av %n GB behövs)</numerusform></translation>
+ </message>
+</context>
+<context>
+ <name>OpenURIDialog</name>
+ <message>
+ <source>Open URI</source>
+ <translation>Öppna URI</translation>
+ </message>
+ <message>
+ <source>Open payment request from URI or file</source>
+ <translation>Öppna betalningsbegäran från URI eller fil</translation>
+ </message>
+ <message>
+ <source>URI:</source>
+ <translation>URI:</translation>
+ </message>
+ <message>
+ <source>Select payment request file</source>
+ <translation>Välj betalningsbegäransfil</translation>
+ </message>
+ <message>
+ <source>Select payment request file to open</source>
+ <translation>Välj betalningsbegäransfil att öppna</translation>
+ </message>
+</context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>Alternativ</translation>
+ </message>
+ <message>
+ <source>&amp;Main</source>
+ <translation>&amp;Allmänt</translation>
+ </message>
+ <message>
+ <source>Size of &amp;database cache</source>
+ <translation>Storleken på &amp;databascache</translation>
+ </message>
+ <message>
+ <source>MB</source>
+ <translation>MB</translation>
+ </message>
+ <message>
+ <source>Number of script &amp;verification threads</source>
+ <translation>Antalet skript&amp;verifikationstrådar</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside</source>
+ <translation>Acceptera anslutningar utifrån</translation>
+ </message>
+ <message>
+ <source>Allow incoming connections</source>
+ <translation>Acceptera inkommande anslutningar</translation>
+ </message>
+ <message>
+ <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
+ <translation>Proxyns IP-adress (t.ex. IPv4: 127.0.0.1 / IPv6: ::1)</translation>
+ </message>
+ <message>
+ <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source>
+ <translation>Minimera istället för att stänga programmet när fönstret stängs. När detta alternativ är aktiverat stängs programmet endast genom att välja Stäng i menyn.</translation>
+ </message>
+ <message>
+ <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source>
+ <translation>Gränssnittets språk kan väljas här. Denna inställning träder i kraft efter omstart av Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source>
+ <translation>Tredjeparts URL:er (t.ex. en blockutforskare) som finns i transaktionstabben som ett menyval i sammanhanget. %s i URL:en ersätts med tansaktionshashen. Flera URL:er är separerade med vertikala streck |.</translation>
+ </message>
+ <message>
+ <source>Third party transaction URLs</source>
+ <translation>Tredjeparts transaktions-URL:er</translation>
+ </message>
+ <message>
+ <source>Active command-line options that override above options:</source>
+ <translation>Aktiva kommandoradsalternativ som ersätter alternativen ovan:</translation>
+ </message>
+ <message>
+ <source>Reset all client options to default.</source>
+ <translation>Återställ alla klientinställningar till förvalen.</translation>
+ </message>
+ <message>
+ <source>&amp;Reset Options</source>
+ <translation>&amp;Återställ alternativ</translation>
+ </message>
+ <message>
+ <source>&amp;Network</source>
+ <translation>&amp;Nätverk</translation>
+ </message>
+ <message>
+ <source>Automatically start Bitcoin Core after logging in to the system.</source>
+ <translation>Kör Bitcoin Core automatiskt vid systeminloggning.</translation>
+ </message>
+ <message>
+ <source>&amp;Start Bitcoin Core on system login</source>
+ <translation>&amp;Kör Bitcoin Core vid systeminloggning</translation>
+ </message>
+ <message>
+ <source>(0 = auto, &lt;0 = leave that many cores free)</source>
+ <translation>(0 = auto, &lt;0 = lämna så många kärnor lediga)</translation>
+ </message>
+ <message>
+ <source>W&amp;allet</source>
+ <translation>&amp;Plånbok</translation>
+ </message>
+ <message>
+ <source>Expert</source>
+ <translation>Expert</translation>
+ </message>
+ <message>
+ <source>Enable coin &amp;control features</source>
+ <translation>Aktivera mynt&amp;kontrollfunktioner</translation>
+ </message>
+ <message>
+ <source>If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.</source>
+ <translation>Om du avaktiverar betalning med obekräftad växel, kan inte växeln från en transaktion användas förrän den transaktionen har minst en bekräftelse.</translation>
+ </message>
+ <message>
+ <source>&amp;Spend unconfirmed change</source>
+ <translation>&amp;Spendera obekräftad växel</translation>
+ </message>
+ <message>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>Öppna automatiskt Bitcoin-klientens port på routern. Detta fungerar endast om din router har UPnP aktiverat.</translation>
+ </message>
+ <message>
+ <source>Map port using &amp;UPnP</source>
+ <translation>Tilldela port med hjälp av &amp;UPnP</translation>
+ </message>
+ <message>
+ <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
+ <translation>Anslut till Bitcoin-nätverket genom en SOCKS5-proxy.</translation>
+ </message>
+ <message>
+ <source>&amp;Connect through SOCKS5 proxy (default proxy):</source>
+ <translation>&amp;Anslut genom SOCKS5-proxy (förvald proxy):</translation>
+ </message>
+ <message>
+ <source>Proxy &amp;IP:</source>
+ <translation>Proxy-&amp;IP: </translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>&amp;Port: </translation>
+ </message>
+ <message>
+ <source>Port of the proxy (e.g. 9050)</source>
+ <translation>Proxyns port (t.ex. 9050)</translation>
+ </message>
+ <message>
+ <source>&amp;Window</source>
+ <translation>&amp;Fönster</translation>
+ </message>
+ <message>
+ <source>Show only a tray icon after minimizing the window.</source>
+ <translation>Visa endast en systemfältsikon vid minimering.</translation>
+ </message>
+ <message>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>&amp;Minimera till systemfältet istället för aktivitetsfältet</translation>
+ </message>
+ <message>
+ <source>M&amp;inimize on close</source>
+ <translation>M&amp;inimera vid stängning</translation>
+ </message>
+ <message>
+ <source>&amp;Display</source>
+ <translation>&amp;Visa</translation>
+ </message>
+ <message>
+ <source>User Interface &amp;language:</source>
+ <translation>Användargränssnittets &amp;språk: </translation>
+ </message>
+ <message>
+ <source>&amp;Unit to show amounts in:</source>
+ <translation>&amp;Måttenhet att visa belopp i: </translation>
+ </message>
+ <message>
+ <source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
+ <translation>Välj en måttenhet att visa i gränssnittet och när du skickar mynt.</translation>
+ </message>
+ <message>
+ <source>Whether to show coin control features or not.</source>
+ <translation>Om myntkontrollfunktioner skall visas eller inte</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>&amp;OK</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>&amp;Avbryt</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>standard</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>ingen</translation>
+ </message>
+ <message>
+ <source>Confirm options reset</source>
+ <translation>Bekräfta att alternativen ska återställs</translation>
+ </message>
+ <message>
+ <source>Client restart required to activate changes.</source>
+ <translation>Klientomstart är nödvändig för att aktivera ändringarna.</translation>
+ </message>
+ <message>
+ <source>Client will be shut down. Do you want to proceed?</source>
+ <translation>Programmet kommer att stängas. Vill du fortsätta?</translation>
+ </message>
+ <message>
+ <source>This change would require a client restart.</source>
+ <translation>Denna ändring kräver en klientomstart.</translation>
+ </message>
+ <message>
+ <source>The supplied proxy address is invalid.</source>
+ <translation>Den angivna proxy-adressen är ogiltig.</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>Formulär</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>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.</translation>
+ </message>
+ <message>
+ <source>Watch-only:</source>
+ <translation>Granska-bara:</translation>
+ </message>
+ <message>
+ <source>Available:</source>
+ <translation>Tillgängligt:</translation>
+ </message>
+ <message>
+ <source>Your current spendable balance</source>
+ <translation>Ditt tillgängliga saldo</translation>
+ </message>
+ <message>
+ <source>Pending:</source>
+ <translation>Pågående:</translation>
+ </message>
+ <message>
+ <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source>
+ <translation>Totalt antal transaktioner som ännu inte bekräftats, och som ännu inte räknas med i aktuellt saldo</translation>
+ </message>
+ <message>
+ <source>Immature:</source>
+ <translation>Omogen:</translation>
+ </message>
+ <message>
+ <source>Mined balance that has not yet matured</source>
+ <translation>Den genererade balansen som ännu inte har mognat</translation>
+ </message>
+ <message>
+ <source>Balances</source>
+ <translation>Balanser</translation>
+ </message>
+ <message>
+ <source>Total:</source>
+ <translation>Totalt:</translation>
+ </message>
+ <message>
+ <source>Your current total balance</source>
+ <translation>Ditt nuvarande totala saldo</translation>
+ </message>
+ <message>
+ <source>Your current balance in watch-only addresses</source>
+ <translation>Ditt nuvarande saldo i granska-bara adresser</translation>
+ </message>
+ <message>
+ <source>Spendable:</source>
+ <translation>Spenderbar:</translation>
+ </message>
+ <message>
+ <source>Recent transactions</source>
+ <translation>Nyligen genomförda transaktioner</translation>
+ </message>
+ <message>
+ <source>Unconfirmed transactions to watch-only addresses</source>
+ <translation>Okonfirmerade transaktioner till granska-bara adresser</translation>
+ </message>
+ <message>
+ <source>Mined balance in watch-only addresses that has not yet matured</source>
+ <translation>Den genererade balansen i granska-bara adresser som ännu inte har mognat</translation>
+ </message>
+ <message>
+ <source>Current total balance in watch-only addresses</source>
+ <translation>Nuvarande total balans i granska-bara adresser</translation>
+ </message>
+</context>
+<context>
+ <name>PaymentServer</name>
+ <message>
+ <source>URI handling</source>
+ <translation>URI hantering</translation>
+ </message>
+ <message>
+ <source>Invalid payment address %1</source>
+ <translation>Felaktig betalningsadress %1</translation>
+ </message>
+ <message>
+ <source>Payment request rejected</source>
+ <translation>Betalningsbegäran avslogs</translation>
+ </message>
+ <message>
+ <source>Payment request network doesn't match client network.</source>
+ <translation>Betalningsbegärans nätverk matchar inte klientens nätverk.</translation>
+ </message>
+ <message>
+ <source>Payment request is not initialized.</source>
+ <translation>Betalningsbegäran är inte initierad.</translation>
+ </message>
+ <message>
+ <source>Requested payment amount of %1 is too small (considered dust).</source>
+ <translation>Begärd betalning av %1 är för liten (betraktas som damm).</translation>
+ </message>
+ <message>
+ <source>Payment request error</source>
+ <translation>Fel vid betalningsbegäran</translation>
+ </message>
+ <message>
+ <source>Cannot start bitcoin: click-to-pay handler</source>
+ <translation>Kan inte starta bitcoin: klicka-och-betala handhavare</translation>
+ </message>
+ <message>
+ <source>Payment request fetch URL is invalid: %1</source>
+ <translation>Betalningsbegärans hämta URL är felaktig: %1</translation>
+ </message>
+ <message>
+ <source>URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source>
+ <translation>URI går inte att tolkas! Detta kan orsakas av en ogiltig Bitcoin-adress eller felaktiga URI parametrar.</translation>
+ </message>
+ <message>
+ <source>Payment request file handling</source>
+ <translation>Hantering av betalningsbegäransfil</translation>
+ </message>
+ <message>
+ <source>Payment request file cannot be read! This can be caused by an invalid payment request file.</source>
+ <translation>Betalningsbegäransfilen kan inte läsas! Detta kan orsakas av en felaktig betalningsbegäransfil.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>Betalningsbegäran löpte ut.</translation>
+ </message>
+ <message>
+ <source>Unverified payment requests to custom payment scripts are unsupported.</source>
+ <translation>Overifierade betalningsbegärningar till specialbetalningsskript stöds inte.</translation>
+ </message>
+ <message>
+ <source>Invalid payment request.</source>
+ <translation>Ogiltig betalningsbegäran.</translation>
+ </message>
+ <message>
+ <source>Refund from %1</source>
+ <translation>Återbetalning från %1</translation>
+ </message>
+ <message>
+ <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source>
+ <translation>Betalningsbegäran %1 är för stor (%2 bytes, tillåten %3 bytes)</translation>
+ </message>
+ <message>
+ <source>Payment request DoS protection</source>
+ <translation>Betalningsbegäran begär DoS-skydd</translation>
+ </message>
+ <message>
+ <source>Error communicating with %1: %2</source>
+ <translation>Kommunikationsfel med %1: %2</translation>
+ </message>
+ <message>
+ <source>Payment request cannot be parsed!</source>
+ <translation>Betalningsbegäran kan inte behandlas!</translation>
+ </message>
+ <message>
+ <source>Bad response from server %1</source>
+ <translation>Dåligt svar från server %1</translation>
+ </message>
+ <message>
+ <source>Payment acknowledged</source>
+ <translation>Betalningen bekräftad</translation>
+ </message>
+ <message>
+ <source>Network request error</source>
+ <translation>Fel vid närverksbegäran</translation>
+ </message>
+</context>
+<context>
+ <name>PeerTableModel</name>
+ <message>
+ <source>User Agent</source>
+ <translation>Användaragent</translation>
+ </message>
+ <message>
+ <source>Node/Service</source>
+ <translation>Nod/Tjänst</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Pingtid</translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>Mängd</translation>
+ </message>
+ <message>
+ <source>Enter a Bitcoin address (e.g. %1)</source>
+ <translation>Ange en Bitcoin-adress (t.ex. %1)</translation>
+ </message>
+ <message>
+ <source>%1 d</source>
+ <translation>%1 d</translation>
+ </message>
+ <message>
+ <source>%1 h</source>
+ <translation>%1 h</translation>
+ </message>
+ <message>
+ <source>%1 m</source>
+ <translation>%1 m</translation>
+ </message>
+ <message>
+ <source>%1 s</source>
+ <translation>%1 s</translation>
+ </message>
+ <message>
+ <source>None</source>
+ <translation>Ingen</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>ej tillgänglig</translation>
+ </message>
+ <message>
+ <source>%1 ms</source>
+ <translation>%1 ms</translation>
+ </message>
+</context>
+<context>
+ <name>QRImageWidget</name>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Spara Bild...</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Image</source>
+ <translation>&amp;Kopiera Bild</translation>
+ </message>
+ <message>
+ <source>Save QR Code</source>
+ <translation>Spara QR-kod</translation>
+ </message>
+ <message>
+ <source>PNG Image (*.png)</source>
+ <translation>PNG-bild (*.png)</translation>
+ </message>
+</context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>Client name</source>
+ <translation>Klientnamn</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>ej tillgänglig</translation>
+ </message>
+ <message>
+ <source>Client version</source>
+ <translation>Klient-version</translation>
+ </message>
+ <message>
+ <source>&amp;Information</source>
+ <translation>&amp;Information</translation>
+ </message>
+ <message>
+ <source>Debug window</source>
+ <translation>Debug fönster</translation>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>Generell</translation>
+ </message>
+ <message>
+ <source>Using OpenSSL version</source>
+ <translation>Använder OpenSSL version</translation>
+ </message>
+ <message>
+ <source>Using BerkeleyDB version</source>
+ <translation>Använder BerkeleyDB versionen</translation>
+ </message>
+ <message>
+ <source>Startup time</source>
+ <translation>Uppstartstid</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Nätverk</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>Namn</translation>
+ </message>
+ <message>
+ <source>Number of connections</source>
+ <translation>Antalet anslutningar</translation>
+ </message>
+ <message>
+ <source>Block chain</source>
+ <translation>Blockkedja</translation>
+ </message>
+ <message>
+ <source>Current number of blocks</source>
+ <translation>Aktuellt antal block</translation>
+ </message>
+ <message>
+ <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source>
+ <translation>Öppna felsökningsloggfilen för Bitcoin Core från den nuvarande datakatalogen. Detta kan ta några sekunder om loggfilen är stor.</translation>
+ </message>
+ <message>
+ <source>Received</source>
+ <translation>Mottagen</translation>
+ </message>
+ <message>
+ <source>Sent</source>
+ <translation>Skickad</translation>
+ </message>
+ <message>
+ <source>&amp;Peers</source>
+ <translation>&amp;Klienter</translation>
+ </message>
+ <message>
+ <source>Select a peer to view detailed information.</source>
+ <translation>Välj en klient för att se detaljerad information.</translation>
+ </message>
+ <message>
+ <source>Direction</source>
+ <translation>Riktning</translation>
+ </message>
+ <message>
+ <source>Version</source>
+ <translation>Version</translation>
+ </message>
+ <message>
+ <source>User Agent</source>
+ <translation>Användaragent</translation>
+ </message>
+ <message>
+ <source>Services</source>
+ <translation>Tjänster</translation>
+ </message>
+ <message>
+ <source>Starting Height</source>
+ <translation>Starthöjd</translation>
+ </message>
+ <message>
+ <source>Sync Height</source>
+ <translation>Synchöjd</translation>
+ </message>
+ <message>
+ <source>Ban Score</source>
+ <translation>Banpoäng</translation>
+ </message>
+ <message>
+ <source>Connection Time</source>
+ <translation>Anslutningstid</translation>
+ </message>
+ <message>
+ <source>Last Send</source>
+ <translation>Senast sänt</translation>
+ </message>
+ <message>
+ <source>Last Receive</source>
+ <translation>Senast mottagen</translation>
+ </message>
+ <message>
+ <source>Bytes Sent</source>
+ <translation>Bytes sänt</translation>
+ </message>
+ <message>
+ <source>Bytes Received</source>
+ <translation>Bytes mottaget</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Pingtid</translation>
+ </message>
+ <message>
+ <source>Time Offset</source>
+ <translation>Tidsförskjutning</translation>
+ </message>
+ <message>
+ <source>Last block time</source>
+ <translation>Sista blocktid</translation>
+ </message>
+ <message>
+ <source>&amp;Open</source>
+ <translation>&amp;Öppna</translation>
+ </message>
+ <message>
+ <source>&amp;Console</source>
+ <translation>&amp;Konsol</translation>
+ </message>
+ <message>
+ <source>&amp;Network Traffic</source>
+ <translation>&amp;Nätverkstrafik</translation>
+ </message>
+ <message>
+ <source>&amp;Clear</source>
+ <translation>&amp;Rensa</translation>
+ </message>
+ <message>
+ <source>Totals</source>
+ <translation>Totalt:</translation>
+ </message>
+ <message>
+ <source>In:</source>
+ <translation>In:</translation>
+ </message>
+ <message>
+ <source>Out:</source>
+ <translation>Ut:</translation>
+ </message>
+ <message>
+ <source>Build date</source>
+ <translation>Kompileringsdatum</translation>
+ </message>
+ <message>
+ <source>Debug log file</source>
+ <translation>Debugloggfil</translation>
+ </message>
+ <message>
+ <source>Clear console</source>
+ <translation>Rensa konsollen</translation>
+ </message>
+ <message>
+ <source>Welcome to the Bitcoin Core RPC console.</source>
+ <translation>Välkommen till RPC-konsolen för Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
+ <translation>Använd upp- och ner-pilarna för att navigera i historiken, och &lt;b&gt;Ctrl-L&lt;/b&gt; för att rensa skärmen.</translation>
+ </message>
+ <message>
+ <source>Type &lt;b&gt;help&lt;/b&gt; for an overview of available commands.</source>
+ <translation>Skriv &lt;b&gt;help&lt;/b&gt; för en översikt av alla kommandon.</translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation>%1 B</translation>
+ </message>
+ <message>
+ <source>%1 KB</source>
+ <translation>%1 KB</translation>
+ </message>
+ <message>
+ <source>%1 MB</source>
+ <translation>%1 MB</translation>
+ </message>
+ <message>
+ <source>%1 GB</source>
+ <translation>%1 GB</translation>
+ </message>
+ <message>
+ <source>via %1</source>
+ <translation>via %1</translation>
+ </message>
+ <message>
+ <source>never</source>
+ <translation>aldrig</translation>
+ </message>
+ <message>
+ <source>Inbound</source>
+ <translation>Inkommande</translation>
+ </message>
+ <message>
+ <source>Outbound</source>
+ <translation>Utgående</translation>
+ </message>
+ <message>
+ <source>Unknown</source>
+ <translation>Okänd</translation>
+ </message>
+ <message>
+ <source>Fetching...</source>
+ <translation>Hämtar...</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Etikett:</translation>
+ </message>
+ <message>
+ <source>&amp;Message:</source>
+ <translation>&amp;Meddelande:</translation>
+ </message>
+ <message>
+ <source>Reuse one of the previously used receiving addresses. Reusing addresses has security and privacy issues. Do not use this unless re-generating a payment request made before.</source>
+ <translation>Återanvänd en av tidigare använda mottagningsadresser. Återanvändning av adresser har både säkerhets och integritetsbrister. Använd inte samma mottagningsadress om du inte gör om samma betalningsbegäran.</translation>
+ </message>
+ <message>
+ <source>R&amp;euse an existing receiving address (not recommended)</source>
+ <translation>Åt&amp;eranvänd en existerande mottagningsadress (rekommenderas inte)</translation>
+ </message>
+ <message>
+ <source>An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network.</source>
+ <translation>Ett frivilligt meddelande att bifoga betalningsbegäran, vilket visas när begäran öppnas. NB: Meddelandet kommer inte att sändas med betalningen över Bitcoinnätverket.</translation>
+ </message>
+ <message>
+ <source>An optional label to associate with the new receiving address.</source>
+ <translation>En frivillig etikett att associera med den nya mottagningsadressen.</translation>
+ </message>
+ <message>
+ <source>Use this form to request payments. All fields are &lt;b&gt;optional&lt;/b&gt;.</source>
+ <translation>Använd detta formulär för att begära betalningar. Alla fält är &lt;b&gt;frivilliga&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>An optional amount to request. Leave this empty or zero to not request a specific amount.</source>
+ <translation>En valfri summa att begära. Lämna denna tom eller noll för att inte begära en specifik summa.</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Rensa alla formulärfälten</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation>Rensa</translation>
+ </message>
+ <message>
+ <source>Requested payments history</source>
+ <translation>Historik för begärda betalningar</translation>
+ </message>
+ <message>
+ <source>&amp;Request payment</source>
+ <translation>Begä&amp;r betalning</translation>
+ </message>
+ <message>
+ <source>Show the selected request (does the same as double clicking an entry)</source>
+ <translation>Visa valda begäranden (gör samma som att dubbelklicka på en post)</translation>
+ </message>
+ <message>
+ <source>Show</source>
+ <translation>Visa</translation>
+ </message>
+ <message>
+ <source>Remove the selected entries from the list</source>
+ <translation>Ta bort valda poster från listan</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>Ta bort</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Kopiera etikett</translation>
+ </message>
+ <message>
+ <source>Copy message</source>
+ <translation>Kopiera meddelande</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopiera belopp</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>QR Code</source>
+ <translation>QR-kod</translation>
+ </message>
+ <message>
+ <source>Copy &amp;URI</source>
+ <translation>Kopiera &amp;URI</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Address</source>
+ <translation>Kopiera &amp;Adress</translation>
+ </message>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Spara Bild...</translation>
+ </message>
+ <message>
+ <source>Request payment to %1</source>
+ <translation>Begär betalning till %1</translation>
+ </message>
+ <message>
+ <source>Payment information</source>
+ <translation>Betalningsinformation</translation>
+ </message>
+ <message>
+ <source>URI</source>
+ <translation>URI</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adress</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Mängd</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etikett</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Meddelande</translation>
+ </message>
+ <message>
+ <source>Resulting URI too long, try to reduce the text for label / message.</source>
+ <translation>URI:n är för lång, försöka minska texten för etikett / meddelande.</translation>
+ </message>
+ <message>
+ <source>Error encoding URI into QR Code.</source>
+ <translation>Fel vid skapande av QR-kod från URI.</translation>
+ </message>
+</context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Datum</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etikett</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Meddelande</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Mängd</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(Ingen etikett)</translation>
+ </message>
+ <message>
+ <source>(no message)</source>
+ <translation>(inget meddelande)</translation>
+ </message>
+ <message>
+ <source>(no amount)</source>
+ <translation>(ingen summa)</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Skicka pengar</translation>
+ </message>
+ <message>
+ <source>Coin Control Features</source>
+ <translation>Myntkontrollfunktioner</translation>
+ </message>
+ <message>
+ <source>Inputs...</source>
+ <translation>Inmatningar...</translation>
+ </message>
+ <message>
+ <source>automatically selected</source>
+ <translation>automatiskt vald</translation>
+ </message>
+ <message>
+ <source>Insufficient funds!</source>
+ <translation>Otillräckliga medel!</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Kvantitet:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Antal Byte:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Belopp:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Prioritet:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Avgift:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Efter avgift:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Växel:</translation>
+ </message>
+ <message>
+ <source>If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address.</source>
+ <translation>Om denna är aktiverad men växeladressen är tom eller felaktig kommer växeln att sändas till en nygenererad adress.</translation>
+ </message>
+ <message>
+ <source>Custom change address</source>
+ <translation>Specialväxeladress</translation>
+ </message>
+ <message>
+ <source>Transaction Fee:</source>
+ <translation>Transaktionsavgift:</translation>
+ </message>
+ <message>
+ <source>Choose...</source>
+ <translation>Välj...</translation>
+ </message>
+ <message>
+ <source>collapse fee-settings</source>
+ <translation>Fäll ihop avgiftsinställningarna</translation>
+ </message>
+ <message>
+ <source>per kilobyte</source>
+ <translation>per kilobyte</translation>
+ </message>
+ <message>
+ <source>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "total at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source>
+ <translation>Om den anpassad avgiften är satt till 1000 satoshi och transaktionen bara är 250 byte, betalar "per kilobyte" bara 250 satoshi i avgift, medans "totalt minst" betalar 1000 satoshi. För transaktioner större än en kilobyte betalar både per kilobyte.</translation>
+ </message>
+ <message>
+ <source>Hide</source>
+ <translation>Göm</translation>
+ </message>
+ <message>
+ <source>total at least</source>
+ <translation>totalt minst</translation>
+ </message>
+ <message>
+ <source>Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process.</source>
+ <translation>Att betala endast den minsta avgiften är bara bra så länge det är mindre transaktionsvolym än utrymme i blocken. Men tänk på att det kan hamna i en aldrig bekräftar transaktion när det finns mer efterfrågan på bitcoin transaktioner än nätverket kan bearbeta.</translation>
+ </message>
+ <message>
+ <source>(read the tooltip)</source>
+ <translation>(läs verktygstips)</translation>
+ </message>
+ <message>
+ <source>Recommended:</source>
+ <translation>Rekommenderad:</translation>
+ </message>
+ <message>
+ <source>Custom:</source>
+ <translation>Anpassad:</translation>
+ </message>
+ <message>
+ <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source>
+ <translation>(Smartavgiften är inte initierad än. Detta tar vanligen några block...)</translation>
+ </message>
+ <message>
+ <source>Confirmation time:</source>
+ <translation>Bekräftelsetid:</translation>
+ </message>
+ <message>
+ <source>normal</source>
+ <translation>normal</translation>
+ </message>
+ <message>
+ <source>fast</source>
+ <translation>snabb</translation>
+ </message>
+ <message>
+ <source>Send as zero-fee transaction if possible</source>
+ <translation>Sänd som nollavgiftstransaktion om möjligt</translation>
+ </message>
+ <message>
+ <source>(confirmation may take longer)</source>
+ <translation>(bekräftelse kan ta längre tid)</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>Skicka till flera mottagare samtidigt</translation>
+ </message>
+ <message>
+ <source>Add &amp;Recipient</source>
+ <translation>Lägg till &amp;mottagare</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Rensa alla formulärfälten</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Damm:</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Rensa &amp;alla</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>Balans:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>Bekräfta sändordern</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>&amp;Skicka</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>Bekräfta skickade mynt</translation>
+ </message>
+ <message>
+ <source>%1 to %2</source>
+ <translation>%1 till %2</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Kopiera kvantitet</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopiera belopp</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Kopiera avgift</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Kopiera efter avgift</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Kopiera byte</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Kopiera prioritet</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Kopiera växel</translation>
+ </message>
+ <message>
+ <source>or</source>
+ <translation>eller</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>Det betalade beloppet måste vara större än 0.</translation>
+ </message>
+ <message>
+ <source>The amount exceeds your balance.</source>
+ <translation>Värdet överstiger ditt saldo.</translation>
+ </message>
+ <message>
+ <source>The total exceeds your balance when the %1 transaction fee is included.</source>
+ <translation>Totalvärdet överstiger ditt saldo när transaktionsavgiften %1 är pålagd.</translation>
+ </message>
+ <message>
+ <source>Transaction creation failed!</source>
+ <translation>Transaktionen gick inte att skapa!</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>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 spenderade här.</translation>
+ </message>
+ <message>
+ <source>A fee higher than %1 is considered an absurdly high fee.</source>
+ <translation>En avgift som är högre än %1 anses vara en orimligt hög avgift.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>Betalningsbegäran löpte ut.</translation>
+ </message>
+ <message numerus="yes">
+ <source>Estimated to begin confirmation within %n block(s).</source>
+ <translation><numerusform>Uppskattas till att påbörja bekräftelse inom %n block.</numerusform><numerusform>Uppskattas till att påbörja bekräftelse inom %n block.</numerusform></translation>
+ </message>
+ <message>
+ <source>Pay only the minimum fee of %1</source>
+ <translation>Betala endast den minimala avgiften på %1</translation>
+ </message>
+ <message>
+ <source>Total Amount %1&lt;span style='font-size:10pt;font-weight:normal;'&gt;&lt;br /&gt;(=%2)&lt;/span&gt;</source>
+ <translation>Total summa %1&lt;span style='font-size:10pt;font-weight:normal;'&gt;&lt;br /&gt;(=%2)&lt;/span&gt;</translation>
+ </message>
+ <message>
+ <source>The recipient address is not valid. Please recheck.</source>
+ <translation>Mottagarens adress är ogiltig. Kontrollera igen.</translation>
+ </message>
+ <message>
+ <source>Duplicate address found: addresses should only be used once each.</source>
+ <translation>Duplicerad adress upptäckt: adresser skall endast användas en gång var.</translation>
+ </message>
+ <message>
+ <source>Warning: Invalid Bitcoin address</source>
+ <translation>Varning: Felaktig Bitcoinadress</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(Ingen etikett)</translation>
+ </message>
+ <message>
+ <source>Warning: Unknown change address</source>
+ <translation>Varning: Okänd växeladress</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Kopiera damm</translation>
+ </message>
+ <message>
+ <source>Are you sure you want to send?</source>
+ <translation>Är du säker på att du vill skicka?</translation>
+ </message>
+ <message>
+ <source>added as transaction fee</source>
+ <translation>adderad som transaktionsavgift</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>&amp;Belopp:</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>Betala &amp;Till:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Ange ett namn för den här adressen och lägg till den i din adressbok</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Etikett:</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Välj tidigare använda adresser</translation>
+ </message>
+ <message>
+ <source>This is a normal payment.</source>
+ <translation>Detta är en normal betalning.</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to send the payment to</source>
+ <translation>Bitcoinadress att sända betalning till</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Klistra in adress från Urklipp</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Remove this entry</source>
+ <translation>Radera denna post</translation>
+ </message>
+ <message>
+ <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source>
+ <translation>Avgiften dras från beloppet som skickas. Mottagaren kommer att få mindre bitcoins än du angivit i belopp-fältet. Om flera mottagare valts kommer avgiften delas jämt.</translation>
+ </message>
+ <message>
+ <source>Message:</source>
+ <translation>Meddelande:</translation>
+ </message>
+ <message>
+ <source>This is an unauthenticated payment request.</source>
+ <translation>Detta är en oautentiserad betalningsbegäran.</translation>
+ </message>
+ <message>
+ <source>This is an authenticated payment request.</source>
+ <translation>Detta är en autentiserad betalningsbegäran.</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to the list of used addresses</source>
+ <translation>Ange en etikett för denna adress att adderas till listan över använda adresser</translation>
+ </message>
+ <message>
+ <source>A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network.</source>
+ <translation>Ett meddelande som bifogades bitcoin-URI, vilket lagras med transaktionen som referens. NB: Meddelandet kommer inte att sändas över Bitcoinnätverket.</translation>
+ </message>
+ <message>
+ <source>Pay To:</source>
+ <translation>Betala Till:</translation>
+ </message>
+ <message>
+ <source>Memo:</source>
+ <translation>PM:</translation>
+ </message>
+</context>
+<context>
+ <name>ShutdownWindow</name>
+ <message>
+ <source>Bitcoin Core is shutting down...</source>
+ <translation>Bitcoin Core stängs av...</translation>
+ </message>
+ <message>
+ <source>Do not shut down the computer until this window disappears.</source>
+ <translation>Stäng inte av datorn förrän denna ruta försvinner.</translation>
+ </message>
+</context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Signatures - Sign / Verify a Message</source>
+ <translation>Signaturer - Signera / Verifiera ett Meddelande</translation>
+ </message>
+ <message>
+ <source>&amp;Sign Message</source>
+ <translation>&amp;Signera Meddelande</translation>
+ </message>
+ <message>
+ <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source>
+ <translation>Du kan underteckna meddelanden/avtal med dina adresser för att bevisa att du kan ta emot bitcoins som skickats till dem. Var försiktig så du inte undertecknar något oklart eller konstigt, eftersom phishing-angrepp kan försöka få dig att underteckna din identitet till dem. Underteckna endast väldetaljerade meddelanden som du godkänner.</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to sign the message with</source>
+ <translation>Bitcoinadress att signera meddelandet med</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Välj tidigare använda adresser</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Klistra in adress från Urklipp</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Enter the message you want to sign here</source>
+ <translation>Skriv in meddelandet du vill signera här</translation>
+ </message>
+ <message>
+ <source>Signature</source>
+ <translation>Signatur</translation>
+ </message>
+ <message>
+ <source>Copy the current signature to the system clipboard</source>
+ <translation>Kopiera signaturen till systemets Urklipp</translation>
+ </message>
+ <message>
+ <source>Sign the message to prove you own this Bitcoin address</source>
+ <translation>Signera meddelandet för att bevisa att du äger denna adress</translation>
+ </message>
+ <message>
+ <source>Sign &amp;Message</source>
+ <translation>Signera &amp;Meddelande</translation>
+ </message>
+ <message>
+ <source>Reset all sign message fields</source>
+ <translation>Rensa alla fält</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Rensa &amp;alla</translation>
+ </message>
+ <message>
+ <source>&amp;Verify Message</source>
+ <translation>&amp;Verifiera Meddelande</translation>
+ </message>
+ <message>
+ <source>Enter the receiver's 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. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source>
+ <translation>Ange mottagarens adress, meddelande (kopiera radbrytningar, mellanrum, flikar, etc. exakt) och signatur nedan för att verifiera meddelandet. Undvik att läsa in mera information i signaturen än vad som stod i själva undertecknade meddelandet, för att undvika ett man-in-the-middle-angrepp. Notera att detta endast bevisar att undertecknad tar emot med adressen, det bevisar inte vem som skickat transaktionen!</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address the message was signed with</source>
+ <translation>Bitcoinadressen som meddelandet signerades med</translation>
+ </message>
+ <message>
+ <source>Verify the message to ensure it was signed with the specified Bitcoin address</source>
+ <translation>Verifiera meddelandet för att vara säker på att den var signerad med den angivna Bitcoin-adressen</translation>
+ </message>
+ <message>
+ <source>Verify &amp;Message</source>
+ <translation>Verifiera &amp;Meddelande</translation>
+ </message>
+ <message>
+ <source>Reset all verify message fields</source>
+ <translation>Rensa alla fält</translation>
+ </message>
+ <message>
+ <source>Click "Sign Message" to generate signature</source>
+ <translation>Klicka "Signera Meddelande" för att få en signatur</translation>
+ </message>
+ <message>
+ <source>The entered address is invalid.</source>
+ <translation>Den angivna adressen är ogiltig.</translation>
+ </message>
+ <message>
+ <source>Please check the address and try again.</source>
+ <translation>Vad god kontrollera adressen och försök igen.</translation>
+ </message>
+ <message>
+ <source>The entered address does not refer to a key.</source>
+ <translation>Den angivna adressen refererar inte till en nyckel.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock was cancelled.</source>
+ <translation>Upplåsningen av plånboken avbröts.</translation>
+ </message>
+ <message>
+ <source>Private key for the entered address is not available.</source>
+ <translation>Privata nyckel för den angivna adressen är inte tillgänglig.</translation>
+ </message>
+ <message>
+ <source>Message signing failed.</source>
+ <translation>Signeringen av meddelandet misslyckades.</translation>
+ </message>
+ <message>
+ <source>Message signed.</source>
+ <translation>Meddelandet är signerat.</translation>
+ </message>
+ <message>
+ <source>The signature could not be decoded.</source>
+ <translation>Signaturen kunde inte avkodas.</translation>
+ </message>
+ <message>
+ <source>Please check the signature and try again.</source>
+ <translation>Kontrollera signaturen och försök igen.</translation>
+ </message>
+ <message>
+ <source>The signature did not match the message digest.</source>
+ <translation>Signaturen matchade inte meddelandesammanfattningen.</translation>
+ </message>
+ <message>
+ <source>Message verification failed.</source>
+ <translation>Meddelandet verifikation misslyckades.</translation>
+ </message>
+ <message>
+ <source>Message verified.</source>
+ <translation>Meddelandet är verifierad.</translation>
+ </message>
+</context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Kärna</translation>
+ </message>
+ <message>
+ <source>The Bitcoin Core developers</source>
+ <translation>Bitcoin Core-utvecklarna</translation>
+ </message>
+ <message>
+ <source>[testnet]</source>
+ <translation>[testnet]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ <message>
+ <source>KB/s</source>
+ <translation>KB/s</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>Öppet till %1</translation>
+ </message>
+ <message>
+ <source>conflicted</source>
+ <translation>konflikterade</translation>
+ </message>
+ <message>
+ <source>%1/offline</source>
+ <translation>%1/nerkopplad</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/obekräftade</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 bekräftelser</translation>
+ </message>
+ <message>
+ <source>Status</source>
+ <translation>Status</translation>
+ </message>
+ <message numerus="yes">
+ <source>, broadcast through %n node(s)</source>
+ <translation><numerusform>, sänd genom %n nod</numerusform><numerusform>, sänd genom %n noder</numerusform></translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Datum</translation>
+ </message>
+ <message>
+ <source>Source</source>
+ <translation>Källa</translation>
+ </message>
+ <message>
+ <source>Generated</source>
+ <translation>Genererad</translation>
+ </message>
+ <message>
+ <source>From</source>
+ <translation>Från</translation>
+ </message>
+ <message>
+ <source>To</source>
+ <translation>Till</translation>
+ </message>
+ <message>
+ <source>own address</source>
+ <translation>egen adress</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>granska-bara</translation>
+ </message>
+ <message>
+ <source>label</source>
+ <translation>etikett</translation>
+ </message>
+ <message>
+ <source>Credit</source>
+ <translation>Kredit</translation>
+ </message>
+ <message numerus="yes">
+ <source>matures in %n more block(s)</source>
+ <translation><numerusform>mognar om %n fler block</numerusform><numerusform>mognar om %n fler block</numerusform></translation>
+ </message>
+ <message>
+ <source>not accepted</source>
+ <translation>inte accepterad</translation>
+ </message>
+ <message>
+ <source>Debit</source>
+ <translation>Belasta</translation>
+ </message>
+ <message>
+ <source>Total debit</source>
+ <translation>Total skuld</translation>
+ </message>
+ <message>
+ <source>Total credit</source>
+ <translation>Total kredit</translation>
+ </message>
+ <message>
+ <source>Transaction fee</source>
+ <translation>Transaktionsavgift</translation>
+ </message>
+ <message>
+ <source>Net amount</source>
+ <translation>Nettobelopp</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Meddelande</translation>
+ </message>
+ <message>
+ <source>Comment</source>
+ <translation>Kommentar</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>Transaktions-ID</translation>
+ </message>
+ <message>
+ <source>Merchant</source>
+ <translation>Handlare</translation>
+ </message>
+ <message>
+ <source>Generated coins must mature %1 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.</source>
+ <translation>Genererade mynt måste vänta %1 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 dess status 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.</translation>
+ </message>
+ <message>
+ <source>Debug information</source>
+ <translation>Debug information</translation>
+ </message>
+ <message>
+ <source>Transaction</source>
+ <translation>Transaktion</translation>
+ </message>
+ <message>
+ <source>Inputs</source>
+ <translation>Inputs</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Mängd</translation>
+ </message>
+ <message>
+ <source>true</source>
+ <translation>sant</translation>
+ </message>
+ <message>
+ <source>false</source>
+ <translation>falsk</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, har inte lyckats skickas ännu</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Öppet för %n mer block</numerusform><numerusform>Öppet för %n mer block</numerusform></translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>okänd</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>Transaktionsdetaljer</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>Den här panelen visar en detaljerad beskrivning av transaktionen</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Datum</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Typ</translation>
+ </message>
+ <message>
+ <source>Immature (%1 confirmations, will be available after %2)</source>
+ <translation>Omogen (%1 konfirmeringar, blir tillgänglig efter %2)</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Öppet för %n mer block</numerusform><numerusform>Öppet för %n mer block</numerusform></translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>Öppet till %1</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>Bekräftad (%1 bekräftelser)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>Det här blocket togs inte emot av några andra noder och kommer antagligen inte att bli godkänt.</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>Genererad men inte accepterad</translation>
+ </message>
+ <message>
+ <source>Offline</source>
+ <translation>Nerkopplad</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etikett</translation>
+ </message>
+ <message>
+ <source>Unconfirmed</source>
+ <translation>Okonfirmerade</translation>
+ </message>
+ <message>
+ <source>Confirming (%1 of %2 recommended confirmations)</source>
+ <translation>Konfirmerar (%1 of %2 konfirmeringar)</translation>
+ </message>
+ <message>
+ <source>Conflicted</source>
+ <translation>Konflikterade</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Mottagen med</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>Mottaget från</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Skickad till</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>Betalning till dig själv</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Genererade</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>granska-bara</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(n/a)</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>Transaktionsstatus. Håll muspekaren över för att se antal bekräftelser.</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Tidpunkt då transaktionen mottogs.</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>Transaktionstyp.</translation>
+ </message>
+ <message>
+ <source>Whether or not a watch-only address is involved in this transaction.</source>
+ <translation>Anger om granska-bara--adresser är involverade i denna transaktion.</translation>
+ </message>
+ <message>
+ <source>User-defined intent/purpose of the transaction.</source>
+ <translation>Användardefinierat syfte/ändamål för transaktionen.</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>Belopp draget eller tillagt till balans.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>Alla</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>Idag</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>Denna vecka</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>Denna månad</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>Föregående månad</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>Det här året</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>Period...</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Mottagen med</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Skickad till</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>Till dig själv</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Genererade</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>Övriga</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>Sök efter adress eller etikett </translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>Minsta mängd</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Kopiera adress</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Kopiera etikett</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Kopiera belopp</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Kopiera transaktions ID</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>Ändra etikett</translation>
+ </message>
+ <message>
+ <source>Show transaction details</source>
+ <translation>Visa transaktionsdetaljer</translation>
+ </message>
+ <message>
+ <source>Export Transaction History</source>
+ <translation>Exportera Transaktionshistoriken</translation>
+ </message>
+ <message>
+ <source>Watch-only</source>
+ <translation>Granska-bara</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Exporteringen misslyckades</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the transaction history to %1.</source>
+ <translation>Det inträffade ett fel när transaktionshistoriken skulle sparas till %1.</translation>
+ </message>
+ <message>
+ <source>Exporting Successful</source>
+ <translation>Exporteringen lyckades</translation>
+ </message>
+ <message>
+ <source>The transaction history was successfully saved to %1.</source>
+ <translation>Transaktionshistoriken sparades utan problem till %1.</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Kommaseparerad fil (*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Bekräftad</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Datum</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Typ</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etikett</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adress</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>Intervall:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>till</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ <message>
+ <source>Unit to show amounts in. Click to select another unit.</source>
+ <translation>&amp;Enhet att visa belopp i. Klicka för att välja annan enhet.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletFrame</name>
+ <message>
+ <source>No wallet has been loaded.</source>
+ <translation>Ingen plånbok har laddats in.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Skicka pengar</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Exportera</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Exportera informationen i den nuvarande fliken till en fil</translation>
+ </message>
+ <message>
+ <source>Backup Wallet</source>
+ <translation>Säkerhetskopiera Plånbok</translation>
+ </message>
+ <message>
+ <source>Wallet Data (*.dat)</source>
+ <translation>Plånboks-data (*.dat)</translation>
+ </message>
+ <message>
+ <source>Backup Failed</source>
+ <translation>Säkerhetskopiering misslyckades</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the wallet data to %1.</source>
+ <translation>Det inträffade ett fel när plånbokens data skulle sparas till %1.</translation>
+ </message>
+ <message>
+ <source>The wallet data was successfully saved to %1.</source>
+ <translation>Plånbokens data sparades utan problem till %1.</translation>
+ </message>
+ <message>
+ <source>Backup Successful</source>
+ <translation>Säkerhetskopiering lyckades</translation>
+ </message>
+</context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>Inställningar:</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>Ange katalog för data</translation>
+ </message>
+ <message>
+ <source>Connect to a node to retrieve peer addresses, and disconnect</source>
+ <translation>Anslut till en nod för att hämta klientadresser, och koppla från</translation>
+ </message>
+ <message>
+ <source>Specify your own public address</source>
+ <translation>Ange din egen publika adress</translation>
+ </message>
+ <message>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>Tillåt kommandon från kommandotolken och JSON-RPC-kommandon</translation>
+ </message>
+ <message>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>Kör i bakgrunden som tjänst och acceptera kommandon</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>Använd testnätverket</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
+ <translation>Acceptera anslutningar utifrån (förvalt: 1 om ingen -proxy eller -connect)</translation>
+ </message>
+ <message>
+ <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
+ <translation>Bind till given adress och lyssna alltid på den. Använd [värd]:port notation för IPv6</translation>
+ </message>
+ <message>
+ <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
+ <translation>Ta bort alla plånbokstransaktioner och återskapa bara dom som är en del av blockkedjan genom att ange -rescan vid uppstart</translation>
+ </message>
+ <message>
+ <source>Distributed under the MIT software license, see the accompanying file COPYING or &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</source>
+ <translation>Distribuerad under MIT mjukvarulicens, se den bifogade filen COPYING eller &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</translation>
+ </message>
+ <message>
+ <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
+ <translation>Exekvera kommando när en plånbokstransaktion ändras (%s i cmd är ersatt av TxID)</translation>
+ </message>
+ <message>
+ <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source>
+ <translation>Maximal total avgift att använda i en plånbokstransaktion. Sätts denna för lågt kommer stora transaktioner att avbrytas (förvalt: %s)</translation>
+ </message>
+ <message>
+ <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, &gt;%u = target size in MiB to use for block files)</source>
+ <translation>Reducera lagringsbehovet genom att beskära (ta bort) gamla block. Detta läge avaktiverar plånbokssupport och är inkompatibel med -txindex. Varning: Ändras denna inställning måste hela blockkedjan laddas ner igen. 0 = avaktivera beskärning av blocks, &gt;%u = målstorlek i MiB att använda för blockfiler)</translation>
+ </message>
+ <message>
+ <source>Set the number of script verification threads (%u to %d, 0 = auto, &lt;0 = leave that many cores free, default: %d)</source>
+ <translation>Ange antalet skriptkontrolltrådar (%u till %d, 0 = auto, &lt;0 = lämna så många kärnor lediga, förval: %d)</translation>
+ </message>
+ <message>
+ <source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source>
+ <translation>Detta är ett förhands testbygge - använd på egen risk - använd inte för mining eller handels applikationer</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer. Bitcoin Core is probably already running.</source>
+ <translation>Det går inte att binda till %s på den här datorn. Bitcoin Core är förmodligen redan igång.</translation>
+ </message>
+ <message>
+ <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>Varning: Onormalt antal block block genererade. %d block mottagna senaste %d timmarna (%d förväntade)</translation>
+ </message>
+ <message>
+ <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>Varning: Kontrollera din närverksanslutning. %d block mottagna senaste %d timmarna, (%d förväntade)</translation>
+ </message>
+ <message>
+ <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>Varning: -paytxfee är satt väldigt hög! Detta är avgiften du kommer betala för varje transaktion.</translation>
+ </message>
+ <message>
+ <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source>
+ <translation>Varning: Nätverket verkar inte vara helt överens! Några miners verkar ha problem.</translation>
+ </message>
+ <message>
+ <source>Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.</source>
+ <translation>Varning: Vi verkar inte helt överens med våra peers! Du kan behöva uppgradera, eller andra noder kan behöva uppgradera.</translation>
+ </message>
+ <message>
+ <source>Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
+ <translation>Varning: fel vid läsning av wallet.dat! Alla nycklar lästes korrekt, men transaktionsdatan eller adressbokens poster kanske saknas eller är felaktiga.</translation>
+ </message>
+ <message>
+ <source>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</source>
+ <translation>Varning: wallet.dat korrupt, datan har räddats! Den ursprungliga wallet.dat har sparas som wallet.{timestamp}.bak i %s; om ditt saldo eller transaktioner är felaktiga ska du återställa från en säkerhetskopia.</translation>
+ </message>
+ <message>
+ <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source>
+ <translation>Vitlista klienter som ansluter från angivna nätmasker eller IP-adresser. Kan specificeras flera gånger.</translation>
+ </message>
+ <message>
+ <source>(default: 1)</source>
+ <translation>(förvalt: 1)</translation>
+ </message>
+ <message>
+ <source>&lt;category&gt; can be:</source>
+ <translation>&lt;category&gt; Kan vara:</translation>
+ </message>
+ <message>
+ <source>Attempt to recover private keys from a corrupt wallet.dat</source>
+ <translation>Försök att rädda de privata nycklarna från en korrupt wallet.dat</translation>
+ </message>
+ <message>
+ <source>Block creation options:</source>
+ <translation>Block skapande inställningar:</translation>
+ </message>
+ <message>
+ <source>Connect only to the specified node(s)</source>
+ <translation>Koppla enbart upp till den/de specificerade noden/noder</translation>
+ </message>
+ <message>
+ <source>Connection options:</source>
+ <translation>Anslutningsoptioner:</translation>
+ </message>
+ <message>
+ <source>Corrupted block database detected</source>
+ <translation>Korrupt blockdatabas har upptäckts</translation>
+ </message>
+ <message>
+ <source>Debugging/Testing options:</source>
+ <translation>Avlusnings/Testnings optioner:</translation>
+ </message>
+ <message>
+ <source>Do not load the wallet and disable wallet RPC calls</source>
+ <translation>Ladda inte plånboken och stäng av RPC-anrop till plånboken</translation>
+ </message>
+ <message>
+ <source>Do you want to rebuild the block database now?</source>
+ <translation>Vill du bygga om blockdatabasen nu?</translation>
+ </message>
+ <message>
+ <source>Error initializing block database</source>
+ <translation>Fel vid initiering av blockdatabasen</translation>
+ </message>
+ <message>
+ <source>Error initializing wallet database environment %s!</source>
+ <translation>Fel vid initiering av plånbokens databasmiljö %s!</translation>
+ </message>
+ <message>
+ <source>Error loading block database</source>
+ <translation>Fel vid inläsning av blockdatabasen</translation>
+ </message>
+ <message>
+ <source>Error opening block database</source>
+ <translation>Fel vid öppning av blockdatabasen</translation>
+ </message>
+ <message>
+ <source>Error: Disk space is low!</source>
+ <translation>Fel: Hårddiskutrymme är lågt!</translation>
+ </message>
+ <message>
+ <source>Failed to listen on any port. Use -listen=0 if you want this.</source>
+ <translation>Misslyckades att lyssna på någon port. Använd -listen=0 om du vill detta.</translation>
+ </message>
+ <message>
+ <source>If &lt;category&gt; is not supplied, output all debugging information.</source>
+ <translation>Om &lt;category&gt; inte anges, skrivs all avlusningsinformation ut.</translation>
+ </message>
+ <message>
+ <source>Importing...</source>
+ <translation>Importerar...</translation>
+ </message>
+ <message>
+ <source>Incorrect or no genesis block found. Wrong datadir for network?</source>
+ <translation>Felaktig eller inget genesisblock hittades. Fel datadir för nätverket?</translation>
+ </message>
+ <message>
+ <source>Invalid -onion address: '%s'</source>
+ <translation>Ogiltig -onion adress:'%s'</translation>
+ </message>
+ <message>
+ <source>Not enough file descriptors available.</source>
+ <translation>Inte tillräckligt med filbeskrivningar tillgängliga.</translation>
+ </message>
+ <message>
+ <source>Only connect to nodes in network &lt;net&gt; (ipv4, ipv6 or onion)</source>
+ <translation>Anslut enbart till noder i nätverket &lt;net&gt; (IPv4, IPv6 eller onion)</translation>
+ </message>
+ <message>
+ <source>Prune cannot be configured with a negative value.</source>
+ <translation>Beskärning kan inte konfigureras med ett negativt värde.</translation>
+ </message>
+ <message>
+ <source>Prune mode is incompatible with -txindex.</source>
+ <translation>Beskärningsläge är inkompatibel med -txindex.</translation>
+ </message>
+ <message>
+ <source>Set database cache size in megabytes (%d to %d, default: %d)</source>
+ <translation>Sätt databasens cachestorlek i megabyte (%d till %d, förvalt: %d)</translation>
+ </message>
+ <message>
+ <source>Set maximum block size in bytes (default: %d)</source>
+ <translation>Sätt maximal blockstorlek i byte (förvalt: %d)</translation>
+ </message>
+ <message>
+ <source>Specify wallet file (within data directory)</source>
+ <translation>Ange plånboksfil (inom datakatalogen)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: %u)</source>
+ <translation>Använd UPnP för att mappa den lyssnande porten (förvalt: %u)</translation>
+ </message>
+ <message>
+ <source>Verifying blocks...</source>
+ <translation>Verifierar block...</translation>
+ </message>
+ <message>
+ <source>Verifying wallet...</source>
+ <translation>Verifierar plånboken...</translation>
+ </message>
+ <message>
+ <source>Wallet %s resides outside data directory %s</source>
+ <translation>Plånbok %s ligger utanför datakatalogen %s</translation>
+ </message>
+ <message>
+ <source>Wallet options:</source>
+ <translation>Plånboksinställningar:</translation>
+ </message>
+ <message>
+ <source>Warning: This version is obsolete; upgrade required!</source>
+ <translation>Varning: Denna version är föråldrad; uppgradering krävs!</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to change -txindex</source>
+ <translation>Du måste återskapa databasen med -reindex för att ändra -txindex</translation>
+ </message>
+ <message>
+ <source>Imports blocks from external blk000??.dat file</source>
+ <translation>Importerar block från extern blk000??.dat fil</translation>
+ </message>
+ <message>
+ <source>Allow JSON-RPC connections from specified source. Valid for &lt;ip&gt; are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times</source>
+ <translation>Tillåt JSON-RPC anslutningar från specifik kalla. Tillåtet för &lt;ip&gt; är enkel IP (t.ex 1.2.3.4), en nätverk/nätmask (t.ex. 1.2.3.4/255.255.255.0) eller ett nätverk/CIDR (t.ex. 1.2.3.4/24). Denna option kan specificeras flera gånger</translation>
+ </message>
+ <message>
+ <source>An error occurred while setting up the RPC address %s port %u for listening: %s</source>
+ <translation>Ett fel uppstod vid upprättandet av RPC adress %s port %u för att lyssna: %s</translation>
+ </message>
+ <message>
+ <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source>
+ <translation>Bind till given adress och vitlista klienter som ansluter till den. Använd [värd]:port notation för IPv6</translation>
+ </message>
+ <message>
+ <source>Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)</source>
+ <translation>Bind till angiven adress för att lyssna på JSON-RPC anslutningar. Använd [värd]:port notation for IPv6. Denna option kan specificeras flera gånger (förvalt: bind till alla gränssnitt)</translation>
+ </message>
+ <message>
+ <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source>
+ <translation>Kan inte låsa data-mappen %s. Bitcoin Core körs förmodligen redan.</translation>
+ </message>
+ <message>
+ <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
+ <translation>Skapa nya filer med systemets förvalda rättigheter, istället för umask 077 (bara effektivt med avaktiverad plånboks funktionalitet)</translation>
+ </message>
+ <message>
+ <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source>
+ <translation>Upptäck egna IP adresser (standard: 1 vid lyssning ingen -externalip eller -proxy)</translation>
+ </message>
+ <message>
+ <source>Error: Listening for incoming connections failed (listen returned error %s)</source>
+ <translation>Fel: Avlyssning av inkommande anslutningar misslyckades (Avlyssningen returnerade felkod %s)</translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source>
+ <translation>Fel: Argumentet -socks stöds inte. Att sätta SOCKS version är inte möjligt längre. Endast SOCKS5 proxy stöds.</translation>
+ </message>
+ <message>
+ <source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source>
+ <translation>Exekvera kommando när ett relevant meddelande är mottagen eller när vi ser en väldigt lång förgrening (%s i cmd är utbytt med ett meddelande)</translation>
+ </message>
+ <message>
+ <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source>
+ <translation>Avgifter (i BTC/Kb) mindre än detta betraktas som nollavgift för vidarebefodran (förvalt: %s)</translation>
+ </message>
+ <message>
+ <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
+ <translation>Om paytxfee inte är satt, inkludera tillräcklig avgift så att transaktionen börjar att konfirmeras inom n blocks (förvalt: %u)</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)</source>
+ <translation>Otillåtet belopp för -maxtxfee=&lt;belopp&gt;: '%s' (måste åtminstånde vara minrelay avgift %s för att förhindra stoppade transkationer)</translation>
+ </message>
+ <message>
+ <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source>
+ <translation>Maximal storlek på data i databärartransaktioner som vi reläar och bryter (förvalt: %u) </translation>
+ </message>
+ <message>
+ <source>Prune configured below the minimum of %d MB. Please use a higher number.</source>
+ <translation>Beskärning konfigurerad under miniminivån %d MB. Var vänlig använd ett högre värde.</translation>
+ </message>
+ <message>
+ <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source>
+ <translation>Sök efter klientadresser med DNS sökningen, om det finns otillräckligt med adresser (förvalt: 1 om inte -connect)</translation>
+ </message>
+ <message>
+ <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source>
+ <translation>Slumpa autentiseringen för varje proxyanslutning. Detta möjliggör Tor ström-isolering (förvalt: %u)</translation>
+ </message>
+ <message>
+ <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
+ <translation>Sätt den maximala storleken av hög-prioriterade/låg-avgifts transaktioner i byte (förvalt: %d)</translation>
+ </message>
+ <message>
+ <source>The transaction amount is too small to send after the fee has been deducted</source>
+ <translation>Transaktionen är för liten att skicka efter det att avgiften har dragits</translation>
+ </message>
+ <message>
+ <source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit &lt;https://www.openssl.org/&gt; and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source>
+ <translation>Denna produkten innehåller mjukvara utvecklad av OpenSSL Project för användning i OpenSSL Toolkit &lt;https://www.openssl.org/&gt; och kryptografisk mjukvara utvecklad av Eric Young samt UPnP-mjukvara skriven av Thomas Bernard.</translation>
+ </message>
+ <message>
+ <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an 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)
+The username and password MUST NOT be the same.
+If the file does not exist, create it with owner-readable-only file permissions.
+It is also recommended to set alertnotify so you are notified of problems;
+for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
+</source>
+ <translation>För att använda bitconid,eller -server optionen till bitcoin-qt så mäste du 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)
+Användarnamnet och lösenordet FÅR INTE vara detsamma.
+Om filen inte existerar, skapa den med enbart ägarläsbara filrättigheter.
+Det är också rekommenderat att sätta alertnotify så du meddelas om problem;
+till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
+</translation>
+ </message>
+ <message>
+ <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source>
+ <translation>Varning: -maxtxfee är satt väldigt hög! Så höga avgifter kan betalas för en enstaka transaktion.</translation>
+ </message>
+ <message>
+ <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source>
+ <translation>Varning: Vänligen kolla så att din dators datum och tid är korrekt! Om din klocka går fel kommer Bitcoin Core inte att fungera korrekt.</translation>
+ </message>
+ <message>
+ <source>Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway</source>
+ <translation>Vitlistade klienter kan inte bli DoS bannade och deras transaktioner reläas alltid, även om dom redan är i mempoolen, användbart för t.ex en gateway </translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source>
+ <translation>Du måste bygga om databasen genom att använda -reindex för att återgå till obeskärt läge. Detta kommer att ladda ner hela blockkedjan.</translation>
+ </message>
+ <message>
+ <source>(default: %u)</source>
+ <translation>(förvalt: %u)</translation>
+ </message>
+ <message>
+ <source>Accept public REST requests (default: %u)</source>
+ <translation>Acceptera publika REST förfrågningar (förvalt: %u)</translation>
+ </message>
+ <message>
+ <source>Activating best chain...</source>
+ <translation>Aktiverar bästa kedjan...</translation>
+ </message>
+ <message>
+ <source>Can't run with a wallet in prune mode.</source>
+ <translation>Kan inte köra med en plånbok i beskärningsläge.</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -whitebind address: '%s'</source>
+ <translation>Kan inte matcha -whitebind adress: '%s'</translation>
+ </message>
+ <message>
+ <source>Choose data directory on startup (default: 0)</source>
+ <translation>Välj datakatalog vid uppstart (förvalt: 0)</translation>
+ </message>
+ <message>
+ <source>Connect through SOCKS5 proxy</source>
+ <translation>Anslut genom SOCKS5 proxy</translation>
+ </message>
+ <message>
+ <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source>
+ <translation>Copyright (C) 2009-%i Bitcoin Core Utvecklarna</translation>
+ </message>
+ <message>
+ <source>Could not parse -rpcbind value %s as network address</source>
+ <translation>Kunde inte tolka -rpcbind värdet %s som en nätverksadress</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source>
+ <translation>Fel vid inläsningen av wallet.dat: Kontofilen kräver en senare version av Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Error reading from database, shutting down.</source>
+ <translation>Fel vid läsning från databas, avslutar.</translation>
+ </message>
+ <message>
+ <source>Error: A fatal internal error occurred, see debug.log for details</source>
+ <translation>Fel: Ett kritiskt internt fel uppstod, se debug.log för detaljer</translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -tor found, use -onion.</source>
+ <translation>Fel: Argumentet -tor stöds inte, använd -onion.</translation>
+ </message>
+ <message>
+ <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source>
+ <translation>Avgift (i BTC/Kb) att lägga till på transaktioner du skickar (förvalt: %s)</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Information</translation>
+ </message>
+ <message>
+ <source>Initialization sanity check failed. Bitcoin Core is shutting down.</source>
+ <translation>Initieringschecken fallerade. Bitcoin Core stängs av...</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Otillåtet belopp för -maxtxfee=&lt;belopp&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -minrelaytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Ogiltigt belopp för -minrelaytxfee=&lt;belopp&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -mintxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Ogiltigt belopp för -mintxfee=&lt;belopp&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s' (must be at least %s)</source>
+ <translation>Ogiltigt belopp för -paytxfee=&lt;belopp&gt;:'%s' (måste vara minst %s)</translation>
+ </message>
+ <message>
+ <source>Invalid netmask specified in -whitelist: '%s'</source>
+ <translation>Ogiltig nätmask angiven i -whitelist: '%s'</translation>
+ </message>
+ <message>
+ <source>Keep at most &lt;n&gt; unconnectable transactions in memory (default: %u)</source>
+ <translation>Håll som mest &lt;n&gt; oanslutningsbara transaktioner i minnet (förvalt: %u)</translation>
+ </message>
+ <message>
+ <source>Need to specify a port with -whitebind: '%s'</source>
+ <translation>Port måste anges med -whitelist: '%s'</translation>
+ </message>
+ <message>
+ <source>Node relay options:</source>
+ <translation>Nodreläoptioner:</translation>
+ </message>
+ <message>
+ <source>Pruning blockstore...</source>
+ <translation>Rensar blockstore...</translation>
+ </message>
+ <message>
+ <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source>
+ <translation>RPC SSL optioner: (se Bitcoin Wiki för SSL inställningsinstruktioner)</translation>
+ </message>
+ <message>
+ <source>RPC server options:</source>
+ <translation>RPC serveroptioner:</translation>
+ </message>
+ <message>
+ <source>RPC support for HTTP persistent connections (default: %d)</source>
+ <translation>RPC support för HTTP permanent anslutning (förvalt: %d)</translation>
+ </message>
+ <message>
+ <source>Rebuild block chain index from current blk000??.dat files on startup</source>
+ <translation>Återskapa blockkedjans index från nuvarande blk000??.dat filer under uppstarten</translation>
+ </message>
+ <message>
+ <source>Receive and display P2P network alerts (default: %u)</source>
+ <translation>Mottag och visa P2P nätverksvarningar (förvalt: %u)</translation>
+ </message>
+ <message>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>Skicka trace-/debuginformation till terminalen istället för till debug.log</translation>
+ </message>
+ <message>
+ <source>Send transactions as zero-fee transactions if possible (default: %u)</source>
+ <translation>Sänd transaktioner som nollavgiftstransaktioner om möjligt (förvalt: %u)</translation>
+ </message>
+ <message>
+ <source>Set SSL root certificates for payment request (default: -system-)</source>
+ <translation>Sätt SSL root-certifikat för betalningsbegäran (förvalt: -system-)</translation>
+ </message>
+ <message>
+ <source>Set language, for example "de_DE" (default: system locale)</source>
+ <translation>Ändra språk, till exempel "de_DE" (förvalt: systemets språk)</translation>
+ </message>
+ <message>
+ <source>Show all debugging options (usage: --help -help-debug)</source>
+ <translation>Visa alla avlusningsoptioner (använd: --help -help-debug)</translation>
+ </message>
+ <message>
+ <source>Show splash screen on startup (default: 1)</source>
+ <translation>Visa startbilden vid uppstart (förvalt: 1)</translation>
+ </message>
+ <message>
+ <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source>
+ <translation>Krymp debug.log filen vid klient start (förvalt: 1 vid ingen -debug)</translation>
+ </message>
+ <message>
+ <source>Signing transaction failed</source>
+ <translation>Signering av transaktion misslyckades</translation>
+ </message>
+ <message>
+ <source>Start minimized</source>
+ <translation>Starta som minimerad</translation>
+ </message>
+ <message>
+ <source>The transaction amount is too small to pay the fee</source>
+ <translation>Transaktionen är för liten för att betala avgiften</translation>
+ </message>
+ <message>
+ <source>This is experimental software.</source>
+ <translation>Detta är experimentmjukvara.</translation>
+ </message>
+ <message>
+ <source>Transaction amount too small</source>
+ <translation>Transaktions belopp för liten</translation>
+ </message>
+ <message>
+ <source>Transaction amounts must be positive</source>
+ <translation>Transaktionens belopp måste vara positiva</translation>
+ </message>
+ <message>
+ <source>Transaction too large for fee policy</source>
+ <translation>Transaktionen är för stor för avgiftspolicyn</translation>
+ </message>
+ <message>
+ <source>Transaction too large</source>
+ <translation>Transaktionen är för stor</translation>
+ </message>
+ <message>
+ <source>UI Options:</source>
+ <translation>UI Alternativ:</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer (bind returned error %s)</source>
+ <translation>Det går inte att binda till %s på den här datorn (bind returnerade felmeddelande %s)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: 1 when listening)</source>
+ <translation>Använd UPnP för att mappa den lyssnande porten (förvalt: 1 under lyssning)</translation>
+ </message>
+ <message>
+ <source>Username for JSON-RPC connections</source>
+ <translation>Användarnamn för JSON-RPC-anslutningar</translation>
+ </message>
+ <message>
+ <source>Wallet needed to be rewritten: restart Bitcoin Core to complete</source>
+ <translation>Kontot behöver sparas om: Starta om Bitcoin Core för att fullfölja</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Varning</translation>
+ </message>
+ <message>
+ <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source>
+ <translation>Varning: Argument -benchmark stöds inte och ignoreras, använd -debug=bench.</translation>
+ </message>
+ <message>
+ <source>Warning: Unsupported argument -debugnet ignored, use -debug=net.</source>
+ <translation>Varning: Argument -debugnet stöds inte och ignorerad, använd -debug=net.</translation>
+ </message>
+ <message>
+ <source>Zapping all transactions from wallet...</source>
+ <translation>Töm plånboken på alla transaktioner...</translation>
+ </message>
+ <message>
+ <source>on startup</source>
+ <translation>under uppstarten</translation>
+ </message>
+ <message>
+ <source>wallet.dat corrupt, salvage failed</source>
+ <translation>wallet.dat korrupt, räddning misslyckades</translation>
+ </message>
+ <message>
+ <source>Password for JSON-RPC connections</source>
+ <translation>Lösenord för JSON-RPC-anslutningar</translation>
+ </message>
+ <message>
+ <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
+ <translation>Exekvera kommando när det bästa blocket ändras (%s i cmd är utbytt av blockhash)</translation>
+ </message>
+ <message>
+ <source>Upgrade wallet to latest format</source>
+ <translation>Uppgradera plånboken till senaste formatet</translation>
+ </message>
+ <message>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>Sök i blockkedjan efter saknade plånboks transaktioner</translation>
+ </message>
+ <message>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>Använd OpenSSL (https) för JSON-RPC-anslutningar</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>Det här hjälp medelandet</translation>
+ </message>
+ <message>
+ <source>Allow DNS lookups for -addnode, -seednode and -connect</source>
+ <translation>Tillåt DNS-sökningar för -addnode, -seednode och -connect</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>Laddar adresser...</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>Fel vid inläsningen av wallet.dat: Plånboken är skadad</translation>
+ </message>
+ <message>
+ <source>(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source>
+ <translation>(1 = spara tx metadata t.ex. kontoägare och betalningsbegäransinformation, 2 = släng tx metadata)</translation>
+ </message>
+ <message>
+ <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
+ <translation>Hur grundlig blockverifikationen vid -checkblocks är (0-4, förvalt: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
+ <translation>Upprätthåll ett fullständigt transaktionsindex, som används av getrawtransaction rpc-anrop (förval: %u)</translation>
+ </message>
+ <message>
+ <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source>
+ <translation>Antal sekunder att hindra klienter som missköter sig från att ansluta (förvalt: %u)</translation>
+ </message>
+ <message>
+ <source>Output debugging information (default: %u, supplying &lt;category&gt; is optional)</source>
+ <translation>Skriv ut avlusningsinformation (förvalt: %u, att ange &lt;category&gt; är frivilligt)</translation>
+ </message>
+ <message>
+ <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source>
+ <translation>Använd separat SOCKS5 proxy för att nå kollegor via dolda tjänster i Tor (förvalt: -%s)</translation>
+ </message>
+ <message>
+ <source>(default: %s)</source>
+ <translation>(förvalt: %s)</translation>
+ </message>
+ <message>
+ <source>Acceptable ciphers (default: %s)</source>
+ <translation>Accepterbara chiffer (förvalt: %s)</translation>
+ </message>
+ <message>
+ <source>Always query for peer addresses via DNS lookup (default: %u)</source>
+ <translation>Sök alltid efter klientadresser med DNS sökningen (förvalt: %u)</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>Fel vid inläsning av plånboksfilen wallet.dat</translation>
+ </message>
+ <message>
+ <source>Generate coins (default: %u)</source>
+ <translation>Generera mynt (förvalt: %u)</translation>
+ </message>
+ <message>
+ <source>How many blocks to check at startup (default: %u, 0 = all)</source>
+ <translation>Hur många block att kontrollera vid uppstart (förvalt: %u, 0 = alla)</translation>
+ </message>
+ <message>
+ <source>Include IP addresses in debug output (default: %u)</source>
+ <translation>Inkludera IP-adresser i debugutskrift (förvalt: %u)</translation>
+ </message>
+ <message>
+ <source>Invalid -proxy address: '%s'</source>
+ <translation>Ogiltig -proxy adress: '%s'</translation>
+ </message>
+ <message>
+ <source>Listen for JSON-RPC connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>Lyssna på JSON-RPC-anslutningar på &lt;port&gt; (förval: %u eller testnet: %u)</translation>
+ </message>
+ <message>
+ <source>Listen for connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>Lyssna efter anslutningar på &lt;port&gt; (förvalt: %u eller testnet: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain at most &lt;n&gt; connections to peers (default: %u)</source>
+ <translation>Ha som mest &lt;n&gt; anslutningar till andra klienter (förvalt: %u)</translation>
+ </message>
+ <message>
+ <source>Make the wallet broadcast transactions</source>
+ <translation>Gör så att plånboken sänder ut transaktionerna</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection receive buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>Maximal mottagningsbuffert per anslutning, &lt;n&gt;*1000 byte (förvalt: %u)</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection send buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>Maximal sändningsbuffert per anslutning, &lt;n&gt;*1000 byte (förvalt: %u)</translation>
+ </message>
+ <message>
+ <source>Prepend debug output with timestamp (default: %u)</source>
+ <translation>Skriv ut tidsstämpel i avlusningsinformationen (förvalt: %u)</translation>
+ </message>
+ <message>
+ <source>Relay and mine data carrier transactions (default: %u)</source>
+ <translation>Reläa och bearbeta databärartransaktioner (förvalt: %u) </translation>
+ </message>
+ <message>
+ <source>Relay non-P2SH multisig (default: %u)</source>
+ <translation>Reläa icke P2SH multisig (förvalt: %u)</translation>
+ </message>
+ <message>
+ <source>Server certificate file (default: %s)</source>
+ <translation>Serverns certifikatfil (förvalt: %s)</translation>
+ </message>
+ <message>
+ <source>Server private key (default: %s)</source>
+ <translation>Serverns privata nyckel (förvalt: %s)</translation>
+ </message>
+ <message>
+ <source>Set key pool size to &lt;n&gt; (default: %u)</source>
+ <translation>Sätt storleken på nyckelpoolen till &lt;n&gt; (förvalt: %u)</translation>
+ </message>
+ <message>
+ <source>Set minimum block size in bytes (default: %u)</source>
+ <translation>Sätt minsta blockstorlek i byte (standard: %u)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads to service RPC calls (default: %d)</source>
+ <translation>Ange antalet trådar för att hantera RPC anrop (förvalt: %d)</translation>
+ </message>
+ <message>
+ <source>Specify configuration file (default: %s)</source>
+ <translation>Ange konfigurationsfil (förvalt: %s)</translation>
+ </message>
+ <message>
+ <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source>
+ <translation>Ange timeout för uppkoppling i millisekunder (minimum:1, förvalt: %d)</translation>
+ </message>
+ <message>
+ <source>Specify pid file (default: %s)</source>
+ <translation>Ange pid-fil (förvalt: %s)</translation>
+ </message>
+ <message>
+ <source>Spend unconfirmed change when sending transactions (default: %u)</source>
+ <translation>Spendera okonfirmerad växel när transaktioner sänds (förvalt: %u)</translation>
+ </message>
+ <message>
+ <source>Threshold for disconnecting misbehaving peers (default: %u)</source>
+ <translation>Tröskelvärde för att koppla ifrån klienter som missköter sig (förvalt: %u)</translation>
+ </message>
+ <message>
+ <source>Unknown network specified in -onlynet: '%s'</source>
+ <translation>Okänt nätverk som anges i -onlynet: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -bind address: '%s'</source>
+ <translation>Kan inte matcha -bind adress: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -externalip address: '%s'</source>
+ <translation>Kan inte matcha -externalip adress: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Ogiltigt belopp för -paytxfee=&lt;belopp&gt;:'%s'</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>Otillräckligt med bitcoins</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>Laddar blockindex...</translation>
+ </message>
+ <message>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>Lägg till en nod att koppla upp mot och försök att hålla anslutningen öppen</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>Laddar plånbok...</translation>
+ </message>
+ <message>
+ <source>Cannot downgrade wallet</source>
+ <translation>Kan inte nedgradera plånboken</translation>
+ </message>
+ <message>
+ <source>Cannot write default address</source>
+ <translation>Kan inte skriva standardadress</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>Söker igen...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>Klar med laddning</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Fel</translation>
+ </message>
+</context>
+</TS> \ No newline at end of file
diff --git a/src/qt/locale/bitcoin_th_TH.ts b/src/qt/locale/bitcoin_th_TH.ts
new file mode 100644
index 0000000000..0980502968
--- /dev/null
+++ b/src/qt/locale/bitcoin_th_TH.ts
@@ -0,0 +1,386 @@
+<TS language="th_TH" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Create a new address</source>
+ <translation>สร้างที่อยู่ใหม่</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>คัดลอกที่อยู่ที่ถูกเลือกไปยัง คลิปบอร์ดของระบบ</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;ลบ</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>คั่นไฟล์ด้วยเครื่องหมายจุลภาค (*.csv)</translation>
+ </message>
+ </context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>ชื่อ</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>ที่อยู่</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(ไม่มีชื่อ)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>ใส่รหัสผ่าน</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>รหัสผา่นใหม่</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>กรุณากรอกรหัสผ่านใหม่อีกครั้งหนึ่ง</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>กระเป๋าสตางค์ที่เข้ารหัส</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>การดำเนินการนี้ต้องมีรหัสผ่านกระเป๋าเงินของคุณเพื่อปลดล็อคกระเป๋าเงิน</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>เปิดกระเป๋าสตางค์</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>การดำเนินการนี้ต้องมีรหัสผ่านกระเป๋าเงินของคุณในการถอดรหัสกระเป๋าเงิน</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>ถอดรหัสกระเป๋าสตางค์</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>เปลี่ยนรหัสผ่าน</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>ยืนยันการเข้ารหัสกระเป๋าสตางค์</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>กระเป๋าสตางค์ถูกเข้ารหัสเรียบร้อยแล้ว</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>การเข้ารหัสกระเป๋าสตางค์ผิดพลาด</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>กระเป๋าเงินเข้ารหัสล้มเหลวเนื่องจากข้อผิดพลาดภายใน กระเป๋าเงินของคุณไม่ได้เข้ารหัส</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>รหัสผ่านที่คุณกรอกไม่ตรงกัน</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>ปลดล็อคกระเป๋าเงินล้มเหลว</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>ป้อนรหัสผ่านสำหรับการถอดรหัสกระเป๋าเงินไม่ถูกต้อง</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>ถอดรหัสกระเป๋าเงินล้มเหลว</translation>
+ </message>
+ </context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>กำลังทำข้อมูลให้ตรงกันกับเครือข่าย ...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;ภาพรวม</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>แสดงภาพรวมทั่วไปของกระเป๋าเงิน</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;การทำรายการ</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>เรียกดูประวัติการทำธุรกรรม</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>ออกจากโปรแกรม</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;ตัวเลือก...</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>เปลี่ยนรหัสผ่านที่ใช้สำหรับการเข้ารหัสกระเป๋าเงิน</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;ไฟล์</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;การตั้งค่า</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>&amp;ช่วยเหลือ</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>แถบเครื่องมือ</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n active connection(s) to Bitcoin network</source>
+ <translation><numerusform>%n ที่ใช้งานการเชื่อมต่อกับเครือข่าย Bitcoin</numerusform></translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>ทันสมัย</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>จับได้...</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>รายการที่ส่ง</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>การทำรายการขาเข้า</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>ระเป๋าเงินถูก &lt;b&gt;เข้ารหัส&lt;/b&gt; และในขณะนี้ &lt;b&gt;ปลดล็อคแล้ว&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>กระเป๋าเงินถูก &lt;b&gt;เข้ารหัส&lt;/b&gt; และในปัจจุบัน &lt;b&gt;ล็อค &lt;/b&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ </context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>(no label)</source>
+ <translation>(ไม่มีชื่อ)</translation>
+ </message>
+ </context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>แก้ไขที่อยู่</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>&amp;ชื่อ</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;ที่อยู่</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>ที่อยู่ผู้รับใหม่</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>ที่อยู่ผู้ส่งใหม่</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>แก้ไขที่อยู่ผู้รับ</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>แก้ไขที่อยู่ผู้ส่ง</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>ป้อนที่อยู่ "%1" ที่มีอยู่แล้วในสมุดที่อยู่</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>ไม่สามารถปลดล็อคกระเป๋าเงิน</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>สร้างกุญแจใหม่ล้มเหลว</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ </context>
+<context>
+ <name>HelpMessageDialog</name>
+ </context>
+<context>
+ <name>Intro</name>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ </context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>ตัวเลือก</translation>
+ </message>
+ </context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>รูป</translation>
+ </message>
+ </context>
+<context>
+ <name>PaymentServer</name>
+ </context>
+<context>
+ <name>PeerTableModel</name>
+ </context>
+<context>
+ <name>QObject</name>
+ </context>
+<context>
+ <name>QRImageWidget</name>
+ </context>
+<context>
+ <name>RPCConsole</name>
+ </context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ </context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>Address</source>
+ <translation>ที่อยู่</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>ชื่อ</translation>
+ </message>
+ </context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>ชื่อ</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(ไม่มีชื่อ)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>ส่งเหรียญ</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(ไม่มีชื่อ)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsEntry</name>
+ </context>
+<context>
+ <name>ShutdownWindow</name>
+ </context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ </context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>[testnet]</source>
+ <translation>[testnet]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ </context>
+<context>
+ <name>TransactionDesc</name>
+ </context>
+<context>
+ <name>TransactionDescDialog</name>
+ </context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>ชื่อ</translation>
+ </message>
+ </context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>Today</source>
+ <translation>วันนี้</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>คั่นไฟล์ด้วยเครื่องหมายจุลภาค (*.csv)</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>ชื่อ</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>ที่อยู่</translation>
+ </message>
+ </context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ </context>
+<context>
+ <name>WalletFrame</name>
+ </context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>ส่งเหรียญ</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ </context>
+<context>
+ <name>bitcoin-core</name>
+ </context>
+</TS> \ 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 0000000000..45be4f7e0f
--- /dev/null
+++ b/src/qt/locale/bitcoin_tr.ts
@@ -0,0 +1,3576 @@
+<TS language="tr" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Right-click to edit address or label</source>
+ <translation>Adres veya etiketi düzenlemek için sağ tıklayınız.</translation>
+ </message>
+ <message>
+ <source>Create a new address</source>
+ <translation>Yeni bir adres oluştur</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>&amp;Yeni</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Seçili adresi panoya kopyala</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>&amp;Kopyala</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>K&amp;apat</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>&amp;Adresi Kopyala</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>Seçili adresi listeden sil</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Açık olan sekmedeki verileri bir dosyaya aktar</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Dışa aktar</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;Sil</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>Bitcoin yollanacak adresi seç</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>Bitcoin alınacak adresi seç</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>S&amp;eç</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>&amp;Gönderme adresleri...</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>Alım adresleri</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>Bunlar ödemeleri göndermek için kullanacağınız Bitcoin adreslerinizdir. Bitcoin yollamadan önce miktarı ve alıcının alım adresini daima kontrol ediniz.</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>Bunlar ödemeleri almak için kullanacağınız Bitcoin adreslerinizdir. Her işlem için yeni bir alım adresi kullanmanız tavsiye edilir.</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>&amp;Etiketi kopyala</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>&amp;Düzenle</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>Adres listesini dışa aktar</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Virgülle ayrılmış değerler dosyası (*.csv)</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Dışa aktarım başarısız oldu</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the address list to %1. Please try again.</source>
+ <translation>Adres listesinin %1 konumuna kaydedilmesi sırasında bir hata meydana geldi. Lütfen tekrar deneyin.</translation>
+ </message>
+</context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Etiket</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adres</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(etiket yok)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Passphrase Dialog</source>
+ <translation>Parola diyaloğu</translation>
+ </message>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Parolayı giriniz</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Yeni parola</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Yeni parolayı tekrarlayınız</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>Cüzdanı şifrele</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>Bu işlem cüzdan kilidini açmak için cüzdan parolanızı gerektirir.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Cüzdan kilidini aç</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>Bu işlem cüzdanın şifrelemesini açmak için cüzdan parolasını gerektirir.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>Cüzdanın şifrelemesini aç</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>Parolayı değiştir</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>Cüzdanın şifrelemesini teyit eder</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>Uyarı: Eğer cüzdanınızı şifrelerseniz ve parolanızı kaybederseniz, &lt;b&gt;TÜM BİTCOİNLERİNİZİ KAYBEDERSİNİZ&lt;/b&gt;!</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>Cüzdanınızı şifrelemek istediğinizden emin misiniz?</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core 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.</source>
+ <translation>Şifreleme işlemini tamamlamak için Bitcoin Çekirdeği ş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.</translation>
+ </message>
+ <message>
+ <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
+ <translation>ÖNEMLİ: Önceden yapmış olduğunuz cüzdan dosyası yedeklemelerinin yeni oluşturulan şifrelenmiş cüzdan dosyası ile değiştirilmeleri gerekir. Güvenlik nedenleriyle yeni, şifrelenmiş cüzdanı kullanmaya başladığınızda eski şifrelenmemiş cüzdan dosyaları işe yaramaz hale gelecektir.</translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>Uyarı: Caps Lock tuşu faal durumda!</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>Cüzdan şifrelendi</translation>
+ </message>
+ <message>
+ <source>Enter the new passphrase to the wallet.&lt;br/&gt;Please use a passphrase of &lt;b&gt;ten or more random characters&lt;/b&gt;, or &lt;b&gt;eight or more words&lt;/b&gt;.</source>
+ <translation>Cüzdan için yeni parolayı giriniz.&lt;br/&gt;Lütfen &lt;b&gt;on ya da daha fazla rastgele karakter&lt;/b&gt; veya &lt;b&gt;sekiz ya da daha fazla kelime&lt;/b&gt; içeren bir parola kullanınız.</translation>
+ </message>
+ <message>
+ <source>Enter the old passphrase and new passphrase to the wallet.</source>
+ <translation>Cüzdan için eski parolayı ve yeni parolayı giriniz.</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>Cüzdan şifrelemesi başarısız oldu</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>Dahili bir hata sebebiyle cüzdan şifrelemesi başarısız oldu. Cüzdanınız şifrelenmedi.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>Girilen parolalar birbirleriyle uyumlu değil.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>Cüzdan kilidinin açılması başarısız oldu</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>Cüzdan şifresinin açılması için girilen parola yanlıştı.</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>Cüzdan şifresinin açılması başarısız oldu</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>Cüzdan parolası başarılı bir şekilde değiştirildi.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>&amp;Mesaj imzala...</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>Şebeke ile senkronizasyon...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;Genel bakış</translation>
+ </message>
+ <message>
+ <source>Node</source>
+ <translation>Düğüm</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>Cüzdana genel bakışı göster</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Muameleler</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>Muamele tarihçesini tara</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>&amp;Çık</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>Uygulamadan çık</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>&amp;Qt hakkında</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>Qt hakkında bilgi görüntü</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;Seçenekler...</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>Cüzdanı &amp;şifrele...</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>Cüzdanı &amp;yedekle...</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>Parolayı &amp;değiştir...</translation>
+ </message>
+ <message>
+ <source>&amp;Sending addresses...</source>
+ <translation>&amp;Gönderme adresleri...</translation>
+ </message>
+ <message>
+ <source>&amp;Receiving addresses...</source>
+ <translation>&amp;Alma adresleri...</translation>
+ </message>
+ <message>
+ <source>Open &amp;URI...</source>
+ <translation>&amp;URI aç...</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core client</source>
+ <translation>Bitcoin Çekirdeği istemcisi</translation>
+ </message>
+ <message>
+ <source>Importing blocks from disk...</source>
+ <translation>Bloklar diskten içe aktarılıyor...</translation>
+ </message>
+ <message>
+ <source>Reindexing blocks on disk...</source>
+ <translation>Diskteki bloklar yeniden endeksleniyor...</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>Bir Bitcoin adresine Bitcoin yolla</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>Cüzdanı diğer bir konumda yedekle</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Cüzdan şifrelemesi için kullanılan parolayı değiştir</translation>
+ </message>
+ <message>
+ <source>&amp;Debug window</source>
+ <translation>&amp;Hata ayıklama penceresi</translation>
+ </message>
+ <message>
+ <source>Open debugging and diagnostic console</source>
+ <translation>Hata ayıklama ve teşhis penceresini aç</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>Mesaj &amp;kontrol et...</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>Cüzdan</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>&amp;Gönder</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>&amp;Al</translation>
+ </message>
+ <message>
+ <source>Show information about Bitcoin Core</source>
+ <translation>Bitcoin Çekirdeği hakkında bilgi göster</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>&amp;Göster / Sakla</translation>
+ </message>
+ <message>
+ <source>Show or hide the main Window</source>
+ <translation>Ana pencereyi görüntüle ya da sakla</translation>
+ </message>
+ <message>
+ <source>Encrypt the private keys that belong to your wallet</source>
+ <translation>Cüzdanınızın özel anahtarlarını şifrele</translation>
+ </message>
+ <message>
+ <source>Sign messages with your Bitcoin addresses to prove you own them</source>
+ <translation>Mesajları adreslerin size ait olduğunu ispatlamak için Bitcoin adresleri ile imzala</translation>
+ </message>
+ <message>
+ <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source>
+ <translation>Belirtilen Bitcoin adresleri ile imzalandıklarından emin olmak için mesajları kontrol et</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;Dosya</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;Ayarlar</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>&amp;Yardım</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>Sekme araç çubuğu</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Çekirdeği</translation>
+ </message>
+ <message>
+ <source>Request payments (generates QR codes and bitcoin: URIs)</source>
+ <translation>Ödeme talep et (QR kodu ve bitcoin URI'si oluşturur)</translation>
+ </message>
+ <message>
+ <source>&amp;About Bitcoin Core</source>
+ <translation>Bitcoin Çekirdeği &amp;hakkında</translation>
+ </message>
+ <message>
+ <source>Modify configuration options for Bitcoin Core</source>
+ <translation>Bitcoin Çekirdeği yapılandırma seçeneklerini değiştir</translation>
+ </message>
+ <message>
+ <source>Show the list of used sending addresses and labels</source>
+ <translation>Kullanılmış gönderme adresleri ve etiketlerin listesini göster</translation>
+ </message>
+ <message>
+ <source>Show the list of used receiving addresses and labels</source>
+ <translation>Kullanılmış alım adresleri ve etiketlerin listesini göster</translation>
+ </message>
+ <message>
+ <source>Open a bitcoin: URI or payment request</source>
+ <translation>Bir bitcoin: bağlantısı ya da ödeme talebi aç</translation>
+ </message>
+ <message>
+ <source>&amp;Command-line options</source>
+ <translation>&amp;Komut satırı seçenekleri</translation>
+ </message>
+ <message>
+ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
+ <translation>Bitcoin komut satırı seçeneklerinin listesini elde etmek için Bitcoin Çekirdeği yardım mesajını göster</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n active connection(s) to Bitcoin network</source>
+ <translation><numerusform>Bitcoin şebekesine %n faal bağlantı</numerusform><numerusform>Bitcoin şebekesine %n faal bağlantı</numerusform></translation>
+ </message>
+ <message>
+ <source>No block source available...</source>
+ <translation>Hiçbir blok kaynağı mevcut değil...</translation>
+ </message>
+ <message numerus="yes">
+ <source>Processed %n block(s) of transaction history.</source>
+ <translation><numerusform>Muamele tarihçesinden %n blok işlendi.</numerusform><numerusform>Muamele tarihçesinden %n blok işlendi</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n hour(s)</source>
+ <translation><numerusform>%n saat</numerusform><numerusform>%n saat</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n day(s)</source>
+ <translation><numerusform>%n gün</numerusform><numerusform>%n gün</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n week(s)</source>
+ <translation><numerusform>%n hafta</numerusform><numerusform>%n hafta</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 and %2</source>
+ <translation>%1 ve %2</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n year(s)</source>
+ <translation><numerusform>%n yıl</numerusform><numerusform>%n yıl</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 behind</source>
+ <translation>%1 geride</translation>
+ </message>
+ <message>
+ <source>Last received block was generated %1 ago.</source>
+ <translation>Son alınan blok %1 evvel oluşturulmuştu.</translation>
+ </message>
+ <message>
+ <source>Transactions after this will not yet be visible.</source>
+ <translation>Bundan sonraki muameleler henüz görüntülenemez.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Hata</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Uyarı</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Bilgi</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>Güncel</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>Aralık kapatılıyor...</translation>
+ </message>
+ <message>
+ <source>Date: %1
+</source>
+ <translation>Tarih: %1
+</translation>
+ </message>
+ <message>
+ <source>Amount: %1
+</source>
+ <translation>Meblağ: %1
+</translation>
+ </message>
+ <message>
+ <source>Type: %1
+</source>
+ <translation>Tür: %1
+</translation>
+ </message>
+ <message>
+ <source>Label: %1
+</source>
+ <translation>Etiket: %1
+</translation>
+ </message>
+ <message>
+ <source>Address: %1
+</source>
+ <translation>Adres: %1
+</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>Muamele yollandı</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>Gelen muamele</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>Cüzdan &lt;b&gt;şifrelenmiştir&lt;/b&gt; ve şu anda &lt;b&gt;kilidi açıktır&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>Cüzdan &lt;b&gt;şifrelenmiştir&lt;/b&gt; ve şu anda &lt;b&gt;kilitlidir&lt;/b&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <source>Network Alert</source>
+ <translation>Şebeke hakkında uyarı</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Coin Selection</source>
+ <translation>Bitcoin Seçimi</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Miktar:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Bayt:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Meblağ:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Öncelik:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Ücret:</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Toz:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Ücretten sonra:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Para üstü:</translation>
+ </message>
+ <message>
+ <source>(un)select all</source>
+ <translation>tümünü seç(me)</translation>
+ </message>
+ <message>
+ <source>Tree mode</source>
+ <translation>Ağaç kipi</translation>
+ </message>
+ <message>
+ <source>List mode</source>
+ <translation>Liste kipi</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Meblağ</translation>
+ </message>
+ <message>
+ <source>Received with label</source>
+ <translation>Şu etiketle alındı</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>Şu adresle alındı</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Tarih</translation>
+ </message>
+ <message>
+ <source>Confirmations</source>
+ <translation>Doğrulamalar</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Doğrulandı</translation>
+ </message>
+ <message>
+ <source>Priority</source>
+ <translation>Öncelik</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Adresi kopyala</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Etiketi kopyala</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Meblağı kopyala</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Muamele kimliğini kopyala</translation>
+ </message>
+ <message>
+ <source>Lock unspent</source>
+ <translation>Harcanmamışı kilitle</translation>
+ </message>
+ <message>
+ <source>Unlock unspent</source>
+ <translation>Harcanmamışın kilidini aç</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Miktarı kopyala</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Ücreti kopyala</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Ücretten sonrakini kopyala</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Baytları kopyala</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Önceliği kopyala</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Tozu kopyala</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Para üstünü kopyala</translation>
+ </message>
+ <message>
+ <source>highest</source>
+ <translation>azami</translation>
+ </message>
+ <message>
+ <source>higher</source>
+ <translation>daha yüksek</translation>
+ </message>
+ <message>
+ <source>high</source>
+ <translation>yüksek</translation>
+ </message>
+ <message>
+ <source>medium-high</source>
+ <translation>orta-yüksek</translation>
+ </message>
+ <message>
+ <source>medium</source>
+ <translation>orta</translation>
+ </message>
+ <message>
+ <source>low-medium</source>
+ <translation>düşük-orta</translation>
+ </message>
+ <message>
+ <source>low</source>
+ <translation>düşük</translation>
+ </message>
+ <message>
+ <source>lower</source>
+ <translation>daha düşük</translation>
+ </message>
+ <message>
+ <source>lowest</source>
+ <translation>asgari</translation>
+ </message>
+ <message>
+ <source>(%1 locked)</source>
+ <translation>(%1 kilitlendi)</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>boş</translation>
+ </message>
+ <message>
+ <source>This label turns red if the transaction size is greater than 1000 bytes.</source>
+ <translation>Eğer muamele boyutu 1000 bayttan yüksek ise bu etiket kırmızı hale gelir.</translation>
+ </message>
+ <message>
+ <source>This label turns red if the priority is smaller than "medium".</source>
+ <translation>Eğer öncelik "ortadan" düşükse bu etiket kırmızı olur.</translation>
+ </message>
+ <message>
+ <source>This label turns red if any recipient receives an amount smaller than %1.</source>
+ <translation>Eğer herhangi bir alıcı %1'den düşük bir meblağ alırsa bu etiket kırmızı olur.</translation>
+ </message>
+ <message>
+ <source>Can vary +/- %1 satoshi(s) per input.</source>
+ <translation>Giriş başına +/- %1 satoshi olarak değişebilir.</translation>
+ </message>
+ <message>
+ <source>yes</source>
+ <translation>evet</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>hayır</translation>
+ </message>
+ <message>
+ <source>This means a fee of at least %1 per kB is required.</source>
+ <translation>Bu, kB başına en az %1 ücret gerektiği anlamnına gelir.</translation>
+ </message>
+ <message>
+ <source>Can vary +/- 1 byte per input.</source>
+ <translation>Girdi başına +/- 1 bayt değişebilir.</translation>
+ </message>
+ <message>
+ <source>Transactions with higher priority are more likely to get included into a block.</source>
+ <translation>Yüksek öncelikli muamelelerin bir bloğa dahil olmaları daha olasıdır.</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(boş etiket)</translation>
+ </message>
+ <message>
+ <source>change from %1 (%2)</source>
+ <translation>%1 unsurundan para üstü (%2)</translation>
+ </message>
+ <message>
+ <source>(change)</source>
+ <translation>(para üstü)</translation>
+ </message>
+</context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>Adresi düzenle</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>&amp;Etiket</translation>
+ </message>
+ <message>
+ <source>The label associated with this address list entry</source>
+ <translation>Bu adres listesi girdisi ile ilişkili etiket</translation>
+ </message>
+ <message>
+ <source>The address associated with this address list entry. This can only be modified for sending addresses.</source>
+ <translation>Bu adres listesi girdisi ile ilişkili adres. Sadece gönderme adresleri için değiştirilebilir.</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;Adres</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>Yeni alım adresi</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>Yeni gönderi adresi</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>Alım adresini düzenle</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>Gönderi adresini düzenle</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>Girilen "%1" adresi hâlihazırda adres defterinde mevcuttur.</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is not a valid Bitcoin address.</source>
+ <translation>Girilen "%1" adresi geçerli bir Bitcoin adresi değildir.</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>Cüzdan kilidi açılamadı.</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>Yeni anahtar oluşturulması başarısız oldu.</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ <message>
+ <source>A new data directory will be created.</source>
+ <translation>Yeni bir veri klasörü oluşturulacaktır.</translation>
+ </message>
+ <message>
+ <source>name</source>
+ <translation>isim</translation>
+ </message>
+ <message>
+ <source>Directory already exists. Add %1 if you intend to create a new directory here.</source>
+ <translation>Klasör hâlihazırda mevcuttur. Burada yeni bir klasör oluşturmak istiyorsanız, %1 ilâve ediniz.</translation>
+ </message>
+ <message>
+ <source>Path already exists, and is not a directory.</source>
+ <translation>Erişim yolu zaten mevcuttur ve klasör değildir.</translation>
+ </message>
+ <message>
+ <source>Cannot create data directory here.</source>
+ <translation>Burada veri klasörü oluşturulamaz.</translation>
+ </message>
+</context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Çekirdeği</translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>sürüm</translation>
+ </message>
+ <message>
+ <source>(%1-bit)</source>
+ <translation>(%1-bit)</translation>
+ </message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>Bitcoin Çekirdeği hakkında</translation>
+ </message>
+ <message>
+ <source>Command-line options</source>
+ <translation>Komut satırı seçenekleri</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>Kullanım:</translation>
+ </message>
+ <message>
+ <source>command-line options</source>
+ <translation>komut satırı seçenekleri</translation>
+ </message>
+</context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Welcome</source>
+ <translation>Hoş geldiniz</translation>
+ </message>
+ <message>
+ <source>Welcome to Bitcoin Core.</source>
+ <translation>Bitcoin Çekirdeğine hoş geldiniz.</translation>
+ </message>
+ <message>
+ <source>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</source>
+ <translation>Bu programı ilk kez başlattığınızdan dolayı Bitcoin Çekirdeğinin verilerini nereye saklayacağını seçebilirsiniz.</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory.</source>
+ <translation>Bitcoin çekirdeği Bitcoin blok zincirinin bir kopyasını indirip saklayacaktır. Asgari %1GB bouyutunda veri bu klasörde saklanacak ve zamanla bu boyut artacaktır. Cüzdan da bu klasörde saklanacaktır. </translation>
+ </message>
+ <message>
+ <source>Use the default data directory</source>
+ <translation>Varsayılan veri klasörünü kullan</translation>
+ </message>
+ <message>
+ <source>Use a custom data directory:</source>
+ <translation>Özel bir veri klasörü kullan:</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Çekirdeği</translation>
+ </message>
+ <message>
+ <source>Error: Specified data directory "%1" cannot be created.</source>
+ <translation>Hata: belirtilen "%1" veri klasörü oluşturulamaz.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Hata</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n GB of free space available</source>
+ <translation><numerusform>%n GB boş alan mevcuttur</numerusform><numerusform>%n GB boş alan mevcuttur</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>(of %n GB needed)</source>
+ <translation><numerusform>(gereken %n GB alandan)</numerusform><numerusform>(gereken %n GB alandan)</numerusform></translation>
+ </message>
+</context>
+<context>
+ <name>OpenURIDialog</name>
+ <message>
+ <source>Open URI</source>
+ <translation>URI aç</translation>
+ </message>
+ <message>
+ <source>Open payment request from URI or file</source>
+ <translation>Dosyadan veya URI'den ödeme talebi aç</translation>
+ </message>
+ <message>
+ <source>URI:</source>
+ <translation>URI:</translation>
+ </message>
+ <message>
+ <source>Select payment request file</source>
+ <translation>Ödeme talebi dosyasını seç</translation>
+ </message>
+ <message>
+ <source>Select payment request file to open</source>
+ <translation>Açılacak ödeme talebi dosyasını seç</translation>
+ </message>
+</context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>Seçenekler</translation>
+ </message>
+ <message>
+ <source>&amp;Main</source>
+ <translation>&amp;Esas ayarlar</translation>
+ </message>
+ <message>
+ <source>Size of &amp;database cache</source>
+ <translation>&amp;Veritabanı tamponunun boyutu</translation>
+ </message>
+ <message>
+ <source>MB</source>
+ <translation>MB</translation>
+ </message>
+ <message>
+ <source>Number of script &amp;verification threads</source>
+ <translation>İş parçacıklarını &amp;denetleme betiği sayısı</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside</source>
+ <translation>Dışarıdan gelen bağlantıları kabul et</translation>
+ </message>
+ <message>
+ <source>Allow incoming connections</source>
+ <translation>Gelen bağlantılara izin ver</translation>
+ </message>
+ <message>
+ <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
+ <translation>Vekil sunucusunun IP adresi (mesela IPv4: 127.0.0.1 / IPv6: ::1)</translation>
+ </message>
+ <message>
+ <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source>
+ <translation>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.</translation>
+ </message>
+ <message>
+ <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source>
+ <translation>Kullanıcı arayüzünün dili burada belirtilebilir. Bu ayar Bitcoin Çekirdeği tekrar başlatıldığında etkinleşecektir.</translation>
+ </message>
+ <message>
+ <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source>
+ <translation>Muameleler sekmesinde bağlam menüsü unsurları olarak görünen üçüncü taraf bağlantıları (mesela bir blok tarayıcısı). URL'deki %s, muamele hash değeri ile değiştirilecektir. Birden çok bağlantılar düşey çubuklar | ile ayrılacaktır.</translation>
+ </message>
+ <message>
+ <source>Third party transaction URLs</source>
+ <translation>Üçüncü taraf muamele URL'leri</translation>
+ </message>
+ <message>
+ <source>Active command-line options that override above options:</source>
+ <translation>Yukarıdaki seçeneklerin yerine geçen faal komut satırı seçenekleri:</translation>
+ </message>
+ <message>
+ <source>Reset all client options to default.</source>
+ <translation>İstemcinin tüm seçeneklerini varsayılan değerlere geri al.</translation>
+ </message>
+ <message>
+ <source>&amp;Reset Options</source>
+ <translation>Seçenekleri Sıfı&amp;rla</translation>
+ </message>
+ <message>
+ <source>&amp;Network</source>
+ <translation>&amp;Şebeke</translation>
+ </message>
+ <message>
+ <source>Automatically start Bitcoin Core after logging in to the system.</source>
+ <translation>Sistemde oturum açıldığında Bitcoin Çekirdeğini otomatik olarak başlat.</translation>
+ </message>
+ <message>
+ <source>&amp;Start Bitcoin Core on system login</source>
+ <translation>Bitcoin Çekirdeğini sistem oturumuyla &amp;başlat</translation>
+ </message>
+ <message>
+ <source>(0 = auto, &lt;0 = leave that many cores free)</source>
+ <translation>(0 = otomatik, &lt;0 = bu kadar çekirdeği kullanma)</translation>
+ </message>
+ <message>
+ <source>W&amp;allet</source>
+ <translation>&amp;Cüzdan</translation>
+ </message>
+ <message>
+ <source>Expert</source>
+ <translation>Gelişmiş</translation>
+ </message>
+ <message>
+ <source>Enable coin &amp;control features</source>
+ <translation>Para &amp;kontrolü özelliklerini etkinleştir</translation>
+ </message>
+ <message>
+ <source>If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.</source>
+ <translation>Teyit edilmemiş para üstünü harcamayı devre dışı bırakırsanız, bir muamelenin para üstü bu muamele için en az bir teyit olana dek harcanamaz. Bu, aynı zamanda bakiyenizin nasıl hesaplandığını da etkiler.</translation>
+ </message>
+ <message>
+ <source>&amp;Spend unconfirmed change</source>
+ <translation>Teyit edilmemiş para üstünü &amp;harca</translation>
+ </message>
+ <message>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>Yönlendiricide Bitcoin istemci portlarını otomatik olarak açar. Bu, sadece yönlendiricinizin UPnP desteği bulunuyorsa ve etkinse çalışabilir.</translation>
+ </message>
+ <message>
+ <source>Map port using &amp;UPnP</source>
+ <translation>Portları &amp;UPnP kullanarak haritala</translation>
+ </message>
+ <message>
+ <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
+ <translation>Bitcoin şebekesine SOCKS5 vekil sunucusu vasıtasıyla bağlan.</translation>
+ </message>
+ <message>
+ <source>&amp;Connect through SOCKS5 proxy (default proxy):</source>
+ <translation>SOCKS5 vekil sunucusu vasıtasıyla &amp;bağlan (varsayılan vekil sunucusu):</translation>
+ </message>
+ <message>
+ <source>Proxy &amp;IP:</source>
+ <translation>Vekil &amp;İP:</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>&amp;Port:</translation>
+ </message>
+ <message>
+ <source>Port of the proxy (e.g. 9050)</source>
+ <translation>Vekil sunucunun portu (mesela 9050)</translation>
+ </message>
+ <message>
+ <source>&amp;Window</source>
+ <translation>&amp;Pencere</translation>
+ </message>
+ <message>
+ <source>Show only a tray icon after minimizing the window.</source>
+ <translation>Küçültüldükten sonra sadece çekmece ikonu göster.</translation>
+ </message>
+ <message>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>İşlem çubuğu yerine sistem çekmecesine &amp;küçült</translation>
+ </message>
+ <message>
+ <source>M&amp;inimize on close</source>
+ <translation>Kapatma sırasında k&amp;üçült</translation>
+ </message>
+ <message>
+ <source>&amp;Display</source>
+ <translation>&amp;Görünüm</translation>
+ </message>
+ <message>
+ <source>User Interface &amp;language:</source>
+ <translation>Kullanıcı arayüzü &amp;lisanı:</translation>
+ </message>
+ <message>
+ <source>&amp;Unit to show amounts in:</source>
+ <translation>Meblağları göstermek için &amp;birim:</translation>
+ </message>
+ <message>
+ <source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
+ <translation>Bitcoin gönderildiğinde arayüzde gösterilecek varsayılan alt birimi seçiniz.</translation>
+ </message>
+ <message>
+ <source>Whether to show coin control features or not.</source>
+ <translation>Para kontrol özelliklerinin gösterilip gösterilmeyeceğini ayarlar.</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>&amp;Tamam</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>&amp;İptal</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>varsayılan</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>boş</translation>
+ </message>
+ <message>
+ <source>Confirm options reset</source>
+ <translation>Seçeneklerin sıfırlanmasını teyit et</translation>
+ </message>
+ <message>
+ <source>Client restart required to activate changes.</source>
+ <translation>Değişikliklerin uygulanması için istemcinin yeniden başlatılması lazımdır.</translation>
+ </message>
+ <message>
+ <source>Client will be shut down. Do you want to proceed?</source>
+ <translation>İstemci kapanacaktır. Devam etmek istiyor musunuz?</translation>
+ </message>
+ <message>
+ <source>This change would require a client restart.</source>
+ <translation>Bu değişiklik istemcinin tekrar başlatılmasını gerektirir.</translation>
+ </message>
+ <message>
+ <source>The supplied proxy address is invalid.</source>
+ <translation>Girilen vekil sunucu adresi geçersizdir.</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>Form</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>Görüntülenen veriler zaman aşımına 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.</translation>
+ </message>
+ <message>
+ <source>Watch-only:</source>
+ <translation>Sadece-izlenen:</translation>
+ </message>
+ <message>
+ <source>Available:</source>
+ <translation>Mevcut:</translation>
+ </message>
+ <message>
+ <source>Your current spendable balance</source>
+ <translation>Güncel harcanabilir bakiyeniz</translation>
+ </message>
+ <message>
+ <source>Pending:</source>
+ <translation>Beklemede:</translation>
+ </message>
+ <message>
+ <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source>
+ <translation>Henüz teyit edilmemiş ve harcanabilir bakiyeye eklenmemiş muamelelerin toplamı</translation>
+ </message>
+ <message>
+ <source>Immature:</source>
+ <translation>Olgunlaşmamış:</translation>
+ </message>
+ <message>
+ <source>Mined balance that has not yet matured</source>
+ <translation>Oluşturulan bakiye henüz olgunlaşmamıştır</translation>
+ </message>
+ <message>
+ <source>Balances</source>
+ <translation>Bakiyeler</translation>
+ </message>
+ <message>
+ <source>Total:</source>
+ <translation>Toplam:</translation>
+ </message>
+ <message>
+ <source>Your current total balance</source>
+ <translation>Güncel toplam bakiyeniz</translation>
+ </message>
+ <message>
+ <source>Your current balance in watch-only addresses</source>
+ <translation>Sadece izlenen adreslerdeki güncel bakiyeniz</translation>
+ </message>
+ <message>
+ <source>Spendable:</source>
+ <translation>Harcanabilir:</translation>
+ </message>
+ <message>
+ <source>Recent transactions</source>
+ <translation>Son muameleler</translation>
+ </message>
+ <message>
+ <source>Unconfirmed transactions to watch-only addresses</source>
+ <translation>Sadece izlenen adreslere gelen teyit edilmemiş muameleler</translation>
+ </message>
+ <message>
+ <source>Mined balance in watch-only addresses that has not yet matured</source>
+ <translation>Sadece izlenen adreslerin henüz olgunlaşmamış oluşturulan bakiyeleri</translation>
+ </message>
+ <message>
+ <source>Current total balance in watch-only addresses</source>
+ <translation>Sadece izlenen adreslerdeki güncel toplam bakiye</translation>
+ </message>
+</context>
+<context>
+ <name>PaymentServer</name>
+ <message>
+ <source>URI handling</source>
+ <translation>URI yönetimi</translation>
+ </message>
+ <message>
+ <source>Invalid payment address %1</source>
+ <translation>Geçersiz ödeme adresi %1</translation>
+ </message>
+ <message>
+ <source>Payment request rejected</source>
+ <translation>Ödeme talebi reddedildi</translation>
+ </message>
+ <message>
+ <source>Payment request network doesn't match client network.</source>
+ <translation>Ödeme talebi şebekesi istemci şebekesine denk gelmiyor.</translation>
+ </message>
+ <message>
+ <source>Payment request is not initialized.</source>
+ <translation>Ödeme talebi başlatılmamış.</translation>
+ </message>
+ <message>
+ <source>Requested payment amount of %1 is too small (considered dust).</source>
+ <translation>Talep edilen %1 meblağında ödeme çok düşüktür (toz olarak kabul edilir).</translation>
+ </message>
+ <message>
+ <source>Payment request error</source>
+ <translation>Ödeme talebi hatası</translation>
+ </message>
+ <message>
+ <source>Cannot start bitcoin: click-to-pay handler</source>
+ <translation>Bitcoin başlatılamadı: tıkla-ve-öde yöneticisi</translation>
+ </message>
+ <message>
+ <source>Payment request fetch URL is invalid: %1</source>
+ <translation>Ödeme talebini alma URL'i geçersiz: %1</translation>
+ </message>
+ <message>
+ <source>URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source>
+ <translation>URI okunamadı! Sebebi geçersiz bir Bitcoin adresi veya hatalı URI parametreleri olabilir.</translation>
+ </message>
+ <message>
+ <source>Payment request file handling</source>
+ <translation>Ödeme talebi dosyası yönetimi</translation>
+ </message>
+ <message>
+ <source>Payment request file cannot be read! This can be caused by an invalid payment request file.</source>
+ <translation>Ödeme talebi okunamaz ya da işlenemez! Bunun sebebi geçersiz bir ödeme talebi dosyası olabilir.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>Ödeme talebinin ömrü doldu.</translation>
+ </message>
+ <message>
+ <source>Unverified payment requests to custom payment scripts are unsupported.</source>
+ <translation>Özel ödeme betiklerine teyit edilmemiş ödeme talepleri desteklenmez.</translation>
+ </message>
+ <message>
+ <source>Invalid payment request.</source>
+ <translation>Geçersiz ödeme talebi.</translation>
+ </message>
+ <message>
+ <source>Refund from %1</source>
+ <translation>%1 öğesinden iade</translation>
+ </message>
+ <message>
+ <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source>
+ <translation>%1 ödeme talebi çok büyük (%2 bayt, müsaade edilen %3 bayt).</translation>
+ </message>
+ <message>
+ <source>Payment request DoS protection</source>
+ <translation>Ödeme talebi DoS koruması</translation>
+ </message>
+ <message>
+ <source>Error communicating with %1: %2</source>
+ <translation>%1 ile iletişimde hata: %2</translation>
+ </message>
+ <message>
+ <source>Payment request cannot be parsed!</source>
+ <translation>Ödeme talebi ayrıştırılamaz!</translation>
+ </message>
+ <message>
+ <source>Bad response from server %1</source>
+ <translation>%1 sunucusundan hatalı cevap</translation>
+ </message>
+ <message>
+ <source>Payment acknowledged</source>
+ <translation>Ödeme teyit edildi</translation>
+ </message>
+ <message>
+ <source>Network request error</source>
+ <translation>Şebeke talebi hatası</translation>
+ </message>
+</context>
+<context>
+ <name>PeerTableModel</name>
+ <message>
+ <source>User Agent</source>
+ <translation>Kullanıcı Yazılımı</translation>
+ </message>
+ <message>
+ <source>Node/Service</source>
+ <translation>Düğüm/Servis</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Ping Süresi</translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>Meblağ</translation>
+ </message>
+ <message>
+ <source>Enter a Bitcoin address (e.g. %1)</source>
+ <translation>Bir Bitcoin adresi giriniz (mesela %1)</translation>
+ </message>
+ <message>
+ <source>%1 d</source>
+ <translation>%1 g</translation>
+ </message>
+ <message>
+ <source>%1 h</source>
+ <translation>%1 s</translation>
+ </message>
+ <message>
+ <source>%1 m</source>
+ <translation>%1 d</translation>
+ </message>
+ <message>
+ <source>%1 s</source>
+ <translation>%1 s</translation>
+ </message>
+ <message>
+ <source>None</source>
+ <translation>Boş</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>Mevcut değil</translation>
+ </message>
+ <message>
+ <source>%1 ms</source>
+ <translation>%1 ms</translation>
+ </message>
+</context>
+<context>
+ <name>QRImageWidget</name>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>Resmi k&amp;aydet...</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Image</source>
+ <translation>Resmi &amp;kopyala</translation>
+ </message>
+ <message>
+ <source>Save QR Code</source>
+ <translation>QR kodu kaydet</translation>
+ </message>
+ <message>
+ <source>PNG Image (*.png)</source>
+ <translation>PNG resim (*.png)</translation>
+ </message>
+</context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>Client name</source>
+ <translation>İstemci ismi</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>Mevcut değil</translation>
+ </message>
+ <message>
+ <source>Client version</source>
+ <translation>İstemci sürümü</translation>
+ </message>
+ <message>
+ <source>&amp;Information</source>
+ <translation>&amp;Malumat</translation>
+ </message>
+ <message>
+ <source>Debug window</source>
+ <translation>Hata ayıklama penceresi</translation>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>Genel</translation>
+ </message>
+ <message>
+ <source>Using OpenSSL version</source>
+ <translation>Kullanılan OpenSSL sürümü</translation>
+ </message>
+ <message>
+ <source>Using BerkeleyDB version</source>
+ <translation>Kullanılan BerkeleyDB sürümü</translation>
+ </message>
+ <message>
+ <source>Startup time</source>
+ <translation>Başlama zamanı</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Şebeke</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>İsim</translation>
+ </message>
+ <message>
+ <source>Number of connections</source>
+ <translation>Bağlantı sayısı</translation>
+ </message>
+ <message>
+ <source>Block chain</source>
+ <translation>Blok zinciri</translation>
+ </message>
+ <message>
+ <source>Current number of blocks</source>
+ <translation>Güncel blok sayısı</translation>
+ </message>
+ <message>
+ <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source>
+ <translation>Güncel veri klasöründen Bitcoin Çekirdeği hata ayıklama kütük dosyasını açar. Büyük kütük dosyaları için bu birkaç saniye alabilir.</translation>
+ </message>
+ <message>
+ <source>Received</source>
+ <translation>Alınan</translation>
+ </message>
+ <message>
+ <source>Sent</source>
+ <translation>Yollanan</translation>
+ </message>
+ <message>
+ <source>&amp;Peers</source>
+ <translation>&amp;Eşler</translation>
+ </message>
+ <message>
+ <source>Select a peer to view detailed information.</source>
+ <translation>Ayrıntılı bilgi görmek için bir eş seçin.</translation>
+ </message>
+ <message>
+ <source>Direction</source>
+ <translation>Yön</translation>
+ </message>
+ <message>
+ <source>Version</source>
+ <translation>Sürüm</translation>
+ </message>
+ <message>
+ <source>User Agent</source>
+ <translation>Kullanıcı Yazılımı</translation>
+ </message>
+ <message>
+ <source>Services</source>
+ <translation>Servisler</translation>
+ </message>
+ <message>
+ <source>Starting Height</source>
+ <translation>Başlama Yüksekliği</translation>
+ </message>
+ <message>
+ <source>Sync Height</source>
+ <translation>Eşleşme Yüksekliği</translation>
+ </message>
+ <message>
+ <source>Ban Score</source>
+ <translation>Yasaklama Skoru</translation>
+ </message>
+ <message>
+ <source>Connection Time</source>
+ <translation>Bağlantı Süresi</translation>
+ </message>
+ <message>
+ <source>Last Send</source>
+ <translation>Son Gönderme</translation>
+ </message>
+ <message>
+ <source>Last Receive</source>
+ <translation>Son Alma</translation>
+ </message>
+ <message>
+ <source>Bytes Sent</source>
+ <translation>Yollanan Baytlar</translation>
+ </message>
+ <message>
+ <source>Bytes Received</source>
+ <translation>Alınan Baytlar</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Ping Süresi</translation>
+ </message>
+ <message>
+ <source>Time Offset</source>
+ <translation>Saat Farkı</translation>
+ </message>
+ <message>
+ <source>Last block time</source>
+ <translation>Son blok zamanı</translation>
+ </message>
+ <message>
+ <source>&amp;Open</source>
+ <translation>&amp;Aç</translation>
+ </message>
+ <message>
+ <source>&amp;Console</source>
+ <translation>&amp;Konsol</translation>
+ </message>
+ <message>
+ <source>&amp;Network Traffic</source>
+ <translation>&amp;Şebeke trafiği</translation>
+ </message>
+ <message>
+ <source>&amp;Clear</source>
+ <translation>&amp;Temizle</translation>
+ </message>
+ <message>
+ <source>Totals</source>
+ <translation>Toplamlar</translation>
+ </message>
+ <message>
+ <source>In:</source>
+ <translation>İçeri:</translation>
+ </message>
+ <message>
+ <source>Out:</source>
+ <translation>Dışarı:</translation>
+ </message>
+ <message>
+ <source>Build date</source>
+ <translation>Derleme tarihi</translation>
+ </message>
+ <message>
+ <source>Debug log file</source>
+ <translation>Hata ayıklama kütük dosyası</translation>
+ </message>
+ <message>
+ <source>Clear console</source>
+ <translation>Konsolu temizle</translation>
+ </message>
+ <message>
+ <source>Welcome to the Bitcoin Core RPC console.</source>
+ <translation>Bitcoin Çekirdeği RPC konsoluna hoş geldiniz.</translation>
+ </message>
+ <message>
+ <source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
+ <translation>Tarihçede gezinmek için imleç tuşlarını kullanınız, &lt;b&gt;Ctrl-L&lt;/b&gt; ile de ekranı temizleyebilirsiniz.</translation>
+ </message>
+ <message>
+ <source>Type &lt;b&gt;help&lt;/b&gt; for an overview of available commands.</source>
+ <translation>Mevcut komutların listesi için &lt;b&gt;help&lt;/b&gt; yazınız.</translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation>%1 B</translation>
+ </message>
+ <message>
+ <source>%1 KB</source>
+ <translation>%1 KB</translation>
+ </message>
+ <message>
+ <source>%1 MB</source>
+ <translation>%1 MB</translation>
+ </message>
+ <message>
+ <source>%1 GB</source>
+ <translation>%1 GB</translation>
+ </message>
+ <message>
+ <source>via %1</source>
+ <translation>%1 vasıtasıyla</translation>
+ </message>
+ <message>
+ <source>never</source>
+ <translation>asla</translation>
+ </message>
+ <message>
+ <source>Inbound</source>
+ <translation>Gelen</translation>
+ </message>
+ <message>
+ <source>Outbound</source>
+ <translation>Giden</translation>
+ </message>
+ <message>
+ <source>Unknown</source>
+ <translation>Bilinmiyor</translation>
+ </message>
+ <message>
+ <source>Fetching...</source>
+ <translation>Alınıyor...</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Amount:</source>
+ <translation>&amp;Meblağ:</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Etiket:</translation>
+ </message>
+ <message>
+ <source>&amp;Message:</source>
+ <translation>Me&amp;saj:</translation>
+ </message>
+ <message>
+ <source>Reuse one of the previously used receiving addresses. Reusing addresses has security and privacy issues. Do not use this unless re-generating a payment request made before.</source>
+ <translation>Daha önce kullanılmış bir alım adresini kullan. Adresleri tekrar kullanmak güvenlik ve gizlilik sorunları doğurur. Bunu, daha önce yaptığınız bir talebi tekrar oluşturmak durumu dışında kullanmayınız.</translation>
+ </message>
+ <message>
+ <source>R&amp;euse an existing receiving address (not recommended)</source>
+ <translation>&amp;Hâlihazırda bulunan bir alım adresini kullan (önerilmez)</translation>
+ </message>
+ <message>
+ <source>An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network.</source>
+ <translation>Talep açıldığında gösterilecek, isteğinize dayalı, ödeme talebi ile ilişkilendirilecek bir mesaj. Not: Bu mesaj ödeme ile birlikte Bitcoin şebekesi üzerinden gönderilmeyecektir.</translation>
+ </message>
+ <message>
+ <source>An optional label to associate with the new receiving address.</source>
+ <translation>Yeni alım adresi ile ilişkili, seçiminize dayalı etiket.</translation>
+ </message>
+ <message>
+ <source>Use this form to request payments. All fields are &lt;b&gt;optional&lt;/b&gt;.</source>
+ <translation>Ödeme talep etmek için bu formu kullanın. Tüm alanlar &lt;b&gt;seçime dayalıdır&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>An optional amount to request. Leave this empty or zero to not request a specific amount.</source>
+ <translation>Seçiminize dayalı talep edilecek meblağ. Belli bir meblağ talep etmemek için bunu boş bırakın veya sıfır değerini kullanın.</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Formdaki tüm alanları temizle.</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation>Temizle</translation>
+ </message>
+ <message>
+ <source>Requested payments history</source>
+ <translation>Talep edilen ödemelerin tarihçesi</translation>
+ </message>
+ <message>
+ <source>&amp;Request payment</source>
+ <translation>Ödeme &amp;talep et</translation>
+ </message>
+ <message>
+ <source>Show the selected request (does the same as double clicking an entry)</source>
+ <translation>Seçilen talebi göster (bir unsura çift tıklamakla aynı anlama gelir)</translation>
+ </message>
+ <message>
+ <source>Show</source>
+ <translation>Göster</translation>
+ </message>
+ <message>
+ <source>Remove the selected entries from the list</source>
+ <translation>Seçilen unsurları listeden kaldır</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>Kaldır</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Etiketi kopyala</translation>
+ </message>
+ <message>
+ <source>Copy message</source>
+ <translation>Mesajı kopyala</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Meblağı kopyala</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>QR Code</source>
+ <translation>QR Kodu</translation>
+ </message>
+ <message>
+ <source>Copy &amp;URI</source>
+ <translation>&amp;URI'yi kopyala</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Address</source>
+ <translation>&amp;Adresi kopyala</translation>
+ </message>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>Resmi ka&amp;ydet...</translation>
+ </message>
+ <message>
+ <source>Request payment to %1</source>
+ <translation>%1 unsuruna ödeme talep et</translation>
+ </message>
+ <message>
+ <source>Payment information</source>
+ <translation>Ödeme bilgisi</translation>
+ </message>
+ <message>
+ <source>URI</source>
+ <translation>URI</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adres</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Meblağ</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiket</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Mesaj</translation>
+ </message>
+ <message>
+ <source>Resulting URI too long, try to reduce the text for label / message.</source>
+ <translation>Sonuç URI çok uzun, etiket ya da mesaj metnini kısaltmayı deneyiniz.</translation>
+ </message>
+ <message>
+ <source>Error encoding URI into QR Code.</source>
+ <translation>URI'nin QR koduna kodlanmasında hata oluştu.</translation>
+ </message>
+</context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Tarih</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiket</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Mesaj</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Meblağ</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(boş etiket)</translation>
+ </message>
+ <message>
+ <source>(no message)</source>
+ <translation>(boş mesaj)</translation>
+ </message>
+ <message>
+ <source>(no amount)</source>
+ <translation>(boş meblağ)</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Bitcoin yolla</translation>
+ </message>
+ <message>
+ <source>Coin Control Features</source>
+ <translation>Para kontrolü özellikleri</translation>
+ </message>
+ <message>
+ <source>Inputs...</source>
+ <translation>Girdiler...</translation>
+ </message>
+ <message>
+ <source>automatically selected</source>
+ <translation>otomatik seçilmiş</translation>
+ </message>
+ <message>
+ <source>Insufficient funds!</source>
+ <translation>Yetersiz fon!</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Miktar:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Bayt:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Meblağ:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Öncelik:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Ücret:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Ücretten sonra:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Para üstü:</translation>
+ </message>
+ <message>
+ <source>If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address.</source>
+ <translation>Bu etkinleştirildiyse fakat para üstü adresi boş ya da geçersizse para üstü yeni oluşturulan bir adrese gönderilecektir.</translation>
+ </message>
+ <message>
+ <source>Custom change address</source>
+ <translation>Özel para üstü adresi</translation>
+ </message>
+ <message>
+ <source>Transaction Fee:</source>
+ <translation>Muamele ücreti:</translation>
+ </message>
+ <message>
+ <source>Choose...</source>
+ <translation>Seç...</translation>
+ </message>
+ <message>
+ <source>collapse fee-settings</source>
+ <translation>ücret-ayarlarını-küçült</translation>
+ </message>
+ <message>
+ <source>per kilobyte</source>
+ <translation>kilobayt başı</translation>
+ </message>
+ <message>
+ <source>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "total at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source>
+ <translation>Eğer özel ücret 1000 satoşi olarak ayarlandıysa ve muamele sadece 250 baytsa, "kilobayt başı" ücret olarak sadece 250 satoşi öder ve "toplam asgari" 1000 satoşi öder. Bir kilobayttan yüksek muameleler için ikisi de kilobayt başı ödeme yapar.</translation>
+ </message>
+ <message>
+ <source>Hide</source>
+ <translation>Sakla</translation>
+ </message>
+ <message>
+ <source>total at least</source>
+ <translation>toplam asgari</translation>
+ </message>
+ <message>
+ <source>Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process.</source>
+ <translation>Asgari ücreti ödemek, bloklarda boşluktan daha az muamele hacmi olduğu sürece bir sorun çıkarmaz. Fakat şebekenin işleyecebileceğinden daha çok bitcoin muameleleri talebi olduğunda bunun asla teyit edilmeyen bir muamele olabileceğinin farkında olmalısınız.</translation>
+ </message>
+ <message>
+ <source>(read the tooltip)</source>
+ <translation>(bilgi balonunu oku)</translation>
+ </message>
+ <message>
+ <source>Recommended:</source>
+ <translation>Tavsiye edilen:</translation>
+ </message>
+ <message>
+ <source>Custom:</source>
+ <translation>Özel:</translation>
+ </message>
+ <message>
+ <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source>
+ <translation>(Zeki ücret henüz başlatılmadı. Bu genelde birkaç blok alır...)</translation>
+ </message>
+ <message>
+ <source>Confirmation time:</source>
+ <translation>Teyit süresi:</translation>
+ </message>
+ <message>
+ <source>normal</source>
+ <translation>normal</translation>
+ </message>
+ <message>
+ <source>fast</source>
+ <translation>çabuk</translation>
+ </message>
+ <message>
+ <source>Send as zero-fee transaction if possible</source>
+ <translation>Mümkünse ücretsiz muamele olarak gönder</translation>
+ </message>
+ <message>
+ <source>(confirmation may take longer)</source>
+ <translation>(teyit daha uzun süre alabilir)</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>Birçok alıcıya aynı anda gönder</translation>
+ </message>
+ <message>
+ <source>Add &amp;Recipient</source>
+ <translation>&amp;Alıcı ekle</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Formdaki tüm alanları temizle.</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Toz:</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Tümünü &amp;temizle</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>Bakiye:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>Yollama etkinliğini teyit ediniz</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>G&amp;önder</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>Gönderiyi teyit ediniz</translation>
+ </message>
+ <message>
+ <source>%1 to %2</source>
+ <translation>%1 öğesinden %2 unsuruna</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Miktarı kopyala</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Meblağı kopyala</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Ücreti kopyala</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Ücretten sonrakini kopyala</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Baytları kopyala</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Önceliği kopyala</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Para üstünü kopyala</translation>
+ </message>
+ <message>
+ <source>or</source>
+ <translation>veya</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>Ödeyeceğiniz tutarın sıfırdan yüksek olması gerekir.</translation>
+ </message>
+ <message>
+ <source>The amount exceeds your balance.</source>
+ <translation>Tutar bakiyenizden yüksektir.</translation>
+ </message>
+ <message>
+ <source>The total exceeds your balance when the %1 transaction fee is included.</source>
+ <translation>Toplam, %1 muamele ücreti ilâve edildiğinde bakiyenizi geçmektedir.</translation>
+ </message>
+ <message>
+ <source>Transaction creation failed!</source>
+ <translation>Muamelenin oluşturulması başarısız oldu!</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>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.</translation>
+ </message>
+ <message>
+ <source>A fee higher than %1 is considered an absurdly high fee.</source>
+ <translation>%1 tutarından yüksek ücret saçma derecede yüksek bir ücret olarak kabul edilir.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>Ödeme talebinin ömrü doldu.</translation>
+ </message>
+ <message>
+ <source>Pay only the minimum fee of %1</source>
+ <translation>Sadece asgari ücret olan %1 tutarını öde</translation>
+ </message>
+ <message>
+ <source>The recipient address is not valid. Please recheck.</source>
+ <translation>Alıcı adresi geçerli değildir. Lütfen denetleyiniz.</translation>
+ </message>
+ <message>
+ <source>Duplicate address found: addresses should only be used once each.</source>
+ <translation>Çift adres bulundu: adresler herbiri için sadece bir kez kullanılmalıdır.</translation>
+ </message>
+ <message>
+ <source>Warning: Invalid Bitcoin address</source>
+ <translation>Uyarı: geçersiz Bitcoin adresi</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(boş etiket)</translation>
+ </message>
+ <message>
+ <source>Warning: Unknown change address</source>
+ <translation>Uyarı: geçersiz para üstü adresi</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Tozu kopyala</translation>
+ </message>
+ <message>
+ <source>Are you sure you want to send?</source>
+ <translation>Göndermek istediğinizden emin misiniz?</translation>
+ </message>
+ <message>
+ <source>added as transaction fee</source>
+ <translation>muamele ücreti olarak eklendi</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>Mebla&amp;ğ:</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>&amp;Şu adrese öde:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Adres defterinize eklemek için bu adrese ilişik bir etiket giriniz</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Etiket:</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Önceden kullanılmış adres seç</translation>
+ </message>
+ <message>
+ <source>This is a normal payment.</source>
+ <translation>Bu, normal bir ödemedir.</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to send the payment to</source>
+ <translation>Ödemenin yollanacağı Bitcoin adresi</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Panodan adres yapıştır</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Remove this entry</source>
+ <translation>Bu unsuru kaldır</translation>
+ </message>
+ <message>
+ <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source>
+ <translation>Ücret yollanan meblağdan alınacaktır. Alıcı meblağ alanında girdiğinizden daha az bitcoin alacaktır. Eğer birden çok alıcı seçiliyse ücret eşit olarak bölünecektir.</translation>
+ </message>
+ <message>
+ <source>S&amp;ubtract fee from amount</source>
+ <translation>Ücreti meblağdan düş</translation>
+ </message>
+ <message>
+ <source>Message:</source>
+ <translation>Mesaj:</translation>
+ </message>
+ <message>
+ <source>This is an unauthenticated payment request.</source>
+ <translation>Bu, kimliği doğrulanmamış bir ödeme talebidir.</translation>
+ </message>
+ <message>
+ <source>This is an authenticated payment request.</source>
+ <translation>Bu, kimliği doğrulanmış bir ödeme talebidir.</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to the list of used addresses</source>
+ <translation>Kullanılmış adres listesine eklemek için bu adrese bir etiket girin</translation>
+ </message>
+ <message>
+ <source>A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network.</source>
+ <translation>Bitcoin: URI'siyle ilişkili ve bilginiz için muameleyle saklanacak bir mesaj. Not: Bu mesaj Bitcoin şebekesi üzerinden gönderilmeyecektir.</translation>
+ </message>
+ <message>
+ <source>Pay To:</source>
+ <translation>Şu adrese öde:</translation>
+ </message>
+ <message>
+ <source>Memo:</source>
+ <translation>Not:</translation>
+ </message>
+</context>
+<context>
+ <name>ShutdownWindow</name>
+ <message>
+ <source>Bitcoin Core is shutting down...</source>
+ <translation>Bitcoin Çekirdeği kapanıyor...</translation>
+ </message>
+ <message>
+ <source>Do not shut down the computer until this window disappears.</source>
+ <translation>Bu pencere kalkıncaya dek bilgisayarı kapatmayınız.</translation>
+ </message>
+</context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Signatures - Sign / Verify a Message</source>
+ <translation>İmzalar - Mesaj İmzala / Kontrol et</translation>
+ </message>
+ <message>
+ <source>&amp;Sign Message</source>
+ <translation>Mesaj &amp;imzala</translation>
+ </message>
+ <message>
+ <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source>
+ <translation>Adreslerinize yollanan bitcoinleri alabileceğiniz ispatlamak için adreslerinizle mesaj/anlaşma imzalayabilirsiniz. Oltalama saldırılarının kimliğinizi imzanızla elde etmeyi deneyebilecekleri için belirsiz ya da rastgele hiçbir şey imzalamamaya dikkat ediniz. Sadece ayrıntılı açıklaması olan ve tümüne katıldığınız ifadeleri imzalayınız.</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to sign the message with</source>
+ <translation>Mesajın imzalanmasında kullanılacak Bitcoin adresi</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Önceden kullanılmış adres seç</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Panodan adres yapıştır</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Enter the message you want to sign here</source>
+ <translation>İmzalamak istediğiniz mesajı burada giriniz</translation>
+ </message>
+ <message>
+ <source>Signature</source>
+ <translation>İmza</translation>
+ </message>
+ <message>
+ <source>Copy the current signature to the system clipboard</source>
+ <translation>Güncel imzayı sistem panosuna kopyala</translation>
+ </message>
+ <message>
+ <source>Sign the message to prove you own this Bitcoin address</source>
+ <translation>Bu Bitcoin adresinin sizin olduğunu ispatlamak için mesajı imzalayın</translation>
+ </message>
+ <message>
+ <source>Sign &amp;Message</source>
+ <translation>&amp;Mesajı imzala</translation>
+ </message>
+ <message>
+ <source>Reset all sign message fields</source>
+ <translation>Tüm mesaj alanlarını sıfırla</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Tümünü &amp;temizle</translation>
+ </message>
+ <message>
+ <source>&amp;Verify Message</source>
+ <translation>Mesaj &amp;kontrol et</translation>
+ </message>
+ <message>
+ <source>Enter the receiver's 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. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source>
+ <translation>Alıcının adresini, mesajı (satır sonları, boşluklar, sekmeler vs. karakterleri tam olarak kopyaladığınızdan emin olunuz) ve imzayı aşağıda giriniz. Bir ortadaki adam saldırısı tarafından kandırılmaya mâni olmak için imzadan, imzalı mesajın içeriğini aşan bir anlam çıkarmamaya dikkat ediniz. Bunun sadece imzalayan tarafın adres ile alım yapabildiğini ispatladığını ve herhangi bir muamelenin gönderi tarafını kanıtlayamayacağını unutmayınız!</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address the message was signed with</source>
+ <translation>Mesajın imzalanmasında kullanılan Bitcoin adresi</translation>
+ </message>
+ <message>
+ <source>Verify the message to ensure it was signed with the specified Bitcoin address</source>
+ <translation>Belirtilen Bitcoin adresi ile imzalandığını doğrulamak için mesajı kontrol et</translation>
+ </message>
+ <message>
+ <source>Verify &amp;Message</source>
+ <translation>&amp;Mesaj kontrol et</translation>
+ </message>
+ <message>
+ <source>Reset all verify message fields</source>
+ <translation>Tüm mesaj kontrolü alanlarını sıfırla</translation>
+ </message>
+ <message>
+ <source>Click "Sign Message" to generate signature</source>
+ <translation>İmzayı oluşturmak için "Mesaj İmzala" unsurunu tıklayın</translation>
+ </message>
+ <message>
+ <source>The entered address is invalid.</source>
+ <translation>Girilen adres geçersizdir.</translation>
+ </message>
+ <message>
+ <source>Please check the address and try again.</source>
+ <translation>Adresi kontrol edip tekrar deneyiniz.</translation>
+ </message>
+ <message>
+ <source>The entered address does not refer to a key.</source>
+ <translation>Girilen adres herhangi bir anahtara işaret etmemektedir.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock was cancelled.</source>
+ <translation>Cüzdan kilidinin açılması iptal edildi.</translation>
+ </message>
+ <message>
+ <source>Private key for the entered address is not available.</source>
+ <translation>Girilen adres için özel anahtar mevcut değildir.</translation>
+ </message>
+ <message>
+ <source>Message signing failed.</source>
+ <translation>Mesajın imzalanması başarısız oldu.</translation>
+ </message>
+ <message>
+ <source>Message signed.</source>
+ <translation>Mesaj imzalandı.</translation>
+ </message>
+ <message>
+ <source>The signature could not be decoded.</source>
+ <translation>İmzanın kodu çözülemedi.</translation>
+ </message>
+ <message>
+ <source>Please check the signature and try again.</source>
+ <translation>İmzayı kontrol edip tekrar deneyiniz.</translation>
+ </message>
+ <message>
+ <source>The signature did not match the message digest.</source>
+ <translation>İmza mesajın hash değeri ile eşleşmedi.</translation>
+ </message>
+ <message>
+ <source>Message verification failed.</source>
+ <translation>Mesaj doğrulaması başarısız oldu.</translation>
+ </message>
+ <message>
+ <source>Message verified.</source>
+ <translation>Mesaj doğrulandı.</translation>
+ </message>
+</context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Çekirdeği</translation>
+ </message>
+ <message>
+ <source>The Bitcoin Core developers</source>
+ <translation>Bitcoin Çekirdeği geliştiricileri</translation>
+ </message>
+ <message>
+ <source>[testnet]</source>
+ <translation>[testnet]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ <message>
+ <source>KB/s</source>
+ <translation>KB/s</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>%1 değerine dek açık</translation>
+ </message>
+ <message>
+ <source>conflicted</source>
+ <translation>çakışma</translation>
+ </message>
+ <message>
+ <source>%1/offline</source>
+ <translation>%1/çevrim dışı</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/doğrulanmadı</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 teyit</translation>
+ </message>
+ <message>
+ <source>Status</source>
+ <translation>Durum</translation>
+ </message>
+ <message numerus="yes">
+ <source>, broadcast through %n node(s)</source>
+ <translation><numerusform>, %n düğüm vasıtasıyla yayınlandı</numerusform><numerusform>, %n düğüm vasıtasıyla yayınlandı</numerusform></translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Tarih</translation>
+ </message>
+ <message>
+ <source>Source</source>
+ <translation>Kaynak</translation>
+ </message>
+ <message>
+ <source>Generated</source>
+ <translation>Oluşturuldu</translation>
+ </message>
+ <message>
+ <source>From</source>
+ <translation>Gönderen</translation>
+ </message>
+ <message>
+ <source>To</source>
+ <translation>Alıcı</translation>
+ </message>
+ <message>
+ <source>own address</source>
+ <translation>kendi adresiniz</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>sadece-izlenen</translation>
+ </message>
+ <message>
+ <source>label</source>
+ <translation>etiket</translation>
+ </message>
+ <message>
+ <source>Credit</source>
+ <translation>Gider</translation>
+ </message>
+ <message numerus="yes">
+ <source>matures in %n more block(s)</source>
+ <translation><numerusform>%n ek blok sonrasında olgunlaşacak</numerusform><numerusform>%n ek blok sonrasında olgunlaşacak</numerusform></translation>
+ </message>
+ <message>
+ <source>not accepted</source>
+ <translation>kabul edilmedi</translation>
+ </message>
+ <message>
+ <source>Debit</source>
+ <translation>Gelir</translation>
+ </message>
+ <message>
+ <source>Total debit</source>
+ <translation>Toplam gider</translation>
+ </message>
+ <message>
+ <source>Total credit</source>
+ <translation>Toplam gelir</translation>
+ </message>
+ <message>
+ <source>Transaction fee</source>
+ <translation>Muamele ücreti</translation>
+ </message>
+ <message>
+ <source>Net amount</source>
+ <translation>Net meblağ</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Mesaj</translation>
+ </message>
+ <message>
+ <source>Comment</source>
+ <translation>Yorum</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>Muamele tanımlayıcı</translation>
+ </message>
+ <message>
+ <source>Merchant</source>
+ <translation>Tüccar</translation>
+ </message>
+ <message>
+ <source>Generated coins must mature %1 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.</source>
+ <translation>Oluşturulan bitcoin'lerin harcanabilmelerinden önce %1 blok beklemeleri gerekmektedir. Bu blok, oluşturduğunuzda, blok zincirine eklenmesi için ağda yayınlandı. Zincire eklenmesi başarısız olursa, durumu "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.</translation>
+ </message>
+ <message>
+ <source>Debug information</source>
+ <translation>Hata ayıklama verileri</translation>
+ </message>
+ <message>
+ <source>Transaction</source>
+ <translation>Muamele</translation>
+ </message>
+ <message>
+ <source>Inputs</source>
+ <translation>Girdiler</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Meblağ</translation>
+ </message>
+ <message>
+ <source>true</source>
+ <translation>doğru</translation>
+ </message>
+ <message>
+ <source>false</source>
+ <translation>yanlış</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, henüz başarılı bir şekilde yayınlanmadı</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>%n ilâve blok için açık</numerusform><numerusform>%n ilâve blok için açık</numerusform></translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>bilinmiyor</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>Muamele detayları</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>Bu pano muamelenin ayrıntılı açıklamasını gösterir</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Tarih</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Tür</translation>
+ </message>
+ <message>
+ <source>Immature (%1 confirmations, will be available after %2)</source>
+ <translation>Olgunlaşmamış (%1 teyit, %2 teyit ardından kullanılabilir olacaktır)</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>%n ilâve blok için açık</numerusform><numerusform>%n ilâve blok için açık</numerusform></translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>%1 değerine dek açık</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>Doğrulandı (%1 teyit)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>Bu blok başka hiçbir düğüm tarafından alınmamıştır ve muhtemelen kabul edilmeyecektir!</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>Oluşturuldu ama kabul edilmedi</translation>
+ </message>
+ <message>
+ <source>Offline</source>
+ <translation>Çevrim dışı</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiket</translation>
+ </message>
+ <message>
+ <source>Unconfirmed</source>
+ <translation>Teyit edilmemiş</translation>
+ </message>
+ <message>
+ <source>Confirming (%1 of %2 recommended confirmations)</source>
+ <translation>Teyit ediliyor (tavsiye edilen %2 teyit üzerinden %1 doğrulama)</translation>
+ </message>
+ <message>
+ <source>Conflicted</source>
+ <translation>Çakışma</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Şununla alındı</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>Alındığı kişi</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Gönderildiği adres</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>Kendinize ödeme</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Madenden çıkarılan</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>sadece-izlenen</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(mevcut değil)</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>Muamele durumu. Doğrulama sayısını görüntülemek için imleci bu alanda tutunuz.</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Muamelenin alındığı tarih ve zaman.</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>Muamele türü.</translation>
+ </message>
+ <message>
+ <source>Whether or not a watch-only address is involved in this transaction.</source>
+ <translation>Bu muamelede sadece izlenen bir adresin bulunup bulunmadığı.</translation>
+ </message>
+ <message>
+ <source>User-defined intent/purpose of the transaction.</source>
+ <translation>Muamelenin kullanıcı tanımlı niyeti/amacı.</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>Bakiyeden alınan ya da bakiyeye eklenen meblağ.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>Hepsi</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>Bugün</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>Bu hafta</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>Bu ay</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>Geçen ay</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>Bu sene</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>Aralık...</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Şununla alınan</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Gönderildiği adres</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>Kendinize</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Oluşturulan</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>Diğer</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>Aranacak adres ya da etiket giriniz</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>Asgari meblağ</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Adresi kopyala</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Etiketi kopyala</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Meblağı kopyala</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Muamele kimliğini kopyala</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>Etiketi düzenle</translation>
+ </message>
+ <message>
+ <source>Show transaction details</source>
+ <translation>Muamele detaylarını göster</translation>
+ </message>
+ <message>
+ <source>Export Transaction History</source>
+ <translation>Muamele tarihçesini dışa aktar</translation>
+ </message>
+ <message>
+ <source>Watch-only</source>
+ <translation>Sadece izlenen</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Dışa aktarım başarısız oldu</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the transaction history to %1.</source>
+ <translation>Muamele tarihçesinin %1 konumuna kaydedilmesi sırasında bir hata meydana geldi.</translation>
+ </message>
+ <message>
+ <source>Exporting Successful</source>
+ <translation>Dışa aktarım başarılı oldu</translation>
+ </message>
+ <message>
+ <source>The transaction history was successfully saved to %1.</source>
+ <translation>Muamele tarihçesi başarılı bir şekilde %1 konumuna kaydedildi.</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Virgülle ayrılmış değerler dosyası (*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Doğrulandı</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Tarih</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Tür</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Etiket</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Adres</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>Tanımlayıcı</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>Aralık:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>ilâ</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ <message>
+ <source>Unit to show amounts in. Click to select another unit.</source>
+ <translation>Meblağları göstermek için birim. Başka bir birim seçmek için tıklayınız.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletFrame</name>
+ <message>
+ <source>No wallet has been loaded.</source>
+ <translation>Hiçbir cüzdan yüklenmemiştir.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Bitcoin yolla</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Dışa aktar</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Güncel sekmedeki verileri bir dosyaya aktar</translation>
+ </message>
+ <message>
+ <source>Backup Wallet</source>
+ <translation>Cüzdanı Yedekle</translation>
+ </message>
+ <message>
+ <source>Wallet Data (*.dat)</source>
+ <translation>Cüzdan verileri (*.dat)</translation>
+ </message>
+ <message>
+ <source>Backup Failed</source>
+ <translation>Yedekleme başarısız oldu</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the wallet data to %1.</source>
+ <translation>Cüzdan verilerinin %1 konumuna kaydedilmesi sırasında bir hata meydana geldi.</translation>
+ </message>
+ <message>
+ <source>The wallet data was successfully saved to %1.</source>
+ <translation>Cüzdan verileri %1 konumuna başarıyla kaydedildi.</translation>
+ </message>
+ <message>
+ <source>Backup Successful</source>
+ <translation>Yedekleme başarılı</translation>
+ </message>
+</context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>Seçenekler:</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>Veri dizinini belirt</translation>
+ </message>
+ <message>
+ <source>Connect to a node to retrieve peer addresses, and disconnect</source>
+ <translation>Eş adresleri elde etmek için bir düğüme bağlan ve ardından bağlantıyı kes</translation>
+ </message>
+ <message>
+ <source>Specify your own public address</source>
+ <translation>Kendi genel adresinizi tanımlayın</translation>
+ </message>
+ <message>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>Komut satırı ve JSON-RPC komutlarını kabul et</translation>
+ </message>
+ <message>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>Arka planda daemon (servis) olarak çalış ve komutları kabul et</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>Deneme şebekesini kullan</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
+ <translation>Dışarıdan gelen bağlantıları kabul et (varsayılan: -proxy veya -connect yoksa 1)</translation>
+ </message>
+ <message>
+ <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
+ <translation>Belirtilen adrese bağlan ve daima ondan dinle. IPv6 için [makine]:port yazımını kullanınız</translation>
+ </message>
+ <message>
+ <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
+ <translation>Tüm cüzdan muamelelerini sil ve başlangıçta -rescan ile sadece blok zincirinin parçası olanları geri getir</translation>
+ </message>
+ <message>
+ <source>Distributed under the MIT software license, see the accompanying file COPYING or &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</source>
+ <translation>MIT yazılım lisansı kapsamında yayınlanmıştır, ekteki COPYING dosyasına ya da &lt;http://www.opensource.org/licenses/mit-license.php&gt; adresine bakınız.</translation>
+ </message>
+ <message>
+ <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
+ <translation>Bir cüzdan muamelesi değiştiğinde komutu çalıştır (komuttaki %s muamele kimliği ile değiştirilecektir)</translation>
+ </message>
+ <message>
+ <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source>
+ <translation>Tek cüzdan muamelesinde kullanılacak azami toplam ücret; bunu çok düşük olarak ayarlamak büyük muameleleri iptal edebilir (varsayılan: %s)</translation>
+ </message>
+ <message>
+ <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, &gt;%u = target size in MiB to use for block files)</source>
+ <translation>Depolama gerekliliğini eski blokları silerek düşür. Bu kip cüzdan desteğini devre dışı bırakır ve -txindex ile uyumsuzdur. İkaz: Bu ayarı geri almak tüm blok zincirini yeniden indirmeyi gerektirir. (varsayılan: 0 = blokları silmeyi devre dışı bırak, &gt;%u = MB olarak blok dosyaları için kullanılacak hedef boyut)</translation>
+ </message>
+ <message>
+ <source>Set the number of script verification threads (%u to %d, 0 = auto, &lt;0 = leave that many cores free, default: %d)</source>
+ <translation>Betik kontrolü iş parçacıklarının sayısını belirler (%u ilâ %d, 0 = otomatik, &lt;0 = bu sayıda çekirdeği kullanma, varsayılan: %d)</translation>
+ </message>
+ <message>
+ <source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source>
+ <translation>Bu yayın öncesi bir deneme sürümüdür - tüm riski siz üstlenmiş olursunuz - bitcoin oluşturmak ya da ticari uygulamalar için kullanmayınız</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer. Bitcoin Core is probably already running.</source>
+ <translation>Bu bilgisayarda %s unsuruna bağlanılamadı. Bitcoin Çekirdeği muhtemelen hâlihazırda çalışmaktadır.</translation>
+ </message>
+ <message>
+ <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>İKAZ: anormal yüksek sayıda blok oluşturulmuştur, %d blok son %d saat içinde alınmıştır (%d bekleniyordu)</translation>
+ </message>
+ <message>
+ <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>İKAZ: ağ bağlantınızı kontrol ediniz, %d blok son %d saat içinde alınmıştır (%d bekleniyordu)</translation>
+ </message>
+ <message>
+ <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>Uyarı: -paytxfee çok yüksek bir değere ayarlanmış! Bu, muamele gönderirseniz ödeyeceğiniz muamele ücretidir.</translation>
+ </message>
+ <message>
+ <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source>
+ <translation>Uyarı: şebeke tamamen mutabık değil gibi görünüyor! Bazı madenciler sorun yaşıyor gibi görünüyor.</translation>
+ </message>
+ <message>
+ <source>Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.</source>
+ <translation>Uyarı: eşlerimizle tamamen mutabık değiliz gibi görünüyor! Güncelleme yapmanız gerekebilir ya da diğer düğümlerin güncelleme yapmaları gerekebilir.</translation>
+ </message>
+ <message>
+ <source>Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
+ <translation>Uyarı: wallet.dat dosyasının okunması sırasında bir hata meydana geldi! Tüm anahtarlar doğru bir şekilde okundu, ancak muamele verileri ya da adres defteri unsurları hatalı veya eksik olabilir.</translation>
+ </message>
+ <message>
+ <source>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</source>
+ <translation>Uyarı: wallet.dat bozuk, veriler geri kazanıldı! Özgün wallet.dat, wallet.{zamandamgası}.bak olarak %s klasörüne kaydedildi; bakiyeniz ya da muameleleriniz yanlışsa bir yedeklemeden tekrar yüklemeniz gerekir.</translation>
+ </message>
+ <message>
+ <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source>
+ <translation>Belirtilen ağ maskesi ya da IP adresinden bağlanan eşleri beyaz listeye al. Birden fazla kez belirtilebilir.</translation>
+ </message>
+ <message>
+ <source>(default: 1)</source>
+ <translation>(varsayılan: 1)</translation>
+ </message>
+ <message>
+ <source>&lt;category&gt; can be:</source>
+ <translation>&lt;kategori&gt; şunlar olabilir:</translation>
+ </message>
+ <message>
+ <source>Attempt to recover private keys from a corrupt wallet.dat</source>
+ <translation>Bozuk bir wallet.dat dosyasından özel anahtarları geri kazanmayı dene</translation>
+ </message>
+ <message>
+ <source>Block creation options:</source>
+ <translation>Blok oluşturma seçenekleri:</translation>
+ </message>
+ <message>
+ <source>Connect only to the specified node(s)</source>
+ <translation>Sadece belirtilen düğüme veya düğümlere bağlan</translation>
+ </message>
+ <message>
+ <source>Connection options:</source>
+ <translation>Bağlantı seçenekleri:</translation>
+ </message>
+ <message>
+ <source>Corrupted block database detected</source>
+ <translation>Bozuk blok veritabanı tespit edildi</translation>
+ </message>
+ <message>
+ <source>Debugging/Testing options:</source>
+ <translation>Hata ayıklama/deneme seçenekleri:</translation>
+ </message>
+ <message>
+ <source>Do not load the wallet and disable wallet RPC calls</source>
+ <translation>Cüzdanı yükleme ve cüzdan RPC çağrılarını devre dışı bırak</translation>
+ </message>
+ <message>
+ <source>Do you want to rebuild the block database now?</source>
+ <translation>Blok veritabanını şimdi yeniden inşa etmek istiyor musunuz?</translation>
+ </message>
+ <message>
+ <source>Error initializing block database</source>
+ <translation>Blok veritabanını başlatılırken bir hata meydana geldi</translation>
+ </message>
+ <message>
+ <source>Error initializing wallet database environment %s!</source>
+ <translation>%s cüzdan veritabanı ortamının başlatılmasında hata meydana geldi!</translation>
+ </message>
+ <message>
+ <source>Error loading block database</source>
+ <translation>Blok veritabanının yüklenmesinde hata</translation>
+ </message>
+ <message>
+ <source>Error opening block database</source>
+ <translation>Blok veritabanının açılışı sırasında hata</translation>
+ </message>
+ <message>
+ <source>Error: Disk space is low!</source>
+ <translation>Hata: Disk alanı düşük!</translation>
+ </message>
+ <message>
+ <source>Failed to listen on any port. Use -listen=0 if you want this.</source>
+ <translation>Herhangi bir portun dinlenmesi başarısız oldu. Bunu istiyorsanız -listen=0 seçeneğini kullanınız.</translation>
+ </message>
+ <message>
+ <source>If &lt;category&gt; is not supplied, output all debugging information.</source>
+ <translation>&lt;kategori&gt; sağlanmamışsa tüm hata ayıklama verilerini dök.</translation>
+ </message>
+ <message>
+ <source>Importing...</source>
+ <translation>İçe aktarılıyor...</translation>
+ </message>
+ <message>
+ <source>Incorrect or no genesis block found. Wrong datadir for network?</source>
+ <translation>Yanlış ya da bulunamamış doğuş bloku. Şebeke için yanlış veri klasörü mü?</translation>
+ </message>
+ <message>
+ <source>Invalid -onion address: '%s'</source>
+ <translation>Geçersiz -onion adresi: '%s'</translation>
+ </message>
+ <message>
+ <source>Not enough file descriptors available.</source>
+ <translation>Kafi derecede dosya tanımlayıcıları mevcut değil.</translation>
+ </message>
+ <message>
+ <source>Only connect to nodes in network &lt;net&gt; (ipv4, ipv6 or onion)</source>
+ <translation>Sadece &lt;net&gt; şebekesindeki düğümlere bağlan (ipv4, ipv6 veya onion)</translation>
+ </message>
+ <message>
+ <source>Prune cannot be configured with a negative value.</source>
+ <translation>Prune negatif bir değerle yapılandırılamaz.</translation>
+ </message>
+ <message>
+ <source>Prune mode is incompatible with -txindex.</source>
+ <translation>Prune kipi -txindex ile uyumsuzdur.</translation>
+ </message>
+ <message>
+ <source>Set database cache size in megabytes (%d to %d, default: %d)</source>
+ <translation>Veritabanı önbellek boyutunu megabayt olarak belirt (%d ilâ %d, varsayılan: %d)</translation>
+ </message>
+ <message>
+ <source>Set maximum block size in bytes (default: %d)</source>
+ <translation>Azami blok boyutunu bayt olarak ayarla (varsayılan: %d)</translation>
+ </message>
+ <message>
+ <source>Specify wallet file (within data directory)</source>
+ <translation>Cüzdan dosyası belirtiniz (veri klasörünün içinde)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: %u)</source>
+ <translation>Dinleme portunu haritalamak için UPnP kullan (varsayılan: %u)</translation>
+ </message>
+ <message>
+ <source>Verifying blocks...</source>
+ <translation>Bloklar kontrol ediliyor...</translation>
+ </message>
+ <message>
+ <source>Verifying wallet...</source>
+ <translation>Cüzdan kontrol ediliyor...</translation>
+ </message>
+ <message>
+ <source>Wallet %s resides outside data directory %s</source>
+ <translation>%s cüzdan %s veri klasörünün dışında bulunuyor</translation>
+ </message>
+ <message>
+ <source>Wallet options:</source>
+ <translation>Cüzdan seçenekleri:</translation>
+ </message>
+ <message>
+ <source>Warning: This version is obsolete; upgrade required!</source>
+ <translation>Uyarı: Bu sürüm çok eskidir; güncellemeniz gerekir!</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to change -txindex</source>
+ <translation>-txindex'i değiştirmek için veritabanını -reindex kullanarak tekrar inşa etmeniz gerekmektedir</translation>
+ </message>
+ <message>
+ <source>Imports blocks from external blk000??.dat file</source>
+ <translation>Harici blk000??.dat dosyasından blokları içe aktarır</translation>
+ </message>
+ <message>
+ <source>Allow JSON-RPC connections from specified source. Valid for &lt;ip&gt; are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times</source>
+ <translation>Belirtilen kaynaktan JSON-RPC bağlantılarını kabul et. Bir &lt;ip&gt; için geçerli olanlar şunlardır: salt IP adresi (mesela 1.2.3.4), bir şebeke/ağ maskesi (örneğin 1.2.3.4/255.255.255.0) ya da bir şebeke/CIDR (mesela 1.2.3.4/24). Bu seçenek birden fazla kez belirtilebilir</translation>
+ </message>
+ <message>
+ <source>An error occurred while setting up the RPC address %s port %u for listening: %s</source>
+ <translation>Dinleme için RPC adresi %s port %u kurulurken bir hata meydana geldi: %s</translation>
+ </message>
+ <message>
+ <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source>
+ <translation>Belirtilen adrese bağlan ve ona bağlanan eşleri beyaz listeye al. IPv6 için [makine]:port imlasını kullanınız</translation>
+ </message>
+ <message>
+ <source>Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)</source>
+ <translation>Belirtilen adrese bağlan ve JSON RPC bağlantıları için dinlemeye geç. IPv6 için [makine]:port imlasını kullanınız. Bu seçenek birden çok kez belirtilebilir (varsayılan: tüm arayüzlere bağlan)</translation>
+ </message>
+ <message>
+ <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source>
+ <translation>%s veri dizininde kilit elde edilemedi. Bitcoin Çekirdeği muhtemelen hâlihazırda çalışmaktadır.</translation>
+ </message>
+ <message>
+ <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
+ <translation>Yeni dosyaları umask 077 yerine varsayılan izinlerle oluştur (sadece devre dışı cüzdan işlevselliği ile etkilidir)</translation>
+ </message>
+ <message>
+ <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source>
+ <translation>Kendi IP adreslerini keşfet (varsayılan: dinlenildiğinde ve -externalip ya da -proxy yoksa 1)</translation>
+ </message>
+ <message>
+ <source>Error: Listening for incoming connections failed (listen returned error %s)</source>
+ <translation>Hata: İçeri gelen bağlantıların dinlenmesi başarısız oldu (dinleme %s hatasını verdi)</translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source>
+ <translation>Hata: Desteklenmeyen -socks argümanı bulundu. SOCKS sürümünün ayarlanması artık mümkün değildir, sadece SOCKS5 vekilleri desteklenmektedir.</translation>
+ </message>
+ <message>
+ <source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source>
+ <translation>İlgili bir uyarı alındığında ya da gerçekten uzun bir çatallama gördüğümüzde komutu çalıştır (komuttaki %s mesaj ile değiştirilir)</translation>
+ </message>
+ <message>
+ <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source>
+ <translation>Kb başına BTC olarak bundan düşük ücretler aktarım için sıfır değerinde ücret olarak kabul edilir (varsayılan: %s)</translation>
+ </message>
+ <message>
+ <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
+ <translation>Eğer paytxfee ayarlanmadıysa kafi derecede ücret ekleyin ki muameleler teyite vasati n blok içinde başlasın (varsayılan: %u)</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)</source>
+ <translation>-maxtxfee=&lt;tutar&gt; için geçersiz tutar: '%s' (Sıkışmış muameleleri önlemek için en az %s değerinde asgari aktarım ücretine eşit olmalıdır)</translation>
+ </message>
+ <message>
+ <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source>
+ <translation>Aktardığımız ve oluşturduğumuz veri taşıyıcı muamelelerindeki azami veri boyutu (varsayılan: %u)</translation>
+ </message>
+ <message>
+ <source>Prune configured below the minimum of %d MB. Please use a higher number.</source>
+ <translation>Prune, asgari değer olan %d MB'den düşük olarak ayarlanmıştır. Lütfen daha yüksek bir sayı kullanınız.</translation>
+ </message>
+ <message>
+ <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source>
+ <translation>Adres sayısı azaldıysa DNS sorgulamasıyla eş adresleri ara (varsayılan: 1 -connect kullanılmadıysa)</translation>
+ </message>
+ <message>
+ <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source>
+ <translation>Her vekil bağlantısı için kimlik verilerini rastgele yap. Bu, Tor akış izolasyonunu etkinleştirir (varsayılan: %u)</translation>
+ </message>
+ <message>
+ <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
+ <translation>Yüksek öncelikli/düşük ücretli muamelelerin azami boyutunu bayt olarak ayarla (varsayılan: %d)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source>
+ <translation>Etkinse bitcoin oluşuturulmasına atanan iş parçacığı sayısını ayarla (-1 = tüm çekirdekler, varsayılan: %d)</translation>
+ </message>
+ <message>
+ <source>The transaction amount is too small to send after the fee has been deducted</source>
+ <translation>Bu muamele, ücret düşüldükten sonra göndermek için çok düşük</translation>
+ </message>
+ <message>
+ <source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit &lt;https://www.openssl.org/&gt; and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source>
+ <translation>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 hazırlanmış şifreleme yazılımları ve Thomas Bernard tarafından programlanmış UPnP yazılımı içerir.</translation>
+ </message>
+ <message>
+ <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an 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)
+The username and password MUST NOT be the same.
+If the file does not exist, create it with owner-readable-only file permissions.
+It is also recommended to set alertnotify so you are notified of problems;
+for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
+</source>
+ <translation>bitcoind ya da bitcoin-qt ile -server seçeneğini kullanmak için yapılandırma dosyasında bir 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)
+Kullanıcı ismi ile parolanın FARKLI olmaları gerekir.
+Dosya mevcut değilse, sadece sahibi için okumayla sınırlı izin ile oluşturunuz.
+Sorunlar hakkında bildiri almak için alertnotify unsurunu ayarlamanız tavsiye edilir;
+mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
+</translation>
+ </message>
+ <message>
+ <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source>
+ <translation>İkaz: -maxtxfee çok yüksek bir değere ayarlanmış! Bu denli yüksek ücretler tek bir muamelede ödenebilir.</translation>
+ </message>
+ <message>
+ <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source>
+ <translation>Uyarı: Lütfen bilgisayarınızın saat ve tarihinin doğru olduğunu kontol ediniz! Saatinizde gecikme varsa Bitcoin Çekirdeği doğru şekilde çalışamaz.</translation>
+ </message>
+ <message>
+ <source>Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway</source>
+ <translation>Beyaz listeye alınan eşler DoS yasaklamasına uğramazlar ve muameleleri zaten mempool'da olsalar da daima aktarılır, bu mesela bir geçit için kullanışlıdır</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source>
+ <translation>Prune olmayan kipe dönmek için veritabanını -reindex ile tekrar derlemeniz gerekir. Bu, tüm blok zincirini tekrar indirecektir</translation>
+ </message>
+ <message>
+ <source>(default: %u)</source>
+ <translation>(varsayılan: %u)</translation>
+ </message>
+ <message>
+ <source>Accept public REST requests (default: %u)</source>
+ <translation>Herkese açık REST taleplerini kabul et (varsayılan: %u)</translation>
+ </message>
+ <message>
+ <source>Activating best chain...</source>
+ <translation>En iyi zincir etkinleştiriliyor...</translation>
+ </message>
+ <message>
+ <source>Can't run with a wallet in prune mode.</source>
+ <translation>Prune kipindeki bir cüzdan ile çalışamaz.</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -whitebind address: '%s'</source>
+ <translation>-whitebind adresi çözümlenemedi: '%s'</translation>
+ </message>
+ <message>
+ <source>Choose data directory on startup (default: 0)</source>
+ <translation>Başlangıçta veri klasörü seç (varsayılan: 0)</translation>
+ </message>
+ <message>
+ <source>Connect through SOCKS5 proxy</source>
+ <translation>SOCKS5 vekil sunucusu vasıtasıyla bağlan</translation>
+ </message>
+ <message>
+ <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source>
+ <translation>Telif hakkı 2009-%i Bitcoin Çekirdeği Geliştiricileri</translation>
+ </message>
+ <message>
+ <source>Could not parse -rpcbind value %s as network address</source>
+ <translation>-rpcbind değeri %s şebeke adresi olarak ayrıştırılamadı</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source>
+ <translation>wallet.dat dosyasının yüklenmesinde hata: Cüzdan Bitcoin Çekirdeğinin daha yeni bir sürümünü gerektirmektedir</translation>
+ </message>
+ <message>
+ <source>Error reading from database, shutting down.</source>
+ <translation>Veritabanından okumada hata, kapatılıyor.</translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -tor found, use -onion.</source>
+ <translation>Hata: Deskteklenmeyen -tor argümanı bulundu, -onion kullanınız.</translation>
+ </message>
+ <message>
+ <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source>
+ <translation>Yolladığınız muamelelere kB başına BTC olarak eklenecek ücret (varsayılan: %s)</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Bilgi</translation>
+ </message>
+ <message>
+ <source>Initialization sanity check failed. Bitcoin Core is shutting down.</source>
+ <translation>Başlatma sınaması başarısız oldu. Bitcoin Çekirdeği kapatılıyor.</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s'</source>
+ <translation>-maxtxfee=&lt;tutar&gt; için geçersiz tutar: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -minrelaytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>-minrelaytxfee=&lt;amount&gt; için geçersiz meblağ: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -mintxfee=&lt;amount&gt;: '%s'</source>
+ <translation>-mintxfee=&lt;amount&gt; için geçersiz meblağ: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s' (must be at least %s)</source>
+ <translation>-paytxfee=&lt;tutar&gt;:'%s' unsurunda geçersiz tutar (asgari %s olması lazımdır)</translation>
+ </message>
+ <message>
+ <source>Invalid netmask specified in -whitelist: '%s'</source>
+ <translation>-whitelist: '%s' unsurunda geçersiz bir ağ maskesi belirtildi</translation>
+ </message>
+ <message>
+ <source>Keep at most &lt;n&gt; unconnectable transactions in memory (default: %u)</source>
+ <translation>Hafızada en çok &lt;n&gt; bağlanılamaz muamele tut (varsayılan: %u)</translation>
+ </message>
+ <message>
+ <source>Need to specify a port with -whitebind: '%s'</source>
+ <translation>-whitebind: '%s' ile bir port belirtilmesi lazımdır</translation>
+ </message>
+ <message>
+ <source>Node relay options:</source>
+ <translation>Düğüm röle seçenekleri:</translation>
+ </message>
+ <message>
+ <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source>
+ <translation>RPC SSL seçenekleri: (SSL kurulumu yönergeleri için Bitcoin vikisine bakınız)</translation>
+ </message>
+ <message>
+ <source>RPC server options:</source>
+ <translation>RPC sunucu seçenekleri:</translation>
+ </message>
+ <message>
+ <source>RPC support for HTTP persistent connections (default: %d)</source>
+ <translation>Kalıcı HTTP bağlantıları için RPC desteği (varsayılan: %d)</translation>
+ </message>
+ <message>
+ <source>Rebuild block chain index from current blk000??.dat files on startup</source>
+ <translation>Başlangıçta blok zinciri indeksini güncel blk000??.dat dosyalarından tekrar inşa et</translation>
+ </message>
+ <message>
+ <source>Receive and display P2P network alerts (default: %u)</source>
+ <translation>P2P ağından gelen önemli uyarıları alın ve gösterin (önseçili değer: %u)</translation>
+ </message>
+ <message>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>Trace/hata ayıklama verilerini debug.log dosyası yerine konsola gönder</translation>
+ </message>
+ <message>
+ <source>Send transactions as zero-fee transactions if possible (default: %u)</source>
+ <translation>Muameleleri mümkünse ücretsiz olarak gönder (varsayılan: %u)</translation>
+ </message>
+ <message>
+ <source>Set SSL root certificates for payment request (default: -system-)</source>
+ <translation>Ödeme talebi için SSL kök sertifikalarını belirle (varsayılan: -system-)</translation>
+ </message>
+ <message>
+ <source>Set language, for example "de_DE" (default: system locale)</source>
+ <translation>Lisan belirt, mesela "de_De" (varsayılan: sistem dili)</translation>
+ </message>
+ <message>
+ <source>Show all debugging options (usage: --help -help-debug)</source>
+ <translation>Tüm hata ayıklama seçeneklerini göster (kullanımı: --help -help-debug)</translation>
+ </message>
+ <message>
+ <source>Show splash screen on startup (default: 1)</source>
+ <translation>Başlatıldığında başlangıç ekranını göster (varsayılan: 1)</translation>
+ </message>
+ <message>
+ <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source>
+ <translation>İstemci başlatıldığında debug.log dosyasını küçült (varsayılan: -debug bulunmadığında 1)</translation>
+ </message>
+ <message>
+ <source>Signing transaction failed</source>
+ <translation>Muamelenin imzalanması başarısız oldu</translation>
+ </message>
+ <message>
+ <source>Start minimized</source>
+ <translation>Küçültülmüş olarak başlat</translation>
+ </message>
+ <message>
+ <source>The transaction amount is too small to pay the fee</source>
+ <translation>Muamele meblağı ücreti ödemek için çok düşük</translation>
+ </message>
+ <message>
+ <source>This is experimental software.</source>
+ <translation>Bu, deneysel bir yazılımdır.</translation>
+ </message>
+ <message>
+ <source>Transaction amount too small</source>
+ <translation>Muamele meblağı çok düşük</translation>
+ </message>
+ <message>
+ <source>Transaction amounts must be positive</source>
+ <translation>Muamele tutarının pozitif olması lazımdır</translation>
+ </message>
+ <message>
+ <source>Transaction too large for fee policy</source>
+ <translation>Ücret politikası için çok büyük muamele</translation>
+ </message>
+ <message>
+ <source>Transaction too large</source>
+ <translation>Muamele çok büyük</translation>
+ </message>
+ <message>
+ <source>UI Options:</source>
+ <translation>Arayüz Seçenkleri:</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer (bind returned error %s)</source>
+ <translation>Bu bilgisayarda %s unsuruna bağlanılamadı (bağlanma %s hatasını verdi)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: 1 when listening)</source>
+ <translation>Dinlenecek portu haritalamak için UPnP kullan (varsayılan: dinlenildiğinde 1)</translation>
+ </message>
+ <message>
+ <source>Username for JSON-RPC connections</source>
+ <translation>JSON-RPC bağlantıları için kullanıcı ismi</translation>
+ </message>
+ <message>
+ <source>Wallet needed to be rewritten: restart Bitcoin Core to complete</source>
+ <translation>Cüzdanın tekrar yazılması gerekmektedir: tamamlamak için Bitcoin Çekirdeğini yeniden başlatın</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Uyarı</translation>
+ </message>
+ <message>
+ <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source>
+ <translation>Uyarı: Deskteklenmeyen -benchmark argümanı görmezden gelindi, -debug=bench kullanınız.</translation>
+ </message>
+ <message>
+ <source>Warning: Unsupported argument -debugnet ignored, use -debug=net.</source>
+ <translation>Uyarı: Desteklenmeyen -debugnet argümanı görmezden gelindi, debug=net kullanınız.</translation>
+ </message>
+ <message>
+ <source>Zapping all transactions from wallet...</source>
+ <translation>Cüzdandaki tüm muameleler kaldırılıyor...</translation>
+ </message>
+ <message>
+ <source>on startup</source>
+ <translation>başlangıçta</translation>
+ </message>
+ <message>
+ <source>wallet.dat corrupt, salvage failed</source>
+ <translation>wallet.dat bozuk, geri kazanım başarısız oldu</translation>
+ </message>
+ <message>
+ <source>Password for JSON-RPC connections</source>
+ <translation>JSON-RPC bağlantıları için parola</translation>
+ </message>
+ <message>
+ <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
+ <translation>En iyi blok değiştiğinde komutu çalıştır (komut için %s parametresi blok hash değeri ile değiştirilecektir)</translation>
+ </message>
+ <message>
+ <source>Upgrade wallet to latest format</source>
+ <translation>Cüzdanı en yeni biçime güncelle</translation>
+ </message>
+ <message>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>Blok zincirini eksik cüzdan muameleleri için tekrar tara</translation>
+ </message>
+ <message>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>JSON-RPC bağlantıları için OpenSSL (https) kullan</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>Bu yardım mesajı</translation>
+ </message>
+ <message>
+ <source>Allow DNS lookups for -addnode, -seednode and -connect</source>
+ <translation>-addnode, -seednode ve -connect için DNS aramalarına izin ver</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>Adresler yükleniyor...</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>wallet.dat dosyasının yüklenmesinde hata oluştu: bozuk cüzdan</translation>
+ </message>
+ <message>
+ <source>(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source>
+ <translation>(1 = tx meta verilerini tut mesela hesap sahibi ve ödeme talebi bilgileri, 2 = tx meta verilerini at)</translation>
+ </message>
+ <message>
+ <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
+ <translation>-checkblocks'un blok kontrolünün ne kadar kapsamlı olacağı (0 ilâ 4, varsayılan: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
+ <translation>Muamelelerin tamamının indeksini tut, getrawtransaction rpc çağrısı tarafından kullanılır (varsayılan: %u)</translation>
+ </message>
+ <message>
+ <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source>
+ <translation>Aksaklık gösteren eşlerle terkar bağlantıyı engelleme süresi, saniye olarak (varsayılan: %u)</translation>
+ </message>
+ <message>
+ <source>Output debugging information (default: %u, supplying &lt;category&gt; is optional)</source>
+ <translation>Hata ayıklama bilgisi dök (varsayılan: %u, &lt;kategori&gt; sağlanması seçime dayalıdır)</translation>
+ </message>
+ <message>
+ <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source>
+ <translation>Eşlere gizli Tor servisleri ile ulaşmak için ayrı SOCKS5 vekil sunucusu kullan (varsayılan: %s)</translation>
+ </message>
+ <message>
+ <source>(default: %s)</source>
+ <translation>(varsayılan: %s)</translation>
+ </message>
+ <message>
+ <source>Acceptable ciphers (default: %s)</source>
+ <translation>Kabul edilebilir şifreler (varsayılan: %s)</translation>
+ </message>
+ <message>
+ <source>Always query for peer addresses via DNS lookup (default: %u)</source>
+ <translation>Eş adresleri sorgulaması için daima DNS aramasını kullan (varsayılan: %u)</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>wallet.dat dosyasının yüklenmesinde hata oluştu</translation>
+ </message>
+ <message>
+ <source>Generate coins (default: %u)</source>
+ <translation>Bitcoin oluştur (varsayılan: %u)</translation>
+ </message>
+ <message>
+ <source>How many blocks to check at startup (default: %u, 0 = all)</source>
+ <translation>Başlangıçta kontrol edilecek blok sayısı (varsayılan: %u, 0 = hepsi)</translation>
+ </message>
+ <message>
+ <source>Include IP addresses in debug output (default: %u)</source>
+ <translation>Hata ayıklama çıktısına IP adreslerini dahil et (varsayılan: %u)</translation>
+ </message>
+ <message>
+ <source>Invalid -proxy address: '%s'</source>
+ <translation>Geçersiz -proxy adresi: '%s'</translation>
+ </message>
+ <message>
+ <source>Listen for JSON-RPC connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>JSON-RPC bağlantılarını &lt;port&gt; üzerinde dinle (varsayılan: %u veya tesnet: %u)</translation>
+ </message>
+ <message>
+ <source>Listen for connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>Bağlantılar için dinlenecek &lt;port&gt; (varsayılan: %u ya da testnet: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain at most &lt;n&gt; connections to peers (default: %u)</source>
+ <translation>Eşler ile en çok &lt;n&gt; adet bağlantı kur (varsayılan: %u)</translation>
+ </message>
+ <message>
+ <source>Make the wallet broadcast transactions</source>
+ <translation>Cüzdanın muameleleri yayınlamasını sağla</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection receive buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>Her bağlantı için azami alım tamponu, &lt;n&gt;*1000 bayt (varsayılan: %u)</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection send buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>Her bağlantı için azami yollama tamponu, &lt;n&gt;*1000 bayt (varsayılan: %u)</translation>
+ </message>
+ <message>
+ <source>Prepend debug output with timestamp (default: %u)</source>
+ <translation>Hata ayıklama verilerinin önüne zaman damgası ekle (varsayılan: %u)</translation>
+ </message>
+ <message>
+ <source>Relay and mine data carrier transactions (default: %u)</source>
+ <translation>Veri taşıyıcı muameleleri oluştur ve aktar (varsayılan: %u)</translation>
+ </message>
+ <message>
+ <source>Relay non-P2SH multisig (default: %u)</source>
+ <translation>P2SH olmayan çoklu imzaları aktar (varsayılan: %u)</translation>
+ </message>
+ <message>
+ <source>Server certificate file (default: %s)</source>
+ <translation>Sunucu sertifika dosyası (varsayılan: %s)</translation>
+ </message>
+ <message>
+ <source>Server private key (default: %s)</source>
+ <translation>Sunucu özel anahtarı (varsayılan: %s)</translation>
+ </message>
+ <message>
+ <source>Set key pool size to &lt;n&gt; (default: %u)</source>
+ <translation>Anahtar alan boyutunu &lt;n&gt; değerine ayarla (varsayılan: %u)</translation>
+ </message>
+ <message>
+ <source>Set minimum block size in bytes (default: %u)</source>
+ <translation>Bayt olarak asgari blok boyutunu tanımla (varsayılan: %u)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads to service RPC calls (default: %d)</source>
+ <translation>Hizmet RCP aramaları iş parçacığı sayısını belirle (varsayılan: %d)</translation>
+ </message>
+ <message>
+ <source>Specify configuration file (default: %s)</source>
+ <translation>Yapılandırma dosyası belirtiniz (varsayılan: %s)</translation>
+ </message>
+ <message>
+ <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source>
+ <translation>Bağlantı zaman aşım süresini milisaniye olarak belirt (asgari: 1, varsayılan: %d)</translation>
+ </message>
+ <message>
+ <source>Specify pid file (default: %s)</source>
+ <translation>Pid dosyası belirtiniz (varsayılan: %s)</translation>
+ </message>
+ <message>
+ <source>Spend unconfirmed change when sending transactions (default: %u)</source>
+ <translation>Gönderme muamelelerinde teyit edilmemiş para üstünü harca (varsayılan: %u)</translation>
+ </message>
+ <message>
+ <source>Threshold for disconnecting misbehaving peers (default: %u)</source>
+ <translation>Aksaklık gösteren eşlerle bağlantıyı kesme sınırı (varsayılan: %u)</translation>
+ </message>
+ <message>
+ <source>Unknown network specified in -onlynet: '%s'</source>
+ <translation>-onlynet için bilinmeyen bir şebeke belirtildi: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -bind address: '%s'</source>
+ <translation>-bind adresi çözümlenemedi: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -externalip address: '%s'</source>
+ <translation>-externalip adresi çözümlenemedi: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>-paytxfee=&lt;meblağ&gt; için geçersiz meblağ: '%s'</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>Yetersiz bakiye</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>Blok indeksi yükleniyor...</translation>
+ </message>
+ <message>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>Bağlanılacak düğüm ekle ve bağlantıyı zinde tutmaya çalış</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>Cüzdan yükleniyor...</translation>
+ </message>
+ <message>
+ <source>Cannot downgrade wallet</source>
+ <translation>Cüzdan eski biçime geri alınamaz</translation>
+ </message>
+ <message>
+ <source>Cannot write default address</source>
+ <translation>Varsayılan adres yazılamadı</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>Yeniden tarama...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>Yükleme tamamlandı</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Hata</translation>
+ </message>
+</context>
+</TS> \ 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 0000000000..fb2f9f8815
--- /dev/null
+++ b/src/qt/locale/bitcoin_uk.ts
@@ -0,0 +1,3592 @@
+<TS language="uk" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Right-click to edit address or label</source>
+ <translation>Клікніть правою кнопкою для редагування адреси або мітки</translation>
+ </message>
+ <message>
+ <source>Create a new address</source>
+ <translation>Створити нову адресу</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>&amp;Нова</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Копіювати виділену адресу в буфер обміну</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>&amp;Копіювати</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>З&amp;акрити</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>&amp;Скопіювати адресу</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>Вилучити вибрані адреси з переліку</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Експортувати дані з поточної вкладки в файл</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Експорт...</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;Видалити</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>Виберіть адресу для відправлення монет</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>Виберіть адресу для отримання монет</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>&amp;Обрати</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>Адреси для відправлення</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>Адреси для отримання</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>Це ваші Bitcoin-адреси для відправлення платежів. Перед відправленням монет завжди перевіряйте суму та адресу прийому.</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>Це ваша нова Bitcoin адреса для отримання платежів. Рекомендовано використовувати нову адресу для кожної транзакції.</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>Скопіювати &amp;мітку</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>&amp;Редагувати</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>Експортувати список адрес</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Значення, розділені комою (*.csv)</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Помилка експорту</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the address list to %1. Please try again.</source>
+ <translation>Виникла помилка при спробі зберігання адрес до %1. Будь ласка спробуйте ще.</translation>
+ </message>
+</context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Назва</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Адреса</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(немає назви)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Passphrase Dialog</source>
+ <translation>Діалог введення паролю</translation>
+ </message>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Введіть пароль</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Новий пароль</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Повторіть пароль</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>Зашифрувати гаманець</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>Ця операція потребує пароль для розблокування гаманця.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Розблокувати гаманець</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>Ця операція потребує пароль для дешифрування гаманця.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>Дешифрувати гаманець</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>Змінити пароль</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>Підтвердити шифрування гаманця</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>УВАГА: Якщо ви зашифруєте гаманець і забудете пароль, ви &lt;b&gt;ВТРАТИТЕ ВСІ СВОЇ БІТКОІНИ&lt;/b&gt;!</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>Ви дійсно хочете зашифрувати свій гаманець?</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core 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.</source>
+ <translation>Клієнт «Bitcoin Core» буде закрито для завершення процесу шифрування. Пам'ятайте, що шифрування гаманця не зможе повністю захистити ваші біткоїни від крадіжки якщо ваш комп'ютер буде інфіковано шкідливими програмами.</translation>
+ </message>
+ <message>
+ <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
+ <translation>ВАЖЛИВО: Всі попередні резервні копії, які ви зробили з вашого файлу гаманця повинні бути замінені новоствореним, зашифрованим файлом гаманця. З міркувань безпеки, попередні резервні копії незашифрованого файла гаманця стануть непридатними одразу ж, як тільки ви почнете використовувати новий, зашифрований гаманець.</translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>Увага: Ввімкнено Caps Lock!</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>Гаманець зашифровано</translation>
+ </message>
+ <message>
+ <source>Enter the new passphrase to the wallet.&lt;br/&gt;Please use a passphrase of &lt;b&gt;ten or more random characters&lt;/b&gt;, or &lt;b&gt;eight or more words&lt;/b&gt;.</source>
+ <translation>Введіть нову кодову фразу для гаманця.&lt;br/&gt;Будь ласка, використовуйте кодові фрази що містять &lt;b&gt; щонайменше десять випадкових символів &lt;/b&gt; або &lt;b&gt; щонайменше вісім слів &lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>Enter the old passphrase and new passphrase to the wallet.</source>
+ <translation>Введіть старий пароль та новий пароль до гаманця.</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>Не вдалося зашифрувати гаманець</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>Виникла помилка під час шифрування гаманця. Ваш гаманець не було зашифровано.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>Введені паролі не співпадають.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>Не вдалося розблокувати гаманець</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>Введений пароль є неправильним.</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>Не вдалося розшифрувати гаманець</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>Пароль було успішно змінено.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>&amp;Підписати повідомлення...</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>Синхронізація з мережею...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;Огляд</translation>
+ </message>
+ <message>
+ <source>Node</source>
+ <translation>Вузол</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>Показати стан гаманця</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Транзакції</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>Переглянути історію транзакцій</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>&amp;Вихід</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>Вийти</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>&amp;Про Qt</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>Показати інформацію про Qt</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;Параметри...</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>&amp;Шифрування гаманця...</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>&amp;Резервне копіювання гаманця...</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>Змінити парол&amp;ь...</translation>
+ </message>
+ <message>
+ <source>&amp;Sending addresses...</source>
+ <translation>Адреси для &amp;відправлення...</translation>
+ </message>
+ <message>
+ <source>&amp;Receiving addresses...</source>
+ <translation>Адреси для &amp;отримання...</translation>
+ </message>
+ <message>
+ <source>Open &amp;URI...</source>
+ <translation>Відкрити &amp;URI</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core client</source>
+ <translation>Клієнт «Bitcoin Core»</translation>
+ </message>
+ <message>
+ <source>Importing blocks from disk...</source>
+ <translation>Імпорт блоків з диску...</translation>
+ </message>
+ <message>
+ <source>Reindexing blocks on disk...</source>
+ <translation>Переіндексація блоків на диску ...</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>Відправити монети на вказану адресу</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>Резервне копіювання гаманця в інше місце</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Змінити пароль, який використовується для шифрування гаманця</translation>
+ </message>
+ <message>
+ <source>&amp;Debug window</source>
+ <translation>В&amp;ікно зневадження</translation>
+ </message>
+ <message>
+ <source>Open debugging and diagnostic console</source>
+ <translation>Відкрити консоль зневадження і діагностики</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>П&amp;еревірити повідомлення...</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>Гаманець</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>&amp;Відправити</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>&amp;Отримати</translation>
+ </message>
+ <message>
+ <source>Show information about Bitcoin Core</source>
+ <translation>Показати інформацію про Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>Показа&amp;ти / Приховати</translation>
+ </message>
+ <message>
+ <source>Show or hide the main Window</source>
+ <translation>Показує або приховує головне вікно</translation>
+ </message>
+ <message>
+ <source>Encrypt the private keys that belong to your wallet</source>
+ <translation>Зашифрувати закриті ключі, що знаходяться у вашому гаманці</translation>
+ </message>
+ <message>
+ <source>Sign messages with your Bitcoin addresses to prove you own them</source>
+ <translation>Підтвердіть, що Ви є власником повідомлення підписавши його Вашою Bitcoin-адресою </translation>
+ </message>
+ <message>
+ <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source>
+ <translation>Перевірте повідомлення для впевненості, що воно підписано вказаною Bitcoin-адресою</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;Файл</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;Налаштування</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>&amp;Довідка</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>Панель вкладок</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Request payments (generates QR codes and bitcoin: URIs)</source>
+ <translation>Створити запит платежу (генерує QR-код та bitcoin: URI)</translation>
+ </message>
+ <message>
+ <source>&amp;About Bitcoin Core</source>
+ <translation>П&amp;ро Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Modify configuration options for Bitcoin Core</source>
+ <translation>Редагувати параметри Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Show the list of used sending addresses and labels</source>
+ <translation>Показати список адрес і міток, що були використані для відправлення</translation>
+ </message>
+ <message>
+ <source>Show the list of used receiving addresses and labels</source>
+ <translation>Показати список адрес і міток, що були використані для отримання</translation>
+ </message>
+ <message>
+ <source>Open a bitcoin: URI or payment request</source>
+ <translation>Відкрити bitcoin: URI чи запит платежу</translation>
+ </message>
+ <message>
+ <source>&amp;Command-line options</source>
+ <translation>П&amp;араметри командного рядка</translation>
+ </message>
+ <message>
+ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
+ <translation>Показати довідку Bitcoin Core для отримання переліку можливих параметрів командного рядка.</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n active connection(s) to Bitcoin network</source>
+ <translation><numerusform>%n активне з'єднання з мережею Bitcoin</numerusform><numerusform>%n активні з'єднання з мережею Bitcoin</numerusform><numerusform>%n активних з'єднань з мережею Bitcoin</numerusform></translation>
+ </message>
+ <message>
+ <source>No block source available...</source>
+ <translation>Недоступно жодного джерела блоків...</translation>
+ </message>
+ <message numerus="yes">
+ <source>Processed %n block(s) of transaction history.</source>
+ <translation><numerusform>Оброблено %n блок історії транзакцій.</numerusform><numerusform>Оброблено %n блоки історії транзакцій.</numerusform><numerusform>Оброблено %n блоків історії транзакцій.</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n hour(s)</source>
+ <translation><numerusform>%n година</numerusform><numerusform>%n години</numerusform><numerusform>%n годин</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n day(s)</source>
+ <translation><numerusform>%n день</numerusform><numerusform>%n дні</numerusform><numerusform>%n днів</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n week(s)</source>
+ <translation><numerusform>%n тиждень</numerusform><numerusform>%n тижня</numerusform><numerusform>%n тижнів</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 and %2</source>
+ <translation>%1 та %2</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n year(s)</source>
+ <translation><numerusform>%n рік</numerusform><numerusform>%n роки</numerusform><numerusform>%n років</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 behind</source>
+ <translation>%1 тому</translation>
+ </message>
+ <message>
+ <source>Last received block was generated %1 ago.</source>
+ <translation>Останній отриманий блок було згенеровано %1 тому.</translation>
+ </message>
+ <message>
+ <source>Transactions after this will not yet be visible.</source>
+ <translation>Пізніші транзакції не буде видно.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Помилка</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Попередження</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Інформація</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>Синхронізовано</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>Синхронізується...</translation>
+ </message>
+ <message>
+ <source>Date: %1
+</source>
+ <translation>Дата: %1
+</translation>
+ </message>
+ <message>
+ <source>Amount: %1
+</source>
+ <translation>Кількість: %1
+</translation>
+ </message>
+ <message>
+ <source>Type: %1
+</source>
+ <translation>Тип: %1
+</translation>
+ </message>
+ <message>
+ <source>Label: %1
+</source>
+ <translation>Мітка: %1
+</translation>
+ </message>
+ <message>
+ <source>Address: %1
+</source>
+ <translation>Адреса: %1
+</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>Надіслані транзакції</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>Отримані транзакції</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>&lt;b&gt;Зашифрований&lt;/b&gt; гаманець &lt;b&gt;розблоковано&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>&lt;b&gt;Зашифрований&lt;/b&gt; гаманець &lt;b&gt;заблоковано&lt;/b&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <source>Network Alert</source>
+ <translation>Сповіщення мережі</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Coin Selection</source>
+ <translation>Вибір Монет</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Кількість:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Байтів:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Сума:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Пріорітет:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Комісія:</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Пил:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Після комісії:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Решта:</translation>
+ </message>
+ <message>
+ <source>(un)select all</source>
+ <translation>Вибрати/зняти всі</translation>
+ </message>
+ <message>
+ <source>Tree mode</source>
+ <translation>Деревом</translation>
+ </message>
+ <message>
+ <source>List mode</source>
+ <translation>Списком</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Кількість</translation>
+ </message>
+ <message>
+ <source>Received with label</source>
+ <translation>Отримано з позначкою</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>Отримано з адресою</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Дата</translation>
+ </message>
+ <message>
+ <source>Confirmations</source>
+ <translation>Підтверджень</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Підтверджені</translation>
+ </message>
+ <message>
+ <source>Priority</source>
+ <translation>Пріоритет</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Скопіювати адресу</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Скопіювати мітку</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Скопіювати суму</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Скопіювати ID транзакції </translation>
+ </message>
+ <message>
+ <source>Lock unspent</source>
+ <translation>Заблокувати</translation>
+ </message>
+ <message>
+ <source>Unlock unspent</source>
+ <translation>Розблокувати</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Скопіювати кількість</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Скопіювати комісію</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Скопіювати після комісії</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Скопіювати байти</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Скопіювати пріорітет</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Скопіювати пил</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Скопіювати решту</translation>
+ </message>
+ <message>
+ <source>highest</source>
+ <translation>найвищий</translation>
+ </message>
+ <message>
+ <source>higher</source>
+ <translation>вищий</translation>
+ </message>
+ <message>
+ <source>high</source>
+ <translation>високий</translation>
+ </message>
+ <message>
+ <source>medium-high</source>
+ <translation>вище за середній</translation>
+ </message>
+ <message>
+ <source>medium</source>
+ <translation>середній</translation>
+ </message>
+ <message>
+ <source>low-medium</source>
+ <translation>нижче за середній</translation>
+ </message>
+ <message>
+ <source>low</source>
+ <translation>низький</translation>
+ </message>
+ <message>
+ <source>lower</source>
+ <translation>нижчий</translation>
+ </message>
+ <message>
+ <source>lowest</source>
+ <translation>найнижчий</translation>
+ </message>
+ <message>
+ <source>(%1 locked)</source>
+ <translation>(%1 заблоковано)</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>відсутній</translation>
+ </message>
+ <message>
+ <source>This label turns red if the transaction size is greater than 1000 bytes.</source>
+ <translation>Ця позначка стане червоною, якщо розмір транзакції перевищить 1000 байтів.</translation>
+ </message>
+ <message>
+ <source>This label turns red if the priority is smaller than "medium".</source>
+ <translation>Ця позначка стане червоною, якщо пріоритет транзакції менше, ніж «середній».</translation>
+ </message>
+ <message>
+ <source>This label turns red if any recipient receives an amount smaller than %1.</source>
+ <translation>Ця позначка стане червоною, якщо будь-який отримувач отримає суму, меншу за %1.</translation>
+ </message>
+ <message>
+ <source>Can vary +/- %1 satoshi(s) per input.</source>
+ <translation>Може відрізнятися на +/- %1 сатоші за вхід</translation>
+ </message>
+ <message>
+ <source>yes</source>
+ <translation>так</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>ні</translation>
+ </message>
+ <message>
+ <source>This means a fee of at least %1 per kB is required.</source>
+ <translation>Це означає, що необхідно внести комісію (щонайменше %1 за КБ).</translation>
+ </message>
+ <message>
+ <source>Can vary +/- 1 byte per input.</source>
+ <translation>Може відрізнятися на +/- 1 байт за вхід.</translation>
+ </message>
+ <message>
+ <source>Transactions with higher priority are more likely to get included into a block.</source>
+ <translation>Транзакції з вищим пріоритетом мають більше шансів бути включеними до блоку.</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(немає назви)</translation>
+ </message>
+ <message>
+ <source>change from %1 (%2)</source>
+ <translation>решта з %1 (%2)</translation>
+ </message>
+ <message>
+ <source>(change)</source>
+ <translation>(решта)</translation>
+ </message>
+</context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>Редагувати адресу</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>&amp;Мітка</translation>
+ </message>
+ <message>
+ <source>The label associated with this address list entry</source>
+ <translation>Мітка, пов'язана з цим записом списку адрес</translation>
+ </message>
+ <message>
+ <source>The address associated with this address list entry. This can only be modified for sending addresses.</source>
+ <translation>Адреса, пов'язана з цим записом списку адрес. Це поле може бути модифіковане лише для адрес відправлення.</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;Адреса</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>Нова адреса для отримання</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>Нова адреса для відправлення</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>Редагувати адресу для отримання</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>Редагувати адресу для відправлення</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>Введена адреса «%1» вже присутня в адресній книзі.</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is not a valid Bitcoin address.</source>
+ <translation>Введена адреса «%1» не є коректною адресою в мережі Bitcoin.</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>Неможливо розблокувати гаманець.</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>Не вдалося згенерувати нові ключі.</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ <message>
+ <source>A new data directory will be created.</source>
+ <translation>Буде створено новий каталог даних.</translation>
+ </message>
+ <message>
+ <source>name</source>
+ <translation>назва</translation>
+ </message>
+ <message>
+ <source>Directory already exists. Add %1 if you intend to create a new directory here.</source>
+ <translation>Каталог вже існує. Додайте %1, якщо ви мали намір створити там новий каталог.</translation>
+ </message>
+ <message>
+ <source>Path already exists, and is not a directory.</source>
+ <translation>Шлях вже існує і не є каталогом.</translation>
+ </message>
+ <message>
+ <source>Cannot create data directory here.</source>
+ <translation>Тут неможливо створити каталог даних.</translation>
+ </message>
+</context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>версії</translation>
+ </message>
+ <message>
+ <source>(%1-bit)</source>
+ <translation>(%1-бітний)</translation>
+ </message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>Про Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Command-line options</source>
+ <translation>Параметри командного рядка</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>Використання:</translation>
+ </message>
+ <message>
+ <source>command-line options</source>
+ <translation>параметри командного рядка</translation>
+ </message>
+</context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Welcome</source>
+ <translation>Вітання</translation>
+ </message>
+ <message>
+ <source>Welcome to Bitcoin Core.</source>
+ <translation>Ласкаво просимо в Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</source>
+ <translation>Оскільки це перший запуск програми, ви можете обрати де Bitcoin Core буде зберігати дані.</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory.</source>
+ <translation>Bitcoin Core завантажить та збереже копію ланцюжка блоків Bitcoin. Щонайменше %1ГБ даних буде збережено в цьому каталозі. Гаманець теж буде збережено в цьому каталозі.</translation>
+ </message>
+ <message>
+ <source>Use the default data directory</source>
+ <translation>Використовувати типовий каталог даних</translation>
+ </message>
+ <message>
+ <source>Use a custom data directory:</source>
+ <translation>Використовувати свій каталог даних:</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Error: Specified data directory "%1" cannot be created.</source>
+ <translation>Помилка: неможливо створити обраний каталог даних «%1».</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Помилка</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n GB of free space available</source>
+ <translation><numerusform>Доступно %n ГБ вільного простору</numerusform><numerusform>Доступно %n ГБ вільного простору</numerusform><numerusform>Доступно %n ГБ вільного простору</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>(of %n GB needed)</source>
+ <translation><numerusform>(в той час, як необхідно %n ГБ)</numerusform><numerusform>(в той час, як необхідно %n ГБ)</numerusform><numerusform>(в той час, як необхідно %n ГБ)</numerusform></translation>
+ </message>
+</context>
+<context>
+ <name>OpenURIDialog</name>
+ <message>
+ <source>Open URI</source>
+ <translation>Відкрити URI</translation>
+ </message>
+ <message>
+ <source>Open payment request from URI or file</source>
+ <translation>Відкрити запит платежу з URI або файлу</translation>
+ </message>
+ <message>
+ <source>URI:</source>
+ <translation>URI:</translation>
+ </message>
+ <message>
+ <source>Select payment request file</source>
+ <translation>Виберіть файл запиту платежу</translation>
+ </message>
+ <message>
+ <source>Select payment request file to open</source>
+ <translation>Виберіть файл запиту платежу для відкриття</translation>
+ </message>
+</context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>Параметри</translation>
+ </message>
+ <message>
+ <source>&amp;Main</source>
+ <translation>&amp;Головні</translation>
+ </message>
+ <message>
+ <source>Size of &amp;database cache</source>
+ <translation>Розмір &amp;кешу бази даних</translation>
+ </message>
+ <message>
+ <source>MB</source>
+ <translation>МБ</translation>
+ </message>
+ <message>
+ <source>Number of script &amp;verification threads</source>
+ <translation>Кількість потоків &amp;сценарію перевірки</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside</source>
+ <translation>Приймати підключення ззовні</translation>
+ </message>
+ <message>
+ <source>Allow incoming connections</source>
+ <translation>Дозволити вхідні з’єднання</translation>
+ </message>
+ <message>
+ <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
+ <translation>IP-адреса проксі-сервера (наприклад IPv4: 127.0.0.1 / IPv6: ::1)</translation>
+ </message>
+ <message>
+ <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source>
+ <translation>Згортати замість закриття. Якщо ця опція включена, програма закриється лише після вибору відповідного пункту в меню.</translation>
+ </message>
+ <message>
+ <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source>
+ <translation>Встановлює мову інтерфейсу. Зміни набудуть чинності після перезапуску Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source>
+ <translation>Сторонні URL (наприклад, block explorer), що з'являться на вкладці транзакцій у вигляді пункту контекстного меню. %s в URL буде замінено на хеш транзакції. Для відокремлення URLів використовуйте вертикальну риску |.</translation>
+ </message>
+ <message>
+ <source>Third party transaction URLs</source>
+ <translation>Сторонні URL транзакцій</translation>
+ </message>
+ <message>
+ <source>Active command-line options that override above options:</source>
+ <translation>Активовані параметри командного рядка, що перекривають вищевказані параметри:</translation>
+ </message>
+ <message>
+ <source>Reset all client options to default.</source>
+ <translation>Скинути всі параметри клієнта на типові.</translation>
+ </message>
+ <message>
+ <source>&amp;Reset Options</source>
+ <translation>С&amp;кинути параметри</translation>
+ </message>
+ <message>
+ <source>&amp;Network</source>
+ <translation>&amp;Мережа</translation>
+ </message>
+ <message>
+ <source>Automatically start Bitcoin Core after logging in to the system.</source>
+ <translation>Автоматично запускати Bitcoin Core при вході до системи.</translation>
+ </message>
+ <message>
+ <source>&amp;Start Bitcoin Core on system login</source>
+ <translation>&amp;Запускати Bitcoin Core при вході до системи</translation>
+ </message>
+ <message>
+ <source>(0 = auto, &lt;0 = leave that many cores free)</source>
+ <translation>(0 = автоматично, &lt;0 = вказує кількість вільних ядер)</translation>
+ </message>
+ <message>
+ <source>W&amp;allet</source>
+ <translation>Г&amp;аманець</translation>
+ </message>
+ <message>
+ <source>Expert</source>
+ <translation>Експерт</translation>
+ </message>
+ <message>
+ <source>Enable coin &amp;control features</source>
+ <translation>Ввімкнути &amp;керування входами</translation>
+ </message>
+ <message>
+ <source>If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.</source>
+ <translation>Якщо вимкнути витрату непідтвердженої решти, то решту від транзакції не можна буде використати, допоки ця транзакція не матиме хоча б одне підтвердження. Це також впливає на розрахунок балансу.</translation>
+ </message>
+ <message>
+ <source>&amp;Spend unconfirmed change</source>
+ <translation>&amp;Витрачати непідтверджену решту</translation>
+ </message>
+ <message>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>Автоматично відкривати порт для клієнту біткоін на роутері. Працює лише якщо ваш роутер підтримує UPnP і ця функція увімкнена.</translation>
+ </message>
+ <message>
+ <source>Map port using &amp;UPnP</source>
+ <translation>Відображення порту через &amp;UPnP</translation>
+ </message>
+ <message>
+ <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
+ <translation>Підключення до мережі Bitcoin через SOCKS5 проксі.</translation>
+ </message>
+ <message>
+ <source>&amp;Connect through SOCKS5 proxy (default proxy):</source>
+ <translation>&amp;Підключення через SOCKS5 проксі (проксі за замовчуванням):</translation>
+ </message>
+ <message>
+ <source>Proxy &amp;IP:</source>
+ <translation>&amp;IP проксі:</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>&amp;Порт:</translation>
+ </message>
+ <message>
+ <source>Port of the proxy (e.g. 9050)</source>
+ <translation>Порт проксі-сервера (наприклад 9050)</translation>
+ </message>
+ <message>
+ <source>&amp;Window</source>
+ <translation>&amp;Вікно</translation>
+ </message>
+ <message>
+ <source>Show only a tray icon after minimizing the window.</source>
+ <translation>Показувати лише іконку в треї після згортання вікна.</translation>
+ </message>
+ <message>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>Мінімізувати &amp;у трей</translation>
+ </message>
+ <message>
+ <source>M&amp;inimize on close</source>
+ <translation>Згортати замість закритт&amp;я</translation>
+ </message>
+ <message>
+ <source>&amp;Display</source>
+ <translation>&amp;Відображення</translation>
+ </message>
+ <message>
+ <source>User Interface &amp;language:</source>
+ <translation>Мов&amp;а інтерфейсу користувача:</translation>
+ </message>
+ <message>
+ <source>&amp;Unit to show amounts in:</source>
+ <translation>В&amp;имірювати монети в:</translation>
+ </message>
+ <message>
+ <source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
+ <translation>Виберіть одиницю вимірювання монет, яка буде відображатись в гаманці та при відправленні.</translation>
+ </message>
+ <message>
+ <source>Whether to show coin control features or not.</source>
+ <translation>Показати або сховати керування входами.</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>&amp;Гаразд</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>&amp;Скасувати</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>типово</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>відсутні</translation>
+ </message>
+ <message>
+ <source>Confirm options reset</source>
+ <translation>Підтвердження скидання параметрів</translation>
+ </message>
+ <message>
+ <source>Client restart required to activate changes.</source>
+ <translation>Для застосування змін необхідно перезапустити клієнта.</translation>
+ </message>
+ <message>
+ <source>Client will be shut down. Do you want to proceed?</source>
+ <translation>Клієнт буде вимкнено. Продовжити?</translation>
+ </message>
+ <message>
+ <source>This change would require a client restart.</source>
+ <translation>Ця зміна вступить в силу після перезапуску клієнта</translation>
+ </message>
+ <message>
+ <source>The supplied proxy address is invalid.</source>
+ <translation>Невірно вказано адресу проксі.</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>Форма</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>Показана інформація вже може бути застарілою. Ваш гаманець буде автоматично синхронізовано з мережею Bitcoin після встановлення підключення, але цей процес ще не завершено.</translation>
+ </message>
+ <message>
+ <source>Watch-only:</source>
+ <translation>Тільки спостереження:</translation>
+ </message>
+ <message>
+ <source>Available:</source>
+ <translation>Наявно:</translation>
+ </message>
+ <message>
+ <source>Your current spendable balance</source>
+ <translation>Ваш поточний підтверджений баланс</translation>
+ </message>
+ <message>
+ <source>Pending:</source>
+ <translation>Очікується:</translation>
+ </message>
+ <message>
+ <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source>
+ <translation>Сума монет у непідтверджених транзакціях</translation>
+ </message>
+ <message>
+ <source>Immature:</source>
+ <translation>Незрілі:</translation>
+ </message>
+ <message>
+ <source>Mined balance that has not yet matured</source>
+ <translation>Баланс видобутих та ще недозрілих монет</translation>
+ </message>
+ <message>
+ <source>Balances</source>
+ <translation>Баланси</translation>
+ </message>
+ <message>
+ <source>Total:</source>
+ <translation>Всього:</translation>
+ </message>
+ <message>
+ <source>Your current total balance</source>
+ <translation>Ваш поточний сукупний баланс</translation>
+ </message>
+ <message>
+ <source>Your current balance in watch-only addresses</source>
+ <translation>Ваш поточний баланс в адресах для спостереження</translation>
+ </message>
+ <message>
+ <source>Spendable:</source>
+ <translation>Доступно:</translation>
+ </message>
+ <message>
+ <source>Recent transactions</source>
+ <translation>Останні транзакції</translation>
+ </message>
+ <message>
+ <source>Unconfirmed transactions to watch-only addresses</source>
+ <translation>Непідтверджені транзакції на адреси для спостереження</translation>
+ </message>
+ <message>
+ <source>Mined balance in watch-only addresses that has not yet matured</source>
+ <translation>Баланс видобутих та ще недозрілих монет на адресах для спостереження</translation>
+ </message>
+ <message>
+ <source>Current total balance in watch-only addresses</source>
+ <translation>Поточний сукупний баланс в адресах для спостереження</translation>
+ </message>
+</context>
+<context>
+ <name>PaymentServer</name>
+ <message>
+ <source>URI handling</source>
+ <translation>Обробка URI</translation>
+ </message>
+ <message>
+ <source>Invalid payment address %1</source>
+ <translation>Помилка в адресі платежу %1</translation>
+ </message>
+ <message>
+ <source>Payment request rejected</source>
+ <translation>Запит платежу відхилено</translation>
+ </message>
+ <message>
+ <source>Payment request network doesn't match client network.</source>
+ <translation>Мережа запиту платежу не є мережею клієнта.</translation>
+ </message>
+ <message>
+ <source>Payment request is not initialized.</source>
+ <translation>Запит платежу не ініціалізовано.</translation>
+ </message>
+ <message>
+ <source>Requested payment amount of %1 is too small (considered dust).</source>
+ <translation>Сума запиту платежу для %1 занадто мала (вважається пилом)</translation>
+ </message>
+ <message>
+ <source>Payment request error</source>
+ <translation>Помилка запиту платежу</translation>
+ </message>
+ <message>
+ <source>Cannot start bitcoin: click-to-pay handler</source>
+ <translation>Неможливо запустити bitcoin: обробник click-to-pay</translation>
+ </message>
+ <message>
+ <source>Payment request fetch URL is invalid: %1</source>
+ <translation>URL запиту платежу є некоректним: %1</translation>
+ </message>
+ <message>
+ <source>URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source>
+ <translation>Неможливо обробити URI! Причиною цього може бути некоректна Bitcoin-адреса або неправильні параметри URI.</translation>
+ </message>
+ <message>
+ <source>Payment request file handling</source>
+ <translation>Обробка файлу запиту платежу</translation>
+ </message>
+ <message>
+ <source>Payment request file cannot be read! This can be caused by an invalid payment request file.</source>
+ <translation>Неможливо прочитати файл запиту платежу! Ймовірно, файл пошкоджено.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>Запит платежу прострочено.</translation>
+ </message>
+ <message>
+ <source>Unverified payment requests to custom payment scripts are unsupported.</source>
+ <translation>Неперевірені запити платежів з власними платіжними сценаріями не підтримуються.</translation>
+ </message>
+ <message>
+ <source>Invalid payment request.</source>
+ <translation>Помилка в запиті платежу.</translation>
+ </message>
+ <message>
+ <source>Refund from %1</source>
+ <translation>Відшкодування з %1</translation>
+ </message>
+ <message>
+ <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source>
+ <translation>Запит платежу %1 занадто великий (%2 байт, дозволено %3 байт).</translation>
+ </message>
+ <message>
+ <source>Payment request DoS protection</source>
+ <translation>Оплата потребує захисту DoS</translation>
+ </message>
+ <message>
+ <source>Error communicating with %1: %2</source>
+ <translation>Помилка зв'язку з %1: %2</translation>
+ </message>
+ <message>
+ <source>Payment request cannot be parsed!</source>
+ <translation>Неможливо розпізнати запит платежу!</translation>
+ </message>
+ <message>
+ <source>Bad response from server %1</source>
+ <translation>Погана відповідь від сервера %1</translation>
+ </message>
+ <message>
+ <source>Payment acknowledged</source>
+ <translation>Платіж підтверджено</translation>
+ </message>
+ <message>
+ <source>Network request error</source>
+ <translation>Помилка мережевого запиту</translation>
+ </message>
+</context>
+<context>
+ <name>PeerTableModel</name>
+ <message>
+ <source>User Agent</source>
+ <translation>Клієнт користувача</translation>
+ </message>
+ <message>
+ <source>Node/Service</source>
+ <translation>Вузол/Сервіс</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Затримка</translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>Кількість</translation>
+ </message>
+ <message>
+ <source>Enter a Bitcoin address (e.g. %1)</source>
+ <translation>Введіть адресу Bitcoin (наприклад %1)</translation>
+ </message>
+ <message>
+ <source>%1 d</source>
+ <translation>%1 д</translation>
+ </message>
+ <message>
+ <source>%1 h</source>
+ <translation>%1 г</translation>
+ </message>
+ <message>
+ <source>%1 m</source>
+ <translation>%1 х</translation>
+ </message>
+ <message>
+ <source>%1 s</source>
+ <translation>%1 с</translation>
+ </message>
+ <message>
+ <source>None</source>
+ <translation>Відсутні</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>Н/Д</translation>
+ </message>
+ <message>
+ <source>%1 ms</source>
+ <translation>%1 мс</translation>
+ </message>
+</context>
+<context>
+ <name>QRImageWidget</name>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Зберегти зображення...</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Image</source>
+ <translation>&amp;Копіювати зображення</translation>
+ </message>
+ <message>
+ <source>Save QR Code</source>
+ <translation>Зберегти QR-код</translation>
+ </message>
+ <message>
+ <source>PNG Image (*.png)</source>
+ <translation>Зображення PNG (*.png)</translation>
+ </message>
+</context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>Client name</source>
+ <translation>Назва клієнту</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>Н/Д</translation>
+ </message>
+ <message>
+ <source>Client version</source>
+ <translation>Версія клієнту</translation>
+ </message>
+ <message>
+ <source>&amp;Information</source>
+ <translation>&amp;Інформація</translation>
+ </message>
+ <message>
+ <source>Debug window</source>
+ <translation>Вікно зневадження</translation>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>Загальна</translation>
+ </message>
+ <message>
+ <source>Using OpenSSL version</source>
+ <translation>Використовується OpenSSL версії</translation>
+ </message>
+ <message>
+ <source>Using BerkeleyDB version</source>
+ <translation>Використовується BerkeleyDB версії</translation>
+ </message>
+ <message>
+ <source>Startup time</source>
+ <translation>Час запуску</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Мережа</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>Ім’я</translation>
+ </message>
+ <message>
+ <source>Number of connections</source>
+ <translation>Кількість підключень</translation>
+ </message>
+ <message>
+ <source>Block chain</source>
+ <translation>Ланцюг блоків</translation>
+ </message>
+ <message>
+ <source>Current number of blocks</source>
+ <translation>Поточне число блоків</translation>
+ </message>
+ <message>
+ <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source>
+ <translation>Відкрити файл журналу налагодження Bitcoin Core з поточного каталогу даних. Це може зайняти кілька секунд для великих файлів журналів.</translation>
+ </message>
+ <message>
+ <source>Received</source>
+ <translation>Отримано</translation>
+ </message>
+ <message>
+ <source>Sent</source>
+ <translation>Відправлено</translation>
+ </message>
+ <message>
+ <source>&amp;Peers</source>
+ <translation>&amp;Учасники</translation>
+ </message>
+ <message>
+ <source>Select a peer to view detailed information.</source>
+ <translation>Виберіть учасника для перегляду детальнішої інформації</translation>
+ </message>
+ <message>
+ <source>Direction</source>
+ <translation>Напрямок</translation>
+ </message>
+ <message>
+ <source>Version</source>
+ <translation>Версія</translation>
+ </message>
+ <message>
+ <source>User Agent</source>
+ <translation>Клієнт користувача</translation>
+ </message>
+ <message>
+ <source>Services</source>
+ <translation>Сервіси</translation>
+ </message>
+ <message>
+ <source>Starting Height</source>
+ <translation>Початкова висота</translation>
+ </message>
+ <message>
+ <source>Sync Height</source>
+ <translation>Висота синхронізації</translation>
+ </message>
+ <message>
+ <source>Ban Score</source>
+ <translation>Очки бану</translation>
+ </message>
+ <message>
+ <source>Connection Time</source>
+ <translation>Час з'єднання</translation>
+ </message>
+ <message>
+ <source>Last Send</source>
+ <translation>Востаннє відправлено</translation>
+ </message>
+ <message>
+ <source>Last Receive</source>
+ <translation>Востаннє отримано</translation>
+ </message>
+ <message>
+ <source>Bytes Sent</source>
+ <translation>Байтів відправлено</translation>
+ </message>
+ <message>
+ <source>Bytes Received</source>
+ <translation>Байтів отримано</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Затримка</translation>
+ </message>
+ <message>
+ <source>Time Offset</source>
+ <translation>Різниця часу</translation>
+ </message>
+ <message>
+ <source>Last block time</source>
+ <translation>Час останнього блоку</translation>
+ </message>
+ <message>
+ <source>&amp;Open</source>
+ <translation>&amp;Відкрити</translation>
+ </message>
+ <message>
+ <source>&amp;Console</source>
+ <translation>&amp;Консоль</translation>
+ </message>
+ <message>
+ <source>&amp;Network Traffic</source>
+ <translation>&amp;Мережевий трафік</translation>
+ </message>
+ <message>
+ <source>&amp;Clear</source>
+ <translation>&amp;Очистити</translation>
+ </message>
+ <message>
+ <source>Totals</source>
+ <translation>Всього</translation>
+ </message>
+ <message>
+ <source>In:</source>
+ <translation>Вхідних:</translation>
+ </message>
+ <message>
+ <source>Out:</source>
+ <translation>Вихідних:</translation>
+ </message>
+ <message>
+ <source>Build date</source>
+ <translation>Дата збирання</translation>
+ </message>
+ <message>
+ <source>Debug log file</source>
+ <translation>Файл звіту зневадження</translation>
+ </message>
+ <message>
+ <source>Clear console</source>
+ <translation>Очистити консоль</translation>
+ </message>
+ <message>
+ <source>Welcome to the Bitcoin Core RPC console.</source>
+ <translation>Вітаємо у RPC-консолі Bitcoin Core.</translation>
+ </message>
+ <message>
+ <source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
+ <translation>Використовуйте стрілки вгору вниз для навігації по історії, і &lt;b&gt;Ctrl-L&lt;/b&gt; для очищення екрана.</translation>
+ </message>
+ <message>
+ <source>Type &lt;b&gt;help&lt;/b&gt; for an overview of available commands.</source>
+ <translation>Наберіть &lt;b&gt;help&lt;/b&gt; для перегляду доступних команд.</translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation>%1 Б</translation>
+ </message>
+ <message>
+ <source>%1 KB</source>
+ <translation>%1 КБ</translation>
+ </message>
+ <message>
+ <source>%1 MB</source>
+ <translation>%1 МБ</translation>
+ </message>
+ <message>
+ <source>%1 GB</source>
+ <translation>%1 ГБ</translation>
+ </message>
+ <message>
+ <source>via %1</source>
+ <translation>через %1</translation>
+ </message>
+ <message>
+ <source>never</source>
+ <translation>ніколи</translation>
+ </message>
+ <message>
+ <source>Inbound</source>
+ <translation>Вхідний</translation>
+ </message>
+ <message>
+ <source>Outbound</source>
+ <translation>Вихідний</translation>
+ </message>
+ <message>
+ <source>Unknown</source>
+ <translation>Невідома</translation>
+ </message>
+ <message>
+ <source>Fetching...</source>
+ <translation>Отримання...</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Amount:</source>
+ <translation>&amp;Кількість:</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Мітка:</translation>
+ </message>
+ <message>
+ <source>&amp;Message:</source>
+ <translation>&amp;Повідомлення:</translation>
+ </message>
+ <message>
+ <source>Reuse one of the previously used receiving addresses. Reusing addresses has security and privacy issues. Do not use this unless re-generating a payment request made before.</source>
+ <translation>Повторно використати одну з адрес. Повторне використання адрес створює ризики безпеки та конфіденційності. Не використовуйте її, окрім як для створення повторного запиту платежу.</translation>
+ </message>
+ <message>
+ <source>R&amp;euse an existing receiving address (not recommended)</source>
+ <translation>По&amp;вторно використати адресу для отримання (не рекомендується)</translation>
+ </message>
+ <message>
+ <source>An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network.</source>
+ <translation>Необов'язкове повідомлення на додаток до запиту платежу, котре буде показане під час відкриття запиту. Примітка: Це повідомлення не буде відправлено з платежем через мережу Bitcoin.</translation>
+ </message>
+ <message>
+ <source>An optional label to associate with the new receiving address.</source>
+ <translation>Необов'язкове поле для мітки нової адреси отримувача.</translation>
+ </message>
+ <message>
+ <source>Use this form to request payments. All fields are &lt;b&gt;optional&lt;/b&gt;.</source>
+ <translation>Використовуйте цю форму, щоб отримати платежі. Всі поля є &lt;b&gt;необов'язковими&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>An optional amount to request. Leave this empty or zero to not request a specific amount.</source>
+ <translation>Необов'язкове поле для суми запиту. Залиште це поле пустим або впишіть нуль, щоб не надсилати у запиті конкретної суми.</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Очистити всі поля в формі</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation>Очистити</translation>
+ </message>
+ <message>
+ <source>Requested payments history</source>
+ <translation>Історія запитів платежу</translation>
+ </message>
+ <message>
+ <source>&amp;Request payment</source>
+ <translation>Н&amp;адіслати запит платежу</translation>
+ </message>
+ <message>
+ <source>Show the selected request (does the same as double clicking an entry)</source>
+ <translation>Показати вибраний запит (робить те ж саме, що й подвійний клік по запису)</translation>
+ </message>
+ <message>
+ <source>Show</source>
+ <translation>Показати</translation>
+ </message>
+ <message>
+ <source>Remove the selected entries from the list</source>
+ <translation>Вилучити вибрані записи зі списку</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>Вилучити</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Скопіювати мітку</translation>
+ </message>
+ <message>
+ <source>Copy message</source>
+ <translation>Скопіювати повідомлення</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Копіювати кількість</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>QR Code</source>
+ <translation>QR-Код</translation>
+ </message>
+ <message>
+ <source>Copy &amp;URI</source>
+ <translation>&amp;Скопіювати URI</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Address</source>
+ <translation>Скопіювати &amp;адресу</translation>
+ </message>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Зберегти зображення...</translation>
+ </message>
+ <message>
+ <source>Request payment to %1</source>
+ <translation>Запит платежу на %1</translation>
+ </message>
+ <message>
+ <source>Payment information</source>
+ <translation>Інформація про платіж</translation>
+ </message>
+ <message>
+ <source>URI</source>
+ <translation>URI</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Адреса</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Кількість</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Назва</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Повідомлення</translation>
+ </message>
+ <message>
+ <source>Resulting URI too long, try to reduce the text for label / message.</source>
+ <translation>Кінцевий URI занадто довгий, спробуйте зменшити текст для мітки / повідомлення.</translation>
+ </message>
+ <message>
+ <source>Error encoding URI into QR Code.</source>
+ <translation>Помилка при кодуванні URI в QR-код.</translation>
+ </message>
+</context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Дата</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Назва</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Повідомлення</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Кількість</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(немає назви)</translation>
+ </message>
+ <message>
+ <source>(no message)</source>
+ <translation>(без повідомлення)</translation>
+ </message>
+ <message>
+ <source>(no amount)</source>
+ <translation>(без суми)</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Відправити</translation>
+ </message>
+ <message>
+ <source>Coin Control Features</source>
+ <translation>Керування монетами</translation>
+ </message>
+ <message>
+ <source>Inputs...</source>
+ <translation>Входи...</translation>
+ </message>
+ <message>
+ <source>automatically selected</source>
+ <translation>вибираються автоматично</translation>
+ </message>
+ <message>
+ <source>Insufficient funds!</source>
+ <translation>Недостатньо коштів!</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Кількість:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Байтів:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Сума:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Пріорітет:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Комісія:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Після комісії:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Решта:</translation>
+ </message>
+ <message>
+ <source>If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address.</source>
+ <translation>Якщо це поле активовано, але адреса для решти відсутня або некоректна, то решта буде відправлена на новостворену адресу.</translation>
+ </message>
+ <message>
+ <source>Custom change address</source>
+ <translation>Вказати адресу для решти</translation>
+ </message>
+ <message>
+ <source>Transaction Fee:</source>
+ <translation>Комісія за передачу:</translation>
+ </message>
+ <message>
+ <source>Choose...</source>
+ <translation>Виберіть...</translation>
+ </message>
+ <message>
+ <source>collapse fee-settings</source>
+ <translation>згорнути налаштування оплат</translation>
+ </message>
+ <message>
+ <source>per kilobyte</source>
+ <translation>за кілобайт</translation>
+ </message>
+ <message>
+ <source>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "total at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source>
+ <translation>Якщо комісія встановлюється в 1000 сатоші і розмір транзакції лише 250 байтів, то опція "за кілобайт" встановлює комісію в 250 сатоші, в той час, як "всього щонайменше" - в 1000 сатоші. Для транзакцій більших за кілобайт в обох випадках буде знято комісію за кілобайт.</translation>
+ </message>
+ <message>
+ <source>Hide</source>
+ <translation>Приховати</translation>
+ </message>
+ <message>
+ <source>total at least</source>
+ <translation>всього щонайменше</translation>
+ </message>
+ <message>
+ <source>Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process.</source>
+ <translation>Оплата тільки мінімальної комісії є прийнятною, допоки обсяг транзакцій є меншим простору в блоках. Але майте на увазі, що це може анулювати транзакцію, якщо попит на Bitcoin транзакції стане більшим, ніж мережа зможе обробити.</translation>
+ </message>
+ <message>
+ <source>(read the tooltip)</source>
+ <translation>(читати підказки)</translation>
+ </message>
+ <message>
+ <source>Recommended:</source>
+ <translation>Рекомендовано:</translation>
+ </message>
+ <message>
+ <source>Custom:</source>
+ <translation>Змінено:</translation>
+ </message>
+ <message>
+ <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source>
+ <translation>(Розумну оплату ще не ініціалізовано. Це, зазвичай, триває кілька блоків...)</translation>
+ </message>
+ <message>
+ <source>Confirmation time:</source>
+ <translation>Час підтвердження:</translation>
+ </message>
+ <message>
+ <source>normal</source>
+ <translation>звичайний</translation>
+ </message>
+ <message>
+ <source>fast</source>
+ <translation>швидкий</translation>
+ </message>
+ <message>
+ <source>Send as zero-fee transaction if possible</source>
+ <translation>Надіслати транзакцію без сплати комісії, якщо це можливо</translation>
+ </message>
+ <message>
+ <source>(confirmation may take longer)</source>
+ <translation>(підтвердження може зайняти більше часу)</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>Відправити на декілька адрес</translation>
+ </message>
+ <message>
+ <source>Add &amp;Recipient</source>
+ <translation>Дод&amp;ати одержувача</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Очистити всі поля в формі</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Пил:</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Очистити &amp;все</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>Баланс:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>Підтвердити відправлення</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>&amp;Відправити</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>Підтвердіть відправлення</translation>
+ </message>
+ <message>
+ <source>%1 to %2</source>
+ <translation>%1 на %2</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Копіювати кількість</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Копіювати суму</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Копіювати комісію</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Копіювати після комісії</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Копіювати байти</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Копіювати пріорітет</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Копіювати решту</translation>
+ </message>
+ <message>
+ <source>or</source>
+ <translation>або</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>Кількість монет для відправлення повинна бути більше 0.</translation>
+ </message>
+ <message>
+ <source>The amount exceeds your balance.</source>
+ <translation>Кількість монет для відправлення перевищує ваш баланс.</translation>
+ </message>
+ <message>
+ <source>The total exceeds your balance when the %1 transaction fee is included.</source>
+ <translation>Сума перевищить ваш баланс, якщо комісія %1 буде додана до вашої транзакції.</translation>
+ </message>
+ <message>
+ <source>Transaction creation failed!</source>
+ <translation>Не вдалося створити транзакцію!</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>Транзакцію відхилено! Це може статись, якщо декілька монет з вашого гаманця вже використані, наприклад, якщо ви використовуєте одну копію гаманця (wallet.dat), а монети були використані з іншої копії, але не позначені як використані в цій.</translation>
+ </message>
+ <message>
+ <source>A fee higher than %1 is considered an absurdly high fee.</source>
+ <translation>Плата вища, ніж %1 вважається шалено високою.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>Запит платежу прострочено.</translation>
+ </message>
+ <message numerus="yes">
+ <source>Estimated to begin confirmation within %n block(s).</source>
+ <translation><numerusform>Перше підтвердження очікується протягом %n блоку.</numerusform><numerusform>Перше підтвердження очікується протягом %n блоків.</numerusform><numerusform>Перше підтвердження очікується протягом %n блоків.</numerusform></translation>
+ </message>
+ <message>
+ <source>Pay only the minimum fee of %1</source>
+ <translation>Платити тільки мінімальну комісію у розмірі %1</translation>
+ </message>
+ <message>
+ <source>Total Amount %1&lt;span style='font-size:10pt;font-weight:normal;'&gt;&lt;br /&gt;(=%2)&lt;/span&gt;</source>
+ <translation>Всього %1&lt;span style='font-size:10pt;font-weight:normal;'&gt;&lt;br /&gt;(=%2)&lt;/span&gt;</translation>
+ </message>
+ <message>
+ <source>The recipient address is not valid. Please recheck.</source>
+ <translation>Адреса отримувача неправильна. Будь ласка, перевірте її.</translation>
+ </message>
+ <message>
+ <source>Duplicate address found: addresses should only be used once each.</source>
+ <translation>Знайдено адресу, що дублюється: кожна адреса має бути вказана не більше одного разу.</translation>
+ </message>
+ <message>
+ <source>Warning: Invalid Bitcoin address</source>
+ <translation>Увага: Неправильна Bitcoin-адреса</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(немає назви)</translation>
+ </message>
+ <message>
+ <source>Warning: Unknown change address</source>
+ <translation>Увага: Невідома адреса для решти</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Копіювати пил</translation>
+ </message>
+ <message>
+ <source>Are you sure you want to send?</source>
+ <translation>Ви впевнені, що хочете відправити?</translation>
+ </message>
+ <message>
+ <source>added as transaction fee</source>
+ <translation>додано як комісія за транзакцію</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>&amp;Кількість:</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>&amp;Отримувач:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Введіть мітку для цієї адреси для додавання її в адресну книгу</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Мітка:</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Обрати ранiш використовувану адресу</translation>
+ </message>
+ <message>
+ <source>This is a normal payment.</source>
+ <translation>Це звичайний платіж.</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to send the payment to</source>
+ <translation>Адреса Bitcoin для відправлення платежу</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Вставити адресу</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Remove this entry</source>
+ <translation>Видалити цей запис</translation>
+ </message>
+ <message>
+ <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source>
+ <translation>Комісію буде знято зі вказаної суми. До отримувача надійде менше біткоінів, ніж було вказано в полі кількості. Якщо ж отримувачів декілька - комісію буде розподілено між ними.</translation>
+ </message>
+ <message>
+ <source>S&amp;ubtract fee from amount</source>
+ <translation>В&amp;ідняти комісію від суми</translation>
+ </message>
+ <message>
+ <source>Message:</source>
+ <translation>Повідомлення:</translation>
+ </message>
+ <message>
+ <source>This is an unauthenticated payment request.</source>
+ <translation>Цей запит платежу не є автентифікованим.</translation>
+ </message>
+ <message>
+ <source>This is an authenticated payment request.</source>
+ <translation>Цей запит платежу є автентифікованим.</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to the list of used addresses</source>
+ <translation>Введіть мітку для цієї адреси для додавання її в список використаних адрес</translation>
+ </message>
+ <message>
+ <source>A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network.</source>
+ <translation>Повідомлення, що було додане до bitcoin:URI та буде збережено разом з транзакцією для довідки. Примітка: Це повідомлення не буде відправлено в мережу Bitcoin.</translation>
+ </message>
+ <message>
+ <source>Pay To:</source>
+ <translation>Отримувач:</translation>
+ </message>
+ <message>
+ <source>Memo:</source>
+ <translation>Нотатка:</translation>
+ </message>
+</context>
+<context>
+ <name>ShutdownWindow</name>
+ <message>
+ <source>Bitcoin Core is shutting down...</source>
+ <translation>Bitcoin Core вимикається...</translation>
+ </message>
+ <message>
+ <source>Do not shut down the computer until this window disappears.</source>
+ <translation>Не вимикайте комп’ютер до зникнення цього вікна.</translation>
+ </message>
+</context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Signatures - Sign / Verify a Message</source>
+ <translation>Підписи - Підпис / Перевірка повідомлення</translation>
+ </message>
+ <message>
+ <source>&amp;Sign Message</source>
+ <translation>&amp;Підписати повідомлення</translation>
+ </message>
+ <message>
+ <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source>
+ <translation>Ви можете підписувати повідомлення/угоди своїми адресами, щоб довести можливість отримання біткоінів, що будуть надіслані на них. Остерігайтеся підписувати будь-що нечітке чи неочікуване, так як за допомогою фішинг-атаки вас можуть спробувати ввести в оману для отримання вашого підпису під чужими словами. Підписуйте лише чіткі твердження, з якими ви повністю згодні.</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to sign the message with</source>
+ <translation>Адреса Bitcoin для підпису цього повідомлення</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>Обрати ранiш використовувану адресу</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Вставити адресу</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Enter the message you want to sign here</source>
+ <translation>Введіть повідомлення, яке ви хочете підписати тут</translation>
+ </message>
+ <message>
+ <source>Signature</source>
+ <translation>Підпис</translation>
+ </message>
+ <message>
+ <source>Copy the current signature to the system clipboard</source>
+ <translation>Копіювати поточну сигнатуру до системного буферу обміну</translation>
+ </message>
+ <message>
+ <source>Sign the message to prove you own this Bitcoin address</source>
+ <translation>Підпишіть повідомлення щоб довести, що ви є власником цієї адреси</translation>
+ </message>
+ <message>
+ <source>Sign &amp;Message</source>
+ <translation>&amp;Підписати повідомлення</translation>
+ </message>
+ <message>
+ <source>Reset all sign message fields</source>
+ <translation>Скинути всі поля підпису повідомлення</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>Очистити &amp;все</translation>
+ </message>
+ <message>
+ <source>&amp;Verify Message</source>
+ <translation>П&amp;еревірити повідомлення</translation>
+ </message>
+ <message>
+ <source>Enter the receiver's 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. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source>
+ <translation>Введіть нижче адресу отримувача, повідомлення (впевніться, що ви точно скопіювали символи завершення рядка, табуляцію, пробіли тощо) та підпис для перевірки повідомлення. Впевніться, що в підпис не було додано зайвих символів: це допоможе уникнути атак типу «людина посередині». Зауважте, що це лише засвідчує можливість отримання транзакцій підписувачем, але не в стані підтвердити джерело жодної транзакції!</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address the message was signed with</source>
+ <translation>Адреса Bitcoin, якою було підписано це повідомлення</translation>
+ </message>
+ <message>
+ <source>Verify the message to ensure it was signed with the specified Bitcoin address</source>
+ <translation>Перевірте повідомлення для впевненості, що воно підписано вказаною Bitcoin-адресою</translation>
+ </message>
+ <message>
+ <source>Verify &amp;Message</source>
+ <translation>Пере&amp;вірити повідомлення</translation>
+ </message>
+ <message>
+ <source>Reset all verify message fields</source>
+ <translation>Скинути всі поля перевірки повідомлення</translation>
+ </message>
+ <message>
+ <source>Click "Sign Message" to generate signature</source>
+ <translation>Натисніть кнопку «Підписати повідомлення», для отримання підпису</translation>
+ </message>
+ <message>
+ <source>The entered address is invalid.</source>
+ <translation>Введена нечинна адреса.</translation>
+ </message>
+ <message>
+ <source>Please check the address and try again.</source>
+ <translation>Будь ласка, перевірте адресу та спробуйте ще.</translation>
+ </message>
+ <message>
+ <source>The entered address does not refer to a key.</source>
+ <translation>Введена адреса не відноситься до ключа.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock was cancelled.</source>
+ <translation>Розблокування гаманця було скасоване.</translation>
+ </message>
+ <message>
+ <source>Private key for the entered address is not available.</source>
+ <translation>Приватний ключ для введеної адреси недоступний. </translation>
+ </message>
+ <message>
+ <source>Message signing failed.</source>
+ <translation>Не вдалося підписати повідомлення.</translation>
+ </message>
+ <message>
+ <source>Message signed.</source>
+ <translation>Повідомлення підписано.</translation>
+ </message>
+ <message>
+ <source>The signature could not be decoded.</source>
+ <translation>Підпис не можливо декодувати.</translation>
+ </message>
+ <message>
+ <source>Please check the signature and try again.</source>
+ <translation>Будь ласка, перевірте підпис та спробуйте ще.</translation>
+ </message>
+ <message>
+ <source>The signature did not match the message digest.</source>
+ <translation>Підпис не збігається з хешем повідомлення.</translation>
+ </message>
+ <message>
+ <source>Message verification failed.</source>
+ <translation>Не вдалося перевірити повідомлення.</translation>
+ </message>
+ <message>
+ <source>Message verified.</source>
+ <translation>Повідомлення перевірено.</translation>
+ </message>
+</context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>The Bitcoin Core developers</source>
+ <translation>Розробники Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>[testnet]</source>
+ <translation>[тестова мережа]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ <message>
+ <source>KB/s</source>
+ <translation>КБ/с</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>Відкрито до %1</translation>
+ </message>
+ <message>
+ <source>conflicted</source>
+ <translation>суперечить</translation>
+ </message>
+ <message>
+ <source>%1/offline</source>
+ <translation>%1/поза інтернетом</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/не підтверджено</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 підтверджень</translation>
+ </message>
+ <message>
+ <source>Status</source>
+ <translation>Статус</translation>
+ </message>
+ <message numerus="yes">
+ <source>, broadcast through %n node(s)</source>
+ <translation><numerusform>, розіслано через %n вузол</numerusform><numerusform>, розіслано через %n вузли</numerusform><numerusform>, розіслано через %n вузлів</numerusform></translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Дата</translation>
+ </message>
+ <message>
+ <source>Source</source>
+ <translation>Джерело</translation>
+ </message>
+ <message>
+ <source>Generated</source>
+ <translation>Згенеровано</translation>
+ </message>
+ <message>
+ <source>From</source>
+ <translation>Відправник</translation>
+ </message>
+ <message>
+ <source>To</source>
+ <translation>Отримувач</translation>
+ </message>
+ <message>
+ <source>own address</source>
+ <translation>Власна адреса</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>тільки спостереження</translation>
+ </message>
+ <message>
+ <source>label</source>
+ <translation>Мітка</translation>
+ </message>
+ <message>
+ <source>Credit</source>
+ <translation>Кредит</translation>
+ </message>
+ <message numerus="yes">
+ <source>matures in %n more block(s)</source>
+ <translation><numerusform>«дозріє» через %n блок</numerusform><numerusform>«дозріє» через %n блоки</numerusform><numerusform>«дозріє» через %n блоків</numerusform></translation>
+ </message>
+ <message>
+ <source>not accepted</source>
+ <translation>не прийнято</translation>
+ </message>
+ <message>
+ <source>Debit</source>
+ <translation>Дебет</translation>
+ </message>
+ <message>
+ <source>Total debit</source>
+ <translation>Загальний дебет</translation>
+ </message>
+ <message>
+ <source>Total credit</source>
+ <translation>Загальний кредит</translation>
+ </message>
+ <message>
+ <source>Transaction fee</source>
+ <translation>Комісія за транзакцію</translation>
+ </message>
+ <message>
+ <source>Net amount</source>
+ <translation>Загальна сума</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>Повідомлення</translation>
+ </message>
+ <message>
+ <source>Comment</source>
+ <translation>Коментар</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>ID транзакції</translation>
+ </message>
+ <message>
+ <source>Merchant</source>
+ <translation>Продавець</translation>
+ </message>
+ <message>
+ <source>Generated coins must mature %1 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.</source>
+ <translation>Після генерації монет, потрібно зачекати %1 блоків, перш ніж їх можна буде використати. Коли ви згенерували цей блок, його було відправлено в мережу для того, щоб він був доданий до ланцюжка блоків. Якщо ця процедура не вдасться, статус буде змінено на «не підтверджено» і ви не зможете витратити згенеровані монети. Таке може статись, якщо хтось інший згенерував блок на декілька секунд раніше.</translation>
+ </message>
+ <message>
+ <source>Debug information</source>
+ <translation>Налагоджувальна інформація</translation>
+ </message>
+ <message>
+ <source>Transaction</source>
+ <translation>Транзакція</translation>
+ </message>
+ <message>
+ <source>Inputs</source>
+ <translation>Входи</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Кількість</translation>
+ </message>
+ <message>
+ <source>true</source>
+ <translation>true</translation>
+ </message>
+ <message>
+ <source>false</source>
+ <translation>false</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, ще не було успішно розіслано</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Відкрито на %n блок</numerusform><numerusform>Відкрито на %n блоки</numerusform><numerusform>Відкрито на %n блоків</numerusform></translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>невідомо</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>Деталі транзакції</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>Даний діалог показує детальну статистику по вибраній транзакції</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Дата</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Тип</translation>
+ </message>
+ <message>
+ <source>Immature (%1 confirmations, will be available after %2)</source>
+ <translation>Незрілі (%1 підтверджень, будуть доступні після %2)</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Відкрито на %n блок</numerusform><numerusform>Відкрито на %n блоки</numerusform><numerusform>Відкрито на %n блоків</numerusform></translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>Відкрито до %1</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>Підтверджено (%1 підтверджень)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>Цей блок не був отриманий жодними іншими вузлами і, ймовірно, не буде прийнятий!</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>Згенеровано, але не підтверджено</translation>
+ </message>
+ <message>
+ <source>Offline</source>
+ <translation>Поза мережею</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Назва</translation>
+ </message>
+ <message>
+ <source>Unconfirmed</source>
+ <translation>Не підтверджено</translation>
+ </message>
+ <message>
+ <source>Confirming (%1 of %2 recommended confirmations)</source>
+ <translation>Підтверджується (%1 з %2 рекомендованих підтверджень)</translation>
+ </message>
+ <message>
+ <source>Conflicted</source>
+ <translation>Суперечить</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Отримані на</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>Отримано від</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Відправлені на</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>Відправлено собі</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Добуті</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>тільки спостереження</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(недоступно)</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>Статус транзакції. Наведіть вказівник на це поле, щоб показати кількість підтверджень.</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Дата і час, коли транзакцію було отримано.</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>Тип транзакції.</translation>
+ </message>
+ <message>
+ <source>Whether or not a watch-only address is involved in this transaction.</source>
+ <translation>Показує, чи було залучено адресу для спостереження в цій транзакції.</translation>
+ </message>
+ <message>
+ <source>User-defined intent/purpose of the transaction.</source>
+ <translation>Призначення транзакції (визначається користувачем).</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>Сума, додана чи знята з балансу.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>Всі</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>Сьогодні</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>На цьому тижні</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>На цьому місяці</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>Минулого місяця</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>Цього року</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>Проміжок...</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Отримані на</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Відправлені на</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>Відправлені собі</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Добуті</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>Інше</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>Введіть адресу чи мітку для пошуку</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>Мінімальна сума</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Скопіювати адресу</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Скопіювати мітку</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Скопіювати суму</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Скопіювати ID транзакції </translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>Редагувати мітку</translation>
+ </message>
+ <message>
+ <source>Show transaction details</source>
+ <translation>Показати деталі транзакції</translation>
+ </message>
+ <message>
+ <source>Export Transaction History</source>
+ <translation>Експортувати історію транзакцій</translation>
+ </message>
+ <message>
+ <source>Watch-only</source>
+ <translation>Для спостереження</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Помилка експорту</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the transaction history to %1.</source>
+ <translation>Виникла помилка при спробі зберігання історії транзакцій до %1.</translation>
+ </message>
+ <message>
+ <source>Exporting Successful</source>
+ <translation>Експорт успішно виконано</translation>
+ </message>
+ <message>
+ <source>The transaction history was successfully saved to %1.</source>
+ <translation>Історію транзакцій було успішно збережено до %1.</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Значення, розділені комою (*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Підтверджені</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Дата</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Тип</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Назва</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Адреса</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>Ідентифікатор</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>Діапазон від:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>до</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ <message>
+ <source>Unit to show amounts in. Click to select another unit.</source>
+ <translation>Одиниця виміру монет. Натисніть для вибору іншої.</translation>
+ </message>
+</context>
+<context>
+ <name>WalletFrame</name>
+ <message>
+ <source>No wallet has been loaded.</source>
+ <translation>Гаманець не завантажувався</translation>
+ </message>
+</context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Відправити</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Експорт</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Експортувати дані з поточної вкладки в файл</translation>
+ </message>
+ <message>
+ <source>Backup Wallet</source>
+ <translation>Зробити резервне копіювання гаманця</translation>
+ </message>
+ <message>
+ <source>Wallet Data (*.dat)</source>
+ <translation>Данi гаманця (*.dat)</translation>
+ </message>
+ <message>
+ <source>Backup Failed</source>
+ <translation>Помилка резервного копіювання</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the wallet data to %1.</source>
+ <translation>Виникла помилка при спробі зберегти гаманець в %1.</translation>
+ </message>
+ <message>
+ <source>The wallet data was successfully saved to %1.</source>
+ <translation>Дані гаманця успішно збережено в %1.</translation>
+ </message>
+ <message>
+ <source>Backup Successful</source>
+ <translation>Успішне створення резервної копії</translation>
+ </message>
+</context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>Параметри:</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>Вкажіть робочий каталог</translation>
+ </message>
+ <message>
+ <source>Connect to a node to retrieve peer addresses, and disconnect</source>
+ <translation>Підключитись до вузла, щоб отримати список адрес інших учасників та від'єднатись</translation>
+ </message>
+ <message>
+ <source>Specify your own public address</source>
+ <translation>Вкажіть вашу власну публічну адресу</translation>
+ </message>
+ <message>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>Приймати команди із командного рядка та команди JSON-RPC</translation>
+ </message>
+ <message>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>Запустити в фоновому режимі (як демон) та приймати команди</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>Використовувати тестову мережу</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
+ <translation>Приймати підключення ззовні (типово: 1 за відсутності -proxy чи -connect)</translation>
+ </message>
+ <message>
+ <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
+ <translation>Прив'язатися до даної адреси та прослуховувати її. Використовуйте запис виду [хост]:порт для IPv6</translation>
+ </message>
+ <message>
+ <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
+ <translation>Видалити всі транзакції гаманця та відновити ті, що будуть знайдені під час запуску за допомогою -rescan</translation>
+ </message>
+ <message>
+ <source>Distributed under the MIT software license, see the accompanying file COPYING or &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</source>
+ <translation>Поширюється за ліцензією MIT, додаткова інформація міститься у файлі COPYING та за адресою &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</translation>
+ </message>
+ <message>
+ <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
+ <translation>Виконати команду, коли транзакція гаманця зміниться (замість %s в команді буде підставлено ідентифікатор транзакції)</translation>
+ </message>
+ <message>
+ <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source>
+ <translation>Максимальна загальна комісія за одну транзакцію; занадто низьке значення може скасувати відправку великих транзакцій (типово: %s)</translation>
+ </message>
+ <message>
+ <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, &gt;%u = target size in MiB to use for block files)</source>
+ <translation>Зменшити вимоги до наявного простору на носії даних за допомогою скорочення ланцюжка (видалення старих блоків). Цей режим вимикає підтримку гаманця та є несумісним з параметром -txindex. Увага: при поверненні до типового значення видалені частини ланцюжка буде повторно завантажено. (типово: 0 = вимкнути скорочення ланцюжка, &gt;%u = очікуваний розмір файлів блоків в МіБ)</translation>
+ </message>
+ <message>
+ <source>Set the number of script verification threads (%u to %d, 0 = auto, &lt;0 = leave that many cores free, default: %d)</source>
+ <translation>Встановити кількість потоків скрипту перевірки (від %u до %d, 0 = автоматично, &lt;0 = вказує кількість вільних ядер, типово: %d)</translation>
+ </message>
+ <message>
+ <source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source>
+ <translation>Це тестова збірка пре-релізної версії - використовуйте на свій страх і ризик - не застосовувати для добування монет або торгівлі</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer. Bitcoin Core is probably already running.</source>
+ <translation>Неможливо прив'язатися до %s на цьому комп'ютері. Можливо, Bitcoin Core вже запущено.</translation>
+ </message>
+ <message>
+ <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>УВАГА: аномально висока кількість згенерованих блоків, %d блок(ів) було отримано за останні %d годин(и) (має бути %d)</translation>
+ </message>
+ <message>
+ <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>УВАГА: перевірте ваше мережеве з'єднання, %d блок(ів) було отримано за останні %d годин(и) (має бути %d)</translation>
+ </message>
+ <message>
+ <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>Увага: встановлено занадто велику комісію (-paytxfee). Комісія зніматиметься кожен раз коли ви проводитимете транзакції.</translation>
+ </message>
+ <message>
+ <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source>
+ <translation>Увага: Частина мережі використовує інший головний ланцюжок! Деякі добувачі, можливо, зазнають проблем.</translation>
+ </message>
+ <message>
+ <source>Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.</source>
+ <translation>Увага: Наш ланцюжок блоків відрізняється від ланцюжків підключених учасників! Можливо, вам, або іншим вузлам, необхідно оновитися.</translation>
+ </message>
+ <message>
+ <source>Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
+ <translation>Увага: помилка читання wallet.dat! Всі ключі прочитано коректно, але дані транзакцій чи записи адресної книги можуть бути пропущені, або пошкоджені.</translation>
+ </message>
+ <message>
+ <source>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</source>
+ <translation>Увага: файл wallet.dat пошкоджено, дані врятовано! Оригінальний wallet.dat збережено як wallet.{timestamp}.bak до %s; якщо Ваш баланс чи транзакції неправильні, Ви можете відновити їх з резервної копії. </translation>
+ </message>
+ <message>
+ <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source>
+ <translation>Додати учасників, що під'єднуються з заданої підмережі чи IP-адреси, в білий список. Можна вказувати декілька разів.</translation>
+ </message>
+ <message>
+ <source>(default: 1)</source>
+ <translation>(типово: 1)</translation>
+ </message>
+ <message>
+ <source>&lt;category&gt; can be:</source>
+ <translation>&lt;category&gt; може бути:</translation>
+ </message>
+ <message>
+ <source>Attempt to recover private keys from a corrupt wallet.dat</source>
+ <translation>Спроба відновити закриті ключі з пошкодженого wallet.dat</translation>
+ </message>
+ <message>
+ <source>Block creation options:</source>
+ <translation>Опції створення блоку:</translation>
+ </message>
+ <message>
+ <source>Connect only to the specified node(s)</source>
+ <translation>Підключитись лише до вказаного вузла/вузлів</translation>
+ </message>
+ <message>
+ <source>Connection options:</source>
+ <translation>Параметри з'єднання:</translation>
+ </message>
+ <message>
+ <source>Corrupted block database detected</source>
+ <translation>Виявлено пошкоджений блок бази даних</translation>
+ </message>
+ <message>
+ <source>Debugging/Testing options:</source>
+ <translation>Параметри тестування/налагодження:</translation>
+ </message>
+ <message>
+ <source>Do not load the wallet and disable wallet RPC calls</source>
+ <translation>Не завантажувати гаманець та вимкнути звернення до нього через RPC</translation>
+ </message>
+ <message>
+ <source>Do you want to rebuild the block database now?</source>
+ <translation>Ви хочете перебудувати базу даних блоків зараз?</translation>
+ </message>
+ <message>
+ <source>Error initializing block database</source>
+ <translation>Помилка ініціалізації бази даних блоків</translation>
+ </message>
+ <message>
+ <source>Error initializing wallet database environment %s!</source>
+ <translation>Помилка ініціалізації середовища бази даних гаманця %s!</translation>
+ </message>
+ <message>
+ <source>Error loading block database</source>
+ <translation>Помилка завантаження бази даних блоків</translation>
+ </message>
+ <message>
+ <source>Error opening block database</source>
+ <translation>Помилка відкриття блоку бази даних </translation>
+ </message>
+ <message>
+ <source>Error: Disk space is low!</source>
+ <translation>Помилка: Мало вільного місця на диску!</translation>
+ </message>
+ <message>
+ <source>Failed to listen on any port. Use -listen=0 if you want this.</source>
+ <translation>Не вдалося слухати на жодному порту. Використовуйте -listen=0, якщо ви хочете цього.</translation>
+ </message>
+ <message>
+ <source>If &lt;category&gt; is not supplied, output all debugging information.</source>
+ <translation>Якщо &lt;category&gt; не задано, виводить всю налагоджувальну інформацію.</translation>
+ </message>
+ <message>
+ <source>Importing...</source>
+ <translation>Імпорт...</translation>
+ </message>
+ <message>
+ <source>Incorrect or no genesis block found. Wrong datadir for network?</source>
+ <translation>Початковий блок некоректний/відсутній. Чи правильно вказано каталог даних для обраної мережі?</translation>
+ </message>
+ <message>
+ <source>Invalid -onion address: '%s'</source>
+ <translation>Помилка в адресі -onion: «%s»</translation>
+ </message>
+ <message>
+ <source>Not enough file descriptors available.</source>
+ <translation>Бракує доступних дескрипторів файлів.</translation>
+ </message>
+ <message>
+ <source>Only connect to nodes in network &lt;net&gt; (ipv4, ipv6 or onion)</source>
+ <translation>Підключатися тільки до вузлів в мережі &lt;net&gt; (ipv4, ipv6 або onion)</translation>
+ </message>
+ <message>
+ <source>Prune cannot be configured with a negative value.</source>
+ <translation>Розмір скороченого ланцюжка блоків не може бути від'ємним. </translation>
+ </message>
+ <message>
+ <source>Prune mode is incompatible with -txindex.</source>
+ <translation>Використання скороченого ланцюжка блоків несумісне з параметром -txindex.</translation>
+ </message>
+ <message>
+ <source>Set database cache size in megabytes (%d to %d, default: %d)</source>
+ <translation>Встановити розмір кешу бази даних в мегабайтах (від %d до %d, типово: %d)</translation>
+ </message>
+ <message>
+ <source>Set maximum block size in bytes (default: %d)</source>
+ <translation>Встановити максимальний розмір блоку у байтах (типово: %d)</translation>
+ </message>
+ <message>
+ <source>Specify wallet file (within data directory)</source>
+ <translation>Вкажіть файл гаманця (в межах каталогу даних)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: %u)</source>
+ <translation>Намагатись використовувати UPnP для відображення порту, що прослуховується, на роутері (типово: %u)</translation>
+ </message>
+ <message>
+ <source>Verifying blocks...</source>
+ <translation>Перевірка блоків...</translation>
+ </message>
+ <message>
+ <source>Verifying wallet...</source>
+ <translation>Перевірка гаманця... </translation>
+ </message>
+ <message>
+ <source>Wallet %s resides outside data directory %s</source>
+ <translation>Гаманець %s знаходиться поза каталогом даних %s</translation>
+ </message>
+ <message>
+ <source>Wallet options:</source>
+ <translation>Параметри гаманця:</translation>
+ </message>
+ <message>
+ <source>Warning: This version is obsolete; upgrade required!</source>
+ <translation>Увага: Поточна версія застаріла, необхідне оновлення!</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to change -txindex</source>
+ <translation>Вам необхідно перебудувати базу даних з використанням -reindex для того, щоб змінити -txindex</translation>
+ </message>
+ <message>
+ <source>Imports blocks from external blk000??.dat file</source>
+ <translation>Імпорт блоків з зовнішнього файлу blk000??.dat</translation>
+ </message>
+ <message>
+ <source>Allow JSON-RPC connections from specified source. Valid for &lt;ip&gt; are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times</source>
+ <translation>Дозволити підключення по протоколу JSON-RPC зі вказаного джерела. Правильною для &lt;ip&gt; є окрема IP-адреса (наприклад, 1.2.3.4), IP-адреса та маска підмережі (наприклад, 1.2.3.4/255.255.255.0) або CIDR-адреса (наприклад, 1.2.3.4/24). Цей параметр можна вказувати декілька разів.</translation>
+ </message>
+ <message>
+ <source>An error occurred while setting up the RPC address %s port %u for listening: %s</source>
+ <translation>Сталася помилка при спробі відкрити порт RPC-адреси %s:%u для прослуховування: %s</translation>
+ </message>
+ <message>
+ <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source>
+ <translation>Прив'язатися до даної адреси та вносити до білого списку учасників, що під'єднуються до неї. Використовуйте запис виду [хост]:порт для IPv6</translation>
+ </message>
+ <message>
+ <source>Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)</source>
+ <translation>Прив'язатися до даної адреси для прослуховування JSON-RPC підключень. Використовуйте запис виду [хост]:порт для IPv6. Цей параметр можна вказувати декілька разів (типово: прив'язуватися до всіх інтерфейсів)</translation>
+ </message>
+ <message>
+ <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source>
+ <translation>Не вдалося встановити блокування на каталог даних %s. Bitcoin Core, ймовірно, вже запущений.</translation>
+ </message>
+ <message>
+ <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
+ <translation>Створювати нові файли з типовими для системи атрибутами доступу замість маски 077 (діє тільки при вимкненому гаманці)</translation>
+ </message>
+ <message>
+ <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source>
+ <translation>Визначити власні IP-адреси (типово: 1 при прослуховуванні та за відсутності -externalip або -proxy)</translation>
+ </message>
+ <message>
+ <source>Error: Listening for incoming connections failed (listen returned error %s)</source>
+ <translation>Помилка: Не вдалося налаштувати прослуховування вхідних підключень (listen повернув помилку: %s)</translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source>
+ <translation>Помилка: Параметр -socks не підтримується. Можливість вказувати версію SOCKS було видалено, так як підтримується лише SOCKS5.</translation>
+ </message>
+ <message>
+ <source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source>
+ <translation>Виконати команду при надходженні важливого сповіщення або при спостереженні тривалого розгалуження ланцюжка (замість %s буде підставлено повідомлення)</translation>
+ </message>
+ <message>
+ <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source>
+ <translation>Комісії (в BTC/КБ), що менші за вказану, вважатимуться нульовими (для ретрансляції) (типово: %s)</translation>
+ </message>
+ <message>
+ <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
+ <translation>Якщо параметр paytxfee не встановлено, включити комісію для отримання перших підтверджень транзакцій протягом n блоків (типово: %u)</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)</source>
+ <translation>Неприпустима сума для -maxtxfee = &lt;amount&gt;: «%s» ( плата повинна бути, принаймні %s, щоб запобігти зависанню транзакцій)</translation>
+ </message>
+ <message>
+ <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source>
+ <translation>Максимальний розмір даних в транзакціях носіїв даних, що ми передаємо і добуваємо (за замовчуванням: %u)</translation>
+ </message>
+ <message>
+ <source>Prune configured below the minimum of %d MB. Please use a higher number.</source>
+ <translation>Встановлений розмір ланцюжка блоків є замалим (менший за %d МБ). Будь ласка, виберіть більше число.</translation>
+ </message>
+ <message>
+ <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source>
+ <translation>Дізнаватися адреси учасників через DNS при замалій кількості відомих адрес (типово: 1 за відсутності -connect)</translation>
+ </message>
+ <message>
+ <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source>
+ <translation>Надавати випадкові дані доступу для кожного проксі-з'єднання. Це дозволяє ввімкнути ізоляцію потоків Tor'у (типово: %u)</translation>
+ </message>
+ <message>
+ <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
+ <translation>Встановити максимальний розмір транзакцій з високим пріоритетом та низькою комісією (в байтах) (типово: %d)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source>
+ <translation>Встановити кількість потоків для генерації монет (-1 = кількості ядер, типово: %d)</translation>
+ </message>
+ <message>
+ <source>The transaction amount is too small to send after the fee has been deducted</source>
+ <translation>Залишок від суми транзакції зі сплатою комісії занадто малий </translation>
+ </message>
+ <message>
+ <source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit &lt;https://www.openssl.org/&gt; and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source>
+ <translation>Цей продукт включає в себе програмне забезпечення, розроблене в рамках проекту OpenSSL &lt;https://www.openssl.org/&gt;, криптографічне програмне забезпечення, написане Еріком Янгом, та функції для роботи з UPnP, написані Томасом Бернардом.</translation>
+ </message>
+ <message>
+ <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an 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)
+The username and password MUST NOT be the same.
+If the file does not exist, create it with owner-readable-only file permissions.
+It is also recommended to set alertnotify so you are notified of problems;
+for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
+</source>
+ <translation>Для використання bitcoind, або bitcoin-qt з параметром -server, ви повинні встановити rpcpassword в файлі конфігурації:
+%s
+Рекомендується використати такий випадковий пароль:
+rpcuser=bitcoinrpc
+rpcpassword=%s
+(вам не треба запам'ятовувати цей пароль)
+Ім'я користувача та пароль ПОВИННІ бути різними.
+Якщо файлу не існує, створіть його, обмеживши доступ правом читання для власника.
+Також рекомендується використовувати alertnotify для того, щоб отримувати сповіщення про проблеми;
+наприклад: alertnotify=echo %%s | mail -s "Сповіщення Bitcoin" admin@foo.com
+</translation>
+ </message>
+ <message>
+ <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source>
+ <translation>Увага: установлено дуже велике значення -maxtxfee! Такі великі комісії можуть бути сплачені в окремій транзакції.</translation>
+ </message>
+ <message>
+ <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source>
+ <translation>Увага: будь ласка, перевірте дату і час на своєму комп'ютері! Якщо ваш годинник йде неправильно, Bitcoin Core може працювати некоректно.</translation>
+ </message>
+ <message>
+ <source>Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway</source>
+ <translation>Учасники, що знаходяться в білому списку, не можуть бути заблоковані за DoS та їхні транзакції завжди ретранслюватимуться (навіть якщо вони є в пам'яті), що може бути корисним, наприклад, для шлюзу</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source>
+ <translation>Вам необхідно перебудувати базу даних з використанням -reindex для завантаження повного ланцюжка блоків.</translation>
+ </message>
+ <message>
+ <source>(default: %u)</source>
+ <translation>(типово: %u)</translation>
+ </message>
+ <message>
+ <source>Accept public REST requests (default: %u)</source>
+ <translation>Приймати публічні REST-запити (типово: %u)</translation>
+ </message>
+ <message>
+ <source>Activating best chain...</source>
+ <translation>Активація найкращого ланцюжка...</translation>
+ </message>
+ <message>
+ <source>Can't run with a wallet in prune mode.</source>
+ <translation>Використання гаманця зі скороченим ланцюжком блоків неможливе.</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -whitebind address: '%s'</source>
+ <translation>Не вдалося розпізнати адресу для -whitebind: «%s»</translation>
+ </message>
+ <message>
+ <source>Choose data directory on startup (default: 0)</source>
+ <translation>Обрати каталог даних під час запуску (типово: 0)</translation>
+ </message>
+ <message>
+ <source>Connect through SOCKS5 proxy</source>
+ <translation>Підключитись через SOCKS5-проксі</translation>
+ </message>
+ <message>
+ <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source>
+ <translation>(C) 2009-%i Розробники Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Could not parse -rpcbind value %s as network address</source>
+ <translation>Неможливо розпізнати мережеву адресу для параметру -rpcbind (%s)</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source>
+ <translation>Помилка при завантаженні wallet.dat: Гаманець потребує новішої версії Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Error reading from database, shutting down.</source>
+ <translation>Помилка читання бази даних, припиняю роботу.</translation>
+ </message>
+ <message>
+ <source>Error: A fatal internal error occurred, see debug.log for details</source>
+ <translation>Помилка: Сталася фатальна помилка (детальніший опис наведено в debug.log)</translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -tor found, use -onion.</source>
+ <translation>Помилка: Параметр -tor не підтримується, використовуйте -onion</translation>
+ </message>
+ <message>
+ <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source>
+ <translation>Комісія (в BTC/КБ), що додаватиметься до вихідних транзакцій (типово: %s)</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Інформація</translation>
+ </message>
+ <message>
+ <source>Initialization sanity check failed. Bitcoin Core is shutting down.</source>
+ <translation>Не вдалося пройти базові перевірки під час ініціалізації. Bitcoin Core буде вимкнено.</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Неприпустима сума для -maxtxfee = &lt;amount&gt;: «%s»</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -minrelaytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Вказано некоректну суму для параметру -minrelaytxfee: «%s»</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -mintxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Вказано некоректну суму для параметру -mintxfee: «%s»</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s' (must be at least %s)</source>
+ <translation>Вказано некоректну суму для параметру -paytxfee: «%s» (повинно бути щонайменше %s)</translation>
+ </message>
+ <message>
+ <source>Invalid netmask specified in -whitelist: '%s'</source>
+ <translation>Вказано неправильну маску підмережі для -whitelist: «%s»</translation>
+ </message>
+ <message>
+ <source>Keep at most &lt;n&gt; unconnectable transactions in memory (default: %u)</source>
+ <translation>Утримувати в пам'яті щонайбільше &lt;n&gt; транзакцій, що споживають невідомі входи (типово: %u)</translation>
+ </message>
+ <message>
+ <source>Need to specify a port with -whitebind: '%s'</source>
+ <translation>Необхідно вказати порт для -whitebind: «%s»</translation>
+ </message>
+ <message>
+ <source>Node relay options:</source>
+ <translation>Параметри вузла ретрансляції:</translation>
+ </message>
+ <message>
+ <source>Pruning blockstore...</source>
+ <translation>Скорочення кількості блоків...</translation>
+ </message>
+ <message>
+ <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source>
+ <translation>Параметри RPC SSL: (див. Bitcoin Wiki для налаштування SSL)</translation>
+ </message>
+ <message>
+ <source>RPC server options:</source>
+ <translation>Параметри сервера RPC:</translation>
+ </message>
+ <message>
+ <source>RPC support for HTTP persistent connections (default: %d)</source>
+ <translation>Підтримка RPC для постійних HTTP-з'єднань (типово: %d)</translation>
+ </message>
+ <message>
+ <source>Rebuild block chain index from current blk000??.dat files on startup</source>
+ <translation>При запуску перебудувати індекс ланцюжка блоків з поточних файлів blk000??.dat</translation>
+ </message>
+ <message>
+ <source>Receive and display P2P network alerts (default: %u)</source>
+ <translation>Отримувати та відображати попередження з мережі (типово: %u)</translation>
+ </message>
+ <message>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>Відсилати налагоджувальну інформацію на консоль, а не у файл debug.log</translation>
+ </message>
+ <message>
+ <source>Send transactions as zero-fee transactions if possible (default: %u)</source>
+ <translation>Не сплачувати комісію за надсилання транзакцій, якщо це можливо (типово: %u)</translation>
+ </message>
+ <message>
+ <source>Set SSL root certificates for payment request (default: -system-)</source>
+ <translation>Вказати кореневі SSL-сертифікати для запиту платежу (типово: -системні-)</translation>
+ </message>
+ <message>
+ <source>Set language, for example "de_DE" (default: system locale)</source>
+ <translation>Встановлення мови, наприклад "de_DE" (типово: системна)</translation>
+ </message>
+ <message>
+ <source>Show all debugging options (usage: --help -help-debug)</source>
+ <translation>Показати всі налагоджувальні параметри (використання: --help -help-debug)</translation>
+ </message>
+ <message>
+ <source>Show splash screen on startup (default: 1)</source>
+ <translation>Показувати заставку під час запуску (типово: 1)</translation>
+ </message>
+ <message>
+ <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source>
+ <translation>Стискати файл debug.log під час старту клієнта (типово: 1 коли відсутній параметр -debug)</translation>
+ </message>
+ <message>
+ <source>Signing transaction failed</source>
+ <translation>Підписання транзакції не вдалося</translation>
+ </message>
+ <message>
+ <source>Start minimized</source>
+ <translation>Запускати згорнутим</translation>
+ </message>
+ <message>
+ <source>The transaction amount is too small to pay the fee</source>
+ <translation>Неможливо сплатити комісію із-за малої суми транзакції</translation>
+ </message>
+ <message>
+ <source>This is experimental software.</source>
+ <translation>Це програмне забезпечення є експериментальним.</translation>
+ </message>
+ <message>
+ <source>Transaction amount too small</source>
+ <translation>Сума транзакції занадто мала</translation>
+ </message>
+ <message>
+ <source>Transaction amounts must be positive</source>
+ <translation>Суми монет у транзакції мають бути позитивними</translation>
+ </message>
+ <message>
+ <source>Transaction too large for fee policy</source>
+ <translation>Транзакція занадто велика для правил комісії</translation>
+ </message>
+ <message>
+ <source>Transaction too large</source>
+ <translation>Транзакція занадто велика</translation>
+ </message>
+ <message>
+ <source>UI Options:</source>
+ <translation>Параметри інтерфейсу:</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer (bind returned error %s)</source>
+ <translation>Неможливо прив'язатися до %s на цьому комп'ютері (bind повернув помилку: %s)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: 1 when listening)</source>
+ <translation>Намагатись використовувати UPnP для відображення порту, що прослуховується на роутері (типово: 1 коли прослуховується)</translation>
+ </message>
+ <message>
+ <source>Username for JSON-RPC connections</source>
+ <translation>Ім'я користувача для JSON-RPC-з'єднань</translation>
+ </message>
+ <message>
+ <source>Wallet needed to be rewritten: restart Bitcoin Core to complete</source>
+ <translation>Потрібно перезаписати гаманець: перезапустіть Bitcoin Core для завершення</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Попередження</translation>
+ </message>
+ <message>
+ <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source>
+ <translation>Увага: Параметр -benchmark не підтримується та буде проігнорований, використовуйте -debug=bench.</translation>
+ </message>
+ <message>
+ <source>Warning: Unsupported argument -debugnet ignored, use -debug=net.</source>
+ <translation>Увага: Параметр -debugnet не підтримується та буде проігнорований, використовуйте -debug=net.</translation>
+ </message>
+ <message>
+ <source>Zapping all transactions from wallet...</source>
+ <translation>Видалення всіх транзакцій з гаманця...</translation>
+ </message>
+ <message>
+ <source>on startup</source>
+ <translation>під час запуску</translation>
+ </message>
+ <message>
+ <source>wallet.dat corrupt, salvage failed</source>
+ <translation>wallet.dat пошкоджено, відновлення не вдалося</translation>
+ </message>
+ <message>
+ <source>Password for JSON-RPC connections</source>
+ <translation>Пароль для JSON-RPC-з'єднань</translation>
+ </message>
+ <message>
+ <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
+ <translation>Виконати команду, коли з'явиться новий блок (%s в команді змінюється на хеш блоку)</translation>
+ </message>
+ <message>
+ <source>Upgrade wallet to latest format</source>
+ <translation>Модернізувати гаманець до найновішого формату</translation>
+ </message>
+ <message>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>Пересканувати ланцюжок блоків, в пошуку втрачених транзакцій</translation>
+ </message>
+ <message>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>Використовувати OpenSSL (https) для JSON-RPC-з'єднань</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>Дана довідка</translation>
+ </message>
+ <message>
+ <source>Allow DNS lookups for -addnode, -seednode and -connect</source>
+ <translation>Дозволити пошук в DNS для команд -addnode, -seednode та -connect</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>Завантаження адрес...</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>Помилка при завантаженні wallet.dat: Гаманець пошкоджено</translation>
+ </message>
+ <message>
+ <source>(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source>
+ <translation>(1 = утримувати метадані транзакцій (до яких відноситься інформація про власника рахунку та запити платежів), 2 - відкинути)</translation>
+ </message>
+ <message>
+ <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
+ <translation>Рівень ретельності перевірки блоків (0-4, типово: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
+ <translation>Утримувати повний індекс транзакцій (використовується RPC-викликом getrawtransaction) (типово: %u)</translation>
+ </message>
+ <message>
+ <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source>
+ <translation>Час в секундах, протягом якого відключені учасники з поганою поведінкою не зможуть підключитися (типово: %u)</translation>
+ </message>
+ <message>
+ <source>Output debugging information (default: %u, supplying &lt;category&gt; is optional)</source>
+ <translation>Виводити налагоджувальну інформацію (типово: %u, вказання &lt;category&gt; необов'язкове)</translation>
+ </message>
+ <message>
+ <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source>
+ <translation>Використовувати окремий SOCKS5-проксі для з'єднання з учасниками через приховані сервіси Tor (типово: %s)</translation>
+ </message>
+ <message>
+ <source>(default: %s)</source>
+ <translation>(типово: %s)</translation>
+ </message>
+ <message>
+ <source>Acceptable ciphers (default: %s)</source>
+ <translation>Допустимі шифри (типово: %s)</translation>
+ </message>
+ <message>
+ <source>Always query for peer addresses via DNS lookup (default: %u)</source>
+ <translation>Завжди дізнаватися адреси учасників через DNS (типово: %u)</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>Помилка при завантаженні wallet.dat</translation>
+ </message>
+ <message>
+ <source>Generate coins (default: %u)</source>
+ <translation>Генерація монет (типово: %u)</translation>
+ </message>
+ <message>
+ <source>How many blocks to check at startup (default: %u, 0 = all)</source>
+ <translation>Скільки блоків перевіряти під час запуску (типово: %u, 0 = всі)</translation>
+ </message>
+ <message>
+ <source>Include IP addresses in debug output (default: %u)</source>
+ <translation>Включити IP-адреси до налагоджувального виводу (типово: %u)</translation>
+ </message>
+ <message>
+ <source>Invalid -proxy address: '%s'</source>
+ <translation>Помилка в адресі проксі-сервера: «%s»</translation>
+ </message>
+ <message>
+ <source>Listen for JSON-RPC connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>Прослуховувати &lt;port&gt; для JSON-RPC з'єднань (типово: %u, для тестової мережі: %u)</translation>
+ </message>
+ <message>
+ <source>Listen for connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>Чекати на з'єднання на &lt;port&gt; (типово: %u, для тестової мережі: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain at most &lt;n&gt; connections to peers (default: %u)</source>
+ <translation>Підтримувати щонайбільше &lt;n&gt; з'єднань з учасниками (типово: %u)</translation>
+ </message>
+ <message>
+ <source>Make the wallet broadcast transactions</source>
+ <translation>Дозволити гаманцю розповсюджувати транзакції</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection receive buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>Максимальний розмір вхідного буферу на одне з'єднання, &lt;n&gt;*1000 байтів (типово: %u)</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection send buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>Максимальний розмір вихідного буферу на одне з'єднання, &lt;n&gt;*1000 байтів (типово: %u)</translation>
+ </message>
+ <message>
+ <source>Prepend debug output with timestamp (default: %u)</source>
+ <translation>Доповнювати налагоджувальний вивід відміткою часу (типово: %u)</translation>
+ </message>
+ <message>
+ <source>Relay and mine data carrier transactions (default: %u)</source>
+ <translation>Ретранслювати та створювати транзакції носіїв даних (типово: %u)</translation>
+ </message>
+ <message>
+ <source>Relay non-P2SH multisig (default: %u)</source>
+ <translation>Ретранслювати не-P2SH транзакції з мультипідписом (типово: %u)</translation>
+ </message>
+ <message>
+ <source>Server certificate file (default: %s)</source>
+ <translation>Файл сертифіката сервера (типово: %s)</translation>
+ </message>
+ <message>
+ <source>Server private key (default: %s)</source>
+ <translation>Закритий ключ сервера (типово: %s)</translation>
+ </message>
+ <message>
+ <source>Set key pool size to &lt;n&gt; (default: %u)</source>
+ <translation>Встановити розмір пулу ключів &lt;n&gt; (типово: %u)</translation>
+ </message>
+ <message>
+ <source>Set minimum block size in bytes (default: %u)</source>
+ <translation>Встановити мінімальний розмір блоку в байтах (типово: %u)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads to service RPC calls (default: %d)</source>
+ <translation>Встановити число потоків для обслуговування викликів RPC (типово: %d)</translation>
+ </message>
+ <message>
+ <source>Specify configuration file (default: %s)</source>
+ <translation>Вказати файл конфігурації (типово: %s)</translation>
+ </message>
+ <message>
+ <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source>
+ <translation>Вказати тайм-аут підключення в мілісекундах (щонайменше: 1, типово: %d)</translation>
+ </message>
+ <message>
+ <source>Specify pid file (default: %s)</source>
+ <translation>Вказати pid-файл (типово: %s)</translation>
+ </message>
+ <message>
+ <source>Spend unconfirmed change when sending transactions (default: %u)</source>
+ <translation>Витрачати непідтверджену решту при відправленні транзакцій (типово: %u)</translation>
+ </message>
+ <message>
+ <source>Threshold for disconnecting misbehaving peers (default: %u)</source>
+ <translation>Поріг відключення учасників з поганою поведінкою (типово: %u)</translation>
+ </message>
+ <message>
+ <source>Unknown network specified in -onlynet: '%s'</source>
+ <translation>Невідома мережа вказана в -onlynet: «%s»</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -bind address: '%s'</source>
+ <translation>Не вдалося розпізнати адресу для -bind: «%s»</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -externalip address: '%s'</source>
+ <translation>Не вдалося розпізнати адресу для -externalip: «%s»</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Помилка у величині комісії -paytxfee=&lt;amount&gt;: «%s»</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>Недостатньо коштів</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>Завантаження індексу блоків...</translation>
+ </message>
+ <message>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>Додати вузол до підключення і лишити його відкритим</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>Завантаження гаманця...</translation>
+ </message>
+ <message>
+ <source>Cannot downgrade wallet</source>
+ <translation>Не вдається понизити версію гаманця</translation>
+ </message>
+ <message>
+ <source>Cannot write default address</source>
+ <translation>Неможливо записати типову адресу</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>Сканування...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>Завантаження завершене</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Помилка</translation>
+ </message>
+</context>
+</TS> \ No newline at end of file
diff --git a/src/qt/locale/bitcoin_ur_PK.ts b/src/qt/locale/bitcoin_ur_PK.ts
new file mode 100644
index 0000000000..d4242d5e3c
--- /dev/null
+++ b/src/qt/locale/bitcoin_ur_PK.ts
@@ -0,0 +1,366 @@
+<TS language="ur_PK" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Right-click to edit address or label</source>
+ <translation>پتہ تبدیل کرے کے لیے دائیاں کلک کریں</translation>
+ </message>
+ <message>
+ <source>Create a new address</source>
+ <translation>نیا ایڈریس بنائیں</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>نیا</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>سلیکٹڈ پتے کو کمپوٹر کی عارضی جگہ رکھیں</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>نقل</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>بند</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>کاپی پتہ</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>سلیکٹڈ پتے کو مٹائیں</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>موجودہ ڈیٹا کو فائیل میں محفوظ کریں</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>برآمد</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>مٹا</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>کوئین وصول کرنے والے کا پتہ</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>کوئین بھیجنے والے کا پتہ</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>چننا</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>جس پتے پر بھیجنے ہیں</translation>
+ </message>
+ </context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>چٹ</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation> پتہ</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>چٹ کے بغیر</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>پاس فریز داخل کریں</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>نیا پاس فریز</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>نیا پاس فریز دہرائیں</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>بٹوے کی رمزنگاری</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>بٹوا ان لاک</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>خفیہ کشائی کر یںبٹوے کے</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>پاس فریز تبدیل کریں</translation>
+ </message>
+ </context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Error</source>
+ <translation>نقص</translation>
+ </message>
+ </context>
+<context>
+ <name>ClientModel</name>
+ </context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Amount</source>
+ <translation>رقم</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>تاریخ</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>چٹ کے بغیر</translation>
+ </message>
+ </context>
+<context>
+ <name>EditAddressDialog</name>
+ </context>
+<context>
+ <name>FreespaceChecker</name>
+ </context>
+<context>
+ <name>HelpMessageDialog</name>
+ </context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Error</source>
+ <translation>نقص</translation>
+ </message>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ </context>
+<context>
+ <name>OptionsDialog</name>
+ </context>
+<context>
+ <name>OverviewPage</name>
+ </context>
+<context>
+ <name>PaymentServer</name>
+ </context>
+<context>
+ <name>PeerTableModel</name>
+ </context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>رقم</translation>
+ </message>
+ </context>
+<context>
+ <name>QRImageWidget</name>
+ </context>
+<context>
+ <name>RPCConsole</name>
+ </context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ </context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>Address</source>
+ <translation> پتہ</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>رقم</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>چٹ</translation>
+ </message>
+ </context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>تاریخ</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>چٹ</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>رقم</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>چٹ کے بغیر</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Balance:</source>
+ <translation>بیلنس:</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>چٹ کے بغیر</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsEntry</name>
+ </context>
+<context>
+ <name>ShutdownWindow</name>
+ </context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ </context>
+<context>
+ <name>SplashScreen</name>
+ </context>
+<context>
+ <name>TrafficGraphWidget</name>
+ </context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Date</source>
+ <translation>تاریخ</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>رقم</translation>
+ </message>
+ </context>
+<context>
+ <name>TransactionDescDialog</name>
+ </context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>تاریخ</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>ٹائپ</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>چٹ</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>کو بھیجا</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(N / A)</translation>
+ </message>
+ </context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>تمام</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>آج</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>اس ہفتے</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>اس مہینے</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>پچھلے مہینے</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>اس سال</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>دیگر</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>کو بھیجا</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>تاریخ</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>ٹائپ</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>چٹ</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation> پتہ</translation>
+ </message>
+ </context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ </context>
+<context>
+ <name>WalletFrame</name>
+ </context>
+<context>
+ <name>WalletModel</name>
+ </context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>برآمد</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>موجودہ ڈیٹا کو فائیل میں محفوظ کریں</translation>
+ </message>
+ </context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>This help message</source>
+ <translation>یہ مدد کا پیغام</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>ناکافی فنڈز</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>نقص</translation>
+ </message>
+</context>
+</TS> \ No newline at end of file
diff --git a/src/qt/locale/bitcoin_uz@Cyrl.ts b/src/qt/locale/bitcoin_uz@Cyrl.ts
new file mode 100644
index 0000000000..cc0a4bba08
--- /dev/null
+++ b/src/qt/locale/bitcoin_uz@Cyrl.ts
@@ -0,0 +1,1914 @@
+<TS language="uz@Cyrl" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Right-click to edit address or label</source>
+ <translation>Манзил ёки ёрлиқни таҳрирлаш учун икки марта босинг</translation>
+ </message>
+ <message>
+ <source>Create a new address</source>
+ <translation>Янги манзил яратинг</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>&amp;Янги</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Жорий танланган манзилни тизим вақтинчалик хотирасига нусха кўчиринг</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>&amp;Нусха олиш</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>&amp;Ёпиш</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>Манзилдан &amp;нусха олиш</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>Жорий танланган манзилни рўйхатдан ўчириш</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Жорий ички ойна ичидаги маълумотларни файлга экспорт қилиш</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Экспорт</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;Ўчириш</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>Тангаларни жўнатиш учун манзилни танланг</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>Тангаларни қабул қилиш учун манзилни танланг</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>&amp;Танлаш</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>Жўнатиладиган манзиллар</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>Қабул қилинадиган манзиллар</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>Улар тўловларни жўнатиш учун сизнинг Bitcoin манзилларингиз. Доимо тангаларни жўнатишдан олдин сумма ва қабул қилувчи манзилни текшириб кўринг. </translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>Улар тўловларни қабул қилиш учун сизнинг Bitcoin манзилларингиз. Ҳар бир ўтказма учун янги қабул қилувчи манзилдан фойдаланиш тавсия қилинади.</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>Нусха олиш ва ёрлиқ</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>&amp;Таҳрирлаш</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>Манзил рўйхатини экспорт қилиш</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Вергул билан ажратилган файл (*.csv)</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Экспорт қилиб бўлмади</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the address list to %1. Please try again.</source>
+ <translation>Манзил рўйхатини %1.га сақлашда хатолик юз берди. Яна уриниб кўринг.</translation>
+ </message>
+</context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Ёрлиқ</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Манзил</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(Ёрлиқ мавжуд эмас)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Passphrase Dialog</source>
+ <translation>Махфий сўз ойнаси</translation>
+ </message>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Махфий сузни киритинг</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Янги махфий суз</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Янги махфий сузни такрорланг</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>Ҳамённи қодлаш</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>Ушбу операцияни амалга ошириш учун ҳамённи қулфдан чиқариш парол сўзини талаб қилади.</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Ҳамённи қулфдан чиқариш</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>Ушбу операцияни амалга ошириш учун ҳамённи коддан чиқариш парол сўзини талаб қилади.</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>Ҳамённи коддан чиқариш</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>Махфий сузни узгартириш</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>Ҳамённи кодлашни тасдиқлаш</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>Диққат: Агар сиз ҳамёнингизни кодласангиз ва махфий сўзингизни унутсангиз, сиз &lt;b&gt;БАРЧА BITCOIN ПУЛЛАРИНГИЗНИ ЙЎҚОТАСИЗ&lt;/b&gt;!</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>Ҳамёнингизни кодлашни ростдан хоҳлайсизми?</translation>
+ </message>
+ <message>
+ <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
+ <translation>МУҲИМ: Сиз қилган олдинги ҳамён файли заҳиралари янги яратилган, кодланган ҳамён файли билан алмаштирилиши керак. Хавфсизлик сабабларига кўра олдинги кодланган ҳамён файли заҳираси янги кодланган ҳамёндан фойдаланишингиз билан яроқсиз ҳолга келади.</translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>Диққат: Caps Lock тугмаси ёқилган!</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>Ҳамёни кодланган</translation>
+ </message>
+ <message>
+ <source>Enter the new passphrase to the wallet.&lt;br/&gt;Please use a passphrase of &lt;b&gt;ten or more random characters&lt;/b&gt;, or &lt;b&gt;eight or more words&lt;/b&gt;.</source>
+ <translation>Ҳамёнга янги махфий сўз киритинг.&lt;br/&gt;Илтимос, &lt;b&gt;ўнта ёки тасодифий белгили&lt;/b&gt; махфий сўздан фойдаланинг ёки &lt;b&gt;саккизта ёки кўпроқ сўзлар&lt;/b&gt;дан фойдаланинг.</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>Ҳамённи кодлаш амалга ошмади</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>Ҳамённи кодлаш ташқи хато туфайли амалга ошмади. Ҳамёнингиз кодланмади.</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>Киритилган пароллар мос келмади.</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>Ҳамённи қулфдан чиқариш амалга ошмади</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>Ҳамённи коддан чиқариш учун киритилган парол нотўғри.</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>Ҳамённи коддан чиқариш амалга ошмади</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>Ҳамён пароли муваффақиятли алмаштирилди.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>&amp;Хабар ёзиш...</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>Тармоқ билан синхронланмоқда...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;Кўриб чиқиш</translation>
+ </message>
+ <message>
+ <source>Node</source>
+ <translation>Улам</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>Ҳамённинг умумий кўринишини кўрсатиш</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Пул ўтказмалари</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>Пул ўтказмалари тарихини кўриш</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>Ч&amp;иқиш</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>Иловадан чиқиш</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>&amp;Qt ҳақида</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>Qt ҳақидаги маълумотларни кўрсатиш</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>&amp;Мосламалар...</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>Ҳамённи &amp;кодлаш...</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>Ҳамённи &amp;заҳиралаш...</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>Махфий сўзни &amp;ўзгартириш...</translation>
+ </message>
+ <message>
+ <source>&amp;Sending addresses...</source>
+ <translation>&amp;Жўнатилувчи манзиллар...</translation>
+ </message>
+ <message>
+ <source>&amp;Receiving addresses...</source>
+ <translation>&amp;Қабул қилувчи манзиллар...</translation>
+ </message>
+ <message>
+ <source>Open &amp;URI...</source>
+ <translation>Интернет манзилни очиш</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core client</source>
+ <translation>Bitcoin асос мижози</translation>
+ </message>
+ <message>
+ <source>Importing blocks from disk...</source>
+ <translation>Дискдан блоклар импорт қилинмоқда...</translation>
+ </message>
+ <message>
+ <source>Reindexing blocks on disk...</source>
+ <translation>Дискдаги блоклар қайта индексланмоқда...</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>Тангаларни Bitcoin манзилига жўнатиш</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>Ҳамённи бошқа манзилга заҳиралаш</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Паролни ўзгартириш ҳамённи кодлашда фойдаланилади</translation>
+ </message>
+ <message>
+ <source>&amp;Debug window</source>
+ <translation>&amp;Носозликни ҳал қилиш ойнаси</translation>
+ </message>
+ <message>
+ <source>Open debugging and diagnostic console</source>
+ <translation>Носозликни ҳал қилиш ва ташхис терминали</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>Хабарни &amp;тасдиқлаш...</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>Ҳамён</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>&amp;Жўнатиш</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>&amp;Қабул қилиш</translation>
+ </message>
+ <message>
+ <source>Show information about Bitcoin Core</source>
+ <translation>Bitcoin Core ҳақидаги маълумотларни кўрсатиш</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>&amp;Кўрсатиш / Яшириш</translation>
+ </message>
+ <message>
+ <source>Show or hide the main Window</source>
+ <translation>Асосий ойнани кўрсатиш ёки яшириш</translation>
+ </message>
+ <message>
+ <source>Encrypt the private keys that belong to your wallet</source>
+ <translation>Ҳамёнингизга тегишли махфий калитларни кодлаш</translation>
+ </message>
+ <message>
+ <source>Sign messages with your Bitcoin addresses to prove you own them</source>
+ <translation>Bitcoin манзилидан унинг эгаси эканлигингизни исботлаш учун хабарлар ёзинг</translation>
+ </message>
+ <message>
+ <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source>
+ <translation>Хабарларни махсус Bitcoin манзилларингиз билан ёзилганлигига ишонч ҳосил қилиш учун уларни тасдиқланг</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;Файл</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp; Созламалар</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>&amp;Ёрдам</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>Ички ойналар асбоблар панели</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Request payments (generates QR codes and bitcoin: URIs)</source>
+ <translation>Тўловлар (QR кодлари ва bitcoin ёрдамида яратишлар: URI’лар) сўраш</translation>
+ </message>
+ <message>
+ <source>&amp;About Bitcoin Core</source>
+ <translation>Bitcoin Core &amp;ҳақида</translation>
+ </message>
+ <message>
+ <source>Show the list of used sending addresses and labels</source>
+ <translation>Фойдаланилган жўнатилган манзиллар ва ёрлиқлар рўйхатини кўрсатиш</translation>
+ </message>
+ <message>
+ <source>Show the list of used receiving addresses and labels</source>
+ <translation>Фойдаланилган қабул қилинган манзиллар ва ёрлиқлар рўйхатини кўрсатиш</translation>
+ </message>
+ <message>
+ <source>Open a bitcoin: URI or payment request</source>
+ <translation>Bitcoin’ни очиш: URI ёки тўлов сўрови</translation>
+ </message>
+ <message>
+ <source>&amp;Command-line options</source>
+ <translation>&amp;Буйруқлар сатри мосламалари</translation>
+ </message>
+ <message>
+ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
+ <translation>Мавжуд Bitcoin буйруқлар матни мосламалари билан Bitcoin Core ёрдам хабарларини олиш рўйхатини кўрсатиш</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n active connection(s) to Bitcoin network</source>
+ <translation><numerusform>%n та Bitcoin тармоғига фаол уланиш мавжуд</numerusform></translation>
+ </message>
+ <message>
+ <source>No block source available...</source>
+ <translation>Блок манбалари мавжуд эмас...</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n hour(s)</source>
+ <translation><numerusform>%n соат</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n day(s)</source>
+ <translation><numerusform>%n кун</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n week(s)</source>
+ <translation><numerusform>%n ҳафта</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 and %2</source>
+ <translation>%1 ва %2</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n year(s)</source>
+ <translation><numerusform>%n йил</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 behind</source>
+ <translation>%1 орқада</translation>
+ </message>
+ <message>
+ <source>Last received block was generated %1 ago.</source>
+ <translation>Сўнги қабул қилинган блок %1 олдин яратилган.</translation>
+ </message>
+ <message>
+ <source>Transactions after this will not yet be visible.</source>
+ <translation>Бундан кейинги пул ўтказмалари кўринмайдиган бўлади.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Хатолик</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Диққат</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Маълумот</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>Янгиланган</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>Банд қилинмоқда...</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>Жўнатилган операция</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>Кирувчи операция</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>Ҳамён &lt;b&gt;кодланган&lt;/b&gt; ва вақтинча &lt;b&gt;қулфдан чиқарилган&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>Ҳамён &lt;b&gt;кодланган&lt;/b&gt; ва вақтинча &lt;b&gt;қулфланган&lt;/b&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <source>Network Alert</source>
+ <translation>Тармоқ огоҳлантиргичи</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Quantity:</source>
+ <translation>Сони:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Байт:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Миқдори:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Муҳимлиги:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Солиқ:</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Ахлат қутиси:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Солиқдан сўнг:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Ўзгартириш:</translation>
+ </message>
+ <message>
+ <source>(un)select all</source>
+ <translation>барчасини танаш (бекор қилиш)</translation>
+ </message>
+ <message>
+ <source>Tree mode</source>
+ <translation>Дарахт усулида</translation>
+ </message>
+ <message>
+ <source>List mode</source>
+ <translation>Рўйхат усулида</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Миқдори</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Сана</translation>
+ </message>
+ <message>
+ <source>Confirmations</source>
+ <translation>Тасдиқлашлар</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Тасдиқланди</translation>
+ </message>
+ <message>
+ <source>Priority</source>
+ <translation>Муҳимлиги</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Манзилни нусхалаш</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Ёрликни нусхала</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Кийматни нусхала</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Ўтказам рақамидан нусха олиш</translation>
+ </message>
+ <message>
+ <source>Lock unspent</source>
+ <translation>Сарфланмаганларни қулфлаш</translation>
+ </message>
+ <message>
+ <source>Unlock unspent</source>
+ <translation>Сарфланмаганларни қулфдан чиқариш</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Нусха сони</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Нусха солиғи</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Нусха солиқдан сўнг</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Нусха байти</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Нусха муҳимлиги</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Нусха чангги</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Нусха қайтими</translation>
+ </message>
+ <message>
+ <source>highest</source>
+ <translation>энг юқори</translation>
+ </message>
+ <message>
+ <source>higher</source>
+ <translation>юқорирок</translation>
+ </message>
+ <message>
+ <source>high</source>
+ <translation>юқори</translation>
+ </message>
+ <message>
+ <source>medium-high</source>
+ <translation>ўртача-юқори</translation>
+ </message>
+ <message>
+ <source>medium</source>
+ <translation>ўрта</translation>
+ </message>
+ <message>
+ <source>low-medium</source>
+ <translation>паст-юқори</translation>
+ </message>
+ <message>
+ <source>low</source>
+ <translation>паст</translation>
+ </message>
+ <message>
+ <source>lower</source>
+ <translation>пастроқ</translation>
+ </message>
+ <message>
+ <source>lowest</source>
+ <translation>энг паст</translation>
+ </message>
+ <message>
+ <source>(%1 locked)</source>
+ <translation>(%1 қулфланган)</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>йўқ</translation>
+ </message>
+ <message>
+ <source>Can vary +/- %1 satoshi(s) per input.</source>
+ <translation>Ҳар бир кирим +/- %1 сатоши(лар) билан ўзгариши мумкин.</translation>
+ </message>
+ <message>
+ <source>yes</source>
+ <translation>ҳа</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>йўқ</translation>
+ </message>
+ <message>
+ <source>This means a fee of at least %1 per kB is required.</source>
+ <translation>Бу дегани солиқ ҳар кб учун камида %1 талаб қилинади.</translation>
+ </message>
+ <message>
+ <source>Can vary +/- 1 byte per input.</source>
+ <translation>Ҳар бир кирим +/- 1 байт билан ўзгариши мумкин.</translation>
+ </message>
+ <message>
+ <source>Transactions with higher priority are more likely to get included into a block.</source>
+ <translation>Юқори муҳимликка эга бўлган ўтказмалар тезда блокнинг ичига қўшимча олади.</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(Ёрлик мавжуд эмас)</translation>
+ </message>
+ <message>
+ <source>change from %1 (%2)</source>
+ <translation>%1 (%2)дан ўзгартириш</translation>
+ </message>
+ <message>
+ <source>(change)</source>
+ <translation>(ўзгартириш)</translation>
+ </message>
+</context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>Манзилларни таҳрирлаш</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>&amp;Ёрлик</translation>
+ </message>
+ <message>
+ <source>The label associated with this address list entry</source>
+ <translation>Ёрлиқ ушбу манзилар рўйхати ёзуви билан боғланган</translation>
+ </message>
+ <message>
+ <source>The address associated with this address list entry. This can only be modified for sending addresses.</source>
+ <translation>Манзил ушбу манзиллар рўйхати ёзуви билан боғланган. Уни фақат жўнатиладиган манзиллар учун ўзгартирса бўлади.</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>&amp;Манзил</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>Янги кабул килувчи манзил</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>Янги жунатилувчи манзил</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>Кабул килувчи манзилни тахрирлаш</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>Жунатилувчи манзилни тахрирлаш</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>Киритилган "%1" манзили аллақачон манзил китобида.</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is not a valid Bitcoin address.</source>
+ <translation>Киритилган "%1" манзили тўғри Bitcoin манзили эмас.</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>Ҳамён қулфдан чиқмади.</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>Янги калит яратиш амалга ошмади.</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ <message>
+ <source>A new data directory will be created.</source>
+ <translation>Янги маълумотлар директорияси яратилади.</translation>
+ </message>
+ <message>
+ <source>name</source>
+ <translation>номи</translation>
+ </message>
+ <message>
+ <source>Directory already exists. Add %1 if you intend to create a new directory here.</source>
+ <translation>Директория аллақачон мавжуд. Агар бу ерда янги директория яратмоқчи бўлсангиз, %1 қўшинг.</translation>
+ </message>
+ <message>
+ <source>Path already exists, and is not a directory.</source>
+ <translation>Йўл аллақачон мавжуд. У директория эмас.</translation>
+ </message>
+ <message>
+ <source>Cannot create data directory here.</source>
+ <translation>Маълумотлар директориясини бу ерда яратиб бўлмайди..</translation>
+ </message>
+</context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>версияси</translation>
+ </message>
+ <message>
+ <source>(%1-bit)</source>
+ <translation>(%1-bit)</translation>
+ </message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>Bitcoin Core ҳақида</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>Фойдаланиш:</translation>
+ </message>
+ <message>
+ <source>command-line options</source>
+ <translation>буйруқлар қатори орқали мослаш</translation>
+ </message>
+</context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Welcome</source>
+ <translation>Хуш келибсиз</translation>
+ </message>
+ <message>
+ <source>Welcome to Bitcoin Core.</source>
+ <translation>"Bitcoin Core"га хуш келибсиз.</translation>
+ </message>
+ <message>
+ <source>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</source>
+ <translation>Биринчи марта дастур ишга тушгани каби сиз Bitcoin Core маълумотларини жойлаштирадиган жойни танлашингиз мумкин.</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory.</source>
+ <translation>Bitcoin Core юклаб олинади ва Bitcoin блок занжири нусхаси жойлаштирилади. Камида %1GB маълумот ушбу директорияга жойлаштирилади ва вақт давомида ўсиб боради. Ҳамён ҳам ушбу директорияда жойлашади.</translation>
+ </message>
+ <message>
+ <source>Use the default data directory</source>
+ <translation>Стандарт маълумотлар директориясидан фойдаланиш</translation>
+ </message>
+ <message>
+ <source>Use a custom data directory:</source>
+ <translation>Бошқа маълумотлар директориясида фойдаланинг:</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Error: Specified data directory "%1" cannot be created.</source>
+ <translation>Хато: кўрсатилган "%1" маълумотлар директориясини яратиб бўлмайди.</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Хатолик</translation>
+ </message>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ <message>
+ <source>Open URI</source>
+ <translation>URI ни очиш</translation>
+ </message>
+ <message>
+ <source>Open payment request from URI or file</source>
+ <translation>URL файлдан тўлов сўровларини очиш</translation>
+ </message>
+ <message>
+ <source>URI:</source>
+ <translation>URI:</translation>
+ </message>
+ <message>
+ <source>Select payment request file</source>
+ <translation>Тўлов сўрови файлини танлаш</translation>
+ </message>
+ <message>
+ <source>Select payment request file to open</source>
+ <translation>Очиш учун тўлов сўрови файлини танлаш</translation>
+ </message>
+</context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>Танламалар</translation>
+ </message>
+ <message>
+ <source>&amp;Main</source>
+ <translation>&amp;Асосий</translation>
+ </message>
+ <message>
+ <source>Size of &amp;database cache</source>
+ <translation>&amp;Маълумотлар базаси кеши</translation>
+ </message>
+ <message>
+ <source>MB</source>
+ <translation>МБ</translation>
+ </message>
+ <message>
+ <source>Number of script &amp;verification threads</source>
+ <translation>Мавзуларни &amp;тўғрилаш скрипти миқдори</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside</source>
+ <translation>Ташқаридан уланишларга рози бўлиш</translation>
+ </message>
+ <message>
+ <source>Allow incoming connections</source>
+ <translation>Кирувчи уланишларга рухсат бериш</translation>
+ </message>
+ <message>
+ <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
+ <translation>Прокси IP манзили (масалан: IPv4: 127.0.0.1 / IPv6: ::1)</translation>
+ </message>
+ <message>
+ <source>Third party transaction URLs</source>
+ <translation>Бегона тараф ўтказмалари URL манзиллари</translation>
+ </message>
+ <message>
+ <source>Proxy &amp;IP:</source>
+ <translation>Прокси &amp;IP рақами:</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>&amp;Порт:</translation>
+ </message>
+ <message>
+ <source>Port of the proxy (e.g. 9050)</source>
+ <translation>Прокси порти (e.g. 9050)</translation>
+ </message>
+ <message>
+ <source>&amp;Window</source>
+ <translation>&amp;Ойна</translation>
+ </message>
+ <message>
+ <source>Show only a tray icon after minimizing the window.</source>
+ <translation>Ойна йиғилгандан сўнг фақат трэй нишончаси кўрсатилсин.</translation>
+ </message>
+ <message>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>Манзиллар панели ўрнига трэйни &amp;йиғиш</translation>
+ </message>
+ <message>
+ <source>M&amp;inimize on close</source>
+ <translation>Ёпишда й&amp;иғиш</translation>
+ </message>
+ <message>
+ <source>&amp;Display</source>
+ <translation>&amp;Кўрсатиш</translation>
+ </message>
+ <message>
+ <source>User Interface &amp;language:</source>
+ <translation>Фойдаланувчи интерфейси &amp;тили:</translation>
+ </message>
+ <message>
+ <source>&amp;Unit to show amounts in:</source>
+ <translation>Миқдорларни кўрсатиш учун &amp;қисм:</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>&amp;OK</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>&amp;Бекор қилиш</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>стандарт</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>йўқ</translation>
+ </message>
+ <message>
+ <source>Confirm options reset</source>
+ <translation>Тасдиқлаш танловларини рад қилиш</translation>
+ </message>
+ <message>
+ <source>Client restart required to activate changes.</source>
+ <translation>Ўзгаришлар амалга ошиши учун мижозни қайта ишга тушириш талаб қилинади.</translation>
+ </message>
+ <message>
+ <source>This change would require a client restart.</source>
+ <translation>Ушбу ўзгариш мижозни қайтадан ишга туширишни талаб қилади.</translation>
+ </message>
+ <message>
+ <source>The supplied proxy address is invalid.</source>
+ <translation>Келтирилган прокси манзили ишламайди.</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>Шакл</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>Кўрсатилган маълумот эскирган бўлиши мумкин. Ҳамёнингиз алоқа ўрнатилгандан сўнг Bitcoin тармоқ билан автоматик тарзда синхронланади, аммо жараён ҳалигача тугалланмади.</translation>
+ </message>
+ <message>
+ <source>Watch-only:</source>
+ <translation>Фақат кўришга</translation>
+ </message>
+ <message>
+ <source>Available:</source>
+ <translation>Мавжуд:</translation>
+ </message>
+ <message>
+ <source>Your current spendable balance</source>
+ <translation>Жорий сарфланадиган балансингиз</translation>
+ </message>
+ <message>
+ <source>Pending:</source>
+ <translation>Кутилмоқда:</translation>
+ </message>
+ <message>
+ <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source>
+ <translation>Жами ўтказмалар ҳозиргача тасдиқланган ва сафланадиган баланс томонга ҳали ҳам ҳисобланмади</translation>
+ </message>
+ <message>
+ <source>Immature:</source>
+ <translation>Тайёр эмас:</translation>
+ </message>
+ <message>
+ <source>Mined balance that has not yet matured</source>
+ <translation>Миналаштирилган баланс ҳалигача тайёр эмас</translation>
+ </message>
+ <message>
+ <source>Balances</source>
+ <translation>Баланслар</translation>
+ </message>
+ <message>
+ <source>Total:</source>
+ <translation>Жами:</translation>
+ </message>
+ <message>
+ <source>Your current total balance</source>
+ <translation>Жорий умумий балансингиз</translation>
+ </message>
+ <message>
+ <source>Your current balance in watch-only addresses</source>
+ <translation>Жорий балансингиз фақат кўринадиган манзилларда</translation>
+ </message>
+ <message>
+ <source>Spendable:</source>
+ <translation>Сарфланадиган:</translation>
+ </message>
+ <message>
+ <source>Recent transactions</source>
+ <translation>Сўнгги пул ўтказмалари</translation>
+ </message>
+ </context>
+<context>
+ <name>PaymentServer</name>
+ </context>
+<context>
+ <name>PeerTableModel</name>
+ <message>
+ <source>Ping Time</source>
+ <translation>Ping вақти</translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>Миқдори</translation>
+ </message>
+ <message>
+ <source>%1 m</source>
+ <translation>%1 д</translation>
+ </message>
+ <message>
+ <source>%1 s</source>
+ <translation>%1 с</translation>
+ </message>
+ <message>
+ <source>None</source>
+ <translation>Йўқ</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>Тўғри келмайди</translation>
+ </message>
+ <message>
+ <source>%1 ms</source>
+ <translation>%1 мс</translation>
+ </message>
+</context>
+<context>
+ <name>QRImageWidget</name>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>Расмни &amp;сақлаш</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Image</source>
+ <translation>Расмдан &amp;нусха олиш</translation>
+ </message>
+ <message>
+ <source>Save QR Code</source>
+ <translation>QR кодни сақлаш</translation>
+ </message>
+ <message>
+ <source>PNG Image (*.png)</source>
+ <translation>PNG расм (*.png)</translation>
+ </message>
+</context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>Client name</source>
+ <translation>Мижоз номи</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>Тўғри келмайди</translation>
+ </message>
+ <message>
+ <source>Client version</source>
+ <translation>Мижоз номи</translation>
+ </message>
+ <message>
+ <source>&amp;Information</source>
+ <translation>&amp;Маълумот</translation>
+ </message>
+ <message>
+ <source>Debug window</source>
+ <translation>Тузатиш ойнаси</translation>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>Асосий</translation>
+ </message>
+ <message>
+ <source>Using OpenSSL version</source>
+ <translation>Фойдаланилаётган OpenSSL версияси</translation>
+ </message>
+ <message>
+ <source>Using BerkeleyDB version</source>
+ <translation>Фойдаланилаётган BerkeleyDB версияси</translation>
+ </message>
+ <message>
+ <source>Startup time</source>
+ <translation>Бошланиш вақти</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Тармоқ</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>Ном</translation>
+ </message>
+ <message>
+ <source>&amp;Peers</source>
+ <translation>&amp;Уламлар</translation>
+ </message>
+ <message>
+ <source>Select a peer to view detailed information.</source>
+ <translation>Батафсил маълумотларни кўриш учун уламни танланг.</translation>
+ </message>
+ <message>
+ <source>Starting Height</source>
+ <translation>Узунликнинг бошланиши</translation>
+ </message>
+ <message>
+ <source>Sync Height</source>
+ <translation>Узунликни синхронлаш</translation>
+ </message>
+ <message>
+ <source>Ban Score</source>
+ <translation>Тезликни бан қилиш</translation>
+ </message>
+ <message>
+ <source>Connection Time</source>
+ <translation>Уланиш вақти</translation>
+ </message>
+ <message>
+ <source>Last Send</source>
+ <translation>Сўнгги жўнатилган</translation>
+ </message>
+ <message>
+ <source>Last Receive</source>
+ <translation>Сўнгги қабул қилинган</translation>
+ </message>
+ <message>
+ <source>Bytes Sent</source>
+ <translation>Жўнатилган байтлар</translation>
+ </message>
+ <message>
+ <source>Bytes Received</source>
+ <translation>Қабул қилинган байтлар</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Ping вақти</translation>
+ </message>
+ <message>
+ <source>Last block time</source>
+ <translation>Сўнгги блок вақти</translation>
+ </message>
+ <message>
+ <source>&amp;Open</source>
+ <translation>&amp;Очиш</translation>
+ </message>
+ <message>
+ <source>&amp;Console</source>
+ <translation>&amp;Терминал</translation>
+ </message>
+ <message>
+ <source>&amp;Network Traffic</source>
+ <translation>&amp;Тармоқ трафиги</translation>
+ </message>
+ <message>
+ <source>&amp;Clear</source>
+ <translation>&amp;Тозалаш</translation>
+ </message>
+ <message>
+ <source>Totals</source>
+ <translation>Жами</translation>
+ </message>
+ <message>
+ <source>In:</source>
+ <translation>Ичига:</translation>
+ </message>
+ <message>
+ <source>Out:</source>
+ <translation>Ташқарига:</translation>
+ </message>
+ <message>
+ <source>Build date</source>
+ <translation>Тузилган санаси</translation>
+ </message>
+ <message>
+ <source>Debug log file</source>
+ <translation>Тузатиш журнали файли</translation>
+ </message>
+ <message>
+ <source>Clear console</source>
+ <translation>Терминални тозалаш</translation>
+ </message>
+ <message>
+ <source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
+ <translation>Тарихни кўриш учун тепага ва пастга кўрсаткичларидан фойдаланинг, экранни тозалаш учун &lt;b&gt;Ctrl-L&lt;/b&gt; тугмалар бирикмасидан фойдаланинг.</translation>
+ </message>
+ <message>
+ <source>Type &lt;b&gt;help&lt;/b&gt; for an overview of available commands.</source>
+ <translation>Мавжуд буйруқларни кўриш учун &lt;b&gt;help&lt;/b&gt; деб ёзинг.</translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation>%1 Б</translation>
+ </message>
+ <message>
+ <source>%1 KB</source>
+ <translation>%1 КБ</translation>
+ </message>
+ <message>
+ <source>%1 MB</source>
+ <translation>%1 МБ</translation>
+ </message>
+ <message>
+ <source>%1 GB</source>
+ <translation>%1 ГБ</translation>
+ </message>
+ <message>
+ <source>via %1</source>
+ <translation>%1 орқали</translation>
+ </message>
+ <message>
+ <source>never</source>
+ <translation>ҳеч қачон</translation>
+ </message>
+ <message>
+ <source>Unknown</source>
+ <translation>Номаълум</translation>
+ </message>
+ <message>
+ <source>Fetching...</source>
+ <translation>Олинмоқда...</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Amount:</source>
+ <translation>&amp;Миқдор:</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Ёрлиқ:</translation>
+ </message>
+ <message>
+ <source>&amp;Message:</source>
+ <translation>&amp;Хабар:</translation>
+ </message>
+ <message>
+ <source>Reuse one of the previously used receiving addresses. Reusing addresses has security and privacy issues. Do not use this unless re-generating a payment request made before.</source>
+ <translation>Олдинги фойдаланилган қабул қилинган манзиллардан биридан қайта фойдаланилсин. Хавсизлик ва махфийлик муаммолар мавжуд манзиллардан қайта фойдаланилмоқда. Бундан тўлов сўров қайта яратилмагунича фойдаланманг.</translation>
+ </message>
+ <message>
+ <source>An optional label to associate with the new receiving address.</source>
+ <translation>Янги қабул қилинаётган манзил билан боғланган танланадиган ёрлиқ.</translation>
+ </message>
+ <message>
+ <source>Use this form to request payments. All fields are &lt;b&gt;optional&lt;/b&gt;.</source>
+ <translation>Ушбу сўровдан тўловларни сўраш учун фойдаланинг. Барча майдонлар &lt;b&gt;мажбурий эмас&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>An optional amount to request. Leave this empty or zero to not request a specific amount.</source>
+ <translation>Хоҳланган миқдор сўрови. Кўрсатилган миқдорни сўраш учун буни бўш ёки ноль қолдиринг.</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Шаклнинг барча майдончаларини тозалаш</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation>Тозалаш</translation>
+ </message>
+ <message>
+ <source>Requested payments history</source>
+ <translation>Сўралган тўлов тарихи</translation>
+ </message>
+ <message>
+ <source>&amp;Request payment</source>
+ <translation>Тўловни &amp;сўраш</translation>
+ </message>
+ <message>
+ <source>Show the selected request (does the same as double clicking an entry)</source>
+ <translation>Танланган сўровни кўрсатиш (икки марта босилганда ҳам бир хил амал бажарилсин)</translation>
+ </message>
+ <message>
+ <source>Show</source>
+ <translation>Кўрсатиш</translation>
+ </message>
+ <message>
+ <source>Remove the selected entries from the list</source>
+ <translation>Танланганларни рўйхатдан ўчириш</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>Ўчириш</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Ёрликни нусхала</translation>
+ </message>
+ <message>
+ <source>Copy message</source>
+ <translation>Хабарни нусхала</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Кийматни нусхала</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>Расмни &amp;сақлаш</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Манзил</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Миқдори</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Ёрлик</translation>
+ </message>
+ </context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Сана</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Ёрлик</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Миқдори</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(Ёрлик мавжуд эмас)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Тангаларни жунат</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Сони:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Байт:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Миқдори:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Муҳимлиги:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Солиқ:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Солиқдан сўнг:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Ўзгартириш:</translation>
+ </message>
+ <message>
+ <source>If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address.</source>
+ <translation>Агар бу фаоллаштирилса, аммо ўзгартирилган манзил бўл ёки нотўғри бўлса, ўзгариш янги яратилган манзилга жўнатилади.</translation>
+ </message>
+ <message>
+ <source>Custom change address</source>
+ <translation>Бошқа ўзгартирилган манзил</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>Бирданига бир нечта қабул қилувчиларга жўнатиш</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Шаклнинг барча майдончаларини тозалаш</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Ахлат қутиси:</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>Баланс</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>Жўнатиш амалини тасдиқлаш</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>Тангалар жўнаишни тасдиқлаш</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>Нусха сони</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Кийматни нусхала</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Нусха солиғи</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Нусха солиқдан сўнг</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>Нусха байти</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>Нусха муҳимлиги</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>Нусха қайтими</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>Тўлов миқдори 0. дан катта бўлиши керак. </translation>
+ </message>
+ <message>
+ <source>Warning: Invalid Bitcoin address</source>
+ <translation>Диққат: Нотўғр Bitcoin манзили</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(Ёрлик мавжуд эмас)</translation>
+ </message>
+ <message>
+ <source>Warning: Unknown change address</source>
+ <translation>Диққат: Номаълум ўзгариш манзили</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Нусха чангги</translation>
+ </message>
+ <message>
+ <source>Are you sure you want to send?</source>
+ <translation>Жўнатишни хоҳлашингизга ишончингиз комилми?</translation>
+ </message>
+ <message>
+ <source>added as transaction fee</source>
+ <translation>ўтказма солиғи қўшилди</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>&amp;Миқдори:</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>&amp;Тўлов олувчи:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Манзил китобингизга қўшиш учун ушбу манзил учун ёрлиқ киритинг</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>&amp;Ёрлиқ:</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Клипбоарддан манзилни қўйиш</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ </context>
+<context>
+ <name>ShutdownWindow</name>
+ </context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>Клипбоарддан манзилни қўйиш</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Signature</source>
+ <translation>Имзо</translation>
+ </message>
+ </context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>The Bitcoin Core developers</source>
+ <translation>Bitcoin Core дастурчилари</translation>
+ </message>
+ <message>
+ <source>[testnet]</source>
+ <translation>[testnet]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ </context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>%1 гача очиш</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/тасдиқланмади</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 тасдиқлашлар</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Сана</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Миқдори</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, ҳалигача трансляция қилингани йўқ</translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>Номаълум</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>Операция тафсилотлари</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>Ушбу ойна операциянинг батафсил таърифини кўрсатади</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Сана</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Тури</translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>%1 гача очиш</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>Тасдиқланди (%1 та тасдиқ)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>Ушбу тўсиқ бирорта бошқа уланишлар томонидан қабул қилинмаган ва тасдиқланмаган!</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>Яратилди, аммо қабул қилинмади</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Ёрлиқ</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Ёрдамида қабул қилиш</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Жўнатиш</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>Ўзингизга тўлов</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Фойда</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(қ/қ)</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>Ўтказма ҳолати. Ушбу майдон бўйлаб тасдиқлашлар сонини кўрсатиш.</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Ўтказма қабул қилинган сана ва вақт.</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>Пул ўтказмаси тури</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>Миқдор ўчирилган ёки балансга қўшилган.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>Барча</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>Бугун</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>Шу ҳафта</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>Шу ой</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>Ўтган хафта</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>Шу йил</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>Оралиқ...</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>Ёрдамида қабул қилинган</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>Жўнатиш</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>Ўзингизга</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>Фойда</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>Бошка</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>Излаш учун манзил ёки ёрлиқни киритинг</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>Мин қиймат</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Манзилни нусхалаш</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Ёрликни нусхалаш</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Кийматни нусхала</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>Ўтказам рақамидан нусха олиш</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>Ёрликни тахрирлаш</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Экспорт қилиб бўлмади</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Вергул билан ажратилган файл (*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Тасдиқланди</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Сана</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Туркум</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Ёрлик</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Манзил</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>Оралиқ:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>Кимга</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ </context>
+<context>
+ <name>WalletFrame</name>
+ </context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>Тангаларни жунат</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Экспорт</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Жорий ички ойна ичидаги маълумотларни файлга экспорт қилиш</translation>
+ </message>
+ </context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>Танламалар:</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>Маълумотлар директориясини кўрсатинг</translation>
+ </message>
+ <message>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>Буйруқлар сатри ва JSON-RPC буйруқларига рози бўлинг</translation>
+ </message>
+ <message>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>Демон сифатида орқа фонда ишга туширинг ва буйруқларга рози бўлинг</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>Синов тармоғидан фойдаланинг</translation>
+ </message>
+ <message>
+ <source>Choose data directory on startup (default: 0)</source>
+ <translation>Ишга тушиш вақтида маълумотлар директориясини танлаш (стандарт: 0)</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Маълумот</translation>
+ </message>
+ <message>
+ <source>Set SSL root certificates for payment request (default: -system-)</source>
+ <translation>Тўлов сўровлари учун SSL асос сертификатларини ўрнатиш (стандарт: -system-)</translation>
+ </message>
+ <message>
+ <source>Start minimized</source>
+ <translation>Йиғилганларни бошлаш</translation>
+ </message>
+ <message>
+ <source>Username for JSON-RPC connections</source>
+ <translation>JSON-RPC уланишлари учун фойдаланувчи номи</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Диққат</translation>
+ </message>
+ <message>
+ <source>Password for JSON-RPC connections</source>
+ <translation>JSON-RPC уланишлари учун парол</translation>
+ </message>
+ <message>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>JSON-RPC уланишлари учун OpenSSL (https)дан фойдаланиш</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>Бу ёрдам хабари</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>Манзиллар юкланмоқда...</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>Тўсиқ индекси юкланмоқда...</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>Ҳамён юкланмоқда...</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>Қайта текшириб чиқилмоқда...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>Юклаш тайёр</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Хатолик</translation>
+ </message>
+</context>
+</TS> \ No newline at end of file
diff --git a/src/qt/locale/bitcoin_vi.ts b/src/qt/locale/bitcoin_vi.ts
new file mode 100644
index 0000000000..64d11d4645
--- /dev/null
+++ b/src/qt/locale/bitcoin_vi.ts
@@ -0,0 +1,210 @@
+<TS language="vi" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Create a new address</source>
+ <translation>Tạo một địa chỉ mới</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>Tạo mới</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Sao chép các địa chỉ đã được chọn vào bộ nhớ tạm thời của hệ thống</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>Sao chép</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>Sao chép địa chỉ</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;Xóa</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Tập tin tách biệt bởi dấu phẩy (*.csv)</translation>
+ </message>
+ </context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Nhãn dữ liệu</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Địa chỉ</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(chưa có nhãn)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ </context>
+<context>
+ <name>BitcoinGUI</name>
+ </context>
+<context>
+ <name>ClientModel</name>
+ </context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Amount</source>
+ <translation>Số lượng</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(chưa có nhãn)</translation>
+ </message>
+ </context>
+<context>
+ <name>EditAddressDialog</name>
+ </context>
+<context>
+ <name>FreespaceChecker</name>
+ </context>
+<context>
+ <name>HelpMessageDialog</name>
+ </context>
+<context>
+ <name>Intro</name>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ </context>
+<context>
+ <name>OptionsDialog</name>
+ </context>
+<context>
+ <name>OverviewPage</name>
+ </context>
+<context>
+ <name>PaymentServer</name>
+ </context>
+<context>
+ <name>PeerTableModel</name>
+ </context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>Số lượng</translation>
+ </message>
+ </context>
+<context>
+ <name>QRImageWidget</name>
+ </context>
+<context>
+ <name>RPCConsole</name>
+ </context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ </context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>Address</source>
+ <translation>Địa chỉ</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Số lượng</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Nhãn dữ liệu</translation>
+ </message>
+ </context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Nhãn dữ liệu</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Số lượng</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(chưa có nhãn)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>(no label)</source>
+ <translation>(chưa có nhãn)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsEntry</name>
+ </context>
+<context>
+ <name>ShutdownWindow</name>
+ </context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ </context>
+<context>
+ <name>SplashScreen</name>
+ </context>
+<context>
+ <name>TrafficGraphWidget</name>
+ </context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Amount</source>
+ <translation>Số lượng</translation>
+ </message>
+ </context>
+<context>
+ <name>TransactionDescDialog</name>
+ </context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Nhãn dữ liệu</translation>
+ </message>
+ </context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Tập tin tách biệt bởi dấu phẩy (*.csv)</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Nhãn dữ liệu</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Địa chỉ</translation>
+ </message>
+ </context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ </context>
+<context>
+ <name>WalletFrame</name>
+ </context>
+<context>
+ <name>WalletModel</name>
+ </context>
+<context>
+ <name>WalletView</name>
+ </context>
+<context>
+ <name>bitcoin-core</name>
+ </context>
+</TS> \ No newline at end of file
diff --git a/src/qt/locale/bitcoin_vi_VN.ts b/src/qt/locale/bitcoin_vi_VN.ts
new file mode 100644
index 0000000000..7bcded7448
--- /dev/null
+++ b/src/qt/locale/bitcoin_vi_VN.ts
@@ -0,0 +1,734 @@
+<TS language="vi_VN" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Right-click to edit address or label</source>
+ <translation>Nhấn chuột phải để sửa địa chỉ hoặc nhãn</translation>
+ </message>
+ <message>
+ <source>Create a new address</source>
+ <translation>Tạo một địa chỉ mới</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>&amp;Mới</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Copy địa chỉ được chọn vào clipboard</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>&amp;Copy</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>Đó&amp;ng</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>&amp;Copy Địa Chỉ</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>Xóa địa chỉ hiện tại từ danh sách</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Xuất dữ liệu trong mục hiện tại ra file</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>X&amp;uất</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>&amp;Xó&amp;a</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>Chọn địa chỉ để gửi coin tới</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>Chọn địa chỉ để nhận coin</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>C&amp;họn</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>Địa chỉ gửi</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>Địa chỉ nhận</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>Copy &amp;Nhãn</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>&amp;Sửa</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>Xuất Danh Sách Địa Chỉ</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Comma separated file (*.csv)</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Xuất Đã Thất Bại</translation>
+ </message>
+ </context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>Nhãn</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Địa chỉ</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(không nhãn)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Passphrase Dialog</source>
+ <translation>Hội thoại Passphrase</translation>
+ </message>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>Điền passphrase</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>Passphrase mới</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>Điền lại passphrase</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>Mã hóa ví</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>Mở khóa ví</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>Giải mã ví</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>Ví đã được mã hóa</translation>
+ </message>
+ </context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>&amp;Tổng quan</translation>
+ </message>
+ <message>
+ <source>Node</source>
+ <translation>Node</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>T&amp;hoát</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>Thoát chương trình</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>Về &amp;Qt</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>Xem thông tin về Qt</translation>
+ </message>
+ <message>
+ <source>Open &amp;URI...</source>
+ <translation>Mở &amp;URI...</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core client</source>
+ <translation>Bitcoin Core client</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>Ví</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>&amp;Gửi</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>&amp;Nhận</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>Ẩn / H&amp;iện</translation>
+ </message>
+ <message>
+ <source>Show or hide the main Window</source>
+ <translation>Hiện hoặc ẩn cửa sổ chính</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>&amp;File</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>&amp;Thiết lập</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>Trợ &amp;giúp</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>&amp;About Bitcoin Core</source>
+ <translation>&amp;Về Bitcoin Core</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n hour(s)</source>
+ <translation><numerusform>%n giờ</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n day(s)</source>
+ <translation><numerusform>%n ngày</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n week(s)</source>
+ <translation><numerusform>%n tuần</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 and %2</source>
+ <translation>%1 và %2</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n year(s)</source>
+ <translation><numerusform>%n năm</numerusform></translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Lỗi</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Chú ý</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Thông tin</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>Đã cập nhật</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>Giao dịch đã gửi</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>Giao dịch đang tới</translation>
+ </message>
+ </context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <source>Network Alert</source>
+ <translation>Network Alert</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Quantity:</source>
+ <translation>Lượng:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Bytes:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Lượng:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Tầm quan trọng:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Phí:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Thay đổi:</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Lượng</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Ngày tháng</translation>
+ </message>
+ <message>
+ <source>Confirmations</source>
+ <translation>Lần xác nhận</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Đã xác nhận</translation>
+ </message>
+ <message>
+ <source>Priority</source>
+ <translation>Tầm quan trọng</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>Copy địa chỉ</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Copy nhãn</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Lượng copy</translation>
+ </message>
+ <message>
+ <source>low</source>
+ <translation>thấp</translation>
+ </message>
+ <message>
+ <source>lower</source>
+ <translation>thấp hơn</translation>
+ </message>
+ <message>
+ <source>lowest</source>
+ <translation>thấp nhất</translation>
+ </message>
+ <message>
+ <source>yes</source>
+ <translation>có</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>không</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(không nhãn)</translation>
+ </message>
+ </context>
+<context>
+ <name>EditAddressDialog</name>
+ </context>
+<context>
+ <name>FreespaceChecker</name>
+ <message>
+ <source>name</source>
+ <translation>tên</translation>
+ </message>
+ </context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>version</translation>
+ </message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>Về Bitcoin Core</translation>
+ </message>
+ </context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Welcome</source>
+ <translation>Chào mừng</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Lỗi</translation>
+ </message>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ <message>
+ <source>Open URI</source>
+ <translation>Mở URI</translation>
+ </message>
+ <message>
+ <source>URI:</source>
+ <translation>URI:</translation>
+ </message>
+ </context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>Lựa chọn</translation>
+ </message>
+ <message>
+ <source>&amp;Main</source>
+ <translation>&amp;Chính</translation>
+ </message>
+ <message>
+ <source>MB</source>
+ <translation>MB</translation>
+ </message>
+ <message>
+ <source>&amp;Display</source>
+ <translation>&amp;Hiển thị</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>&amp;OK</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>&amp;Từ chối</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>mặc định</translation>
+ </message>
+ </context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>Form</translation>
+ </message>
+ <message>
+ <source>Total:</source>
+ <translation>Tổng:</translation>
+ </message>
+ </context>
+<context>
+ <name>PaymentServer</name>
+ </context>
+<context>
+ <name>PeerTableModel</name>
+ <message>
+ <source>User Agent</source>
+ <translation>User Agent</translation>
+ </message>
+ </context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>Lượng</translation>
+ </message>
+ </context>
+<context>
+ <name>QRImageWidget</name>
+ </context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>General</source>
+ <translation>Nhìn Chung</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>Tên</translation>
+ </message>
+ <message>
+ <source>Block chain</source>
+ <translation>Block chain</translation>
+ </message>
+ <message>
+ <source>Sent</source>
+ <translation>Đã gửi</translation>
+ </message>
+ <message>
+ <source>User Agent</source>
+ <translation>User Agent</translation>
+ </message>
+ </context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>Copy label</source>
+ <translation>Copy nhãn</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Lượng copy</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>Address</source>
+ <translation>Địa chỉ</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Lượng</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Nhãn</translation>
+ </message>
+ </context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Ngày tháng</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Nhãn</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Lượng</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(không nhãn)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Quantity:</source>
+ <translation>Lượng:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Bytes:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>Lượng:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Tầm quan trọng:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Phí:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Thay đổi:</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Lượng copy</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(không nhãn)</translation>
+ </message>
+ </context>
+<context>
+ <name>SendCoinsEntry</name>
+ </context>
+<context>
+ <name>ShutdownWindow</name>
+ </context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ </context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>Bitcoin Core</translation>
+ </message>
+ </context>
+<context>
+ <name>TrafficGraphWidget</name>
+ </context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Date</source>
+ <translation>Ngày tháng</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Lượng</translation>
+ </message>
+ </context>
+<context>
+ <name>TransactionDescDialog</name>
+ </context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Ngày tháng</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Nhãn</translation>
+ </message>
+ </context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>Copy address</source>
+ <translation>Copy địa chỉ</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>Copy nhãn</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>Lượng copy</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Xuất Đã Thất Bại</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Comma separated file (*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Đã xác nhận</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Ngày tháng</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>Nhãn</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>Địa chỉ</translation>
+ </message>
+ </context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ </context>
+<context>
+ <name>WalletFrame</name>
+ </context>
+<context>
+ <name>WalletModel</name>
+ </context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>X&amp;uất</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Xuất dữ liệu trong mục hiện tại ra file</translation>
+ </message>
+ </context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Information</source>
+ <translation>Thông tin</translation>
+ </message>
+ <message>
+ <source>Transaction too large</source>
+ <translation>Giao dịch quá lớn</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Chú ý</translation>
+ </message>
+ <message>
+ <source>on startup</source>
+ <translation>khi khởi động</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>Thông điệp trợ giúp này</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>Đang đọc các địa chỉ...</translation>
+ </message>
+ <message>
+ <source>(default: %s)</source>
+ <translation>(mặc định: %s)</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>Không đủ tiền</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>Đang đọc block index...</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>Đang đọc ví...</translation>
+ </message>
+ <message>
+ <source>Cannot downgrade wallet</source>
+ <translation>Không downgrade được ví</translation>
+ </message>
+ <message>
+ <source>Cannot write default address</source>
+ <translation>Không ghi được địa chỉ mặc định</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>Đang quét lại...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>Đã nạp xong</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Lỗi</translation>
+ </message>
+</context>
+</TS> \ 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 0000000000..72ed56c41e
--- /dev/null
+++ b/src/qt/locale/bitcoin_zh_CN.ts
@@ -0,0 +1,3593 @@
+<TS language="zh_CN" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Right-click to edit address or label</source>
+ <translation>鼠标右击编辑地址或标签</translation>
+ </message>
+ <message>
+ <source>Create a new address</source>
+ <translation>创建新地址</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>新建(&amp;N)</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>复制当前选中的地址到系统剪贴板</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>复制(&amp;C)</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>关闭(&amp;C)</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>复制地址(&amp;C)</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>从列表中删除选中的地址</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>导出当前数据到文件</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>导出(&amp;E)</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>删除(&amp;D)</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>选择发款地址</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>选择收款地址</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>选择(&amp;H)</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>正在发送地址</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>正在接收地址</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>这是您用来付款的比特币地址。在付款前,请仔细核实付款金额和收款地址。</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>这些都是您的比特币地址,可用于收款。建议对每笔交易都使用一个新的地址。</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>复制标签(&amp;L)</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>编辑(&amp;E)</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>导出地址列表</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>逗号分隔文件 (*.csv)</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>导出失败</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the address list to %1. Please try again.</source>
+ <translation>保存地址列表出现 %1错误。请重试。</translation>
+ </message>
+</context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>标签</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>地址</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(没有标签)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Passphrase Dialog</source>
+ <translation>密码对话框</translation>
+ </message>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>输入密码</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>新密码</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>重复新密码</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>钱包加密</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>此操作需要您首先使用密码解锁该钱包。</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>解锁钱包</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>该操作需要您首先使用密码解密钱包。</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>解密钱包</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>更改密码</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>确认加密钱包</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>警告:如果您加密了您的钱包,但是忘记了密码,你将会&lt;b&gt;丢失所有的比特币&lt;/b&gt;!</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>您确定需要为钱包加密吗?</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core 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.</source>
+ <translation>比特币核心现在将关闭以完成加密过程。请记住,在您的计算机被恶意软件感染的情况下,加密不能完全保护您的比特币免于被盗。</translation>
+ </message>
+ <message>
+ <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
+ <translation>重要提示:您以前备份的钱包文件应该替换成最新生成的加密钱包文件(重新备份)。从安全性上考虑,您以前备份的未加密的钱包文件,在您使用新的加密钱包后将无效,请重新备份。</translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>警告:大写锁定键处于打开状态!</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>钱包已加密</translation>
+ </message>
+ <message>
+ <source>Enter the new passphrase to the wallet.&lt;br/&gt;Please use a passphrase of &lt;b&gt;ten or more random characters&lt;/b&gt;, or &lt;b&gt;eight or more words&lt;/b&gt;.</source>
+ <translation>请输入新的钱包密码. &lt;br/&gt;密码须包含&lt;b&gt;10个以上字符&lt;/b&gt;,或&lt;b&gt;8个以上单词&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>Enter the old passphrase and new passphrase to the wallet.</source>
+ <translation>请输入钱包的旧密码与新密码。</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>钱包加密失败</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>由于一个本地错误,加密钱包的操作已经失败。您的钱包没能被加密。</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>密码不匹配。</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>钱包解锁失败</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>用于解密钱包的密码不正确。</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>钱包解密失败。</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>修改钱包密码成功。</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>消息签名(&amp;M)...</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>正在与网络同步...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>概况(&amp;O)</translation>
+ </message>
+ <message>
+ <source>Node</source>
+ <translation>节点</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>显示钱包概况</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>交易记录(&amp;T)</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>查看交易历史</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>退出(&amp;X)</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>退出程序</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>关于 &amp;Qt</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>显示 Qt 相关信息</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>选项(&amp;O)...</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>加密钱包(&amp;E)...</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>备份钱包(&amp;B)...</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>更改密码(&amp;C)...</translation>
+ </message>
+ <message>
+ <source>&amp;Sending addresses...</source>
+ <translation>正在发送地址(&amp;S)...</translation>
+ </message>
+ <message>
+ <source>&amp;Receiving addresses...</source>
+ <translation>正在接收地址(&amp;R)...</translation>
+ </message>
+ <message>
+ <source>Open &amp;URI...</source>
+ <translation>打开 &amp;URI...</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core client</source>
+ <translation>比特币核心钱包</translation>
+ </message>
+ <message>
+ <source>Importing blocks from disk...</source>
+ <translation>正在从磁盘导入数据块...</translation>
+ </message>
+ <message>
+ <source>Reindexing blocks on disk...</source>
+ <translation>正在为数据块建立索引...</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>向一个比特币地址发送比特币</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>备份钱包到其他文件夹</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>更改钱包加密口令</translation>
+ </message>
+ <message>
+ <source>&amp;Debug window</source>
+ <translation>调试窗口(&amp;D)</translation>
+ </message>
+ <message>
+ <source>Open debugging and diagnostic console</source>
+ <translation>打开调试和诊断控制台</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>验证消息(&amp;V)...</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>比特币</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>钱包</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>发送(&amp;S)</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>接收(&amp;R)</translation>
+ </message>
+ <message>
+ <source>Show information about Bitcoin Core</source>
+ <translation>显示有关比特币核心钱包信息</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>显示 / 隐藏(&amp;S)</translation>
+ </message>
+ <message>
+ <source>Show or hide the main Window</source>
+ <translation>显示或隐藏主窗口</translation>
+ </message>
+ <message>
+ <source>Encrypt the private keys that belong to your wallet</source>
+ <translation>对钱包中的私钥加密</translation>
+ </message>
+ <message>
+ <source>Sign messages with your Bitcoin addresses to prove you own them</source>
+ <translation>用比特币地址关联的私钥为消息签名,以证明您拥有这个比特币地址</translation>
+ </message>
+ <message>
+ <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source>
+ <translation>校验消息,确保该消息是由指定的比特币地址所有者签名的</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>文件(&amp;F)</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>设置(&amp;S)</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>帮助(&amp;H)</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>分页工具栏</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>比特币核心</translation>
+ </message>
+ <message>
+ <source>Request payments (generates QR codes and bitcoin: URIs)</source>
+ <translation>请求支付(生成二维码和 bitcoin: URI)</translation>
+ </message>
+ <message>
+ <source>&amp;About Bitcoin Core</source>
+ <translation>关于比特币核心(&amp;A)</translation>
+ </message>
+ <message>
+ <source>Modify configuration options for Bitcoin Core</source>
+ <translation>修改比特币核心的配置选项</translation>
+ </message>
+ <message>
+ <source>Show the list of used sending addresses and labels</source>
+ <translation>显示用过的发送地址和标签的列表</translation>
+ </message>
+ <message>
+ <source>Show the list of used receiving addresses and labels</source>
+ <translation>显示用过的接收地址和标签的列表</translation>
+ </message>
+ <message>
+ <source>Open a bitcoin: URI or payment request</source>
+ <translation>打开一个比特币:URI 或支付请求</translation>
+ </message>
+ <message>
+ <source>&amp;Command-line options</source>
+ <translation>命令行选项(&amp;C)</translation>
+ </message>
+ <message>
+ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
+ <translation>显示比特币核心 程序帮助信息,获取可用的命令行选项 </translation>
+ </message>
+ <message numerus="yes">
+ <source>%n active connection(s) to Bitcoin network</source>
+ <translation><numerusform>%n 个到比特币网络的活动连接</numerusform></translation>
+ </message>
+ <message>
+ <source>No block source available...</source>
+ <translation>沒有可用的区块来源...</translation>
+ </message>
+ <message numerus="yes">
+ <source>Processed %n block(s) of transaction history.</source>
+ <translation><numerusform>已处理 %n 个交易历史数据块。</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n hour(s)</source>
+ <translation><numerusform>%n 小时</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n day(s)</source>
+ <translation><numerusform>%n 天</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n week(s)</source>
+ <translation><numerusform>%n 周</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 and %2</source>
+ <translation>%1 和 %2</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n year(s)</source>
+ <translation><numerusform>%n 年</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 behind</source>
+ <translation>落后 %1 </translation>
+ </message>
+ <message>
+ <source>Last received block was generated %1 ago.</source>
+ <translation>最新收到的区块产生于 %1。</translation>
+ </message>
+ <message>
+ <source>Transactions after this will not yet be visible.</source>
+ <translation>在此之后的交易尚未可见</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>错误</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>警告</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>信息</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>已是最新</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>更新中...</translation>
+ </message>
+ <message>
+ <source>Date: %1
+</source>
+ <translation>日期: %1
+</translation>
+ </message>
+ <message>
+ <source>Amount: %1
+</source>
+ <translation>金额: %1
+</translation>
+ </message>
+ <message>
+ <source>Type: %1
+</source>
+ <translation>类型: %1
+</translation>
+ </message>
+ <message>
+ <source>Label: %1
+</source>
+ <translation>标签: %1
+</translation>
+ </message>
+ <message>
+ <source>Address: %1
+</source>
+ <translation>地址: %1
+</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>发送交易</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>流入交易</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>钱包已被&lt;b&gt;加密&lt;/b&gt;,当前为&lt;b&gt;解锁&lt;/b&gt;状态</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>钱包已被&lt;b&gt;加密&lt;/b&gt;,当前为&lt;b&gt;锁定&lt;/b&gt;状态</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <source>Network Alert</source>
+ <translation>网络警报</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Coin Selection</source>
+ <translation>币源选择(Coin Selection)</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>总量:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>字节:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>金额:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>优先级:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>费用:</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>小额:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>加上交易费用后:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>变更 : </translation>
+ </message>
+ <message>
+ <source>(un)select all</source>
+ <translation>(不)全选</translation>
+ </message>
+ <message>
+ <source>Tree mode</source>
+ <translation>树状模式</translation>
+ </message>
+ <message>
+ <source>List mode</source>
+ <translation>列表模式</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>金额</translation>
+ </message>
+ <message>
+ <source>Received with label</source>
+ <translation>按标签收款</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>按地址收款</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>日期</translation>
+ </message>
+ <message>
+ <source>Confirmations</source>
+ <translation>确认</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>已确认</translation>
+ </message>
+ <message>
+ <source>Priority</source>
+ <translation>优先级</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>复制地址</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>复制标签</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>复制金额</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>复制交易编号</translation>
+ </message>
+ <message>
+ <source>Lock unspent</source>
+ <translation>锁定未花费</translation>
+ </message>
+ <message>
+ <source>Unlock unspent</source>
+ <translation>解锁未花费</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>复制金额</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>复制交易费</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>复制含交易费的金额</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>复制字节</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>复制优先级</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>复制小额</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>复制零钱</translation>
+ </message>
+ <message>
+ <source>highest</source>
+ <translation>最高</translation>
+ </message>
+ <message>
+ <source>higher</source>
+ <translation>更高</translation>
+ </message>
+ <message>
+ <source>high</source>
+ <translation>高</translation>
+ </message>
+ <message>
+ <source>medium-high</source>
+ <translation>中高</translation>
+ </message>
+ <message>
+ <source>medium</source>
+ <translation>中等</translation>
+ </message>
+ <message>
+ <source>low-medium</source>
+ <translation>中低</translation>
+ </message>
+ <message>
+ <source>low</source>
+ <translation>低</translation>
+ </message>
+ <message>
+ <source>lower</source>
+ <translation>更低</translation>
+ </message>
+ <message>
+ <source>lowest</source>
+ <translation>最低</translation>
+ </message>
+ <message>
+ <source>(%1 locked)</source>
+ <translation>(%1 锁定)</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>无</translation>
+ </message>
+ <message>
+ <source>This label turns red if the transaction size is greater than 1000 bytes.</source>
+ <translation>如果交易规模大于 1000 字节,此标签将变为红色。</translation>
+ </message>
+ <message>
+ <source>This label turns red if the priority is smaller than "medium".</source>
+ <translation>如果优先级小于“中等”,此标签将变为红色。</translation>
+ </message>
+ <message>
+ <source>This label turns red if any recipient receives an amount smaller than %1.</source>
+ <translation>如果任何接收人收到的金额小于 %1,此标签将变为红色。</translation>
+ </message>
+ <message>
+ <source>Can vary +/- %1 satoshi(s) per input.</source>
+ <translation>可能会有 正负 %1 聪(satoshi)的偏差 </translation>
+ </message>
+ <message>
+ <source>yes</source>
+ <translation>是</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>否</translation>
+ </message>
+ <message>
+ <source>This means a fee of at least %1 per kB is required.</source>
+ <translation>这意味着将对交易收取 %1/千字节 的交易费。</translation>
+ </message>
+ <message>
+ <source>Can vary +/- 1 byte per input.</source>
+ <translation>每笔输入可能会有 正负1字节的偏差。</translation>
+ </message>
+ <message>
+ <source>Transactions with higher priority are more likely to get included into a block.</source>
+ <translation>交易的优先级越高,被矿工收入数据块的速度也越快。</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(没有标签)</translation>
+ </message>
+ <message>
+ <source>change from %1 (%2)</source>
+ <translation>来自%1的零钱 (%2)</translation>
+ </message>
+ <message>
+ <source>(change)</source>
+ <translation>(零钱)</translation>
+ </message>
+</context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>编辑地址</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>标签(&amp;L)</translation>
+ </message>
+ <message>
+ <source>The label associated with this address list entry</source>
+ <translation>与此地址相关的标签项</translation>
+ </message>
+ <message>
+ <source>The address associated with this address list entry. This can only be modified for sending addresses.</source>
+ <translation>该地址已与地址列表中的条目关联,只能被发送地址修改。</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>地址(&amp;A)</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>新建接收地址</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>新建发送地址</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>编辑接收地址</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>编辑发送地址</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>输入的地址“%1”已经存在于地址簿中。</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is not a valid Bitcoin address.</source>
+ <translation>您输入的“%1”不是有效的比特币地址。</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>无法解锁钱包</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>新的密钥生成失败。</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ <message>
+ <source>A new data directory will be created.</source>
+ <translation>一个新的数据目录将被创建。</translation>
+ </message>
+ <message>
+ <source>name</source>
+ <translation>名称</translation>
+ </message>
+ <message>
+ <source>Directory already exists. Add %1 if you intend to create a new directory here.</source>
+ <translation>目录已存在。如果您打算在这里创建一个新目录,添加 %1。</translation>
+ </message>
+ <message>
+ <source>Path already exists, and is not a directory.</source>
+ <translation>路径已存在,并且不是一个目录。</translation>
+ </message>
+ <message>
+ <source>Cannot create data directory here.</source>
+ <translation>无法在此创建数据目录。</translation>
+ </message>
+</context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>比特币核心</translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>版本</translation>
+ </message>
+ <message>
+ <source>(%1-bit)</source>
+ <translation>(%1 位)</translation>
+ </message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>关于比特币核心</translation>
+ </message>
+ <message>
+ <source>Command-line options</source>
+ <translation>命令行选项</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>使用:</translation>
+ </message>
+ <message>
+ <source>command-line options</source>
+ <translation>命令行选项</translation>
+ </message>
+</context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Welcome</source>
+ <translation>欢迎</translation>
+ </message>
+ <message>
+ <source>Welcome to Bitcoin Core.</source>
+ <translation>欢迎使用 比特币核心 程序。</translation>
+ </message>
+ <message>
+ <source>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</source>
+ <translation>由于这是第一次运行 比特币核心 程序,您可以选择数据存储目录。</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory.</source>
+ <translation>比特币核心 程序会下载储存一份数据块链(blockchain)。至少需要 %1 GB的存储空间,随着时间推移会需要更多的存储空间。钱包文件也储存在该目录。</translation>
+ </message>
+ <message>
+ <source>Use the default data directory</source>
+ <translation>使用默认的数据目录</translation>
+ </message>
+ <message>
+ <source>Use a custom data directory:</source>
+ <translation>使用自定义的数据目录:</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>比特币核心</translation>
+ </message>
+ <message>
+ <source>Error: Specified data directory "%1" cannot be created.</source>
+ <translation>错误:无法创建 指定的数据目录 "%1" </translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>错误</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n GB of free space available</source>
+ <translation><numerusform>有 %n GB 空闲空间</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>(of %n GB needed)</source>
+ <translation><numerusform>(需要%n GB空间)</numerusform></translation>
+ </message>
+</context>
+<context>
+ <name>OpenURIDialog</name>
+ <message>
+ <source>Open URI</source>
+ <translation>打开 URI</translation>
+ </message>
+ <message>
+ <source>Open payment request from URI or file</source>
+ <translation>打开来自URI或文件的付款请求 </translation>
+ </message>
+ <message>
+ <source>URI:</source>
+ <translation>URI: </translation>
+ </message>
+ <message>
+ <source>Select payment request file</source>
+ <translation>选择付款请求文件 </translation>
+ </message>
+ <message>
+ <source>Select payment request file to open</source>
+ <translation>选择需要打开的付款请求文件 </translation>
+ </message>
+</context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>选项</translation>
+ </message>
+ <message>
+ <source>&amp;Main</source>
+ <translation>主要(&amp;M)</translation>
+ </message>
+ <message>
+ <source>Size of &amp;database cache</source>
+ <translation>数据库缓存大小(&amp;D)</translation>
+ </message>
+ <message>
+ <source>MB</source>
+ <translation>MB</translation>
+ </message>
+ <message>
+ <source>Number of script &amp;verification threads</source>
+ <translation>脚本验证线程数(&amp;V)</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside</source>
+ <translation>接收外部连接</translation>
+ </message>
+ <message>
+ <source>Allow incoming connections</source>
+ <translation>允许流入连接</translation>
+ </message>
+ <message>
+ <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
+ <translation>代理的 IP 地址 (例如 IPv4: 127.0.0.1 / IPv6: ::1)</translation>
+ </message>
+ <message>
+ <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source>
+ <translation>窗口被关闭时最小化而不是退出应用程序。当此选项启用时,应用程序只会在菜单中选择退出时退出。</translation>
+ </message>
+ <message>
+ <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source>
+ <translation>可以在这里设置用户界面语言。此设置将在重新启动比特币核心后生效。</translation>
+ </message>
+ <message>
+ <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source>
+ <translation>出现在交易的选项卡的上下文菜单项的第三方网址 (例如:区块链接查询) 。 %s的URL被替换为交易哈希。多个的URL需要竖线 | 分隔。</translation>
+ </message>
+ <message>
+ <source>Third party transaction URLs</source>
+ <translation>第三方交易网址</translation>
+ </message>
+ <message>
+ <source>Active command-line options that override above options:</source>
+ <translation>有效的命令行参数覆盖上述选项:</translation>
+ </message>
+ <message>
+ <source>Reset all client options to default.</source>
+ <translation>恢复客户端的缺省设置</translation>
+ </message>
+ <message>
+ <source>&amp;Reset Options</source>
+ <translation>恢复缺省设置(&amp;R)</translation>
+ </message>
+ <message>
+ <source>&amp;Network</source>
+ <translation>网络(&amp;N)</translation>
+ </message>
+ <message>
+ <source>Automatically start Bitcoin Core after logging in to the system.</source>
+ <translation>登录到系统后自动启动比特币核心。</translation>
+ </message>
+ <message>
+ <source>&amp;Start Bitcoin Core on system login</source>
+ <translation>系统登录时启动比特币核心(&amp;S)</translation>
+ </message>
+ <message>
+ <source>(0 = auto, &lt;0 = leave that many cores free)</source>
+ <translation>(0 = 自动, &lt;0 = 离开很多免费的核心)</translation>
+ </message>
+ <message>
+ <source>W&amp;allet</source>
+ <translation>钱包(&amp;A)</translation>
+ </message>
+ <message>
+ <source>Expert</source>
+ <translation>专家</translation>
+ </message>
+ <message>
+ <source>Enable coin &amp;control features</source>
+ <translation>启动货币控制功能(&amp;C)</translation>
+ </message>
+ <message>
+ <source>If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.</source>
+ <translation>如果禁用未确认的零钱,则零钱至少需要1个确认才能使用。同时账户余额显示会受到影响。</translation>
+ </message>
+ <message>
+ <source>&amp;Spend unconfirmed change</source>
+ <translation>使用未经确认的零钱(&amp;S)</translation>
+ </message>
+ <message>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>自动在路由器中打开比特币端口。只有当您的路由器开启了 UPnP 选项时此功能才有效。</translation>
+ </message>
+ <message>
+ <source>Map port using &amp;UPnP</source>
+ <translation>使用 &amp;UPnP 映射端口</translation>
+ </message>
+ <message>
+ <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
+ <translation>通过 SOCKS5 代理连接比特币网络。</translation>
+ </message>
+ <message>
+ <source>&amp;Connect through SOCKS5 proxy (default proxy):</source>
+ <translation>通过 SO&amp;CKS5 代理连接(默认代理):</translation>
+ </message>
+ <message>
+ <source>Proxy &amp;IP:</source>
+ <translation>代理服务器 &amp;IP:</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>端口(&amp;P):</translation>
+ </message>
+ <message>
+ <source>Port of the proxy (e.g. 9050)</source>
+ <translation>代理端口(例如 9050)</translation>
+ </message>
+ <message>
+ <source>&amp;Window</source>
+ <translation>窗口(&amp;W)</translation>
+ </message>
+ <message>
+ <source>Show only a tray icon after minimizing the window.</source>
+ <translation>最小化窗口后仅显示托盘图标</translation>
+ </message>
+ <message>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>最小化到托盘(&amp;M)</translation>
+ </message>
+ <message>
+ <source>M&amp;inimize on close</source>
+ <translation>单击关闭按钮最小化(&amp;I)</translation>
+ </message>
+ <message>
+ <source>&amp;Display</source>
+ <translation>显示(&amp;D)</translation>
+ </message>
+ <message>
+ <source>User Interface &amp;language:</source>
+ <translation>用户界面语言(&amp;L):</translation>
+ </message>
+ <message>
+ <source>&amp;Unit to show amounts in:</source>
+ <translation>比特币金额单位(&amp;U):</translation>
+ </message>
+ <message>
+ <source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
+ <translation>选择比特币单位。</translation>
+ </message>
+ <message>
+ <source>Whether to show coin control features or not.</source>
+ <translation>是否需要交易源地址控制功能。</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>确定(&amp;O)</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>取消(&amp;C)</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>默认</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>无</translation>
+ </message>
+ <message>
+ <source>Confirm options reset</source>
+ <translation>确认恢复缺省设置</translation>
+ </message>
+ <message>
+ <source>Client restart required to activate changes.</source>
+ <translation>更改生效需要重启客户端。</translation>
+ </message>
+ <message>
+ <source>Client will be shut down. Do you want to proceed?</source>
+ <translation>客户端即将关闭,您想继续吗?</translation>
+ </message>
+ <message>
+ <source>This change would require a client restart.</source>
+ <translation>此更改需要重启客户端。</translation>
+ </message>
+ <message>
+ <source>The supplied proxy address is invalid.</source>
+ <translation>提供的代理服务器地址无效。</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>表单</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>现在显示的消息可能是过期的. 在连接上比特币网络节点后,您的钱包将自动与网络同步,但是这个过程还没有完成。</translation>
+ </message>
+ <message>
+ <source>Watch-only:</source>
+ <translation>查看-只有:</translation>
+ </message>
+ <message>
+ <source>Available:</source>
+ <translation>可使用的余额:</translation>
+ </message>
+ <message>
+ <source>Your current spendable balance</source>
+ <translation>您当前可使用的余额</translation>
+ </message>
+ <message>
+ <source>Pending:</source>
+ <translation>等待中的余额:</translation>
+ </message>
+ <message>
+ <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source>
+ <translation>尚未确认的交易总额,未计入当前余额</translation>
+ </message>
+ <message>
+ <source>Immature:</source>
+ <translation>未成熟的:</translation>
+ </message>
+ <message>
+ <source>Mined balance that has not yet matured</source>
+ <translation>尚未成熟的挖矿收入余额</translation>
+ </message>
+ <message>
+ <source>Balances</source>
+ <translation>余额</translation>
+ </message>
+ <message>
+ <source>Total:</source>
+ <translation>总额:</translation>
+ </message>
+ <message>
+ <source>Your current total balance</source>
+ <translation>您当前的总余额</translation>
+ </message>
+ <message>
+ <source>Your current balance in watch-only addresses</source>
+ <translation>您当前 观察地址(watch-only address)的余额 </translation>
+ </message>
+ <message>
+ <source>Spendable:</source>
+ <translation>可使用:</translation>
+ </message>
+ <message>
+ <source>Recent transactions</source>
+ <translation>最近交易记录</translation>
+ </message>
+ <message>
+ <source>Unconfirmed transactions to watch-only addresses</source>
+ <translation>观察地址(watch-only address)的未确认交易记录 </translation>
+ </message>
+ <message>
+ <source>Mined balance in watch-only addresses that has not yet matured</source>
+ <translation>观察地址(watch-only address)中尚未成熟(matured)的挖矿收入余额:</translation>
+ </message>
+ <message>
+ <source>Current total balance in watch-only addresses</source>
+ <translation>观察地址(watch-only address)中的当前总余额 </translation>
+ </message>
+</context>
+<context>
+ <name>PaymentServer</name>
+ <message>
+ <source>URI handling</source>
+ <translation>URI 处理</translation>
+ </message>
+ <message>
+ <source>Invalid payment address %1</source>
+ <translation>无效的付款地址 %1</translation>
+ </message>
+ <message>
+ <source>Payment request rejected</source>
+ <translation>支付请求被拒绝</translation>
+ </message>
+ <message>
+ <source>Payment request network doesn't match client network.</source>
+ <translation>付款请求所在的网络与当前客户端所在的网络不匹配。</translation>
+ </message>
+ <message>
+ <source>Payment request is not initialized.</source>
+ <translation>支付请求未成形。</translation>
+ </message>
+ <message>
+ <source>Requested payment amount of %1 is too small (considered dust).</source>
+ <translation>请求支付的金额 %1 太小(就像尘埃)。</translation>
+ </message>
+ <message>
+ <source>Payment request error</source>
+ <translation>支付请求出错</translation>
+ </message>
+ <message>
+ <source>Cannot start bitcoin: click-to-pay handler</source>
+ <translation>暂时无法启动比特币:点击支付功能</translation>
+ </message>
+ <message>
+ <source>Payment request fetch URL is invalid: %1</source>
+ <translation>付款请求URI链接非法: %1</translation>
+ </message>
+ <message>
+ <source>URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source>
+ <translation>URI无法解析!原因可能是比特币地址不正确,或者URI参数错误。</translation>
+ </message>
+ <message>
+ <source>Payment request file handling</source>
+ <translation>付款请求文件处理 </translation>
+ </message>
+ <message>
+ <source>Payment request file cannot be read! This can be caused by an invalid payment request file.</source>
+ <translation>付款请求文件无法读取!可能是付款请求文件不合格。</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>支付请求已过期。</translation>
+ </message>
+ <message>
+ <source>Unverified payment requests to custom payment scripts are unsupported.</source>
+ <translation>不支持到自定义付款脚本的未验证付款请求。</translation>
+ </message>
+ <message>
+ <source>Invalid payment request.</source>
+ <translation>无效的支付请求。</translation>
+ </message>
+ <message>
+ <source>Refund from %1</source>
+ <translation>退款来自 %1</translation>
+ </message>
+ <message>
+ <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source>
+ <translation>支付请求 %1 太大 (%2 字节。只允许 %3 字节)。</translation>
+ </message>
+ <message>
+ <source>Payment request DoS protection</source>
+ <translation>支付请求防滥用保护</translation>
+ </message>
+ <message>
+ <source>Error communicating with %1: %2</source>
+ <translation>%1: %2 通讯出错</translation>
+ </message>
+ <message>
+ <source>Payment request cannot be parsed!</source>
+ <translation>无法解析 付款请求!</translation>
+ </message>
+ <message>
+ <source>Bad response from server %1</source>
+ <translation>来自 %1 服务器的错误响应</translation>
+ </message>
+ <message>
+ <source>Payment acknowledged</source>
+ <translation>支付已到账</translation>
+ </message>
+ <message>
+ <source>Network request error</source>
+ <translation>网络请求出错</translation>
+ </message>
+</context>
+<context>
+ <name>PeerTableModel</name>
+ <message>
+ <source>User Agent</source>
+ <translation>用户代理</translation>
+ </message>
+ <message>
+ <source>Node/Service</source>
+ <translation>节点/服务</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Ping 时间</translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>金额</translation>
+ </message>
+ <message>
+ <source>Enter a Bitcoin address (e.g. %1)</source>
+ <translation>请输入一个比特币地址 (例如 %1)</translation>
+ </message>
+ <message>
+ <source>%1 d</source>
+ <translation>%1 天</translation>
+ </message>
+ <message>
+ <source>%1 h</source>
+ <translation>%1 小时</translation>
+ </message>
+ <message>
+ <source>%1 m</source>
+ <translation>%1 分钟</translation>
+ </message>
+ <message>
+ <source>%1 s</source>
+ <translation>%1 秒</translation>
+ </message>
+ <message>
+ <source>None</source>
+ <translation>无</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>不可用</translation>
+ </message>
+ <message>
+ <source>%1 ms</source>
+ <translation>%1 毫秒</translation>
+ </message>
+</context>
+<context>
+ <name>QRImageWidget</name>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>保存图片(&amp;S)...</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Image</source>
+ <translation>复制图片(&amp;C)</translation>
+ </message>
+ <message>
+ <source>Save QR Code</source>
+ <translation>保存二维码</translation>
+ </message>
+ <message>
+ <source>PNG Image (*.png)</source>
+ <translation>PNG图片(*.png)</translation>
+ </message>
+</context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>Client name</source>
+ <translation>客户端名称</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>不可用</translation>
+ </message>
+ <message>
+ <source>Client version</source>
+ <translation>客户端版本</translation>
+ </message>
+ <message>
+ <source>&amp;Information</source>
+ <translation>信息</translation>
+ </message>
+ <message>
+ <source>Debug window</source>
+ <translation>调试窗口</translation>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>常规</translation>
+ </message>
+ <message>
+ <source>Using OpenSSL version</source>
+ <translation>使用 OpenSSL 版本</translation>
+ </message>
+ <message>
+ <source>Using BerkeleyDB version</source>
+ <translation>使用的 BerkeleyDB 版本</translation>
+ </message>
+ <message>
+ <source>Startup time</source>
+ <translation>启动时间</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>网络</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>姓名</translation>
+ </message>
+ <message>
+ <source>Number of connections</source>
+ <translation>连接数</translation>
+ </message>
+ <message>
+ <source>Block chain</source>
+ <translation>数据链</translation>
+ </message>
+ <message>
+ <source>Current number of blocks</source>
+ <translation>当前数据块数量</translation>
+ </message>
+ <message>
+ <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source>
+ <translation>从当前的数据目录打开比特币核心调试日志文件。对于较大的日志文件,这可能需要几秒钟。</translation>
+ </message>
+ <message>
+ <source>Received</source>
+ <translation>收到</translation>
+ </message>
+ <message>
+ <source>Sent</source>
+ <translation>发送</translation>
+ </message>
+ <message>
+ <source>&amp;Peers</source>
+ <translation>同伴(&amp;P)</translation>
+ </message>
+ <message>
+ <source>Select a peer to view detailed information.</source>
+ <translation>选择节点查看详细信息。</translation>
+ </message>
+ <message>
+ <source>Direction</source>
+ <translation>方向</translation>
+ </message>
+ <message>
+ <source>Version</source>
+ <translation>版本</translation>
+ </message>
+ <message>
+ <source>User Agent</source>
+ <translation>用户代理</translation>
+ </message>
+ <message>
+ <source>Services</source>
+ <translation>服务</translation>
+ </message>
+ <message>
+ <source>Starting Height</source>
+ <translation>开始高度</translation>
+ </message>
+ <message>
+ <source>Sync Height</source>
+ <translation>同步高度</translation>
+ </message>
+ <message>
+ <source>Ban Score</source>
+ <translation>禁止得分</translation>
+ </message>
+ <message>
+ <source>Connection Time</source>
+ <translation>连接时间</translation>
+ </message>
+ <message>
+ <source>Last Send</source>
+ <translation>最后发送</translation>
+ </message>
+ <message>
+ <source>Last Receive</source>
+ <translation>最后接收</translation>
+ </message>
+ <message>
+ <source>Bytes Sent</source>
+ <translation>发送字节</translation>
+ </message>
+ <message>
+ <source>Bytes Received</source>
+ <translation>接收字节</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Ping 时间</translation>
+ </message>
+ <message>
+ <source>Time Offset</source>
+ <translation>时间偏移</translation>
+ </message>
+ <message>
+ <source>Last block time</source>
+ <translation>上一数据块时间</translation>
+ </message>
+ <message>
+ <source>&amp;Open</source>
+ <translation>打开(&amp;O)</translation>
+ </message>
+ <message>
+ <source>&amp;Console</source>
+ <translation>控制台(&amp;C)</translation>
+ </message>
+ <message>
+ <source>&amp;Network Traffic</source>
+ <translation>网络流量(&amp;N)</translation>
+ </message>
+ <message>
+ <source>&amp;Clear</source>
+ <translation>清除(&amp;C)</translation>
+ </message>
+ <message>
+ <source>Totals</source>
+ <translation>总数</translation>
+ </message>
+ <message>
+ <source>In:</source>
+ <translation>输入:</translation>
+ </message>
+ <message>
+ <source>Out:</source>
+ <translation>输出:</translation>
+ </message>
+ <message>
+ <source>Build date</source>
+ <translation>创建时间</translation>
+ </message>
+ <message>
+ <source>Debug log file</source>
+ <translation>调试日志文件</translation>
+ </message>
+ <message>
+ <source>Clear console</source>
+ <translation>清空控制台</translation>
+ </message>
+ <message>
+ <source>Welcome to the Bitcoin Core RPC console.</source>
+ <translation>欢迎使用 比特币核心 RPC 控制台。</translation>
+ </message>
+ <message>
+ <source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
+ <translation>使用上下方向键浏览历史, &lt;b&gt;Ctrl-L&lt;/b&gt;清除屏幕。</translation>
+ </message>
+ <message>
+ <source>Type &lt;b&gt;help&lt;/b&gt; for an overview of available commands.</source>
+ <translation>使用 &lt;b&gt;help&lt;/b&gt; 命令显示帮助信息。</translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation>%1 字节</translation>
+ </message>
+ <message>
+ <source>%1 KB</source>
+ <translation>%1 KB</translation>
+ </message>
+ <message>
+ <source>%1 MB</source>
+ <translation>%1 MB</translation>
+ </message>
+ <message>
+ <source>%1 GB</source>
+ <translation>%1 GB</translation>
+ </message>
+ <message>
+ <source>via %1</source>
+ <translation>通过 %1</translation>
+ </message>
+ <message>
+ <source>never</source>
+ <translation>从未</translation>
+ </message>
+ <message>
+ <source>Inbound</source>
+ <translation>传入</translation>
+ </message>
+ <message>
+ <source>Outbound</source>
+ <translation>传出</translation>
+ </message>
+ <message>
+ <source>Unknown</source>
+ <translation>未知</translation>
+ </message>
+ <message>
+ <source>Fetching...</source>
+ <translation>获取中...</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Amount:</source>
+ <translation>总额(&amp;A):</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>标签(&amp;L):</translation>
+ </message>
+ <message>
+ <source>&amp;Message:</source>
+ <translation>消息(&amp;M):</translation>
+ </message>
+ <message>
+ <source>Reuse one of the previously used receiving addresses. Reusing addresses has security and privacy issues. Do not use this unless re-generating a payment request made before.</source>
+ <translation>重复使用以前用过的接收地址。重用地址有安全和隐私方面的隐患。除非是为重复生成同一项支付请求,否则请不要这样做。</translation>
+ </message>
+ <message>
+ <source>R&amp;euse an existing receiving address (not recommended)</source>
+ <translation>重用现有的接收地址(不推荐)</translation>
+ </message>
+ <message>
+ <source>An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network.</source>
+ <translation>可在付款请求上备注一条信息,在打开付款请求时可以看到。注意:该消息不是通过比特币网络传送。</translation>
+ </message>
+ <message>
+ <source>An optional label to associate with the new receiving address.</source>
+ <translation>可为新建的收款地址添加一个标签。</translation>
+ </message>
+ <message>
+ <source>Use this form to request payments. All fields are &lt;b&gt;optional&lt;/b&gt;.</source>
+ <translation>使用此表单要求付款。所有字段都是&lt;b&gt;可选&lt;/b&gt;。</translation>
+ </message>
+ <message>
+ <source>An optional amount to request. Leave this empty or zero to not request a specific amount.</source>
+ <translation>可选的请求金额。留空或填零为不要求具体金额。</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>清除此表单的所有字段。</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation>清除</translation>
+ </message>
+ <message>
+ <source>Requested payments history</source>
+ <translation>请求付款的历史</translation>
+ </message>
+ <message>
+ <source>&amp;Request payment</source>
+ <translation>请求付款(&amp;R)</translation>
+ </message>
+ <message>
+ <source>Show the selected request (does the same as double clicking an entry)</source>
+ <translation>显示选中的请求 (双击也可以显示)</translation>
+ </message>
+ <message>
+ <source>Show</source>
+ <translation>显示</translation>
+ </message>
+ <message>
+ <source>Remove the selected entries from the list</source>
+ <translation>从列表中移除选中的条目</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>移除</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>复制标签</translation>
+ </message>
+ <message>
+ <source>Copy message</source>
+ <translation>复制消息 </translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>复制金额</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>QR Code</source>
+ <translation>二维码</translation>
+ </message>
+ <message>
+ <source>Copy &amp;URI</source>
+ <translation>复制 URI(&amp;U)</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Address</source>
+ <translation>复制地址(&amp;A)</translation>
+ </message>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>保存图片(&amp;S)...</translation>
+ </message>
+ <message>
+ <source>Request payment to %1</source>
+ <translation>请求付款到 %1</translation>
+ </message>
+ <message>
+ <source>Payment information</source>
+ <translation>付款信息</translation>
+ </message>
+ <message>
+ <source>URI</source>
+ <translation>URI</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>地址</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>金额</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>标签</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>消息</translation>
+ </message>
+ <message>
+ <source>Resulting URI too long, try to reduce the text for label / message.</source>
+ <translation>URI 太长,请试着精简标签或消息文本。</translation>
+ </message>
+ <message>
+ <source>Error encoding URI into QR Code.</source>
+ <translation>将 URI 转为二维码失败。</translation>
+ </message>
+</context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>日期</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>标签</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>消息</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>金额</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(没有标签)</translation>
+ </message>
+ <message>
+ <source>(no message)</source>
+ <translation>(无消息)</translation>
+ </message>
+ <message>
+ <source>(no amount)</source>
+ <translation>(无金额) </translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>发送比特币</translation>
+ </message>
+ <message>
+ <source>Coin Control Features</source>
+ <translation>交易源地址控制功能</translation>
+ </message>
+ <message>
+ <source>Inputs...</source>
+ <translation>输入...</translation>
+ </message>
+ <message>
+ <source>automatically selected</source>
+ <translation>自动选择</translation>
+ </message>
+ <message>
+ <source>Insufficient funds!</source>
+ <translation>存款不足!</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>总量:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>字节:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>金额:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>优先级:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>费用:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>加上交易费用后:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>变更 : </translation>
+ </message>
+ <message>
+ <source>If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address.</source>
+ <translation>如果激活该选项,但是零钱地址用光或者非法,将会新生成零钱地址,转入零钱。</translation>
+ </message>
+ <message>
+ <source>Custom change address</source>
+ <translation>自定义零钱地址</translation>
+ </message>
+ <message>
+ <source>Transaction Fee:</source>
+ <translation>交易费用:</translation>
+ </message>
+ <message>
+ <source>Choose...</source>
+ <translation>选择... </translation>
+ </message>
+ <message>
+ <source>collapse fee-settings</source>
+ <translation>收起 费用设置 </translation>
+ </message>
+ <message>
+ <source>per kilobyte</source>
+ <translation>每kb</translation>
+ </message>
+ <message>
+ <source>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "total at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source>
+ <translation>如果自定义交易费设置为 1000聪而交易大小只有250字节,则“每千字节" 模式只支付250聪交易费, 而"最少"模式则支付1000聪。 大于1000字节的交易按每千字节付费。</translation>
+ </message>
+ <message>
+ <source>Hide</source>
+ <translation>隐藏</translation>
+ </message>
+ <message>
+ <source>total at least</source>
+ <translation>最小额 </translation>
+ </message>
+ <message>
+ <source>Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process.</source>
+ <translation>交易量小时只支付最小交易费是可以的。但是请注意,当交易量大时您的交易可能永远无法确认。</translation>
+ </message>
+ <message>
+ <source>(read the tooltip)</source>
+ <translation>(请注意提示信息)</translation>
+ </message>
+ <message>
+ <source>Recommended:</source>
+ <translation>推荐:</translation>
+ </message>
+ <message>
+ <source>Custom:</source>
+ <translation>自定义:</translation>
+ </message>
+ <message>
+ <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source>
+ <translation>(智能交易费用 尚未初始化。 需要再下载一些数据块...)</translation>
+ </message>
+ <message>
+ <source>Confirmation time:</source>
+ <translation>确认时间:</translation>
+ </message>
+ <message>
+ <source>normal</source>
+ <translation>一般</translation>
+ </message>
+ <message>
+ <source>fast</source>
+ <translation>快速</translation>
+ </message>
+ <message>
+ <source>Send as zero-fee transaction if possible</source>
+ <translation>发送时尽可能 不支付交易费用</translation>
+ </message>
+ <message>
+ <source>(confirmation may take longer)</source>
+ <translation>(确认时间更长) </translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>一次发送给多个接收者</translation>
+ </message>
+ <message>
+ <source>Add &amp;Recipient</source>
+ <translation>添加收款人(&amp;R)</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>清除此表单的所有字段。</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>小额:</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>清除所有(&amp;A)</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>余额:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>确认并发送货币</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>发送(&amp;E)</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>确认发送货币</translation>
+ </message>
+ <message>
+ <source>%1 to %2</source>
+ <translation>%1 到 %2</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>复制金额</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>复制金额</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>复制交易费</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>复制含交易费的金额</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>复制字节</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>复制优先级</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>复制零钱</translation>
+ </message>
+ <message>
+ <source>or</source>
+ <translation>或</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>支付金额必须大于0。</translation>
+ </message>
+ <message>
+ <source>The amount exceeds your balance.</source>
+ <translation>金额超出您的账上余额。</translation>
+ </message>
+ <message>
+ <source>The total exceeds your balance when the %1 transaction fee is included.</source>
+ <translation>计入 %1 交易费后的金额超出您的账上余额。</translation>
+ </message>
+ <message>
+ <source>Transaction creation failed!</source>
+ <translation>交易创建失败!</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>错误:该交易被拒绝!发生这种错误的原因可能是:钱包中的比特币已经被用掉,有可能您复制了wallet.dat钱包文件,然后用复制的钱包文件支付了比特币,但是这个钱包文件中没有记录。</translation>
+ </message>
+ <message>
+ <source>A fee higher than %1 is considered an absurdly high fee.</source>
+ <translation>超过 %1 的交易费被认为是荒谬的高费率。</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>支付请求已过期。</translation>
+ </message>
+ <message numerus="yes">
+ <source>Estimated to begin confirmation within %n block(s).</source>
+ <translation><numerusform>预计 %n 个数据块后被确认。</numerusform></translation>
+ </message>
+ <message>
+ <source>Pay only the minimum fee of %1</source>
+ <translation>只支付最小费用 %1</translation>
+ </message>
+ <message>
+ <source>Total Amount %1&lt;span style='font-size:10pt;font-weight:normal;'&gt;&lt;br /&gt;(=%2)&lt;/span&gt;</source>
+ <translation>总金额 %1&lt;span style='font-size:10pt;font-weight:normal;'&gt;&lt;br /&gt;(=%2)&lt;/span&gt;</translation>
+ </message>
+ <message>
+ <source>The recipient address is not valid. Please recheck.</source>
+ <translation>接收人地址无效。请重新检查。</translation>
+ </message>
+ <message>
+ <source>Duplicate address found: addresses should only be used once each.</source>
+ <translation>发现重复地址:每个地址应该只使用一次。</translation>
+ </message>
+ <message>
+ <source>Warning: Invalid Bitcoin address</source>
+ <translation>警告:无效的比特币地址</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(没有标签)</translation>
+ </message>
+ <message>
+ <source>Warning: Unknown change address</source>
+ <translation>警告:未知的更改地址</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>复制小额</translation>
+ </message>
+ <message>
+ <source>Are you sure you want to send?</source>
+ <translation>您确定要发出吗?</translation>
+ </message>
+ <message>
+ <source>added as transaction fee</source>
+ <translation>已添加交易费</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>金额(&amp;M)</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>付给(&amp;T):</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>为这个地址输入一个标签,以便将它添加到您的地址簿</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>标签(&amp;L):</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>选择以前用过的地址</translation>
+ </message>
+ <message>
+ <source>This is a normal payment.</source>
+ <translation>这是笔正常的支付。</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to send the payment to</source>
+ <translation>付款目的地址</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>从剪贴板粘贴地址</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Remove this entry</source>
+ <translation>移除此项</translation>
+ </message>
+ <message>
+ <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source>
+ <translation>交易费将从发送总额中扣除。接收人将收到比您在金额框中输入的更少的比特币。如果选中了多个收件人,交易费平分。</translation>
+ </message>
+ <message>
+ <source>S&amp;ubtract fee from amount</source>
+ <translation>从金额中减去交易费(&amp;U)</translation>
+ </message>
+ <message>
+ <source>Message:</source>
+ <translation>消息:</translation>
+ </message>
+ <message>
+ <source>This is an unauthenticated payment request.</source>
+ <translation>这是一个未经验证的支付请求。</translation>
+ </message>
+ <message>
+ <source>This is an authenticated payment request.</source>
+ <translation>这是一个已经验证的支付请求。</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to the list of used addresses</source>
+ <translation>请为此地址输入一个标签以将它加入用过的地址列表</translation>
+ </message>
+ <message>
+ <source>A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network.</source>
+ <translation>bitcoin:URI 附带的备注信息,将会和交易一起存储,备查。 注意:该消息不会通过比特币网络传输。</translation>
+ </message>
+ <message>
+ <source>Pay To:</source>
+ <translation>支付给:</translation>
+ </message>
+ <message>
+ <source>Memo:</source>
+ <translation>便条:</translation>
+ </message>
+</context>
+<context>
+ <name>ShutdownWindow</name>
+ <message>
+ <source>Bitcoin Core is shutting down...</source>
+ <translation>比特币核心正在关机...</translation>
+ </message>
+ <message>
+ <source>Do not shut down the computer until this window disappears.</source>
+ <translation>在此窗口消失前不要关闭计算机。</translation>
+ </message>
+</context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Signatures - Sign / Verify a Message</source>
+ <translation>签名 - 为消息签名/验证签名消息</translation>
+ </message>
+ <message>
+ <source>&amp;Sign Message</source>
+ <translation>签名消息(&amp;S)</translation>
+ </message>
+ <message>
+ <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source>
+ <translation>您可以用你的地址对消息/协议进行签名,以证明您可以接收发送到该地址的比特币。注意不要对任何模棱两可或者随机的消息进行签名,以免遭受钓鱼式攻击。请确保消息内容准确的表达了您的真实意愿。</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to sign the message with</source>
+ <translation>用来对消息签名的地址 </translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>选择以前用过的地址</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>从剪贴板粘贴地址</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Enter the message you want to sign here</source>
+ <translation>请输入您要发送的签名消息</translation>
+ </message>
+ <message>
+ <source>Signature</source>
+ <translation>签名</translation>
+ </message>
+ <message>
+ <source>Copy the current signature to the system clipboard</source>
+ <translation>复制当前签名至剪切板</translation>
+ </message>
+ <message>
+ <source>Sign the message to prove you own this Bitcoin address</source>
+ <translation>签名消息,证明这个地址属于您。</translation>
+ </message>
+ <message>
+ <source>Sign &amp;Message</source>
+ <translation>消息签名(&amp;M)</translation>
+ </message>
+ <message>
+ <source>Reset all sign message fields</source>
+ <translation>清空所有签名消息栏</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>清除所有(&amp;A)</translation>
+ </message>
+ <message>
+ <source>&amp;Verify Message</source>
+ <translation>验证消息(&amp;V)</translation>
+ </message>
+ <message>
+ <source>Enter the receiver's 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. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source>
+ <translation>请在下面输入接收者地址、消息(确保换行符、空格符、制表符等完全相同)和签名以验证消息。请仔细核对签名信息,以提防中间人攻击。请注意,这只是证明接收方签名的地址,它不能证明任何交易!</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address the message was signed with</source>
+ <translation>消息使用的签名地址</translation>
+ </message>
+ <message>
+ <source>Verify the message to ensure it was signed with the specified Bitcoin address</source>
+ <translation>验证消息,确保消息是由指定的比特币地址签名过的。</translation>
+ </message>
+ <message>
+ <source>Verify &amp;Message</source>
+ <translation>验证消息签名(&amp;M)</translation>
+ </message>
+ <message>
+ <source>Reset all verify message fields</source>
+ <translation>清空所有验证消息栏</translation>
+ </message>
+ <message>
+ <source>Click "Sign Message" to generate signature</source>
+ <translation>单击“签名消息“产生签名。</translation>
+ </message>
+ <message>
+ <source>The entered address is invalid.</source>
+ <translation>输入的地址非法。</translation>
+ </message>
+ <message>
+ <source>Please check the address and try again.</source>
+ <translation>请检查地址后重试。</translation>
+ </message>
+ <message>
+ <source>The entered address does not refer to a key.</source>
+ <translation>输入的地址没有关联的公私钥对。</translation>
+ </message>
+ <message>
+ <source>Wallet unlock was cancelled.</source>
+ <translation>钱包解锁动作取消。</translation>
+ </message>
+ <message>
+ <source>Private key for the entered address is not available.</source>
+ <translation>找不到输入地址关联的私钥。</translation>
+ </message>
+ <message>
+ <source>Message signing failed.</source>
+ <translation>消息签名失败。</translation>
+ </message>
+ <message>
+ <source>Message signed.</source>
+ <translation>消息已签名。</translation>
+ </message>
+ <message>
+ <source>The signature could not be decoded.</source>
+ <translation>签名无法解码。</translation>
+ </message>
+ <message>
+ <source>Please check the signature and try again.</source>
+ <translation>请检查签名后重试。</translation>
+ </message>
+ <message>
+ <source>The signature did not match the message digest.</source>
+ <translation>签名与消息摘要不匹配。</translation>
+ </message>
+ <message>
+ <source>Message verification failed.</source>
+ <translation>消息验证失败。</translation>
+ </message>
+ <message>
+ <source>Message verified.</source>
+ <translation>消息验证成功。</translation>
+ </message>
+</context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>比特币核心</translation>
+ </message>
+ <message>
+ <source>The Bitcoin Core developers</source>
+ <translation>Bitcoin Core 的开发者</translation>
+ </message>
+ <message>
+ <source>[testnet]</source>
+ <translation>[测试网络]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ <message>
+ <source>KB/s</source>
+ <translation>KB/s</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>至 %1 个数据块时开启</translation>
+ </message>
+ <message>
+ <source>conflicted</source>
+ <translation>发现冲突</translation>
+ </message>
+ <message>
+ <source>%1/offline</source>
+ <translation>%1 / 离线</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1/未确认</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>%1 已确认</translation>
+ </message>
+ <message>
+ <source>Status</source>
+ <translation>状态</translation>
+ </message>
+ <message numerus="yes">
+ <source>, broadcast through %n node(s)</source>
+ <translation><numerusform>, 通过 %n 个节点广播 </numerusform></translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>日期</translation>
+ </message>
+ <message>
+ <source>Source</source>
+ <translation>源</translation>
+ </message>
+ <message>
+ <source>Generated</source>
+ <translation>生成</translation>
+ </message>
+ <message>
+ <source>From</source>
+ <translation>来自</translation>
+ </message>
+ <message>
+ <source>To</source>
+ <translation>到</translation>
+ </message>
+ <message>
+ <source>own address</source>
+ <translation>自己的地址</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>观察地址(watch-only) </translation>
+ </message>
+ <message>
+ <source>label</source>
+ <translation>标签</translation>
+ </message>
+ <message>
+ <source>Credit</source>
+ <translation>收入</translation>
+ </message>
+ <message numerus="yes">
+ <source>matures in %n more block(s)</source>
+ <translation><numerusform>%n 个数据块后成熟(mature) </numerusform></translation>
+ </message>
+ <message>
+ <source>not accepted</source>
+ <translation>未被接受</translation>
+ </message>
+ <message>
+ <source>Debit</source>
+ <translation>支出</translation>
+ </message>
+ <message>
+ <source>Total debit</source>
+ <translation>总收入</translation>
+ </message>
+ <message>
+ <source>Total credit</source>
+ <translation>总支出</translation>
+ </message>
+ <message>
+ <source>Transaction fee</source>
+ <translation>交易费</translation>
+ </message>
+ <message>
+ <source>Net amount</source>
+ <translation>净额</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>消息</translation>
+ </message>
+ <message>
+ <source>Comment</source>
+ <translation>备注</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>Merchant</source>
+ <translation>商店</translation>
+ </message>
+ <message>
+ <source>Generated coins must mature %1 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.</source>
+ <translation>生成的比特币在可以使用前必须有 %1 个成熟的区块。当您生成了此区块后,它将被广播到网络中以加入区块链。如果它未成功进入区块链,其状态将变更为“不接受”并且不可使用。这可能偶尔会发生,如果另一个节点比你早几秒钟成功生成一个区块。</translation>
+ </message>
+ <message>
+ <source>Debug information</source>
+ <translation>调试信息</translation>
+ </message>
+ <message>
+ <source>Transaction</source>
+ <translation>交易</translation>
+ </message>
+ <message>
+ <source>Inputs</source>
+ <translation>输入</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>金额</translation>
+ </message>
+ <message>
+ <source>true</source>
+ <translation>正确</translation>
+ </message>
+ <message>
+ <source>false</source>
+ <translation>错误</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>,未被成功广播</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>再打开 %n 个数据块</numerusform></translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>未知</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>交易细节</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>当前面板显示了交易的详细信息</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>日期</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>类别</translation>
+ </message>
+ <message>
+ <source>Immature (%1 confirmations, will be available after %2)</source>
+ <translation>未成熟 (%1 个确认,将在 %2 个后可用)</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>再打开 %n 个数据块</numerusform></translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>至 %1 个数据块时开启</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>已确认 (%1 条确认信息)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>此数据块未被任何其他节点接收,可能不被接受!</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>已生成但未被接受</translation>
+ </message>
+ <message>
+ <source>Offline</source>
+ <translation>掉线</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>标签</translation>
+ </message>
+ <message>
+ <source>Unconfirmed</source>
+ <translation>未确认的 </translation>
+ </message>
+ <message>
+ <source>Confirming (%1 of %2 recommended confirmations)</source>
+ <translation>确认中 (推荐 %2个确认,已经有 %1个确认)</translation>
+ </message>
+ <message>
+ <source>Conflicted</source>
+ <translation>冲突的</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>接收于</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>收款来自</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>发送给</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>付款给自己</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>挖矿所得</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>观察地址(watch-only) </translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(不可用)</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>交易状态。 鼠标移到此区域可显示确认项数量。</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>接收到交易的时间</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>交易类别。</translation>
+ </message>
+ <message>
+ <source>Whether or not a watch-only address is involved in this transaction.</source>
+ <translation>该交易中是否涉及 观察地址(watch-only address)。</translation>
+ </message>
+ <message>
+ <source>User-defined intent/purpose of the transaction.</source>
+ <translation>用户定义的该交易的意图/目的。</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>从余额添加或移除的金额。</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>全部</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>今天</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>本周</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>本月</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>上月</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>今年</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>范围...</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>接收于</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>发送给</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>到自己</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>挖矿所得</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>其他</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>输入地址或标签进行搜索</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>最小金额</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>复制地址</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>复制标签</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>复制金额</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>复制交易编号</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>编辑标签</translation>
+ </message>
+ <message>
+ <source>Show transaction details</source>
+ <translation>显示交易详情</translation>
+ </message>
+ <message>
+ <source>Export Transaction History</source>
+ <translation>导出交易历史</translation>
+ </message>
+ <message>
+ <source>Watch-only</source>
+ <translation>观察地址(Watch-only) </translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>导出失败</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the transaction history to %1.</source>
+ <translation>导出交易历史到 %1 时发生错误。</translation>
+ </message>
+ <message>
+ <source>Exporting Successful</source>
+ <translation>导出成功</translation>
+ </message>
+ <message>
+ <source>The transaction history was successfully saved to %1.</source>
+ <translation>交易历史已成功保存到 %1。</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>逗号分隔文件 (*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>已确认</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>日期</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>类别</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>标签</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>地址</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>范围:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>到</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ <message>
+ <source>Unit to show amounts in. Click to select another unit.</source>
+ <translation>金额单位。单击选择别的单位。</translation>
+ </message>
+</context>
+<context>
+ <name>WalletFrame</name>
+ <message>
+ <source>No wallet has been loaded.</source>
+ <translation>没有载入钱包。</translation>
+ </message>
+</context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>发送比特币</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>导出(&amp;E)</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>导出当前数据到文件</translation>
+ </message>
+ <message>
+ <source>Backup Wallet</source>
+ <translation>备份钱包</translation>
+ </message>
+ <message>
+ <source>Wallet Data (*.dat)</source>
+ <translation>钱包文件(*.dat)</translation>
+ </message>
+ <message>
+ <source>Backup Failed</source>
+ <translation>备份失败</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the wallet data to %1.</source>
+ <translation>尝试保存钱包数据至 %1 时发生错误。</translation>
+ </message>
+ <message>
+ <source>The wallet data was successfully saved to %1.</source>
+ <translation>钱包数据成功保存至 %1 。</translation>
+ </message>
+ <message>
+ <source>Backup Successful</source>
+ <translation>备份成功</translation>
+ </message>
+</context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>选项:
+</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>指定数据目录
+</translation>
+ </message>
+ <message>
+ <source>Connect to a node to retrieve peer addresses, and disconnect</source>
+ <translation>连接一个节点并获取对端地址,然后断开连接</translation>
+ </message>
+ <message>
+ <source>Specify your own public address</source>
+ <translation>指定您的公共地址</translation>
+ </message>
+ <message>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>接受命令行和 JSON-RPC 命令
+</translation>
+ </message>
+ <message>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>在后台运行并接受命令
+
+</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>使用测试网络
+</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
+ <translation>接受来自外部的连接 (缺省: 如果不带 -proxy or -connect 参数设置为1)</translation>
+ </message>
+ <message>
+ <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
+ <translation>绑定指定的IP地址开始监听。IPv6地址请使用[host]:port 格式</translation>
+ </message>
+ <message>
+ <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
+ <translation>删除钱包的所有交易记录,且只有用 -rescan参数启动客户端才能重新取回交易记录 </translation>
+ </message>
+ <message>
+ <source>Distributed under the MIT software license, see the accompanying file COPYING or &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</source>
+ <translation>Distributed under the MIT software license, see the accompanying file COPYING or &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</translation>
+ </message>
+ <message>
+ <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
+ <translation>当最佳区块变化时执行命令 (命令行中的 %s 会被替换成区块哈希值)</translation>
+ </message>
+ <message>
+ <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source>
+ <translation>单次交易最多使用交易费;设置太低可能导致大宗交易中止 (默认: %s)</translation>
+ </message>
+ <message>
+ <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, &gt;%u = target size in MiB to use for block files)</source>
+ <translation>通过修剪(删除)旧数据块减少存储需求。此模式将禁用钱包支持,并与 -txindex 不兼容。警告:还原此设置需要重新下载整个数据链。(默认: 0 = 禁用修剪数据块, &gt;%u = 数据块文件目标大小,单位 MiB)</translation>
+ </message>
+ <message>
+ <source>Set the number of script verification threads (%u to %d, 0 = auto, &lt;0 = leave that many cores free, default: %d)</source>
+ <translation>设置脚本验证的程序 (%u 到 %d, 0 = 自动, &lt;0 = 保留自由的核心, 默认值: %d)</translation>
+ </message>
+ <message>
+ <source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source>
+ <translation>这是测试用的预发布版本 - 请谨慎使用 - 不要用来挖矿,或者在正式商用环境下使用</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer. Bitcoin Core is probably already running.</source>
+ <translation>无法 %s的绑定到电脑上,比特币核心钱包可能已经在运行。</translation>
+ </message>
+ <message>
+ <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>警告:数据块生成数量异常,最近 %d 小时收到了 %d 个数据块(预期为 %d 个)</translation>
+ </message>
+ <message>
+ <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>警告:请检查您的网络连接,最近 %d 小时收到了 %d 个数据块(预期为 %d 个)</translation>
+ </message>
+ <message>
+ <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>警告:-paytxfee 交易费设置得太高了!每笔交易都将支付交易费。</translation>
+ </message>
+ <message>
+ <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source>
+ <translation>警告:网络似乎并不完全同意!有些矿工似乎遇到了问题。</translation>
+ </message>
+ <message>
+ <source>Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.</source>
+ <translation>警告:我们的同行似乎不完全同意!您可能需要升级,或者其他节点可能需要升级。</translation>
+ </message>
+ <message>
+ <source>Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
+ <translation>警告:钱包文件wallet.dat读取失败!最重要的公钥、私钥数据都没有问题,但是交易记录或地址簿数据不正确,或者存在数据丢失。</translation>
+ </message>
+ <message>
+ <source>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</source>
+ <translation>警告:钱包文件wallet.dat损坏! 原始的钱包文件已经备份到%s目录下并重命名为{timestamp}.bak 。如果您的账户余额或者交易记录不正确,请使用您的钱包备份文件恢复。</translation>
+ </message>
+ <message>
+ <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source>
+ <translation>节点白名单,网络掩码或IP址。可多次指定。</translation>
+ </message>
+ <message>
+ <source>(default: 1)</source>
+ <translation>(默认值: 1)</translation>
+ </message>
+ <message>
+ <source>&lt;category&gt; can be:</source>
+ <translation>&lt;category&gt; 可能是:</translation>
+ </message>
+ <message>
+ <source>Attempt to recover private keys from a corrupt wallet.dat</source>
+ <translation>尝试从损坏的钱包文件wallet.dat中恢复私钥</translation>
+ </message>
+ <message>
+ <source>Block creation options:</source>
+ <translation>数据块创建选项:</translation>
+ </message>
+ <message>
+ <source>Connect only to the specified node(s)</source>
+ <translation>仅连接到指定节点</translation>
+ </message>
+ <message>
+ <source>Connection options:</source>
+ <translation>连接选项:</translation>
+ </message>
+ <message>
+ <source>Corrupted block database detected</source>
+ <translation>检测发现数据块数据库损坏。请使用 -reindex参数重启客户端。</translation>
+ </message>
+ <message>
+ <source>Debugging/Testing options:</source>
+ <translation>调试/测试选项:</translation>
+ </message>
+ <message>
+ <source>Do not load the wallet and disable wallet RPC calls</source>
+ <translation>不要加载钱包和禁用钱包的 RPC 调用</translation>
+ </message>
+ <message>
+ <source>Do you want to rebuild the block database now?</source>
+ <translation>你想现在就重建块数据库吗?</translation>
+ </message>
+ <message>
+ <source>Error initializing block database</source>
+ <translation>初始化数据块数据库出错</translation>
+ </message>
+ <message>
+ <source>Error initializing wallet database environment %s!</source>
+ <translation>Error initializing wallet database environment %s!</translation>
+ </message>
+ <message>
+ <source>Error loading block database</source>
+ <translation>导入数据块数据库出错</translation>
+ </message>
+ <message>
+ <source>Error opening block database</source>
+ <translation>导入数据块数据库出错</translation>
+ </message>
+ <message>
+ <source>Error: Disk space is low!</source>
+ <translation>错误:磁盘剩余空间低!</translation>
+ </message>
+ <message>
+ <source>Failed to listen on any port. Use -listen=0 if you want this.</source>
+ <translation>监听端口失败。请使用 -listen=0 参数。</translation>
+ </message>
+ <message>
+ <source>If &lt;category&gt; is not supplied, output all debugging information.</source>
+ <translation>如果&lt;category&gt;未提供,将输出所有调试信息。</translation>
+ </message>
+ <message>
+ <source>Importing...</source>
+ <translation>导入中...</translation>
+ </message>
+ <message>
+ <source>Incorrect or no genesis block found. Wrong datadir for network?</source>
+ <translation>不正确或没有找到起源区块。网络错误?</translation>
+ </message>
+ <message>
+ <source>Invalid -onion address: '%s'</source>
+ <translation>无效的 -onion 地址:“%s”</translation>
+ </message>
+ <message>
+ <source>Not enough file descriptors available.</source>
+ <translation>没有足够的文件描述符可用。</translation>
+ </message>
+ <message>
+ <source>Only connect to nodes in network &lt;net&gt; (ipv4, ipv6 or onion)</source>
+ <translation>只连接 &lt;net&gt;网络中的节点 (ipv4, ipv6 或 onion) </translation>
+ </message>
+ <message>
+ <source>Prune cannot be configured with a negative value.</source>
+ <translation>修剪不能配置一个负数。</translation>
+ </message>
+ <message>
+ <source>Prune mode is incompatible with -txindex.</source>
+ <translation>修剪模式与 -txindex 不兼容。</translation>
+ </message>
+ <message>
+ <source>Set database cache size in megabytes (%d to %d, default: %d)</source>
+ <translation>设置以MB为单位的数据库缓存大小(%d 到 %d, 默认值: %d)</translation>
+ </message>
+ <message>
+ <source>Set maximum block size in bytes (default: %d)</source>
+ <translation>设置最大区块大小 (默认: %d,单位字节)</translation>
+ </message>
+ <message>
+ <source>Specify wallet file (within data directory)</source>
+ <translation>指定钱包文件(数据目录内)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: %u)</source>
+ <translation>使用UPnp映射监听端口 (默认: %u) </translation>
+ </message>
+ <message>
+ <source>Verifying blocks...</source>
+ <translation>正在验证数据库的完整性...</translation>
+ </message>
+ <message>
+ <source>Verifying wallet...</source>
+ <translation>正在检测钱包的完整性...</translation>
+ </message>
+ <message>
+ <source>Wallet %s resides outside data directory %s</source>
+ <translation>钱包 %s 在外部的数据目录 %s</translation>
+ </message>
+ <message>
+ <source>Wallet options:</source>
+ <translation>钱包选项:</translation>
+ </message>
+ <message>
+ <source>Warning: This version is obsolete; upgrade required!</source>
+ <translation>警告:此版本已过时,必须升级!</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to change -txindex</source>
+ <translation>您需要将 -reindex 改为 -txindex 以重建数据库</translation>
+ </message>
+ <message>
+ <source>Imports blocks from external blk000??.dat file</source>
+ <translation>从blk000??.dat文件导入数据块</translation>
+ </message>
+ <message>
+ <source>Allow JSON-RPC connections from specified source. Valid for &lt;ip&gt; are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times</source>
+ <translation>允许来自指定地址的 JSON-RPC 连接。 &lt;ip&gt;为单一IP (如: 1.2.3.4), 网络/掩码 (如: 1.2.3.4/255.255.255.0), 网络/CIDR (如: 1.2.3.4/24)。该选项可多次指定。</translation>
+ </message>
+ <message>
+ <source>An error occurred while setting up the RPC address %s port %u for listening: %s</source>
+ <translation>设置RPC监听端口 %s:%u 时发生错误: %s</translation>
+ </message>
+ <message>
+ <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source>
+ <translation>绑定到指定地址和连接的白名单节点。 IPv6使用 [主机]:端口 格式 </translation>
+ </message>
+ <message>
+ <source>Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)</source>
+ <translation>绑定到指定地址监听 JSON-RPC连接。 IPv6使用[主机]:端口 格式。该选项可多次指定 (默认: 绑定到所有接口) </translation>
+ </message>
+ <message>
+ <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source>
+ <translation>无法获取数据目录的 %s. 比特币核心钱包可能已经在运行.</translation>
+ </message>
+ <message>
+ <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
+ <translation>创建系统默认权限的文件,而不是 umask 077 (只在关闭钱包功能时有效) </translation>
+ </message>
+ <message>
+ <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source>
+ <translation>发现自己的 IP 地址(默认: 监听并且无 -externalip 或 -proxy 时为 1)</translation>
+ </message>
+ <message>
+ <source>Error: Listening for incoming connections failed (listen returned error %s)</source>
+ <translation>错误:监听外部连接失败 (监听返回错误 %s) </translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source>
+ <translation>错误:不支持的 -socks 参数。不再支持设置SOCKS版本,现在只支持 SOCKS5代理。</translation>
+ </message>
+ <message>
+ <source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source>
+ <translation>当收到相关提醒或者我们看到一个长分叉时执行命令(%s 将替换为消息)</translation>
+ </message>
+ <message>
+ <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source>
+ <translation>交易费(BTC/kb)比这更小的交易在转发时将被视为零费交易 (默认: %s) </translation>
+ </message>
+ <message>
+ <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
+ <translation>如果未设置交易费用,自动添加足够的交易费以确保交易在平均n个数据块内被确认 (默认: %u) </translation>
+ </message>
+ <message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)</source>
+ <translation>-maxtxfee=&lt;amount&gt;: '%s' 的金额无效(交易费至少为 %s,以免交易滞留过久)</translation>
+ </message>
+ <message>
+ <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source>
+ <translation>Maximum size of data in data carrier transactions we relay and mine (default: %u)</translation>
+ </message>
+ <message>
+ <source>Prune configured below the minimum of %d MB. Please use a higher number.</source>
+ <translation>修剪被配置为比最小值 %d MB 更低。请使用更大的数字。</translation>
+ </message>
+ <message>
+ <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source>
+ <translation>通过DNS查询每个地址,如果短地址 (默认值: 1 除非 -连接)</translation>
+ </message>
+ <message>
+ <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source>
+ <translation>为每个代理连接随机化凭据。这将启用 Tor 流隔离 (默认: %u)</translation>
+ </message>
+ <message>
+ <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
+ <translation>设置 高优先级/低交易费 交易的最大字节 (缺省: %d)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source>
+ <translation>设置比特币生成线程数 ( -1=所有核, 默认: %d) </translation>
+ </message>
+ <message>
+ <source>The transaction amount is too small to send after the fee has been deducted</source>
+ <translation>在交易费被扣除后发送的交易金额太小</translation>
+ </message>
+ <message>
+ <source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit &lt;https://www.openssl.org/&gt; and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source>
+ <translation>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit &lt;https://www.openssl.org/&gt; and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</translation>
+ </message>
+ <message>
+ <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an 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)
+The username and password MUST NOT be the same.
+If the file does not exist, create it with owner-readable-only file permissions.
+It is also recommended to set alertnotify so you are notified of problems;
+for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
+</source>
+ <translation>要使用 bitcoind 或者 bitcoin-qt 中的 -server 选项,您必须在配置文件中设置一个密码:
+%s
+建议您使用下列随机密码:
+rpcuser=bitcoinrpc
+rpcpassword=%s
+(您不需要记住这个密码)
+用户名和密码不能相同。
+如果该文件不存在,创建一个文件并设置权限为仅创建者可读。
+此外,还建议您设置 alertnotify 以便您能注意到问题:
+例如 alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
+</translation>
+ </message>
+ <message>
+ <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source>
+ <translation>警告:-maxtxfee 设置的太高了!每进行一笔交易时您都要花费这么多费用。</translation>
+ </message>
+ <message>
+ <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source>
+ <translation>警告:请检查电脑的日期时间设置是否正确!时间错误可能会导致比特币客户端运行异常。</translation>
+ </message>
+ <message>
+ <source>Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway</source>
+ <translation>白名单节点不能被DoS banned ,且转发所有来自他们的交易(即便这些交易已经存在于mempool中),常用于网关 </translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source>
+ <translation>您需要使用 -reindex 重新构建数据库以返回未修剪的模式。这将重新下载整个区块链</translation>
+ </message>
+ <message>
+ <source>(default: %u)</source>
+ <translation>(默认: %u)</translation>
+ </message>
+ <message>
+ <source>Accept public REST requests (default: %u)</source>
+ <translation>接受公共 REST 请求 (默认: %u)</translation>
+ </message>
+ <message>
+ <source>Activating best chain...</source>
+ <translation>正在激活最佳数据链...</translation>
+ </message>
+ <message>
+ <source>Can't run with a wallet in prune mode.</source>
+ <translation>不能在修剪模式下运行一个钱包。</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -whitebind address: '%s'</source>
+ <translation>无法解析 -whitebind 地址: '%s'</translation>
+ </message>
+ <message>
+ <source>Choose data directory on startup (default: 0)</source>
+ <translation>在启动时选择数据目录(默认:0)</translation>
+ </message>
+ <message>
+ <source>Connect through SOCKS5 proxy</source>
+ <translation>通过 SOCKS5 代理连接</translation>
+ </message>
+ <message>
+ <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source>
+ <translation>版权所有 (C) 2009-%i Bitcoin Core 开发者</translation>
+ </message>
+ <message>
+ <source>Could not parse -rpcbind value %s as network address</source>
+ <translation>无法解析 -rpcbind 的值 %s 为网络地址</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source>
+ <translation>加载wallet.dat错误:需要新版的比特币核心钱包</translation>
+ </message>
+ <message>
+ <source>Error reading from database, shutting down.</source>
+ <translation>读取数据库出错,关闭中。</translation>
+ </message>
+ <message>
+ <source>Error: A fatal internal error occurred, see debug.log for details</source>
+ <translation>错误:发生了致命的内部错误,详情见 debug.log 文件</translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -tor found, use -onion.</source>
+ <translation>错误:发现了不支持的参数 -tor,请使用 -onion。</translation>
+ </message>
+ <message>
+ <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source>
+ <translation>为付款交易添加交易费 (BTC/kb) (默认: %s) </translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>信息</translation>
+ </message>
+ <message>
+ <source>Initialization sanity check failed. Bitcoin Core is shutting down.</source>
+ <translation>初始化完整性检查失败。Bitcoin Core 即将关闭。</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s'</source>
+ <translation>-maxtxfee=&lt;amount&gt;: '%s' 的金额无效</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -minrelaytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>-minrelaytxfee=&lt;amount&gt;: '%s' 无效的金额</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -mintxfee=&lt;amount&gt;: '%s'</source>
+ <translation>-mintxfee=&lt;amount&gt;: '%s' 无效的金额</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s' (must be at least %s)</source>
+ <translation>无效的金额 -paytxfee=&lt;amount&gt;: '%s' (必须至少为 %s)</translation>
+ </message>
+ <message>
+ <source>Invalid netmask specified in -whitelist: '%s'</source>
+ <translation>-whitelist: '%s' 指定的网络掩码无效</translation>
+ </message>
+ <message>
+ <source>Need to specify a port with -whitebind: '%s'</source>
+ <translation>-whitebind: '%s' 需要指定一个端口</translation>
+ </message>
+ <message>
+ <source>Node relay options:</source>
+ <translation>节点中继选项:</translation>
+ </message>
+ <message>
+ <source>Pruning blockstore...</source>
+ <translation>正在修剪区块存储...</translation>
+ </message>
+ <message>
+ <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source>
+ <translation>RPC SSL选项:(见有关比特币设置用于SSL说明的维基百科)</translation>
+ </message>
+ <message>
+ <source>RPC server options:</source>
+ <translation>RPC 服务器选项:</translation>
+ </message>
+ <message>
+ <source>RPC support for HTTP persistent connections (default: %d)</source>
+ <translation>RPC 支持 HTTP 持久连接 (默认: %d)</translation>
+ </message>
+ <message>
+ <source>Rebuild block chain index from current blk000??.dat files on startup</source>
+ <translation>启动时重新为当前的 blk000??.dat 文件建立索引</translation>
+ </message>
+ <message>
+ <source>Receive and display P2P network alerts (default: %u)</source>
+ <translation>收到并且显示P2P网络的告警(默认:%u)</translation>
+ </message>
+ <message>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>跟踪/调试信息输出到控制台,不输出到 debug.log 文件</translation>
+ </message>
+ <message>
+ <source>Send transactions as zero-fee transactions if possible (default: %u)</source>
+ <translation>发送时尽可能 不支付交易费用 (默认: %u) </translation>
+ </message>
+ <message>
+ <source>Set SSL root certificates for payment request (default: -system-)</source>
+ <translation>设置SSL根证书的付款请求(默认:-系统-)</translation>
+ </message>
+ <message>
+ <source>Set language, for example "de_DE" (default: system locale)</source>
+ <translation>设置语言, 例如“zh-TW”(默认为系统语言)</translation>
+ </message>
+ <message>
+ <source>Show all debugging options (usage: --help -help-debug)</source>
+ <translation>显示所有调试选项 (用法: --帮助 -帮助调试)</translation>
+ </message>
+ <message>
+ <source>Show splash screen on startup (default: 1)</source>
+ <translation>启动时显示版权页 (缺省: 1)</translation>
+ </message>
+ <message>
+ <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source>
+ <translation>客户端启动时压缩debug.log文件(缺省:no-debug模式时为1)</translation>
+ </message>
+ <message>
+ <source>Signing transaction failed</source>
+ <translation>签署交易失败</translation>
+ </message>
+ <message>
+ <source>Start minimized</source>
+ <translation>启动时最小化
+</translation>
+ </message>
+ <message>
+ <source>The transaction amount is too small to pay the fee</source>
+ <translation>交易金额太小,不足以支付交易费</translation>
+ </message>
+ <message>
+ <source>This is experimental software.</source>
+ <translation>这是实验性的软件。</translation>
+ </message>
+ <message>
+ <source>Transaction amount too small</source>
+ <translation>交易量太小</translation>
+ </message>
+ <message>
+ <source>Transaction amounts must be positive</source>
+ <translation>交易金额必须是积极的</translation>
+ </message>
+ <message>
+ <source>Transaction too large for fee policy</source>
+ <translation>费用策略的交易太大</translation>
+ </message>
+ <message>
+ <source>Transaction too large</source>
+ <translation>交易太大</translation>
+ </message>
+ <message>
+ <source>UI Options:</source>
+ <translation>界面选项:</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer (bind returned error %s)</source>
+ <translation>无法在此计算机上绑定 %s (绑定返回错误 %s)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: 1 when listening)</source>
+ <translation>使用UPnp映射监听端口(缺省: 监听状态设为1)</translation>
+ </message>
+ <message>
+ <source>Username for JSON-RPC connections</source>
+ <translation>JSON-RPC 连接用户名</translation>
+ </message>
+ <message>
+ <source>Wallet needed to be rewritten: restart Bitcoin Core to complete</source>
+ <translation>钱包需要被改写:重新启动核心钱包来完成</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>警告</translation>
+ </message>
+ <message>
+ <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source>
+ <translation>警告:不支持的参数 -benchmark 已忽略,请使用 -debug=bench。</translation>
+ </message>
+ <message>
+ <source>Warning: Unsupported argument -debugnet ignored, use -debug=net.</source>
+ <translation>警告:不支持的参数 -debugnet 已忽略,请使用 -debug=net。</translation>
+ </message>
+ <message>
+ <source>Zapping all transactions from wallet...</source>
+ <translation>Zapping all transactions from wallet...</translation>
+ </message>
+ <message>
+ <source>on startup</source>
+ <translation>启动中</translation>
+ </message>
+ <message>
+ <source>wallet.dat corrupt, salvage failed</source>
+ <translation>钱包文件wallet.dat损坏,抢救备份失败</translation>
+ </message>
+ <message>
+ <source>Password for JSON-RPC connections</source>
+ <translation>JSON-RPC 连接密码
+</translation>
+ </message>
+ <message>
+ <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
+ <translation>当最佳数据块变化时执行命令 (命令行中的 %s 会被替换成数据块哈希值)</translation>
+ </message>
+ <message>
+ <source>Upgrade wallet to latest format</source>
+ <translation>将钱包升级到最新的格式</translation>
+ </message>
+ <message>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>重新扫描区块链以查找遗漏的钱包交易</translation>
+ </message>
+ <message>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>为 JSON-RPC 连接使用 OpenSSL (https) 连接</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>本帮助信息
+</translation>
+ </message>
+ <message>
+ <source>Allow DNS lookups for -addnode, -seednode and -connect</source>
+ <translation>使用 -addnode, -seednode 和 -connect 选项时允许查询DNS</translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>正在加载地址簿...</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>wallet.dat 钱包文件加载出错:钱包损坏</translation>
+ </message>
+ <message>
+ <source>(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source>
+ <translation>(1 = 保留 tx meta data , 如 account owner 和 payment request information, 2 = 不保留 tx meta data) </translation>
+ </message>
+ <message>
+ <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
+ <translation>数据块验证 严密级别 -checkblocks (0-4, 默认: %u) </translation>
+ </message>
+ <message>
+ <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
+ <translation>维护一份完整的交易索引, 用于 getrawtransaction RPC调用 (默认: %u)</translation>
+ </message>
+ <message>
+ <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source>
+ <translation>限制 非礼节点 若干秒内不能连接 (默认: %u) </translation>
+ </message>
+ <message>
+ <source>Output debugging information (default: %u, supplying &lt;category&gt; is optional)</source>
+ <translation>输出调试信息 (默认: %u, 提供 &lt;category&gt; 是可选项)</translation>
+ </message>
+ <message>
+ <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source>
+ <translation>通过Tor隐藏服务连接节点时 使用不同的SOCKS5代理 (默认: %s)</translation>
+ </message>
+ <message>
+ <source>(default: %s)</source>
+ <translation>(默认: %s) </translation>
+ </message>
+ <message>
+ <source>Acceptable ciphers (default: %s)</source>
+ <translation>可接受的密码算法 (默认: %s) </translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>wallet.dat 钱包文件加载出错</translation>
+ </message>
+ <message>
+ <source>Generate coins (default: %u)</source>
+ <translation>生成比特币 (默认: %u)</translation>
+ </message>
+ <message>
+ <source>How many blocks to check at startup (default: %u, 0 = all)</source>
+ <translation>启动时检测多少个数据块(默认: %u, 0=所有)</translation>
+ </message>
+ <message>
+ <source>Include IP addresses in debug output (default: %u)</source>
+ <translation>在调试输出中包含IP地址 (默认: %u)</translation>
+ </message>
+ <message>
+ <source>Invalid -proxy address: '%s'</source>
+ <translation>无效的代理地址:%s</translation>
+ </message>
+ <message>
+ <source>Listen for JSON-RPC connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>使用 &lt;port&gt;端口监听 JSON-RPC 连接 (默认: %u ; testnet: %u) </translation>
+ </message>
+ <message>
+ <source>Listen for connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>使用端口 &lt;port&gt; 监听连接 (默认: %u ; testnet: %u) </translation>
+ </message>
+ <message>
+ <source>Maintain at most &lt;n&gt; connections to peers (default: %u)</source>
+ <translation>保留最多 &lt;n&gt; 条节点连接 (默认: %u) </translation>
+ </message>
+ <message>
+ <source>Make the wallet broadcast transactions</source>
+ <translation>钱包广播事务处理</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection receive buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>每个连接的最大接收缓存,&lt;n&gt;*1000 字节 (默认: %u)</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection send buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>每个连接的最大发送缓存,&lt;n&gt;*1000 字节 (默认: %u)</translation>
+ </message>
+ <message>
+ <source>Prepend debug output with timestamp (default: %u)</source>
+ <translation>输出调试信息时,前面加上时间戳 (默认: %u)</translation>
+ </message>
+ <message>
+ <source>Relay and mine data carrier transactions (default: %u)</source>
+ <translation>Relay and mine data carrier transactions (default: %u)</translation>
+ </message>
+ <message>
+ <source>Relay non-P2SH multisig (default: %u)</source>
+ <translation>是否转发 非P2SH格式的多签名交易 (默认: %u) </translation>
+ </message>
+ <message>
+ <source>Server certificate file (default: %s)</source>
+ <translation>服务器证书文件 (默认: %s) </translation>
+ </message>
+ <message>
+ <source>Server private key (default: %s)</source>
+ <translation>服务器私钥 (默认: %s) </translation>
+ </message>
+ <message>
+ <source>Set key pool size to &lt;n&gt; (default: %u)</source>
+ <translation>设置私钥池大小为 &lt;n&gt; (默认:%u) </translation>
+ </message>
+ <message>
+ <source>Set minimum block size in bytes (default: %u)</source>
+ <translation>设置数据块 最小字节数 (默认: %u) </translation>
+ </message>
+ <message>
+ <source>Set the number of threads to service RPC calls (default: %d)</source>
+ <translation>设置RPC服务线程数 (默认: %d) </translation>
+ </message>
+ <message>
+ <source>Specify configuration file (default: %s)</source>
+ <translation>指定配置文件 (默认: %s) </translation>
+ </message>
+ <message>
+ <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source>
+ <translation>指定连接超时毫秒数 (最小: 1, 默认: %d) </translation>
+ </message>
+ <message>
+ <source>Specify pid file (default: %s)</source>
+ <translation>指定 pid 文件 (默认: %s) </translation>
+ </message>
+ <message>
+ <source>Spend unconfirmed change when sending transactions (default: %u)</source>
+ <translation>付款时允许使用未确认的零钱 (默认: %u) </translation>
+ </message>
+ <message>
+ <source>Threshold for disconnecting misbehaving peers (default: %u)</source>
+ <translation>断开 非礼节点的阀值 (默认: %u) </translation>
+ </message>
+ <message>
+ <source>Unknown network specified in -onlynet: '%s'</source>
+ <translation>-onlynet 指定的是未知网络:%s</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -bind address: '%s'</source>
+ <translation>无法解析 -bind 端口地址: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -externalip address: '%s'</source>
+ <translation>无法解析 -externalip 地址: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>非法金额 -paytxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>金额不足</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>正在加载数据块索引...</translation>
+ </message>
+ <message>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>添加节点并与其保持连接</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>正在加载钱包...</translation>
+ </message>
+ <message>
+ <source>Cannot downgrade wallet</source>
+ <translation>无法降级钱包</translation>
+ </message>
+ <message>
+ <source>Cannot write default address</source>
+ <translation>无法写入默认地址</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>正在重新扫描...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>加载完成</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>错误</translation>
+ </message>
+</context>
+</TS> \ No newline at end of file
diff --git a/src/qt/locale/bitcoin_zh_HK.ts b/src/qt/locale/bitcoin_zh_HK.ts
new file mode 100644
index 0000000000..7062377f45
--- /dev/null
+++ b/src/qt/locale/bitcoin_zh_HK.ts
@@ -0,0 +1,110 @@
+<TS language="zh_HK" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ </context>
+<context>
+ <name>AddressTableModel</name>
+ </context>
+<context>
+ <name>AskPassphraseDialog</name>
+ </context>
+<context>
+ <name>BitcoinGUI</name>
+ </context>
+<context>
+ <name>ClientModel</name>
+ </context>
+<context>
+ <name>CoinControlDialog</name>
+ </context>
+<context>
+ <name>EditAddressDialog</name>
+ </context>
+<context>
+ <name>FreespaceChecker</name>
+ </context>
+<context>
+ <name>HelpMessageDialog</name>
+ </context>
+<context>
+ <name>Intro</name>
+ </context>
+<context>
+ <name>OpenURIDialog</name>
+ </context>
+<context>
+ <name>OptionsDialog</name>
+ </context>
+<context>
+ <name>OverviewPage</name>
+ </context>
+<context>
+ <name>PaymentServer</name>
+ </context>
+<context>
+ <name>PeerTableModel</name>
+ </context>
+<context>
+ <name>QObject</name>
+ </context>
+<context>
+ <name>QRImageWidget</name>
+ </context>
+<context>
+ <name>RPCConsole</name>
+ </context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ </context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ </context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ </context>
+<context>
+ <name>SendCoinsDialog</name>
+ </context>
+<context>
+ <name>SendCoinsEntry</name>
+ </context>
+<context>
+ <name>ShutdownWindow</name>
+ </context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ </context>
+<context>
+ <name>SplashScreen</name>
+ </context>
+<context>
+ <name>TrafficGraphWidget</name>
+ </context>
+<context>
+ <name>TransactionDesc</name>
+ </context>
+<context>
+ <name>TransactionDescDialog</name>
+ </context>
+<context>
+ <name>TransactionTableModel</name>
+ </context>
+<context>
+ <name>TransactionView</name>
+ </context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ </context>
+<context>
+ <name>WalletFrame</name>
+ </context>
+<context>
+ <name>WalletModel</name>
+ </context>
+<context>
+ <name>WalletView</name>
+ </context>
+<context>
+ <name>bitcoin-core</name>
+ </context>
+</TS> \ 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 0000000000..b7adeaf77c
--- /dev/null
+++ b/src/qt/locale/bitcoin_zh_TW.ts
@@ -0,0 +1,3585 @@
+<TS language="zh_TW" version="2.0">
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <source>Right-click to edit address or label</source>
+ <translation>右鍵點一下來修改位址或標記</translation>
+ </message>
+ <message>
+ <source>Create a new address</source>
+ <translation>新增新的位址</translation>
+ </message>
+ <message>
+ <source>&amp;New</source>
+ <translation>新增</translation>
+ </message>
+ <message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>複製目前選擇的位址到系統剪貼簿</translation>
+ </message>
+ <message>
+ <source>&amp;Copy</source>
+ <translation>複製</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>關閉</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>複製位址</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>把目前選擇的位址從列表中刪掉</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>把目前分頁的資料匯出存成檔案</translation>
+ </message>
+ <message>
+ <source>&amp;Export</source>
+ <translation>匯出</translation>
+ </message>
+ <message>
+ <source>&amp;Delete</source>
+ <translation>刪掉</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>選擇要付錢過去的位址</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>選擇要收錢進來的位址</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>選取</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>付款位址</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>收款位址</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>這些是你要付款過去的位元幣位址。在付錢之前,務必要檢查金額和收款位址是否正確。</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>這些是你用來收款的位元幣位址。建議在每次交易時,都使用一個新的收款位址。</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>複製標記</translation>
+ </message>
+ <message>
+ <source>&amp;Edit</source>
+ <translation>編輯</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>匯出位址清單</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>逗號分隔資料檔(*.csv)</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>匯出失敗</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the address list to %1. Please try again.</source>
+ <translation>儲存位址列表到 %1 時發生錯誤。請重試一次。</translation>
+ </message>
+</context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <source>Label</source>
+ <translation>標記</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>位址</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(無標記)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <source>Passphrase Dialog</source>
+ <translation>密碼對話視窗</translation>
+ </message>
+ <message>
+ <source>Enter passphrase</source>
+ <translation>請輸入密碼</translation>
+ </message>
+ <message>
+ <source>New passphrase</source>
+ <translation>新密碼</translation>
+ </message>
+ <message>
+ <source>Repeat new passphrase</source>
+ <translation>重複新密碼</translation>
+ </message>
+ <message>
+ <source>Encrypt wallet</source>
+ <translation>加密錢包</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>這個動作需要你的錢包密碼來解鎖錢包。</translation>
+ </message>
+ <message>
+ <source>Unlock wallet</source>
+ <translation>解鎖錢包</translation>
+ </message>
+ <message>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>這個動作需要你的錢包密碼來把錢包解密。</translation>
+ </message>
+ <message>
+ <source>Decrypt wallet</source>
+ <translation>解密錢包</translation>
+ </message>
+ <message>
+ <source>Change passphrase</source>
+ <translation>改變密碼</translation>
+ </message>
+ <message>
+ <source>Confirm wallet encryption</source>
+ <translation>確認錢包加密</translation>
+ </message>
+ <message>
+ <source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
+ <translation>警告: 如果把錢包加密後又忘記密碼,你就會從此&lt;b&gt;失去其中所有的位元幣了&lt;/b&gt;!</translation>
+ </message>
+ <message>
+ <source>Are you sure you wish to encrypt your wallet?</source>
+ <translation>你確定要把錢包加密嗎?</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core 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.</source>
+ <translation>位元幣核心現在要關閉,好完成加密程序。請注意,加密錢包不能完全防止入侵你的電腦的惡意程式偷取位元幣。</translation>
+ </message>
+ <message>
+ <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
+ <translation>重要: 請改用新產生有加密的錢包檔,來取代舊錢包檔的備份。為了安全性的理由,當你開始使用新的有加密的錢包後,舊錢包檔的備份就不能再使用了。</translation>
+ </message>
+ <message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>警告: 大寫字母鎖定作用中!</translation>
+ </message>
+ <message>
+ <source>Wallet encrypted</source>
+ <translation>錢包已加密</translation>
+ </message>
+ <message>
+ <source>Enter the new passphrase to the wallet.&lt;br/&gt;Please use a passphrase of &lt;b&gt;ten or more random characters&lt;/b&gt;, or &lt;b&gt;eight or more words&lt;/b&gt;.</source>
+ <translation>輸入錢包的新密碼。&lt;br/&gt;密碼請用&lt;b&gt;10 個以上的字元&lt;/b&gt;,或是&lt;b&gt;8 個以上的字詞&lt;/b&gt;。</translation>
+ </message>
+ <message>
+ <source>Enter the old passphrase and new passphrase to the wallet.</source>
+ <translation>請輸入錢包的舊密碼和新密碼。</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed</source>
+ <translation>錢包加密失敗</translation>
+ </message>
+ <message>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>因為內部錯誤導致錢包加密失敗。你的錢包還是沒加密。</translation>
+ </message>
+ <message>
+ <source>The supplied passphrases do not match.</source>
+ <translation>提供的密碼不一樣。</translation>
+ </message>
+ <message>
+ <source>Wallet unlock failed</source>
+ <translation>錢包解鎖失敗</translation>
+ </message>
+ <message>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>輸入要用來解密錢包的密碼不對。</translation>
+ </message>
+ <message>
+ <source>Wallet decryption failed</source>
+ <translation>錢包解密失敗</translation>
+ </message>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>錢包密碼改成功了。</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <source>Sign &amp;message...</source>
+ <translation>簽署訊息...</translation>
+ </message>
+ <message>
+ <source>Synchronizing with network...</source>
+ <translation>正在跟網路進行同步...</translation>
+ </message>
+ <message>
+ <source>&amp;Overview</source>
+ <translation>總覽</translation>
+ </message>
+ <message>
+ <source>Node</source>
+ <translation>節點</translation>
+ </message>
+ <message>
+ <source>Show general overview of wallet</source>
+ <translation>顯示錢包一般總覽</translation>
+ </message>
+ <message>
+ <source>&amp;Transactions</source>
+ <translation>交易</translation>
+ </message>
+ <message>
+ <source>Browse transaction history</source>
+ <translation>瀏覽交易紀錄</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>結束</translation>
+ </message>
+ <message>
+ <source>Quit application</source>
+ <translation>結束應用程式</translation>
+ </message>
+ <message>
+ <source>About &amp;Qt</source>
+ <translation>關於 &amp;Qt</translation>
+ </message>
+ <message>
+ <source>Show information about Qt</source>
+ <translation>顯示 Qt 相關資訊</translation>
+ </message>
+ <message>
+ <source>&amp;Options...</source>
+ <translation>選項...</translation>
+ </message>
+ <message>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>加密錢包...</translation>
+ </message>
+ <message>
+ <source>&amp;Backup Wallet...</source>
+ <translation>備份錢包...</translation>
+ </message>
+ <message>
+ <source>&amp;Change Passphrase...</source>
+ <translation>改變密碼...</translation>
+ </message>
+ <message>
+ <source>&amp;Sending addresses...</source>
+ <translation>付款位址...</translation>
+ </message>
+ <message>
+ <source>&amp;Receiving addresses...</source>
+ <translation>收款位址...</translation>
+ </message>
+ <message>
+ <source>Open &amp;URI...</source>
+ <translation>開啓 URI...</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core client</source>
+ <translation>位元幣核心客戶端軟體</translation>
+ </message>
+ <message>
+ <source>Importing blocks from disk...</source>
+ <translation>正在從磁碟匯入區塊資料...</translation>
+ </message>
+ <message>
+ <source>Reindexing blocks on disk...</source>
+ <translation>正在為磁碟裡的區塊重建索引...</translation>
+ </message>
+ <message>
+ <source>Send coins to a Bitcoin address</source>
+ <translation>付錢給一個位元幣位址</translation>
+ </message>
+ <message>
+ <source>Backup wallet to another location</source>
+ <translation>把錢包備份到其它地方</translation>
+ </message>
+ <message>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>改變錢包加密用的密碼</translation>
+ </message>
+ <message>
+ <source>&amp;Debug window</source>
+ <translation>除錯視窗</translation>
+ </message>
+ <message>
+ <source>Open debugging and diagnostic console</source>
+ <translation>開啓除錯和診斷主控台</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>驗證訊息...</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>位元幣</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>錢包</translation>
+ </message>
+ <message>
+ <source>&amp;Send</source>
+ <translation>已傳送</translation>
+ </message>
+ <message>
+ <source>&amp;Receive</source>
+ <translation>已接收</translation>
+ </message>
+ <message>
+ <source>Show information about Bitcoin Core</source>
+ <translation>顯示位元幣核心的相關資訊</translation>
+ </message>
+ <message>
+ <source>&amp;Show / Hide</source>
+ <translation>顯示或隱藏</translation>
+ </message>
+ <message>
+ <source>Show or hide the main Window</source>
+ <translation>顯示或隱藏主視窗</translation>
+ </message>
+ <message>
+ <source>Encrypt the private keys that belong to your wallet</source>
+ <translation>把錢包中的密鑰加密</translation>
+ </message>
+ <message>
+ <source>Sign messages with your Bitcoin addresses to prove you own them</source>
+ <translation>用位元幣位址簽署訊息來證明位址是你的</translation>
+ </message>
+ <message>
+ <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source>
+ <translation>驗證訊息是用來確定訊息是用指定的位元幣位址簽署的</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <translation>檔案</translation>
+ </message>
+ <message>
+ <source>&amp;Settings</source>
+ <translation>設定</translation>
+ </message>
+ <message>
+ <source>&amp;Help</source>
+ <translation>說明</translation>
+ </message>
+ <message>
+ <source>Tabs toolbar</source>
+ <translation>分頁工具列</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>位元幣核心</translation>
+ </message>
+ <message>
+ <source>Request payments (generates QR codes and bitcoin: URIs)</source>
+ <translation>要求付款(產生 QR Code 和位元幣付款協議的 URI)</translation>
+ </message>
+ <message>
+ <source>&amp;About Bitcoin Core</source>
+ <translation>關於位元幣核心</translation>
+ </message>
+ <message>
+ <source>Modify configuration options for Bitcoin Core</source>
+ <translation>修改位元幣核心的設定選項</translation>
+ </message>
+ <message>
+ <source>Show the list of used sending addresses and labels</source>
+ <translation>顯示已使用過的付款位址和標記的清單</translation>
+ </message>
+ <message>
+ <source>Show the list of used receiving addresses and labels</source>
+ <translation>顯示已使用過的收款位址和標記的清單</translation>
+ </message>
+ <message>
+ <source>Open a bitcoin: URI or payment request</source>
+ <translation>開啓 bitcoin 協議的 URI 或付款要求</translation>
+ </message>
+ <message>
+ <source>&amp;Command-line options</source>
+ <translation>命令列選項</translation>
+ </message>
+ <message>
+ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
+ <translation>顯示位元幣核心的說明訊息,來取得可用命令列選項的列表</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n active connection(s) to Bitcoin network</source>
+ <translation><numerusform>%n 個運作中的位元幣網路連線</numerusform></translation>
+ </message>
+ <message>
+ <source>No block source available...</source>
+ <translation>沒有可用的區塊來源...</translation>
+ </message>
+ <message numerus="yes">
+ <source>Processed %n block(s) of transaction history.</source>
+ <translation><numerusform>已經處理了 %n 個區塊的交易紀錄。</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n hour(s)</source>
+ <translation><numerusform>%n 個小時</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n day(s)</source>
+ <translation><numerusform>%n 天</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n week(s)</source>
+ <translation><numerusform>%n 個星期</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 and %2</source>
+ <translation>%1又 %2</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n year(s)</source>
+ <translation><numerusform>%n 年</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 behind</source>
+ <translation>落後 %1</translation>
+ </message>
+ <message>
+ <source>Last received block was generated %1 ago.</source>
+ <translation>最近收到的區塊是在 %1 以前生出來的。</translation>
+ </message>
+ <message>
+ <source>Transactions after this will not yet be visible.</source>
+ <translation>暫時會看不到在這之後的交易。</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>錯誤</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>警告</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>資訊</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>最新狀態</translation>
+ </message>
+ <message>
+ <source>Catching up...</source>
+ <translation>正在趕進度...</translation>
+ </message>
+ <message>
+ <source>Date: %1
+</source>
+ <translation>日期: %1
+</translation>
+ </message>
+ <message>
+ <source>Amount: %1
+</source>
+ <translation>金額: %1
+</translation>
+ </message>
+ <message>
+ <source>Type: %1
+</source>
+ <translation>種類: %1
+</translation>
+ </message>
+ <message>
+ <source>Label: %1
+</source>
+ <translation>標記: %1
+</translation>
+ </message>
+ <message>
+ <source>Address: %1
+</source>
+ <translation>位址: %1
+</translation>
+ </message>
+ <message>
+ <source>Sent transaction</source>
+ <translation>付款交易</translation>
+ </message>
+ <message>
+ <source>Incoming transaction</source>
+ <translation>收款交易</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>錢包&lt;b&gt;已加密&lt;/b&gt;並且&lt;b&gt;解鎖中&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>錢包&lt;b&gt;已加密&lt;/b&gt;並且&lt;b&gt;上鎖中&lt;/b&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>ClientModel</name>
+ <message>
+ <source>Network Alert</source>
+ <translation>網路警報</translation>
+ </message>
+</context>
+<context>
+ <name>CoinControlDialog</name>
+ <message>
+ <source>Coin Selection</source>
+ <translation>選擇錢幣</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>數目:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>位元組數:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>金額:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>優先度:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>手續費:</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>零散錢:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>計費後金額:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>找零金額:</translation>
+ </message>
+ <message>
+ <source>(un)select all</source>
+ <translation>全選或全不選</translation>
+ </message>
+ <message>
+ <source>Tree mode</source>
+ <translation>樹狀模式</translation>
+ </message>
+ <message>
+ <source>List mode</source>
+ <translation>列表模式</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>金額</translation>
+ </message>
+ <message>
+ <source>Received with label</source>
+ <translation>收款標記</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>收款位址</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>日期</translation>
+ </message>
+ <message>
+ <source>Confirmations</source>
+ <translation>確認次數</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>已確認</translation>
+ </message>
+ <message>
+ <source>Priority</source>
+ <translation>優先度</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>複製位址</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>複製標記</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>複製金額</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>複製交易識別碼</translation>
+ </message>
+ <message>
+ <source>Lock unspent</source>
+ <translation>鎖定不用</translation>
+ </message>
+ <message>
+ <source>Unlock unspent</source>
+ <translation>解鎖可用</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>複製數目</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>複製手續費</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>複製計費後金額</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>複製位元組數</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>複製優先度</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>複製零散金額</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>複製找零金額</translation>
+ </message>
+ <message>
+ <source>highest</source>
+ <translation>最高</translation>
+ </message>
+ <message>
+ <source>higher</source>
+ <translation>很高</translation>
+ </message>
+ <message>
+ <source>high</source>
+ <translation>高</translation>
+ </message>
+ <message>
+ <source>medium-high</source>
+ <translation>中高</translation>
+ </message>
+ <message>
+ <source>medium</source>
+ <translation>中等</translation>
+ </message>
+ <message>
+ <source>low-medium</source>
+ <translation>中低</translation>
+ </message>
+ <message>
+ <source>low</source>
+ <translation>低</translation>
+ </message>
+ <message>
+ <source>lower</source>
+ <translation>很低</translation>
+ </message>
+ <message>
+ <source>lowest</source>
+ <translation>最低</translation>
+ </message>
+ <message>
+ <source>(%1 locked)</source>
+ <translation>(鎖定 %1 枚)</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>無</translation>
+ </message>
+ <message>
+ <source>This label turns red if the transaction size is greater than 1000 bytes.</source>
+ <translation>當交易大小大於 1000 位元組時,文字會變紅色。</translation>
+ </message>
+ <message>
+ <source>This label turns red if the priority is smaller than "medium".</source>
+ <translation>當優先度低於「中等」時,文字會變紅色。</translation>
+ </message>
+ <message>
+ <source>This label turns red if any recipient receives an amount smaller than %1.</source>
+ <translation>當任何一個收款金額小於 %1 時,文字會變紅色。</translation>
+ </message>
+ <message>
+ <source>Can vary +/- %1 satoshi(s) per input.</source>
+ <translation>每組輸入可能有 +/- %1 個 satoshi 的誤差。</translation>
+ </message>
+ <message>
+ <source>yes</source>
+ <translation>是</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>否</translation>
+ </message>
+ <message>
+ <source>This means a fee of at least %1 per kB is required.</source>
+ <translation>表示每一千位元組(kB)需要至少 %1 的手續費。</translation>
+ </message>
+ <message>
+ <source>Can vary +/- 1 byte per input.</source>
+ <translation>每組輸入可能會誤差多或少 1 個位元組。</translation>
+ </message>
+ <message>
+ <source>Transactions with higher priority are more likely to get included into a block.</source>
+ <translation>優先度較高的交易比較有可能被接受放進區塊中。</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(無標記)</translation>
+ </message>
+ <message>
+ <source>change from %1 (%2)</source>
+ <translation>找零前是 %1 (%2)</translation>
+ </message>
+ <message>
+ <source>(change)</source>
+ <translation>(找零)</translation>
+ </message>
+</context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <source>Edit Address</source>
+ <translation>編輯位址</translation>
+ </message>
+ <message>
+ <source>&amp;Label</source>
+ <translation>標記</translation>
+ </message>
+ <message>
+ <source>The label associated with this address list entry</source>
+ <translation>跟這個位址簿項目關聯的標記</translation>
+ </message>
+ <message>
+ <source>The address associated with this address list entry. This can only be modified for sending addresses.</source>
+ <translation>跟這個位址簿項目關聯的位址。只有付款位址能被修改。</translation>
+ </message>
+ <message>
+ <source>&amp;Address</source>
+ <translation>位址</translation>
+ </message>
+ <message>
+ <source>New receiving address</source>
+ <translation>造新的收款位址</translation>
+ </message>
+ <message>
+ <source>New sending address</source>
+ <translation>造新的付款位址</translation>
+ </message>
+ <message>
+ <source>Edit receiving address</source>
+ <translation>編輯收款位址</translation>
+ </message>
+ <message>
+ <source>Edit sending address</source>
+ <translation>編輯付款位址</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>輸入的位址 %1 在位址簿中已經有了。</translation>
+ </message>
+ <message>
+ <source>The entered address "%1" is not a valid Bitcoin address.</source>
+ <translation>輸入的位址 %1 並不是有效的位元幣位址。</translation>
+ </message>
+ <message>
+ <source>Could not unlock wallet.</source>
+ <translation>沒辦法把錢包解鎖。</translation>
+ </message>
+ <message>
+ <source>New key generation failed.</source>
+ <translation>產生新的密鑰失敗了。</translation>
+ </message>
+</context>
+<context>
+ <name>FreespaceChecker</name>
+ <message>
+ <source>A new data directory will be created.</source>
+ <translation>就要產生新的資料目錄。</translation>
+ </message>
+ <message>
+ <source>name</source>
+ <translation>名稱</translation>
+ </message>
+ <message>
+ <source>Directory already exists. Add %1 if you intend to create a new directory here.</source>
+ <translation>已經有這個目錄了。如果你要在裡面造出新的目錄的話,請加上 %1.</translation>
+ </message>
+ <message>
+ <source>Path already exists, and is not a directory.</source>
+ <translation>已經有指定的路徑了,並且不是一個目錄。</translation>
+ </message>
+ <message>
+ <source>Cannot create data directory here.</source>
+ <translation>沒辦法在這裡造出資料目錄。</translation>
+ </message>
+</context>
+<context>
+ <name>HelpMessageDialog</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>位元幣核心</translation>
+ </message>
+ <message>
+ <source>version</source>
+ <translation>版本</translation>
+ </message>
+ <message>
+ <source>(%1-bit)</source>
+ <translation>(%1 位元)</translation>
+ </message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>關於位元幣核心</translation>
+ </message>
+ <message>
+ <source>Command-line options</source>
+ <translation>命令列選項</translation>
+ </message>
+ <message>
+ <source>Usage:</source>
+ <translation>用法:</translation>
+ </message>
+ <message>
+ <source>command-line options</source>
+ <translation>命令列選項</translation>
+ </message>
+</context>
+<context>
+ <name>Intro</name>
+ <message>
+ <source>Welcome</source>
+ <translation>歡迎</translation>
+ </message>
+ <message>
+ <source>Welcome to Bitcoin Core.</source>
+ <translation>歡迎使用位元幣核心</translation>
+ </message>
+ <message>
+ <source>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</source>
+ <translation>因為這是程式第一次啓動,你可以選擇位元幣核心儲存資料的地方。</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory.</source>
+ <translation>位元幣核心會下載並儲存一份位元幣區塊鏈的拷貝。至少有 %1GB 的資料會儲存到這個目錄中,並且還會持續增長。另外錢包資料也會儲存在這個目錄。</translation>
+ </message>
+ <message>
+ <source>Use the default data directory</source>
+ <translation>使用預設的資料目錄</translation>
+ </message>
+ <message>
+ <source>Use a custom data directory:</source>
+ <translation>使用自定的資料目錄:</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>位元幣核心</translation>
+ </message>
+ <message>
+ <source>Error: Specified data directory "%1" cannot be created.</source>
+ <translation>錯誤: 無法新增指定的資料目錄: %1</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>錯誤</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n GB of free space available</source>
+ <translation><numerusform>可用空間尚存 %n GB</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>(of %n GB needed)</source>
+ <translation><numerusform>(需要 %n GB)</numerusform></translation>
+ </message>
+</context>
+<context>
+ <name>OpenURIDialog</name>
+ <message>
+ <source>Open URI</source>
+ <translation>開啓 URI</translation>
+ </message>
+ <message>
+ <source>Open payment request from URI or file</source>
+ <translation>從 URI 或檔案開啟付款要求</translation>
+ </message>
+ <message>
+ <source>URI:</source>
+ <translation>URI:</translation>
+ </message>
+ <message>
+ <source>Select payment request file</source>
+ <translation>選擇付款要求資料檔</translation>
+ </message>
+ <message>
+ <source>Select payment request file to open</source>
+ <translation>選擇要開啟的付款要求資料檔</translation>
+ </message>
+</context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <source>Options</source>
+ <translation>選項</translation>
+ </message>
+ <message>
+ <source>&amp;Main</source>
+ <translation>主要</translation>
+ </message>
+ <message>
+ <source>Size of &amp;database cache</source>
+ <translation>資料庫快取大小</translation>
+ </message>
+ <message>
+ <source>MB</source>
+ <translation>MB (百萬位元組)</translation>
+ </message>
+ <message>
+ <source>Number of script &amp;verification threads</source>
+ <translation>指令碼驗證執行緒數目</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside</source>
+ <translation>接受外來連線</translation>
+ </message>
+ <message>
+ <source>Allow incoming connections</source>
+ <translation>接受外來連線</translation>
+ </message>
+ <message>
+ <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
+ <translation>代理伺服器的網際網路位址(像是 IPv4 的 127.0.0.1 或 IPv6 的 ::1)</translation>
+ </message>
+ <message>
+ <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source>
+ <translation>當視窗關閉時,把應用程式縮到最小,而不是結束。當勾選這個選項時,只能夠用選單中的結束來關掉應用程式。</translation>
+ </message>
+ <message>
+ <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source>
+ <translation>可以在這裡設定使用者介面的語言。這個設定在重啓位元幣核心後才會生效。</translation>
+ </message>
+ <message>
+ <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source>
+ <translation>在交易頁籤的情境選單出現的第三方(比如說區塊探索網站)網址連結。網址中的 %s 會被取代為交易的雜湊值。可以用直線符號 | 來分隔多個連結。</translation>
+ </message>
+ <message>
+ <source>Third party transaction URLs</source>
+ <translation>交易的第三方網址連結</translation>
+ </message>
+ <message>
+ <source>Active command-line options that override above options:</source>
+ <translation>從命令列取代掉以上設定的選項有:</translation>
+ </message>
+ <message>
+ <source>Reset all client options to default.</source>
+ <translation>重設所有客戶端軟體選項成預設值。</translation>
+ </message>
+ <message>
+ <source>&amp;Reset Options</source>
+ <translation>重設選項</translation>
+ </message>
+ <message>
+ <source>&amp;Network</source>
+ <translation>網路</translation>
+ </message>
+ <message>
+ <source>Automatically start Bitcoin Core after logging in to the system.</source>
+ <translation>在登入系統後自動啓動位元幣核心。</translation>
+ </message>
+ <message>
+ <source>&amp;Start Bitcoin Core on system login</source>
+ <translation>系統登入時啟動位元幣核心</translation>
+ </message>
+ <message>
+ <source>(0 = auto, &lt;0 = leave that many cores free)</source>
+ <translation>(0 表示程式自動決定,小於 0 表示保留處理器核心不用的數目)</translation>
+ </message>
+ <message>
+ <source>W&amp;allet</source>
+ <translation>錢包</translation>
+ </message>
+ <message>
+ <source>Expert</source>
+ <translation>專家</translation>
+ </message>
+ <message>
+ <source>Enable coin &amp;control features</source>
+ <translation>開啟錢幣控制功能</translation>
+ </message>
+ <message>
+ <source>If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.</source>
+ <translation>如果你關掉「可以花還沒確認的零錢」,那麼交易中找零的零錢就必須要等交易至少有一次確認後,才能夠使用。這也會影響餘額的計算方式。</translation>
+ </message>
+ <message>
+ <source>&amp;Spend unconfirmed change</source>
+ <translation>可以花還沒確認的零錢</translation>
+ </message>
+ <message>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>自動在路由器上開放位元幣的客戶端通訊埠。只有在你的路由器支援且開啓「通用即插即用」協定(UPnP)時才有作用。</translation>
+ </message>
+ <message>
+ <source>Map port using &amp;UPnP</source>
+ <translation>用 &amp;UPnP 設定通訊埠對應</translation>
+ </message>
+ <message>
+ <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
+ <translation>透過 SOCKS5 代理伺服器來連線到位元幣網路。</translation>
+ </message>
+ <message>
+ <source>&amp;Connect through SOCKS5 proxy (default proxy):</source>
+ <translation>透過 SOCKS5 代理伺服器連線(預設代理伺服器):</translation>
+ </message>
+ <message>
+ <source>Proxy &amp;IP:</source>
+ <translation>代理位址:</translation>
+ </message>
+ <message>
+ <source>&amp;Port:</source>
+ <translation>埠號:</translation>
+ </message>
+ <message>
+ <source>Port of the proxy (e.g. 9050)</source>
+ <translation>代理伺服器的通訊埠(像是 9050)</translation>
+ </message>
+ <message>
+ <source>&amp;Window</source>
+ <translation>視窗</translation>
+ </message>
+ <message>
+ <source>Show only a tray icon after minimizing the window.</source>
+ <translation>視窗縮到最小後只在通知區域顯示圖示。</translation>
+ </message>
+ <message>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>縮到最小到通知區域而不是工作列</translation>
+ </message>
+ <message>
+ <source>M&amp;inimize on close</source>
+ <translation>關閉時縮到最小</translation>
+ </message>
+ <message>
+ <source>&amp;Display</source>
+ <translation>顯示</translation>
+ </message>
+ <message>
+ <source>User Interface &amp;language:</source>
+ <translation>使用界面語言:</translation>
+ </message>
+ <message>
+ <source>&amp;Unit to show amounts in:</source>
+ <translation>金額顯示單位:</translation>
+ </message>
+ <message>
+ <source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
+ <translation>選擇操作界面和付款時,預設顯示金額的細分單位。</translation>
+ </message>
+ <message>
+ <source>Whether to show coin control features or not.</source>
+ <translation>是否要顯示錢幣控制功能。</translation>
+ </message>
+ <message>
+ <source>&amp;OK</source>
+ <translation>好</translation>
+ </message>
+ <message>
+ <source>&amp;Cancel</source>
+ <translation>取消</translation>
+ </message>
+ <message>
+ <source>default</source>
+ <translation>預設值</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>無</translation>
+ </message>
+ <message>
+ <source>Confirm options reset</source>
+ <translation>確認重設選項</translation>
+ </message>
+ <message>
+ <source>Client restart required to activate changes.</source>
+ <translation>需要重新啟動客戶端軟體來讓改變生效。</translation>
+ </message>
+ <message>
+ <source>Client will be shut down. Do you want to proceed?</source>
+ <translation>客戶端軟體就要關掉了。繼續做下去嗎?</translation>
+ </message>
+ <message>
+ <source>This change would require a client restart.</source>
+ <translation>這項改變需要重新啟動客戶端軟體。</translation>
+ </message>
+ <message>
+ <source>The supplied proxy address is invalid.</source>
+ <translation>提供的代理伺服器位址無效。</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <source>Form</source>
+ <translation>表單</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>顯示的資訊可能是過期的。跟位元幣網路的連線建立後,你的錢包會自動和網路同步,但是這個步驟還沒完成。</translation>
+ </message>
+ <message>
+ <source>Watch-only:</source>
+ <translation>只能看:</translation>
+ </message>
+ <message>
+ <source>Available:</source>
+ <translation>可用金額:</translation>
+ </message>
+ <message>
+ <source>Your current spendable balance</source>
+ <translation>目前可用餘額</translation>
+ </message>
+ <message>
+ <source>Pending:</source>
+ <translation>未定金額:</translation>
+ </message>
+ <message>
+ <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source>
+ <translation>還沒被確認的交易的總金額,可用餘額不包含這些金額</translation>
+ </message>
+ <message>
+ <source>Immature:</source>
+ <translation>未成熟金額:</translation>
+ </message>
+ <message>
+ <source>Mined balance that has not yet matured</source>
+ <translation>還沒成熟的開採金額</translation>
+ </message>
+ <message>
+ <source>Balances</source>
+ <translation>餘額</translation>
+ </message>
+ <message>
+ <source>Total:</source>
+ <translation>總金額:</translation>
+ </message>
+ <message>
+ <source>Your current total balance</source>
+ <translation>目前全部餘額</translation>
+ </message>
+ <message>
+ <source>Your current balance in watch-only addresses</source>
+ <translation>所有只能看位址的目前餘額</translation>
+ </message>
+ <message>
+ <source>Spendable:</source>
+ <translation>可支配:</translation>
+ </message>
+ <message>
+ <source>Recent transactions</source>
+ <translation>最近的交易</translation>
+ </message>
+ <message>
+ <source>Unconfirmed transactions to watch-only addresses</source>
+ <translation>所有只能看位址還沒確認的交易</translation>
+ </message>
+ <message>
+ <source>Mined balance in watch-only addresses that has not yet matured</source>
+ <translation>所有只能看位址還沒成熟的開採金額</translation>
+ </message>
+ <message>
+ <source>Current total balance in watch-only addresses</source>
+ <translation>所有只能看位址的目前全部餘額</translation>
+ </message>
+</context>
+<context>
+ <name>PaymentServer</name>
+ <message>
+ <source>URI handling</source>
+ <translation>URI 處理</translation>
+ </message>
+ <message>
+ <source>Invalid payment address %1</source>
+ <translation>無效的付款位址 %1</translation>
+ </message>
+ <message>
+ <source>Payment request rejected</source>
+ <translation>付款的要求被拒絕了</translation>
+ </message>
+ <message>
+ <source>Payment request network doesn't match client network.</source>
+ <translation>付款要求的網路類型跟客戶端不符。</translation>
+ </message>
+ <message>
+ <source>Payment request is not initialized.</source>
+ <translation>付款的要求沒有完成初始化。</translation>
+ </message>
+ <message>
+ <source>Requested payment amount of %1 is too small (considered dust).</source>
+ <translation>要求付款的金額 %1 太少(會被網路認為是沒必要的零散錢)。</translation>
+ </message>
+ <message>
+ <source>Payment request error</source>
+ <translation>要求付款時發生錯誤</translation>
+ </message>
+ <message>
+ <source>Cannot start bitcoin: click-to-pay handler</source>
+ <translation>沒辦法啟動 bitcoin 協議的按就付處理器</translation>
+ </message>
+ <message>
+ <source>Payment request fetch URL is invalid: %1</source>
+ <translation>取得付款要求的 URL 無效: %1</translation>
+ </message>
+ <message>
+ <source>URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source>
+ <translation>沒辦法解析 URI 位址!可能是因為位元幣位址無效,或是 URI 參數格式錯誤。</translation>
+ </message>
+ <message>
+ <source>Payment request file handling</source>
+ <translation>處理付款要求檔案</translation>
+ </message>
+ <message>
+ <source>Payment request file cannot be read! This can be caused by an invalid payment request file.</source>
+ <translation>沒辦法讀取付款要求檔案!可能是無效的檔案造成的。</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>付款的要求過期了。</translation>
+ </message>
+ <message>
+ <source>Unverified payment requests to custom payment scripts are unsupported.</source>
+ <translation>不支援含有自訂付款指令碼,且沒驗證過的付款要求。</translation>
+ </message>
+ <message>
+ <source>Invalid payment request.</source>
+ <translation>付款的要求無效。</translation>
+ </message>
+ <message>
+ <source>Refund from %1</source>
+ <translation>來自 %1 的退款</translation>
+ </message>
+ <message>
+ <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source>
+ <translation>付款要求 %1 過大 (%2 位元組, 上限 %3 位元組).</translation>
+ </message>
+ <message>
+ <source>Payment request DoS protection</source>
+ <translation>支付請求的分佈式阻斷服務攻擊DoS保護</translation>
+ </message>
+ <message>
+ <source>Error communicating with %1: %2</source>
+ <translation>跟 %1 通訊時發生錯誤: %2</translation>
+ </message>
+ <message>
+ <source>Payment request cannot be parsed!</source>
+ <translation>沒辦法解析付款要求內容!</translation>
+ </message>
+ <message>
+ <source>Bad response from server %1</source>
+ <translation>伺服器 %1 的回應有誤</translation>
+ </message>
+ <message>
+ <source>Payment acknowledged</source>
+ <translation>已確認付款</translation>
+ </message>
+ <message>
+ <source>Network request error</source>
+ <translation>發出要求時發生網路錯誤</translation>
+ </message>
+</context>
+<context>
+ <name>PeerTableModel</name>
+ <message>
+ <source>User Agent</source>
+ <translation>使用者代理</translation>
+ </message>
+ <message>
+ <source>Node/Service</source>
+ <translation>節點/服務</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Ping 時間</translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>金額</translation>
+ </message>
+ <message>
+ <source>Enter a Bitcoin address (e.g. %1)</source>
+ <translation>輸入位元幣位址 (比如說 %1)</translation>
+ </message>
+ <message>
+ <source>%1 d</source>
+ <translation>%1 天</translation>
+ </message>
+ <message>
+ <source>%1 h</source>
+ <translation>%1 小時</translation>
+ </message>
+ <message>
+ <source>%1 m</source>
+ <translation>%1 分鐘</translation>
+ </message>
+ <message>
+ <source>%1 s</source>
+ <translation>%1 秒</translation>
+ </message>
+ <message>
+ <source>None</source>
+ <translation>無</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>未知</translation>
+ </message>
+ <message>
+ <source>%1 ms</source>
+ <translation>%1 毫秒</translation>
+ </message>
+</context>
+<context>
+ <name>QRImageWidget</name>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>儲存圖片...</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Image</source>
+ <translation>複製圖片</translation>
+ </message>
+ <message>
+ <source>Save QR Code</source>
+ <translation>儲存 QR Code</translation>
+ </message>
+ <message>
+ <source>PNG Image (*.png)</source>
+ <translation>PNG 圖檔(*.png)</translation>
+ </message>
+</context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <source>Client name</source>
+ <translation>客戶端軟體名稱</translation>
+ </message>
+ <message>
+ <source>N/A</source>
+ <translation>未知</translation>
+ </message>
+ <message>
+ <source>Client version</source>
+ <translation>客戶端軟體版本</translation>
+ </message>
+ <message>
+ <source>&amp;Information</source>
+ <translation>資訊</translation>
+ </message>
+ <message>
+ <source>Debug window</source>
+ <translation>除錯視窗</translation>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>普通</translation>
+ </message>
+ <message>
+ <source>Using OpenSSL version</source>
+ <translation>使用的 OpenSSL 版本</translation>
+ </message>
+ <message>
+ <source>Using BerkeleyDB version</source>
+ <translation>使用 BerkeleyDB 版本</translation>
+ </message>
+ <message>
+ <source>Startup time</source>
+ <translation>啓動時間</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>網路</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>名稱</translation>
+ </message>
+ <message>
+ <source>Number of connections</source>
+ <translation>連線數</translation>
+ </message>
+ <message>
+ <source>Block chain</source>
+ <translation>區塊鏈</translation>
+ </message>
+ <message>
+ <source>Current number of blocks</source>
+ <translation>目前區塊數</translation>
+ </message>
+ <message>
+ <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source>
+ <translation>從目前的資料目錄下開啓位元幣核心的除錯紀錄檔。當紀錄檔很大時,可能會花好幾秒的時間。</translation>
+ </message>
+ <message>
+ <source>Received</source>
+ <translation>收款</translation>
+ </message>
+ <message>
+ <source>Sent</source>
+ <translation>付款</translation>
+ </message>
+ <message>
+ <source>&amp;Peers</source>
+ <translation>節點</translation>
+ </message>
+ <message>
+ <source>Select a peer to view detailed information.</source>
+ <translation>選一個節點來看詳細資訊</translation>
+ </message>
+ <message>
+ <source>Direction</source>
+ <translation>方向</translation>
+ </message>
+ <message>
+ <source>Version</source>
+ <translation>版本</translation>
+ </message>
+ <message>
+ <source>User Agent</source>
+ <translation>使用者代理</translation>
+ </message>
+ <message>
+ <source>Services</source>
+ <translation>服務</translation>
+ </message>
+ <message>
+ <source>Starting Height</source>
+ <translation>起始高度</translation>
+ </message>
+ <message>
+ <source>Sync Height</source>
+ <translation>同步高度</translation>
+ </message>
+ <message>
+ <source>Ban Score</source>
+ <translation>惡劣分數</translation>
+ </message>
+ <message>
+ <source>Connection Time</source>
+ <translation>連線時間</translation>
+ </message>
+ <message>
+ <source>Last Send</source>
+ <translation>最近送出</translation>
+ </message>
+ <message>
+ <source>Last Receive</source>
+ <translation>最近收到</translation>
+ </message>
+ <message>
+ <source>Bytes Sent</source>
+ <translation>送出位元組</translation>
+ </message>
+ <message>
+ <source>Bytes Received</source>
+ <translation>收到位元組</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Ping 時間</translation>
+ </message>
+ <message>
+ <source>Time Offset</source>
+ <translation>時間差</translation>
+ </message>
+ <message>
+ <source>Last block time</source>
+ <translation>最近區塊時間</translation>
+ </message>
+ <message>
+ <source>&amp;Open</source>
+ <translation>開啓</translation>
+ </message>
+ <message>
+ <source>&amp;Console</source>
+ <translation>主控台</translation>
+ </message>
+ <message>
+ <source>&amp;Network Traffic</source>
+ <translation>網路流量</translation>
+ </message>
+ <message>
+ <source>&amp;Clear</source>
+ <translation>清掉</translation>
+ </message>
+ <message>
+ <source>Totals</source>
+ <translation>總計</translation>
+ </message>
+ <message>
+ <source>In:</source>
+ <translation>輸入:</translation>
+ </message>
+ <message>
+ <source>Out:</source>
+ <translation>輸出:</translation>
+ </message>
+ <message>
+ <source>Build date</source>
+ <translation>建置日期</translation>
+ </message>
+ <message>
+ <source>Debug log file</source>
+ <translation>除錯紀錄檔</translation>
+ </message>
+ <message>
+ <source>Clear console</source>
+ <translation>清主控台</translation>
+ </message>
+ <message>
+ <source>Welcome to the Bitcoin Core RPC console.</source>
+ <translation>歡迎使用位元幣核心 RPC 主控台。</translation>
+ </message>
+ <message>
+ <source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
+ <translation>請用上下游標鍵來瀏覽先前指令的紀錄,並用 &lt;b&gt;Ctrl-L&lt;/b&gt; 來清畫面。</translation>
+ </message>
+ <message>
+ <source>Type &lt;b&gt;help&lt;/b&gt; for an overview of available commands.</source>
+ <translation>請打 &lt;b&gt;help&lt;/b&gt; 來看可用指令的簡介。</translation>
+ </message>
+ <message>
+ <source>%1 B</source>
+ <translation>%1 B (位元組)</translation>
+ </message>
+ <message>
+ <source>%1 KB</source>
+ <translation>%1 KB (千位元組)</translation>
+ </message>
+ <message>
+ <source>%1 MB</source>
+ <translation>%1 MB (百萬位元組)</translation>
+ </message>
+ <message>
+ <source>%1 GB</source>
+ <translation>%1 GB (十億位元組)</translation>
+ </message>
+ <message>
+ <source>via %1</source>
+ <translation>經由 %1</translation>
+ </message>
+ <message>
+ <source>never</source>
+ <translation>沒有過</translation>
+ </message>
+ <message>
+ <source>Inbound</source>
+ <translation>進來</translation>
+ </message>
+ <message>
+ <source>Outbound</source>
+ <translation>出去</translation>
+ </message>
+ <message>
+ <source>Unknown</source>
+ <translation>不明</translation>
+ </message>
+ <message>
+ <source>Fetching...</source>
+ <translation>正在擷取中...</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveCoinsDialog</name>
+ <message>
+ <source>&amp;Amount:</source>
+ <translation>金額:</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>標記:</translation>
+ </message>
+ <message>
+ <source>&amp;Message:</source>
+ <translation>訊息:</translation>
+ </message>
+ <message>
+ <source>Reuse one of the previously used receiving addresses. Reusing addresses has security and privacy issues. Do not use this unless re-generating a payment request made before.</source>
+ <translation>重複使用先前使用過的收款位址。重複使用位址會有安全和隱私方面的問題。除非是要重新產生先前的付款要求,不然請不要使用。</translation>
+ </message>
+ <message>
+ <source>R&amp;euse an existing receiving address (not recommended)</source>
+ <translation>重複使用現有的收款位址(不建議)</translation>
+ </message>
+ <message>
+ <source>An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network.</source>
+ <translation>附加在付款要求中的訊息,可以不填,打開要求內容時會顯示。注意: 這個訊息不會隨著付款送到位元幣網路上。</translation>
+ </message>
+ <message>
+ <source>An optional label to associate with the new receiving address.</source>
+ <translation>跟新收款位址關聯的標記,可以不填。</translation>
+ </message>
+ <message>
+ <source>Use this form to request payments. All fields are &lt;b&gt;optional&lt;/b&gt;.</source>
+ <translation>請用這份表單來要求付款。所有欄位都&lt;b&gt;可以不填&lt;/b&gt;。</translation>
+ </message>
+ <message>
+ <source>An optional amount to request. Leave this empty or zero to not request a specific amount.</source>
+ <translation>要求付款的金額,可以不填。不確定金額時可以留白或是填零。</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>把表單中的所有欄位清空。</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation>清空</translation>
+ </message>
+ <message>
+ <source>Requested payments history</source>
+ <translation>先前要求付款的記錄</translation>
+ </message>
+ <message>
+ <source>&amp;Request payment</source>
+ <translation>要求付款</translation>
+ </message>
+ <message>
+ <source>Show the selected request (does the same as double clicking an entry)</source>
+ <translation>顯示選擇的要求內容(效果跟按它兩下一樣)</translation>
+ </message>
+ <message>
+ <source>Show</source>
+ <translation>顯示</translation>
+ </message>
+ <message>
+ <source>Remove the selected entries from the list</source>
+ <translation>從列表中刪掉選擇的項目</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>刪掉</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>複製標記</translation>
+ </message>
+ <message>
+ <source>Copy message</source>
+ <translation>複製訊息</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>複製金額</translation>
+ </message>
+</context>
+<context>
+ <name>ReceiveRequestDialog</name>
+ <message>
+ <source>QR Code</source>
+ <translation>QR Code</translation>
+ </message>
+ <message>
+ <source>Copy &amp;URI</source>
+ <translation>複製 URI</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Address</source>
+ <translation>複製位址</translation>
+ </message>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>儲存圖片...</translation>
+ </message>
+ <message>
+ <source>Request payment to %1</source>
+ <translation>付款給 %1 的要求</translation>
+ </message>
+ <message>
+ <source>Payment information</source>
+ <translation>付款資訊</translation>
+ </message>
+ <message>
+ <source>URI</source>
+ <translation>URI</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>位址</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>金額</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>標記</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>訊息</translation>
+ </message>
+ <message>
+ <source>Resulting URI too long, try to reduce the text for label / message.</source>
+ <translation>產生的 URI 過長,請試著縮短標記或訊息的文字內容。</translation>
+ </message>
+ <message>
+ <source>Error encoding URI into QR Code.</source>
+ <translation>把 URI 編碼成 QR Code 時發生錯誤。</translation>
+ </message>
+</context>
+<context>
+ <name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>日期</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>標記</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>訊息</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>金額</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(無標記)</translation>
+ </message>
+ <message>
+ <source>(no message)</source>
+ <translation>(無訊息)</translation>
+ </message>
+ <message>
+ <source>(no amount)</source>
+ <translation>(無金額)</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>付款</translation>
+ </message>
+ <message>
+ <source>Coin Control Features</source>
+ <translation>錢幣控制功能</translation>
+ </message>
+ <message>
+ <source>Inputs...</source>
+ <translation>輸入...</translation>
+ </message>
+ <message>
+ <source>automatically selected</source>
+ <translation>自動選擇</translation>
+ </message>
+ <message>
+ <source>Insufficient funds!</source>
+ <translation>累計金額不足!</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>數目:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>位元組數:</translation>
+ </message>
+ <message>
+ <source>Amount:</source>
+ <translation>金額:</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>優先度:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>手續費:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>計費後金額:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>找零金額:</translation>
+ </message>
+ <message>
+ <source>If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address.</source>
+ <translation>如果這項有打開,但是找零位址是空的或無效,那麼找零的錢會送到一個新產生的位址去。</translation>
+ </message>
+ <message>
+ <source>Custom change address</source>
+ <translation>自定找零位址</translation>
+ </message>
+ <message>
+ <source>Transaction Fee:</source>
+ <translation>交易手續費:</translation>
+ </message>
+ <message>
+ <source>Choose...</source>
+ <translation>選項...</translation>
+ </message>
+ <message>
+ <source>collapse fee-settings</source>
+ <translation>展開手續費設定</translation>
+ </message>
+ <message>
+ <source>per kilobyte</source>
+ <translation>每千位元組</translation>
+ </message>
+ <message>
+ <source>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "total at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source>
+ <translation>如果自訂手續費設定為 1000 satoshi, 而交易資料大小只有 250 個位元組的話,那麽選擇「每千位元組」就只會付 250 satoshi 的手續費,換做選「總共至少」就會付 1000 satoshi. 但是如果交易資料大小超過一千個位元組,那麽兩者都是每千位元組的費用。</translation>
+ </message>
+ <message>
+ <source>Hide</source>
+ <translation>隱藏</translation>
+ </message>
+ <message>
+ <source>total at least</source>
+ <translation>總共最少</translation>
+ </message>
+ <message>
+ <source>Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process.</source>
+ <translation>當交易量少於區塊可容納的空間時,只付最低手續費不會有什麽問題。但是當交易量的需求成長到超過整體網路可以處理的量時,可能會造成一筆一直不會被確認的交易。</translation>
+ </message>
+ <message>
+ <source>(read the tooltip)</source>
+ <translation>(請看提示)</translation>
+ </message>
+ <message>
+ <source>Recommended:</source>
+ <translation>建議值:</translation>
+ </message>
+ <message>
+ <source>Custom:</source>
+ <translation>自訂:</translation>
+ </message>
+ <message>
+ <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source>
+ <translation>(手續費智慧演算法還沒準備好。通常都要等幾個區塊才行...)</translation>
+ </message>
+ <message>
+ <source>Confirmation time:</source>
+ <translation>確認時間:</translation>
+ </message>
+ <message>
+ <source>normal</source>
+ <translation>正常</translation>
+ </message>
+ <message>
+ <source>fast</source>
+ <translation>快速</translation>
+ </message>
+ <message>
+ <source>Send as zero-fee transaction if possible</source>
+ <translation>盡可能送不用付手續費的交易</translation>
+ </message>
+ <message>
+ <source>(confirmation may take longer)</source>
+ <translation>(確認時間可能拉長)</translation>
+ </message>
+ <message>
+ <source>Send to multiple recipients at once</source>
+ <translation>一次付給多個收款人</translation>
+ </message>
+ <message>
+ <source>Add &amp;Recipient</source>
+ <translation>增加收款人</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>把表單中的所有欄位清空。</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>零散錢:</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>全部清掉</translation>
+ </message>
+ <message>
+ <source>Balance:</source>
+ <translation>餘額:</translation>
+ </message>
+ <message>
+ <source>Confirm the send action</source>
+ <translation>確認付款動作</translation>
+ </message>
+ <message>
+ <source>S&amp;end</source>
+ <translation>付款</translation>
+ </message>
+ <message>
+ <source>Confirm send coins</source>
+ <translation>確認付款金額</translation>
+ </message>
+ <message>
+ <source>%1 to %2</source>
+ <translation>%1 給 %2</translation>
+ </message>
+ <message>
+ <source>Copy quantity</source>
+ <translation>複製數目</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>複製金額</translation>
+ </message>
+ <message>
+ <source>Copy fee</source>
+ <translation>複製手續費</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>複製計費後金額</translation>
+ </message>
+ <message>
+ <source>Copy bytes</source>
+ <translation>複製位元組數</translation>
+ </message>
+ <message>
+ <source>Copy priority</source>
+ <translation>複製優先度</translation>
+ </message>
+ <message>
+ <source>Copy change</source>
+ <translation>複製找零金額</translation>
+ </message>
+ <message>
+ <source>or</source>
+ <translation>或</translation>
+ </message>
+ <message>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>付款金額必須大於零。</translation>
+ </message>
+ <message>
+ <source>The amount exceeds your balance.</source>
+ <translation>金額超過餘額了。</translation>
+ </message>
+ <message>
+ <source>The total exceeds your balance when the %1 transaction fee is included.</source>
+ <translation>包含 %1 的交易手續費後,總金額超過你的餘額了。</translation>
+ </message>
+ <message>
+ <source>Transaction creation failed!</source>
+ <translation>製造交易失敗了!</translation>
+ </message>
+ <message>
+ <source>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.</source>
+ <translation>交易被拒絕了!有時候會發生這種錯誤,是因為你錢包中的一些錢已經被花掉了。比如說你複製了錢包檔 wallet.dat, 然後用複製的錢包花掉了錢,你現在所用的原來的錢包中,卻沒有那筆錢已經花掉的紀錄。</translation>
+ </message>
+ <message>
+ <source>A fee higher than %1 is considered an absurdly high fee.</source>
+ <translation>高於 %1 的手續費會被認為是不合理。</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>付款的要求過期了。</translation>
+ </message>
+ <message>
+ <source>Pay only the minimum fee of %1</source>
+ <translation>只付最低手續費 %1</translation>
+ </message>
+ <message>
+ <source>Total Amount %1&lt;span style='font-size:10pt;font-weight:normal;'&gt;&lt;br /&gt;(=%2)&lt;/span&gt;</source>
+ <translation>總金額 %1&lt;span style='font-size:10pt;font-weight:normal;'&gt;&lt;br /&gt;(=%2)&lt;/span&gt;</translation>
+ </message>
+ <message>
+ <source>The recipient address is not valid. Please recheck.</source>
+ <translation>收款位址無效。請再檢查看看。</translation>
+ </message>
+ <message>
+ <source>Duplicate address found: addresses should only be used once each.</source>
+ <translation>發現有重複的位址: 每個位址只能出現一次。</translation>
+ </message>
+ <message>
+ <source>Warning: Invalid Bitcoin address</source>
+ <translation>警告: 位元幣位址無效</translation>
+ </message>
+ <message>
+ <source>(no label)</source>
+ <translation>(無標記)</translation>
+ </message>
+ <message>
+ <source>Warning: Unknown change address</source>
+ <translation>警告: 不明的找零位址</translation>
+ </message>
+ <message>
+ <source>Copy dust</source>
+ <translation>複製零散金額</translation>
+ </message>
+ <message>
+ <source>Are you sure you want to send?</source>
+ <translation>你確定要付錢出去嗎?</translation>
+ </message>
+ <message>
+ <source>added as transaction fee</source>
+ <translation>加做交易手續費</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <source>A&amp;mount:</source>
+ <translation>金額:</translation>
+ </message>
+ <message>
+ <source>Pay &amp;To:</source>
+ <translation>付給:</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>請輸入這個位址的標記來把它加進位址簿中</translation>
+ </message>
+ <message>
+ <source>&amp;Label:</source>
+ <translation>標記:</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>選擇先前使用過的位址</translation>
+ </message>
+ <message>
+ <source>This is a normal payment.</source>
+ <translation>這是一筆正常的付款。</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to send the payment to</source>
+ <translation>接收付款的位元幣位址</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>貼上剪貼簿裡的位址</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Remove this entry</source>
+ <translation>刪掉這個項目</translation>
+ </message>
+ <message>
+ <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source>
+ <translation>手續費會從要付款出去的金額中扣掉。因此收款人會收到比輸入的金額還要少的位元幣。如果有多個收款人的話,手續費會平均分配來扣除。</translation>
+ </message>
+ <message>
+ <source>S&amp;ubtract fee from amount</source>
+ <translation>從付款金額減去手續費</translation>
+ </message>
+ <message>
+ <source>Message:</source>
+ <translation>訊息:</translation>
+ </message>
+ <message>
+ <source>This is an unauthenticated payment request.</source>
+ <translation>這是個沒驗證過的付款要求。</translation>
+ </message>
+ <message>
+ <source>This is an authenticated payment request.</source>
+ <translation>這是個已驗證的付款要求。</translation>
+ </message>
+ <message>
+ <source>Enter a label for this address to add it to the list of used addresses</source>
+ <translation>請輸入這個位址的標記,來把它加進去已使用過位址的清單。</translation>
+ </message>
+ <message>
+ <source>A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network.</source>
+ <translation>附加在位元幣付款協議 URI 中的訊息,會和交易內容一起存起來,給你自己做參考。注意: 這個訊息不會送到位元幣網路上。</translation>
+ </message>
+ <message>
+ <source>Pay To:</source>
+ <translation>付給:</translation>
+ </message>
+ <message>
+ <source>Memo:</source>
+ <translation>備註:</translation>
+ </message>
+</context>
+<context>
+ <name>ShutdownWindow</name>
+ <message>
+ <source>Bitcoin Core is shutting down...</source>
+ <translation>正在關閉位元幣核心中...</translation>
+ </message>
+ <message>
+ <source>Do not shut down the computer until this window disappears.</source>
+ <translation> 在這個視窗不見以前,請不要關掉電腦。</translation>
+ </message>
+</context>
+<context>
+ <name>SignVerifyMessageDialog</name>
+ <message>
+ <source>Signatures - Sign / Verify a Message</source>
+ <translation>簽章 - 簽署或驗證訊息</translation>
+ </message>
+ <message>
+ <source>&amp;Sign Message</source>
+ <translation>簽署訊息</translation>
+ </message>
+ <message>
+ <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source>
+ <translation>你可以用自己的位址簽署訊息或合約,來證明你可以從該位址收款。但是請小心,不要簽署語意含糊不清,或隨機產生的內容,因為釣魚式詐騙可能會用騙你簽署的手法來冒充是你。只有在語句中的細節你都同意時才簽署。</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to sign the message with</source>
+ <translation>用來簽署訊息的位元幣位址</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>選擇先前使用過的位址</translation>
+ </message>
+ <message>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <source>Paste address from clipboard</source>
+ <translation>貼上剪貼簿裡的位址</translation>
+ </message>
+ <message>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <source>Enter the message you want to sign here</source>
+ <translation>請在這裡輸入你想簽署的訊息</translation>
+ </message>
+ <message>
+ <source>Signature</source>
+ <translation>簽章</translation>
+ </message>
+ <message>
+ <source>Copy the current signature to the system clipboard</source>
+ <translation>複製目前的簽章到系統剪貼簿</translation>
+ </message>
+ <message>
+ <source>Sign the message to prove you own this Bitcoin address</source>
+ <translation>簽署這個訊息來證明這個位元幣位址是你的</translation>
+ </message>
+ <message>
+ <source>Sign &amp;Message</source>
+ <translation>簽署訊息</translation>
+ </message>
+ <message>
+ <source>Reset all sign message fields</source>
+ <translation>重設所有訊息簽署欄位</translation>
+ </message>
+ <message>
+ <source>Clear &amp;All</source>
+ <translation>全部清掉</translation>
+ </message>
+ <message>
+ <source>&amp;Verify Message</source>
+ <translation>驗證訊息</translation>
+ </message>
+ <message>
+ <source>Enter the receiver's 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. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source>
+ <translation>請在下面輸入收款人的位址,訊息(請確定完整複製了所包含的換行,空格,跳位符號等等),以及簽章,來驗證這個訊息。請小心,除了訊息內容以外,不要對簽章本身過度解讀,以避免被用「中間人攻擊法」詐騙。請注意,通過驗證的簽章只能證明簽章人確實可以從該位址收款,不能證明任何交易中的付款人身份!</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address the message was signed with</source>
+ <translation>簽署這個訊息的位元幣位址</translation>
+ </message>
+ <message>
+ <source>Verify the message to ensure it was signed with the specified Bitcoin address</source>
+ <translation>驗證這個訊息來確定是用指定的位元幣位址簽署的</translation>
+ </message>
+ <message>
+ <source>Verify &amp;Message</source>
+ <translation>驗證訊息</translation>
+ </message>
+ <message>
+ <source>Reset all verify message fields</source>
+ <translation>重設所有訊息驗證欄位</translation>
+ </message>
+ <message>
+ <source>Click "Sign Message" to generate signature</source>
+ <translation>請按一下「簽署訊息」來產生簽章</translation>
+ </message>
+ <message>
+ <source>The entered address is invalid.</source>
+ <translation>輸入的位址無效。</translation>
+ </message>
+ <message>
+ <source>Please check the address and try again.</source>
+ <translation>請檢查位址是否正確後再試一次。</translation>
+ </message>
+ <message>
+ <source>The entered address does not refer to a key.</source>
+ <translation>輸入的位址沒有對應到你的任何密鑰。</translation>
+ </message>
+ <message>
+ <source>Wallet unlock was cancelled.</source>
+ <translation>錢包解鎖已取消。</translation>
+ </message>
+ <message>
+ <source>Private key for the entered address is not available.</source>
+ <translation>沒有對應輸入位址的密鑰。</translation>
+ </message>
+ <message>
+ <source>Message signing failed.</source>
+ <translation>訊息簽署失敗。</translation>
+ </message>
+ <message>
+ <source>Message signed.</source>
+ <translation>訊息簽署好了。</translation>
+ </message>
+ <message>
+ <source>The signature could not be decoded.</source>
+ <translation>沒辦法把這個簽章解碼。</translation>
+ </message>
+ <message>
+ <source>Please check the signature and try again.</source>
+ <translation>請檢查簽章是否正確後再試一次。</translation>
+ </message>
+ <message>
+ <source>The signature did not match the message digest.</source>
+ <translation>這個簽章跟訊息的數位摘要不符。</translation>
+ </message>
+ <message>
+ <source>Message verification failed.</source>
+ <translation>訊息驗證失敗。</translation>
+ </message>
+ <message>
+ <source>Message verified.</source>
+ <translation>訊息驗證沒錯。</translation>
+ </message>
+</context>
+<context>
+ <name>SplashScreen</name>
+ <message>
+ <source>Bitcoin Core</source>
+ <translation>位元幣核心</translation>
+ </message>
+ <message>
+ <source>The Bitcoin Core developers</source>
+ <translation>位元幣核心開發人員</translation>
+ </message>
+ <message>
+ <source>[testnet]</source>
+ <translation>[testnet]</translation>
+ </message>
+</context>
+<context>
+ <name>TrafficGraphWidget</name>
+ <message>
+ <source>KB/s</source>
+ <translation>KB/s</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <source>Open until %1</source>
+ <translation>到 %1 前可修改</translation>
+ </message>
+ <message>
+ <source>conflicted</source>
+ <translation>有衝突</translation>
+ </message>
+ <message>
+ <source>%1/offline</source>
+ <translation>%1 次/離線中</translation>
+ </message>
+ <message>
+ <source>%1/unconfirmed</source>
+ <translation>%1 次/未確認</translation>
+ </message>
+ <message>
+ <source>%1 confirmations</source>
+ <translation>確認 %1 次</translation>
+ </message>
+ <message>
+ <source>Status</source>
+ <translation>狀態</translation>
+ </message>
+ <message numerus="yes">
+ <source>, broadcast through %n node(s)</source>
+ <translation><numerusform>,已公告給 %n 個節點</numerusform></translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>日期</translation>
+ </message>
+ <message>
+ <source>Source</source>
+ <translation>來源</translation>
+ </message>
+ <message>
+ <source>Generated</source>
+ <translation>生產出來</translation>
+ </message>
+ <message>
+ <source>From</source>
+ <translation>來源</translation>
+ </message>
+ <message>
+ <source>To</source>
+ <translation>目的</translation>
+ </message>
+ <message>
+ <source>own address</source>
+ <translation>自己的位址</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>只能看</translation>
+ </message>
+ <message>
+ <source>label</source>
+ <translation>標記</translation>
+ </message>
+ <message>
+ <source>Credit</source>
+ <translation>入帳</translation>
+ </message>
+ <message numerus="yes">
+ <source>matures in %n more block(s)</source>
+ <translation><numerusform>再等 %n 個區塊生出來後成熟</numerusform></translation>
+ </message>
+ <message>
+ <source>not accepted</source>
+ <translation>不被接受</translation>
+ </message>
+ <message>
+ <source>Debit</source>
+ <translation>出帳</translation>
+ </message>
+ <message>
+ <source>Total debit</source>
+ <translation>出帳總額</translation>
+ </message>
+ <message>
+ <source>Total credit</source>
+ <translation>入帳總額</translation>
+ </message>
+ <message>
+ <source>Transaction fee</source>
+ <translation>交易手續費</translation>
+ </message>
+ <message>
+ <source>Net amount</source>
+ <translation>淨額</translation>
+ </message>
+ <message>
+ <source>Message</source>
+ <translation>訊息</translation>
+ </message>
+ <message>
+ <source>Comment</source>
+ <translation>附註</translation>
+ </message>
+ <message>
+ <source>Transaction ID</source>
+ <translation>交易識別碼</translation>
+ </message>
+ <message>
+ <source>Merchant</source>
+ <translation>商家</translation>
+ </message>
+ <message>
+ <source>Generated coins must mature %1 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.</source>
+ <translation>生產出來的錢要再等 %1 個區塊生出來後才成熟可以用。當區塊生產出來時會公布到網路上,來被加進區塊鏈。如果加失敗了,狀態就會變成「不被接受」,而且不能夠花。如果在你生產出區塊的幾秒鐘內,也有其他節點生產出來的話,就有可能會發生這種情形。</translation>
+ </message>
+ <message>
+ <source>Debug information</source>
+ <translation>除錯資訊</translation>
+ </message>
+ <message>
+ <source>Transaction</source>
+ <translation>交易</translation>
+ </message>
+ <message>
+ <source>Inputs</source>
+ <translation>輸入</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>金額</translation>
+ </message>
+ <message>
+ <source>true</source>
+ <translation>是</translation>
+ </message>
+ <message>
+ <source>false</source>
+ <translation>否</translation>
+ </message>
+ <message>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>,還沒成功公告出去</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>到下 %n 個區塊生出來前可修改</numerusform></translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>未知</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <source>Transaction details</source>
+ <translation>交易明細</translation>
+ </message>
+ <message>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>這個版面顯示這次交易的詳細說明</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>日期</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>種類</translation>
+ </message>
+ <message>
+ <source>Immature (%1 confirmations, will be available after %2)</source>
+ <translation>未成熟(確認 %1 次,會在 %2 次後可用)</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>到下 %n 個區塊生出來前可修改</numerusform></translation>
+ </message>
+ <message>
+ <source>Open until %1</source>
+ <translation>到 %1 前可修改</translation>
+ </message>
+ <message>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>已確認(%1 次)</translation>
+ </message>
+ <message>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>沒有其他節點收到這個區塊,也許它不會被接受!</translation>
+ </message>
+ <message>
+ <source>Generated but not accepted</source>
+ <translation>生產出來但是不被接受</translation>
+ </message>
+ <message>
+ <source>Offline</source>
+ <translation>離線中</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>標記</translation>
+ </message>
+ <message>
+ <source>Unconfirmed</source>
+ <translation>未確認</translation>
+ </message>
+ <message>
+ <source>Confirming (%1 of %2 recommended confirmations)</source>
+ <translation>確認中(已經 %1 次,建議至少 %2 次)</translation>
+ </message>
+ <message>
+ <source>Conflicted</source>
+ <translation>有衝突</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>收款在</translation>
+ </message>
+ <message>
+ <source>Received from</source>
+ <translation>收款自</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>付款給</translation>
+ </message>
+ <message>
+ <source>Payment to yourself</source>
+ <translation>付給自己</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>開採所得</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>只能看</translation>
+ </message>
+ <message>
+ <source>(n/a)</source>
+ <translation>(不適用)</translation>
+ </message>
+ <message>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>交易狀態。把游標停在欄位上會顯示確認次數。</translation>
+ </message>
+ <message>
+ <source>Date and time that the transaction was received.</source>
+ <translation>收到交易的日期和時間。</translation>
+ </message>
+ <message>
+ <source>Type of transaction.</source>
+ <translation>交易的種類。</translation>
+ </message>
+ <message>
+ <source>Whether or not a watch-only address is involved in this transaction.</source>
+ <translation>不論如何有一個只能觀看的地只有參與這次的交易</translation>
+ </message>
+ <message>
+ <source>User-defined intent/purpose of the transaction.</source>
+ <translation>使用者定義的交易動機或理由。</translation>
+ </message>
+ <message>
+ <source>Amount removed from or added to balance.</source>
+ <translation>要減掉或加進餘額的金額。</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <source>All</source>
+ <translation>全部</translation>
+ </message>
+ <message>
+ <source>Today</source>
+ <translation>今天</translation>
+ </message>
+ <message>
+ <source>This week</source>
+ <translation>這星期</translation>
+ </message>
+ <message>
+ <source>This month</source>
+ <translation>這個月</translation>
+ </message>
+ <message>
+ <source>Last month</source>
+ <translation>上個月</translation>
+ </message>
+ <message>
+ <source>This year</source>
+ <translation>今年</translation>
+ </message>
+ <message>
+ <source>Range...</source>
+ <translation>指定範圍...</translation>
+ </message>
+ <message>
+ <source>Received with</source>
+ <translation>收款</translation>
+ </message>
+ <message>
+ <source>Sent to</source>
+ <translation>付款</translation>
+ </message>
+ <message>
+ <source>To yourself</source>
+ <translation>給自己</translation>
+ </message>
+ <message>
+ <source>Mined</source>
+ <translation>開採所得</translation>
+ </message>
+ <message>
+ <source>Other</source>
+ <translation>其它</translation>
+ </message>
+ <message>
+ <source>Enter address or label to search</source>
+ <translation>請輸入要搜尋的位址或標記</translation>
+ </message>
+ <message>
+ <source>Min amount</source>
+ <translation>最小金額</translation>
+ </message>
+ <message>
+ <source>Copy address</source>
+ <translation>複製位址</translation>
+ </message>
+ <message>
+ <source>Copy label</source>
+ <translation>複製標記</translation>
+ </message>
+ <message>
+ <source>Copy amount</source>
+ <translation>複製金額</translation>
+ </message>
+ <message>
+ <source>Copy transaction ID</source>
+ <translation>複製交易識別碼</translation>
+ </message>
+ <message>
+ <source>Edit label</source>
+ <translation>編輯標記</translation>
+ </message>
+ <message>
+ <source>Show transaction details</source>
+ <translation>顯示交易明細</translation>
+ </message>
+ <message>
+ <source>Export Transaction History</source>
+ <translation>匯出交易記錄</translation>
+ </message>
+ <message>
+ <source>Watch-only</source>
+ <translation>只能觀看的</translation>
+ </message>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>匯出失敗</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the transaction history to %1.</source>
+ <translation>儲存交易記錄到 %1 時發生錯誤。</translation>
+ </message>
+ <message>
+ <source>Exporting Successful</source>
+ <translation>匯出成功</translation>
+ </message>
+ <message>
+ <source>The transaction history was successfully saved to %1.</source>
+ <translation>交易記錄已經成功儲存到 %1 了。</translation>
+ </message>
+ <message>
+ <source>Comma separated file (*.csv)</source>
+ <translation>逗點分隔資料檔(*.csv)</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>已確認</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>日期</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>種類</translation>
+ </message>
+ <message>
+ <source>Label</source>
+ <translation>標記</translation>
+ </message>
+ <message>
+ <source>Address</source>
+ <translation>位址</translation>
+ </message>
+ <message>
+ <source>ID</source>
+ <translation>識別碼</translation>
+ </message>
+ <message>
+ <source>Range:</source>
+ <translation>範圍:</translation>
+ </message>
+ <message>
+ <source>to</source>
+ <translation>到</translation>
+ </message>
+</context>
+<context>
+ <name>UnitDisplayStatusBarControl</name>
+ <message>
+ <source>Unit to show amounts in. Click to select another unit.</source>
+ <translation>金額顯示單位。可以點選其他單位。</translation>
+ </message>
+</context>
+<context>
+ <name>WalletFrame</name>
+ <message>
+ <source>No wallet has been loaded.</source>
+ <translation>沒有載入錢包。</translation>
+ </message>
+</context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <source>Send Coins</source>
+ <translation>付款</translation>
+ </message>
+</context>
+<context>
+ <name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>匯出</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>把目前分頁的資料匯出存成檔案</translation>
+ </message>
+ <message>
+ <source>Backup Wallet</source>
+ <translation>備份錢包</translation>
+ </message>
+ <message>
+ <source>Wallet Data (*.dat)</source>
+ <translation>錢包資料檔(*.dat)</translation>
+ </message>
+ <message>
+ <source>Backup Failed</source>
+ <translation>備份失敗</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the wallet data to %1.</source>
+ <translation>儲存錢包資料到 %1 時發生錯誤。</translation>
+ </message>
+ <message>
+ <source>The wallet data was successfully saved to %1.</source>
+ <translation>錢包的資料已經成功儲存到 %1 了。</translation>
+ </message>
+ <message>
+ <source>Backup Successful</source>
+ <translation>備份成功</translation>
+ </message>
+</context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <source>Options:</source>
+ <translation>選項:</translation>
+ </message>
+ <message>
+ <source>Specify data directory</source>
+ <translation>指定資料目錄</translation>
+ </message>
+ <message>
+ <source>Connect to a node to retrieve peer addresses, and disconnect</source>
+ <translation>連線到某個節點來取得其它節點的位址,然後斷線</translation>
+ </message>
+ <message>
+ <source>Specify your own public address</source>
+ <translation>指定自己的公開位址</translation>
+ </message>
+ <message>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>接受指令列和 JSON-RPC 指令
+</translation>
+ </message>
+ <message>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>用護靈模式在背後執行並接受指令</translation>
+ </message>
+ <message>
+ <source>Use the test network</source>
+ <translation>使用測試網路</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
+ <translation>是否接受外來連線(預設值: 當沒有 -proxy 或 -connect 時為 1)</translation>
+ </message>
+ <message>
+ <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
+ <translation>和指定的位址繫結,並且一直在指定位址聽候連線。IPv6 請用 [主機]:通訊埠 這種格式</translation>
+ </message>
+ <message>
+ <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
+ <translation>清掉錢包裡的所有交易,並且在下次啟動時,使用 -rescan 來從區塊鏈中復原回來。</translation>
+ </message>
+ <message>
+ <source>Distributed under the MIT software license, see the accompanying file COPYING or &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</source>
+ <translation>這套軟體是依據 MIT 軟體授權條款散布,詳情請見附帶的 COPYING 檔案,或是以下網站: &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</translation>
+ </message>
+ <message>
+ <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
+ <translation>當錢包有交易改變時要執行的指令(指令中的 %s 會被取代成交易識別碼)</translation>
+ </message>
+ <message>
+ <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source>
+ <translation>一次錢包交易允許付出最高的總手續費;設定太低的話,可能會無法進行資料量大的交易(預設值: %s)</translation>
+ </message>
+ <message>
+ <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, &gt;%u = target size in MiB to use for block files)</source>
+ <translation>修剪(刪除)掉老舊區塊來減少儲存空間的需求。這種模式會關閉錢包功能,並且和 -txindex 參數不相容。警告: 從這種模式還原會需要重新下載一整個區塊鏈。(預設值: 0 表示不修剪區塊,&gt;%u 表示為區塊檔案的目標大小,單位是百萬位元組 MiB)</translation>
+ </message>
+ <message>
+ <source>Set the number of script verification threads (%u to %d, 0 = auto, &lt;0 = leave that many cores free, default: %d)</source>
+ <translation>設定指令碼驗證的執行緒數目 (%u 到 %d,0 表示程式自動決定,小於 0 表示保留處理器核心不用的數目,預設值: %d)</translation>
+ </message>
+ <message>
+ <source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source>
+ <translation>這是個還沒發表的測試版本 - 使用請自負風險 - 請不要用來開採或商業應用</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer. Bitcoin Core is probably already running.</source>
+ <translation>沒辦法繫結在這台電腦上的 %s 。位元幣核心可能已經在執行了。</translation>
+ </message>
+ <message>
+ <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>警告: 收到了不尋常地多的 %d 個區塊在過去 %d 小時內生產出來(預期是 %d 個)</translation>
+ </message>
+ <message>
+ <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>警告: 請檢查你的網路連線狀況,收到了 %d 個區塊是在過去 %d 小時內生產出來(預期是 %d 個)</translation>
+ </message>
+ <message>
+ <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>警告: -paytxfee 設定了很高的金額!這可是你交易付款所要付的手續費。</translation>
+ </message>
+ <message>
+ <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source>
+ <translation>警告: 位元幣網路對於區塊鏈結的決定目前有分歧!看來有些礦工會有問題。</translation>
+ </message>
+ <message>
+ <source>Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.</source>
+ <translation>警告: 我們和某些連線的節點對於區塊鏈結的決定不同!你可能需要升級,或是需要等其它的節點升級。</translation>
+ </message>
+ <message>
+ <source>Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
+ <translation>警告: 讀取錢包檔 wallet.dat 時發生錯誤!所有的密鑰都正確讀取了,但是交易資料或位址簿資料可能會缺少或不正確。</translation>
+ </message>
+ <message>
+ <source>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</source>
+ <translation>警告: 錢包檔 wallet.dat 壞掉,但資料被拯救回來了!原來的 wallet.dat 會改儲存在 %s, 檔名是 wallet.{timestamp}.bak. 如果餘額或交易資料有誤,你應該要用備份資料復原回來。</translation>
+ </message>
+ <message>
+ <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source>
+ <translation>把來自指定網域或位址的節點放進白名單。這個選項可以設定多次。</translation>
+ </message>
+ <message>
+ <source>(default: 1)</source>
+ <translation>(預設值: 1)</translation>
+ </message>
+ <message>
+ <source>&lt;category&gt; can be:</source>
+ <translation>&lt;category&gt; 可以是:</translation>
+ </message>
+ <message>
+ <source>Attempt to recover private keys from a corrupt wallet.dat</source>
+ <translation>嘗試從壞掉的錢包檔 wallet.dat 復原密鑰</translation>
+ </message>
+ <message>
+ <source>Block creation options:</source>
+ <translation>區塊製造選項:</translation>
+ </message>
+ <message>
+ <source>Connect only to the specified node(s)</source>
+ <translation>只連線到指定節點(可多個)</translation>
+ </message>
+ <message>
+ <source>Connection options:</source>
+ <translation>連線選項:</translation>
+ </message>
+ <message>
+ <source>Corrupted block database detected</source>
+ <translation>發現區塊資料庫壞掉了</translation>
+ </message>
+ <message>
+ <source>Debugging/Testing options:</source>
+ <translation>除錯與測試選項</translation>
+ </message>
+ <message>
+ <source>Do not load the wallet and disable wallet RPC calls</source>
+ <translation>不要載入錢包,並且拿掉錢包相關的 RPC 功能請求。</translation>
+ </message>
+ <message>
+ <source>Do you want to rebuild the block database now?</source>
+ <translation>你想要現在重建區塊資料庫嗎?</translation>
+ </message>
+ <message>
+ <source>Error initializing block database</source>
+ <translation>初始化區塊資料庫時發生錯誤</translation>
+ </message>
+ <message>
+ <source>Error initializing wallet database environment %s!</source>
+ <translation>初始化錢包資料庫環境 %s 時發生錯誤!</translation>
+ </message>
+ <message>
+ <source>Error loading block database</source>
+ <translation>載入區塊資料庫時發生錯誤</translation>
+ </message>
+ <message>
+ <source>Error opening block database</source>
+ <translation>打開區塊資料庫時發生錯誤</translation>
+ </message>
+ <message>
+ <source>Error: Disk space is low!</source>
+ <translation>錯誤: 磁碟空間很少!</translation>
+ </message>
+ <message>
+ <source>Failed to listen on any port. Use -listen=0 if you want this.</source>
+ <translation>在任意的通訊埠聽候失敗。如果你希望這樣的話,可以設定 -listen=0.</translation>
+ </message>
+ <message>
+ <source>If &lt;category&gt; is not supplied, output all debugging information.</source>
+ <translation>如果沒有提供 &lt;category&gt; 就會輸出所有的除錯資訊。</translation>
+ </message>
+ <message>
+ <source>Importing...</source>
+ <translation>正在匯入中...</translation>
+ </message>
+ <message>
+ <source>Incorrect or no genesis block found. Wrong datadir for network?</source>
+ <translation>創世區塊不正確或找不到。資料目錄錯了嗎?</translation>
+ </message>
+ <message>
+ <source>Invalid -onion address: '%s'</source>
+ <translation>無效的 -onion 位址: '%s'</translation>
+ </message>
+ <message>
+ <source>Not enough file descriptors available.</source>
+ <translation>檔案描述元不足。</translation>
+ </message>
+ <message>
+ <source>Only connect to nodes in network &lt;net&gt; (ipv4, ipv6 or onion)</source>
+ <translation>只有連接到網絡節點 &lt;net&gt; (IPv4,IPv6或onion)</translation>
+ </message>
+ <message>
+ <source>Prune cannot be configured with a negative value.</source>
+ <translation>修剪值不能設定為負的。</translation>
+ </message>
+ <message>
+ <source>Prune mode is incompatible with -txindex.</source>
+ <translation>修剪模式和 -txindex 參數不相容。</translation>
+ </message>
+ <message>
+ <source>Set database cache size in megabytes (%d to %d, default: %d)</source>
+ <translation>設定資料庫快取大小是多少百萬位元組(MB,範圍: %d 到 %d,預設值: %d)</translation>
+ </message>
+ <message>
+ <source>Set maximum block size in bytes (default: %d)</source>
+ <translation>設定區塊大小上限成多少位元組(預設值: %d)</translation>
+ </message>
+ <message>
+ <source>Specify wallet file (within data directory)</source>
+ <translation>指定錢包檔(會在資料目錄中)</translation>
+ </message>
+ <message>
+ <source>Verifying blocks...</source>
+ <translation>正在驗證區塊資料...</translation>
+ </message>
+ <message>
+ <source>Verifying wallet...</source>
+ <translation>正在驗證錢包資料...</translation>
+ </message>
+ <message>
+ <source>Wallet %s resides outside data directory %s</source>
+ <translation>錢包檔 %s 沒有在資料目錄 %s 裡面</translation>
+ </message>
+ <message>
+ <source>Wallet options:</source>
+ <translation>錢包選項:</translation>
+ </message>
+ <message>
+ <source>Warning: This version is obsolete; upgrade required!</source>
+ <translation>警告: 這個版本已經被淘汰了;必須要升級!</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to change -txindex</source>
+ <translation>改變 -txindex 參數後,必須要用 -reindex 參數來重建資料庫</translation>
+ </message>
+ <message>
+ <source>Imports blocks from external blk000??.dat file</source>
+ <translation>從其它來源的 blk000??.dat 檔匯入區塊</translation>
+ </message>
+ <message>
+ <source>Allow JSON-RPC connections from specified source. Valid for &lt;ip&gt; are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times</source>
+ <translation>允許指定的來源建立 JSON-RPC 連線。&lt;ip&gt; 的有效值可以是一個單獨位址(像是 1.2.3.4),一個網段/網段罩遮值(像是 1.2.3.4/255.255.255.0),或是網段/CIDR值(像是 1.2.3.4/24)。這個選項可以設定多次。</translation>
+ </message>
+ <message>
+ <source>An error occurred while setting up the RPC address %s port %u for listening: %s</source>
+ <translation>設定在網路上以位址 %s 和通訊埠 %u 聽候 RPC 連線時發生錯誤: %s</translation>
+ </message>
+ <message>
+ <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source>
+ <translation>和指定的位址繫結,並且把連線過來的節點放進白名單。IPv6 請用 [主機]:通訊埠 這種格式</translation>
+ </message>
+ <message>
+ <source>Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)</source>
+ <translation>和指定的位址繫結以聽候 JSON-RPC 連線。IPv6 請用 [主機]:通訊埠 這種格式。這個選項可以設定多次。(預設值: 跟所有網路界面上的位址繫結)</translation>
+ </message>
+ <message>
+ <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source>
+ <translation>沒辦法鎖定資料目錄 %s。位元幣核心可能已經在執行了。</translation>
+ </message>
+ <message>
+ <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
+ <translation>用系統預設權限來造出新的檔案,而不是用使用者權限罩遮(umask)值 077 (只有在關掉錢包功能時才有作用)。</translation>
+ </message>
+ <message>
+ <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source>
+ <translation>找出自己的網際網路位址(預設值: 當有聽候連線且沒有指定 -externalip 或 -proxy 時為 1)</translation>
+ </message>
+ <message>
+ <source>Error: Listening for incoming connections failed (listen returned error %s)</source>
+ <translation>錯誤: 聽候外來連線失敗(回傳錯誤 %s)</translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source>
+ <translation>錯誤: 找到不再支援的 -socks 參數。現在只支援 SOCKS5 協定的代理伺服器了,因為不再能夠指定 SOCKS 協定版本。</translation>
+ </message>
+ <message>
+ <source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source>
+ <translation>當收到相關警示,或發現相當長的分支時,所要執行的指令(指令中的 %s 會被取代成警示訊息)</translation>
+ </message>
+ <message>
+ <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source>
+ <translation>當處理轉發的交易時,如果每千位元組(Kb)的手續費比這個值低,就視為沒付手續費 (預設值: %s)</translation>
+ </message>
+ <message>
+ <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
+ <translation>當沒有設定 paytxfee 時,自動包含可以讓交易能在平均 n 個區塊內開始確認的手續費(預設值: %u)</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)</source>
+ <translation>-maxtxfee=&lt;amount&gt;: '%s' 的金額無效 (必須大於最低轉發手續費 %s 以避免交易無法確認)</translation>
+ </message>
+ <message>
+ <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source>
+ <translation>轉發和開採時,對只帶資料的交易的大小上限(預設值: %u)</translation>
+ </message>
+ <message>
+ <source>Prune configured below the minimum of %d MB. Please use a higher number.</source>
+ <translation>設定的修剪值小於最小需求的 %d MB. 請指定大一點的數字。</translation>
+ </message>
+ <message>
+ <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source>
+ <translation>是否允許在節點位址數目不足時,使用域名查詢來搜尋節點 (預設值: 當沒用 -connect 時為 1)</translation>
+ </message>
+ <message>
+ <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source>
+ <translation>對每個代理連線使用隨機產生的憑證。這個選項會開啟 Tor 的串流隔離(預設值: %u)</translation>
+ </message>
+ <message>
+ <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
+ <translation>設定高優先度或低手續費的交易資料大小上限成多少位元組(預設值: %d)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source>
+ <translation>設定產生錢幣的執行緒數目(-1 表示處理器核心數,預設值: %d)</translation>
+ </message>
+ <message>
+ <source>The transaction amount is too small to send after the fee has been deducted</source>
+ <translation>扣除手續費後的交易金額太少而不能傳送</translation>
+ </message>
+ <message>
+ <source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit &lt;https://www.openssl.org/&gt; and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source>
+ <translation>此產品也包含了由 OpenSSL Project 所開發的 OpenSSL Toolkit 軟體 &lt;https://www.openssl.org/&gt;, 和由 Eric Young 撰寫的加解密軟體,以及由 Thomas Bernard 所撰寫的 UPnP 軟體。</translation>
+ </message>
+ <message>
+ <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an 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)
+The username and password MUST NOT be the same.
+If the file does not exist, create it with owner-readable-only file permissions.
+It is also recommended to set alertnotify so you are notified of problems;
+for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
+</source>
+ <translation>要使用 bitcoind, 或是對 bitcoin-qt 指定 -server 選項,你必須要在以下設定檔中設定 RPC 密碼(選項: rpcpassword):
+%s
+建議你使用以下隨機產生的密碼:
+rpcuser=bitcoinrpc
+rpcpassword=%s
+(你不用記住這個密碼)
+注意使用者名稱(rpcuser)和密碼(rpcpassword)不可以相同!
+如果設定檔還不存在,請在新增時,設定檔案權限為"只有主人才能讀取"。
+也建議你設定警示通知,這樣發生問題時你才會被通知到;
+比如說設定: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
+</translation>
+ </message>
+ <message>
+ <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source>
+ <translation>警告: -maxtxfee 設定了很高的金額!這可是一次交易就有可能付出的最高手續費。</translation>
+ </message>
+ <message>
+ <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source>
+ <translation>警告: 請檢查電腦日期和時間是否正確!位元幣核心沒辦法在時鐘不準的情況下正常運作。</translation>
+ </message>
+ <message>
+ <source>Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway</source>
+ <translation>在白名單中的節點不會因為偵測到阻斷服務攻擊而被停用。來自這些節點的交易也一定會被轉發,即使說交易本來就在記憶池裡了也一樣。適用於像是閘道伺服器。</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source>
+ <translation>回到非修剪的模式需要用 -reindex 參數來重建資料庫。這會導致重新下載整個區塊鏈。</translation>
+ </message>
+ <message>
+ <source>(default: %u)</source>
+ <translation>(預設值: %u)</translation>
+ </message>
+ <message>
+ <source>Accept public REST requests (default: %u)</source>
+ <translation>接受公開的REST請求 (預設值: %u)</translation>
+ </message>
+ <message>
+ <source>Activating best chain...</source>
+ <translation>啟用最佳鏈結...</translation>
+ </message>
+ <message>
+ <source>Can't run with a wallet in prune mode.</source>
+ <translation>不能在有錢包時執行修剪模式。</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -whitebind address: '%s'</source>
+ <translation>沒辦法解析 -whitebind 指定的位址: '%s'</translation>
+ </message>
+ <message>
+ <source>Choose data directory on startup (default: 0)</source>
+ <translation>啓動時選擇資料目錄(預設值: 0)</translation>
+ </message>
+ <message>
+ <source>Connect through SOCKS5 proxy</source>
+ <translation>透過 SOCKS5 代理伺服器連線</translation>
+ </message>
+ <message>
+ <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source>
+ <translation>版權為位元幣核心開發人員自西元 2009 至 %i 年起所有</translation>
+ </message>
+ <message>
+ <source>Could not parse -rpcbind value %s as network address</source>
+ <translation>沒辦法解析 -rpcbind 參數值 %s 為網路位址</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source>
+ <translation>載入 wallet.dat 檔案時發生錯誤: 這個錢包需要新版的位元幣核心</translation>
+ </message>
+ <message>
+ <source>Error reading from database, shutting down.</source>
+ <translation>讀取資料庫時發生錯誤,要關閉了。</translation>
+ </message>
+ <message>
+ <source>Error: A fatal internal error occurred, see debug.log for details</source>
+ <translation>錯誤: 發生了致命的內部錯誤,詳情請看 debug.log</translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -tor found, use -onion.</source>
+ <translation>錯誤: 找到不再支援的 -tor 參數,請改用 -onion 參數。</translation>
+ </message>
+ <message>
+ <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source>
+ <translation>交易付款時每千位元組(kB)的交易手續費 (預設值: %s)</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>資訊</translation>
+ </message>
+ <message>
+ <source>Initialization sanity check failed. Bitcoin Core is shutting down.</source>
+ <translation>初始化時的基本檢查失敗了。位元幣核心就要關閉了。</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s'</source>
+ <translation>-maxtxfee=&lt;amount&gt;: '%s' 的金額無效</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -minrelaytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>設定最低轉發手續費 -minrelaytxfee=&lt;金額&gt; 的金額無效: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -mintxfee=&lt;amount&gt;: '%s'</source>
+ <translation>設定 -mintxfee=&lt;金額&gt; 的金額無效: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s' (must be at least %s)</source>
+ <translation>設定 -paytxfee=&lt;金額&gt; 的金額無效: '%s' (至少要有 %s)</translation>
+ </message>
+ <message>
+ <source>Invalid netmask specified in -whitelist: '%s'</source>
+ <translation>指定在 -whitelist 的網段無效: '%s'</translation>
+ </message>
+ <message>
+ <source>Keep at most &lt;n&gt; unconnectable transactions in memory (default: %u)</source>
+ <translation>保持最多 &lt;n&gt; 無法連結的交易在記憶體 (預設: %u)</translation>
+ </message>
+ <message>
+ <source>Need to specify a port with -whitebind: '%s'</source>
+ <translation>指定 -whitebind 時必須包含通訊埠: '%s'</translation>
+ </message>
+ <message>
+ <source>Node relay options:</source>
+ <translation>節點轉發選項:</translation>
+ </message>
+ <message>
+ <source>Pruning blockstore...</source>
+ <translation>正在修剪區塊資料庫中...</translation>
+ </message>
+ <message>
+ <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source>
+ <translation>RPC SSL 選項: (SSL 設定程序請見 Bitcoin Wiki)</translation>
+ </message>
+ <message>
+ <source>RPC server options:</source>
+ <translation>RPC 伺服器選項:</translation>
+ </message>
+ <message>
+ <source>RPC support for HTTP persistent connections (default: %d)</source>
+ <translation>RPC 是否支援 HTTP 持久連線(預設值: %d)</translation>
+ </message>
+ <message>
+ <source>Rebuild block chain index from current blk000??.dat files on startup</source>
+ <translation>啟動時從目前的區塊檔 blk000??.dat 重建區塊鏈的索引</translation>
+ </message>
+ <message>
+ <source>Receive and display P2P network alerts (default: %u)</source>
+ <translation>接收並顯示對等網路(P2P)警示 (預設值: %u)</translation>
+ </message>
+ <message>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>在終端機顯示追蹤或除錯資訊,而不是寫到檔案 debug.log 中</translation>
+ </message>
+ <message>
+ <source>Send transactions as zero-fee transactions if possible (default: %u)</source>
+ <translation>盡可能送出不用付手續費的交易(預設值: %u)</translation>
+ </message>
+ <message>
+ <source>Set SSL root certificates for payment request (default: -system-)</source>
+ <translation>設定付款請求時所使用的 SSL 根憑證 (預設值: 系統憑證庫)</translation>
+ </message>
+ <message>
+ <source>Set language, for example "de_DE" (default: system locale)</source>
+ <translation>設定語言,比如說 de_DE (預設值: 系統語系)</translation>
+ </message>
+ <message>
+ <source>Show all debugging options (usage: --help -help-debug)</source>
+ <translation>顯示所有的除錯選項 (用法: --help --help-debug)</translation>
+ </message>
+ <message>
+ <source>Show splash screen on startup (default: 1)</source>
+ <translation>顯示啓動畫面(預設值: 1)</translation>
+ </message>
+ <message>
+ <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source>
+ <translation>客戶端軟體啓動時把 debug.log 檔縮小(預設值: 當沒有 -debug 時為 1)</translation>
+ </message>
+ <message>
+ <source>Signing transaction failed</source>
+ <translation>簽署交易失敗</translation>
+ </message>
+ <message>
+ <source>Start minimized</source>
+ <translation>啓動時縮到最小</translation>
+ </message>
+ <message>
+ <source>The transaction amount is too small to pay the fee</source>
+ <translation>交易金額太少而付不起手續費</translation>
+ </message>
+ <message>
+ <source>This is experimental software.</source>
+ <translation>這套軟體屬於實驗性質。</translation>
+ </message>
+ <message>
+ <source>Transaction amount too small</source>
+ <translation>交易金額太小</translation>
+ </message>
+ <message>
+ <source>Transaction amounts must be positive</source>
+ <translation>交易金額必須是正的</translation>
+ </message>
+ <message>
+ <source>Transaction too large for fee policy</source>
+ <translation>根據交易手續費準則,本交易的位元量過大</translation>
+ </message>
+ <message>
+ <source>Transaction too large</source>
+ <translation>交易位元量太大</translation>
+ </message>
+ <message>
+ <source>UI Options:</source>
+ <translation>使用介面選項:</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer (bind returned error %s)</source>
+ <translation>無法和這台電腦上的 %s 繫結(回傳錯誤 %s)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: 1 when listening)</source>
+ <translation>是否要使用「通用即插即用」協定(UPnP),來設定聽候連線的通訊埠的對應(預設值: 當有聽候連線時為 1)</translation>
+ </message>
+ <message>
+ <source>Username for JSON-RPC connections</source>
+ <translation>JSON-RPC 連線使用者名稱</translation>
+ </message>
+ <message>
+ <source>Wallet needed to be rewritten: restart Bitcoin Core to complete</source>
+ <translation>錢包需要重寫: 請重新啓動位元幣核心來完成</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>警告</translation>
+ </message>
+ <message>
+ <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source>
+ <translation>警告: 忽略了不再支援的 -benchmark 參數,請改用 -debug=bench.</translation>
+ </message>
+ <message>
+ <source>Warning: Unsupported argument -debugnet ignored, use -debug=net.</source>
+ <translation>警告: 忽略了不再支援的 -debugnet 參數,請改用 -debug=net.</translation>
+ </message>
+ <message>
+ <source>Zapping all transactions from wallet...</source>
+ <translation>正在砍掉錢包中的所有交易...</translation>
+ </message>
+ <message>
+ <source>on startup</source>
+ <translation>當啟動時</translation>
+ </message>
+ <message>
+ <source>wallet.dat corrupt, salvage failed</source>
+ <translation>錢包檔 weallet.dat 壞掉了,拯救失敗</translation>
+ </message>
+ <message>
+ <source>Password for JSON-RPC connections</source>
+ <translation>JSON-RPC 連線密碼</translation>
+ </message>
+ <message>
+ <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
+ <translation>當最新區塊改變時要執行的指令(指令中的 %s 會被取代成區塊雜湊值)</translation>
+ </message>
+ <message>
+ <source>Upgrade wallet to latest format</source>
+ <translation>把錢包檔案升級成最新的格式</translation>
+ </message>
+ <message>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>重新掃描區塊鏈,來尋找錢包可能漏掉的交易。</translation>
+ </message>
+ <message>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>在 JSON-RPC 連線使用 OpenSSL (https)</translation>
+ </message>
+ <message>
+ <source>This help message</source>
+ <translation>這些說明訊息</translation>
+ </message>
+ <message>
+ <source>Allow DNS lookups for -addnode, -seednode and -connect</source>
+ <translation>允許對 -addnode, -seednode, -connect 的參數使用域名查詢 </translation>
+ </message>
+ <message>
+ <source>Loading addresses...</source>
+ <translation>正在載入位址資料...</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>載入檔案 wallet.dat 時發生錯誤: 錢包損毀了</translation>
+ </message>
+ <message>
+ <source>(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source>
+ <translation>(1 表示保留交易描述資料,像是帳戶使用者和付款請求資訊;2 表示丟掉交易描述資料)</translation>
+ </message>
+ <message>
+ <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
+ <translation>使用 -checkblocks 檢查區塊的仔細程度(0 到 4,預設值: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
+ <translation>維護全部交易的索引,用在 getrawtransaction 這個 RPC 請求(預設值: %u)</translation>
+ </message>
+ <message>
+ <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source>
+ <translation>避免與亂搞的節點連線的秒數(預設: %u)</translation>
+ </message>
+ <message>
+ <source>Output debugging information (default: %u, supplying &lt;category&gt; is optional)</source>
+ <translation>輸出除錯資訊(預設值: %u, 不一定要指定 &lt;category&gt;)</translation>
+ </message>
+ <message>
+ <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source>
+ <translation>使用另外的 SOCK5 代理伺服器,來透過 Tor 隱藏服務跟節點聯繫(預設值: %s)</translation>
+ </message>
+ <message>
+ <source>(default: %s)</source>
+ <translation>(預設值: %s)</translation>
+ </message>
+ <message>
+ <source>Acceptable ciphers (default: %s)</source>
+ <translation>可以接受的加密演算法(預設值: %s)</translation>
+ </message>
+ <message>
+ <source>Always query for peer addresses via DNS lookup (default: %u)</source>
+ <translation>是否一定要用域名查詢來搜尋節點(預設值: %u)</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>載入錢包檔 wallet.dat 時發生錯誤</translation>
+ </message>
+ <message>
+ <source>Generate coins (default: %u)</source>
+ <translation>生產位元幣(預設值: %u)</translation>
+ </message>
+ <message>
+ <source>How many blocks to check at startup (default: %u, 0 = all)</source>
+ <translation>啓動時檢查的區塊數(預設值: %u, 指定 0 表示全部)</translation>
+ </message>
+ <message>
+ <source>Include IP addresses in debug output (default: %u)</source>
+ <translation>在除錯輸出內容中包含網際網路位址(預設值: %u)</translation>
+ </message>
+ <message>
+ <source>Invalid -proxy address: '%s'</source>
+ <translation>無效的 -proxy 位址: '%s'</translation>
+ </message>
+ <message>
+ <source>Listen for JSON-RPC connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>在通訊埠 &lt;port&gt; 聽候 JSON-RPC 連線(預設值: %u, 或若為測試網路: %u)</translation>
+ </message>
+ <message>
+ <source>Listen for connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>在通訊埠 &lt;port&gt; 聽候連線(預設值: %u, 或若為測試網路: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain at most &lt;n&gt; connections to peers (default: %u)</source>
+ <translation>維持與節點連線數的上限為 &lt;n&gt; 個(預設值: %u)</translation>
+ </message>
+ <message>
+ <source>Make the wallet broadcast transactions</source>
+ <translation>讓錢包能公告交易</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection receive buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>每個連線的接收緩衝區大小上限為 &lt;n&gt;*1000 個位元組(預設值: %u)</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection send buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>每個連線的傳送緩衝區大小上限為 &lt;n&gt;*1000 個位元組(預設值: %u)</translation>
+ </message>
+ <message>
+ <source>Prepend debug output with timestamp (default: %u)</source>
+ <translation>在除錯輸出內容前附加時間(預設值: %u)</translation>
+ </message>
+ <message>
+ <source>Relay and mine data carrier transactions (default: %u)</source>
+ <translation>允許轉發和開採只帶資料的交易(預設值: %u)</translation>
+ </message>
+ <message>
+ <source>Relay non-P2SH multisig (default: %u)</source>
+ <translation>允許轉發非 P2SH 的多簽章交易(預設值: %u)</translation>
+ </message>
+ <message>
+ <source>Server certificate file (default: %s)</source>
+ <translation>伺服器憑證檔(預設值: %s)</translation>
+ </message>
+ <message>
+ <source>Server private key (default: %s)</source>
+ <translation>伺服器密鑰檔(預設值: %s)</translation>
+ </message>
+ <message>
+ <source>Set key pool size to &lt;n&gt; (default: %u)</source>
+ <translation>設定密鑰池大小為 &lt;n&gt; (預設值: %u)</translation>
+ </message>
+ <message>
+ <source>Set minimum block size in bytes (default: %u)</source>
+ <translation>設定區塊大小下限為多少位元組(預設值: %u)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads to service RPC calls (default: %d)</source>
+ <translation>設定處理 RPC 服務請求的執行緒數目(預設值: %d)</translation>
+ </message>
+ <message>
+ <source>Specify configuration file (default: %s)</source>
+ <translation>指定設定檔(預設值: %s)</translation>
+ </message>
+ <message>
+ <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source>
+ <translation>指定連線在幾毫秒後逾時 (最少值: 1, 預設值: %d)</translation>
+ </message>
+ <message>
+ <source>Specify pid file (default: %s)</source>
+ <translation>指定行程識別碼檔案(預設值: %s)</translation>
+ </message>
+ <message>
+ <source>Spend unconfirmed change when sending transactions (default: %u)</source>
+ <translation>傳送交易時可以花還沒確認的零錢(預設值: %u)</translation>
+ </message>
+ <message>
+ <source>Threshold for disconnecting misbehaving peers (default: %u)</source>
+ <translation>與亂搞的節點斷線的臨界值 (預設: %u)</translation>
+ </message>
+ <message>
+ <source>Unknown network specified in -onlynet: '%s'</source>
+ <translation>在 -onlynet 指定了不明的網路別: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -bind address: '%s'</source>
+ <translation>沒辦法解析 -bind 位址: '%s'</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -externalip address: '%s'</source>
+ <translation>沒辦法解析 -externalip 位址: '%s'</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s'</source>
+ <translation>設定 -paytxfee=&lt;金額&gt; 的金額無效: '%s'</translation>
+ </message>
+ <message>
+ <source>Insufficient funds</source>
+ <translation>累積金額不足</translation>
+ </message>
+ <message>
+ <source>Loading block index...</source>
+ <translation>正在載入區塊索引...</translation>
+ </message>
+ <message>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>增加一個要連線的節線,並試著保持對它的連線暢通</translation>
+ </message>
+ <message>
+ <source>Loading wallet...</source>
+ <translation>正在載入錢包資料...</translation>
+ </message>
+ <message>
+ <source>Cannot downgrade wallet</source>
+ <translation>沒辦法把錢包格式降級</translation>
+ </message>
+ <message>
+ <source>Cannot write default address</source>
+ <translation>沒辦法把預設位址寫進去</translation>
+ </message>
+ <message>
+ <source>Rescanning...</source>
+ <translation>正在重新掃描...</translation>
+ </message>
+ <message>
+ <source>Done loading</source>
+ <translation>載入完成</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>錯誤</translation>
+ </message>
+</context>
+</TS> \ No newline at end of file
diff --git a/src/qt/macdockiconhandler.h b/src/qt/macdockiconhandler.h
new file mode 100644
index 0000000000..8bd867c103
--- /dev/null
+++ b/src/qt/macdockiconhandler.h
@@ -0,0 +1,44 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_MACDOCKICONHANDLER_H
+#define BITCOIN_QT_MACDOCKICONHANDLER_H
+
+#include <QMainWindow>
+#include <QObject>
+
+QT_BEGIN_NAMESPACE
+class QIcon;
+class QMenu;
+class QWidget;
+QT_END_NAMESPACE
+
+/** Macintosh-specific dock icon handler.
+ */
+class MacDockIconHandler : public QObject
+{
+ Q_OBJECT
+
+public:
+ ~MacDockIconHandler();
+
+ QMenu *dockMenu();
+ void setIcon(const QIcon &icon);
+ void setMainWindow(QMainWindow *window);
+ static MacDockIconHandler *instance();
+ static void cleanup();
+ void handleDockIconClickEvent();
+
+Q_SIGNALS:
+ void dockIconClicked();
+
+private:
+ MacDockIconHandler();
+
+ QWidget *m_dummyWidget;
+ QMenu *m_dockMenu;
+ QMainWindow *mainWindow;
+};
+
+#endif // BITCOIN_QT_MACDOCKICONHANDLER_H
diff --git a/src/qt/macdockiconhandler.mm b/src/qt/macdockiconhandler.mm
new file mode 100644
index 0000000000..a41d39d51e
--- /dev/null
+++ b/src/qt/macdockiconhandler.mm
@@ -0,0 +1,134 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "macdockiconhandler.h"
+
+#include <QImageWriter>
+#include <QMenu>
+#include <QBuffer>
+#include <QWidget>
+
+#undef slots
+#include <Cocoa/Cocoa.h>
+#include <objc/objc.h>
+#include <objc/message.h>
+
+#if QT_VERSION < 0x050000
+extern void qt_mac_set_dock_menu(QMenu *);
+#endif
+
+static MacDockIconHandler *s_instance = NULL;
+
+bool dockClickHandler(id self,SEL _cmd,...) {
+ Q_UNUSED(self)
+ Q_UNUSED(_cmd)
+
+ s_instance->handleDockIconClickEvent();
+
+ // Return NO (false) to suppress the default OS X actions
+ return false;
+}
+
+void setupDockClickHandler() {
+ Class cls = objc_getClass("NSApplication");
+ id appInst = objc_msgSend((id)cls, sel_registerName("sharedApplication"));
+
+ if (appInst != NULL) {
+ id delegate = objc_msgSend(appInst, sel_registerName("delegate"));
+ Class delClass = (Class)objc_msgSend(delegate, sel_registerName("class"));
+ SEL shouldHandle = sel_registerName("applicationShouldHandleReopen:hasVisibleWindows:");
+ if (class_getInstanceMethod(delClass, shouldHandle))
+ class_replaceMethod(delClass, shouldHandle, (IMP)dockClickHandler, "B@:");
+ else
+ class_addMethod(delClass, shouldHandle, (IMP)dockClickHandler,"B@:");
+ }
+}
+
+
+MacDockIconHandler::MacDockIconHandler() : QObject()
+{
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+ setupDockClickHandler();
+ this->m_dummyWidget = new QWidget();
+ this->m_dockMenu = new QMenu(this->m_dummyWidget);
+ this->setMainWindow(NULL);
+#if QT_VERSION < 0x050000
+ qt_mac_set_dock_menu(this->m_dockMenu);
+#elif QT_VERSION >= 0x050200
+ this->m_dockMenu->setAsDockMenu();
+#endif
+ [pool release];
+}
+
+void MacDockIconHandler::setMainWindow(QMainWindow *window) {
+ this->mainWindow = window;
+}
+
+MacDockIconHandler::~MacDockIconHandler()
+{
+ delete this->m_dummyWidget;
+ this->setMainWindow(NULL);
+}
+
+QMenu *MacDockIconHandler::dockMenu()
+{
+ return this->m_dockMenu;
+}
+
+void MacDockIconHandler::setIcon(const QIcon &icon)
+{
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ NSImage *image = nil;
+ if (icon.isNull())
+ image = [[NSImage imageNamed:@"NSApplicationIcon"] retain];
+ else {
+ // generate NSImage from QIcon and use this as dock icon.
+ QSize size = icon.actualSize(QSize(128, 128));
+ QPixmap pixmap = icon.pixmap(size);
+
+ // Write image into a R/W buffer from raw pixmap, then save the image.
+ QBuffer notificationBuffer;
+ if (!pixmap.isNull() && notificationBuffer.open(QIODevice::ReadWrite)) {
+ QImageWriter writer(&notificationBuffer, "PNG");
+ if (writer.write(pixmap.toImage())) {
+ NSData* macImgData = [NSData dataWithBytes:notificationBuffer.buffer().data()
+ length:notificationBuffer.buffer().size()];
+ image = [[NSImage alloc] initWithData:macImgData];
+ }
+ }
+
+ if(!image) {
+ // if testnet image could not be created, load std. app icon
+ image = [[NSImage imageNamed:@"NSApplicationIcon"] retain];
+ }
+ }
+
+ [NSApp setApplicationIconImage:image];
+ [image release];
+ [pool release];
+}
+
+MacDockIconHandler *MacDockIconHandler::instance()
+{
+ if (!s_instance)
+ s_instance = new MacDockIconHandler();
+ return s_instance;
+}
+
+void MacDockIconHandler::cleanup()
+{
+ delete s_instance;
+}
+
+void MacDockIconHandler::handleDockIconClickEvent()
+{
+ if (this->mainWindow)
+ {
+ this->mainWindow->activateWindow();
+ this->mainWindow->show();
+ }
+
+ Q_EMIT this->dockIconClicked();
+}
diff --git a/src/qt/macnotificationhandler.h b/src/qt/macnotificationhandler.h
new file mode 100644
index 0000000000..bd66b96b21
--- /dev/null
+++ b/src/qt/macnotificationhandler.h
@@ -0,0 +1,30 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_MACNOTIFICATIONHANDLER_H
+#define BITCOIN_QT_MACNOTIFICATIONHANDLER_H
+
+#include <QObject>
+
+/** Macintosh-specific notification handler (supports UserNotificationCenter and Growl).
+ */
+class MacNotificationHandler : public QObject
+{
+ Q_OBJECT
+
+public:
+ /** shows a 10.8+ UserNotification in the UserNotificationCenter
+ */
+ void showNotification(const QString &title, const QString &text);
+
+ /** executes AppleScript */
+ void sendAppleScript(const QString &script);
+
+ /** check if OS can handle UserNotifications */
+ bool hasUserNotificationCenterSupport(void);
+ static MacNotificationHandler *instance();
+};
+
+
+#endif // BITCOIN_QT_MACNOTIFICATIONHANDLER_H
diff --git a/src/qt/macnotificationhandler.mm b/src/qt/macnotificationhandler.mm
new file mode 100644
index 0000000000..dd3f622818
--- /dev/null
+++ b/src/qt/macnotificationhandler.mm
@@ -0,0 +1,91 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "macnotificationhandler.h"
+
+#undef slots
+#import <objc/runtime.h>
+#include <Cocoa/Cocoa.h>
+
+// Add an obj-c category (extension) to return the expected bundle identifier
+@implementation NSBundle(returnCorrectIdentifier)
+- (NSString *)__bundleIdentifier
+{
+ if (self == [NSBundle mainBundle]) {
+ return @"org.bitcoinfoundation.Bitcoin-Qt";
+ } else {
+ return [self __bundleIdentifier];
+ }
+}
+@end
+
+void MacNotificationHandler::showNotification(const QString &title, const QString &text)
+{
+ // check if users OS has support for NSUserNotification
+ if(this->hasUserNotificationCenterSupport()) {
+ // okay, seems like 10.8+
+ QByteArray utf8 = title.toUtf8();
+ char* cString = (char *)utf8.constData();
+ NSString *titleMac = [[NSString alloc] initWithUTF8String:cString];
+
+ utf8 = text.toUtf8();
+ cString = (char *)utf8.constData();
+ NSString *textMac = [[NSString alloc] initWithUTF8String:cString];
+
+ // do everything weak linked (because we will keep <10.8 compatibility)
+ id userNotification = [[NSClassFromString(@"NSUserNotification") alloc] init];
+ [userNotification performSelector:@selector(setTitle:) withObject:titleMac];
+ [userNotification performSelector:@selector(setInformativeText:) withObject:textMac];
+
+ id notificationCenterInstance = [NSClassFromString(@"NSUserNotificationCenter") performSelector:@selector(defaultUserNotificationCenter)];
+ [notificationCenterInstance performSelector:@selector(deliverNotification:) withObject:userNotification];
+
+ [titleMac release];
+ [textMac release];
+ [userNotification release];
+ }
+}
+
+// sendAppleScript just take a QString and executes it as apple script
+void MacNotificationHandler::sendAppleScript(const QString &script)
+{
+ QByteArray utf8 = script.toUtf8();
+ char* cString = (char *)utf8.constData();
+ NSString *scriptApple = [[NSString alloc] initWithUTF8String:cString];
+
+ NSAppleScript *as = [[NSAppleScript alloc] initWithSource:scriptApple];
+ NSDictionary *err = nil;
+ [as executeAndReturnError:&err];
+ [as release];
+ [scriptApple release];
+}
+
+bool MacNotificationHandler::hasUserNotificationCenterSupport(void)
+{
+ Class possibleClass = NSClassFromString(@"NSUserNotificationCenter");
+
+ // check if users OS has support for NSUserNotification
+ if(possibleClass!=nil) {
+ return true;
+ }
+ return false;
+}
+
+
+MacNotificationHandler *MacNotificationHandler::instance()
+{
+ static MacNotificationHandler *s_instance = NULL;
+ if (!s_instance) {
+ s_instance = new MacNotificationHandler();
+
+ Class aPossibleClass = objc_getClass("NSBundle");
+ if (aPossibleClass) {
+ // change NSBundle -bundleIdentifier method to return a correct bundle identifier
+ // a bundle identifier is required to use OSXs User Notification Center
+ method_exchangeImplementations(class_getInstanceMethod(aPossibleClass, @selector(bundleIdentifier)),
+ class_getInstanceMethod(aPossibleClass, @selector(__bundleIdentifier)));
+ }
+ }
+ return s_instance;
+}
diff --git a/src/qt/networkstyle.cpp b/src/qt/networkstyle.cpp
new file mode 100644
index 0000000000..e28f903b2e
--- /dev/null
+++ b/src/qt/networkstyle.cpp
@@ -0,0 +1,97 @@
+// Copyright (c) 2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "networkstyle.h"
+
+#include "guiconstants.h"
+#include "scicon.h"
+
+#include <QApplication>
+
+static const struct {
+ const char *networkId;
+ const char *appName;
+ const int iconColorHueShift;
+ const int iconColorSaturationReduction;
+ const char *titleAddText;
+} network_styles[] = {
+ {"main", QAPP_APP_NAME_DEFAULT, 0, 0, ""},
+ {"test", QAPP_APP_NAME_TESTNET, 70, 30, QT_TRANSLATE_NOOP("SplashScreen", "[testnet]")},
+ {"regtest", QAPP_APP_NAME_TESTNET, 160, 30, "[regtest]"}
+};
+static const unsigned network_styles_count = sizeof(network_styles)/sizeof(*network_styles);
+
+// titleAddText needs to be const char* for tr()
+NetworkStyle::NetworkStyle(const QString &appName, const int iconColorHueShift, const int iconColorSaturationReduction, const char *titleAddText):
+ appName(appName),
+ titleAddText(qApp->translate("SplashScreen", titleAddText))
+{
+ // load pixmap
+ QPixmap pixmap(":/icons/bitcoin");
+
+ if(iconColorHueShift != 0 && iconColorSaturationReduction != 0)
+ {
+ // generate QImage from QPixmap
+ QImage img = pixmap.toImage();
+
+ int h,s,l,a;
+
+ // traverse though lines
+ for(int y=0;y<img.height();y++)
+ {
+ QRgb *scL = reinterpret_cast< QRgb *>( img.scanLine( y ) );
+
+ // loop through pixels
+ for(int x=0;x<img.width();x++)
+ {
+ // preserve alpha because QColor::getHsl doesen't return the alpha value
+ a = qAlpha(scL[x]);
+ QColor col(scL[x]);
+
+ // get hue value
+ col.getHsl(&h,&s,&l);
+
+ // rotate color on RGB color circle
+ // 70° should end up with the typical "testnet" green
+ h+=iconColorHueShift;
+
+ // change saturation value
+ if(s>iconColorSaturationReduction)
+ {
+ s -= iconColorSaturationReduction;
+ }
+ col.setHsl(h,s,l,a);
+
+ // set the pixel
+ scL[x] = col.rgba();
+ }
+ }
+
+ //convert back to QPixmap
+#if QT_VERSION >= 0x040700
+ pixmap.convertFromImage(img);
+#else
+ pixmap = QPixmap::fromImage(img);
+#endif
+ }
+
+ appIcon = QIcon(pixmap);
+ trayAndWindowIcon = QIcon(pixmap.scaled(QSize(256,256)));
+}
+
+const NetworkStyle *NetworkStyle::instantiate(const QString &networkId)
+{
+ for (unsigned x=0; x<network_styles_count; ++x)
+ {
+ if (networkId == network_styles[x].networkId)
+ {
+ return new NetworkStyle(
+ network_styles[x].appName,
+ network_styles[x].iconColorHueShift,
+ network_styles[x].iconColorSaturationReduction,
+ network_styles[x].titleAddText);
+ }
+ }
+ return 0;
+}
diff --git a/src/qt/networkstyle.h b/src/qt/networkstyle.h
new file mode 100644
index 0000000000..b78a9f5948
--- /dev/null
+++ b/src/qt/networkstyle.h
@@ -0,0 +1,33 @@
+// Copyright (c) 2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_NETWORKSTYLE_H
+#define BITCOIN_QT_NETWORKSTYLE_H
+
+#include <QIcon>
+#include <QPixmap>
+#include <QString>
+
+/* Coin network-specific GUI style information */
+class NetworkStyle
+{
+public:
+ /** Get style associated with provided BIP70 network id, or 0 if not known */
+ static const NetworkStyle *instantiate(const QString &networkId);
+
+ const QString &getAppName() const { return appName; }
+ const QIcon &getAppIcon() const { return appIcon; }
+ const QIcon &getTrayAndWindowIcon() const { return trayAndWindowIcon; }
+ const QString &getTitleAddText() const { return titleAddText; }
+
+private:
+ NetworkStyle(const QString &appName, const int iconColorHueShift, const int iconColorSaturationReduction, const char *titleAddText);
+
+ QString appName;
+ QIcon appIcon;
+ QIcon trayAndWindowIcon;
+ QString titleAddText;
+};
+
+#endif // BITCOIN_QT_NETWORKSTYLE_H
diff --git a/src/qt/notificator.cpp b/src/qt/notificator.cpp
new file mode 100644
index 0000000000..5a564248ec
--- /dev/null
+++ b/src/qt/notificator.cpp
@@ -0,0 +1,326 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "notificator.h"
+
+#include <QApplication>
+#include <QByteArray>
+#include <QIcon>
+#include <QImageWriter>
+#include <QMessageBox>
+#include <QMetaType>
+#include <QStyle>
+#include <QSystemTrayIcon>
+#include <QTemporaryFile>
+#include <QVariant>
+#ifdef USE_DBUS
+#include <stdint.h>
+#include <QtDBus>
+#endif
+// Include ApplicationServices.h after QtDbus to avoid redefinition of check().
+// This affects at least OSX 10.6. See /usr/include/AssertMacros.h for details.
+// Note: This could also be worked around using:
+// #define __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES 0
+#ifdef Q_OS_MAC
+#include <ApplicationServices/ApplicationServices.h>
+#include "macnotificationhandler.h"
+#endif
+
+
+#ifdef USE_DBUS
+// https://wiki.ubuntu.com/NotificationDevelopmentGuidelines recommends at least 128
+const int FREEDESKTOP_NOTIFICATION_ICON_SIZE = 128;
+#endif
+
+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_OS_MAC
+ // check if users OS has support for NSUserNotification
+ if( MacNotificationHandler::instance()->hasUserNotificationCenterSupport()) {
+ mode = UserNotificationCenter;
+ }
+ else {
+ // 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 marshalled 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<const uint32_t*>(tmp.bits());
+
+ 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<FreedesktopImage>();
+}
+
+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<QVariant> 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_OS_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(&notificationIconFile, "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");
+ MacNotificationHandler::instance()->sendAppleScript(script.arg(notificationApp, quotedTitle, quotedText, notificationIcon, growlApp));
+}
+
+void Notificator::notifyMacUserNotificationCenter(Class cls, const QString &title, const QString &text, const QIcon &icon) {
+ // icon is not supported by the user notification center yet. OSX will use the app icon.
+ MacNotificationHandler::instance()->showNotification(title, text);
+}
+
+#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_OS_MAC
+ case UserNotificationCenter:
+ notifyMacUserNotificationCenter(cls, title, text, icon);
+ break;
+ case Growl12:
+ case Growl13:
+ notifyGrowl(cls, title, text, icon);
+ break;
+#endif
+ default:
+ if(cls == Critical)
+ {
+ // Fall back to old fashioned pop-up 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 0000000000..f2a15e9c34
--- /dev/null
+++ b/src/qt/notificator.h
@@ -0,0 +1,80 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_NOTIFICATOR_H
+#define BITCOIN_QT_NOTIFICATOR_H
+
+#if defined(HAVE_CONFIG_H)
+#include "config/bitcoin-config.h"
+#endif
+
+#include <QIcon>
+#include <QObject>
+
+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, QSystemTrayIcon *trayIcon, QWidget *parent);
+ ~Notificator();
+
+ // Message class
+ enum Class
+ {
+ Information, /**< Informational message */
+ Warning, /**< Notify user of potential problem */
+ Critical /**< An error occurred */
+ };
+
+public Q_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) */
+ UserNotificationCenter /**< Use the 10.8+ User Notification Center (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_OS_MAC
+ void notifyGrowl(Class cls, const QString &title, const QString &text, const QIcon &icon);
+ void notifyMacUserNotificationCenter(Class cls, const QString &title, const QString &text, const QIcon &icon);
+#endif
+};
+
+#endif // BITCOIN_QT_NOTIFICATOR_H
diff --git a/src/qt/openuridialog.cpp b/src/qt/openuridialog.cpp
new file mode 100644
index 0000000000..1c843aecb1
--- /dev/null
+++ b/src/qt/openuridialog.cpp
@@ -0,0 +1,52 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "openuridialog.h"
+#include "ui_openuridialog.h"
+
+#include "guiutil.h"
+#include "walletmodel.h"
+
+#include <QUrl>
+
+OpenURIDialog::OpenURIDialog(QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::OpenURIDialog)
+{
+ ui->setupUi(this);
+#if QT_VERSION >= 0x040700
+ ui->uriEdit->setPlaceholderText("bitcoin:");
+#endif
+}
+
+OpenURIDialog::~OpenURIDialog()
+{
+ delete ui;
+}
+
+QString OpenURIDialog::getURI()
+{
+ return ui->uriEdit->text();
+}
+
+void OpenURIDialog::accept()
+{
+ SendCoinsRecipient rcp;
+ if(GUIUtil::parseBitcoinURI(getURI(), &rcp))
+ {
+ /* Only accept value URIs */
+ QDialog::accept();
+ } else {
+ ui->uriEdit->setValid(false);
+ }
+}
+
+void OpenURIDialog::on_selectFileButton_clicked()
+{
+ QString filename = GUIUtil::getOpenFileName(this, tr("Select payment request file to open"), "", "", NULL);
+ if(filename.isEmpty())
+ return;
+ QUrl fileUri = QUrl::fromLocalFile(filename);
+ ui->uriEdit->setText("bitcoin:?r=" + QUrl::toPercentEncoding(fileUri.toString()));
+}
diff --git a/src/qt/openuridialog.h b/src/qt/openuridialog.h
new file mode 100644
index 0000000000..28b8f56ca6
--- /dev/null
+++ b/src/qt/openuridialog.h
@@ -0,0 +1,34 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_OPENURIDIALOG_H
+#define BITCOIN_QT_OPENURIDIALOG_H
+
+#include <QDialog>
+
+namespace Ui {
+ class OpenURIDialog;
+}
+
+class OpenURIDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit OpenURIDialog(QWidget *parent);
+ ~OpenURIDialog();
+
+ QString getURI();
+
+protected Q_SLOTS:
+ void accept();
+
+private Q_SLOTS:
+ void on_selectFileButton_clicked();
+
+private:
+ Ui::OpenURIDialog *ui;
+};
+
+#endif // BITCOIN_QT_OPENURIDIALOG_H
diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp
new file mode 100644
index 0000000000..1731992907
--- /dev/null
+++ b/src/qt/optionsdialog.cpp
@@ -0,0 +1,288 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#if defined(HAVE_CONFIG_H)
+#include "config/bitcoin-config.h"
+#endif
+
+#include "optionsdialog.h"
+#include "ui_optionsdialog.h"
+
+#include "bitcoinunits.h"
+#include "guiutil.h"
+#include "optionsmodel.h"
+
+#include "main.h" // for MAX_SCRIPTCHECK_THREADS
+#include "netbase.h"
+#include "txdb.h" // for -dbcache defaults
+
+#ifdef ENABLE_WALLET
+#include "wallet/wallet.h" // for CWallet::minTxFee
+#endif
+
+#include <boost/thread.hpp>
+
+#include <QDataWidgetMapper>
+#include <QDir>
+#include <QIntValidator>
+#include <QLocale>
+#include <QMessageBox>
+#include <QTimer>
+
+OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) :
+ QDialog(parent),
+ ui(new Ui::OptionsDialog),
+ model(0),
+ mapper(0),
+ fProxyIpValid(true)
+{
+ ui->setupUi(this);
+
+ /* Main elements init */
+ ui->databaseCache->setMinimum(nMinDbCache);
+ ui->databaseCache->setMaximum(nMaxDbCache);
+ ui->threadsScriptVerif->setMinimum(-(int)boost::thread::hardware_concurrency());
+ ui->threadsScriptVerif->setMaximum(MAX_SCRIPTCHECK_THREADS);
+
+ /* Network elements init */
+#ifndef USE_UPNP
+ ui->mapPortUpnp->setEnabled(false);
+#endif
+
+ ui->proxyIp->setEnabled(false);
+ ui->proxyPort->setEnabled(false);
+ ui->proxyPort->setValidator(new QIntValidator(1, 65535, this));
+
+ 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_OS_MAC
+ /* remove Window tab on Mac */
+ ui->tabWidget->removeTab(ui->tabWidget->indexOf(ui->tabWindow));
+#endif
+
+ /* remove Wallet tab in case of -disablewallet */
+ if (!enableWallet) {
+ ui->tabWidget->removeTab(ui->tabWidget->indexOf(ui->tabWallet));
+ }
+
+ /* Display elements init */
+ QDir translations(":translations");
+ ui->lang->addItem(QString("(") + tr("default") + QString(")"), QVariant(""));
+ Q_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
+ }
+ }
+#if QT_VERSION >= 0x040700
+ ui->thirdPartyTxUrls->setPlaceholderText("https://example.com/tx/%s");
+#endif
+
+ ui->unit->setModel(new BitcoinUnits(this));
+
+ /* Widget-to-option mapper */
+ mapper = new QDataWidgetMapper(this);
+ mapper->setSubmitPolicy(QDataWidgetMapper::ManualSubmit);
+ mapper->setOrientation(Qt::Vertical);
+
+ /* setup/change UI elements when proxy IP is invalid/valid */
+ connect(this, SIGNAL(proxyIpChecks(QValidatedLineEdit *, int)), this, SLOT(doProxyIpChecks(QValidatedLineEdit *, int)));
+}
+
+OptionsDialog::~OptionsDialog()
+{
+ delete ui;
+}
+
+void OptionsDialog::setModel(OptionsModel *model)
+{
+ this->model = model;
+
+ if(model)
+ {
+ /* check if client restart is needed and show persistent message */
+ if (model->isRestartRequired())
+ showRestartWarning(true);
+
+ QString strLabel = model->getOverriddenByCommandLine();
+ if (strLabel.isEmpty())
+ strLabel = tr("none");
+ ui->overriddenByCommandLineLabel->setText(strLabel);
+
+ mapper->setModel(model);
+ setMapper();
+ mapper->toFirst();
+ }
+
+ /* warn when one of the following settings changes by user action (placed here so init via mapper doesn't trigger them) */
+
+ /* Main */
+ connect(ui->databaseCache, SIGNAL(valueChanged(int)), this, SLOT(showRestartWarning()));
+ connect(ui->threadsScriptVerif, SIGNAL(valueChanged(int)), this, SLOT(showRestartWarning()));
+ /* Wallet */
+ connect(ui->spendZeroConfChange, SIGNAL(clicked(bool)), this, SLOT(showRestartWarning()));
+ /* Network */
+ connect(ui->allowIncoming, SIGNAL(clicked(bool)), this, SLOT(showRestartWarning()));
+ connect(ui->connectSocks, SIGNAL(clicked(bool)), this, SLOT(showRestartWarning()));
+ /* Display */
+ connect(ui->lang, SIGNAL(valueChanged()), this, SLOT(showRestartWarning()));
+ connect(ui->thirdPartyTxUrls, SIGNAL(textChanged(const QString &)), this, SLOT(showRestartWarning()));
+}
+
+void OptionsDialog::setMapper()
+{
+ /* Main */
+ mapper->addMapping(ui->bitcoinAtStartup, OptionsModel::StartAtStartup);
+ mapper->addMapping(ui->threadsScriptVerif, OptionsModel::ThreadsScriptVerif);
+ mapper->addMapping(ui->databaseCache, OptionsModel::DatabaseCache);
+
+ /* Wallet */
+ mapper->addMapping(ui->spendZeroConfChange, OptionsModel::SpendZeroConfChange);
+ mapper->addMapping(ui->coinControlFeatures, OptionsModel::CoinControlFeatures);
+
+ /* Network */
+ mapper->addMapping(ui->mapPortUpnp, OptionsModel::MapPortUPnP);
+ mapper->addMapping(ui->allowIncoming, OptionsModel::Listen);
+
+ mapper->addMapping(ui->connectSocks, OptionsModel::ProxyUse);
+ mapper->addMapping(ui->proxyIp, OptionsModel::ProxyIP);
+ mapper->addMapping(ui->proxyPort, OptionsModel::ProxyPort);
+
+ /* Window */
+#ifndef Q_OS_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->thirdPartyTxUrls, OptionsModel::ThirdPartyTxUrls);
+}
+
+void OptionsDialog::enableOkButton()
+{
+ /* prevent enabling of the OK button when data modified, if there is an invalid proxy address present */
+ if(fProxyIpValid)
+ setOkButtonState(true);
+}
+
+void OptionsDialog::disableOkButton()
+{
+ setOkButtonState(false);
+}
+
+void OptionsDialog::setOkButtonState(bool fState)
+{
+ ui->okButton->setEnabled(fState);
+}
+
+void OptionsDialog::on_resetButton_clicked()
+{
+ if(model)
+ {
+ // confirmation dialog
+ QMessageBox::StandardButton btnRetVal = QMessageBox::question(this, tr("Confirm options reset"),
+ tr("Client restart required to activate changes.") + "<br><br>" + tr("Client will be shut down. Do you want to proceed?"),
+ QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel);
+
+ if(btnRetVal == QMessageBox::Cancel)
+ return;
+
+ /* reset all options and close GUI */
+ model->Reset();
+ QApplication::quit();
+ }
+}
+
+void OptionsDialog::on_okButton_clicked()
+{
+ mapper->submit();
+ accept();
+}
+
+void OptionsDialog::on_cancelButton_clicked()
+{
+ reject();
+}
+
+void OptionsDialog::showRestartWarning(bool fPersistent)
+{
+ ui->statusLabel->setStyleSheet("QLabel { color: red; }");
+
+ if(fPersistent)
+ {
+ ui->statusLabel->setText(tr("Client restart required to activate changes."));
+ }
+ else
+ {
+ ui->statusLabel->setText(tr("This change would require a client restart."));
+ // clear non-persistent status label after 10 seconds
+ // Todo: should perhaps be a class attribute, if we extend the use of statusLabel
+ QTimer::singleShot(10000, this, SLOT(clearStatusLabel()));
+ }
+}
+
+void OptionsDialog::clearStatusLabel()
+{
+ ui->statusLabel->clear();
+}
+
+void OptionsDialog::doProxyIpChecks(QValidatedLineEdit *pUiProxyIp, int nProxyPort)
+{
+ Q_UNUSED(nProxyPort);
+
+ const std::string strAddrProxy = pUiProxyIp->text().toStdString();
+ CService addrProxy;
+
+ /* Check for a valid IPv4 / IPv6 address */
+ if (!(fProxyIpValid = LookupNumeric(strAddrProxy.c_str(), addrProxy)))
+ {
+ disableOkButton();
+ pUiProxyIp->setValid(false);
+ ui->statusLabel->setStyleSheet("QLabel { color: red; }");
+ ui->statusLabel->setText(tr("The supplied proxy address is invalid."));
+ }
+ else
+ {
+ enableOkButton();
+ ui->statusLabel->clear();
+ }
+}
+
+bool OptionsDialog::eventFilter(QObject *object, QEvent *event)
+{
+ if(event->type() == QEvent::FocusOut)
+ {
+ if(object == ui->proxyIp)
+ {
+ Q_EMIT proxyIpChecks(ui->proxyIp, ui->proxyPort->text().toInt());
+ }
+ }
+ return QDialog::eventFilter(object, event);
+}
diff --git a/src/qt/optionsdialog.h b/src/qt/optionsdialog.h
new file mode 100644
index 0000000000..fa983e798c
--- /dev/null
+++ b/src/qt/optionsdialog.h
@@ -0,0 +1,61 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_OPTIONSDIALOG_H
+#define BITCOIN_QT_OPTIONSDIALOG_H
+
+#include <QDialog>
+
+class OptionsModel;
+class QValidatedLineEdit;
+
+QT_BEGIN_NAMESPACE
+class QDataWidgetMapper;
+QT_END_NAMESPACE
+
+namespace Ui {
+class OptionsDialog;
+}
+
+/** Preferences dialog. */
+class OptionsDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit OptionsDialog(QWidget *parent, bool enableWallet);
+ ~OptionsDialog();
+
+ void setModel(OptionsModel *model);
+ void setMapper();
+
+protected:
+ bool eventFilter(QObject *object, QEvent *event);
+
+private Q_SLOTS:
+ /* enable OK button */
+ void enableOkButton();
+ /* disable OK button */
+ void disableOkButton();
+ /* set OK button state (enabled / disabled) */
+ void setOkButtonState(bool fState);
+ void on_resetButton_clicked();
+ void on_okButton_clicked();
+ void on_cancelButton_clicked();
+
+ void showRestartWarning(bool fPersistent = false);
+ void clearStatusLabel();
+ void doProxyIpChecks(QValidatedLineEdit *pUiProxyIp, int nProxyPort);
+
+Q_SIGNALS:
+ void proxyIpChecks(QValidatedLineEdit *pUiProxyIp, int nProxyPort);
+
+private:
+ Ui::OptionsDialog *ui;
+ OptionsModel *model;
+ QDataWidgetMapper *mapper;
+ bool fProxyIpValid;
+};
+
+#endif // BITCOIN_QT_OPTIONSDIALOG_H
diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp
new file mode 100644
index 0000000000..b4ce8191d0
--- /dev/null
+++ b/src/qt/optionsmodel.cpp
@@ -0,0 +1,359 @@
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#if defined(HAVE_CONFIG_H)
+#include "config/bitcoin-config.h"
+#endif
+
+#include "optionsmodel.h"
+
+#include "bitcoinunits.h"
+#include "guiutil.h"
+
+#include "amount.h"
+#include "init.h"
+#include "main.h"
+#include "net.h"
+#include "txdb.h" // for -dbcache defaults
+
+#ifdef ENABLE_WALLET
+#include "wallet/wallet.h"
+#include "wallet/walletdb.h"
+#endif
+
+#include <QNetworkProxy>
+#include <QSettings>
+#include <QStringList>
+
+OptionsModel::OptionsModel(QObject *parent) :
+ QAbstractListModel(parent)
+{
+ Init();
+}
+
+void OptionsModel::addOverriddenOption(const std::string &option)
+{
+ strOverriddenByCommandLine += QString::fromStdString(option) + "=" + QString::fromStdString(mapArgs[option]) + " ";
+}
+
+// Writes all missing QSettings with their default values
+void OptionsModel::Init()
+{
+ QSettings settings;
+
+ // Ensure restart flag is unset on client startup
+ setRestartRequired(false);
+
+ // These are Qt-only settings:
+
+ // Window
+ if (!settings.contains("fMinimizeToTray"))
+ settings.setValue("fMinimizeToTray", false);
+ fMinimizeToTray = settings.value("fMinimizeToTray").toBool();
+
+ if (!settings.contains("fMinimizeOnClose"))
+ settings.setValue("fMinimizeOnClose", false);
+ fMinimizeOnClose = settings.value("fMinimizeOnClose").toBool();
+
+ // Display
+ if (!settings.contains("nDisplayUnit"))
+ settings.setValue("nDisplayUnit", BitcoinUnits::BTC);
+ nDisplayUnit = settings.value("nDisplayUnit").toInt();
+
+ if (!settings.contains("strThirdPartyTxUrls"))
+ settings.setValue("strThirdPartyTxUrls", "");
+ strThirdPartyTxUrls = settings.value("strThirdPartyTxUrls", "").toString();
+
+ if (!settings.contains("fCoinControlFeatures"))
+ settings.setValue("fCoinControlFeatures", false);
+ fCoinControlFeatures = settings.value("fCoinControlFeatures", false).toBool();
+
+ // These are shared with the core or have a command-line parameter
+ // and we want command-line parameters to overwrite the GUI settings.
+ //
+ // If setting doesn't exist create it with defaults.
+ //
+ // If SoftSetArg() or SoftSetBoolArg() return false we were overridden
+ // by command-line and show this in the UI.
+
+ // Main
+ if (!settings.contains("nDatabaseCache"))
+ settings.setValue("nDatabaseCache", (qint64)nDefaultDbCache);
+ if (!SoftSetArg("-dbcache", settings.value("nDatabaseCache").toString().toStdString()))
+ addOverriddenOption("-dbcache");
+
+ if (!settings.contains("nThreadsScriptVerif"))
+ settings.setValue("nThreadsScriptVerif", DEFAULT_SCRIPTCHECK_THREADS);
+ if (!SoftSetArg("-par", settings.value("nThreadsScriptVerif").toString().toStdString()))
+ addOverriddenOption("-par");
+
+ // Wallet
+#ifdef ENABLE_WALLET
+ if (!settings.contains("bSpendZeroConfChange"))
+ settings.setValue("bSpendZeroConfChange", true);
+ if (!SoftSetBoolArg("-spendzeroconfchange", settings.value("bSpendZeroConfChange").toBool()))
+ addOverriddenOption("-spendzeroconfchange");
+#endif
+
+ // Network
+ if (!settings.contains("fUseUPnP"))
+ settings.setValue("fUseUPnP", DEFAULT_UPNP);
+ if (!SoftSetBoolArg("-upnp", settings.value("fUseUPnP").toBool()))
+ addOverriddenOption("-upnp");
+
+ if (!settings.contains("fListen"))
+ settings.setValue("fListen", DEFAULT_LISTEN);
+ if (!SoftSetBoolArg("-listen", settings.value("fListen").toBool()))
+ addOverriddenOption("-listen");
+
+ if (!settings.contains("fUseProxy"))
+ settings.setValue("fUseProxy", false);
+ if (!settings.contains("addrProxy"))
+ settings.setValue("addrProxy", "127.0.0.1:9050");
+ // Only try to set -proxy, if user has enabled fUseProxy
+ if (settings.value("fUseProxy").toBool() && !SoftSetArg("-proxy", settings.value("addrProxy").toString().toStdString()))
+ addOverriddenOption("-proxy");
+ else if(!settings.value("fUseProxy").toBool() && !GetArg("-proxy", "").empty())
+ addOverriddenOption("-proxy");
+
+ // Display
+ if (!settings.contains("language"))
+ settings.setValue("language", "");
+ if (!SoftSetArg("-lang", settings.value("language").toString().toStdString()))
+ addOverriddenOption("-lang");
+
+ language = settings.value("language").toString();
+}
+
+void OptionsModel::Reset()
+{
+ QSettings settings;
+
+ // Remove all entries from our QSettings object
+ settings.clear();
+
+ // default setting for OptionsModel::StartAtStartup - disabled
+ if (GUIUtil::GetStartOnSystemStartup())
+ GUIUtil::SetStartOnSystemStartup(false);
+}
+
+int OptionsModel::rowCount(const QModelIndex & parent) const
+{
+ return OptionIDRowCount;
+}
+
+// read QSettings values and return them
+QVariant OptionsModel::data(const QModelIndex & index, int role) const
+{
+ if(role == Qt::EditRole)
+ {
+ QSettings settings;
+ switch(index.row())
+ {
+ case StartAtStartup:
+ return GUIUtil::GetStartOnSystemStartup();
+ case MinimizeToTray:
+ return fMinimizeToTray;
+ case MapPortUPnP:
+#ifdef USE_UPNP
+ return settings.value("fUseUPnP");
+#else
+ return false;
+#endif
+ case MinimizeOnClose:
+ return fMinimizeOnClose;
+
+ // default proxy
+ case ProxyUse:
+ return settings.value("fUseProxy", false);
+ case ProxyIP: {
+ // contains IP at index 0 and port at index 1
+ QStringList strlIpPort = settings.value("addrProxy").toString().split(":", QString::SkipEmptyParts);
+ return strlIpPort.at(0);
+ }
+ case ProxyPort: {
+ // contains IP at index 0 and port at index 1
+ QStringList strlIpPort = settings.value("addrProxy").toString().split(":", QString::SkipEmptyParts);
+ return strlIpPort.at(1);
+ }
+
+#ifdef ENABLE_WALLET
+ case SpendZeroConfChange:
+ return settings.value("bSpendZeroConfChange");
+#endif
+ case DisplayUnit:
+ return nDisplayUnit;
+ case ThirdPartyTxUrls:
+ return strThirdPartyTxUrls;
+ case Language:
+ return settings.value("language");
+ case CoinControlFeatures:
+ return fCoinControlFeatures;
+ case DatabaseCache:
+ return settings.value("nDatabaseCache");
+ case ThreadsScriptVerif:
+ return settings.value("nThreadsScriptVerif");
+ case Listen:
+ return settings.value("fListen");
+ default:
+ return QVariant();
+ }
+ }
+ return QVariant();
+}
+
+// write QSettings values
+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: // core option - can be changed on-the-fly
+ settings.setValue("fUseUPnP", value.toBool());
+ MapPort(value.toBool());
+ break;
+ case MinimizeOnClose:
+ fMinimizeOnClose = value.toBool();
+ settings.setValue("fMinimizeOnClose", fMinimizeOnClose);
+ break;
+
+ // default proxy
+ case ProxyUse:
+ if (settings.value("fUseProxy") != value) {
+ settings.setValue("fUseProxy", value.toBool());
+ setRestartRequired(true);
+ }
+ break;
+ case ProxyIP: {
+ // contains current IP at index 0 and current port at index 1
+ QStringList strlIpPort = settings.value("addrProxy").toString().split(":", QString::SkipEmptyParts);
+ // if that key doesn't exist or has a changed IP
+ if (!settings.contains("addrProxy") || strlIpPort.at(0) != value.toString()) {
+ // construct new value from new IP and current port
+ QString strNewValue = value.toString() + ":" + strlIpPort.at(1);
+ settings.setValue("addrProxy", strNewValue);
+ setRestartRequired(true);
+ }
+ }
+ break;
+ case ProxyPort: {
+ // contains current IP at index 0 and current port at index 1
+ QStringList strlIpPort = settings.value("addrProxy").toString().split(":", QString::SkipEmptyParts);
+ // if that key doesn't exist or has a changed port
+ if (!settings.contains("addrProxy") || strlIpPort.at(1) != value.toString()) {
+ // construct new value from current IP and new port
+ QString strNewValue = strlIpPort.at(0) + ":" + value.toString();
+ settings.setValue("addrProxy", strNewValue);
+ setRestartRequired(true);
+ }
+ }
+ break;
+#ifdef ENABLE_WALLET
+ case SpendZeroConfChange:
+ if (settings.value("bSpendZeroConfChange") != value) {
+ settings.setValue("bSpendZeroConfChange", value);
+ setRestartRequired(true);
+ }
+ break;
+#endif
+ case DisplayUnit:
+ setDisplayUnit(value);
+ break;
+ case ThirdPartyTxUrls:
+ if (strThirdPartyTxUrls != value.toString()) {
+ strThirdPartyTxUrls = value.toString();
+ settings.setValue("strThirdPartyTxUrls", strThirdPartyTxUrls);
+ setRestartRequired(true);
+ }
+ break;
+ case Language:
+ if (settings.value("language") != value) {
+ settings.setValue("language", value);
+ setRestartRequired(true);
+ }
+ break;
+ case CoinControlFeatures:
+ fCoinControlFeatures = value.toBool();
+ settings.setValue("fCoinControlFeatures", fCoinControlFeatures);
+ Q_EMIT coinControlFeaturesChanged(fCoinControlFeatures);
+ break;
+ case DatabaseCache:
+ if (settings.value("nDatabaseCache") != value) {
+ settings.setValue("nDatabaseCache", value);
+ setRestartRequired(true);
+ }
+ break;
+ case ThreadsScriptVerif:
+ if (settings.value("nThreadsScriptVerif") != value) {
+ settings.setValue("nThreadsScriptVerif", value);
+ setRestartRequired(true);
+ }
+ break;
+ case Listen:
+ if (settings.value("fListen") != value) {
+ settings.setValue("fListen", value);
+ setRestartRequired(true);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ Q_EMIT dataChanged(index, index);
+
+ return successful;
+}
+
+/** Updates current unit in memory, settings and emits displayUnitChanged(newUnit) signal */
+void OptionsModel::setDisplayUnit(const QVariant &value)
+{
+ if (!value.isNull())
+ {
+ QSettings settings;
+ nDisplayUnit = value.toInt();
+ settings.setValue("nDisplayUnit", nDisplayUnit);
+ Q_EMIT displayUnitChanged(nDisplayUnit);
+ }
+}
+
+bool OptionsModel::getProxySettings(QNetworkProxy& proxy) const
+{
+ // Directly query current base proxy, because
+ // GUI settings can be overridden with -proxy.
+ proxyType curProxy;
+ if (GetProxy(NET_IPV4, curProxy)) {
+ proxy.setType(QNetworkProxy::Socks5Proxy);
+ proxy.setHostName(QString::fromStdString(curProxy.proxy.ToStringIP()));
+ proxy.setPort(curProxy.proxy.GetPort());
+
+ return true;
+ }
+ else
+ proxy.setType(QNetworkProxy::NoProxy);
+
+ return false;
+}
+
+void OptionsModel::setRestartRequired(bool fRequired)
+{
+ QSettings settings;
+ return settings.setValue("fRestartRequired", fRequired);
+}
+
+bool OptionsModel::isRestartRequired()
+{
+ QSettings settings;
+ return settings.value("fRestartRequired", false).toBool();
+}
diff --git a/src/qt/optionsmodel.h b/src/qt/optionsmodel.h
new file mode 100644
index 0000000000..fc26d65b04
--- /dev/null
+++ b/src/qt/optionsmodel.h
@@ -0,0 +1,89 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_OPTIONSMODEL_H
+#define BITCOIN_QT_OPTIONSMODEL_H
+
+#include "amount.h"
+
+#include <QAbstractListModel>
+
+QT_BEGIN_NAMESPACE
+class QNetworkProxy;
+QT_END_NAMESPACE
+
+/** 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
+ DisplayUnit, // BitcoinUnits::Unit
+ ThirdPartyTxUrls, // QString
+ Language, // QString
+ CoinControlFeatures, // bool
+ ThreadsScriptVerif, // int
+ DatabaseCache, // int
+ SpendZeroConfChange, // bool
+ Listen, // bool
+ OptionIDRowCount,
+ };
+
+ void Init();
+ void Reset();
+
+ 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);
+ /** Updates current unit in memory, settings and emits displayUnitChanged(newUnit) signal */
+ void setDisplayUnit(const QVariant &value);
+
+ /* Explicit getters */
+ bool getMinimizeToTray() { return fMinimizeToTray; }
+ bool getMinimizeOnClose() { return fMinimizeOnClose; }
+ int getDisplayUnit() { return nDisplayUnit; }
+ QString getThirdPartyTxUrls() { return strThirdPartyTxUrls; }
+ bool getProxySettings(QNetworkProxy& proxy) const;
+ bool getCoinControlFeatures() { return fCoinControlFeatures; }
+ const QString& getOverriddenByCommandLine() { return strOverriddenByCommandLine; }
+
+ /* Restart flag helper */
+ void setRestartRequired(bool fRequired);
+ bool isRestartRequired();
+
+private:
+ /* Qt-only settings */
+ bool fMinimizeToTray;
+ bool fMinimizeOnClose;
+ QString language;
+ int nDisplayUnit;
+ QString strThirdPartyTxUrls;
+ bool fCoinControlFeatures;
+ /* settings that were overriden by command-line */
+ QString strOverriddenByCommandLine;
+
+ /// Add option to list of GUI options overridden through command line/config file
+ void addOverriddenOption(const std::string &option);
+
+Q_SIGNALS:
+ void displayUnitChanged(int unit);
+ void coinControlFeaturesChanged(bool);
+};
+
+#endif // BITCOIN_QT_OPTIONSMODEL_H
diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp
new file mode 100644
index 0000000000..bbd95ef478
--- /dev/null
+++ b/src/qt/overviewpage.cpp
@@ -0,0 +1,264 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "overviewpage.h"
+#include "ui_overviewpage.h"
+
+#include "bitcoinunits.h"
+#include "clientmodel.h"
+#include "guiconstants.h"
+#include "guiutil.h"
+#include "optionsmodel.h"
+#include "scicon.h"
+#include "transactionfilterproxy.h"
+#include "transactiontablemodel.h"
+#include "walletmodel.h"
+
+#include <QAbstractItemDelegate>
+#include <QPainter>
+
+#define DECORATION_SIZE 54
+#define NUM_ITEMS 5
+
+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<QIcon>(index.data(TransactionTableModel::RawDecorationRole));
+ 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 = SingleColorIcon(icon, SingleColor());
+ 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(value.canConvert<QBrush>())
+ {
+ QBrush brush = qvariant_cast<QBrush>(value);
+ foreground = brush.color();
+ }
+
+ painter->setPen(foreground);
+ QRect boundingRect;
+ painter->drawText(addressRect, Qt::AlignLeft|Qt::AlignVCenter, address, &boundingRect);
+
+ if (index.data(TransactionTableModel::WatchonlyRole).toBool())
+ {
+ QIcon iconWatchonly = qvariant_cast<QIcon>(index.data(TransactionTableModel::WatchonlyDecorationRole));
+ QRect watchonlyRect(boundingRect.right() + 5, mainRect.top()+ypad+halfheight, 16, halfheight);
+ iconWatchonly.paint(painter, watchonlyRect);
+ }
+
+ 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, BitcoinUnits::separatorAlways);
+ 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),
+ clientModel(0),
+ walletModel(0),
+ currentBalance(-1),
+ currentUnconfirmedBalance(-1),
+ currentImmatureBalance(-1),
+ currentWatchOnlyBalance(-1),
+ currentWatchUnconfBalance(-1),
+ currentWatchImmatureBalance(-1),
+ txdelegate(new TxViewDelegate()),
+ filter(0)
+{
+ ui->setupUi(this);
+
+ // use a SingleColorIcon for the "out of sync warning" icon
+ QIcon icon = SingleColorIcon(":/icons/warning");
+ icon.addPixmap(icon.pixmap(QSize(64,64), QIcon::Normal), QIcon::Disabled); // also set the disabled icon because we are using a disabled QPushButton to work around missing HiDPI support of QLabel (https://bugreports.qt.io/browse/QTBUG-42503)
+ ui->labelTransactionsStatus->setIcon(icon);
+ ui->labelWalletStatus->setIcon(icon);
+
+ // 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)));
+
+ // start with displaying the "out of sync" warnings
+ showOutOfSyncWarning(true);
+}
+
+void OverviewPage::handleTransactionClicked(const QModelIndex &index)
+{
+ if(filter)
+ Q_EMIT transactionClicked(filter->mapToSource(index));
+}
+
+OverviewPage::~OverviewPage()
+{
+ delete ui;
+}
+
+void OverviewPage::setBalance(const CAmount& balance, const CAmount& unconfirmedBalance, const CAmount& immatureBalance, const CAmount& watchOnlyBalance, const CAmount& watchUnconfBalance, const CAmount& watchImmatureBalance)
+{
+ int unit = walletModel->getOptionsModel()->getDisplayUnit();
+ currentBalance = balance;
+ currentUnconfirmedBalance = unconfirmedBalance;
+ currentImmatureBalance = immatureBalance;
+ currentWatchOnlyBalance = watchOnlyBalance;
+ currentWatchUnconfBalance = watchUnconfBalance;
+ currentWatchImmatureBalance = watchImmatureBalance;
+ ui->labelBalance->setText(BitcoinUnits::formatWithUnit(unit, balance, false, BitcoinUnits::separatorAlways));
+ ui->labelUnconfirmed->setText(BitcoinUnits::formatWithUnit(unit, unconfirmedBalance, false, BitcoinUnits::separatorAlways));
+ ui->labelImmature->setText(BitcoinUnits::formatWithUnit(unit, immatureBalance, false, BitcoinUnits::separatorAlways));
+ ui->labelTotal->setText(BitcoinUnits::formatWithUnit(unit, balance + unconfirmedBalance + immatureBalance, false, BitcoinUnits::separatorAlways));
+ ui->labelWatchAvailable->setText(BitcoinUnits::formatWithUnit(unit, watchOnlyBalance, false, BitcoinUnits::separatorAlways));
+ ui->labelWatchPending->setText(BitcoinUnits::formatWithUnit(unit, watchUnconfBalance, false, BitcoinUnits::separatorAlways));
+ ui->labelWatchImmature->setText(BitcoinUnits::formatWithUnit(unit, watchImmatureBalance, false, BitcoinUnits::separatorAlways));
+ ui->labelWatchTotal->setText(BitcoinUnits::formatWithUnit(unit, watchOnlyBalance + watchUnconfBalance + watchImmatureBalance, false, BitcoinUnits::separatorAlways));
+
+ // 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;
+ bool showWatchOnlyImmature = watchImmatureBalance != 0;
+
+ // for symmetry reasons also show immature label when the watch-only one is shown
+ ui->labelImmature->setVisible(showImmature || showWatchOnlyImmature);
+ ui->labelImmatureText->setVisible(showImmature || showWatchOnlyImmature);
+ ui->labelWatchImmature->setVisible(showWatchOnlyImmature); // show watch-only immature balance
+}
+
+// show/hide watch-only labels
+void OverviewPage::updateWatchOnlyLabels(bool showWatchOnly)
+{
+ ui->labelSpendable->setVisible(showWatchOnly); // show spendable label (only when watch-only is active)
+ ui->labelWatchonly->setVisible(showWatchOnly); // show watch-only label
+ ui->lineWatchBalance->setVisible(showWatchOnly); // show watch-only balance separator line
+ ui->labelWatchAvailable->setVisible(showWatchOnly); // show watch-only available balance
+ ui->labelWatchPending->setVisible(showWatchOnly); // show watch-only pending balance
+ ui->labelWatchTotal->setVisible(showWatchOnly); // show watch-only total balance
+
+ if (!showWatchOnly)
+ ui->labelWatchImmature->hide();
+}
+
+void OverviewPage::setClientModel(ClientModel *model)
+{
+ this->clientModel = model;
+ if(model)
+ {
+ // Show warning if this is a prerelease version
+ connect(model, SIGNAL(alertsChanged(QString)), this, SLOT(updateAlerts(QString)));
+ updateAlerts(model->getStatusBarWarnings());
+ }
+}
+
+void OverviewPage::setWalletModel(WalletModel *model)
+{
+ this->walletModel = 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->setShowInactive(false);
+ 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(),
+ model->getWatchBalance(), model->getWatchUnconfirmedBalance(), model->getWatchImmatureBalance());
+ connect(model, SIGNAL(balanceChanged(CAmount,CAmount,CAmount,CAmount,CAmount,CAmount)), this, SLOT(setBalance(CAmount,CAmount,CAmount,CAmount,CAmount,CAmount)));
+
+ connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
+
+ updateWatchOnlyLabels(model->haveWatchOnly());
+ connect(model, SIGNAL(notifyWatchonlyChanged(bool)), this, SLOT(updateWatchOnlyLabels(bool)));
+ }
+
+ // update the display unit, to not use the default ("BTC")
+ updateDisplayUnit();
+}
+
+void OverviewPage::updateDisplayUnit()
+{
+ if(walletModel && walletModel->getOptionsModel())
+ {
+ if(currentBalance != -1)
+ setBalance(currentBalance, currentUnconfirmedBalance, currentImmatureBalance,
+ currentWatchOnlyBalance, currentWatchUnconfBalance, currentWatchImmatureBalance);
+
+ // Update txdelegate->unit with the current unit
+ txdelegate->unit = walletModel->getOptionsModel()->getDisplayUnit();
+
+ ui->listTransactions->update();
+ }
+}
+
+void OverviewPage::updateAlerts(const QString &warnings)
+{
+ this->ui->labelAlerts->setVisible(!warnings.isEmpty());
+ this->ui->labelAlerts->setText(warnings);
+}
+
+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 0000000000..de5ac345da
--- /dev/null
+++ b/src/qt/overviewpage.h
@@ -0,0 +1,66 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_OVERVIEWPAGE_H
+#define BITCOIN_QT_OVERVIEWPAGE_H
+
+#include "amount.h"
+
+#include <QWidget>
+
+class ClientModel;
+class TransactionFilterProxy;
+class TxViewDelegate;
+class WalletModel;
+
+namespace Ui {
+ class OverviewPage;
+}
+
+QT_BEGIN_NAMESPACE
+class QModelIndex;
+QT_END_NAMESPACE
+
+/** Overview ("home") page widget */
+class OverviewPage : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit OverviewPage(QWidget *parent = 0);
+ ~OverviewPage();
+
+ void setClientModel(ClientModel *clientModel);
+ void setWalletModel(WalletModel *walletModel);
+ void showOutOfSyncWarning(bool fShow);
+
+public Q_SLOTS:
+ void setBalance(const CAmount& balance, const CAmount& unconfirmedBalance, const CAmount& immatureBalance,
+ const CAmount& watchOnlyBalance, const CAmount& watchUnconfBalance, const CAmount& watchImmatureBalance);
+
+Q_SIGNALS:
+ void transactionClicked(const QModelIndex &index);
+
+private:
+ Ui::OverviewPage *ui;
+ ClientModel *clientModel;
+ WalletModel *walletModel;
+ CAmount currentBalance;
+ CAmount currentUnconfirmedBalance;
+ CAmount currentImmatureBalance;
+ CAmount currentWatchOnlyBalance;
+ CAmount currentWatchUnconfBalance;
+ CAmount currentWatchImmatureBalance;
+
+ TxViewDelegate *txdelegate;
+ TransactionFilterProxy *filter;
+
+private Q_SLOTS:
+ void updateDisplayUnit();
+ void handleTransactionClicked(const QModelIndex &index);
+ void updateAlerts(const QString &warnings);
+ void updateWatchOnlyLabels(bool showWatchOnly);
+};
+
+#endif // BITCOIN_QT_OVERVIEWPAGE_H
diff --git a/src/qt/paymentrequest.proto b/src/qt/paymentrequest.proto
new file mode 100644
index 0000000000..b2281c4c7b
--- /dev/null
+++ b/src/qt/paymentrequest.proto
@@ -0,0 +1,46 @@
+//
+// Simple Bitcoin Payment Protocol messages
+//
+// Use fields 100+ for extensions;
+// to avoid conflicts, register extensions at:
+// https://en.bitcoin.it/wiki/Payment_Request
+//
+
+package payments;
+option java_package = "org.bitcoin.protocols.payments";
+option java_outer_classname = "Protos";
+
+// Generalized form of "send payment to this/these bitcoin addresses"
+message Output {
+ optional uint64 amount = 1 [default = 0]; // amount is integer-number-of-satoshis
+ required bytes script = 2; // usually one of the standard Script forms
+}
+message PaymentDetails {
+ optional string network = 1 [default = "main"]; // "main" or "test"
+ repeated Output outputs = 2; // Where payment should be sent
+ required uint64 time = 3; // Timestamp; when payment request created
+ optional uint64 expires = 4; // Timestamp; when this request should be considered invalid
+ optional string memo = 5; // Human-readable description of request for the customer
+ optional string payment_url = 6; // URL to send Payment and get PaymentACK
+ optional bytes merchant_data = 7; // Arbitrary data to include in the Payment message
+}
+message PaymentRequest {
+ optional uint32 payment_details_version = 1 [default = 1];
+ optional string pki_type = 2 [default = "none"]; // none / x509+sha256 / x509+sha1
+ optional bytes pki_data = 3; // depends on pki_type
+ required bytes serialized_payment_details = 4; // PaymentDetails
+ optional bytes signature = 5; // pki-dependent signature
+}
+message X509Certificates {
+ repeated bytes certificate = 1; // DER-encoded X.509 certificate chain
+}
+message Payment {
+ optional bytes merchant_data = 1; // From PaymentDetails.merchant_data
+ repeated bytes transactions = 2; // Signed transactions that satisfy PaymentDetails.outputs
+ repeated Output refund_to = 3; // Where to send refunds, if a refund is necessary
+ optional string memo = 4; // Human-readable message for the merchant
+}
+message PaymentACK {
+ required Payment payment = 1; // Payment message that triggered this ACK
+ optional string memo = 2; // human-readable message for customer
+}
diff --git a/src/qt/paymentrequestplus.cpp b/src/qt/paymentrequestplus.cpp
new file mode 100644
index 0000000000..7e9729eeb9
--- /dev/null
+++ b/src/qt/paymentrequestplus.cpp
@@ -0,0 +1,209 @@
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+//
+// Wraps dumb protocol buffer paymentRequest
+// with some extra methods
+//
+
+#include "paymentrequestplus.h"
+
+#include "util.h"
+
+#include <stdexcept>
+
+#include <openssl/x509_vfy.h>
+
+#include <QDateTime>
+#include <QDebug>
+#include <QSslCertificate>
+
+using namespace std;
+
+class SSLVerifyError : public std::runtime_error
+{
+public:
+ SSLVerifyError(std::string err) : std::runtime_error(err) { }
+};
+
+bool PaymentRequestPlus::parse(const QByteArray& data)
+{
+ bool parseOK = paymentRequest.ParseFromArray(data.data(), data.size());
+ if (!parseOK) {
+ qWarning() << "PaymentRequestPlus::parse: Error parsing payment request";
+ return false;
+ }
+ if (paymentRequest.payment_details_version() > 1) {
+ qWarning() << "PaymentRequestPlus::parse: Received up-version payment details, version=" << paymentRequest.payment_details_version();
+ return false;
+ }
+
+ parseOK = details.ParseFromString(paymentRequest.serialized_payment_details());
+ if (!parseOK)
+ {
+ qWarning() << "PaymentRequestPlus::parse: Error parsing payment details";
+ paymentRequest.Clear();
+ return false;
+ }
+ return true;
+}
+
+bool PaymentRequestPlus::SerializeToString(string* output) const
+{
+ return paymentRequest.SerializeToString(output);
+}
+
+bool PaymentRequestPlus::IsInitialized() const
+{
+ return paymentRequest.IsInitialized();
+}
+
+bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) const
+{
+ merchant.clear();
+
+ if (!IsInitialized())
+ return false;
+
+ // One day we'll support more PKI types, but just
+ // x509 for now:
+ const EVP_MD* digestAlgorithm = NULL;
+ if (paymentRequest.pki_type() == "x509+sha256") {
+ digestAlgorithm = EVP_sha256();
+ }
+ else if (paymentRequest.pki_type() == "x509+sha1") {
+ digestAlgorithm = EVP_sha1();
+ }
+ else if (paymentRequest.pki_type() == "none") {
+ qWarning() << "PaymentRequestPlus::getMerchant: Payment request: pki_type == none";
+ return false;
+ }
+ else {
+ qWarning() << "PaymentRequestPlus::getMerchant: Payment request: unknown pki_type " << QString::fromStdString(paymentRequest.pki_type());
+ return false;
+ }
+
+ payments::X509Certificates certChain;
+ if (!certChain.ParseFromString(paymentRequest.pki_data())) {
+ qWarning() << "PaymentRequestPlus::getMerchant: Payment request: error parsing pki_data";
+ return false;
+ }
+
+ std::vector<X509*> certs;
+ const QDateTime currentTime = QDateTime::currentDateTime();
+ for (int i = 0; i < certChain.certificate_size(); i++) {
+ QByteArray certData(certChain.certificate(i).data(), certChain.certificate(i).size());
+ QSslCertificate qCert(certData, QSsl::Der);
+ if (currentTime < qCert.effectiveDate() || currentTime > qCert.expiryDate()) {
+ qWarning() << "PaymentRequestPlus::getMerchant: Payment request: certificate expired or not yet active: " << qCert;
+ return false;
+ }
+#if QT_VERSION >= 0x050000
+ if (qCert.isBlacklisted()) {
+ qWarning() << "PaymentRequestPlus::getMerchant: Payment request: certificate blacklisted: " << qCert;
+ return false;
+ }
+#endif
+ const unsigned char *data = (const unsigned char *)certChain.certificate(i).data();
+ X509 *cert = d2i_X509(NULL, &data, certChain.certificate(i).size());
+ if (cert)
+ certs.push_back(cert);
+ }
+ if (certs.empty()) {
+ qWarning() << "PaymentRequestPlus::getMerchant: Payment request: empty certificate chain";
+ return false;
+ }
+
+ // The first cert is the signing cert, the rest are untrusted certs that chain
+ // to a valid root authority. OpenSSL needs them separately.
+ STACK_OF(X509) *chain = sk_X509_new_null();
+ for (int i = certs.size() - 1; i > 0; i--) {
+ sk_X509_push(chain, certs[i]);
+ }
+ X509 *signing_cert = certs[0];
+
+ // Now create a "store context", which is a single use object for checking,
+ // load the signing cert into it and verify.
+ X509_STORE_CTX *store_ctx = X509_STORE_CTX_new();
+ if (!store_ctx) {
+ qWarning() << "PaymentRequestPlus::getMerchant: Payment request: error creating X509_STORE_CTX";
+ return false;
+ }
+
+ char *website = NULL;
+ bool fResult = true;
+ try
+ {
+ if (!X509_STORE_CTX_init(store_ctx, certStore, signing_cert, chain))
+ {
+ int error = X509_STORE_CTX_get_error(store_ctx);
+ throw SSLVerifyError(X509_verify_cert_error_string(error));
+ }
+
+ // Now do the verification!
+ int result = X509_verify_cert(store_ctx);
+ if (result != 1) {
+ int error = X509_STORE_CTX_get_error(store_ctx);
+ // For testing payment requests, we allow self signed root certs!
+ // This option is just shown in the UI options, if -help-debug is enabled.
+ if (!(error == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT && GetBoolArg("-allowselfsignedrootcertificates", false))) {
+ throw SSLVerifyError(X509_verify_cert_error_string(error));
+ } else {
+ qDebug() << "PaymentRequestPlus::getMerchant: Allowing self signed root certificate, because -allowselfsignedrootcertificates is true.";
+ }
+ }
+ X509_NAME *certname = X509_get_subject_name(signing_cert);
+
+ // Valid cert; check signature:
+ payments::PaymentRequest rcopy(paymentRequest); // Copy
+ rcopy.set_signature(std::string(""));
+ std::string data_to_verify; // Everything but the signature
+ rcopy.SerializeToString(&data_to_verify);
+
+ EVP_MD_CTX ctx;
+ EVP_PKEY *pubkey = X509_get_pubkey(signing_cert);
+ EVP_MD_CTX_init(&ctx);
+ if (!EVP_VerifyInit_ex(&ctx, digestAlgorithm, NULL) ||
+ !EVP_VerifyUpdate(&ctx, data_to_verify.data(), data_to_verify.size()) ||
+ !EVP_VerifyFinal(&ctx, (const unsigned char*)paymentRequest.signature().data(), (unsigned int)paymentRequest.signature().size(), pubkey)) {
+ throw SSLVerifyError("Bad signature, invalid payment request.");
+ }
+
+ // OpenSSL API for getting human printable strings from certs is baroque.
+ int textlen = X509_NAME_get_text_by_NID(certname, NID_commonName, NULL, 0);
+ website = new char[textlen + 1];
+ if (X509_NAME_get_text_by_NID(certname, NID_commonName, website, textlen + 1) == textlen && textlen > 0) {
+ merchant = website;
+ }
+ else {
+ throw SSLVerifyError("Bad certificate, missing common name.");
+ }
+ // TODO: detect EV certificates and set merchant = business name instead of unfriendly NID_commonName ?
+ }
+ catch (const SSLVerifyError& err) {
+ fResult = false;
+ qWarning() << "PaymentRequestPlus::getMerchant: SSL error: " << err.what();
+ }
+
+ if (website)
+ delete[] website;
+ X509_STORE_CTX_free(store_ctx);
+ for (unsigned int i = 0; i < certs.size(); i++)
+ X509_free(certs[i]);
+
+ return fResult;
+}
+
+QList<std::pair<CScript,CAmount> > PaymentRequestPlus::getPayTo() const
+{
+ QList<std::pair<CScript,CAmount> > result;
+ for (int i = 0; i < details.outputs_size(); i++)
+ {
+ const unsigned char* scriptStr = (const unsigned char*)details.outputs(i).script().data();
+ CScript s(scriptStr, scriptStr+details.outputs(i).script().size());
+
+ result.append(make_pair(s, details.outputs(i).amount()));
+ }
+ return result;
+}
diff --git a/src/qt/paymentrequestplus.h b/src/qt/paymentrequestplus.h
new file mode 100644
index 0000000000..99a7186b85
--- /dev/null
+++ b/src/qt/paymentrequestplus.h
@@ -0,0 +1,46 @@
+// Copyright (c) 2011-2014 The Bitcoin developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_PAYMENTREQUESTPLUS_H
+#define BITCOIN_QT_PAYMENTREQUESTPLUS_H
+
+#include "paymentrequest.pb.h"
+
+#include "base58.h"
+
+#include <openssl/x509.h>
+
+#include <QByteArray>
+#include <QList>
+#include <QString>
+
+//
+// Wraps dumb protocol buffer paymentRequest
+// with extra methods
+//
+
+class PaymentRequestPlus
+{
+public:
+ PaymentRequestPlus() { }
+
+ bool parse(const QByteArray& data);
+ bool SerializeToString(std::string* output) const;
+
+ bool IsInitialized() const;
+ // Returns true if merchant's identity is authenticated, and
+ // returns human-readable merchant identity in merchant
+ bool getMerchant(X509_STORE* certStore, QString& merchant) const;
+
+ // Returns list of outputs, amount
+ QList<std::pair<CScript,CAmount> > getPayTo() const;
+
+ const payments::PaymentDetails& getDetails() const { return details; }
+
+private:
+ payments::PaymentRequest paymentRequest;
+ payments::PaymentDetails details;
+};
+
+#endif // BITCOIN_QT_PAYMENTREQUESTPLUS_H
diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp
new file mode 100644
index 0000000000..0e21d4e1f6
--- /dev/null
+++ b/src/qt/paymentserver.cpp
@@ -0,0 +1,805 @@
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "paymentserver.h"
+
+#include "bitcoinunits.h"
+#include "guiutil.h"
+#include "optionsmodel.h"
+
+#include "base58.h"
+#include "chainparams.h"
+#include "main.h"
+#include "ui_interface.h"
+#include "util.h"
+#include "wallet/wallet.h"
+
+#include <cstdlib>
+
+#include <openssl/x509_vfy.h>
+
+#include <QApplication>
+#include <QByteArray>
+#include <QDataStream>
+#include <QDateTime>
+#include <QDebug>
+#include <QFile>
+#include <QFileOpenEvent>
+#include <QHash>
+#include <QList>
+#include <QLocalServer>
+#include <QLocalSocket>
+#include <QNetworkAccessManager>
+#include <QNetworkProxy>
+#include <QNetworkReply>
+#include <QNetworkRequest>
+#include <QSslCertificate>
+#include <QSslError>
+#include <QSslSocket>
+#include <QStringList>
+#include <QTextDocument>
+
+#if QT_VERSION < 0x050000
+#include <QUrl>
+#else
+#include <QUrlQuery>
+#endif
+
+using namespace std;
+
+const int BITCOIN_IPC_CONNECT_TIMEOUT = 1000; // milliseconds
+const QString BITCOIN_IPC_PREFIX("bitcoin:");
+// BIP70 payment protocol messages
+const char* BIP70_MESSAGE_PAYMENTACK = "PaymentACK";
+const char* BIP70_MESSAGE_PAYMENTREQUEST = "PaymentRequest";
+// BIP71 payment protocol media types
+const char* BIP71_MIMETYPE_PAYMENT = "application/bitcoin-payment";
+const char* BIP71_MIMETYPE_PAYMENTACK = "application/bitcoin-paymentack";
+const char* BIP71_MIMETYPE_PAYMENTREQUEST = "application/bitcoin-paymentrequest";
+// BIP70 max payment request size in bytes (DoS protection)
+const qint64 BIP70_MAX_PAYMENTREQUEST_SIZE = 50000;
+
+X509_STORE* PaymentServer::certStore = NULL;
+void PaymentServer::freeCertStore()
+{
+ if (PaymentServer::certStore != NULL)
+ {
+ X509_STORE_free(PaymentServer::certStore);
+ PaymentServer::certStore = NULL;
+ }
+}
+
+//
+// Create a name that is unique for:
+// testnet / non-testnet
+// data directory
+//
+static QString ipcServerName()
+{
+ QString name("BitcoinQt");
+
+ // Append a simple hash of the datadir
+ // Note that GetDataDir(true) returns a different path
+ // for -testnet versus main net
+ QString ddir(QString::fromStdString(GetDataDir(true).string()));
+ name.append(QString::number(qHash(ddir)));
+
+ return name;
+}
+
+//
+// We store payment URIs and requests received before
+// the main GUI window is up and ready to ask the user
+// to send payment.
+
+static QList<QString> savedPaymentRequests;
+
+static void ReportInvalidCertificate(const QSslCertificate& cert)
+{
+#if QT_VERSION < 0x050000
+ qDebug() << QString("%1: Payment server found an invalid certificate: ").arg(__func__) << cert.serialNumber() << cert.subjectInfo(QSslCertificate::CommonName) << cert.subjectInfo(QSslCertificate::OrganizationalUnitName);
+#else
+ qDebug() << QString("%1: Payment server found an invalid certificate: ").arg(__func__) << cert.serialNumber() << cert.subjectInfo(QSslCertificate::CommonName) << cert.subjectInfo(QSslCertificate::DistinguishedNameQualifier) << cert.subjectInfo(QSslCertificate::OrganizationalUnitName);
+#endif
+}
+
+//
+// Load OpenSSL's list of root certificate authorities
+//
+void PaymentServer::LoadRootCAs(X509_STORE* _store)
+{
+ if (PaymentServer::certStore == NULL)
+ atexit(PaymentServer::freeCertStore);
+ else
+ freeCertStore();
+
+ // Unit tests mostly use this, to pass in fake root CAs:
+ if (_store)
+ {
+ PaymentServer::certStore = _store;
+ return;
+ }
+
+ // Normal execution, use either -rootcertificates or system certs:
+ PaymentServer::certStore = X509_STORE_new();
+
+ // Note: use "-system-" default here so that users can pass -rootcertificates=""
+ // and get 'I don't like X.509 certificates, don't trust anybody' behavior:
+ QString certFile = QString::fromStdString(GetArg("-rootcertificates", "-system-"));
+
+ // Empty store
+ if (certFile.isEmpty()) {
+ qDebug() << QString("PaymentServer::%1: Payment request authentication via X.509 certificates disabled.").arg(__func__);
+ return;
+ }
+
+ QList<QSslCertificate> certList;
+
+ if (certFile != "-system-") {
+ qDebug() << QString("PaymentServer::%1: Using \"%2\" as trusted root certificate.").arg(__func__).arg(certFile);
+
+ certList = QSslCertificate::fromPath(certFile);
+ // Use those certificates when fetching payment requests, too:
+ QSslSocket::setDefaultCaCertificates(certList);
+ } else
+ certList = QSslSocket::systemCaCertificates();
+
+ int nRootCerts = 0;
+ const QDateTime currentTime = QDateTime::currentDateTime();
+
+ Q_FOREACH (const QSslCertificate& cert, certList) {
+ // Don't log NULL certificates
+ if (cert.isNull())
+ continue;
+
+ // Not yet active/valid, or expired certificate
+ if (currentTime < cert.effectiveDate() || currentTime > cert.expiryDate()) {
+ ReportInvalidCertificate(cert);
+ continue;
+ }
+
+#if QT_VERSION >= 0x050000
+ // Blacklisted certificate
+ if (cert.isBlacklisted()) {
+ ReportInvalidCertificate(cert);
+ continue;
+ }
+#endif
+ QByteArray certData = cert.toDer();
+ const unsigned char *data = (const unsigned char *)certData.data();
+
+ X509* x509 = d2i_X509(0, &data, certData.size());
+ if (x509 && X509_STORE_add_cert(PaymentServer::certStore, x509))
+ {
+ // Note: X509_STORE_free will free the X509* objects when
+ // the PaymentServer is destroyed
+ ++nRootCerts;
+ }
+ else
+ {
+ ReportInvalidCertificate(cert);
+ continue;
+ }
+ }
+ qWarning() << "PaymentServer::LoadRootCAs: Loaded " << nRootCerts << " root certificates";
+
+ // Project for another day:
+ // Fetch certificate revocation lists, and add them to certStore.
+ // Issues to consider:
+ // performance (start a thread to fetch in background?)
+ // privacy (fetch through tor/proxy so IP address isn't revealed)
+ // would it be easier to just use a compiled-in blacklist?
+ // or use Qt's blacklist?
+ // "certificate stapling" with server-side caching is more efficient
+}
+
+//
+// Sending to the server is done synchronously, at startup.
+// If the server isn't already running, startup continues,
+// and the items in savedPaymentRequest will be handled
+// when uiReady() is called.
+//
+// Warning: ipcSendCommandLine() is called early in init,
+// so don't use "Q_EMIT message()", but "QMessageBox::"!
+//
+void PaymentServer::ipcParseCommandLine(int argc, char* argv[])
+{
+ for (int i = 1; i < argc; i++)
+ {
+ QString arg(argv[i]);
+ if (arg.startsWith("-"))
+ continue;
+
+ // If the bitcoin: URI contains a payment request, we are not able to detect the
+ // network as that would require fetching and parsing the payment request.
+ // That means clicking such an URI which contains a testnet payment request
+ // will start a mainnet instance and throw a "wrong network" error.
+ if (arg.startsWith(BITCOIN_IPC_PREFIX, Qt::CaseInsensitive)) // bitcoin: URI
+ {
+ savedPaymentRequests.append(arg);
+
+ SendCoinsRecipient r;
+ if (GUIUtil::parseBitcoinURI(arg, &r) && !r.address.isEmpty())
+ {
+ CBitcoinAddress address(r.address.toStdString());
+
+ if (address.IsValid(Params(CBaseChainParams::MAIN)))
+ {
+ SelectParams(CBaseChainParams::MAIN);
+ }
+ else if (address.IsValid(Params(CBaseChainParams::TESTNET)))
+ {
+ SelectParams(CBaseChainParams::TESTNET);
+ }
+ }
+ }
+ else if (QFile::exists(arg)) // Filename
+ {
+ savedPaymentRequests.append(arg);
+
+ PaymentRequestPlus request;
+ if (readPaymentRequestFromFile(arg, request))
+ {
+ if (request.getDetails().network() == "main")
+ {
+ SelectParams(CBaseChainParams::MAIN);
+ }
+ else if (request.getDetails().network() == "test")
+ {
+ SelectParams(CBaseChainParams::TESTNET);
+ }
+ }
+ }
+ else
+ {
+ // Printing to debug.log is about the best we can do here, the
+ // GUI hasn't started yet so we can't pop up a message box.
+ qWarning() << "PaymentServer::ipcSendCommandLine: Payment request file does not exist: " << arg;
+ }
+ }
+}
+
+//
+// Sending to the server is done synchronously, at startup.
+// If the server isn't already running, startup continues,
+// and the items in savedPaymentRequest will be handled
+// when uiReady() is called.
+//
+bool PaymentServer::ipcSendCommandLine()
+{
+ bool fResult = false;
+ Q_FOREACH (const QString& r, savedPaymentRequests)
+ {
+ QLocalSocket* socket = new QLocalSocket();
+ socket->connectToServer(ipcServerName(), QIODevice::WriteOnly);
+ if (!socket->waitForConnected(BITCOIN_IPC_CONNECT_TIMEOUT))
+ {
+ delete socket;
+ socket = NULL;
+ return false;
+ }
+
+ QByteArray block;
+ QDataStream out(&block, QIODevice::WriteOnly);
+ out.setVersion(QDataStream::Qt_4_0);
+ out << r;
+ out.device()->seek(0);
+
+ socket->write(block);
+ socket->flush();
+ socket->waitForBytesWritten(BITCOIN_IPC_CONNECT_TIMEOUT);
+ socket->disconnectFromServer();
+
+ delete socket;
+ socket = NULL;
+ fResult = true;
+ }
+
+ return fResult;
+}
+
+PaymentServer::PaymentServer(QObject* parent, bool startLocalServer) :
+ QObject(parent),
+ saveURIs(true),
+ uriServer(0),
+ netManager(0),
+ optionsModel(0)
+{
+ // Verify that the version of the library that we linked against is
+ // compatible with the version of the headers we compiled against.
+ GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+ // Install global event filter to catch QFileOpenEvents
+ // on Mac: sent when you click bitcoin: links
+ // other OSes: helpful when dealing with payment request files
+ if (parent)
+ parent->installEventFilter(this);
+
+ QString name = ipcServerName();
+
+ // Clean up old socket leftover from a crash:
+ QLocalServer::removeServer(name);
+
+ if (startLocalServer)
+ {
+ uriServer = new QLocalServer(this);
+
+ if (!uriServer->listen(name)) {
+ // constructor is called early in init, so don't use "Q_EMIT message()" here
+ QMessageBox::critical(0, tr("Payment request error"),
+ tr("Cannot start bitcoin: click-to-pay handler"));
+ }
+ else {
+ connect(uriServer, SIGNAL(newConnection()), this, SLOT(handleURIConnection()));
+ connect(this, SIGNAL(receivedPaymentACK(QString)), this, SLOT(handlePaymentACK(QString)));
+ }
+ }
+}
+
+PaymentServer::~PaymentServer()
+{
+ google::protobuf::ShutdownProtobufLibrary();
+}
+
+//
+// OSX-specific way of handling bitcoin: URIs and PaymentRequest mime types.
+// Also used by paymentservertests.cpp and when opening a payment request file
+// via "Open URI..." menu entry.
+//
+bool PaymentServer::eventFilter(QObject *object, QEvent *event)
+{
+ if (event->type() == QEvent::FileOpen) {
+ QFileOpenEvent *fileEvent = static_cast<QFileOpenEvent*>(event);
+ if (!fileEvent->file().isEmpty())
+ handleURIOrFile(fileEvent->file());
+ else if (!fileEvent->url().isEmpty())
+ handleURIOrFile(fileEvent->url().toString());
+
+ return true;
+ }
+
+ return QObject::eventFilter(object, event);
+}
+
+void PaymentServer::initNetManager()
+{
+ if (!optionsModel)
+ return;
+ if (netManager != NULL)
+ delete netManager;
+
+ // netManager is used to fetch paymentrequests given in bitcoin: URIs
+ netManager = new QNetworkAccessManager(this);
+
+ QNetworkProxy proxy;
+
+ // Query active SOCKS5 proxy
+ if (optionsModel->getProxySettings(proxy)) {
+ netManager->setProxy(proxy);
+
+ qDebug() << "PaymentServer::initNetManager: Using SOCKS5 proxy" << proxy.hostName() << ":" << proxy.port();
+ }
+ else
+ qDebug() << "PaymentServer::initNetManager: No active proxy server found.";
+
+ connect(netManager, SIGNAL(finished(QNetworkReply*)),
+ this, SLOT(netRequestFinished(QNetworkReply*)));
+ connect(netManager, SIGNAL(sslErrors(QNetworkReply*, const QList<QSslError> &)),
+ this, SLOT(reportSslErrors(QNetworkReply*, const QList<QSslError> &)));
+}
+
+void PaymentServer::uiReady()
+{
+ initNetManager();
+
+ saveURIs = false;
+ Q_FOREACH (const QString& s, savedPaymentRequests)
+ {
+ handleURIOrFile(s);
+ }
+ savedPaymentRequests.clear();
+}
+
+void PaymentServer::handleURIOrFile(const QString& s)
+{
+ if (saveURIs)
+ {
+ savedPaymentRequests.append(s);
+ return;
+ }
+
+ if (s.startsWith(BITCOIN_IPC_PREFIX, Qt::CaseInsensitive)) // bitcoin: URI
+ {
+#if QT_VERSION < 0x050000
+ QUrl uri(s);
+#else
+ QUrlQuery uri((QUrl(s)));
+#endif
+ if (uri.hasQueryItem("r")) // payment request URI
+ {
+ QByteArray temp;
+ temp.append(uri.queryItemValue("r"));
+ QString decoded = QUrl::fromPercentEncoding(temp);
+ QUrl fetchUrl(decoded, QUrl::StrictMode);
+
+ if (fetchUrl.isValid())
+ {
+ qDebug() << "PaymentServer::handleURIOrFile: fetchRequest(" << fetchUrl << ")";
+ fetchRequest(fetchUrl);
+ }
+ else
+ {
+ qWarning() << "PaymentServer::handleURIOrFile: Invalid URL: " << fetchUrl;
+ Q_EMIT message(tr("URI handling"),
+ tr("Payment request fetch URL is invalid: %1").arg(fetchUrl.toString()),
+ CClientUIInterface::ICON_WARNING);
+ }
+
+ return;
+ }
+ else // normal URI
+ {
+ SendCoinsRecipient recipient;
+ if (GUIUtil::parseBitcoinURI(s, &recipient))
+ {
+ CBitcoinAddress address(recipient.address.toStdString());
+ if (!address.IsValid()) {
+ Q_EMIT message(tr("URI handling"), tr("Invalid payment address %1").arg(recipient.address),
+ CClientUIInterface::MSG_ERROR);
+ }
+ else
+ Q_EMIT receivedPaymentRequest(recipient);
+ }
+ else
+ Q_EMIT message(tr("URI handling"),
+ tr("URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters."),
+ CClientUIInterface::ICON_WARNING);
+
+ return;
+ }
+ }
+
+ if (QFile::exists(s)) // payment request file
+ {
+ PaymentRequestPlus request;
+ SendCoinsRecipient recipient;
+ if (!readPaymentRequestFromFile(s, request))
+ {
+ Q_EMIT message(tr("Payment request file handling"),
+ tr("Payment request file cannot be read! This can be caused by an invalid payment request file."),
+ CClientUIInterface::ICON_WARNING);
+ }
+ else if (processPaymentRequest(request, recipient))
+ Q_EMIT receivedPaymentRequest(recipient);
+
+ return;
+ }
+}
+
+void PaymentServer::handleURIConnection()
+{
+ QLocalSocket *clientConnection = uriServer->nextPendingConnection();
+
+ while (clientConnection->bytesAvailable() < (int)sizeof(quint32))
+ clientConnection->waitForReadyRead();
+
+ connect(clientConnection, SIGNAL(disconnected()),
+ clientConnection, SLOT(deleteLater()));
+
+ QDataStream in(clientConnection);
+ in.setVersion(QDataStream::Qt_4_0);
+ if (clientConnection->bytesAvailable() < (int)sizeof(quint16)) {
+ return;
+ }
+ QString msg;
+ in >> msg;
+
+ handleURIOrFile(msg);
+}
+
+//
+// Warning: readPaymentRequestFromFile() is used in ipcSendCommandLine()
+// so don't use "Q_EMIT message()", but "QMessageBox::"!
+//
+bool PaymentServer::readPaymentRequestFromFile(const QString& filename, PaymentRequestPlus& request)
+{
+ QFile f(filename);
+ if (!f.open(QIODevice::ReadOnly)) {
+ qWarning() << QString("PaymentServer::%1: Failed to open %2").arg(__func__).arg(filename);
+ return false;
+ }
+
+ // BIP70 DoS protection
+ if (f.size() > BIP70_MAX_PAYMENTREQUEST_SIZE) {
+ qWarning() << QString("PaymentServer::%1: Payment request %2 is too large (%3 bytes, allowed %4 bytes).")
+ .arg(__func__)
+ .arg(filename)
+ .arg(f.size())
+ .arg(BIP70_MAX_PAYMENTREQUEST_SIZE);
+ return false;
+ }
+
+ QByteArray data = f.readAll();
+
+ return request.parse(data);
+}
+
+bool PaymentServer::processPaymentRequest(const PaymentRequestPlus& request, SendCoinsRecipient& recipient)
+{
+ if (!optionsModel)
+ return false;
+
+ if (request.IsInitialized()) {
+ // Payment request network matches client network?
+ if (!verifyNetwork(request.getDetails())) {
+ Q_EMIT message(tr("Payment request rejected"), tr("Payment request network doesn't match client network."),
+ CClientUIInterface::MSG_ERROR);
+
+ return false;
+ }
+
+ // Make sure any payment requests involved are still valid.
+ // This is re-checked just before sending coins in WalletModel::sendCoins().
+ if (verifyExpired(request.getDetails())) {
+ Q_EMIT message(tr("Payment request rejected"), tr("Payment request expired."),
+ CClientUIInterface::MSG_ERROR);
+
+ return false;
+ }
+ } else {
+ Q_EMIT message(tr("Payment request error"), tr("Payment request is not initialized."),
+ CClientUIInterface::MSG_ERROR);
+
+ return false;
+ }
+
+ recipient.paymentRequest = request;
+ recipient.message = GUIUtil::HtmlEscape(request.getDetails().memo());
+
+ request.getMerchant(PaymentServer::certStore, recipient.authenticatedMerchant);
+
+ QList<std::pair<CScript, CAmount> > sendingTos = request.getPayTo();
+ QStringList addresses;
+
+ Q_FOREACH(const PAIRTYPE(CScript, CAmount)& sendingTo, sendingTos) {
+ // Extract and check destination addresses
+ CTxDestination dest;
+ if (ExtractDestination(sendingTo.first, dest)) {
+ // Append destination address
+ addresses.append(QString::fromStdString(CBitcoinAddress(dest).ToString()));
+ }
+ else if (!recipient.authenticatedMerchant.isEmpty()) {
+ // Unauthenticated payment requests to custom bitcoin addresses are not supported
+ // (there is no good way to tell the user where they are paying in a way they'd
+ // have a chance of understanding).
+ Q_EMIT message(tr("Payment request rejected"),
+ tr("Unverified payment requests to custom payment scripts are unsupported."),
+ CClientUIInterface::MSG_ERROR);
+ return false;
+ }
+
+ // Bitcoin amounts are stored as (optional) uint64 in the protobuf messages (see paymentrequest.proto),
+ // but CAmount is defined as int64_t. Because of that we need to verify that amounts are in a valid range
+ // and no overflow has happened.
+ if (!verifyAmount(sendingTo.second)) {
+ Q_EMIT message(tr("Payment request rejected"), tr("Invalid payment request."), CClientUIInterface::MSG_ERROR);
+ return false;
+ }
+
+ // Extract and check amounts
+ CTxOut txOut(sendingTo.second, sendingTo.first);
+ if (txOut.IsDust(::minRelayTxFee)) {
+ Q_EMIT message(tr("Payment request error"), tr("Requested payment amount of %1 is too small (considered dust).")
+ .arg(BitcoinUnits::formatWithUnit(optionsModel->getDisplayUnit(), sendingTo.second)),
+ CClientUIInterface::MSG_ERROR);
+
+ return false;
+ }
+
+ recipient.amount += sendingTo.second;
+ // Also verify that the final amount is still in a valid range after adding additional amounts.
+ if (!verifyAmount(recipient.amount)) {
+ Q_EMIT message(tr("Payment request rejected"), tr("Invalid payment request."), CClientUIInterface::MSG_ERROR);
+ return false;
+ }
+ }
+ // Store addresses and format them to fit nicely into the GUI
+ recipient.address = addresses.join("<br />");
+
+ if (!recipient.authenticatedMerchant.isEmpty()) {
+ qDebug() << "PaymentServer::processPaymentRequest: Secure payment request from " << recipient.authenticatedMerchant;
+ }
+ else {
+ qDebug() << "PaymentServer::processPaymentRequest: Insecure payment request to " << addresses.join(", ");
+ }
+
+ return true;
+}
+
+void PaymentServer::fetchRequest(const QUrl& url)
+{
+ QNetworkRequest netRequest;
+ netRequest.setAttribute(QNetworkRequest::User, BIP70_MESSAGE_PAYMENTREQUEST);
+ netRequest.setUrl(url);
+ netRequest.setRawHeader("User-Agent", CLIENT_NAME.c_str());
+ netRequest.setRawHeader("Accept", BIP71_MIMETYPE_PAYMENTREQUEST);
+ netManager->get(netRequest);
+}
+
+void PaymentServer::fetchPaymentACK(CWallet* wallet, SendCoinsRecipient recipient, QByteArray transaction)
+{
+ const payments::PaymentDetails& details = recipient.paymentRequest.getDetails();
+ if (!details.has_payment_url())
+ return;
+
+ QNetworkRequest netRequest;
+ netRequest.setAttribute(QNetworkRequest::User, BIP70_MESSAGE_PAYMENTACK);
+ netRequest.setUrl(QString::fromStdString(details.payment_url()));
+ netRequest.setHeader(QNetworkRequest::ContentTypeHeader, BIP71_MIMETYPE_PAYMENT);
+ netRequest.setRawHeader("User-Agent", CLIENT_NAME.c_str());
+ netRequest.setRawHeader("Accept", BIP71_MIMETYPE_PAYMENTACK);
+
+ payments::Payment payment;
+ payment.set_merchant_data(details.merchant_data());
+ payment.add_transactions(transaction.data(), transaction.size());
+
+ // Create a new refund address, or re-use:
+ QString account = tr("Refund from %1").arg(recipient.authenticatedMerchant);
+ std::string strAccount = account.toStdString();
+ set<CTxDestination> refundAddresses = wallet->GetAccountAddresses(strAccount);
+ if (!refundAddresses.empty()) {
+ CScript s = GetScriptForDestination(*refundAddresses.begin());
+ payments::Output* refund_to = payment.add_refund_to();
+ refund_to->set_script(&s[0], s.size());
+ }
+ else {
+ CPubKey newKey;
+ if (wallet->GetKeyFromPool(newKey)) {
+ CKeyID keyID = newKey.GetID();
+ wallet->SetAddressBook(keyID, strAccount, "refund");
+
+ CScript s = GetScriptForDestination(keyID);
+ payments::Output* refund_to = payment.add_refund_to();
+ refund_to->set_script(&s[0], s.size());
+ }
+ else {
+ // This should never happen, because sending coins should have
+ // just unlocked the wallet and refilled the keypool.
+ qWarning() << "PaymentServer::fetchPaymentACK: Error getting refund key, refund_to not set";
+ }
+ }
+
+ int length = payment.ByteSize();
+ netRequest.setHeader(QNetworkRequest::ContentLengthHeader, length);
+ QByteArray serData(length, '\0');
+ if (payment.SerializeToArray(serData.data(), length)) {
+ netManager->post(netRequest, serData);
+ }
+ else {
+ // This should never happen, either.
+ qWarning() << "PaymentServer::fetchPaymentACK: Error serializing payment message";
+ }
+}
+
+void PaymentServer::netRequestFinished(QNetworkReply* reply)
+{
+ reply->deleteLater();
+
+ // BIP70 DoS protection
+ if (reply->size() > BIP70_MAX_PAYMENTREQUEST_SIZE) {
+ QString msg = tr("Payment request %1 is too large (%2 bytes, allowed %3 bytes).")
+ .arg(reply->request().url().toString())
+ .arg(reply->size())
+ .arg(BIP70_MAX_PAYMENTREQUEST_SIZE);
+
+ qWarning() << QString("PaymentServer::%1:").arg(__func__) << msg;
+ Q_EMIT message(tr("Payment request DoS protection"), msg, CClientUIInterface::MSG_ERROR);
+ return;
+ }
+
+ if (reply->error() != QNetworkReply::NoError) {
+ QString msg = tr("Error communicating with %1: %2")
+ .arg(reply->request().url().toString())
+ .arg(reply->errorString());
+
+ qWarning() << "PaymentServer::netRequestFinished: " << msg;
+ Q_EMIT message(tr("Payment request error"), msg, CClientUIInterface::MSG_ERROR);
+ return;
+ }
+
+ QByteArray data = reply->readAll();
+
+ QString requestType = reply->request().attribute(QNetworkRequest::User).toString();
+ if (requestType == BIP70_MESSAGE_PAYMENTREQUEST)
+ {
+ PaymentRequestPlus request;
+ SendCoinsRecipient recipient;
+ if (!request.parse(data))
+ {
+ qWarning() << "PaymentServer::netRequestFinished: Error parsing payment request";
+ Q_EMIT message(tr("Payment request error"),
+ tr("Payment request cannot be parsed!"),
+ CClientUIInterface::MSG_ERROR);
+ }
+ else if (processPaymentRequest(request, recipient))
+ Q_EMIT receivedPaymentRequest(recipient);
+
+ return;
+ }
+ else if (requestType == BIP70_MESSAGE_PAYMENTACK)
+ {
+ payments::PaymentACK paymentACK;
+ if (!paymentACK.ParseFromArray(data.data(), data.size()))
+ {
+ QString msg = tr("Bad response from server %1")
+ .arg(reply->request().url().toString());
+
+ qWarning() << "PaymentServer::netRequestFinished: " << msg;
+ Q_EMIT message(tr("Payment request error"), msg, CClientUIInterface::MSG_ERROR);
+ }
+ else
+ {
+ Q_EMIT receivedPaymentACK(GUIUtil::HtmlEscape(paymentACK.memo()));
+ }
+ }
+}
+
+void PaymentServer::reportSslErrors(QNetworkReply* reply, const QList<QSslError> &errs)
+{
+ Q_UNUSED(reply);
+
+ QString errString;
+ Q_FOREACH (const QSslError& err, errs) {
+ qWarning() << "PaymentServer::reportSslErrors: " << err;
+ errString += err.errorString() + "\n";
+ }
+ Q_EMIT message(tr("Network request error"), errString, CClientUIInterface::MSG_ERROR);
+}
+
+void PaymentServer::setOptionsModel(OptionsModel *optionsModel)
+{
+ this->optionsModel = optionsModel;
+}
+
+void PaymentServer::handlePaymentACK(const QString& paymentACKMsg)
+{
+ // currently we don't further process or store the paymentACK message
+ Q_EMIT message(tr("Payment acknowledged"), paymentACKMsg, CClientUIInterface::ICON_INFORMATION | CClientUIInterface::MODAL);
+}
+
+bool PaymentServer::verifyNetwork(const payments::PaymentDetails& requestDetails)
+{
+ bool fVerified = requestDetails.network() == Params().NetworkIDString();
+ if (!fVerified) {
+ qWarning() << QString("PaymentServer::%1: Payment request network \"%2\" doesn't match client network \"%3\".")
+ .arg(__func__)
+ .arg(QString::fromStdString(requestDetails.network()))
+ .arg(QString::fromStdString(Params().NetworkIDString()));
+ }
+ return fVerified;
+}
+
+bool PaymentServer::verifyExpired(const payments::PaymentDetails& requestDetails)
+{
+ bool fVerified = (requestDetails.has_expires() && (int64_t)requestDetails.expires() < GetTime());
+ if (fVerified) {
+ const QString requestExpires = QString::fromStdString(DateTimeStrFormat("%Y-%m-%d %H:%M:%S", (int64_t)requestDetails.expires()));
+ qWarning() << QString("PaymentServer::%1: Payment request expired \"%2\".")
+ .arg(__func__)
+ .arg(requestExpires);
+ }
+ return fVerified;
+}
+
+bool PaymentServer::verifyAmount(const CAmount& requestAmount)
+{
+ bool fVerified = MoneyRange(requestAmount);
+ if (!fVerified) {
+ qWarning() << QString("PaymentServer::%1: Payment request amount out of allowed range (%2, allowed 0 - %3).")
+ .arg(__func__)
+ .arg(requestAmount)
+ .arg(MAX_MONEY);
+ }
+ return fVerified;
+}
diff --git a/src/qt/paymentserver.h b/src/qt/paymentserver.h
new file mode 100644
index 0000000000..5df0a14cf7
--- /dev/null
+++ b/src/qt/paymentserver.h
@@ -0,0 +1,151 @@
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_PAYMENTSERVER_H
+#define BITCOIN_QT_PAYMENTSERVER_H
+
+// This class handles payment requests from clicking on
+// bitcoin: URIs
+//
+// This is somewhat tricky, because we have to deal with
+// the situation where the user clicks on a link during
+// startup/initialization, when the splash-screen is up
+// but the main window (and the Send Coins tab) is not.
+//
+// So, the strategy is:
+//
+// Create the server, and register the event handler,
+// when the application is created. Save any URIs
+// received at or during startup in a list.
+//
+// When startup is finished and the main window is
+// shown, a signal is sent to slot uiReady(), which
+// emits a receivedURL() signal for any payment
+// requests that happened during startup.
+//
+// After startup, receivedURL() happens as usual.
+//
+// This class has one more feature: a static
+// method that finds URIs passed in the command line
+// and, if a server is running in another process,
+// sends them to the server.
+//
+
+#include "paymentrequestplus.h"
+#include "walletmodel.h"
+
+#include <QObject>
+#include <QString>
+
+class OptionsModel;
+
+class CWallet;
+
+QT_BEGIN_NAMESPACE
+class QApplication;
+class QByteArray;
+class QLocalServer;
+class QNetworkAccessManager;
+class QNetworkReply;
+class QSslError;
+class QUrl;
+QT_END_NAMESPACE
+
+// BIP70 max payment request size in bytes (DoS protection)
+extern const qint64 BIP70_MAX_PAYMENTREQUEST_SIZE;
+
+class PaymentServer : public QObject
+{
+ Q_OBJECT
+
+public:
+ // Parse URIs on command line
+ // Returns false on error
+ static void ipcParseCommandLine(int argc, char *argv[]);
+
+ // Returns true if there were URIs on the command line
+ // which were successfully sent to an already-running
+ // process.
+ // Note: if a payment request is given, SelectParams(MAIN/TESTNET)
+ // will be called so we startup in the right mode.
+ static bool ipcSendCommandLine();
+
+ // parent should be QApplication object
+ PaymentServer(QObject* parent, bool startLocalServer = true);
+ ~PaymentServer();
+
+ // Load root certificate authorities. Pass NULL (default)
+ // to read from the file specified in the -rootcertificates setting,
+ // or, if that's not set, to use the system default root certificates.
+ // If you pass in a store, you should not X509_STORE_free it: it will be
+ // freed either at exit or when another set of CAs are loaded.
+ static void LoadRootCAs(X509_STORE* store = NULL);
+
+ // Return certificate store
+ static X509_STORE* getCertStore() { return certStore; }
+
+ // OptionsModel is used for getting proxy settings and display unit
+ void setOptionsModel(OptionsModel *optionsModel);
+
+ // This is now public, because we use it in paymentservertests.cpp
+ static bool readPaymentRequestFromFile(const QString& filename, PaymentRequestPlus& request);
+
+ // Verify that the payment request network matches the client network
+ static bool verifyNetwork(const payments::PaymentDetails& requestDetails);
+ // Verify if the payment request is expired
+ static bool verifyExpired(const payments::PaymentDetails& requestDetails);
+ // Verify the payment request amount is valid
+ static bool verifyAmount(const CAmount& requestAmount);
+
+Q_SIGNALS:
+ // Fired when a valid payment request is received
+ void receivedPaymentRequest(SendCoinsRecipient);
+
+ // Fired when a valid PaymentACK is received
+ void receivedPaymentACK(const QString &paymentACKMsg);
+
+ // Fired when a message should be reported to the user
+ void message(const QString &title, const QString &message, unsigned int style);
+
+public Q_SLOTS:
+ // Signal this when the main window's UI is ready
+ // to display payment requests to the user
+ void uiReady();
+
+ // Submit Payment message to a merchant, get back PaymentACK:
+ void fetchPaymentACK(CWallet* wallet, SendCoinsRecipient recipient, QByteArray transaction);
+
+ // Handle an incoming URI, URI with local file scheme or file
+ void handleURIOrFile(const QString& s);
+
+private Q_SLOTS:
+ void handleURIConnection();
+ void netRequestFinished(QNetworkReply*);
+ void reportSslErrors(QNetworkReply*, const QList<QSslError> &);
+ void handlePaymentACK(const QString& paymentACKMsg);
+
+protected:
+ // Constructor registers this on the parent QApplication to
+ // receive QEvent::FileOpen and QEvent:Drop events
+ bool eventFilter(QObject *object, QEvent *event);
+
+private:
+ bool processPaymentRequest(const PaymentRequestPlus& request, SendCoinsRecipient& recipient);
+ void fetchRequest(const QUrl& url);
+
+ // Setup networking
+ void initNetManager();
+
+ bool saveURIs; // true during startup
+ QLocalServer* uriServer;
+
+ static X509_STORE* certStore; // Trusted root certificates
+ static void freeCertStore();
+
+ QNetworkAccessManager* netManager; // Used to fetch payment requests
+
+ OptionsModel *optionsModel;
+};
+
+#endif // BITCOIN_QT_PAYMENTSERVER_H
diff --git a/src/qt/peertablemodel.cpp b/src/qt/peertablemodel.cpp
new file mode 100644
index 0000000000..4ab9528cc4
--- /dev/null
+++ b/src/qt/peertablemodel.cpp
@@ -0,0 +1,241 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "peertablemodel.h"
+
+#include "clientmodel.h"
+#include "guiconstants.h"
+#include "guiutil.h"
+
+#include "net.h"
+#include "sync.h"
+
+#include <QDebug>
+#include <QList>
+#include <QTimer>
+
+bool NodeLessThan::operator()(const CNodeCombinedStats &left, const CNodeCombinedStats &right) const
+{
+ const CNodeStats *pLeft = &(left.nodeStats);
+ const CNodeStats *pRight = &(right.nodeStats);
+
+ if (order == Qt::DescendingOrder)
+ std::swap(pLeft, pRight);
+
+ switch(column)
+ {
+ case PeerTableModel::Address:
+ return pLeft->addrName.compare(pRight->addrName) < 0;
+ case PeerTableModel::Subversion:
+ return pLeft->cleanSubVer.compare(pRight->cleanSubVer) < 0;
+ case PeerTableModel::Ping:
+ return pLeft->dPingTime < pRight->dPingTime;
+ }
+
+ return false;
+}
+
+// private implementation
+class PeerTablePriv
+{
+public:
+ /** Local cache of peer information */
+ QList<CNodeCombinedStats> cachedNodeStats;
+ /** Column to sort nodes by */
+ int sortColumn;
+ /** Order (ascending or descending) to sort nodes by */
+ Qt::SortOrder sortOrder;
+ /** Index of rows by node ID */
+ std::map<NodeId, int> mapNodeRows;
+
+ /** Pull a full list of peers from vNodes into our cache */
+ void refreshPeers()
+ {
+ {
+ TRY_LOCK(cs_vNodes, lockNodes);
+ if (!lockNodes)
+ {
+ // skip the refresh if we can't immediately get the lock
+ return;
+ }
+ cachedNodeStats.clear();
+#if QT_VERSION >= 0x040700
+ cachedNodeStats.reserve(vNodes.size());
+#endif
+ Q_FOREACH (CNode* pnode, vNodes)
+ {
+ CNodeCombinedStats stats;
+ stats.nodeStateStats.nMisbehavior = 0;
+ stats.nodeStateStats.nSyncHeight = -1;
+ stats.fNodeStateStatsAvailable = false;
+ pnode->copyStats(stats.nodeStats);
+ cachedNodeStats.append(stats);
+ }
+ }
+
+ // Try to retrieve the CNodeStateStats for each node.
+ {
+ TRY_LOCK(cs_main, lockMain);
+ if (lockMain)
+ {
+ BOOST_FOREACH(CNodeCombinedStats &stats, cachedNodeStats)
+ stats.fNodeStateStatsAvailable = GetNodeStateStats(stats.nodeStats.nodeid, stats.nodeStateStats);
+ }
+ }
+
+ if (sortColumn >= 0)
+ // sort cacheNodeStats (use stable sort to prevent rows jumping around unneceesarily)
+ qStableSort(cachedNodeStats.begin(), cachedNodeStats.end(), NodeLessThan(sortColumn, sortOrder));
+
+ // build index map
+ mapNodeRows.clear();
+ int row = 0;
+ Q_FOREACH (const CNodeCombinedStats& stats, cachedNodeStats)
+ mapNodeRows.insert(std::pair<NodeId, int>(stats.nodeStats.nodeid, row++));
+ }
+
+ int size()
+ {
+ return cachedNodeStats.size();
+ }
+
+ CNodeCombinedStats *index(int idx)
+ {
+ if(idx >= 0 && idx < cachedNodeStats.size()) {
+ return &cachedNodeStats[idx];
+ } else {
+ return 0;
+ }
+ }
+};
+
+PeerTableModel::PeerTableModel(ClientModel *parent) :
+ QAbstractTableModel(parent),
+ clientModel(parent),
+ timer(0)
+{
+ columns << tr("Node/Service") << tr("User Agent") << tr("Ping Time");
+ priv = new PeerTablePriv();
+ // default to unsorted
+ priv->sortColumn = -1;
+
+ // set up timer for auto refresh
+ timer = new QTimer();
+ connect(timer, SIGNAL(timeout()), SLOT(refresh()));
+ timer->setInterval(MODEL_UPDATE_DELAY);
+
+ // load initial data
+ refresh();
+}
+
+void PeerTableModel::startAutoRefresh()
+{
+ timer->start();
+}
+
+void PeerTableModel::stopAutoRefresh()
+{
+ timer->stop();
+}
+
+int PeerTableModel::rowCount(const QModelIndex &parent) const
+{
+ Q_UNUSED(parent);
+ return priv->size();
+}
+
+int PeerTableModel::columnCount(const QModelIndex &parent) const
+{
+ Q_UNUSED(parent);
+ return columns.length();;
+}
+
+QVariant PeerTableModel::data(const QModelIndex &index, int role) const
+{
+ if(!index.isValid())
+ return QVariant();
+
+ CNodeCombinedStats *rec = static_cast<CNodeCombinedStats*>(index.internalPointer());
+
+ if (role == Qt::DisplayRole) {
+ switch(index.column())
+ {
+ case Address:
+ return QString::fromStdString(rec->nodeStats.addrName);
+ case Subversion:
+ return QString::fromStdString(rec->nodeStats.cleanSubVer);
+ case Ping:
+ return GUIUtil::formatPingTime(rec->nodeStats.dPingTime);
+ }
+ } else if (role == Qt::TextAlignmentRole) {
+ if (index.column() == Ping)
+ return (int)(Qt::AlignRight | Qt::AlignVCenter);
+ }
+
+ return QVariant();
+}
+
+QVariant PeerTableModel::headerData(int section, Qt::Orientation orientation, int role) const
+{
+ if(orientation == Qt::Horizontal)
+ {
+ if(role == Qt::DisplayRole && section < columns.size())
+ {
+ return columns[section];
+ }
+ }
+ return QVariant();
+}
+
+Qt::ItemFlags PeerTableModel::flags(const QModelIndex &index) const
+{
+ if(!index.isValid())
+ return 0;
+
+ Qt::ItemFlags retval = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
+ return retval;
+}
+
+QModelIndex PeerTableModel::index(int row, int column, const QModelIndex &parent) const
+{
+ Q_UNUSED(parent);
+ CNodeCombinedStats *data = priv->index(row);
+
+ if (data)
+ {
+ return createIndex(row, column, data);
+ }
+ else
+ {
+ return QModelIndex();
+ }
+}
+
+const CNodeCombinedStats *PeerTableModel::getNodeStats(int idx)
+{
+ return priv->index(idx);
+}
+
+void PeerTableModel::refresh()
+{
+ Q_EMIT layoutAboutToBeChanged();
+ priv->refreshPeers();
+ Q_EMIT layoutChanged();
+}
+
+int PeerTableModel::getRowByNodeId(NodeId nodeid)
+{
+ std::map<NodeId, int>::iterator it = priv->mapNodeRows.find(nodeid);
+ if (it == priv->mapNodeRows.end())
+ return -1;
+
+ return it->second;
+}
+
+void PeerTableModel::sort(int column, Qt::SortOrder order)
+{
+ priv->sortColumn = column;
+ priv->sortOrder = order;
+ refresh();
+}
diff --git a/src/qt/peertablemodel.h b/src/qt/peertablemodel.h
new file mode 100644
index 0000000000..fcb89b7611
--- /dev/null
+++ b/src/qt/peertablemodel.h
@@ -0,0 +1,81 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_PEERTABLEMODEL_H
+#define BITCOIN_QT_PEERTABLEMODEL_H
+
+#include "main.h"
+#include "net.h"
+
+#include <QAbstractTableModel>
+#include <QStringList>
+
+class ClientModel;
+class PeerTablePriv;
+
+QT_BEGIN_NAMESPACE
+class QTimer;
+QT_END_NAMESPACE
+
+struct CNodeCombinedStats {
+ CNodeStats nodeStats;
+ CNodeStateStats nodeStateStats;
+ bool fNodeStateStatsAvailable;
+};
+
+class NodeLessThan
+{
+public:
+ NodeLessThan(int nColumn, Qt::SortOrder fOrder) :
+ column(nColumn), order(fOrder) {}
+ bool operator()(const CNodeCombinedStats &left, const CNodeCombinedStats &right) const;
+
+private:
+ int column;
+ Qt::SortOrder order;
+};
+
+/**
+ Qt model providing information about connected peers, similar to the
+ "getpeerinfo" RPC call. Used by the rpc console UI.
+ */
+class PeerTableModel : public QAbstractTableModel
+{
+ Q_OBJECT
+
+public:
+ explicit PeerTableModel(ClientModel *parent = 0);
+ const CNodeCombinedStats *getNodeStats(int idx);
+ int getRowByNodeId(NodeId nodeid);
+ void startAutoRefresh();
+ void stopAutoRefresh();
+
+ enum ColumnIndex {
+ Address = 0,
+ Subversion = 1,
+ Ping = 2
+ };
+
+ /** @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;
+ QVariant headerData(int section, Qt::Orientation orientation, int role) const;
+ QModelIndex index(int row, int column, const QModelIndex &parent) const;
+ Qt::ItemFlags flags(const QModelIndex &index) const;
+ void sort(int column, Qt::SortOrder order);
+ /*@}*/
+
+public Q_SLOTS:
+ void refresh();
+
+private:
+ ClientModel *clientModel;
+ QStringList columns;
+ PeerTablePriv *priv;
+ QTimer *timer;
+};
+
+#endif // BITCOIN_QT_PEERTABLEMODEL_H
diff --git a/src/qt/qvalidatedlineedit.cpp b/src/qt/qvalidatedlineedit.cpp
new file mode 100644
index 0000000000..346369392c
--- /dev/null
+++ b/src/qt/qvalidatedlineedit.cpp
@@ -0,0 +1,107 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "qvalidatedlineedit.h"
+
+#include "bitcoinaddressvalidator.h"
+#include "guiconstants.h"
+
+QValidatedLineEdit::QValidatedLineEdit(QWidget *parent) :
+ QLineEdit(parent),
+ valid(true),
+ checkValidator(0)
+{
+ 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::focusOutEvent(QFocusEvent *evt)
+{
+ checkValidity();
+
+ QLineEdit::focusOutEvent(evt);
+}
+
+void QValidatedLineEdit::markValid()
+{
+ // As long as a user is typing ensure we display state as valid
+ setValid(true);
+}
+
+void QValidatedLineEdit::clear()
+{
+ setValid(true);
+ QLineEdit::clear();
+}
+
+void QValidatedLineEdit::setEnabled(bool enabled)
+{
+ if (!enabled)
+ {
+ // A disabled QValidatedLineEdit should be marked valid
+ setValid(true);
+ }
+ else
+ {
+ // Recheck validity when QValidatedLineEdit gets enabled
+ checkValidity();
+ }
+
+ QLineEdit::setEnabled(enabled);
+}
+
+void QValidatedLineEdit::checkValidity()
+{
+ if (text().isEmpty())
+ {
+ setValid(true);
+ }
+ else if (hasAcceptableInput())
+ {
+ setValid(true);
+
+ // Check contents on focus out
+ if (checkValidator)
+ {
+ QString address = text();
+ int pos = 0;
+ if (checkValidator->validate(address, pos) == QValidator::Acceptable)
+ setValid(true);
+ else
+ setValid(false);
+ }
+ }
+ else
+ setValid(false);
+}
+
+void QValidatedLineEdit::setCheckValidator(const QValidator *v)
+{
+ checkValidator = v;
+}
diff --git a/src/qt/qvalidatedlineedit.h b/src/qt/qvalidatedlineedit.h
new file mode 100644
index 0000000000..8665acda5e
--- /dev/null
+++ b/src/qt/qvalidatedlineedit.h
@@ -0,0 +1,39 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_QVALIDATEDLINEEDIT_H
+#define BITCOIN_QT_QVALIDATEDLINEEDIT_H
+
+#include <QLineEdit>
+
+/** 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);
+ void clear();
+ void setCheckValidator(const QValidator *v);
+
+protected:
+ void focusInEvent(QFocusEvent *evt);
+ void focusOutEvent(QFocusEvent *evt);
+
+private:
+ bool valid;
+ const QValidator *checkValidator;
+
+public Q_SLOTS:
+ void setValid(bool valid);
+ void setEnabled(bool enabled);
+
+private Q_SLOTS:
+ void markValid();
+ void checkValidity();
+};
+
+#endif // BITCOIN_QT_QVALIDATEDLINEEDIT_H
diff --git a/src/qt/qvaluecombobox.cpp b/src/qt/qvaluecombobox.cpp
new file mode 100644
index 0000000000..800436661f
--- /dev/null
+++ b/src/qt/qvaluecombobox.cpp
@@ -0,0 +1,31 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#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)
+{
+ Q_EMIT valueChanged();
+}
diff --git a/src/qt/qvaluecombobox.h b/src/qt/qvaluecombobox.h
new file mode 100644
index 0000000000..5b20e6a5a4
--- /dev/null
+++ b/src/qt/qvaluecombobox.h
@@ -0,0 +1,37 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_QVALUECOMBOBOX_H
+#define BITCOIN_QT_QVALUECOMBOBOX_H
+
+#include <QComboBox>
+#include <QVariant>
+
+/* 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);
+
+Q_SIGNALS:
+ void valueChanged();
+
+private:
+ int role;
+
+private Q_SLOTS:
+ void handleSelectionChanged(int idx);
+};
+
+#endif // BITCOIN_QT_QVALUECOMBOBOX_H
diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp
new file mode 100644
index 0000000000..43b46c63b5
--- /dev/null
+++ b/src/qt/receivecoinsdialog.cpp
@@ -0,0 +1,269 @@
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "receivecoinsdialog.h"
+#include "ui_receivecoinsdialog.h"
+
+#include "addressbookpage.h"
+#include "addresstablemodel.h"
+#include "bitcoinunits.h"
+#include "guiutil.h"
+#include "optionsmodel.h"
+#include "receiverequestdialog.h"
+#include "recentrequeststablemodel.h"
+#include "scicon.h"
+#include "walletmodel.h"
+
+#include <QAction>
+#include <QCursor>
+#include <QItemSelection>
+#include <QMessageBox>
+#include <QScrollBar>
+#include <QTextDocument>
+
+ReceiveCoinsDialog::ReceiveCoinsDialog(QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::ReceiveCoinsDialog),
+ model(0)
+{
+ ui->setupUi(this);
+
+#ifdef Q_OS_MAC // Icons on push buttons are very uncommon on Mac
+ ui->clearButton->setIcon(QIcon());
+ ui->receiveButton->setIcon(QIcon());
+ ui->showRequestButton->setIcon(QIcon());
+ ui->removeRequestButton->setIcon(QIcon());
+#else
+ ui->clearButton->setIcon(SingleColorIcon(":/icons/remove"));
+ ui->receiveButton->setIcon(SingleColorIcon(":/icons/receiving_addresses"));
+ ui->showRequestButton->setIcon(SingleColorIcon(":/icons/edit"));
+ ui->removeRequestButton->setIcon(SingleColorIcon(":/icons/remove"));
+#endif
+
+ // context menu actions
+ QAction *copyLabelAction = new QAction(tr("Copy label"), this);
+ QAction *copyMessageAction = new QAction(tr("Copy message"), this);
+ QAction *copyAmountAction = new QAction(tr("Copy amount"), this);
+
+ // context menu
+ contextMenu = new QMenu();
+ contextMenu->addAction(copyLabelAction);
+ contextMenu->addAction(copyMessageAction);
+ contextMenu->addAction(copyAmountAction);
+
+ // context menu signals
+ connect(ui->recentRequestsView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showMenu(QPoint)));
+ connect(copyLabelAction, SIGNAL(triggered()), this, SLOT(copyLabel()));
+ connect(copyMessageAction, SIGNAL(triggered()), this, SLOT(copyMessage()));
+ connect(copyAmountAction, SIGNAL(triggered()), this, SLOT(copyAmount()));
+
+ connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(clear()));
+}
+
+void ReceiveCoinsDialog::setModel(WalletModel *model)
+{
+ this->model = model;
+
+ if(model && model->getOptionsModel())
+ {
+ model->getRecentRequestsTableModel()->sort(RecentRequestsTableModel::Date, Qt::DescendingOrder);
+ connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
+ updateDisplayUnit();
+
+ QTableView* tableView = ui->recentRequestsView;
+
+ tableView->verticalHeader()->hide();
+ tableView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ tableView->setModel(model->getRecentRequestsTableModel());
+ tableView->setAlternatingRowColors(true);
+ tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
+ tableView->setSelectionMode(QAbstractItemView::ContiguousSelection);
+ tableView->setColumnWidth(RecentRequestsTableModel::Date, DATE_COLUMN_WIDTH);
+ tableView->setColumnWidth(RecentRequestsTableModel::Label, LABEL_COLUMN_WIDTH);
+
+ connect(tableView->selectionModel(),
+ SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this,
+ SLOT(recentRequestsView_selectionChanged(QItemSelection, QItemSelection)));
+ // Last 2 columns are set by the columnResizingFixer, when the table geometry is ready.
+ columnResizingFixer = new GUIUtil::TableViewLastColumnResizingFixer(tableView, AMOUNT_MINIMUM_COLUMN_WIDTH, DATE_COLUMN_WIDTH);
+ }
+}
+
+ReceiveCoinsDialog::~ReceiveCoinsDialog()
+{
+ delete ui;
+}
+
+void ReceiveCoinsDialog::clear()
+{
+ ui->reqAmount->clear();
+ ui->reqLabel->setText("");
+ ui->reqMessage->setText("");
+ ui->reuseAddress->setChecked(false);
+ updateDisplayUnit();
+}
+
+void ReceiveCoinsDialog::reject()
+{
+ clear();
+}
+
+void ReceiveCoinsDialog::accept()
+{
+ clear();
+}
+
+void ReceiveCoinsDialog::updateDisplayUnit()
+{
+ if(model && model->getOptionsModel())
+ {
+ ui->reqAmount->setDisplayUnit(model->getOptionsModel()->getDisplayUnit());
+ }
+}
+
+void ReceiveCoinsDialog::on_receiveButton_clicked()
+{
+ if(!model || !model->getOptionsModel() || !model->getAddressTableModel() || !model->getRecentRequestsTableModel())
+ return;
+
+ QString address;
+ QString label = ui->reqLabel->text();
+ if(ui->reuseAddress->isChecked())
+ {
+ /* Choose existing receiving address */
+ AddressBookPage dlg(AddressBookPage::ForSelection, AddressBookPage::ReceivingTab, this);
+ dlg.setModel(model->getAddressTableModel());
+ if(dlg.exec())
+ {
+ address = dlg.getReturnValue();
+ if(label.isEmpty()) /* If no label provided, use the previously used label */
+ {
+ label = model->getAddressTableModel()->labelForAddress(address);
+ }
+ } else {
+ return;
+ }
+ } else {
+ /* Generate new receiving address */
+ address = model->getAddressTableModel()->addRow(AddressTableModel::Receive, label, "");
+ }
+ SendCoinsRecipient info(address, label,
+ ui->reqAmount->value(), ui->reqMessage->text());
+ ReceiveRequestDialog *dialog = new ReceiveRequestDialog(this);
+ dialog->setAttribute(Qt::WA_DeleteOnClose);
+ dialog->setModel(model->getOptionsModel());
+ dialog->setInfo(info);
+ dialog->show();
+ clear();
+
+ /* Store request for later reference */
+ model->getRecentRequestsTableModel()->addNewRequest(info);
+}
+
+void ReceiveCoinsDialog::on_recentRequestsView_doubleClicked(const QModelIndex &index)
+{
+ const RecentRequestsTableModel *submodel = model->getRecentRequestsTableModel();
+ ReceiveRequestDialog *dialog = new ReceiveRequestDialog(this);
+ dialog->setModel(model->getOptionsModel());
+ dialog->setInfo(submodel->entry(index.row()).recipient);
+ dialog->setAttribute(Qt::WA_DeleteOnClose);
+ dialog->show();
+}
+
+void ReceiveCoinsDialog::recentRequestsView_selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
+{
+ // Enable Show/Remove buttons only if anything is selected.
+ bool enable = !ui->recentRequestsView->selectionModel()->selectedRows().isEmpty();
+ ui->showRequestButton->setEnabled(enable);
+ ui->removeRequestButton->setEnabled(enable);
+}
+
+void ReceiveCoinsDialog::on_showRequestButton_clicked()
+{
+ if(!model || !model->getRecentRequestsTableModel() || !ui->recentRequestsView->selectionModel())
+ return;
+ QModelIndexList selection = ui->recentRequestsView->selectionModel()->selectedRows();
+
+ Q_FOREACH (const QModelIndex& index, selection) {
+ on_recentRequestsView_doubleClicked(index);
+ }
+}
+
+void ReceiveCoinsDialog::on_removeRequestButton_clicked()
+{
+ if(!model || !model->getRecentRequestsTableModel() || !ui->recentRequestsView->selectionModel())
+ return;
+ QModelIndexList selection = ui->recentRequestsView->selectionModel()->selectedRows();
+ if(selection.empty())
+ return;
+ // correct for selection mode ContiguousSelection
+ QModelIndex firstIndex = selection.at(0);
+ model->getRecentRequestsTableModel()->removeRows(firstIndex.row(), selection.length(), firstIndex.parent());
+}
+
+// We override the virtual resizeEvent of the QWidget to adjust tables column
+// sizes as the tables width is proportional to the dialogs width.
+void ReceiveCoinsDialog::resizeEvent(QResizeEvent *event)
+{
+ QWidget::resizeEvent(event);
+ columnResizingFixer->stretchColumnWidth(RecentRequestsTableModel::Message);
+}
+
+void ReceiveCoinsDialog::keyPressEvent(QKeyEvent *event)
+{
+ if (event->key() == Qt::Key_Return)
+ {
+ // press return -> submit form
+ if (ui->reqLabel->hasFocus() || ui->reqAmount->hasFocus() || ui->reqMessage->hasFocus())
+ {
+ event->ignore();
+ on_receiveButton_clicked();
+ return;
+ }
+ }
+
+ this->QDialog::keyPressEvent(event);
+}
+
+// copy column of selected row to clipboard
+void ReceiveCoinsDialog::copyColumnToClipboard(int column)
+{
+ if(!model || !model->getRecentRequestsTableModel() || !ui->recentRequestsView->selectionModel())
+ return;
+ QModelIndexList selection = ui->recentRequestsView->selectionModel()->selectedRows();
+ if(selection.empty())
+ return;
+ // correct for selection mode ContiguousSelection
+ QModelIndex firstIndex = selection.at(0);
+ GUIUtil::setClipboard(model->getRecentRequestsTableModel()->data(firstIndex.child(firstIndex.row(), column), Qt::EditRole).toString());
+}
+
+// context menu
+void ReceiveCoinsDialog::showMenu(const QPoint &point)
+{
+ if(!model || !model->getRecentRequestsTableModel() || !ui->recentRequestsView->selectionModel())
+ return;
+ QModelIndexList selection = ui->recentRequestsView->selectionModel()->selectedRows();
+ if(selection.empty())
+ return;
+ contextMenu->exec(QCursor::pos());
+}
+
+// context menu action: copy label
+void ReceiveCoinsDialog::copyLabel()
+{
+ copyColumnToClipboard(RecentRequestsTableModel::Label);
+}
+
+// context menu action: copy message
+void ReceiveCoinsDialog::copyMessage()
+{
+ copyColumnToClipboard(RecentRequestsTableModel::Message);
+}
+
+// context menu action: copy amount
+void ReceiveCoinsDialog::copyAmount()
+{
+ copyColumnToClipboard(RecentRequestsTableModel::Amount);
+}
diff --git a/src/qt/receivecoinsdialog.h b/src/qt/receivecoinsdialog.h
new file mode 100644
index 0000000000..6bb159482b
--- /dev/null
+++ b/src/qt/receivecoinsdialog.h
@@ -0,0 +1,76 @@
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_RECEIVECOINSDIALOG_H
+#define BITCOIN_QT_RECEIVECOINSDIALOG_H
+
+#include "guiutil.h"
+
+#include <QDialog>
+#include <QHeaderView>
+#include <QItemSelection>
+#include <QKeyEvent>
+#include <QMenu>
+#include <QPoint>
+#include <QVariant>
+
+class OptionsModel;
+class WalletModel;
+
+namespace Ui {
+ class ReceiveCoinsDialog;
+}
+
+QT_BEGIN_NAMESPACE
+class QModelIndex;
+QT_END_NAMESPACE
+
+/** Dialog for requesting payment of bitcoins */
+class ReceiveCoinsDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ enum ColumnWidths {
+ DATE_COLUMN_WIDTH = 130,
+ LABEL_COLUMN_WIDTH = 120,
+ AMOUNT_MINIMUM_COLUMN_WIDTH = 160,
+ MINIMUM_COLUMN_WIDTH = 130
+ };
+
+ explicit ReceiveCoinsDialog(QWidget *parent = 0);
+ ~ReceiveCoinsDialog();
+
+ void setModel(WalletModel *model);
+
+public Q_SLOTS:
+ void clear();
+ void reject();
+ void accept();
+
+protected:
+ virtual void keyPressEvent(QKeyEvent *event);
+
+private:
+ Ui::ReceiveCoinsDialog *ui;
+ GUIUtil::TableViewLastColumnResizingFixer *columnResizingFixer;
+ WalletModel *model;
+ QMenu *contextMenu;
+ void copyColumnToClipboard(int column);
+ virtual void resizeEvent(QResizeEvent *event);
+
+private Q_SLOTS:
+ void on_receiveButton_clicked();
+ void on_showRequestButton_clicked();
+ void on_removeRequestButton_clicked();
+ void on_recentRequestsView_doubleClicked(const QModelIndex &index);
+ void recentRequestsView_selectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
+ void updateDisplayUnit();
+ void showMenu(const QPoint &point);
+ void copyLabel();
+ void copyMessage();
+ void copyAmount();
+};
+
+#endif // BITCOIN_QT_RECEIVECOINSDIALOG_H
diff --git a/src/qt/receiverequestdialog.cpp b/src/qt/receiverequestdialog.cpp
new file mode 100644
index 0000000000..0c4a20cf92
--- /dev/null
+++ b/src/qt/receiverequestdialog.cpp
@@ -0,0 +1,197 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "receiverequestdialog.h"
+#include "ui_receiverequestdialog.h"
+
+#include "bitcoinunits.h"
+#include "guiconstants.h"
+#include "guiutil.h"
+#include "optionsmodel.h"
+#include "walletmodel.h"
+
+#include <QClipboard>
+#include <QDrag>
+#include <QMenu>
+#include <QMimeData>
+#include <QMouseEvent>
+#include <QPixmap>
+#if QT_VERSION < 0x050000
+#include <QUrl>
+#endif
+
+#if defined(HAVE_CONFIG_H)
+#include "config/bitcoin-config.h" /* for USE_QRCODE */
+#endif
+
+#ifdef USE_QRCODE
+#include <qrencode.h>
+#endif
+
+QRImageWidget::QRImageWidget(QWidget *parent):
+ QLabel(parent), contextMenu(0)
+{
+ contextMenu = new QMenu();
+ QAction *saveImageAction = new QAction(tr("&Save Image..."), this);
+ connect(saveImageAction, SIGNAL(triggered()), this, SLOT(saveImage()));
+ contextMenu->addAction(saveImageAction);
+ QAction *copyImageAction = new QAction(tr("&Copy Image"), this);
+ connect(copyImageAction, SIGNAL(triggered()), this, SLOT(copyImage()));
+ contextMenu->addAction(copyImageAction);
+}
+
+QImage QRImageWidget::exportImage()
+{
+ if(!pixmap())
+ return QImage();
+ return pixmap()->toImage().scaled(EXPORT_IMAGE_SIZE, EXPORT_IMAGE_SIZE);
+}
+
+void QRImageWidget::mousePressEvent(QMouseEvent *event)
+{
+ if(event->button() == Qt::LeftButton && pixmap())
+ {
+ event->accept();
+ QMimeData *mimeData = new QMimeData;
+ mimeData->setImageData(exportImage());
+
+ QDrag *drag = new QDrag(this);
+ drag->setMimeData(mimeData);
+ drag->exec();
+ } else {
+ QLabel::mousePressEvent(event);
+ }
+}
+
+void QRImageWidget::saveImage()
+{
+ if(!pixmap())
+ return;
+ QString fn = GUIUtil::getSaveFileName(this, tr("Save QR Code"), QString(), tr("PNG Image (*.png)"), NULL);
+ if (!fn.isEmpty())
+ {
+ exportImage().save(fn);
+ }
+}
+
+void QRImageWidget::copyImage()
+{
+ if(!pixmap())
+ return;
+ QApplication::clipboard()->setImage(exportImage());
+}
+
+void QRImageWidget::contextMenuEvent(QContextMenuEvent *event)
+{
+ if(!pixmap())
+ return;
+ contextMenu->exec(event->globalPos());
+}
+
+ReceiveRequestDialog::ReceiveRequestDialog(QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::ReceiveRequestDialog),
+ model(0)
+{
+ ui->setupUi(this);
+
+#ifndef USE_QRCODE
+ ui->btnSaveAs->setVisible(false);
+ ui->lblQRCode->setVisible(false);
+#endif
+
+ connect(ui->btnSaveAs, SIGNAL(clicked()), ui->lblQRCode, SLOT(saveImage()));
+}
+
+ReceiveRequestDialog::~ReceiveRequestDialog()
+{
+ delete ui;
+}
+
+void ReceiveRequestDialog::setModel(OptionsModel *model)
+{
+ this->model = model;
+
+ if (model)
+ connect(model, SIGNAL(displayUnitChanged(int)), this, SLOT(update()));
+
+ // update the display unit if necessary
+ update();
+}
+
+void ReceiveRequestDialog::setInfo(const SendCoinsRecipient &info)
+{
+ this->info = info;
+ update();
+}
+
+void ReceiveRequestDialog::update()
+{
+ if(!model)
+ return;
+ QString target = info.label;
+ if(target.isEmpty())
+ target = info.address;
+ setWindowTitle(tr("Request payment to %1").arg(target));
+
+ QString uri = GUIUtil::formatBitcoinURI(info);
+ ui->btnSaveAs->setEnabled(false);
+ QString html;
+ html += "<html><font face='verdana, arial, helvetica, sans-serif'>";
+ html += "<b>"+tr("Payment information")+"</b><br>";
+ html += "<b>"+tr("URI")+"</b>: ";
+ html += "<a href=\""+uri+"\">" + GUIUtil::HtmlEscape(uri) + "</a><br>";
+ html += "<b>"+tr("Address")+"</b>: " + GUIUtil::HtmlEscape(info.address) + "<br>";
+ if(info.amount)
+ html += "<b>"+tr("Amount")+"</b>: " + BitcoinUnits::formatWithUnit(model->getDisplayUnit(), info.amount) + "<br>";
+ if(!info.label.isEmpty())
+ html += "<b>"+tr("Label")+"</b>: " + GUIUtil::HtmlEscape(info.label) + "<br>";
+ if(!info.message.isEmpty())
+ html += "<b>"+tr("Message")+"</b>: " + GUIUtil::HtmlEscape(info.message) + "<br>";
+ ui->outUri->setText(html);
+
+#ifdef USE_QRCODE
+ ui->lblQRCode->setText("");
+ if(!uri.isEmpty())
+ {
+ // limit URI length
+ if (uri.length() > MAX_URI_LENGTH)
+ {
+ ui->lblQRCode->setText(tr("Resulting URI too long, try to reduce the text for label / message."));
+ } else {
+ 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;
+ }
+ QImage 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->btnSaveAs->setEnabled(true);
+ }
+ }
+#endif
+}
+
+void ReceiveRequestDialog::on_btnCopyURI_clicked()
+{
+ GUIUtil::setClipboard(GUIUtil::formatBitcoinURI(info));
+}
+
+void ReceiveRequestDialog::on_btnCopyAddress_clicked()
+{
+ GUIUtil::setClipboard(info.address);
+}
diff --git a/src/qt/receiverequestdialog.h b/src/qt/receiverequestdialog.h
new file mode 100644
index 0000000000..69f84ebbd7
--- /dev/null
+++ b/src/qt/receiverequestdialog.h
@@ -0,0 +1,70 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_RECEIVEREQUESTDIALOG_H
+#define BITCOIN_QT_RECEIVEREQUESTDIALOG_H
+
+#include "walletmodel.h"
+
+#include <QDialog>
+#include <QImage>
+#include <QLabel>
+
+class OptionsModel;
+
+namespace Ui {
+ class ReceiveRequestDialog;
+}
+
+QT_BEGIN_NAMESPACE
+class QMenu;
+QT_END_NAMESPACE
+
+/* Label widget for QR code. This image can be dragged, dropped, copied and saved
+ * to disk.
+ */
+class QRImageWidget : public QLabel
+{
+ Q_OBJECT
+
+public:
+ explicit QRImageWidget(QWidget *parent = 0);
+ QImage exportImage();
+
+public Q_SLOTS:
+ void saveImage();
+ void copyImage();
+
+protected:
+ virtual void mousePressEvent(QMouseEvent *event);
+ virtual void contextMenuEvent(QContextMenuEvent *event);
+
+private:
+ QMenu *contextMenu;
+};
+
+class ReceiveRequestDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit ReceiveRequestDialog(QWidget *parent = 0);
+ ~ReceiveRequestDialog();
+
+ void setModel(OptionsModel *model);
+ void setInfo(const SendCoinsRecipient &info);
+
+private Q_SLOTS:
+ void on_btnCopyURI_clicked();
+ void on_btnCopyAddress_clicked();
+
+ void update();
+
+private:
+ Ui::ReceiveRequestDialog *ui;
+ OptionsModel *model;
+ SendCoinsRecipient info;
+};
+
+#endif // BITCOIN_QT_RECEIVEREQUESTDIALOG_H
diff --git a/src/qt/recentrequeststablemodel.cpp b/src/qt/recentrequeststablemodel.cpp
new file mode 100644
index 0000000000..5692a7aaef
--- /dev/null
+++ b/src/qt/recentrequeststablemodel.cpp
@@ -0,0 +1,245 @@
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "recentrequeststablemodel.h"
+
+#include "bitcoinunits.h"
+#include "guiutil.h"
+#include "optionsmodel.h"
+
+#include "clientversion.h"
+#include "streams.h"
+
+#include <boost/foreach.hpp>
+
+RecentRequestsTableModel::RecentRequestsTableModel(CWallet *wallet, WalletModel *parent) :
+ walletModel(parent)
+{
+ Q_UNUSED(wallet);
+ nReceiveRequestsMaxId = 0;
+
+ // Load entries from wallet
+ std::vector<std::string> vReceiveRequests;
+ parent->loadReceiveRequests(vReceiveRequests);
+ BOOST_FOREACH(const std::string& request, vReceiveRequests)
+ addNewRequest(request);
+
+ /* These columns must match the indices in the ColumnIndex enumeration */
+ columns << tr("Date") << tr("Label") << tr("Message") << getAmountTitle();
+
+ connect(walletModel->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
+}
+
+RecentRequestsTableModel::~RecentRequestsTableModel()
+{
+ /* Intentionally left empty */
+}
+
+int RecentRequestsTableModel::rowCount(const QModelIndex &parent) const
+{
+ Q_UNUSED(parent);
+
+ return list.length();
+}
+
+int RecentRequestsTableModel::columnCount(const QModelIndex &parent) const
+{
+ Q_UNUSED(parent);
+
+ return columns.length();
+}
+
+QVariant RecentRequestsTableModel::data(const QModelIndex &index, int role) const
+{
+ if(!index.isValid() || index.row() >= list.length())
+ return QVariant();
+
+ const RecentRequestEntry *rec = &list[index.row()];
+
+ if(role == Qt::DisplayRole || role == Qt::EditRole)
+ {
+ switch(index.column())
+ {
+ case Date:
+ return GUIUtil::dateTimeStr(rec->date);
+ case Label:
+ if(rec->recipient.label.isEmpty() && role == Qt::DisplayRole)
+ {
+ return tr("(no label)");
+ }
+ else
+ {
+ return rec->recipient.label;
+ }
+ case Message:
+ if(rec->recipient.message.isEmpty() && role == Qt::DisplayRole)
+ {
+ return tr("(no message)");
+ }
+ else
+ {
+ return rec->recipient.message;
+ }
+ case Amount:
+ if (rec->recipient.amount == 0 && role == Qt::DisplayRole)
+ return tr("(no amount)");
+ else if (role == Qt::EditRole)
+ return BitcoinUnits::format(walletModel->getOptionsModel()->getDisplayUnit(), rec->recipient.amount, false, BitcoinUnits::separatorNever);
+ else
+ return BitcoinUnits::format(walletModel->getOptionsModel()->getDisplayUnit(), rec->recipient.amount);
+ }
+ }
+ else if (role == Qt::TextAlignmentRole)
+ {
+ if (index.column() == Amount)
+ return (int)(Qt::AlignRight|Qt::AlignVCenter);
+ }
+ return QVariant();
+}
+
+bool RecentRequestsTableModel::setData(const QModelIndex &index, const QVariant &value, int role)
+{
+ return true;
+}
+
+QVariant RecentRequestsTableModel::headerData(int section, Qt::Orientation orientation, int role) const
+{
+ if(orientation == Qt::Horizontal)
+ {
+ if(role == Qt::DisplayRole && section < columns.size())
+ {
+ return columns[section];
+ }
+ }
+ return QVariant();
+}
+
+/** Updates the column title to "Amount (DisplayUnit)" and emits headerDataChanged() signal for table headers to react. */
+void RecentRequestsTableModel::updateAmountColumnTitle()
+{
+ columns[Amount] = getAmountTitle();
+ Q_EMIT headerDataChanged(Qt::Horizontal,Amount,Amount);
+}
+
+/** Gets title for amount column including current display unit if optionsModel reference available. */
+QString RecentRequestsTableModel::getAmountTitle()
+{
+ QString amountTitle = tr("Amount");
+ if (this->walletModel->getOptionsModel() != NULL)
+ {
+ amountTitle += " ("+BitcoinUnits::name(this->walletModel->getOptionsModel()->getDisplayUnit()) + ")";
+ }
+ return amountTitle;
+}
+
+QModelIndex RecentRequestsTableModel::index(int row, int column, const QModelIndex &parent) const
+{
+ Q_UNUSED(parent);
+
+ return createIndex(row, column);
+}
+
+bool RecentRequestsTableModel::removeRows(int row, int count, const QModelIndex &parent)
+{
+ Q_UNUSED(parent);
+
+ if(count > 0 && row >= 0 && (row+count) <= list.size())
+ {
+ const RecentRequestEntry *rec;
+ for (int i = 0; i < count; ++i)
+ {
+ rec = &list[row+i];
+ if (!walletModel->saveReceiveRequest(rec->recipient.address.toStdString(), rec->id, ""))
+ return false;
+ }
+
+ beginRemoveRows(parent, row, row + count - 1);
+ list.erase(list.begin() + row, list.begin() + row + count);
+ endRemoveRows();
+ return true;
+ } else {
+ return false;
+ }
+}
+
+Qt::ItemFlags RecentRequestsTableModel::flags(const QModelIndex &index) const
+{
+ return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
+}
+
+// called when adding a request from the GUI
+void RecentRequestsTableModel::addNewRequest(const SendCoinsRecipient &recipient)
+{
+ RecentRequestEntry newEntry;
+ newEntry.id = ++nReceiveRequestsMaxId;
+ newEntry.date = QDateTime::currentDateTime();
+ newEntry.recipient = recipient;
+
+ CDataStream ss(SER_DISK, CLIENT_VERSION);
+ ss << newEntry;
+
+ if (!walletModel->saveReceiveRequest(recipient.address.toStdString(), newEntry.id, ss.str()))
+ return;
+
+ addNewRequest(newEntry);
+}
+
+// called from ctor when loading from wallet
+void RecentRequestsTableModel::addNewRequest(const std::string &recipient)
+{
+ std::vector<char> data(recipient.begin(), recipient.end());
+ CDataStream ss(data, SER_DISK, CLIENT_VERSION);
+
+ RecentRequestEntry entry;
+ ss >> entry;
+
+ if (entry.id == 0) // should not happen
+ return;
+
+ if (entry.id > nReceiveRequestsMaxId)
+ nReceiveRequestsMaxId = entry.id;
+
+ addNewRequest(entry);
+}
+
+// actually add to table in GUI
+void RecentRequestsTableModel::addNewRequest(RecentRequestEntry &recipient)
+{
+ beginInsertRows(QModelIndex(), 0, 0);
+ list.prepend(recipient);
+ endInsertRows();
+}
+
+void RecentRequestsTableModel::sort(int column, Qt::SortOrder order)
+{
+ qSort(list.begin(), list.end(), RecentRequestEntryLessThan(column, order));
+ Q_EMIT dataChanged(index(0, 0, QModelIndex()), index(list.size() - 1, NUMBER_OF_COLUMNS - 1, QModelIndex()));
+}
+
+void RecentRequestsTableModel::updateDisplayUnit()
+{
+ updateAmountColumnTitle();
+}
+
+bool RecentRequestEntryLessThan::operator()(RecentRequestEntry &left, RecentRequestEntry &right) const
+{
+ RecentRequestEntry *pLeft = &left;
+ RecentRequestEntry *pRight = &right;
+ if (order == Qt::DescendingOrder)
+ std::swap(pLeft, pRight);
+
+ switch(column)
+ {
+ case RecentRequestsTableModel::Date:
+ return pLeft->date.toTime_t() < pRight->date.toTime_t();
+ case RecentRequestsTableModel::Label:
+ return pLeft->recipient.label < pRight->recipient.label;
+ case RecentRequestsTableModel::Message:
+ return pLeft->recipient.message < pRight->recipient.message;
+ case RecentRequestsTableModel::Amount:
+ return pLeft->recipient.amount < pRight->recipient.amount;
+ default:
+ return pLeft->id < pRight->id;
+ }
+}
diff --git a/src/qt/recentrequeststablemodel.h b/src/qt/recentrequeststablemodel.h
new file mode 100644
index 0000000000..64faa72d45
--- /dev/null
+++ b/src/qt/recentrequeststablemodel.h
@@ -0,0 +1,108 @@
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_RECENTREQUESTSTABLEMODEL_H
+#define BITCOIN_QT_RECENTREQUESTSTABLEMODEL_H
+
+#include "walletmodel.h"
+
+#include <QAbstractTableModel>
+#include <QStringList>
+#include <QDateTime>
+
+class CWallet;
+
+class RecentRequestEntry
+{
+public:
+ RecentRequestEntry() : nVersion(RecentRequestEntry::CURRENT_VERSION), id(0) { }
+
+ static const int CURRENT_VERSION = 1;
+ int nVersion;
+ int64_t id;
+ QDateTime date;
+ SendCoinsRecipient recipient;
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ unsigned int nDate = date.toTime_t();
+
+ READWRITE(this->nVersion);
+ nVersion = this->nVersion;
+ READWRITE(id);
+ READWRITE(nDate);
+ READWRITE(recipient);
+
+ if (ser_action.ForRead())
+ date = QDateTime::fromTime_t(nDate);
+ }
+};
+
+class RecentRequestEntryLessThan
+{
+public:
+ RecentRequestEntryLessThan(int nColumn, Qt::SortOrder fOrder):
+ column(nColumn), order(fOrder) {}
+ bool operator()(RecentRequestEntry &left, RecentRequestEntry &right) const;
+
+private:
+ int column;
+ Qt::SortOrder order;
+};
+
+/** Model for list of recently generated payment requests / bitcoin: URIs.
+ * Part of wallet model.
+ */
+class RecentRequestsTableModel: public QAbstractTableModel
+{
+ Q_OBJECT
+
+public:
+ explicit RecentRequestsTableModel(CWallet *wallet, WalletModel *parent);
+ ~RecentRequestsTableModel();
+
+ enum ColumnIndex {
+ Date = 0,
+ Label = 1,
+ Message = 2,
+ Amount = 3,
+ NUMBER_OF_COLUMNS
+ };
+
+ /** @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;
+ /*@}*/
+
+ const RecentRequestEntry &entry(int row) const { return list[row]; }
+ void addNewRequest(const SendCoinsRecipient &recipient);
+ void addNewRequest(const std::string &recipient);
+ void addNewRequest(RecentRequestEntry &recipient);
+
+public Q_SLOTS:
+ void sort(int column, Qt::SortOrder order = Qt::AscendingOrder);
+ void updateDisplayUnit();
+
+private:
+ WalletModel *walletModel;
+ QStringList columns;
+ QList<RecentRequestEntry> list;
+ int64_t nReceiveRequestsMaxId;
+
+ /** Updates the column title to "Amount (DisplayUnit)" and emits headerDataChanged() signal for table headers to react. */
+ void updateAmountColumnTitle();
+ /** Gets title for amount column including current display unit if optionsModel reference available. */
+ QString getAmountTitle();
+};
+
+#endif // BITCOIN_QT_RECENTREQUESTSTABLEMODEL_H
diff --git a/src/qt/res/bitcoin-qt-res.rc b/src/qt/res/bitcoin-qt-res.rc
new file mode 100644
index 0000000000..9f66d0af79
--- /dev/null
+++ b/src/qt/res/bitcoin-qt-res.rc
@@ -0,0 +1,37 @@
+IDI_ICON1 ICON DISCARDABLE "icons/bitcoin.ico"
+
+#include <windows.h> // needed for VERSIONINFO
+#include "../../clientversion.h" // holds the needed client version information
+
+#define VER_PRODUCTVERSION CLIENT_VERSION_MAJOR,CLIENT_VERSION_MINOR,CLIENT_VERSION_REVISION,CLIENT_VERSION_BUILD
+#define VER_PRODUCTVERSION_STR STRINGIZE(CLIENT_VERSION_MAJOR) "." STRINGIZE(CLIENT_VERSION_MINOR) "." STRINGIZE(CLIENT_VERSION_REVISION) "." STRINGIZE(CLIENT_VERSION_BUILD)
+#define VER_FILEVERSION VER_PRODUCTVERSION
+#define VER_FILEVERSION_STR VER_PRODUCTVERSION_STR
+
+VS_VERSION_INFO VERSIONINFO
+FILEVERSION VER_FILEVERSION
+PRODUCTVERSION VER_PRODUCTVERSION
+FILEOS VOS_NT_WINDOWS32
+FILETYPE VFT_APP
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904E4" // U.S. English - multilingual (hex)
+ BEGIN
+ VALUE "CompanyName", "Bitcoin"
+ VALUE "FileDescription", "Bitcoin Core (GUI node for Bitcoin)"
+ VALUE "FileVersion", VER_FILEVERSION_STR
+ VALUE "InternalName", "bitcoin-qt"
+ VALUE "LegalCopyright", COPYRIGHT_STR
+ VALUE "LegalTrademarks1", "Distributed under the MIT software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php."
+ VALUE "OriginalFilename", "bitcoin-qt.exe"
+ VALUE "ProductName", "Bitcoin Core"
+ VALUE "ProductVersion", VER_PRODUCTVERSION_STR
+ END
+ END
+
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0, 1252 // language neutral - multilingual (decimal)
+ END
+END
diff --git a/src/qt/res/icons/about.png b/src/qt/res/icons/about.png
new file mode 100644
index 0000000000..83eb3c07ee
--- /dev/null
+++ b/src/qt/res/icons/about.png
Binary files differ
diff --git a/src/qt/res/icons/about_qt.png b/src/qt/res/icons/about_qt.png
new file mode 100644
index 0000000000..dd27a99d0a
--- /dev/null
+++ b/src/qt/res/icons/about_qt.png
Binary files differ
diff --git a/src/qt/res/icons/add.png b/src/qt/res/icons/add.png
new file mode 100644
index 0000000000..1442b4e85e
--- /dev/null
+++ b/src/qt/res/icons/add.png
Binary files differ
diff --git a/src/qt/res/icons/address-book.png b/src/qt/res/icons/address-book.png
new file mode 100644
index 0000000000..b11c7d5356
--- /dev/null
+++ b/src/qt/res/icons/address-book.png
Binary files differ
diff --git a/src/qt/res/icons/bitcoin.icns b/src/qt/res/icons/bitcoin.icns
new file mode 100644
index 0000000000..54d02d34dd
--- /dev/null
+++ b/src/qt/res/icons/bitcoin.icns
Binary files differ
diff --git a/src/qt/res/icons/bitcoin.ico b/src/qt/res/icons/bitcoin.ico
new file mode 100755
index 0000000000..8f5045015d
--- /dev/null
+++ b/src/qt/res/icons/bitcoin.ico
Binary files differ
diff --git a/src/qt/res/icons/bitcoin.png b/src/qt/res/icons/bitcoin.png
new file mode 100644
index 0000000000..435621af23
--- /dev/null
+++ b/src/qt/res/icons/bitcoin.png
Binary files differ
diff --git a/src/qt/res/icons/clock1.png b/src/qt/res/icons/clock1.png
new file mode 100644
index 0000000000..ceae5ed0d9
--- /dev/null
+++ b/src/qt/res/icons/clock1.png
Binary files differ
diff --git a/src/qt/res/icons/clock2.png b/src/qt/res/icons/clock2.png
new file mode 100644
index 0000000000..159f69a8fc
--- /dev/null
+++ b/src/qt/res/icons/clock2.png
Binary files differ
diff --git a/src/qt/res/icons/clock3.png b/src/qt/res/icons/clock3.png
new file mode 100644
index 0000000000..d668e35ffc
--- /dev/null
+++ b/src/qt/res/icons/clock3.png
Binary files differ
diff --git a/src/qt/res/icons/clock4.png b/src/qt/res/icons/clock4.png
new file mode 100644
index 0000000000..5ebf8ed7ac
--- /dev/null
+++ b/src/qt/res/icons/clock4.png
Binary files differ
diff --git a/src/qt/res/icons/clock5.png b/src/qt/res/icons/clock5.png
new file mode 100644
index 0000000000..96f15ef7d9
--- /dev/null
+++ b/src/qt/res/icons/clock5.png
Binary files differ
diff --git a/src/qt/res/icons/configure.png b/src/qt/res/icons/configure.png
new file mode 100644
index 0000000000..5333c83d5e
--- /dev/null
+++ b/src/qt/res/icons/configure.png
Binary files differ
diff --git a/src/qt/res/icons/connect0.png b/src/qt/res/icons/connect0.png
new file mode 100644
index 0000000000..58e2c3e965
--- /dev/null
+++ b/src/qt/res/icons/connect0.png
Binary files differ
diff --git a/src/qt/res/icons/connect1.png b/src/qt/res/icons/connect1.png
new file mode 100644
index 0000000000..949e7a922d
--- /dev/null
+++ b/src/qt/res/icons/connect1.png
Binary files differ
diff --git a/src/qt/res/icons/connect2.png b/src/qt/res/icons/connect2.png
new file mode 100644
index 0000000000..143b2054fb
--- /dev/null
+++ b/src/qt/res/icons/connect2.png
Binary files differ
diff --git a/src/qt/res/icons/connect3.png b/src/qt/res/icons/connect3.png
new file mode 100644
index 0000000000..143b2054fb
--- /dev/null
+++ b/src/qt/res/icons/connect3.png
Binary files differ
diff --git a/src/qt/res/icons/connect4.png b/src/qt/res/icons/connect4.png
new file mode 100644
index 0000000000..f96e3455ce
--- /dev/null
+++ b/src/qt/res/icons/connect4.png
Binary files differ
diff --git a/src/qt/res/icons/debugwindow.png b/src/qt/res/icons/debugwindow.png
new file mode 100644
index 0000000000..290fe60864
--- /dev/null
+++ b/src/qt/res/icons/debugwindow.png
Binary files differ
diff --git a/src/qt/res/icons/edit.png b/src/qt/res/icons/edit.png
new file mode 100644
index 0000000000..46582716ef
--- /dev/null
+++ b/src/qt/res/icons/edit.png
Binary files differ
diff --git a/src/qt/res/icons/editcopy.png b/src/qt/res/icons/editcopy.png
new file mode 100644
index 0000000000..74ac8b2774
--- /dev/null
+++ b/src/qt/res/icons/editcopy.png
Binary files differ
diff --git a/src/qt/res/icons/editpaste.png b/src/qt/res/icons/editpaste.png
new file mode 100644
index 0000000000..7b47f4d52b
--- /dev/null
+++ b/src/qt/res/icons/editpaste.png
Binary files differ
diff --git a/src/qt/res/icons/export.png b/src/qt/res/icons/export.png
new file mode 100644
index 0000000000..ac76cc1eff
--- /dev/null
+++ b/src/qt/res/icons/export.png
Binary files differ
diff --git a/src/qt/res/icons/eye.png b/src/qt/res/icons/eye.png
new file mode 100644
index 0000000000..f2f139dbb2
--- /dev/null
+++ b/src/qt/res/icons/eye.png
Binary files differ
diff --git a/src/qt/res/icons/eye_minus.png b/src/qt/res/icons/eye_minus.png
new file mode 100644
index 0000000000..795bf6436a
--- /dev/null
+++ b/src/qt/res/icons/eye_minus.png
Binary files differ
diff --git a/src/qt/res/icons/eye_plus.png b/src/qt/res/icons/eye_plus.png
new file mode 100644
index 0000000000..eaab69297a
--- /dev/null
+++ b/src/qt/res/icons/eye_plus.png
Binary files differ
diff --git a/src/qt/res/icons/filesave.png b/src/qt/res/icons/filesave.png
new file mode 100644
index 0000000000..779cca1d52
--- /dev/null
+++ b/src/qt/res/icons/filesave.png
Binary files differ
diff --git a/src/qt/res/icons/history.png b/src/qt/res/icons/history.png
new file mode 100644
index 0000000000..68d841fa85
--- /dev/null
+++ b/src/qt/res/icons/history.png
Binary files differ
diff --git a/src/qt/res/icons/info.png b/src/qt/res/icons/info.png
new file mode 100644
index 0000000000..692b50c2a9
--- /dev/null
+++ b/src/qt/res/icons/info.png
Binary files differ
diff --git a/src/qt/res/icons/key.png b/src/qt/res/icons/key.png
new file mode 100644
index 0000000000..f301c4f38c
--- /dev/null
+++ b/src/qt/res/icons/key.png
Binary files differ
diff --git a/src/qt/res/icons/lock_closed.png b/src/qt/res/icons/lock_closed.png
new file mode 100644
index 0000000000..1bd98b21a6
--- /dev/null
+++ b/src/qt/res/icons/lock_closed.png
Binary files differ
diff --git a/src/qt/res/icons/lock_open.png b/src/qt/res/icons/lock_open.png
new file mode 100644
index 0000000000..a7045133b1
--- /dev/null
+++ b/src/qt/res/icons/lock_open.png
Binary files differ
diff --git a/src/qt/res/icons/open.png b/src/qt/res/icons/open.png
new file mode 100644
index 0000000000..4d958f0e18
--- /dev/null
+++ b/src/qt/res/icons/open.png
Binary files differ
diff --git a/src/qt/res/icons/overview.png b/src/qt/res/icons/overview.png
new file mode 100644
index 0000000000..411595413d
--- /dev/null
+++ b/src/qt/res/icons/overview.png
Binary files differ
diff --git a/src/qt/res/icons/quit.png b/src/qt/res/icons/quit.png
new file mode 100644
index 0000000000..55e34de4b8
--- /dev/null
+++ b/src/qt/res/icons/quit.png
Binary files differ
diff --git a/src/qt/res/icons/receive.png b/src/qt/res/icons/receive.png
new file mode 100644
index 0000000000..f4e6f58d05
--- /dev/null
+++ b/src/qt/res/icons/receive.png
Binary files differ
diff --git a/src/qt/res/icons/remove.png b/src/qt/res/icons/remove.png
new file mode 100644
index 0000000000..8e738d6301
--- /dev/null
+++ b/src/qt/res/icons/remove.png
Binary files differ
diff --git a/src/qt/res/icons/send.png b/src/qt/res/icons/send.png
new file mode 100644
index 0000000000..ac76cc1eff
--- /dev/null
+++ b/src/qt/res/icons/send.png
Binary files differ
diff --git a/src/qt/res/icons/synced.png b/src/qt/res/icons/synced.png
new file mode 100644
index 0000000000..5ac28d36a3
--- /dev/null
+++ b/src/qt/res/icons/synced.png
Binary files differ
diff --git a/src/qt/res/icons/transaction0.png b/src/qt/res/icons/transaction0.png
new file mode 100644
index 0000000000..1091b86e68
--- /dev/null
+++ b/src/qt/res/icons/transaction0.png
Binary files differ
diff --git a/src/qt/res/icons/transaction2.png b/src/qt/res/icons/transaction2.png
new file mode 100644
index 0000000000..5ac28d36a3
--- /dev/null
+++ b/src/qt/res/icons/transaction2.png
Binary files differ
diff --git a/src/qt/res/icons/transaction_conflicted.png b/src/qt/res/icons/transaction_conflicted.png
new file mode 100644
index 0000000000..55e34de4b8
--- /dev/null
+++ b/src/qt/res/icons/transaction_conflicted.png
Binary files differ
diff --git a/src/qt/res/icons/tx_inout.png b/src/qt/res/icons/tx_inout.png
new file mode 100644
index 0000000000..0a6e72a898
--- /dev/null
+++ b/src/qt/res/icons/tx_inout.png
Binary files differ
diff --git a/src/qt/res/icons/tx_input.png b/src/qt/res/icons/tx_input.png
new file mode 100644
index 0000000000..9e9ee92932
--- /dev/null
+++ b/src/qt/res/icons/tx_input.png
Binary files differ
diff --git a/src/qt/res/icons/tx_mined.png b/src/qt/res/icons/tx_mined.png
new file mode 100644
index 0000000000..5a6ef521c0
--- /dev/null
+++ b/src/qt/res/icons/tx_mined.png
Binary files differ
diff --git a/src/qt/res/icons/tx_output.png b/src/qt/res/icons/tx_output.png
new file mode 100644
index 0000000000..6f66ab6547
--- /dev/null
+++ b/src/qt/res/icons/tx_output.png
Binary files differ
diff --git a/src/qt/res/icons/verify.png b/src/qt/res/icons/verify.png
new file mode 100644
index 0000000000..8e2cb2cc14
--- /dev/null
+++ b/src/qt/res/icons/verify.png
Binary files differ
diff --git a/src/qt/res/icons/warning.png b/src/qt/res/icons/warning.png
new file mode 100644
index 0000000000..723a30a658
--- /dev/null
+++ b/src/qt/res/icons/warning.png
Binary files differ
diff --git a/src/qt/res/movies/makespinner.sh b/src/qt/res/movies/makespinner.sh
new file mode 100755
index 0000000000..625fb17173
--- /dev/null
+++ b/src/qt/res/movies/makespinner.sh
@@ -0,0 +1,6 @@
+for i in {1..35}
+do
+ value=$(printf "%03d" $i)
+ angle=$(($i * 10))
+ convert spinner-000.png -background "rgba(0,0,0,0.0)" -distort SRT $angle spinner-$value.png
+done
diff --git a/src/qt/res/movies/spinner-000.png b/src/qt/res/movies/spinner-000.png
new file mode 100644
index 0000000000..1e92d859da
--- /dev/null
+++ b/src/qt/res/movies/spinner-000.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-001.png b/src/qt/res/movies/spinner-001.png
new file mode 100644
index 0000000000..d167f20541
--- /dev/null
+++ b/src/qt/res/movies/spinner-001.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-002.png b/src/qt/res/movies/spinner-002.png
new file mode 100644
index 0000000000..4a1f1f8e56
--- /dev/null
+++ b/src/qt/res/movies/spinner-002.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-003.png b/src/qt/res/movies/spinner-003.png
new file mode 100644
index 0000000000..fb1c2cd4ad
--- /dev/null
+++ b/src/qt/res/movies/spinner-003.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-004.png b/src/qt/res/movies/spinner-004.png
new file mode 100644
index 0000000000..4df2132344
--- /dev/null
+++ b/src/qt/res/movies/spinner-004.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-005.png b/src/qt/res/movies/spinner-005.png
new file mode 100644
index 0000000000..5d6f41e0dc
--- /dev/null
+++ b/src/qt/res/movies/spinner-005.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-006.png b/src/qt/res/movies/spinner-006.png
new file mode 100644
index 0000000000..c1f7d18899
--- /dev/null
+++ b/src/qt/res/movies/spinner-006.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-007.png b/src/qt/res/movies/spinner-007.png
new file mode 100644
index 0000000000..1e794b2626
--- /dev/null
+++ b/src/qt/res/movies/spinner-007.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-008.png b/src/qt/res/movies/spinner-008.png
new file mode 100644
index 0000000000..df12ea8719
--- /dev/null
+++ b/src/qt/res/movies/spinner-008.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-009.png b/src/qt/res/movies/spinner-009.png
new file mode 100644
index 0000000000..18fc3a7d16
--- /dev/null
+++ b/src/qt/res/movies/spinner-009.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-010.png b/src/qt/res/movies/spinner-010.png
new file mode 100644
index 0000000000..a79c845fe8
--- /dev/null
+++ b/src/qt/res/movies/spinner-010.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-011.png b/src/qt/res/movies/spinner-011.png
new file mode 100644
index 0000000000..57baf66895
--- /dev/null
+++ b/src/qt/res/movies/spinner-011.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-012.png b/src/qt/res/movies/spinner-012.png
new file mode 100644
index 0000000000..9deae7853a
--- /dev/null
+++ b/src/qt/res/movies/spinner-012.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-013.png b/src/qt/res/movies/spinner-013.png
new file mode 100644
index 0000000000..0659d48dec
--- /dev/null
+++ b/src/qt/res/movies/spinner-013.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-014.png b/src/qt/res/movies/spinner-014.png
new file mode 100644
index 0000000000..bc1ef51bde
--- /dev/null
+++ b/src/qt/res/movies/spinner-014.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-015.png b/src/qt/res/movies/spinner-015.png
new file mode 100644
index 0000000000..24b57b62c2
--- /dev/null
+++ b/src/qt/res/movies/spinner-015.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-016.png b/src/qt/res/movies/spinner-016.png
new file mode 100644
index 0000000000..d622872651
--- /dev/null
+++ b/src/qt/res/movies/spinner-016.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-017.png b/src/qt/res/movies/spinner-017.png
new file mode 100644
index 0000000000..f48f688db2
--- /dev/null
+++ b/src/qt/res/movies/spinner-017.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-018.png b/src/qt/res/movies/spinner-018.png
new file mode 100644
index 0000000000..a2c8f38b1d
--- /dev/null
+++ b/src/qt/res/movies/spinner-018.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-019.png b/src/qt/res/movies/spinner-019.png
new file mode 100644
index 0000000000..9d7cc35d82
--- /dev/null
+++ b/src/qt/res/movies/spinner-019.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-020.png b/src/qt/res/movies/spinner-020.png
new file mode 100644
index 0000000000..1a07acc454
--- /dev/null
+++ b/src/qt/res/movies/spinner-020.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-021.png b/src/qt/res/movies/spinner-021.png
new file mode 100644
index 0000000000..9cea8f2543
--- /dev/null
+++ b/src/qt/res/movies/spinner-021.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-022.png b/src/qt/res/movies/spinner-022.png
new file mode 100644
index 0000000000..60250f6dea
--- /dev/null
+++ b/src/qt/res/movies/spinner-022.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-023.png b/src/qt/res/movies/spinner-023.png
new file mode 100644
index 0000000000..fc290a0cf2
--- /dev/null
+++ b/src/qt/res/movies/spinner-023.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-024.png b/src/qt/res/movies/spinner-024.png
new file mode 100644
index 0000000000..c5dcf1eae9
--- /dev/null
+++ b/src/qt/res/movies/spinner-024.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-025.png b/src/qt/res/movies/spinner-025.png
new file mode 100644
index 0000000000..7f3577a4de
--- /dev/null
+++ b/src/qt/res/movies/spinner-025.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-026.png b/src/qt/res/movies/spinner-026.png
new file mode 100644
index 0000000000..1663ddf44c
--- /dev/null
+++ b/src/qt/res/movies/spinner-026.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-027.png b/src/qt/res/movies/spinner-027.png
new file mode 100644
index 0000000000..d0e6da4503
--- /dev/null
+++ b/src/qt/res/movies/spinner-027.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-028.png b/src/qt/res/movies/spinner-028.png
new file mode 100644
index 0000000000..2a7aba50e2
--- /dev/null
+++ b/src/qt/res/movies/spinner-028.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-029.png b/src/qt/res/movies/spinner-029.png
new file mode 100644
index 0000000000..c8ca15c1e1
--- /dev/null
+++ b/src/qt/res/movies/spinner-029.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-030.png b/src/qt/res/movies/spinner-030.png
new file mode 100644
index 0000000000..c847c99a93
--- /dev/null
+++ b/src/qt/res/movies/spinner-030.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-031.png b/src/qt/res/movies/spinner-031.png
new file mode 100644
index 0000000000..403443144e
--- /dev/null
+++ b/src/qt/res/movies/spinner-031.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-032.png b/src/qt/res/movies/spinner-032.png
new file mode 100644
index 0000000000..f9db080567
--- /dev/null
+++ b/src/qt/res/movies/spinner-032.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-033.png b/src/qt/res/movies/spinner-033.png
new file mode 100644
index 0000000000..43f57719e7
--- /dev/null
+++ b/src/qt/res/movies/spinner-033.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-034.png b/src/qt/res/movies/spinner-034.png
new file mode 100644
index 0000000000..c26656ff17
--- /dev/null
+++ b/src/qt/res/movies/spinner-034.png
Binary files differ
diff --git a/src/qt/res/movies/spinner-035.png b/src/qt/res/movies/spinner-035.png
new file mode 100644
index 0000000000..e471f950a3
--- /dev/null
+++ b/src/qt/res/movies/spinner-035.png
Binary files differ
diff --git a/src/qt/res/spinner.png b/src/qt/res/spinner.png
new file mode 100644
index 0000000000..b296a58481
--- /dev/null
+++ b/src/qt/res/spinner.png
Binary files differ
diff --git a/src/qt/res/src/bitcoin.svg b/src/qt/res/src/bitcoin.svg
new file mode 100644
index 0000000000..14cf0c5e11
--- /dev/null
+++ b/src/qt/res/src/bitcoin.svg
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Designer: Jonas Schnelli
+ License: MIT
+-->
+
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1"
+ id="svg2" sodipodi:docname="bitcoin-logo-noshadow.svg" inkscape:version="0.48.2 r9819" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="1024px" height="1024px"
+ viewBox="-34 -34 580 580" enable-background="new 0 0 1024 1024" xml:space="preserve">
+
+ <!-- nice shadow with alpha 0.35 -->
+ <filter id="dropShadowAlpha">
+ <feColorMatrix result="matrixOut" in="SourceAlpha" type="saturate"
+ values="0.1" />
+ <feGaussianBlur in="matrixOut" result="blur-out" stdDeviation="6" />
+ <feColorMatrix in="blur-out" result="color-out" type="matrix"
+ values="0 0 0 0 0
+ 0 0 0 0 0
+ 0 0 0 0 0
+ 0 0 0 0.35 0"/>
+ <feBlend in="SourceGraphic" in2="color-out" mode="normal" />
+ </filter>
+
+ <g>
+ <!-- white background circle for making B not transparent but still keep inner shadows -->
+ <circle cx="255" cy="255" r="200" stroke-width="2" fill="white"/>
+
+ <radialGradient id="innerBtop" cx="277.4905" cy="196.4412" r="34.3969" gradientUnits="userSpaceOnUse">
+ <stop offset="0" style="stop-color:#F9AA4B"/>
+ <stop offset="1" style="stop-color:#F7931A"/>
+ </radialGradient>
+ <path fill="url(#innerBtop)" filter="url(#dropShadowAlpha)" d="M254.647,174.6l-13.983,56.08c15.855,3.951,64.735,20.071,72.656-11.656
+ C321.568,185.928,270.503,178.552,254.647,174.6z"/>
+
+ <radialGradient id="innerBbottom" cx="261.9153" cy="284.5671" r="39.8381" gradientUnits="userSpaceOnUse">
+ <stop offset="0" style="stop-color:#F9AA4B"/>
+ <stop offset="1" style="stop-color:#F7931A"/>
+ </radialGradient>
+ <path fill="url(#innerBbottom)" filter="url(#dropShadowAlpha)" d="M233.608,258.984l-15.425,61.832c19.04,4.729,77.769,23.584,86.448-11.296
+ C313.703,273.144,252.647,263.736,233.608,258.984z"/>
+
+ <radialGradient id="coinShape" cx="256.0276" cy="256.0027" r="255.9878" gradientUnits="userSpaceOnUse">
+ <stop offset="0" style="stop-color:#F9AA4B"/>
+ <stop offset="1" style="stop-color:#F7931A"/>
+ </radialGradient>
+ <path fill="url(#coinShape)" filter="url(#dropShadowAlpha)" d="M317.871,7.656c-137.12-34.192-276.024,49.28-310.2,186.44
+ c-34.208,137.136,49.256,276.048,186.36,310.24c137.16,34.199,276.063-49.265,310.256-186.408
+ C538.479,180.776,455.023,41.848,317.871,7.656z M368.807,219.528c-3.688,24.936-17.512,37.008-35.864,41.24
+ c25.2,13.12,38.024,33.239,25.809,68.12c-15.16,43.319-51.176,46.976-99.072,37.912l-11.624,46.584l-28.088-7l11.472-45.96
+ c-7.279-1.809-14.72-3.729-22.384-5.809l-11.512,46.177l-28.056-7l11.624-46.673c-6.561-1.68-13.225-3.464-20.024-5.168
+ l-36.552-9.111l13.943-32.152c0,0,20.696,5.504,20.416,5.096c7.952,1.969,11.48-3.216,12.872-6.672l18.368-73.64l0.048-0.2
+ l13.104-52.568c0.344-5.968-1.712-13.496-13.088-16.336c0.439-0.296-20.4-5.072-20.4-5.072l7.472-30l38.736,9.673l-0.032,0.144
+ c5.824,1.448,11.824,2.824,17.937,4.216L245.423,89.2l28.072,7l-11.28,45.224c7.536,1.721,15.12,3.456,22.504,5.297l11.2-44.929
+ l28.088,7l-11.504,46.145C347.967,167.152,373.904,185.464,368.807,219.528z"/>
+ </g>
+</svg>
diff --git a/src/qt/res/src/clock_0.svg b/src/qt/res/src/clock_0.svg
new file mode 100644
index 0000000000..2a4ae02355
--- /dev/null
+++ b/src/qt/res/src/clock_0.svg
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 18.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 841.9 841.9" enable-background="new 0 0 841.9 841.9" xml:space="preserve">
+<g>
+ <path d="M297.6,677.3c-68.5,0-132.9-26.7-181.3-75.1S41.3,489.4,41.3,420.9s26.7-132.9,75.1-181.3c48.4-48.4,112.8-75.1,181.3-75.1
+ s132.9,26.7,181.3,75.1c48.4,48.4,75.1,112.8,75.1,181.3s-26.7,132.9-75.1,181.3S366.1,677.3,297.6,677.3z M297.6,204.6
+ c-57.8,0-112.1,22.5-153,63.4c-40.9,40.9-63.4,95.2-63.4,153c0,57.8,22.5,112.1,63.4,153c40.9,40.9,95.2,63.4,153,63.4
+ c57.8,0,112.1-22.5,153-63.4c40.9-40.9,63.4-95.2,63.4-153c0-57.8-22.5-112.1-63.4-153C409.8,227.1,355.4,204.6,297.6,204.6z"/>
+</g>
+<path fill="#000000" d="M293.5,452.6h99.6c14.9,0,24.8-9.9,24.8-24.8S408,403,393.1,403h-74.8V278.2c0-14.9-9.9-24.8-24.8-24.8
+ c-14.9,0-24.8,9.9-24.8,24.8v149.6C268.7,440.2,278.7,452.6,293.5,452.6z"/>
+</svg>
diff --git a/src/qt/res/src/clock_1.svg b/src/qt/res/src/clock_1.svg
new file mode 100644
index 0000000000..4e49772d26
--- /dev/null
+++ b/src/qt/res/src/clock_1.svg
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 18.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 841.9 841.9" enable-background="new 0 0 841.9 841.9" xml:space="preserve">
+<g>
+ <path d="M297.6,677.3c-68.5,0-132.9-26.7-181.3-75.1S41.3,489.4,41.3,420.9s26.7-132.9,75.1-181.3c48.4-48.4,112.8-75.1,181.3-75.1
+ s132.9,26.7,181.3,75.1c48.4,48.4,75.1,112.8,75.1,181.3s-26.7,132.9-75.1,181.3S366.1,677.3,297.6,677.3z M297.6,204.6
+ c-57.8,0-112.1,22.5-153,63.4c-40.9,40.9-63.4,95.2-63.4,153c0,57.8,22.5,112.1,63.4,153c40.9,40.9,95.2,63.4,153,63.4
+ c57.8,0,112.1-22.5,153-63.4c40.9-40.9,63.4-95.2,63.4-153c0-57.8-22.5-112.1-63.4-153C409.8,227.1,355.4,204.6,297.6,204.6z"/>
+</g>
+<polygon points="478.3,253.4 297.6,184.6 297.6,420.9 534,420.9 "/>
+</svg>
diff --git a/src/qt/res/src/clock_2.svg b/src/qt/res/src/clock_2.svg
new file mode 100644
index 0000000000..995446e46e
--- /dev/null
+++ b/src/qt/res/src/clock_2.svg
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 18.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 841.9 841.9" enable-background="new 0 0 841.9 841.9" xml:space="preserve">
+<g>
+ <path d="M297.6,677.3c-68.5,0-132.9-26.7-181.3-75.1S41.3,489.4,41.3,420.9s26.7-132.9,75.1-181.3c48.4-48.4,112.8-75.1,181.3-75.1
+ s132.9,26.7,181.3,75.1c48.4,48.4,75.1,112.8,75.1,181.3s-26.7,132.9-75.1,181.3S366.1,677.3,297.6,677.3z M297.6,204.6
+ c-57.8,0-112.1,22.5-153,63.4c-40.9,40.9-63.4,95.2-63.4,153c0,57.8,22.5,112.1,63.4,153c40.9,40.9,95.2,63.4,153,63.4
+ c57.8,0,112.1-22.5,153-63.4c40.9-40.9,63.4-95.2,63.4-153c0-57.8-22.5-112.1-63.4-153C409.8,227.1,355.4,204.6,297.6,204.6z"/>
+</g>
+<polygon points="465.2,601.6 534,420.9 297.6,420.9 297.6,657.3 "/>
+<polygon points="478.3,253.4 297.6,184.6 297.6,420.9 534,420.9 "/>
+</svg>
diff --git a/src/qt/res/src/clock_3.svg b/src/qt/res/src/clock_3.svg
new file mode 100644
index 0000000000..ea47a84730
--- /dev/null
+++ b/src/qt/res/src/clock_3.svg
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 18.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 841.9 841.9" enable-background="new 0 0 841.9 841.9" xml:space="preserve">
+<g>
+ <path d="M297.6,677.3c-68.5,0-132.9-26.7-181.3-75.1S41.3,489.4,41.3,420.9s26.7-132.9,75.1-181.3c48.4-48.4,112.8-75.1,181.3-75.1
+ s132.9,26.7,181.3,75.1c48.4,48.4,75.1,112.8,75.1,181.3s-26.7,132.9-75.1,181.3S366.1,677.3,297.6,677.3z M297.6,204.6
+ c-57.8,0-112.1,22.5-153,63.4c-40.9,40.9-63.4,95.2-63.4,153c0,57.8,22.5,112.1,63.4,153c40.9,40.9,95.2,63.4,153,63.4
+ c57.8,0,112.1-22.5,153-63.4c40.9-40.9,63.4-95.2,63.4-153c0-57.8-22.5-112.1-63.4-153C409.8,227.1,355.4,204.6,297.6,204.6z"/>
+</g>
+<polygon points="117,588.5 297.6,657.3 297.6,420.9 61.3,420.9 "/>
+<polygon points="465.2,601.6 534,420.9 297.6,420.9 297.6,657.3 "/>
+<polygon points="478.3,253.4 297.6,184.6 297.6,420.9 534,420.9 "/>
+</svg>
diff --git a/src/qt/res/src/clock_4.svg b/src/qt/res/src/clock_4.svg
new file mode 100644
index 0000000000..43160288d8
--- /dev/null
+++ b/src/qt/res/src/clock_4.svg
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 18.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 841.9 841.9" enable-background="new 0 0 841.9 841.9" xml:space="preserve">
+<g>
+ <path d="M297.6,677.3c-68.5,0-132.9-26.7-181.3-75.1S41.3,489.4,41.3,420.9s26.7-132.9,75.1-181.3c48.4-48.4,112.8-75.1,181.3-75.1
+ s132.9,26.7,181.3,75.1c48.4,48.4,75.1,112.8,75.1,181.3s-26.7,132.9-75.1,181.3S366.1,677.3,297.6,677.3z M297.6,204.6
+ c-57.8,0-112.1,22.5-153,63.4c-40.9,40.9-63.4,95.2-63.4,153c0,57.8,22.5,112.1,63.4,153c40.9,40.9,95.2,63.4,153,63.4
+ c57.8,0,112.1-22.5,153-63.4c40.9-40.9,63.4-95.2,63.4-153c0-57.8-22.5-112.1-63.4-153C409.8,227.1,355.4,204.6,297.6,204.6z"/>
+</g>
+<polygon points="130.1,240.3 61.3,420.9 297.6,420.9 297.6,184.6 "/>
+<polygon points="117,588.5 297.6,657.3 297.6,420.9 61.3,420.9 "/>
+<polygon points="465.2,601.6 534,420.9 297.6,420.9 297.6,657.3 "/>
+<polygon points="478.3,253.4 297.6,184.6 297.6,420.9 534,420.9 "/>
+<path fill="#FFFFFF" d="M293.5,452.6h99.6c14.9,0,24.8-9.9,24.8-24.8S408,403,393.1,403h-74.8V278.2c0-14.9-9.9-24.8-24.8-24.8
+ c-14.9,0-24.8,9.9-24.8,24.8v149.6C268.7,440.2,278.7,452.6,293.5,452.6z"/>
+</svg>
diff --git a/src/qt/res/src/connect-0.svg b/src/qt/res/src/connect-0.svg
new file mode 100644
index 0000000000..bedbec7777
--- /dev/null
+++ b/src/qt/res/src/connect-0.svg
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
+<path fill="none" stroke="#000000" stroke-miterlimit="10" d="M13.4,19.4c0.8-0.8,0.8-2,0-2.8c-0.8-0.8-2-0.8-2.8,0
+ c-0.8,0.8-0.8,2.1,0,2.8C11.4,20.2,12.6,20.2,13.4,19.4z M7.8,15.8c-0.5,0-1-0.2-1.4-0.6c-0.8-0.8-0.8-2,0-2.8
+ c3.1-3.1,8.2-3.1,11.3,0c0.8,0.8,0.8,2,0,2.8c-0.8,0.8-2,0.8-2.8,0c-1.6-1.6-4.1-1.6-5.7,0C8.8,15.6,8.3,15.8,7.8,15.8z"/>
+<path fill="none" stroke="#000000" stroke-miterlimit="10" d="M20.5,11.5c-0.5,0-1-0.2-1.4-0.6C15.2,7,8.8,7,4.9,10.9
+ c-0.8,0.8-2,0.8-2.8,0c-0.8-0.8-0.8-2,0-2.8c5.5-5.5,14.3-5.5,19.8,0c0.8,0.8,0.8,2,0,2.8C21.5,11.3,21,11.5,20.5,11.5z"/>
+</svg>
diff --git a/src/qt/res/src/connect-1.svg b/src/qt/res/src/connect-1.svg
new file mode 100644
index 0000000000..d3d4e46a41
--- /dev/null
+++ b/src/qt/res/src/connect-1.svg
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
+<g>
+ <path d="M12,11c1.9,0,3.6,0.7,4.9,2c0.4,0.4,0.4,1,0,1.4c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3C14.6,13.5,13.3,13,12,13
+ c-1.3,0-2.6,0.5-3.5,1.5c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4C8.4,11.7,10.1,11,12,11 M12,17
+ c0.3,0,0.5,0.1,0.7,0.3c0.2,0.2,0.3,0.4,0.3,0.7s-0.1,0.5-0.3,0.7C12.5,18.9,12.3,19,12,19c-0.3,0-0.5-0.1-0.7-0.3
+ C11.1,18.5,11,18.3,11,18c0-0.3,0.1-0.5,0.3-0.7C11.5,17.1,11.7,17,12,17 M12,10c-2,0-4.1,0.8-5.7,2.3c-0.8,0.8-0.8,2,0,2.8
+ c0.4,0.4,0.9,0.6,1.4,0.6c0.5,0,1-0.2,1.4-0.6C10,14.4,11,14,12,14c1,0,2,0.4,2.8,1.2c0.4,0.4,0.9,0.6,1.4,0.6s1-0.2,1.4-0.6
+ c0.8-0.8,0.8-2,0-2.8C16.1,10.8,14,10,12,10L12,10z M12,16c-0.5,0-1,0.2-1.4,0.6c-0.8,0.8-0.8,2.1,0,2.8C11,19.8,11.5,20,12,20
+ c0.5,0,1-0.2,1.4-0.6c0.8-0.8,0.8-2,0-2.8C13,16.2,12.5,16,12,16L12,16z"/>
+</g>
+<g>
+ <path d="M12,5c3.5,0,6.7,1.3,9.2,3.8c0.4,0.4,0.4,1,0,1.4c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3C17.7,8.1,14.9,7,12,7
+ c-2.9,0-5.7,1.1-7.8,3.2c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4C5.3,6.4,8.5,5,12,5 M12,4
+ C8.4,4,4.8,5.4,2.1,8.1c-0.8,0.8-0.8,2,0,2.8c0.4,0.4,0.9,0.6,1.4,0.6c0.5,0,1-0.2,1.4-0.6C6.9,9,9.4,8,12,8c2.6,0,5.1,1,7.1,2.9
+ c0.4,0.4,0.9,0.6,1.4,0.6c0.5,0,1-0.2,1.4-0.6c0.8-0.8,0.8-2,0-2.8C19.2,5.4,15.6,4,12,4L12,4z"/>
+</g>
+</svg>
diff --git a/src/qt/res/src/connect-2.svg b/src/qt/res/src/connect-2.svg
new file mode 100644
index 0000000000..d5becc52b7
--- /dev/null
+++ b/src/qt/res/src/connect-2.svg
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
+<path d="M13.4,19.4c0.8-0.8,0.8-2,0-2.8c-0.8-0.8-2-0.8-2.8,0c-0.8,0.8-0.8,2.1,0,2.8C11.4,20.2,12.6,20.2,13.4,19.4z"/>
+<g>
+ <path d="M12,11c1.9,0,3.6,0.7,4.9,2c0.4,0.4,0.4,1,0,1.4c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3C14.6,13.5,13.3,13,12,13
+ c-1.3,0-2.6,0.5-3.5,1.5c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4C8.4,11.7,10.1,11,12,11 M12,17
+ c0.3,0,0.5,0.1,0.7,0.3c0.2,0.2,0.3,0.4,0.3,0.7s-0.1,0.5-0.3,0.7C12.5,18.9,12.3,19,12,19c-0.3,0-0.5-0.1-0.7-0.3
+ C11.1,18.5,11,18.3,11,18c0-0.3,0.1-0.5,0.3-0.7C11.5,17.1,11.7,17,12,17 M12,10c-2,0-4.1,0.8-5.7,2.3c-0.8,0.8-0.8,2,0,2.8
+ c0.4,0.4,0.9,0.6,1.4,0.6c0.5,0,1-0.2,1.4-0.6C10,14.4,11,14,12,14c1,0,2,0.4,2.8,1.2c0.4,0.4,0.9,0.6,1.4,0.6s1-0.2,1.4-0.6
+ c0.8-0.8,0.8-2,0-2.8C16.1,10.8,14,10,12,10L12,10z M12,16c-0.5,0-1,0.2-1.4,0.6c-0.8,0.8-0.8,2.1,0,2.8C11,19.8,11.5,20,12,20
+ c0.5,0,1-0.2,1.4-0.6c0.8-0.8,0.8-2,0-2.8C13,16.2,12.5,16,12,16L12,16z"/>
+</g>
+<g>
+ <path d="M12,5c3.5,0,6.7,1.3,9.2,3.8c0.4,0.4,0.4,1,0,1.4c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3C17.7,8.1,14.9,7,12,7
+ c-2.9,0-5.7,1.1-7.8,3.2c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4C5.3,6.4,8.5,5,12,5 M12,4
+ C8.4,4,4.8,5.4,2.1,8.1c-0.8,0.8-0.8,2,0,2.8c0.4,0.4,0.9,0.6,1.4,0.6c0.5,0,1-0.2,1.4-0.6C6.9,9,9.4,8,12,8c2.6,0,5.1,1,7.1,2.9
+ c0.4,0.4,0.9,0.6,1.4,0.6c0.5,0,1-0.2,1.4-0.6c0.8-0.8,0.8-2,0-2.8C19.2,5.4,15.6,4,12,4L12,4z"/>
+</g>
+</svg>
diff --git a/src/qt/res/src/connect-3.svg b/src/qt/res/src/connect-3.svg
new file mode 100644
index 0000000000..9bfa04721f
--- /dev/null
+++ b/src/qt/res/src/connect-3.svg
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
+<path d="M13.4,19.4c0.8-0.8,0.8-2,0-2.8c-0.8-0.8-2-0.8-2.8,0c-0.8,0.8-0.8,2.1,0,2.8C11.4,20.2,12.6,20.2,13.4,19.4z"/>
+<path d="M13.4,19.4c0.8-0.8,0.8-2,0-2.8c-0.8-0.8-2-0.8-2.8,0c-0.8,0.8-0.8,2.1,0,2.8C11.4,20.2,12.6,20.2,13.4,19.4z M7.8,15.8
+ c-0.5,0-1-0.2-1.4-0.6c-0.8-0.8-0.8-2,0-2.8c3.1-3.1,8.2-3.1,11.3,0c0.8,0.8,0.8,2,0,2.8c-0.8,0.8-2,0.8-2.8,0
+ c-1.6-1.6-4.1-1.6-5.7,0C8.8,15.6,8.3,15.8,7.8,15.8z"/>
+<g>
+ <path d="M12,5c3.5,0,6.7,1.3,9.2,3.8c0.4,0.4,0.4,1,0,1.4c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3C17.7,8.1,14.9,7,12,7
+ c-2.9,0-5.7,1.1-7.8,3.2c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4C5.3,6.4,8.5,5,12,5 M12,4
+ C8.4,4,4.8,5.4,2.1,8.1c-0.8,0.8-0.8,2,0,2.8c0.4,0.4,0.9,0.6,1.4,0.6c0.5,0,1-0.2,1.4-0.6C6.9,9,9.4,8,12,8c2.6,0,5.1,1,7.1,2.9
+ c0.4,0.4,0.9,0.6,1.4,0.6c0.5,0,1-0.2,1.4-0.6c0.8-0.8,0.8-2,0-2.8C19.2,5.4,15.6,4,12,4L12,4z"/>
+</g>
+</svg>
diff --git a/src/qt/res/src/mine.svg b/src/qt/res/src/mine.svg
new file mode 100644
index 0000000000..4a3f786607
--- /dev/null
+++ b/src/qt/res/src/mine.svg
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 841.9 595.3" enable-background="new 0 0 841.9 595.3" xml:space="preserve">
+<rect x="464" y="158.6" transform="matrix(-0.7071 0.7071 -0.7071 -0.7071 1027.5018 42.8013)" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" width="81.9" height="151.3"/>
+<rect x="190" y="342.1" transform="matrix(-0.7071 0.7071 -0.7071 -0.7071 882.9977 387.9771)" fill="none" stroke="#000000" stroke-width="30" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" width="342.3" height="69.4"/>
+<path stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M445.7,186l32.2-32.2
+ c-44.6-37.2-124-74.4-218.3-64.5l-2.5,9.9C361.4,114.1,403.6,153.8,445.7,186z"/>
+<path stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M552.4,292.7l32.2-32.2
+ c37.2,44.6,74.4,124,64.5,218.3l-9.9,2.5C624.3,377,584.6,332.4,552.4,292.7z"/>
+</svg>
diff --git a/src/qt/res/src/qt.svg b/src/qt/res/src/qt.svg
new file mode 100644
index 0000000000..9ef54f493c
--- /dev/null
+++ b/src/qt/res/src/qt.svg
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 841.9 595.3" enable-background="new 0 0 841.9 595.3" xml:space="preserve">
+<g>
+ <path d="M182.8,310c0-74.4,0-148.8,0-220.7c0-19.8,5-39.7,19.8-54.6c12.4-12.4,27.3-17.4,44.6-19.8c37.2-5,74.4,2.5,109.1,7.4
+ C428.4,34.7,497.8,44.6,569.8,57c27.3,5,57,9.9,84.3,12.4c7.4,0,5,5,5,9.9c0,91.8,0,181.1,0,272.8c0,32.2,0,64.5,0,99.2
+ c0,14.9-5,29.8-12.4,44.6c-9.9,14.9-22.3,22.3-39.7,27.3c-69.4,12.4-138.9,22.3-208.3,34.7c-57,9.9-114.1,19.8-171.1,29.8
+ c-2.5,0-5,0-7.4-2.5c-12.4-14.9-22.3-24.8-32.2-34.7c-2.5-2.5-2.5-7.4-2.5-9.9c0-71.9,0-143.9,0-215.8
+ C182.8,320,182.8,315,182.8,310z M430.9,436.5c9.9-7.4,19.8-12.4,29.8-19.8c14.9-14.9,24.8-32.2,29.8-54.6
+ c12.4-54.6,14.9-111.6,0-166.2c-12.4-47.1-42.2-74.4-84.3-79.4c-37.2-2.5-67,7.4-86.8,39.7c-7.4,14.9-12.4,29.8-14.9,44.6
+ c-9.9,39.7-9.9,81.9-5,121.5c2.5,22.3,7.4,44.6,17.4,67c12.4,24.8,29.8,42.2,54.6,49.6c2.5,0,5,2.5,5,5c5,12.4,7.4,22.3,12.4,34.7
+ s17.4,19.8,32.2,22.3c14.9,2.5,27.3,2.5,42.2,0c2.5,0,2.5-2.5,2.5-2.5c0-9.9,0-22.3,0-32.2C438.3,461.3,433.3,456.4,430.9,436.5z
+ M505.3,191c0,12.4,0,22.3,0,34.7c0,2.5,2.5,2.5,5,2.5c5,0,7.4,0,12.4,0c0,2.5,0,5,0,9.9c0,44.6,0,86.8,0,131.5
+ c0,7.4,0,17.4,2.5,24.8c2.5,12.4,12.4,22.3,24.8,24.8c19.8,5,37.2-2.5,54.6-9.9l2.5-2.5c0-9.9,0-19.8,0-29.8
+ c-7.4,2.5-14.9,5-22.3,5s-12.4-2.5-14.9-9.9c0-5-2.5-9.9-2.5-14.9c0-39.7,0-79.4,0-119.1c0-2.5,0-5,0-7.4c9.9,0,19.8,0,29.8,2.5
+ c5,0,7.4-2.5,7.4-7.4c0-7.4,0-14.9,0-22.3c0-5-2.5-7.4-7.4-7.4c-7.4,0-14.9-2.5-22.3-2.5c-5,0-7.4-2.5-7.4-7.4
+ c0-14.9,0-29.8,0-42.2c0-5-2.5-5-5-7.4c-5,0-12.4,0-17.4-2.5s-7.4,0-9.9,7.4c-2.5,17.4-7.4,32.2-12.4,49.6
+ C520.2,191,512.7,191,505.3,191z"/>
+ <path d="M443.3,277.8c-2.5,27.3-5,57-9.9,84.3c0,7.4-5,17.4-9.9,24.8c-12.4,17.4-32.2,14.9-44.6-2.5c-9.9-14.9-12.4-32.2-14.9-49.6
+ c-5-42.2-5-81.9,0-124c5-12.4,7.4-24.8,14.9-37.2c12.4-17.4,34.7-17.4,47.1-2.5c2.5,5,7.4,9.9,7.4,14.9c2.5,9.9,5,19.8,7.4,32.2
+ c2.5,9.9,2.5,22.3,2.5,34.7C440.8,260.4,440.8,270.4,443.3,277.8L443.3,277.8z"/>
+</g>
+</svg>
diff --git a/src/qt/res/src/tx_in.svg b/src/qt/res/src/tx_in.svg
new file mode 100644
index 0000000000..a8911f9045
--- /dev/null
+++ b/src/qt/res/src/tx_in.svg
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
+<path d="M13,17.5c-2.5,0-4.5-2-4.5-4.5c0-0.6-0.4-1-1-1s-1,0.4-1,1c0,3.6,2.9,6.5,6.5,6.5s6.5-2.9,6.5-6.5S16.6,6.5,13,6.5
+ c-0.6,0-1,0.4-1,1s0.4,1,1,1c2.5,0,4.5,2,4.5,4.5S15.5,17.5,13,17.5z M3.7,10.3c-0.6,0-1-0.4-1-1s0.4-1,1-1H7L5.3,6.6L1.2,2.5
+ c-0.4-0.4-0.4-1,0-1.4c0.2-0.2,0.4-0.3,0.7-0.3s0.5,0.1,0.7,0.3l4.1,4.1l1.7,1.7V3.6c0-0.6,0.4-1,1-1s1,0.4,1,1v6.7L3.7,10.3"/>
+</svg>
diff --git a/src/qt/res/src/tx_inout.svg b/src/qt/res/src/tx_inout.svg
new file mode 100644
index 0000000000..5b66889783
--- /dev/null
+++ b/src/qt/res/src/tx_inout.svg
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
+<path d="M14.7,19.5c-2.5,0-4.5-2-4.5-4.5c0-0.6-0.4-1-1-1c-0.6,0-1,0.4-1,1c0,3.6,2.9,6.5,6.5,6.5s6.5-2.9,6.5-6.5s-2.9-6.5-6.5-6.5
+ c-0.6,0-1,0.4-1,1s0.4,1,1,1c2.5,0,4.5,2,4.5,4.5S17.2,19.5,14.7,19.5z M5.9,12.5c-0.6,0-1-0.4-1-1s0.4-1,1-1h3.2L7.4,8.8L3.3,4.7
+ c-0.4-0.4-0.4-1,0-1.4C3.5,3.1,3.7,3,4,3s0.5,0.1,0.7,0.3l4.1,4.1l1.7,1.7V5.8c0-0.6,0.4-1,1-1s1,0.4,1,1v6.7L5.9,12.5 M7.5,0.8
+ c0.6,0,1,0.4,1,1s-0.4,1-1,1H4.3L6,4.5l4.1,4.1c0.4,0.4,0.4,1,0,1.4c-0.2,0.2-0.4,0.3-0.7,0.3S8.9,10.2,8.7,10L4.6,5.9L2.9,4.2v3.2
+ c0,0.6-0.4,1-1,1s-1-0.4-1-1V0.8L7.5,0.8"/>
+</svg>
diff --git a/src/qt/res/src/verify.svg b/src/qt/res/src/verify.svg
new file mode 100644
index 0000000000..1ff11b7f5e
--- /dev/null
+++ b/src/qt/res/src/verify.svg
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 841.9 595.3" enable-background="new 0 0 841.9 595.3" xml:space="preserve">
+<path d="M654.1,317.5c-14.9-9.9-37.2-2.5-44.6,12.4l-62,111.6l-34.7-34.7c-12.4-12.4-34.7-12.4-47.1,0c-12.4,12.4-12.4,34.7,0,47.1
+ l67,67c7.4,7.4,14.9,9.9,22.3,9.9h5c9.9-2.5,19.8-7.4,24.8-17.4l81.9-148.8C676.4,347.2,671.5,327.4,654.1,317.5z"/>
+<path d="M326.7,471.3H177.9V362.1l94.3-94.3c-5-14.9-7.4-29.8-7.4-44.6c0-81.9,67-148.8,148.8-148.8s148.8,67,148.8,148.8
+ s-67,148.8-148.8,148.8h-37.2v49.6h-49.6L326.7,471.3L326.7,471.3z M227.5,421.7h49.6v-49.6h49.6v-49.6h86.8
+ c54.6,0,99.2-44.6,99.2-99.2S468.1,124,413.5,124s-99.2,44.6-99.2,99.2c0,14.9,2.5,27.3,9.9,39.7l7.4,14.9L230,379.5v42.2H227.5z
+ M413.5,198.4c14.9,0,24.8,9.9,24.8,24.8c0,14.9-9.9,24.8-24.8,24.8c-14.9,0-24.8-9.9-24.8-24.8
+ C388.7,208.3,401.1,198.4,413.5,198.4 M413.5,173.6c-27.3,0-49.6,22.3-49.6,49.6c0,27.3,22.3,49.6,49.6,49.6
+ c27.3,0,49.6-22.3,49.6-49.6C463.1,195.9,443.3,173.6,413.5,173.6z"/>
+</svg>
diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp
new file mode 100644
index 0000000000..bdf2925fed
--- /dev/null
+++ b/src/qt/rpcconsole.cpp
@@ -0,0 +1,661 @@
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "rpcconsole.h"
+#include "ui_rpcconsole.h"
+
+#include "clientmodel.h"
+#include "guiutil.h"
+#include "peertablemodel.h"
+#include "scicon.h"
+
+#include "main.h"
+#include "chainparams.h"
+#include "rpcserver.h"
+#include "rpcclient.h"
+#include "util.h"
+
+#include "json/json_spirit_value.h"
+
+#include <openssl/crypto.h>
+
+#ifdef ENABLE_WALLET
+#include <db_cxx.h>
+#endif
+
+#include <QKeyEvent>
+#include <QScrollBar>
+#include <QThread>
+#include <QTime>
+
+#if QT_VERSION < 0x050000
+#include <QUrl>
+#endif
+
+// TODO: add a scrollback limit, as there is currently none
+// TODO: make it possible to filter out categories (esp debug messages when implemented)
+// TODO: receive errors and debug messages through ClientModel
+
+const int CONSOLE_HISTORY = 50;
+const QSize ICON_SIZE(24, 24);
+
+const int INITIAL_TRAFFIC_GRAPH_MINS = 30;
+
+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 Q_SLOTS:
+ void request(const QString &command);
+
+Q_SIGNALS:
+ void reply(int category, const QString &command);
+};
+
+#include "rpcconsole.moc"
+
+/**
+ * Split shell command line into a list of arguments. Aims to emulate \c bash and friends.
+ *
+ * - Arguments are delimited with whitespace
+ * - Extra whitespace at the beginning and end and between arguments will be ignored
+ * - Text can be "double" or 'single' quoted
+ * - The backslash \c \ is used as escape character
+ * - Outside quotes, any character can be escaped
+ * - Within double quotes, only escape \c " and backslashes before a \c " or another backslash
+ * - Within single quotes, no escaping is possible and no special interpretation takes place
+ *
+ * @param[out] args Parsed arguments will be appended to this list
+ * @param[in] strCommand Command line to split
+ */
+bool parseCommandLine(std::vector<std::string> &args, const std::string &strCommand)
+{
+ enum CmdParseState
+ {
+ STATE_EATING_SPACES,
+ STATE_ARGUMENT,
+ STATE_SINGLEQUOTED,
+ STATE_DOUBLEQUOTED,
+ STATE_ESCAPE_OUTER,
+ STATE_ESCAPE_DOUBLEQUOTED
+ } state = STATE_EATING_SPACES;
+ std::string curarg;
+ Q_FOREACH(char ch, strCommand)
+ {
+ switch(state)
+ {
+ case STATE_ARGUMENT: // In or after argument
+ case STATE_EATING_SPACES: // Handle runs of whitespace
+ switch(ch)
+ {
+ case '"': state = STATE_DOUBLEQUOTED; break;
+ case '\'': state = STATE_SINGLEQUOTED; break;
+ case '\\': state = STATE_ESCAPE_OUTER; break;
+ case ' ': case '\n': case '\t':
+ if(state == STATE_ARGUMENT) // Space ends argument
+ {
+ args.push_back(curarg);
+ curarg.clear();
+ }
+ state = STATE_EATING_SPACES;
+ break;
+ default: curarg += ch; state = STATE_ARGUMENT;
+ }
+ break;
+ case STATE_SINGLEQUOTED: // Single-quoted string
+ switch(ch)
+ {
+ case '\'': state = STATE_ARGUMENT; break;
+ default: curarg += ch;
+ }
+ break;
+ case STATE_DOUBLEQUOTED: // Double-quoted string
+ switch(ch)
+ {
+ case '"': state = STATE_ARGUMENT; break;
+ case '\\': state = STATE_ESCAPE_DOUBLEQUOTED; break;
+ default: curarg += ch;
+ }
+ break;
+ case STATE_ESCAPE_OUTER: // '\' outside quotes
+ curarg += ch; state = STATE_ARGUMENT;
+ break;
+ case STATE_ESCAPE_DOUBLEQUOTED: // '\' in double-quoted text
+ if(ch != '"' && ch != '\\') curarg += '\\'; // keep '\' for everything but the quote and '\' itself
+ curarg += ch; state = STATE_DOUBLEQUOTED;
+ break;
+ }
+ }
+ switch(state) // final state
+ {
+ case STATE_EATING_SPACES:
+ return true;
+ case STATE_ARGUMENT:
+ args.push_back(curarg);
+ return true;
+ default: // ERROR to end in one of the other states
+ return false;
+ }
+}
+
+void RPCExecutor::request(const QString &command)
+{
+ std::vector<std::string> args;
+ if(!parseCommandLine(args, command.toStdString()))
+ {
+ Q_EMIT reply(RPCConsole::CMD_ERROR, QString("Parse error: unbalanced ' or \""));
+ return;
+ }
+ if(args.empty())
+ return; // Nothing to do
+ try
+ {
+ std::string strPrint;
+ // Convert argument list to JSON objects in method-dependent way,
+ // and pass it along with the method name to the dispatcher.
+ json_spirit::Value result = tableRPC.execute(
+ args[0],
+ RPCConvertValues(args[0], std::vector<std::string>(args.begin() + 1, args.end())));
+
+ // 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);
+
+ Q_EMIT reply(RPCConsole::CMD_REPLY, QString::fromStdString(strPrint));
+ }
+ catch (const json_spirit::Object& objError)
+ {
+ try // Nice formatting for standard-format error
+ {
+ int code = find_value(objError, "code").get_int();
+ std::string message = find_value(objError, "message").get_str();
+ Q_EMIT reply(RPCConsole::CMD_ERROR, QString::fromStdString(message) + " (code " + QString::number(code) + ")");
+ }
+ catch (const std::runtime_error&) // raised when converting to invalid type, i.e. missing code or message
+ { // Show raw JSON object
+ Q_EMIT reply(RPCConsole::CMD_ERROR, QString::fromStdString(write_string(json_spirit::Value(objError), false)));
+ }
+ }
+ catch (const std::exception& e)
+ {
+ Q_EMIT reply(RPCConsole::CMD_ERROR, QString("Error: ") + QString::fromStdString(e.what()));
+ }
+}
+
+RPCConsole::RPCConsole(QWidget *parent) :
+ QWidget(parent),
+ ui(new Ui::RPCConsole),
+ clientModel(0),
+ historyPtr(0),
+ cachedNodeid(-1)
+{
+ ui->setupUi(this);
+ GUIUtil::restoreWindowGeometry("nRPCConsoleWindow", this->size(), this);
+
+#ifndef Q_OS_MAC
+ ui->openDebugLogfileButton->setIcon(SingleColorIcon(":/icons/export"));
+#endif
+ ui->clearButton->setIcon(SingleColorIcon(":/icons/remove"));
+
+ // Install event filter for up and down arrow
+ ui->lineEdit->installEventFilter(this);
+ ui->messagesWidget->installEventFilter(this);
+
+ connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(clear()));
+ connect(ui->btnClearTrafficGraph, SIGNAL(clicked()), ui->trafficGraph, SLOT(clear()));
+
+ // set library version labels
+ ui->openSSLVersion->setText(SSLeay_version(SSLEAY_VERSION));
+#ifdef ENABLE_WALLET
+ ui->berkeleyDBVersion->setText(DbEnv::version(0, 0, 0));
+#else
+ ui->label_berkeleyDBVersion->hide();
+ ui->berkeleyDBVersion->hide();
+#endif
+
+ startExecutor();
+ setTrafficGraphRange(INITIAL_TRAFFIC_GRAPH_MINS);
+
+ ui->detailWidget->hide();
+ ui->peerHeading->setText(tr("Select a peer to view detailed information."));
+
+ clear();
+}
+
+RPCConsole::~RPCConsole()
+{
+ GUIUtil::saveWindowGeometry("nRPCConsoleWindow", this);
+ Q_EMIT stopExecutor();
+ delete ui;
+}
+
+bool RPCConsole::eventFilter(QObject* obj, QEvent *event)
+{
+ if(event->type() == QEvent::KeyPress) // Special key handling
+ {
+ QKeyEvent *keyevt = static_cast<QKeyEvent*>(event);
+ int key = keyevt->key();
+ Qt::KeyboardModifiers mod = keyevt->modifiers();
+ switch(key)
+ {
+ case Qt::Key_Up: if(obj == ui->lineEdit) { browseHistory(-1); return true; } break;
+ case Qt::Key_Down: if(obj == ui->lineEdit) { browseHistory(1); return true; } break;
+ case Qt::Key_PageUp: /* pass paging keys to messages widget */
+ case Qt::Key_PageDown:
+ if(obj == ui->lineEdit)
+ {
+ QApplication::postEvent(ui->messagesWidget, new QKeyEvent(*keyevt));
+ return true;
+ }
+ break;
+ default:
+ // Typing in messages widget brings focus to line edit, and redirects key there
+ // Exclude most combinations and keys that emit no text, except paste shortcuts
+ if(obj == ui->messagesWidget && (
+ (!mod && !keyevt->text().isEmpty() && key != Qt::Key_Tab) ||
+ ((mod & Qt::ControlModifier) && key == Qt::Key_V) ||
+ ((mod & Qt::ShiftModifier) && key == Qt::Key_Insert)))
+ {
+ ui->lineEdit->setFocus();
+ QApplication::postEvent(ui->lineEdit, new QKeyEvent(*keyevt));
+ return true;
+ }
+ }
+ }
+ return QWidget::eventFilter(obj, event);
+}
+
+void RPCConsole::setClientModel(ClientModel *model)
+{
+ clientModel = model;
+ ui->trafficGraph->setClientModel(model);
+ if(model)
+ {
+ // Keep up to date with client
+ setNumConnections(model->getNumConnections());
+ connect(model, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int)));
+
+ setNumBlocks(model->getNumBlocks(), model->getLastBlockDate());
+ connect(model, SIGNAL(numBlocksChanged(int,QDateTime)), this, SLOT(setNumBlocks(int,QDateTime)));
+
+ updateTrafficStats(model->getTotalBytesRecv(), model->getTotalBytesSent());
+ connect(model, SIGNAL(bytesChanged(quint64,quint64)), this, SLOT(updateTrafficStats(quint64, quint64)));
+
+ // set up peer table
+ ui->peerWidget->setModel(model->getPeerTableModel());
+ ui->peerWidget->verticalHeader()->hide();
+ ui->peerWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
+ ui->peerWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
+ ui->peerWidget->setSelectionMode(QAbstractItemView::SingleSelection);
+ ui->peerWidget->setColumnWidth(PeerTableModel::Address, ADDRESS_COLUMN_WIDTH);
+ ui->peerWidget->setColumnWidth(PeerTableModel::Subversion, SUBVERSION_COLUMN_WIDTH);
+ ui->peerWidget->setColumnWidth(PeerTableModel::Ping, PING_COLUMN_WIDTH);
+
+ // connect the peerWidget selection model to our peerSelected() handler
+ connect(ui->peerWidget->selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)),
+ this, SLOT(peerSelected(const QItemSelection &, const QItemSelection &)));
+ connect(model->getPeerTableModel(), SIGNAL(layoutChanged()), this, SLOT(peerLayoutChanged()));
+
+ // Provide initial values
+ ui->clientVersion->setText(model->formatFullVersion());
+ ui->clientName->setText(model->clientName());
+ ui->buildDate->setText(model->formatBuildDate());
+ ui->startupTime->setText(model->formatClientStartupTime());
+
+ ui->networkName->setText(QString::fromStdString(Params().NetworkIDString()));
+ }
+}
+
+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();
+ history.clear();
+ historyPtr = 0;
+ 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),
+ SingleColorImage(ICON_MAPPING[i].source, SingleColor()).scaled(ICON_SIZE, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
+ }
+
+ // Set default style sheet
+ ui->messagesWidget->document()->setDefaultStyleSheet(
+ "table { }"
+ "td.time { color: #808080; padding-top: 3px; } "
+ "td.cmd-request { color: #006060; } "
+ "td.cmd-error { color: red; } "
+ "b { color: #006060; } "
+ );
+
+ message(CMD_REPLY, (tr("Welcome to the Bitcoin Core RPC console.") + "<br>" +
+ tr("Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.") + "<br>" +
+ tr("Type <b>help</b> for an overview of available commands.")), true);
+}
+
+void RPCConsole::keyPressEvent(QKeyEvent *event)
+{
+ if(windowType() != Qt::Widget && event->key() == Qt::Key_Escape)
+ {
+ close();
+ }
+}
+
+void RPCConsole::message(int category, const QString &message, bool html)
+{
+ QTime time = QTime::currentTime();
+ QString timeString = time.toString();
+ QString out;
+ out += "<table><tr><td class=\"time\" width=\"65\">" + timeString + "</td>";
+ out += "<td class=\"icon\" width=\"32\"><img src=\"" + categoryClass(category) + "\"></td>";
+ out += "<td class=\"message " + categoryClass(category) + "\" valign=\"middle\">";
+ if(html)
+ out += message;
+ else
+ out += GUIUtil::HtmlEscape(message, true);
+ out += "</td></tr></table>";
+ ui->messagesWidget->append(out);
+}
+
+void RPCConsole::setNumConnections(int count)
+{
+ if (!clientModel)
+ return;
+
+ QString connections = QString::number(count) + " (";
+ connections += tr("In:") + " " + QString::number(clientModel->getNumConnections(CONNECTIONS_IN)) + " / ";
+ connections += tr("Out:") + " " + QString::number(clientModel->getNumConnections(CONNECTIONS_OUT)) + ")";
+
+ ui->numberOfConnections->setText(connections);
+}
+
+void RPCConsole::setNumBlocks(int count, const QDateTime& blockDate)
+{
+ ui->numberOfBlocks->setText(QString::number(count));
+ ui->lastBlockTime->setText(blockDate.toString());
+}
+
+void RPCConsole::on_lineEdit_returnPressed()
+{
+ QString cmd = ui->lineEdit->text();
+ ui->lineEdit->clear();
+
+ if(!cmd.isEmpty())
+ {
+ message(CMD_REQUEST, cmd);
+ Q_EMIT cmdRequest(cmd);
+ // Remove command, if already in history
+ history.removeOne(cmd);
+ // 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);
+
+ // 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_sldGraphRange_valueChanged(int value)
+{
+ const int multiplier = 5; // each position on the slider represents 5 min
+ int mins = value * multiplier;
+ setTrafficGraphRange(mins);
+}
+
+QString RPCConsole::FormatBytes(quint64 bytes)
+{
+ if(bytes < 1024)
+ return QString(tr("%1 B")).arg(bytes);
+ if(bytes < 1024 * 1024)
+ return QString(tr("%1 KB")).arg(bytes / 1024);
+ if(bytes < 1024 * 1024 * 1024)
+ return QString(tr("%1 MB")).arg(bytes / 1024 / 1024);
+
+ return QString(tr("%1 GB")).arg(bytes / 1024 / 1024 / 1024);
+}
+
+void RPCConsole::setTrafficGraphRange(int mins)
+{
+ ui->trafficGraph->setGraphRangeMins(mins);
+ ui->lblGraphRange->setText(GUIUtil::formatDurationStr(mins * 60));
+}
+
+void RPCConsole::updateTrafficStats(quint64 totalBytesIn, quint64 totalBytesOut)
+{
+ ui->lblBytesIn->setText(FormatBytes(totalBytesIn));
+ ui->lblBytesOut->setText(FormatBytes(totalBytesOut));
+}
+
+void RPCConsole::peerSelected(const QItemSelection &selected, const QItemSelection &deselected)
+{
+ Q_UNUSED(deselected);
+
+ if (!clientModel || selected.indexes().isEmpty())
+ return;
+
+ const CNodeCombinedStats *stats = clientModel->getPeerTableModel()->getNodeStats(selected.indexes().first().row());
+ if (stats)
+ updateNodeDetail(stats);
+}
+
+void RPCConsole::peerLayoutChanged()
+{
+ if (!clientModel)
+ return;
+
+ const CNodeCombinedStats *stats = NULL;
+ bool fUnselect = false;
+ bool fReselect = false;
+
+ if (cachedNodeid == -1) // no node selected yet
+ return;
+
+ // find the currently selected row
+ int selectedRow;
+ QModelIndexList selectedModelIndex = ui->peerWidget->selectionModel()->selectedIndexes();
+ if (selectedModelIndex.isEmpty())
+ selectedRow = -1;
+ else
+ selectedRow = selectedModelIndex.first().row();
+
+ // check if our detail node has a row in the table (it may not necessarily
+ // be at selectedRow since its position can change after a layout change)
+ int detailNodeRow = clientModel->getPeerTableModel()->getRowByNodeId(cachedNodeid);
+
+ if (detailNodeRow < 0)
+ {
+ // detail node disappeared from table (node disconnected)
+ fUnselect = true;
+ cachedNodeid = -1;
+ ui->detailWidget->hide();
+ ui->peerHeading->setText(tr("Select a peer to view detailed information."));
+ }
+ else
+ {
+ if (detailNodeRow != selectedRow)
+ {
+ // detail node moved position
+ fUnselect = true;
+ fReselect = true;
+ }
+
+ // get fresh stats on the detail node.
+ stats = clientModel->getPeerTableModel()->getNodeStats(detailNodeRow);
+ }
+
+ if (fUnselect && selectedRow >= 0)
+ {
+ ui->peerWidget->selectionModel()->select(QItemSelection(selectedModelIndex.first(), selectedModelIndex.last()),
+ QItemSelectionModel::Deselect);
+ }
+
+ if (fReselect)
+ {
+ ui->peerWidget->selectRow(detailNodeRow);
+ }
+
+ if (stats)
+ updateNodeDetail(stats);
+}
+
+void RPCConsole::updateNodeDetail(const CNodeCombinedStats *stats)
+{
+ // Update cached nodeid
+ cachedNodeid = stats->nodeStats.nodeid;
+
+ // update the detail ui with latest node information
+ QString peerAddrDetails(QString::fromStdString(stats->nodeStats.addrName));
+ if (!stats->nodeStats.addrLocal.empty())
+ peerAddrDetails += "<br />" + tr("via %1").arg(QString::fromStdString(stats->nodeStats.addrLocal));
+ ui->peerHeading->setText(peerAddrDetails);
+ ui->peerServices->setText(GUIUtil::formatServicesStr(stats->nodeStats.nServices));
+ ui->peerLastSend->setText(stats->nodeStats.nLastSend ? GUIUtil::formatDurationStr(GetTime() - stats->nodeStats.nLastSend) : tr("never"));
+ ui->peerLastRecv->setText(stats->nodeStats.nLastRecv ? GUIUtil::formatDurationStr(GetTime() - stats->nodeStats.nLastRecv) : tr("never"));
+ ui->peerBytesSent->setText(FormatBytes(stats->nodeStats.nSendBytes));
+ ui->peerBytesRecv->setText(FormatBytes(stats->nodeStats.nRecvBytes));
+ ui->peerConnTime->setText(GUIUtil::formatDurationStr(GetTime() - stats->nodeStats.nTimeConnected));
+ ui->peerPingTime->setText(GUIUtil::formatPingTime(stats->nodeStats.dPingTime));
+ ui->timeoffset->setText(GUIUtil::formatTimeOffset(stats->nodeStats.nTimeOffset));
+ ui->peerVersion->setText(QString("%1").arg(stats->nodeStats.nVersion));
+ ui->peerSubversion->setText(QString::fromStdString(stats->nodeStats.cleanSubVer));
+ ui->peerDirection->setText(stats->nodeStats.fInbound ? tr("Inbound") : tr("Outbound"));
+ ui->peerHeight->setText(QString("%1").arg(stats->nodeStats.nStartingHeight));
+
+ // This check fails for example if the lock was busy and
+ // nodeStateStats couldn't be fetched.
+ if (stats->fNodeStateStatsAvailable) {
+ // Ban score is init to 0
+ ui->peerBanScore->setText(QString("%1").arg(stats->nodeStateStats.nMisbehavior));
+
+ // Sync height is init to -1
+ if (stats->nodeStateStats.nSyncHeight > -1)
+ ui->peerSyncHeight->setText(QString("%1").arg(stats->nodeStateStats.nSyncHeight));
+ else
+ ui->peerSyncHeight->setText(tr("Unknown"));
+ } else {
+ ui->peerBanScore->setText(tr("Fetching..."));
+ ui->peerSyncHeight->setText(tr("Fetching..."));
+ }
+
+ ui->detailWidget->show();
+}
+
+void RPCConsole::resizeEvent(QResizeEvent *event)
+{
+ QWidget::resizeEvent(event);
+}
+
+void RPCConsole::showEvent(QShowEvent *event)
+{
+ QWidget::showEvent(event);
+
+ if (!clientModel)
+ return;
+
+ // start PeerTableModel auto refresh
+ clientModel->getPeerTableModel()->startAutoRefresh();
+}
+
+void RPCConsole::hideEvent(QHideEvent *event)
+{
+ QWidget::hideEvent(event);
+
+ if (!clientModel)
+ return;
+
+ // stop PeerTableModel auto refresh
+ clientModel->getPeerTableModel()->stopAutoRefresh();
+}
diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h
new file mode 100644
index 0000000000..e93a61e9b4
--- /dev/null
+++ b/src/qt/rpcconsole.h
@@ -0,0 +1,103 @@
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_RPCCONSOLE_H
+#define BITCOIN_QT_RPCCONSOLE_H
+
+#include "guiutil.h"
+#include "peertablemodel.h"
+
+#include "net.h"
+
+#include <QWidget>
+
+class ClientModel;
+
+namespace Ui {
+ class RPCConsole;
+}
+
+QT_BEGIN_NAMESPACE
+class QItemSelection;
+QT_END_NAMESPACE
+
+/** Local Bitcoin RPC console. */
+class RPCConsole: public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit RPCConsole(QWidget *parent);
+ ~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);
+ void keyPressEvent(QKeyEvent *);
+
+private Q_SLOTS:
+ void on_lineEdit_returnPressed();
+ void on_tabWidget_currentChanged(int index);
+ /** open the debug.log from the current datadir */
+ void on_openDebugLogfileButton_clicked();
+ /** change the time range of the network traffic graph */
+ void on_sldGraphRange_valueChanged(int value);
+ /** update traffic statistics */
+ void updateTrafficStats(quint64 totalBytesIn, quint64 totalBytesOut);
+ void resizeEvent(QResizeEvent *event);
+ void showEvent(QShowEvent *event);
+ void hideEvent(QHideEvent *event);
+
+public Q_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 and last block date shown in the UI */
+ void setNumBlocks(int count, const QDateTime& blockDate);
+ /** Go forward or back in history */
+ void browseHistory(int offset);
+ /** Scroll console view to end */
+ void scrollToEnd();
+ /** Handle selection of peer in peers list */
+ void peerSelected(const QItemSelection &selected, const QItemSelection &deselected);
+ /** Handle updated peer information */
+ void peerLayoutChanged();
+
+Q_SIGNALS:
+ // For RPC command executor
+ void stopExecutor();
+ void cmdRequest(const QString &command);
+
+private:
+ static QString FormatBytes(quint64 bytes);
+ void startExecutor();
+ void setTrafficGraphRange(int mins);
+ /** show detailed information on ui about selected node */
+ void updateNodeDetail(const CNodeCombinedStats *stats);
+
+ enum ColumnWidths
+ {
+ ADDRESS_COLUMN_WIDTH = 200,
+ SUBVERSION_COLUMN_WIDTH = 100,
+ PING_COLUMN_WIDTH = 80
+ };
+
+ Ui::RPCConsole *ui;
+ ClientModel *clientModel;
+ QStringList history;
+ int historyPtr;
+ NodeId cachedNodeid;
+};
+
+#endif // BITCOIN_QT_RPCCONSOLE_H
diff --git a/src/qt/scicon.cpp b/src/qt/scicon.cpp
new file mode 100644
index 0000000000..c493b5569e
--- /dev/null
+++ b/src/qt/scicon.cpp
@@ -0,0 +1,98 @@
+// Copyright (c) 2014 The Bitcoin developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "scicon.h"
+
+#include <QApplication>
+#include <QColor>
+#include <QIcon>
+#include <QImage>
+#include <QPalette>
+#include <QPixmap>
+
+namespace {
+
+void MakeSingleColorImage(QImage& img, const QColor& colorbase)
+{
+ img = img.convertToFormat(QImage::Format_ARGB32);
+ for (int x = img.width(); x--; )
+ {
+ for (int y = img.height(); y--; )
+ {
+ const QRgb rgb = img.pixel(x, y);
+ img.setPixel(x, y, qRgba(colorbase.red(), colorbase.green(), colorbase.blue(), qAlpha(rgb)));
+ }
+ }
+}
+
+}
+
+QImage SingleColorImage(const QString& filename, const QColor& colorbase)
+{
+ QImage img(filename);
+#if !defined(WIN32) && !defined(MAC_OSX)
+ MakeSingleColorImage(img, colorbase);
+#endif
+ return img;
+}
+
+QIcon SingleColorIcon(const QIcon& ico, const QColor& colorbase)
+{
+#if defined(WIN32) || defined(MAC_OSX)
+ return ico;
+#else
+ QIcon new_ico;
+ QSize sz;
+ Q_FOREACH(sz, ico.availableSizes())
+ {
+ QImage img(ico.pixmap(sz).toImage());
+ MakeSingleColorImage(img, colorbase);
+ new_ico.addPixmap(QPixmap::fromImage(img));
+ }
+ return new_ico;
+#endif
+}
+
+QIcon SingleColorIcon(const QString& filename, const QColor& colorbase)
+{
+ return QIcon(QPixmap::fromImage(SingleColorImage(filename, colorbase)));
+}
+
+QColor SingleColor()
+{
+#if defined(WIN32) || defined(MAC_OSX)
+ return QColor(0,0,0);
+#else
+ const QColor colorHighlightBg(QApplication::palette().color(QPalette::Highlight));
+ const QColor colorHighlightFg(QApplication::palette().color(QPalette::HighlightedText));
+ const QColor colorText(QApplication::palette().color(QPalette::WindowText));
+ const int colorTextLightness = colorText.lightness();
+ QColor colorbase;
+ if (abs(colorHighlightBg.lightness() - colorTextLightness) < abs(colorHighlightFg.lightness() - colorTextLightness))
+ colorbase = colorHighlightBg;
+ else
+ colorbase = colorHighlightFg;
+ return colorbase;
+#endif
+}
+
+QIcon SingleColorIcon(const QString& filename)
+{
+ return SingleColorIcon(filename, SingleColor());
+}
+
+static QColor TextColor()
+{
+ return QColor(QApplication::palette().color(QPalette::WindowText));
+}
+
+QIcon TextColorIcon(const QString& filename)
+{
+ return SingleColorIcon(filename, TextColor());
+}
+
+QIcon TextColorIcon(const QIcon& ico)
+{
+ return SingleColorIcon(ico, TextColor());
+}
diff --git a/src/qt/scicon.h b/src/qt/scicon.h
new file mode 100644
index 0000000000..1388069ddb
--- /dev/null
+++ b/src/qt/scicon.h
@@ -0,0 +1,24 @@
+// Copyright (c) 2014 The Bitcoin developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_SCICON_H
+#define BITCOIN_QT_SCICON_H
+
+#include <QtCore>
+
+QT_BEGIN_NAMESPACE
+class QColor;
+class QIcon;
+class QString;
+QT_END_NAMESPACE
+
+QImage SingleColorImage(const QString& filename, const QColor&);
+QIcon SingleColorIcon(const QIcon&, const QColor&);
+QIcon SingleColorIcon(const QString& filename, const QColor&);
+QColor SingleColor();
+QIcon SingleColorIcon(const QString& filename);
+QIcon TextColorIcon(const QIcon&);
+QIcon TextColorIcon(const QString& filename);
+
+#endif // BITCOIN_QT_SCICON_H
diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp
new file mode 100644
index 0000000000..f02161cf8a
--- /dev/null
+++ b/src/qt/sendcoinsdialog.cpp
@@ -0,0 +1,816 @@
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "sendcoinsdialog.h"
+#include "ui_sendcoinsdialog.h"
+
+#include "addresstablemodel.h"
+#include "bitcoinunits.h"
+#include "clientmodel.h"
+#include "coincontroldialog.h"
+#include "guiutil.h"
+#include "optionsmodel.h"
+#include "scicon.h"
+#include "sendcoinsentry.h"
+#include "walletmodel.h"
+
+#include "base58.h"
+#include "coincontrol.h"
+#include "main.h"
+#include "ui_interface.h"
+#include "wallet/wallet.h"
+
+#include <QMessageBox>
+#include <QScrollBar>
+#include <QSettings>
+#include <QTextDocument>
+
+SendCoinsDialog::SendCoinsDialog(QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::SendCoinsDialog),
+ clientModel(0),
+ model(0),
+ fNewRecipientAllowed(true),
+ fFeeMinimized(true)
+{
+ ui->setupUi(this);
+
+#ifdef Q_OS_MAC // Icons on push buttons are very uncommon on Mac
+ ui->addButton->setIcon(QIcon());
+ ui->clearButton->setIcon(QIcon());
+ ui->sendButton->setIcon(QIcon());
+#else
+ ui->addButton->setIcon(SingleColorIcon(":/icons/add"));
+ ui->clearButton->setIcon(SingleColorIcon(":/icons/remove"));
+ ui->sendButton->setIcon(SingleColorIcon(":/icons/send"));
+#endif
+
+ GUIUtil::setupAddressWidget(ui->lineEditCoinControlChange, this);
+
+ addEntry();
+
+ connect(ui->addButton, SIGNAL(clicked()), this, SLOT(addEntry()));
+ connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(clear()));
+
+ // Coin Control
+ connect(ui->pushButtonCoinControl, SIGNAL(clicked()), this, SLOT(coinControlButtonClicked()));
+ connect(ui->checkBoxCoinControlChange, SIGNAL(stateChanged(int)), this, SLOT(coinControlChangeChecked(int)));
+ connect(ui->lineEditCoinControlChange, SIGNAL(textEdited(const QString &)), this, SLOT(coinControlChangeEdited(const QString &)));
+
+ // Coin Control: clipboard actions
+ QAction *clipboardQuantityAction = new QAction(tr("Copy quantity"), this);
+ QAction *clipboardAmountAction = new QAction(tr("Copy amount"), this);
+ QAction *clipboardFeeAction = new QAction(tr("Copy fee"), this);
+ QAction *clipboardAfterFeeAction = new QAction(tr("Copy after fee"), this);
+ QAction *clipboardBytesAction = new QAction(tr("Copy bytes"), this);
+ QAction *clipboardPriorityAction = new QAction(tr("Copy priority"), this);
+ QAction *clipboardLowOutputAction = new QAction(tr("Copy dust"), this);
+ QAction *clipboardChangeAction = new QAction(tr("Copy change"), this);
+ connect(clipboardQuantityAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardQuantity()));
+ connect(clipboardAmountAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardAmount()));
+ connect(clipboardFeeAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardFee()));
+ connect(clipboardAfterFeeAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardAfterFee()));
+ connect(clipboardBytesAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardBytes()));
+ connect(clipboardPriorityAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardPriority()));
+ connect(clipboardLowOutputAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardLowOutput()));
+ connect(clipboardChangeAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardChange()));
+ ui->labelCoinControlQuantity->addAction(clipboardQuantityAction);
+ ui->labelCoinControlAmount->addAction(clipboardAmountAction);
+ ui->labelCoinControlFee->addAction(clipboardFeeAction);
+ ui->labelCoinControlAfterFee->addAction(clipboardAfterFeeAction);
+ ui->labelCoinControlBytes->addAction(clipboardBytesAction);
+ ui->labelCoinControlPriority->addAction(clipboardPriorityAction);
+ ui->labelCoinControlLowOutput->addAction(clipboardLowOutputAction);
+ ui->labelCoinControlChange->addAction(clipboardChangeAction);
+
+ // init transaction fee section
+ QSettings settings;
+ if (!settings.contains("fFeeSectionMinimized"))
+ settings.setValue("fFeeSectionMinimized", true);
+ if (!settings.contains("nFeeRadio") && settings.contains("nTransactionFee") && settings.value("nTransactionFee").toLongLong() > 0) // compatibility
+ settings.setValue("nFeeRadio", 1); // custom
+ if (!settings.contains("nFeeRadio"))
+ settings.setValue("nFeeRadio", 0); // recommended
+ if (!settings.contains("nCustomFeeRadio") && settings.contains("nTransactionFee") && settings.value("nTransactionFee").toLongLong() > 0) // compatibility
+ settings.setValue("nCustomFeeRadio", 1); // total at least
+ if (!settings.contains("nCustomFeeRadio"))
+ settings.setValue("nCustomFeeRadio", 0); // per kilobyte
+ if (!settings.contains("nSmartFeeSliderPosition"))
+ settings.setValue("nSmartFeeSliderPosition", 0);
+ if (!settings.contains("nTransactionFee"))
+ settings.setValue("nTransactionFee", (qint64)DEFAULT_TRANSACTION_FEE);
+ if (!settings.contains("fPayOnlyMinFee"))
+ settings.setValue("fPayOnlyMinFee", false);
+ if (!settings.contains("fSendFreeTransactions"))
+ settings.setValue("fSendFreeTransactions", false);
+ ui->groupFee->setId(ui->radioSmartFee, 0);
+ ui->groupFee->setId(ui->radioCustomFee, 1);
+ ui->groupFee->button((int)std::max(0, std::min(1, settings.value("nFeeRadio").toInt())))->setChecked(true);
+ ui->groupCustomFee->setId(ui->radioCustomPerKilobyte, 0);
+ ui->groupCustomFee->setId(ui->radioCustomAtLeast, 1);
+ ui->groupCustomFee->button((int)std::max(0, std::min(1, settings.value("nCustomFeeRadio").toInt())))->setChecked(true);
+ ui->sliderSmartFee->setValue(settings.value("nSmartFeeSliderPosition").toInt());
+ ui->customFee->setValue(settings.value("nTransactionFee").toLongLong());
+ ui->checkBoxMinimumFee->setChecked(settings.value("fPayOnlyMinFee").toBool());
+ ui->checkBoxFreeTx->setChecked(settings.value("fSendFreeTransactions").toBool());
+ minimizeFeeSection(settings.value("fFeeSectionMinimized").toBool());
+}
+
+void SendCoinsDialog::setClientModel(ClientModel *clientModel)
+{
+ this->clientModel = clientModel;
+
+ if (clientModel) {
+ connect(clientModel, SIGNAL(numBlocksChanged(int,QDateTime)), this, SLOT(updateSmartFeeLabel()));
+ }
+}
+
+void SendCoinsDialog::setModel(WalletModel *model)
+{
+ this->model = model;
+
+ if(model && model->getOptionsModel())
+ {
+ for(int i = 0; i < ui->entries->count(); ++i)
+ {
+ SendCoinsEntry *entry = qobject_cast<SendCoinsEntry*>(ui->entries->itemAt(i)->widget());
+ if(entry)
+ {
+ entry->setModel(model);
+ }
+ }
+
+ setBalance(model->getBalance(), model->getUnconfirmedBalance(), model->getImmatureBalance(),
+ model->getWatchBalance(), model->getWatchUnconfirmedBalance(), model->getWatchImmatureBalance());
+ connect(model, SIGNAL(balanceChanged(CAmount,CAmount,CAmount,CAmount,CAmount,CAmount)), this, SLOT(setBalance(CAmount,CAmount,CAmount,CAmount,CAmount,CAmount)));
+ connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
+ updateDisplayUnit();
+
+ // Coin Control
+ connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(coinControlUpdateLabels()));
+ connect(model->getOptionsModel(), SIGNAL(coinControlFeaturesChanged(bool)), this, SLOT(coinControlFeatureChanged(bool)));
+ ui->frameCoinControl->setVisible(model->getOptionsModel()->getCoinControlFeatures());
+ coinControlUpdateLabels();
+
+ // fee section
+ connect(ui->sliderSmartFee, SIGNAL(valueChanged(int)), this, SLOT(updateSmartFeeLabel()));
+ connect(ui->sliderSmartFee, SIGNAL(valueChanged(int)), this, SLOT(updateGlobalFeeVariables()));
+ connect(ui->sliderSmartFee, SIGNAL(valueChanged(int)), this, SLOT(coinControlUpdateLabels()));
+ connect(ui->groupFee, SIGNAL(buttonClicked(int)), this, SLOT(updateFeeSectionControls()));
+ connect(ui->groupFee, SIGNAL(buttonClicked(int)), this, SLOT(updateGlobalFeeVariables()));
+ connect(ui->groupFee, SIGNAL(buttonClicked(int)), this, SLOT(coinControlUpdateLabels()));
+ connect(ui->groupCustomFee, SIGNAL(buttonClicked(int)), this, SLOT(updateGlobalFeeVariables()));
+ connect(ui->groupCustomFee, SIGNAL(buttonClicked(int)), this, SLOT(coinControlUpdateLabels()));
+ connect(ui->customFee, SIGNAL(valueChanged()), this, SLOT(updateGlobalFeeVariables()));
+ connect(ui->customFee, SIGNAL(valueChanged()), this, SLOT(coinControlUpdateLabels()));
+ connect(ui->checkBoxMinimumFee, SIGNAL(stateChanged(int)), this, SLOT(setMinimumFee()));
+ connect(ui->checkBoxMinimumFee, SIGNAL(stateChanged(int)), this, SLOT(updateFeeSectionControls()));
+ connect(ui->checkBoxMinimumFee, SIGNAL(stateChanged(int)), this, SLOT(updateGlobalFeeVariables()));
+ connect(ui->checkBoxMinimumFee, SIGNAL(stateChanged(int)), this, SLOT(coinControlUpdateLabels()));
+ connect(ui->checkBoxFreeTx, SIGNAL(stateChanged(int)), this, SLOT(updateGlobalFeeVariables()));
+ connect(ui->checkBoxFreeTx, SIGNAL(stateChanged(int)), this, SLOT(coinControlUpdateLabels()));
+ ui->customFee->setSingleStep(CWallet::minTxFee.GetFeePerK());
+ updateFeeSectionControls();
+ updateMinFeeLabel();
+ updateSmartFeeLabel();
+ updateGlobalFeeVariables();
+ }
+}
+
+SendCoinsDialog::~SendCoinsDialog()
+{
+ QSettings settings;
+ settings.setValue("fFeeSectionMinimized", fFeeMinimized);
+ settings.setValue("nFeeRadio", ui->groupFee->checkedId());
+ settings.setValue("nCustomFeeRadio", ui->groupCustomFee->checkedId());
+ settings.setValue("nSmartFeeSliderPosition", ui->sliderSmartFee->value());
+ settings.setValue("nTransactionFee", (qint64)ui->customFee->value());
+ settings.setValue("fPayOnlyMinFee", ui->checkBoxMinimumFee->isChecked());
+ settings.setValue("fSendFreeTransactions", ui->checkBoxFreeTx->isChecked());
+
+ delete ui;
+}
+
+void SendCoinsDialog::on_sendButton_clicked()
+{
+ if(!model || !model->getOptionsModel())
+ return;
+
+ QList<SendCoinsRecipient> recipients;
+ bool valid = true;
+
+ for(int i = 0; i < ui->entries->count(); ++i)
+ {
+ SendCoinsEntry *entry = qobject_cast<SendCoinsEntry*>(ui->entries->itemAt(i)->widget());
+ if(entry)
+ {
+ if(entry->validate())
+ {
+ recipients.append(entry->getValue());
+ }
+ else
+ {
+ valid = false;
+ }
+ }
+ }
+
+ if(!valid || recipients.isEmpty())
+ {
+ return;
+ }
+
+ fNewRecipientAllowed = false;
+ WalletModel::UnlockContext ctx(model->requestUnlock());
+ if(!ctx.isValid())
+ {
+ // Unlock wallet was cancelled
+ fNewRecipientAllowed = true;
+ return;
+ }
+
+ // prepare transaction for getting txFee earlier
+ WalletModelTransaction currentTransaction(recipients);
+ WalletModel::SendCoinsReturn prepareStatus;
+ if (model->getOptionsModel()->getCoinControlFeatures()) // coin control enabled
+ prepareStatus = model->prepareTransaction(currentTransaction, CoinControlDialog::coinControl);
+ else
+ prepareStatus = model->prepareTransaction(currentTransaction);
+
+ // process prepareStatus and on error generate message shown to user
+ processSendCoinsReturn(prepareStatus,
+ BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), currentTransaction.getTransactionFee()));
+
+ if(prepareStatus.status != WalletModel::OK) {
+ fNewRecipientAllowed = true;
+ return;
+ }
+
+ CAmount txFee = currentTransaction.getTransactionFee();
+
+ // Format confirmation message
+ QStringList formatted;
+ Q_FOREACH(const SendCoinsRecipient &rcp, currentTransaction.getRecipients())
+ {
+ // generate bold amount string
+ QString amount = "<b>" + BitcoinUnits::formatHtmlWithUnit(model->getOptionsModel()->getDisplayUnit(), rcp.amount);
+ amount.append("</b>");
+ // generate monospace address string
+ QString address = "<span style='font-family: monospace;'>" + rcp.address;
+ address.append("</span>");
+
+ QString recipientElement;
+
+ if (!rcp.paymentRequest.IsInitialized()) // normal payment
+ {
+ if(rcp.label.length() > 0) // label with address
+ {
+ recipientElement = tr("%1 to %2").arg(amount, GUIUtil::HtmlEscape(rcp.label));
+ recipientElement.append(QString(" (%1)").arg(address));
+ }
+ else // just address
+ {
+ recipientElement = tr("%1 to %2").arg(amount, address);
+ }
+ }
+ else if(!rcp.authenticatedMerchant.isEmpty()) // authenticated payment request
+ {
+ recipientElement = tr("%1 to %2").arg(amount, GUIUtil::HtmlEscape(rcp.authenticatedMerchant));
+ }
+ else // unauthenticated payment request
+ {
+ recipientElement = tr("%1 to %2").arg(amount, address);
+ }
+
+ formatted.append(recipientElement);
+ }
+
+ QString questionString = tr("Are you sure you want to send?");
+ questionString.append("<br /><br />%1");
+
+ if(txFee > 0)
+ {
+ // append fee string if a fee is required
+ questionString.append("<hr /><span style='color:#aa0000;'>");
+ questionString.append(BitcoinUnits::formatHtmlWithUnit(model->getOptionsModel()->getDisplayUnit(), txFee));
+ questionString.append("</span> ");
+ questionString.append(tr("added as transaction fee"));
+
+ // append transaction size
+ questionString.append(" (" + QString::number((double)currentTransaction.getTransactionSize() / 1000) + " kB)");
+ }
+
+ // add total amount in all subdivision units
+ questionString.append("<hr />");
+ CAmount totalAmount = currentTransaction.getTotalTransactionAmount() + txFee;
+ QStringList alternativeUnits;
+ Q_FOREACH(BitcoinUnits::Unit u, BitcoinUnits::availableUnits())
+ {
+ if(u != model->getOptionsModel()->getDisplayUnit())
+ alternativeUnits.append(BitcoinUnits::formatHtmlWithUnit(u, totalAmount));
+ }
+ questionString.append(tr("Total Amount %1<span style='font-size:10pt;font-weight:normal;'><br />(=%2)</span>")
+ .arg(BitcoinUnits::formatHtmlWithUnit(model->getOptionsModel()->getDisplayUnit(), totalAmount))
+ .arg(alternativeUnits.join(" " + tr("or") + "<br />")));
+
+ QMessageBox::StandardButton retval = QMessageBox::question(this, tr("Confirm send coins"),
+ questionString.arg(formatted.join("<br />")),
+ QMessageBox::Yes | QMessageBox::Cancel,
+ QMessageBox::Cancel);
+
+ if(retval != QMessageBox::Yes)
+ {
+ fNewRecipientAllowed = true;
+ return;
+ }
+
+ // now send the prepared transaction
+ WalletModel::SendCoinsReturn sendStatus = model->sendCoins(currentTransaction);
+ // process sendStatus and on error generate message shown to user
+ processSendCoinsReturn(sendStatus);
+
+ if (sendStatus.status == WalletModel::OK)
+ {
+ accept();
+ CoinControlDialog::coinControl->UnSelectAll();
+ coinControlUpdateLabels();
+ }
+ fNewRecipientAllowed = true;
+}
+
+void SendCoinsDialog::clear()
+{
+ // Remove entries until only one left
+ while(ui->entries->count())
+ {
+ ui->entries->takeAt(0)->widget()->deleteLater();
+ }
+ addEntry();
+
+ updateTabsAndLabels();
+}
+
+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*)));
+ connect(entry, SIGNAL(payAmountChanged()), this, SLOT(coinControlUpdateLabels()));
+ connect(entry, SIGNAL(subtractFeeFromAmountChanged()), this, SLOT(coinControlUpdateLabels()));
+
+ updateTabsAndLabels();
+
+ // Focus the field, so that entry can start immediately
+ entry->clear();
+ entry->setFocus();
+ ui->scrollAreaWidgetContents->resize(ui->scrollAreaWidgetContents->sizeHint());
+ qApp->processEvents();
+ QScrollBar* bar = ui->scrollArea->verticalScrollBar();
+ if(bar)
+ bar->setSliderPosition(bar->maximum());
+ return entry;
+}
+
+void SendCoinsDialog::updateTabsAndLabels()
+{
+ setupTabChain(0);
+ coinControlUpdateLabels();
+}
+
+void SendCoinsDialog::removeEntry(SendCoinsEntry* entry)
+{
+ entry->hide();
+
+ // If the last entry is about to be removed add an empty one
+ if (ui->entries->count() == 1)
+ addEntry();
+
+ entry->deleteLater();
+
+ updateTabsAndLabels();
+}
+
+QWidget *SendCoinsDialog::setupTabChain(QWidget *prev)
+{
+ for(int i = 0; i < ui->entries->count(); ++i)
+ {
+ SendCoinsEntry *entry = qobject_cast<SendCoinsEntry*>(ui->entries->itemAt(i)->widget());
+ if(entry)
+ {
+ prev = entry->setupTabChain(prev);
+ }
+ }
+ QWidget::setTabOrder(prev, ui->sendButton);
+ QWidget::setTabOrder(ui->sendButton, ui->clearButton);
+ QWidget::setTabOrder(ui->clearButton, ui->addButton);
+ return ui->addButton;
+}
+
+void SendCoinsDialog::setAddress(const QString &address)
+{
+ SendCoinsEntry *entry = 0;
+ // Replace the first entry if it is still unused
+ if(ui->entries->count() == 1)
+ {
+ SendCoinsEntry *first = qobject_cast<SendCoinsEntry*>(ui->entries->itemAt(0)->widget());
+ if(first->isClear())
+ {
+ entry = first;
+ }
+ }
+ if(!entry)
+ {
+ entry = addEntry();
+ }
+
+ entry->setAddress(address);
+}
+
+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<SendCoinsEntry*>(ui->entries->itemAt(0)->widget());
+ if(first->isClear())
+ {
+ entry = first;
+ }
+ }
+ if(!entry)
+ {
+ entry = addEntry();
+ }
+
+ entry->setValue(rv);
+ updateTabsAndLabels();
+}
+
+bool SendCoinsDialog::handlePaymentRequest(const SendCoinsRecipient &rv)
+{
+ // Just paste the entry, all pre-checks
+ // are done in paymentserver.cpp.
+ pasteEntry(rv);
+ return true;
+}
+
+void SendCoinsDialog::setBalance(const CAmount& balance, const CAmount& unconfirmedBalance, const CAmount& immatureBalance,
+ const CAmount& watchBalance, const CAmount& watchUnconfirmedBalance, const CAmount& watchImmatureBalance)
+{
+ Q_UNUSED(unconfirmedBalance);
+ Q_UNUSED(immatureBalance);
+ Q_UNUSED(watchBalance);
+ Q_UNUSED(watchUnconfirmedBalance);
+ Q_UNUSED(watchImmatureBalance);
+
+ if(model && model->getOptionsModel())
+ {
+ ui->labelBalance->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), balance));
+ }
+}
+
+void SendCoinsDialog::updateDisplayUnit()
+{
+ setBalance(model->getBalance(), 0, 0, 0, 0, 0);
+ ui->customFee->setDisplayUnit(model->getOptionsModel()->getDisplayUnit());
+ updateMinFeeLabel();
+ updateSmartFeeLabel();
+}
+
+void SendCoinsDialog::processSendCoinsReturn(const WalletModel::SendCoinsReturn &sendCoinsReturn, const QString &msgArg)
+{
+ QPair<QString, CClientUIInterface::MessageBoxFlags> msgParams;
+ // Default to a warning message, override if error message is needed
+ msgParams.second = CClientUIInterface::MSG_WARNING;
+
+ // This comment is specific to SendCoinsDialog usage of WalletModel::SendCoinsReturn.
+ // WalletModel::TransactionCommitFailed is used only in WalletModel::sendCoins()
+ // all others are used only in WalletModel::prepareTransaction()
+ switch(sendCoinsReturn.status)
+ {
+ case WalletModel::InvalidAddress:
+ msgParams.first = tr("The recipient address is not valid. Please recheck.");
+ break;
+ case WalletModel::InvalidAmount:
+ msgParams.first = tr("The amount to pay must be larger than 0.");
+ break;
+ case WalletModel::AmountExceedsBalance:
+ msgParams.first = tr("The amount exceeds your balance.");
+ break;
+ case WalletModel::AmountWithFeeExceedsBalance:
+ msgParams.first = tr("The total exceeds your balance when the %1 transaction fee is included.").arg(msgArg);
+ break;
+ case WalletModel::DuplicateAddress:
+ msgParams.first = tr("Duplicate address found: addresses should only be used once each.");
+ break;
+ case WalletModel::TransactionCreationFailed:
+ msgParams.first = tr("Transaction creation failed!");
+ msgParams.second = CClientUIInterface::MSG_ERROR;
+ break;
+ case WalletModel::TransactionCommitFailed:
+ msgParams.first = tr("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.");
+ msgParams.second = CClientUIInterface::MSG_ERROR;
+ break;
+ case WalletModel::AbsurdFee:
+ msgParams.first = tr("A fee higher than %1 is considered an absurdly high fee.").arg(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), 10000000));
+ break;
+ case WalletModel::PaymentRequestExpired:
+ msgParams.first = tr("Payment request expired.");
+ msgParams.second = CClientUIInterface::MSG_ERROR;
+ break;
+ // included to prevent a compiler warning.
+ case WalletModel::OK:
+ default:
+ return;
+ }
+
+ Q_EMIT message(tr("Send Coins"), msgParams.first, msgParams.second);
+}
+
+void SendCoinsDialog::minimizeFeeSection(bool fMinimize)
+{
+ ui->labelFeeMinimized->setVisible(fMinimize);
+ ui->buttonChooseFee ->setVisible(fMinimize);
+ ui->buttonMinimizeFee->setVisible(!fMinimize);
+ ui->frameFeeSelection->setVisible(!fMinimize);
+ ui->horizontalLayoutSmartFee->setContentsMargins(0, (fMinimize ? 0 : 6), 0, 0);
+ fFeeMinimized = fMinimize;
+}
+
+void SendCoinsDialog::on_buttonChooseFee_clicked()
+{
+ minimizeFeeSection(false);
+}
+
+void SendCoinsDialog::on_buttonMinimizeFee_clicked()
+{
+ updateFeeMinimizedLabel();
+ minimizeFeeSection(true);
+}
+
+void SendCoinsDialog::setMinimumFee()
+{
+ ui->radioCustomPerKilobyte->setChecked(true);
+ ui->customFee->setValue(CWallet::minTxFee.GetFeePerK());
+}
+
+void SendCoinsDialog::updateFeeSectionControls()
+{
+ ui->sliderSmartFee ->setEnabled(ui->radioSmartFee->isChecked());
+ ui->labelSmartFee ->setEnabled(ui->radioSmartFee->isChecked());
+ ui->labelSmartFee2 ->setEnabled(ui->radioSmartFee->isChecked());
+ ui->labelSmartFee3 ->setEnabled(ui->radioSmartFee->isChecked());
+ ui->labelFeeEstimation ->setEnabled(ui->radioSmartFee->isChecked());
+ ui->labelSmartFeeNormal ->setEnabled(ui->radioSmartFee->isChecked());
+ ui->labelSmartFeeFast ->setEnabled(ui->radioSmartFee->isChecked());
+ ui->checkBoxMinimumFee ->setEnabled(ui->radioCustomFee->isChecked());
+ ui->labelMinFeeWarning ->setEnabled(ui->radioCustomFee->isChecked());
+ ui->radioCustomPerKilobyte ->setEnabled(ui->radioCustomFee->isChecked() && !ui->checkBoxMinimumFee->isChecked());
+ ui->radioCustomAtLeast ->setEnabled(ui->radioCustomFee->isChecked() && !ui->checkBoxMinimumFee->isChecked());
+ ui->customFee ->setEnabled(ui->radioCustomFee->isChecked() && !ui->checkBoxMinimumFee->isChecked());
+}
+
+void SendCoinsDialog::updateGlobalFeeVariables()
+{
+ if (ui->radioSmartFee->isChecked())
+ {
+ nTxConfirmTarget = defaultConfirmTarget - ui->sliderSmartFee->value();
+ payTxFee = CFeeRate(0);
+ }
+ else
+ {
+ nTxConfirmTarget = defaultConfirmTarget;
+ payTxFee = CFeeRate(ui->customFee->value());
+ fPayAtLeastCustomFee = ui->radioCustomAtLeast->isChecked();
+ }
+
+ fSendFreeTransactions = ui->checkBoxFreeTx->isChecked();
+}
+
+void SendCoinsDialog::updateFeeMinimizedLabel()
+{
+ if(!model || !model->getOptionsModel())
+ return;
+
+ if (ui->radioSmartFee->isChecked())
+ ui->labelFeeMinimized->setText(ui->labelSmartFee->text());
+ else {
+ ui->labelFeeMinimized->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), ui->customFee->value()) +
+ ((ui->radioCustomPerKilobyte->isChecked()) ? "/kB" : ""));
+ }
+}
+
+void SendCoinsDialog::updateMinFeeLabel()
+{
+ if (model && model->getOptionsModel())
+ ui->checkBoxMinimumFee->setText(tr("Pay only the minimum fee of %1").arg(
+ BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), CWallet::minTxFee.GetFeePerK()) + "/kB")
+ );
+}
+
+void SendCoinsDialog::updateSmartFeeLabel()
+{
+ if(!model || !model->getOptionsModel())
+ return;
+
+ int nBlocksToConfirm = defaultConfirmTarget - ui->sliderSmartFee->value();
+ CFeeRate feeRate = mempool.estimateFee(nBlocksToConfirm);
+ if (feeRate <= CFeeRate(0)) // not enough data => minfee
+ {
+ ui->labelSmartFee->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), CWallet::minTxFee.GetFeePerK()) + "/kB");
+ ui->labelSmartFee2->show(); // (Smart fee not initialized yet. This usually takes a few blocks...)
+ ui->labelFeeEstimation->setText("");
+ }
+ else
+ {
+ ui->labelSmartFee->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), feeRate.GetFeePerK()) + "/kB");
+ ui->labelSmartFee2->hide();
+ ui->labelFeeEstimation->setText(tr("Estimated to begin confirmation within %n block(s).", "", nBlocksToConfirm));
+ }
+
+ updateFeeMinimizedLabel();
+}
+
+// Coin Control: copy label "Quantity" to clipboard
+void SendCoinsDialog::coinControlClipboardQuantity()
+{
+ GUIUtil::setClipboard(ui->labelCoinControlQuantity->text());
+}
+
+// Coin Control: copy label "Amount" to clipboard
+void SendCoinsDialog::coinControlClipboardAmount()
+{
+ GUIUtil::setClipboard(ui->labelCoinControlAmount->text().left(ui->labelCoinControlAmount->text().indexOf(" ")));
+}
+
+// Coin Control: copy label "Fee" to clipboard
+void SendCoinsDialog::coinControlClipboardFee()
+{
+ GUIUtil::setClipboard(ui->labelCoinControlFee->text().left(ui->labelCoinControlFee->text().indexOf(" ")).replace(ASYMP_UTF8, ""));
+}
+
+// Coin Control: copy label "After fee" to clipboard
+void SendCoinsDialog::coinControlClipboardAfterFee()
+{
+ GUIUtil::setClipboard(ui->labelCoinControlAfterFee->text().left(ui->labelCoinControlAfterFee->text().indexOf(" ")).replace(ASYMP_UTF8, ""));
+}
+
+// Coin Control: copy label "Bytes" to clipboard
+void SendCoinsDialog::coinControlClipboardBytes()
+{
+ GUIUtil::setClipboard(ui->labelCoinControlBytes->text().replace(ASYMP_UTF8, ""));
+}
+
+// Coin Control: copy label "Priority" to clipboard
+void SendCoinsDialog::coinControlClipboardPriority()
+{
+ GUIUtil::setClipboard(ui->labelCoinControlPriority->text());
+}
+
+// Coin Control: copy label "Dust" to clipboard
+void SendCoinsDialog::coinControlClipboardLowOutput()
+{
+ GUIUtil::setClipboard(ui->labelCoinControlLowOutput->text());
+}
+
+// Coin Control: copy label "Change" to clipboard
+void SendCoinsDialog::coinControlClipboardChange()
+{
+ GUIUtil::setClipboard(ui->labelCoinControlChange->text().left(ui->labelCoinControlChange->text().indexOf(" ")).replace(ASYMP_UTF8, ""));
+}
+
+// Coin Control: settings menu - coin control enabled/disabled by user
+void SendCoinsDialog::coinControlFeatureChanged(bool checked)
+{
+ ui->frameCoinControl->setVisible(checked);
+
+ if (!checked && model) // coin control features disabled
+ CoinControlDialog::coinControl->SetNull();
+
+ if (checked)
+ coinControlUpdateLabels();
+}
+
+// Coin Control: button inputs -> show actual coin control dialog
+void SendCoinsDialog::coinControlButtonClicked()
+{
+ CoinControlDialog dlg;
+ dlg.setModel(model);
+ dlg.exec();
+ coinControlUpdateLabels();
+}
+
+// Coin Control: checkbox custom change address
+void SendCoinsDialog::coinControlChangeChecked(int state)
+{
+ if (state == Qt::Unchecked)
+ {
+ CoinControlDialog::coinControl->destChange = CNoDestination();
+ ui->labelCoinControlChangeLabel->clear();
+ }
+ else
+ // use this to re-validate an already entered address
+ coinControlChangeEdited(ui->lineEditCoinControlChange->text());
+
+ ui->lineEditCoinControlChange->setEnabled((state == Qt::Checked));
+}
+
+// Coin Control: custom change address changed
+void SendCoinsDialog::coinControlChangeEdited(const QString& text)
+{
+ if (model && model->getAddressTableModel())
+ {
+ // Default to no change address until verified
+ CoinControlDialog::coinControl->destChange = CNoDestination();
+ ui->labelCoinControlChangeLabel->setStyleSheet("QLabel{color:red;}");
+
+ CBitcoinAddress addr = CBitcoinAddress(text.toStdString());
+
+ if (text.isEmpty()) // Nothing entered
+ {
+ ui->labelCoinControlChangeLabel->setText("");
+ }
+ else if (!addr.IsValid()) // Invalid address
+ {
+ ui->labelCoinControlChangeLabel->setText(tr("Warning: Invalid Bitcoin address"));
+ }
+ else // Valid address
+ {
+ CPubKey pubkey;
+ CKeyID keyid;
+ addr.GetKeyID(keyid);
+ if (!model->getPubKey(keyid, pubkey)) // Unknown change address
+ {
+ ui->labelCoinControlChangeLabel->setText(tr("Warning: Unknown change address"));
+ }
+ else // Known change address
+ {
+ ui->labelCoinControlChangeLabel->setStyleSheet("QLabel{color:black;}");
+
+ // Query label
+ QString associatedLabel = model->getAddressTableModel()->labelForAddress(text);
+ if (!associatedLabel.isEmpty())
+ ui->labelCoinControlChangeLabel->setText(associatedLabel);
+ else
+ ui->labelCoinControlChangeLabel->setText(tr("(no label)"));
+
+ CoinControlDialog::coinControl->destChange = addr.Get();
+ }
+ }
+ }
+}
+
+// Coin Control: update labels
+void SendCoinsDialog::coinControlUpdateLabels()
+{
+ if (!model || !model->getOptionsModel() || !model->getOptionsModel()->getCoinControlFeatures())
+ return;
+
+ // set pay amounts
+ CoinControlDialog::payAmounts.clear();
+ CoinControlDialog::fSubtractFeeFromAmount = false;
+ for(int i = 0; i < ui->entries->count(); ++i)
+ {
+ SendCoinsEntry *entry = qobject_cast<SendCoinsEntry*>(ui->entries->itemAt(i)->widget());
+ if(entry)
+ {
+ SendCoinsRecipient rcp = entry->getValue();
+ CoinControlDialog::payAmounts.append(rcp.amount);
+ if (rcp.fSubtractFeeFromAmount)
+ CoinControlDialog::fSubtractFeeFromAmount = true;
+ }
+ }
+
+ if (CoinControlDialog::coinControl->HasSelected())
+ {
+ // actual coin control calculation
+ CoinControlDialog::updateLabels(model, this);
+
+ // show coin control stats
+ ui->labelCoinControlAutomaticallySelected->hide();
+ ui->widgetCoinControl->show();
+ }
+ else
+ {
+ // hide coin control stats
+ ui->labelCoinControlAutomaticallySelected->show();
+ ui->widgetCoinControl->hide();
+ ui->labelCoinControlInsuffFunds->hide();
+ }
+}
diff --git a/src/qt/sendcoinsdialog.h b/src/qt/sendcoinsdialog.h
new file mode 100644
index 0000000000..c833da84b2
--- /dev/null
+++ b/src/qt/sendcoinsdialog.h
@@ -0,0 +1,101 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_SENDCOINSDIALOG_H
+#define BITCOIN_QT_SENDCOINSDIALOG_H
+
+#include "walletmodel.h"
+
+#include <QDialog>
+#include <QString>
+
+class ClientModel;
+class OptionsModel;
+class SendCoinsEntry;
+class SendCoinsRecipient;
+
+namespace Ui {
+ class SendCoinsDialog;
+}
+
+QT_BEGIN_NAMESPACE
+class QUrl;
+QT_END_NAMESPACE
+
+const int defaultConfirmTarget = 25;
+
+/** Dialog for sending bitcoins */
+class SendCoinsDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit SendCoinsDialog(QWidget *parent = 0);
+ ~SendCoinsDialog();
+
+ void setClientModel(ClientModel *clientModel);
+ void setModel(WalletModel *model);
+
+ /** Set up the tab chain manually, as Qt messes up the tab chain by default in some cases (issue https://bugreports.qt-project.org/browse/QTBUG-10907).
+ */
+ QWidget *setupTabChain(QWidget *prev);
+
+ void setAddress(const QString &address);
+ void pasteEntry(const SendCoinsRecipient &rv);
+ bool handlePaymentRequest(const SendCoinsRecipient &recipient);
+
+public Q_SLOTS:
+ void clear();
+ void reject();
+ void accept();
+ SendCoinsEntry *addEntry();
+ void updateTabsAndLabels();
+ void setBalance(const CAmount& balance, const CAmount& unconfirmedBalance, const CAmount& immatureBalance,
+ const CAmount& watchOnlyBalance, const CAmount& watchUnconfBalance, const CAmount& watchImmatureBalance);
+
+private:
+ Ui::SendCoinsDialog *ui;
+ ClientModel *clientModel;
+ WalletModel *model;
+ bool fNewRecipientAllowed;
+ bool fFeeMinimized;
+
+ // Process WalletModel::SendCoinsReturn and generate a pair consisting
+ // of a message and message flags for use in Q_EMIT message().
+ // Additional parameter msgArg can be used via .arg(msgArg).
+ void processSendCoinsReturn(const WalletModel::SendCoinsReturn &sendCoinsReturn, const QString &msgArg = QString());
+ void minimizeFeeSection(bool fMinimize);
+ void updateFeeMinimizedLabel();
+
+private Q_SLOTS:
+ void on_sendButton_clicked();
+ void on_buttonChooseFee_clicked();
+ void on_buttonMinimizeFee_clicked();
+ void removeEntry(SendCoinsEntry* entry);
+ void updateDisplayUnit();
+ void coinControlFeatureChanged(bool);
+ void coinControlButtonClicked();
+ void coinControlChangeChecked(int);
+ void coinControlChangeEdited(const QString &);
+ void coinControlUpdateLabels();
+ void coinControlClipboardQuantity();
+ void coinControlClipboardAmount();
+ void coinControlClipboardFee();
+ void coinControlClipboardAfterFee();
+ void coinControlClipboardBytes();
+ void coinControlClipboardPriority();
+ void coinControlClipboardLowOutput();
+ void coinControlClipboardChange();
+ void setMinimumFee();
+ void updateFeeSectionControls();
+ void updateMinFeeLabel();
+ void updateSmartFeeLabel();
+ void updateGlobalFeeVariables();
+
+Q_SIGNALS:
+ // Fired when a message should be reported to the user
+ void message(const QString &title, const QString &message, unsigned int style);
+};
+
+#endif // BITCOIN_QT_SENDCOINSDIALOG_H
diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp
new file mode 100644
index 0000000000..90a8cbdc4e
--- /dev/null
+++ b/src/qt/sendcoinsentry.cpp
@@ -0,0 +1,266 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "sendcoinsentry.h"
+#include "ui_sendcoinsentry.h"
+
+#include "addressbookpage.h"
+#include "addresstablemodel.h"
+#include "guiutil.h"
+#include "optionsmodel.h"
+#include "scicon.h"
+#include "walletmodel.h"
+
+#include <QApplication>
+#include <QClipboard>
+
+SendCoinsEntry::SendCoinsEntry(QWidget *parent) :
+ QStackedWidget(parent),
+ ui(new Ui::SendCoinsEntry),
+ model(0)
+{
+ ui->setupUi(this);
+
+ ui->addressBookButton->setIcon(SingleColorIcon(":/icons/address-book"));
+ ui->pasteButton->setIcon(SingleColorIcon(":/icons/editpaste"));
+ ui->deleteButton->setIcon(SingleColorIcon(":/icons/remove"));
+ ui->deleteButton_is->setIcon(SingleColorIcon(":/icons/remove"));
+ ui->deleteButton_s->setIcon(SingleColorIcon(":/icons/remove"));
+
+ setCurrentWidget(ui->SendCoins);
+
+#ifdef Q_OS_MAC
+ ui->payToLayout->setSpacing(4);
+#endif
+#if QT_VERSION >= 0x040700
+ ui->addAsLabel->setPlaceholderText(tr("Enter a label for this address to add it to your address book"));
+#endif
+
+ // normal bitcoin address field
+ GUIUtil::setupAddressWidget(ui->payTo, this);
+ // just a label for displaying bitcoin address(es)
+ ui->payTo_is->setFont(GUIUtil::bitcoinAddressFont());
+
+ // Connect signals
+ connect(ui->payAmount, SIGNAL(valueChanged()), this, SIGNAL(payAmountChanged()));
+ connect(ui->checkboxSubtractFeeFromAmount, SIGNAL(toggled(bool)), this, SIGNAL(subtractFeeFromAmountChanged()));
+ connect(ui->deleteButton, SIGNAL(clicked()), this, SLOT(deleteClicked()));
+ connect(ui->deleteButton_is, SIGNAL(clicked()), this, SLOT(deleteClicked()));
+ connect(ui->deleteButton_s, SIGNAL(clicked()), this, SLOT(deleteClicked()));
+}
+
+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::ForSelection, 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)
+{
+ updateLabel(address);
+}
+
+void SendCoinsEntry::setModel(WalletModel *model)
+{
+ this->model = model;
+
+ if (model && model->getOptionsModel())
+ connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
+
+ clear();
+}
+
+void SendCoinsEntry::clear()
+{
+ // clear UI elements for normal payment
+ ui->payTo->clear();
+ ui->addAsLabel->clear();
+ ui->payAmount->clear();
+ ui->checkboxSubtractFeeFromAmount->setCheckState(Qt::Unchecked);
+ ui->messageTextLabel->clear();
+ ui->messageTextLabel->hide();
+ ui->messageLabel->hide();
+ // clear UI elements for unauthenticated payment request
+ ui->payTo_is->clear();
+ ui->memoTextLabel_is->clear();
+ ui->payAmount_is->clear();
+ // clear UI elements for authenticated payment request
+ ui->payTo_s->clear();
+ ui->memoTextLabel_s->clear();
+ ui->payAmount_s->clear();
+
+ // update the display unit, to not use the default ("BTC")
+ updateDisplayUnit();
+}
+
+void SendCoinsEntry::deleteClicked()
+{
+ Q_EMIT removeEntry(this);
+}
+
+bool SendCoinsEntry::validate()
+{
+ if (!model)
+ return false;
+
+ // Check input validity
+ bool retval = true;
+
+ // Skip checks for payment request
+ if (recipient.paymentRequest.IsInitialized())
+ return retval;
+
+ if (!model->validateAddress(ui->payTo->text()))
+ {
+ ui->payTo->setValid(false);
+ retval = false;
+ }
+
+ if (!ui->payAmount->validate())
+ {
+ retval = false;
+ }
+
+ // Sending a zero amount is invalid
+ if (ui->payAmount->value(0) <= 0)
+ {
+ ui->payAmount->setValid(false);
+ retval = false;
+ }
+
+ // Reject dust outputs:
+ if (retval && GUIUtil::isDust(ui->payTo->text(), ui->payAmount->value())) {
+ ui->payAmount->setValid(false);
+ retval = false;
+ }
+
+ return retval;
+}
+
+SendCoinsRecipient SendCoinsEntry::getValue()
+{
+ // Payment request
+ if (recipient.paymentRequest.IsInitialized())
+ return recipient;
+
+ // Normal payment
+ recipient.address = ui->payTo->text();
+ recipient.label = ui->addAsLabel->text();
+ recipient.amount = ui->payAmount->value();
+ recipient.message = ui->messageTextLabel->text();
+ recipient.fSubtractFeeFromAmount = (ui->checkboxSubtractFeeFromAmount->checkState() == Qt::Checked);
+
+ return recipient;
+}
+
+QWidget *SendCoinsEntry::setupTabChain(QWidget *prev)
+{
+ QWidget::setTabOrder(prev, ui->payTo);
+ QWidget::setTabOrder(ui->payTo, ui->addAsLabel);
+ QWidget *w = ui->payAmount->setupTabChain(ui->addAsLabel);
+ QWidget::setTabOrder(w, ui->checkboxSubtractFeeFromAmount);
+ QWidget::setTabOrder(ui->checkboxSubtractFeeFromAmount, ui->addressBookButton);
+ QWidget::setTabOrder(ui->addressBookButton, ui->pasteButton);
+ QWidget::setTabOrder(ui->pasteButton, ui->deleteButton);
+ return ui->deleteButton;
+}
+
+void SendCoinsEntry::setValue(const SendCoinsRecipient &value)
+{
+ recipient = value;
+
+ if (recipient.paymentRequest.IsInitialized()) // payment request
+ {
+ if (recipient.authenticatedMerchant.isEmpty()) // unauthenticated
+ {
+ ui->payTo_is->setText(recipient.address);
+ ui->memoTextLabel_is->setText(recipient.message);
+ ui->payAmount_is->setValue(recipient.amount);
+ ui->payAmount_is->setReadOnly(true);
+ setCurrentWidget(ui->SendCoins_UnauthenticatedPaymentRequest);
+ }
+ else // authenticated
+ {
+ ui->payTo_s->setText(recipient.authenticatedMerchant);
+ ui->memoTextLabel_s->setText(recipient.message);
+ ui->payAmount_s->setValue(recipient.amount);
+ ui->payAmount_s->setReadOnly(true);
+ setCurrentWidget(ui->SendCoins_AuthenticatedPaymentRequest);
+ }
+ }
+ else // normal payment
+ {
+ // message
+ ui->messageTextLabel->setText(recipient.message);
+ ui->messageTextLabel->setVisible(!recipient.message.isEmpty());
+ ui->messageLabel->setVisible(!recipient.message.isEmpty());
+
+ ui->addAsLabel->clear();
+ ui->payTo->setText(recipient.address); // this may set a label from addressbook
+ if (!recipient.label.isEmpty()) // if a label had been set from the addressbook, don't overwrite with an empty label
+ ui->addAsLabel->setText(recipient.label);
+ ui->payAmount->setValue(recipient.amount);
+ }
+}
+
+void SendCoinsEntry::setAddress(const QString &address)
+{
+ ui->payTo->setText(address);
+ ui->payAmount->setFocus();
+}
+
+bool SendCoinsEntry::isClear()
+{
+ return ui->payTo->text().isEmpty() && ui->payTo_is->text().isEmpty() && ui->payTo_s->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());
+ ui->payAmount_is->setDisplayUnit(model->getOptionsModel()->getDisplayUnit());
+ ui->payAmount_s->setDisplayUnit(model->getOptionsModel()->getDisplayUnit());
+ }
+}
+
+bool SendCoinsEntry::updateLabel(const QString &address)
+{
+ if(!model)
+ return false;
+
+ // 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);
+ return true;
+ }
+
+ return false;
+}
diff --git a/src/qt/sendcoinsentry.h b/src/qt/sendcoinsentry.h
new file mode 100644
index 0000000000..d7e655fdc3
--- /dev/null
+++ b/src/qt/sendcoinsentry.h
@@ -0,0 +1,71 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_SENDCOINSENTRY_H
+#define BITCOIN_QT_SENDCOINSENTRY_H
+
+#include "walletmodel.h"
+
+#include <QStackedWidget>
+
+class WalletModel;
+
+namespace Ui {
+ class SendCoinsEntry;
+}
+
+/**
+ * A single entry in the dialog for sending bitcoins.
+ * Stacked widget, with different UIs for payment requests
+ * with a strong payee identity.
+ */
+class SendCoinsEntry : public QStackedWidget
+{
+ 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);
+ void setAddress(const QString &address);
+
+ /** Set up the tab chain manually, as Qt messes up the tab chain by default in some cases
+ * (issue https://bugreports.qt-project.org/browse/QTBUG-10907).
+ */
+ QWidget *setupTabChain(QWidget *prev);
+
+ void setFocus();
+
+public Q_SLOTS:
+ void clear();
+
+Q_SIGNALS:
+ void removeEntry(SendCoinsEntry *entry);
+ void payAmountChanged();
+ void subtractFeeFromAmountChanged();
+
+private Q_SLOTS:
+ void deleteClicked();
+ void on_payTo_textChanged(const QString &address);
+ void on_addressBookButton_clicked();
+ void on_pasteButton_clicked();
+ void updateDisplayUnit();
+
+private:
+ SendCoinsRecipient recipient;
+ Ui::SendCoinsEntry *ui;
+ WalletModel *model;
+
+ bool updateLabel(const QString &address);
+};
+
+#endif // BITCOIN_QT_SENDCOINSENTRY_H
diff --git a/src/qt/signverifymessagedialog.cpp b/src/qt/signverifymessagedialog.cpp
new file mode 100644
index 0000000000..ce166f3672
--- /dev/null
+++ b/src/qt/signverifymessagedialog.cpp
@@ -0,0 +1,283 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "signverifymessagedialog.h"
+#include "ui_signverifymessagedialog.h"
+
+#include "addressbookpage.h"
+#include "guiutil.h"
+#include "scicon.h"
+#include "walletmodel.h"
+
+#include "base58.h"
+#include "init.h"
+#include "main.h" // For strMessageMagic
+#include "wallet/wallet.h"
+
+#include <string>
+#include <vector>
+
+#include <QClipboard>
+
+SignVerifyMessageDialog::SignVerifyMessageDialog(QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::SignVerifyMessageDialog),
+ model(0)
+{
+ ui->setupUi(this);
+
+ ui->addressBookButton_SM->setIcon(SingleColorIcon(":/icons/address-book"));
+ ui->pasteButton_SM->setIcon(SingleColorIcon(":/icons/editpaste"));
+ ui->copySignatureButton_SM->setIcon(SingleColorIcon(":/icons/editcopy"));
+ ui->signMessageButton_SM->setIcon(SingleColorIcon(":/icons/edit"));
+ ui->clearButton_SM->setIcon(SingleColorIcon(":/icons/remove"));
+ ui->addressBookButton_VM->setIcon(SingleColorIcon(":/icons/address-book"));
+ ui->verifyMessageButton_VM->setIcon(SingleColorIcon(":/icons/transaction_0"));
+ ui->clearButton_VM->setIcon(SingleColorIcon(":/icons/remove"));
+
+#if QT_VERSION >= 0x040700
+ ui->signatureOut_SM->setPlaceholderText(tr("Click \"Sign Message\" to generate 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(const QString &address)
+{
+ ui->addressIn_SM->setText(address);
+ ui->messageIn_SM->setFocus();
+}
+
+void SignVerifyMessageDialog::setAddress_VM(const 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::ForSelection, 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()
+{
+ if (!model)
+ return;
+
+ /* 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->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 cancelled."));
+ 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<unsigned char> vchSig;
+ if (!key.SignCompact(Hash(ss.begin(), ss.end()), vchSig))
+ {
+ ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }");
+ ui->statusLabel_SM->setText(QString("<nobr>") + tr("Message signing failed.") + QString("</nobr>"));
+ return;
+ }
+
+ ui->statusLabel_SM->setStyleSheet("QLabel { color: green; }");
+ ui->statusLabel_SM->setText(QString("<nobr>") + tr("Message signed.") + QString("</nobr>"));
+
+ ui->signatureOut_SM->setText(QString::fromStdString(EncodeBase64(&vchSig[0], vchSig.size())));
+}
+
+void SignVerifyMessageDialog::on_copySignatureButton_SM_clicked()
+{
+ GUIUtil::setClipboard(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::ForSelection, 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->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<unsigned char> 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();
+
+ CPubKey pubkey;
+ if (!pubkey.RecoverCompact(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(pubkey.GetID()) == addr))
+ {
+ ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }");
+ ui->statusLabel_VM->setText(QString("<nobr>") + tr("Message verification failed.") + QString("</nobr>"));
+ return;
+ }
+
+ ui->statusLabel_VM->setStyleSheet("QLabel { color: green; }");
+ ui->statusLabel_VM->setText(QString("<nobr>") + tr("Message verified.") + QString("</nobr>"));
+}
+
+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 0000000000..bf841e4f8b
--- /dev/null
+++ b/src/qt/signverifymessagedialog.h
@@ -0,0 +1,51 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_SIGNVERIFYMESSAGEDIALOG_H
+#define BITCOIN_QT_SIGNVERIFYMESSAGEDIALOG_H
+
+#include <QDialog>
+
+class WalletModel;
+
+namespace Ui {
+ class SignVerifyMessageDialog;
+}
+
+class SignVerifyMessageDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit SignVerifyMessageDialog(QWidget *parent);
+ ~SignVerifyMessageDialog();
+
+ void setModel(WalletModel *model);
+ void setAddress_SM(const QString &address);
+ void setAddress_VM(const 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 Q_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 // BITCOIN_QT_SIGNVERIFYMESSAGEDIALOG_H
diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp
new file mode 100644
index 0000000000..c15b64c327
--- /dev/null
+++ b/src/qt/splashscreen.cpp
@@ -0,0 +1,202 @@
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "splashscreen.h"
+
+#include "networkstyle.h"
+
+#include "clientversion.h"
+#include "init.h"
+#include "util.h"
+#include "ui_interface.h"
+#include "version.h"
+
+#ifdef ENABLE_WALLET
+#include "wallet/wallet.h"
+#endif
+
+#include <QApplication>
+#include <QCloseEvent>
+#include <QDesktopWidget>
+#include <QPainter>
+#include <QRadialGradient>
+
+SplashScreen::SplashScreen(Qt::WindowFlags f, const NetworkStyle *networkStyle) :
+ QWidget(0, f), curAlignment(0)
+{
+ // set reference point, paddings
+ int paddingRight = 50;
+ int paddingTop = 50;
+ int titleVersionVSpace = 17;
+ int titleCopyrightVSpace = 40;
+
+ float fontFactor = 1.0;
+ float devicePixelRatio = 1.0;
+#if QT_VERSION > 0x050100
+ devicePixelRatio = ((QGuiApplication*)QCoreApplication::instance())->devicePixelRatio();
+#endif
+
+ // define text to place
+ QString titleText = tr("Bitcoin Core");
+ QString versionText = QString("Version %1").arg(QString::fromStdString(FormatFullVersion()));
+ QString copyrightText = QChar(0xA9)+QString(" 2009-%1 ").arg(COPYRIGHT_YEAR) + QString(tr("The Bitcoin Core developers"));
+ QString titleAddText = networkStyle->getTitleAddText();
+
+ QString font = QApplication::font().toString();
+
+ // create a bitmap according to device pixelratio
+ QSize splashSize(480*devicePixelRatio,320*devicePixelRatio);
+ pixmap = QPixmap(splashSize);
+
+#if QT_VERSION > 0x050100
+ // change to HiDPI if it makes sense
+ pixmap.setDevicePixelRatio(devicePixelRatio);
+#endif
+
+ QPainter pixPaint(&pixmap);
+ pixPaint.setPen(QColor(100,100,100));
+
+ // draw a slightly radial gradient
+ QRadialGradient gradient(QPoint(0,0), splashSize.width()/devicePixelRatio);
+ gradient.setColorAt(0, Qt::white);
+ gradient.setColorAt(1, QColor(247,247,247));
+ QRect rGradient(QPoint(0,0), splashSize);
+ pixPaint.fillRect(rGradient, gradient);
+
+ // draw the bitcoin icon, expected size of PNG: 1024x1024
+ QRect rectIcon(QPoint(-150,-122), QSize(430,430));
+
+ const QSize requiredSize(1024,1024);
+ QPixmap icon(networkStyle->getAppIcon().pixmap(requiredSize));
+
+ pixPaint.drawPixmap(rectIcon, icon);
+
+ // check font size and drawing with
+ pixPaint.setFont(QFont(font, 33*fontFactor));
+ QFontMetrics fm = pixPaint.fontMetrics();
+ int titleTextWidth = fm.width(titleText);
+ if(titleTextWidth > 160) {
+ // strange font rendering, Arial probably not found
+ fontFactor = 0.75;
+ }
+
+ pixPaint.setFont(QFont(font, 33*fontFactor));
+ fm = pixPaint.fontMetrics();
+ titleTextWidth = fm.width(titleText);
+ pixPaint.drawText(pixmap.width()/devicePixelRatio-titleTextWidth-paddingRight,paddingTop,titleText);
+
+ pixPaint.setFont(QFont(font, 15*fontFactor));
+
+ // if the version string is to long, reduce size
+ fm = pixPaint.fontMetrics();
+ int versionTextWidth = fm.width(versionText);
+ if(versionTextWidth > titleTextWidth+paddingRight-10) {
+ pixPaint.setFont(QFont(font, 10*fontFactor));
+ titleVersionVSpace -= 5;
+ }
+ pixPaint.drawText(pixmap.width()/devicePixelRatio-titleTextWidth-paddingRight+2,paddingTop+titleVersionVSpace,versionText);
+
+ // draw copyright stuff
+ pixPaint.setFont(QFont(font, 10*fontFactor));
+ pixPaint.drawText(pixmap.width()/devicePixelRatio-titleTextWidth-paddingRight,paddingTop+titleCopyrightVSpace,copyrightText);
+
+ // draw additional text if special network
+ if(!titleAddText.isEmpty()) {
+ QFont boldFont = QFont(font, 10*fontFactor);
+ boldFont.setWeight(QFont::Bold);
+ pixPaint.setFont(boldFont);
+ fm = pixPaint.fontMetrics();
+ int titleAddTextWidth = fm.width(titleAddText);
+ pixPaint.drawText(pixmap.width()/devicePixelRatio-titleAddTextWidth-10,15,titleAddText);
+ }
+
+ pixPaint.end();
+
+ // Set window title
+ setWindowTitle(titleText + " " + titleAddText);
+
+ // Resize window and move to center of desktop, disallow resizing
+ QRect r(QPoint(), QSize(pixmap.size().width()/devicePixelRatio,pixmap.size().height()/devicePixelRatio));
+ resize(r.size());
+ setFixedSize(r.size());
+ move(QApplication::desktop()->screenGeometry().center() - r.center());
+
+ subscribeToCoreSignals();
+}
+
+SplashScreen::~SplashScreen()
+{
+ unsubscribeFromCoreSignals();
+}
+
+void SplashScreen::slotFinish(QWidget *mainWin)
+{
+ Q_UNUSED(mainWin);
+ hide();
+}
+
+static void InitMessage(SplashScreen *splash, const std::string &message)
+{
+ QMetaObject::invokeMethod(splash, "showMessage",
+ Qt::QueuedConnection,
+ Q_ARG(QString, QString::fromStdString(message)),
+ Q_ARG(int, Qt::AlignBottom|Qt::AlignHCenter),
+ Q_ARG(QColor, QColor(55,55,55)));
+}
+
+static void ShowProgress(SplashScreen *splash, const std::string &title, int nProgress)
+{
+ InitMessage(splash, title + strprintf("%d", nProgress) + "%");
+}
+
+#ifdef ENABLE_WALLET
+static void ConnectWallet(SplashScreen *splash, CWallet* wallet)
+{
+ wallet->ShowProgress.connect(boost::bind(ShowProgress, splash, _1, _2));
+}
+#endif
+
+void SplashScreen::subscribeToCoreSignals()
+{
+ // Connect signals to client
+ uiInterface.InitMessage.connect(boost::bind(InitMessage, this, _1));
+ uiInterface.ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2));
+#ifdef ENABLE_WALLET
+ uiInterface.LoadWallet.connect(boost::bind(ConnectWallet, this, _1));
+#endif
+}
+
+void SplashScreen::unsubscribeFromCoreSignals()
+{
+ // Disconnect signals from client
+ uiInterface.InitMessage.disconnect(boost::bind(InitMessage, this, _1));
+ uiInterface.ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2));
+#ifdef ENABLE_WALLET
+ if(pwalletMain)
+ pwalletMain->ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2));
+#endif
+}
+
+void SplashScreen::showMessage(const QString &message, int alignment, const QColor &color)
+{
+ curMessage = message;
+ curAlignment = alignment;
+ curColor = color;
+ update();
+}
+
+void SplashScreen::paintEvent(QPaintEvent *event)
+{
+ QPainter painter(this);
+ painter.drawPixmap(0, 0, pixmap);
+ QRect r = rect().adjusted(5, 5, -5, -5);
+ painter.setPen(curColor);
+ painter.drawText(r, curAlignment, curMessage);
+}
+
+void SplashScreen::closeEvent(QCloseEvent *event)
+{
+ StartShutdown(); // allows an "emergency" shutdown during startup
+ event->ignore();
+}
diff --git a/src/qt/splashscreen.h b/src/qt/splashscreen.h
new file mode 100644
index 0000000000..29d16d4eae
--- /dev/null
+++ b/src/qt/splashscreen.h
@@ -0,0 +1,49 @@
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_SPLASHSCREEN_H
+#define BITCOIN_QT_SPLASHSCREEN_H
+
+#include <QSplashScreen>
+
+class NetworkStyle;
+
+/** Class for the splashscreen with information of the running client.
+ *
+ * @note this is intentionally not a QSplashScreen. Bitcoin Core initialization
+ * can take a long time, and in that case a progress window that cannot be
+ * moved around and minimized has turned out to be frustrating to the user.
+ */
+class SplashScreen : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit SplashScreen(Qt::WindowFlags f, const NetworkStyle *networkStyle);
+ ~SplashScreen();
+
+protected:
+ void paintEvent(QPaintEvent *event);
+ void closeEvent(QCloseEvent *event);
+
+public Q_SLOTS:
+ /** Slot to call finish() method as it's not defined as slot */
+ void slotFinish(QWidget *mainWin);
+
+ /** Show message and progress */
+ void showMessage(const QString &message, int alignment, const QColor &color);
+
+private:
+ /** Connect core signals to splash screen */
+ void subscribeToCoreSignals();
+ /** Disconnect core signals to splash screen */
+ void unsubscribeFromCoreSignals();
+
+ QPixmap pixmap;
+ QString curMessage;
+ QColor curColor;
+ int curAlignment;
+};
+
+#endif // BITCOIN_QT_SPLASHSCREEN_H
diff --git a/src/qt/test/Makefile b/src/qt/test/Makefile
new file mode 100644
index 0000000000..a02f86b62a
--- /dev/null
+++ b/src/qt/test/Makefile
@@ -0,0 +1,6 @@
+all:
+ $(MAKE) -C ../../ test_bitcoin_qt
+clean:
+ $(MAKE) -C ../../ test_bitcoin_qt_clean
+check:
+ $(MAKE) -C ../../ test_bitcoin_qt_check
diff --git a/src/qt/test/paymentrequestdata.h b/src/qt/test/paymentrequestdata.h
new file mode 100644
index 0000000000..c548ffe429
--- /dev/null
+++ b/src/qt/test/paymentrequestdata.h
@@ -0,0 +1,460 @@
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+//
+// Data for paymentservertests.cpp
+//
+
+// Base64/DER-encoded fake certificate authority certificates.
+// Convert pem to base64/der with:
+// openssl x509 -in cert.pem -inform PEM -outform DER | openssl enc -base64
+
+// Serial Number: 10302349811211485352 (0x8ef94c91b112c0a8)
+// Issuer: CN=PaymentRequest Test CA
+// Subject: CN=PaymentRequest Test CA
+// Not Valid After : Dec 8 16:37:24 2022 GMT
+//
+const char* caCert1_BASE64 =
+"\
+MIIB0DCCATmgAwIBAgIJAI75TJGxEsCoMA0GCSqGSIb3DQEBCwUAMCExHzAdBgNV\
+BAMTFlBheW1lbnRSZXF1ZXN0IFRlc3QgQ0EwHhcNMTIxMjEwMTYzNzI0WhcNMjIx\
+MjA4MTYzNzI0WjAhMR8wHQYDVQQDExZQYXltZW50UmVxdWVzdCBUZXN0IENBMIGf\
+MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCvua59nX9radoqDYyplcns5qdVDTN1\
+7tmcGixmMYOYU3UYMU55VSsJs0dWKnMm3COQDY+N63c0XSbRqarBcsLTkaNASuPX\
+FCv1VWuEKSyy5xe4zeoDU7CVSzlxtQD9wbZW/s3ISjgaXBpwn6eVmntb0JwYxxPc\
+M1u/hrMD8BDbSQIDAQABoxAwDjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUA\
+A4GBADSaRgK5xe47XxycXBhHhr0Wgl4pAsFsufqA9aB9r8KNEHJ0yUvvbD/jaJJM\
+RtQcf0AJ9olzUMY4syehxbzUJP6aeXhZEYiMvdvcv9D55clq6+WLLlNT3jBgAaVn\
+p3waRjPD4bUX3nv+ojz5s4puw7Qq5QUZlhGsMzPvwDGCmZkL\
+";
+
+// Serial Number: f0:da:97:e4:38:d7:64:16
+// Issuer: CN=PaymentRequest Test CA
+// Subject: CN=PaymentRequest Test CA
+// Not Valid After : Jan 8 18:21:06 2025 GMT
+//
+const char* caCert2_BASE64 =
+"\
+MIIC1TCCAb2gAwIBAgIJAPDal+Q412QWMA0GCSqGSIb3DQEBCwUAMCExHzAdBgNV\
+BAMMFlBheW1lbnRSZXF1ZXN0IFRlc3QgQ0EwHhcNMTUwMTExMTgyMTA2WhcNMjUw\
+MTA4MTgyMTA2WjAhMR8wHQYDVQQDDBZQYXltZW50UmVxdWVzdCBUZXN0IENBMIIB\
+IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1S9wVLfTplJuT/1OaaBgl/Mb\
+I392v8S9kHbzYz7B4OTMslaO7piz0v3SO3TKMh0dswjiRdHrIgpO7XdIUQiU/ugg\
+xDw0kuNehfz1ycaGedlFFtFHTNXqLyIUF3dlwHhQwaomM6RXoJmxLny5BhYHEcmk\
+yWwr3Cdjd9gAZpblugVJB9C1e40uyL8ao4PHdLzOqO27iSe6riP8SwwisJZEbMaz\
+AZpgNEEMbIXPJEFvm5HTRXSMtQCOTSZYMFF0M2yrtmlECnz7hWP19b9bcoDzZQB4\
+ylIsFG/7q2jV7MC/e2STZv+niJiHL08RUdoFpAgzaxMgqj63C7B55HgNDNHJYQID\
+AQABoxAwDjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBGejPxLxj9\
++crv6gUeEBMZPiUx7pUgcI22Wm5yymP96B4fwI3Y0DBehq20d76vbWGPN17Z6pH3\
+ge7PVY1SYqXtS6hXTo4olCm/BZADli+2Bs2xCiaa+Ltve4ufVej+bKJXN/YnrhvO\
+Kq+klQkuuHywU+GJV/NQeBqToIrSOBgi477NgLFCCCmmx2QWsxHoCFGfuRCBVseT\
+z2k/tMuALCDXGeZBRPTsGHu1y4cj84swAeoDK5QSQcI+Ub7GKc+zkoj02sdDLiMo\
+3wokYPcIy47oclhmb4xubHc+y7nF610yZBoC/zgbhbawnZ65hDDWkdQ/SVAnWZD7\
+9PFfmNnYPTQH\
+";
+
+//
+// This payment request validates directly against the
+// caCert1 certificate authority.
+//
+const char* paymentrequest1_cert1_BASE64 =
+"\
+Egt4NTA5K3NoYTI1NhrxAwruAzCCAeowggFToAMCAQICAQEwDQYJKoZIhvcNAQEL\
+BQAwITEfMB0GA1UEAxMWUGF5bWVudFJlcXVlc3QgVGVzdCBDQTAeFw0xMjEyMTAx\
+NjM3MjRaFw0yMjEyMDgxNjM3MjRaMEMxGTAXBgNVBAMMEHRlc3RtZXJjaGFudC5v\
+cmcxJjAkBgNVBAoMHVBheW1lbnQgUmVxdWVzdCBUZXN0IE1lcmNoYW50MIGfMA0G\
+CSqGSIb3DQEBAQUAA4GNADCBiQKBgQDHkMy8W1u6HsWlSqdWTmMKf54gICxNfxbY\
++rcMtAftr62hCYx2d2QiSRd1pCUzmo12IiSX3WxSHwaTnT3MFD6jRx6+zM6XdGar\
+I2zpYle11ANzu4gAthN17uRQHV2O5QxVtzNaMdKeJLXT2L9tfEdyL++9ZUqoQmdA\
+YG9ix330hQIDAQABoxAwDjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4GB\
+AIkyO99KC68bi9PFRyQQ7nvn5GlQEb3Ca1bRG5+AKN9N5vc8rZ9G2hejtM8wEXni\
+eGBP+chVMsbTPEHKLrwREn7IvcyCcbAStaklPC3w0B/2idQSHskb6P3X13OR2bTH\
+a2+6wuhsOZRUrVNr24rM95DKx/eCC6JN1VW+qRPU6fqzIjQSHwiw2wYSGXapFJVg\
+igPI+6XpExtNLO/i1WFV8ZmoiKwYsuHFiwUqC1VuaXRUZXN0T25lKoABS0j59iMU\
+Uc9MdIfwsO1BskIET0eJSGNZ7eXb9N62u+qf831PMpEHkmlGpk8rHy92nPcgua/U\
+Yt8oZMn3QaTZ5A6HjJbc3A73eLylp1a0SwCl+KDMEvDQhqMn1jAVu2v92AH3uB7n\
+SiWVbw0tX/68iSQEGGfh9n6ee/8Myb3ICdw=\
+";
+
+//
+// Signed, but expired, merchant cert in the request
+//
+const char* paymentrequest2_cert1_BASE64 =
+"\
+Egt4NTA5K3NoYTI1NhrsAwrpAzCCAeUwggFOoAMCAQICAQMwDQYJKoZIhvcNAQEL\
+BQAwITEfMB0GA1UEAxMWUGF5bWVudFJlcXVlc3QgVGVzdCBDQTAeFw0xMzAyMjMy\
+MTI2NDNaFw0xMzAyMjQyMTI2NDNaMD4xHDAaBgNVBAMME2V4cGlyZWRtZXJjaGFu\
+dC5vcmcxHjAcBgNVBAoMFUV4cGlyZWQgVGVzdCBNZXJjaGFudDCBnzANBgkqhkiG\
+9w0BAQEFAAOBjQAwgYkCgYEAx5DMvFtbuh7FpUqnVk5jCn+eICAsTX8W2Pq3DLQH\
+7a+toQmMdndkIkkXdaQlM5qNdiIkl91sUh8Gk509zBQ+o0cevszOl3RmqyNs6WJX\
+tdQDc7uIALYTde7kUB1djuUMVbczWjHSniS109i/bXxHci/vvWVKqEJnQGBvYsd9\
+9IUCAwEAAaMQMA4wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOBgQAaU137\
+j53rvSjlmYZpZ4RWTP7EdD6fl5ZxBeXHytN6DQL33H0eD7OFHt+ofc7E6D7keubl\
+UfCu+jOvt/MvvPUmtCI9yXZ0dNC4sjyETv+wQpxO0UNZwOM4uegdCzlo6Bi3pD4/\
+KKLdMkWuUfuPBmoammny74lZaOVr5deKXztTuCI0Eh8IsNsGEhl2qRSVYIoDyPul\
+6RMbTSzv4tVhVfGZqIisGLLhxYsFKgtVbml0VGVzdFR3byqAAXHuo4nZEPniLpkd\
+y30TkwBxVgprWJ18a9z/7Py35Qss/JMbOXbnBhJtmJCdIowHRI0aa+zqt3KKKAXi\
+mm+V4seMgxTcxMS+eDDkiTcB/RtWWSyRcS2ANjFeY0T4SLMwiCL9qWPi03hr8j96\
+tejrSPOBNSJ3Mi/q5u2Yl4gJZY2b\
+";
+
+//
+// 10-long certificate chain, all intermediates valid
+//
+const char* paymentrequest3_cert1_BASE64 =
+"\
+Egt4NTA5K3NoYTI1Nhq8JAr/AzCCAfswggFkoAMCAQICAQEwDQYJKoZIhvcNAQEL\
+BQAwPzEUMBIGA1UEAwwLdGVzdGNhOC5vcmcxJzAlBgNVBAoMHlBheW1lbnQgUmVx\
+dWVzdCBJbnRlcm1lZGlhdGUgODAeFw0xMzAyMjMyMjQyMzFaFw0yMzAyMjEyMjQy\
+MzFaMDYxGjAYBgNVBAMMEXRlc3RtZXJjaGFudDgub3JnMRgwFgYDVQQKDA9UZXN0\
+IE1lcmNoYW50IDgwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMMCHA3hiHbS\
+TKZ5K9jHRwE8NxkGp3IOx56PDB2diNkldG8XweTcRq7bBm7pdiBt4IVggtfs+6hE\
+hDYIOecyoAnVzPFTdvQ7KQdQ/fD9YLe6lk+o0edOqutPMyrxLFjSluXxEQyk7fdt\
+URloMMYfp3p1/hFCboA1rAsQ2RW38hR5AgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8w\
+DQYJKoZIhvcNAQELBQADgYEAPsdFatnc2RJSpvZsw+nCiPVsllycw5ELglq9vfJz\
+nJJucRxgzmqI2iuas1ugwbXn0BEIRLK7vMF/qBzQR6M/nTxttah+KEu+okjps9vJ\
+cIyhfTyGPC5xkHaHZ7sG+UHOFhPw0/kXn0x+pbVgBZ5315axqcp1R+DTSj/whMAr\
+n0AKiAQwggIEMIIBbaADAgECAgECMA0GCSqGSIb3DQEBCwUAMD8xFDASBgNVBAMM\
+C3Rlc3RjYTcub3JnMScwJQYDVQQKDB5QYXltZW50IFJlcXVlc3QgSW50ZXJtZWRp\
+YXRlIDcwHhcNMTMwMjIzMjI0MjMxWhcNMjMwMjIxMjI0MjMxWjA/MRQwEgYDVQQD\
+DAt0ZXN0Y2E4Lm9yZzEnMCUGA1UECgweUGF5bWVudCBSZXF1ZXN0IEludGVybWVk\
+aWF0ZSA4MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDexUFfxb1sThvabp7u\
+dZz59ciThGmmAW0nP4tjrgEACgvWIInr2dZpTHbiQNF34ycsk0le1JD93D7Qb8rd\
+25OrpaO8XS2Li2zjR9cleixXjSLwV/zv8zJ8yPl/27XL++PDTKBXVpJ8/Syp+9Ty\
+plV1BqDhqtIHb/QSHEkTQXjeYQIDAQABoxAwDjAMBgNVHRMEBTADAQH/MA0GCSqG\
+SIb3DQEBCwUAA4GBACMooQVbkbIZ2DaPwHDc4ULwguG3VI2Kzj50UdExmHtzm2S4\
+MQei+n+HEPjtJAx5OY520+10nfuP+12H2DRLQmWmdvDpeQ/Cv0yavlw4ZRejRFo7\
+KS83C0wo5rd+qTvvOmAN4UTArWkzYcEUulPdiXnRamb0WQHTeVdIbHVkMormCogE\
+MIICBDCCAW2gAwIBAgIBAjANBgkqhkiG9w0BAQsFADA/MRQwEgYDVQQDDAt0ZXN0\
+Y2E2Lm9yZzEnMCUGA1UECgweUGF5bWVudCBSZXF1ZXN0IEludGVybWVkaWF0ZSA2\
+MB4XDTEzMDIyMzIyNDIzMVoXDTIzMDIyMTIyNDIzMVowPzEUMBIGA1UEAwwLdGVz\
+dGNhNy5vcmcxJzAlBgNVBAoMHlBheW1lbnQgUmVxdWVzdCBJbnRlcm1lZGlhdGUg\
+NzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAtjBRazrkebXAhXsbjimrMIRm\
+W/f9SwAHwXfc042keNtl0t2z6XE6UPcR2v/KrssXuCZgodeYxz6IM6lWosCM1xot\
+C3ChKKFBfVO30reuKBRUxXfKAFqxaG0YOAEzdZkkY9AGhqWloeSmgxpIfhInU0EF\
+JjCwrJ6IkijBatGoAAECAwEAAaMQMA4wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0B\
+AQsFAAOBgQDBRTi1MolmOA0niHYX0A2lN5QWHkCfX0A7GwyoMA3dvM45m/NYd4WB\
+X+HwfnfYcI6X9jOgNo5OWmc4GGsld0HlxwMYEKISBS9PbSHPBrb3TBOlw5ztQpXZ\
+91+bOhLux52Fr03sK7v9qExmBM12M8UR2ltpzAMiUgLLMHyPfiWkvQqIBDCCAgQw\
+ggFtoAMCAQICAQIwDQYJKoZIhvcNAQELBQAwPzEUMBIGA1UEAwwLdGVzdGNhNS5v\
+cmcxJzAlBgNVBAoMHlBheW1lbnQgUmVxdWVzdCBJbnRlcm1lZGlhdGUgNTAeFw0x\
+MzAyMjMyMjQyMzBaFw0yMzAyMjEyMjQyMzBaMD8xFDASBgNVBAMMC3Rlc3RjYTYu\
+b3JnMScwJQYDVQQKDB5QYXltZW50IFJlcXVlc3QgSW50ZXJtZWRpYXRlIDYwgZ8w\
+DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANJSH3xivX1t9olIdHsznI1aE9SD7t9i\
+SZJsIB0otoETHZRVv9M9LvyzBNK98ZV+kTOlST7PJgC0d9BQM9sgYApSRq5oqKDM\
+9FXbOm/yaReAbU3mkFNFw5roTlJ5ThEy0yOGT/DS0YBRaGIvRPRj2DiqDVdCZZ+w\
+4jo1IYHkZt4FAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQAD\
+gYEATm6+J1OmbrothO60xALKonWMBKr6hudb4amkFBqKbA9wMeM3jl+I/yKfz/Uf\
+xWuJ071IhiNv6Gxx5YwNvhUe1xMhUqHv0gpyK1Z47bD+kYS2se5sWNPNo3Y9qZDG\
+IXiGQxwHmrzaFk79Uy1xsmvsEz42w6hr25Yaw7HkIgrFveoKiAQwggIEMIIBbaAD\
+AgECAgECMA0GCSqGSIb3DQEBCwUAMD8xFDASBgNVBAMMC3Rlc3RjYTQub3JnMScw\
+JQYDVQQKDB5QYXltZW50IFJlcXVlc3QgSW50ZXJtZWRpYXRlIDQwHhcNMTMwMjIz\
+MjI0MjMwWhcNMjMwMjIxMjI0MjMwWjA/MRQwEgYDVQQDDAt0ZXN0Y2E1Lm9yZzEn\
+MCUGA1UECgweUGF5bWVudCBSZXF1ZXN0IEludGVybWVkaWF0ZSA1MIGfMA0GCSqG\
+SIb3DQEBAQUAA4GNADCBiQKBgQC7vVUFpxHzz2Tr/xij3k58s8d/BPA0R6D5RXTV\
+vmhAzc1Zuin4zUKRFs/aCj/0yED8Wu/COfNGF4tVlRNMdl9EcFsxa8XGEL4eAZa+\
+H/rOHH+7/1EINrrVWhZlUecyhilN8jmCZmqEM3ecuD0NAViqyMrgmaiFmsLoQZpE\
+GepDUQIDAQABoxAwDjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4GBAEdJ\
+Ss8jWiooja3WZzHXeF95QkBJNjIlpDLGcpl4opOYLSuEl9Uxp//LaQQiXuzpj4/I\
+pkWGQmMy5HOyH1lqDyiMgXpcG8PE0jEQAoEUGZ0QEqB1mZ6BCrYvmUuf/5aSVd8Y\
+6lKMR3WzFDYU9Zy0nzuHB/3nvp6MeDRQeRMtYvz4CogEMIICBDCCAW2gAwIBAgIB\
+AjANBgkqhkiG9w0BAQsFADA/MRQwEgYDVQQDDAt0ZXN0Y2EzLm9yZzEnMCUGA1UE\
+CgweUGF5bWVudCBSZXF1ZXN0IEludGVybWVkaWF0ZSAzMB4XDTEzMDIyMzIyNDIy\
+OVoXDTIzMDIyMTIyNDIyOVowPzEUMBIGA1UEAwwLdGVzdGNhNC5vcmcxJzAlBgNV\
+BAoMHlBheW1lbnQgUmVxdWVzdCBJbnRlcm1lZGlhdGUgNDCBnzANBgkqhkiG9w0B\
+AQEFAAOBjQAwgYkCgYEAxYYo3w2UXiYg6O8b4QgwN/vgreTkiW122Ep/z2TiDrhV\
+MhfOOiKdwYESPflfnXnVaQQzCGexYTQqsvqvzHSyna5hL0zPTRJxSKmTVrXRsWtp\
+dCRhjxCGipS3tlQBDi7vb+7SNRIBK4dBjjGzALNk7gMCpy+yM8f6I043jTlmGb0C\
+AwEAAaMQMA4wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOBgQDU+IQxt3Oh\
+KqaUYWC23+cB2gekvWqwMBnrCNrX/Dp+kjoJKUoR2Fs3qw53raHES4SIhpGT9l9l\
+rppNQgFe/JMHeYqOZMZO+6kuU0olJanBJ14tPIc7zlMTQ9OfmZ6v07IpyFbsQDtR\
+hpe80DpuvSFPfJ4fh0WrQf6kn3KDVpGDnAqIBDCCAgQwggFtoAMCAQICAQIwDQYJ\
+KoZIhvcNAQELBQAwPzEUMBIGA1UEAwwLdGVzdGNhMi5vcmcxJzAlBgNVBAoMHlBh\
+eW1lbnQgUmVxdWVzdCBJbnRlcm1lZGlhdGUgMjAeFw0xMzAyMjMyMjQyMjlaFw0y\
+MzAyMjEyMjQyMjlaMD8xFDASBgNVBAMMC3Rlc3RjYTMub3JnMScwJQYDVQQKDB5Q\
+YXltZW50IFJlcXVlc3QgSW50ZXJtZWRpYXRlIDMwgZ8wDQYJKoZIhvcNAQEBBQAD\
+gY0AMIGJAoGBANzgVP99Qg98e6NsKEz1v5KqRB7NTBRRsYnBvb/TSWipvMQaCYuE\
+yk1xG57x++QuASKeR3QHRQJOoAhQaj9JLUhSSv9GQ5PrFLLsOFv7L1tpzXHh2dOB\
+IW92X2yFRW2s39q+Q21yvN+N8uoKdqXhzRA+dDoXh3cavaVeHX1G+IrlAgMBAAGj\
+EDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADgYEASTwg84cX+1UhOG9s\
+ejFV3m34QuI1hPZ+qhqVJlRYUtego8Wng1BburDSwqVAv4ch2wi3c2s4e8J7AXyL\
+tzSbSQG4RN0oZi0mR8EtTTN+Mix/hBIk79dMZg85+I29uFA6Zj2d9oAhQv2qkHhc\
+6tcaheNvkQRlCyH68k3iF1Fqf+4KiAQwggIEMIIBbaADAgECAgECMA0GCSqGSIb3\
+DQEBCwUAMD8xFDASBgNVBAMMC3Rlc3RjYTEub3JnMScwJQYDVQQKDB5QYXltZW50\
+IFJlcXVlc3QgSW50ZXJtZWRpYXRlIDEwHhcNMTMwMjIzMjI0MjI5WhcNMjMwMjIx\
+MjI0MjI5WjA/MRQwEgYDVQQDDAt0ZXN0Y2EyLm9yZzEnMCUGA1UECgweUGF5bWVu\
+dCBSZXF1ZXN0IEludGVybWVkaWF0ZSAyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB\
+iQKBgQDaV8zhfyQuSf/f+fauMfgs3g/RnWy9yxxUkvQneQQPH3uZzCyk3A6q72ip\
+TtwNqiibG9455L9A7SaUjGtnpUz0NKT/VWUdqbfCl1PqXjEZbDobbAQ5hxLGOTyL\
+RQhLIcgeq2/BnmeCqHsC4md04nUp+nBo1HwKyygvK+9sMbCp/wIDAQABoxAwDjAM\
+BgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4GBACvYyE+PPmWFkbjyRu9LAt8D\
+crtyYYLRClKSg6tVvutwukLG2l//kDOohYkJtgTqr6LnCIIIwYdXN+4wxugmw4cn\
+PIZmP6kovxjhhVM95okilor1zniTAo3RN7JDIfTGNgxLdGu1btt7DOFL4zTbeSJM\
+b8M1JpPftehH+x/VLyuUCuoDMIIB5jCCAU+gAwIBAgIBBTANBgkqhkiG9w0BAQsF\
+ADAhMR8wHQYDVQQDExZQYXltZW50UmVxdWVzdCBUZXN0IENBMB4XDTEzMDIyMzIy\
+NDIyOFoXDTIzMDIyMTIyNDIyOFowPzEUMBIGA1UEAwwLdGVzdGNhMS5vcmcxJzAl\
+BgNVBAoMHlBheW1lbnQgUmVxdWVzdCBJbnRlcm1lZGlhdGUgMTCBnzANBgkqhkiG\
+9w0BAQEFAAOBjQAwgYkCgYEAo5Vy9H3nA/OOkF5Ap89yfVNSiTay/LYCaB0eALpc\
+U690U75O9Q3w2M+2AN8wpbbHsJHZMIjEeBRoQfjlYXW1ucQTxWKyT+liu0D25mGX\
+X27CBXBd4iXTxVII/iX+u3lcjORjoHOBy7QgeIDIIS9y0vYu8eArpjh7m4thrVgI\
+RtMCAwEAAaMQMA4wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOBgQB9LKcV\
+JK9sjASNzpQlpUp7nCiw5FSjVY+XMRIKK/kavzlKjZ+InsmmyRVGjDoZi9GrqG9P\
+VHgLBxi2VtVjmokZoNPqao3OfhqORAubC+JR/JLepM7aDaxDdTHVhSUk4lgNAvi2\
+6dGY7nZMsnHlPQ2tPp/HvRRiMq1oDjlylc8VTCI2Eh8IsNsGEhl2qRSVYIoDyPul\
+6RMbTSzv4tVhVfGZqIisGLLhxYsFKg1Vbml0VGVzdFRocmVlKoABn2HTsUQtMNI4\
+yNvkfkFNka3pRvTUTydJrvyfmEeLzImfM1BWddZjnywku9RToNFZZNgow5QnljmF\
+chhR/aHOuEMTxmc12K4rNlgYtHCsxLP9zd+6u0cva3TucZ6EzS8PKEib/+r12/52\
+664NuWA9WtsK7QCFrK2K95PnVCRmWl0=\
+";
+
+//
+// Long certificate chain, with an expired certificate in the middle
+//
+const char* paymentrequest4_cert1_BASE64 =
+"\
+Egt4NTA5K3NoYTI1NhqeJAr/AzCCAfswggFkoAMCAQICAQEwDQYJKoZIhvcNAQEL\
+BQAwPzEUMBIGA1UEAwwLdGVzdGNhOC5vcmcxJzAlBgNVBAoMHlBheW1lbnQgUmVx\
+dWVzdCBJbnRlcm1lZGlhdGUgODAeFw0xMzAyMjMyMjQyMzFaFw0yMzAyMjEyMjQy\
+MzFaMDYxGjAYBgNVBAMMEXRlc3RtZXJjaGFudDgub3JnMRgwFgYDVQQKDA9UZXN0\
+IE1lcmNoYW50IDgwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMMCHA3hiHbS\
+TKZ5K9jHRwE8NxkGp3IOx56PDB2diNkldG8XweTcRq7bBm7pdiBt4IVggtfs+6hE\
+hDYIOecyoAnVzPFTdvQ7KQdQ/fD9YLe6lk+o0edOqutPMyrxLFjSluXxEQyk7fdt\
+URloMMYfp3p1/hFCboA1rAsQ2RW38hR5AgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8w\
+DQYJKoZIhvcNAQELBQADgYEAPsdFatnc2RJSpvZsw+nCiPVsllycw5ELglq9vfJz\
+nJJucRxgzmqI2iuas1ugwbXn0BEIRLK7vMF/qBzQR6M/nTxttah+KEu+okjps9vJ\
+cIyhfTyGPC5xkHaHZ7sG+UHOFhPw0/kXn0x+pbVgBZ5315axqcp1R+DTSj/whMAr\
+n0AKiAQwggIEMIIBbaADAgECAgECMA0GCSqGSIb3DQEBCwUAMD8xFDASBgNVBAMM\
+C3Rlc3RjYTcub3JnMScwJQYDVQQKDB5QYXltZW50IFJlcXVlc3QgSW50ZXJtZWRp\
+YXRlIDcwHhcNMTMwMjIzMjI0MjMxWhcNMjMwMjIxMjI0MjMxWjA/MRQwEgYDVQQD\
+DAt0ZXN0Y2E4Lm9yZzEnMCUGA1UECgweUGF5bWVudCBSZXF1ZXN0IEludGVybWVk\
+aWF0ZSA4MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDexUFfxb1sThvabp7u\
+dZz59ciThGmmAW0nP4tjrgEACgvWIInr2dZpTHbiQNF34ycsk0le1JD93D7Qb8rd\
+25OrpaO8XS2Li2zjR9cleixXjSLwV/zv8zJ8yPl/27XL++PDTKBXVpJ8/Syp+9Ty\
+plV1BqDhqtIHb/QSHEkTQXjeYQIDAQABoxAwDjAMBgNVHRMEBTADAQH/MA0GCSqG\
+SIb3DQEBCwUAA4GBACMooQVbkbIZ2DaPwHDc4ULwguG3VI2Kzj50UdExmHtzm2S4\
+MQei+n+HEPjtJAx5OY520+10nfuP+12H2DRLQmWmdvDpeQ/Cv0yavlw4ZRejRFo7\
+KS83C0wo5rd+qTvvOmAN4UTArWkzYcEUulPdiXnRamb0WQHTeVdIbHVkMormCogE\
+MIICBDCCAW2gAwIBAgIBAjANBgkqhkiG9w0BAQsFADA/MRQwEgYDVQQDDAt0ZXN0\
+Y2E2Lm9yZzEnMCUGA1UECgweUGF5bWVudCBSZXF1ZXN0IEludGVybWVkaWF0ZSA2\
+MB4XDTEzMDIyMzIyNDIzMVoXDTIzMDIyMTIyNDIzMVowPzEUMBIGA1UEAwwLdGVz\
+dGNhNy5vcmcxJzAlBgNVBAoMHlBheW1lbnQgUmVxdWVzdCBJbnRlcm1lZGlhdGUg\
+NzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAtjBRazrkebXAhXsbjimrMIRm\
+W/f9SwAHwXfc042keNtl0t2z6XE6UPcR2v/KrssXuCZgodeYxz6IM6lWosCM1xot\
+C3ChKKFBfVO30reuKBRUxXfKAFqxaG0YOAEzdZkkY9AGhqWloeSmgxpIfhInU0EF\
+JjCwrJ6IkijBatGoAAECAwEAAaMQMA4wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0B\
+AQsFAAOBgQDBRTi1MolmOA0niHYX0A2lN5QWHkCfX0A7GwyoMA3dvM45m/NYd4WB\
+X+HwfnfYcI6X9jOgNo5OWmc4GGsld0HlxwMYEKISBS9PbSHPBrb3TBOlw5ztQpXZ\
+91+bOhLux52Fr03sK7v9qExmBM12M8UR2ltpzAMiUgLLMHyPfiWkvQqIBDCCAgQw\
+ggFtoAMCAQICAQIwDQYJKoZIhvcNAQELBQAwPzEUMBIGA1UEAwwLdGVzdGNhNS5v\
+cmcxJzAlBgNVBAoMHlBheW1lbnQgUmVxdWVzdCBJbnRlcm1lZGlhdGUgNTAeFw0x\
+MzAyMjMyMjQyMzBaFw0yMzAyMjEyMjQyMzBaMD8xFDASBgNVBAMMC3Rlc3RjYTYu\
+b3JnMScwJQYDVQQKDB5QYXltZW50IFJlcXVlc3QgSW50ZXJtZWRpYXRlIDYwgZ8w\
+DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANJSH3xivX1t9olIdHsznI1aE9SD7t9i\
+SZJsIB0otoETHZRVv9M9LvyzBNK98ZV+kTOlST7PJgC0d9BQM9sgYApSRq5oqKDM\
+9FXbOm/yaReAbU3mkFNFw5roTlJ5ThEy0yOGT/DS0YBRaGIvRPRj2DiqDVdCZZ+w\
+4jo1IYHkZt4FAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQAD\
+gYEATm6+J1OmbrothO60xALKonWMBKr6hudb4amkFBqKbA9wMeM3jl+I/yKfz/Uf\
+xWuJ071IhiNv6Gxx5YwNvhUe1xMhUqHv0gpyK1Z47bD+kYS2se5sWNPNo3Y9qZDG\
+IXiGQxwHmrzaFk79Uy1xsmvsEz42w6hr25Yaw7HkIgrFveoK6gMwggHmMIIBT6AD\
+AgECAgEGMA0GCSqGSIb3DQEBCwUAMCExHzAdBgNVBAMTFlBheW1lbnRSZXF1ZXN0\
+IFRlc3QgQ0EwHhcNMTMwMjIzMjI1OTUxWhcNMTMwMjI0MjI1OTUxWjA/MRQwEgYD\
+VQQDDAt0ZXN0Y2E1Lm9yZzEnMCUGA1UECgweUGF5bWVudCBSZXF1ZXN0IEludGVy\
+bWVkaWF0ZSA1MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7vVUFpxHzz2Tr\
+/xij3k58s8d/BPA0R6D5RXTVvmhAzc1Zuin4zUKRFs/aCj/0yED8Wu/COfNGF4tV\
+lRNMdl9EcFsxa8XGEL4eAZa+H/rOHH+7/1EINrrVWhZlUecyhilN8jmCZmqEM3ec\
+uD0NAViqyMrgmaiFmsLoQZpEGepDUQIDAQABoxAwDjAMBgNVHRMEBTADAQH/MA0G\
+CSqGSIb3DQEBCwUAA4GBAEmcUEnhua/oiXy1fwScLgMqt+jk9mHRpE6SVsIop23Q\
+CY2JfpG6RxhMMzzzhGklEGN6cxG0HCi6B3HJx6PYrFEfTB0rW4K6m0Tvx3WpS9mN\
+uoEuJHLy18ausI/sYAPDHCL+SfBVcqorpaIG2sSpZouRBjRHAyqFAYlwlW87uq5n\
+CogEMIICBDCCAW2gAwIBAgIBAjANBgkqhkiG9w0BAQsFADA/MRQwEgYDVQQDDAt0\
+ZXN0Y2EzLm9yZzEnMCUGA1UECgweUGF5bWVudCBSZXF1ZXN0IEludGVybWVkaWF0\
+ZSAzMB4XDTEzMDIyMzIyNDIyOVoXDTIzMDIyMTIyNDIyOVowPzEUMBIGA1UEAwwL\
+dGVzdGNhNC5vcmcxJzAlBgNVBAoMHlBheW1lbnQgUmVxdWVzdCBJbnRlcm1lZGlh\
+dGUgNDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAxYYo3w2UXiYg6O8b4Qgw\
+N/vgreTkiW122Ep/z2TiDrhVMhfOOiKdwYESPflfnXnVaQQzCGexYTQqsvqvzHSy\
+na5hL0zPTRJxSKmTVrXRsWtpdCRhjxCGipS3tlQBDi7vb+7SNRIBK4dBjjGzALNk\
+7gMCpy+yM8f6I043jTlmGb0CAwEAAaMQMA4wDAYDVR0TBAUwAwEB/zANBgkqhkiG\
+9w0BAQsFAAOBgQDU+IQxt3OhKqaUYWC23+cB2gekvWqwMBnrCNrX/Dp+kjoJKUoR\
+2Fs3qw53raHES4SIhpGT9l9lrppNQgFe/JMHeYqOZMZO+6kuU0olJanBJ14tPIc7\
+zlMTQ9OfmZ6v07IpyFbsQDtRhpe80DpuvSFPfJ4fh0WrQf6kn3KDVpGDnAqIBDCC\
+AgQwggFtoAMCAQICAQIwDQYJKoZIhvcNAQELBQAwPzEUMBIGA1UEAwwLdGVzdGNh\
+Mi5vcmcxJzAlBgNVBAoMHlBheW1lbnQgUmVxdWVzdCBJbnRlcm1lZGlhdGUgMjAe\
+Fw0xMzAyMjMyMjQyMjlaFw0yMzAyMjEyMjQyMjlaMD8xFDASBgNVBAMMC3Rlc3Rj\
+YTMub3JnMScwJQYDVQQKDB5QYXltZW50IFJlcXVlc3QgSW50ZXJtZWRpYXRlIDMw\
+gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANzgVP99Qg98e6NsKEz1v5KqRB7N\
+TBRRsYnBvb/TSWipvMQaCYuEyk1xG57x++QuASKeR3QHRQJOoAhQaj9JLUhSSv9G\
+Q5PrFLLsOFv7L1tpzXHh2dOBIW92X2yFRW2s39q+Q21yvN+N8uoKdqXhzRA+dDoX\
+h3cavaVeHX1G+IrlAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEL\
+BQADgYEASTwg84cX+1UhOG9sejFV3m34QuI1hPZ+qhqVJlRYUtego8Wng1BburDS\
+wqVAv4ch2wi3c2s4e8J7AXyLtzSbSQG4RN0oZi0mR8EtTTN+Mix/hBIk79dMZg85\
++I29uFA6Zj2d9oAhQv2qkHhc6tcaheNvkQRlCyH68k3iF1Fqf+4KiAQwggIEMIIB\
+baADAgECAgECMA0GCSqGSIb3DQEBCwUAMD8xFDASBgNVBAMMC3Rlc3RjYTEub3Jn\
+MScwJQYDVQQKDB5QYXltZW50IFJlcXVlc3QgSW50ZXJtZWRpYXRlIDEwHhcNMTMw\
+MjIzMjI0MjI5WhcNMjMwMjIxMjI0MjI5WjA/MRQwEgYDVQQDDAt0ZXN0Y2EyLm9y\
+ZzEnMCUGA1UECgweUGF5bWVudCBSZXF1ZXN0IEludGVybWVkaWF0ZSAyMIGfMA0G\
+CSqGSIb3DQEBAQUAA4GNADCBiQKBgQDaV8zhfyQuSf/f+fauMfgs3g/RnWy9yxxU\
+kvQneQQPH3uZzCyk3A6q72ipTtwNqiibG9455L9A7SaUjGtnpUz0NKT/VWUdqbfC\
+l1PqXjEZbDobbAQ5hxLGOTyLRQhLIcgeq2/BnmeCqHsC4md04nUp+nBo1HwKyygv\
+K+9sMbCp/wIDAQABoxAwDjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4GB\
+ACvYyE+PPmWFkbjyRu9LAt8DcrtyYYLRClKSg6tVvutwukLG2l//kDOohYkJtgTq\
+r6LnCIIIwYdXN+4wxugmw4cnPIZmP6kovxjhhVM95okilor1zniTAo3RN7JDIfTG\
+NgxLdGu1btt7DOFL4zTbeSJMb8M1JpPftehH+x/VLyuUCuoDMIIB5jCCAU+gAwIB\
+AgIBBTANBgkqhkiG9w0BAQsFADAhMR8wHQYDVQQDExZQYXltZW50UmVxdWVzdCBU\
+ZXN0IENBMB4XDTEzMDIyMzIyNDIyOFoXDTIzMDIyMTIyNDIyOFowPzEUMBIGA1UE\
+AwwLdGVzdGNhMS5vcmcxJzAlBgNVBAoMHlBheW1lbnQgUmVxdWVzdCBJbnRlcm1l\
+ZGlhdGUgMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAo5Vy9H3nA/OOkF5A\
+p89yfVNSiTay/LYCaB0eALpcU690U75O9Q3w2M+2AN8wpbbHsJHZMIjEeBRoQfjl\
+YXW1ucQTxWKyT+liu0D25mGXX27CBXBd4iXTxVII/iX+u3lcjORjoHOBy7QgeIDI\
+IS9y0vYu8eArpjh7m4thrVgIRtMCAwEAAaMQMA4wDAYDVR0TBAUwAwEB/zANBgkq\
+hkiG9w0BAQsFAAOBgQB9LKcVJK9sjASNzpQlpUp7nCiw5FSjVY+XMRIKK/kavzlK\
+jZ+InsmmyRVGjDoZi9GrqG9PVHgLBxi2VtVjmokZoNPqao3OfhqORAubC+JR/JLe\
+pM7aDaxDdTHVhSUk4lgNAvi26dGY7nZMsnHlPQ2tPp/HvRRiMq1oDjlylc8VTCI1\
+Eh8IsNsGEhl2qRSVYIoDyPul6RMbTSzv4tVhVfGZqIisGLLhxYsFKgxVbml0VGVz\
+dEZvdXIqgAEBE1PP93Tkpif35F+dYmXn9kLA/1djcPjCs2o2rwRMM4Uk356O5dgu\
+HXQjsfdR58qZQS9CS5DAtRUf0R8+43/wijO/hb49VNaNXmY+/cPHMkahP2aV3tZi\
+FAyZblLik9A7ZvF+UsjeFQiHB5wzWQvbqk5wQ4yabHIXoYv/E0q+eQ==\
+";
+
+//
+// Validly signed, but by a CA not in our root CA list
+//
+const char* paymentrequest5_cert1_BASE64 =
+"\
+Egt4NTA5K3NoYTI1NhrxAwruAzCCAeowggFToAMCAQICAQEwDQYJKoZIhvcNAQEL\
+BQAwITEfMB0GA1UEAxMWUGF5bWVudFJlcXVlc3QgVGVzdCBDQTAeFw0xMzA0MTkx\
+NzIwMDZaFw0yMzA0MTcxNzIwMDZaMEMxGTAXBgNVBAMMEHRlc3RtZXJjaGFudC5v\
+cmcxJjAkBgNVBAoMHVBheW1lbnQgUmVxdWVzdCBUZXN0IE1lcmNoYW50MIGfMA0G\
+CSqGSIb3DQEBAQUAA4GNADCBiQKBgQDhV6Yn47aEEmbl50YLvXoqGEJA51I/40wr\
+Z6VQGdXYaRqYktagrWDlgYY9h0JQ1bQhm8HgW7ju0R4NaDTXUqxg4HjprF0z3Mfm\
+/6mmebkLOOptfkVD7ceAteNI7cyuqWGIAZA7D9mV97mXoCAtTlBUycvkmoiClCCS\
+h0EpF/UTaQIDAQABoxAwDjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4GB\
+AGIRwW7I0QvLga+RnJoJSZNZQbtu4rQW3xmoz8WfZMBYXX3QBYg5ftycbdK+/IbP\
+qozfjGW2AS6DNArvpveSPDTK9+GJBNo1paiNtVqwXkC3Ddscv5AIms1eZGiIOQNC\
+mUvdLkpoXo48WAer3EGsZ3B15GyNEELc0q9W5yUebba1IjUSHwiw2wYSGXapFJVg\
+igPI+6XpExtNLO/i1WFV8ZmoiKwYuPvFiwUqDFVuaXRUZXN0Rml2ZSqAAXdsMgdG\
+ssymvca1S/1KeM3n8Ydi2fi1JUzAAr59xPvNJRUeqCLP9upHn5z7br3P12Oz9A20\
+5/4wL4ClPRPVnOHgij0bEg+y0tGESqmF1rfOfXDszlo2U92wCxS07kq79YAZJ1Zo\
+XYh860/Q4wvc7lfiTe+dXBzPKAKhMy91yETY\
+";
+
+//
+// Contains a testnet paytoaddress, so payment request network doesn't match client network
+//
+const char* paymentrequest1_cert2_BASE64 =
+"\
+Egt4NTA5K3NoYTI1NhrQBArNBDCCAkkwggExoAMCAQICAQEwDQYJKoZIhvcNAQEL\
+BQAwITEfMB0GA1UEAwwWUGF5bWVudFJlcXVlc3QgVGVzdCBDQTAeFw0xNTAxMTEx\
+ODIxMDhaFw0yNTAxMDgxODIxMDhaMCExHzAdBgNVBAMMFlBheW1lbnRSZXF1ZXN0\
+IFRlc3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMsZqzkzeBGo+i2N\
+mUak3Ciodr1V7S062VOy7N0OQYNDQHYkgDFAUET7cEb5VJaHPv5m3ppTBpU9xBcf\
+wbHHUt4VjA+mhRmYrl1khjvZM+X8kEqvWn20BtcM9R6r0yIYec8UERDDHBleL/P8\
+RkxEnVLjYTV9zigCXfMsgYb3EQShAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJ\
+KoZIhvcNAQELBQADggEBABUJpl3QCqsoDSxAsQdV6zKT4VGV76AzoGj7etQsQY+r\
++S26VfWh/fMobEzuxFChr0USgLJ6FoK78hAtoZvt1lrye9yqFv/ig3WLWsJKWHHb\
+3RT6oR03CIwZXFSUasi08QDVLxafwsU5OMcPLucF3a1lRL1ccYrNgVCCx1+X7Bos\
+tIgDGRQQ4AyoHTcfVd2hEGeUv7k14mOxFsAp6851yosHq9Q2kwmdH+rHEJbjof87\
+yyKLagc4owyXBZYkQmkeHWCNqnuRmO5vUsfVb0UUrkD64o7Th/NjwooA7SCiUXl6\
+dfygT1b7ggpx7GC+sP2DsIM47IAZ55drjqX5u2f+Ba0iPQoEdGVzdBIhCIDWwowE\
+Ehl2qRQErGqUUwSsaMpDvWIaGnJGNQqi8oisGNeMy6UFKgxKdXN0IFRlc3Rpbmcq\
+gAFwThsozZxkZxzCn4R8WxNiLFV6m0ye9fEtSbolfaW+EjBMpO03lr/dwNnrclhg\
+ew+A05xfZztrAt16XKEY7qKJ/eY2nLd0fVAIu/nIt+7/VYVXT83zLrWc150aRS7W\
+AdJbL3JOJLs6Eyp5zrPbfI8faRttFAdONKDrJgIpuW1E3g==\
+";
+
+//
+// Expired payment request (expires is set to 1 = 1970-01-01 00:00:01)
+//
+const char* paymentrequest2_cert2_BASE64 =
+"\
+Egt4NTA5K3NoYTI1NhrQBArNBDCCAkkwggExoAMCAQICAQEwDQYJKoZIhvcNAQEL\
+BQAwITEfMB0GA1UEAwwWUGF5bWVudFJlcXVlc3QgVGVzdCBDQTAeFw0xNTAxMTEx\
+ODIxMDhaFw0yNTAxMDgxODIxMDhaMCExHzAdBgNVBAMMFlBheW1lbnRSZXF1ZXN0\
+IFRlc3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMsZqzkzeBGo+i2N\
+mUak3Ciodr1V7S062VOy7N0OQYNDQHYkgDFAUET7cEb5VJaHPv5m3ppTBpU9xBcf\
+wbHHUt4VjA+mhRmYrl1khjvZM+X8kEqvWn20BtcM9R6r0yIYec8UERDDHBleL/P8\
+RkxEnVLjYTV9zigCXfMsgYb3EQShAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJ\
+KoZIhvcNAQELBQADggEBABUJpl3QCqsoDSxAsQdV6zKT4VGV76AzoGj7etQsQY+r\
++S26VfWh/fMobEzuxFChr0USgLJ6FoK78hAtoZvt1lrye9yqFv/ig3WLWsJKWHHb\
+3RT6oR03CIwZXFSUasi08QDVLxafwsU5OMcPLucF3a1lRL1ccYrNgVCCx1+X7Bos\
+tIgDGRQQ4AyoHTcfVd2hEGeUv7k14mOxFsAp6851yosHq9Q2kwmdH+rHEJbjof87\
+yyKLagc4owyXBZYkQmkeHWCNqnuRmO5vUsfVb0UUrkD64o7Th/NjwooA7SCiUXl6\
+dfygT1b7ggpx7GC+sP2DsIM47IAZ55drjqX5u2f+Ba0iQgoEdGVzdBIgCICt4gQS\
+GXapFASsapRTBKxoykO9YhoackY1CqLyiKwYiNLUpQUgASoQVGVzdGluZyB0ZXN0\
+bmV0ISqAATXq9A5nmJgtmee/bQTeHeif4w1YYFPBlKghwx6qbVgXTWnwBJtOQhhV\
+sZdzbTl95ENR7/Y7VJupW9kDWobCK7zUUhLAzUlwmLlcx6itHw8LTUF5HK+AwsZm\
+Zs85lISGvOS0NZW/ENa6l+oQRnL87oqVZr/EDGiuqjz6T0ThQi0l\
+";
+
+//
+// Unexpired payment request (expires is set to 0x7FFFFFFFFFFFFFFF = max. int64_t)
+//
+const char* paymentrequest3_cert2_BASE64 =
+"\
+Egt4NTA5K3NoYTI1NhrQBArNBDCCAkkwggExoAMCAQICAQEwDQYJKoZIhvcNAQEL\
+BQAwITEfMB0GA1UEAwwWUGF5bWVudFJlcXVlc3QgVGVzdCBDQTAeFw0xNTAxMTEx\
+ODIxMDhaFw0yNTAxMDgxODIxMDhaMCExHzAdBgNVBAMMFlBheW1lbnRSZXF1ZXN0\
+IFRlc3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMsZqzkzeBGo+i2N\
+mUak3Ciodr1V7S062VOy7N0OQYNDQHYkgDFAUET7cEb5VJaHPv5m3ppTBpU9xBcf\
+wbHHUt4VjA+mhRmYrl1khjvZM+X8kEqvWn20BtcM9R6r0yIYec8UERDDHBleL/P8\
+RkxEnVLjYTV9zigCXfMsgYb3EQShAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJ\
+KoZIhvcNAQELBQADggEBABUJpl3QCqsoDSxAsQdV6zKT4VGV76AzoGj7etQsQY+r\
++S26VfWh/fMobEzuxFChr0USgLJ6FoK78hAtoZvt1lrye9yqFv/ig3WLWsJKWHHb\
+3RT6oR03CIwZXFSUasi08QDVLxafwsU5OMcPLucF3a1lRL1ccYrNgVCCx1+X7Bos\
+tIgDGRQQ4AyoHTcfVd2hEGeUv7k14mOxFsAp6851yosHq9Q2kwmdH+rHEJbjof87\
+yyKLagc4owyXBZYkQmkeHWCNqnuRmO5vUsfVb0UUrkD64o7Th/NjwooA7SCiUXl6\
+dfygT1b7ggpx7GC+sP2DsIM47IAZ55drjqX5u2f+Ba0iSgoEdGVzdBIgCICt4gQS\
+GXapFASsapRTBKxoykO9YhoackY1CqLyiKwYyNfZpQUg//////////9/KhBUZXN0\
+aW5nIHRlc3RuZXQhKoABNwi8WnMW4aMvbmvorTiiWJLFhofLFnsoWCJnj3rWLnLh\
+n3w6q/fZ26p50ERL/noxdTUfeFsKnlECkUu/fOcOrqyYDiwvxI0SZ034DleVyFU1\
+Z3T+X0zcL8oe7bX01Yf+s2V+5JXQXarKnKBrZCGgv2ARjFNSZe7E7vGg5K4Q6Q8=\
+";
+
+//
+// Unexpired payment request (expires is set to 0x8000000000000000 > max. int64_t, allowed uint64)
+//
+const char* paymentrequest4_cert2_BASE64 =
+"\
+Egt4NTA5K3NoYTI1NhrQBArNBDCCAkkwggExoAMCAQICAQEwDQYJKoZIhvcNAQEL\
+BQAwITEfMB0GA1UEAwwWUGF5bWVudFJlcXVlc3QgVGVzdCBDQTAeFw0xNTAxMTEx\
+ODIxMDhaFw0yNTAxMDgxODIxMDhaMCExHzAdBgNVBAMMFlBheW1lbnRSZXF1ZXN0\
+IFRlc3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMsZqzkzeBGo+i2N\
+mUak3Ciodr1V7S062VOy7N0OQYNDQHYkgDFAUET7cEb5VJaHPv5m3ppTBpU9xBcf\
+wbHHUt4VjA+mhRmYrl1khjvZM+X8kEqvWn20BtcM9R6r0yIYec8UERDDHBleL/P8\
+RkxEnVLjYTV9zigCXfMsgYb3EQShAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJ\
+KoZIhvcNAQELBQADggEBABUJpl3QCqsoDSxAsQdV6zKT4VGV76AzoGj7etQsQY+r\
++S26VfWh/fMobEzuxFChr0USgLJ6FoK78hAtoZvt1lrye9yqFv/ig3WLWsJKWHHb\
+3RT6oR03CIwZXFSUasi08QDVLxafwsU5OMcPLucF3a1lRL1ccYrNgVCCx1+X7Bos\
+tIgDGRQQ4AyoHTcfVd2hEGeUv7k14mOxFsAp6851yosHq9Q2kwmdH+rHEJbjof87\
+yyKLagc4owyXBZYkQmkeHWCNqnuRmO5vUsfVb0UUrkD64o7Th/NjwooA7SCiUXl6\
+dfygT1b7ggpx7GC+sP2DsIM47IAZ55drjqX5u2f+Ba0iSwoEdGVzdBIgCICt4gQS\
+GXapFASsapRTBKxoykO9YhoackY1CqLyiKwYt+HZpQUggICAgICAgICAASoQVGVz\
+dGluZyB0ZXN0bmV0ISqAAXSQG8+GFA18VaKarlYrOz293rNMIub0swKGcQm8jAGX\
+HSLaRgHfUDeEPr4hydy4dtfu59KNwe2xsHOHu/SpO4L8SrA4Dm9A7SlNBVWdcLbw\
+d2hj739GDLz0b5KuJ2SG6VknMRQM976w/m2qlq0ccVGaaZ2zMIGfpzL3p6adwx/5\
+";
+
+//
+// Payment request with amount overflow (amount is set to 21000001 BTC)
+//
+const char* paymentrequest5_cert2_BASE64 =
+"\
+Egt4NTA5K3NoYTI1NhrQBArNBDCCAkkwggExoAMCAQICAQEwDQYJKoZIhvcNAQEL\
+BQAwITEfMB0GA1UEAwwWUGF5bWVudFJlcXVlc3QgVGVzdCBDQTAeFw0xNTAxMTEx\
+ODIxMDhaFw0yNTAxMDgxODIxMDhaMCExHzAdBgNVBAMMFlBheW1lbnRSZXF1ZXN0\
+IFRlc3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMsZqzkzeBGo+i2N\
+mUak3Ciodr1V7S062VOy7N0OQYNDQHYkgDFAUET7cEb5VJaHPv5m3ppTBpU9xBcf\
+wbHHUt4VjA+mhRmYrl1khjvZM+X8kEqvWn20BtcM9R6r0yIYec8UERDDHBleL/P8\
+RkxEnVLjYTV9zigCXfMsgYb3EQShAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJ\
+KoZIhvcNAQELBQADggEBABUJpl3QCqsoDSxAsQdV6zKT4VGV76AzoGj7etQsQY+r\
++S26VfWh/fMobEzuxFChr0USgLJ6FoK78hAtoZvt1lrye9yqFv/ig3WLWsJKWHHb\
+3RT6oR03CIwZXFSUasi08QDVLxafwsU5OMcPLucF3a1lRL1ccYrNgVCCx1+X7Bos\
+tIgDGRQQ4AyoHTcfVd2hEGeUv7k14mOxFsAp6851yosHq9Q2kwmdH+rHEJbjof87\
+yyKLagc4owyXBZYkQmkeHWCNqnuRmO5vUsfVb0UUrkD64o7Th/NjwooA7SCiUXl6\
+dfygT1b7ggpx7GC+sP2DsIM47IAZ55drjqX5u2f+Ba0iTAoEdGVzdBIkCIDC9P+F\
+vt0DEhl2qRQErGqUUwSsaMpDvWIaGnJGNQqi8oisGLzcrKYFKhhUZXN0aW5nIGFt\
+b3VudCBvdmVyZmxvdyEqgAG8S7WEDUC6tCL6q2CTBjop/AitgEy31RL9IqYruytR\
+iEBFUrBDJZU+UEezGwr7/zoECjo5ZY3PmtZcM2sILNjyweJF6XVzGqTxUw6pN6sW\
+XR2T3Gy2LzRvhVA25QgGqpz0/juS2BtmNbsZPkN9gMMwKimgzc+PuCzmEKwPK9cQ\
+YQ==\
+";
diff --git a/src/qt/test/paymentservertests.cpp b/src/qt/test/paymentservertests.cpp
new file mode 100644
index 0000000000..b28934cd31
--- /dev/null
+++ b/src/qt/test/paymentservertests.cpp
@@ -0,0 +1,210 @@
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "paymentservertests.h"
+
+#include "optionsmodel.h"
+#include "paymentrequestdata.h"
+
+#include "amount.h"
+#include "random.h"
+#include "script/script.h"
+#include "script/standard.h"
+#include "util.h"
+#include "utilstrencodings.h"
+
+#include <openssl/x509.h>
+#include <openssl/x509_vfy.h>
+
+#include <QFileOpenEvent>
+#include <QTemporaryFile>
+
+X509 *parse_b64der_cert(const char* cert_data)
+{
+ std::vector<unsigned char> data = DecodeBase64(cert_data);
+ assert(data.size() > 0);
+ const unsigned char* dptr = &data[0];
+ X509 *cert = d2i_X509(NULL, &dptr, data.size());
+ assert(cert);
+ return cert;
+}
+
+//
+// Test payment request handling
+//
+
+static SendCoinsRecipient handleRequest(PaymentServer* server, std::vector<unsigned char>& data)
+{
+ RecipientCatcher sigCatcher;
+ QObject::connect(server, SIGNAL(receivedPaymentRequest(SendCoinsRecipient)),
+ &sigCatcher, SLOT(getRecipient(SendCoinsRecipient)));
+
+ // Write data to a temp file:
+ QTemporaryFile f;
+ f.open();
+ f.write((const char*)&data[0], data.size());
+ f.close();
+
+ // Create a QObject, install event filter from PaymentServer
+ // and send a file open event to the object
+ QObject object;
+ object.installEventFilter(server);
+ QFileOpenEvent event(f.fileName());
+ // If sending the event fails, this will cause sigCatcher to be empty,
+ // which will lead to a test failure anyway.
+ QCoreApplication::sendEvent(&object, &event);
+
+ QObject::disconnect(server, SIGNAL(receivedPaymentRequest(SendCoinsRecipient)),
+ &sigCatcher, SLOT(getRecipient(SendCoinsRecipient)));
+
+ // Return results from sigCatcher
+ return sigCatcher.recipient;
+}
+
+void PaymentServerTests::paymentServerTests()
+{
+ SelectParams(CBaseChainParams::MAIN);
+ OptionsModel optionsModel;
+ PaymentServer* server = new PaymentServer(NULL, false);
+ X509_STORE* caStore = X509_STORE_new();
+ X509_STORE_add_cert(caStore, parse_b64der_cert(caCert1_BASE64));
+ PaymentServer::LoadRootCAs(caStore);
+ server->setOptionsModel(&optionsModel);
+ server->uiReady();
+
+ std::vector<unsigned char> data;
+ SendCoinsRecipient r;
+ QString merchant;
+
+ // Now feed PaymentRequests to server, and observe signals it produces
+
+ // This payment request validates directly against the
+ // caCert1 certificate authority:
+ data = DecodeBase64(paymentrequest1_cert1_BASE64);
+ r = handleRequest(server, data);
+ r.paymentRequest.getMerchant(caStore, merchant);
+ QCOMPARE(merchant, QString("testmerchant.org"));
+
+ // Signed, but expired, merchant cert in the request:
+ data = DecodeBase64(paymentrequest2_cert1_BASE64);
+ r = handleRequest(server, data);
+ r.paymentRequest.getMerchant(caStore, merchant);
+ QCOMPARE(merchant, QString(""));
+
+ // 10-long certificate chain, all intermediates valid:
+ data = DecodeBase64(paymentrequest3_cert1_BASE64);
+ r = handleRequest(server, data);
+ r.paymentRequest.getMerchant(caStore, merchant);
+ QCOMPARE(merchant, QString("testmerchant8.org"));
+
+ // Long certificate chain, with an expired certificate in the middle:
+ data = DecodeBase64(paymentrequest4_cert1_BASE64);
+ r = handleRequest(server, data);
+ r.paymentRequest.getMerchant(caStore, merchant);
+ QCOMPARE(merchant, QString(""));
+
+ // Validly signed, but by a CA not in our root CA list:
+ data = DecodeBase64(paymentrequest5_cert1_BASE64);
+ r = handleRequest(server, data);
+ r.paymentRequest.getMerchant(caStore, merchant);
+ QCOMPARE(merchant, QString(""));
+
+ // Try again with no root CA's, verifiedMerchant should be empty:
+ caStore = X509_STORE_new();
+ PaymentServer::LoadRootCAs(caStore);
+ data = DecodeBase64(paymentrequest1_cert1_BASE64);
+ r = handleRequest(server, data);
+ r.paymentRequest.getMerchant(caStore, merchant);
+ QCOMPARE(merchant, QString(""));
+
+ // Load second root certificate
+ caStore = X509_STORE_new();
+ X509_STORE_add_cert(caStore, parse_b64der_cert(caCert2_BASE64));
+ PaymentServer::LoadRootCAs(caStore);
+
+ QByteArray byteArray;
+
+ // For the tests below we just need the payment request data from
+ // paymentrequestdata.h parsed + stored in r.paymentRequest.
+ //
+ // These tests require us to bypass the following normal client execution flow
+ // shown below to be able to explicitly just trigger a certain condition!
+ //
+ // handleRequest()
+ // -> PaymentServer::eventFilter()
+ // -> PaymentServer::handleURIOrFile()
+ // -> PaymentServer::readPaymentRequestFromFile()
+ // -> PaymentServer::processPaymentRequest()
+
+ // Contains a testnet paytoaddress, so payment request network doesn't match client network:
+ data = DecodeBase64(paymentrequest1_cert2_BASE64);
+ byteArray = QByteArray((const char*)&data[0], data.size());
+ r.paymentRequest.parse(byteArray);
+ // Ensure the request is initialized, because network "main" is default, even for
+ // uninizialized payment requests and that will fail our test here.
+ QVERIFY(r.paymentRequest.IsInitialized());
+ QCOMPARE(PaymentServer::verifyNetwork(r.paymentRequest.getDetails()), false);
+
+ // Expired payment request (expires is set to 1 = 1970-01-01 00:00:01):
+ data = DecodeBase64(paymentrequest2_cert2_BASE64);
+ byteArray = QByteArray((const char*)&data[0], data.size());
+ r.paymentRequest.parse(byteArray);
+ // Ensure the request is initialized
+ QVERIFY(r.paymentRequest.IsInitialized());
+ // compares 1 < GetTime() == false (treated as expired payment request)
+ QCOMPARE(PaymentServer::verifyExpired(r.paymentRequest.getDetails()), true);
+
+ // Unexpired payment request (expires is set to 0x7FFFFFFFFFFFFFFF = max. int64_t):
+ // 9223372036854775807 (uint64), 9223372036854775807 (int64_t) and -1 (int32_t)
+ // -1 is 1969-12-31 23:59:59 (for a 32 bit time values)
+ data = DecodeBase64(paymentrequest3_cert2_BASE64);
+ byteArray = QByteArray((const char*)&data[0], data.size());
+ r.paymentRequest.parse(byteArray);
+ // Ensure the request is initialized
+ QVERIFY(r.paymentRequest.IsInitialized());
+ // compares 9223372036854775807 < GetTime() == false (treated as unexpired payment request)
+ QCOMPARE(PaymentServer::verifyExpired(r.paymentRequest.getDetails()), false);
+
+ // Unexpired payment request (expires is set to 0x8000000000000000 > max. int64_t, allowed uint64):
+ // 9223372036854775808 (uint64), -9223372036854775808 (int64_t) and 0 (int32_t)
+ // 0 is 1970-01-01 00:00:00 (for a 32 bit time values)
+ data = DecodeBase64(paymentrequest4_cert2_BASE64);
+ byteArray = QByteArray((const char*)&data[0], data.size());
+ r.paymentRequest.parse(byteArray);
+ // Ensure the request is initialized
+ QVERIFY(r.paymentRequest.IsInitialized());
+ // compares -9223372036854775808 < GetTime() == true (treated as expired payment request)
+ QCOMPARE(PaymentServer::verifyExpired(r.paymentRequest.getDetails()), true);
+
+ // Test BIP70 DoS protection:
+ unsigned char randData[BIP70_MAX_PAYMENTREQUEST_SIZE + 1];
+ GetRandBytes(randData, sizeof(randData));
+ // Write data to a temp file:
+ QTemporaryFile tempFile;
+ tempFile.open();
+ tempFile.write((const char*)randData, sizeof(randData));
+ tempFile.close();
+ QCOMPARE(PaymentServer::readPaymentRequestFromFile(tempFile.fileName(), r.paymentRequest), false);
+
+ // Payment request with amount overflow (amount is set to 21000001 BTC):
+ data = DecodeBase64(paymentrequest5_cert2_BASE64);
+ byteArray = QByteArray((const char*)&data[0], data.size());
+ r.paymentRequest.parse(byteArray);
+ // Ensure the request is initialized
+ QVERIFY(r.paymentRequest.IsInitialized());
+ // Extract address and amount from the request
+ QList<std::pair<CScript, CAmount> > sendingTos = r.paymentRequest.getPayTo();
+ Q_FOREACH (const PAIRTYPE(CScript, CAmount)& sendingTo, sendingTos) {
+ CTxDestination dest;
+ if (ExtractDestination(sendingTo.first, dest))
+ QCOMPARE(PaymentServer::verifyAmount(sendingTo.second), false);
+ }
+
+ delete server;
+}
+
+void RecipientCatcher::getRecipient(SendCoinsRecipient r)
+{
+ recipient = r;
+}
diff --git a/src/qt/test/paymentservertests.h b/src/qt/test/paymentservertests.h
new file mode 100644
index 0000000000..71d61fcbe7
--- /dev/null
+++ b/src/qt/test/paymentservertests.h
@@ -0,0 +1,35 @@
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_TEST_PAYMENTSERVERTESTS_H
+#define BITCOIN_QT_TEST_PAYMENTSERVERTESTS_H
+
+#include "../paymentserver.h"
+
+#include <QObject>
+#include <QTest>
+
+class PaymentServerTests : public QObject
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+ void paymentServerTests();
+};
+
+// Dummy class to receive paymentserver signals.
+// If SendCoinsRecipient was a proper QObject, then
+// we could use QSignalSpy... but it's not.
+class RecipientCatcher : public QObject
+{
+ Q_OBJECT
+
+public Q_SLOTS:
+ void getRecipient(SendCoinsRecipient r);
+
+public:
+ SendCoinsRecipient recipient;
+};
+
+#endif // BITCOIN_QT_TEST_PAYMENTSERVERTESTS_H
diff --git a/src/qt/test/test_main.cpp b/src/qt/test/test_main.cpp
new file mode 100644
index 0000000000..bb768f1325
--- /dev/null
+++ b/src/qt/test/test_main.cpp
@@ -0,0 +1,49 @@
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#if defined(HAVE_CONFIG_H)
+#include "config/bitcoin-config.h"
+#endif
+
+#include "util.h"
+#include "uritests.h"
+
+#ifdef ENABLE_WALLET
+#include "paymentservertests.h"
+#endif
+
+#include <QCoreApplication>
+#include <QObject>
+#include <QTest>
+
+#if defined(QT_STATICPLUGIN) && QT_VERSION < 0x050000
+#include <QtPlugin>
+Q_IMPORT_PLUGIN(qcncodecs)
+Q_IMPORT_PLUGIN(qjpcodecs)
+Q_IMPORT_PLUGIN(qtwcodecs)
+Q_IMPORT_PLUGIN(qkrcodecs)
+#endif
+
+// This is all you need to run all the tests
+int main(int argc, char *argv[])
+{
+ SetupEnvironment();
+ bool fInvalid = false;
+
+ // Don't remove this, it's needed to access
+ // QCoreApplication:: in the tests
+ QCoreApplication app(argc, argv);
+ app.setApplicationName("Bitcoin-Qt-test");
+
+ URITests test1;
+ if (QTest::qExec(&test1) != 0)
+ fInvalid = true;
+#ifdef ENABLE_WALLET
+ PaymentServerTests test2;
+ if (QTest::qExec(&test2) != 0)
+ fInvalid = true;
+#endif
+
+ return fInvalid;
+}
diff --git a/src/qt/test/uritests.cpp b/src/qt/test/uritests.cpp
new file mode 100644
index 0000000000..8b53c0d5c7
--- /dev/null
+++ b/src/qt/test/uritests.cpp
@@ -0,0 +1,66 @@
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "uritests.h"
+
+#include "guiutil.h"
+#include "walletmodel.h"
+
+#include <QUrl>
+
+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 == 10000000000LL);
+ 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());
+
+ 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 0000000000..434169dcde
--- /dev/null
+++ b/src/qt/test/uritests.h
@@ -0,0 +1,19 @@
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_TEST_URITESTS_H
+#define BITCOIN_QT_TEST_URITESTS_H
+
+#include <QObject>
+#include <QTest>
+
+class URITests : public QObject
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+ void uriTests();
+};
+
+#endif // BITCOIN_QT_TEST_URITESTS_H
diff --git a/src/qt/trafficgraphwidget.cpp b/src/qt/trafficgraphwidget.cpp
new file mode 100644
index 0000000000..9b67445bc0
--- /dev/null
+++ b/src/qt/trafficgraphwidget.cpp
@@ -0,0 +1,175 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "trafficgraphwidget.h"
+#include "clientmodel.h"
+
+#include <QPainter>
+#include <QColor>
+#include <QTimer>
+
+#include <cmath>
+
+#define DESIRED_SAMPLES 800
+
+#define XMARGIN 10
+#define YMARGIN 10
+
+TrafficGraphWidget::TrafficGraphWidget(QWidget *parent) :
+ QWidget(parent),
+ timer(0),
+ fMax(0.0f),
+ nMins(0),
+ vSamplesIn(),
+ vSamplesOut(),
+ nLastBytesIn(0),
+ nLastBytesOut(0),
+ clientModel(0)
+{
+ timer = new QTimer(this);
+ connect(timer, SIGNAL(timeout()), SLOT(updateRates()));
+}
+
+void TrafficGraphWidget::setClientModel(ClientModel *model)
+{
+ clientModel = model;
+ if(model) {
+ nLastBytesIn = model->getTotalBytesRecv();
+ nLastBytesOut = model->getTotalBytesSent();
+ }
+}
+
+int TrafficGraphWidget::getGraphRangeMins() const
+{
+ return nMins;
+}
+
+void TrafficGraphWidget::paintPath(QPainterPath &path, QQueue<float> &samples)
+{
+ int h = height() - YMARGIN * 2, w = width() - XMARGIN * 2;
+ int sampleCount = samples.size(), x = XMARGIN + w, y;
+ if(sampleCount > 0) {
+ path.moveTo(x, YMARGIN + h);
+ for(int i = 0; i < sampleCount; ++i) {
+ x = XMARGIN + w - w * i / DESIRED_SAMPLES;
+ y = YMARGIN + h - (int)(h * samples.at(i) / fMax);
+ path.lineTo(x, y);
+ }
+ path.lineTo(x, YMARGIN + h);
+ }
+}
+
+void TrafficGraphWidget::paintEvent(QPaintEvent *)
+{
+ QPainter painter(this);
+ painter.fillRect(rect(), Qt::black);
+
+ if(fMax <= 0.0f) return;
+
+ QColor axisCol(Qt::gray);
+ int h = height() - YMARGIN * 2;
+ painter.setPen(axisCol);
+ painter.drawLine(XMARGIN, YMARGIN + h, width() - XMARGIN, YMARGIN + h);
+
+ // decide what order of magnitude we are
+ int base = floor(log10(fMax));
+ float val = pow(10.0f, base);
+
+ const QString units = tr("KB/s");
+ const float yMarginText = 2.0;
+
+ // draw lines
+ painter.setPen(axisCol);
+ painter.drawText(XMARGIN, YMARGIN + h - h * val / fMax-yMarginText, QString("%1 %2").arg(val).arg(units));
+ for(float y = val; y < fMax; y += val) {
+ int yy = YMARGIN + h - h * y / fMax;
+ painter.drawLine(XMARGIN, yy, width() - XMARGIN, yy);
+ }
+ // if we drew 3 or fewer lines, break them up at the next lower order of magnitude
+ if(fMax / val <= 3.0f) {
+ axisCol = axisCol.darker();
+ val = pow(10.0f, base - 1);
+ painter.setPen(axisCol);
+ painter.drawText(XMARGIN, YMARGIN + h - h * val / fMax-yMarginText, QString("%1 %2").arg(val).arg(units));
+ int count = 1;
+ for(float y = val; y < fMax; y += val, count++) {
+ // don't overwrite lines drawn above
+ if(count % 10 == 0)
+ continue;
+ int yy = YMARGIN + h - h * y / fMax;
+ painter.drawLine(XMARGIN, yy, width() - XMARGIN, yy);
+ }
+ }
+
+ if(!vSamplesIn.empty()) {
+ QPainterPath p;
+ paintPath(p, vSamplesIn);
+ painter.fillPath(p, QColor(0, 255, 0, 128));
+ painter.setPen(Qt::green);
+ painter.drawPath(p);
+ }
+ if(!vSamplesOut.empty()) {
+ QPainterPath p;
+ paintPath(p, vSamplesOut);
+ painter.fillPath(p, QColor(255, 0, 0, 128));
+ painter.setPen(Qt::red);
+ painter.drawPath(p);
+ }
+}
+
+void TrafficGraphWidget::updateRates()
+{
+ if(!clientModel) return;
+
+ quint64 bytesIn = clientModel->getTotalBytesRecv(),
+ bytesOut = clientModel->getTotalBytesSent();
+ float inRate = (bytesIn - nLastBytesIn) / 1024.0f * 1000 / timer->interval();
+ float outRate = (bytesOut - nLastBytesOut) / 1024.0f * 1000 / timer->interval();
+ vSamplesIn.push_front(inRate);
+ vSamplesOut.push_front(outRate);
+ nLastBytesIn = bytesIn;
+ nLastBytesOut = bytesOut;
+
+ while(vSamplesIn.size() > DESIRED_SAMPLES) {
+ vSamplesIn.pop_back();
+ }
+ while(vSamplesOut.size() > DESIRED_SAMPLES) {
+ vSamplesOut.pop_back();
+ }
+
+ float tmax = 0.0f;
+ Q_FOREACH(float f, vSamplesIn) {
+ if(f > tmax) tmax = f;
+ }
+ Q_FOREACH(float f, vSamplesOut) {
+ if(f > tmax) tmax = f;
+ }
+ fMax = tmax;
+ update();
+}
+
+void TrafficGraphWidget::setGraphRangeMins(int mins)
+{
+ nMins = mins;
+ int msecsPerSample = nMins * 60 * 1000 / DESIRED_SAMPLES;
+ timer->stop();
+ timer->setInterval(msecsPerSample);
+
+ clear();
+}
+
+void TrafficGraphWidget::clear()
+{
+ timer->stop();
+
+ vSamplesOut.clear();
+ vSamplesIn.clear();
+ fMax = 0.0f;
+
+ if(clientModel) {
+ nLastBytesIn = clientModel->getTotalBytesRecv();
+ nLastBytesOut = clientModel->getTotalBytesSent();
+ }
+ timer->start();
+}
diff --git a/src/qt/trafficgraphwidget.h b/src/qt/trafficgraphwidget.h
new file mode 100644
index 0000000000..6336a8d144
--- /dev/null
+++ b/src/qt/trafficgraphwidget.h
@@ -0,0 +1,48 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_TRAFFICGRAPHWIDGET_H
+#define BITCOIN_QT_TRAFFICGRAPHWIDGET_H
+
+#include <QWidget>
+#include <QQueue>
+
+class ClientModel;
+
+QT_BEGIN_NAMESPACE
+class QPaintEvent;
+class QTimer;
+QT_END_NAMESPACE
+
+class TrafficGraphWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit TrafficGraphWidget(QWidget *parent = 0);
+ void setClientModel(ClientModel *model);
+ int getGraphRangeMins() const;
+
+protected:
+ void paintEvent(QPaintEvent *);
+
+public Q_SLOTS:
+ void updateRates();
+ void setGraphRangeMins(int mins);
+ void clear();
+
+private:
+ void paintPath(QPainterPath &path, QQueue<float> &samples);
+
+ QTimer *timer;
+ float fMax;
+ int nMins;
+ QQueue<float> vSamplesIn;
+ QQueue<float> vSamplesOut;
+ quint64 nLastBytesIn;
+ quint64 nLastBytesOut;
+ ClientModel *clientModel;
+};
+
+#endif // BITCOIN_QT_TRAFFICGRAPHWIDGET_H
diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp
new file mode 100644
index 0000000000..d7ee3d4c78
--- /dev/null
+++ b/src/qt/transactiondesc.cpp
@@ -0,0 +1,320 @@
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "transactiondesc.h"
+
+#include "bitcoinunits.h"
+#include "guiutil.h"
+#include "paymentserver.h"
+#include "transactionrecord.h"
+
+#include "base58.h"
+#include "consensus/consensus.h"
+#include "main.h"
+#include "script/script.h"
+#include "timedata.h"
+#include "util.h"
+#include "wallet/db.h"
+#include "wallet/wallet.h"
+
+#include <stdint.h>
+#include <string>
+
+using namespace std;
+
+QString TransactionDesc::FormatTxStatus(const CWalletTx& wtx)
+{
+ AssertLockHeld(cs_main);
+ if (!CheckFinalTx(wtx))
+ {
+ if (wtx.nLockTime < LOCKTIME_THRESHOLD)
+ return tr("Open for %n more block(s)", "", wtx.nLockTime - chainActive.Height());
+ else
+ return tr("Open until %1").arg(GUIUtil::dateTimeStr(wtx.nLockTime));
+ }
+ else
+ {
+ int nDepth = wtx.GetDepthInMainChain();
+ if (nDepth < 0)
+ return tr("conflicted");
+ else 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, TransactionRecord *rec, int unit)
+{
+ QString strHTML;
+
+ LOCK2(cs_main, wallet->cs_wallet);
+ strHTML.reserve(4000);
+ strHTML += "<html><font face='verdana, arial, helvetica, sans-serif'>";
+
+ int64_t nTime = wtx.GetTxTime();
+ CAmount nCredit = wtx.GetCredit(ISMINE_ALL);
+ CAmount nDebit = wtx.GetDebit(ISMINE_ALL);
+ CAmount nNet = nCredit - nDebit;
+
+ strHTML += "<b>" + tr("Status") + ":</b> " + 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 += "<br>";
+
+ strHTML += "<b>" + tr("Date") + ":</b> " + (nTime ? GUIUtil::dateTimeStr(nTime) : "") + "<br>";
+
+ //
+ // From
+ //
+ if (wtx.IsCoinBase())
+ {
+ strHTML += "<b>" + tr("Source") + ":</b> " + tr("Generated") + "<br>";
+ }
+ else if (wtx.mapValue.count("from") && !wtx.mapValue["from"].empty())
+ {
+ // Online transaction
+ strHTML += "<b>" + tr("From") + ":</b> " + GUIUtil::HtmlEscape(wtx.mapValue["from"]) + "<br>";
+ }
+ else
+ {
+ // Offline transaction
+ if (nNet > 0)
+ {
+ // Credit
+ if (CBitcoinAddress(rec->address).IsValid())
+ {
+ CTxDestination address = CBitcoinAddress(rec->address).Get();
+ if (wallet->mapAddressBook.count(address))
+ {
+ strHTML += "<b>" + tr("From") + ":</b> " + tr("unknown") + "<br>";
+ strHTML += "<b>" + tr("To") + ":</b> ";
+ strHTML += GUIUtil::HtmlEscape(rec->address);
+ QString addressOwned = (::IsMine(*wallet, address) == ISMINE_SPENDABLE) ? tr("own address") : tr("watch-only");
+ if (!wallet->mapAddressBook[address].name.empty())
+ strHTML += " (" + addressOwned + ", " + tr("label") + ": " + GUIUtil::HtmlEscape(wallet->mapAddressBook[address].name) + ")";
+ else
+ strHTML += " (" + addressOwned + ")";
+ strHTML += "<br>";
+ }
+ }
+ }
+ }
+
+ //
+ // To
+ //
+ if (wtx.mapValue.count("to") && !wtx.mapValue["to"].empty())
+ {
+ // Online transaction
+ std::string strAddress = wtx.mapValue["to"];
+ strHTML += "<b>" + tr("To") + ":</b> ";
+ CTxDestination dest = CBitcoinAddress(strAddress).Get();
+ if (wallet->mapAddressBook.count(dest) && !wallet->mapAddressBook[dest].name.empty())
+ strHTML += GUIUtil::HtmlEscape(wallet->mapAddressBook[dest].name) + " ";
+ strHTML += GUIUtil::HtmlEscape(strAddress) + "<br>";
+ }
+
+ //
+ // Amount
+ //
+ if (wtx.IsCoinBase() && nCredit == 0)
+ {
+ //
+ // Coinbase
+ //
+ CAmount nUnmatured = 0;
+ BOOST_FOREACH(const CTxOut& txout, wtx.vout)
+ nUnmatured += wallet->GetCredit(txout, ISMINE_ALL);
+ strHTML += "<b>" + tr("Credit") + ":</b> ";
+ if (wtx.IsInMainChain())
+ strHTML += BitcoinUnits::formatHtmlWithUnit(unit, nUnmatured)+ " (" + tr("matures in %n more block(s)", "", wtx.GetBlocksToMaturity()) + ")";
+ else
+ strHTML += "(" + tr("not accepted") + ")";
+ strHTML += "<br>";
+ }
+ else if (nNet > 0)
+ {
+ //
+ // Credit
+ //
+ strHTML += "<b>" + tr("Credit") + ":</b> " + BitcoinUnits::formatHtmlWithUnit(unit, nNet) + "<br>";
+ }
+ else
+ {
+ isminetype fAllFromMe = ISMINE_SPENDABLE;
+ BOOST_FOREACH(const CTxIn& txin, wtx.vin)
+ {
+ isminetype mine = wallet->IsMine(txin);
+ if(fAllFromMe > mine) fAllFromMe = mine;
+ }
+
+ isminetype fAllToMe = ISMINE_SPENDABLE;
+ BOOST_FOREACH(const CTxOut& txout, wtx.vout)
+ {
+ isminetype mine = wallet->IsMine(txout);
+ if(fAllToMe > mine) fAllToMe = mine;
+ }
+
+ if (fAllFromMe)
+ {
+ if(fAllFromMe == ISMINE_WATCH_ONLY)
+ strHTML += "<b>" + tr("From") + ":</b> " + tr("watch-only") + "<br>";
+
+ //
+ // Debit
+ //
+ BOOST_FOREACH(const CTxOut& txout, wtx.vout)
+ {
+ // Ignore change
+ isminetype toSelf = wallet->IsMine(txout);
+ if ((toSelf == ISMINE_SPENDABLE) && (fAllFromMe == ISMINE_SPENDABLE))
+ continue;
+
+ if (!wtx.mapValue.count("to") || wtx.mapValue["to"].empty())
+ {
+ // Offline transaction
+ CTxDestination address;
+ if (ExtractDestination(txout.scriptPubKey, address))
+ {
+ strHTML += "<b>" + tr("To") + ":</b> ";
+ if (wallet->mapAddressBook.count(address) && !wallet->mapAddressBook[address].name.empty())
+ strHTML += GUIUtil::HtmlEscape(wallet->mapAddressBook[address].name) + " ";
+ strHTML += GUIUtil::HtmlEscape(CBitcoinAddress(address).ToString());
+ if(toSelf == ISMINE_SPENDABLE)
+ strHTML += " (own address)";
+ else if(toSelf == ISMINE_WATCH_ONLY)
+ strHTML += " (watch-only)";
+ strHTML += "<br>";
+ }
+ }
+
+ strHTML += "<b>" + tr("Debit") + ":</b> " + BitcoinUnits::formatHtmlWithUnit(unit, -txout.nValue) + "<br>";
+ if(toSelf)
+ strHTML += "<b>" + tr("Credit") + ":</b> " + BitcoinUnits::formatHtmlWithUnit(unit, txout.nValue) + "<br>";
+ }
+
+ if (fAllToMe)
+ {
+ // Payment to self
+ CAmount nChange = wtx.GetChange();
+ CAmount nValue = nCredit - nChange;
+ strHTML += "<b>" + tr("Total debit") + ":</b> " + BitcoinUnits::formatHtmlWithUnit(unit, -nValue) + "<br>";
+ strHTML += "<b>" + tr("Total credit") + ":</b> " + BitcoinUnits::formatHtmlWithUnit(unit, nValue) + "<br>";
+ }
+
+ CAmount nTxFee = nDebit - wtx.GetValueOut();
+ if (nTxFee > 0)
+ strHTML += "<b>" + tr("Transaction fee") + ":</b> " + BitcoinUnits::formatHtmlWithUnit(unit, -nTxFee) + "<br>";
+ }
+ else
+ {
+ //
+ // Mixed debit transaction
+ //
+ BOOST_FOREACH(const CTxIn& txin, wtx.vin)
+ if (wallet->IsMine(txin))
+ strHTML += "<b>" + tr("Debit") + ":</b> " + BitcoinUnits::formatHtmlWithUnit(unit, -wallet->GetDebit(txin, ISMINE_ALL)) + "<br>";
+ BOOST_FOREACH(const CTxOut& txout, wtx.vout)
+ if (wallet->IsMine(txout))
+ strHTML += "<b>" + tr("Credit") + ":</b> " + BitcoinUnits::formatHtmlWithUnit(unit, wallet->GetCredit(txout, ISMINE_ALL)) + "<br>";
+ }
+ }
+
+ strHTML += "<b>" + tr("Net amount") + ":</b> " + BitcoinUnits::formatHtmlWithUnit(unit, nNet, true) + "<br>";
+
+ //
+ // Message
+ //
+ if (wtx.mapValue.count("message") && !wtx.mapValue["message"].empty())
+ strHTML += "<br><b>" + tr("Message") + ":</b><br>" + GUIUtil::HtmlEscape(wtx.mapValue["message"], true) + "<br>";
+ if (wtx.mapValue.count("comment") && !wtx.mapValue["comment"].empty())
+ strHTML += "<br><b>" + tr("Comment") + ":</b><br>" + GUIUtil::HtmlEscape(wtx.mapValue["comment"], true) + "<br>";
+
+ strHTML += "<b>" + tr("Transaction ID") + ":</b> " + TransactionRecord::formatSubTxId(wtx.GetHash(), rec->idx) + "<br>";
+
+ // Message from normal bitcoin:URI (bitcoin:123...?message=example)
+ Q_FOREACH (const PAIRTYPE(string, string)& r, wtx.vOrderForm)
+ if (r.first == "Message")
+ strHTML += "<br><b>" + tr("Message") + ":</b><br>" + GUIUtil::HtmlEscape(r.second, true) + "<br>";
+
+ //
+ // PaymentRequest info:
+ //
+ Q_FOREACH (const PAIRTYPE(string, string)& r, wtx.vOrderForm)
+ {
+ if (r.first == "PaymentRequest")
+ {
+ PaymentRequestPlus req;
+ req.parse(QByteArray::fromRawData(r.second.data(), r.second.size()));
+ QString merchant;
+ if (req.getMerchant(PaymentServer::getCertStore(), merchant))
+ strHTML += "<b>" + tr("Merchant") + ":</b> " + GUIUtil::HtmlEscape(merchant) + "<br>";
+ }
+ }
+
+ if (wtx.IsCoinBase())
+ {
+ quint32 numBlocksToMaturity = COINBASE_MATURITY + 1;
+ strHTML += "<br>" + tr("Generated coins must mature %1 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.").arg(QString::number(numBlocksToMaturity)) + "<br>";
+ }
+
+ //
+ // Debug view
+ //
+ if (fDebug)
+ {
+ strHTML += "<hr><br>" + tr("Debug information") + "<br><br>";
+ BOOST_FOREACH(const CTxIn& txin, wtx.vin)
+ if(wallet->IsMine(txin))
+ strHTML += "<b>" + tr("Debit") + ":</b> " + BitcoinUnits::formatHtmlWithUnit(unit, -wallet->GetDebit(txin, ISMINE_ALL)) + "<br>";
+ BOOST_FOREACH(const CTxOut& txout, wtx.vout)
+ if(wallet->IsMine(txout))
+ strHTML += "<b>" + tr("Credit") + ":</b> " + BitcoinUnits::formatHtmlWithUnit(unit, wallet->GetCredit(txout, ISMINE_ALL)) + "<br>";
+
+ strHTML += "<br><b>" + tr("Transaction") + ":</b><br>";
+ strHTML += GUIUtil::HtmlEscape(wtx.ToString(), true);
+
+ strHTML += "<br><b>" + tr("Inputs") + ":</b>";
+ strHTML += "<ul>";
+
+ BOOST_FOREACH(const CTxIn& txin, wtx.vin)
+ {
+ COutPoint prevout = txin.prevout;
+
+ CCoins prev;
+ if(pcoinsTip->GetCoins(prevout.hash, prev))
+ {
+ if (prevout.n < prev.vout.size())
+ {
+ strHTML += "<li>";
+ const CTxOut &vout = prev.vout[prevout.n];
+ CTxDestination address;
+ if (ExtractDestination(vout.scriptPubKey, address))
+ {
+ if (wallet->mapAddressBook.count(address) && !wallet->mapAddressBook[address].name.empty())
+ strHTML += GUIUtil::HtmlEscape(wallet->mapAddressBook[address].name) + " ";
+ strHTML += QString::fromStdString(CBitcoinAddress(address).ToString());
+ }
+ strHTML = strHTML + " " + tr("Amount") + "=" + BitcoinUnits::formatHtmlWithUnit(unit, vout.nValue);
+ strHTML = strHTML + " IsMine=" + (wallet->IsMine(vout) & ISMINE_SPENDABLE ? tr("true") : tr("false")) + "</li>";
+ strHTML = strHTML + " IsWatchOnly=" + (wallet->IsMine(vout) & ISMINE_WATCH_ONLY ? tr("true") : tr("false")) + "</li>";
+ }
+ }
+ }
+
+ strHTML += "</ul>";
+ }
+
+ strHTML += "</font></html>";
+ return strHTML;
+}
diff --git a/src/qt/transactiondesc.h b/src/qt/transactiondesc.h
new file mode 100644
index 0000000000..5467348ee9
--- /dev/null
+++ b/src/qt/transactiondesc.h
@@ -0,0 +1,31 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_TRANSACTIONDESC_H
+#define BITCOIN_QT_TRANSACTIONDESC_H
+
+#include <QObject>
+#include <QString>
+
+class TransactionRecord;
+
+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, TransactionRecord *rec, int unit);
+
+private:
+ TransactionDesc() {}
+
+ static QString FormatTxStatus(const CWalletTx& wtx);
+};
+
+#endif // BITCOIN_QT_TRANSACTIONDESC_H
diff --git a/src/qt/transactiondescdialog.cpp b/src/qt/transactiondescdialog.cpp
new file mode 100644
index 0000000000..fadaa98f4a
--- /dev/null
+++ b/src/qt/transactiondescdialog.cpp
@@ -0,0 +1,24 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "transactiondescdialog.h"
+#include "ui_transactiondescdialog.h"
+
+#include "transactiontablemodel.h"
+
+#include <QModelIndex>
+
+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 0000000000..54374e359d
--- /dev/null
+++ b/src/qt/transactiondescdialog.h
@@ -0,0 +1,31 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_TRANSACTIONDESCDIALOG_H
+#define BITCOIN_QT_TRANSACTIONDESCDIALOG_H
+
+#include <QDialog>
+
+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 // BITCOIN_QT_TRANSACTIONDESCDIALOG_H
diff --git a/src/qt/transactionfilterproxy.cpp b/src/qt/transactionfilterproxy.cpp
new file mode 100644
index 0000000000..7981eb7c91
--- /dev/null
+++ b/src/qt/transactionfilterproxy.cpp
@@ -0,0 +1,114 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "transactionfilterproxy.h"
+
+#include "transactiontablemodel.h"
+#include "transactionrecord.h"
+
+#include <cstdlib>
+
+#include <QDateTime>
+
+// 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),
+ watchOnlyFilter(WatchOnlyFilter_All),
+ minAmount(0),
+ limitRows(-1),
+ showInactive(true)
+{
+}
+
+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();
+ bool involvesWatchAddress = index.data(TransactionTableModel::WatchonlyRole).toBool();
+ QString address = index.data(TransactionTableModel::AddressRole).toString();
+ QString label = index.data(TransactionTableModel::LabelRole).toString();
+ qint64 amount = llabs(index.data(TransactionTableModel::AmountRole).toLongLong());
+ int status = index.data(TransactionTableModel::StatusRole).toInt();
+
+ if(!showInactive && status == TransactionStatus::Conflicted)
+ return false;
+ if(!(TYPE(type) & typeFilter))
+ return false;
+ if (involvesWatchAddress && watchOnlyFilter == WatchOnlyFilter_No)
+ return false;
+ if (!involvesWatchAddress && watchOnlyFilter == WatchOnlyFilter_Yes)
+ 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(const CAmount& minimum)
+{
+ this->minAmount = minimum;
+ invalidateFilter();
+}
+
+void TransactionFilterProxy::setWatchOnlyFilter(WatchOnlyFilter filter)
+{
+ this->watchOnlyFilter = filter;
+ invalidateFilter();
+}
+
+void TransactionFilterProxy::setLimit(int limit)
+{
+ this->limitRows = limit;
+}
+
+void TransactionFilterProxy::setShowInactive(bool showInactive)
+{
+ this->showInactive = showInactive;
+ invalidateFilter();
+}
+
+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 0000000000..acea9a1e3b
--- /dev/null
+++ b/src/qt/transactionfilterproxy.h
@@ -0,0 +1,68 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_TRANSACTIONFILTERPROXY_H
+#define BITCOIN_QT_TRANSACTIONFILTERPROXY_H
+
+#include "amount.h"
+
+#include <QDateTime>
+#include <QSortFilterProxyModel>
+
+/** 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<<type; }
+
+ enum WatchOnlyFilter
+ {
+ WatchOnlyFilter_All,
+ WatchOnlyFilter_Yes,
+ WatchOnlyFilter_No
+ };
+
+ void setDateRange(const QDateTime &from, const QDateTime &to);
+ void setAddressPrefix(const QString &addrPrefix);
+ /**
+ @note Type filter takes a bit field created with TYPE() or ALL_TYPES
+ */
+ void setTypeFilter(quint32 modes);
+ void setMinAmount(const CAmount& minimum);
+ void setWatchOnlyFilter(WatchOnlyFilter filter);
+
+ /** Set maximum number of rows returned, -1 if unlimited. */
+ void setLimit(int limit);
+
+ /** Set whether to show conflicted transactions. */
+ void setShowInactive(bool showInactive);
+
+ int rowCount(const QModelIndex &parent = QModelIndex()) const;
+
+protected:
+ bool filterAcceptsRow(int source_row, const QModelIndex & source_parent) const;
+
+private:
+ QDateTime dateFrom;
+ QDateTime dateTo;
+ QString addrPrefix;
+ quint32 typeFilter;
+ WatchOnlyFilter watchOnlyFilter;
+ CAmount minAmount;
+ int limitRows;
+ bool showInactive;
+};
+
+#endif // BITCOIN_QT_TRANSACTIONFILTERPROXY_H
diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp
new file mode 100644
index 0000000000..15d13e9fc9
--- /dev/null
+++ b/src/qt/transactionrecord.cpp
@@ -0,0 +1,270 @@
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "transactionrecord.h"
+
+#include "base58.h"
+#include "consensus/consensus.h"
+#include "main.h"
+#include "timedata.h"
+#include "wallet/wallet.h"
+
+#include <stdint.h>
+
+#include <boost/foreach.hpp>
+
+/* Return positive answer if transaction should be shown in list.
+ */
+bool TransactionRecord::showTransaction(const CWalletTx &wtx)
+{
+ if (wtx.IsCoinBase())
+ {
+ // Ensures we show generated coins / mined transactions at depth 1
+ if (!wtx.IsInMainChain())
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+/*
+ * Decompose CWallet transaction to model transaction records.
+ */
+QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet *wallet, const CWalletTx &wtx)
+{
+ QList<TransactionRecord> parts;
+ int64_t nTime = wtx.GetTxTime();
+ CAmount nCredit = wtx.GetCredit(ISMINE_ALL);
+ CAmount nDebit = wtx.GetDebit(ISMINE_ALL);
+ CAmount nNet = nCredit - nDebit;
+ uint256 hash = wtx.GetHash();
+ std::map<std::string, std::string> mapValue = wtx.mapValue;
+
+ if (nNet > 0 || wtx.IsCoinBase())
+ {
+ //
+ // Credit
+ //
+ BOOST_FOREACH(const CTxOut& txout, wtx.vout)
+ {
+ isminetype mine = wallet->IsMine(txout);
+ if(mine)
+ {
+ TransactionRecord sub(hash, nTime);
+ CTxDestination address;
+ sub.idx = parts.size(); // sequence number
+ sub.credit = txout.nValue;
+ sub.involvesWatchAddress = mine == ISMINE_WATCH_ONLY;
+ 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"];
+ }
+ if (wtx.IsCoinBase())
+ {
+ // Generated
+ sub.type = TransactionRecord::Generated;
+ }
+
+ parts.append(sub);
+ }
+ }
+ }
+ else
+ {
+ bool involvesWatchAddress = false;
+ isminetype fAllFromMe = ISMINE_SPENDABLE;
+ BOOST_FOREACH(const CTxIn& txin, wtx.vin)
+ {
+ isminetype mine = wallet->IsMine(txin);
+ if(mine == ISMINE_WATCH_ONLY) involvesWatchAddress = true;
+ if(fAllFromMe > mine) fAllFromMe = mine;
+ }
+
+ isminetype fAllToMe = ISMINE_SPENDABLE;
+ BOOST_FOREACH(const CTxOut& txout, wtx.vout)
+ {
+ isminetype mine = wallet->IsMine(txout);
+ if(mine == ISMINE_WATCH_ONLY) involvesWatchAddress = true;
+ if(fAllToMe > mine) fAllToMe = mine;
+ }
+
+ if (fAllFromMe && fAllToMe)
+ {
+ // Payment to self
+ CAmount nChange = wtx.GetChange();
+
+ parts.append(TransactionRecord(hash, nTime, TransactionRecord::SendToSelf, "",
+ -(nDebit - nChange), nCredit - nChange));
+ parts.last().involvesWatchAddress = involvesWatchAddress; // maybe pass to TransactionRecord as constructor argument
+ }
+ else if (fAllFromMe)
+ {
+ //
+ // Debit
+ //
+ CAmount 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();
+ sub.involvesWatchAddress = involvesWatchAddress;
+
+ 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"];
+ }
+
+ CAmount 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));
+ parts.last().involvesWatchAddress = involvesWatchAddress;
+ }
+ }
+
+ return parts;
+}
+
+void TransactionRecord::updateStatus(const CWalletTx &wtx)
+{
+ AssertLockHeld(cs_main);
+ // Determine transaction status
+
+ // Find the block the tx is in
+ CBlockIndex* pindex = NULL;
+ BlockMap::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<int>::max()),
+ (wtx.IsCoinBase() ? 1 : 0),
+ wtx.nTimeReceived,
+ idx);
+ status.countsForBalance = wtx.IsTrusted() && !(wtx.GetBlocksToMaturity() > 0);
+ status.depth = wtx.GetDepthInMainChain();
+ status.cur_num_blocks = chainActive.Height();
+
+ if (!CheckFinalTx(wtx))
+ {
+ if (wtx.nLockTime < LOCKTIME_THRESHOLD)
+ {
+ status.status = TransactionStatus::OpenUntilBlock;
+ status.open_for = wtx.nLockTime - chainActive.Height();
+ }
+ else
+ {
+ status.status = TransactionStatus::OpenUntilDate;
+ status.open_for = wtx.nLockTime;
+ }
+ }
+ // For generated transactions, determine maturity
+ else if(type == TransactionRecord::Generated)
+ {
+ if (wtx.GetBlocksToMaturity() > 0)
+ {
+ status.status = 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.status = TransactionStatus::MaturesWarning;
+ }
+ else
+ {
+ status.status = TransactionStatus::NotAccepted;
+ }
+ }
+ else
+ {
+ status.status = TransactionStatus::Confirmed;
+ }
+ }
+ else
+ {
+ if (status.depth < 0)
+ {
+ status.status = TransactionStatus::Conflicted;
+ }
+ else if (GetAdjustedTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0)
+ {
+ status.status = TransactionStatus::Offline;
+ }
+ else if (status.depth == 0)
+ {
+ status.status = TransactionStatus::Unconfirmed;
+ }
+ else if (status.depth < RecommendedNumConfirmations)
+ {
+ status.status = TransactionStatus::Confirming;
+ }
+ else
+ {
+ status.status = TransactionStatus::Confirmed;
+ }
+ }
+
+}
+
+bool TransactionRecord::statusUpdateNeeded()
+{
+ AssertLockHeld(cs_main);
+ return status.cur_num_blocks != chainActive.Height();
+}
+
+QString TransactionRecord::getTxID() const
+{
+ return formatSubTxId(hash, idx);
+}
+
+QString TransactionRecord::formatSubTxId(const uint256 &hash, int vout)
+{
+ return QString::fromStdString(hash.ToString() + strprintf("-%03d", vout));
+}
+
diff --git a/src/qt/transactionrecord.h b/src/qt/transactionrecord.h
new file mode 100644
index 0000000000..a5bc375717
--- /dev/null
+++ b/src/qt/transactionrecord.h
@@ -0,0 +1,143 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_TRANSACTIONRECORD_H
+#define BITCOIN_QT_TRANSACTIONRECORD_H
+
+#include "amount.h"
+#include "uint256.h"
+
+#include <QList>
+#include <QString>
+
+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():
+ countsForBalance(false), sortKey(""),
+ matures_in(0), status(Offline), depth(0), open_for(0), cur_num_blocks(-1)
+ { }
+
+ enum Status {
+ Confirmed, /**< Have 6 or more confirmations (normal tx) or fully mature (mined tx) **/
+ /// Normal (sent/received) transactions
+ OpenUntilDate, /**< Transaction not yet final, waiting for date */
+ OpenUntilBlock, /**< Transaction not yet final, waiting for block */
+ Offline, /**< Not sent to any other nodes **/
+ Unconfirmed, /**< Not yet mined into a block **/
+ Confirming, /**< Confirmed, but waiting for the recommended number of confirmations **/
+ Conflicted, /**< Conflicts with other transaction or mempool **/
+ /// Generated (mined) transactions
+ Immature, /**< Mined but waiting for maturity */
+ MaturesWarning, /**< Transaction will likely not mature because no nodes have confirmed */
+ NotAccepted /**< Mined but not accepted */
+ };
+
+ /// Transaction counts towards available balance
+ bool countsForBalance;
+ /// Sorting key based on status
+ std::string sortKey;
+
+ /** @name Generated (mined) transactions
+ @{*/
+ int matures_in;
+ /**@}*/
+
+ /** @name Reported status
+ @{*/
+ Status status;
+ qint64 depth;
+ qint64 open_for; /**< Timestamp if status==OpenUntilDate, otherwise number
+ of additional blocks that need to be mined before
+ finalization */
+ /**@}*/
+
+ /** 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 recommended for accepting a transaction */
+ static const int RecommendedNumConfirmations = 6;
+
+ TransactionRecord():
+ hash(), time(0), type(Other), address(""), debit(0), credit(0), idx(0)
+ {
+ }
+
+ TransactionRecord(uint256 hash, qint64 time):
+ hash(hash), time(time), type(Other), address(""), debit(0),
+ credit(0), idx(0)
+ {
+ }
+
+ TransactionRecord(uint256 hash, qint64 time,
+ Type type, const std::string &address,
+ const CAmount& debit, const CAmount& 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<TransactionRecord> decomposeTransaction(const CWallet *wallet, const CWalletTx &wtx);
+
+ /** @name Immutable transaction attributes
+ @{*/
+ uint256 hash;
+ qint64 time;
+ Type type;
+ std::string address;
+ CAmount debit;
+ CAmount credit;
+ /**@}*/
+
+ /** Subtransaction index, for sort key */
+ int idx;
+
+ /** Status: can change with block chain update */
+ TransactionStatus status;
+
+ /** Whether the transaction was sent/received with a watch-only address */
+ bool involvesWatchAddress;
+
+ /** Return the unique identifier for this transaction (part) */
+ QString getTxID() const;
+
+ /** Format subtransaction id */
+ static QString formatSubTxId(const uint256 &hash, int vout);
+
+ /** Update status from core wallet tx.
+ */
+ void updateStatus(const CWalletTx &wtx);
+
+ /** Return whether a status update is needed.
+ */
+ bool statusUpdateNeeded();
+};
+
+#endif // BITCOIN_QT_TRANSACTIONRECORD_H
diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp
new file mode 100644
index 0000000000..e3d64387f7
--- /dev/null
+++ b/src/qt/transactiontablemodel.cpp
@@ -0,0 +1,733 @@
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "transactiontablemodel.h"
+
+#include "addresstablemodel.h"
+#include "guiconstants.h"
+#include "guiutil.h"
+#include "optionsmodel.h"
+#include "scicon.h"
+#include "transactiondesc.h"
+#include "transactionrecord.h"
+#include "walletmodel.h"
+
+#include "main.h"
+#include "sync.h"
+#include "uint256.h"
+#include "util.h"
+#include "wallet/wallet.h"
+
+#include <QColor>
+#include <QDateTime>
+#include <QDebug>
+#include <QIcon>
+#include <QList>
+
+// Amount column is right-aligned it contains numbers
+static int column_alignments[] = {
+ Qt::AlignLeft|Qt::AlignVCenter, /* status */
+ Qt::AlignLeft|Qt::AlignVCenter, /* watchonly */
+ Qt::AlignLeft|Qt::AlignVCenter, /* date */
+ Qt::AlignLeft|Qt::AlignVCenter, /* type */
+ Qt::AlignLeft|Qt::AlignVCenter, /* address */
+ Qt::AlignRight|Qt::AlignVCenter /* amount */
+ };
+
+// 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<TransactionRecord> cachedWallet;
+
+ /* Query entire wallet anew from core.
+ */
+ void refreshWallet()
+ {
+ qDebug() << "TransactionTablePriv::refreshWallet";
+ cachedWallet.clear();
+ {
+ LOCK2(cs_main, wallet->cs_wallet);
+ for(std::map<uint256, CWalletTx>::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, bool showTransaction)
+ {
+ qDebug() << "TransactionTablePriv::updateWallet: " + QString::fromStdString(hash.ToString()) + " " + QString::number(status);
+
+ // Find bounds of this transaction in model
+ QList<TransactionRecord>::iterator lower = qLowerBound(
+ cachedWallet.begin(), cachedWallet.end(), hash, TxLessThan());
+ QList<TransactionRecord>::iterator upper = qUpperBound(
+ cachedWallet.begin(), cachedWallet.end(), hash, TxLessThan());
+ int lowerIndex = (lower - cachedWallet.begin());
+ int upperIndex = (upper - cachedWallet.begin());
+ bool inModel = (lower != upper);
+
+ 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 */
+ }
+
+ qDebug() << " inModel=" + QString::number(inModel) +
+ " Index=" + QString::number(lowerIndex) + "-" + QString::number(upperIndex) +
+ " showTransaction=" + QString::number(showTransaction) + " derivedStatus=" + QString::number(status);
+
+ switch(status)
+ {
+ case CT_NEW:
+ if(inModel)
+ {
+ qWarning() << "TransactionTablePriv::updateWallet: Warning: Got CT_NEW, but transaction is already in model";
+ break;
+ }
+ if(showTransaction)
+ {
+ LOCK2(cs_main, wallet->cs_wallet);
+ // Find transaction in wallet
+ std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(hash);
+ if(mi == wallet->mapWallet.end())
+ {
+ qWarning() << "TransactionTablePriv::updateWallet: Warning: Got CT_NEW, but transaction is not in wallet";
+ break;
+ }
+ // Added -- insert at the right position
+ QList<TransactionRecord> 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;
+ Q_FOREACH(const TransactionRecord &rec, toInsert)
+ {
+ cachedWallet.insert(insert_idx, rec);
+ insert_idx += 1;
+ }
+ parent->endInsertRows();
+ }
+ }
+ break;
+ case CT_DELETED:
+ if(!inModel)
+ {
+ qWarning() << "TransactionTablePriv::updateWallet: Warning: Got CT_DELETED, but transaction is not in model";
+ 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];
+
+ // Get required locks upfront. This avoids the GUI from getting
+ // stuck if the core is holding the locks for a longer time - for
+ // example, during a wallet rescan.
+ //
+ // 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.
+ TRY_LOCK(cs_main, lockMain);
+ if(lockMain)
+ {
+ TRY_LOCK(wallet->cs_wallet, lockWallet);
+ if(lockWallet && rec->statusUpdateNeeded())
+ {
+ std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(rec->hash);
+
+ if(mi != wallet->mapWallet.end())
+ {
+ rec->updateStatus(mi->second);
+ }
+ }
+ }
+ return rec;
+ }
+ return 0;
+ }
+
+ QString describe(TransactionRecord *rec, int unit)
+ {
+ {
+ LOCK2(cs_main, wallet->cs_wallet);
+ std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(rec->hash);
+ if(mi != wallet->mapWallet.end())
+ {
+ return TransactionDesc::toHTML(wallet, mi->second, rec, unit);
+ }
+ }
+ return QString();
+ }
+};
+
+TransactionTableModel::TransactionTableModel(CWallet* wallet, WalletModel *parent):
+ QAbstractTableModel(parent),
+ wallet(wallet),
+ walletModel(parent),
+ priv(new TransactionTablePriv(wallet, this)),
+ fProcessingQueuedTransactions(false)
+{
+ columns << QString() << QString() << tr("Date") << tr("Type") << tr("Label") << BitcoinUnits::getAmountColumnTitle(walletModel->getOptionsModel()->getDisplayUnit());
+ priv->refreshWallet();
+
+ connect(walletModel->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
+
+ subscribeToCoreSignals();
+}
+
+TransactionTableModel::~TransactionTableModel()
+{
+ unsubscribeFromCoreSignals();
+ delete priv;
+}
+
+/** Updates the column title to "Amount (DisplayUnit)" and emits headerDataChanged() signal for table headers to react. */
+void TransactionTableModel::updateAmountColumnTitle()
+{
+ columns[Amount] = BitcoinUnits::getAmountColumnTitle(walletModel->getOptionsModel()->getDisplayUnit());
+ Q_EMIT headerDataChanged(Qt::Horizontal,Amount,Amount);
+}
+
+void TransactionTableModel::updateTransaction(const QString &hash, int status, bool showTransaction)
+{
+ uint256 updated;
+ updated.SetHex(hash.toStdString());
+
+ priv->updateWallet(updated, status, showTransaction);
+}
+
+void TransactionTableModel::updateConfirmations()
+{
+ // 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.
+ Q_EMIT dataChanged(index(0, Status), index(priv->size()-1, Status));
+ Q_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 more 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");
+ break;
+ case TransactionStatus::Unconfirmed:
+ status = tr("Unconfirmed");
+ break;
+ case TransactionStatus::Confirming:
+ status = tr("Confirming (%1 of %2 recommended confirmations)").arg(wtx->status.depth).arg(TransactionRecord::RecommendedNumConfirmations);
+ break;
+ case TransactionStatus::Confirmed:
+ status = tr("Confirmed (%1 confirmations)").arg(wtx->status.depth);
+ break;
+ case TransactionStatus::Conflicted:
+ status = tr("Conflicted");
+ break;
+ case TransactionStatus::Immature:
+ status = tr("Immature (%1 confirmations, will be available after %2)").arg(wtx->status.depth).arg(wtx->status.depth + wtx->status.matures_in);
+ break;
+ case TransactionStatus::MaturesWarning:
+ status = tr("This block was not received by any other nodes and will probably not be accepted!");
+ break;
+ case TransactionStatus::NotAccepted:
+ status = tr("Generated but not accepted");
+ break;
+ }
+
+ return status;
+}
+
+QString TransactionTableModel::formatTxDate(const TransactionRecord *wtx) const
+{
+ if(wtx->time)
+ {
+ return GUIUtil::dateTimeStr(wtx->time);
+ }
+ 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;
+ }
+ if(label.isEmpty() || 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");
+ }
+}
+
+QString TransactionTableModel::formatTxToAddress(const TransactionRecord *wtx, bool tooltip) const
+{
+ QString watchAddress;
+ if (tooltip) {
+ // Mark transactions involving watch-only addresses by adding " (watch-only)"
+ watchAddress = wtx->involvesWatchAddress ? QString(" (") + tr("watch-only") + QString(")") : "";
+ }
+
+ switch(wtx->type)
+ {
+ case TransactionRecord::RecvFromOther:
+ return QString::fromStdString(wtx->address) + watchAddress;
+ case TransactionRecord::RecvWithAddress:
+ case TransactionRecord::SendToAddress:
+ case TransactionRecord::Generated:
+ return lookupAddress(wtx->address, tooltip) + watchAddress;
+ case TransactionRecord::SendToOther:
+ return QString::fromStdString(wtx->address) + watchAddress;
+ case TransactionRecord::SendToSelf:
+ default:
+ return tr("(n/a)") + watchAddress;
+ }
+}
+
+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:
+ case TransactionRecord::Generated:
+ {
+ QString label = walletModel->getAddressTableModel()->labelForAddress(QString::fromStdString(wtx->address));
+ if(label.isEmpty())
+ return COLOR_BAREADDRESS;
+ } break;
+ case TransactionRecord::SendToSelf:
+ return COLOR_BAREADDRESS;
+ default:
+ break;
+ }
+ return QVariant();
+}
+
+QString TransactionTableModel::formatTxAmount(const TransactionRecord *wtx, bool showUnconfirmed, BitcoinUnits::SeparatorStyle separators) const
+{
+ QString str = BitcoinUnits::format(walletModel->getOptionsModel()->getDisplayUnit(), wtx->credit + wtx->debit, false, separators);
+ if(showUnconfirmed)
+ {
+ if(!wtx->status.countsForBalance)
+ {
+ str = QString("[") + str + QString("]");
+ }
+ }
+ return QString(str);
+}
+
+QVariant TransactionTableModel::txStatusDecoration(const TransactionRecord *wtx) const
+{
+ switch(wtx->status.status)
+ {
+ case TransactionStatus::OpenUntilBlock:
+ case TransactionStatus::OpenUntilDate:
+ return COLOR_TX_STATUS_OPENUNTILDATE;
+ case TransactionStatus::Offline:
+ return COLOR_TX_STATUS_OFFLINE;
+ case TransactionStatus::Unconfirmed:
+ return QIcon(":/icons/transaction_0");
+ case TransactionStatus::Confirming:
+ switch(wtx->status.depth)
+ {
+ 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::Confirmed:
+ return QIcon(":/icons/transaction_confirmed");
+ case TransactionStatus::Conflicted:
+ return QIcon(":/icons/transaction_conflicted");
+ 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::MaturesWarning:
+ case TransactionStatus::NotAccepted:
+ return QIcon(":/icons/transaction_0");
+ default:
+ return COLOR_BLACK;
+ }
+}
+
+QVariant TransactionTableModel::txWatchonlyDecoration(const TransactionRecord *wtx) const
+{
+ if (wtx->involvesWatchAddress)
+ return QIcon(":/icons/eye");
+ else
+ return QVariant();
+}
+
+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<TransactionRecord*>(index.internalPointer());
+
+ switch(role)
+ {
+ case RawDecorationRole:
+ switch(index.column())
+ {
+ case Status:
+ return txStatusDecoration(rec);
+ case Watchonly:
+ return txWatchonlyDecoration(rec);
+ case ToAddress:
+ return txAddressDecoration(rec);
+ }
+ break;
+ case Qt::DecorationRole:
+ {
+ QIcon icon = qvariant_cast<QIcon>(index.data(RawDecorationRole));
+ return TextColorIcon(icon);
+ }
+ 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, true, BitcoinUnits::separatorAlways);
+ }
+ 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 Watchonly:
+ return (rec->involvesWatchAddress ? 1 : 0);
+ case ToAddress:
+ return formatTxToAddress(rec, true);
+ case Amount:
+ return qint64(rec->credit + rec->debit);
+ }
+ break;
+ case Qt::ToolTipRole:
+ return formatTooltip(rec);
+ case Qt::TextAlignmentRole:
+ return column_alignments[index.column()];
+ case Qt::ForegroundRole:
+ // Non-confirmed (but not immature) as transactions are grey
+ if(!rec->status.countsForBalance && rec->status.status != TransactionStatus::Immature)
+ {
+ 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<uint>(rec->time));
+ case WatchonlyRole:
+ return rec->involvesWatchAddress;
+ case WatchonlyDecorationRole:
+ return txWatchonlyDecoration(rec);
+ case LongDescriptionRole:
+ return priv->describe(rec, walletModel->getOptionsModel()->getDisplayUnit());
+ case AddressRole:
+ return QString::fromStdString(rec->address);
+ case LabelRole:
+ return walletModel->getAddressTableModel()->labelForAddress(QString::fromStdString(rec->address));
+ case AmountRole:
+ return qint64(rec->credit + rec->debit);
+ case TxIDRole:
+ return rec->getTxID();
+ case TxHashRole:
+ return QString::fromStdString(rec->hash.ToString());
+ case ConfirmedRole:
+ return rec->status.countsForBalance;
+ case FormattedAmountRole:
+ // Used for copy/export, so don't include separators
+ return formatTxAmount(rec, false, BitcoinUnits::separatorNever);
+ case StatusRole:
+ return rec->status.status;
+ }
+ 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 Watchonly:
+ return tr("Whether or not a watch-only address is involved in this transaction.");
+ case ToAddress:
+ return tr("User-defined intent/purpose of the 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));
+ }
+ return QModelIndex();
+}
+
+void TransactionTableModel::updateDisplayUnit()
+{
+ // emit dataChanged to update Amount column with the current unit
+ updateAmountColumnTitle();
+ Q_EMIT dataChanged(index(0, Amount), index(priv->size()-1, Amount));
+}
+
+// queue notifications to show a non freezing progress dialog e.g. for rescan
+struct TransactionNotification
+{
+public:
+ TransactionNotification() {}
+ TransactionNotification(uint256 hash, ChangeType status, bool showTransaction):
+ hash(hash), status(status), showTransaction(showTransaction) {}
+
+ void invoke(QObject *ttm)
+ {
+ QString strHash = QString::fromStdString(hash.GetHex());
+ qDebug() << "NotifyTransactionChanged: " + strHash + " status= " + QString::number(status);
+ QMetaObject::invokeMethod(ttm, "updateTransaction", Qt::QueuedConnection,
+ Q_ARG(QString, strHash),
+ Q_ARG(int, status),
+ Q_ARG(bool, showTransaction));
+ }
+private:
+ uint256 hash;
+ ChangeType status;
+ bool showTransaction;
+};
+
+static bool fQueueNotifications = false;
+static std::vector< TransactionNotification > vQueueNotifications;
+
+static void NotifyTransactionChanged(TransactionTableModel *ttm, CWallet *wallet, const uint256 &hash, ChangeType status)
+{
+ // Find transaction in wallet
+ std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(hash);
+ // Determine whether to show transaction or not (determine this here so that no relocking is needed in GUI thread)
+ bool inWallet = mi != wallet->mapWallet.end();
+ bool showTransaction = (inWallet && TransactionRecord::showTransaction(mi->second));
+
+ TransactionNotification notification(hash, status, showTransaction);
+
+ if (fQueueNotifications)
+ {
+ vQueueNotifications.push_back(notification);
+ return;
+ }
+ notification.invoke(ttm);
+}
+
+static void ShowProgress(TransactionTableModel *ttm, const std::string &title, int nProgress)
+{
+ if (nProgress == 0)
+ fQueueNotifications = true;
+
+ if (nProgress == 100)
+ {
+ fQueueNotifications = false;
+ if (vQueueNotifications.size() > 10) // prevent balloon spam, show maximum 10 balloons
+ QMetaObject::invokeMethod(ttm, "setProcessingQueuedTransactions", Qt::QueuedConnection, Q_ARG(bool, true));
+ for (unsigned int i = 0; i < vQueueNotifications.size(); ++i)
+ {
+ if (vQueueNotifications.size() - i <= 10)
+ QMetaObject::invokeMethod(ttm, "setProcessingQueuedTransactions", Qt::QueuedConnection, Q_ARG(bool, false));
+
+ vQueueNotifications[i].invoke(ttm);
+ }
+ std::vector<TransactionNotification >().swap(vQueueNotifications); // clear
+ }
+}
+
+void TransactionTableModel::subscribeToCoreSignals()
+{
+ // Connect signals to wallet
+ wallet->NotifyTransactionChanged.connect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3));
+ wallet->ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2));
+}
+
+void TransactionTableModel::unsubscribeFromCoreSignals()
+{
+ // Disconnect signals from wallet
+ wallet->NotifyTransactionChanged.disconnect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3));
+ wallet->ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2));
+}
diff --git a/src/qt/transactiontablemodel.h b/src/qt/transactiontablemodel.h
new file mode 100644
index 0000000000..25c82c764b
--- /dev/null
+++ b/src/qt/transactiontablemodel.h
@@ -0,0 +1,114 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_TRANSACTIONTABLEMODEL_H
+#define BITCOIN_QT_TRANSACTIONTABLEMODEL_H
+
+#include "bitcoinunits.h"
+
+#include <QAbstractTableModel>
+#include <QStringList>
+
+class TransactionRecord;
+class TransactionTablePriv;
+class WalletModel;
+
+class CWallet;
+
+/** 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,
+ Watchonly = 1,
+ Date = 2,
+ Type = 3,
+ ToAddress = 4,
+ Amount = 5
+ };
+
+ /** 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,
+ /** Watch-only boolean */
+ WatchonlyRole,
+ /** Watch-only icon */
+ WatchonlyDecorationRole,
+ /** Long description (HTML format) */
+ LongDescriptionRole,
+ /** Address of transaction */
+ AddressRole,
+ /** Label of address related to transaction */
+ LabelRole,
+ /** Net amount of transaction */
+ AmountRole,
+ /** Unique identifier */
+ TxIDRole,
+ /** Transaction hash */
+ TxHashRole,
+ /** Is transaction confirmed? */
+ ConfirmedRole,
+ /** Formatted amount, without brackets when unconfirmed */
+ FormattedAmountRole,
+ /** Transaction status (TransactionRecord::Status) */
+ StatusRole,
+ /** Unprocessed icon */
+ RawDecorationRole,
+ };
+
+ 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;
+ bool processingQueuedTransactions() { return fProcessingQueuedTransactions; }
+
+private:
+ CWallet* wallet;
+ WalletModel *walletModel;
+ QStringList columns;
+ TransactionTablePriv *priv;
+ bool fProcessingQueuedTransactions;
+
+ void subscribeToCoreSignals();
+ void unsubscribeFromCoreSignals();
+
+ 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, BitcoinUnits::SeparatorStyle separators=BitcoinUnits::separatorStandard) const;
+ QString formatTooltip(const TransactionRecord *rec) const;
+ QVariant txStatusDecoration(const TransactionRecord *wtx) const;
+ QVariant txWatchonlyDecoration(const TransactionRecord *wtx) const;
+ QVariant txAddressDecoration(const TransactionRecord *wtx) const;
+
+public Q_SLOTS:
+ /* New transaction, or transaction changed status */
+ void updateTransaction(const QString &hash, int status, bool showTransaction);
+ void updateConfirmations();
+ void updateDisplayUnit();
+ /** Updates the column title to "Amount (DisplayUnit)" and emits headerDataChanged() signal for table headers to react. */
+ void updateAmountColumnTitle();
+ /* Needed to update fProcessingQueuedTransactions through a QueuedConnection */
+ void setProcessingQueuedTransactions(bool value) { fProcessingQueuedTransactions = value; }
+
+ friend class TransactionTablePriv;
+};
+
+#endif // BITCOIN_QT_TRANSACTIONTABLEMODEL_H
diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp
new file mode 100644
index 0000000000..998789b3ae
--- /dev/null
+++ b/src/qt/transactionview.cpp
@@ -0,0 +1,536 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "transactionview.h"
+
+#include "addresstablemodel.h"
+#include "bitcoinunits.h"
+#include "csvmodelwriter.h"
+#include "editaddressdialog.h"
+#include "guiutil.h"
+#include "optionsmodel.h"
+#include "scicon.h"
+#include "transactiondescdialog.h"
+#include "transactionfilterproxy.h"
+#include "transactionrecord.h"
+#include "transactiontablemodel.h"
+#include "walletmodel.h"
+
+#include "ui_interface.h"
+
+#include <QComboBox>
+#include <QDateTimeEdit>
+#include <QDesktopServices>
+#include <QDoubleValidator>
+#include <QHBoxLayout>
+#include <QHeaderView>
+#include <QLabel>
+#include <QLineEdit>
+#include <QMenu>
+#include <QPoint>
+#include <QScrollBar>
+#include <QSignalMapper>
+#include <QTableView>
+#include <QUrl>
+#include <QVBoxLayout>
+
+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_OS_MAC
+ hlayout->setSpacing(5);
+ hlayout->addSpacing(26);
+#else
+ hlayout->setSpacing(0);
+ hlayout->addSpacing(23);
+#endif
+
+ watchOnlyWidget = new QComboBox(this);
+ watchOnlyWidget->setFixedWidth(24);
+ watchOnlyWidget->addItem("", TransactionFilterProxy::WatchOnlyFilter_All);
+ watchOnlyWidget->addItem(SingleColorIcon(":/icons/eye_plus"), "", TransactionFilterProxy::WatchOnlyFilter_Yes);
+ watchOnlyWidget->addItem(SingleColorIcon(":/icons/eye_minus"), "", TransactionFilterProxy::WatchOnlyFilter_No);
+ hlayout->addWidget(watchOnlyWidget);
+
+ dateWidget = new QComboBox(this);
+#ifdef Q_OS_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_OS_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
+ addressWidget->setPlaceholderText(tr("Enter address or label to search"));
+#endif
+ hlayout->addWidget(addressWidget);
+
+ amountWidget = new QLineEdit(this);
+#if QT_VERSION >= 0x040700
+ amountWidget->setPlaceholderText(tr("Min amount"));
+#endif
+#ifdef Q_OS_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_OS_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);
+
+ view->installEventFilter(this);
+
+ 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 *copyTxIDAction = new QAction(tr("Copy transaction ID"), 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(copyTxIDAction);
+ contextMenu->addAction(editLabelAction);
+ contextMenu->addAction(showDetailsAction);
+
+ mapperThirdPartyTxUrls = new QSignalMapper(this);
+
+ // Connect actions
+ connect(mapperThirdPartyTxUrls, SIGNAL(mapped(QString)), this, SLOT(openThirdPartyTxUrl(QString)));
+
+ connect(dateWidget, SIGNAL(activated(int)), this, SLOT(chooseDate(int)));
+ connect(typeWidget, SIGNAL(activated(int)), this, SLOT(chooseType(int)));
+ connect(watchOnlyWidget, SIGNAL(activated(int)), this, SLOT(chooseWatchonly(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(copyTxIDAction, SIGNAL(triggered()), this, SLOT(copyTxID()));
+ 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->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ 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->setColumnWidth(TransactionTableModel::Status, STATUS_COLUMN_WIDTH);
+ transactionView->setColumnWidth(TransactionTableModel::Watchonly, WATCHONLY_COLUMN_WIDTH);
+ transactionView->setColumnWidth(TransactionTableModel::Date, DATE_COLUMN_WIDTH);
+ transactionView->setColumnWidth(TransactionTableModel::Type, TYPE_COLUMN_WIDTH);
+ transactionView->setColumnWidth(TransactionTableModel::Amount, AMOUNT_MINIMUM_COLUMN_WIDTH);
+
+ columnResizingFixer = new GUIUtil::TableViewLastColumnResizingFixer(transactionView, AMOUNT_MINIMUM_COLUMN_WIDTH, MINIMUM_COLUMN_WIDTH);
+
+ if (model->getOptionsModel())
+ {
+ // Add third party transaction URLs to context menu
+ QStringList listUrls = model->getOptionsModel()->getThirdPartyTxUrls().split("|", QString::SkipEmptyParts);
+ for (int i = 0; i < listUrls.size(); ++i)
+ {
+ QString host = QUrl(listUrls[i].trimmed(), QUrl::StrictMode).host();
+ if (!host.isEmpty())
+ {
+ QAction *thirdPartyTxUrlAction = new QAction(host, this); // use host as menu item label
+ if (i == 0)
+ contextMenu->addSeparator();
+ contextMenu->addAction(thirdPartyTxUrlAction);
+ connect(thirdPartyTxUrlAction, SIGNAL(triggered()), mapperThirdPartyTxUrls, SLOT(map()));
+ mapperThirdPartyTxUrls->setMapping(thirdPartyTxUrlAction, listUrls[i].trimmed());
+ }
+ }
+ }
+
+ // show/hide column Watch-only
+ updateWatchOnlyColumn(model->haveWatchOnly());
+
+ // Watch-only signal
+ connect(model, SIGNAL(notifyWatchonlyChanged(bool)), this, SLOT(updateWatchOnlyColumn(bool)));
+ }
+}
+
+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::chooseWatchonly(int idx)
+{
+ if(!transactionProxyModel)
+ return;
+ transactionProxyModel->setWatchOnlyFilter(
+ (TransactionFilterProxy::WatchOnlyFilter)watchOnlyWidget->itemData(idx).toInt());
+}
+
+void TransactionView::changedPrefix(const QString &prefix)
+{
+ if(!transactionProxyModel)
+ return;
+ transactionProxyModel->setAddressPrefix(prefix);
+}
+
+void TransactionView::changedAmount(const QString &amount)
+{
+ if(!transactionProxyModel)
+ return;
+ CAmount 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 History"), QString(),
+ tr("Comma separated file (*.csv)"), NULL);
+
+ if (filename.isNull())
+ return;
+
+ CSVModelWriter writer(filename);
+
+ // name, column, role
+ writer.setModel(transactionProxyModel);
+ writer.addColumn(tr("Confirmed"), 0, TransactionTableModel::ConfirmedRole);
+ if (model && model->haveWatchOnly())
+ writer.addColumn(tr("Watch-only"), TransactionTableModel::Watchonly);
+ 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(BitcoinUnits::getAmountColumnTitle(model->getOptionsModel()->getDisplayUnit()), 0, TransactionTableModel::FormattedAmountRole);
+ writer.addColumn(tr("ID"), 0, TransactionTableModel::TxIDRole);
+
+ if(!writer.write()) {
+ Q_EMIT message(tr("Exporting Failed"), tr("There was an error trying to save the transaction history to %1.").arg(filename),
+ CClientUIInterface::MSG_ERROR);
+ }
+ else {
+ Q_EMIT message(tr("Exporting Successful"), tr("The transaction history was successfully saved to %1.").arg(filename),
+ CClientUIInterface::MSG_INFORMATION);
+ }
+}
+
+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::copyTxID()
+{
+ GUIUtil::copyEntryData(transactionView, 0, TransactionTableModel::TxIDRole);
+}
+
+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();
+ }
+}
+
+void TransactionView::openThirdPartyTxUrl(QString url)
+{
+ if(!transactionView || !transactionView->selectionModel())
+ return;
+ QModelIndexList selection = transactionView->selectionModel()->selectedRows(0);
+ if(!selection.isEmpty())
+ QDesktopServices::openUrl(QUrl::fromUserInput(url.replace("%s", selection.at(0).data(TransactionTableModel::TxHashRole).toString())));
+}
+
+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();
+}
+
+// We override the virtual resizeEvent of the QWidget to adjust tables column
+// sizes as the tables width is proportional to the dialogs width.
+void TransactionView::resizeEvent(QResizeEvent* event)
+{
+ QWidget::resizeEvent(event);
+ columnResizingFixer->stretchColumnWidth(TransactionTableModel::ToAddress);
+}
+
+// Need to override default Ctrl+C action for amount as default behaviour is just to copy DisplayRole text
+bool TransactionView::eventFilter(QObject *obj, QEvent *event)
+{
+ if (event->type() == QEvent::KeyPress)
+ {
+ QKeyEvent *ke = static_cast<QKeyEvent *>(event);
+ if (ke->key() == Qt::Key_C && ke->modifiers().testFlag(Qt::ControlModifier))
+ {
+ QModelIndex i = this->transactionView->currentIndex();
+ if (i.isValid() && i.column() == TransactionTableModel::Amount)
+ {
+ GUIUtil::setClipboard(i.data(TransactionTableModel::FormattedAmountRole).toString());
+ return true;
+ }
+ }
+ }
+ return QWidget::eventFilter(obj, event);
+}
+
+// show/hide column Watch-only
+void TransactionView::updateWatchOnlyColumn(bool fHaveWatchOnly)
+{
+ watchOnlyWidget->setVisible(fHaveWatchOnly);
+ transactionView->setColumnHidden(TransactionTableModel::Watchonly, !fHaveWatchOnly);
+}
diff --git a/src/qt/transactionview.h b/src/qt/transactionview.h
new file mode 100644
index 0000000000..6c35362be4
--- /dev/null
+++ b/src/qt/transactionview.h
@@ -0,0 +1,115 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_TRANSACTIONVIEW_H
+#define BITCOIN_QT_TRANSACTIONVIEW_H
+
+#include "guiutil.h"
+
+#include <QWidget>
+#include <QKeyEvent>
+
+class TransactionFilterProxy;
+class WalletModel;
+
+QT_BEGIN_NAMESPACE
+class QComboBox;
+class QDateTimeEdit;
+class QFrame;
+class QLineEdit;
+class QMenu;
+class QModelIndex;
+class QSignalMapper;
+class QTableView;
+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
+ };
+
+ enum ColumnWidths {
+ STATUS_COLUMN_WIDTH = 30,
+ WATCHONLY_COLUMN_WIDTH = 23,
+ DATE_COLUMN_WIDTH = 120,
+ TYPE_COLUMN_WIDTH = 113,
+ AMOUNT_MINIMUM_COLUMN_WIDTH = 120,
+ MINIMUM_COLUMN_WIDTH = 23
+ };
+
+private:
+ WalletModel *model;
+ TransactionFilterProxy *transactionProxyModel;
+ QTableView *transactionView;
+
+ QComboBox *dateWidget;
+ QComboBox *typeWidget;
+ QComboBox *watchOnlyWidget;
+ QLineEdit *addressWidget;
+ QLineEdit *amountWidget;
+
+ QMenu *contextMenu;
+ QSignalMapper *mapperThirdPartyTxUrls;
+
+ QFrame *dateRangeWidget;
+ QDateTimeEdit *dateFrom;
+ QDateTimeEdit *dateTo;
+
+ QWidget *createDateRangeWidget();
+
+ GUIUtil::TableViewLastColumnResizingFixer *columnResizingFixer;
+
+ virtual void resizeEvent(QResizeEvent* event);
+
+ bool eventFilter(QObject *obj, QEvent *event);
+
+private Q_SLOTS:
+ void contextualMenu(const QPoint &);
+ void dateRangeChanged();
+ void showDetails();
+ void copyAddress();
+ void editLabel();
+ void copyLabel();
+ void copyAmount();
+ void copyTxID();
+ void openThirdPartyTxUrl(QString url);
+ void updateWatchOnlyColumn(bool fHaveWatchOnly);
+
+Q_SIGNALS:
+ void doubleClicked(const QModelIndex&);
+
+ /** Fired when a message should be reported to the user */
+ void message(const QString &title, const QString &message, unsigned int style);
+
+public Q_SLOTS:
+ void chooseDate(int idx);
+ void chooseType(int idx);
+ void chooseWatchonly(int idx);
+ void changedPrefix(const QString &prefix);
+ void changedAmount(const QString &amount);
+ void exportClicked();
+ void focusTransaction(const QModelIndex&);
+
+};
+
+#endif // BITCOIN_QT_TRANSACTIONVIEW_H
diff --git a/src/qt/utilitydialog.cpp b/src/qt/utilitydialog.cpp
new file mode 100644
index 0000000000..5e26f3e01b
--- /dev/null
+++ b/src/qt/utilitydialog.cpp
@@ -0,0 +1,173 @@
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "utilitydialog.h"
+
+#include "ui_helpmessagedialog.h"
+
+#include "bitcoingui.h"
+#include "clientmodel.h"
+#include "guiutil.h"
+
+#include "clientversion.h"
+#include "init.h"
+#include "util.h"
+
+#include <stdio.h>
+
+#include <QCloseEvent>
+#include <QLabel>
+#include <QRegExp>
+#include <QTextTable>
+#include <QTextCursor>
+#include <QVBoxLayout>
+
+/** "Help message" or "About" dialog box */
+HelpMessageDialog::HelpMessageDialog(QWidget *parent, bool about) :
+ QDialog(parent),
+ ui(new Ui::HelpMessageDialog)
+{
+ ui->setupUi(this);
+
+ QString version = tr("Bitcoin Core") + " " + tr("version") + " " + QString::fromStdString(FormatFullVersion());
+ /* On x86 add a bit specifier to the version so that users can distinguish between
+ * 32 and 64 bit builds. On other architectures, 32/64 bit may be more ambigious.
+ */
+#if defined(__x86_64__)
+ version += " " + tr("(%1-bit)").arg(64);
+#elif defined(__i386__ )
+ version += " " + tr("(%1-bit)").arg(32);
+#endif
+
+ if (about)
+ {
+ setWindowTitle(tr("About Bitcoin Core"));
+
+ /// HTML-format the license message from the core
+ QString licenseInfo = QString::fromStdString(LicenseInfo());
+ QString licenseInfoHTML = licenseInfo;
+ // Make URLs clickable
+ QRegExp uri("<(.*)>", Qt::CaseSensitive, QRegExp::RegExp2);
+ uri.setMinimal(true); // use non-greedy matching
+ licenseInfoHTML.replace(uri, "<a href=\"\\1\">\\1</a>");
+ // Replace newlines with HTML breaks
+ licenseInfoHTML.replace("\n\n", "<br><br>");
+
+ ui->aboutMessage->setTextFormat(Qt::RichText);
+ ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+ text = version + "\n" + licenseInfo;
+ ui->aboutMessage->setText(version + "<br><br>" + licenseInfoHTML);
+ ui->aboutMessage->setWordWrap(true);
+ ui->helpMessage->setVisible(false);
+ } else {
+ setWindowTitle(tr("Command-line options"));
+ QString header = tr("Usage:") + "\n" +
+ " bitcoin-qt [" + tr("command-line options") + "] " + "\n";
+ QTextCursor cursor(ui->helpMessage->document());
+ cursor.insertText(version);
+ cursor.insertBlock();
+ cursor.insertText(header);
+ cursor.insertBlock();
+
+ QString coreOptions = QString::fromStdString(HelpMessage(HMM_BITCOIN_QT));
+ text = version + "\n" + header + "\n" + coreOptions;
+
+ QTextTableFormat tf;
+ tf.setBorderStyle(QTextFrameFormat::BorderStyle_None);
+ tf.setCellPadding(2);
+ QVector<QTextLength> widths;
+ widths << QTextLength(QTextLength::PercentageLength, 35);
+ widths << QTextLength(QTextLength::PercentageLength, 65);
+ tf.setColumnWidthConstraints(widths);
+
+ QTextCharFormat bold;
+ bold.setFontWeight(QFont::Bold);
+
+ Q_FOREACH (const QString &line, coreOptions.split("\n")) {
+ if (line.startsWith(" -"))
+ {
+ cursor.currentTable()->appendRows(1);
+ cursor.movePosition(QTextCursor::PreviousCell);
+ cursor.movePosition(QTextCursor::NextRow);
+ cursor.insertText(line.trimmed());
+ cursor.movePosition(QTextCursor::NextCell);
+ } else if (line.startsWith(" ")) {
+ cursor.insertText(line.trimmed()+' ');
+ } else if (line.size() > 0) {
+ //Title of a group
+ if (cursor.currentTable())
+ cursor.currentTable()->appendRows(1);
+ cursor.movePosition(QTextCursor::Down);
+ cursor.insertText(line.trimmed(), bold);
+ cursor.insertTable(1, 2, tf);
+ }
+ }
+
+ ui->helpMessage->moveCursor(QTextCursor::Start);
+ ui->scrollArea->setVisible(false);
+ ui->aboutLogo->setVisible(false);
+ }
+}
+
+HelpMessageDialog::~HelpMessageDialog()
+{
+ delete ui;
+}
+
+void HelpMessageDialog::printToConsole()
+{
+ // On other operating systems, the expected action is to print the message to the console.
+ fprintf(stdout, "%s\n", qPrintable(text));
+}
+
+void HelpMessageDialog::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
+}
+
+void HelpMessageDialog::on_okButton_accepted()
+{
+ close();
+}
+
+
+/** "Shutdown" window */
+ShutdownWindow::ShutdownWindow(QWidget *parent, Qt::WindowFlags f):
+ QWidget(parent, f)
+{
+ QVBoxLayout *layout = new QVBoxLayout();
+ layout->addWidget(new QLabel(
+ tr("Bitcoin Core is shutting down...") + "<br /><br />" +
+ tr("Do not shut down the computer until this window disappears.")));
+ setLayout(layout);
+}
+
+void ShutdownWindow::showShutdownWindow(BitcoinGUI *window)
+{
+ if (!window)
+ return;
+
+ // Show a simple window indicating shutdown status
+ QWidget *shutdownWindow = new ShutdownWindow();
+ // We don't hold a direct pointer to the shutdown window after creation, so use
+ // Qt::WA_DeleteOnClose to make sure that the window will be deleted eventually.
+ shutdownWindow->setAttribute(Qt::WA_DeleteOnClose);
+ shutdownWindow->setWindowTitle(window->windowTitle());
+
+ // Center shutdown window at where main window was
+ const QPoint global = window->mapToGlobal(window->rect().center());
+ shutdownWindow->move(global.x() - shutdownWindow->width() / 2, global.y() - shutdownWindow->height() / 2);
+ shutdownWindow->show();
+}
+
+void ShutdownWindow::closeEvent(QCloseEvent *event)
+{
+ event->ignore();
+}
diff --git a/src/qt/utilitydialog.h b/src/qt/utilitydialog.h
new file mode 100644
index 0000000000..47282ae2d0
--- /dev/null
+++ b/src/qt/utilitydialog.h
@@ -0,0 +1,52 @@
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_UTILITYDIALOG_H
+#define BITCOIN_QT_UTILITYDIALOG_H
+
+#include <QDialog>
+#include <QObject>
+
+class BitcoinGUI;
+class ClientModel;
+
+namespace Ui {
+ class HelpMessageDialog;
+}
+
+/** "Help message" dialog box */
+class HelpMessageDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit HelpMessageDialog(QWidget *parent, bool about);
+ ~HelpMessageDialog();
+
+ void printToConsole();
+ void showOrPrint();
+
+private:
+ Ui::HelpMessageDialog *ui;
+ QString text;
+
+private Q_SLOTS:
+ void on_okButton_accepted();
+};
+
+
+/** "Shutdown" window */
+class ShutdownWindow : public QWidget
+{
+ Q_OBJECT
+
+public:
+ ShutdownWindow(QWidget *parent=0, Qt::WindowFlags f=0);
+ static void showShutdownWindow(BitcoinGUI *window);
+
+protected:
+ void closeEvent(QCloseEvent *event);
+};
+
+#endif // BITCOIN_QT_UTILITYDIALOG_H
diff --git a/src/qt/walletframe.cpp b/src/qt/walletframe.cpp
new file mode 100644
index 0000000000..892947bf3a
--- /dev/null
+++ b/src/qt/walletframe.cpp
@@ -0,0 +1,196 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "walletframe.h"
+
+#include "bitcoingui.h"
+#include "walletview.h"
+
+#include <cstdio>
+
+#include <QHBoxLayout>
+#include <QLabel>
+
+WalletFrame::WalletFrame(BitcoinGUI *_gui) :
+ QFrame(_gui),
+ gui(_gui)
+{
+ // Leave HBox hook for adding a list view later
+ QHBoxLayout *walletFrameLayout = new QHBoxLayout(this);
+ setContentsMargins(0,0,0,0);
+ walletStack = new QStackedWidget(this);
+ walletFrameLayout->setContentsMargins(0,0,0,0);
+ walletFrameLayout->addWidget(walletStack);
+
+ QLabel *noWallet = new QLabel(tr("No wallet has been loaded."));
+ noWallet->setAlignment(Qt::AlignCenter);
+ walletStack->addWidget(noWallet);
+}
+
+WalletFrame::~WalletFrame()
+{
+}
+
+void WalletFrame::setClientModel(ClientModel *clientModel)
+{
+ this->clientModel = clientModel;
+}
+
+bool WalletFrame::addWallet(const QString& name, WalletModel *walletModel)
+{
+ if (!gui || !clientModel || !walletModel || mapWalletViews.count(name) > 0)
+ return false;
+
+ WalletView *walletView = new WalletView(this);
+ walletView->setBitcoinGUI(gui);
+ walletView->setClientModel(clientModel);
+ walletView->setWalletModel(walletModel);
+ walletView->showOutOfSyncWarning(bOutOfSync);
+
+ /* TODO we should goto the currently selected page once dynamically adding wallets is supported */
+ walletView->gotoOverviewPage();
+ walletStack->addWidget(walletView);
+ mapWalletViews[name] = walletView;
+
+ // Ensure a walletView is able to show the main window
+ connect(walletView, SIGNAL(showNormalIfMinimized()), gui, SLOT(showNormalIfMinimized()));
+
+ return true;
+}
+
+bool WalletFrame::setCurrentWallet(const QString& name)
+{
+ if (mapWalletViews.count(name) == 0)
+ return false;
+
+ WalletView *walletView = mapWalletViews.value(name);
+ walletStack->setCurrentWidget(walletView);
+ walletView->updateEncryptionStatus();
+ return true;
+}
+
+bool WalletFrame::removeWallet(const QString &name)
+{
+ if (mapWalletViews.count(name) == 0)
+ return false;
+
+ WalletView *walletView = mapWalletViews.take(name);
+ walletStack->removeWidget(walletView);
+ return true;
+}
+
+void WalletFrame::removeAllWallets()
+{
+ QMap<QString, WalletView*>::const_iterator i;
+ for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
+ walletStack->removeWidget(i.value());
+ mapWalletViews.clear();
+}
+
+bool WalletFrame::handlePaymentRequest(const SendCoinsRecipient &recipient)
+{
+ WalletView *walletView = currentWalletView();
+ if (!walletView)
+ return false;
+
+ return walletView->handlePaymentRequest(recipient);
+}
+
+void WalletFrame::showOutOfSyncWarning(bool fShow)
+{
+ bOutOfSync = fShow;
+ QMap<QString, WalletView*>::const_iterator i;
+ for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
+ i.value()->showOutOfSyncWarning(fShow);
+}
+
+void WalletFrame::gotoOverviewPage()
+{
+ QMap<QString, WalletView*>::const_iterator i;
+ for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
+ i.value()->gotoOverviewPage();
+}
+
+void WalletFrame::gotoHistoryPage()
+{
+ QMap<QString, WalletView*>::const_iterator i;
+ for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
+ i.value()->gotoHistoryPage();
+}
+
+void WalletFrame::gotoReceiveCoinsPage()
+{
+ QMap<QString, WalletView*>::const_iterator i;
+ for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
+ i.value()->gotoReceiveCoinsPage();
+}
+
+void WalletFrame::gotoSendCoinsPage(QString addr)
+{
+ QMap<QString, WalletView*>::const_iterator i;
+ for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
+ i.value()->gotoSendCoinsPage(addr);
+}
+
+void WalletFrame::gotoSignMessageTab(QString addr)
+{
+ WalletView *walletView = currentWalletView();
+ if (walletView)
+ walletView->gotoSignMessageTab(addr);
+}
+
+void WalletFrame::gotoVerifyMessageTab(QString addr)
+{
+ WalletView *walletView = currentWalletView();
+ if (walletView)
+ walletView->gotoVerifyMessageTab(addr);
+}
+
+void WalletFrame::encryptWallet(bool status)
+{
+ WalletView *walletView = currentWalletView();
+ if (walletView)
+ walletView->encryptWallet(status);
+}
+
+void WalletFrame::backupWallet()
+{
+ WalletView *walletView = currentWalletView();
+ if (walletView)
+ walletView->backupWallet();
+}
+
+void WalletFrame::changePassphrase()
+{
+ WalletView *walletView = currentWalletView();
+ if (walletView)
+ walletView->changePassphrase();
+}
+
+void WalletFrame::unlockWallet()
+{
+ WalletView *walletView = currentWalletView();
+ if (walletView)
+ walletView->unlockWallet();
+}
+
+void WalletFrame::usedSendingAddresses()
+{
+ WalletView *walletView = currentWalletView();
+ if (walletView)
+ walletView->usedSendingAddresses();
+}
+
+void WalletFrame::usedReceivingAddresses()
+{
+ WalletView *walletView = currentWalletView();
+ if (walletView)
+ walletView->usedReceivingAddresses();
+}
+
+WalletView *WalletFrame::currentWalletView()
+{
+ return qobject_cast<WalletView*>(walletStack->currentWidget());
+}
+
diff --git a/src/qt/walletframe.h b/src/qt/walletframe.h
new file mode 100644
index 0000000000..5a5e2ab944
--- /dev/null
+++ b/src/qt/walletframe.h
@@ -0,0 +1,80 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_WALLETFRAME_H
+#define BITCOIN_QT_WALLETFRAME_H
+
+#include <QFrame>
+#include <QMap>
+
+class BitcoinGUI;
+class ClientModel;
+class SendCoinsRecipient;
+class WalletModel;
+class WalletView;
+
+QT_BEGIN_NAMESPACE
+class QStackedWidget;
+QT_END_NAMESPACE
+
+class WalletFrame : public QFrame
+{
+ Q_OBJECT
+
+public:
+ explicit WalletFrame(BitcoinGUI *_gui = 0);
+ ~WalletFrame();
+
+ void setClientModel(ClientModel *clientModel);
+
+ bool addWallet(const QString& name, WalletModel *walletModel);
+ bool setCurrentWallet(const QString& name);
+ bool removeWallet(const QString &name);
+ void removeAllWallets();
+
+ bool handlePaymentRequest(const SendCoinsRecipient& recipient);
+
+ void showOutOfSyncWarning(bool fShow);
+
+private:
+ QStackedWidget *walletStack;
+ BitcoinGUI *gui;
+ ClientModel *clientModel;
+ QMap<QString, WalletView*> mapWalletViews;
+
+ bool bOutOfSync;
+
+ WalletView *currentWalletView();
+
+public Q_SLOTS:
+ /** Switch to overview (home) page */
+ void gotoOverviewPage();
+ /** Switch to history (transactions) page */
+ void gotoHistoryPage();
+ /** Switch to receive coins page */
+ void gotoReceiveCoinsPage();
+ /** Switch to send coins page */
+ void gotoSendCoinsPage(QString addr = "");
+
+ /** 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 = "");
+
+ /** Encrypt the wallet */
+ void encryptWallet(bool status);
+ /** Backup the wallet */
+ void backupWallet();
+ /** Change encrypted wallet passphrase */
+ void changePassphrase();
+ /** Ask for passphrase to unlock wallet temporarily */
+ void unlockWallet();
+
+ /** Show used sending addresses */
+ void usedSendingAddresses();
+ /** Show used receiving addresses */
+ void usedReceivingAddresses();
+};
+
+#endif // BITCOIN_QT_WALLETFRAME_H
diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp
new file mode 100644
index 0000000000..2691fa9309
--- /dev/null
+++ b/src/qt/walletmodel.cpp
@@ -0,0 +1,663 @@
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "walletmodel.h"
+
+#include "addresstablemodel.h"
+#include "guiconstants.h"
+#include "guiutil.h"
+#include "paymentserver.h"
+#include "recentrequeststablemodel.h"
+#include "transactiontablemodel.h"
+
+#include "base58.h"
+#include "keystore.h"
+#include "main.h"
+#include "sync.h"
+#include "ui_interface.h"
+#include "wallet/wallet.h"
+#include "wallet/walletdb.h" // for BackupWallet
+
+#include <stdint.h>
+
+#include <QDebug>
+#include <QSet>
+#include <QTimer>
+
+using namespace std;
+
+WalletModel::WalletModel(CWallet *wallet, OptionsModel *optionsModel, QObject *parent) :
+ QObject(parent), wallet(wallet), optionsModel(optionsModel), addressTableModel(0),
+ transactionTableModel(0),
+ recentRequestsTableModel(0),
+ cachedBalance(0), cachedUnconfirmedBalance(0), cachedImmatureBalance(0),
+ cachedEncryptionStatus(Unencrypted),
+ cachedNumBlocks(0)
+{
+ fHaveWatchOnly = wallet->HaveWatchOnly();
+ fForceCheckBalanceChanged = false;
+
+ addressTableModel = new AddressTableModel(wallet, this);
+ transactionTableModel = new TransactionTableModel(wallet, this);
+ recentRequestsTableModel = new RecentRequestsTableModel(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();
+}
+
+CAmount WalletModel::getBalance(const CCoinControl *coinControl) const
+{
+ if (coinControl)
+ {
+ CAmount nBalance = 0;
+ std::vector<COutput> vCoins;
+ wallet->AvailableCoins(vCoins, true, coinControl);
+ BOOST_FOREACH(const COutput& out, vCoins)
+ if(out.fSpendable)
+ nBalance += out.tx->vout[out.i].nValue;
+
+ return nBalance;
+ }
+
+ return wallet->GetBalance();
+}
+
+CAmount WalletModel::getUnconfirmedBalance() const
+{
+ return wallet->GetUnconfirmedBalance();
+}
+
+CAmount WalletModel::getImmatureBalance() const
+{
+ return wallet->GetImmatureBalance();
+}
+
+bool WalletModel::haveWatchOnly() const
+{
+ return fHaveWatchOnly;
+}
+
+CAmount WalletModel::getWatchBalance() const
+{
+ return wallet->GetWatchOnlyBalance();
+}
+
+CAmount WalletModel::getWatchUnconfirmedBalance() const
+{
+ return wallet->GetUnconfirmedWatchOnlyBalance();
+}
+
+CAmount WalletModel::getWatchImmatureBalance() const
+{
+ return wallet->GetImmatureWatchOnlyBalance();
+}
+
+void WalletModel::updateStatus()
+{
+ EncryptionStatus newEncryptionStatus = getEncryptionStatus();
+
+ if(cachedEncryptionStatus != newEncryptionStatus)
+ Q_EMIT encryptionStatusChanged(newEncryptionStatus);
+}
+
+void WalletModel::pollBalanceChanged()
+{
+ // Get required locks upfront. This avoids the GUI from getting stuck on
+ // periodical polls if the core is holding the locks for a longer time -
+ // for example, during a wallet rescan.
+ TRY_LOCK(cs_main, lockMain);
+ if(!lockMain)
+ return;
+ TRY_LOCK(wallet->cs_wallet, lockWallet);
+ if(!lockWallet)
+ return;
+
+ if(fForceCheckBalanceChanged || chainActive.Height() != cachedNumBlocks)
+ {
+ fForceCheckBalanceChanged = false;
+
+ // Balance and number of transactions might have changed
+ cachedNumBlocks = chainActive.Height();
+
+ checkBalanceChanged();
+ if(transactionTableModel)
+ transactionTableModel->updateConfirmations();
+ }
+}
+
+void WalletModel::checkBalanceChanged()
+{
+ CAmount newBalance = getBalance();
+ CAmount newUnconfirmedBalance = getUnconfirmedBalance();
+ CAmount newImmatureBalance = getImmatureBalance();
+ CAmount newWatchOnlyBalance = 0;
+ CAmount newWatchUnconfBalance = 0;
+ CAmount newWatchImmatureBalance = 0;
+ if (haveWatchOnly())
+ {
+ newWatchOnlyBalance = getWatchBalance();
+ newWatchUnconfBalance = getWatchUnconfirmedBalance();
+ newWatchImmatureBalance = getWatchImmatureBalance();
+ }
+
+ if(cachedBalance != newBalance || cachedUnconfirmedBalance != newUnconfirmedBalance || cachedImmatureBalance != newImmatureBalance ||
+ cachedWatchOnlyBalance != newWatchOnlyBalance || cachedWatchUnconfBalance != newWatchUnconfBalance || cachedWatchImmatureBalance != newWatchImmatureBalance)
+ {
+ cachedBalance = newBalance;
+ cachedUnconfirmedBalance = newUnconfirmedBalance;
+ cachedImmatureBalance = newImmatureBalance;
+ cachedWatchOnlyBalance = newWatchOnlyBalance;
+ cachedWatchUnconfBalance = newWatchUnconfBalance;
+ cachedWatchImmatureBalance = newWatchImmatureBalance;
+ Q_EMIT balanceChanged(newBalance, newUnconfirmedBalance, newImmatureBalance,
+ newWatchOnlyBalance, newWatchUnconfBalance, newWatchImmatureBalance);
+ }
+}
+
+void WalletModel::updateTransaction()
+{
+ // Balance and number of transactions might have changed
+ fForceCheckBalanceChanged = true;
+}
+
+void WalletModel::updateAddressBook(const QString &address, const QString &label,
+ bool isMine, const QString &purpose, int status)
+{
+ if(addressTableModel)
+ addressTableModel->updateEntry(address, label, isMine, purpose, status);
+}
+
+void WalletModel::updateWatchOnlyFlag(bool fHaveWatchonly)
+{
+ fHaveWatchOnly = fHaveWatchonly;
+ Q_EMIT notifyWatchonlyChanged(fHaveWatchonly);
+}
+
+bool WalletModel::validateAddress(const QString &address)
+{
+ CBitcoinAddress addressParsed(address.toStdString());
+ return addressParsed.IsValid();
+}
+
+WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransaction &transaction, const CCoinControl *coinControl)
+{
+ CAmount total = 0;
+ bool fSubtractFeeFromAmount = false;
+ QList<SendCoinsRecipient> recipients = transaction.getRecipients();
+ std::vector<CRecipient> vecSend;
+
+ if(recipients.empty())
+ {
+ return OK;
+ }
+
+ QSet<QString> setAddress; // Used to detect duplicates
+ int nAddresses = 0;
+
+ // Pre-check input data for validity
+ Q_FOREACH(const SendCoinsRecipient &rcp, recipients)
+ {
+ if (rcp.fSubtractFeeFromAmount)
+ fSubtractFeeFromAmount = true;
+
+ if (rcp.paymentRequest.IsInitialized())
+ { // PaymentRequest...
+ CAmount subtotal = 0;
+ const payments::PaymentDetails& details = rcp.paymentRequest.getDetails();
+ for (int i = 0; i < details.outputs_size(); i++)
+ {
+ const payments::Output& out = details.outputs(i);
+ if (out.amount() <= 0) continue;
+ subtotal += out.amount();
+ const unsigned char* scriptStr = (const unsigned char*)out.script().data();
+ CScript scriptPubKey(scriptStr, scriptStr+out.script().size());
+ CAmount nAmount = out.amount();
+ CRecipient recipient = {scriptPubKey, nAmount, rcp.fSubtractFeeFromAmount};
+ vecSend.push_back(recipient);
+ }
+ if (subtotal <= 0)
+ {
+ return InvalidAmount;
+ }
+ total += subtotal;
+ }
+ else
+ { // User-entered bitcoin address / amount:
+ if(!validateAddress(rcp.address))
+ {
+ return InvalidAddress;
+ }
+ if(rcp.amount <= 0)
+ {
+ return InvalidAmount;
+ }
+ setAddress.insert(rcp.address);
+ ++nAddresses;
+
+ CScript scriptPubKey = GetScriptForDestination(CBitcoinAddress(rcp.address.toStdString()).Get());
+ CRecipient recipient = {scriptPubKey, rcp.amount, rcp.fSubtractFeeFromAmount};
+ vecSend.push_back(recipient);
+
+ total += rcp.amount;
+ }
+ }
+ if(setAddress.size() != nAddresses)
+ {
+ return DuplicateAddress;
+ }
+
+ CAmount nBalance = getBalance(coinControl);
+
+ if(total > nBalance)
+ {
+ return AmountExceedsBalance;
+ }
+
+ {
+ LOCK2(cs_main, wallet->cs_wallet);
+
+ transaction.newPossibleKeyChange(wallet);
+
+ CAmount nFeeRequired = 0;
+ int nChangePosRet = -1;
+ std::string strFailReason;
+
+ CWalletTx *newTx = transaction.getTransaction();
+ CReserveKey *keyChange = transaction.getPossibleKeyChange();
+ bool fCreated = wallet->CreateTransaction(vecSend, *newTx, *keyChange, nFeeRequired, nChangePosRet, strFailReason, coinControl);
+ transaction.setTransactionFee(nFeeRequired);
+ if (fSubtractFeeFromAmount && fCreated)
+ transaction.reassignAmounts(nChangePosRet);
+
+ if(!fCreated)
+ {
+ if(!fSubtractFeeFromAmount && (total + nFeeRequired) > nBalance)
+ {
+ return SendCoinsReturn(AmountWithFeeExceedsBalance);
+ }
+ Q_EMIT message(tr("Send Coins"), QString::fromStdString(strFailReason),
+ CClientUIInterface::MSG_ERROR);
+ return TransactionCreationFailed;
+ }
+
+ // reject absurdly high fee > 0.1 bitcoin
+ if (nFeeRequired > 10000000)
+ return AbsurdFee;
+ }
+
+ return SendCoinsReturn(OK);
+}
+
+WalletModel::SendCoinsReturn WalletModel::sendCoins(WalletModelTransaction &transaction)
+{
+ QByteArray transaction_array; /* store serialized transaction */
+
+ {
+ LOCK2(cs_main, wallet->cs_wallet);
+ CWalletTx *newTx = transaction.getTransaction();
+
+ Q_FOREACH(const SendCoinsRecipient &rcp, transaction.getRecipients())
+ {
+ if (rcp.paymentRequest.IsInitialized())
+ {
+ // Make sure any payment requests involved are still valid.
+ if (PaymentServer::verifyExpired(rcp.paymentRequest.getDetails())) {
+ return PaymentRequestExpired;
+ }
+
+ // Store PaymentRequests in wtx.vOrderForm in wallet.
+ std::string key("PaymentRequest");
+ std::string value;
+ rcp.paymentRequest.SerializeToString(&value);
+ newTx->vOrderForm.push_back(make_pair(key, value));
+ }
+ else if (!rcp.message.isEmpty()) // Message from normal bitcoin:URI (bitcoin:123...?message=example)
+ newTx->vOrderForm.push_back(make_pair("Message", rcp.message.toStdString()));
+ }
+
+ CReserveKey *keyChange = transaction.getPossibleKeyChange();
+ if(!wallet->CommitTransaction(*newTx, *keyChange))
+ return TransactionCommitFailed;
+
+ CTransaction* t = (CTransaction*)newTx;
+ CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
+ ssTx << *t;
+ transaction_array.append(&(ssTx[0]), ssTx.size());
+ }
+
+ // Add addresses / update labels that we've sent to to the address book,
+ // and emit coinsSent signal for each recipient
+ Q_FOREACH(const SendCoinsRecipient &rcp, transaction.getRecipients())
+ {
+ // Don't touch the address book when we have a payment request
+ if (!rcp.paymentRequest.IsInitialized())
+ {
+ std::string strAddress = rcp.address.toStdString();
+ CTxDestination dest = CBitcoinAddress(strAddress).Get();
+ std::string strLabel = rcp.label.toStdString();
+ {
+ LOCK(wallet->cs_wallet);
+
+ std::map<CTxDestination, CAddressBookData>::iterator mi = wallet->mapAddressBook.find(dest);
+
+ // Check if we have a new address or an updated label
+ if (mi == wallet->mapAddressBook.end())
+ {
+ wallet->SetAddressBook(dest, strLabel, "send");
+ }
+ else if (mi->second.name != strLabel)
+ {
+ wallet->SetAddressBook(dest, strLabel, ""); // "" means don't change purpose
+ }
+ }
+ }
+ Q_EMIT coinsSent(wallet, rcp, transaction_array);
+ }
+ checkBalanceChanged(); // update balance immediately, otherwise there could be a short noticeable delay until pollBalanceChanged hits
+
+ return SendCoinsReturn(OK);
+}
+
+OptionsModel *WalletModel::getOptionsModel()
+{
+ return optionsModel;
+}
+
+AddressTableModel *WalletModel::getAddressTableModel()
+{
+ return addressTableModel;
+}
+
+TransactionTableModel *WalletModel::getTransactionTableModel()
+{
+ return transactionTableModel;
+}
+
+RecentRequestsTableModel *WalletModel::getRecentRequestsTableModel()
+{
+ return recentRequestsTableModel;
+}
+
+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)
+{
+ qDebug() << "NotifyKeyStoreStatusChanged";
+ QMetaObject::invokeMethod(walletmodel, "updateStatus", Qt::QueuedConnection);
+}
+
+static void NotifyAddressBookChanged(WalletModel *walletmodel, CWallet *wallet,
+ const CTxDestination &address, const std::string &label, bool isMine,
+ const std::string &purpose, ChangeType status)
+{
+ QString strAddress = QString::fromStdString(CBitcoinAddress(address).ToString());
+ QString strLabel = QString::fromStdString(label);
+ QString strPurpose = QString::fromStdString(purpose);
+
+ qDebug() << "NotifyAddressBookChanged: " + strAddress + " " + strLabel + " isMine=" + QString::number(isMine) + " purpose=" + strPurpose + " status=" + QString::number(status);
+ QMetaObject::invokeMethod(walletmodel, "updateAddressBook", Qt::QueuedConnection,
+ Q_ARG(QString, strAddress),
+ Q_ARG(QString, strLabel),
+ Q_ARG(bool, isMine),
+ Q_ARG(QString, strPurpose),
+ Q_ARG(int, status));
+}
+
+static void NotifyTransactionChanged(WalletModel *walletmodel, CWallet *wallet, const uint256 &hash, ChangeType status)
+{
+ Q_UNUSED(wallet);
+ Q_UNUSED(hash);
+ Q_UNUSED(status);
+ QMetaObject::invokeMethod(walletmodel, "updateTransaction", Qt::QueuedConnection);
+}
+
+static void ShowProgress(WalletModel *walletmodel, const std::string &title, int nProgress)
+{
+ // emits signal "showProgress"
+ QMetaObject::invokeMethod(walletmodel, "showProgress", Qt::QueuedConnection,
+ Q_ARG(QString, QString::fromStdString(title)),
+ Q_ARG(int, nProgress));
+}
+
+static void NotifyWatchonlyChanged(WalletModel *walletmodel, bool fHaveWatchonly)
+{
+ QMetaObject::invokeMethod(walletmodel, "updateWatchOnlyFlag", Qt::QueuedConnection,
+ Q_ARG(bool, fHaveWatchonly));
+}
+
+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, _6));
+ wallet->NotifyTransactionChanged.connect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3));
+ wallet->ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2));
+ wallet->NotifyWatchonlyChanged.connect(boost::bind(NotifyWatchonlyChanged, this, _1));
+}
+
+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, _6));
+ wallet->NotifyTransactionChanged.disconnect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3));
+ wallet->ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2));
+ wallet->NotifyWatchonlyChanged.disconnect(boost::bind(NotifyWatchonlyChanged, this, _1));
+}
+
+// WalletModel::UnlockContext implementation
+WalletModel::UnlockContext WalletModel::requestUnlock()
+{
+ bool was_locked = getEncryptionStatus() == Locked;
+ if(was_locked)
+ {
+ // Request UI to unlock wallet
+ Q_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;
+}
+
+bool WalletModel::getPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const
+{
+ return wallet->GetPubKey(address, vchPubKeyOut);
+}
+
+// returns a list of COutputs from COutPoints
+void WalletModel::getOutputs(const std::vector<COutPoint>& vOutpoints, std::vector<COutput>& vOutputs)
+{
+ LOCK2(cs_main, wallet->cs_wallet);
+ BOOST_FOREACH(const COutPoint& outpoint, vOutpoints)
+ {
+ if (!wallet->mapWallet.count(outpoint.hash)) continue;
+ int nDepth = wallet->mapWallet[outpoint.hash].GetDepthInMainChain();
+ if (nDepth < 0) continue;
+ COutput out(&wallet->mapWallet[outpoint.hash], outpoint.n, nDepth, true);
+ vOutputs.push_back(out);
+ }
+}
+
+bool WalletModel::isSpent(const COutPoint& outpoint) const
+{
+ LOCK2(cs_main, wallet->cs_wallet);
+ return wallet->IsSpent(outpoint.hash, outpoint.n);
+}
+
+// AvailableCoins + LockedCoins grouped by wallet address (put change in one group with wallet address)
+void WalletModel::listCoins(std::map<QString, std::vector<COutput> >& mapCoins) const
+{
+ std::vector<COutput> vCoins;
+ wallet->AvailableCoins(vCoins);
+
+ LOCK2(cs_main, wallet->cs_wallet); // ListLockedCoins, mapWallet
+ std::vector<COutPoint> vLockedCoins;
+ wallet->ListLockedCoins(vLockedCoins);
+
+ // add locked coins
+ BOOST_FOREACH(const COutPoint& outpoint, vLockedCoins)
+ {
+ if (!wallet->mapWallet.count(outpoint.hash)) continue;
+ int nDepth = wallet->mapWallet[outpoint.hash].GetDepthInMainChain();
+ if (nDepth < 0) continue;
+ COutput out(&wallet->mapWallet[outpoint.hash], outpoint.n, nDepth, true);
+ if (outpoint.n < out.tx->vout.size() && wallet->IsMine(out.tx->vout[outpoint.n]) == ISMINE_SPENDABLE)
+ vCoins.push_back(out);
+ }
+
+ BOOST_FOREACH(const COutput& out, vCoins)
+ {
+ COutput cout = out;
+
+ while (wallet->IsChange(cout.tx->vout[cout.i]) && cout.tx->vin.size() > 0 && wallet->IsMine(cout.tx->vin[0]))
+ {
+ if (!wallet->mapWallet.count(cout.tx->vin[0].prevout.hash)) break;
+ cout = COutput(&wallet->mapWallet[cout.tx->vin[0].prevout.hash], cout.tx->vin[0].prevout.n, 0, true);
+ }
+
+ CTxDestination address;
+ if(!out.fSpendable || !ExtractDestination(cout.tx->vout[cout.i].scriptPubKey, address))
+ continue;
+ mapCoins[QString::fromStdString(CBitcoinAddress(address).ToString())].push_back(out);
+ }
+}
+
+bool WalletModel::isLockedCoin(uint256 hash, unsigned int n) const
+{
+ LOCK2(cs_main, wallet->cs_wallet);
+ return wallet->IsLockedCoin(hash, n);
+}
+
+void WalletModel::lockCoin(COutPoint& output)
+{
+ LOCK2(cs_main, wallet->cs_wallet);
+ wallet->LockCoin(output);
+}
+
+void WalletModel::unlockCoin(COutPoint& output)
+{
+ LOCK2(cs_main, wallet->cs_wallet);
+ wallet->UnlockCoin(output);
+}
+
+void WalletModel::listLockedCoins(std::vector<COutPoint>& vOutpts)
+{
+ LOCK2(cs_main, wallet->cs_wallet);
+ wallet->ListLockedCoins(vOutpts);
+}
+
+void WalletModel::loadReceiveRequests(std::vector<std::string>& vReceiveRequests)
+{
+ LOCK(wallet->cs_wallet);
+ BOOST_FOREACH(const PAIRTYPE(CTxDestination, CAddressBookData)& item, wallet->mapAddressBook)
+ BOOST_FOREACH(const PAIRTYPE(std::string, std::string)& item2, item.second.destdata)
+ if (item2.first.size() > 2 && item2.first.substr(0,2) == "rr") // receive request
+ vReceiveRequests.push_back(item2.second);
+}
+
+bool WalletModel::saveReceiveRequest(const std::string &sAddress, const int64_t nId, const std::string &sRequest)
+{
+ CTxDestination dest = CBitcoinAddress(sAddress).Get();
+
+ std::stringstream ss;
+ ss << nId;
+ std::string key = "rr" + ss.str(); // "rr" prefix = "receive request" in destdata
+
+ LOCK(wallet->cs_wallet);
+ if (sRequest.empty())
+ return wallet->EraseDestData(dest, key);
+ else
+ return wallet->AddDestData(dest, key, sRequest);
+}
diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h
new file mode 100644
index 0000000000..40bc623543
--- /dev/null
+++ b/src/qt/walletmodel.h
@@ -0,0 +1,268 @@
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_WALLETMODEL_H
+#define BITCOIN_QT_WALLETMODEL_H
+
+#include "paymentrequestplus.h"
+#include "walletmodeltransaction.h"
+
+#include "support/allocators/secure.h"
+
+#include <map>
+#include <vector>
+
+#include <QObject>
+
+class AddressTableModel;
+class OptionsModel;
+class RecentRequestsTableModel;
+class TransactionTableModel;
+class WalletModelTransaction;
+
+class CCoinControl;
+class CKeyID;
+class COutPoint;
+class COutput;
+class CPubKey;
+class CWallet;
+class uint256;
+
+QT_BEGIN_NAMESPACE
+class QTimer;
+QT_END_NAMESPACE
+
+class SendCoinsRecipient
+{
+public:
+ explicit SendCoinsRecipient() : amount(0), fSubtractFeeFromAmount(false), nVersion(SendCoinsRecipient::CURRENT_VERSION) { }
+ explicit SendCoinsRecipient(const QString &addr, const QString &label, const CAmount& amount, const QString &message):
+ address(addr), label(label), amount(amount), message(message), fSubtractFeeFromAmount(false), nVersion(SendCoinsRecipient::CURRENT_VERSION) {}
+
+ // If from an unauthenticated payment request, this is used for storing
+ // the addresses, e.g. address-A<br />address-B<br />address-C.
+ // Info: As we don't need to process addresses in here when using
+ // payment requests, we can abuse it for displaying an address list.
+ // Todo: This is a hack, should be replaced with a cleaner solution!
+ QString address;
+ QString label;
+ CAmount amount;
+ // If from a payment request, this is used for storing the memo
+ QString message;
+
+ // If from a payment request, paymentRequest.IsInitialized() will be true
+ PaymentRequestPlus paymentRequest;
+ // Empty if no authentication or invalid signature/cert/etc.
+ QString authenticatedMerchant;
+
+ bool fSubtractFeeFromAmount; // memory only
+
+ static const int CURRENT_VERSION = 1;
+ int nVersion;
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ std::string sAddress = address.toStdString();
+ std::string sLabel = label.toStdString();
+ std::string sMessage = message.toStdString();
+ std::string sPaymentRequest;
+ if (!ser_action.ForRead() && paymentRequest.IsInitialized())
+ paymentRequest.SerializeToString(&sPaymentRequest);
+ std::string sAuthenticatedMerchant = authenticatedMerchant.toStdString();
+
+ READWRITE(this->nVersion);
+ nVersion = this->nVersion;
+ READWRITE(sAddress);
+ READWRITE(sLabel);
+ READWRITE(amount);
+ READWRITE(sMessage);
+ READWRITE(sPaymentRequest);
+ READWRITE(sAuthenticatedMerchant);
+
+ if (ser_action.ForRead())
+ {
+ address = QString::fromStdString(sAddress);
+ label = QString::fromStdString(sLabel);
+ message = QString::fromStdString(sMessage);
+ if (!sPaymentRequest.empty())
+ paymentRequest.parse(QByteArray::fromRawData(sPaymentRequest.data(), sPaymentRequest.size()));
+ authenticatedMerchant = QString::fromStdString(sAuthenticatedMerchant);
+ }
+ }
+};
+
+/** 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,
+ AbsurdFee,
+ PaymentRequestExpired
+ };
+
+ enum EncryptionStatus
+ {
+ Unencrypted, // !wallet->IsCrypted()
+ Locked, // wallet->IsCrypted() && wallet->IsLocked()
+ Unlocked // wallet->IsCrypted() && !wallet->IsLocked()
+ };
+
+ OptionsModel *getOptionsModel();
+ AddressTableModel *getAddressTableModel();
+ TransactionTableModel *getTransactionTableModel();
+ RecentRequestsTableModel *getRecentRequestsTableModel();
+
+ CAmount getBalance(const CCoinControl *coinControl = NULL) const;
+ CAmount getUnconfirmedBalance() const;
+ CAmount getImmatureBalance() const;
+ bool haveWatchOnly() const;
+ CAmount getWatchBalance() const;
+ CAmount getWatchUnconfirmedBalance() const;
+ CAmount getWatchImmatureBalance() 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 = OK):
+ status(status) {}
+ StatusCode status;
+ };
+
+ // prepare transaction for getting txfee before sending coins
+ SendCoinsReturn prepareTransaction(WalletModelTransaction &transaction, const CCoinControl *coinControl = NULL);
+
+ // Send coins to a list of recipients
+ SendCoinsReturn sendCoins(WalletModelTransaction &transaction);
+
+ // 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();
+
+ bool getPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const;
+ void getOutputs(const std::vector<COutPoint>& vOutpoints, std::vector<COutput>& vOutputs);
+ bool isSpent(const COutPoint& outpoint) const;
+ void listCoins(std::map<QString, std::vector<COutput> >& mapCoins) const;
+
+ bool isLockedCoin(uint256 hash, unsigned int n) const;
+ void lockCoin(COutPoint& output);
+ void unlockCoin(COutPoint& output);
+ void listLockedCoins(std::vector<COutPoint>& vOutpts);
+
+ void loadReceiveRequests(std::vector<std::string>& vReceiveRequests);
+ bool saveReceiveRequest(const std::string &sAddress, const int64_t nId, const std::string &sRequest);
+
+private:
+ CWallet *wallet;
+ bool fHaveWatchOnly;
+ bool fForceCheckBalanceChanged;
+
+ // Wallet has an options model for wallet-specific options
+ // (transaction fee, for example)
+ OptionsModel *optionsModel;
+
+ AddressTableModel *addressTableModel;
+ TransactionTableModel *transactionTableModel;
+ RecentRequestsTableModel *recentRequestsTableModel;
+
+ // Cache some values to be able to detect changes
+ CAmount cachedBalance;
+ CAmount cachedUnconfirmedBalance;
+ CAmount cachedImmatureBalance;
+ CAmount cachedWatchOnlyBalance;
+ CAmount cachedWatchUnconfBalance;
+ CAmount cachedWatchImmatureBalance;
+ EncryptionStatus cachedEncryptionStatus;
+ int cachedNumBlocks;
+
+ QTimer *pollTimer;
+
+ void subscribeToCoreSignals();
+ void unsubscribeFromCoreSignals();
+ void checkBalanceChanged();
+
+Q_SIGNALS:
+ // Signal that balance in wallet changed
+ void balanceChanged(const CAmount& balance, const CAmount& unconfirmedBalance, const CAmount& immatureBalance,
+ const CAmount& watchOnlyBalance, const CAmount& watchUnconfBalance, const CAmount& watchImmatureBalance);
+
+ // 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();
+
+ // Fired when a message should be reported to the user
+ void message(const QString &title, const QString &message, unsigned int style);
+
+ // Coins sent: from wallet, to recipient, in (serialized) transaction:
+ void coinsSent(CWallet* wallet, SendCoinsRecipient recipient, QByteArray transaction);
+
+ // Show progress dialog e.g. for rescan
+ void showProgress(const QString &title, int nProgress);
+
+ // Watch-only address added
+ void notifyWatchonlyChanged(bool fHaveWatchonly);
+
+public Q_SLOTS:
+ /* Wallet status might have changed */
+ void updateStatus();
+ /* New transaction, or transaction changed status */
+ void updateTransaction();
+ /* New, updated or removed address book entry */
+ void updateAddressBook(const QString &address, const QString &label, bool isMine, const QString &purpose, int status);
+ /* Watch-only added */
+ void updateWatchOnlyFlag(bool fHaveWatchonly);
+ /* Current, immature or unconfirmed balance might have changed - emit 'balanceChanged' if so */
+ void pollBalanceChanged();
+};
+
+#endif // BITCOIN_QT_WALLETMODEL_H
diff --git a/src/qt/walletmodeltransaction.cpp b/src/qt/walletmodeltransaction.cpp
new file mode 100644
index 0000000000..6a9b2d5bd3
--- /dev/null
+++ b/src/qt/walletmodeltransaction.cpp
@@ -0,0 +1,99 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "walletmodeltransaction.h"
+
+#include "wallet/wallet.h"
+
+WalletModelTransaction::WalletModelTransaction(const QList<SendCoinsRecipient> &recipients) :
+ recipients(recipients),
+ walletTransaction(0),
+ keyChange(0),
+ fee(0)
+{
+ walletTransaction = new CWalletTx();
+}
+
+WalletModelTransaction::~WalletModelTransaction()
+{
+ delete keyChange;
+ delete walletTransaction;
+}
+
+QList<SendCoinsRecipient> WalletModelTransaction::getRecipients()
+{
+ return recipients;
+}
+
+CWalletTx *WalletModelTransaction::getTransaction()
+{
+ return walletTransaction;
+}
+
+unsigned int WalletModelTransaction::getTransactionSize()
+{
+ return (!walletTransaction ? 0 : (::GetSerializeSize(*(CTransaction*)walletTransaction, SER_NETWORK, PROTOCOL_VERSION)));
+}
+
+CAmount WalletModelTransaction::getTransactionFee()
+{
+ return fee;
+}
+
+void WalletModelTransaction::setTransactionFee(const CAmount& newFee)
+{
+ fee = newFee;
+}
+
+void WalletModelTransaction::reassignAmounts(int nChangePosRet)
+{
+ int i = 0;
+ for (QList<SendCoinsRecipient>::iterator it = recipients.begin(); it != recipients.end(); ++it)
+ {
+ SendCoinsRecipient& rcp = (*it);
+
+ if (rcp.paymentRequest.IsInitialized())
+ {
+ CAmount subtotal = 0;
+ const payments::PaymentDetails& details = rcp.paymentRequest.getDetails();
+ for (int j = 0; j < details.outputs_size(); j++)
+ {
+ const payments::Output& out = details.outputs(j);
+ if (out.amount() <= 0) continue;
+ if (i == nChangePosRet)
+ i++;
+ subtotal += walletTransaction->vout[i].nValue;
+ i++;
+ }
+ rcp.amount = subtotal;
+ }
+ else // normal recipient (no payment request)
+ {
+ if (i == nChangePosRet)
+ i++;
+ rcp.amount = walletTransaction->vout[i].nValue;
+ i++;
+ }
+ }
+}
+
+CAmount WalletModelTransaction::getTotalTransactionAmount()
+{
+ CAmount totalTransactionAmount = 0;
+ Q_FOREACH(const SendCoinsRecipient &rcp, recipients)
+ {
+ totalTransactionAmount += rcp.amount;
+ }
+ return totalTransactionAmount;
+}
+
+void WalletModelTransaction::newPossibleKeyChange(CWallet *wallet)
+{
+ keyChange = new CReserveKey(wallet);
+}
+
+CReserveKey *WalletModelTransaction::getPossibleKeyChange()
+{
+ return keyChange;
+}
diff --git a/src/qt/walletmodeltransaction.h b/src/qt/walletmodeltransaction.h
new file mode 100644
index 0000000000..7765fea4af
--- /dev/null
+++ b/src/qt/walletmodeltransaction.h
@@ -0,0 +1,47 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_WALLETMODELTRANSACTION_H
+#define BITCOIN_QT_WALLETMODELTRANSACTION_H
+
+#include "walletmodel.h"
+
+#include <QObject>
+
+class SendCoinsRecipient;
+
+class CReserveKey;
+class CWallet;
+class CWalletTx;
+
+/** Data model for a walletmodel transaction. */
+class WalletModelTransaction
+{
+public:
+ explicit WalletModelTransaction(const QList<SendCoinsRecipient> &recipients);
+ ~WalletModelTransaction();
+
+ QList<SendCoinsRecipient> getRecipients();
+
+ CWalletTx *getTransaction();
+ unsigned int getTransactionSize();
+
+ void setTransactionFee(const CAmount& newFee);
+ CAmount getTransactionFee();
+
+ CAmount getTotalTransactionAmount();
+
+ void newPossibleKeyChange(CWallet *wallet);
+ CReserveKey *getPossibleKeyChange();
+
+ void reassignAmounts(int nChangePosRet); // needed for the subtract-fee-from-amount feature
+
+private:
+ QList<SendCoinsRecipient> recipients;
+ CWalletTx *walletTransaction;
+ CReserveKey *keyChange;
+ CAmount fee;
+};
+
+#endif // BITCOIN_QT_WALLETMODELTRANSACTION_H
diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp
new file mode 100644
index 0000000000..c5f556b444
--- /dev/null
+++ b/src/qt/walletview.cpp
@@ -0,0 +1,312 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "walletview.h"
+
+#include "addressbookpage.h"
+#include "askpassphrasedialog.h"
+#include "bitcoingui.h"
+#include "clientmodel.h"
+#include "guiutil.h"
+#include "optionsmodel.h"
+#include "overviewpage.h"
+#include "receivecoinsdialog.h"
+#include "scicon.h"
+#include "sendcoinsdialog.h"
+#include "signverifymessagedialog.h"
+#include "transactiontablemodel.h"
+#include "transactionview.h"
+#include "walletmodel.h"
+
+#include "ui_interface.h"
+
+#include <QAction>
+#include <QActionGroup>
+#include <QFileDialog>
+#include <QHBoxLayout>
+#include <QProgressDialog>
+#include <QPushButton>
+#include <QVBoxLayout>
+
+WalletView::WalletView(QWidget *parent):
+ QStackedWidget(parent),
+ clientModel(0),
+ walletModel(0)
+{
+ // Create tabs
+ overviewPage = new OverviewPage();
+
+ transactionsPage = new QWidget(this);
+ QVBoxLayout *vbox = new QVBoxLayout();
+ QHBoxLayout *hbox_buttons = new QHBoxLayout();
+ transactionView = new TransactionView(this);
+ vbox->addWidget(transactionView);
+ QPushButton *exportButton = new QPushButton(tr("&Export"), this);
+ exportButton->setToolTip(tr("Export the data in the current tab to a file"));
+#ifndef Q_OS_MAC // Icons on push buttons are very uncommon on Mac
+ exportButton->setIcon(SingleColorIcon(":/icons/export"));
+#endif
+ hbox_buttons->addStretch();
+ hbox_buttons->addWidget(exportButton);
+ vbox->addLayout(hbox_buttons);
+ transactionsPage->setLayout(vbox);
+
+ receiveCoinsPage = new ReceiveCoinsDialog();
+ sendCoinsPage = new SendCoinsDialog();
+
+ addWidget(overviewPage);
+ addWidget(transactionsPage);
+ addWidget(receiveCoinsPage);
+ addWidget(sendCoinsPage);
+
+ // Clicking on a transaction on the overview pre-selects the transaction on the transaction history page
+ connect(overviewPage, SIGNAL(transactionClicked(QModelIndex)), transactionView, SLOT(focusTransaction(QModelIndex)));
+
+ // Double-clicking on a transaction on the transaction history page shows details
+ connect(transactionView, SIGNAL(doubleClicked(QModelIndex)), transactionView, SLOT(showDetails()));
+
+ // Clicking on "Export" allows to export the transaction list
+ connect(exportButton, SIGNAL(clicked()), transactionView, SLOT(exportClicked()));
+
+ // Pass through messages from sendCoinsPage
+ connect(sendCoinsPage, SIGNAL(message(QString,QString,unsigned int)), this, SIGNAL(message(QString,QString,unsigned int)));
+ // Pass through messages from transactionView
+ connect(transactionView, SIGNAL(message(QString,QString,unsigned int)), this, SIGNAL(message(QString,QString,unsigned int)));
+}
+
+WalletView::~WalletView()
+{
+}
+
+void WalletView::setBitcoinGUI(BitcoinGUI *gui)
+{
+ if (gui)
+ {
+ // Clicking on a transaction on the overview page simply sends you to transaction history page
+ connect(overviewPage, SIGNAL(transactionClicked(QModelIndex)), gui, SLOT(gotoHistoryPage()));
+
+ // Receive and report messages
+ connect(this, SIGNAL(message(QString,QString,unsigned int)), gui, SLOT(message(QString,QString,unsigned int)));
+
+ // Pass through encryption status changed signals
+ connect(this, SIGNAL(encryptionStatusChanged(int)), gui, SLOT(setEncryptionStatus(int)));
+
+ // Pass through transaction notifications
+ connect(this, SIGNAL(incomingTransaction(QString,int,CAmount,QString,QString,QString)), gui, SLOT(incomingTransaction(QString,int,CAmount,QString,QString,QString)));
+ }
+}
+
+void WalletView::setClientModel(ClientModel *clientModel)
+{
+ this->clientModel = clientModel;
+
+ overviewPage->setClientModel(clientModel);
+ sendCoinsPage->setClientModel(clientModel);
+}
+
+void WalletView::setWalletModel(WalletModel *walletModel)
+{
+ this->walletModel = walletModel;
+
+ // Put transaction list in tabs
+ transactionView->setModel(walletModel);
+ overviewPage->setWalletModel(walletModel);
+ receiveCoinsPage->setModel(walletModel);
+ sendCoinsPage->setModel(walletModel);
+
+ if (walletModel)
+ {
+ // Receive and pass through messages from wallet model
+ connect(walletModel, SIGNAL(message(QString,QString,unsigned int)), this, SIGNAL(message(QString,QString,unsigned int)));
+
+ // Handle changes in encryption status
+ connect(walletModel, SIGNAL(encryptionStatusChanged(int)), this, SIGNAL(encryptionStatusChanged(int)));
+ updateEncryptionStatus();
+
+ // Balloon pop-up for new transaction
+ connect(walletModel->getTransactionTableModel(), SIGNAL(rowsInserted(QModelIndex,int,int)),
+ this, SLOT(processNewTransaction(QModelIndex,int,int)));
+
+ // Ask for passphrase if needed
+ connect(walletModel, SIGNAL(requireUnlock()), this, SLOT(unlockWallet()));
+
+ // Show progress dialog
+ connect(walletModel, SIGNAL(showProgress(QString,int)), this, SLOT(showProgress(QString,int)));
+ }
+}
+
+void WalletView::processNewTransaction(const QModelIndex& parent, int start, int /*end*/)
+{
+ // Prevent balloon-spam when initial block download is in progress
+ if (!walletModel || !clientModel || clientModel->inInitialBlockDownload())
+ return;
+
+ TransactionTableModel *ttm = walletModel->getTransactionTableModel();
+ if (!ttm || ttm->processingQueuedTransactions())
+ return;
+
+ QString date = ttm->index(start, TransactionTableModel::Date, parent).data().toString();
+ qint64 amount = ttm->index(start, TransactionTableModel::Amount, parent).data(Qt::EditRole).toULongLong();
+ QString type = ttm->index(start, TransactionTableModel::Type, parent).data().toString();
+ QModelIndex index = ttm->index(start, 0, parent);
+ QString address = ttm->data(index, TransactionTableModel::AddressRole).toString();
+ QString label = ttm->data(index, TransactionTableModel::LabelRole).toString();
+
+ Q_EMIT incomingTransaction(date, walletModel->getOptionsModel()->getDisplayUnit(), amount, type, address, label);
+}
+
+void WalletView::gotoOverviewPage()
+{
+ setCurrentWidget(overviewPage);
+}
+
+void WalletView::gotoHistoryPage()
+{
+ setCurrentWidget(transactionsPage);
+}
+
+void WalletView::gotoReceiveCoinsPage()
+{
+ setCurrentWidget(receiveCoinsPage);
+}
+
+void WalletView::gotoSendCoinsPage(QString addr)
+{
+ setCurrentWidget(sendCoinsPage);
+
+ if (!addr.isEmpty())
+ sendCoinsPage->setAddress(addr);
+}
+
+void WalletView::gotoSignMessageTab(QString addr)
+{
+ // calls show() in showTab_SM()
+ SignVerifyMessageDialog *signVerifyMessageDialog = new SignVerifyMessageDialog(this);
+ signVerifyMessageDialog->setAttribute(Qt::WA_DeleteOnClose);
+ signVerifyMessageDialog->setModel(walletModel);
+ signVerifyMessageDialog->showTab_SM(true);
+
+ if (!addr.isEmpty())
+ signVerifyMessageDialog->setAddress_SM(addr);
+}
+
+void WalletView::gotoVerifyMessageTab(QString addr)
+{
+ // calls show() in showTab_VM()
+ SignVerifyMessageDialog *signVerifyMessageDialog = new SignVerifyMessageDialog(this);
+ signVerifyMessageDialog->setAttribute(Qt::WA_DeleteOnClose);
+ signVerifyMessageDialog->setModel(walletModel);
+ signVerifyMessageDialog->showTab_VM(true);
+
+ if (!addr.isEmpty())
+ signVerifyMessageDialog->setAddress_VM(addr);
+}
+
+bool WalletView::handlePaymentRequest(const SendCoinsRecipient& recipient)
+{
+ return sendCoinsPage->handlePaymentRequest(recipient);
+}
+
+void WalletView::showOutOfSyncWarning(bool fShow)
+{
+ overviewPage->showOutOfSyncWarning(fShow);
+}
+
+void WalletView::updateEncryptionStatus()
+{
+ Q_EMIT encryptionStatusChanged(walletModel->getEncryptionStatus());
+}
+
+void WalletView::encryptWallet(bool status)
+{
+ if(!walletModel)
+ return;
+ AskPassphraseDialog dlg(status ? AskPassphraseDialog::Encrypt : AskPassphraseDialog::Decrypt, this);
+ dlg.setModel(walletModel);
+ dlg.exec();
+
+ updateEncryptionStatus();
+}
+
+void WalletView::backupWallet()
+{
+ QString filename = GUIUtil::getSaveFileName(this,
+ tr("Backup Wallet"), QString(),
+ tr("Wallet Data (*.dat)"), NULL);
+
+ if (filename.isEmpty())
+ return;
+
+ if (!walletModel->backupWallet(filename)) {
+ Q_EMIT message(tr("Backup Failed"), tr("There was an error trying to save the wallet data to %1.").arg(filename),
+ CClientUIInterface::MSG_ERROR);
+ }
+ else {
+ Q_EMIT message(tr("Backup Successful"), tr("The wallet data was successfully saved to %1.").arg(filename),
+ CClientUIInterface::MSG_INFORMATION);
+ }
+}
+
+void WalletView::changePassphrase()
+{
+ AskPassphraseDialog dlg(AskPassphraseDialog::ChangePass, this);
+ dlg.setModel(walletModel);
+ dlg.exec();
+}
+
+void WalletView::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 WalletView::usedSendingAddresses()
+{
+ if(!walletModel)
+ return;
+ AddressBookPage *dlg = new AddressBookPage(AddressBookPage::ForEditing, AddressBookPage::SendingTab, this);
+ dlg->setAttribute(Qt::WA_DeleteOnClose);
+ dlg->setModel(walletModel->getAddressTableModel());
+ dlg->show();
+}
+
+void WalletView::usedReceivingAddresses()
+{
+ if(!walletModel)
+ return;
+ AddressBookPage *dlg = new AddressBookPage(AddressBookPage::ForEditing, AddressBookPage::ReceivingTab, this);
+ dlg->setAttribute(Qt::WA_DeleteOnClose);
+ dlg->setModel(walletModel->getAddressTableModel());
+ dlg->show();
+}
+
+void WalletView::showProgress(const QString &title, int nProgress)
+{
+ if (nProgress == 0)
+ {
+ progressDialog = new QProgressDialog(title, "", 0, 100);
+ progressDialog->setWindowModality(Qt::ApplicationModal);
+ progressDialog->setMinimumDuration(0);
+ progressDialog->setCancelButton(0);
+ progressDialog->setAutoClose(false);
+ progressDialog->setValue(0);
+ }
+ else if (nProgress == 100)
+ {
+ if (progressDialog)
+ {
+ progressDialog->close();
+ progressDialog->deleteLater();
+ }
+ }
+ else if (progressDialog)
+ progressDialog->setValue(nProgress);
+}
diff --git a/src/qt/walletview.h b/src/qt/walletview.h
new file mode 100644
index 0000000000..87c5d7bfbf
--- /dev/null
+++ b/src/qt/walletview.h
@@ -0,0 +1,119 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_WALLETVIEW_H
+#define BITCOIN_QT_WALLETVIEW_H
+
+#include "amount.h"
+
+#include <QStackedWidget>
+
+class BitcoinGUI;
+class ClientModel;
+class OverviewPage;
+class ReceiveCoinsDialog;
+class SendCoinsDialog;
+class SendCoinsRecipient;
+class TransactionView;
+class WalletModel;
+
+QT_BEGIN_NAMESPACE
+class QModelIndex;
+class QProgressDialog;
+QT_END_NAMESPACE
+
+/*
+ WalletView class. This class represents the view to a single wallet.
+ It was added to support multiple wallet functionality. Each wallet gets its own WalletView instance.
+ It communicates with both the client and the wallet models to give the user an up-to-date view of the
+ current core state.
+*/
+class WalletView : public QStackedWidget
+{
+ Q_OBJECT
+
+public:
+ explicit WalletView(QWidget *parent);
+ ~WalletView();
+
+ void setBitcoinGUI(BitcoinGUI *gui);
+ /** 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);
+
+ bool handlePaymentRequest(const SendCoinsRecipient& recipient);
+
+ void showOutOfSyncWarning(bool fShow);
+
+private:
+ ClientModel *clientModel;
+ WalletModel *walletModel;
+
+ OverviewPage *overviewPage;
+ QWidget *transactionsPage;
+ ReceiveCoinsDialog *receiveCoinsPage;
+ SendCoinsDialog *sendCoinsPage;
+
+ TransactionView *transactionView;
+
+ QProgressDialog *progressDialog;
+
+public Q_SLOTS:
+ /** Switch to overview (home) page */
+ void gotoOverviewPage();
+ /** Switch to history (transactions) page */
+ void gotoHistoryPage();
+ /** Switch to receive coins page */
+ void gotoReceiveCoinsPage();
+ /** Switch to send coins page */
+ void gotoSendCoinsPage(QString addr = "");
+
+ /** 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 incoming transaction notification for new transactions.
+
+ The new items are those between start and end inclusive, under the given parent item.
+ */
+ void processNewTransaction(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 passphrase to unlock wallet temporarily */
+ void unlockWallet();
+
+ /** Show used sending addresses */
+ void usedSendingAddresses();
+ /** Show used receiving addresses */
+ void usedReceivingAddresses();
+
+ /** Re-emit encryption status signal */
+ void updateEncryptionStatus();
+
+ /** Show progress dialog e.g. for rescan */
+ void showProgress(const QString &title, int nProgress);
+
+Q_SIGNALS:
+ /** Signal that we want to show the main window */
+ void showNormalIfMinimized();
+ /** Fired when a message should be reported to the user */
+ void message(const QString &title, const QString &message, unsigned int style);
+ /** Encryption status of wallet changed */
+ void encryptionStatusChanged(int status);
+ /** Notify that a new transaction appeared */
+ void incomingTransaction(const QString& date, int unit, const CAmount& amount, const QString& type, const QString& address, const QString& label);
+};
+
+#endif // BITCOIN_QT_WALLETVIEW_H
diff --git a/src/qt/winshutdownmonitor.cpp b/src/qt/winshutdownmonitor.cpp
new file mode 100644
index 0000000000..1bc4f77959
--- /dev/null
+++ b/src/qt/winshutdownmonitor.cpp
@@ -0,0 +1,70 @@
+// Copyright (c) 2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "winshutdownmonitor.h"
+
+#if defined(Q_OS_WIN) && QT_VERSION >= 0x050000
+#include "init.h"
+#include "util.h"
+
+#include <windows.h>
+
+#include <QDebug>
+
+#include <openssl/rand.h>
+
+// If we don't want a message to be processed by Qt, return true and set result to
+// the value that the window procedure should return. Otherwise return false.
+bool WinShutdownMonitor::nativeEventFilter(const QByteArray &eventType, void *pMessage, long *pnResult)
+{
+ Q_UNUSED(eventType);
+
+ MSG *pMsg = static_cast<MSG *>(pMessage);
+
+ // Seed OpenSSL PRNG with Windows event data (e.g. mouse movements and other user interactions)
+ if (RAND_event(pMsg->message, pMsg->wParam, pMsg->lParam) == 0) {
+ // Warn only once as this is performance-critical
+ static bool warned = false;
+ if (!warned) {
+ LogPrint("%s: OpenSSL RAND_event() failed to seed OpenSSL PRNG with enough data.\n", __func__);
+ warned = true;
+ }
+ }
+
+ switch(pMsg->message)
+ {
+ case WM_QUERYENDSESSION:
+ {
+ // Initiate a client shutdown after receiving a WM_QUERYENDSESSION and block
+ // Windows session end until we have finished client shutdown.
+ StartShutdown();
+ *pnResult = FALSE;
+ return true;
+ }
+
+ case WM_ENDSESSION:
+ {
+ *pnResult = FALSE;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void WinShutdownMonitor::registerShutdownBlockReason(const QString& strReason, const HWND& mainWinId)
+{
+ typedef BOOL (WINAPI *PSHUTDOWNBRCREATE)(HWND, LPCWSTR);
+ PSHUTDOWNBRCREATE shutdownBRCreate = (PSHUTDOWNBRCREATE)GetProcAddress(GetModuleHandleA("User32.dll"), "ShutdownBlockReasonCreate");
+ if (shutdownBRCreate == NULL) {
+ qWarning() << "registerShutdownBlockReason: GetProcAddress for ShutdownBlockReasonCreate failed";
+ return;
+ }
+
+ if (shutdownBRCreate(mainWinId, strReason.toStdWString().c_str()))
+ qWarning() << "registerShutdownBlockReason: Successfully registered: " + strReason;
+ else
+ qWarning() << "registerShutdownBlockReason: Failed to register: " + strReason;
+}
+#endif
diff --git a/src/qt/winshutdownmonitor.h b/src/qt/winshutdownmonitor.h
new file mode 100644
index 0000000000..0bed55a2c6
--- /dev/null
+++ b/src/qt/winshutdownmonitor.h
@@ -0,0 +1,29 @@
+// Copyright (c) 2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_WINSHUTDOWNMONITOR_H
+#define BITCOIN_QT_WINSHUTDOWNMONITOR_H
+
+#ifdef WIN32
+#include <QByteArray>
+#include <QString>
+
+#if QT_VERSION >= 0x050000
+#include <windef.h> // for HWND
+
+#include <QAbstractNativeEventFilter>
+
+class WinShutdownMonitor : public QAbstractNativeEventFilter
+{
+public:
+ /** Implements QAbstractNativeEventFilter interface for processing Windows messages */
+ bool nativeEventFilter(const QByteArray &eventType, void *pMessage, long *pnResult);
+
+ /** Register the reason for blocking shutdown on Windows to allow clean client exit */
+ static void registerShutdownBlockReason(const QString& strReason, const HWND& mainWinId);
+};
+#endif
+#endif
+
+#endif // BITCOIN_QT_WINSHUTDOWNMONITOR_H
diff --git a/src/random.cpp b/src/random.cpp
new file mode 100644
index 0000000000..0ba0de908d
--- /dev/null
+++ b/src/random.cpp
@@ -0,0 +1,139 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "random.h"
+
+#include "support/cleanse.h"
+#ifdef WIN32
+#include "compat.h" // for Windows API
+#endif
+#include "serialize.h" // for begin_ptr(vec)
+#include "util.h" // for LogPrint()
+#include "utilstrencodings.h" // for GetTime()
+
+#include <limits>
+
+#ifndef WIN32
+#include <sys/time.h>
+#endif
+
+#include <openssl/err.h>
+#include <openssl/rand.h>
+
+static inline int64_t GetPerformanceCounter()
+{
+ int64_t nCounter = 0;
+#ifdef WIN32
+ QueryPerformanceCounter((LARGE_INTEGER*)&nCounter);
+#else
+ timeval t;
+ gettimeofday(&t, NULL);
+ nCounter = (int64_t)(t.tv_sec * 1000000 + t.tv_usec);
+#endif
+ return nCounter;
+}
+
+void RandAddSeed()
+{
+ // Seed with CPU performance counter
+ int64_t nCounter = GetPerformanceCounter();
+ RAND_add(&nCounter, sizeof(nCounter), 1.5);
+ memory_cleanse((void*)&nCounter, sizeof(nCounter));
+}
+
+void RandAddSeedPerfmon()
+{
+ RandAddSeed();
+
+#ifdef WIN32
+ // Don't need this on Linux, OpenSSL automatically uses /dev/urandom
+ // Seed with the entire set of perfmon data
+
+ // This can take up to 2 seconds, so only do it every 10 minutes
+ static int64_t nLastPerfmon;
+ if (GetTime() < nLastPerfmon + 10 * 60)
+ return;
+ nLastPerfmon = GetTime();
+
+ std::vector<unsigned char> vData(250000, 0);
+ long ret = 0;
+ unsigned long nSize = 0;
+ const size_t nMaxSize = 10000000; // Bail out at more than 10MB of performance data
+ while (true) {
+ nSize = vData.size();
+ ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, begin_ptr(vData), &nSize);
+ if (ret != ERROR_MORE_DATA || vData.size() >= nMaxSize)
+ break;
+ vData.resize(std::max((vData.size() * 3) / 2, nMaxSize)); // Grow size of buffer exponentially
+ }
+ RegCloseKey(HKEY_PERFORMANCE_DATA);
+ if (ret == ERROR_SUCCESS) {
+ RAND_add(begin_ptr(vData), nSize, nSize / 100.0);
+ memory_cleanse(begin_ptr(vData), nSize);
+ LogPrint("rand", "%s: %lu bytes\n", __func__, nSize);
+ } else {
+ static bool warned = false; // Warn only once
+ if (!warned) {
+ LogPrintf("%s: Warning: RegQueryValueExA(HKEY_PERFORMANCE_DATA) failed with code %i\n", __func__, ret);
+ warned = true;
+ }
+ }
+#endif
+}
+
+void GetRandBytes(unsigned char* buf, int num)
+{
+ if (RAND_bytes(buf, num) != 1) {
+ LogPrintf("%s: OpenSSL RAND_bytes() failed with error: %s\n", __func__, ERR_error_string(ERR_get_error(), NULL));
+ assert(false);
+ }
+}
+
+uint64_t GetRand(uint64_t 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_t nRange = (std::numeric_limits<uint64_t>::max() / nMax) * nMax;
+ uint64_t nRand = 0;
+ do {
+ GetRandBytes((unsigned char*)&nRand, sizeof(nRand));
+ } while (nRand >= nRange);
+ return (nRand % nMax);
+}
+
+int GetRandInt(int nMax)
+{
+ return GetRand(nMax);
+}
+
+uint256 GetRandHash()
+{
+ uint256 hash;
+ GetRandBytes((unsigned char*)&hash, sizeof(hash));
+ return hash;
+}
+
+uint32_t insecure_rand_Rz = 11;
+uint32_t insecure_rand_Rw = 11;
+void seed_insecure_rand(bool fDeterministic)
+{
+ // The seed values have some unlikely fixed points which we avoid.
+ if (fDeterministic) {
+ insecure_rand_Rz = insecure_rand_Rw = 11;
+ } else {
+ uint32_t tmp;
+ do {
+ GetRandBytes((unsigned char*)&tmp, 4);
+ } while (tmp == 0 || tmp == 0x9068ffffU);
+ insecure_rand_Rz = tmp;
+ do {
+ GetRandBytes((unsigned char*)&tmp, 4);
+ } while (tmp == 0 || tmp == 0x464fffffU);
+ insecure_rand_Rw = tmp;
+ }
+}
diff --git a/src/random.h b/src/random.h
new file mode 100644
index 0000000000..1a2d3e8ee2
--- /dev/null
+++ b/src/random.h
@@ -0,0 +1,49 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_RANDOM_H
+#define BITCOIN_RANDOM_H
+
+#include "uint256.h"
+
+#include <stdint.h>
+
+/**
+ * Seed OpenSSL PRNG with additional entropy data
+ */
+void RandAddSeed();
+void RandAddSeedPerfmon();
+
+/**
+ * Functions to gather random data via the OpenSSL PRNG
+ */
+void GetRandBytes(unsigned char* buf, int num);
+uint64_t GetRand(uint64_t nMax);
+int GetRandInt(int nMax);
+uint256 GetRandHash();
+
+/**
+ * Seed insecure_rand using the random pool.
+ * @param Deterministic Use a deterministic seed
+ */
+void seed_insecure_rand(bool fDeterministic = false);
+
+/**
+ * MWC RNG of George Marsaglia
+ * This is intended to be fast. It has a period of 2^59.3, though the
+ * least significant 16 bits only have a period of about 2^30.1.
+ *
+ * @return random value
+ */
+extern uint32_t insecure_rand_Rz;
+extern uint32_t insecure_rand_Rw;
+static inline uint32_t insecure_rand(void)
+{
+ insecure_rand_Rz = 36969 * (insecure_rand_Rz & 65535) + (insecure_rand_Rz >> 16);
+ insecure_rand_Rw = 18000 * (insecure_rand_Rw & 65535) + (insecure_rand_Rw >> 16);
+ return (insecure_rand_Rw << 16) + insecure_rand_Rz;
+}
+
+#endif // BITCOIN_RANDOM_H
diff --git a/src/rest.cpp b/src/rest.cpp
new file mode 100644
index 0000000000..7c238d506d
--- /dev/null
+++ b/src/rest.cpp
@@ -0,0 +1,573 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "primitives/block.h"
+#include "primitives/transaction.h"
+#include "main.h"
+#include "rpcserver.h"
+#include "streams.h"
+#include "sync.h"
+#include "txmempool.h"
+#include "utilstrencodings.h"
+#include "version.h"
+
+#include <boost/algorithm/string.hpp>
+#include <boost/dynamic_bitset.hpp>
+
+using namespace std;
+using namespace json_spirit;
+
+static const int MAX_GETUTXOS_OUTPOINTS = 15; //allow a max of 15 outpoints to be queried at once
+
+enum RetFormat {
+ RF_UNDEF,
+ RF_BINARY,
+ RF_HEX,
+ RF_JSON,
+};
+
+static const struct {
+ enum RetFormat rf;
+ const char* name;
+} rf_names[] = {
+ {RF_UNDEF, ""},
+ {RF_BINARY, "bin"},
+ {RF_HEX, "hex"},
+ {RF_JSON, "json"},
+};
+
+struct CCoin {
+ uint32_t nTxVer; // Don't call this nVersion, that name has a special meaning inside IMPLEMENT_SERIALIZE
+ uint32_t nHeight;
+ CTxOut out;
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion)
+ {
+ READWRITE(nTxVer);
+ READWRITE(nHeight);
+ READWRITE(out);
+ }
+};
+
+class RestErr
+{
+public:
+ enum HTTPStatusCode status;
+ string message;
+};
+
+extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry);
+extern Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false);
+extern void ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out, bool fIncludeHex);
+
+static RestErr RESTERR(enum HTTPStatusCode status, string message)
+{
+ RestErr re;
+ re.status = status;
+ re.message = message;
+ return re;
+}
+
+static enum RetFormat ParseDataFormat(vector<string>& params, const string strReq)
+{
+ boost::split(params, strReq, boost::is_any_of("."));
+ if (params.size() > 1) {
+ for (unsigned int i = 0; i < ARRAYLEN(rf_names); i++)
+ if (params[1] == rf_names[i].name)
+ return rf_names[i].rf;
+ }
+
+ return rf_names[0].rf;
+}
+
+static string AvailableDataFormatsString()
+{
+ string formats = "";
+ for (unsigned int i = 0; i < ARRAYLEN(rf_names); i++)
+ if (strlen(rf_names[i].name) > 0) {
+ formats.append(".");
+ formats.append(rf_names[i].name);
+ formats.append(", ");
+ }
+
+ if (formats.length() > 0)
+ return formats.substr(0, formats.length() - 2);
+
+ return formats;
+}
+
+static bool ParseHashStr(const string& strReq, uint256& v)
+{
+ if (!IsHex(strReq) || (strReq.size() != 64))
+ return false;
+
+ v.SetHex(strReq);
+ return true;
+}
+
+static bool rest_headers(AcceptedConnection* conn,
+ const std::string& strURIPart,
+ const std::string& strRequest,
+ const std::map<std::string, std::string>& mapHeaders,
+ bool fRun)
+{
+ vector<string> params;
+ const RetFormat rf = ParseDataFormat(params, strURIPart);
+ vector<string> path;
+ boost::split(path, params[0], boost::is_any_of("/"));
+
+ if (path.size() != 2)
+ throw RESTERR(HTTP_BAD_REQUEST, "No header count specified. Use /rest/headers/<count>/<hash>.<ext>.");
+
+ long count = strtol(path[0].c_str(), NULL, 10);
+ if (count < 1 || count > 2000)
+ throw RESTERR(HTTP_BAD_REQUEST, "Header count out of range: " + path[0]);
+
+ string hashStr = path[1];
+ uint256 hash;
+ if (!ParseHashStr(hashStr, hash))
+ throw RESTERR(HTTP_BAD_REQUEST, "Invalid hash: " + hashStr);
+
+ std::vector<CBlockHeader> headers;
+ headers.reserve(count);
+ {
+ LOCK(cs_main);
+ BlockMap::const_iterator it = mapBlockIndex.find(hash);
+ const CBlockIndex *pindex = (it != mapBlockIndex.end()) ? it->second : NULL;
+ while (pindex != NULL && chainActive.Contains(pindex)) {
+ headers.push_back(pindex->GetBlockHeader());
+ if (headers.size() == (unsigned long)count)
+ break;
+ pindex = chainActive.Next(pindex);
+ }
+ }
+
+ CDataStream ssHeader(SER_NETWORK, PROTOCOL_VERSION);
+ BOOST_FOREACH(const CBlockHeader &header, headers) {
+ ssHeader << header;
+ }
+
+ switch (rf) {
+ case RF_BINARY: {
+ string binaryHeader = ssHeader.str();
+ conn->stream() << HTTPReplyHeader(HTTP_OK, fRun, binaryHeader.size(), "application/octet-stream") << binaryHeader << std::flush;
+ return true;
+ }
+
+ case RF_HEX: {
+ string strHex = HexStr(ssHeader.begin(), ssHeader.end()) + "\n";
+ conn->stream() << HTTPReply(HTTP_OK, strHex, fRun, false, "text/plain") << std::flush;
+ return true;
+ }
+
+ default: {
+ throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: .bin, .hex)");
+ }
+ }
+
+ // not reached
+ return true; // continue to process further HTTP reqs on this cxn
+}
+
+static bool rest_block(AcceptedConnection* conn,
+ const std::string& strURIPart,
+ const std::string& strRequest,
+ const std::map<std::string, std::string>& mapHeaders,
+ bool fRun,
+ bool showTxDetails)
+{
+ vector<string> params;
+ const RetFormat rf = ParseDataFormat(params, strURIPart);
+
+ string hashStr = params[0];
+ uint256 hash;
+ if (!ParseHashStr(hashStr, hash))
+ throw RESTERR(HTTP_BAD_REQUEST, "Invalid hash: " + hashStr);
+
+ CBlock block;
+ CBlockIndex* pblockindex = NULL;
+ {
+ LOCK(cs_main);
+ if (mapBlockIndex.count(hash) == 0)
+ throw RESTERR(HTTP_NOT_FOUND, hashStr + " not found");
+
+ pblockindex = mapBlockIndex[hash];
+ if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0)
+ throw RESTERR(HTTP_NOT_FOUND, hashStr + " not available (pruned data)");
+
+ if (!ReadBlockFromDisk(block, pblockindex))
+ throw RESTERR(HTTP_NOT_FOUND, hashStr + " not found");
+ }
+
+ CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION);
+ ssBlock << block;
+
+ switch (rf) {
+ case RF_BINARY: {
+ string binaryBlock = ssBlock.str();
+ conn->stream() << HTTPReplyHeader(HTTP_OK, fRun, binaryBlock.size(), "application/octet-stream") << binaryBlock << std::flush;
+ return true;
+ }
+
+ case RF_HEX: {
+ string strHex = HexStr(ssBlock.begin(), ssBlock.end()) + "\n";
+ conn->stream() << HTTPReply(HTTP_OK, strHex, fRun, false, "text/plain") << std::flush;
+ return true;
+ }
+
+ case RF_JSON: {
+ Object objBlock = blockToJSON(block, pblockindex, showTxDetails);
+ string strJSON = write_string(Value(objBlock), false) + "\n";
+ conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush;
+ return true;
+ }
+
+ default: {
+ throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")");
+ }
+ }
+
+ // not reached
+ return true; // continue to process further HTTP reqs on this cxn
+}
+
+static bool rest_block_extended(AcceptedConnection* conn,
+ const std::string& strURIPart,
+ const std::string& strRequest,
+ const std::map<std::string, std::string>& mapHeaders,
+ bool fRun)
+{
+ return rest_block(conn, strURIPart, strRequest, mapHeaders, fRun, true);
+}
+
+static bool rest_block_notxdetails(AcceptedConnection* conn,
+ const std::string& strURIPart,
+ const std::string& strRequest,
+ const std::map<std::string, std::string>& mapHeaders,
+ bool fRun)
+{
+ return rest_block(conn, strURIPart, strRequest, mapHeaders, fRun, false);
+}
+
+static bool rest_chaininfo(AcceptedConnection* conn,
+ const std::string& strURIPart,
+ const std::string& strRequest,
+ const std::map<std::string, std::string>& mapHeaders,
+ bool fRun)
+{
+ vector<string> params;
+ const RetFormat rf = ParseDataFormat(params, strURIPart);
+
+ switch (rf) {
+ case RF_JSON: {
+ Array rpcParams;
+ Value chainInfoObject = getblockchaininfo(rpcParams, false);
+
+ string strJSON = write_string(chainInfoObject, false) + "\n";
+ conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush;
+ return true;
+ }
+ default: {
+ throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: json)");
+ }
+ }
+
+ // not reached
+ return true; // continue to process further HTTP reqs on this cxn
+}
+
+static bool rest_tx(AcceptedConnection* conn,
+ const std::string& strURIPart,
+ const std::string& strRequest,
+ const std::map<std::string, std::string>& mapHeaders,
+ bool fRun)
+{
+ vector<string> params;
+ const RetFormat rf = ParseDataFormat(params, strURIPart);
+
+ string hashStr = params[0];
+ uint256 hash;
+ if (!ParseHashStr(hashStr, hash))
+ throw RESTERR(HTTP_BAD_REQUEST, "Invalid hash: " + hashStr);
+
+ CTransaction tx;
+ uint256 hashBlock = uint256();
+ if (!GetTransaction(hash, tx, hashBlock, true))
+ throw RESTERR(HTTP_NOT_FOUND, hashStr + " not found");
+
+ CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
+ ssTx << tx;
+
+ switch (rf) {
+ case RF_BINARY: {
+ string binaryTx = ssTx.str();
+ conn->stream() << HTTPReplyHeader(HTTP_OK, fRun, binaryTx.size(), "application/octet-stream") << binaryTx << std::flush;
+ return true;
+ }
+
+ case RF_HEX: {
+ string strHex = HexStr(ssTx.begin(), ssTx.end()) + "\n";
+ conn->stream() << HTTPReply(HTTP_OK, strHex, fRun, false, "text/plain") << std::flush;
+ return true;
+ }
+
+ case RF_JSON: {
+ Object objTx;
+ TxToJSON(tx, hashBlock, objTx);
+ string strJSON = write_string(Value(objTx), false) + "\n";
+ conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush;
+ return true;
+ }
+
+ default: {
+ throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")");
+ }
+ }
+
+ // not reached
+ return true; // continue to process further HTTP reqs on this cxn
+}
+
+static bool rest_getutxos(AcceptedConnection* conn,
+ const std::string& strURIPart,
+ const std::string& strRequest,
+ const std::map<std::string, std::string>& mapHeaders,
+ bool fRun)
+{
+ vector<string> params;
+ enum RetFormat rf = ParseDataFormat(params, strURIPart);
+
+ vector<string> uriParts;
+ if (params.size() > 0 && params[0].length() > 1)
+ {
+ std::string strUriParams = params[0].substr(1);
+ boost::split(uriParts, strUriParams, boost::is_any_of("/"));
+ }
+
+ // throw exception in case of a empty request
+ if (strRequest.length() == 0 && uriParts.size() == 0)
+ throw RESTERR(HTTP_INTERNAL_SERVER_ERROR, "Error: empty request");
+
+ bool fInputParsed = false;
+ bool fCheckMemPool = false;
+ vector<COutPoint> vOutPoints;
+
+ // parse/deserialize input
+ // input-format = output-format, rest/getutxos/bin requires binary input, gives binary output, ...
+
+ if (uriParts.size() > 0)
+ {
+
+ //inputs is sent over URI scheme (/rest/getutxos/checkmempool/txid1-n/txid2-n/...)
+ if (uriParts.size() > 0 && uriParts[0] == "checkmempool")
+ fCheckMemPool = true;
+
+ for (size_t i = (fCheckMemPool) ? 1 : 0; i < uriParts.size(); i++)
+ {
+ uint256 txid;
+ int32_t nOutput;
+ std::string strTxid = uriParts[i].substr(0, uriParts[i].find("-"));
+ std::string strOutput = uriParts[i].substr(uriParts[i].find("-")+1);
+
+ if (!ParseInt32(strOutput, &nOutput) || !IsHex(strTxid))
+ throw RESTERR(HTTP_INTERNAL_SERVER_ERROR, "Parse error");
+
+ txid.SetHex(strTxid);
+ vOutPoints.push_back(COutPoint(txid, (uint32_t)nOutput));
+ }
+
+ if (vOutPoints.size() > 0)
+ fInputParsed = true;
+ else
+ throw RESTERR(HTTP_INTERNAL_SERVER_ERROR, "Error: empty request");
+ }
+
+ string strRequestMutable = strRequest; //convert const string to string for allowing hex to bin converting
+
+ switch (rf) {
+ case RF_HEX: {
+ // convert hex to bin, continue then with bin part
+ std::vector<unsigned char> strRequestV = ParseHex(strRequest);
+ strRequestMutable.assign(strRequestV.begin(), strRequestV.end());
+ }
+
+ case RF_BINARY: {
+ try {
+ //deserialize only if user sent a request
+ if (strRequestMutable.size() > 0)
+ {
+ if (fInputParsed) //don't allow sending input over URI and HTTP RAW DATA
+ throw RESTERR(HTTP_INTERNAL_SERVER_ERROR, "Combination of URI scheme inputs and raw post data is not allowed");
+
+ CDataStream oss(SER_NETWORK, PROTOCOL_VERSION);
+ oss << strRequestMutable;
+ oss >> fCheckMemPool;
+ oss >> vOutPoints;
+ }
+ } catch (const std::ios_base::failure& e) {
+ // abort in case of unreadable binary data
+ throw RESTERR(HTTP_INTERNAL_SERVER_ERROR, "Parse error");
+ }
+ break;
+ }
+
+ case RF_JSON: {
+ if (!fInputParsed)
+ throw RESTERR(HTTP_INTERNAL_SERVER_ERROR, "Error: empty request");
+ break;
+ }
+ default: {
+ throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")");
+ }
+ }
+
+ // limit max outpoints
+ if (vOutPoints.size() > MAX_GETUTXOS_OUTPOINTS)
+ throw RESTERR(HTTP_INTERNAL_SERVER_ERROR, strprintf("Error: max outpoints exceeded (max: %d, tried: %d)", MAX_GETUTXOS_OUTPOINTS, vOutPoints.size()));
+
+ // check spentness and form a bitmap (as well as a JSON capable human-readble string representation)
+ vector<unsigned char> bitmap;
+ vector<CCoin> outs;
+ std::string bitmapStringRepresentation;
+ boost::dynamic_bitset<unsigned char> hits(vOutPoints.size());
+ {
+ LOCK2(cs_main, mempool.cs);
+
+ CCoinsView viewDummy;
+ CCoinsViewCache view(&viewDummy);
+
+ CCoinsViewCache& viewChain = *pcoinsTip;
+ CCoinsViewMemPool viewMempool(&viewChain, mempool);
+
+ if (fCheckMemPool)
+ view.SetBackend(viewMempool); // switch cache backend to db+mempool in case user likes to query mempool
+
+ for (size_t i = 0; i < vOutPoints.size(); i++) {
+ CCoins coins;
+ uint256 hash = vOutPoints[i].hash;
+ if (view.GetCoins(hash, coins)) {
+ mempool.pruneSpent(hash, coins);
+ if (coins.IsAvailable(vOutPoints[i].n)) {
+ hits[i] = true;
+ // Safe to index into vout here because IsAvailable checked if it's off the end of the array, or if
+ // n is valid but points to an already spent output (IsNull).
+ CCoin coin;
+ coin.nTxVer = coins.nVersion;
+ coin.nHeight = coins.nHeight;
+ coin.out = coins.vout.at(vOutPoints[i].n);
+ assert(!coin.out.IsNull());
+ outs.push_back(coin);
+ }
+ }
+
+ bitmapStringRepresentation.append(hits[i] ? "1" : "0"); // form a binary string representation (human-readable for json output)
+ }
+ }
+ boost::to_block_range(hits, std::back_inserter(bitmap));
+
+ switch (rf) {
+ case RF_BINARY: {
+ // serialize data
+ // use exact same output as mentioned in Bip64
+ CDataStream ssGetUTXOResponse(SER_NETWORK, PROTOCOL_VERSION);
+ ssGetUTXOResponse << chainActive.Height() << chainActive.Tip()->GetBlockHash() << bitmap << outs;
+ string ssGetUTXOResponseString = ssGetUTXOResponse.str();
+
+ conn->stream() << HTTPReplyHeader(HTTP_OK, fRun, ssGetUTXOResponseString.size(), "application/octet-stream") << ssGetUTXOResponseString << std::flush;
+ return true;
+ }
+
+ case RF_HEX: {
+ CDataStream ssGetUTXOResponse(SER_NETWORK, PROTOCOL_VERSION);
+ ssGetUTXOResponse << chainActive.Height() << chainActive.Tip()->GetBlockHash() << bitmap << outs;
+ string strHex = HexStr(ssGetUTXOResponse.begin(), ssGetUTXOResponse.end()) + "\n";
+
+ conn->stream() << HTTPReply(HTTP_OK, strHex, fRun, false, "text/plain") << std::flush;
+ return true;
+ }
+
+ case RF_JSON: {
+ Object objGetUTXOResponse;
+
+ // pack in some essentials
+ // use more or less the same output as mentioned in Bip64
+ objGetUTXOResponse.push_back(Pair("chainHeight", chainActive.Height()));
+ objGetUTXOResponse.push_back(Pair("chaintipHash", chainActive.Tip()->GetBlockHash().GetHex()));
+ objGetUTXOResponse.push_back(Pair("bitmap", bitmapStringRepresentation));
+
+ Array utxos;
+ BOOST_FOREACH (const CCoin& coin, outs) {
+ Object utxo;
+ utxo.push_back(Pair("txvers", (int32_t)coin.nTxVer));
+ utxo.push_back(Pair("height", (int32_t)coin.nHeight));
+ utxo.push_back(Pair("value", ValueFromAmount(coin.out.nValue)));
+
+ // include the script in a json output
+ Object o;
+ ScriptPubKeyToJSON(coin.out.scriptPubKey, o, true);
+ utxo.push_back(Pair("scriptPubKey", o));
+ utxos.push_back(utxo);
+ }
+ objGetUTXOResponse.push_back(Pair("utxos", utxos));
+
+ // return json string
+ string strJSON = write_string(Value(objGetUTXOResponse), false) + "\n";
+ conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush;
+ return true;
+ }
+ default: {
+ throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")");
+ }
+ }
+
+ // not reached
+ return true; // continue to process further HTTP reqs on this cxn
+}
+
+static const struct {
+ const char* prefix;
+ bool (*handler)(AcceptedConnection* conn,
+ const std::string& strURIPart,
+ const std::string& strRequest,
+ const std::map<std::string, std::string>& mapHeaders,
+ bool fRun);
+} uri_prefixes[] = {
+ {"/rest/tx/", rest_tx},
+ {"/rest/block/notxdetails/", rest_block_notxdetails},
+ {"/rest/block/", rest_block_extended},
+ {"/rest/chaininfo", rest_chaininfo},
+ {"/rest/headers/", rest_headers},
+ {"/rest/getutxos", rest_getutxos},
+};
+
+bool HTTPReq_REST(AcceptedConnection* conn,
+ const std::string& strURI,
+ const string& strRequest,
+ const std::map<std::string, std::string>& mapHeaders,
+ bool fRun)
+{
+ try {
+ std::string statusmessage;
+ if (RPCIsInWarmup(&statusmessage))
+ throw RESTERR(HTTP_SERVICE_UNAVAILABLE, "Service temporarily unavailable: " + statusmessage);
+
+ for (unsigned int i = 0; i < ARRAYLEN(uri_prefixes); i++) {
+ unsigned int plen = strlen(uri_prefixes[i].prefix);
+ if (strURI.substr(0, plen) == uri_prefixes[i].prefix) {
+ string strURIPart = strURI.substr(plen);
+ return uri_prefixes[i].handler(conn, strURIPart, strRequest, mapHeaders, fRun);
+ }
+ }
+ } catch (const RestErr& re) {
+ conn->stream() << HTTPReply(re.status, re.message + "\r\n", false, false, "text/plain") << std::flush;
+ return false;
+ }
+
+ conn->stream() << HTTPError(HTTP_NOT_FOUND, false) << std::flush;
+ return false;
+}
diff --git a/src/reverselock.h b/src/reverselock.h
new file mode 100644
index 0000000000..567636e16a
--- /dev/null
+++ b/src/reverselock.h
@@ -0,0 +1,31 @@
+// Copyright (c) 2015 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_REVERSELOCK_H
+#define BITCOIN_REVERSELOCK_H
+
+/**
+ * An RAII-style reverse lock. Unlocks on construction and locks on destruction.
+ */
+template<typename Lock>
+class reverse_lock
+{
+public:
+
+ explicit reverse_lock(Lock& lock) : lock(lock) {
+ lock.unlock();
+ }
+
+ ~reverse_lock() {
+ lock.lock();
+ }
+
+private:
+ reverse_lock(reverse_lock const&);
+ reverse_lock& operator=(reverse_lock const&);
+
+ Lock& lock;
+};
+
+#endif // BITCOIN_REVERSELOCK_H
diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp
new file mode 100644
index 0000000000..1bab3b66a2
--- /dev/null
+++ b/src/rpcblockchain.cpp
@@ -0,0 +1,767 @@
+// Copyright (c) 2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "checkpoints.h"
+#include "consensus/validation.h"
+#include "main.h"
+#include "primitives/transaction.h"
+#include "rpcserver.h"
+#include "sync.h"
+#include "util.h"
+
+#include <stdint.h>
+
+#include "json/json_spirit_value.h"
+
+using namespace json_spirit;
+using namespace std;
+
+extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry);
+void ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out, bool fIncludeHex);
+
+double GetDifficulty(const CBlockIndex* blockindex)
+{
+ // Floating point number that is a multiple of the minimum difficulty,
+ // minimum difficulty = 1.0.
+ if (blockindex == NULL)
+ {
+ if (chainActive.Tip() == NULL)
+ return 1.0;
+ else
+ blockindex = chainActive.Tip();
+ }
+
+ 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;
+}
+
+
+Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false)
+{
+ Object result;
+ result.push_back(Pair("hash", block.GetHash().GetHex()));
+ int confirmations = -1;
+ // Only report confirmations if the block is on the main chain
+ if (chainActive.Contains(blockindex))
+ confirmations = chainActive.Height() - blockindex->nHeight + 1;
+ result.push_back(Pair("confirmations", confirmations));
+ 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)
+ {
+ if(txDetails)
+ {
+ Object objTx;
+ TxToJSON(tx, uint256(), objTx);
+ txs.push_back(objTx);
+ }
+ else
+ txs.push_back(tx.GetHash().GetHex());
+ }
+ result.push_back(Pair("tx", txs));
+ result.push_back(Pair("time", block.GetBlockTime()));
+ result.push_back(Pair("nonce", (uint64_t)block.nNonce));
+ result.push_back(Pair("bits", strprintf("%08x", block.nBits)));
+ result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
+ result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex()));
+
+ if (blockindex->pprev)
+ result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()));
+ CBlockIndex *pnext = chainActive.Next(blockindex);
+ if (pnext)
+ result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex()));
+ return result;
+}
+
+
+Value getblockcount(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() != 0)
+ throw runtime_error(
+ "getblockcount\n"
+ "\nReturns the number of blocks in the longest block chain.\n"
+ "\nResult:\n"
+ "n (numeric) The current block count\n"
+ "\nExamples:\n"
+ + HelpExampleCli("getblockcount", "")
+ + HelpExampleRpc("getblockcount", "")
+ );
+
+ LOCK(cs_main);
+ return chainActive.Height();
+}
+
+Value getbestblockhash(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() != 0)
+ throw runtime_error(
+ "getbestblockhash\n"
+ "\nReturns the hash of the best (tip) block in the longest block chain.\n"
+ "\nResult\n"
+ "\"hex\" (string) the block hash hex encoded\n"
+ "\nExamples\n"
+ + HelpExampleCli("getbestblockhash", "")
+ + HelpExampleRpc("getbestblockhash", "")
+ );
+
+ LOCK(cs_main);
+ return chainActive.Tip()->GetBlockHash().GetHex();
+}
+
+Value getdifficulty(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() != 0)
+ throw runtime_error(
+ "getdifficulty\n"
+ "\nReturns the proof-of-work difficulty as a multiple of the minimum difficulty.\n"
+ "\nResult:\n"
+ "n.nnn (numeric) the proof-of-work difficulty as a multiple of the minimum difficulty.\n"
+ "\nExamples:\n"
+ + HelpExampleCli("getdifficulty", "")
+ + HelpExampleRpc("getdifficulty", "")
+ );
+
+ LOCK(cs_main);
+ return GetDifficulty();
+}
+
+
+Value getrawmempool(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() > 1)
+ throw runtime_error(
+ "getrawmempool ( verbose )\n"
+ "\nReturns all transaction ids in memory pool as a json array of string transaction ids.\n"
+ "\nArguments:\n"
+ "1. verbose (boolean, optional, default=false) true for a json object, false for array of transaction ids\n"
+ "\nResult: (for verbose = false):\n"
+ "[ (json array of string)\n"
+ " \"transactionid\" (string) The transaction id\n"
+ " ,...\n"
+ "]\n"
+ "\nResult: (for verbose = true):\n"
+ "{ (json object)\n"
+ " \"transactionid\" : { (json object)\n"
+ " \"size\" : n, (numeric) transaction size in bytes\n"
+ " \"fee\" : n, (numeric) transaction fee in bitcoins\n"
+ " \"time\" : n, (numeric) local time transaction entered pool in seconds since 1 Jan 1970 GMT\n"
+ " \"height\" : n, (numeric) block height when transaction entered pool\n"
+ " \"startingpriority\" : n, (numeric) priority when transaction entered pool\n"
+ " \"currentpriority\" : n, (numeric) transaction priority now\n"
+ " \"depends\" : [ (array) unconfirmed transactions used as inputs for this transaction\n"
+ " \"transactionid\", (string) parent transaction id\n"
+ " ... ]\n"
+ " }, ...\n"
+ "}\n"
+ "\nExamples\n"
+ + HelpExampleCli("getrawmempool", "true")
+ + HelpExampleRpc("getrawmempool", "true")
+ );
+
+ LOCK(cs_main);
+
+ bool fVerbose = false;
+ if (params.size() > 0)
+ fVerbose = params[0].get_bool();
+
+ if (fVerbose)
+ {
+ LOCK(mempool.cs);
+ Object o;
+ BOOST_FOREACH(const PAIRTYPE(uint256, CTxMemPoolEntry)& entry, mempool.mapTx)
+ {
+ const uint256& hash = entry.first;
+ const CTxMemPoolEntry& e = entry.second;
+ Object info;
+ info.push_back(Pair("size", (int)e.GetTxSize()));
+ info.push_back(Pair("fee", ValueFromAmount(e.GetFee())));
+ info.push_back(Pair("time", e.GetTime()));
+ info.push_back(Pair("height", (int)e.GetHeight()));
+ info.push_back(Pair("startingpriority", e.GetPriority(e.GetHeight())));
+ info.push_back(Pair("currentpriority", e.GetPriority(chainActive.Height())));
+ const CTransaction& tx = e.GetTx();
+ set<string> setDepends;
+ BOOST_FOREACH(const CTxIn& txin, tx.vin)
+ {
+ if (mempool.exists(txin.prevout.hash))
+ setDepends.insert(txin.prevout.hash.ToString());
+ }
+ Array depends(setDepends.begin(), setDepends.end());
+ info.push_back(Pair("depends", depends));
+ o.push_back(Pair(hash.ToString(), info));
+ }
+ return o;
+ }
+ else
+ {
+ vector<uint256> 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 index\n"
+ "\nReturns hash of block in best-block-chain at index provided.\n"
+ "\nArguments:\n"
+ "1. index (numeric, required) The block index\n"
+ "\nResult:\n"
+ "\"hash\" (string) The block hash\n"
+ "\nExamples:\n"
+ + HelpExampleCli("getblockhash", "1000")
+ + HelpExampleRpc("getblockhash", "1000")
+ );
+
+ LOCK(cs_main);
+
+ int nHeight = params[0].get_int();
+ if (nHeight < 0 || nHeight > chainActive.Height())
+ throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
+
+ CBlockIndex* pblockindex = chainActive[nHeight];
+ return pblockindex->GetBlockHash().GetHex();
+}
+
+Value getblock(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() < 1 || params.size() > 2)
+ throw runtime_error(
+ "getblock \"hash\" ( verbose )\n"
+ "\nIf verbose is false, returns a string that is serialized, hex-encoded data for block 'hash'.\n"
+ "If verbose is true, returns an Object with information about block <hash>.\n"
+ "\nArguments:\n"
+ "1. \"hash\" (string, required) The block hash\n"
+ "2. verbose (boolean, optional, default=true) true for a json object, false for the hex encoded data\n"
+ "\nResult (for verbose = true):\n"
+ "{\n"
+ " \"hash\" : \"hash\", (string) the block hash (same as provided)\n"
+ " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n"
+ " \"size\" : n, (numeric) The block size\n"
+ " \"height\" : n, (numeric) The block height or index\n"
+ " \"version\" : n, (numeric) The block version\n"
+ " \"merkleroot\" : \"xxxx\", (string) The merkle root\n"
+ " \"tx\" : [ (array of string) The transaction ids\n"
+ " \"transactionid\" (string) The transaction id\n"
+ " ,...\n"
+ " ],\n"
+ " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
+ " \"nonce\" : n, (numeric) The nonce\n"
+ " \"bits\" : \"1d00ffff\", (string) The bits\n"
+ " \"difficulty\" : x.xxx, (numeric) The difficulty\n"
+ " \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n"
+ " \"nextblockhash\" : \"hash\" (string) The hash of the next block\n"
+ "}\n"
+ "\nResult (for verbose=false):\n"
+ "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n"
+ "\nExamples:\n"
+ + HelpExampleCli("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
+ + HelpExampleRpc("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
+ );
+
+ LOCK(cs_main);
+
+ std::string strHash = params[0].get_str();
+ uint256 hash(uint256S(strHash));
+
+ bool fVerbose = true;
+ if (params.size() > 1)
+ fVerbose = params[1].get_bool();
+
+ if (mapBlockIndex.count(hash) == 0)
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
+
+ CBlock block;
+ CBlockIndex* pblockindex = mapBlockIndex[hash];
+
+ if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0)
+ throw JSONRPCError(RPC_INTERNAL_ERROR, "Block not available (pruned data)");
+
+ if(!ReadBlockFromDisk(block, pblockindex))
+ throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk");
+
+ if (!fVerbose)
+ {
+ CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION);
+ ssBlock << block;
+ std::string strHex = HexStr(ssBlock.begin(), ssBlock.end());
+ return strHex;
+ }
+
+ return blockToJSON(block, pblockindex);
+}
+
+Value gettxoutsetinfo(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() != 0)
+ throw runtime_error(
+ "gettxoutsetinfo\n"
+ "\nReturns statistics about the unspent transaction output set.\n"
+ "Note this call may take some time.\n"
+ "\nResult:\n"
+ "{\n"
+ " \"height\":n, (numeric) The current block height (index)\n"
+ " \"bestblock\": \"hex\", (string) the best block hash hex\n"
+ " \"transactions\": n, (numeric) The number of transactions\n"
+ " \"txouts\": n, (numeric) The number of output transactions\n"
+ " \"bytes_serialized\": n, (numeric) The serialized size\n"
+ " \"hash_serialized\": \"hash\", (string) The serialized hash\n"
+ " \"total_amount\": x.xxx (numeric) The total amount\n"
+ "}\n"
+ "\nExamples:\n"
+ + HelpExampleCli("gettxoutsetinfo", "")
+ + HelpExampleRpc("gettxoutsetinfo", "")
+ );
+
+ LOCK(cs_main);
+
+ Object ret;
+
+ CCoinsStats stats;
+ FlushStateToDisk();
+ if (pcoinsTip->GetStats(stats)) {
+ ret.push_back(Pair("height", (int64_t)stats.nHeight));
+ ret.push_back(Pair("bestblock", stats.hashBlock.GetHex()));
+ ret.push_back(Pair("transactions", (int64_t)stats.nTransactions));
+ ret.push_back(Pair("txouts", (int64_t)stats.nTransactionOutputs));
+ ret.push_back(Pair("bytes_serialized", (int64_t)stats.nSerializedSize));
+ ret.push_back(Pair("hash_serialized", stats.hashSerialized.GetHex()));
+ ret.push_back(Pair("total_amount", ValueFromAmount(stats.nTotalAmount)));
+ }
+ return ret;
+}
+
+Value gettxout(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() < 2 || params.size() > 3)
+ throw runtime_error(
+ "gettxout \"txid\" n ( includemempool )\n"
+ "\nReturns details about an unspent transaction output.\n"
+ "\nArguments:\n"
+ "1. \"txid\" (string, required) The transaction id\n"
+ "2. n (numeric, required) vout value\n"
+ "3. includemempool (boolean, optional) Whether to included the mem pool\n"
+ "\nResult:\n"
+ "{\n"
+ " \"bestblock\" : \"hash\", (string) the block hash\n"
+ " \"confirmations\" : n, (numeric) The number of confirmations\n"
+ " \"value\" : x.xxx, (numeric) The transaction value in btc\n"
+ " \"scriptPubKey\" : { (json object)\n"
+ " \"asm\" : \"code\", (string) \n"
+ " \"hex\" : \"hex\", (string) \n"
+ " \"reqSigs\" : n, (numeric) Number of required signatures\n"
+ " \"type\" : \"pubkeyhash\", (string) The type, eg pubkeyhash\n"
+ " \"addresses\" : [ (array of string) array of bitcoin addresses\n"
+ " \"bitcoinaddress\" (string) bitcoin address\n"
+ " ,...\n"
+ " ]\n"
+ " },\n"
+ " \"version\" : n, (numeric) The version\n"
+ " \"coinbase\" : true|false (boolean) Coinbase or not\n"
+ "}\n"
+
+ "\nExamples:\n"
+ "\nGet unspent transactions\n"
+ + HelpExampleCli("listunspent", "") +
+ "\nView the details\n"
+ + HelpExampleCli("gettxout", "\"txid\" 1") +
+ "\nAs a json rpc call\n"
+ + HelpExampleRpc("gettxout", "\"txid\", 1")
+ );
+
+ LOCK(cs_main);
+
+ Object ret;
+
+ std::string strHash = params[0].get_str();
+ uint256 hash(uint256S(strHash));
+ int n = params[1].get_int();
+ bool fMempool = true;
+ if (params.size() > 2)
+ fMempool = params[2].get_bool();
+
+ CCoins coins;
+ if (fMempool) {
+ LOCK(mempool.cs);
+ CCoinsViewMemPool view(pcoinsTip, mempool);
+ if (!view.GetCoins(hash, coins))
+ return Value::null;
+ mempool.pruneSpent(hash, coins); // TODO: this should be done by the CCoinsViewMemPool
+ } else {
+ if (!pcoinsTip->GetCoins(hash, coins))
+ return Value::null;
+ }
+ if (n<0 || (unsigned int)n>=coins.vout.size() || coins.vout[n].IsNull())
+ return Value::null;
+
+ BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
+ CBlockIndex *pindex = it->second;
+ ret.push_back(Pair("bestblock", pindex->GetBlockHash().GetHex()));
+ if ((unsigned int)coins.nHeight == MEMPOOL_HEIGHT)
+ ret.push_back(Pair("confirmations", 0));
+ else
+ ret.push_back(Pair("confirmations", pindex->nHeight - coins.nHeight + 1));
+ ret.push_back(Pair("value", ValueFromAmount(coins.vout[n].nValue)));
+ Object o;
+ ScriptPubKeyToJSON(coins.vout[n].scriptPubKey, o, true);
+ ret.push_back(Pair("scriptPubKey", o));
+ ret.push_back(Pair("version", coins.nVersion));
+ ret.push_back(Pair("coinbase", coins.fCoinBase));
+
+ return ret;
+}
+
+Value verifychain(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() > 2)
+ throw runtime_error(
+ "verifychain ( checklevel numblocks )\n"
+ "\nVerifies blockchain database.\n"
+ "\nArguments:\n"
+ "1. checklevel (numeric, optional, 0-4, default=3) How thorough the block verification is.\n"
+ "2. numblocks (numeric, optional, default=288, 0=all) The number of blocks to check.\n"
+ "\nResult:\n"
+ "true|false (boolean) Verified or not\n"
+ "\nExamples:\n"
+ + HelpExampleCli("verifychain", "")
+ + HelpExampleRpc("verifychain", "")
+ );
+
+ LOCK(cs_main);
+
+ int nCheckLevel = GetArg("-checklevel", 3);
+ int nCheckDepth = GetArg("-checkblocks", 288);
+ if (params.size() > 0)
+ nCheckLevel = params[0].get_int();
+ if (params.size() > 1)
+ nCheckDepth = params[1].get_int();
+
+ return CVerifyDB().VerifyDB(pcoinsTip, nCheckLevel, nCheckDepth);
+}
+
+/** Implementation of IsSuperMajority with better feedback */
+Object SoftForkMajorityDesc(int minVersion, CBlockIndex* pindex, int nRequired, const Consensus::Params& consensusParams)
+{
+ int nFound = 0;
+ CBlockIndex* pstart = pindex;
+ for (int i = 0; i < consensusParams.nMajorityWindow && pstart != NULL; i++)
+ {
+ if (pstart->nVersion >= minVersion)
+ ++nFound;
+ pstart = pstart->pprev;
+ }
+
+ Object rv;
+ rv.push_back(Pair("status", nFound >= nRequired));
+ rv.push_back(Pair("found", nFound));
+ rv.push_back(Pair("required", nRequired));
+ rv.push_back(Pair("window", consensusParams.nMajorityWindow));
+ return rv;
+}
+
+Object SoftForkDesc(const std::string &name, int version, CBlockIndex* pindex, const Consensus::Params& consensusParams)
+{
+ Object rv;
+ rv.push_back(Pair("id", name));
+ rv.push_back(Pair("version", version));
+ rv.push_back(Pair("enforce", SoftForkMajorityDesc(version, pindex, consensusParams.nMajorityEnforceBlockUpgrade, consensusParams)));
+ rv.push_back(Pair("reject", SoftForkMajorityDesc(version, pindex, consensusParams.nMajorityRejectBlockOutdated, consensusParams)));
+ return rv;
+}
+
+Value getblockchaininfo(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() != 0)
+ throw runtime_error(
+ "getblockchaininfo\n"
+ "Returns an object containing various state info regarding block chain processing.\n"
+ "\nResult:\n"
+ "{\n"
+ " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n"
+ " \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n"
+ " \"headers\": xxxxxx, (numeric) the current number of headers we have validated\n"
+ " \"bestblockhash\": \"...\", (string) the hash of the currently best block\n"
+ " \"difficulty\": xxxxxx, (numeric) the current difficulty\n"
+ " \"verificationprogress\": xxxx, (numeric) estimate of verification progress [0..1]\n"
+ " \"chainwork\": \"xxxx\" (string) total amount of work in active chain, in hexadecimal\n"
+ " \"softforks\": [ (array) status of softforks in progress\n"
+ " {\n"
+ " \"id\": \"xxxx\", (string) name of softfork\n"
+ " \"version\": xx, (numeric) block version\n"
+ " \"enforce\": { (object) progress toward enforcing the softfork rules for new-version blocks\n"
+ " \"status\": xx, (boolean) true if threshold reached\n"
+ " \"found\": xx, (numeric) number of blocks with the new version found\n"
+ " \"required\": xx, (numeric) number of blocks required to trigger\n"
+ " \"window\": xx, (numeric) maximum size of examined window of recent blocks\n"
+ " },\n"
+ " \"reject\": { ... } (object) progress toward rejecting pre-softfork blocks (same fields as \"enforce\")\n"
+ " }, ...\n"
+ " ]\n"
+ "}\n"
+ "\nExamples:\n"
+ + HelpExampleCli("getblockchaininfo", "")
+ + HelpExampleRpc("getblockchaininfo", "")
+ );
+
+ LOCK(cs_main);
+
+ Object obj;
+ obj.push_back(Pair("chain", Params().NetworkIDString()));
+ obj.push_back(Pair("blocks", (int)chainActive.Height()));
+ obj.push_back(Pair("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1));
+ obj.push_back(Pair("bestblockhash", chainActive.Tip()->GetBlockHash().GetHex()));
+ obj.push_back(Pair("difficulty", (double)GetDifficulty()));
+ obj.push_back(Pair("verificationprogress", Checkpoints::GuessVerificationProgress(Params().Checkpoints(), chainActive.Tip())));
+ obj.push_back(Pair("chainwork", chainActive.Tip()->nChainWork.GetHex()));
+ obj.push_back(Pair("pruned", fPruneMode));
+
+ const Consensus::Params& consensusParams = Params().GetConsensus();
+ CBlockIndex* tip = chainActive.Tip();
+ Array softforks;
+ softforks.push_back(SoftForkDesc("bip34", 2, tip, consensusParams));
+ softforks.push_back(SoftForkDesc("bip66", 3, tip, consensusParams));
+ softforks.push_back(SoftForkDesc("bip65", 4, tip, consensusParams));
+ obj.push_back(Pair("softforks", softforks));
+
+ if (fPruneMode)
+ {
+ CBlockIndex *block = chainActive.Tip();
+ while (block && block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA))
+ block = block->pprev;
+
+ obj.push_back(Pair("pruneheight", block->nHeight));
+ }
+ return obj;
+}
+
+/** Comparison function for sorting the getchaintips heads. */
+struct CompareBlocksByHeight
+{
+ bool operator()(const CBlockIndex* a, const CBlockIndex* b) const
+ {
+ /* Make sure that unequal blocks with the same height do not compare
+ equal. Use the pointers themselves to make a distinction. */
+
+ if (a->nHeight != b->nHeight)
+ return (a->nHeight > b->nHeight);
+
+ return a < b;
+ }
+};
+
+Value getchaintips(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() != 0)
+ throw runtime_error(
+ "getchaintips\n"
+ "Return information about all known tips in the block tree,"
+ " including the main chain as well as orphaned branches.\n"
+ "\nResult:\n"
+ "[\n"
+ " {\n"
+ " \"height\": xxxx, (numeric) height of the chain tip\n"
+ " \"hash\": \"xxxx\", (string) block hash of the tip\n"
+ " \"branchlen\": 0 (numeric) zero for main chain\n"
+ " \"status\": \"active\" (string) \"active\" for the main chain\n"
+ " },\n"
+ " {\n"
+ " \"height\": xxxx,\n"
+ " \"hash\": \"xxxx\",\n"
+ " \"branchlen\": 1 (numeric) length of branch connecting the tip to the main chain\n"
+ " \"status\": \"xxxx\" (string) status of the chain (active, valid-fork, valid-headers, headers-only, invalid)\n"
+ " }\n"
+ "]\n"
+ "Possible values for status:\n"
+ "1. \"invalid\" This branch contains at least one invalid block\n"
+ "2. \"headers-only\" Not all blocks for this branch are available, but the headers are valid\n"
+ "3. \"valid-headers\" All blocks are available for this branch, but they were never fully validated\n"
+ "4. \"valid-fork\" This branch is not part of the active chain, but is fully validated\n"
+ "5. \"active\" This is the tip of the active main chain, which is certainly valid\n"
+ "\nExamples:\n"
+ + HelpExampleCli("getchaintips", "")
+ + HelpExampleRpc("getchaintips", "")
+ );
+
+ LOCK(cs_main);
+
+ /* Build up a list of chain tips. We start with the list of all
+ known blocks, and successively remove blocks that appear as pprev
+ of another block. */
+ std::set<const CBlockIndex*, CompareBlocksByHeight> setTips;
+ BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex)
+ setTips.insert(item.second);
+ BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex)
+ {
+ const CBlockIndex* pprev = item.second->pprev;
+ if (pprev)
+ setTips.erase(pprev);
+ }
+
+ // Always report the currently active tip.
+ setTips.insert(chainActive.Tip());
+
+ /* Construct the output array. */
+ Array res;
+ BOOST_FOREACH(const CBlockIndex* block, setTips)
+ {
+ Object obj;
+ obj.push_back(Pair("height", block->nHeight));
+ obj.push_back(Pair("hash", block->phashBlock->GetHex()));
+
+ const int branchLen = block->nHeight - chainActive.FindFork(block)->nHeight;
+ obj.push_back(Pair("branchlen", branchLen));
+
+ string status;
+ if (chainActive.Contains(block)) {
+ // This block is part of the currently active chain.
+ status = "active";
+ } else if (block->nStatus & BLOCK_FAILED_MASK) {
+ // This block or one of its ancestors is invalid.
+ status = "invalid";
+ } else if (block->nChainTx == 0) {
+ // This block cannot be connected because full block data for it or one of its parents is missing.
+ status = "headers-only";
+ } else if (block->IsValid(BLOCK_VALID_SCRIPTS)) {
+ // This block is fully validated, but no longer part of the active chain. It was probably the active block once, but was reorganized.
+ status = "valid-fork";
+ } else if (block->IsValid(BLOCK_VALID_TREE)) {
+ // The headers for this block are valid, but it has not been validated. It was probably never part of the most-work chain.
+ status = "valid-headers";
+ } else {
+ // No clue.
+ status = "unknown";
+ }
+ obj.push_back(Pair("status", status));
+
+ res.push_back(obj);
+ }
+
+ return res;
+}
+
+Value getmempoolinfo(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() != 0)
+ throw runtime_error(
+ "getmempoolinfo\n"
+ "\nReturns details on the active state of the TX memory pool.\n"
+ "\nResult:\n"
+ "{\n"
+ " \"size\": xxxxx (numeric) Current tx count\n"
+ " \"bytes\": xxxxx (numeric) Sum of all tx sizes\n"
+ "}\n"
+ "\nExamples:\n"
+ + HelpExampleCli("getmempoolinfo", "")
+ + HelpExampleRpc("getmempoolinfo", "")
+ );
+
+ Object ret;
+ ret.push_back(Pair("size", (int64_t) mempool.size()));
+ ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize()));
+
+ return ret;
+}
+
+Value invalidateblock(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() != 1)
+ throw runtime_error(
+ "invalidateblock \"hash\"\n"
+ "\nPermanently marks a block as invalid, as if it violated a consensus rule.\n"
+ "\nArguments:\n"
+ "1. hash (string, required) the hash of the block to mark as invalid\n"
+ "\nResult:\n"
+ "\nExamples:\n"
+ + HelpExampleCli("invalidateblock", "\"blockhash\"")
+ + HelpExampleRpc("invalidateblock", "\"blockhash\"")
+ );
+
+ std::string strHash = params[0].get_str();
+ uint256 hash(uint256S(strHash));
+ CValidationState state;
+
+ {
+ LOCK(cs_main);
+ if (mapBlockIndex.count(hash) == 0)
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
+
+ CBlockIndex* pblockindex = mapBlockIndex[hash];
+ InvalidateBlock(state, pblockindex);
+ }
+
+ if (state.IsValid()) {
+ ActivateBestChain(state);
+ }
+
+ if (!state.IsValid()) {
+ throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
+ }
+
+ return Value::null;
+}
+
+Value reconsiderblock(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() != 1)
+ throw runtime_error(
+ "reconsiderblock \"hash\"\n"
+ "\nRemoves invalidity status of a block and its descendants, reconsider them for activation.\n"
+ "This can be used to undo the effects of invalidateblock.\n"
+ "\nArguments:\n"
+ "1. hash (string, required) the hash of the block to reconsider\n"
+ "\nResult:\n"
+ "\nExamples:\n"
+ + HelpExampleCli("reconsiderblock", "\"blockhash\"")
+ + HelpExampleRpc("reconsiderblock", "\"blockhash\"")
+ );
+
+ std::string strHash = params[0].get_str();
+ uint256 hash(uint256S(strHash));
+ CValidationState state;
+
+ {
+ LOCK(cs_main);
+ if (mapBlockIndex.count(hash) == 0)
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
+
+ CBlockIndex* pblockindex = mapBlockIndex[hash];
+ ReconsiderBlock(state, pblockindex);
+ }
+
+ if (state.IsValid()) {
+ ActivateBestChain(state);
+ }
+
+ if (!state.IsValid()) {
+ throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
+ }
+
+ return Value::null;
+}
diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp
new file mode 100644
index 0000000000..4b576b3707
--- /dev/null
+++ b/src/rpcclient.cpp
@@ -0,0 +1,146 @@
+// Copyright (c) 2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "rpcclient.h"
+
+#include "rpcprotocol.h"
+#include "util.h"
+
+#include <set>
+#include <stdint.h>
+
+using namespace std;
+using namespace json_spirit;
+
+class CRPCConvertParam
+{
+public:
+ std::string methodName; //! method whose params want conversion
+ int paramIdx; //! 0-based idx of param to convert
+};
+
+static const CRPCConvertParam vRPCConvertParams[] =
+{
+ { "stop", 0 },
+ { "setmocktime", 0 },
+ { "getaddednodeinfo", 0 },
+ { "setgenerate", 0 },
+ { "setgenerate", 1 },
+ { "generate", 0 },
+ { "getnetworkhashps", 0 },
+ { "getnetworkhashps", 1 },
+ { "sendtoaddress", 1 },
+ { "sendtoaddress", 4 },
+ { "settxfee", 0 },
+ { "getreceivedbyaddress", 1 },
+ { "getreceivedbyaccount", 1 },
+ { "listreceivedbyaddress", 0 },
+ { "listreceivedbyaddress", 1 },
+ { "listreceivedbyaddress", 2 },
+ { "listreceivedbyaccount", 0 },
+ { "listreceivedbyaccount", 1 },
+ { "listreceivedbyaccount", 2 },
+ { "getbalance", 1 },
+ { "getbalance", 2 },
+ { "getblockhash", 0 },
+ { "move", 2 },
+ { "move", 3 },
+ { "sendfrom", 2 },
+ { "sendfrom", 3 },
+ { "listtransactions", 1 },
+ { "listtransactions", 2 },
+ { "listtransactions", 3 },
+ { "listaccounts", 0 },
+ { "listaccounts", 1 },
+ { "walletpassphrase", 1 },
+ { "getblocktemplate", 0 },
+ { "listsinceblock", 1 },
+ { "listsinceblock", 2 },
+ { "sendmany", 1 },
+ { "sendmany", 2 },
+ { "sendmany", 4 },
+ { "addmultisigaddress", 0 },
+ { "addmultisigaddress", 1 },
+ { "createmultisig", 0 },
+ { "createmultisig", 1 },
+ { "listunspent", 0 },
+ { "listunspent", 1 },
+ { "listunspent", 2 },
+ { "getblock", 1 },
+ { "gettransaction", 1 },
+ { "getrawtransaction", 1 },
+ { "createrawtransaction", 0 },
+ { "createrawtransaction", 1 },
+ { "signrawtransaction", 1 },
+ { "signrawtransaction", 2 },
+ { "sendrawtransaction", 1 },
+ { "gettxout", 1 },
+ { "gettxout", 2 },
+ { "gettxoutproof", 0 },
+ { "lockunspent", 0 },
+ { "lockunspent", 1 },
+ { "importprivkey", 2 },
+ { "importaddress", 2 },
+ { "verifychain", 0 },
+ { "verifychain", 1 },
+ { "keypoolrefill", 0 },
+ { "getrawmempool", 0 },
+ { "estimatefee", 0 },
+ { "estimatepriority", 0 },
+ { "prioritisetransaction", 1 },
+ { "prioritisetransaction", 2 },
+};
+
+class CRPCConvertTable
+{
+private:
+ std::set<std::pair<std::string, int> > members;
+
+public:
+ CRPCConvertTable();
+
+ bool convert(const std::string& method, int idx) {
+ return (members.count(std::make_pair(method, idx)) > 0);
+ }
+};
+
+CRPCConvertTable::CRPCConvertTable()
+{
+ const unsigned int n_elem =
+ (sizeof(vRPCConvertParams) / sizeof(vRPCConvertParams[0]));
+
+ for (unsigned int i = 0; i < n_elem; i++) {
+ members.insert(std::make_pair(vRPCConvertParams[i].methodName,
+ vRPCConvertParams[i].paramIdx));
+ }
+}
+
+static CRPCConvertTable rpcCvtTable;
+
+/** Convert strings to command-specific RPC representation */
+Array RPCConvertValues(const std::string &strMethod, const std::vector<std::string> &strParams)
+{
+ Array params;
+
+ for (unsigned int idx = 0; idx < strParams.size(); idx++) {
+ const std::string& strVal = strParams[idx];
+
+ // insert string value directly
+ if (!rpcCvtTable.convert(strMethod, idx)) {
+ params.push_back(strVal);
+ }
+
+ // parse string as JSON, insert bool/number/object/etc. value
+ else {
+ Value jVal;
+ if (!read_string(strVal, jVal))
+ throw runtime_error(string("Error parsing JSON:")+strVal);
+ params.push_back(jVal);
+ }
+ }
+
+ return params;
+}
+
diff --git a/src/rpcclient.h b/src/rpcclient.h
new file mode 100644
index 0000000000..42fa2d06fe
--- /dev/null
+++ b/src/rpcclient.h
@@ -0,0 +1,15 @@
+// Copyright (c) 2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_RPCCLIENT_H
+#define BITCOIN_RPCCLIENT_H
+
+#include "json/json_spirit_reader_template.h"
+#include "json/json_spirit_utils.h"
+#include "json/json_spirit_writer_template.h"
+
+json_spirit::Array RPCConvertValues(const std::string& strMethod, const std::vector<std::string>& strParams);
+
+#endif // BITCOIN_RPCCLIENT_H
diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp
new file mode 100644
index 0000000000..528d5406f4
--- /dev/null
+++ b/src/rpcmining.cpp
@@ -0,0 +1,728 @@
+// Copyright (c) 2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "amount.h"
+#include "chainparams.h"
+#include "consensus/consensus.h"
+#include "consensus/validation.h"
+#include "core_io.h"
+#include "init.h"
+#include "main.h"
+#include "miner.h"
+#include "net.h"
+#include "pow.h"
+#include "rpcserver.h"
+#include "util.h"
+#include "validationinterface.h"
+#ifdef ENABLE_WALLET
+#include "wallet/wallet.h"
+#endif
+
+#include <stdint.h>
+
+#include <boost/assign/list_of.hpp>
+
+#include "json/json_spirit_utils.h"
+#include "json/json_spirit_value.h"
+
+using namespace json_spirit;
+using namespace std;
+
+/**
+ * Return average network hashes per second based on the last 'lookup' blocks,
+ * or from the last difficulty change if 'lookup' is nonpositive.
+ * If 'height' is nonnegative, compute the estimate at the time when a given block was found.
+ */
+Value GetNetworkHashPS(int lookup, int height) {
+ CBlockIndex *pb = chainActive.Tip();
+
+ if (height >= 0 && height < chainActive.Height())
+ pb = chainActive[height];
+
+ if (pb == NULL || !pb->nHeight)
+ return 0;
+
+ // If lookup is -1, then use blocks since last difficulty change.
+ if (lookup <= 0)
+ lookup = pb->nHeight % Params().GetConsensus().DifficultyAdjustmentInterval() + 1;
+
+ // If lookup is larger than chain, then set it to chain length.
+ if (lookup > pb->nHeight)
+ lookup = pb->nHeight;
+
+ CBlockIndex *pb0 = pb;
+ int64_t minTime = pb0->GetBlockTime();
+ int64_t maxTime = minTime;
+ for (int i = 0; i < lookup; i++) {
+ pb0 = pb0->pprev;
+ int64_t time = pb0->GetBlockTime();
+ minTime = std::min(time, minTime);
+ maxTime = std::max(time, maxTime);
+ }
+
+ // In case there's a situation where minTime == maxTime, we don't want a divide by zero exception.
+ if (minTime == maxTime)
+ return 0;
+
+ arith_uint256 workDiff = pb->nChainWork - pb0->nChainWork;
+ int64_t timeDiff = maxTime - minTime;
+
+ return (int64_t)(workDiff.getdouble() / timeDiff);
+}
+
+Value getnetworkhashps(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() > 2)
+ throw runtime_error(
+ "getnetworkhashps ( blocks height )\n"
+ "\nReturns the estimated network hashes per second based on the last n blocks.\n"
+ "Pass in [blocks] to override # of blocks, -1 specifies since last difficulty change.\n"
+ "Pass in [height] to estimate the network speed at the time when a certain block was found.\n"
+ "\nArguments:\n"
+ "1. blocks (numeric, optional, default=120) The number of blocks, or -1 for blocks since last difficulty change.\n"
+ "2. height (numeric, optional, default=-1) To estimate at the time of the given height.\n"
+ "\nResult:\n"
+ "x (numeric) Hashes per second estimated\n"
+ "\nExamples:\n"
+ + HelpExampleCli("getnetworkhashps", "")
+ + HelpExampleRpc("getnetworkhashps", "")
+ );
+
+ LOCK(cs_main);
+ return GetNetworkHashPS(params.size() > 0 ? params[0].get_int() : 120, params.size() > 1 ? params[1].get_int() : -1);
+}
+
+#ifdef ENABLE_WALLET
+Value getgenerate(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() != 0)
+ throw runtime_error(
+ "getgenerate\n"
+ "\nReturn if the server is set to generate coins or not. The default is false.\n"
+ "It is set with the command line argument -gen (or bitcoin.conf setting gen)\n"
+ "It can also be set with the setgenerate call.\n"
+ "\nResult\n"
+ "true|false (boolean) If the server is set to generate coins or not\n"
+ "\nExamples:\n"
+ + HelpExampleCli("getgenerate", "")
+ + HelpExampleRpc("getgenerate", "")
+ );
+
+ LOCK(cs_main);
+ return GetBoolArg("-gen", false);
+}
+
+Value generate(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() < 1 || params.size() > 1)
+ throw runtime_error(
+ "generate numblocks\n"
+ "\nMine blocks immediately (before the RPC call returns)\n"
+ "\nNote: this function can only be used on the regtest network\n"
+ "1. numblocks (numeric) How many blocks are generated immediately.\n"
+ "\nResult\n"
+ "[ blockhashes ] (array) hashes of blocks generated\n"
+ "\nExamples:\n"
+ "\nGenerate 11 blocks\n"
+ + HelpExampleCli("generate", "11")
+ );
+
+ if (pwalletMain == NULL)
+ throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)");
+ if (!Params().MineBlocksOnDemand())
+ throw JSONRPCError(RPC_METHOD_NOT_FOUND, "This method can only be used on regtest");
+
+ int nHeightStart = 0;
+ int nHeightEnd = 0;
+ int nHeight = 0;
+ int nGenerate = params[0].get_int();
+ CReserveKey reservekey(pwalletMain);
+
+ { // Don't keep cs_main locked
+ LOCK(cs_main);
+ nHeightStart = chainActive.Height();
+ nHeight = nHeightStart;
+ nHeightEnd = nHeightStart+nGenerate;
+ }
+ unsigned int nExtraNonce = 0;
+ Array blockHashes;
+ while (nHeight < nHeightEnd)
+ {
+ auto_ptr<CBlockTemplate> pblocktemplate(CreateNewBlockWithKey(reservekey));
+ if (!pblocktemplate.get())
+ throw JSONRPCError(RPC_INTERNAL_ERROR, "Wallet keypool empty");
+ CBlock *pblock = &pblocktemplate->block;
+ {
+ LOCK(cs_main);
+ IncrementExtraNonce(pblock, chainActive.Tip(), nExtraNonce);
+ }
+ while (!CheckProofOfWork(pblock->GetHash(), pblock->nBits, Params().GetConsensus())) {
+ // Yes, there is a chance every nonce could fail to satisfy the -regtest
+ // target -- 1 in 2^(2^32). That ain't gonna happen.
+ ++pblock->nNonce;
+ }
+ CValidationState state;
+ if (!ProcessNewBlock(state, NULL, pblock, true, NULL))
+ throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted");
+ ++nHeight;
+ blockHashes.push_back(pblock->GetHash().GetHex());
+ }
+ return blockHashes;
+}
+
+
+Value setgenerate(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() < 1 || params.size() > 2)
+ throw runtime_error(
+ "setgenerate generate ( genproclimit )\n"
+ "\nSet 'generate' true or false to turn generation on or off.\n"
+ "Generation is limited to 'genproclimit' processors, -1 is unlimited.\n"
+ "See the getgenerate call for the current setting.\n"
+ "\nArguments:\n"
+ "1. generate (boolean, required) Set to true to turn on generation, off to turn off.\n"
+ "2. genproclimit (numeric, optional) Set the processor limit for when generation is on. Can be -1 for unlimited.\n"
+ "\nExamples:\n"
+ "\nSet the generation on with a limit of one processor\n"
+ + HelpExampleCli("setgenerate", "true 1") +
+ "\nCheck the setting\n"
+ + HelpExampleCli("getgenerate", "") +
+ "\nTurn off generation\n"
+ + HelpExampleCli("setgenerate", "false") +
+ "\nUsing json rpc\n"
+ + HelpExampleRpc("setgenerate", "true, 1")
+ );
+
+ if (pwalletMain == NULL)
+ throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)");
+ if (Params().MineBlocksOnDemand())
+ throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Use the generate method instead of setgenerate on this network");
+
+ bool fGenerate = true;
+ if (params.size() > 0)
+ fGenerate = params[0].get_bool();
+
+ int nGenProcLimit = -1;
+ if (params.size() > 1)
+ {
+ nGenProcLimit = params[1].get_int();
+ if (nGenProcLimit == 0)
+ fGenerate = false;
+ }
+
+ mapArgs["-gen"] = (fGenerate ? "1" : "0");
+ mapArgs ["-genproclimit"] = itostr(nGenProcLimit);
+ GenerateBitcoins(fGenerate, pwalletMain, nGenProcLimit);
+
+ return Value::null;
+}
+#endif
+
+
+Value getmininginfo(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() != 0)
+ throw runtime_error(
+ "getmininginfo\n"
+ "\nReturns a json object containing mining-related information."
+ "\nResult:\n"
+ "{\n"
+ " \"blocks\": nnn, (numeric) The current block\n"
+ " \"currentblocksize\": nnn, (numeric) The last block size\n"
+ " \"currentblocktx\": nnn, (numeric) The last block transaction\n"
+ " \"difficulty\": xxx.xxxxx (numeric) The current difficulty\n"
+ " \"errors\": \"...\" (string) Current errors\n"
+ " \"generate\": true|false (boolean) If the generation is on or off (see getgenerate or setgenerate calls)\n"
+ " \"genproclimit\": n (numeric) The processor limit for generation. -1 if no generation. (see getgenerate or setgenerate calls)\n"
+ " \"pooledtx\": n (numeric) The size of the mem pool\n"
+ " \"testnet\": true|false (boolean) If using testnet or not\n"
+ " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n"
+ "}\n"
+ "\nExamples:\n"
+ + HelpExampleCli("getmininginfo", "")
+ + HelpExampleRpc("getmininginfo", "")
+ );
+
+
+ LOCK(cs_main);
+
+ Object obj;
+ obj.push_back(Pair("blocks", (int)chainActive.Height()));
+ 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("genproclimit", (int)GetArg("-genproclimit", -1)));
+ obj.push_back(Pair("networkhashps", getnetworkhashps(params, false)));
+ obj.push_back(Pair("pooledtx", (uint64_t)mempool.size()));
+ obj.push_back(Pair("testnet", Params().TestnetToBeDeprecatedFieldRPC()));
+ obj.push_back(Pair("chain", Params().NetworkIDString()));
+#ifdef ENABLE_WALLET
+ obj.push_back(Pair("generate", getgenerate(params, false)));
+#endif
+ return obj;
+}
+
+
+// NOTE: Unlike wallet RPC (which use BTC values), mining RPCs follow GBT (BIP 22) in using satoshi amounts
+Value prioritisetransaction(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() != 3)
+ throw runtime_error(
+ "prioritisetransaction <txid> <priority delta> <fee delta>\n"
+ "Accepts the transaction into mined blocks at a higher (or lower) priority\n"
+ "\nArguments:\n"
+ "1. \"txid\" (string, required) The transaction id.\n"
+ "2. priority delta (numeric, required) The priority to add or subtract.\n"
+ " The transaction selection algorithm considers the tx as it would have a higher priority.\n"
+ " (priority of a transaction is calculated: coinage * value_in_satoshis / txsize) \n"
+ "3. fee delta (numeric, required) The fee value (in satoshis) to add (or subtract, if negative).\n"
+ " The fee is not actually paid, only the algorithm for selecting transactions into a block\n"
+ " considers the transaction as it would have paid a higher (or lower) fee.\n"
+ "\nResult\n"
+ "true (boolean) Returns true\n"
+ "\nExamples:\n"
+ + HelpExampleCli("prioritisetransaction", "\"txid\" 0.0 10000")
+ + HelpExampleRpc("prioritisetransaction", "\"txid\", 0.0, 10000")
+ );
+
+ LOCK(cs_main);
+
+ uint256 hash = ParseHashStr(params[0].get_str(), "txid");
+ CAmount nAmount = params[2].get_int64();
+
+ mempool.PrioritiseTransaction(hash, params[0].get_str(), params[1].get_real(), nAmount);
+ return true;
+}
+
+
+// NOTE: Assumes a conclusive result; if result is inconclusive, it must be handled by caller
+static Value BIP22ValidationResult(const CValidationState& state)
+{
+ if (state.IsValid())
+ return Value::null;
+
+ std::string strRejectReason = state.GetRejectReason();
+ if (state.IsError())
+ throw JSONRPCError(RPC_VERIFY_ERROR, strRejectReason);
+ if (state.IsInvalid())
+ {
+ if (strRejectReason.empty())
+ return "rejected";
+ return strRejectReason;
+ }
+ // Should be impossible
+ return "valid?";
+}
+
+Value getblocktemplate(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() > 1)
+ throw runtime_error(
+ "getblocktemplate ( \"jsonrequestobject\" )\n"
+ "\nIf the request parameters include a 'mode' key, that is used to explicitly select between the default 'template' request or a 'proposal'.\n"
+ "It returns data needed to construct a block to work on.\n"
+ "See https://en.bitcoin.it/wiki/BIP_0022 for full specification.\n"
+
+ "\nArguments:\n"
+ "1. \"jsonrequestobject\" (string, optional) A json object in the following spec\n"
+ " {\n"
+ " \"mode\":\"template\" (string, optional) This must be set to \"template\" or omitted\n"
+ " \"capabilities\":[ (array, optional) A list of strings\n"
+ " \"support\" (string) client side supported feature, 'longpoll', 'coinbasetxn', 'coinbasevalue', 'proposal', 'serverlist', 'workid'\n"
+ " ,...\n"
+ " ]\n"
+ " }\n"
+ "\n"
+
+ "\nResult:\n"
+ "{\n"
+ " \"version\" : n, (numeric) The block version\n"
+ " \"previousblockhash\" : \"xxxx\", (string) The hash of current highest block\n"
+ " \"transactions\" : [ (array) contents of non-coinbase transactions that should be included in the next block\n"
+ " {\n"
+ " \"data\" : \"xxxx\", (string) transaction data encoded in hexadecimal (byte-for-byte)\n"
+ " \"hash\" : \"xxxx\", (string) hash/id encoded in little-endian hexadecimal\n"
+ " \"depends\" : [ (array) array of numbers \n"
+ " n (numeric) transactions before this one (by 1-based index in 'transactions' list) that must be present in the final block if this one is\n"
+ " ,...\n"
+ " ],\n"
+ " \"fee\": n, (numeric) difference in value between transaction inputs and outputs (in Satoshis); for coinbase transactions, this is a negative Number of the total collected block fees (ie, not including the block subsidy); if key is not present, fee is unknown and clients MUST NOT assume there isn't one\n"
+ " \"sigops\" : n, (numeric) total number of SigOps, as counted for purposes of block limits; if key is not present, sigop count is unknown and clients MUST NOT assume there aren't any\n"
+ " \"required\" : true|false (boolean) if provided and true, this transaction must be in the final block\n"
+ " }\n"
+ " ,...\n"
+ " ],\n"
+ " \"coinbaseaux\" : { (json object) data that should be included in the coinbase's scriptSig content\n"
+ " \"flags\" : \"flags\" (string) \n"
+ " },\n"
+ " \"coinbasevalue\" : n, (numeric) maximum allowable input to coinbase transaction, including the generation award and transaction fees (in Satoshis)\n"
+ " \"coinbasetxn\" : { ... }, (json object) information for coinbase transaction\n"
+ " \"target\" : \"xxxx\", (string) The hash target\n"
+ " \"mintime\" : xxx, (numeric) The minimum timestamp appropriate for next block time in seconds since epoch (Jan 1 1970 GMT)\n"
+ " \"mutable\" : [ (array of string) list of ways the block template may be changed \n"
+ " \"value\" (string) A way the block template may be changed, e.g. 'time', 'transactions', 'prevblock'\n"
+ " ,...\n"
+ " ],\n"
+ " \"noncerange\" : \"00000000ffffffff\", (string) A range of valid nonces\n"
+ " \"sigoplimit\" : n, (numeric) limit of sigops in blocks\n"
+ " \"sizelimit\" : n, (numeric) limit of block size\n"
+ " \"curtime\" : ttt, (numeric) current timestamp in seconds since epoch (Jan 1 1970 GMT)\n"
+ " \"bits\" : \"xxx\", (string) compressed target of next block\n"
+ " \"height\" : n (numeric) The height of the next block\n"
+ "}\n"
+
+ "\nExamples:\n"
+ + HelpExampleCli("getblocktemplate", "")
+ + HelpExampleRpc("getblocktemplate", "")
+ );
+
+ LOCK(cs_main);
+
+ std::string strMode = "template";
+ Value lpval = Value::null;
+ if (params.size() > 0)
+ {
+ const Object& oparam = params[0].get_obj();
+ const Value& modeval = find_value(oparam, "mode");
+ if (modeval.type() == str_type)
+ strMode = modeval.get_str();
+ else if (modeval.type() == null_type)
+ {
+ /* Do nothing */
+ }
+ else
+ throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode");
+ lpval = find_value(oparam, "longpollid");
+
+ if (strMode == "proposal")
+ {
+ const Value& dataval = find_value(oparam, "data");
+ if (dataval.type() != str_type)
+ throw JSONRPCError(RPC_TYPE_ERROR, "Missing data String key for proposal");
+
+ CBlock block;
+ if (!DecodeHexBlk(block, dataval.get_str()))
+ throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed");
+
+ uint256 hash = block.GetHash();
+ BlockMap::iterator mi = mapBlockIndex.find(hash);
+ if (mi != mapBlockIndex.end()) {
+ CBlockIndex *pindex = mi->second;
+ if (pindex->IsValid(BLOCK_VALID_SCRIPTS))
+ return "duplicate";
+ if (pindex->nStatus & BLOCK_FAILED_MASK)
+ return "duplicate-invalid";
+ return "duplicate-inconclusive";
+ }
+
+ CBlockIndex* const pindexPrev = chainActive.Tip();
+ // TestBlockValidity only supports blocks built on the current Tip
+ if (block.hashPrevBlock != pindexPrev->GetBlockHash())
+ return "inconclusive-not-best-prevblk";
+ CValidationState state;
+ TestBlockValidity(state, block, pindexPrev, false, true);
+ return BIP22ValidationResult(state);
+ }
+ }
+
+ if (strMode != "template")
+ throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode");
+
+ if (vNodes.empty())
+ throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Bitcoin is not connected!");
+
+ if (IsInitialBlockDownload())
+ throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Bitcoin is downloading blocks...");
+
+ static unsigned int nTransactionsUpdatedLast;
+
+ if (lpval.type() != null_type)
+ {
+ // Wait to respond until either the best block changes, OR a minute has passed and there are more transactions
+ uint256 hashWatchedChain;
+ boost::system_time checktxtime;
+ unsigned int nTransactionsUpdatedLastLP;
+
+ if (lpval.type() == str_type)
+ {
+ // Format: <hashBestChain><nTransactionsUpdatedLast>
+ std::string lpstr = lpval.get_str();
+
+ hashWatchedChain.SetHex(lpstr.substr(0, 64));
+ nTransactionsUpdatedLastLP = atoi64(lpstr.substr(64));
+ }
+ else
+ {
+ // NOTE: Spec does not specify behaviour for non-string longpollid, but this makes testing easier
+ hashWatchedChain = chainActive.Tip()->GetBlockHash();
+ nTransactionsUpdatedLastLP = nTransactionsUpdatedLast;
+ }
+
+ // Release the wallet and main lock while waiting
+ LEAVE_CRITICAL_SECTION(cs_main);
+ {
+ checktxtime = boost::get_system_time() + boost::posix_time::minutes(1);
+
+ boost::unique_lock<boost::mutex> lock(csBestBlock);
+ while (chainActive.Tip()->GetBlockHash() == hashWatchedChain && IsRPCRunning())
+ {
+ if (!cvBlockChange.timed_wait(lock, checktxtime))
+ {
+ // Timeout: Check transactions for update
+ if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLastLP)
+ break;
+ checktxtime += boost::posix_time::seconds(10);
+ }
+ }
+ }
+ ENTER_CRITICAL_SECTION(cs_main);
+
+ if (!IsRPCRunning())
+ throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Shutting down");
+ // TODO: Maybe recheck connections/IBD and (if something wrong) send an expires-immediately template to stop miners?
+ }
+
+ // Update block
+ static CBlockIndex* pindexPrev;
+ static int64_t nStart;
+ static CBlockTemplate* pblocktemplate;
+ if (pindexPrev != chainActive.Tip() ||
+ (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 5))
+ {
+ // Clear pindexPrev so future calls make a new block, despite any failures from here on
+ pindexPrev = NULL;
+
+ // Store the pindexBest used before CreateNewBlock, to avoid races
+ nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
+ CBlockIndex* pindexPrevNew = chainActive.Tip();
+ nStart = GetTime();
+
+ // Create new block
+ if(pblocktemplate)
+ {
+ delete pblocktemplate;
+ pblocktemplate = NULL;
+ }
+ CScript scriptDummy = CScript() << OP_TRUE;
+ pblocktemplate = CreateNewBlock(scriptDummy);
+ if (!pblocktemplate)
+ throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");
+
+ // Need to update only after we know CreateNewBlock succeeded
+ pindexPrev = pindexPrevNew;
+ }
+ CBlock* pblock = &pblocktemplate->block; // pointer for convenience
+
+ // Update nTime
+ UpdateTime(pblock, Params().GetConsensus(), pindexPrev);
+ pblock->nNonce = 0;
+
+ static const Array aCaps = boost::assign::list_of("proposal");
+
+ Array transactions;
+ map<uint256, int64_t> setTxIndex;
+ int i = 0;
+ BOOST_FOREACH (CTransaction& tx, pblock->vtx)
+ {
+ uint256 txHash = tx.GetHash();
+ setTxIndex[txHash] = i++;
+
+ if (tx.IsCoinBase())
+ continue;
+
+ Object entry;
+
+ entry.push_back(Pair("data", EncodeHexTx(tx)));
+
+ entry.push_back(Pair("hash", txHash.GetHex()));
+
+ Array deps;
+ BOOST_FOREACH (const CTxIn &in, tx.vin)
+ {
+ if (setTxIndex.count(in.prevout.hash))
+ deps.push_back(setTxIndex[in.prevout.hash]);
+ }
+ entry.push_back(Pair("depends", deps));
+
+ int index_in_template = i - 1;
+ entry.push_back(Pair("fee", pblocktemplate->vTxFees[index_in_template]));
+ entry.push_back(Pair("sigops", pblocktemplate->vTxSigOps[index_in_template]));
+
+ transactions.push_back(entry);
+ }
+
+ Object aux;
+ aux.push_back(Pair("flags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end())));
+
+ arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits);
+
+ static Array aMutable;
+ if (aMutable.empty())
+ {
+ aMutable.push_back("time");
+ aMutable.push_back("transactions");
+ aMutable.push_back("prevblock");
+ }
+
+ Object result;
+ result.push_back(Pair("capabilities", aCaps));
+ 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("longpollid", chainActive.Tip()->GetBlockHash().GetHex() + i64tostr(nTransactionsUpdatedLast)));
+ 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", pblock->GetBlockTime()));
+ result.push_back(Pair("bits", strprintf("%08x", pblock->nBits)));
+ result.push_back(Pair("height", (int64_t)(pindexPrev->nHeight+1)));
+
+ return result;
+}
+
+class submitblock_StateCatcher : public CValidationInterface
+{
+public:
+ uint256 hash;
+ bool found;
+ CValidationState state;
+
+ submitblock_StateCatcher(const uint256 &hashIn) : hash(hashIn), found(false), state() {};
+
+protected:
+ virtual void BlockChecked(const CBlock& block, const CValidationState& stateIn) {
+ if (block.GetHash() != hash)
+ return;
+ found = true;
+ state = stateIn;
+ };
+};
+
+Value submitblock(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() < 1 || params.size() > 2)
+ throw runtime_error(
+ "submitblock \"hexdata\" ( \"jsonparametersobject\" )\n"
+ "\nAttempts to submit new block to network.\n"
+ "The 'jsonparametersobject' parameter is currently ignored.\n"
+ "See https://en.bitcoin.it/wiki/BIP_0022 for full specification.\n"
+
+ "\nArguments\n"
+ "1. \"hexdata\" (string, required) the hex-encoded block data to submit\n"
+ "2. \"jsonparametersobject\" (string, optional) object of optional parameters\n"
+ " {\n"
+ " \"workid\" : \"id\" (string, optional) if the server provided a workid, it MUST be included with submissions\n"
+ " }\n"
+ "\nResult:\n"
+ "\nExamples:\n"
+ + HelpExampleCli("submitblock", "\"mydata\"")
+ + HelpExampleRpc("submitblock", "\"mydata\"")
+ );
+
+ CBlock block;
+ if (!DecodeHexBlk(block, params[0].get_str()))
+ throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed");
+
+ uint256 hash = block.GetHash();
+ bool fBlockPresent = false;
+ {
+ LOCK(cs_main);
+ BlockMap::iterator mi = mapBlockIndex.find(hash);
+ if (mi != mapBlockIndex.end()) {
+ CBlockIndex *pindex = mi->second;
+ if (pindex->IsValid(BLOCK_VALID_SCRIPTS))
+ return "duplicate";
+ if (pindex->nStatus & BLOCK_FAILED_MASK)
+ return "duplicate-invalid";
+ // Otherwise, we might only have the header - process the block before returning
+ fBlockPresent = true;
+ }
+ }
+
+ CValidationState state;
+ submitblock_StateCatcher sc(block.GetHash());
+ RegisterValidationInterface(&sc);
+ bool fAccepted = ProcessNewBlock(state, NULL, &block, true, NULL);
+ UnregisterValidationInterface(&sc);
+ if (fBlockPresent)
+ {
+ if (fAccepted && !sc.found)
+ return "duplicate-inconclusive";
+ return "duplicate";
+ }
+ if (fAccepted)
+ {
+ if (!sc.found)
+ return "inconclusive";
+ state = sc.state;
+ }
+ return BIP22ValidationResult(state);
+}
+
+Value estimatefee(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() != 1)
+ throw runtime_error(
+ "estimatefee nblocks\n"
+ "\nEstimates the approximate fee per kilobyte\n"
+ "needed for a transaction to begin confirmation\n"
+ "within nblocks blocks.\n"
+ "\nArguments:\n"
+ "1. nblocks (numeric)\n"
+ "\nResult:\n"
+ "n : (numeric) estimated fee-per-kilobyte\n"
+ "\n"
+ "-1.0 is returned if not enough transactions and\n"
+ "blocks have been observed to make an estimate.\n"
+ "\nExample:\n"
+ + HelpExampleCli("estimatefee", "6")
+ );
+
+ RPCTypeCheck(params, boost::assign::list_of(int_type));
+
+ int nBlocks = params[0].get_int();
+ if (nBlocks < 1)
+ nBlocks = 1;
+
+ CFeeRate feeRate = mempool.estimateFee(nBlocks);
+ if (feeRate == CFeeRate(0))
+ return -1.0;
+
+ return ValueFromAmount(feeRate.GetFeePerK());
+}
+
+Value estimatepriority(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() != 1)
+ throw runtime_error(
+ "estimatepriority nblocks\n"
+ "\nEstimates the approximate priority\n"
+ "a zero-fee transaction needs to begin confirmation\n"
+ "within nblocks blocks.\n"
+ "\nArguments:\n"
+ "1. nblocks (numeric)\n"
+ "\nResult:\n"
+ "n : (numeric) estimated priority\n"
+ "\n"
+ "-1.0 is returned if not enough transactions and\n"
+ "blocks have been observed to make an estimate.\n"
+ "\nExample:\n"
+ + HelpExampleCli("estimatepriority", "6")
+ );
+
+ RPCTypeCheck(params, boost::assign::list_of(int_type));
+
+ int nBlocks = params[0].get_int();
+ if (nBlocks < 1)
+ nBlocks = 1;
+
+ return mempool.estimatePriority(nBlocks);
+}
diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp
new file mode 100644
index 0000000000..f5bef2a077
--- /dev/null
+++ b/src/rpcmisc.cpp
@@ -0,0 +1,397 @@
+// Copyright (c) 2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "base58.h"
+#include "clientversion.h"
+#include "init.h"
+#include "main.h"
+#include "net.h"
+#include "netbase.h"
+#include "rpcserver.h"
+#include "timedata.h"
+#include "util.h"
+#ifdef ENABLE_WALLET
+#include "wallet/wallet.h"
+#include "wallet/walletdb.h"
+#endif
+
+#include <stdint.h>
+
+#include <boost/assign/list_of.hpp>
+#include "json/json_spirit_utils.h"
+#include "json/json_spirit_value.h"
+
+using namespace json_spirit;
+using namespace std;
+
+/**
+ * @note Do not add or change anything in the information returned by this
+ * method. `getinfo` exists for backwards-compatibility only. It combines
+ * information from wildly different sources in the program, which is a mess,
+ * and is thus planned to be deprecated eventually.
+ *
+ * Based on the source of the information, new information should be added to:
+ * - `getblockchaininfo`,
+ * - `getnetworkinfo` or
+ * - `getwalletinfo`
+ *
+ * Or alternatively, create a specific query method for the information.
+ **/
+Value getinfo(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() != 0)
+ throw runtime_error(
+ "getinfo\n"
+ "Returns an object containing various state info.\n"
+ "\nResult:\n"
+ "{\n"
+ " \"version\": xxxxx, (numeric) the server version\n"
+ " \"protocolversion\": xxxxx, (numeric) the protocol version\n"
+ " \"walletversion\": xxxxx, (numeric) the wallet version\n"
+ " \"balance\": xxxxxxx, (numeric) the total bitcoin balance of the wallet\n"
+ " \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n"
+ " \"timeoffset\": xxxxx, (numeric) the time offset\n"
+ " \"connections\": xxxxx, (numeric) the number of connections\n"
+ " \"proxy\": \"host:port\", (string, optional) the proxy used by the server\n"
+ " \"difficulty\": xxxxxx, (numeric) the current difficulty\n"
+ " \"testnet\": true|false, (boolean) if the server is using testnet or not\n"
+ " \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since GMT epoch) of the oldest pre-generated key in the key pool\n"
+ " \"keypoolsize\": xxxx, (numeric) how many new keys are pre-generated\n"
+ " \"unlocked_until\": ttt, (numeric) the timestamp in seconds since epoch (midnight Jan 1 1970 GMT) that the wallet is unlocked for transfers, or 0 if the wallet is locked\n"
+ " \"paytxfee\": x.xxxx, (numeric) the transaction fee set in btc/kb\n"
+ " \"relayfee\": x.xxxx, (numeric) minimum relay fee for non-free transactions in btc/kb\n"
+ " \"errors\": \"...\" (string) any error messages\n"
+ "}\n"
+ "\nExamples:\n"
+ + HelpExampleCli("getinfo", "")
+ + HelpExampleRpc("getinfo", "")
+ );
+
+#ifdef ENABLE_WALLET
+ LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL);
+#else
+ LOCK(cs_main);
+#endif
+
+ proxyType proxy;
+ GetProxy(NET_IPV4, proxy);
+
+ Object obj;
+ obj.push_back(Pair("version", CLIENT_VERSION));
+ obj.push_back(Pair("protocolversion", PROTOCOL_VERSION));
+#ifdef ENABLE_WALLET
+ if (pwalletMain) {
+ obj.push_back(Pair("walletversion", pwalletMain->GetVersion()));
+ obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance())));
+ }
+#endif
+ obj.push_back(Pair("blocks", (int)chainActive.Height()));
+ obj.push_back(Pair("timeoffset", GetTimeOffset()));
+ obj.push_back(Pair("connections", (int)vNodes.size()));
+ obj.push_back(Pair("proxy", (proxy.IsValid() ? proxy.proxy.ToStringIPPort() : string())));
+ obj.push_back(Pair("difficulty", (double)GetDifficulty()));
+ obj.push_back(Pair("testnet", Params().TestnetToBeDeprecatedFieldRPC()));
+#ifdef ENABLE_WALLET
+ if (pwalletMain) {
+ obj.push_back(Pair("keypoololdest", pwalletMain->GetOldestKeyPoolTime()));
+ obj.push_back(Pair("keypoolsize", (int)pwalletMain->GetKeyPoolSize()));
+ }
+ if (pwalletMain && pwalletMain->IsCrypted())
+ obj.push_back(Pair("unlocked_until", nWalletUnlockTime));
+ obj.push_back(Pair("paytxfee", ValueFromAmount(payTxFee.GetFeePerK())));
+#endif
+ obj.push_back(Pair("relayfee", ValueFromAmount(::minRelayTxFee.GetFeePerK())));
+ obj.push_back(Pair("errors", GetWarnings("statusbar")));
+ return obj;
+}
+
+#ifdef ENABLE_WALLET
+class DescribeAddressVisitor : public boost::static_visitor<Object>
+{
+private:
+ isminetype mine;
+
+public:
+ DescribeAddressVisitor(isminetype mineIn) : mine(mineIn) {}
+
+ Object operator()(const CNoDestination &dest) const { return Object(); }
+
+ Object operator()(const CKeyID &keyID) const {
+ Object obj;
+ CPubKey vchPubKey;
+ obj.push_back(Pair("isscript", false));
+ if (mine == ISMINE_SPENDABLE) {
+ pwalletMain->GetPubKey(keyID, vchPubKey);
+ obj.push_back(Pair("pubkey", HexStr(vchPubKey)));
+ obj.push_back(Pair("iscompressed", vchPubKey.IsCompressed()));
+ }
+ return obj;
+ }
+
+ Object operator()(const CScriptID &scriptID) const {
+ Object obj;
+ obj.push_back(Pair("isscript", true));
+ if (mine != ISMINE_NO) {
+ CScript subscript;
+ pwalletMain->GetCScript(scriptID, subscript);
+ std::vector<CTxDestination> addresses;
+ txnouttype whichType;
+ int nRequired;
+ ExtractDestinations(subscript, whichType, addresses, nRequired);
+ obj.push_back(Pair("script", GetTxnOutputType(whichType)));
+ obj.push_back(Pair("hex", HexStr(subscript.begin(), subscript.end())));
+ 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;
+ }
+};
+#endif
+
+Value validateaddress(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() != 1)
+ throw runtime_error(
+ "validateaddress \"bitcoinaddress\"\n"
+ "\nReturn information about the given bitcoin address.\n"
+ "\nArguments:\n"
+ "1. \"bitcoinaddress\" (string, required) The bitcoin address to validate\n"
+ "\nResult:\n"
+ "{\n"
+ " \"isvalid\" : true|false, (boolean) If the address is valid or not. If not, this is the only property returned.\n"
+ " \"address\" : \"bitcoinaddress\", (string) The bitcoin address validated\n"
+ " \"scriptPubKey\" : \"hex\", (string) The hex encoded scriptPubKey generated by the address\n"
+ " \"ismine\" : true|false, (boolean) If the address is yours or not\n"
+ " \"isscript\" : true|false, (boolean) If the key is a script\n"
+ " \"pubkey\" : \"publickeyhex\", (string) The hex value of the raw public key\n"
+ " \"iscompressed\" : true|false, (boolean) If the address is compressed\n"
+ " \"account\" : \"account\" (string) DEPRECATED. The account associated with the address, \"\" is the default account\n"
+ "}\n"
+ "\nExamples:\n"
+ + HelpExampleCli("validateaddress", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"")
+ + HelpExampleRpc("validateaddress", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"")
+ );
+
+#ifdef ENABLE_WALLET
+ LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL);
+#else
+ LOCK(cs_main);
+#endif
+
+ 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));
+
+ CScript scriptPubKey = GetScriptForDestination(dest);
+ ret.push_back(Pair("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
+
+#ifdef ENABLE_WALLET
+ isminetype mine = pwalletMain ? IsMine(*pwalletMain, dest) : ISMINE_NO;
+ ret.push_back(Pair("ismine", (mine & ISMINE_SPENDABLE) ? true : false));
+ if (mine != ISMINE_NO) {
+ ret.push_back(Pair("iswatchonly", (mine & ISMINE_WATCH_ONLY) ? true: false));
+ Object detail = boost::apply_visitor(DescribeAddressVisitor(mine), dest);
+ ret.insert(ret.end(), detail.begin(), detail.end());
+ }
+ if (pwalletMain && pwalletMain->mapAddressBook.count(dest))
+ ret.push_back(Pair("account", pwalletMain->mapAddressBook[dest].name));
+#endif
+ }
+ return ret;
+}
+
+/**
+ * Used by addmultisigaddress / createmultisig:
+ */
+CScript _createmultisig_redeemScript(const Array& params)
+{
+ int nRequired = params[0].get_int();
+ const Array& keys = params[1].get_array();
+
+ // 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 %u keys, but need at least %d to redeem)", keys.size(), nRequired));
+ if (keys.size() > 16)
+ throw runtime_error("Number of addresses involved in the multisignature address creation > 16\nReduce the number");
+ std::vector<CPubKey> pubkeys;
+ pubkeys.resize(keys.size());
+ for (unsigned int i = 0; i < keys.size(); i++)
+ {
+ const std::string& ks = keys[i].get_str();
+#ifdef ENABLE_WALLET
+ // Case 1: Bitcoin address and we have full public key:
+ CBitcoinAddress address(ks);
+ if (pwalletMain && address.IsValid())
+ {
+ CKeyID keyID;
+ if (!address.GetKeyID(keyID))
+ throw runtime_error(
+ strprintf("%s does not refer to a key",ks));
+ CPubKey vchPubKey;
+ if (!pwalletMain->GetPubKey(keyID, vchPubKey))
+ throw runtime_error(
+ strprintf("no full public key for address %s",ks));
+ if (!vchPubKey.IsFullyValid())
+ throw runtime_error(" Invalid public key: "+ks);
+ pubkeys[i] = vchPubKey;
+ }
+
+ // Case 2: hex public key
+ else
+#endif
+ if (IsHex(ks))
+ {
+ CPubKey vchPubKey(ParseHex(ks));
+ if (!vchPubKey.IsFullyValid())
+ throw runtime_error(" Invalid public key: "+ks);
+ pubkeys[i] = vchPubKey;
+ }
+ else
+ {
+ throw runtime_error(" Invalid public key: "+ks);
+ }
+ }
+ CScript result = GetScriptForMultisig(nRequired, pubkeys);
+
+ if (result.size() > MAX_SCRIPT_ELEMENT_SIZE)
+ throw runtime_error(
+ strprintf("redeemScript exceeds size limit: %d > %d", result.size(), MAX_SCRIPT_ELEMENT_SIZE));
+
+ return result;
+}
+
+Value createmultisig(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() < 2 || params.size() > 2)
+ {
+ string msg = "createmultisig nrequired [\"key\",...]\n"
+ "\nCreates a multi-signature address with n signature of m keys required.\n"
+ "It returns a json object with the address and redeemScript.\n"
+
+ "\nArguments:\n"
+ "1. nrequired (numeric, required) The number of required signatures out of the n keys or addresses.\n"
+ "2. \"keys\" (string, required) A json array of keys which are bitcoin addresses or hex-encoded public keys\n"
+ " [\n"
+ " \"key\" (string) bitcoin address or hex-encoded public key\n"
+ " ,...\n"
+ " ]\n"
+
+ "\nResult:\n"
+ "{\n"
+ " \"address\":\"multisigaddress\", (string) The value of the new multisig address.\n"
+ " \"redeemScript\":\"script\" (string) The string value of the hex-encoded redemption script.\n"
+ "}\n"
+
+ "\nExamples:\n"
+ "\nCreate a multisig address from 2 addresses\n"
+ + HelpExampleCli("createmultisig", "2 \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"") +
+ "\nAs a json rpc call\n"
+ + HelpExampleRpc("createmultisig", "2, \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"")
+ ;
+ throw runtime_error(msg);
+ }
+
+ // Construct using pay-to-script-hash:
+ CScript inner = _createmultisig_redeemScript(params);
+ CScriptID innerID(inner);
+ CBitcoinAddress address(innerID);
+
+ Object result;
+ result.push_back(Pair("address", address.ToString()));
+ result.push_back(Pair("redeemScript", HexStr(inner.begin(), inner.end())));
+
+ return result;
+}
+
+Value verifymessage(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() != 3)
+ throw runtime_error(
+ "verifymessage \"bitcoinaddress\" \"signature\" \"message\"\n"
+ "\nVerify a signed message\n"
+ "\nArguments:\n"
+ "1. \"bitcoinaddress\" (string, required) The bitcoin address to use for the signature.\n"
+ "2. \"signature\" (string, required) The signature provided by the signer in base 64 encoding (see signmessage).\n"
+ "3. \"message\" (string, required) The message that was signed.\n"
+ "\nResult:\n"
+ "true|false (boolean) If the signature is verified or not.\n"
+ "\nExamples:\n"
+ "\nUnlock the wallet for 30 seconds\n"
+ + HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") +
+ "\nCreate the signature\n"
+ + HelpExampleCli("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"my message\"") +
+ "\nVerify the signature\n"
+ + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"signature\" \"my message\"") +
+ "\nAs json rpc\n"
+ + HelpExampleRpc("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", \"signature\", \"my message\"")
+ );
+
+ LOCK(cs_main);
+
+ 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(RPC_TYPE_ERROR, "Invalid address");
+
+ CKeyID keyID;
+ if (!addr.GetKeyID(keyID))
+ throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key");
+
+ bool fInvalid = false;
+ vector<unsigned char> vchSig = DecodeBase64(strSign.c_str(), &fInvalid);
+
+ if (fInvalid)
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Malformed base64 encoding");
+
+ CHashWriter ss(SER_GETHASH, 0);
+ ss << strMessageMagic;
+ ss << strMessage;
+
+ CPubKey pubkey;
+ if (!pubkey.RecoverCompact(ss.GetHash(), vchSig))
+ return false;
+
+ return (pubkey.GetID() == keyID);
+}
+
+Value setmocktime(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() != 1)
+ throw runtime_error(
+ "setmocktime timestamp\n"
+ "\nSet the local time to given timestamp (-regtest only)\n"
+ "\nArguments:\n"
+ "1. timestamp (integer, required) Unix seconds-since-epoch timestamp\n"
+ " Pass 0 to go back to using the system time."
+ );
+
+ if (!Params().MineBlocksOnDemand())
+ throw runtime_error("setmocktime for regression testing (-regtest mode) only");
+
+ LOCK(cs_main);
+
+ RPCTypeCheck(params, boost::assign::list_of(int_type));
+ SetMockTime(params[0].get_int64());
+
+ return Value::null;
+}
diff --git a/src/rpcnet.cpp b/src/rpcnet.cpp
new file mode 100644
index 0000000000..bdee5b9f2e
--- /dev/null
+++ b/src/rpcnet.cpp
@@ -0,0 +1,445 @@
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "rpcserver.h"
+
+#include "clientversion.h"
+#include "main.h"
+#include "net.h"
+#include "netbase.h"
+#include "protocol.h"
+#include "sync.h"
+#include "timedata.h"
+#include "util.h"
+#include "version.h"
+
+#include <boost/foreach.hpp>
+
+#include "json/json_spirit_value.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"
+ "\nReturns the number of connections to other nodes.\n"
+ "\nbResult:\n"
+ "n (numeric) The connection count\n"
+ "\nExamples:\n"
+ + HelpExampleCli("getconnectioncount", "")
+ + HelpExampleRpc("getconnectioncount", "")
+ );
+
+ LOCK2(cs_main, cs_vNodes);
+
+ return (int)vNodes.size();
+}
+
+Value ping(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() != 0)
+ throw runtime_error(
+ "ping\n"
+ "\nRequests that a ping be sent to all other nodes, to measure ping time.\n"
+ "Results provided in getpeerinfo, pingtime and pingwait fields are decimal seconds.\n"
+ "Ping command is handled in queue with all other commands, so it measures processing backlog, not just network ping.\n"
+ "\nExamples:\n"
+ + HelpExampleCli("ping", "")
+ + HelpExampleRpc("ping", "")
+ );
+
+ // Request that each node send a ping during next message processing pass
+ LOCK2(cs_main, cs_vNodes);
+
+ BOOST_FOREACH(CNode* pNode, vNodes) {
+ pNode->fPingQueued = true;
+ }
+
+ return Value::null;
+}
+
+static void CopyNodeStats(std::vector<CNodeStats>& 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"
+ "\nReturns data about each connected network node as a json array of objects.\n"
+ "\nbResult:\n"
+ "[\n"
+ " {\n"
+ " \"id\": n, (numeric) Peer index\n"
+ " \"addr\":\"host:port\", (string) The ip address and port of the peer\n"
+ " \"addrlocal\":\"ip:port\", (string) local address\n"
+ " \"services\":\"xxxxxxxxxxxxxxxx\", (string) The services offered\n"
+ " \"lastsend\": ttt, (numeric) The time in seconds since epoch (Jan 1 1970 GMT) of the last send\n"
+ " \"lastrecv\": ttt, (numeric) The time in seconds since epoch (Jan 1 1970 GMT) of the last receive\n"
+ " \"bytessent\": n, (numeric) The total bytes sent\n"
+ " \"bytesrecv\": n, (numeric) The total bytes received\n"
+ " \"conntime\": ttt, (numeric) The connection time in seconds since epoch (Jan 1 1970 GMT)\n"
+ " \"timeoffset\": ttt, (numeric) The time offset in seconds\n"
+ " \"pingtime\": n, (numeric) ping time\n"
+ " \"pingwait\": n, (numeric) ping wait\n"
+ " \"version\": v, (numeric) The peer version, such as 7001\n"
+ " \"subver\": \"/Satoshi:0.8.5/\", (string) The string version\n"
+ " \"inbound\": true|false, (boolean) Inbound (true) or Outbound (false)\n"
+ " \"startingheight\": n, (numeric) The starting height (block) of the peer\n"
+ " \"banscore\": n, (numeric) The ban score\n"
+ " \"synced_headers\": n, (numeric) The last header we have in common with this peer\n"
+ " \"synced_blocks\": n, (numeric) The last block we have in common with this peer\n"
+ " \"inflight\": [\n"
+ " n, (numeric) The heights of blocks we're currently asking from this peer\n"
+ " ...\n"
+ " ]\n"
+ " }\n"
+ " ,...\n"
+ "]\n"
+ "\nExamples:\n"
+ + HelpExampleCli("getpeerinfo", "")
+ + HelpExampleRpc("getpeerinfo", "")
+ );
+
+ LOCK(cs_main);
+
+ vector<CNodeStats> vstats;
+ CopyNodeStats(vstats);
+
+ Array ret;
+
+ BOOST_FOREACH(const CNodeStats& stats, vstats) {
+ Object obj;
+ CNodeStateStats statestats;
+ bool fStateStats = GetNodeStateStats(stats.nodeid, statestats);
+ obj.push_back(Pair("id", stats.nodeid));
+ obj.push_back(Pair("addr", stats.addrName));
+ if (!(stats.addrLocal.empty()))
+ obj.push_back(Pair("addrlocal", stats.addrLocal));
+ obj.push_back(Pair("services", strprintf("%016x", stats.nServices)));
+ obj.push_back(Pair("lastsend", stats.nLastSend));
+ obj.push_back(Pair("lastrecv", stats.nLastRecv));
+ obj.push_back(Pair("bytessent", stats.nSendBytes));
+ obj.push_back(Pair("bytesrecv", stats.nRecvBytes));
+ obj.push_back(Pair("conntime", stats.nTimeConnected));
+ obj.push_back(Pair("timeoffset", stats.nTimeOffset));
+ obj.push_back(Pair("pingtime", stats.dPingTime));
+ if (stats.dPingWait > 0.0)
+ obj.push_back(Pair("pingwait", stats.dPingWait));
+ obj.push_back(Pair("version", stats.nVersion));
+ // Use the sanitized form of subver here, to avoid tricksy remote peers from
+ // corrupting or modifiying the JSON output by putting special characters in
+ // their ver message.
+ obj.push_back(Pair("subver", stats.cleanSubVer));
+ obj.push_back(Pair("inbound", stats.fInbound));
+ obj.push_back(Pair("startingheight", stats.nStartingHeight));
+ if (fStateStats) {
+ obj.push_back(Pair("banscore", statestats.nMisbehavior));
+ obj.push_back(Pair("synced_headers", statestats.nSyncHeight));
+ obj.push_back(Pair("synced_blocks", statestats.nCommonHeight));
+ Array heights;
+ BOOST_FOREACH(int height, statestats.vHeightInFlight) {
+ heights.push_back(height);
+ }
+ obj.push_back(Pair("inflight", heights));
+ }
+ obj.push_back(Pair("whitelisted", stats.fWhitelisted));
+
+ ret.push_back(obj);
+ }
+
+ return ret;
+}
+
+Value addnode(const Array& params, bool fHelp)
+{
+ string strCommand;
+ if (params.size() == 2)
+ strCommand = params[1].get_str();
+ if (fHelp || params.size() != 2 ||
+ (strCommand != "onetry" && strCommand != "add" && strCommand != "remove"))
+ throw runtime_error(
+ "addnode \"node\" \"add|remove|onetry\"\n"
+ "\nAttempts add or remove a node from the addnode list.\n"
+ "Or try a connection to a node once.\n"
+ "\nArguments:\n"
+ "1. \"node\" (string, required) The node (see getpeerinfo for nodes)\n"
+ "2. \"command\" (string, required) 'add' to add a node to the list, 'remove' to remove a node from the list, 'onetry' to try a connection to the node once\n"
+ "\nExamples:\n"
+ + HelpExampleCli("addnode", "\"192.168.0.6:8333\" \"onetry\"")
+ + HelpExampleRpc("addnode", "\"192.168.0.6:8333\", \"onetry\"")
+ );
+
+ string strNode = params[0].get_str();
+
+ if (strCommand == "onetry")
+ {
+ CAddress addr;
+ OpenNetworkConnection(addr, NULL, strNode.c_str());
+ return Value::null;
+ }
+
+ LOCK(cs_vAddedNodes);
+ vector<string>::iterator it = vAddedNodes.begin();
+ for(; it != vAddedNodes.end(); it++)
+ if (strNode == *it)
+ break;
+
+ if (strCommand == "add")
+ {
+ if (it != vAddedNodes.end())
+ throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: Node already added");
+ vAddedNodes.push_back(strNode);
+ }
+ else if(strCommand == "remove")
+ {
+ if (it == vAddedNodes.end())
+ throw JSONRPCError(RPC_CLIENT_NODE_NOT_ADDED, "Error: Node has not been added.");
+ vAddedNodes.erase(it);
+ }
+
+ return Value::null;
+}
+
+Value getaddednodeinfo(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() < 1 || params.size() > 2)
+ throw runtime_error(
+ "getaddednodeinfo dns ( \"node\" )\n"
+ "\nReturns information about the given added node, or all added nodes\n"
+ "(note that onetry addnodes are not listed here)\n"
+ "If dns is false, only a list of added nodes will be provided,\n"
+ "otherwise connected information will also be available.\n"
+ "\nArguments:\n"
+ "1. dns (boolean, required) If false, only a list of added nodes will be provided, otherwise connected information will also be available.\n"
+ "2. \"node\" (string, optional) If provided, return information about this specific node, otherwise all nodes are returned.\n"
+ "\nResult:\n"
+ "[\n"
+ " {\n"
+ " \"addednode\" : \"192.168.0.201\", (string) The node ip address\n"
+ " \"connected\" : true|false, (boolean) If connected\n"
+ " \"addresses\" : [\n"
+ " {\n"
+ " \"address\" : \"192.168.0.201:8333\", (string) The bitcoin server host and port\n"
+ " \"connected\" : \"outbound\" (string) connection, inbound or outbound\n"
+ " }\n"
+ " ,...\n"
+ " ]\n"
+ " }\n"
+ " ,...\n"
+ "]\n"
+ "\nExamples:\n"
+ + HelpExampleCli("getaddednodeinfo", "true")
+ + HelpExampleCli("getaddednodeinfo", "true \"192.168.0.201\"")
+ + HelpExampleRpc("getaddednodeinfo", "true, \"192.168.0.201\"")
+ );
+
+ bool fDns = params[0].get_bool();
+
+ list<string> laddedNodes(0);
+ if (params.size() == 1)
+ {
+ LOCK(cs_vAddedNodes);
+ BOOST_FOREACH(string& strAddNode, vAddedNodes)
+ laddedNodes.push_back(strAddNode);
+ }
+ else
+ {
+ string strNode = params[1].get_str();
+ LOCK(cs_vAddedNodes);
+ BOOST_FOREACH(string& strAddNode, vAddedNodes)
+ if (strAddNode == strNode)
+ {
+ laddedNodes.push_back(strAddNode);
+ break;
+ }
+ if (laddedNodes.size() == 0)
+ throw JSONRPCError(RPC_CLIENT_NODE_NOT_ADDED, "Error: Node has not been added.");
+ }
+
+ Array ret;
+ if (!fDns)
+ {
+ BOOST_FOREACH(string& strAddNode, laddedNodes)
+ {
+ Object obj;
+ obj.push_back(Pair("addednode", strAddNode));
+ ret.push_back(obj);
+ }
+ return ret;
+ }
+
+ list<pair<string, vector<CService> > > laddedAddreses(0);
+ BOOST_FOREACH(string& strAddNode, laddedNodes)
+ {
+ vector<CService> vservNode(0);
+ if(Lookup(strAddNode.c_str(), vservNode, Params().GetDefaultPort(), fNameLookup, 0))
+ laddedAddreses.push_back(make_pair(strAddNode, vservNode));
+ else
+ {
+ Object obj;
+ obj.push_back(Pair("addednode", strAddNode));
+ obj.push_back(Pair("connected", false));
+ Array addresses;
+ obj.push_back(Pair("addresses", addresses));
+ }
+ }
+
+ LOCK(cs_vNodes);
+ for (list<pair<string, vector<CService> > >::iterator it = laddedAddreses.begin(); it != laddedAddreses.end(); it++)
+ {
+ Object obj;
+ obj.push_back(Pair("addednode", it->first));
+
+ Array addresses;
+ bool fConnected = false;
+ BOOST_FOREACH(CService& addrNode, it->second)
+ {
+ bool fFound = false;
+ Object node;
+ node.push_back(Pair("address", addrNode.ToString()));
+ BOOST_FOREACH(CNode* pnode, vNodes)
+ if (pnode->addr == addrNode)
+ {
+ fFound = true;
+ fConnected = true;
+ node.push_back(Pair("connected", pnode->fInbound ? "inbound" : "outbound"));
+ break;
+ }
+ if (!fFound)
+ node.push_back(Pair("connected", "false"));
+ addresses.push_back(node);
+ }
+ obj.push_back(Pair("connected", fConnected));
+ obj.push_back(Pair("addresses", addresses));
+ ret.push_back(obj);
+ }
+
+ return ret;
+}
+
+Value getnettotals(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() > 0)
+ throw runtime_error(
+ "getnettotals\n"
+ "\nReturns information about network traffic, including bytes in, bytes out,\n"
+ "and current time.\n"
+ "\nResult:\n"
+ "{\n"
+ " \"totalbytesrecv\": n, (numeric) Total bytes received\n"
+ " \"totalbytessent\": n, (numeric) Total bytes sent\n"
+ " \"timemillis\": t (numeric) Total cpu time\n"
+ "}\n"
+ "\nExamples:\n"
+ + HelpExampleCli("getnettotals", "")
+ + HelpExampleRpc("getnettotals", "")
+ );
+
+ Object obj;
+ obj.push_back(Pair("totalbytesrecv", CNode::GetTotalBytesRecv()));
+ obj.push_back(Pair("totalbytessent", CNode::GetTotalBytesSent()));
+ obj.push_back(Pair("timemillis", GetTimeMillis()));
+ return obj;
+}
+
+static Array GetNetworksInfo()
+{
+ Array networks;
+ for(int n=0; n<NET_MAX; ++n)
+ {
+ enum Network network = static_cast<enum Network>(n);
+ if(network == NET_UNROUTABLE)
+ continue;
+ proxyType proxy;
+ Object obj;
+ GetProxy(network, proxy);
+ obj.push_back(Pair("name", GetNetworkName(network)));
+ obj.push_back(Pair("limited", IsLimited(network)));
+ obj.push_back(Pair("reachable", IsReachable(network)));
+ obj.push_back(Pair("proxy", proxy.IsValid() ? proxy.proxy.ToStringIPPort() : string()));
+ obj.push_back(Pair("proxy_randomize_credentials", proxy.randomize_credentials));
+ networks.push_back(obj);
+ }
+ return networks;
+}
+
+Value getnetworkinfo(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() != 0)
+ throw runtime_error(
+ "getnetworkinfo\n"
+ "Returns an object containing various state info regarding P2P networking.\n"
+ "\nResult:\n"
+ "{\n"
+ " \"version\": xxxxx, (numeric) the server version\n"
+ " \"subversion\": \"/Satoshi:x.x.x/\", (string) the server subversion string\n"
+ " \"protocolversion\": xxxxx, (numeric) the protocol version\n"
+ " \"localservices\": \"xxxxxxxxxxxxxxxx\", (string) the services we offer to the network\n"
+ " \"timeoffset\": xxxxx, (numeric) the time offset\n"
+ " \"connections\": xxxxx, (numeric) the number of connections\n"
+ " \"networks\": [ (array) information per network\n"
+ " {\n"
+ " \"name\": \"xxx\", (string) network (ipv4, ipv6 or onion)\n"
+ " \"limited\": true|false, (boolean) is the network limited using -onlynet?\n"
+ " \"reachable\": true|false, (boolean) is the network reachable?\n"
+ " \"proxy\": \"host:port\" (string) the proxy that is used for this network, or empty if none\n"
+ " }\n"
+ " ,...\n"
+ " ],\n"
+ " \"relayfee\": x.xxxxxxxx, (numeric) minimum relay fee for non-free transactions in btc/kb\n"
+ " \"localaddresses\": [ (array) list of local addresses\n"
+ " {\n"
+ " \"address\": \"xxxx\", (string) network address\n"
+ " \"port\": xxx, (numeric) network port\n"
+ " \"score\": xxx (numeric) relative score\n"
+ " }\n"
+ " ,...\n"
+ " ]\n"
+ "}\n"
+ "\nExamples:\n"
+ + HelpExampleCli("getnetworkinfo", "")
+ + HelpExampleRpc("getnetworkinfo", "")
+ );
+
+ LOCK(cs_main);
+
+ Object obj;
+ obj.push_back(Pair("version", CLIENT_VERSION));
+ obj.push_back(Pair("subversion",
+ FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>())));
+ obj.push_back(Pair("protocolversion",PROTOCOL_VERSION));
+ obj.push_back(Pair("localservices", strprintf("%016x", nLocalServices)));
+ obj.push_back(Pair("timeoffset", GetTimeOffset()));
+ obj.push_back(Pair("connections", (int)vNodes.size()));
+ obj.push_back(Pair("networks", GetNetworksInfo()));
+ obj.push_back(Pair("relayfee", ValueFromAmount(::minRelayTxFee.GetFeePerK())));
+ Array localAddresses;
+ {
+ LOCK(cs_mapLocalHost);
+ BOOST_FOREACH(const PAIRTYPE(CNetAddr, LocalServiceInfo) &item, mapLocalHost)
+ {
+ Object rec;
+ rec.push_back(Pair("address", item.first.ToString()));
+ rec.push_back(Pair("port", item.second.nPort));
+ rec.push_back(Pair("score", item.second.nScore));
+ localAddresses.push_back(rec);
+ }
+ }
+ obj.push_back(Pair("localaddresses", localAddresses));
+ return obj;
+}
diff --git a/src/rpcprotocol.cpp b/src/rpcprotocol.cpp
new file mode 100644
index 0000000000..95d6b9e531
--- /dev/null
+++ b/src/rpcprotocol.cpp
@@ -0,0 +1,290 @@
+// Copyright (c) 2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "rpcprotocol.h"
+
+#include "clientversion.h"
+#include "tinyformat.h"
+#include "util.h"
+#include "utilstrencodings.h"
+#include "utiltime.h"
+#include "version.h"
+
+#include <stdint.h>
+
+#include <boost/algorithm/string.hpp>
+#include <boost/asio.hpp>
+#include <boost/asio/ssl.hpp>
+#include <boost/bind.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/foreach.hpp>
+#include <boost/iostreams/concepts.hpp>
+#include <boost/iostreams/stream.hpp>
+#include <boost/shared_ptr.hpp>
+#include "json/json_spirit_writer_template.h"
+
+using namespace std;
+using namespace json_spirit;
+
+//! Number of bytes to allocate and read at most at once in post data
+const size_t POST_READ_SIZE = 256 * 1024;
+
+/**
+ * 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<string,string>& mapRequestHeaders)
+{
+ ostringstream s;
+ s << "POST / HTTP/1.1\r\n"
+ << "User-Agent: bitcoin-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();
+}
+
+static string rfc1123Time()
+{
+ return DateTimeStrFormat("%a, %d %b %Y %H:%M:%S +0000", GetTime());
+}
+
+static const char *httpStatusDescription(int nStatus)
+{
+ switch (nStatus) {
+ case HTTP_OK: return "OK";
+ case HTTP_BAD_REQUEST: return "Bad Request";
+ case HTTP_FORBIDDEN: return "Forbidden";
+ case HTTP_NOT_FOUND: return "Not Found";
+ case HTTP_INTERNAL_SERVER_ERROR: return "Internal Server Error";
+ default: return "";
+ }
+}
+
+string HTTPError(int nStatus, bool keepalive, bool headersOnly)
+{
+ if (nStatus == HTTP_UNAUTHORIZED)
+ return strprintf("HTTP/1.0 401 Authorization Required\r\n"
+ "Date: %s\r\n"
+ "Server: bitcoin-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"
+ "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\r\n"
+ "\"http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd\">\r\n"
+ "<HTML>\r\n"
+ "<HEAD>\r\n"
+ "<TITLE>Error</TITLE>\r\n"
+ "<META HTTP-EQUIV='Content-Type' CONTENT='text/html; charset=ISO-8859-1'>\r\n"
+ "</HEAD>\r\n"
+ "<BODY><H1>401 Unauthorized.</H1></BODY>\r\n"
+ "</HTML>\r\n", rfc1123Time(), FormatFullVersion());
+
+ return HTTPReply(nStatus, httpStatusDescription(nStatus), keepalive,
+ headersOnly, "text/plain");
+}
+
+string HTTPReplyHeader(int nStatus, bool keepalive, size_t contentLength, const char *contentType)
+{
+ return strprintf(
+ "HTTP/1.1 %d %s\r\n"
+ "Date: %s\r\n"
+ "Connection: %s\r\n"
+ "Content-Length: %u\r\n"
+ "Content-Type: %s\r\n"
+ "Server: bitcoin-json-rpc/%s\r\n"
+ "\r\n",
+ nStatus,
+ httpStatusDescription(nStatus),
+ rfc1123Time(),
+ keepalive ? "keep-alive" : "close",
+ contentLength,
+ contentType,
+ FormatFullVersion());
+}
+
+string HTTPReply(int nStatus, const string& strMsg, bool keepalive,
+ bool headersOnly, const char *contentType)
+{
+ if (headersOnly)
+ {
+ return HTTPReplyHeader(nStatus, keepalive, 0, contentType);
+ } else {
+ return HTTPReplyHeader(nStatus, keepalive, strMsg.size(), contentType) + strMsg;
+ }
+}
+
+bool ReadHTTPRequestLine(std::basic_istream<char>& stream, int &proto,
+ string& http_method, string& http_uri)
+{
+ string str;
+ getline(stream, str);
+
+ // HTTP request line is space-delimited
+ vector<string> vWords;
+ boost::split(vWords, str, boost::is_any_of(" "));
+ if (vWords.size() < 2)
+ return false;
+
+ // HTTP methods permitted: GET, POST
+ http_method = vWords[0];
+ if (http_method != "GET" && http_method != "POST")
+ return false;
+
+ // HTTP URI must be an absolute path, relative to current host
+ http_uri = vWords[1];
+ if (http_uri.size() == 0 || http_uri[0] != '/')
+ return false;
+
+ // parse proto, if present
+ string strProto = "";
+ if (vWords.size() > 2)
+ strProto = vWords[2];
+
+ proto = 0;
+ const char *ver = strstr(strProto.c_str(), "HTTP/1.");
+ if (ver != NULL)
+ proto = atoi(ver+7);
+
+ return true;
+}
+
+int ReadHTTPStatus(std::basic_istream<char>& stream, int &proto)
+{
+ string str;
+ getline(stream, str);
+ vector<string> vWords;
+ boost::split(vWords, str, boost::is_any_of(" "));
+ if (vWords.size() < 2)
+ return HTTP_INTERNAL_SERVER_ERROR;
+ 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 ReadHTTPHeaders(std::basic_istream<char>& stream, map<string, string>& mapHeadersRet)
+{
+ int nLen = 0;
+ while (true)
+ {
+ 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 ReadHTTPMessage(std::basic_istream<char>& stream, map<string,
+ string>& mapHeadersRet, string& strMessageRet,
+ int nProto, size_t max_size)
+{
+ mapHeadersRet.clear();
+ strMessageRet = "";
+
+ // Read header
+ int nLen = ReadHTTPHeaders(stream, mapHeadersRet);
+ if (nLen < 0 || (size_t)nLen > max_size)
+ return HTTP_INTERNAL_SERVER_ERROR;
+
+ // Read message
+ if (nLen > 0)
+ {
+ vector<char> vch;
+ size_t ptr = 0;
+ while (ptr < (size_t)nLen)
+ {
+ size_t bytes_to_read = std::min((size_t)nLen - ptr, POST_READ_SIZE);
+ vch.resize(ptr + bytes_to_read);
+ stream.read(&vch[ptr], bytes_to_read);
+ if (!stream) // Connection lost while reading
+ return HTTP_INTERNAL_SERVER_ERROR;
+ ptr += bytes_to_read;
+ }
+ 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 HTTP_OK;
+}
+
+/**
+ * JSON-RPC protocol. Bitcoin 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://jsonrpc.org/historical/json-rpc-over-http.html
+ * 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";
+}
+
+Object JSONRPCError(int code, const string& message)
+{
+ Object error;
+ error.push_back(Pair("code", code));
+ error.push_back(Pair("message", message));
+ return error;
+}
diff --git a/src/rpcprotocol.h b/src/rpcprotocol.h
new file mode 100644
index 0000000000..4f3f70fb37
--- /dev/null
+++ b/src/rpcprotocol.h
@@ -0,0 +1,168 @@
+// Copyright (c) 2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_RPCPROTOCOL_H
+#define BITCOIN_RPCPROTOCOL_H
+
+#include <list>
+#include <map>
+#include <stdint.h>
+#include <string>
+#include <boost/iostreams/concepts.hpp>
+#include <boost/iostreams/stream.hpp>
+#include <boost/asio.hpp>
+#include <boost/asio/ssl.hpp>
+
+#include "json/json_spirit_reader_template.h"
+#include "json/json_spirit_utils.h"
+#include "json/json_spirit_writer_template.h"
+
+//! HTTP status codes
+enum HTTPStatusCode
+{
+ HTTP_OK = 200,
+ HTTP_BAD_REQUEST = 400,
+ HTTP_UNAUTHORIZED = 401,
+ HTTP_FORBIDDEN = 403,
+ HTTP_NOT_FOUND = 404,
+ HTTP_INTERNAL_SERVER_ERROR = 500,
+ HTTP_SERVICE_UNAVAILABLE = 503,
+};
+
+//! Bitcoin RPC error codes
+enum RPCErrorCode
+{
+ //! Standard JSON-RPC 2.0 errors
+ RPC_INVALID_REQUEST = -32600,
+ RPC_METHOD_NOT_FOUND = -32601,
+ RPC_INVALID_PARAMS = -32602,
+ RPC_INTERNAL_ERROR = -32603,
+ RPC_PARSE_ERROR = -32700,
+
+ //! General application defined errors
+ RPC_MISC_ERROR = -1, //! std::exception thrown in command handling
+ RPC_FORBIDDEN_BY_SAFE_MODE = -2, //! Server is in safe mode, and command is not allowed in safe mode
+ RPC_TYPE_ERROR = -3, //! Unexpected type was passed as parameter
+ RPC_INVALID_ADDRESS_OR_KEY = -5, //! Invalid address or key
+ RPC_OUT_OF_MEMORY = -7, //! Ran out of memory during operation
+ RPC_INVALID_PARAMETER = -8, //! Invalid, missing or duplicate parameter
+ RPC_DATABASE_ERROR = -20, //! Database error
+ RPC_DESERIALIZATION_ERROR = -22, //! Error parsing or validating structure in raw format
+ RPC_VERIFY_ERROR = -25, //! General error during transaction or block submission
+ RPC_VERIFY_REJECTED = -26, //! Transaction or block was rejected by network rules
+ RPC_VERIFY_ALREADY_IN_CHAIN = -27, //! Transaction already in chain
+ RPC_IN_WARMUP = -28, //! Client still warming up
+
+ //! Aliases for backward compatibility
+ RPC_TRANSACTION_ERROR = RPC_VERIFY_ERROR,
+ RPC_TRANSACTION_REJECTED = RPC_VERIFY_REJECTED,
+ RPC_TRANSACTION_ALREADY_IN_CHAIN= RPC_VERIFY_ALREADY_IN_CHAIN,
+
+ //! P2P client errors
+ RPC_CLIENT_NOT_CONNECTED = -9, //! Bitcoin is not connected
+ RPC_CLIENT_IN_INITIAL_DOWNLOAD = -10, //! Still downloading initial blocks
+ RPC_CLIENT_NODE_ALREADY_ADDED = -23, //! Node is already added
+ RPC_CLIENT_NODE_NOT_ADDED = -24, //! Node has not been added before
+
+ //! Wallet errors
+ RPC_WALLET_ERROR = -4, //! Unspecified problem with wallet (key not found etc.)
+ RPC_WALLET_INSUFFICIENT_FUNDS = -6, //! Not enough funds in wallet or account
+ RPC_WALLET_INVALID_ACCOUNT_NAME = -11, //! Invalid account name
+ RPC_WALLET_KEYPOOL_RAN_OUT = -12, //! Keypool ran out, call keypoolrefill first
+ RPC_WALLET_UNLOCK_NEEDED = -13, //! Enter the wallet passphrase with walletpassphrase first
+ RPC_WALLET_PASSPHRASE_INCORRECT = -14, //! The wallet passphrase entered was incorrect
+ RPC_WALLET_WRONG_ENC_STATE = -15, //! Command given in wrong wallet encryption state (encrypting an encrypted wallet etc.)
+ RPC_WALLET_ENCRYPTION_FAILED = -16, //! Failed to encrypt the wallet
+ RPC_WALLET_ALREADY_UNLOCKED = -17, //! Wallet is already unlocked
+};
+
+/**
+ * IOStream device that speaks SSL but can also speak non-SSL
+ */
+template <typename Protocol>
+class SSLIOStreamDevice : public boost::iostreams::device<boost::iostreams::bidirectional> {
+public:
+ SSLIOStreamDevice(boost::asio::ssl::stream<typename Protocol::socket> &streamIn, bool fUseSSLIn) : stream(streamIn)
+ {
+ fUseSSL = fUseSSLIn;
+ fNeedHandshake = fUseSSLIn;
+ }
+
+ void handshake(boost::asio::ssl::stream_base::handshake_type role)
+ {
+ if (!fNeedHandshake) return;
+ fNeedHandshake = false;
+ stream.handshake(role);
+ }
+ std::streamsize read(char* s, std::streamsize n)
+ {
+ handshake(boost::asio::ssl::stream_base::server); // HTTPS servers read first
+ if (fUseSSL) return stream.read_some(boost::asio::buffer(s, n));
+ return stream.next_layer().read_some(boost::asio::buffer(s, n));
+ }
+ std::streamsize write(const char* s, std::streamsize n)
+ {
+ handshake(boost::asio::ssl::stream_base::client); // HTTPS clients write first
+ if (fUseSSL) return boost::asio::write(stream, boost::asio::buffer(s, n));
+ return boost::asio::write(stream.next_layer(), boost::asio::buffer(s, n));
+ }
+ bool connect(const std::string& server, const std::string& port)
+ {
+ using namespace boost::asio::ip;
+ tcp::resolver resolver(stream.get_io_service());
+ tcp::resolver::iterator endpoint_iterator;
+#if BOOST_VERSION >= 104300
+ try {
+#endif
+ // The default query (flags address_configured) tries IPv6 if
+ // non-localhost IPv6 configured, and IPv4 if non-localhost IPv4
+ // configured.
+ tcp::resolver::query query(server.c_str(), port.c_str());
+ endpoint_iterator = resolver.resolve(query);
+#if BOOST_VERSION >= 104300
+ } catch (const boost::system::system_error&) {
+ // If we at first don't succeed, try blanket lookup (IPv4+IPv6 independent of configured interfaces)
+ tcp::resolver::query query(server.c_str(), port.c_str(), resolver_query_base::flags());
+ endpoint_iterator = resolver.resolve(query);
+ }
+#endif
+ boost::system::error_code error = boost::asio::error::host_not_found;
+ tcp::resolver::iterator end;
+ 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;
+ boost::asio::ssl::stream<typename Protocol::socket>& stream;
+};
+
+std::string HTTPPost(const std::string& strMsg, const std::map<std::string,std::string>& mapRequestHeaders);
+std::string HTTPError(int nStatus, bool keepalive,
+ bool headerOnly = false);
+std::string HTTPReplyHeader(int nStatus, bool keepalive, size_t contentLength,
+ const char *contentType = "application/json");
+std::string HTTPReply(int nStatus, const std::string& strMsg, bool keepalive,
+ bool headerOnly = false,
+ const char *contentType = "application/json");
+bool ReadHTTPRequestLine(std::basic_istream<char>& stream, int &proto,
+ std::string& http_method, std::string& http_uri);
+int ReadHTTPStatus(std::basic_istream<char>& stream, int &proto);
+int ReadHTTPHeaders(std::basic_istream<char>& stream, std::map<std::string, std::string>& mapHeadersRet);
+int ReadHTTPMessage(std::basic_istream<char>& stream, std::map<std::string, std::string>& mapHeadersRet,
+ std::string& strMessageRet, int nProto, size_t max_size);
+std::string JSONRPCRequest(const std::string& strMethod, const json_spirit::Array& params, const json_spirit::Value& id);
+json_spirit::Object JSONRPCReplyObj(const json_spirit::Value& result, const json_spirit::Value& error, const json_spirit::Value& id);
+std::string JSONRPCReply(const json_spirit::Value& result, const json_spirit::Value& error, const json_spirit::Value& id);
+json_spirit::Object JSONRPCError(int code, const std::string& message);
+
+#endif // BITCOIN_RPCPROTOCOL_H
diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp
new file mode 100644
index 0000000000..3e37b797e8
--- /dev/null
+++ b/src/rpcrawtransaction.cpp
@@ -0,0 +1,808 @@
+// Copyright (c) 2010 Satoshi Nakamoto
+// Copyright (c) 2009-2015 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "base58.h"
+#include "consensus/validation.h"
+#include "core_io.h"
+#include "init.h"
+#include "keystore.h"
+#include "main.h"
+#include "merkleblock.h"
+#include "net.h"
+#include "primitives/transaction.h"
+#include "rpcserver.h"
+#include "script/script.h"
+#include "script/script_error.h"
+#include "script/sign.h"
+#include "script/standard.h"
+#include "uint256.h"
+#ifdef ENABLE_WALLET
+#include "wallet/wallet.h"
+#endif
+
+#include <stdint.h>
+
+#include <boost/assign/list_of.hpp>
+#include "json/json_spirit_utils.h"
+#include "json/json_spirit_value.h"
+
+using namespace json_spirit;
+using namespace std;
+
+void ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out, bool fIncludeHex)
+{
+ txnouttype type;
+ vector<CTxDestination> addresses;
+ int nRequired;
+
+ out.push_back(Pair("asm", scriptPubKey.ToString()));
+ if (fIncludeHex)
+ out.push_back(Pair("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
+
+ if (!ExtractDestinations(scriptPubKey, type, addresses, nRequired)) {
+ out.push_back(Pair("type", GetTxnOutputType(type)));
+ 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", (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", (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", (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", (int64_t)i));
+ Object o;
+ ScriptPubKeyToJSON(txout.scriptPubKey, o, true);
+ out.push_back(Pair("scriptPubKey", o));
+ vout.push_back(out);
+ }
+ entry.push_back(Pair("vout", vout));
+
+ if (!hashBlock.IsNull()) {
+ entry.push_back(Pair("blockhash", hashBlock.GetHex()));
+ BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
+ if (mi != mapBlockIndex.end() && (*mi).second) {
+ CBlockIndex* pindex = (*mi).second;
+ if (chainActive.Contains(pindex)) {
+ entry.push_back(Pair("confirmations", 1 + chainActive.Height() - pindex->nHeight));
+ entry.push_back(Pair("time", pindex->GetBlockTime()));
+ entry.push_back(Pair("blocktime", pindex->GetBlockTime()));
+ }
+ 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 \"txid\" ( verbose )\n"
+ "\nNOTE: By default this function only works sometimes. This is when the tx is in the mempool\n"
+ "or there is an unspent output in the utxo for this transaction. To make it always work,\n"
+ "you need to maintain a transaction index, using the -txindex command line option.\n"
+ "\nReturn the raw transaction data.\n"
+ "\nIf verbose=0, returns a string that is serialized, hex-encoded data for 'txid'.\n"
+ "If verbose is non-zero, returns an Object with information about 'txid'.\n"
+
+ "\nArguments:\n"
+ "1. \"txid\" (string, required) The transaction id\n"
+ "2. verbose (numeric, optional, default=0) If 0, return a string, other return a json object\n"
+
+ "\nResult (if verbose is not set or set to 0):\n"
+ "\"data\" (string) The serialized, hex-encoded data for 'txid'\n"
+
+ "\nResult (if verbose > 0):\n"
+ "{\n"
+ " \"hex\" : \"data\", (string) The serialized, hex-encoded data for 'txid'\n"
+ " \"txid\" : \"id\", (string) The transaction id (same as provided)\n"
+ " \"version\" : n, (numeric) The version\n"
+ " \"locktime\" : ttt, (numeric) The lock time\n"
+ " \"vin\" : [ (array of json objects)\n"
+ " {\n"
+ " \"txid\": \"id\", (string) The transaction id\n"
+ " \"vout\": n, (numeric) \n"
+ " \"scriptSig\": { (json object) The script\n"
+ " \"asm\": \"asm\", (string) asm\n"
+ " \"hex\": \"hex\" (string) hex\n"
+ " },\n"
+ " \"sequence\": n (numeric) The script sequence number\n"
+ " }\n"
+ " ,...\n"
+ " ],\n"
+ " \"vout\" : [ (array of json objects)\n"
+ " {\n"
+ " \"value\" : x.xxx, (numeric) The value in btc\n"
+ " \"n\" : n, (numeric) index\n"
+ " \"scriptPubKey\" : { (json object)\n"
+ " \"asm\" : \"asm\", (string) the asm\n"
+ " \"hex\" : \"hex\", (string) the hex\n"
+ " \"reqSigs\" : n, (numeric) The required sigs\n"
+ " \"type\" : \"pubkeyhash\", (string) The type, eg 'pubkeyhash'\n"
+ " \"addresses\" : [ (json array of string)\n"
+ " \"bitcoinaddress\" (string) bitcoin address\n"
+ " ,...\n"
+ " ]\n"
+ " }\n"
+ " }\n"
+ " ,...\n"
+ " ],\n"
+ " \"blockhash\" : \"hash\", (string) the block hash\n"
+ " \"confirmations\" : n, (numeric) The confirmations\n"
+ " \"time\" : ttt, (numeric) The transaction time in seconds since epoch (Jan 1 1970 GMT)\n"
+ " \"blocktime\" : ttt (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n"
+ "}\n"
+
+ "\nExamples:\n"
+ + HelpExampleCli("getrawtransaction", "\"mytxid\"")
+ + HelpExampleCli("getrawtransaction", "\"mytxid\" 1")
+ + HelpExampleRpc("getrawtransaction", "\"mytxid\", 1")
+ );
+
+ LOCK(cs_main);
+
+ uint256 hash = ParseHashV(params[0], "parameter 1");
+
+ bool fVerbose = false;
+ if (params.size() > 1)
+ fVerbose = (params[1].get_int() != 0);
+
+ CTransaction tx;
+ uint256 hashBlock;
+ if (!GetTransaction(hash, tx, hashBlock, true))
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction");
+
+ string strHex = EncodeHexTx(tx);
+
+ if (!fVerbose)
+ return strHex;
+
+ Object result;
+ result.push_back(Pair("hex", strHex));
+ TxToJSON(tx, hashBlock, result);
+ return result;
+}
+
+Value gettxoutproof(const Array& params, bool fHelp)
+{
+ if (fHelp || (params.size() != 1 && params.size() != 2))
+ throw runtime_error(
+ "gettxoutproof [\"txid\",...] ( blockhash )\n"
+ "\nReturns a hex-encoded proof that \"txid\" was included in a block.\n"
+ "\nNOTE: By default this function only works sometimes. This is when there is an\n"
+ "unspent output in the utxo for this transaction. To make it always work,\n"
+ "you need to maintain a transaction index, using the -txindex command line option or\n"
+ "specify the block in which the transaction is included in manually (by blockhash).\n"
+ "\nReturn the raw transaction data.\n"
+ "\nArguments:\n"
+ "1. \"txids\" (string) A json array of txids to filter\n"
+ " [\n"
+ " \"txid\" (string) A transaction hash\n"
+ " ,...\n"
+ " ]\n"
+ "2. \"block hash\" (string, optional) If specified, looks for txid in the block with this hash\n"
+ "\nResult:\n"
+ "\"data\" (string) A string that is a serialized, hex-encoded data for the proof.\n"
+ );
+
+ set<uint256> setTxids;
+ uint256 oneTxid;
+ Array txids = params[0].get_array();
+ BOOST_FOREACH(Value& txid, txids) {
+ if (txid.get_str().length() != 64 || !IsHex(txid.get_str()))
+ throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid txid ")+txid.get_str());
+ uint256 hash(uint256S(txid.get_str()));
+ if (setTxids.count(hash))
+ throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated txid: ")+txid.get_str());
+ setTxids.insert(hash);
+ oneTxid = hash;
+ }
+
+ LOCK(cs_main);
+
+ CBlockIndex* pblockindex = NULL;
+
+ uint256 hashBlock;
+ if (params.size() > 1)
+ {
+ hashBlock = uint256S(params[1].get_str());
+ if (!mapBlockIndex.count(hashBlock))
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
+ pblockindex = mapBlockIndex[hashBlock];
+ } else {
+ CCoins coins;
+ if (pcoinsTip->GetCoins(oneTxid, coins) && coins.nHeight > 0 && coins.nHeight <= chainActive.Height())
+ pblockindex = chainActive[coins.nHeight];
+ }
+
+ if (pblockindex == NULL)
+ {
+ CTransaction tx;
+ if (!GetTransaction(oneTxid, tx, hashBlock, false) || hashBlock.IsNull())
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not yet in block");
+ if (!mapBlockIndex.count(hashBlock))
+ throw JSONRPCError(RPC_INTERNAL_ERROR, "Transaction index corrupt");
+ pblockindex = mapBlockIndex[hashBlock];
+ }
+
+ CBlock block;
+ if(!ReadBlockFromDisk(block, pblockindex))
+ throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk");
+
+ unsigned int ntxFound = 0;
+ BOOST_FOREACH(const CTransaction&tx, block.vtx)
+ if (setTxids.count(tx.GetHash()))
+ ntxFound++;
+ if (ntxFound != setTxids.size())
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "(Not all) transactions not found in specified block");
+
+ CDataStream ssMB(SER_NETWORK, PROTOCOL_VERSION);
+ CMerkleBlock mb(block, setTxids);
+ ssMB << mb;
+ std::string strHex = HexStr(ssMB.begin(), ssMB.end());
+ return strHex;
+}
+
+Value verifytxoutproof(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() != 1)
+ throw runtime_error(
+ "verifytxoutproof \"proof\"\n"
+ "\nVerifies that a proof points to a transaction in a block, returning the transaction it commits to\n"
+ "and throwing an RPC error if the block is not in our best chain\n"
+ "\nArguments:\n"
+ "1. \"proof\" (string, required) The hex-encoded proof generated by gettxoutproof\n"
+ "\nResult:\n"
+ "[\"txid\"] (array, strings) The txid(s) which the proof commits to, or empty array if the proof is invalid\n"
+ );
+
+ CDataStream ssMB(ParseHexV(params[0], "proof"), SER_NETWORK, PROTOCOL_VERSION);
+ CMerkleBlock merkleBlock;
+ ssMB >> merkleBlock;
+
+ Array res;
+
+ vector<uint256> vMatch;
+ if (merkleBlock.txn.ExtractMatches(vMatch) != merkleBlock.header.hashMerkleRoot)
+ return res;
+
+ LOCK(cs_main);
+
+ if (!mapBlockIndex.count(merkleBlock.header.GetHash()) || !chainActive.Contains(mapBlockIndex[merkleBlock.header.GetHash()]))
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found in chain");
+
+ BOOST_FOREACH(const uint256& hash, vMatch)
+ res.push_back(hash.GetHex());
+ return res;
+}
+
+Value createrawtransaction(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() != 2)
+ throw runtime_error(
+ "createrawtransaction [{\"txid\":\"id\",\"vout\":n},...] {\"address\":amount,...}\n"
+ "\nCreate a transaction spending the given inputs and sending to the given addresses.\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.\n"
+
+ "\nArguments:\n"
+ "1. \"transactions\" (string, required) A json array of json objects\n"
+ " [\n"
+ " {\n"
+ " \"txid\":\"id\", (string, required) The transaction id\n"
+ " \"vout\":n (numeric, required) The output number\n"
+ " }\n"
+ " ,...\n"
+ " ]\n"
+ "2. \"addresses\" (string, required) a json object with addresses as keys and amounts as values\n"
+ " {\n"
+ " \"address\": x.xxx (numeric, required) The key is the bitcoin address, the value is the btc amount\n"
+ " ,...\n"
+ " }\n"
+
+ "\nResult:\n"
+ "\"transaction\" (string) hex string of the transaction\n"
+
+ "\nExamples\n"
+ + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"{\\\"address\\\":0.01}\"")
+ + HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"{\\\"address\\\":0.01}\"")
+ );
+
+ LOCK(cs_main);
+ RPCTypeCheck(params, boost::assign::list_of(array_type)(obj_type));
+
+ Array inputs = params[0].get_array();
+ Object sendTo = params[1].get_obj();
+
+ CMutableTransaction rawTx;
+
+ BOOST_FOREACH(const Value& input, inputs) {
+ const Object& o = input.get_obj();
+
+ uint256 txid = ParseHashO(o, "txid");
+
+ const Value& vout_v = find_value(o, "vout");
+ if (vout_v.type() != int_type)
+ throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing vout key");
+ int nOutput = vout_v.get_int();
+ if (nOutput < 0)
+ throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive");
+
+ CTxIn in(COutPoint(txid, nOutput));
+ rawTx.vin.push_back(in);
+ }
+
+ set<CBitcoinAddress> setAddress;
+ BOOST_FOREACH(const Pair& s, sendTo) {
+ CBitcoinAddress address(s.name_);
+ if (!address.IsValid())
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+s.name_);
+
+ if (setAddress.count(address))
+ throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+s.name_);
+ setAddress.insert(address);
+
+ CScript scriptPubKey = GetScriptForDestination(address.Get());
+ CAmount nAmount = AmountFromValue(s.value_);
+
+ CTxOut out(nAmount, scriptPubKey);
+ rawTx.vout.push_back(out);
+ }
+
+ return EncodeHexTx(rawTx);
+}
+
+Value decoderawtransaction(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() != 1)
+ throw runtime_error(
+ "decoderawtransaction \"hexstring\"\n"
+ "\nReturn a JSON object representing the serialized, hex-encoded transaction.\n"
+
+ "\nArguments:\n"
+ "1. \"hex\" (string, required) The transaction hex string\n"
+
+ "\nResult:\n"
+ "{\n"
+ " \"txid\" : \"id\", (string) The transaction id\n"
+ " \"version\" : n, (numeric) The version\n"
+ " \"locktime\" : ttt, (numeric) The lock time\n"
+ " \"vin\" : [ (array of json objects)\n"
+ " {\n"
+ " \"txid\": \"id\", (string) The transaction id\n"
+ " \"vout\": n, (numeric) The output number\n"
+ " \"scriptSig\": { (json object) The script\n"
+ " \"asm\": \"asm\", (string) asm\n"
+ " \"hex\": \"hex\" (string) hex\n"
+ " },\n"
+ " \"sequence\": n (numeric) The script sequence number\n"
+ " }\n"
+ " ,...\n"
+ " ],\n"
+ " \"vout\" : [ (array of json objects)\n"
+ " {\n"
+ " \"value\" : x.xxx, (numeric) The value in btc\n"
+ " \"n\" : n, (numeric) index\n"
+ " \"scriptPubKey\" : { (json object)\n"
+ " \"asm\" : \"asm\", (string) the asm\n"
+ " \"hex\" : \"hex\", (string) the hex\n"
+ " \"reqSigs\" : n, (numeric) The required sigs\n"
+ " \"type\" : \"pubkeyhash\", (string) The type, eg 'pubkeyhash'\n"
+ " \"addresses\" : [ (json array of string)\n"
+ " \"12tvKAXCxZjSmdNbao16dKXC8tRWfcF5oc\" (string) bitcoin address\n"
+ " ,...\n"
+ " ]\n"
+ " }\n"
+ " }\n"
+ " ,...\n"
+ " ],\n"
+ "}\n"
+
+ "\nExamples:\n"
+ + HelpExampleCli("decoderawtransaction", "\"hexstring\"")
+ + HelpExampleRpc("decoderawtransaction", "\"hexstring\"")
+ );
+
+ LOCK(cs_main);
+ RPCTypeCheck(params, boost::assign::list_of(str_type));
+
+ CTransaction tx;
+
+ if (!DecodeHexTx(tx, params[0].get_str()))
+ throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
+
+ Object result;
+ TxToJSON(tx, uint256(), result);
+
+ return result;
+}
+
+Value decodescript(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() != 1)
+ throw runtime_error(
+ "decodescript \"hex\"\n"
+ "\nDecode a hex-encoded script.\n"
+ "\nArguments:\n"
+ "1. \"hex\" (string) the hex encoded script\n"
+ "\nResult:\n"
+ "{\n"
+ " \"asm\":\"asm\", (string) Script public key\n"
+ " \"hex\":\"hex\", (string) hex encoded public key\n"
+ " \"type\":\"type\", (string) The output type\n"
+ " \"reqSigs\": n, (numeric) The required signatures\n"
+ " \"addresses\": [ (json array of string)\n"
+ " \"address\" (string) bitcoin address\n"
+ " ,...\n"
+ " ],\n"
+ " \"p2sh\",\"address\" (string) script address\n"
+ "}\n"
+ "\nExamples:\n"
+ + HelpExampleCli("decodescript", "\"hexstring\"")
+ + HelpExampleRpc("decodescript", "\"hexstring\"")
+ );
+
+ LOCK(cs_main);
+ RPCTypeCheck(params, boost::assign::list_of(str_type));
+
+ Object r;
+ CScript script;
+ if (params[0].get_str().size() > 0){
+ vector<unsigned char> scriptData(ParseHexV(params[0], "argument"));
+ script = CScript(scriptData.begin(), scriptData.end());
+ } else {
+ // Empty scripts are valid
+ }
+ ScriptPubKeyToJSON(script, r, false);
+
+ r.push_back(Pair("p2sh", CBitcoinAddress(CScriptID(script)).ToString()));
+ return r;
+}
+
+/** Pushes a JSON object for script verification or signing errors to vErrorsRet. */
+static void TxInErrorToJSON(const CTxIn& txin, Array& vErrorsRet, const std::string& strMessage)
+{
+ Object entry;
+ entry.push_back(Pair("txid", txin.prevout.hash.ToString()));
+ entry.push_back(Pair("vout", (uint64_t)txin.prevout.n));
+ entry.push_back(Pair("scriptSig", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
+ entry.push_back(Pair("sequence", (uint64_t)txin.nSequence));
+ entry.push_back(Pair("error", strMessage));
+ vErrorsRet.push_back(entry);
+}
+
+Value signrawtransaction(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() < 1 || params.size() > 4)
+ throw runtime_error(
+ "signrawtransaction \"hexstring\" ( [{\"txid\":\"id\",\"vout\":n,\"scriptPubKey\":\"hex\",\"redeemScript\":\"hex\"},...] [\"privatekey1\",...] sighashtype )\n"
+ "\nSign inputs for raw transaction (serialized, hex-encoded).\n"
+ "The second optional argument (may be null) is an array of previous transaction outputs that\n"
+ "this transaction depends on but may not yet be in the block chain.\n"
+ "The third optional argument (may be null) is an array of base58-encoded private\n"
+ "keys that, if given, will be the only keys used to sign the transaction.\n"
+#ifdef ENABLE_WALLET
+ + HelpRequiringPassphrase() + "\n"
+#endif
+
+ "\nArguments:\n"
+ "1. \"hexstring\" (string, required) The transaction hex string\n"
+ "2. \"prevtxs\" (string, optional) An json array of previous dependent transaction outputs\n"
+ " [ (json array of json objects, or 'null' if none provided)\n"
+ " {\n"
+ " \"txid\":\"id\", (string, required) The transaction id\n"
+ " \"vout\":n, (numeric, required) The output number\n"
+ " \"scriptPubKey\": \"hex\", (string, required) script key\n"
+ " \"redeemScript\": \"hex\" (string, required for P2SH) redeem script\n"
+ " }\n"
+ " ,...\n"
+ " ]\n"
+ "3. \"privatekeys\" (string, optional) A json array of base58-encoded private keys for signing\n"
+ " [ (json array of strings, or 'null' if none provided)\n"
+ " \"privatekey\" (string) private key in base58-encoding\n"
+ " ,...\n"
+ " ]\n"
+ "4. \"sighashtype\" (string, optional, default=ALL) The signature hash type. Must be one of\n"
+ " \"ALL\"\n"
+ " \"NONE\"\n"
+ " \"SINGLE\"\n"
+ " \"ALL|ANYONECANPAY\"\n"
+ " \"NONE|ANYONECANPAY\"\n"
+ " \"SINGLE|ANYONECANPAY\"\n"
+
+ "\nResult:\n"
+ "{\n"
+ " \"hex\" : \"value\", (string) The hex-encoded raw transaction with signature(s)\n"
+ " \"complete\" : true|false, (boolean) If the transaction has a complete set of signatures\n"
+ " \"errors\" : [ (json array of objects) Script verification errors (if there are any)\n"
+ " {\n"
+ " \"txid\" : \"hash\", (string) The hash of the referenced, previous transaction\n"
+ " \"vout\" : n, (numeric) The index of the output to spent and used as input\n"
+ " \"scriptSig\" : \"hex\", (string) The hex-encoded signature script\n"
+ " \"sequence\" : n, (numeric) Script sequence number\n"
+ " \"error\" : \"text\" (string) Verification or signing error related to the input\n"
+ " }\n"
+ " ,...\n"
+ " ]\n"
+ "}\n"
+
+ "\nExamples:\n"
+ + HelpExampleCli("signrawtransaction", "\"myhex\"")
+ + HelpExampleRpc("signrawtransaction", "\"myhex\"")
+ );
+
+#ifdef ENABLE_WALLET
+ LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL);
+#else
+ LOCK(cs_main);
+#endif
+ RPCTypeCheck(params, boost::assign::list_of(str_type)(array_type)(array_type)(str_type), true);
+
+ vector<unsigned char> txData(ParseHexV(params[0], "argument 1"));
+ CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION);
+ vector<CMutableTransaction> txVariants;
+ while (!ssData.empty()) {
+ try {
+ CMutableTransaction tx;
+ ssData >> tx;
+ txVariants.push_back(tx);
+ }
+ catch (const std::exception&) {
+ throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
+ }
+ }
+
+ if (txVariants.empty())
+ throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Missing transaction");
+
+ // mergedTx will end up with all the signatures; it
+ // starts as a clone of the rawtx:
+ CMutableTransaction mergedTx(txVariants[0]);
+
+ // Fetch previous transactions (inputs):
+ CCoinsView viewDummy;
+ CCoinsViewCache view(&viewDummy);
+ {
+ LOCK(mempool.cs);
+ CCoinsViewCache &viewChain = *pcoinsTip;
+ CCoinsViewMemPool viewMempool(&viewChain, mempool);
+ view.SetBackend(viewMempool); // temporarily switch cache backend to db+mempool view
+
+ BOOST_FOREACH(const CTxIn& txin, mergedTx.vin) {
+ const uint256& prevHash = txin.prevout.hash;
+ CCoins coins;
+ view.AccessCoins(prevHash); // this is certainly allowed to fail
+ }
+
+ view.SetBackend(viewDummy); // switch back to avoid locking mempool for too long
+ }
+
+ bool fGivenKeys = false;
+ CBasicKeyStore tempKeystore;
+ if (params.size() > 2 && params[2].type() != null_type) {
+ 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(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key");
+ CKey key = vchSecret.GetKey();
+ if (!key.IsValid())
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Private key outside allowed range");
+ tempKeystore.AddKey(key);
+ }
+ }
+#ifdef ENABLE_WALLET
+ else if (pwalletMain)
+ EnsureWalletIsUnlocked();
+#endif
+
+ // Add previous txouts given in the RPC call:
+ if (params.size() > 1 && params[1].type() != null_type) {
+ Array prevTxs = params[1].get_array();
+ BOOST_FOREACH(Value& p, prevTxs) {
+ if (p.type() != obj_type)
+ throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "expected object with {\"txid'\",\"vout\",\"scriptPubKey\"}");
+
+ Object prevOut = p.get_obj();
+
+ RPCTypeCheck(prevOut, boost::assign::map_list_of("txid", str_type)("vout", int_type)("scriptPubKey", str_type));
+
+ uint256 txid = ParseHashO(prevOut, "txid");
+
+ int nOut = find_value(prevOut, "vout").get_int();
+ if (nOut < 0)
+ throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "vout must be positive");
+
+ vector<unsigned char> pkData(ParseHexO(prevOut, "scriptPubKey"));
+ CScript scriptPubKey(pkData.begin(), pkData.end());
+
+ {
+ CCoinsModifier coins = view.ModifyCoins(txid);
+ if (coins->IsAvailable(nOut) && coins->vout[nOut].scriptPubKey != scriptPubKey) {
+ string err("Previous output scriptPubKey mismatch:\n");
+ err = err + coins->vout[nOut].scriptPubKey.ToString() + "\nvs:\n"+
+ scriptPubKey.ToString();
+ throw JSONRPCError(RPC_DESERIALIZATION_ERROR, err);
+ }
+ if ((unsigned int)nOut >= coins->vout.size())
+ coins->vout.resize(nOut+1);
+ coins->vout[nOut].scriptPubKey = scriptPubKey;
+ coins->vout[nOut].nValue = 0; // we don't know the actual output value
+ }
+
+ // if redeemScript given and not using the local wallet (private keys
+ // given), add redeemScript to the tempKeystore so it can be signed:
+ if (fGivenKeys && scriptPubKey.IsPayToScriptHash()) {
+ RPCTypeCheck(prevOut, boost::assign::map_list_of("txid", str_type)("vout", int_type)("scriptPubKey", str_type)("redeemScript",str_type));
+ Value v = find_value(prevOut, "redeemScript");
+ if (!(v == Value::null)) {
+ vector<unsigned char> rsData(ParseHexV(v, "redeemScript"));
+ CScript redeemScript(rsData.begin(), rsData.end());
+ tempKeystore.AddCScript(redeemScript);
+ }
+ }
+ }
+ }
+
+#ifdef ENABLE_WALLET
+ const CKeyStore& keystore = ((fGivenKeys || !pwalletMain) ? tempKeystore : *pwalletMain);
+#else
+ const CKeyStore& keystore = tempKeystore;
+#endif
+
+ int nHashType = SIGHASH_ALL;
+ if (params.size() > 3 && params[3].type() != null_type) {
+ static map<string, int> 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(RPC_INVALID_PARAMETER, "Invalid sighash param");
+ }
+
+ bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE);
+
+ // Script verification errors
+ Array vErrors;
+
+ // Sign what we can:
+ for (unsigned int i = 0; i < mergedTx.vin.size(); i++) {
+ CTxIn& txin = mergedTx.vin[i];
+ const CCoins* coins = view.AccessCoins(txin.prevout.hash);
+ if (coins == NULL || !coins->IsAvailable(txin.prevout.n)) {
+ TxInErrorToJSON(txin, vErrors, "Input not found or already spent");
+ continue;
+ }
+ const CScript& prevPubKey = coins->vout[txin.prevout.n].scriptPubKey;
+
+ txin.scriptSig.clear();
+ // Only sign SIGHASH_SINGLE if there's a corresponding output:
+ if (!fHashSingle || (i < mergedTx.vout.size()))
+ SignSignature(keystore, prevPubKey, mergedTx, i, nHashType);
+
+ // ... and merge in other signatures:
+ BOOST_FOREACH(const CMutableTransaction& txv, txVariants) {
+ txin.scriptSig = CombineSignatures(prevPubKey, mergedTx, i, txin.scriptSig, txv.vin[i].scriptSig);
+ }
+ ScriptError serror = SCRIPT_ERR_OK;
+ if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(&mergedTx, i), &serror)) {
+ TxInErrorToJSON(txin, vErrors, ScriptErrorString(serror));
+ }
+ }
+ bool fComplete = vErrors.empty();
+
+ Object result;
+ result.push_back(Pair("hex", EncodeHexTx(mergedTx)));
+ result.push_back(Pair("complete", fComplete));
+ if (!vErrors.empty()) {
+ result.push_back(Pair("errors", vErrors));
+ }
+
+ return result;
+}
+
+Value sendrawtransaction(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() < 1 || params.size() > 2)
+ throw runtime_error(
+ "sendrawtransaction \"hexstring\" ( allowhighfees )\n"
+ "\nSubmits raw transaction (serialized, hex-encoded) to local node and network.\n"
+ "\nAlso see createrawtransaction and signrawtransaction calls.\n"
+ "\nArguments:\n"
+ "1. \"hexstring\" (string, required) The hex string of the raw transaction)\n"
+ "2. allowhighfees (boolean, optional, default=false) Allow high fees\n"
+ "\nResult:\n"
+ "\"hex\" (string) The transaction hash in hex\n"
+ "\nExamples:\n"
+ "\nCreate a transaction\n"
+ + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\" : \\\"mytxid\\\",\\\"vout\\\":0}]\" \"{\\\"myaddress\\\":0.01}\"") +
+ "Sign the transaction, and get back the hex\n"
+ + HelpExampleCli("signrawtransaction", "\"myhex\"") +
+ "\nSend the transaction (signed hex)\n"
+ + HelpExampleCli("sendrawtransaction", "\"signedhex\"") +
+ "\nAs a json rpc call\n"
+ + HelpExampleRpc("sendrawtransaction", "\"signedhex\"")
+ );
+
+ LOCK(cs_main);
+ RPCTypeCheck(params, boost::assign::list_of(str_type)(bool_type));
+
+ // parse hex string from parameter
+ CTransaction tx;
+ if (!DecodeHexTx(tx, params[0].get_str()))
+ throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
+ uint256 hashTx = tx.GetHash();
+
+ bool fOverrideFees = false;
+ if (params.size() > 1)
+ fOverrideFees = params[1].get_bool();
+
+ CCoinsViewCache &view = *pcoinsTip;
+ const CCoins* existingCoins = view.AccessCoins(hashTx);
+ bool fHaveMempool = mempool.exists(hashTx);
+ bool fHaveChain = existingCoins && existingCoins->nHeight < 1000000000;
+ if (!fHaveMempool && !fHaveChain) {
+ // push to local node and sync with wallets
+ CValidationState state;
+ bool fMissingInputs;
+ if (!AcceptToMemoryPool(mempool, state, tx, false, &fMissingInputs, !fOverrideFees)) {
+ if (state.IsInvalid()) {
+ throw JSONRPCError(RPC_TRANSACTION_REJECTED, strprintf("%i: %s", state.GetRejectCode(), state.GetRejectReason()));
+ } else {
+ if (fMissingInputs) {
+ throw JSONRPCError(RPC_TRANSACTION_ERROR, "Missing inputs");
+ }
+ throw JSONRPCError(RPC_TRANSACTION_ERROR, state.GetRejectReason());
+ }
+ }
+ } else if (fHaveChain) {
+ throw JSONRPCError(RPC_TRANSACTION_ALREADY_IN_CHAIN, "transaction already in block chain");
+ }
+ RelayTransaction(tx);
+
+ return hashTx.GetHex();
+}
diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp
new file mode 100644
index 0000000000..824648464e
--- /dev/null
+++ b/src/rpcserver.cpp
@@ -0,0 +1,1038 @@
+// Copyright (c) 2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "rpcserver.h"
+
+#include "base58.h"
+#include "init.h"
+#include "random.h"
+#include "sync.h"
+#include "ui_interface.h"
+#include "util.h"
+#include "utilstrencodings.h"
+#ifdef ENABLE_WALLET
+#include "wallet/wallet.h"
+#endif
+
+#include <boost/algorithm/string.hpp>
+#include <boost/asio.hpp>
+#include <boost/asio/ssl.hpp>
+#include <boost/bind.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/foreach.hpp>
+#include <boost/iostreams/concepts.hpp>
+#include <boost/iostreams/stream.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/signals2/signal.hpp>
+#include <boost/thread.hpp>
+#include "json/json_spirit_writer_template.h"
+
+using namespace boost::asio;
+using namespace json_spirit;
+using namespace RPCServer;
+using namespace std;
+
+static std::string strRPCUserColonPass;
+
+static bool fRPCRunning = false;
+static bool fRPCInWarmup = true;
+static std::string rpcWarmupStatus("RPC server started");
+static CCriticalSection cs_rpcWarmup;
+
+//! These are created by StartRPCThreads, destroyed in StopRPCThreads
+static boost::asio::io_service* rpc_io_service = NULL;
+static map<string, boost::shared_ptr<deadline_timer> > deadlineTimers;
+static ssl::context* rpc_ssl_context = NULL;
+static boost::thread_group* rpc_worker_group = NULL;
+static boost::asio::io_service::work *rpc_dummy_work = NULL;
+static std::vector<CSubNet> rpc_allow_subnets; //!< List of subnets to allow RPC connections from
+static std::vector< boost::shared_ptr<ip::tcp::acceptor> > rpc_acceptors;
+
+static struct CRPCSignals
+{
+ boost::signals2::signal<void ()> Started;
+ boost::signals2::signal<void ()> Stopped;
+ boost::signals2::signal<void (const CRPCCommand&)> PreCommand;
+ boost::signals2::signal<void (const CRPCCommand&)> PostCommand;
+} g_rpcSignals;
+
+void RPCServer::OnStarted(boost::function<void ()> slot)
+{
+ g_rpcSignals.Started.connect(slot);
+}
+
+void RPCServer::OnStopped(boost::function<void ()> slot)
+{
+ g_rpcSignals.Stopped.connect(slot);
+}
+
+void RPCServer::OnPreCommand(boost::function<void (const CRPCCommand&)> slot)
+{
+ g_rpcSignals.PreCommand.connect(boost::bind(slot, _1));
+}
+
+void RPCServer::OnPostCommand(boost::function<void (const CRPCCommand&)> slot)
+{
+ g_rpcSignals.PostCommand.connect(boost::bind(slot, _1));
+}
+
+void RPCTypeCheck(const Array& params,
+ const list<Value_type>& typesExpected,
+ bool fAllowNull)
+{
+ unsigned int i = 0;
+ BOOST_FOREACH(Value_type t, typesExpected)
+ {
+ if (params.size() <= i)
+ break;
+
+ const Value& v = params[i];
+ if (!((v.type() == t) || (fAllowNull && (v.type() == null_type))))
+ {
+ string err = strprintf("Expected type %s, got %s",
+ Value_type_name[t], Value_type_name[v.type()]);
+ throw JSONRPCError(RPC_TYPE_ERROR, err);
+ }
+ i++;
+ }
+}
+
+void RPCTypeCheck(const Object& o,
+ const map<string, Value_type>& typesExpected,
+ bool fAllowNull)
+{
+ BOOST_FOREACH(const PAIRTYPE(string, Value_type)& t, typesExpected)
+ {
+ const Value& v = find_value(o, t.first);
+ if (!fAllowNull && v.type() == null_type)
+ throw JSONRPCError(RPC_TYPE_ERROR, strprintf("Missing %s", t.first));
+
+ if (!((v.type() == t.second) || (fAllowNull && (v.type() == null_type))))
+ {
+ string err = strprintf("Expected type %s for %s, got %s",
+ Value_type_name[t.second], t.first, Value_type_name[v.type()]);
+ throw JSONRPCError(RPC_TYPE_ERROR, err);
+ }
+ }
+}
+
+static inline int64_t roundint64(double d)
+{
+ return (int64_t)(d > 0 ? d + 0.5 : d - 0.5);
+}
+
+CAmount AmountFromValue(const Value& value)
+{
+ double dAmount = value.get_real();
+ if (dAmount <= 0.0 || dAmount > 21000000.0)
+ throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount");
+ CAmount nAmount = roundint64(dAmount * COIN);
+ if (!MoneyRange(nAmount))
+ throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount");
+ return nAmount;
+}
+
+Value ValueFromAmount(const CAmount& amount)
+{
+ return (double)amount / (double)COIN;
+}
+
+uint256 ParseHashV(const Value& v, string strName)
+{
+ string strHex;
+ if (v.type() == str_type)
+ strHex = v.get_str();
+ if (!IsHex(strHex)) // Note: IsHex("") is false
+ throw JSONRPCError(RPC_INVALID_PARAMETER, strName+" must be hexadecimal string (not '"+strHex+"')");
+ uint256 result;
+ result.SetHex(strHex);
+ return result;
+}
+uint256 ParseHashO(const Object& o, string strKey)
+{
+ return ParseHashV(find_value(o, strKey), strKey);
+}
+vector<unsigned char> ParseHexV(const Value& v, string strName)
+{
+ string strHex;
+ if (v.type() == str_type)
+ strHex = v.get_str();
+ if (!IsHex(strHex))
+ throw JSONRPCError(RPC_INVALID_PARAMETER, strName+" must be hexadecimal string (not '"+strHex+"')");
+ return ParseHex(strHex);
+}
+vector<unsigned char> ParseHexO(const Object& o, string strKey)
+{
+ return ParseHexV(find_value(o, strKey), strKey);
+}
+
+
+/**
+ * Note: This interface may still be subject to change.
+ */
+
+string CRPCTable::help(string strCommand) const
+{
+ string strRet;
+ string category;
+ set<rpcfn_type> setDone;
+ vector<pair<string, const CRPCCommand*> > vCommands;
+
+ for (map<string, const CRPCCommand*>::const_iterator mi = mapCommands.begin(); mi != mapCommands.end(); ++mi)
+ vCommands.push_back(make_pair(mi->second->category + mi->first, mi->second));
+ sort(vCommands.begin(), vCommands.end());
+
+ BOOST_FOREACH(const PAIRTYPE(string, const CRPCCommand*)& command, vCommands)
+ {
+ const CRPCCommand *pcmd = command.second;
+ string strMethod = pcmd->name;
+ // We already filter duplicates, but these deprecated screw up the sort order
+ if (strMethod.find("label") != string::npos)
+ continue;
+ if ((strCommand != "" || pcmd->category == "hidden") && strMethod != strCommand)
+ continue;
+ try
+ {
+ Array params;
+ rpcfn_type pfn = pcmd->actor;
+ if (setDone.insert(pfn).second)
+ (*pfn)(params, true);
+ }
+ catch (const 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'));
+
+ if (category != pcmd->category)
+ {
+ if (!category.empty())
+ strRet += "\n";
+ category = pcmd->category;
+ string firstLetter = category.substr(0,1);
+ boost::to_upper(firstLetter);
+ strRet += "== " + firstLetter + category.substr(1) + " ==\n";
+ }
+ }
+ strRet += strHelp + "\n";
+ }
+ }
+ if (strRet == "")
+ strRet = strprintf("help: unknown command: %s\n", strCommand);
+ 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"
+ "\nList all commands, or get help for a specified command.\n"
+ "\nArguments:\n"
+ "1. \"command\" (string, optional) The command to get help on\n"
+ "\nResult:\n"
+ "\"text\" (string) The help text\n"
+ );
+
+ string strCommand;
+ if (params.size() > 0)
+ strCommand = params[0].get_str();
+
+ return tableRPC.help(strCommand);
+}
+
+
+Value stop(const Array& params, bool fHelp)
+{
+ // Accept the deprecated and ignored 'detach' boolean argument
+ if (fHelp || params.size() > 1)
+ throw runtime_error(
+ "stop\n"
+ "\nStop Bitcoin server.");
+ // Shutdown will take long enough that the response should get back
+ StartShutdown();
+ return "Bitcoin server stopping";
+}
+
+
+
+/**
+ * Call Table
+ */
+static const CRPCCommand vRPCCommands[] =
+{ // category name actor (function) okSafeMode
+ // --------------------- ------------------------ ----------------------- ----------
+ /* Overall control/query calls */
+ { "control", "getinfo", &getinfo, true }, /* uses wallet if enabled */
+ { "control", "help", &help, true },
+ { "control", "stop", &stop, true },
+
+ /* P2P networking */
+ { "network", "getnetworkinfo", &getnetworkinfo, true },
+ { "network", "addnode", &addnode, true },
+ { "network", "getaddednodeinfo", &getaddednodeinfo, true },
+ { "network", "getconnectioncount", &getconnectioncount, true },
+ { "network", "getnettotals", &getnettotals, true },
+ { "network", "getpeerinfo", &getpeerinfo, true },
+ { "network", "ping", &ping, true },
+
+ /* Block chain and UTXO */
+ { "blockchain", "getblockchaininfo", &getblockchaininfo, true },
+ { "blockchain", "getbestblockhash", &getbestblockhash, true },
+ { "blockchain", "getblockcount", &getblockcount, true },
+ { "blockchain", "getblock", &getblock, true },
+ { "blockchain", "getblockhash", &getblockhash, true },
+ { "blockchain", "getchaintips", &getchaintips, true },
+ { "blockchain", "getdifficulty", &getdifficulty, true },
+ { "blockchain", "getmempoolinfo", &getmempoolinfo, true },
+ { "blockchain", "getrawmempool", &getrawmempool, true },
+ { "blockchain", "gettxout", &gettxout, true },
+ { "blockchain", "gettxoutproof", &gettxoutproof, true },
+ { "blockchain", "verifytxoutproof", &verifytxoutproof, true },
+ { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, true },
+ { "blockchain", "verifychain", &verifychain, true },
+
+ /* Mining */
+ { "mining", "getblocktemplate", &getblocktemplate, true },
+ { "mining", "getmininginfo", &getmininginfo, true },
+ { "mining", "getnetworkhashps", &getnetworkhashps, true },
+ { "mining", "prioritisetransaction", &prioritisetransaction, true },
+ { "mining", "submitblock", &submitblock, true },
+
+#ifdef ENABLE_WALLET
+ /* Coin generation */
+ { "generating", "getgenerate", &getgenerate, true },
+ { "generating", "setgenerate", &setgenerate, true },
+ { "generating", "generate", &generate, true },
+#endif
+
+ /* Raw transactions */
+ { "rawtransactions", "createrawtransaction", &createrawtransaction, true },
+ { "rawtransactions", "decoderawtransaction", &decoderawtransaction, true },
+ { "rawtransactions", "decodescript", &decodescript, true },
+ { "rawtransactions", "getrawtransaction", &getrawtransaction, true },
+ { "rawtransactions", "sendrawtransaction", &sendrawtransaction, false },
+ { "rawtransactions", "signrawtransaction", &signrawtransaction, false }, /* uses wallet if enabled */
+
+ /* Utility functions */
+ { "util", "createmultisig", &createmultisig, true },
+ { "util", "validateaddress", &validateaddress, true }, /* uses wallet if enabled */
+ { "util", "verifymessage", &verifymessage, true },
+ { "util", "estimatefee", &estimatefee, true },
+ { "util", "estimatepriority", &estimatepriority, true },
+
+ /* Not shown in help */
+ { "hidden", "invalidateblock", &invalidateblock, true },
+ { "hidden", "reconsiderblock", &reconsiderblock, true },
+ { "hidden", "setmocktime", &setmocktime, true },
+#ifdef ENABLE_WALLET
+ { "hidden", "resendwallettransactions", &resendwallettransactions, true},
+#endif
+
+#ifdef ENABLE_WALLET
+ /* Wallet */
+ { "wallet", "addmultisigaddress", &addmultisigaddress, true },
+ { "wallet", "backupwallet", &backupwallet, true },
+ { "wallet", "dumpprivkey", &dumpprivkey, true },
+ { "wallet", "dumpwallet", &dumpwallet, true },
+ { "wallet", "encryptwallet", &encryptwallet, true },
+ { "wallet", "getaccountaddress", &getaccountaddress, true },
+ { "wallet", "getaccount", &getaccount, true },
+ { "wallet", "getaddressesbyaccount", &getaddressesbyaccount, true },
+ { "wallet", "getbalance", &getbalance, false },
+ { "wallet", "getnewaddress", &getnewaddress, true },
+ { "wallet", "getrawchangeaddress", &getrawchangeaddress, true },
+ { "wallet", "getreceivedbyaccount", &getreceivedbyaccount, false },
+ { "wallet", "getreceivedbyaddress", &getreceivedbyaddress, false },
+ { "wallet", "gettransaction", &gettransaction, false },
+ { "wallet", "getunconfirmedbalance", &getunconfirmedbalance, false },
+ { "wallet", "getwalletinfo", &getwalletinfo, false },
+ { "wallet", "importprivkey", &importprivkey, true },
+ { "wallet", "importwallet", &importwallet, true },
+ { "wallet", "importaddress", &importaddress, true },
+ { "wallet", "keypoolrefill", &keypoolrefill, true },
+ { "wallet", "listaccounts", &listaccounts, false },
+ { "wallet", "listaddressgroupings", &listaddressgroupings, false },
+ { "wallet", "listlockunspent", &listlockunspent, false },
+ { "wallet", "listreceivedbyaccount", &listreceivedbyaccount, false },
+ { "wallet", "listreceivedbyaddress", &listreceivedbyaddress, false },
+ { "wallet", "listsinceblock", &listsinceblock, false },
+ { "wallet", "listtransactions", &listtransactions, false },
+ { "wallet", "listunspent", &listunspent, false },
+ { "wallet", "lockunspent", &lockunspent, true },
+ { "wallet", "move", &movecmd, false },
+ { "wallet", "sendfrom", &sendfrom, false },
+ { "wallet", "sendmany", &sendmany, false },
+ { "wallet", "sendtoaddress", &sendtoaddress, false },
+ { "wallet", "setaccount", &setaccount, true },
+ { "wallet", "settxfee", &settxfee, true },
+ { "wallet", "signmessage", &signmessage, true },
+ { "wallet", "walletlock", &walletlock, true },
+ { "wallet", "walletpassphrasechange", &walletpassphrasechange, true },
+ { "wallet", "walletpassphrase", &walletpassphrase, true },
+#endif // ENABLE_WALLET
+};
+
+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<string, const CRPCCommand*>::const_iterator it = mapCommands.find(name);
+ if (it == mapCommands.end())
+ return NULL;
+ return (*it).second;
+}
+
+
+bool HTTPAuthorized(map<string, string>& 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 TimingResistantEqual(strUserPass, strRPCUserColonPass);
+}
+
+void ErrorReply(std::ostream& stream, const Object& objError, const Value& id)
+{
+ // Send error reply from json-rpc error object
+ int nStatus = HTTP_INTERNAL_SERVER_ERROR;
+ int code = find_value(objError, "code").get_int();
+ if (code == RPC_INVALID_REQUEST) nStatus = HTTP_BAD_REQUEST;
+ else if (code == RPC_METHOD_NOT_FOUND) nStatus = HTTP_NOT_FOUND;
+ string strReply = JSONRPCReply(Value::null, objError, id);
+ stream << HTTPReply(nStatus, strReply, false) << std::flush;
+}
+
+CNetAddr BoostAsioToCNetAddr(boost::asio::ip::address address)
+{
+ CNetAddr netaddr;
+ // 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()))
+ address = address.to_v6().to_v4();
+
+ if(address.is_v4())
+ {
+ boost::asio::ip::address_v4::bytes_type bytes = address.to_v4().to_bytes();
+ netaddr.SetRaw(NET_IPV4, &bytes[0]);
+ }
+ else
+ {
+ boost::asio::ip::address_v6::bytes_type bytes = address.to_v6().to_bytes();
+ netaddr.SetRaw(NET_IPV6, &bytes[0]);
+ }
+ return netaddr;
+}
+
+bool ClientAllowed(const boost::asio::ip::address& address)
+{
+ CNetAddr netaddr = BoostAsioToCNetAddr(address);
+ BOOST_FOREACH(const CSubNet &subnet, rpc_allow_subnets)
+ if (subnet.Match(netaddr))
+ return true;
+ return false;
+}
+
+template <typename Protocol>
+class AcceptedConnectionImpl : public AcceptedConnection
+{
+public:
+ AcceptedConnectionImpl(
+ boost::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;
+ boost::asio::ssl::stream<typename Protocol::socket> sslStream;
+
+private:
+ SSLIOStreamDevice<Protocol> _d;
+ boost::iostreams::stream< SSLIOStreamDevice<Protocol> > _stream;
+};
+
+void ServiceConnection(AcceptedConnection *conn);
+
+//! Forward declaration required for RPCListen
+template <typename Protocol, typename SocketAcceptorService>
+static void RPCAcceptHandler(boost::shared_ptr< basic_socket_acceptor<Protocol, SocketAcceptorService> > acceptor,
+ ssl::context& context,
+ bool fUseSSL,
+ boost::shared_ptr< AcceptedConnection > conn,
+ const boost::system::error_code& error);
+
+/**
+ * Sets up I/O resources to accept and handle a new connection.
+ */
+template <typename Protocol, typename SocketAcceptorService>
+static void RPCListen(boost::shared_ptr< basic_socket_acceptor<Protocol, SocketAcceptorService> > acceptor,
+ ssl::context& context,
+ const bool fUseSSL)
+{
+ // Accept connection
+ boost::shared_ptr< AcceptedConnectionImpl<Protocol> > conn(new AcceptedConnectionImpl<Protocol>(acceptor->get_io_service(), context, fUseSSL));
+
+ acceptor->async_accept(
+ conn->sslStream.lowest_layer(),
+ conn->peer,
+ boost::bind(&RPCAcceptHandler<Protocol, SocketAcceptorService>,
+ acceptor,
+ boost::ref(context),
+ fUseSSL,
+ conn,
+ _1));
+}
+
+
+/**
+ * Accept and handle incoming connection.
+ */
+template <typename Protocol, typename SocketAcceptorService>
+static void RPCAcceptHandler(boost::shared_ptr< basic_socket_acceptor<Protocol, SocketAcceptorService> > acceptor,
+ ssl::context& context,
+ const bool fUseSSL,
+ boost::shared_ptr< AcceptedConnection > conn,
+ const boost::system::error_code& error)
+{
+ // Immediately start accepting new connections, except when we're cancelled or our socket is closed.
+ if (error != boost::asio::error::operation_aborted && acceptor->is_open())
+ RPCListen(acceptor, context, fUseSSL);
+
+ AcceptedConnectionImpl<ip::tcp>* tcp_conn = dynamic_cast< AcceptedConnectionImpl<ip::tcp>* >(conn.get());
+
+ if (error)
+ {
+ // TODO: Actually handle errors
+ LogPrintf("%s: Error: %s\n", __func__, error.message());
+ }
+ // 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() << HTTPError(HTTP_FORBIDDEN, false) << std::flush;
+ conn->close();
+ }
+ else {
+ ServiceConnection(conn.get());
+ conn->close();
+ }
+}
+
+static ip::tcp::endpoint ParseEndpoint(const std::string &strEndpoint, int defaultPort)
+{
+ std::string addr;
+ int port = defaultPort;
+ SplitHostPort(strEndpoint, port, addr);
+ return ip::tcp::endpoint(boost::asio::ip::address::from_string(addr), port);
+}
+
+void StartRPCThreads()
+{
+ rpc_allow_subnets.clear();
+ rpc_allow_subnets.push_back(CSubNet("127.0.0.0/8")); // always allow IPv4 local subnet
+ rpc_allow_subnets.push_back(CSubNet("::1")); // always allow IPv6 localhost
+ if (mapMultiArgs.count("-rpcallowip"))
+ {
+ const vector<string>& vAllow = mapMultiArgs["-rpcallowip"];
+ BOOST_FOREACH(string strAllow, vAllow)
+ {
+ CSubNet subnet(strAllow);
+ if(!subnet.IsValid())
+ {
+ uiInterface.ThreadSafeMessageBox(
+ strprintf("Invalid -rpcallowip subnet specification: %s. Valid are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24).", strAllow),
+ "", CClientUIInterface::MSG_ERROR);
+ StartShutdown();
+ return;
+ }
+ rpc_allow_subnets.push_back(subnet);
+ }
+ }
+ std::string strAllowed;
+ BOOST_FOREACH(const CSubNet &subnet, rpc_allow_subnets)
+ strAllowed += subnet.ToString() + " ";
+ LogPrint("rpc", "Allowing RPC connections from: %s\n", strAllowed);
+
+ strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"];
+ if (((mapArgs["-rpcpassword"] == "") ||
+ (mapArgs["-rpcuser"] == mapArgs["-rpcpassword"])) && Params().RequireRPCPassword())
+ {
+ unsigned char rand_pwd[32];
+ GetRandBytes(rand_pwd, 32);
+ uiInterface.ThreadSafeMessageBox(strprintf(
+ _("To use bitcoind, or the -server option to bitcoin-qt, you must set an rpcpassword in the configuration file:\n"
+ "%s\n"
+ "It is recommended you use the following random password:\n"
+ "rpcuser=bitcoinrpc\n"
+ "rpcpassword=%s\n"
+ "(you do not need to remember this password)\n"
+ "The username and password MUST NOT be the same.\n"
+ "If the file does not exist, create it with owner-readable-only file permissions.\n"
+ "It is also recommended to set alertnotify so you are notified of problems;\n"
+ "for example: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com\n"),
+ GetConfigFile().string(),
+ EncodeBase58(&rand_pwd[0],&rand_pwd[0]+32)),
+ "", CClientUIInterface::MSG_ERROR | CClientUIInterface::SECURE);
+ StartShutdown();
+ return;
+ }
+
+ assert(rpc_io_service == NULL);
+ rpc_io_service = new boost::asio::io_service();
+ rpc_ssl_context = new ssl::context(*rpc_io_service, ssl::context::sslv23);
+
+ const bool fUseSSL = GetBoolArg("-rpcssl", false);
+
+ if (fUseSSL)
+ {
+ rpc_ssl_context->set_options(ssl::context::no_sslv2 | ssl::context::no_sslv3);
+
+ boost::filesystem::path pathCertFile(GetArg("-rpcsslcertificatechainfile", "server.cert"));
+ if (!pathCertFile.is_complete()) pathCertFile = boost::filesystem::path(GetDataDir()) / pathCertFile;
+ if (boost::filesystem::exists(pathCertFile)) rpc_ssl_context->use_certificate_chain_file(pathCertFile.string());
+ else LogPrintf("ThreadRPCServer ERROR: missing server certificate file %s\n", pathCertFile.string());
+
+ boost::filesystem::path pathPKFile(GetArg("-rpcsslprivatekeyfile", "server.pem"));
+ if (!pathPKFile.is_complete()) pathPKFile = boost::filesystem::path(GetDataDir()) / pathPKFile;
+ if (boost::filesystem::exists(pathPKFile)) rpc_ssl_context->use_private_key_file(pathPKFile.string(), ssl::context::pem);
+ else LogPrintf("ThreadRPCServer ERROR: missing server private key file %s\n", pathPKFile.string());
+
+ string strCiphers = GetArg("-rpcsslciphers", "TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH");
+ SSL_CTX_set_cipher_list(rpc_ssl_context->impl(), strCiphers.c_str());
+ }
+
+ std::vector<ip::tcp::endpoint> vEndpoints;
+ bool bBindAny = false;
+ int defaultPort = GetArg("-rpcport", BaseParams().RPCPort());
+ if (!mapArgs.count("-rpcallowip")) // Default to loopback if not allowing external IPs
+ {
+ vEndpoints.push_back(ip::tcp::endpoint(boost::asio::ip::address_v6::loopback(), defaultPort));
+ vEndpoints.push_back(ip::tcp::endpoint(boost::asio::ip::address_v4::loopback(), defaultPort));
+ if (mapArgs.count("-rpcbind"))
+ {
+ LogPrintf("WARNING: option -rpcbind was ignored because -rpcallowip was not specified, refusing to allow everyone to connect\n");
+ }
+ } else if (mapArgs.count("-rpcbind")) // Specific bind address
+ {
+ BOOST_FOREACH(const std::string &addr, mapMultiArgs["-rpcbind"])
+ {
+ try {
+ vEndpoints.push_back(ParseEndpoint(addr, defaultPort));
+ }
+ catch (const boost::system::system_error&)
+ {
+ uiInterface.ThreadSafeMessageBox(
+ strprintf(_("Could not parse -rpcbind value %s as network address"), addr),
+ "", CClientUIInterface::MSG_ERROR);
+ StartShutdown();
+ return;
+ }
+ }
+ } else { // No specific bind address specified, bind to any
+ vEndpoints.push_back(ip::tcp::endpoint(boost::asio::ip::address_v6::any(), defaultPort));
+ vEndpoints.push_back(ip::tcp::endpoint(boost::asio::ip::address_v4::any(), defaultPort));
+ // Prefer making the socket dual IPv6/IPv4 instead of binding
+ // to both addresses separately.
+ bBindAny = true;
+ }
+
+ bool fListening = false;
+ std::string strerr;
+ std::string straddress;
+ BOOST_FOREACH(const ip::tcp::endpoint &endpoint, vEndpoints)
+ {
+ try {
+ boost::asio::ip::address bindAddress = endpoint.address();
+ straddress = bindAddress.to_string();
+ LogPrintf("Binding RPC on address %s port %i (IPv4+IPv6 bind any: %i)\n", straddress, endpoint.port(), bBindAny);
+ boost::system::error_code v6_only_error;
+ boost::shared_ptr<ip::tcp::acceptor> acceptor(new ip::tcp::acceptor(*rpc_io_service));
+
+ acceptor->open(endpoint.protocol());
+ acceptor->set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
+
+ // Try making the socket dual IPv6/IPv4 when listening on the IPv6 "any" address
+ acceptor->set_option(boost::asio::ip::v6_only(
+ !bBindAny || bindAddress != boost::asio::ip::address_v6::any()), v6_only_error);
+
+ acceptor->bind(endpoint);
+ acceptor->listen(socket_base::max_connections);
+
+ RPCListen(acceptor, *rpc_ssl_context, fUseSSL);
+
+ fListening = true;
+ rpc_acceptors.push_back(acceptor);
+ // If dual IPv6/IPv4 bind successful, skip binding to IPv4 separately
+ if(bBindAny && bindAddress == boost::asio::ip::address_v6::any() && !v6_only_error)
+ break;
+ }
+ catch (const boost::system::system_error& e)
+ {
+ LogPrintf("ERROR: Binding RPC on address %s port %i failed: %s\n", straddress, endpoint.port(), e.what());
+ strerr = strprintf(_("An error occurred while setting up the RPC address %s port %u for listening: %s"), straddress, endpoint.port(), e.what());
+ }
+ }
+
+ if (!fListening) {
+ uiInterface.ThreadSafeMessageBox(strerr, "", CClientUIInterface::MSG_ERROR);
+ StartShutdown();
+ return;
+ }
+
+ rpc_worker_group = new boost::thread_group();
+ for (int i = 0; i < GetArg("-rpcthreads", 4); i++)
+ rpc_worker_group->create_thread(boost::bind(&boost::asio::io_service::run, rpc_io_service));
+ fRPCRunning = true;
+ g_rpcSignals.Started();
+}
+
+void StartDummyRPCThread()
+{
+ if(rpc_io_service == NULL)
+ {
+ rpc_io_service = new boost::asio::io_service();
+ /* Create dummy "work" to keep the thread from exiting when no timeouts active,
+ * see http://www.boost.org/doc/libs/1_51_0/doc/html/boost_asio/reference/io_service.html#boost_asio.reference.io_service.stopping_the_io_service_from_running_out_of_work */
+ rpc_dummy_work = new boost::asio::io_service::work(*rpc_io_service);
+ rpc_worker_group = new boost::thread_group();
+ rpc_worker_group->create_thread(boost::bind(&boost::asio::io_service::run, rpc_io_service));
+ fRPCRunning = true;
+ }
+}
+
+void StopRPCThreads()
+{
+ if (rpc_io_service == NULL) return;
+ // Set this to false first, so that longpolling loops will exit when woken up
+ fRPCRunning = false;
+
+ // First, cancel all timers and acceptors
+ // This is not done automatically by ->stop(), and in some cases the destructor of
+ // boost::asio::io_service can hang if this is skipped.
+ boost::system::error_code ec;
+ BOOST_FOREACH(const boost::shared_ptr<ip::tcp::acceptor> &acceptor, rpc_acceptors)
+ {
+ acceptor->cancel(ec);
+ if (ec)
+ LogPrintf("%s: Warning: %s when cancelling acceptor\n", __func__, ec.message());
+ }
+ rpc_acceptors.clear();
+ BOOST_FOREACH(const PAIRTYPE(std::string, boost::shared_ptr<deadline_timer>) &timer, deadlineTimers)
+ {
+ timer.second->cancel(ec);
+ if (ec)
+ LogPrintf("%s: Warning: %s when cancelling timer\n", __func__, ec.message());
+ }
+ deadlineTimers.clear();
+
+ rpc_io_service->stop();
+ g_rpcSignals.Stopped();
+ if (rpc_worker_group != NULL)
+ rpc_worker_group->join_all();
+ delete rpc_dummy_work; rpc_dummy_work = NULL;
+ delete rpc_worker_group; rpc_worker_group = NULL;
+ delete rpc_ssl_context; rpc_ssl_context = NULL;
+ delete rpc_io_service; rpc_io_service = NULL;
+}
+
+bool IsRPCRunning()
+{
+ return fRPCRunning;
+}
+
+void SetRPCWarmupStatus(const std::string& newStatus)
+{
+ LOCK(cs_rpcWarmup);
+ rpcWarmupStatus = newStatus;
+}
+
+void SetRPCWarmupFinished()
+{
+ LOCK(cs_rpcWarmup);
+ assert(fRPCInWarmup);
+ fRPCInWarmup = false;
+}
+
+bool RPCIsInWarmup(std::string *outStatus)
+{
+ LOCK(cs_rpcWarmup);
+ if (outStatus)
+ *outStatus = rpcWarmupStatus;
+ return fRPCInWarmup;
+}
+
+void RPCRunHandler(const boost::system::error_code& err, boost::function<void(void)> func)
+{
+ if (!err)
+ func();
+}
+
+void RPCRunLater(const std::string& name, boost::function<void(void)> func, int64_t nSeconds)
+{
+ assert(rpc_io_service != NULL);
+
+ if (deadlineTimers.count(name) == 0)
+ {
+ deadlineTimers.insert(make_pair(name,
+ boost::shared_ptr<deadline_timer>(new deadline_timer(*rpc_io_service))));
+ }
+ deadlineTimers[name]->expires_from_now(boost::posix_time::seconds(nSeconds));
+ deadlineTimers[name]->async_wait(boost::bind(RPCRunHandler, _1, func));
+}
+
+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(RPC_INVALID_REQUEST, "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(RPC_INVALID_REQUEST, "Missing method");
+ if (valMethod.type() != str_type)
+ throw JSONRPCError(RPC_INVALID_REQUEST, "Method must be a string");
+ strMethod = valMethod.get_str();
+ if (strMethod != "getblocktemplate")
+ LogPrint("rpc", "ThreadRPCServer method=%s\n", SanitizeString(strMethod));
+
+ // 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(RPC_INVALID_REQUEST, "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 (const Object& objError)
+ {
+ rpc_result = JSONRPCReplyObj(Value::null, objError, jreq.id);
+ }
+ catch (const std::exception& e)
+ {
+ rpc_result = JSONRPCReplyObj(Value::null,
+ JSONRPCError(RPC_PARSE_ERROR, 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 bool HTTPReq_JSONRPC(AcceptedConnection *conn,
+ string& strRequest,
+ map<string, string>& mapHeaders,
+ bool fRun)
+{
+ // Check authorization
+ if (mapHeaders.count("authorization") == 0)
+ {
+ conn->stream() << HTTPError(HTTP_UNAUTHORIZED, false) << std::flush;
+ return false;
+ }
+
+ if (!HTTPAuthorized(mapHeaders))
+ {
+ LogPrintf("ThreadRPCServer incorrect password attempt from %s\n", conn->peer_address_to_string());
+ /* Deter brute-forcing
+ We don't support exposing the RPC port, so this shouldn't result
+ in a DoS. */
+ MilliSleep(250);
+
+ conn->stream() << HTTPError(HTTP_UNAUTHORIZED, false) << std::flush;
+ return false;
+ }
+
+ JSONRequest jreq;
+ try
+ {
+ // Parse request
+ Value valRequest;
+ if (!read_string(strRequest, valRequest))
+ throw JSONRPCError(RPC_PARSE_ERROR, "Parse error");
+
+ // Return immediately if in warmup
+ {
+ LOCK(cs_rpcWarmup);
+ if (fRPCInWarmup)
+ throw JSONRPCError(RPC_IN_WARMUP, rpcWarmupStatus);
+ }
+
+ 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(RPC_PARSE_ERROR, "Top-level object parse error");
+
+ conn->stream() << HTTPReplyHeader(HTTP_OK, fRun, strReply.size()) << strReply << std::flush;
+ }
+ catch (const Object& objError)
+ {
+ ErrorReply(conn->stream(), objError, jreq.id);
+ return false;
+ }
+ catch (const std::exception& e)
+ {
+ ErrorReply(conn->stream(), JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id);
+ return false;
+ }
+ return true;
+}
+
+void ServiceConnection(AcceptedConnection *conn)
+{
+ bool fRun = true;
+ while (fRun && !ShutdownRequested())
+ {
+ int nProto = 0;
+ map<string, string> mapHeaders;
+ string strRequest, strMethod, strURI;
+
+ // Read HTTP request line
+ if (!ReadHTTPRequestLine(conn->stream(), nProto, strMethod, strURI))
+ break;
+
+ // Read HTTP message headers and body
+ ReadHTTPMessage(conn->stream(), mapHeaders, strRequest, nProto, MAX_SIZE);
+
+ // HTTP Keep-Alive is false; close connection immediately
+ if ((mapHeaders["connection"] == "close") || (!GetBoolArg("-rpckeepalive", true)))
+ fRun = false;
+
+ // Process via JSON-RPC API
+ if (strURI == "/") {
+ if (!HTTPReq_JSONRPC(conn, strRequest, mapHeaders, fRun))
+ break;
+
+ // Process via HTTP REST API
+ } else if (strURI.substr(0, 6) == "/rest/" && GetBoolArg("-rest", false)) {
+ if (!HTTPReq_REST(conn, strURI, strRequest, mapHeaders, fRun))
+ break;
+
+ } else {
+ conn->stream() << HTTPError(HTTP_NOT_FOUND, false) << std::flush;
+ break;
+ }
+ }
+}
+
+json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_spirit::Array &params) const
+{
+ // Find method
+ const CRPCCommand *pcmd = tableRPC[strMethod];
+ if (!pcmd)
+ throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found");
+
+ g_rpcSignals.PreCommand(*pcmd);
+
+ try
+ {
+ // Execute
+ return pcmd->actor(params, false);
+ }
+ catch (const std::exception& e)
+ {
+ throw JSONRPCError(RPC_MISC_ERROR, e.what());
+ }
+
+ g_rpcSignals.PostCommand(*pcmd);
+}
+
+std::string HelpExampleCli(string methodname, string args){
+ return "> bitcoin-cli " + methodname + " " + args + "\n";
+}
+
+std::string HelpExampleRpc(string methodname, string args){
+ return "> curl --user myusername --data-binary '{\"jsonrpc\": \"1.0\", \"id\":\"curltest\", "
+ "\"method\": \"" + methodname + "\", \"params\": [" + args + "] }' -H 'content-type: text/plain;' http://127.0.0.1:8332/\n";
+}
+
+const CRPCTable tableRPC;
diff --git a/src/rpcserver.h b/src/rpcserver.h
new file mode 100644
index 0000000000..30a5b28db7
--- /dev/null
+++ b/src/rpcserver.h
@@ -0,0 +1,246 @@
+// Copyright (c) 2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_RPCSERVER_H
+#define BITCOIN_RPCSERVER_H
+
+#include "amount.h"
+#include "rpcprotocol.h"
+#include "uint256.h"
+
+#include <list>
+#include <map>
+#include <stdint.h>
+#include <string>
+
+#include "json/json_spirit_reader_template.h"
+#include "json/json_spirit_utils.h"
+#include "json/json_spirit_writer_template.h"
+
+class CRPCCommand;
+
+namespace RPCServer
+{
+ void OnStarted(boost::function<void ()> slot);
+ void OnStopped(boost::function<void ()> slot);
+ void OnPreCommand(boost::function<void (const CRPCCommand&)> slot);
+ void OnPostCommand(boost::function<void (const CRPCCommand&)> slot);
+}
+
+class CBlockIndex;
+class CNetAddr;
+
+class AcceptedConnection
+{
+public:
+ virtual ~AcceptedConnection() {}
+
+ virtual std::iostream& stream() = 0;
+ virtual std::string peer_address_to_string() const = 0;
+ virtual void close() = 0;
+};
+
+/** Start RPC threads */
+void StartRPCThreads();
+/**
+ * Alternative to StartRPCThreads for the GUI, when no server is
+ * used. The RPC thread in this case is only used to handle timeouts.
+ * If real RPC threads have already been started this is a no-op.
+ */
+void StartDummyRPCThread();
+/** Stop RPC threads */
+void StopRPCThreads();
+/** Query whether RPC is running */
+bool IsRPCRunning();
+
+/**
+ * Set the RPC warmup status. When this is done, all RPC calls will error out
+ * immediately with RPC_IN_WARMUP.
+ */
+void SetRPCWarmupStatus(const std::string& newStatus);
+/* Mark warmup as done. RPC calls will be processed from now on. */
+void SetRPCWarmupFinished();
+
+/* returns the current warmup state. */
+bool RPCIsInWarmup(std::string *statusOut);
+
+/**
+ * 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<json_spirit::Value_type>& typesExpected, bool fAllowNull=false);
+/**
+ * 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<std::string, json_spirit::Value_type>& typesExpected, bool fAllowNull=false);
+
+/**
+ * Run func nSeconds from now. Uses boost deadline timers.
+ * Overrides previous timer <name> (if any).
+ */
+void RPCRunLater(const std::string& name, boost::function<void(void)> func, int64_t nSeconds);
+
+//! Convert boost::asio address to CNetAddr
+extern CNetAddr BoostAsioToCNetAddr(boost::asio::ip::address address);
+
+typedef json_spirit::Value(*rpcfn_type)(const json_spirit::Array& params, bool fHelp);
+
+class CRPCCommand
+{
+public:
+ std::string category;
+ std::string name;
+ rpcfn_type actor;
+ bool okSafeMode;
+};
+
+/**
+ * Bitcoin RPC command dispatcher.
+ */
+class CRPCTable
+{
+private:
+ std::map<std::string, const CRPCCommand*> 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 &params) const;
+};
+
+extern const CRPCTable tableRPC;
+
+/**
+ * Utilities: convert hex-encoded Values
+ * (throws error if not hex).
+ */
+extern uint256 ParseHashV(const json_spirit::Value& v, std::string strName);
+extern uint256 ParseHashO(const json_spirit::Object& o, std::string strKey);
+extern std::vector<unsigned char> ParseHexV(const json_spirit::Value& v, std::string strName);
+extern std::vector<unsigned char> ParseHexO(const json_spirit::Object& o, std::string strKey);
+
+extern void InitRPCMining();
+extern void ShutdownRPCMining();
+
+extern int64_t nWalletUnlockTime;
+extern CAmount AmountFromValue(const json_spirit::Value& value);
+extern json_spirit::Value ValueFromAmount(const CAmount& amount);
+extern double GetDifficulty(const CBlockIndex* blockindex = NULL);
+extern std::string HelpRequiringPassphrase();
+extern std::string HelpExampleCli(std::string methodname, std::string args);
+extern std::string HelpExampleRpc(std::string methodname, std::string args);
+
+extern void EnsureWalletIsUnlocked();
+
+extern json_spirit::Value getconnectioncount(const json_spirit::Array& params, bool fHelp); // in rpcnet.cpp
+extern json_spirit::Value getpeerinfo(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value ping(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value addnode(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value getaddednodeinfo(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value getnettotals(const json_spirit::Array& params, bool fHelp);
+
+extern json_spirit::Value dumpprivkey(const json_spirit::Array& params, bool fHelp); // in rpcdump.cpp
+extern json_spirit::Value importprivkey(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value importaddress(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value dumpwallet(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value importwallet(const json_spirit::Array& params, bool fHelp);
+
+extern json_spirit::Value getgenerate(const json_spirit::Array& params, bool fHelp); // in rpcmining.cpp
+extern json_spirit::Value setgenerate(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value generate(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value getnetworkhashps(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value getmininginfo(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value prioritisetransaction(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value getblocktemplate(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value submitblock(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value estimatefee(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value estimatepriority(const json_spirit::Array& params, bool fHelp);
+
+extern json_spirit::Value getnewaddress(const json_spirit::Array& params, bool fHelp); // in rpcwallet.cpp
+extern json_spirit::Value getaccountaddress(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value getrawchangeaddress(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value setaccount(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value getaccount(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value getaddressesbyaccount(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value sendtoaddress(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value signmessage(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value verifymessage(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value getreceivedbyaddress(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value getreceivedbyaccount(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value getbalance(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value getunconfirmedbalance(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value movecmd(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value sendfrom(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value sendmany(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value addmultisigaddress(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value createmultisig(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value listreceivedbyaddress(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value listreceivedbyaccount(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value listtransactions(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value listaddressgroupings(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value listaccounts(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value listsinceblock(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value gettransaction(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value backupwallet(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value keypoolrefill(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value walletpassphrase(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value walletpassphrasechange(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value walletlock(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value encryptwallet(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value validateaddress(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value getinfo(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value getwalletinfo(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value getblockchaininfo(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value getnetworkinfo(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value setmocktime(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value resendwallettransactions(const json_spirit::Array& params, bool fHelp);
+
+extern json_spirit::Value getrawtransaction(const json_spirit::Array& params, bool fHelp); // in rcprawtransaction.cpp
+extern json_spirit::Value listunspent(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value lockunspent(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value listlockunspent(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value createrawtransaction(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value decoderawtransaction(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value decodescript(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value signrawtransaction(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value sendrawtransaction(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value gettxoutproof(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value verifytxoutproof(const json_spirit::Array& params, bool fHelp);
+
+extern json_spirit::Value getblockcount(const json_spirit::Array& params, bool fHelp); // in rpcblockchain.cpp
+extern json_spirit::Value getbestblockhash(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value getdifficulty(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value settxfee(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value getmempoolinfo(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value getrawmempool(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value getblockhash(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value getblock(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value gettxoutsetinfo(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value gettxout(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value verifychain(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value getchaintips(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value invalidateblock(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value reconsiderblock(const json_spirit::Array& params, bool fHelp);
+
+// in rest.cpp
+extern bool HTTPReq_REST(AcceptedConnection *conn,
+ const std::string& strURI,
+ const std::string& strRequest,
+ const std::map<std::string, std::string>& mapHeaders,
+ bool fRun);
+
+#endif // BITCOIN_RPCSERVER_H
diff --git a/src/scheduler.cpp b/src/scheduler.cpp
new file mode 100644
index 0000000000..184ddc28ab
--- /dev/null
+++ b/src/scheduler.cpp
@@ -0,0 +1,131 @@
+// Copyright (c) 2015 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "scheduler.h"
+
+#include "reverselock.h"
+
+#include <assert.h>
+#include <boost/bind.hpp>
+#include <utility>
+
+CScheduler::CScheduler() : nThreadsServicingQueue(0), stopRequested(false), stopWhenEmpty(false)
+{
+}
+
+CScheduler::~CScheduler()
+{
+ assert(nThreadsServicingQueue == 0);
+}
+
+
+#if BOOST_VERSION < 105000
+static boost::system_time toPosixTime(const boost::chrono::system_clock::time_point& t)
+{
+ return boost::posix_time::from_time_t(boost::chrono::system_clock::to_time_t(t));
+}
+#endif
+
+void CScheduler::serviceQueue()
+{
+ boost::unique_lock<boost::mutex> lock(newTaskMutex);
+ ++nThreadsServicingQueue;
+
+ // newTaskMutex is locked throughout this loop EXCEPT
+ // when the thread is waiting or when the user's function
+ // is called.
+ while (!shouldStop()) {
+ try {
+ while (!shouldStop() && taskQueue.empty()) {
+ // Wait until there is something to do.
+ newTaskScheduled.wait(lock);
+ }
+
+ // Wait until either there is a new task, or until
+ // the time of the first item on the queue:
+
+// wait_until needs boost 1.50 or later; older versions have timed_wait:
+#if BOOST_VERSION < 105000
+ while (!shouldStop() && !taskQueue.empty() &&
+ newTaskScheduled.timed_wait(lock, toPosixTime(taskQueue.begin()->first))) {
+ // Keep waiting until timeout
+ }
+#else
+ // Some boost versions have a conflicting overload of wait_until that returns void.
+ // Explicitly use a template here to avoid hitting that overload.
+ while (!shouldStop() && !taskQueue.empty() &&
+ newTaskScheduled.wait_until<>(lock, taskQueue.begin()->first) != boost::cv_status::timeout) {
+ // Keep waiting until timeout
+ }
+#endif
+ // If there are multiple threads, the queue can empty while we're waiting (another
+ // thread may service the task we were waiting on).
+ if (shouldStop() || taskQueue.empty())
+ continue;
+
+ Function f = taskQueue.begin()->second;
+ taskQueue.erase(taskQueue.begin());
+
+ {
+ // Unlock before calling f, so it can reschedule itself or another task
+ // without deadlocking:
+ reverse_lock<boost::unique_lock<boost::mutex> > rlock(lock);
+ f();
+ }
+ } catch (...) {
+ --nThreadsServicingQueue;
+ throw;
+ }
+ }
+ --nThreadsServicingQueue;
+}
+
+void CScheduler::stop(bool drain)
+{
+ {
+ boost::unique_lock<boost::mutex> lock(newTaskMutex);
+ if (drain)
+ stopWhenEmpty = true;
+ else
+ stopRequested = true;
+ }
+ newTaskScheduled.notify_all();
+}
+
+void CScheduler::schedule(CScheduler::Function f, boost::chrono::system_clock::time_point t)
+{
+ {
+ boost::unique_lock<boost::mutex> lock(newTaskMutex);
+ taskQueue.insert(std::make_pair(t, f));
+ }
+ newTaskScheduled.notify_one();
+}
+
+void CScheduler::scheduleFromNow(CScheduler::Function f, int64_t deltaSeconds)
+{
+ schedule(f, boost::chrono::system_clock::now() + boost::chrono::seconds(deltaSeconds));
+}
+
+static void Repeat(CScheduler* s, CScheduler::Function f, int64_t deltaSeconds)
+{
+ f();
+ s->scheduleFromNow(boost::bind(&Repeat, s, f, deltaSeconds), deltaSeconds);
+}
+
+void CScheduler::scheduleEvery(CScheduler::Function f, int64_t deltaSeconds)
+{
+ scheduleFromNow(boost::bind(&Repeat, this, f, deltaSeconds), deltaSeconds);
+}
+
+size_t CScheduler::getQueueInfo(boost::chrono::system_clock::time_point &first,
+ boost::chrono::system_clock::time_point &last) const
+{
+ boost::unique_lock<boost::mutex> lock(newTaskMutex);
+ size_t result = taskQueue.size();
+ if (!taskQueue.empty()) {
+ first = taskQueue.begin()->first;
+ last = taskQueue.rbegin()->first;
+ }
+ return result;
+}
diff --git a/src/scheduler.h b/src/scheduler.h
new file mode 100644
index 0000000000..436659e58b
--- /dev/null
+++ b/src/scheduler.h
@@ -0,0 +1,83 @@
+// Copyright (c) 2015 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_SCHEDULER_H
+#define BITCOIN_SCHEDULER_H
+
+//
+// NOTE:
+// boost::thread / boost::function / boost::chrono should be ported to
+// std::thread / std::function / std::chrono when we support C++11.
+//
+#include <boost/function.hpp>
+#include <boost/chrono/chrono.hpp>
+#include <boost/thread.hpp>
+#include <map>
+
+//
+// Simple class for background tasks that should be run
+// periodically or once "after a while"
+//
+// Usage:
+//
+// CScheduler* s = new CScheduler();
+// s->scheduleFromNow(doSomething, 11); // Assuming a: void doSomething() { }
+// s->scheduleFromNow(boost::bind(Class::func, this, argument), 3);
+// boost::thread* t = new boost::thread(boost::bind(CScheduler::serviceQueue, s));
+//
+// ... then at program shutdown, clean up the thread running serviceQueue:
+// t->interrupt();
+// t->join();
+// delete t;
+// delete s; // Must be done after thread is interrupted/joined.
+//
+
+class CScheduler
+{
+public:
+ CScheduler();
+ ~CScheduler();
+
+ typedef boost::function<void(void)> Function;
+
+ // Call func at/after time t
+ void schedule(Function f, boost::chrono::system_clock::time_point t);
+
+ // Convenience method: call f once deltaSeconds from now
+ void scheduleFromNow(Function f, int64_t deltaSeconds);
+
+ // Another convenience method: call f approximately
+ // every deltaSeconds forever, starting deltaSeconds from now.
+ // To be more precise: every time f is finished, it
+ // is rescheduled to run deltaSeconds later. If you
+ // need more accurate scheduling, don't use this method.
+ void scheduleEvery(Function f, int64_t deltaSeconds);
+
+ // To keep things as simple as possible, there is no unschedule.
+
+ // Services the queue 'forever'. Should be run in a thread,
+ // and interrupted using boost::interrupt_thread
+ void serviceQueue();
+
+ // Tell any threads running serviceQueue to stop as soon as they're
+ // done servicing whatever task they're currently servicing (drain=false)
+ // or when there is no work left to be done (drain=true)
+ void stop(bool drain=false);
+
+ // Returns number of tasks waiting to be serviced,
+ // and first and last task times
+ size_t getQueueInfo(boost::chrono::system_clock::time_point &first,
+ boost::chrono::system_clock::time_point &last) const;
+
+private:
+ std::multimap<boost::chrono::system_clock::time_point, Function> taskQueue;
+ boost::condition_variable newTaskScheduled;
+ mutable boost::mutex newTaskMutex;
+ int nThreadsServicingQueue;
+ bool stopRequested;
+ bool stopWhenEmpty;
+ bool shouldStop() { return stopRequested || (stopWhenEmpty && taskQueue.empty()); }
+};
+
+#endif
diff --git a/src/script/bitcoinconsensus.cpp b/src/script/bitcoinconsensus.cpp
new file mode 100644
index 0000000000..b0d5faaf77
--- /dev/null
+++ b/src/script/bitcoinconsensus.cpp
@@ -0,0 +1,91 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "bitcoinconsensus.h"
+
+#include "primitives/transaction.h"
+#include "script/interpreter.h"
+#include "version.h"
+
+namespace {
+
+/** A class that deserializes a single CTransaction one time. */
+class TxInputStream
+{
+public:
+ TxInputStream(int nTypeIn, int nVersionIn, const unsigned char *txTo, size_t txToLen) :
+ m_type(nTypeIn),
+ m_version(nVersionIn),
+ m_data(txTo),
+ m_remaining(txToLen)
+ {}
+
+ TxInputStream& read(char* pch, size_t nSize)
+ {
+ if (nSize > m_remaining)
+ throw std::ios_base::failure(std::string(__func__) + ": end of data");
+
+ if (pch == NULL)
+ throw std::ios_base::failure(std::string(__func__) + ": bad destination buffer");
+
+ if (m_data == NULL)
+ throw std::ios_base::failure(std::string(__func__) + ": bad source buffer");
+
+ memcpy(pch, m_data, nSize);
+ m_remaining -= nSize;
+ m_data += nSize;
+ return *this;
+ }
+
+ template<typename T>
+ TxInputStream& operator>>(T& obj)
+ {
+ ::Unserialize(*this, obj, m_type, m_version);
+ return *this;
+ }
+
+private:
+ const int m_type;
+ const int m_version;
+ const unsigned char* m_data;
+ size_t m_remaining;
+};
+
+inline int set_error(bitcoinconsensus_error* ret, bitcoinconsensus_error serror)
+{
+ if (ret)
+ *ret = serror;
+ return 0;
+}
+
+} // anon namespace
+
+int bitcoinconsensus_verify_script(const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen,
+ const unsigned char *txTo , unsigned int txToLen,
+ unsigned int nIn, unsigned int flags, bitcoinconsensus_error* err)
+{
+ try {
+ TxInputStream stream(SER_NETWORK, PROTOCOL_VERSION, txTo, txToLen);
+ CTransaction tx;
+ stream >> tx;
+ if (nIn >= tx.vin.size())
+ return set_error(err, bitcoinconsensus_ERR_TX_INDEX);
+ if (tx.GetSerializeSize(SER_NETWORK, PROTOCOL_VERSION) != txToLen)
+ return set_error(err, bitcoinconsensus_ERR_TX_SIZE_MISMATCH);
+
+ // Regardless of the verification result, the tx did not error.
+ set_error(err, bitcoinconsensus_ERR_OK);
+
+ return VerifyScript(tx.vin[nIn].scriptSig, CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), flags, TransactionSignatureChecker(&tx, nIn), NULL);
+ } catch (const std::exception&) {
+ return set_error(err, bitcoinconsensus_ERR_TX_DESERIALIZE); // Error deserializing
+ }
+}
+
+unsigned int bitcoinconsensus_version()
+{
+ // Just use the API version for now
+ return BITCOINCONSENSUS_API_VER;
+}
diff --git a/src/script/bitcoinconsensus.h b/src/script/bitcoinconsensus.h
new file mode 100644
index 0000000000..a48ff1e18d
--- /dev/null
+++ b/src/script/bitcoinconsensus.h
@@ -0,0 +1,69 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_BITCOINCONSENSUS_H
+#define BITCOIN_BITCOINCONSENSUS_H
+
+#if defined(BUILD_BITCOIN_INTERNAL) && defined(HAVE_CONFIG_H)
+#include "config/bitcoin-config.h"
+ #if defined(_WIN32)
+ #if defined(DLL_EXPORT)
+ #if defined(HAVE_FUNC_ATTRIBUTE_DLLEXPORT)
+ #define EXPORT_SYMBOL __declspec(dllexport)
+ #else
+ #define EXPORT_SYMBOL
+ #endif
+ #endif
+ #elif defined(HAVE_FUNC_ATTRIBUTE_VISIBILITY)
+ #define EXPORT_SYMBOL __attribute__ ((visibility ("default")))
+ #endif
+#elif defined(MSC_VER) && !defined(STATIC_LIBBITCOINCONSENSUS)
+ #define EXPORT_SYMBOL __declspec(dllimport)
+#endif
+
+#ifndef EXPORT_SYMBOL
+ #define EXPORT_SYMBOL
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define BITCOINCONSENSUS_API_VER 0
+
+typedef enum bitcoinconsensus_error_t
+{
+ bitcoinconsensus_ERR_OK = 0,
+ bitcoinconsensus_ERR_TX_INDEX,
+ bitcoinconsensus_ERR_TX_SIZE_MISMATCH,
+ bitcoinconsensus_ERR_TX_DESERIALIZE,
+} bitcoinconsensus_error;
+
+/** Script verification flags */
+enum
+{
+ bitcoinconsensus_SCRIPT_FLAGS_VERIFY_NONE = 0,
+ bitcoinconsensus_SCRIPT_FLAGS_VERIFY_P2SH = (1U << 0), // evaluate P2SH (BIP16) subscripts
+ bitcoinconsensus_SCRIPT_FLAGS_VERIFY_DERSIG = (1U << 2), // enforce strict DER (BIP66) compliance
+ bitcoinconsensus_SCRIPT_FLAGS_VERIFY_CHECKLOCKTIMEVERIFY = (1U << 9), // enable CHECKLOCKTIMEVERIFY (BIP65)
+};
+
+/// Returns 1 if the input nIn of the serialized transaction pointed to by
+/// txTo correctly spends the scriptPubKey pointed to by scriptPubKey under
+/// the additional constraints specified by flags.
+/// If not NULL, err will contain an error/success code for the operation
+EXPORT_SYMBOL int bitcoinconsensus_verify_script(const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen,
+ const unsigned char *txTo , unsigned int txToLen,
+ unsigned int nIn, unsigned int flags, bitcoinconsensus_error* err);
+
+EXPORT_SYMBOL unsigned int bitcoinconsensus_version();
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#undef EXPORT_SYMBOL
+
+#endif // BITCOIN_BITCOINCONSENSUS_H
diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp
new file mode 100644
index 0000000000..0b78fdf5a8
--- /dev/null
+++ b/src/script/interpreter.cpp
@@ -0,0 +1,1229 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "interpreter.h"
+
+#include "primitives/transaction.h"
+#include "crypto/ripemd160.h"
+#include "crypto/sha1.h"
+#include "crypto/sha256.h"
+#include "eccryptoverify.h"
+#include "pubkey.h"
+#include "script/script.h"
+#include "uint256.h"
+
+using namespace std;
+
+typedef vector<unsigned char> valtype;
+
+namespace {
+
+inline bool set_success(ScriptError* ret)
+{
+ if (ret)
+ *ret = SCRIPT_ERR_OK;
+ return true;
+}
+
+inline bool set_error(ScriptError* ret, const ScriptError serror)
+{
+ if (ret)
+ *ret = serror;
+ return false;
+}
+
+} // anon namespace
+
+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;
+}
+
+/**
+ * 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<valtype>& stack)
+{
+ if (stack.empty())
+ throw runtime_error("popstack(): stack empty");
+ stack.pop_back();
+}
+
+bool static IsCompressedOrUncompressedPubKey(const valtype &vchPubKey) {
+ if (vchPubKey.size() < 33) {
+ // Non-canonical public key: too short
+ return false;
+ }
+ if (vchPubKey[0] == 0x04) {
+ if (vchPubKey.size() != 65) {
+ // Non-canonical public key: invalid length for uncompressed key
+ return false;
+ }
+ } else if (vchPubKey[0] == 0x02 || vchPubKey[0] == 0x03) {
+ if (vchPubKey.size() != 33) {
+ // Non-canonical public key: invalid length for compressed key
+ return false;
+ }
+ } else {
+ // Non-canonical public key: neither compressed nor uncompressed
+ return false;
+ }
+ return true;
+}
+
+/**
+ * A canonical signature exists of: <30> <total len> <02> <len R> <R> <02> <len S> <S> <hashtype>
+ * Where R and S are not negative (their first byte has its highest bit not set), and not
+ * excessively padded (do not start with a 0 byte, unless an otherwise negative number follows,
+ * in which case a single 0 byte is necessary and even required).
+ *
+ * See https://bitcointalk.org/index.php?topic=8392.msg127623#msg127623
+ *
+ * This function is consensus-critical since BIP66.
+ */
+bool static IsValidSignatureEncoding(const std::vector<unsigned char> &sig) {
+ // Format: 0x30 [total-length] 0x02 [R-length] [R] 0x02 [S-length] [S] [sighash]
+ // * total-length: 1-byte length descriptor of everything that follows,
+ // excluding the sighash byte.
+ // * R-length: 1-byte length descriptor of the R value that follows.
+ // * R: arbitrary-length big-endian encoded R value. It must use the shortest
+ // possible encoding for a positive integers (which means no null bytes at
+ // the start, except a single one when the next byte has its highest bit set).
+ // * S-length: 1-byte length descriptor of the S value that follows.
+ // * S: arbitrary-length big-endian encoded S value. The same rules apply.
+ // * sighash: 1-byte value indicating what data is hashed (not part of the DER
+ // signature)
+
+ // Minimum and maximum size constraints.
+ if (sig.size() < 9) return false;
+ if (sig.size() > 73) return false;
+
+ // A signature is of type 0x30 (compound).
+ if (sig[0] != 0x30) return false;
+
+ // Make sure the length covers the entire signature.
+ if (sig[1] != sig.size() - 3) return false;
+
+ // Extract the length of the R element.
+ unsigned int lenR = sig[3];
+
+ // Make sure the length of the S element is still inside the signature.
+ if (5 + lenR >= sig.size()) return false;
+
+ // Extract the length of the S element.
+ unsigned int lenS = sig[5 + lenR];
+
+ // Verify that the length of the signature matches the sum of the length
+ // of the elements.
+ if ((size_t)(lenR + lenS + 7) != sig.size()) return false;
+
+ // Check whether the R element is an integer.
+ if (sig[2] != 0x02) return false;
+
+ // Zero-length integers are not allowed for R.
+ if (lenR == 0) return false;
+
+ // Negative numbers are not allowed for R.
+ if (sig[4] & 0x80) return false;
+
+ // Null bytes at the start of R are not allowed, unless R would
+ // otherwise be interpreted as a negative number.
+ if (lenR > 1 && (sig[4] == 0x00) && !(sig[5] & 0x80)) return false;
+
+ // Check whether the S element is an integer.
+ if (sig[lenR + 4] != 0x02) return false;
+
+ // Zero-length integers are not allowed for S.
+ if (lenS == 0) return false;
+
+ // Negative numbers are not allowed for S.
+ if (sig[lenR + 6] & 0x80) return false;
+
+ // Null bytes at the start of S are not allowed, unless S would otherwise be
+ // interpreted as a negative number.
+ if (lenS > 1 && (sig[lenR + 6] == 0x00) && !(sig[lenR + 7] & 0x80)) return false;
+
+ return true;
+}
+
+bool static IsLowDERSignature(const valtype &vchSig, ScriptError* serror) {
+ if (!IsValidSignatureEncoding(vchSig)) {
+ return set_error(serror, SCRIPT_ERR_SIG_DER);
+ }
+ unsigned int nLenR = vchSig[3];
+ unsigned int nLenS = vchSig[5+nLenR];
+ const unsigned char *S = &vchSig[6+nLenR];
+ // If the S value is above the order of the curve divided by two, its
+ // complement modulo the order could have been used instead, which is
+ // one byte shorter when encoded correctly.
+ if (!eccrypto::CheckSignatureElement(S, nLenS, true))
+ return set_error(serror, SCRIPT_ERR_SIG_HIGH_S);
+
+ return true;
+}
+
+bool static IsDefinedHashtypeSignature(const valtype &vchSig) {
+ if (vchSig.size() == 0) {
+ return false;
+ }
+ unsigned char nHashType = vchSig[vchSig.size() - 1] & (~(SIGHASH_ANYONECANPAY));
+ if (nHashType < SIGHASH_ALL || nHashType > SIGHASH_SINGLE)
+ return false;
+
+ return true;
+}
+
+bool static CheckSignatureEncoding(const valtype &vchSig, unsigned int flags, ScriptError* serror) {
+ // Empty signature. Not strictly DER encoded, but allowed to provide a
+ // compact way to provide an invalid signature for use with CHECK(MULTI)SIG
+ if (vchSig.size() == 0) {
+ return true;
+ }
+ if ((flags & (SCRIPT_VERIFY_DERSIG | SCRIPT_VERIFY_LOW_S | SCRIPT_VERIFY_STRICTENC)) != 0 && !IsValidSignatureEncoding(vchSig)) {
+ return set_error(serror, SCRIPT_ERR_SIG_DER);
+ } else if ((flags & SCRIPT_VERIFY_LOW_S) != 0 && !IsLowDERSignature(vchSig, serror)) {
+ // serror is set
+ return false;
+ } else if ((flags & SCRIPT_VERIFY_STRICTENC) != 0 && !IsDefinedHashtypeSignature(vchSig)) {
+ return set_error(serror, SCRIPT_ERR_SIG_HASHTYPE);
+ }
+ return true;
+}
+
+bool static CheckPubKeyEncoding(const valtype &vchSig, unsigned int flags, ScriptError* serror) {
+ if ((flags & SCRIPT_VERIFY_STRICTENC) != 0 && !IsCompressedOrUncompressedPubKey(vchSig)) {
+ return set_error(serror, SCRIPT_ERR_PUBKEYTYPE);
+ }
+ return true;
+}
+
+bool static CheckMinimalPush(const valtype& data, opcodetype opcode) {
+ if (data.size() == 0) {
+ // Could have used OP_0.
+ return opcode == OP_0;
+ } else if (data.size() == 1 && data[0] >= 1 && data[0] <= 16) {
+ // Could have used OP_1 .. OP_16.
+ return opcode == OP_1 + (data[0] - 1);
+ } else if (data.size() == 1 && data[0] == 0x81) {
+ // Could have used OP_1NEGATE.
+ return opcode == OP_1NEGATE;
+ } else if (data.size() <= 75) {
+ // Could have used a direct push (opcode indicating number of bytes pushed + those bytes).
+ return opcode == data.size();
+ } else if (data.size() <= 255) {
+ // Could have used OP_PUSHDATA.
+ return opcode == OP_PUSHDATA1;
+ } else if (data.size() <= 65535) {
+ // Could have used OP_PUSHDATA2.
+ return opcode == OP_PUSHDATA2;
+ }
+ return true;
+}
+
+bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror)
+{
+ static const CScriptNum bnZero(0);
+ static const CScriptNum bnOne(1);
+ static const CScriptNum bnFalse(0);
+ static const CScriptNum bnTrue(1);
+ static const valtype vchFalse(0);
+ static const valtype vchZero(0);
+ static const valtype vchTrue(1, 1);
+
+ CScript::const_iterator pc = script.begin();
+ CScript::const_iterator pend = script.end();
+ CScript::const_iterator pbegincodehash = script.begin();
+ opcodetype opcode;
+ valtype vchPushValue;
+ vector<bool> vfExec;
+ vector<valtype> altstack;
+ set_error(serror, SCRIPT_ERR_UNKNOWN_ERROR);
+ if (script.size() > 10000)
+ return set_error(serror, SCRIPT_ERR_SCRIPT_SIZE);
+ int nOpCount = 0;
+ bool fRequireMinimal = (flags & SCRIPT_VERIFY_MINIMALDATA) != 0;
+
+ try
+ {
+ while (pc < pend)
+ {
+ bool fExec = !count(vfExec.begin(), vfExec.end(), false);
+
+ //
+ // Read instruction
+ //
+ if (!script.GetOp(pc, opcode, vchPushValue))
+ return set_error(serror, SCRIPT_ERR_BAD_OPCODE);
+ if (vchPushValue.size() > MAX_SCRIPT_ELEMENT_SIZE)
+ return set_error(serror, SCRIPT_ERR_PUSH_SIZE);
+
+ // Note how OP_RESERVED does not count towards the opcode limit.
+ if (opcode > OP_16 && ++nOpCount > 201)
+ return set_error(serror, SCRIPT_ERR_OP_COUNT);
+
+ 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 set_error(serror, SCRIPT_ERR_DISABLED_OPCODE); // Disabled opcodes.
+
+ if (fExec && 0 <= opcode && opcode <= OP_PUSHDATA4) {
+ if (fRequireMinimal && !CheckMinimalPush(vchPushValue, opcode)) {
+ return set_error(serror, SCRIPT_ERR_MINIMALDATA);
+ }
+ 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)
+ CScriptNum bn((int)opcode - (int)(OP_1 - 1));
+ stack.push_back(bn.getvch());
+ // The result of these opcodes should always be the minimal way to push the data
+ // they push, so no need for a CheckMinimalPush here.
+ }
+ break;
+
+
+ //
+ // Control
+ //
+ case OP_NOP:
+ break;
+
+ case OP_CHECKLOCKTIMEVERIFY:
+ {
+ if (!(flags & SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY)) {
+ // not enabled; treat as a NOP2
+ if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) {
+ return set_error(serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS);
+ }
+ break;
+ }
+
+ if (stack.size() < 1)
+ return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
+
+ // Note that elsewhere numeric opcodes are limited to
+ // operands in the range -2**31+1 to 2**31-1, however it is
+ // legal for opcodes to produce results exceeding that
+ // range. This limitation is implemented by CScriptNum's
+ // default 4-byte limit.
+ //
+ // If we kept to that limit we'd have a year 2038 problem,
+ // even though the nLockTime field in transactions
+ // themselves is uint32 which only becomes meaningless
+ // after the year 2106.
+ //
+ // Thus as a special case we tell CScriptNum to accept up
+ // to 5-byte bignums, which are good until 2**39-1, well
+ // beyond the 2**32-1 limit of the nLockTime field itself.
+ const CScriptNum nLockTime(stacktop(-1), fRequireMinimal, 5);
+
+ // In the rare event that the argument may be < 0 due to
+ // some arithmetic being done first, you can always use
+ // 0 MAX CHECKLOCKTIMEVERIFY.
+ if (nLockTime < 0)
+ return set_error(serror, SCRIPT_ERR_NEGATIVE_LOCKTIME);
+
+ // Actually compare the specified lock time with the transaction.
+ if (!checker.CheckLockTime(nLockTime))
+ return set_error(serror, SCRIPT_ERR_UNSATISFIED_LOCKTIME);
+
+ break;
+ }
+
+ case OP_NOP1: case OP_NOP3: case OP_NOP4: case OP_NOP5:
+ case OP_NOP6: case OP_NOP7: case OP_NOP8: case OP_NOP9: case OP_NOP10:
+ {
+ if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS)
+ return set_error(serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS);
+ }
+ break;
+
+ case OP_IF:
+ case OP_NOTIF:
+ {
+ // <expression> if [statements] [else [statements]] endif
+ bool fValue = false;
+ if (fExec)
+ {
+ if (stack.size() < 1)
+ return set_error(serror, SCRIPT_ERR_UNBALANCED_CONDITIONAL);
+ 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 set_error(serror, SCRIPT_ERR_UNBALANCED_CONDITIONAL);
+ vfExec.back() = !vfExec.back();
+ }
+ break;
+
+ case OP_ENDIF:
+ {
+ if (vfExec.empty())
+ return set_error(serror, SCRIPT_ERR_UNBALANCED_CONDITIONAL);
+ vfExec.pop_back();
+ }
+ break;
+
+ case OP_VERIFY:
+ {
+ // (true -- ) or
+ // (false -- false) and return
+ if (stack.size() < 1)
+ return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
+ bool fValue = CastToBool(stacktop(-1));
+ if (fValue)
+ popstack(stack);
+ else
+ return set_error(serror, SCRIPT_ERR_VERIFY);
+ }
+ break;
+
+ case OP_RETURN:
+ {
+ return set_error(serror, SCRIPT_ERR_OP_RETURN);
+ }
+ break;
+
+
+ //
+ // Stack ops
+ //
+ case OP_TOALTSTACK:
+ {
+ if (stack.size() < 1)
+ return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
+ altstack.push_back(stacktop(-1));
+ popstack(stack);
+ }
+ break;
+
+ case OP_FROMALTSTACK:
+ {
+ if (altstack.size() < 1)
+ return set_error(serror, SCRIPT_ERR_INVALID_ALTSTACK_OPERATION);
+ stack.push_back(altstacktop(-1));
+ popstack(altstack);
+ }
+ break;
+
+ case OP_2DROP:
+ {
+ // (x1 x2 -- )
+ if (stack.size() < 2)
+ return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
+ popstack(stack);
+ popstack(stack);
+ }
+ break;
+
+ case OP_2DUP:
+ {
+ // (x1 x2 -- x1 x2 x1 x2)
+ if (stack.size() < 2)
+ return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
+ 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 set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
+ 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 set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
+ 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 set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
+ 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 set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
+ swap(stacktop(-4), stacktop(-2));
+ swap(stacktop(-3), stacktop(-1));
+ }
+ break;
+
+ case OP_IFDUP:
+ {
+ // (x - 0 | x x)
+ if (stack.size() < 1)
+ return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
+ valtype vch = stacktop(-1);
+ if (CastToBool(vch))
+ stack.push_back(vch);
+ }
+ break;
+
+ case OP_DEPTH:
+ {
+ // -- stacksize
+ CScriptNum bn(stack.size());
+ stack.push_back(bn.getvch());
+ }
+ break;
+
+ case OP_DROP:
+ {
+ // (x -- )
+ if (stack.size() < 1)
+ return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
+ popstack(stack);
+ }
+ break;
+
+ case OP_DUP:
+ {
+ // (x -- x x)
+ if (stack.size() < 1)
+ return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
+ valtype vch = stacktop(-1);
+ stack.push_back(vch);
+ }
+ break;
+
+ case OP_NIP:
+ {
+ // (x1 x2 -- x2)
+ if (stack.size() < 2)
+ return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
+ stack.erase(stack.end() - 2);
+ }
+ break;
+
+ case OP_OVER:
+ {
+ // (x1 x2 -- x1 x2 x1)
+ if (stack.size() < 2)
+ return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
+ 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 set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
+ int n = CScriptNum(stacktop(-1), fRequireMinimal).getint();
+ popstack(stack);
+ if (n < 0 || n >= (int)stack.size())
+ return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
+ 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 set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
+ swap(stacktop(-3), stacktop(-2));
+ swap(stacktop(-2), stacktop(-1));
+ }
+ break;
+
+ case OP_SWAP:
+ {
+ // (x1 x2 -- x2 x1)
+ if (stack.size() < 2)
+ return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
+ swap(stacktop(-2), stacktop(-1));
+ }
+ break;
+
+ case OP_TUCK:
+ {
+ // (x1 x2 -- x2 x1 x2)
+ if (stack.size() < 2)
+ return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
+ valtype vch = stacktop(-1);
+ stack.insert(stack.end()-2, vch);
+ }
+ break;
+
+
+ case OP_SIZE:
+ {
+ // (in -- in size)
+ if (stack.size() < 1)
+ return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
+ CScriptNum bn(stacktop(-1).size());
+ stack.push_back(bn.getvch());
+ }
+ break;
+
+
+ //
+ // Bitwise logic
+ //
+ case OP_EQUAL:
+ case OP_EQUALVERIFY:
+ //case OP_NOTEQUAL: // use OP_NUMNOTEQUAL
+ {
+ // (x1 x2 - bool)
+ if (stack.size() < 2)
+ return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
+ 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 set_error(serror, SCRIPT_ERR_EQUALVERIFY);
+ }
+ }
+ break;
+
+
+ //
+ // Numeric
+ //
+ case OP_1ADD:
+ case OP_1SUB:
+ case OP_NEGATE:
+ case OP_ABS:
+ case OP_NOT:
+ case OP_0NOTEQUAL:
+ {
+ // (in -- out)
+ if (stack.size() < 1)
+ return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
+ CScriptNum bn(stacktop(-1), fRequireMinimal);
+ switch (opcode)
+ {
+ case OP_1ADD: bn += bnOne; break;
+ case OP_1SUB: bn -= bnOne; 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_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 set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
+ CScriptNum bn1(stacktop(-2), fRequireMinimal);
+ CScriptNum bn2(stacktop(-1), fRequireMinimal);
+ CScriptNum bn(0);
+ switch (opcode)
+ {
+ case OP_ADD:
+ bn = bn1 + bn2;
+ break;
+
+ case OP_SUB:
+ bn = bn1 - bn2;
+ 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 set_error(serror, SCRIPT_ERR_NUMEQUALVERIFY);
+ }
+ }
+ break;
+
+ case OP_WITHIN:
+ {
+ // (x min max -- out)
+ if (stack.size() < 3)
+ return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
+ CScriptNum bn1(stacktop(-3), fRequireMinimal);
+ CScriptNum bn2(stacktop(-2), fRequireMinimal);
+ CScriptNum bn3(stacktop(-1), fRequireMinimal);
+ 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 set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
+ valtype& vch = stacktop(-1);
+ valtype vchHash((opcode == OP_RIPEMD160 || opcode == OP_SHA1 || opcode == OP_HASH160) ? 20 : 32);
+ if (opcode == OP_RIPEMD160)
+ CRIPEMD160().Write(begin_ptr(vch), vch.size()).Finalize(begin_ptr(vchHash));
+ else if (opcode == OP_SHA1)
+ CSHA1().Write(begin_ptr(vch), vch.size()).Finalize(begin_ptr(vchHash));
+ else if (opcode == OP_SHA256)
+ CSHA256().Write(begin_ptr(vch), vch.size()).Finalize(begin_ptr(vchHash));
+ else if (opcode == OP_HASH160)
+ CHash160().Write(begin_ptr(vch), vch.size()).Finalize(begin_ptr(vchHash));
+ else if (opcode == OP_HASH256)
+ CHash256().Write(begin_ptr(vch), vch.size()).Finalize(begin_ptr(vchHash));
+ 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 set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
+
+ valtype& vchSig = stacktop(-2);
+ valtype& vchPubKey = stacktop(-1);
+
+ // 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));
+
+ if (!CheckSignatureEncoding(vchSig, flags, serror) || !CheckPubKeyEncoding(vchPubKey, flags, serror)) {
+ //serror is set
+ return false;
+ }
+ bool fSuccess = checker.CheckSig(vchSig, vchPubKey, scriptCode);
+
+ popstack(stack);
+ popstack(stack);
+ stack.push_back(fSuccess ? vchTrue : vchFalse);
+ if (opcode == OP_CHECKSIGVERIFY)
+ {
+ if (fSuccess)
+ popstack(stack);
+ else
+ return set_error(serror, SCRIPT_ERR_CHECKSIGVERIFY);
+ }
+ }
+ 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 set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
+
+ int nKeysCount = CScriptNum(stacktop(-i), fRequireMinimal).getint();
+ if (nKeysCount < 0 || nKeysCount > 20)
+ return set_error(serror, SCRIPT_ERR_PUBKEY_COUNT);
+ nOpCount += nKeysCount;
+ if (nOpCount > 201)
+ return set_error(serror, SCRIPT_ERR_OP_COUNT);
+ int ikey = ++i;
+ i += nKeysCount;
+ if ((int)stack.size() < i)
+ return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
+
+ int nSigsCount = CScriptNum(stacktop(-i), fRequireMinimal).getint();
+ if (nSigsCount < 0 || nSigsCount > nKeysCount)
+ return set_error(serror, SCRIPT_ERR_SIG_COUNT);
+ int isig = ++i;
+ i += nSigsCount;
+ if ((int)stack.size() < i)
+ return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
+
+ // 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);
+
+ // Note how this makes the exact order of pubkey/signature evaluation
+ // distinguishable by CHECKMULTISIG NOT if the STRICTENC flag is set.
+ // See the script_(in)valid tests for details.
+ if (!CheckSignatureEncoding(vchSig, flags, serror) || !CheckPubKeyEncoding(vchPubKey, flags, serror)) {
+ // serror is set
+ return false;
+ }
+
+ // Check signature
+ bool fOk = checker.CheckSig(vchSig, vchPubKey, scriptCode);
+
+ if (fOk) {
+ isig++;
+ nSigsCount--;
+ }
+ ikey++;
+ nKeysCount--;
+
+ // If there are more signatures left than keys left,
+ // then too many signatures have failed. Exit early,
+ // without checking any further signatures.
+ if (nSigsCount > nKeysCount)
+ fSuccess = false;
+ }
+
+ // Clean up stack of actual arguments
+ while (i-- > 1)
+ popstack(stack);
+
+ // A bug causes CHECKMULTISIG to consume one extra argument
+ // whose contents were not checked in any way.
+ //
+ // Unfortunately this is a potential source of mutability,
+ // so optionally verify it is exactly equal to zero prior
+ // to removing it from the stack.
+ if (stack.size() < 1)
+ return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
+ if ((flags & SCRIPT_VERIFY_NULLDUMMY) && stacktop(-1).size())
+ return set_error(serror, SCRIPT_ERR_SIG_NULLDUMMY);
+ popstack(stack);
+
+ stack.push_back(fSuccess ? vchTrue : vchFalse);
+
+ if (opcode == OP_CHECKMULTISIGVERIFY)
+ {
+ if (fSuccess)
+ popstack(stack);
+ else
+ return set_error(serror, SCRIPT_ERR_CHECKMULTISIGVERIFY);
+ }
+ }
+ break;
+
+ default:
+ return set_error(serror, SCRIPT_ERR_BAD_OPCODE);
+ }
+
+ // Size limits
+ if (stack.size() + altstack.size() > 1000)
+ return set_error(serror, SCRIPT_ERR_STACK_SIZE);
+ }
+ }
+ catch (...)
+ {
+ return set_error(serror, SCRIPT_ERR_UNKNOWN_ERROR);
+ }
+
+ if (!vfExec.empty())
+ return set_error(serror, SCRIPT_ERR_UNBALANCED_CONDITIONAL);
+
+ return set_success(serror);
+}
+
+namespace {
+
+/**
+ * Wrapper that serializes like CTransaction, but with the modifications
+ * required for the signature hash done in-place
+ */
+class CTransactionSignatureSerializer {
+private:
+ const CTransaction &txTo; //! reference to the spending transaction (the one being serialized)
+ const CScript &scriptCode; //! output script being consumed
+ const unsigned int nIn; //! input index of txTo being signed
+ const bool fAnyoneCanPay; //! whether the hashtype has the SIGHASH_ANYONECANPAY flag set
+ const bool fHashSingle; //! whether the hashtype is SIGHASH_SINGLE
+ const bool fHashNone; //! whether the hashtype is SIGHASH_NONE
+
+public:
+ CTransactionSignatureSerializer(const CTransaction &txToIn, const CScript &scriptCodeIn, unsigned int nInIn, int nHashTypeIn) :
+ txTo(txToIn), scriptCode(scriptCodeIn), nIn(nInIn),
+ fAnyoneCanPay(!!(nHashTypeIn & SIGHASH_ANYONECANPAY)),
+ fHashSingle((nHashTypeIn & 0x1f) == SIGHASH_SINGLE),
+ fHashNone((nHashTypeIn & 0x1f) == SIGHASH_NONE) {}
+
+ /** Serialize the passed scriptCode, skipping OP_CODESEPARATORs */
+ template<typename S>
+ void SerializeScriptCode(S &s, int nType, int nVersion) const {
+ CScript::const_iterator it = scriptCode.begin();
+ CScript::const_iterator itBegin = it;
+ opcodetype opcode;
+ unsigned int nCodeSeparators = 0;
+ while (scriptCode.GetOp(it, opcode)) {
+ if (opcode == OP_CODESEPARATOR)
+ nCodeSeparators++;
+ }
+ ::WriteCompactSize(s, scriptCode.size() - nCodeSeparators);
+ it = itBegin;
+ while (scriptCode.GetOp(it, opcode)) {
+ if (opcode == OP_CODESEPARATOR) {
+ s.write((char*)&itBegin[0], it-itBegin-1);
+ itBegin = it;
+ }
+ }
+ if (itBegin != scriptCode.end())
+ s.write((char*)&itBegin[0], it-itBegin);
+ }
+
+ /** Serialize an input of txTo */
+ template<typename S>
+ void SerializeInput(S &s, unsigned int nInput, int nType, int nVersion) const {
+ // In case of SIGHASH_ANYONECANPAY, only the input being signed is serialized
+ if (fAnyoneCanPay)
+ nInput = nIn;
+ // Serialize the prevout
+ ::Serialize(s, txTo.vin[nInput].prevout, nType, nVersion);
+ // Serialize the script
+ if (nInput != nIn)
+ // Blank out other inputs' signatures
+ ::Serialize(s, CScript(), nType, nVersion);
+ else
+ SerializeScriptCode(s, nType, nVersion);
+ // Serialize the nSequence
+ if (nInput != nIn && (fHashSingle || fHashNone))
+ // let the others update at will
+ ::Serialize(s, (int)0, nType, nVersion);
+ else
+ ::Serialize(s, txTo.vin[nInput].nSequence, nType, nVersion);
+ }
+
+ /** Serialize an output of txTo */
+ template<typename S>
+ void SerializeOutput(S &s, unsigned int nOutput, int nType, int nVersion) const {
+ if (fHashSingle && nOutput != nIn)
+ // Do not lock-in the txout payee at other indices as txin
+ ::Serialize(s, CTxOut(), nType, nVersion);
+ else
+ ::Serialize(s, txTo.vout[nOutput], nType, nVersion);
+ }
+
+ /** Serialize txTo */
+ template<typename S>
+ void Serialize(S &s, int nType, int nVersion) const {
+ // Serialize nVersion
+ ::Serialize(s, txTo.nVersion, nType, nVersion);
+ // Serialize vin
+ unsigned int nInputs = fAnyoneCanPay ? 1 : txTo.vin.size();
+ ::WriteCompactSize(s, nInputs);
+ for (unsigned int nInput = 0; nInput < nInputs; nInput++)
+ SerializeInput(s, nInput, nType, nVersion);
+ // Serialize vout
+ unsigned int nOutputs = fHashNone ? 0 : (fHashSingle ? nIn+1 : txTo.vout.size());
+ ::WriteCompactSize(s, nOutputs);
+ for (unsigned int nOutput = 0; nOutput < nOutputs; nOutput++)
+ SerializeOutput(s, nOutput, nType, nVersion);
+ // Serialize nLockTime
+ ::Serialize(s, txTo.nLockTime, nType, nVersion);
+ }
+};
+
+} // anon namespace
+
+uint256 SignatureHash(const CScript& scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType)
+{
+ static const uint256 one(uint256S("0000000000000000000000000000000000000000000000000000000000000001"));
+ if (nIn >= txTo.vin.size()) {
+ // nIn out of range
+ return one;
+ }
+
+ // Check for invalid use of SIGHASH_SINGLE
+ if ((nHashType & 0x1f) == SIGHASH_SINGLE) {
+ if (nIn >= txTo.vout.size()) {
+ // nOut out of range
+ return one;
+ }
+ }
+
+ // Wrapper to serialize only the necessary parts of the transaction being signed
+ CTransactionSignatureSerializer txTmp(txTo, scriptCode, nIn, nHashType);
+
+ // Serialize and hash
+ CHashWriter ss(SER_GETHASH, 0);
+ ss << txTmp << nHashType;
+ return ss.GetHash();
+}
+
+bool TransactionSignatureChecker::VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& pubkey, const uint256& sighash) const
+{
+ return pubkey.Verify(sighash, vchSig);
+}
+
+bool TransactionSignatureChecker::CheckSig(const vector<unsigned char>& vchSigIn, const vector<unsigned char>& vchPubKey, const CScript& scriptCode) const
+{
+ CPubKey pubkey(vchPubKey);
+ if (!pubkey.IsValid())
+ return false;
+
+ // Hash type is one byte tacked on to the end of the signature
+ vector<unsigned char> vchSig(vchSigIn);
+ if (vchSig.empty())
+ return false;
+ int nHashType = vchSig.back();
+ vchSig.pop_back();
+
+ uint256 sighash = SignatureHash(scriptCode, *txTo, nIn, nHashType);
+
+ if (!VerifySignature(vchSig, pubkey, sighash))
+ return false;
+
+ return true;
+}
+
+bool TransactionSignatureChecker::CheckLockTime(const CScriptNum& nLockTime) const
+{
+ // There are two times of nLockTime: lock-by-blockheight
+ // and lock-by-blocktime, distinguished by whether
+ // nLockTime < LOCKTIME_THRESHOLD.
+ //
+ // We want to compare apples to apples, so fail the script
+ // unless the type of nLockTime being tested is the same as
+ // the nLockTime in the transaction.
+ if (!(
+ (txTo->nLockTime < LOCKTIME_THRESHOLD && nLockTime < LOCKTIME_THRESHOLD) ||
+ (txTo->nLockTime >= LOCKTIME_THRESHOLD && nLockTime >= LOCKTIME_THRESHOLD)
+ ))
+ return false;
+
+ // Now that we know we're comparing apples-to-apples, the
+ // comparison is a simple numeric one.
+ if (nLockTime > (int64_t)txTo->nLockTime)
+ return false;
+
+ // Finally the nLockTime feature can be disabled and thus
+ // CHECKLOCKTIMEVERIFY bypassed if every txin has been
+ // finalized by setting nSequence to maxint. The
+ // transaction would be allowed into the blockchain, making
+ // the opcode ineffective.
+ //
+ // Testing if this vin is not final is sufficient to
+ // prevent this condition. Alternatively we could test all
+ // inputs, but testing just this input minimizes the data
+ // required to prove correct CHECKLOCKTIMEVERIFY execution.
+ if (txTo->vin[nIn].IsFinal())
+ return false;
+
+ return true;
+}
+
+
+bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror)
+{
+ set_error(serror, SCRIPT_ERR_UNKNOWN_ERROR);
+
+ if ((flags & SCRIPT_VERIFY_SIGPUSHONLY) != 0 && !scriptSig.IsPushOnly()) {
+ return set_error(serror, SCRIPT_ERR_SIG_PUSHONLY);
+ }
+
+ vector<vector<unsigned char> > stack, stackCopy;
+ if (!EvalScript(stack, scriptSig, flags, checker, serror))
+ // serror is set
+ return false;
+ if (flags & SCRIPT_VERIFY_P2SH)
+ stackCopy = stack;
+ if (!EvalScript(stack, scriptPubKey, flags, checker, serror))
+ // serror is set
+ return false;
+ if (stack.empty())
+ return set_error(serror, SCRIPT_ERR_EVAL_FALSE);
+ if (CastToBool(stack.back()) == false)
+ return set_error(serror, SCRIPT_ERR_EVAL_FALSE);
+
+ // Additional validation for spend-to-script-hash transactions:
+ if ((flags & SCRIPT_VERIFY_P2SH) && scriptPubKey.IsPayToScriptHash())
+ {
+ // scriptSig must be literals-only or validation fails
+ if (!scriptSig.IsPushOnly())
+ return set_error(serror, SCRIPT_ERR_SIG_PUSHONLY);
+
+ // Restore stack.
+ swap(stack, stackCopy);
+
+ // stack cannot be empty here, because if it was the
+ // P2SH HASH <> EQUAL scriptPubKey would be evaluated with
+ // an empty stack and the EvalScript above would return false.
+ assert(!stack.empty());
+
+ const valtype& pubKeySerialized = stack.back();
+ CScript pubKey2(pubKeySerialized.begin(), pubKeySerialized.end());
+ popstack(stack);
+
+ if (!EvalScript(stack, pubKey2, flags, checker, serror))
+ // serror is set
+ return false;
+ if (stack.empty())
+ return set_error(serror, SCRIPT_ERR_EVAL_FALSE);
+ if (!CastToBool(stack.back()))
+ return set_error(serror, SCRIPT_ERR_EVAL_FALSE);
+ }
+
+ // The CLEANSTACK check is only performed after potential P2SH evaluation,
+ // as the non-P2SH evaluation of a P2SH script will obviously not result in
+ // a clean stack (the P2SH inputs remain).
+ if ((flags & SCRIPT_VERIFY_CLEANSTACK) != 0) {
+ // Disallow CLEANSTACK without P2SH, as otherwise a switch CLEANSTACK->P2SH+CLEANSTACK
+ // would be possible, which is not a softfork (and P2SH should be one).
+ assert((flags & SCRIPT_VERIFY_P2SH) != 0);
+ if (stack.size() != 1) {
+ return set_error(serror, SCRIPT_ERR_CLEANSTACK);
+ }
+ }
+
+ return set_success(serror);
+}
diff --git a/src/script/interpreter.h b/src/script/interpreter.h
new file mode 100644
index 0000000000..35d572f0ad
--- /dev/null
+++ b/src/script/interpreter.h
@@ -0,0 +1,131 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_SCRIPT_INTERPRETER_H
+#define BITCOIN_SCRIPT_INTERPRETER_H
+
+#include "script_error.h"
+#include "primitives/transaction.h"
+
+#include <vector>
+#include <stdint.h>
+#include <string>
+
+class CPubKey;
+class CScript;
+class CTransaction;
+class uint256;
+
+/** Signature hash types/flags */
+enum
+{
+ SIGHASH_ALL = 1,
+ SIGHASH_NONE = 2,
+ SIGHASH_SINGLE = 3,
+ SIGHASH_ANYONECANPAY = 0x80,
+};
+
+/** Script verification flags */
+enum
+{
+ SCRIPT_VERIFY_NONE = 0,
+
+ // Evaluate P2SH subscripts (softfork safe, BIP16).
+ SCRIPT_VERIFY_P2SH = (1U << 0),
+
+ // Passing a non-strict-DER signature or one with undefined hashtype to a checksig operation causes script failure.
+ // Evaluating a pubkey that is not (0x04 + 64 bytes) or (0x02 or 0x03 + 32 bytes) by checksig causes script failure.
+ // (softfork safe, but not used or intended as a consensus rule).
+ SCRIPT_VERIFY_STRICTENC = (1U << 1),
+
+ // Passing a non-strict-DER signature to a checksig operation causes script failure (softfork safe, BIP62 rule 1)
+ SCRIPT_VERIFY_DERSIG = (1U << 2),
+
+ // Passing a non-strict-DER signature or one with S > order/2 to a checksig operation causes script failure
+ // (softfork safe, BIP62 rule 5).
+ SCRIPT_VERIFY_LOW_S = (1U << 3),
+
+ // verify dummy stack item consumed by CHECKMULTISIG is of zero-length (softfork safe, BIP62 rule 7).
+ SCRIPT_VERIFY_NULLDUMMY = (1U << 4),
+
+ // Using a non-push operator in the scriptSig causes script failure (softfork safe, BIP62 rule 2).
+ SCRIPT_VERIFY_SIGPUSHONLY = (1U << 5),
+
+ // Require minimal encodings for all push operations (OP_0... OP_16, OP_1NEGATE where possible, direct
+ // pushes up to 75 bytes, OP_PUSHDATA up to 255 bytes, OP_PUSHDATA2 for anything larger). Evaluating
+ // any other push causes the script to fail (BIP62 rule 3).
+ // In addition, whenever a stack element is interpreted as a number, it must be of minimal length (BIP62 rule 4).
+ // (softfork safe)
+ SCRIPT_VERIFY_MINIMALDATA = (1U << 6),
+
+ // Discourage use of NOPs reserved for upgrades (NOP1-10)
+ //
+ // Provided so that nodes can avoid accepting or mining transactions
+ // containing executed NOP's whose meaning may change after a soft-fork,
+ // thus rendering the script invalid; with this flag set executing
+ // discouraged NOPs fails the script. This verification flag will never be
+ // a mandatory flag applied to scripts in a block. NOPs that are not
+ // executed, e.g. within an unexecuted IF ENDIF block, are *not* rejected.
+ SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS = (1U << 7),
+
+ // Require that only a single stack element remains after evaluation. This changes the success criterion from
+ // "At least one stack element must remain, and when interpreted as a boolean, it must be true" to
+ // "Exactly one stack element must remain, and when interpreted as a boolean, it must be true".
+ // (softfork safe, BIP62 rule 6)
+ // Note: CLEANSTACK should never be used without P2SH.
+ SCRIPT_VERIFY_CLEANSTACK = (1U << 8),
+
+ // Verify CHECKLOCKTIMEVERIFY
+ //
+ // See BIP65 for details.
+ SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY = (1U << 9),
+};
+
+uint256 SignatureHash(const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType);
+
+class BaseSignatureChecker
+{
+public:
+ virtual bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode) const
+ {
+ return false;
+ }
+
+ virtual bool CheckLockTime(const CScriptNum& nLockTime) const
+ {
+ return false;
+ }
+
+ virtual ~BaseSignatureChecker() {}
+};
+
+class TransactionSignatureChecker : public BaseSignatureChecker
+{
+private:
+ const CTransaction* txTo;
+ unsigned int nIn;
+
+protected:
+ virtual bool VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const;
+
+public:
+ TransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn) : txTo(txToIn), nIn(nInIn) {}
+ bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode) const;
+ bool CheckLockTime(const CScriptNum& nLockTime) const;
+};
+
+class MutableTransactionSignatureChecker : public TransactionSignatureChecker
+{
+private:
+ const CTransaction txTo;
+
+public:
+ MutableTransactionSignatureChecker(const CMutableTransaction* txToIn, unsigned int nInIn) : TransactionSignatureChecker(&txTo, nInIn), txTo(*txToIn) {}
+};
+
+bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* error = NULL);
+bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* error = NULL);
+
+#endif // BITCOIN_SCRIPT_INTERPRETER_H
diff --git a/src/script/script.cpp b/src/script/script.cpp
new file mode 100644
index 0000000000..fd33924732
--- /dev/null
+++ b/src/script/script.cpp
@@ -0,0 +1,262 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "script.h"
+
+#include "tinyformat.h"
+#include "utilstrencodings.h"
+
+namespace {
+inline std::string ValueString(const std::vector<unsigned char>& vch)
+{
+ if (vch.size() <= 4)
+ return strprintf("%d", CScriptNum(vch, false).getint());
+ else
+ return HexStr(vch);
+}
+} // anon namespace
+
+using namespace std;
+
+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";
+
+ case OP_INVALIDOPCODE : return "OP_INVALIDOPCODE";
+
+ // Note:
+ // The template matching params OP_SMALLDATA/etc are defined in opcodetype enum
+ // as kind of implementation hack, they are *NOT* real opcodes. If found in real
+ // Script, just let the default: case deal with them.
+
+ default:
+ return "OP_UNKNOWN";
+ }
+}
+
+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<unsigned char> data;
+ while (pc < scriptSig.end())
+ {
+ opcodetype opcode;
+ if (!scriptSig.GetOp(pc, opcode, data))
+ return 0;
+ if (opcode > OP_16)
+ return 0;
+ }
+
+ /// ... and return its 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);
+}
+
+bool CScript::IsPushOnly() const
+{
+ const_iterator pc = begin();
+ while (pc < end())
+ {
+ opcodetype opcode;
+ if (!GetOp(pc, opcode))
+ return false;
+ // Note that IsPushOnly() *does* consider OP_RESERVED to be a
+ // push-type opcode, however execution of OP_RESERVED fails, so
+ // it's not relevant to P2SH/BIP62 as the scriptSig would fail prior to
+ // the P2SH special validation code being executed.
+ if (opcode > OP_16)
+ return false;
+ }
+ return true;
+}
+
+std::string CScript::ToString() const
+{
+ std::string str;
+ opcodetype opcode;
+ std::vector<unsigned char> 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;
+}
diff --git a/src/script/script.h b/src/script/script.h
new file mode 100644
index 0000000000..c09899aabd
--- /dev/null
+++ b/src/script/script.h
@@ -0,0 +1,612 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_SCRIPT_SCRIPT_H
+#define BITCOIN_SCRIPT_SCRIPT_H
+
+#include "crypto/common.h"
+
+#include <assert.h>
+#include <climits>
+#include <limits>
+#include <stdexcept>
+#include <stdint.h>
+#include <string.h>
+#include <string>
+#include <vector>
+
+static const unsigned int MAX_SCRIPT_ELEMENT_SIZE = 520; // bytes
+
+// 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
+
+template <typename T>
+std::vector<unsigned char> ToByteVector(const T& in)
+{
+ return std::vector<unsigned char>(in.begin(), in.end());
+}
+
+/** 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_CHECKLOCKTIMEVERIFY = OP_NOP2,
+ 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_SMALLDATA = 0xf9,
+ OP_SMALLINTEGER = 0xfa,
+ OP_PUBKEYS = 0xfb,
+ OP_PUBKEYHASH = 0xfd,
+ OP_PUBKEY = 0xfe,
+
+ OP_INVALIDOPCODE = 0xff,
+};
+
+const char* GetOpName(opcodetype opcode);
+
+class scriptnum_error : public std::runtime_error
+{
+public:
+ explicit scriptnum_error(const std::string& str) : std::runtime_error(str) {}
+};
+
+class CScriptNum
+{
+/**
+ * Numeric opcodes (OP_1ADD, etc) are restricted to operating on 4-byte integers.
+ * The semantics are subtle, though: operands must be in the range [-2^31 +1...2^31 -1],
+ * but results may overflow (and are valid as long as they are not used in a subsequent
+ * numeric operation). CScriptNum enforces those semantics by storing results as
+ * an int64 and allowing out-of-range values to be returned as a vector of bytes but
+ * throwing an exception if arithmetic is done or the result is interpreted as an integer.
+ */
+public:
+
+ explicit CScriptNum(const int64_t& n)
+ {
+ m_value = n;
+ }
+
+ static const size_t nDefaultMaxNumSize = 4;
+
+ explicit CScriptNum(const std::vector<unsigned char>& vch, bool fRequireMinimal,
+ const size_t nMaxNumSize = nDefaultMaxNumSize)
+ {
+ if (vch.size() > nMaxNumSize) {
+ throw scriptnum_error("script number overflow");
+ }
+ if (fRequireMinimal && vch.size() > 0) {
+ // Check that the number is encoded with the minimum possible
+ // number of bytes.
+ //
+ // If the most-significant-byte - excluding the sign bit - is zero
+ // then we're not minimal. Note how this test also rejects the
+ // negative-zero encoding, 0x80.
+ if ((vch.back() & 0x7f) == 0) {
+ // One exception: if there's more than one byte and the most
+ // significant bit of the second-most-significant-byte is set
+ // it would conflict with the sign bit. An example of this case
+ // is +-255, which encode to 0xff00 and 0xff80 respectively.
+ // (big-endian).
+ if (vch.size() <= 1 || (vch[vch.size() - 2] & 0x80) == 0) {
+ throw scriptnum_error("non-minimally encoded script number");
+ }
+ }
+ }
+ m_value = set_vch(vch);
+ }
+
+ inline bool operator==(const int64_t& rhs) const { return m_value == rhs; }
+ inline bool operator!=(const int64_t& rhs) const { return m_value != rhs; }
+ inline bool operator<=(const int64_t& rhs) const { return m_value <= rhs; }
+ inline bool operator< (const int64_t& rhs) const { return m_value < rhs; }
+ inline bool operator>=(const int64_t& rhs) const { return m_value >= rhs; }
+ inline bool operator> (const int64_t& rhs) const { return m_value > rhs; }
+
+ inline bool operator==(const CScriptNum& rhs) const { return operator==(rhs.m_value); }
+ inline bool operator!=(const CScriptNum& rhs) const { return operator!=(rhs.m_value); }
+ inline bool operator<=(const CScriptNum& rhs) const { return operator<=(rhs.m_value); }
+ inline bool operator< (const CScriptNum& rhs) const { return operator< (rhs.m_value); }
+ inline bool operator>=(const CScriptNum& rhs) const { return operator>=(rhs.m_value); }
+ inline bool operator> (const CScriptNum& rhs) const { return operator> (rhs.m_value); }
+
+ inline CScriptNum operator+( const int64_t& rhs) const { return CScriptNum(m_value + rhs);}
+ inline CScriptNum operator-( const int64_t& rhs) const { return CScriptNum(m_value - rhs);}
+ inline CScriptNum operator+( const CScriptNum& rhs) const { return operator+(rhs.m_value); }
+ inline CScriptNum operator-( const CScriptNum& rhs) const { return operator-(rhs.m_value); }
+
+ inline CScriptNum& operator+=( const CScriptNum& rhs) { return operator+=(rhs.m_value); }
+ inline CScriptNum& operator-=( const CScriptNum& rhs) { return operator-=(rhs.m_value); }
+
+ inline CScriptNum operator-() const
+ {
+ assert(m_value != std::numeric_limits<int64_t>::min());
+ return CScriptNum(-m_value);
+ }
+
+ inline CScriptNum& operator=( const int64_t& rhs)
+ {
+ m_value = rhs;
+ return *this;
+ }
+
+ inline CScriptNum& operator+=( const int64_t& rhs)
+ {
+ assert(rhs == 0 || (rhs > 0 && m_value <= std::numeric_limits<int64_t>::max() - rhs) ||
+ (rhs < 0 && m_value >= std::numeric_limits<int64_t>::min() - rhs));
+ m_value += rhs;
+ return *this;
+ }
+
+ inline CScriptNum& operator-=( const int64_t& rhs)
+ {
+ assert(rhs == 0 || (rhs > 0 && m_value >= std::numeric_limits<int64_t>::min() + rhs) ||
+ (rhs < 0 && m_value <= std::numeric_limits<int64_t>::max() + rhs));
+ m_value -= rhs;
+ return *this;
+ }
+
+ int getint() const
+ {
+ if (m_value > std::numeric_limits<int>::max())
+ return std::numeric_limits<int>::max();
+ else if (m_value < std::numeric_limits<int>::min())
+ return std::numeric_limits<int>::min();
+ return m_value;
+ }
+
+ std::vector<unsigned char> getvch() const
+ {
+ return serialize(m_value);
+ }
+
+ static std::vector<unsigned char> serialize(const int64_t& value)
+ {
+ if(value == 0)
+ return std::vector<unsigned char>();
+
+ std::vector<unsigned char> result;
+ const bool neg = value < 0;
+ uint64_t absvalue = neg ? -value : value;
+
+ while(absvalue)
+ {
+ result.push_back(absvalue & 0xff);
+ absvalue >>= 8;
+ }
+
+// - If the most significant byte is >= 0x80 and the value is positive, push a
+// new zero-byte to make the significant byte < 0x80 again.
+
+// - If the most significant byte is >= 0x80 and the value is negative, push a
+// new 0x80 byte that will be popped off when converting to an integral.
+
+// - If the most significant byte is < 0x80 and the value is negative, add
+// 0x80 to it, since it will be subtracted and interpreted as a negative when
+// converting to an integral.
+
+ if (result.back() & 0x80)
+ result.push_back(neg ? 0x80 : 0);
+ else if (neg)
+ result.back() |= 0x80;
+
+ return result;
+ }
+
+private:
+ static int64_t set_vch(const std::vector<unsigned char>& vch)
+ {
+ if (vch.empty())
+ return 0;
+
+ int64_t result = 0;
+ for (size_t i = 0; i != vch.size(); ++i)
+ result |= static_cast<int64_t>(vch[i]) << 8*i;
+
+ // If the input vector's most significant byte is 0x80, remove it from
+ // the result's msb and return a negative.
+ if (vch.back() & 0x80)
+ return -((int64_t)(result & ~(0x80ULL << (8 * (vch.size() - 1)))));
+
+ return result;
+ }
+
+ int64_t m_value;
+};
+
+/** Serialized script, used inside transaction inputs and outputs */
+class CScript : public std::vector<unsigned char>
+{
+protected:
+ CScript& push_int64(int64_t n)
+ {
+ if (n == -1 || (n >= 1 && n <= 16))
+ {
+ push_back(n + (OP_1 - 1));
+ }
+ else if (n == 0)
+ {
+ push_back(OP_0);
+ }
+ else
+ {
+ *this << CScriptNum::serialize(n);
+ }
+ return *this;
+ }
+public:
+ CScript() { }
+ CScript(const CScript& b) : std::vector<unsigned char>(b.begin(), b.end()) { }
+ CScript(const_iterator pbegin, const_iterator pend) : std::vector<unsigned char>(pbegin, pend) { }
+ CScript(const unsigned char* pbegin, const unsigned char* pend) : std::vector<unsigned char>(pbegin, pend) { }
+
+ 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;
+ }
+
+ CScript(int64_t b) { operator<<(b); }
+
+ explicit CScript(opcodetype b) { operator<<(b); }
+ explicit CScript(const CScriptNum& b) { operator<<(b); }
+ explicit CScript(const std::vector<unsigned char>& b) { operator<<(b); }
+
+
+ CScript& operator<<(int64_t b) { return push_int64(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 CScriptNum& b)
+ {
+ *this << b.getvch();
+ return *this;
+ }
+
+ CScript& operator<<(const std::vector<unsigned char>& 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);
+ uint8_t data[2];
+ WriteLE16(data, b.size());
+ insert(end(), data, data + sizeof(data));
+ }
+ else
+ {
+ insert(end(), OP_PUSHDATA4);
+ uint8_t data[4];
+ WriteLE32(data, b.size());
+ insert(end(), data, data + sizeof(data));
+ }
+ 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<unsigned char>& 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<unsigned char>& 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<unsigned char>* 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 = 0;
+ 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 = ReadLE16(&pc[0]);
+ pc += 2;
+ }
+ else if (opcode == OP_PUSHDATA4)
+ {
+ if (end() - pc < 4)
+ return false;
+ nSize = ReadLE32(&pc[0]);
+ 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)
+ {
+ pc = 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 IsStandardTx and P2SH/BIP62 VerifyScript (which makes it consensus-critical). */
+ bool IsPushOnly() const;
+
+ /**
+ * Returns whether the script is guaranteed to fail at execution,
+ * regardless of the initial stack. This allows outputs to be pruned
+ * instantly when entering the UTXO set.
+ */
+ bool IsUnspendable() const
+ {
+ return (size() > 0 && *begin() == OP_RETURN);
+ }
+
+ std::string ToString() const;
+ void clear()
+ {
+ // The default std::vector::clear() does not release memory.
+ std::vector<unsigned char>().swap(*this);
+ }
+};
+
+#endif // BITCOIN_SCRIPT_SCRIPT_H
diff --git a/src/script/script_error.cpp b/src/script/script_error.cpp
new file mode 100644
index 0000000000..f1aa1fb408
--- /dev/null
+++ b/src/script/script_error.cpp
@@ -0,0 +1,75 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "script_error.h"
+
+const char* ScriptErrorString(const ScriptError serror)
+{
+ switch (serror)
+ {
+ case SCRIPT_ERR_OK:
+ return "No error";
+ case SCRIPT_ERR_EVAL_FALSE:
+ return "Script evaluated without error but finished with a false/empty top stack element";
+ case SCRIPT_ERR_VERIFY:
+ return "Script failed an OP_VERIFY operation";
+ case SCRIPT_ERR_EQUALVERIFY:
+ return "Script failed an OP_EQUALVERIFY operation";
+ case SCRIPT_ERR_CHECKMULTISIGVERIFY:
+ return "Script failed an OP_CHECKMULTISIGVERIFY operation";
+ case SCRIPT_ERR_CHECKSIGVERIFY:
+ return "Script failed an OP_CHECKSIGVERIFY operation";
+ case SCRIPT_ERR_NUMEQUALVERIFY:
+ return "Script failed an OP_NUMEQUALVERIFY operation";
+ case SCRIPT_ERR_SCRIPT_SIZE:
+ return "Script is too big";
+ case SCRIPT_ERR_PUSH_SIZE:
+ return "Push value size limit exceeded";
+ case SCRIPT_ERR_OP_COUNT:
+ return "Operation limit exceeded";
+ case SCRIPT_ERR_STACK_SIZE:
+ return "Stack size limit exceeded";
+ case SCRIPT_ERR_SIG_COUNT:
+ return "Signature count negative or greater than pubkey count";
+ case SCRIPT_ERR_PUBKEY_COUNT:
+ return "Pubkey count negative or limit exceeded";
+ case SCRIPT_ERR_BAD_OPCODE:
+ return "Opcode missing or not understood";
+ case SCRIPT_ERR_DISABLED_OPCODE:
+ return "Attempted to use a disabled opcode";
+ case SCRIPT_ERR_INVALID_STACK_OPERATION:
+ return "Operation not valid with the current stack size";
+ case SCRIPT_ERR_INVALID_ALTSTACK_OPERATION:
+ return "Operation not valid with the current altstack size";
+ case SCRIPT_ERR_OP_RETURN:
+ return "OP_RETURN was encountered";
+ case SCRIPT_ERR_UNBALANCED_CONDITIONAL:
+ return "Invalid OP_IF construction";
+ case SCRIPT_ERR_NEGATIVE_LOCKTIME:
+ return "Negative locktime";
+ case SCRIPT_ERR_UNSATISFIED_LOCKTIME:
+ return "Locktime requirement not satisfied";
+ case SCRIPT_ERR_SIG_HASHTYPE:
+ return "Signature hash type missing or not understood";
+ case SCRIPT_ERR_SIG_DER:
+ return "Non-canonical DER signature";
+ case SCRIPT_ERR_MINIMALDATA:
+ return "Data push larger than necessary";
+ case SCRIPT_ERR_SIG_PUSHONLY:
+ return "Only non-push operators allowed in signatures";
+ case SCRIPT_ERR_SIG_HIGH_S:
+ return "Non-canonical signature: S value is unnecessarily high";
+ case SCRIPT_ERR_SIG_NULLDUMMY:
+ return "Dummy CHECKMULTISIG argument must be zero";
+ case SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS:
+ return "NOPx reserved for soft-fork upgrades";
+ case SCRIPT_ERR_PUBKEYTYPE:
+ return "Public key is neither compressed or uncompressed";
+ case SCRIPT_ERR_UNKNOWN_ERROR:
+ case SCRIPT_ERR_ERROR_COUNT:
+ default: break;
+ }
+ return "unknown error";
+}
diff --git a/src/script/script_error.h b/src/script/script_error.h
new file mode 100644
index 0000000000..bb10b8a293
--- /dev/null
+++ b/src/script/script_error.h
@@ -0,0 +1,62 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_SCRIPT_SCRIPT_ERROR_H
+#define BITCOIN_SCRIPT_SCRIPT_ERROR_H
+
+typedef enum ScriptError_t
+{
+ SCRIPT_ERR_OK = 0,
+ SCRIPT_ERR_UNKNOWN_ERROR,
+ SCRIPT_ERR_EVAL_FALSE,
+ SCRIPT_ERR_OP_RETURN,
+
+ /* Max sizes */
+ SCRIPT_ERR_SCRIPT_SIZE,
+ SCRIPT_ERR_PUSH_SIZE,
+ SCRIPT_ERR_OP_COUNT,
+ SCRIPT_ERR_STACK_SIZE,
+ SCRIPT_ERR_SIG_COUNT,
+ SCRIPT_ERR_PUBKEY_COUNT,
+
+ /* Failed verify operations */
+ SCRIPT_ERR_VERIFY,
+ SCRIPT_ERR_EQUALVERIFY,
+ SCRIPT_ERR_CHECKMULTISIGVERIFY,
+ SCRIPT_ERR_CHECKSIGVERIFY,
+ SCRIPT_ERR_NUMEQUALVERIFY,
+
+ /* Logical/Format/Canonical errors */
+ SCRIPT_ERR_BAD_OPCODE,
+ SCRIPT_ERR_DISABLED_OPCODE,
+ SCRIPT_ERR_INVALID_STACK_OPERATION,
+ SCRIPT_ERR_INVALID_ALTSTACK_OPERATION,
+ SCRIPT_ERR_UNBALANCED_CONDITIONAL,
+
+ /* OP_CHECKLOCKTIMEVERIFY */
+ SCRIPT_ERR_NEGATIVE_LOCKTIME,
+ SCRIPT_ERR_UNSATISFIED_LOCKTIME,
+
+ /* BIP62 */
+ SCRIPT_ERR_SIG_HASHTYPE,
+ SCRIPT_ERR_SIG_DER,
+ SCRIPT_ERR_MINIMALDATA,
+ SCRIPT_ERR_SIG_PUSHONLY,
+ SCRIPT_ERR_SIG_HIGH_S,
+ SCRIPT_ERR_SIG_NULLDUMMY,
+ SCRIPT_ERR_PUBKEYTYPE,
+ SCRIPT_ERR_CLEANSTACK,
+
+ /* softfork safeness */
+ SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS,
+
+ SCRIPT_ERR_ERROR_COUNT
+} ScriptError;
+
+#define SCRIPT_ERR_LAST SCRIPT_ERR_ERROR_COUNT
+
+const char* ScriptErrorString(const ScriptError error);
+
+#endif // BITCOIN_SCRIPT_SCRIPT_ERROR_H
diff --git a/src/script/sigcache.cpp b/src/script/sigcache.cpp
new file mode 100644
index 0000000000..099b4ad0e3
--- /dev/null
+++ b/src/script/sigcache.cpp
@@ -0,0 +1,90 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "sigcache.h"
+
+#include "pubkey.h"
+#include "random.h"
+#include "uint256.h"
+#include "util.h"
+
+#include <boost/thread.hpp>
+#include <boost/tuple/tuple_comparison.hpp>
+
+namespace {
+
+/**
+ * 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<uint256, std::vector<unsigned char>, CPubKey> sigdata_type;
+ std::set< sigdata_type> setValid;
+ boost::shared_mutex cs_sigcache;
+
+public:
+ bool
+ Get(const uint256 &hash, const std::vector<unsigned char>& vchSig, const CPubKey& pubKey)
+ {
+ boost::shared_lock<boost::shared_mutex> lock(cs_sigcache);
+
+ sigdata_type k(hash, vchSig, pubKey);
+ std::set<sigdata_type>::iterator mi = setValid.find(k);
+ if (mi != setValid.end())
+ return true;
+ return false;
+ }
+
+ void Set(const uint256 &hash, const std::vector<unsigned char>& vchSig, const CPubKey& 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_t nMaxCacheSize = GetArg("-maxsigcachesize", 50000);
+ if (nMaxCacheSize <= 0) return;
+
+ boost::unique_lock<boost::shared_mutex> lock(cs_sigcache);
+
+ while (static_cast<int64_t>(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<unsigned char> unused;
+ std::set<sigdata_type>::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 CachingTransactionSignatureChecker::VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& pubkey, const uint256& sighash) const
+{
+ static CSignatureCache signatureCache;
+
+ if (signatureCache.Get(sighash, vchSig, pubkey))
+ return true;
+
+ if (!TransactionSignatureChecker::VerifySignature(vchSig, pubkey, sighash))
+ return false;
+
+ if (store)
+ signatureCache.Set(sighash, vchSig, pubkey);
+ return true;
+}
diff --git a/src/script/sigcache.h b/src/script/sigcache.h
new file mode 100644
index 0000000000..b299038daa
--- /dev/null
+++ b/src/script/sigcache.h
@@ -0,0 +1,26 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_SCRIPT_SIGCACHE_H
+#define BITCOIN_SCRIPT_SIGCACHE_H
+
+#include "script/interpreter.h"
+
+#include <vector>
+
+class CPubKey;
+
+class CachingTransactionSignatureChecker : public TransactionSignatureChecker
+{
+private:
+ bool store;
+
+public:
+ CachingTransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, bool storeIn=true) : TransactionSignatureChecker(txToIn, nInIn), store(storeIn) {}
+
+ bool VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const;
+};
+
+#endif // BITCOIN_SCRIPT_SIGCACHE_H
diff --git a/src/script/sign.cpp b/src/script/sign.cpp
new file mode 100644
index 0000000000..eab629cd91
--- /dev/null
+++ b/src/script/sign.cpp
@@ -0,0 +1,277 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "script/sign.h"
+
+#include "primitives/transaction.h"
+#include "key.h"
+#include "keystore.h"
+#include "script/standard.h"
+#include "uint256.h"
+
+#include <boost/foreach.hpp>
+
+using namespace std;
+
+typedef vector<unsigned char> valtype;
+
+TransactionSignatureCreator::TransactionSignatureCreator(const CKeyStore* keystoreIn, const CTransaction* txToIn, unsigned int nInIn, int nHashTypeIn) : BaseSignatureCreator(keystoreIn), txTo(txToIn), nIn(nInIn), nHashType(nHashTypeIn), checker(txTo, nIn) {}
+
+bool TransactionSignatureCreator::CreateSig(std::vector<unsigned char>& vchSig, const CKeyID& address, const CScript& scriptCode) const
+{
+ CKey key;
+ if (!keystore->GetKey(address, key))
+ return false;
+
+ uint256 hash = SignatureHash(scriptCode, *txTo, nIn, nHashType);
+ if (!key.Sign(hash, vchSig))
+ return false;
+ vchSig.push_back((unsigned char)nHashType);
+ return true;
+}
+
+static bool Sign1(const CKeyID& address, const BaseSignatureCreator& creator, const CScript& scriptCode, CScript& scriptSigRet)
+{
+ vector<unsigned char> vchSig;
+ if (!creator.CreateSig(vchSig, address, scriptCode))
+ return false;
+ scriptSigRet << vchSig;
+ return true;
+}
+
+static bool SignN(const vector<valtype>& multisigdata, const BaseSignatureCreator& creator, const CScript& scriptCode, 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, creator, scriptCode, scriptSigRet))
+ ++nSigned;
+ }
+ return nSigned==nRequired;
+}
+
+/**
+ * Sign scriptPubKey using signature made with creator.
+ * 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 satisfied.
+ */
+static bool SignStep(const BaseSignatureCreator& creator, const CScript& scriptPubKey,
+ CScript& scriptSigRet, txnouttype& whichTypeRet)
+{
+ scriptSigRet.clear();
+
+ vector<valtype> vSolutions;
+ if (!Solver(scriptPubKey, whichTypeRet, vSolutions))
+ return false;
+
+ CKeyID keyID;
+ switch (whichTypeRet)
+ {
+ case TX_NONSTANDARD:
+ case TX_NULL_DATA:
+ return false;
+ case TX_PUBKEY:
+ keyID = CPubKey(vSolutions[0]).GetID();
+ return Sign1(keyID, creator, scriptPubKey, scriptSigRet);
+ case TX_PUBKEYHASH:
+ keyID = CKeyID(uint160(vSolutions[0]));
+ if (!Sign1(keyID, creator, scriptPubKey, scriptSigRet))
+ return false;
+ else
+ {
+ CPubKey vch;
+ creator.KeyStore().GetPubKey(keyID, vch);
+ scriptSigRet << ToByteVector(vch);
+ }
+ return true;
+ case TX_SCRIPTHASH:
+ return creator.KeyStore().GetCScript(uint160(vSolutions[0]), scriptSigRet);
+
+ case TX_MULTISIG:
+ scriptSigRet << OP_0; // workaround CHECKMULTISIG bug
+ return (SignN(vSolutions, creator, scriptPubKey, scriptSigRet));
+ }
+ return false;
+}
+
+bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& fromPubKey, CScript& scriptSig)
+{
+ txnouttype whichType;
+ if (!SignStep(creator, fromPubKey, 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 = scriptSig;
+
+ txnouttype subType;
+ bool fSolved =
+ SignStep(creator, subscript, scriptSig, subType) && subType != TX_SCRIPTHASH;
+ // Append serialized subscript whether or not it is completely signed:
+ scriptSig << static_cast<valtype>(subscript);
+ if (!fSolved) return false;
+ }
+
+ // Test solution
+ return VerifyScript(scriptSig, fromPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, creator.Checker());
+}
+
+bool SignSignature(const CKeyStore &keystore, const CScript& fromPubKey, CMutableTransaction& txTo, unsigned int nIn, int nHashType)
+{
+ assert(nIn < txTo.vin.size());
+ CTxIn& txin = txTo.vin[nIn];
+
+ CTransaction txToConst(txTo);
+ TransactionSignatureCreator creator(&keystore, &txToConst, nIn, nHashType);
+
+ return ProduceSignature(creator, fromPubKey, txin.scriptSig);
+}
+
+bool SignSignature(const CKeyStore &keystore, const CTransaction& txFrom, CMutableTransaction& 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);
+}
+
+static CScript PushAll(const vector<valtype>& values)
+{
+ CScript result;
+ BOOST_FOREACH(const valtype& v, values)
+ result << v;
+ return result;
+}
+
+static CScript CombineMultisig(const CScript& scriptPubKey, const BaseSignatureChecker& checker,
+ const vector<valtype>& vSolutions,
+ const vector<valtype>& sigs1, const vector<valtype>& sigs2)
+{
+ // Combine all the signatures we've got:
+ set<valtype> 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<valtype, valtype> 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 (checker.CheckSig(sig, pubkey, scriptPubKey))
+ {
+ 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(const CScript& scriptPubKey, const BaseSignatureChecker& checker,
+ const txnouttype txType, const vector<valtype>& vSolutions,
+ vector<valtype>& sigs1, vector<valtype>& sigs2)
+{
+ switch (txType)
+ {
+ case TX_NONSTANDARD:
+ case TX_NULL_DATA:
+ // 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
+ {
+ // Recur to combine:
+ valtype spk = sigs1.back();
+ CScript pubKey2(spk.begin(), spk.end());
+
+ txnouttype txType2;
+ vector<vector<unsigned char> > vSolutions2;
+ Solver(pubKey2, txType2, vSolutions2);
+ sigs1.pop_back();
+ sigs2.pop_back();
+ CScript result = CombineSignatures(pubKey2, checker, txType2, vSolutions2, sigs1, sigs2);
+ result << spk;
+ return result;
+ }
+ case TX_MULTISIG:
+ return CombineMultisig(scriptPubKey, checker, vSolutions, sigs1, sigs2);
+ }
+
+ return CScript();
+}
+
+CScript CombineSignatures(const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn,
+ const CScript& scriptSig1, const CScript& scriptSig2)
+{
+ TransactionSignatureChecker checker(&txTo, nIn);
+ return CombineSignatures(scriptPubKey, checker, scriptSig1, scriptSig2);
+}
+
+CScript CombineSignatures(const CScript& scriptPubKey, const BaseSignatureChecker& checker,
+ const CScript& scriptSig1, const CScript& scriptSig2)
+{
+ txnouttype txType;
+ vector<vector<unsigned char> > vSolutions;
+ Solver(scriptPubKey, txType, vSolutions);
+
+ vector<valtype> stack1;
+ EvalScript(stack1, scriptSig1, SCRIPT_VERIFY_STRICTENC, BaseSignatureChecker());
+ vector<valtype> stack2;
+ EvalScript(stack2, scriptSig2, SCRIPT_VERIFY_STRICTENC, BaseSignatureChecker());
+
+ return CombineSignatures(scriptPubKey, checker, txType, vSolutions, stack1, stack2);
+}
diff --git a/src/script/sign.h b/src/script/sign.h
new file mode 100644
index 0000000000..0c4cf61e5e
--- /dev/null
+++ b/src/script/sign.h
@@ -0,0 +1,59 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_SCRIPT_SIGN_H
+#define BITCOIN_SCRIPT_SIGN_H
+
+#include "script/interpreter.h"
+
+class CKeyID;
+class CKeyStore;
+class CScript;
+class CTransaction;
+
+struct CMutableTransaction;
+
+/** Virtual base class for signature creators. */
+class BaseSignatureCreator {
+protected:
+ const CKeyStore* keystore;
+
+public:
+ BaseSignatureCreator(const CKeyStore* keystoreIn) : keystore(keystoreIn) {}
+ const CKeyStore& KeyStore() const { return *keystore; };
+ virtual ~BaseSignatureCreator() {}
+ virtual const BaseSignatureChecker& Checker() const =0;
+
+ /** Create a singular (non-script) signature. */
+ virtual bool CreateSig(std::vector<unsigned char>& vchSig, const CKeyID& keyid, const CScript& scriptCode) const =0;
+};
+
+/** A signature creator for transactions. */
+class TransactionSignatureCreator : public BaseSignatureCreator {
+ const CTransaction* txTo;
+ unsigned int nIn;
+ int nHashType;
+ const TransactionSignatureChecker checker;
+
+public:
+ TransactionSignatureCreator(const CKeyStore* keystoreIn, const CTransaction* txToIn, unsigned int nInIn, int nHashTypeIn=SIGHASH_ALL);
+ const BaseSignatureChecker& Checker() const { return checker; }
+ bool CreateSig(std::vector<unsigned char>& vchSig, const CKeyID& keyid, const CScript& scriptCode) const;
+};
+
+/** Produce a script signature using a generic signature creator. */
+bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& scriptPubKey, CScript& scriptSig);
+
+/** Produce a script signature for a transaction. */
+bool SignSignature(const CKeyStore& keystore, const CScript& fromPubKey, CMutableTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL);
+bool SignSignature(const CKeyStore& keystore, const CTransaction& txFrom, CMutableTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL);
+
+/** Combine two script signatures using a generic signature checker, intelligently, possibly with OP_0 placeholders. */
+CScript CombineSignatures(const CScript& scriptPubKey, const BaseSignatureChecker& checker, const CScript& scriptSig1, const CScript& scriptSig2);
+
+/** Combine two script signatures on transactions. */
+CScript CombineSignatures(const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, const CScript& scriptSig1, const CScript& scriptSig2);
+
+#endif // BITCOIN_SCRIPT_SIGN_H
diff --git a/src/script/standard.cpp b/src/script/standard.cpp
new file mode 100644
index 0000000000..ce50e3aad8
--- /dev/null
+++ b/src/script/standard.cpp
@@ -0,0 +1,318 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "script/standard.h"
+
+#include "pubkey.h"
+#include "script/script.h"
+#include "util.h"
+#include "utilstrencodings.h"
+
+#include <boost/foreach.hpp>
+
+using namespace std;
+
+typedef vector<unsigned char> valtype;
+
+unsigned nMaxDatacarrierBytes = MAX_OP_RETURN_RELAY;
+
+CScriptID::CScriptID(const CScript& in) : uint160(Hash160(in.begin(), in.end())) {}
+
+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";
+ case TX_NULL_DATA: return "nulldata";
+ }
+ return NULL;
+}
+
+/**
+ * Return public keys or hashes from scriptPubKey, for 'standard' transaction types.
+ */
+bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, vector<vector<unsigned char> >& vSolutionsRet)
+{
+ // Templates
+ static multimap<txnouttype, CScript> 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));
+
+ // Empty, provably prunable, data-carrying output
+ if (GetBoolArg("-datacarrier", true))
+ mTemplates.insert(make_pair(TX_NULL_DATA, CScript() << OP_RETURN << OP_SMALLDATA));
+ mTemplates.insert(make_pair(TX_NULL_DATA, CScript() << OP_RETURN));
+ }
+
+ // 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<unsigned char> 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<unsigned char> vch1, vch2;
+
+ // Compare
+ CScript::const_iterator pc1 = script1.begin();
+ CScript::const_iterator pc2 = script2.begin();
+ while (true)
+ {
+ 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() <= 65)
+ {
+ 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 statements
+ }
+
+ if (opcode2 == OP_PUBKEY)
+ {
+ if (vch1.size() < 33 || vch1.size() > 65)
+ 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 (opcode2 == OP_SMALLDATA)
+ {
+ // small pushdata, <= nMaxDatacarrierBytes
+ if (vch1.size() > nMaxDatacarrierBytes)
+ break;
+ }
+ else if (opcode1 != opcode2 || vch1 != vch2)
+ {
+ // Others must match exactly
+ break;
+ }
+ }
+ }
+
+ vSolutionsRet.clear();
+ typeRet = TX_NONSTANDARD;
+ return false;
+}
+
+int ScriptSigArgsExpected(txnouttype t, const std::vector<std::vector<unsigned char> >& vSolutions)
+{
+ switch (t)
+ {
+ case TX_NONSTANDARD:
+ case TX_NULL_DATA:
+ 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, txnouttype& whichType)
+{
+ vector<valtype> vSolutions;
+ 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;
+}
+
+bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
+{
+ vector<valtype> vSolutions;
+ txnouttype whichType;
+ if (!Solver(scriptPubKey, whichType, vSolutions))
+ return false;
+
+ if (whichType == TX_PUBKEY)
+ {
+ CPubKey pubKey(vSolutions[0]);
+ if (!pubKey.IsValid())
+ return false;
+
+ addressRet = pubKey.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<CTxDestination>& addressRet, int& nRequiredRet)
+{
+ addressRet.clear();
+ typeRet = TX_NONSTANDARD;
+ vector<valtype> vSolutions;
+ if (!Solver(scriptPubKey, typeRet, vSolutions))
+ return false;
+ if (typeRet == TX_NULL_DATA){
+ // This is data, not addresses
+ return false;
+ }
+
+ if (typeRet == TX_MULTISIG)
+ {
+ nRequiredRet = vSolutions.front()[0];
+ for (unsigned int i = 1; i < vSolutions.size()-1; i++)
+ {
+ CPubKey pubKey(vSolutions[i]);
+ if (!pubKey.IsValid())
+ continue;
+
+ CTxDestination address = pubKey.GetID();
+ addressRet.push_back(address);
+ }
+
+ if (addressRet.empty())
+ return false;
+ }
+ else
+ {
+ nRequiredRet = 1;
+ CTxDestination address;
+ if (!ExtractDestination(scriptPubKey, address))
+ return false;
+ addressRet.push_back(address);
+ }
+
+ return true;
+}
+
+namespace
+{
+class CScriptVisitor : public boost::static_visitor<bool>
+{
+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 << ToByteVector(keyID) << OP_EQUALVERIFY << OP_CHECKSIG;
+ return true;
+ }
+
+ bool operator()(const CScriptID &scriptID) const {
+ script->clear();
+ *script << OP_HASH160 << ToByteVector(scriptID) << OP_EQUAL;
+ return true;
+ }
+};
+}
+
+CScript GetScriptForDestination(const CTxDestination& dest)
+{
+ CScript script;
+
+ boost::apply_visitor(CScriptVisitor(&script), dest);
+ return script;
+}
+
+CScript GetScriptForMultisig(int nRequired, const std::vector<CPubKey>& keys)
+{
+ CScript script;
+
+ script << CScript::EncodeOP_N(nRequired);
+ BOOST_FOREACH(const CPubKey& key, keys)
+ script << ToByteVector(key);
+ script << CScript::EncodeOP_N(keys.size()) << OP_CHECKMULTISIG;
+ return script;
+}
diff --git a/src/script/standard.h b/src/script/standard.h
new file mode 100644
index 0000000000..6d72bad230
--- /dev/null
+++ b/src/script/standard.h
@@ -0,0 +1,97 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_SCRIPT_STANDARD_H
+#define BITCOIN_SCRIPT_STANDARD_H
+
+#include "script/interpreter.h"
+#include "uint256.h"
+
+#include <boost/variant.hpp>
+
+#include <stdint.h>
+
+class CKeyID;
+class CScript;
+
+/** A reference to a CScript: the Hash160 of its serialization (see script.h) */
+class CScriptID : public uint160
+{
+public:
+ CScriptID() : uint160() {}
+ CScriptID(const CScript& in);
+ CScriptID(const uint160& in) : uint160(in) {}
+};
+
+static const unsigned int MAX_OP_RETURN_RELAY = 80; //! bytes
+extern unsigned nMaxDatacarrierBytes;
+
+/**
+ * Mandatory script verification flags that all new blocks must comply with for
+ * them to be valid. (but old blocks may not comply with) Currently just P2SH,
+ * but in the future other flags may be added, such as a soft-fork to enforce
+ * strict DER encoding.
+ *
+ * Failing one of these tests may trigger a DoS ban - see CheckInputs() for
+ * details.
+ */
+static const unsigned int MANDATORY_SCRIPT_VERIFY_FLAGS = SCRIPT_VERIFY_P2SH;
+
+/**
+ * Standard script verification flags that standard transactions will comply
+ * with. However scripts violating these flags may still be present in valid
+ * blocks and we must accept those blocks.
+ */
+static const unsigned int STANDARD_SCRIPT_VERIFY_FLAGS = MANDATORY_SCRIPT_VERIFY_FLAGS |
+ SCRIPT_VERIFY_DERSIG |
+ SCRIPT_VERIFY_STRICTENC |
+ SCRIPT_VERIFY_MINIMALDATA |
+ SCRIPT_VERIFY_NULLDUMMY |
+ SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS |
+ SCRIPT_VERIFY_CLEANSTACK |
+ SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY |
+ SCRIPT_VERIFY_LOW_S;
+
+/** For convenience, standard but not mandatory verify flags. */
+static const unsigned int STANDARD_NOT_MANDATORY_VERIFY_FLAGS = STANDARD_SCRIPT_VERIFY_FLAGS & ~MANDATORY_SCRIPT_VERIFY_FLAGS;
+
+enum txnouttype
+{
+ TX_NONSTANDARD,
+ // 'standard' transaction types:
+ TX_PUBKEY,
+ TX_PUBKEYHASH,
+ TX_SCRIPTHASH,
+ TX_MULTISIG,
+ TX_NULL_DATA,
+};
+
+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<CNoDestination, CKeyID, CScriptID> CTxDestination;
+
+const char* GetTxnOutputType(txnouttype t);
+
+bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<std::vector<unsigned char> >& vSolutionsRet);
+int ScriptSigArgsExpected(txnouttype t, const std::vector<std::vector<unsigned char> >& vSolutions);
+bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType);
+bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet);
+bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<CTxDestination>& addressRet, int& nRequiredRet);
+
+CScript GetScriptForDestination(const CTxDestination& dest);
+CScript GetScriptForMultisig(int nRequired, const std::vector<CPubKey>& keys);
+
+#endif // BITCOIN_SCRIPT_STANDARD_H
diff --git a/src/secp256k1/.gitignore b/src/secp256k1/.gitignore
new file mode 100644
index 0000000000..076ff1295f
--- /dev/null
+++ b/src/secp256k1/.gitignore
@@ -0,0 +1,37 @@
+bench_inv
+bench_sign
+bench_verify
+bench_recover
+bench_internal
+tests
+*.exe
+*.so
+*.a
+!.gitignore
+
+Makefile
+configure
+.libs/
+Makefile.in
+aclocal.m4
+autom4te.cache/
+config.log
+config.status
+*.tar.gz
+*.la
+libtool
+.deps/
+.dirstamp
+build-aux/
+*.lo
+*.o
+*~
+src/libsecp256k1-config.h
+src/libsecp256k1-config.h.in
+m4/libtool.m4
+m4/ltoptions.m4
+m4/ltsugar.m4
+m4/ltversion.m4
+m4/lt~obsolete.m4
+src/stamp-h1
+libsecp256k1.pc
diff --git a/src/secp256k1/.travis.yml b/src/secp256k1/.travis.yml
new file mode 100644
index 0000000000..0d8089cfe4
--- /dev/null
+++ b/src/secp256k1/.travis.yml
@@ -0,0 +1,59 @@
+language: c
+sudo: false
+addons:
+ apt:
+ packages: libgmp-dev
+compiler:
+ - clang
+ - gcc
+env:
+ global:
+ - FIELD=auto BIGNUM=auto SCALAR=auto ENDOMORPHISM=no ASM=no BUILD=check EXTRAFLAGS= HOST=
+ matrix:
+ - SCALAR=32bit
+ - SCALAR=64bit
+ - FIELD=64bit
+ - FIELD=64bit ENDOMORPHISM=yes
+ - FIELD=64bit ASM=x86_64
+ - FIELD=64bit ENDOMORPHISM=yes ASM=x86_64
+ - FIELD=32bit
+ - FIELD=32bit ENDOMORPHISM=yes
+ - BIGNUM=no
+ - BIGNUM=no ENDOMORPHISM=yes
+ - BUILD=distcheck
+ - EXTRAFLAGS=CFLAGS=-DDETERMINISTIC
+matrix:
+ fast_finish: true
+ include:
+ - compiler: clang
+ env: HOST=i686-linux-gnu ENDOMORPHISM=yes
+ addons:
+ apt:
+ packages:
+ - gcc-multilib
+ - libgmp-dev:i386
+ - compiler: clang
+ env: HOST=i686-linux-gnu
+ addons:
+ apt:
+ packages:
+ - gcc-multilib
+ - compiler: gcc
+ env: HOST=i686-linux-gnu ENDOMORPHISM=yes
+ addons:
+ apt:
+ packages:
+ - gcc-multilib
+ - compiler: gcc
+ env: HOST=i686-linux-gnu
+ addons:
+ apt:
+ packages:
+ - gcc-multilib
+ - libgmp-dev:i386
+before_script: ./autogen.sh
+script:
+ - if [ -n "$HOST" ]; then export USE_HOST="--host=$HOST"; fi
+ - if [ "x$HOST" = "xi686-linux-gnu" ]; then export CC="$CC -m32"; fi
+ - ./configure --enable-endomorphism=$ENDOMORPHISM --with-field=$FIELD --with-bignum=$BIGNUM --with-scalar=$SCALAR $EXTRAFLAGS $USE_HOST && make -j2 $BUILD
+os: linux
diff --git a/src/secp256k1/COPYING b/src/secp256k1/COPYING
new file mode 100644
index 0000000000..4522a5990e
--- /dev/null
+++ b/src/secp256k1/COPYING
@@ -0,0 +1,19 @@
+Copyright (c) 2013 Pieter Wuille
+
+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/secp256k1/Makefile.am b/src/secp256k1/Makefile.am
new file mode 100644
index 0000000000..cc15338b7e
--- /dev/null
+++ b/src/secp256k1/Makefile.am
@@ -0,0 +1,77 @@
+ACLOCAL_AMFLAGS = -I build-aux/m4
+
+lib_LTLIBRARIES = libsecp256k1.la
+include_HEADERS = include/secp256k1.h
+noinst_HEADERS =
+noinst_HEADERS += src/scalar.h
+noinst_HEADERS += src/scalar_4x64.h
+noinst_HEADERS += src/scalar_8x32.h
+noinst_HEADERS += src/scalar_impl.h
+noinst_HEADERS += src/scalar_4x64_impl.h
+noinst_HEADERS += src/scalar_8x32_impl.h
+noinst_HEADERS += src/group.h
+noinst_HEADERS += src/group_impl.h
+noinst_HEADERS += src/num_gmp.h
+noinst_HEADERS += src/num_gmp_impl.h
+noinst_HEADERS += src/ecdsa.h
+noinst_HEADERS += src/ecdsa_impl.h
+noinst_HEADERS += src/eckey.h
+noinst_HEADERS += src/eckey_impl.h
+noinst_HEADERS += src/ecmult.h
+noinst_HEADERS += src/ecmult_impl.h
+noinst_HEADERS += src/ecmult_gen.h
+noinst_HEADERS += src/ecmult_gen_impl.h
+noinst_HEADERS += src/num.h
+noinst_HEADERS += src/num_impl.h
+noinst_HEADERS += src/field_10x26.h
+noinst_HEADERS += src/field_10x26_impl.h
+noinst_HEADERS += src/field_5x52.h
+noinst_HEADERS += src/field_5x52_impl.h
+noinst_HEADERS += src/field_5x52_int128_impl.h
+noinst_HEADERS += src/field_5x52_asm_impl.h
+noinst_HEADERS += src/java/org_bitcoin_NativeSecp256k1.h
+noinst_HEADERS += src/util.h
+noinst_HEADERS += src/testrand.h
+noinst_HEADERS += src/testrand_impl.h
+noinst_HEADERS += src/hash.h
+noinst_HEADERS += src/hash_impl.h
+noinst_HEADERS += src/field.h
+noinst_HEADERS += src/field_impl.h
+noinst_HEADERS += src/bench.h
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = libsecp256k1.pc
+
+libsecp256k1_la_SOURCES = src/secp256k1.c
+libsecp256k1_la_CPPFLAGS = -I$(top_srcdir)/include $(SECP_INCLUDES)
+libsecp256k1_la_LIBADD = $(SECP_LIBS)
+
+
+noinst_PROGRAMS =
+if USE_BENCHMARK
+noinst_PROGRAMS += bench_verify bench_recover bench_sign bench_internal
+bench_verify_SOURCES = src/bench_verify.c
+bench_verify_LDADD = libsecp256k1.la $(SECP_LIBS)
+bench_verify_LDFLAGS = -static
+bench_recover_SOURCES = src/bench_recover.c
+bench_recover_LDADD = libsecp256k1.la $(SECP_LIBS)
+bench_recover_LDFLAGS = -static
+bench_sign_SOURCES = src/bench_sign.c
+bench_sign_LDADD = libsecp256k1.la $(SECP_LIBS)
+bench_sign_LDFLAGS = -static
+bench_internal_SOURCES = src/bench_internal.c
+bench_internal_LDADD = $(SECP_LIBS)
+bench_internal_LDFLAGS = -static
+bench_internal_CPPFLAGS = $(SECP_INCLUDES)
+endif
+
+if USE_TESTS
+noinst_PROGRAMS += tests
+tests_SOURCES = src/tests.c
+tests_CPPFLAGS = -DVERIFY $(SECP_INCLUDES) $(SECP_TEST_INCLUDES)
+tests_LDADD = $(SECP_LIBS) $(SECP_TEST_LIBS)
+tests_LDFLAGS = -static
+TESTS = tests
+endif
+
+EXTRA_DIST = autogen.sh
diff --git a/src/secp256k1/README.md b/src/secp256k1/README.md
new file mode 100644
index 0000000000..6095db4220
--- /dev/null
+++ b/src/secp256k1/README.md
@@ -0,0 +1,61 @@
+libsecp256k1
+============
+
+[![Build Status](https://travis-ci.org/bitcoin/secp256k1.svg?branch=master)](https://travis-ci.org/bitcoin/secp256k1)
+
+Optimized C library for EC operations on curve secp256k1.
+
+This library is a work in progress and is being used to research best practices. Use at your own risk.
+
+Features:
+* secp256k1 ECDSA signing/verification and key generation.
+* Adding/multiplying private/public keys.
+* Serialization/parsing of private keys, public keys, signatures.
+* Constant time, constant memory access signing and pubkey generation.
+* Derandomized DSA (via RFC6979 or with a caller provided function.)
+* Very efficient implementation.
+
+Implementation details
+----------------------
+
+* General
+ * No runtime heap allocation.
+ * Extensive testing infrastructure.
+ * Structured to facilitate review and analysis.
+ * Intended to be portable to any system with a C89 compiler and uint64_t support.
+ * Expose only higher level interfaces to minimize the API surface and improve application security. ("Be difficult to use insecurely.")
+* Field operations
+ * Optimized implementation of arithmetic modulo the curve's field size (2^256 - 0x1000003D1).
+ * Using 5 52-bit limbs (including hand-optimized assembly for x86_64, by Diederik Huys).
+ * Using 10 26-bit limbs.
+ * Field inverses and square roots using a sliding window over blocks of 1s (by Peter Dettman).
+* Scalar operations
+ * Optimized implementation without data-dependent branches of arithmetic modulo the curve's order.
+ * Using 4 64-bit limbs (relying on __int128 support in the compiler).
+ * Using 8 32-bit limbs.
+* Group operations
+ * Point addition formula specifically simplified for the curve equation (y^2 = x^3 + 7).
+ * Use addition between points in Jacobian and affine coordinates where possible.
+ * Use a unified addition/doubling formula where necessary to avoid data-dependent branches.
+ * Point/x comparison without a field inversion by comparison in the Jacobian coordinate space.
+* Point multiplication for verification (a*P + b*G).
+ * Use wNAF notation for point multiplicands.
+ * Use a much larger window for multiples of G, using precomputed multiples.
+ * Use Shamir's trick to do the multiplication with the public key and the generator simultaneously.
+ * Optionally (off by default) use secp256k1's efficiently-computable endomorphism to split the P multiplicand into 2 half-sized ones.
+* Point multiplication for signing
+ * Use a precomputed table of multiples of powers of 16 multiplied with the generator, so general multiplication becomes a series of additions.
+ * Access the table with branch-free conditional moves so memory access is uniform.
+ * No data-dependent branches
+ * The precomputed tables add and eventually subtract points for which no known scalar (private key) is known, preventing even an attacker with control over the private key used to control the data internally.
+
+Build steps
+-----------
+
+libsecp256k1 is built using autotools:
+
+ $ ./autogen.sh
+ $ ./configure
+ $ make
+ $ ./tests
+ $ sudo make install # optional
diff --git a/src/secp256k1/TODO b/src/secp256k1/TODO
new file mode 100644
index 0000000000..a300e1c5eb
--- /dev/null
+++ b/src/secp256k1/TODO
@@ -0,0 +1,3 @@
+* Unit tests for fieldelem/groupelem, including ones intended to
+ trigger fieldelem's boundary cases.
+* Complete constant-time operations for signing/keygen
diff --git a/src/secp256k1/autogen.sh b/src/secp256k1/autogen.sh
new file mode 100755
index 0000000000..65286b9353
--- /dev/null
+++ b/src/secp256k1/autogen.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+set -e
+autoreconf -if --warnings=all
diff --git a/src/secp256k1/build-aux/m4/bitcoin_secp.m4 b/src/secp256k1/build-aux/m4/bitcoin_secp.m4
new file mode 100644
index 0000000000..4a398d6c93
--- /dev/null
+++ b/src/secp256k1/build-aux/m4/bitcoin_secp.m4
@@ -0,0 +1,61 @@
+dnl libsecp25k1 helper checks
+AC_DEFUN([SECP_INT128_CHECK],[
+has_int128=$ac_cv_type___int128
+])
+
+dnl
+AC_DEFUN([SECP_64BIT_ASM_CHECK],[
+AC_MSG_CHECKING(for x86_64 assembly availability)
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+ #include <stdint.h>]],[[
+ uint64_t a = 11, tmp;
+ __asm__ __volatile__("movq $0x100000000,%1; mulq %%rsi" : "+a"(a) : "S"(tmp) : "cc", "%rdx");
+ ]])],[has_64bit_asm=yes],[has_64bit_asm=no])
+AC_MSG_RESULT([$has_64bit_asm])
+])
+
+dnl
+AC_DEFUN([SECP_OPENSSL_CHECK],[
+if test x"$use_pkgconfig" = x"yes"; then
+ : #NOP
+ m4_ifdef([PKG_CHECK_MODULES],[
+ PKG_CHECK_MODULES([CRYPTO], [libcrypto], [has_libcrypto=yes],[has_libcrypto=no])
+ if test x"$has_libcrypto" = x"yes"; then
+ TEMP_LIBS="$LIBS"
+ LIBS="$LIBS $CRYPTO_LIBS"
+ AC_CHECK_LIB(crypto, main,[AC_DEFINE(HAVE_LIBCRYPTO,1,[Define this symbol if libcrypto is installed])],[has_libcrypto=no])
+ LIBS="$TEMP_LIBS"
+ fi
+ ])
+else
+ AC_CHECK_HEADER(openssl/crypto.h,[AC_CHECK_LIB(crypto, main,[has_libcrypto=yes; CRYPTO_LIBS=-lcrypto; AC_DEFINE(HAVE_LIBCRYPTO,1,[Define this symbol if libcrypto is installed])]
+)])
+ LIBS=
+fi
+if test x"$has_libcrypto" = x"yes" && test x"$has_openssl_ec" = x; then
+ AC_MSG_CHECKING(for EC functions in libcrypto)
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+ #include <openssl/ec.h>
+ #include <openssl/ecdsa.h>
+ #include <openssl/obj_mac.h>]],[[
+ EC_KEY *eckey = EC_KEY_new_by_curve_name(NID_secp256k1);
+ ECDSA_sign(0, NULL, 0, NULL, NULL, eckey);
+ ECDSA_verify(0, NULL, 0, NULL, 0, eckey);
+ EC_KEY_free(eckey);
+ ]])],[has_openssl_ec=yes],[has_openssl_ec=no])
+ AC_MSG_RESULT([$has_openssl_ec])
+fi
+])
+
+dnl
+AC_DEFUN([SECP_GMP_CHECK],[
+if test x"$has_gmp" != x"yes"; then
+ CPPFLAGS_TEMP="$CPPFLAGS"
+ CPPFLAGS="$GMP_CPPFLAGS $CPPFLAGS"
+ LIBS_TEMP="$LIBS"
+ LIBS="$GMP_LIBS $LIBS"
+ AC_CHECK_HEADER(gmp.h,[AC_CHECK_LIB(gmp, __gmpz_init,[has_gmp=yes; GMP_LIBS="$GMP_LIBS -lgmp"; AC_DEFINE(HAVE_LIBGMP,1,[Define this symbol if libgmp is installed])])])
+ CPPFLAGS="$CPPFLAGS_TEMP"
+ LIBS="$LIBS_TEMP"
+fi
+])
diff --git a/src/secp256k1/configure.ac b/src/secp256k1/configure.ac
new file mode 100644
index 0000000000..3dc1829516
--- /dev/null
+++ b/src/secp256k1/configure.ac
@@ -0,0 +1,330 @@
+AC_PREREQ([2.60])
+AC_INIT([libsecp256k1],[0.1])
+AC_CONFIG_AUX_DIR([build-aux])
+AC_CONFIG_MACRO_DIR([build-aux/m4])
+AC_CANONICAL_HOST
+AH_TOP([#ifndef LIBSECP256K1_CONFIG_H])
+AH_TOP([#define LIBSECP256K1_CONFIG_H])
+AH_BOTTOM([#endif /*LIBSECP256K1_CONFIG_H*/])
+AM_INIT_AUTOMAKE([foreign subdir-objects])
+LT_INIT
+
+dnl make the compilation flags quiet unless V=1 is used
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
+
+PKG_PROG_PKG_CONFIG
+
+AC_PATH_TOOL(AR, ar)
+AC_PATH_TOOL(RANLIB, ranlib)
+AC_PATH_TOOL(STRIP, strip)
+
+if test "x$CFLAGS" = "x"; then
+ CFLAGS="-O3 -g"
+fi
+
+AC_PROG_CC_C89
+if test x"$ac_cv_prog_cc_c89" = x"no"; then
+ AC_MSG_ERROR([c89 compiler support required])
+fi
+
+case $host in
+ *mingw*)
+ use_pkgconfig=no
+ ;;
+ *)
+ use_pkgconfig=yes
+ ;;
+esac
+
+case $host_os in
+ *darwin*)
+ if test x$cross_compiling != xyes; then
+ AC_PATH_PROG([BREW],brew,)
+ if test x$BREW != x; then
+ dnl These Homebrew packages may be keg-only, meaning that they won't be found
+ dnl in expected paths because they may conflict with system files. Ask
+ dnl Homebrew where each one is located, then adjust paths accordingly.
+
+ openssl_prefix=`$BREW --prefix openssl 2>/dev/null`
+ gmp_prefix=`$BREW --prefix gmp 2>/dev/null`
+ if test x$openssl_prefix != x; then
+ PKG_CONFIG_PATH="$openssl_prefix/lib/pkgconfig:$PKG_CONFIG_PATH"
+ export PKG_CONFIG_PATH
+ fi
+ if test x$gmp_prefix != x; then
+ GMP_CPPFLAGS="-I$gmp_prefix/include"
+ GMP_LIBS="-L$gmp_prefix/lib"
+ fi
+ else
+ AC_PATH_PROG([PORT],port,)
+ dnl if homebrew isn't installed and macports is, add the macports default paths
+ dnl as a last resort.
+ if test x$PORT != x; then
+ CPPFLAGS="$CPPFLAGS -isystem /opt/local/include"
+ LDFLAGS="$LDFLAGS -L/opt/local/lib"
+ fi
+ fi
+ fi
+ ;;
+esac
+
+CFLAGS="$CFLAGS -W"
+
+warn_CFLAGS="-std=c89 -pedantic -Wall -Wextra -Wcast-align -Wnested-externs -Wshadow -Wstrict-prototypes -Wno-unused-function -Wno-long-long -Wno-overlength-strings"
+saved_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS $warn_CFLAGS"
+AC_MSG_CHECKING([if ${CC} supports ${warn_CFLAGS}])
+AC_COMPILE_IFELSE([AC_LANG_SOURCE([[char foo;]])],
+ [ AC_MSG_RESULT([yes]) ],
+ [ AC_MSG_RESULT([no])
+ CFLAGS="$saved_CFLAGS"
+ ])
+
+
+AC_ARG_ENABLE(benchmark,
+ AS_HELP_STRING([--enable-benchmark],[compile benchmark (default is no)]),
+ [use_benchmark=$enableval],
+ [use_benchmark=no])
+
+AC_ARG_ENABLE(tests,
+ AS_HELP_STRING([--enable-tests],[compile tests (default is yes)]),
+ [use_tests=$enableval],
+ [use_tests=yes])
+
+AC_ARG_ENABLE(endomorphism,
+ AS_HELP_STRING([--enable-endomorphism],[enable endomorphism (default is no)]),
+ [use_endomorphism=$enableval],
+ [use_endomorphism=no])
+
+AC_ARG_WITH([field], [AS_HELP_STRING([--with-field=64bit|32bit|auto],
+[Specify Field Implementation. Default is auto])],[req_field=$withval], [req_field=auto])
+
+AC_ARG_WITH([bignum], [AS_HELP_STRING([--with-bignum=gmp|no|auto],
+[Specify Bignum Implementation. Default is auto])],[req_bignum=$withval], [req_bignum=auto])
+
+AC_ARG_WITH([scalar], [AS_HELP_STRING([--with-scalar=64bit|32bit|auto],
+[Specify scalar implementation. Default is auto])],[req_scalar=$withval], [req_scalar=auto])
+
+AC_ARG_WITH([asm], [AS_HELP_STRING([--with-asm=x86_64|no|auto]
+[Specify assembly optimizations to use. Default is auto])],[req_asm=$withval], [req_asm=auto])
+
+AC_CHECK_TYPES([__int128])
+
+AC_MSG_CHECKING([for __builtin_expect])
+AC_COMPILE_IFELSE([AC_LANG_SOURCE([[void myfunc() {__builtin_expect(0,0);}]])],
+ [ AC_MSG_RESULT([yes]);AC_DEFINE(HAVE_BUILTIN_EXPECT,1,[Define this symbol if __builtin_expect is available]) ],
+ [ AC_MSG_RESULT([no])
+ ])
+
+if test x"$req_asm" = x"auto"; then
+ SECP_64BIT_ASM_CHECK
+ if test x"$has_64bit_asm" = x"yes"; then
+ set_asm=x86_64
+ fi
+ if test x"$set_asm" = x; then
+ set_asm=no
+ fi
+else
+ set_asm=$req_asm
+ case $set_asm in
+ x86_64)
+ SECP_64BIT_ASM_CHECK
+ if test x"$has_64bit_asm" != x"yes"; then
+ AC_MSG_ERROR([x86_64 assembly optimization requested but not available])
+ fi
+ ;;
+ no)
+ ;;
+ *)
+ AC_MSG_ERROR([invalid assembly optimization selection])
+ ;;
+ esac
+fi
+
+if test x"$req_field" = x"auto"; then
+ if test x"set_asm" = x"x86_64"; then
+ set_field=64bit
+ fi
+ if test x"$set_field" = x; then
+ SECP_INT128_CHECK
+ if test x"$has_int128" = x"yes"; then
+ set_field=64bit
+ fi
+ fi
+ if test x"$set_field" = x; then
+ set_field=32bit
+ fi
+else
+ set_field=$req_field
+ case $set_field in
+ 64bit)
+ if test x"$set_asm" != x"x86_64"; then
+ SECP_INT128_CHECK
+ if test x"$has_int128" != x"yes"; then
+ AC_MSG_ERROR([64bit field explicitly requested but neither __int128 support or x86_64 assembly available])
+ fi
+ fi
+ ;;
+ 32bit)
+ ;;
+ *)
+ AC_MSG_ERROR([invalid field implementation selection])
+ ;;
+ esac
+fi
+
+if test x"$req_scalar" = x"auto"; then
+ SECP_INT128_CHECK
+ if test x"$has_int128" = x"yes"; then
+ set_scalar=64bit
+ fi
+ if test x"$set_scalar" = x; then
+ set_scalar=32bit
+ fi
+else
+ set_scalar=$req_scalar
+ case $set_scalar in
+ 64bit)
+ SECP_INT128_CHECK
+ if test x"$has_int128" != x"yes"; then
+ AC_MSG_ERROR([64bit scalar explicitly requested but __int128 support not available])
+ fi
+ ;;
+ 32bit)
+ ;;
+ *)
+ AC_MSG_ERROR([invalid scalar implementation selected])
+ ;;
+ esac
+fi
+
+if test x"$req_bignum" = x"auto"; then
+ SECP_GMP_CHECK
+ if test x"$has_gmp" = x"yes"; then
+ set_bignum=gmp
+ fi
+
+ if test x"$set_bignum" = x; then
+ set_bignum=no
+ fi
+else
+ set_bignum=$req_bignum
+ case $set_bignum in
+ gmp)
+ SECP_GMP_CHECK
+ if test x"$has_gmp" != x"yes"; then
+ AC_MSG_ERROR([gmp bignum explicitly requested but libgmp not available])
+ fi
+ ;;
+ no)
+ ;;
+ *)
+ AC_MSG_ERROR([invalid bignum implementation selection])
+ ;;
+ esac
+fi
+
+# select assembly optimization
+case $set_asm in
+x86_64)
+ AC_DEFINE(USE_ASM_X86_64, 1, [Define this symbol to enable x86_64 assembly optimizations])
+ ;;
+no)
+ ;;
+*)
+ AC_MSG_ERROR([invalid assembly optimizations])
+ ;;
+esac
+
+# select field implementation
+case $set_field in
+64bit)
+ AC_DEFINE(USE_FIELD_5X52, 1, [Define this symbol to use the FIELD_5X52 implementation])
+ ;;
+32bit)
+ AC_DEFINE(USE_FIELD_10X26, 1, [Define this symbol to use the FIELD_10X26 implementation])
+ ;;
+*)
+ AC_MSG_ERROR([invalid field implementation])
+ ;;
+esac
+
+# select bignum implementation
+case $set_bignum in
+gmp)
+ AC_DEFINE(HAVE_LIBGMP, 1, [Define this symbol if libgmp is installed])
+ AC_DEFINE(USE_NUM_GMP, 1, [Define this symbol to use the gmp implementation for num])
+ AC_DEFINE(USE_FIELD_INV_NUM, 1, [Define this symbol to use the num-based field inverse implementation])
+ AC_DEFINE(USE_SCALAR_INV_NUM, 1, [Define this symbol to use the num-based scalar inverse implementation])
+ ;;
+no)
+ AC_DEFINE(USE_NUM_NONE, 1, [Define this symbol to use no num implementation])
+ AC_DEFINE(USE_FIELD_INV_BUILTIN, 1, [Define this symbol to use the native field inverse implementation])
+ AC_DEFINE(USE_SCALAR_INV_BUILTIN, 1, [Define this symbol to use the native scalar inverse implementation])
+ ;;
+*)
+ AC_MSG_ERROR([invalid bignum implementation])
+ ;;
+esac
+
+#select scalar implementation
+case $set_scalar in
+64bit)
+ AC_DEFINE(USE_SCALAR_4X64, 1, [Define this symbol to use the 4x64 scalar implementation])
+ ;;
+32bit)
+ AC_DEFINE(USE_SCALAR_8X32, 1, [Define this symbol to use the 8x32 scalar implementation])
+ ;;
+*)
+ AC_MSG_ERROR([invalid scalar implementation])
+ ;;
+esac
+
+if test x"$use_tests" = x"yes"; then
+ SECP_OPENSSL_CHECK
+ if test x"$has_openssl_ec" = x"yes"; then
+ AC_DEFINE(ENABLE_OPENSSL_TESTS, 1, [Define this symbol if OpenSSL EC functions are available])
+ SECP_TEST_INCLUDES="$SSL_CFLAGS $CRYPTO_CFLAGS"
+ SECP_TEST_LIBS="$CRYPTO_LIBS"
+
+ case $host in
+ *mingw*)
+ SECP_TEST_LIBS="$SECP_TEST_LIBS -lgdi32"
+ ;;
+ esac
+
+ fi
+fi
+
+if test x"$set_bignum" = x"gmp"; then
+ SECP_LIBS="$SECP_LIBS $GMP_LIBS"
+ SECP_INCLUDES="$SECP_INCLUDES $GMP_CPPFLAGS"
+fi
+
+if test x"$use_endomorphism" = x"yes"; then
+ AC_DEFINE(USE_ENDOMORPHISM, 1, [Define this symbol to use endomorphism optimization])
+fi
+
+AC_C_BIGENDIAN()
+
+AC_MSG_NOTICE([Using assembly optimizations: $set_asm])
+AC_MSG_NOTICE([Using field implementation: $set_field])
+AC_MSG_NOTICE([Using bignum implementation: $set_bignum])
+AC_MSG_NOTICE([Using scalar implementation: $set_scalar])
+AC_MSG_NOTICE([Using endomorphism optimizations: $use_endomorphism])
+
+AC_CONFIG_HEADERS([src/libsecp256k1-config.h])
+AC_CONFIG_FILES([Makefile libsecp256k1.pc])
+AC_SUBST(SECP_INCLUDES)
+AC_SUBST(SECP_LIBS)
+AC_SUBST(SECP_TEST_LIBS)
+AC_SUBST(SECP_TEST_INCLUDES)
+AM_CONDITIONAL([USE_TESTS], [test x"$use_tests" != x"no"])
+AM_CONDITIONAL([USE_BENCHMARK], [test x"$use_benchmark" = x"yes"])
+
+dnl make sure nothing new is exported so that we don't break the cache
+PKGCONFIG_PATH_TEMP="$PKG_CONFIG_PATH"
+unset PKG_CONFIG_PATH
+PKG_CONFIG_PATH="$PKGCONFIG_PATH_TEMP"
+
+AC_OUTPUT
diff --git a/src/secp256k1/include/secp256k1.h b/src/secp256k1/include/secp256k1.h
new file mode 100644
index 0000000000..06afd4c65b
--- /dev/null
+++ b/src/secp256k1/include/secp256k1.h
@@ -0,0 +1,347 @@
+#ifndef _SECP256K1_
+# define _SECP256K1_
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+# if !defined(SECP256K1_GNUC_PREREQ)
+# if defined(__GNUC__)&&defined(__GNUC_MINOR__)
+# define SECP256K1_GNUC_PREREQ(_maj,_min) \
+ ((__GNUC__<<16)+__GNUC_MINOR__>=((_maj)<<16)+(_min))
+# else
+# define SECP256K1_GNUC_PREREQ(_maj,_min) 0
+# endif
+# endif
+
+# if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) )
+# if SECP256K1_GNUC_PREREQ(2,7)
+# define SECP256K1_INLINE __inline__
+# elif (defined(_MSC_VER))
+# define SECP256K1_INLINE __inline
+# else
+# define SECP256K1_INLINE
+# endif
+# else
+# define SECP256K1_INLINE inline
+# endif
+
+/**Warning attributes
+ * NONNULL is not used if SECP256K1_BUILD is set to avoid the compiler optimizing out
+ * some paranoid null checks. */
+# if defined(__GNUC__) && SECP256K1_GNUC_PREREQ(3, 4)
+# define SECP256K1_WARN_UNUSED_RESULT __attribute__ ((__warn_unused_result__))
+# else
+# define SECP256K1_WARN_UNUSED_RESULT
+# endif
+# if !defined(SECP256K1_BUILD) && defined(__GNUC__) && SECP256K1_GNUC_PREREQ(3, 4)
+# define SECP256K1_ARG_NONNULL(_x) __attribute__ ((__nonnull__(_x)))
+# else
+# define SECP256K1_ARG_NONNULL(_x)
+# endif
+
+/** Opaque data structure that holds context information (precomputed tables etc.).
+ * Only functions that take a pointer to a non-const context require exclusive
+ * access to it. Multiple functions that take a pointer to a const context may
+ * run simultaneously.
+ */
+typedef struct secp256k1_context_struct secp256k1_context_t;
+
+/** Flags to pass to secp256k1_context_create. */
+# define SECP256K1_CONTEXT_VERIFY (1 << 0)
+# define SECP256K1_CONTEXT_SIGN (1 << 1)
+
+/** Create a secp256k1 context object.
+ * Returns: a newly created context object.
+ * In: flags: which parts of the context to initialize.
+ */
+secp256k1_context_t* secp256k1_context_create(
+ int flags
+) SECP256K1_WARN_UNUSED_RESULT;
+
+/** Copies a secp256k1 context object.
+ * Returns: a newly created context object.
+ * In: ctx: an existing context to copy
+ */
+secp256k1_context_t* secp256k1_context_clone(
+ const secp256k1_context_t* ctx
+) SECP256K1_WARN_UNUSED_RESULT;
+
+/** Destroy a secp256k1 context object.
+ * The context pointer may not be used afterwards.
+ */
+void secp256k1_context_destroy(
+ secp256k1_context_t* ctx
+) SECP256K1_ARG_NONNULL(1);
+
+/** Verify an ECDSA signature.
+ * Returns: 1: correct signature
+ * 0: incorrect signature
+ * -1: invalid public key
+ * -2: invalid signature
+ * In: ctx: a secp256k1 context object, initialized for verification.
+ * msg32: the 32-byte message hash being verified (cannot be NULL)
+ * sig: the signature being verified (cannot be NULL)
+ * siglen: the length of the signature
+ * pubkey: the public key to verify with (cannot be NULL)
+ * pubkeylen: the length of pubkey
+ */
+SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_verify(
+ const secp256k1_context_t* ctx,
+ const unsigned char *msg32,
+ const unsigned char *sig,
+ int siglen,
+ const unsigned char *pubkey,
+ int pubkeylen
+) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5);
+
+/** A pointer to a function to deterministically generate a nonce.
+ * Returns: 1 if a nonce was successfully generated. 0 will cause signing to fail.
+ * In: msg32: the 32-byte message hash being verified (will not be NULL)
+ * key32: pointer to a 32-byte secret key (will not be NULL)
+ * attempt: how many iterations we have tried to find a nonce.
+ * This will almost always be 0, but different attempt values
+ * are required to result in a different nonce.
+ * data: Arbitrary data pointer that is passed through.
+ * Out: nonce32: pointer to a 32-byte array to be filled by the function.
+ * Except for test cases, this function should compute some cryptographic hash of
+ * the message, the key and the attempt.
+ */
+typedef int (*secp256k1_nonce_function_t)(
+ unsigned char *nonce32,
+ const unsigned char *msg32,
+ const unsigned char *key32,
+ unsigned int attempt,
+ const void *data
+);
+
+/** An implementation of RFC6979 (using HMAC-SHA256) as nonce generation function.
+ * If a data pointer is passed, it is assumed to be a pointer to 32 bytes of
+ * extra entropy.
+ */
+extern const secp256k1_nonce_function_t secp256k1_nonce_function_rfc6979;
+
+/** A default safe nonce generation function (currently equal to secp256k1_nonce_function_rfc6979). */
+extern const secp256k1_nonce_function_t secp256k1_nonce_function_default;
+
+
+/** Create an ECDSA signature.
+ * Returns: 1: signature created
+ * 0: the nonce generation function failed, the private key was invalid, or there is not
+ * enough space in the signature (as indicated by siglen).
+ * In: ctx: pointer to a context object, initialized for signing (cannot be NULL)
+ * msg32: the 32-byte message hash being signed (cannot be NULL)
+ * seckey: pointer to a 32-byte secret key (cannot be NULL)
+ * noncefp:pointer to a nonce generation function. If NULL, secp256k1_nonce_function_default is used
+ * ndata: pointer to arbitrary data used by the nonce generation function (can be NULL)
+ * Out: sig: pointer to an array where the signature will be placed (cannot be NULL)
+ * In/Out: siglen: pointer to an int with the length of sig, which will be updated
+ * to contain the actual signature length (<=72).
+ *
+ * The sig always has an s value in the lower half of the range (From 0x1
+ * to 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0,
+ * inclusive), unlike many other implementations.
+ * With ECDSA a third-party can can forge a second distinct signature
+ * of the same message given a single initial signature without knowing
+ * the key by setting s to its additive inverse mod-order, 'flipping' the
+ * sign of the random point R which is not included in the signature.
+ * Since the forgery is of the same message this isn't universally
+ * problematic, but in systems where message malleability or uniqueness
+ * of signatures is important this can cause issues. This forgery can be
+ * blocked by all verifiers forcing signers to use a canonical form. The
+ * lower-S form reduces the size of signatures slightly on average when
+ * variable length encodings (such as DER) are used and is cheap to
+ * verify, making it a good choice. Security of always using lower-S is
+ * assured because anyone can trivially modify a signature after the
+ * fact to enforce this property. Adjusting it inside the signing
+ * function avoids the need to re-serialize or have curve specific
+ * constants outside of the library. By always using a canonical form
+ * even in applications where it isn't needed it becomes possible to
+ * impose a requirement later if a need is discovered.
+ * No other forms of ECDSA malleability are known and none seem likely,
+ * but there is no formal proof that ECDSA, even with this additional
+ * restriction, is free of other malleability. Commonly used serialization
+ * schemes will also accept various non-unique encodings, so care should
+ * be taken when this property is required for an application.
+ */
+int secp256k1_ecdsa_sign(
+ const secp256k1_context_t* ctx,
+ const unsigned char *msg32,
+ unsigned char *sig,
+ int *siglen,
+ const unsigned char *seckey,
+ secp256k1_nonce_function_t noncefp,
+ const void *ndata
+) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
+
+/** Create a compact ECDSA signature (64 byte + recovery id).
+ * Returns: 1: signature created
+ * 0: the nonce generation function failed, or the secret key was invalid.
+ * In: ctx: pointer to a context object, initialized for signing (cannot be NULL)
+ * msg32: the 32-byte message hash being signed (cannot be NULL)
+ * seckey: pointer to a 32-byte secret key (cannot be NULL)
+ * noncefp:pointer to a nonce generation function. If NULL, secp256k1_nonce_function_default is used
+ * ndata: pointer to arbitrary data used by the nonce generation function (can be NULL)
+ * Out: sig: pointer to a 64-byte array where the signature will be placed (cannot be NULL)
+ * In case 0 is returned, the returned signature length will be zero.
+ * recid: pointer to an int, which will be updated to contain the recovery id (can be NULL)
+ */
+int secp256k1_ecdsa_sign_compact(
+ const secp256k1_context_t* ctx,
+ const unsigned char *msg32,
+ unsigned char *sig64,
+ const unsigned char *seckey,
+ secp256k1_nonce_function_t noncefp,
+ const void *ndata,
+ int *recid
+) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
+
+/** Recover an ECDSA public key from a compact signature.
+ * Returns: 1: public key successfully recovered (which guarantees a correct signature).
+ * 0: otherwise.
+ * In: ctx: pointer to a context object, initialized for verification (cannot be NULL)
+ * msg32: the 32-byte message hash assumed to be signed (cannot be NULL)
+ * sig64: signature as 64 byte array (cannot be NULL)
+ * compressed: whether to recover a compressed or uncompressed pubkey
+ * recid: the recovery id (0-3, as returned by ecdsa_sign_compact)
+ * Out: pubkey: pointer to a 33 or 65 byte array to put the pubkey (cannot be NULL)
+ * pubkeylen: pointer to an int that will contain the pubkey length (cannot be NULL)
+ */
+SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_recover_compact(
+ const secp256k1_context_t* ctx,
+ const unsigned char *msg32,
+ const unsigned char *sig64,
+ unsigned char *pubkey,
+ int *pubkeylen,
+ int compressed,
+ int recid
+) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
+
+/** Verify an ECDSA secret key.
+ * Returns: 1: secret key is valid
+ * 0: secret key is invalid
+ * In: ctx: pointer to a context object (cannot be NULL)
+ * seckey: pointer to a 32-byte secret key (cannot be NULL)
+ */
+SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_verify(
+ const secp256k1_context_t* ctx,
+ const unsigned char *seckey
+) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
+
+/** Just validate a public key.
+ * Returns: 1: public key is valid
+ * 0: public key is invalid
+ * In: ctx: pointer to a context object (cannot be NULL)
+ * pubkey: pointer to a 33-byte or 65-byte public key (cannot be NULL).
+ * pubkeylen: length of pubkey
+ */
+SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_verify(
+ const secp256k1_context_t* ctx,
+ const unsigned char *pubkey,
+ int pubkeylen
+) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
+
+/** Compute the public key for a secret key.
+ * In: ctx: pointer to a context object, initialized for signing (cannot be NULL)
+ * compressed: whether the computed public key should be compressed
+ * seckey: pointer to a 32-byte private key (cannot be NULL)
+ * Out: pubkey: pointer to a 33-byte (if compressed) or 65-byte (if uncompressed)
+ * area to store the public key (cannot be NULL)
+ * pubkeylen: pointer to int that will be updated to contains the pubkey's
+ * length (cannot be NULL)
+ * Returns: 1: secret was valid, public key stores
+ * 0: secret was invalid, try again
+ */
+SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_create(
+ const secp256k1_context_t* ctx,
+ unsigned char *pubkey,
+ int *pubkeylen,
+ const unsigned char *seckey,
+ int compressed
+) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
+
+/** Decompress a public key.
+ * In: ctx: pointer to a context object (cannot be NULL)
+ * In/Out: pubkey: pointer to a 65-byte array to put the decompressed public key.
+ * It must contain a 33-byte or 65-byte public key already (cannot be NULL)
+ * pubkeylen: pointer to the size of the public key pointed to by pubkey (cannot be NULL)
+ * It will be updated to reflect the new size.
+ * Returns: 0: pubkey was invalid
+ * 1: pubkey was valid, and was replaced with its decompressed version
+ */
+SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_decompress(
+ const secp256k1_context_t* ctx,
+ unsigned char *pubkey,
+ int *pubkeylen
+) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
+
+/** Export a private key in DER format.
+ * In: ctx: pointer to a context object, initialized for signing (cannot be NULL)
+ */
+SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_export(
+ const secp256k1_context_t* ctx,
+ const unsigned char *seckey,
+ unsigned char *privkey,
+ int *privkeylen,
+ int compressed
+) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
+
+/** Import a private key in DER format. */
+SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_import(
+ const secp256k1_context_t* ctx,
+ unsigned char *seckey,
+ const unsigned char *privkey,
+ int privkeylen
+) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
+
+/** Tweak a private key by adding tweak to it. */
+SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_add(
+ const secp256k1_context_t* ctx,
+ unsigned char *seckey,
+ const unsigned char *tweak
+) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
+
+/** Tweak a public key by adding tweak times the generator to it.
+ * In: ctx: pointer to a context object, initialized for verification (cannot be NULL)
+ */
+SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_add(
+ const secp256k1_context_t* ctx,
+ unsigned char *pubkey,
+ int pubkeylen,
+ const unsigned char *tweak
+) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4);
+
+/** Tweak a private key by multiplying it with tweak. */
+SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_mul(
+ const secp256k1_context_t* ctx,
+ unsigned char *seckey,
+ const unsigned char *tweak
+) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
+
+/** Tweak a public key by multiplying it with tweak.
+ * In: ctx: pointer to a context object, initialized for verification (cannot be NULL)
+ */
+SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_mul(
+ const secp256k1_context_t* ctx,
+ unsigned char *pubkey,
+ int pubkeylen,
+ const unsigned char *tweak
+) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4);
+
+/** Updates the context randomization.
+ * Returns: 1: randomization successfully updated
+ * 0: error
+ * In: ctx: pointer to a context object (cannot be NULL)
+ * seed32: pointer to a 32-byte random seed (NULL resets to initial state)
+ */
+SECP256K1_WARN_UNUSED_RESULT int secp256k1_context_randomize(
+ secp256k1_context_t* ctx,
+ const unsigned char *seed32
+) SECP256K1_ARG_NONNULL(1);
+
+
+# ifdef __cplusplus
+}
+# endif
+
+#endif
diff --git a/src/secp256k1/libsecp256k1.pc.in b/src/secp256k1/libsecp256k1.pc.in
new file mode 100644
index 0000000000..1c72dd0003
--- /dev/null
+++ b/src/secp256k1/libsecp256k1.pc.in
@@ -0,0 +1,13 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: libsecp256k1
+Description: Optimized C library for EC operations on curve secp256k1
+URL: https://github.com/bitcoin/secp256k1
+Version: @PACKAGE_VERSION@
+Cflags: -I${includedir}
+Libs.private: @SECP_LIBS@
+Libs: -L${libdir} -lsecp256k1
+
diff --git a/src/secp256k1/obj/.gitignore b/src/secp256k1/obj/.gitignore
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/src/secp256k1/obj/.gitignore
diff --git a/src/secp256k1/src/bench.h b/src/secp256k1/src/bench.h
new file mode 100644
index 0000000000..db5f68cee1
--- /dev/null
+++ b/src/secp256k1/src/bench.h
@@ -0,0 +1,56 @@
+/**********************************************************************
+ * Copyright (c) 2014 Pieter Wuille *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
+ **********************************************************************/
+
+#ifndef _SECP256K1_BENCH_H_
+#define _SECP256K1_BENCH_H_
+
+#include <stdio.h>
+#include <math.h>
+#include "sys/time.h"
+
+static double gettimedouble(void) {
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ return tv.tv_usec * 0.000001 + tv.tv_sec;
+}
+
+void print_number(double x) {
+ double y = x;
+ int c = 0;
+ if (y < 0.0) y = -y;
+ while (y < 100.0) {
+ y *= 10.0;
+ c++;
+ }
+ printf("%.*f", c, x);
+}
+
+void run_benchmark(char *name, void (*benchmark)(void*), void (*setup)(void*), void (*teardown)(void*), void* data, int count, int iter) {
+ int i;
+ double min = HUGE_VAL;
+ double sum = 0.0;
+ double max = 0.0;
+ for (i = 0; i < count; i++) {
+ double begin, total;
+ if (setup) setup(data);
+ begin = gettimedouble();
+ benchmark(data);
+ total = gettimedouble() - begin;
+ if (teardown) teardown(data);
+ if (total < min) min = total;
+ if (total > max) max = total;
+ sum += total;
+ }
+ printf("%s: min ", name);
+ print_number(min * 1000000.0 / iter);
+ printf("us / avg ");
+ print_number((sum / count) * 1000000.0 / iter);
+ printf("us / max ");
+ print_number(max * 1000000.0 / iter);
+ printf("us\n");
+}
+
+#endif
diff --git a/src/secp256k1/src/bench_internal.c b/src/secp256k1/src/bench_internal.c
new file mode 100644
index 0000000000..a960549b94
--- /dev/null
+++ b/src/secp256k1/src/bench_internal.c
@@ -0,0 +1,318 @@
+/**********************************************************************
+ * Copyright (c) 2014-2015 Pieter Wuille *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
+ **********************************************************************/
+#include <stdio.h>
+
+#include "include/secp256k1.h"
+
+#include "util.h"
+#include "hash_impl.h"
+#include "num_impl.h"
+#include "field_impl.h"
+#include "group_impl.h"
+#include "scalar_impl.h"
+#include "ecmult_impl.h"
+#include "bench.h"
+
+typedef struct {
+ secp256k1_scalar_t scalar_x, scalar_y;
+ secp256k1_fe_t fe_x, fe_y;
+ secp256k1_ge_t ge_x, ge_y;
+ secp256k1_gej_t gej_x, gej_y;
+ unsigned char data[32];
+ int wnaf[256];
+} bench_inv_t;
+
+void bench_setup(void* arg) {
+ bench_inv_t *data = (bench_inv_t*)arg;
+
+ static const unsigned char init_x[32] = {
+ 0x02, 0x03, 0x05, 0x07, 0x0b, 0x0d, 0x11, 0x13,
+ 0x17, 0x1d, 0x1f, 0x25, 0x29, 0x2b, 0x2f, 0x35,
+ 0x3b, 0x3d, 0x43, 0x47, 0x49, 0x4f, 0x53, 0x59,
+ 0x61, 0x65, 0x67, 0x6b, 0x6d, 0x71, 0x7f, 0x83
+ };
+
+ static const unsigned char init_y[32] = {
+ 0x82, 0x83, 0x85, 0x87, 0x8b, 0x8d, 0x81, 0x83,
+ 0x97, 0xad, 0xaf, 0xb5, 0xb9, 0xbb, 0xbf, 0xc5,
+ 0xdb, 0xdd, 0xe3, 0xe7, 0xe9, 0xef, 0xf3, 0xf9,
+ 0x11, 0x15, 0x17, 0x1b, 0x1d, 0xb1, 0xbf, 0xd3
+ };
+
+ secp256k1_scalar_set_b32(&data->scalar_x, init_x, NULL);
+ secp256k1_scalar_set_b32(&data->scalar_y, init_y, NULL);
+ secp256k1_fe_set_b32(&data->fe_x, init_x);
+ secp256k1_fe_set_b32(&data->fe_y, init_y);
+ CHECK(secp256k1_ge_set_xo_var(&data->ge_x, &data->fe_x, 0));
+ CHECK(secp256k1_ge_set_xo_var(&data->ge_y, &data->fe_y, 1));
+ secp256k1_gej_set_ge(&data->gej_x, &data->ge_x);
+ secp256k1_gej_set_ge(&data->gej_y, &data->ge_y);
+ memcpy(data->data, init_x, 32);
+}
+
+void bench_scalar_add(void* arg) {
+ int i;
+ bench_inv_t *data = (bench_inv_t*)arg;
+
+ for (i = 0; i < 2000000; i++) {
+ secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y);
+ }
+}
+
+void bench_scalar_negate(void* arg) {
+ int i;
+ bench_inv_t *data = (bench_inv_t*)arg;
+
+ for (i = 0; i < 2000000; i++) {
+ secp256k1_scalar_negate(&data->scalar_x, &data->scalar_x);
+ }
+}
+
+void bench_scalar_sqr(void* arg) {
+ int i;
+ bench_inv_t *data = (bench_inv_t*)arg;
+
+ for (i = 0; i < 200000; i++) {
+ secp256k1_scalar_sqr(&data->scalar_x, &data->scalar_x);
+ }
+}
+
+void bench_scalar_mul(void* arg) {
+ int i;
+ bench_inv_t *data = (bench_inv_t*)arg;
+
+ for (i = 0; i < 200000; i++) {
+ secp256k1_scalar_mul(&data->scalar_x, &data->scalar_x, &data->scalar_y);
+ }
+}
+
+#ifdef USE_ENDOMORPHISM
+void bench_scalar_split(void* arg) {
+ int i;
+ bench_inv_t *data = (bench_inv_t*)arg;
+
+ for (i = 0; i < 20000; i++) {
+ secp256k1_scalar_t l, r;
+ secp256k1_scalar_split_lambda_var(&l, &r, &data->scalar_x);
+ secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y);
+ }
+}
+#endif
+
+void bench_scalar_inverse(void* arg) {
+ int i;
+ bench_inv_t *data = (bench_inv_t*)arg;
+
+ for (i = 0; i < 2000; i++) {
+ secp256k1_scalar_inverse(&data->scalar_x, &data->scalar_x);
+ secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y);
+ }
+}
+
+void bench_scalar_inverse_var(void* arg) {
+ int i;
+ bench_inv_t *data = (bench_inv_t*)arg;
+
+ for (i = 0; i < 2000; i++) {
+ secp256k1_scalar_inverse_var(&data->scalar_x, &data->scalar_x);
+ secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y);
+ }
+}
+
+void bench_field_normalize(void* arg) {
+ int i;
+ bench_inv_t *data = (bench_inv_t*)arg;
+
+ for (i = 0; i < 2000000; i++) {
+ secp256k1_fe_normalize(&data->fe_x);
+ }
+}
+
+void bench_field_normalize_weak(void* arg) {
+ int i;
+ bench_inv_t *data = (bench_inv_t*)arg;
+
+ for (i = 0; i < 2000000; i++) {
+ secp256k1_fe_normalize_weak(&data->fe_x);
+ }
+}
+
+void bench_field_mul(void* arg) {
+ int i;
+ bench_inv_t *data = (bench_inv_t*)arg;
+
+ for (i = 0; i < 200000; i++) {
+ secp256k1_fe_mul(&data->fe_x, &data->fe_x, &data->fe_y);
+ }
+}
+
+void bench_field_sqr(void* arg) {
+ int i;
+ bench_inv_t *data = (bench_inv_t*)arg;
+
+ for (i = 0; i < 200000; i++) {
+ secp256k1_fe_sqr(&data->fe_x, &data->fe_x);
+ }
+}
+
+void bench_field_inverse(void* arg) {
+ int i;
+ bench_inv_t *data = (bench_inv_t*)arg;
+
+ for (i = 0; i < 20000; i++) {
+ secp256k1_fe_inv(&data->fe_x, &data->fe_x);
+ secp256k1_fe_add(&data->fe_x, &data->fe_y);
+ }
+}
+
+void bench_field_inverse_var(void* arg) {
+ int i;
+ bench_inv_t *data = (bench_inv_t*)arg;
+
+ for (i = 0; i < 20000; i++) {
+ secp256k1_fe_inv_var(&data->fe_x, &data->fe_x);
+ secp256k1_fe_add(&data->fe_x, &data->fe_y);
+ }
+}
+
+void bench_field_sqrt_var(void* arg) {
+ int i;
+ bench_inv_t *data = (bench_inv_t*)arg;
+
+ for (i = 0; i < 20000; i++) {
+ secp256k1_fe_sqrt_var(&data->fe_x, &data->fe_x);
+ secp256k1_fe_add(&data->fe_x, &data->fe_y);
+ }
+}
+
+void bench_group_double_var(void* arg) {
+ int i;
+ bench_inv_t *data = (bench_inv_t*)arg;
+
+ for (i = 0; i < 200000; i++) {
+ secp256k1_gej_double_var(&data->gej_x, &data->gej_x);
+ }
+}
+
+void bench_group_add_var(void* arg) {
+ int i;
+ bench_inv_t *data = (bench_inv_t*)arg;
+
+ for (i = 0; i < 200000; i++) {
+ secp256k1_gej_add_var(&data->gej_x, &data->gej_x, &data->gej_y);
+ }
+}
+
+void bench_group_add_affine(void* arg) {
+ int i;
+ bench_inv_t *data = (bench_inv_t*)arg;
+
+ for (i = 0; i < 200000; i++) {
+ secp256k1_gej_add_ge(&data->gej_x, &data->gej_x, &data->ge_y);
+ }
+}
+
+void bench_group_add_affine_var(void* arg) {
+ int i;
+ bench_inv_t *data = (bench_inv_t*)arg;
+
+ for (i = 0; i < 200000; i++) {
+ secp256k1_gej_add_ge_var(&data->gej_x, &data->gej_x, &data->ge_y);
+ }
+}
+
+void bench_ecmult_wnaf(void* arg) {
+ int i;
+ bench_inv_t *data = (bench_inv_t*)arg;
+
+ for (i = 0; i < 20000; i++) {
+ secp256k1_ecmult_wnaf(data->wnaf, &data->scalar_x, WINDOW_A);
+ secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y);
+ }
+}
+
+
+void bench_sha256(void* arg) {
+ int i;
+ bench_inv_t *data = (bench_inv_t*)arg;
+ secp256k1_sha256_t sha;
+
+ for (i = 0; i < 20000; i++) {
+ secp256k1_sha256_initialize(&sha);
+ secp256k1_sha256_write(&sha, data->data, 32);
+ secp256k1_sha256_finalize(&sha, data->data);
+ }
+}
+
+void bench_hmac_sha256(void* arg) {
+ int i;
+ bench_inv_t *data = (bench_inv_t*)arg;
+ secp256k1_hmac_sha256_t hmac;
+
+ for (i = 0; i < 20000; i++) {
+ secp256k1_hmac_sha256_initialize(&hmac, data->data, 32);
+ secp256k1_hmac_sha256_write(&hmac, data->data, 32);
+ secp256k1_hmac_sha256_finalize(&hmac, data->data);
+ }
+}
+
+void bench_rfc6979_hmac_sha256(void* arg) {
+ int i;
+ bench_inv_t *data = (bench_inv_t*)arg;
+ secp256k1_rfc6979_hmac_sha256_t rng;
+
+ for (i = 0; i < 20000; i++) {
+ secp256k1_rfc6979_hmac_sha256_initialize(&rng, data->data, 32, data->data, 32, NULL, 0);
+ secp256k1_rfc6979_hmac_sha256_generate(&rng, data->data, 32);
+ }
+}
+
+
+int have_flag(int argc, char** argv, char *flag) {
+ char** argm = argv + argc;
+ argv++;
+ if (argv == argm) {
+ return 1;
+ }
+ while (argv != NULL && argv != argm) {
+ if (strcmp(*argv, flag) == 0) return 1;
+ argv++;
+ }
+ return 0;
+}
+
+int main(int argc, char **argv) {
+ bench_inv_t data;
+ if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "add")) run_benchmark("scalar_add", bench_scalar_add, bench_setup, NULL, &data, 10, 2000000);
+ if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "negate")) run_benchmark("scalar_negate", bench_scalar_negate, bench_setup, NULL, &data, 10, 2000000);
+ if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "sqr")) run_benchmark("scalar_sqr", bench_scalar_sqr, bench_setup, NULL, &data, 10, 200000);
+ if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "mul")) run_benchmark("scalar_mul", bench_scalar_mul, bench_setup, NULL, &data, 10, 200000);
+#ifdef USE_ENDOMORPHISM
+ if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "split")) run_benchmark("scalar_split", bench_scalar_split, bench_setup, NULL, &data, 10, 20000);
+#endif
+ if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "inverse")) run_benchmark("scalar_inverse", bench_scalar_inverse, bench_setup, NULL, &data, 10, 2000);
+ if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "inverse")) run_benchmark("scalar_inverse_var", bench_scalar_inverse_var, bench_setup, NULL, &data, 10, 2000);
+
+ if (have_flag(argc, argv, "field") || have_flag(argc, argv, "normalize")) run_benchmark("field_normalize", bench_field_normalize, bench_setup, NULL, &data, 10, 2000000);
+ if (have_flag(argc, argv, "field") || have_flag(argc, argv, "normalize")) run_benchmark("field_normalize_weak", bench_field_normalize_weak, bench_setup, NULL, &data, 10, 2000000);
+ if (have_flag(argc, argv, "field") || have_flag(argc, argv, "sqr")) run_benchmark("field_sqr", bench_field_sqr, bench_setup, NULL, &data, 10, 200000);
+ if (have_flag(argc, argv, "field") || have_flag(argc, argv, "mul")) run_benchmark("field_mul", bench_field_mul, bench_setup, NULL, &data, 10, 200000);
+ if (have_flag(argc, argv, "field") || have_flag(argc, argv, "inverse")) run_benchmark("field_inverse", bench_field_inverse, bench_setup, NULL, &data, 10, 20000);
+ if (have_flag(argc, argv, "field") || have_flag(argc, argv, "inverse")) run_benchmark("field_inverse_var", bench_field_inverse_var, bench_setup, NULL, &data, 10, 20000);
+ if (have_flag(argc, argv, "field") || have_flag(argc, argv, "sqrt")) run_benchmark("field_sqrt_var", bench_field_sqrt_var, bench_setup, NULL, &data, 10, 20000);
+
+ if (have_flag(argc, argv, "group") || have_flag(argc, argv, "double")) run_benchmark("group_double_var", bench_group_double_var, bench_setup, NULL, &data, 10, 200000);
+ if (have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_var", bench_group_add_var, bench_setup, NULL, &data, 10, 200000);
+ if (have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_affine", bench_group_add_affine, bench_setup, NULL, &data, 10, 200000);
+ if (have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_affine_var", bench_group_add_affine_var, bench_setup, NULL, &data, 10, 200000);
+
+ if (have_flag(argc, argv, "ecmult") || have_flag(argc, argv, "wnaf")) run_benchmark("ecmult_wnaf", bench_ecmult_wnaf, bench_setup, NULL, &data, 10, 20000);
+
+ if (have_flag(argc, argv, "hash") || have_flag(argc, argv, "sha256")) run_benchmark("hash_sha256", bench_sha256, bench_setup, NULL, &data, 10, 20000);
+ if (have_flag(argc, argv, "hash") || have_flag(argc, argv, "hmac")) run_benchmark("hash_hmac_sha256", bench_hmac_sha256, bench_setup, NULL, &data, 10, 20000);
+ if (have_flag(argc, argv, "hash") || have_flag(argc, argv, "rng6979")) run_benchmark("hash_rfc6979_hmac_sha256", bench_rfc6979_hmac_sha256, bench_setup, NULL, &data, 10, 20000);
+ return 0;
+}
diff --git a/src/secp256k1/src/bench_recover.c b/src/secp256k1/src/bench_recover.c
new file mode 100644
index 0000000000..56faed11a0
--- /dev/null
+++ b/src/secp256k1/src/bench_recover.c
@@ -0,0 +1,51 @@
+/**********************************************************************
+ * Copyright (c) 2014 Pieter Wuille *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
+ **********************************************************************/
+
+#include "include/secp256k1.h"
+#include "util.h"
+#include "bench.h"
+
+typedef struct {
+ secp256k1_context_t *ctx;
+ unsigned char msg[32];
+ unsigned char sig[64];
+} bench_recover_t;
+
+void bench_recover(void* arg) {
+ int i;
+ bench_recover_t *data = (bench_recover_t*)arg;
+ unsigned char pubkey[33];
+
+ for (i = 0; i < 20000; i++) {
+ int j;
+ int pubkeylen = 33;
+ CHECK(secp256k1_ecdsa_recover_compact(data->ctx, data->msg, data->sig, pubkey, &pubkeylen, 1, i % 2));
+ for (j = 0; j < 32; j++) {
+ data->sig[j + 32] = data->msg[j]; /* Move former message to S. */
+ data->msg[j] = data->sig[j]; /* Move former R to message. */
+ data->sig[j] = pubkey[j + 1]; /* Move recovered pubkey X coordinate to R (which must be a valid X coordinate). */
+ }
+ }
+}
+
+void bench_recover_setup(void* arg) {
+ int i;
+ bench_recover_t *data = (bench_recover_t*)arg;
+
+ for (i = 0; i < 32; i++) data->msg[i] = 1 + i;
+ for (i = 0; i < 64; i++) data->sig[i] = 65 + i;
+}
+
+int main(void) {
+ bench_recover_t data;
+
+ data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY);
+
+ run_benchmark("ecdsa_recover", bench_recover, bench_recover_setup, NULL, &data, 10, 20000);
+
+ secp256k1_context_destroy(data.ctx);
+ return 0;
+}
diff --git a/src/secp256k1/src/bench_sign.c b/src/secp256k1/src/bench_sign.c
new file mode 100644
index 0000000000..072a37af51
--- /dev/null
+++ b/src/secp256k1/src/bench_sign.c
@@ -0,0 +1,50 @@
+/**********************************************************************
+ * Copyright (c) 2014 Pieter Wuille *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
+ **********************************************************************/
+
+#include "include/secp256k1.h"
+#include "util.h"
+#include "bench.h"
+
+typedef struct {
+ secp256k1_context_t* ctx;
+ unsigned char msg[32];
+ unsigned char key[32];
+} bench_sign_t;
+
+static void bench_sign_setup(void* arg) {
+ int i;
+ bench_sign_t *data = (bench_sign_t*)arg;
+
+ for (i = 0; i < 32; i++) data->msg[i] = i + 1;
+ for (i = 0; i < 32; i++) data->key[i] = i + 65;
+}
+
+static void bench_sign(void* arg) {
+ int i;
+ bench_sign_t *data = (bench_sign_t*)arg;
+
+ unsigned char sig[64];
+ for (i = 0; i < 20000; i++) {
+ int j;
+ int recid = 0;
+ CHECK(secp256k1_ecdsa_sign_compact(data->ctx, data->msg, sig, data->key, NULL, NULL, &recid));
+ for (j = 0; j < 32; j++) {
+ data->msg[j] = sig[j]; /* Move former R to message. */
+ data->key[j] = sig[j + 32]; /* Move former S to key. */
+ }
+ }
+}
+
+int main(void) {
+ bench_sign_t data;
+
+ data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN);
+
+ run_benchmark("ecdsa_sign", bench_sign, bench_sign_setup, NULL, &data, 10, 20000);
+
+ secp256k1_context_destroy(data.ctx);
+ return 0;
+}
diff --git a/src/secp256k1/src/bench_verify.c b/src/secp256k1/src/bench_verify.c
new file mode 100644
index 0000000000..c8c82752ce
--- /dev/null
+++ b/src/secp256k1/src/bench_verify.c
@@ -0,0 +1,56 @@
+/**********************************************************************
+ * Copyright (c) 2014 Pieter Wuille *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
+ **********************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+
+#include "include/secp256k1.h"
+#include "util.h"
+#include "bench.h"
+
+typedef struct {
+ secp256k1_context_t *ctx;
+ unsigned char msg[32];
+ unsigned char key[32];
+ unsigned char sig[72];
+ int siglen;
+ unsigned char pubkey[33];
+ int pubkeylen;
+} benchmark_verify_t;
+
+static void benchmark_verify(void* arg) {
+ int i;
+ benchmark_verify_t* data = (benchmark_verify_t*)arg;
+
+ for (i = 0; i < 20000; i++) {
+ data->sig[data->siglen - 1] ^= (i & 0xFF);
+ data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF);
+ data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF);
+ CHECK(secp256k1_ecdsa_verify(data->ctx, data->msg, data->sig, data->siglen, data->pubkey, data->pubkeylen) == (i == 0));
+ data->sig[data->siglen - 1] ^= (i & 0xFF);
+ data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF);
+ data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF);
+ }
+}
+
+int main(void) {
+ int i;
+ benchmark_verify_t data;
+
+ data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
+
+ for (i = 0; i < 32; i++) data.msg[i] = 1 + i;
+ for (i = 0; i < 32; i++) data.key[i] = 33 + i;
+ data.siglen = 72;
+ secp256k1_ecdsa_sign(data.ctx, data.msg, data.sig, &data.siglen, data.key, NULL, NULL);
+ data.pubkeylen = 33;
+ CHECK(secp256k1_ec_pubkey_create(data.ctx, data.pubkey, &data.pubkeylen, data.key, 1));
+
+ run_benchmark("ecdsa_verify", benchmark_verify, NULL, NULL, &data, 10, 20000);
+
+ secp256k1_context_destroy(data.ctx);
+ return 0;
+}
diff --git a/src/secp256k1/src/ecdsa.h b/src/secp256k1/src/ecdsa.h
new file mode 100644
index 0000000000..4ef78e8afb
--- /dev/null
+++ b/src/secp256k1/src/ecdsa.h
@@ -0,0 +1,24 @@
+/**********************************************************************
+ * Copyright (c) 2013, 2014 Pieter Wuille *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
+ **********************************************************************/
+
+#ifndef _SECP256K1_ECDSA_
+#define _SECP256K1_ECDSA_
+
+#include "scalar.h"
+#include "group.h"
+#include "ecmult.h"
+
+typedef struct {
+ secp256k1_scalar_t r, s;
+} secp256k1_ecdsa_sig_t;
+
+static int secp256k1_ecdsa_sig_parse(secp256k1_ecdsa_sig_t *r, const unsigned char *sig, int size);
+static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, int *size, const secp256k1_ecdsa_sig_t *a);
+static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context_t *ctx, const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message);
+static int secp256k1_ecdsa_sig_sign(const secp256k1_ecmult_gen_context_t *ctx, secp256k1_ecdsa_sig_t *sig, const secp256k1_scalar_t *seckey, const secp256k1_scalar_t *message, const secp256k1_scalar_t *nonce, int *recid);
+static int secp256k1_ecdsa_sig_recover(const secp256k1_ecmult_context_t *ctx, const secp256k1_ecdsa_sig_t *sig, secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message, int recid);
+
+#endif
diff --git a/src/secp256k1/src/ecdsa_impl.h b/src/secp256k1/src/ecdsa_impl.h
new file mode 100644
index 0000000000..ed1d228189
--- /dev/null
+++ b/src/secp256k1/src/ecdsa_impl.h
@@ -0,0 +1,263 @@
+/**********************************************************************
+ * Copyright (c) 2013, 2014 Pieter Wuille *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
+ **********************************************************************/
+
+
+#ifndef _SECP256K1_ECDSA_IMPL_H_
+#define _SECP256K1_ECDSA_IMPL_H_
+
+#include "scalar.h"
+#include "field.h"
+#include "group.h"
+#include "ecmult.h"
+#include "ecmult_gen.h"
+#include "ecdsa.h"
+
+/** Group order for secp256k1 defined as 'n' in "Standards for Efficient Cryptography" (SEC2) 2.7.1
+ * sage: for t in xrange(1023, -1, -1):
+ * .. p = 2**256 - 2**32 - t
+ * .. if p.is_prime():
+ * .. print '%x'%p
+ * .. break
+ * 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f'
+ * sage: a = 0
+ * sage: b = 7
+ * sage: F = FiniteField (p)
+ * sage: '%x' % (EllipticCurve ([F (a), F (b)]).order())
+ * 'fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141'
+ */
+static const secp256k1_fe_t secp256k1_ecdsa_const_order_as_fe = SECP256K1_FE_CONST(
+ 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFEUL,
+ 0xBAAEDCE6UL, 0xAF48A03BUL, 0xBFD25E8CUL, 0xD0364141UL
+);
+
+/** Difference between field and order, values 'p' and 'n' values defined in
+ * "Standards for Efficient Cryptography" (SEC2) 2.7.1.
+ * sage: p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
+ * sage: a = 0
+ * sage: b = 7
+ * sage: F = FiniteField (p)
+ * sage: '%x' % (p - EllipticCurve ([F (a), F (b)]).order())
+ * '14551231950b75fc4402da1722fc9baee'
+ */
+static const secp256k1_fe_t secp256k1_ecdsa_const_p_minus_order = SECP256K1_FE_CONST(
+ 0, 0, 0, 1, 0x45512319UL, 0x50B75FC4UL, 0x402DA172UL, 0x2FC9BAEEUL
+);
+
+static int secp256k1_ecdsa_sig_parse(secp256k1_ecdsa_sig_t *r, const unsigned char *sig, int size) {
+ unsigned char ra[32] = {0}, sa[32] = {0};
+ const unsigned char *rp;
+ const unsigned char *sp;
+ int lenr;
+ int lens;
+ int overflow;
+ if (sig[0] != 0x30) {
+ return 0;
+ }
+ lenr = sig[3];
+ if (5+lenr >= size) {
+ return 0;
+ }
+ lens = sig[lenr+5];
+ if (sig[1] != lenr+lens+4) {
+ return 0;
+ }
+ if (lenr+lens+6 > size) {
+ return 0;
+ }
+ if (sig[2] != 0x02) {
+ return 0;
+ }
+ if (lenr == 0) {
+ return 0;
+ }
+ if (sig[lenr+4] != 0x02) {
+ return 0;
+ }
+ if (lens == 0) {
+ return 0;
+ }
+ sp = sig + 6 + lenr;
+ while (lens > 0 && sp[0] == 0) {
+ lens--;
+ sp++;
+ }
+ if (lens > 32) {
+ return 0;
+ }
+ rp = sig + 4;
+ while (lenr > 0 && rp[0] == 0) {
+ lenr--;
+ rp++;
+ }
+ if (lenr > 32) {
+ return 0;
+ }
+ memcpy(ra + 32 - lenr, rp, lenr);
+ memcpy(sa + 32 - lens, sp, lens);
+ overflow = 0;
+ secp256k1_scalar_set_b32(&r->r, ra, &overflow);
+ if (overflow) {
+ return 0;
+ }
+ secp256k1_scalar_set_b32(&r->s, sa, &overflow);
+ if (overflow) {
+ return 0;
+ }
+ return 1;
+}
+
+static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, int *size, const secp256k1_ecdsa_sig_t *a) {
+ unsigned char r[33] = {0}, s[33] = {0};
+ unsigned char *rp = r, *sp = s;
+ int lenR = 33, lenS = 33;
+ secp256k1_scalar_get_b32(&r[1], &a->r);
+ secp256k1_scalar_get_b32(&s[1], &a->s);
+ while (lenR > 1 && rp[0] == 0 && rp[1] < 0x80) { lenR--; rp++; }
+ while (lenS > 1 && sp[0] == 0 && sp[1] < 0x80) { lenS--; sp++; }
+ if (*size < 6+lenS+lenR) {
+ return 0;
+ }
+ *size = 6 + lenS + lenR;
+ sig[0] = 0x30;
+ sig[1] = 4 + lenS + lenR;
+ sig[2] = 0x02;
+ sig[3] = lenR;
+ memcpy(sig+4, rp, lenR);
+ sig[4+lenR] = 0x02;
+ sig[5+lenR] = lenS;
+ memcpy(sig+lenR+6, sp, lenS);
+ return 1;
+}
+
+static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context_t *ctx, const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message) {
+ unsigned char c[32];
+ secp256k1_scalar_t sn, u1, u2;
+ secp256k1_fe_t xr;
+ secp256k1_gej_t pubkeyj;
+ secp256k1_gej_t pr;
+
+ if (secp256k1_scalar_is_zero(&sig->r) || secp256k1_scalar_is_zero(&sig->s)) {
+ return 0;
+ }
+
+ secp256k1_scalar_inverse_var(&sn, &sig->s);
+ secp256k1_scalar_mul(&u1, &sn, message);
+ secp256k1_scalar_mul(&u2, &sn, &sig->r);
+ secp256k1_gej_set_ge(&pubkeyj, pubkey);
+ secp256k1_ecmult(ctx, &pr, &pubkeyj, &u2, &u1);
+ if (secp256k1_gej_is_infinity(&pr)) {
+ return 0;
+ }
+ secp256k1_scalar_get_b32(c, &sig->r);
+ secp256k1_fe_set_b32(&xr, c);
+
+ /** We now have the recomputed R point in pr, and its claimed x coordinate (modulo n)
+ * in xr. Naively, we would extract the x coordinate from pr (requiring a inversion modulo p),
+ * compute the remainder modulo n, and compare it to xr. However:
+ *
+ * xr == X(pr) mod n
+ * <=> exists h. (xr + h * n < p && xr + h * n == X(pr))
+ * [Since 2 * n > p, h can only be 0 or 1]
+ * <=> (xr == X(pr)) || (xr + n < p && xr + n == X(pr))
+ * [In Jacobian coordinates, X(pr) is pr.x / pr.z^2 mod p]
+ * <=> (xr == pr.x / pr.z^2 mod p) || (xr + n < p && xr + n == pr.x / pr.z^2 mod p)
+ * [Multiplying both sides of the equations by pr.z^2 mod p]
+ * <=> (xr * pr.z^2 mod p == pr.x) || (xr + n < p && (xr + n) * pr.z^2 mod p == pr.x)
+ *
+ * Thus, we can avoid the inversion, but we have to check both cases separately.
+ * secp256k1_gej_eq_x implements the (xr * pr.z^2 mod p == pr.x) test.
+ */
+ if (secp256k1_gej_eq_x_var(&xr, &pr)) {
+ /* xr.x == xr * xr.z^2 mod p, so the signature is valid. */
+ return 1;
+ }
+ if (secp256k1_fe_cmp_var(&xr, &secp256k1_ecdsa_const_p_minus_order) >= 0) {
+ /* xr + p >= n, so we can skip testing the second case. */
+ return 0;
+ }
+ secp256k1_fe_add(&xr, &secp256k1_ecdsa_const_order_as_fe);
+ if (secp256k1_gej_eq_x_var(&xr, &pr)) {
+ /* (xr + n) * pr.z^2 mod p == pr.x, so the signature is valid. */
+ return 1;
+ }
+ return 0;
+}
+
+static int secp256k1_ecdsa_sig_recover(const secp256k1_ecmult_context_t *ctx, const secp256k1_ecdsa_sig_t *sig, secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message, int recid) {
+ unsigned char brx[32];
+ secp256k1_fe_t fx;
+ secp256k1_ge_t x;
+ secp256k1_gej_t xj;
+ secp256k1_scalar_t rn, u1, u2;
+ secp256k1_gej_t qj;
+
+ if (secp256k1_scalar_is_zero(&sig->r) || secp256k1_scalar_is_zero(&sig->s)) {
+ return 0;
+ }
+
+ secp256k1_scalar_get_b32(brx, &sig->r);
+ VERIFY_CHECK(secp256k1_fe_set_b32(&fx, brx)); /* brx comes from a scalar, so is less than the order; certainly less than p */
+ if (recid & 2) {
+ if (secp256k1_fe_cmp_var(&fx, &secp256k1_ecdsa_const_p_minus_order) >= 0) {
+ return 0;
+ }
+ secp256k1_fe_add(&fx, &secp256k1_ecdsa_const_order_as_fe);
+ }
+ if (!secp256k1_ge_set_xo_var(&x, &fx, recid & 1)) {
+ return 0;
+ }
+ secp256k1_gej_set_ge(&xj, &x);
+ secp256k1_scalar_inverse_var(&rn, &sig->r);
+ secp256k1_scalar_mul(&u1, &rn, message);
+ secp256k1_scalar_negate(&u1, &u1);
+ secp256k1_scalar_mul(&u2, &rn, &sig->s);
+ secp256k1_ecmult(ctx, &qj, &xj, &u2, &u1);
+ secp256k1_ge_set_gej_var(pubkey, &qj);
+ return !secp256k1_gej_is_infinity(&qj);
+}
+
+static int secp256k1_ecdsa_sig_sign(const secp256k1_ecmult_gen_context_t *ctx, secp256k1_ecdsa_sig_t *sig, const secp256k1_scalar_t *seckey, const secp256k1_scalar_t *message, const secp256k1_scalar_t *nonce, int *recid) {
+ unsigned char b[32];
+ secp256k1_gej_t rp;
+ secp256k1_ge_t r;
+ secp256k1_scalar_t n;
+ int overflow = 0;
+
+ secp256k1_ecmult_gen(ctx, &rp, nonce);
+ secp256k1_ge_set_gej(&r, &rp);
+ secp256k1_fe_normalize(&r.x);
+ secp256k1_fe_normalize(&r.y);
+ secp256k1_fe_get_b32(b, &r.x);
+ secp256k1_scalar_set_b32(&sig->r, b, &overflow);
+ if (secp256k1_scalar_is_zero(&sig->r)) {
+ /* P.x = order is on the curve, so technically sig->r could end up zero, which would be an invalid signature. */
+ secp256k1_gej_clear(&rp);
+ secp256k1_ge_clear(&r);
+ return 0;
+ }
+ if (recid) {
+ *recid = (overflow ? 2 : 0) | (secp256k1_fe_is_odd(&r.y) ? 1 : 0);
+ }
+ secp256k1_scalar_mul(&n, &sig->r, seckey);
+ secp256k1_scalar_add(&n, &n, message);
+ secp256k1_scalar_inverse(&sig->s, nonce);
+ secp256k1_scalar_mul(&sig->s, &sig->s, &n);
+ secp256k1_scalar_clear(&n);
+ secp256k1_gej_clear(&rp);
+ secp256k1_ge_clear(&r);
+ if (secp256k1_scalar_is_zero(&sig->s)) {
+ return 0;
+ }
+ if (secp256k1_scalar_is_high(&sig->s)) {
+ secp256k1_scalar_negate(&sig->s, &sig->s);
+ if (recid) {
+ *recid ^= 1;
+ }
+ }
+ return 1;
+}
+
+#endif
diff --git a/src/secp256k1/src/eckey.h b/src/secp256k1/src/eckey.h
new file mode 100644
index 0000000000..53b818485e
--- /dev/null
+++ b/src/secp256k1/src/eckey.h
@@ -0,0 +1,26 @@
+/**********************************************************************
+ * Copyright (c) 2013, 2014 Pieter Wuille *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
+ **********************************************************************/
+
+#ifndef _SECP256K1_ECKEY_
+#define _SECP256K1_ECKEY_
+
+#include "group.h"
+#include "scalar.h"
+#include "ecmult.h"
+#include "ecmult_gen.h"
+
+static int secp256k1_eckey_pubkey_parse(secp256k1_ge_t *elem, const unsigned char *pub, int size);
+static int secp256k1_eckey_pubkey_serialize(secp256k1_ge_t *elem, unsigned char *pub, int *size, int compressed);
+
+static int secp256k1_eckey_privkey_parse(secp256k1_scalar_t *key, const unsigned char *privkey, int privkeylen);
+static int secp256k1_eckey_privkey_serialize(const secp256k1_ecmult_gen_context_t *ctx, unsigned char *privkey, int *privkeylen, const secp256k1_scalar_t *key, int compressed);
+
+static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar_t *key, const secp256k1_scalar_t *tweak);
+static int secp256k1_eckey_pubkey_tweak_add(const secp256k1_ecmult_context_t *ctx, secp256k1_ge_t *key, const secp256k1_scalar_t *tweak);
+static int secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar_t *key, const secp256k1_scalar_t *tweak);
+static int secp256k1_eckey_pubkey_tweak_mul(const secp256k1_ecmult_context_t *ctx, secp256k1_ge_t *key, const secp256k1_scalar_t *tweak);
+
+#endif
diff --git a/src/secp256k1/src/eckey_impl.h b/src/secp256k1/src/eckey_impl.h
new file mode 100644
index 0000000000..a332bd34ec
--- /dev/null
+++ b/src/secp256k1/src/eckey_impl.h
@@ -0,0 +1,202 @@
+/**********************************************************************
+ * Copyright (c) 2013, 2014 Pieter Wuille *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
+ **********************************************************************/
+
+#ifndef _SECP256K1_ECKEY_IMPL_H_
+#define _SECP256K1_ECKEY_IMPL_H_
+
+#include "eckey.h"
+
+#include "scalar.h"
+#include "field.h"
+#include "group.h"
+#include "ecmult_gen.h"
+
+static int secp256k1_eckey_pubkey_parse(secp256k1_ge_t *elem, const unsigned char *pub, int size) {
+ if (size == 33 && (pub[0] == 0x02 || pub[0] == 0x03)) {
+ secp256k1_fe_t x;
+ return secp256k1_fe_set_b32(&x, pub+1) && secp256k1_ge_set_xo_var(elem, &x, pub[0] == 0x03);
+ } else if (size == 65 && (pub[0] == 0x04 || pub[0] == 0x06 || pub[0] == 0x07)) {
+ secp256k1_fe_t x, y;
+ if (!secp256k1_fe_set_b32(&x, pub+1) || !secp256k1_fe_set_b32(&y, pub+33)) {
+ return 0;
+ }
+ secp256k1_ge_set_xy(elem, &x, &y);
+ if ((pub[0] == 0x06 || pub[0] == 0x07) && secp256k1_fe_is_odd(&y) != (pub[0] == 0x07)) {
+ return 0;
+ }
+ return secp256k1_ge_is_valid_var(elem);
+ } else {
+ return 0;
+ }
+}
+
+static int secp256k1_eckey_pubkey_serialize(secp256k1_ge_t *elem, unsigned char *pub, int *size, int compressed) {
+ if (secp256k1_ge_is_infinity(elem)) {
+ return 0;
+ }
+ secp256k1_fe_normalize_var(&elem->x);
+ secp256k1_fe_normalize_var(&elem->y);
+ secp256k1_fe_get_b32(&pub[1], &elem->x);
+ if (compressed) {
+ *size = 33;
+ pub[0] = 0x02 | (secp256k1_fe_is_odd(&elem->y) ? 0x01 : 0x00);
+ } else {
+ *size = 65;
+ pub[0] = 0x04;
+ secp256k1_fe_get_b32(&pub[33], &elem->y);
+ }
+ return 1;
+}
+
+static int secp256k1_eckey_privkey_parse(secp256k1_scalar_t *key, const unsigned char *privkey, int privkeylen) {
+ unsigned char c[32] = {0};
+ const unsigned char *end = privkey + privkeylen;
+ int lenb = 0;
+ int len = 0;
+ int overflow = 0;
+ /* sequence header */
+ if (end < privkey+1 || *privkey != 0x30) {
+ return 0;
+ }
+ privkey++;
+ /* sequence length constructor */
+ if (end < privkey+1 || !(*privkey & 0x80)) {
+ return 0;
+ }
+ lenb = *privkey & ~0x80; privkey++;
+ if (lenb < 1 || lenb > 2) {
+ return 0;
+ }
+ if (end < privkey+lenb) {
+ return 0;
+ }
+ /* sequence length */
+ len = privkey[lenb-1] | (lenb > 1 ? privkey[lenb-2] << 8 : 0);
+ privkey += lenb;
+ if (end < privkey+len) {
+ return 0;
+ }
+ /* sequence element 0: version number (=1) */
+ if (end < privkey+3 || privkey[0] != 0x02 || privkey[1] != 0x01 || privkey[2] != 0x01) {
+ return 0;
+ }
+ privkey += 3;
+ /* sequence element 1: octet string, up to 32 bytes */
+ if (end < privkey+2 || privkey[0] != 0x04 || privkey[1] > 0x20 || end < privkey+2+privkey[1]) {
+ return 0;
+ }
+ memcpy(c + 32 - privkey[1], privkey + 2, privkey[1]);
+ secp256k1_scalar_set_b32(key, c, &overflow);
+ memset(c, 0, 32);
+ return !overflow;
+}
+
+static int secp256k1_eckey_privkey_serialize(const secp256k1_ecmult_gen_context_t *ctx, unsigned char *privkey, int *privkeylen, const secp256k1_scalar_t *key, int compressed) {
+ secp256k1_gej_t rp;
+ secp256k1_ge_t r;
+ int pubkeylen = 0;
+ secp256k1_ecmult_gen(ctx, &rp, key);
+ secp256k1_ge_set_gej(&r, &rp);
+ if (compressed) {
+ static const unsigned char begin[] = {
+ 0x30,0x81,0xD3,0x02,0x01,0x01,0x04,0x20
+ };
+ static const unsigned char middle[] = {
+ 0xA0,0x81,0x85,0x30,0x81,0x82,0x02,0x01,0x01,0x30,0x2C,0x06,0x07,0x2A,0x86,0x48,
+ 0xCE,0x3D,0x01,0x01,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F,0x30,0x06,0x04,0x01,0x00,0x04,0x01,0x07,0x04,
+ 0x21,0x02,0x79,0xBE,0x66,0x7E,0xF9,0xDC,0xBB,0xAC,0x55,0xA0,0x62,0x95,0xCE,0x87,
+ 0x0B,0x07,0x02,0x9B,0xFC,0xDB,0x2D,0xCE,0x28,0xD9,0x59,0xF2,0x81,0x5B,0x16,0xF8,
+ 0x17,0x98,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFE,0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,0xBF,0xD2,0x5E,
+ 0x8C,0xD0,0x36,0x41,0x41,0x02,0x01,0x01,0xA1,0x24,0x03,0x22,0x00
+ };
+ unsigned char *ptr = privkey;
+ memcpy(ptr, begin, sizeof(begin)); ptr += sizeof(begin);
+ secp256k1_scalar_get_b32(ptr, key); ptr += 32;
+ memcpy(ptr, middle, sizeof(middle)); ptr += sizeof(middle);
+ if (!secp256k1_eckey_pubkey_serialize(&r, ptr, &pubkeylen, 1)) {
+ return 0;
+ }
+ ptr += pubkeylen;
+ *privkeylen = ptr - privkey;
+ } else {
+ static const unsigned char begin[] = {
+ 0x30,0x82,0x01,0x13,0x02,0x01,0x01,0x04,0x20
+ };
+ static const unsigned char middle[] = {
+ 0xA0,0x81,0xA5,0x30,0x81,0xA2,0x02,0x01,0x01,0x30,0x2C,0x06,0x07,0x2A,0x86,0x48,
+ 0xCE,0x3D,0x01,0x01,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F,0x30,0x06,0x04,0x01,0x00,0x04,0x01,0x07,0x04,
+ 0x41,0x04,0x79,0xBE,0x66,0x7E,0xF9,0xDC,0xBB,0xAC,0x55,0xA0,0x62,0x95,0xCE,0x87,
+ 0x0B,0x07,0x02,0x9B,0xFC,0xDB,0x2D,0xCE,0x28,0xD9,0x59,0xF2,0x81,0x5B,0x16,0xF8,
+ 0x17,0x98,0x48,0x3A,0xDA,0x77,0x26,0xA3,0xC4,0x65,0x5D,0xA4,0xFB,0xFC,0x0E,0x11,
+ 0x08,0xA8,0xFD,0x17,0xB4,0x48,0xA6,0x85,0x54,0x19,0x9C,0x47,0xD0,0x8F,0xFB,0x10,
+ 0xD4,0xB8,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFE,0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,0xBF,0xD2,0x5E,
+ 0x8C,0xD0,0x36,0x41,0x41,0x02,0x01,0x01,0xA1,0x44,0x03,0x42,0x00
+ };
+ unsigned char *ptr = privkey;
+ memcpy(ptr, begin, sizeof(begin)); ptr += sizeof(begin);
+ secp256k1_scalar_get_b32(ptr, key); ptr += 32;
+ memcpy(ptr, middle, sizeof(middle)); ptr += sizeof(middle);
+ if (!secp256k1_eckey_pubkey_serialize(&r, ptr, &pubkeylen, 0)) {
+ return 0;
+ }
+ ptr += pubkeylen;
+ *privkeylen = ptr - privkey;
+ }
+ return 1;
+}
+
+static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar_t *key, const secp256k1_scalar_t *tweak) {
+ secp256k1_scalar_add(key, key, tweak);
+ if (secp256k1_scalar_is_zero(key)) {
+ return 0;
+ }
+ return 1;
+}
+
+static int secp256k1_eckey_pubkey_tweak_add(const secp256k1_ecmult_context_t *ctx, secp256k1_ge_t *key, const secp256k1_scalar_t *tweak) {
+ secp256k1_gej_t pt;
+ secp256k1_scalar_t one;
+ secp256k1_gej_set_ge(&pt, key);
+ secp256k1_scalar_set_int(&one, 1);
+ secp256k1_ecmult(ctx, &pt, &pt, &one, tweak);
+
+ if (secp256k1_gej_is_infinity(&pt)) {
+ return 0;
+ }
+ secp256k1_ge_set_gej(key, &pt);
+ return 1;
+}
+
+static int secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar_t *key, const secp256k1_scalar_t *tweak) {
+ if (secp256k1_scalar_is_zero(tweak)) {
+ return 0;
+ }
+
+ secp256k1_scalar_mul(key, key, tweak);
+ return 1;
+}
+
+static int secp256k1_eckey_pubkey_tweak_mul(const secp256k1_ecmult_context_t *ctx, secp256k1_ge_t *key, const secp256k1_scalar_t *tweak) {
+ secp256k1_scalar_t zero;
+ secp256k1_gej_t pt;
+ if (secp256k1_scalar_is_zero(tweak)) {
+ return 0;
+ }
+
+ secp256k1_scalar_set_int(&zero, 0);
+ secp256k1_gej_set_ge(&pt, key);
+ secp256k1_ecmult(ctx, &pt, &pt, tweak, &zero);
+ secp256k1_ge_set_gej(key, &pt);
+ return 1;
+}
+
+#endif
diff --git a/src/secp256k1/src/ecmult.h b/src/secp256k1/src/ecmult.h
new file mode 100644
index 0000000000..bab9e4ef52
--- /dev/null
+++ b/src/secp256k1/src/ecmult.h
@@ -0,0 +1,31 @@
+/**********************************************************************
+ * Copyright (c) 2013, 2014 Pieter Wuille *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
+ **********************************************************************/
+
+#ifndef _SECP256K1_ECMULT_
+#define _SECP256K1_ECMULT_
+
+#include "num.h"
+#include "group.h"
+
+typedef struct {
+ /* For accelerating the computation of a*P + b*G: */
+ secp256k1_ge_storage_t (*pre_g)[]; /* odd multiples of the generator */
+#ifdef USE_ENDOMORPHISM
+ secp256k1_ge_storage_t (*pre_g_128)[]; /* odd multiples of 2^128*generator */
+#endif
+} secp256k1_ecmult_context_t;
+
+static void secp256k1_ecmult_context_init(secp256k1_ecmult_context_t *ctx);
+static void secp256k1_ecmult_context_build(secp256k1_ecmult_context_t *ctx);
+static void secp256k1_ecmult_context_clone(secp256k1_ecmult_context_t *dst,
+ const secp256k1_ecmult_context_t *src);
+static void secp256k1_ecmult_context_clear(secp256k1_ecmult_context_t *ctx);
+static int secp256k1_ecmult_context_is_built(const secp256k1_ecmult_context_t *ctx);
+
+/** Double multiply: R = na*A + ng*G */
+static void secp256k1_ecmult(const secp256k1_ecmult_context_t *ctx, secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_scalar_t *na, const secp256k1_scalar_t *ng);
+
+#endif
diff --git a/src/secp256k1/src/ecmult_gen.h b/src/secp256k1/src/ecmult_gen.h
new file mode 100644
index 0000000000..3745633c47
--- /dev/null
+++ b/src/secp256k1/src/ecmult_gen.h
@@ -0,0 +1,43 @@
+/**********************************************************************
+ * Copyright (c) 2013, 2014 Pieter Wuille *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
+ **********************************************************************/
+
+#ifndef _SECP256K1_ECMULT_GEN_
+#define _SECP256K1_ECMULT_GEN_
+
+#include "scalar.h"
+#include "group.h"
+
+typedef struct {
+ /* For accelerating the computation of a*G:
+ * To harden against timing attacks, use the following mechanism:
+ * * Break up the multiplicand into groups of 4 bits, called n_0, n_1, n_2, ..., n_63.
+ * * Compute sum(n_i * 16^i * G + U_i, i=0..63), where:
+ * * U_i = U * 2^i (for i=0..62)
+ * * U_i = U * (1-2^63) (for i=63)
+ * where U is a point with no known corresponding scalar. Note that sum(U_i, i=0..63) = 0.
+ * For each i, and each of the 16 possible values of n_i, (n_i * 16^i * G + U_i) is
+ * precomputed (call it prec(i, n_i)). The formula now becomes sum(prec(i, n_i), i=0..63).
+ * None of the resulting prec group elements have a known scalar, and neither do any of
+ * the intermediate sums while computing a*G.
+ */
+ secp256k1_ge_storage_t (*prec)[64][16]; /* prec[j][i] = 16^j * i * G + U_i */
+ secp256k1_scalar_t blind;
+ secp256k1_gej_t initial;
+} secp256k1_ecmult_gen_context_t;
+
+static void secp256k1_ecmult_gen_context_init(secp256k1_ecmult_gen_context_t* ctx);
+static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context_t* ctx);
+static void secp256k1_ecmult_gen_context_clone(secp256k1_ecmult_gen_context_t *dst,
+ const secp256k1_ecmult_gen_context_t* src);
+static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context_t* ctx);
+static int secp256k1_ecmult_gen_context_is_built(const secp256k1_ecmult_gen_context_t* ctx);
+
+/** Multiply with the generator: R = a*G */
+static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context_t* ctx, secp256k1_gej_t *r, const secp256k1_scalar_t *a);
+
+static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context_t *ctx, const unsigned char *seed32);
+
+#endif
diff --git a/src/secp256k1/src/ecmult_gen_impl.h b/src/secp256k1/src/ecmult_gen_impl.h
new file mode 100644
index 0000000000..4697753ac8
--- /dev/null
+++ b/src/secp256k1/src/ecmult_gen_impl.h
@@ -0,0 +1,184 @@
+/**********************************************************************
+ * Copyright (c) 2013, 2014, 2015 Pieter Wuille, Gregory Maxwell *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
+ **********************************************************************/
+
+#ifndef _SECP256K1_ECMULT_GEN_IMPL_H_
+#define _SECP256K1_ECMULT_GEN_IMPL_H_
+
+#include "scalar.h"
+#include "group.h"
+#include "ecmult_gen.h"
+#include "hash_impl.h"
+
+static void secp256k1_ecmult_gen_context_init(secp256k1_ecmult_gen_context_t *ctx) {
+ ctx->prec = NULL;
+}
+
+static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context_t *ctx) {
+ secp256k1_ge_t prec[1024];
+ secp256k1_gej_t gj;
+ secp256k1_gej_t nums_gej;
+ int i, j;
+
+ if (ctx->prec != NULL) {
+ return;
+ }
+
+ ctx->prec = (secp256k1_ge_storage_t (*)[64][16])checked_malloc(sizeof(*ctx->prec));
+
+ /* get the generator */
+ secp256k1_gej_set_ge(&gj, &secp256k1_ge_const_g);
+
+ /* Construct a group element with no known corresponding scalar (nothing up my sleeve). */
+ {
+ static const unsigned char nums_b32[33] = "The scalar for this x is unknown";
+ secp256k1_fe_t nums_x;
+ secp256k1_ge_t nums_ge;
+ VERIFY_CHECK(secp256k1_fe_set_b32(&nums_x, nums_b32));
+ VERIFY_CHECK(secp256k1_ge_set_xo_var(&nums_ge, &nums_x, 0));
+ secp256k1_gej_set_ge(&nums_gej, &nums_ge);
+ /* Add G to make the bits in x uniformly distributed. */
+ secp256k1_gej_add_ge_var(&nums_gej, &nums_gej, &secp256k1_ge_const_g);
+ }
+
+ /* compute prec. */
+ {
+ secp256k1_gej_t precj[1024]; /* Jacobian versions of prec. */
+ secp256k1_gej_t gbase;
+ secp256k1_gej_t numsbase;
+ gbase = gj; /* 16^j * G */
+ numsbase = nums_gej; /* 2^j * nums. */
+ for (j = 0; j < 64; j++) {
+ /* Set precj[j*16 .. j*16+15] to (numsbase, numsbase + gbase, ..., numsbase + 15*gbase). */
+ precj[j*16] = numsbase;
+ for (i = 1; i < 16; i++) {
+ secp256k1_gej_add_var(&precj[j*16 + i], &precj[j*16 + i - 1], &gbase);
+ }
+ /* Multiply gbase by 16. */
+ for (i = 0; i < 4; i++) {
+ secp256k1_gej_double_var(&gbase, &gbase);
+ }
+ /* Multiply numbase by 2. */
+ secp256k1_gej_double_var(&numsbase, &numsbase);
+ if (j == 62) {
+ /* In the last iteration, numsbase is (1 - 2^j) * nums instead. */
+ secp256k1_gej_neg(&numsbase, &numsbase);
+ secp256k1_gej_add_var(&numsbase, &numsbase, &nums_gej);
+ }
+ }
+ secp256k1_ge_set_all_gej_var(1024, prec, precj);
+ }
+ for (j = 0; j < 64; j++) {
+ for (i = 0; i < 16; i++) {
+ secp256k1_ge_to_storage(&(*ctx->prec)[j][i], &prec[j*16 + i]);
+ }
+ }
+ secp256k1_ecmult_gen_blind(ctx, NULL);
+}
+
+static int secp256k1_ecmult_gen_context_is_built(const secp256k1_ecmult_gen_context_t* ctx) {
+ return ctx->prec != NULL;
+}
+
+static void secp256k1_ecmult_gen_context_clone(secp256k1_ecmult_gen_context_t *dst,
+ const secp256k1_ecmult_gen_context_t *src) {
+ if (src->prec == NULL) {
+ dst->prec = NULL;
+ } else {
+ dst->prec = (secp256k1_ge_storage_t (*)[64][16])checked_malloc(sizeof(*dst->prec));
+ memcpy(dst->prec, src->prec, sizeof(*dst->prec));
+ dst->initial = src->initial;
+ dst->blind = src->blind;
+ }
+}
+
+static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context_t *ctx) {
+ free(ctx->prec);
+ secp256k1_scalar_clear(&ctx->blind);
+ secp256k1_gej_clear(&ctx->initial);
+ ctx->prec = NULL;
+}
+
+static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context_t *ctx, secp256k1_gej_t *r, const secp256k1_scalar_t *gn) {
+ secp256k1_ge_t add;
+ secp256k1_ge_storage_t adds;
+ secp256k1_scalar_t gnb;
+ int bits;
+ int i, j;
+ memset(&adds, 0, sizeof(adds));
+ *r = ctx->initial;
+ /* Blind scalar/point multiplication by computing (n-b)G + bG instead of nG. */
+ secp256k1_scalar_add(&gnb, gn, &ctx->blind);
+ add.infinity = 0;
+ for (j = 0; j < 64; j++) {
+ bits = secp256k1_scalar_get_bits(&gnb, j * 4, 4);
+ for (i = 0; i < 16; i++) {
+ /** This uses a conditional move to avoid any secret data in array indexes.
+ * _Any_ use of secret indexes has been demonstrated to result in timing
+ * sidechannels, even when the cache-line access patterns are uniform.
+ * See also:
+ * "A word of warning", CHES 2013 Rump Session, by Daniel J. Bernstein and Peter Schwabe
+ * (https://cryptojedi.org/peter/data/chesrump-20130822.pdf) and
+ * "Cache Attacks and Countermeasures: the Case of AES", RSA 2006,
+ * by Dag Arne Osvik, Adi Shamir, and Eran Tromer
+ * (http://www.tau.ac.il/~tromer/papers/cache.pdf)
+ */
+ secp256k1_ge_storage_cmov(&adds, &(*ctx->prec)[j][i], i == bits);
+ }
+ secp256k1_ge_from_storage(&add, &adds);
+ secp256k1_gej_add_ge(r, r, &add);
+ }
+ bits = 0;
+ secp256k1_ge_clear(&add);
+ secp256k1_scalar_clear(&gnb);
+}
+
+/* Setup blinding values for secp256k1_ecmult_gen. */
+static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context_t *ctx, const unsigned char *seed32) {
+ secp256k1_scalar_t b;
+ secp256k1_gej_t gb;
+ secp256k1_fe_t s;
+ unsigned char nonce32[32];
+ secp256k1_rfc6979_hmac_sha256_t rng;
+ int retry;
+ if (!seed32) {
+ /* When seed is NULL, reset the initial point and blinding value. */
+ secp256k1_gej_set_ge(&ctx->initial, &secp256k1_ge_const_g);
+ secp256k1_gej_neg(&ctx->initial, &ctx->initial);
+ secp256k1_scalar_set_int(&ctx->blind, 1);
+ }
+ /* The prior blinding value (if not reset) is chained forward by including it in the hash. */
+ secp256k1_scalar_get_b32(nonce32, &ctx->blind);
+ /** Using a CSPRNG allows a failure free interface, avoids needing large amounts of random data,
+ * and guards against weak or adversarial seeds. This is a simpler and safer interface than
+ * asking the caller for blinding values directly and expecting them to retry on failure.
+ */
+ secp256k1_rfc6979_hmac_sha256_initialize(&rng, seed32 ? seed32 : nonce32, 32, nonce32, 32, NULL, 0);
+ /* Retry for out of range results to achieve uniformity. */
+ do {
+ secp256k1_rfc6979_hmac_sha256_generate(&rng, nonce32, 32);
+ retry = !secp256k1_fe_set_b32(&s, nonce32);
+ retry |= secp256k1_fe_is_zero(&s);
+ } while (retry);
+ /* Randomize the projection to defend against multiplier sidechannels. */
+ secp256k1_gej_rescale(&ctx->initial, &s);
+ secp256k1_fe_clear(&s);
+ do {
+ secp256k1_rfc6979_hmac_sha256_generate(&rng, nonce32, 32);
+ secp256k1_scalar_set_b32(&b, nonce32, &retry);
+ /* A blinding value of 0 works, but would undermine the projection hardening. */
+ retry |= secp256k1_scalar_is_zero(&b);
+ } while (retry);
+ secp256k1_rfc6979_hmac_sha256_finalize(&rng);
+ memset(nonce32, 0, 32);
+ secp256k1_ecmult_gen(ctx, &gb, &b);
+ secp256k1_scalar_negate(&b, &b);
+ ctx->blind = b;
+ ctx->initial = gb;
+ secp256k1_scalar_clear(&b);
+ secp256k1_gej_clear(&gb);
+}
+
+#endif
diff --git a/src/secp256k1/src/ecmult_impl.h b/src/secp256k1/src/ecmult_impl.h
new file mode 100644
index 0000000000..1b2856f83d
--- /dev/null
+++ b/src/secp256k1/src/ecmult_impl.h
@@ -0,0 +1,317 @@
+/**********************************************************************
+ * Copyright (c) 2013, 2014 Pieter Wuille *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
+ **********************************************************************/
+
+#ifndef _SECP256K1_ECMULT_IMPL_H_
+#define _SECP256K1_ECMULT_IMPL_H_
+
+#include "group.h"
+#include "scalar.h"
+#include "ecmult.h"
+
+/* optimal for 128-bit and 256-bit exponents. */
+#define WINDOW_A 5
+
+/** larger numbers may result in slightly better performance, at the cost of
+ exponentially larger precomputed tables. */
+#ifdef USE_ENDOMORPHISM
+/** Two tables for window size 15: 1.375 MiB. */
+#define WINDOW_G 15
+#else
+/** One table for window size 16: 1.375 MiB. */
+#define WINDOW_G 16
+#endif
+
+/** Fill a table 'pre' with precomputed odd multiples of a. W determines the size of the table.
+ * pre will contains the values [1*a,3*a,5*a,...,(2^(w-1)-1)*a], so it needs place for
+ * 2^(w-2) entries.
+ *
+ * There are two versions of this function:
+ * - secp256k1_ecmult_precomp_wnaf_gej, which operates on group elements in jacobian notation,
+ * fast to precompute, but slower to use in later additions.
+ * - secp256k1_ecmult_precomp_wnaf_ge, which operates on group elements in affine notations,
+ * (much) slower to precompute, but a bit faster to use in later additions.
+ * To compute a*P + b*G, we use the jacobian version for P, and the affine version for G, as
+ * G is constant, so it only needs to be done once in advance.
+ */
+static void secp256k1_ecmult_table_precomp_gej_var(secp256k1_gej_t *pre, const secp256k1_gej_t *a, int w) {
+ secp256k1_gej_t d;
+ int i;
+ pre[0] = *a;
+ secp256k1_gej_double_var(&d, &pre[0]);
+ for (i = 1; i < (1 << (w-2)); i++) {
+ secp256k1_gej_add_var(&pre[i], &d, &pre[i-1]);
+ }
+}
+
+static void secp256k1_ecmult_table_precomp_ge_storage_var(secp256k1_ge_storage_t *pre, const secp256k1_gej_t *a, int w) {
+ secp256k1_gej_t d;
+ int i;
+ const int table_size = 1 << (w-2);
+ secp256k1_gej_t *prej = (secp256k1_gej_t *)checked_malloc(sizeof(secp256k1_gej_t) * table_size);
+ secp256k1_ge_t *prea = (secp256k1_ge_t *)checked_malloc(sizeof(secp256k1_ge_t) * table_size);
+ prej[0] = *a;
+ secp256k1_gej_double_var(&d, a);
+ for (i = 1; i < table_size; i++) {
+ secp256k1_gej_add_var(&prej[i], &d, &prej[i-1]);
+ }
+ secp256k1_ge_set_all_gej_var(table_size, prea, prej);
+ for (i = 0; i < table_size; i++) {
+ secp256k1_ge_to_storage(&pre[i], &prea[i]);
+ }
+ free(prej);
+ free(prea);
+}
+
+/** The number of entries a table with precomputed multiples needs to have. */
+#define ECMULT_TABLE_SIZE(w) (1 << ((w)-2))
+
+/** The following two macro retrieves a particular odd multiple from a table
+ * of precomputed multiples. */
+#define ECMULT_TABLE_GET_GEJ(r,pre,n,w) do { \
+ VERIFY_CHECK(((n) & 1) == 1); \
+ VERIFY_CHECK((n) >= -((1 << ((w)-1)) - 1)); \
+ VERIFY_CHECK((n) <= ((1 << ((w)-1)) - 1)); \
+ if ((n) > 0) { \
+ *(r) = (pre)[((n)-1)/2]; \
+ } else { \
+ secp256k1_gej_neg((r), &(pre)[(-(n)-1)/2]); \
+ } \
+} while(0)
+#define ECMULT_TABLE_GET_GE_STORAGE(r,pre,n,w) do { \
+ VERIFY_CHECK(((n) & 1) == 1); \
+ VERIFY_CHECK((n) >= -((1 << ((w)-1)) - 1)); \
+ VERIFY_CHECK((n) <= ((1 << ((w)-1)) - 1)); \
+ if ((n) > 0) { \
+ secp256k1_ge_from_storage((r), &(pre)[((n)-1)/2]); \
+ } else { \
+ secp256k1_ge_from_storage((r), &(pre)[(-(n)-1)/2]); \
+ secp256k1_ge_neg((r), (r)); \
+ } \
+} while(0)
+
+static void secp256k1_ecmult_context_init(secp256k1_ecmult_context_t *ctx) {
+ ctx->pre_g = NULL;
+#ifdef USE_ENDOMORPHISM
+ ctx->pre_g_128 = NULL;
+#endif
+}
+
+static void secp256k1_ecmult_context_build(secp256k1_ecmult_context_t *ctx) {
+ secp256k1_gej_t gj;
+
+ if (ctx->pre_g != NULL) {
+ return;
+ }
+
+ /* get the generator */
+ secp256k1_gej_set_ge(&gj, &secp256k1_ge_const_g);
+
+ ctx->pre_g = (secp256k1_ge_storage_t (*)[])checked_malloc(sizeof((*ctx->pre_g)[0]) * ECMULT_TABLE_SIZE(WINDOW_G));
+
+ /* precompute the tables with odd multiples */
+ secp256k1_ecmult_table_precomp_ge_storage_var(*ctx->pre_g, &gj, WINDOW_G);
+
+#ifdef USE_ENDOMORPHISM
+ {
+ secp256k1_gej_t g_128j;
+ int i;
+
+ ctx->pre_g_128 = (secp256k1_ge_storage_t (*)[])checked_malloc(sizeof((*ctx->pre_g_128)[0]) * ECMULT_TABLE_SIZE(WINDOW_G));
+
+ /* calculate 2^128*generator */
+ g_128j = gj;
+ for (i = 0; i < 128; i++) {
+ secp256k1_gej_double_var(&g_128j, &g_128j);
+ }
+ secp256k1_ecmult_table_precomp_ge_storage_var(*ctx->pre_g_128, &g_128j, WINDOW_G);
+ }
+#endif
+}
+
+static void secp256k1_ecmult_context_clone(secp256k1_ecmult_context_t *dst,
+ const secp256k1_ecmult_context_t *src) {
+ if (src->pre_g == NULL) {
+ dst->pre_g = NULL;
+ } else {
+ size_t size = sizeof((*dst->pre_g)[0]) * ECMULT_TABLE_SIZE(WINDOW_G);
+ dst->pre_g = (secp256k1_ge_storage_t (*)[])checked_malloc(size);
+ memcpy(dst->pre_g, src->pre_g, size);
+ }
+#ifdef USE_ENDOMORPHISM
+ if (src->pre_g_128 == NULL) {
+ dst->pre_g_128 = NULL;
+ } else {
+ size_t size = sizeof((*dst->pre_g_128)[0]) * ECMULT_TABLE_SIZE(WINDOW_G);
+ dst->pre_g_128 = (secp256k1_ge_storage_t (*)[])checked_malloc(size);
+ memcpy(dst->pre_g_128, src->pre_g_128, size);
+ }
+#endif
+}
+
+static int secp256k1_ecmult_context_is_built(const secp256k1_ecmult_context_t *ctx) {
+ return ctx->pre_g != NULL;
+}
+
+static void secp256k1_ecmult_context_clear(secp256k1_ecmult_context_t *ctx) {
+ free(ctx->pre_g);
+#ifdef USE_ENDOMORPHISM
+ free(ctx->pre_g_128);
+#endif
+ secp256k1_ecmult_context_init(ctx);
+}
+
+/** Convert a number to WNAF notation. The number becomes represented by sum(2^i * wnaf[i], i=0..bits),
+ * with the following guarantees:
+ * - each wnaf[i] is either 0, or an odd integer between -(1<<(w-1) - 1) and (1<<(w-1) - 1)
+ * - two non-zero entries in wnaf are separated by at least w-1 zeroes.
+ * - the number of set values in wnaf is returned. This number is at most 256, and at most one more
+ * - than the number of bits in the (absolute value) of the input.
+ */
+static int secp256k1_ecmult_wnaf(int *wnaf, const secp256k1_scalar_t *a, int w) {
+ secp256k1_scalar_t s = *a;
+ int set_bits = 0;
+ int bit = 0;
+ int sign = 1;
+
+ if (secp256k1_scalar_get_bits(&s, 255, 1)) {
+ secp256k1_scalar_negate(&s, &s);
+ sign = -1;
+ }
+
+ while (bit < 256) {
+ int now;
+ int word;
+ if (secp256k1_scalar_get_bits(&s, bit, 1) == 0) {
+ bit++;
+ continue;
+ }
+ while (set_bits < bit) {
+ wnaf[set_bits++] = 0;
+ }
+ now = w;
+ if (bit + now > 256) {
+ now = 256 - bit;
+ }
+ word = secp256k1_scalar_get_bits_var(&s, bit, now);
+ if (word & (1 << (w-1))) {
+ secp256k1_scalar_add_bit(&s, bit + w);
+ wnaf[set_bits++] = sign * (word - (1 << w));
+ } else {
+ wnaf[set_bits++] = sign * word;
+ }
+ bit += now;
+ }
+ return set_bits;
+}
+
+static void secp256k1_ecmult(const secp256k1_ecmult_context_t *ctx, secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_scalar_t *na, const secp256k1_scalar_t *ng) {
+ secp256k1_gej_t tmpj;
+ secp256k1_gej_t pre_a[ECMULT_TABLE_SIZE(WINDOW_A)];
+ secp256k1_ge_t tmpa;
+#ifdef USE_ENDOMORPHISM
+ secp256k1_gej_t pre_a_lam[ECMULT_TABLE_SIZE(WINDOW_A)];
+ secp256k1_scalar_t na_1, na_lam;
+ /* Splitted G factors. */
+ secp256k1_scalar_t ng_1, ng_128;
+ int wnaf_na_1[130];
+ int wnaf_na_lam[130];
+ int bits_na_1;
+ int bits_na_lam;
+ int wnaf_ng_1[129];
+ int bits_ng_1;
+ int wnaf_ng_128[129];
+ int bits_ng_128;
+#else
+ int wnaf_na[256];
+ int bits_na;
+ int wnaf_ng[257];
+ int bits_ng;
+#endif
+ int i;
+ int bits;
+
+#ifdef USE_ENDOMORPHISM
+ /* split na into na_1 and na_lam (where na = na_1 + na_lam*lambda, and na_1 and na_lam are ~128 bit) */
+ secp256k1_scalar_split_lambda_var(&na_1, &na_lam, na);
+
+ /* build wnaf representation for na_1 and na_lam. */
+ bits_na_1 = secp256k1_ecmult_wnaf(wnaf_na_1, &na_1, WINDOW_A);
+ bits_na_lam = secp256k1_ecmult_wnaf(wnaf_na_lam, &na_lam, WINDOW_A);
+ VERIFY_CHECK(bits_na_1 <= 130);
+ VERIFY_CHECK(bits_na_lam <= 130);
+ bits = bits_na_1;
+ if (bits_na_lam > bits) {
+ bits = bits_na_lam;
+ }
+#else
+ /* build wnaf representation for na. */
+ bits_na = secp256k1_ecmult_wnaf(wnaf_na, na, WINDOW_A);
+ bits = bits_na;
+#endif
+
+ /* calculate odd multiples of a */
+ secp256k1_ecmult_table_precomp_gej_var(pre_a, a, WINDOW_A);
+
+#ifdef USE_ENDOMORPHISM
+ for (i = 0; i < ECMULT_TABLE_SIZE(WINDOW_A); i++) {
+ secp256k1_gej_mul_lambda(&pre_a_lam[i], &pre_a[i]);
+ }
+
+ /* split ng into ng_1 and ng_128 (where gn = gn_1 + gn_128*2^128, and gn_1 and gn_128 are ~128 bit) */
+ secp256k1_scalar_split_128(&ng_1, &ng_128, ng);
+
+ /* Build wnaf representation for ng_1 and ng_128 */
+ bits_ng_1 = secp256k1_ecmult_wnaf(wnaf_ng_1, &ng_1, WINDOW_G);
+ bits_ng_128 = secp256k1_ecmult_wnaf(wnaf_ng_128, &ng_128, WINDOW_G);
+ if (bits_ng_1 > bits) {
+ bits = bits_ng_1;
+ }
+ if (bits_ng_128 > bits) {
+ bits = bits_ng_128;
+ }
+#else
+ bits_ng = secp256k1_ecmult_wnaf(wnaf_ng, ng, WINDOW_G);
+ if (bits_ng > bits) {
+ bits = bits_ng;
+ }
+#endif
+
+ secp256k1_gej_set_infinity(r);
+
+ for (i = bits-1; i >= 0; i--) {
+ int n;
+ secp256k1_gej_double_var(r, r);
+#ifdef USE_ENDOMORPHISM
+ if (i < bits_na_1 && (n = wnaf_na_1[i])) {
+ ECMULT_TABLE_GET_GEJ(&tmpj, pre_a, n, WINDOW_A);
+ secp256k1_gej_add_var(r, r, &tmpj);
+ }
+ if (i < bits_na_lam && (n = wnaf_na_lam[i])) {
+ ECMULT_TABLE_GET_GEJ(&tmpj, pre_a_lam, n, WINDOW_A);
+ secp256k1_gej_add_var(r, r, &tmpj);
+ }
+ if (i < bits_ng_1 && (n = wnaf_ng_1[i])) {
+ ECMULT_TABLE_GET_GE_STORAGE(&tmpa, *ctx->pre_g, n, WINDOW_G);
+ secp256k1_gej_add_ge_var(r, r, &tmpa);
+ }
+ if (i < bits_ng_128 && (n = wnaf_ng_128[i])) {
+ ECMULT_TABLE_GET_GE_STORAGE(&tmpa, *ctx->pre_g_128, n, WINDOW_G);
+ secp256k1_gej_add_ge_var(r, r, &tmpa);
+ }
+#else
+ if (i < bits_na && (n = wnaf_na[i])) {
+ ECMULT_TABLE_GET_GEJ(&tmpj, pre_a, n, WINDOW_A);
+ secp256k1_gej_add_var(r, r, &tmpj);
+ }
+ if (i < bits_ng && (n = wnaf_ng[i])) {
+ ECMULT_TABLE_GET_GE_STORAGE(&tmpa, *ctx->pre_g, n, WINDOW_G);
+ secp256k1_gej_add_ge_var(r, r, &tmpa);
+ }
+#endif
+ }
+}
+
+#endif
diff --git a/src/secp256k1/src/field.h b/src/secp256k1/src/field.h
new file mode 100644
index 0000000000..41b280892d
--- /dev/null
+++ b/src/secp256k1/src/field.h
@@ -0,0 +1,119 @@
+/**********************************************************************
+ * Copyright (c) 2013, 2014 Pieter Wuille *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
+ **********************************************************************/
+
+#ifndef _SECP256K1_FIELD_
+#define _SECP256K1_FIELD_
+
+/** Field element module.
+ *
+ * Field elements can be represented in several ways, but code accessing
+ * it (and implementations) need to take certain properaties into account:
+ * - Each field element can be normalized or not.
+ * - Each field element has a magnitude, which represents how far away
+ * its representation is away from normalization. Normalized elements
+ * always have a magnitude of 1, but a magnitude of 1 doesn't imply
+ * normality.
+ */
+
+#if defined HAVE_CONFIG_H
+#include "libsecp256k1-config.h"
+#endif
+
+#if defined(USE_FIELD_10X26)
+#include "field_10x26.h"
+#elif defined(USE_FIELD_5X52)
+#include "field_5x52.h"
+#else
+#error "Please select field implementation"
+#endif
+
+/** Normalize a field element. */
+static void secp256k1_fe_normalize(secp256k1_fe_t *r);
+
+/** Weakly normalize a field element: reduce it magnitude to 1, but don't fully normalize. */
+static void secp256k1_fe_normalize_weak(secp256k1_fe_t *r);
+
+/** Normalize a field element, without constant-time guarantee. */
+static void secp256k1_fe_normalize_var(secp256k1_fe_t *r);
+
+/** Verify whether a field element represents zero i.e. would normalize to a zero value. The field
+ * implementation may optionally normalize the input, but this should not be relied upon. */
+static int secp256k1_fe_normalizes_to_zero(secp256k1_fe_t *r);
+
+/** Verify whether a field element represents zero i.e. would normalize to a zero value. The field
+ * implementation may optionally normalize the input, but this should not be relied upon. */
+static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe_t *r);
+
+/** Set a field element equal to a small integer. Resulting field element is normalized. */
+static void secp256k1_fe_set_int(secp256k1_fe_t *r, int a);
+
+/** Verify whether a field element is zero. Requires the input to be normalized. */
+static int secp256k1_fe_is_zero(const secp256k1_fe_t *a);
+
+/** Check the "oddness" of a field element. Requires the input to be normalized. */
+static int secp256k1_fe_is_odd(const secp256k1_fe_t *a);
+
+/** Compare two field elements. Requires magnitude-1 inputs. */
+static int secp256k1_fe_equal_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b);
+
+/** Compare two field elements. Requires both inputs to be normalized */
+static int secp256k1_fe_cmp_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b);
+
+/** Set a field element equal to 32-byte big endian value. If succesful, the resulting field element is normalized. */
+static int secp256k1_fe_set_b32(secp256k1_fe_t *r, const unsigned char *a);
+
+/** Convert a field element to a 32-byte big endian value. Requires the input to be normalized */
+static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe_t *a);
+
+/** Set a field element equal to the additive inverse of another. Takes a maximum magnitude of the input
+ * as an argument. The magnitude of the output is one higher. */
+static void secp256k1_fe_negate(secp256k1_fe_t *r, const secp256k1_fe_t *a, int m);
+
+/** Multiplies the passed field element with a small integer constant. Multiplies the magnitude by that
+ * small integer. */
+static void secp256k1_fe_mul_int(secp256k1_fe_t *r, int a);
+
+/** Adds a field element to another. The result has the sum of the inputs' magnitudes as magnitude. */
+static void secp256k1_fe_add(secp256k1_fe_t *r, const secp256k1_fe_t *a);
+
+/** Sets a field element to be the product of two others. Requires the inputs' magnitudes to be at most 8.
+ * The output magnitude is 1 (but not guaranteed to be normalized). */
+static void secp256k1_fe_mul(secp256k1_fe_t *r, const secp256k1_fe_t *a, const secp256k1_fe_t * SECP256K1_RESTRICT b);
+
+/** Sets a field element to be the square of another. Requires the input's magnitude to be at most 8.
+ * The output magnitude is 1 (but not guaranteed to be normalized). */
+static void secp256k1_fe_sqr(secp256k1_fe_t *r, const secp256k1_fe_t *a);
+
+/** Sets a field element to be the (modular) square root (if any exist) of another. Requires the
+ * input's magnitude to be at most 8. The output magnitude is 1 (but not guaranteed to be
+ * normalized). Return value indicates whether a square root was found. */
+static int secp256k1_fe_sqrt_var(secp256k1_fe_t *r, const secp256k1_fe_t *a);
+
+/** Sets a field element to be the (modular) inverse of another. Requires the input's magnitude to be
+ * at most 8. The output magnitude is 1 (but not guaranteed to be normalized). */
+static void secp256k1_fe_inv(secp256k1_fe_t *r, const secp256k1_fe_t *a);
+
+/** Potentially faster version of secp256k1_fe_inv, without constant-time guarantee. */
+static void secp256k1_fe_inv_var(secp256k1_fe_t *r, const secp256k1_fe_t *a);
+
+/** Calculate the (modular) inverses of a batch of field elements. Requires the inputs' magnitudes to be
+ * at most 8. The output magnitudes are 1 (but not guaranteed to be normalized). The inputs and
+ * outputs must not overlap in memory. */
+static void secp256k1_fe_inv_all_var(size_t len, secp256k1_fe_t *r, const secp256k1_fe_t *a);
+
+/** Convert a field element to the storage type. */
+static void secp256k1_fe_to_storage(secp256k1_fe_storage_t *r, const secp256k1_fe_t*);
+
+/** Convert a field element back from the storage type. */
+static void secp256k1_fe_from_storage(secp256k1_fe_t *r, const secp256k1_fe_storage_t*);
+
+/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. */
+static void secp256k1_fe_storage_cmov(secp256k1_fe_storage_t *r, const secp256k1_fe_storage_t *a, int flag);
+
+/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. */
+static void secp256k1_fe_cmov(secp256k1_fe_t *r, const secp256k1_fe_t *a, int flag);
+
+#endif
diff --git a/src/secp256k1/src/field_10x26.h b/src/secp256k1/src/field_10x26.h
new file mode 100644
index 0000000000..44bce6525d
--- /dev/null
+++ b/src/secp256k1/src/field_10x26.h
@@ -0,0 +1,47 @@
+/**********************************************************************
+ * Copyright (c) 2013, 2014 Pieter Wuille *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
+ **********************************************************************/
+
+#ifndef _SECP256K1_FIELD_REPR_
+#define _SECP256K1_FIELD_REPR_
+
+#include <stdint.h>
+
+typedef struct {
+ /* X = sum(i=0..9, elem[i]*2^26) mod n */
+ uint32_t n[10];
+#ifdef VERIFY
+ int magnitude;
+ int normalized;
+#endif
+} secp256k1_fe_t;
+
+/* Unpacks a constant into a overlapping multi-limbed FE element. */
+#define SECP256K1_FE_CONST_INNER(d7, d6, d5, d4, d3, d2, d1, d0) { \
+ (d0) & 0x3FFFFFFUL, \
+ ((d0) >> 26) | ((d1) & 0xFFFFFUL) << 6, \
+ ((d1) >> 20) | ((d2) & 0x3FFFUL) << 12, \
+ ((d2) >> 14) | ((d3) & 0xFFUL) << 18, \
+ ((d3) >> 8) | ((d4) & 0x3) << 24, \
+ ((d4) >> 2) & 0x3FFFFFFUL, \
+ ((d4) >> 28) | ((d5) & 0x3FFFFFUL) << 4, \
+ ((d5) >> 22) | ((d6) & 0xFFFF) << 10, \
+ ((d6) >> 16) | ((d7) & 0x3FF) << 16, \
+ ((d7) >> 10) \
+}
+
+#ifdef VERIFY
+#define SECP256K1_FE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {SECP256K1_FE_CONST_INNER((d7), (d6), (d5), (d4), (d3), (d2), (d1), (d0)), 1, 1}
+#else
+#define SECP256K1_FE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {SECP256K1_FE_CONST_INNER((d7), (d6), (d5), (d4), (d3), (d2), (d1), (d0))}
+#endif
+
+typedef struct {
+ uint32_t n[8];
+} secp256k1_fe_storage_t;
+
+#define SECP256K1_FE_STORAGE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{ (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }}
+
+#endif
diff --git a/src/secp256k1/src/field_10x26_impl.h b/src/secp256k1/src/field_10x26_impl.h
new file mode 100644
index 0000000000..871b91f912
--- /dev/null
+++ b/src/secp256k1/src/field_10x26_impl.h
@@ -0,0 +1,1136 @@
+/**********************************************************************
+ * Copyright (c) 2013, 2014 Pieter Wuille *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
+ **********************************************************************/
+
+#ifndef _SECP256K1_FIELD_REPR_IMPL_H_
+#define _SECP256K1_FIELD_REPR_IMPL_H_
+
+#include <stdio.h>
+#include <string.h>
+#include "util.h"
+#include "num.h"
+#include "field.h"
+
+#ifdef VERIFY
+static void secp256k1_fe_verify(const secp256k1_fe_t *a) {
+ const uint32_t *d = a->n;
+ int m = a->normalized ? 1 : 2 * a->magnitude, r = 1;
+ r &= (d[0] <= 0x3FFFFFFUL * m);
+ r &= (d[1] <= 0x3FFFFFFUL * m);
+ r &= (d[2] <= 0x3FFFFFFUL * m);
+ r &= (d[3] <= 0x3FFFFFFUL * m);
+ r &= (d[4] <= 0x3FFFFFFUL * m);
+ r &= (d[5] <= 0x3FFFFFFUL * m);
+ r &= (d[6] <= 0x3FFFFFFUL * m);
+ r &= (d[7] <= 0x3FFFFFFUL * m);
+ r &= (d[8] <= 0x3FFFFFFUL * m);
+ r &= (d[9] <= 0x03FFFFFUL * m);
+ r &= (a->magnitude >= 0);
+ r &= (a->magnitude <= 32);
+ if (a->normalized) {
+ r &= (a->magnitude <= 1);
+ if (r && (d[9] == 0x03FFFFFUL)) {
+ uint32_t mid = d[8] & d[7] & d[6] & d[5] & d[4] & d[3] & d[2];
+ if (mid == 0x3FFFFFFUL) {
+ r &= ((d[1] + 0x40UL + ((d[0] + 0x3D1UL) >> 26)) <= 0x3FFFFFFUL);
+ }
+ }
+ }
+ VERIFY_CHECK(r == 1);
+}
+#else
+static void secp256k1_fe_verify(const secp256k1_fe_t *a) {
+ (void)a;
+}
+#endif
+
+static void secp256k1_fe_normalize(secp256k1_fe_t *r) {
+ uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4],
+ t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9];
+
+ /* Reduce t9 at the start so there will be at most a single carry from the first pass */
+ uint32_t m;
+ uint32_t x = t9 >> 22; t9 &= 0x03FFFFFUL;
+
+ /* The first pass ensures the magnitude is 1, ... */
+ t0 += x * 0x3D1UL; t1 += (x << 6);
+ t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL;
+ t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL;
+ t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; m = t2;
+ t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; m &= t3;
+ t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; m &= t4;
+ t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; m &= t5;
+ t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; m &= t6;
+ t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; m &= t7;
+ t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; m &= t8;
+
+ /* ... except for a possible carry at bit 22 of t9 (i.e. bit 256 of the field element) */
+ VERIFY_CHECK(t9 >> 23 == 0);
+
+ /* At most a single final reduction is needed; check if the value is >= the field characteristic */
+ x = (t9 >> 22) | ((t9 == 0x03FFFFFUL) & (m == 0x3FFFFFFUL)
+ & ((t1 + 0x40UL + ((t0 + 0x3D1UL) >> 26)) > 0x3FFFFFFUL));
+
+ /* Apply the final reduction (for constant-time behaviour, we do it always) */
+ t0 += x * 0x3D1UL; t1 += (x << 6);
+ t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL;
+ t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL;
+ t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL;
+ t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL;
+ t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL;
+ t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL;
+ t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL;
+ t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL;
+ t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL;
+
+ /* If t9 didn't carry to bit 22 already, then it should have after any final reduction */
+ VERIFY_CHECK(t9 >> 22 == x);
+
+ /* Mask off the possible multiple of 2^256 from the final reduction */
+ t9 &= 0x03FFFFFUL;
+
+ r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4;
+ r->n[5] = t5; r->n[6] = t6; r->n[7] = t7; r->n[8] = t8; r->n[9] = t9;
+
+#ifdef VERIFY
+ r->magnitude = 1;
+ r->normalized = 1;
+ secp256k1_fe_verify(r);
+#endif
+}
+
+static void secp256k1_fe_normalize_weak(secp256k1_fe_t *r) {
+ uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4],
+ t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9];
+
+ /* Reduce t9 at the start so there will be at most a single carry from the first pass */
+ uint32_t x = t9 >> 22; t9 &= 0x03FFFFFUL;
+
+ /* The first pass ensures the magnitude is 1, ... */
+ t0 += x * 0x3D1UL; t1 += (x << 6);
+ t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL;
+ t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL;
+ t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL;
+ t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL;
+ t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL;
+ t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL;
+ t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL;
+ t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL;
+ t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL;
+
+ /* ... except for a possible carry at bit 22 of t9 (i.e. bit 256 of the field element) */
+ VERIFY_CHECK(t9 >> 23 == 0);
+
+ r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4;
+ r->n[5] = t5; r->n[6] = t6; r->n[7] = t7; r->n[8] = t8; r->n[9] = t9;
+
+#ifdef VERIFY
+ r->magnitude = 1;
+ secp256k1_fe_verify(r);
+#endif
+}
+
+static void secp256k1_fe_normalize_var(secp256k1_fe_t *r) {
+ uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4],
+ t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9];
+
+ /* Reduce t9 at the start so there will be at most a single carry from the first pass */
+ uint32_t m;
+ uint32_t x = t9 >> 22; t9 &= 0x03FFFFFUL;
+
+ /* The first pass ensures the magnitude is 1, ... */
+ t0 += x * 0x3D1UL; t1 += (x << 6);
+ t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL;
+ t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL;
+ t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; m = t2;
+ t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; m &= t3;
+ t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; m &= t4;
+ t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; m &= t5;
+ t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; m &= t6;
+ t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; m &= t7;
+ t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; m &= t8;
+
+ /* ... except for a possible carry at bit 22 of t9 (i.e. bit 256 of the field element) */
+ VERIFY_CHECK(t9 >> 23 == 0);
+
+ /* At most a single final reduction is needed; check if the value is >= the field characteristic */
+ x = (t9 >> 22) | ((t9 == 0x03FFFFFUL) & (m == 0x3FFFFFFUL)
+ & ((t1 + 0x40UL + ((t0 + 0x3D1UL) >> 26)) > 0x3FFFFFFUL));
+
+ if (x) {
+ t0 += 0x3D1UL; t1 += (x << 6);
+ t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL;
+ t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL;
+ t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL;
+ t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL;
+ t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL;
+ t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL;
+ t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL;
+ t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL;
+ t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL;
+
+ /* If t9 didn't carry to bit 22 already, then it should have after any final reduction */
+ VERIFY_CHECK(t9 >> 22 == x);
+
+ /* Mask off the possible multiple of 2^256 from the final reduction */
+ t9 &= 0x03FFFFFUL;
+ }
+
+ r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4;
+ r->n[5] = t5; r->n[6] = t6; r->n[7] = t7; r->n[8] = t8; r->n[9] = t9;
+
+#ifdef VERIFY
+ r->magnitude = 1;
+ r->normalized = 1;
+ secp256k1_fe_verify(r);
+#endif
+}
+
+static int secp256k1_fe_normalizes_to_zero(secp256k1_fe_t *r) {
+ uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4],
+ t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9];
+
+ /* z0 tracks a possible raw value of 0, z1 tracks a possible raw value of P */
+ uint32_t z0, z1;
+
+ /* Reduce t9 at the start so there will be at most a single carry from the first pass */
+ uint32_t x = t9 >> 22; t9 &= 0x03FFFFFUL;
+
+ /* The first pass ensures the magnitude is 1, ... */
+ t0 += x * 0x3D1UL; t1 += (x << 6);
+ t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL; z0 = t0; z1 = t0 ^ 0x3D0UL;
+ t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL; z0 |= t1; z1 &= t1 ^ 0x40UL;
+ t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; z0 |= t2; z1 &= t2;
+ t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; z0 |= t3; z1 &= t3;
+ t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; z0 |= t4; z1 &= t4;
+ t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; z0 |= t5; z1 &= t5;
+ t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; z0 |= t6; z1 &= t6;
+ t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; z0 |= t7; z1 &= t7;
+ t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; z0 |= t8; z1 &= t8;
+ z0 |= t9; z1 &= t9 ^ 0x3C00000UL;
+
+ /* ... except for a possible carry at bit 22 of t9 (i.e. bit 256 of the field element) */
+ VERIFY_CHECK(t9 >> 23 == 0);
+
+ return (z0 == 0) | (z1 == 0x3FFFFFFUL);
+}
+
+static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe_t *r) {
+ uint32_t t0, t1, t2, t3, t4, t5, t6, t7, t8, t9;
+ uint32_t z0, z1;
+ uint32_t x;
+
+ t0 = r->n[0];
+ t9 = r->n[9];
+
+ /* Reduce t9 at the start so there will be at most a single carry from the first pass */
+ x = t9 >> 22;
+
+ /* The first pass ensures the magnitude is 1, ... */
+ t0 += x * 0x3D1UL;
+
+ /* z0 tracks a possible raw value of 0, z1 tracks a possible raw value of P */
+ z0 = t0 & 0x3FFFFFFUL;
+ z1 = z0 ^ 0x3D0UL;
+
+ /* Fast return path should catch the majority of cases */
+ if ((z0 != 0UL) & (z1 != 0x3FFFFFFUL)) {
+ return 0;
+ }
+
+ t1 = r->n[1];
+ t2 = r->n[2];
+ t3 = r->n[3];
+ t4 = r->n[4];
+ t5 = r->n[5];
+ t6 = r->n[6];
+ t7 = r->n[7];
+ t8 = r->n[8];
+
+ t9 &= 0x03FFFFFUL;
+ t1 += (x << 6);
+
+ t1 += (t0 >> 26); t0 = z0;
+ t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL; z0 |= t1; z1 &= t1 ^ 0x40UL;
+ t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; z0 |= t2; z1 &= t2;
+ t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; z0 |= t3; z1 &= t3;
+ t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; z0 |= t4; z1 &= t4;
+ t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; z0 |= t5; z1 &= t5;
+ t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; z0 |= t6; z1 &= t6;
+ t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; z0 |= t7; z1 &= t7;
+ t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; z0 |= t8; z1 &= t8;
+ z0 |= t9; z1 &= t9 ^ 0x3C00000UL;
+
+ /* ... except for a possible carry at bit 22 of t9 (i.e. bit 256 of the field element) */
+ VERIFY_CHECK(t9 >> 23 == 0);
+
+ return (z0 == 0) | (z1 == 0x3FFFFFFUL);
+}
+
+SECP256K1_INLINE static void secp256k1_fe_set_int(secp256k1_fe_t *r, int a) {
+ r->n[0] = a;
+ r->n[1] = r->n[2] = r->n[3] = r->n[4] = r->n[5] = r->n[6] = r->n[7] = r->n[8] = r->n[9] = 0;
+#ifdef VERIFY
+ r->magnitude = 1;
+ r->normalized = 1;
+ secp256k1_fe_verify(r);
+#endif
+}
+
+SECP256K1_INLINE static int secp256k1_fe_is_zero(const secp256k1_fe_t *a) {
+ const uint32_t *t = a->n;
+#ifdef VERIFY
+ VERIFY_CHECK(a->normalized);
+ secp256k1_fe_verify(a);
+#endif
+ return (t[0] | t[1] | t[2] | t[3] | t[4] | t[5] | t[6] | t[7] | t[8] | t[9]) == 0;
+}
+
+SECP256K1_INLINE static int secp256k1_fe_is_odd(const secp256k1_fe_t *a) {
+#ifdef VERIFY
+ VERIFY_CHECK(a->normalized);
+ secp256k1_fe_verify(a);
+#endif
+ return a->n[0] & 1;
+}
+
+SECP256K1_INLINE static void secp256k1_fe_clear(secp256k1_fe_t *a) {
+ int i;
+#ifdef VERIFY
+ a->magnitude = 0;
+ a->normalized = 1;
+#endif
+ for (i=0; i<10; i++) {
+ a->n[i] = 0;
+ }
+}
+
+static int secp256k1_fe_cmp_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b) {
+ int i;
+#ifdef VERIFY
+ VERIFY_CHECK(a->normalized);
+ VERIFY_CHECK(b->normalized);
+ secp256k1_fe_verify(a);
+ secp256k1_fe_verify(b);
+#endif
+ for (i = 9; i >= 0; i--) {
+ if (a->n[i] > b->n[i]) {
+ return 1;
+ }
+ if (a->n[i] < b->n[i]) {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int secp256k1_fe_set_b32(secp256k1_fe_t *r, const unsigned char *a) {
+ int i;
+ r->n[0] = r->n[1] = r->n[2] = r->n[3] = r->n[4] = 0;
+ r->n[5] = r->n[6] = r->n[7] = r->n[8] = r->n[9] = 0;
+ for (i=0; i<32; i++) {
+ int j;
+ for (j=0; j<4; j++) {
+ int limb = (8*i+2*j)/26;
+ int shift = (8*i+2*j)%26;
+ r->n[limb] |= (uint32_t)((a[31-i] >> (2*j)) & 0x3) << shift;
+ }
+ }
+ if (r->n[9] == 0x3FFFFFUL && (r->n[8] & r->n[7] & r->n[6] & r->n[5] & r->n[4] & r->n[3] & r->n[2]) == 0x3FFFFFFUL && (r->n[1] + 0x40UL + ((r->n[0] + 0x3D1UL) >> 26)) > 0x3FFFFFFUL) {
+ return 0;
+ }
+#ifdef VERIFY
+ r->magnitude = 1;
+ r->normalized = 1;
+ secp256k1_fe_verify(r);
+#endif
+ return 1;
+}
+
+/** Convert a field element to a 32-byte big endian value. Requires the input to be normalized */
+static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe_t *a) {
+ int i;
+#ifdef VERIFY
+ VERIFY_CHECK(a->normalized);
+ secp256k1_fe_verify(a);
+#endif
+ for (i=0; i<32; i++) {
+ int j;
+ int c = 0;
+ for (j=0; j<4; j++) {
+ int limb = (8*i+2*j)/26;
+ int shift = (8*i+2*j)%26;
+ c |= ((a->n[limb] >> shift) & 0x3) << (2 * j);
+ }
+ r[31-i] = c;
+ }
+}
+
+SECP256K1_INLINE static void secp256k1_fe_negate(secp256k1_fe_t *r, const secp256k1_fe_t *a, int m) {
+#ifdef VERIFY
+ VERIFY_CHECK(a->magnitude <= m);
+ secp256k1_fe_verify(a);
+#endif
+ r->n[0] = 0x3FFFC2FUL * 2 * (m + 1) - a->n[0];
+ r->n[1] = 0x3FFFFBFUL * 2 * (m + 1) - a->n[1];
+ r->n[2] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[2];
+ r->n[3] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[3];
+ r->n[4] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[4];
+ r->n[5] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[5];
+ r->n[6] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[6];
+ r->n[7] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[7];
+ r->n[8] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[8];
+ r->n[9] = 0x03FFFFFUL * 2 * (m + 1) - a->n[9];
+#ifdef VERIFY
+ r->magnitude = m + 1;
+ r->normalized = 0;
+ secp256k1_fe_verify(r);
+#endif
+}
+
+SECP256K1_INLINE static void secp256k1_fe_mul_int(secp256k1_fe_t *r, int a) {
+ r->n[0] *= a;
+ r->n[1] *= a;
+ r->n[2] *= a;
+ r->n[3] *= a;
+ r->n[4] *= a;
+ r->n[5] *= a;
+ r->n[6] *= a;
+ r->n[7] *= a;
+ r->n[8] *= a;
+ r->n[9] *= a;
+#ifdef VERIFY
+ r->magnitude *= a;
+ r->normalized = 0;
+ secp256k1_fe_verify(r);
+#endif
+}
+
+SECP256K1_INLINE static void secp256k1_fe_add(secp256k1_fe_t *r, const secp256k1_fe_t *a) {
+#ifdef VERIFY
+ secp256k1_fe_verify(a);
+#endif
+ r->n[0] += a->n[0];
+ r->n[1] += a->n[1];
+ r->n[2] += a->n[2];
+ r->n[3] += a->n[3];
+ r->n[4] += a->n[4];
+ r->n[5] += a->n[5];
+ r->n[6] += a->n[6];
+ r->n[7] += a->n[7];
+ r->n[8] += a->n[8];
+ r->n[9] += a->n[9];
+#ifdef VERIFY
+ r->magnitude += a->magnitude;
+ r->normalized = 0;
+ secp256k1_fe_verify(r);
+#endif
+}
+
+#ifdef VERIFY
+#define VERIFY_BITS(x, n) VERIFY_CHECK(((x) >> (n)) == 0)
+#else
+#define VERIFY_BITS(x, n) do { } while(0)
+#endif
+
+SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint32_t *r, const uint32_t *a, const uint32_t * SECP256K1_RESTRICT b) {
+ uint64_t c, d;
+ uint64_t u0, u1, u2, u3, u4, u5, u6, u7, u8;
+ uint32_t t9, t1, t0, t2, t3, t4, t5, t6, t7;
+ const uint32_t M = 0x3FFFFFFUL, R0 = 0x3D10UL, R1 = 0x400UL;
+
+ VERIFY_BITS(a[0], 30);
+ VERIFY_BITS(a[1], 30);
+ VERIFY_BITS(a[2], 30);
+ VERIFY_BITS(a[3], 30);
+ VERIFY_BITS(a[4], 30);
+ VERIFY_BITS(a[5], 30);
+ VERIFY_BITS(a[6], 30);
+ VERIFY_BITS(a[7], 30);
+ VERIFY_BITS(a[8], 30);
+ VERIFY_BITS(a[9], 26);
+ VERIFY_BITS(b[0], 30);
+ VERIFY_BITS(b[1], 30);
+ VERIFY_BITS(b[2], 30);
+ VERIFY_BITS(b[3], 30);
+ VERIFY_BITS(b[4], 30);
+ VERIFY_BITS(b[5], 30);
+ VERIFY_BITS(b[6], 30);
+ VERIFY_BITS(b[7], 30);
+ VERIFY_BITS(b[8], 30);
+ VERIFY_BITS(b[9], 26);
+
+ /** [... a b c] is a shorthand for ... + a<<52 + b<<26 + c<<0 mod n.
+ * px is a shorthand for sum(a[i]*b[x-i], i=0..x).
+ * Note that [x 0 0 0 0 0 0 0 0 0 0] = [x*R1 x*R0].
+ */
+
+ d = (uint64_t)a[0] * b[9]
+ + (uint64_t)a[1] * b[8]
+ + (uint64_t)a[2] * b[7]
+ + (uint64_t)a[3] * b[6]
+ + (uint64_t)a[4] * b[5]
+ + (uint64_t)a[5] * b[4]
+ + (uint64_t)a[6] * b[3]
+ + (uint64_t)a[7] * b[2]
+ + (uint64_t)a[8] * b[1]
+ + (uint64_t)a[9] * b[0];
+ /* VERIFY_BITS(d, 64); */
+ /* [d 0 0 0 0 0 0 0 0 0] = [p9 0 0 0 0 0 0 0 0 0] */
+ t9 = d & M; d >>= 26;
+ VERIFY_BITS(t9, 26);
+ VERIFY_BITS(d, 38);
+ /* [d t9 0 0 0 0 0 0 0 0 0] = [p9 0 0 0 0 0 0 0 0 0] */
+
+ c = (uint64_t)a[0] * b[0];
+ VERIFY_BITS(c, 60);
+ /* [d t9 0 0 0 0 0 0 0 0 c] = [p9 0 0 0 0 0 0 0 0 p0] */
+ d += (uint64_t)a[1] * b[9]
+ + (uint64_t)a[2] * b[8]
+ + (uint64_t)a[3] * b[7]
+ + (uint64_t)a[4] * b[6]
+ + (uint64_t)a[5] * b[5]
+ + (uint64_t)a[6] * b[4]
+ + (uint64_t)a[7] * b[3]
+ + (uint64_t)a[8] * b[2]
+ + (uint64_t)a[9] * b[1];
+ VERIFY_BITS(d, 63);
+ /* [d t9 0 0 0 0 0 0 0 0 c] = [p10 p9 0 0 0 0 0 0 0 0 p0] */
+ u0 = d & M; d >>= 26; c += u0 * R0;
+ VERIFY_BITS(u0, 26);
+ VERIFY_BITS(d, 37);
+ VERIFY_BITS(c, 61);
+ /* [d u0 t9 0 0 0 0 0 0 0 0 c-u0*R0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */
+ t0 = c & M; c >>= 26; c += u0 * R1;
+ VERIFY_BITS(t0, 26);
+ VERIFY_BITS(c, 37);
+ /* [d u0 t9 0 0 0 0 0 0 0 c-u0*R1 t0-u0*R0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */
+ /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */
+
+ c += (uint64_t)a[0] * b[1]
+ + (uint64_t)a[1] * b[0];
+ VERIFY_BITS(c, 62);
+ /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p10 p9 0 0 0 0 0 0 0 p1 p0] */
+ d += (uint64_t)a[2] * b[9]
+ + (uint64_t)a[3] * b[8]
+ + (uint64_t)a[4] * b[7]
+ + (uint64_t)a[5] * b[6]
+ + (uint64_t)a[6] * b[5]
+ + (uint64_t)a[7] * b[4]
+ + (uint64_t)a[8] * b[3]
+ + (uint64_t)a[9] * b[2];
+ VERIFY_BITS(d, 63);
+ /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */
+ u1 = d & M; d >>= 26; c += u1 * R0;
+ VERIFY_BITS(u1, 26);
+ VERIFY_BITS(d, 37);
+ VERIFY_BITS(c, 63);
+ /* [d u1 0 t9 0 0 0 0 0 0 0 c-u1*R0 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */
+ t1 = c & M; c >>= 26; c += u1 * R1;
+ VERIFY_BITS(t1, 26);
+ VERIFY_BITS(c, 38);
+ /* [d u1 0 t9 0 0 0 0 0 0 c-u1*R1 t1-u1*R0 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */
+ /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */
+
+ c += (uint64_t)a[0] * b[2]
+ + (uint64_t)a[1] * b[1]
+ + (uint64_t)a[2] * b[0];
+ VERIFY_BITS(c, 62);
+ /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */
+ d += (uint64_t)a[3] * b[9]
+ + (uint64_t)a[4] * b[8]
+ + (uint64_t)a[5] * b[7]
+ + (uint64_t)a[6] * b[6]
+ + (uint64_t)a[7] * b[5]
+ + (uint64_t)a[8] * b[4]
+ + (uint64_t)a[9] * b[3];
+ VERIFY_BITS(d, 63);
+ /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */
+ u2 = d & M; d >>= 26; c += u2 * R0;
+ VERIFY_BITS(u2, 26);
+ VERIFY_BITS(d, 37);
+ VERIFY_BITS(c, 63);
+ /* [d u2 0 0 t9 0 0 0 0 0 0 c-u2*R0 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */
+ t2 = c & M; c >>= 26; c += u2 * R1;
+ VERIFY_BITS(t2, 26);
+ VERIFY_BITS(c, 38);
+ /* [d u2 0 0 t9 0 0 0 0 0 c-u2*R1 t2-u2*R0 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */
+ /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */
+
+ c += (uint64_t)a[0] * b[3]
+ + (uint64_t)a[1] * b[2]
+ + (uint64_t)a[2] * b[1]
+ + (uint64_t)a[3] * b[0];
+ VERIFY_BITS(c, 63);
+ /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */
+ d += (uint64_t)a[4] * b[9]
+ + (uint64_t)a[5] * b[8]
+ + (uint64_t)a[6] * b[7]
+ + (uint64_t)a[7] * b[6]
+ + (uint64_t)a[8] * b[5]
+ + (uint64_t)a[9] * b[4];
+ VERIFY_BITS(d, 63);
+ /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */
+ u3 = d & M; d >>= 26; c += u3 * R0;
+ VERIFY_BITS(u3, 26);
+ VERIFY_BITS(d, 37);
+ /* VERIFY_BITS(c, 64); */
+ /* [d u3 0 0 0 t9 0 0 0 0 0 c-u3*R0 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */
+ t3 = c & M; c >>= 26; c += u3 * R1;
+ VERIFY_BITS(t3, 26);
+ VERIFY_BITS(c, 39);
+ /* [d u3 0 0 0 t9 0 0 0 0 c-u3*R1 t3-u3*R0 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */
+ /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */
+
+ c += (uint64_t)a[0] * b[4]
+ + (uint64_t)a[1] * b[3]
+ + (uint64_t)a[2] * b[2]
+ + (uint64_t)a[3] * b[1]
+ + (uint64_t)a[4] * b[0];
+ VERIFY_BITS(c, 63);
+ /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */
+ d += (uint64_t)a[5] * b[9]
+ + (uint64_t)a[6] * b[8]
+ + (uint64_t)a[7] * b[7]
+ + (uint64_t)a[8] * b[6]
+ + (uint64_t)a[9] * b[5];
+ VERIFY_BITS(d, 62);
+ /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */
+ u4 = d & M; d >>= 26; c += u4 * R0;
+ VERIFY_BITS(u4, 26);
+ VERIFY_BITS(d, 36);
+ /* VERIFY_BITS(c, 64); */
+ /* [d u4 0 0 0 0 t9 0 0 0 0 c-u4*R0 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */
+ t4 = c & M; c >>= 26; c += u4 * R1;
+ VERIFY_BITS(t4, 26);
+ VERIFY_BITS(c, 39);
+ /* [d u4 0 0 0 0 t9 0 0 0 c-u4*R1 t4-u4*R0 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */
+ /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */
+
+ c += (uint64_t)a[0] * b[5]
+ + (uint64_t)a[1] * b[4]
+ + (uint64_t)a[2] * b[3]
+ + (uint64_t)a[3] * b[2]
+ + (uint64_t)a[4] * b[1]
+ + (uint64_t)a[5] * b[0];
+ VERIFY_BITS(c, 63);
+ /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */
+ d += (uint64_t)a[6] * b[9]
+ + (uint64_t)a[7] * b[8]
+ + (uint64_t)a[8] * b[7]
+ + (uint64_t)a[9] * b[6];
+ VERIFY_BITS(d, 62);
+ /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */
+ u5 = d & M; d >>= 26; c += u5 * R0;
+ VERIFY_BITS(u5, 26);
+ VERIFY_BITS(d, 36);
+ /* VERIFY_BITS(c, 64); */
+ /* [d u5 0 0 0 0 0 t9 0 0 0 c-u5*R0 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */
+ t5 = c & M; c >>= 26; c += u5 * R1;
+ VERIFY_BITS(t5, 26);
+ VERIFY_BITS(c, 39);
+ /* [d u5 0 0 0 0 0 t9 0 0 c-u5*R1 t5-u5*R0 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */
+ /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */
+
+ c += (uint64_t)a[0] * b[6]
+ + (uint64_t)a[1] * b[5]
+ + (uint64_t)a[2] * b[4]
+ + (uint64_t)a[3] * b[3]
+ + (uint64_t)a[4] * b[2]
+ + (uint64_t)a[5] * b[1]
+ + (uint64_t)a[6] * b[0];
+ VERIFY_BITS(c, 63);
+ /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */
+ d += (uint64_t)a[7] * b[9]
+ + (uint64_t)a[8] * b[8]
+ + (uint64_t)a[9] * b[7];
+ VERIFY_BITS(d, 61);
+ /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */
+ u6 = d & M; d >>= 26; c += u6 * R0;
+ VERIFY_BITS(u6, 26);
+ VERIFY_BITS(d, 35);
+ /* VERIFY_BITS(c, 64); */
+ /* [d u6 0 0 0 0 0 0 t9 0 0 c-u6*R0 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */
+ t6 = c & M; c >>= 26; c += u6 * R1;
+ VERIFY_BITS(t6, 26);
+ VERIFY_BITS(c, 39);
+ /* [d u6 0 0 0 0 0 0 t9 0 c-u6*R1 t6-u6*R0 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */
+ /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */
+
+ c += (uint64_t)a[0] * b[7]
+ + (uint64_t)a[1] * b[6]
+ + (uint64_t)a[2] * b[5]
+ + (uint64_t)a[3] * b[4]
+ + (uint64_t)a[4] * b[3]
+ + (uint64_t)a[5] * b[2]
+ + (uint64_t)a[6] * b[1]
+ + (uint64_t)a[7] * b[0];
+ /* VERIFY_BITS(c, 64); */
+ VERIFY_CHECK(c <= 0x8000007C00000007ULL);
+ /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */
+ d += (uint64_t)a[8] * b[9]
+ + (uint64_t)a[9] * b[8];
+ VERIFY_BITS(d, 58);
+ /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */
+ u7 = d & M; d >>= 26; c += u7 * R0;
+ VERIFY_BITS(u7, 26);
+ VERIFY_BITS(d, 32);
+ /* VERIFY_BITS(c, 64); */
+ VERIFY_CHECK(c <= 0x800001703FFFC2F7ULL);
+ /* [d u7 0 0 0 0 0 0 0 t9 0 c-u7*R0 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */
+ t7 = c & M; c >>= 26; c += u7 * R1;
+ VERIFY_BITS(t7, 26);
+ VERIFY_BITS(c, 38);
+ /* [d u7 0 0 0 0 0 0 0 t9 c-u7*R1 t7-u7*R0 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */
+ /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */
+
+ c += (uint64_t)a[0] * b[8]
+ + (uint64_t)a[1] * b[7]
+ + (uint64_t)a[2] * b[6]
+ + (uint64_t)a[3] * b[5]
+ + (uint64_t)a[4] * b[4]
+ + (uint64_t)a[5] * b[3]
+ + (uint64_t)a[6] * b[2]
+ + (uint64_t)a[7] * b[1]
+ + (uint64_t)a[8] * b[0];
+ /* VERIFY_BITS(c, 64); */
+ VERIFY_CHECK(c <= 0x9000007B80000008ULL);
+ /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+ d += (uint64_t)a[9] * b[9];
+ VERIFY_BITS(d, 57);
+ /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+ u8 = d & M; d >>= 26; c += u8 * R0;
+ VERIFY_BITS(u8, 26);
+ VERIFY_BITS(d, 31);
+ /* VERIFY_BITS(c, 64); */
+ VERIFY_CHECK(c <= 0x9000016FBFFFC2F8ULL);
+ /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 t4 t3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+
+ r[3] = t3;
+ VERIFY_BITS(r[3], 26);
+ /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 t4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+ r[4] = t4;
+ VERIFY_BITS(r[4], 26);
+ /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+ r[5] = t5;
+ VERIFY_BITS(r[5], 26);
+ /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+ r[6] = t6;
+ VERIFY_BITS(r[6], 26);
+ /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+ r[7] = t7;
+ VERIFY_BITS(r[7], 26);
+ /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+
+ r[8] = c & M; c >>= 26; c += u8 * R1;
+ VERIFY_BITS(r[8], 26);
+ VERIFY_BITS(c, 39);
+ /* [d u8 0 0 0 0 0 0 0 0 t9+c-u8*R1 r8-u8*R0 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+ /* [d 0 0 0 0 0 0 0 0 0 t9+c r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+ c += d * R0 + t9;
+ VERIFY_BITS(c, 45);
+ /* [d 0 0 0 0 0 0 0 0 0 c-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+ r[9] = c & (M >> 4); c >>= 22; c += d * (R1 << 4);
+ VERIFY_BITS(r[9], 22);
+ VERIFY_BITS(c, 46);
+ /* [d 0 0 0 0 0 0 0 0 r9+((c-d*R1<<4)<<22)-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+ /* [d 0 0 0 0 0 0 0 -d*R1 r9+(c<<22)-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+ /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+
+ d = c * (R0 >> 4) + t0;
+ VERIFY_BITS(d, 56);
+ /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1 d-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+ r[0] = d & M; d >>= 26;
+ VERIFY_BITS(r[0], 26);
+ VERIFY_BITS(d, 30);
+ /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1+d r0-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+ d += c * (R1 >> 4) + t1;
+ VERIFY_BITS(d, 53);
+ VERIFY_CHECK(d <= 0x10000003FFFFBFULL);
+ /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 d-c*R1>>4 r0-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+ /* [r9 r8 r7 r6 r5 r4 r3 t2 d r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+ r[1] = d & M; d >>= 26;
+ VERIFY_BITS(r[1], 26);
+ VERIFY_BITS(d, 27);
+ VERIFY_CHECK(d <= 0x4000000ULL);
+ /* [r9 r8 r7 r6 r5 r4 r3 t2+d r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+ d += t2;
+ VERIFY_BITS(d, 27);
+ /* [r9 r8 r7 r6 r5 r4 r3 d r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+ r[2] = d;
+ VERIFY_BITS(r[2], 27);
+ /* [r9 r8 r7 r6 r5 r4 r3 r2 r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+}
+
+SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint32_t *r, const uint32_t *a) {
+ uint64_t c, d;
+ uint64_t u0, u1, u2, u3, u4, u5, u6, u7, u8;
+ uint32_t t9, t0, t1, t2, t3, t4, t5, t6, t7;
+ const uint32_t M = 0x3FFFFFFUL, R0 = 0x3D10UL, R1 = 0x400UL;
+
+ VERIFY_BITS(a[0], 30);
+ VERIFY_BITS(a[1], 30);
+ VERIFY_BITS(a[2], 30);
+ VERIFY_BITS(a[3], 30);
+ VERIFY_BITS(a[4], 30);
+ VERIFY_BITS(a[5], 30);
+ VERIFY_BITS(a[6], 30);
+ VERIFY_BITS(a[7], 30);
+ VERIFY_BITS(a[8], 30);
+ VERIFY_BITS(a[9], 26);
+
+ /** [... a b c] is a shorthand for ... + a<<52 + b<<26 + c<<0 mod n.
+ * px is a shorthand for sum(a[i]*a[x-i], i=0..x).
+ * Note that [x 0 0 0 0 0 0 0 0 0 0] = [x*R1 x*R0].
+ */
+
+ d = (uint64_t)(a[0]*2) * a[9]
+ + (uint64_t)(a[1]*2) * a[8]
+ + (uint64_t)(a[2]*2) * a[7]
+ + (uint64_t)(a[3]*2) * a[6]
+ + (uint64_t)(a[4]*2) * a[5];
+ /* VERIFY_BITS(d, 64); */
+ /* [d 0 0 0 0 0 0 0 0 0] = [p9 0 0 0 0 0 0 0 0 0] */
+ t9 = d & M; d >>= 26;
+ VERIFY_BITS(t9, 26);
+ VERIFY_BITS(d, 38);
+ /* [d t9 0 0 0 0 0 0 0 0 0] = [p9 0 0 0 0 0 0 0 0 0] */
+
+ c = (uint64_t)a[0] * a[0];
+ VERIFY_BITS(c, 60);
+ /* [d t9 0 0 0 0 0 0 0 0 c] = [p9 0 0 0 0 0 0 0 0 p0] */
+ d += (uint64_t)(a[1]*2) * a[9]
+ + (uint64_t)(a[2]*2) * a[8]
+ + (uint64_t)(a[3]*2) * a[7]
+ + (uint64_t)(a[4]*2) * a[6]
+ + (uint64_t)a[5] * a[5];
+ VERIFY_BITS(d, 63);
+ /* [d t9 0 0 0 0 0 0 0 0 c] = [p10 p9 0 0 0 0 0 0 0 0 p0] */
+ u0 = d & M; d >>= 26; c += u0 * R0;
+ VERIFY_BITS(u0, 26);
+ VERIFY_BITS(d, 37);
+ VERIFY_BITS(c, 61);
+ /* [d u0 t9 0 0 0 0 0 0 0 0 c-u0*R0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */
+ t0 = c & M; c >>= 26; c += u0 * R1;
+ VERIFY_BITS(t0, 26);
+ VERIFY_BITS(c, 37);
+ /* [d u0 t9 0 0 0 0 0 0 0 c-u0*R1 t0-u0*R0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */
+ /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */
+
+ c += (uint64_t)(a[0]*2) * a[1];
+ VERIFY_BITS(c, 62);
+ /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p10 p9 0 0 0 0 0 0 0 p1 p0] */
+ d += (uint64_t)(a[2]*2) * a[9]
+ + (uint64_t)(a[3]*2) * a[8]
+ + (uint64_t)(a[4]*2) * a[7]
+ + (uint64_t)(a[5]*2) * a[6];
+ VERIFY_BITS(d, 63);
+ /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */
+ u1 = d & M; d >>= 26; c += u1 * R0;
+ VERIFY_BITS(u1, 26);
+ VERIFY_BITS(d, 37);
+ VERIFY_BITS(c, 63);
+ /* [d u1 0 t9 0 0 0 0 0 0 0 c-u1*R0 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */
+ t1 = c & M; c >>= 26; c += u1 * R1;
+ VERIFY_BITS(t1, 26);
+ VERIFY_BITS(c, 38);
+ /* [d u1 0 t9 0 0 0 0 0 0 c-u1*R1 t1-u1*R0 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */
+ /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */
+
+ c += (uint64_t)(a[0]*2) * a[2]
+ + (uint64_t)a[1] * a[1];
+ VERIFY_BITS(c, 62);
+ /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */
+ d += (uint64_t)(a[3]*2) * a[9]
+ + (uint64_t)(a[4]*2) * a[8]
+ + (uint64_t)(a[5]*2) * a[7]
+ + (uint64_t)a[6] * a[6];
+ VERIFY_BITS(d, 63);
+ /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */
+ u2 = d & M; d >>= 26; c += u2 * R0;
+ VERIFY_BITS(u2, 26);
+ VERIFY_BITS(d, 37);
+ VERIFY_BITS(c, 63);
+ /* [d u2 0 0 t9 0 0 0 0 0 0 c-u2*R0 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */
+ t2 = c & M; c >>= 26; c += u2 * R1;
+ VERIFY_BITS(t2, 26);
+ VERIFY_BITS(c, 38);
+ /* [d u2 0 0 t9 0 0 0 0 0 c-u2*R1 t2-u2*R0 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */
+ /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */
+
+ c += (uint64_t)(a[0]*2) * a[3]
+ + (uint64_t)(a[1]*2) * a[2];
+ VERIFY_BITS(c, 63);
+ /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */
+ d += (uint64_t)(a[4]*2) * a[9]
+ + (uint64_t)(a[5]*2) * a[8]
+ + (uint64_t)(a[6]*2) * a[7];
+ VERIFY_BITS(d, 63);
+ /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */
+ u3 = d & M; d >>= 26; c += u3 * R0;
+ VERIFY_BITS(u3, 26);
+ VERIFY_BITS(d, 37);
+ /* VERIFY_BITS(c, 64); */
+ /* [d u3 0 0 0 t9 0 0 0 0 0 c-u3*R0 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */
+ t3 = c & M; c >>= 26; c += u3 * R1;
+ VERIFY_BITS(t3, 26);
+ VERIFY_BITS(c, 39);
+ /* [d u3 0 0 0 t9 0 0 0 0 c-u3*R1 t3-u3*R0 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */
+ /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */
+
+ c += (uint64_t)(a[0]*2) * a[4]
+ + (uint64_t)(a[1]*2) * a[3]
+ + (uint64_t)a[2] * a[2];
+ VERIFY_BITS(c, 63);
+ /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */
+ d += (uint64_t)(a[5]*2) * a[9]
+ + (uint64_t)(a[6]*2) * a[8]
+ + (uint64_t)a[7] * a[7];
+ VERIFY_BITS(d, 62);
+ /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */
+ u4 = d & M; d >>= 26; c += u4 * R0;
+ VERIFY_BITS(u4, 26);
+ VERIFY_BITS(d, 36);
+ /* VERIFY_BITS(c, 64); */
+ /* [d u4 0 0 0 0 t9 0 0 0 0 c-u4*R0 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */
+ t4 = c & M; c >>= 26; c += u4 * R1;
+ VERIFY_BITS(t4, 26);
+ VERIFY_BITS(c, 39);
+ /* [d u4 0 0 0 0 t9 0 0 0 c-u4*R1 t4-u4*R0 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */
+ /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */
+
+ c += (uint64_t)(a[0]*2) * a[5]
+ + (uint64_t)(a[1]*2) * a[4]
+ + (uint64_t)(a[2]*2) * a[3];
+ VERIFY_BITS(c, 63);
+ /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */
+ d += (uint64_t)(a[6]*2) * a[9]
+ + (uint64_t)(a[7]*2) * a[8];
+ VERIFY_BITS(d, 62);
+ /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */
+ u5 = d & M; d >>= 26; c += u5 * R0;
+ VERIFY_BITS(u5, 26);
+ VERIFY_BITS(d, 36);
+ /* VERIFY_BITS(c, 64); */
+ /* [d u5 0 0 0 0 0 t9 0 0 0 c-u5*R0 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */
+ t5 = c & M; c >>= 26; c += u5 * R1;
+ VERIFY_BITS(t5, 26);
+ VERIFY_BITS(c, 39);
+ /* [d u5 0 0 0 0 0 t9 0 0 c-u5*R1 t5-u5*R0 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */
+ /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */
+
+ c += (uint64_t)(a[0]*2) * a[6]
+ + (uint64_t)(a[1]*2) * a[5]
+ + (uint64_t)(a[2]*2) * a[4]
+ + (uint64_t)a[3] * a[3];
+ VERIFY_BITS(c, 63);
+ /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */
+ d += (uint64_t)(a[7]*2) * a[9]
+ + (uint64_t)a[8] * a[8];
+ VERIFY_BITS(d, 61);
+ /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */
+ u6 = d & M; d >>= 26; c += u6 * R0;
+ VERIFY_BITS(u6, 26);
+ VERIFY_BITS(d, 35);
+ /* VERIFY_BITS(c, 64); */
+ /* [d u6 0 0 0 0 0 0 t9 0 0 c-u6*R0 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */
+ t6 = c & M; c >>= 26; c += u6 * R1;
+ VERIFY_BITS(t6, 26);
+ VERIFY_BITS(c, 39);
+ /* [d u6 0 0 0 0 0 0 t9 0 c-u6*R1 t6-u6*R0 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */
+ /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */
+
+ c += (uint64_t)(a[0]*2) * a[7]
+ + (uint64_t)(a[1]*2) * a[6]
+ + (uint64_t)(a[2]*2) * a[5]
+ + (uint64_t)(a[3]*2) * a[4];
+ /* VERIFY_BITS(c, 64); */
+ VERIFY_CHECK(c <= 0x8000007C00000007ULL);
+ /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */
+ d += (uint64_t)(a[8]*2) * a[9];
+ VERIFY_BITS(d, 58);
+ /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */
+ u7 = d & M; d >>= 26; c += u7 * R0;
+ VERIFY_BITS(u7, 26);
+ VERIFY_BITS(d, 32);
+ /* VERIFY_BITS(c, 64); */
+ VERIFY_CHECK(c <= 0x800001703FFFC2F7ULL);
+ /* [d u7 0 0 0 0 0 0 0 t9 0 c-u7*R0 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */
+ t7 = c & M; c >>= 26; c += u7 * R1;
+ VERIFY_BITS(t7, 26);
+ VERIFY_BITS(c, 38);
+ /* [d u7 0 0 0 0 0 0 0 t9 c-u7*R1 t7-u7*R0 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */
+ /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */
+
+ c += (uint64_t)(a[0]*2) * a[8]
+ + (uint64_t)(a[1]*2) * a[7]
+ + (uint64_t)(a[2]*2) * a[6]
+ + (uint64_t)(a[3]*2) * a[5]
+ + (uint64_t)a[4] * a[4];
+ /* VERIFY_BITS(c, 64); */
+ VERIFY_CHECK(c <= 0x9000007B80000008ULL);
+ /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+ d += (uint64_t)a[9] * a[9];
+ VERIFY_BITS(d, 57);
+ /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+ u8 = d & M; d >>= 26; c += u8 * R0;
+ VERIFY_BITS(u8, 26);
+ VERIFY_BITS(d, 31);
+ /* VERIFY_BITS(c, 64); */
+ VERIFY_CHECK(c <= 0x9000016FBFFFC2F8ULL);
+ /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 t4 t3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+
+ r[3] = t3;
+ VERIFY_BITS(r[3], 26);
+ /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 t4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+ r[4] = t4;
+ VERIFY_BITS(r[4], 26);
+ /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+ r[5] = t5;
+ VERIFY_BITS(r[5], 26);
+ /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+ r[6] = t6;
+ VERIFY_BITS(r[6], 26);
+ /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+ r[7] = t7;
+ VERIFY_BITS(r[7], 26);
+ /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+
+ r[8] = c & M; c >>= 26; c += u8 * R1;
+ VERIFY_BITS(r[8], 26);
+ VERIFY_BITS(c, 39);
+ /* [d u8 0 0 0 0 0 0 0 0 t9+c-u8*R1 r8-u8*R0 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+ /* [d 0 0 0 0 0 0 0 0 0 t9+c r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+ c += d * R0 + t9;
+ VERIFY_BITS(c, 45);
+ /* [d 0 0 0 0 0 0 0 0 0 c-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+ r[9] = c & (M >> 4); c >>= 22; c += d * (R1 << 4);
+ VERIFY_BITS(r[9], 22);
+ VERIFY_BITS(c, 46);
+ /* [d 0 0 0 0 0 0 0 0 r9+((c-d*R1<<4)<<22)-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+ /* [d 0 0 0 0 0 0 0 -d*R1 r9+(c<<22)-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+ /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+
+ d = c * (R0 >> 4) + t0;
+ VERIFY_BITS(d, 56);
+ /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1 d-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+ r[0] = d & M; d >>= 26;
+ VERIFY_BITS(r[0], 26);
+ VERIFY_BITS(d, 30);
+ /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1+d r0-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+ d += c * (R1 >> 4) + t1;
+ VERIFY_BITS(d, 53);
+ VERIFY_CHECK(d <= 0x10000003FFFFBFULL);
+ /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 d-c*R1>>4 r0-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+ /* [r9 r8 r7 r6 r5 r4 r3 t2 d r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+ r[1] = d & M; d >>= 26;
+ VERIFY_BITS(r[1], 26);
+ VERIFY_BITS(d, 27);
+ VERIFY_CHECK(d <= 0x4000000ULL);
+ /* [r9 r8 r7 r6 r5 r4 r3 t2+d r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+ d += t2;
+ VERIFY_BITS(d, 27);
+ /* [r9 r8 r7 r6 r5 r4 r3 d r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+ r[2] = d;
+ VERIFY_BITS(r[2], 27);
+ /* [r9 r8 r7 r6 r5 r4 r3 r2 r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+}
+
+
+static void secp256k1_fe_mul(secp256k1_fe_t *r, const secp256k1_fe_t *a, const secp256k1_fe_t * SECP256K1_RESTRICT b) {
+#ifdef VERIFY
+ VERIFY_CHECK(a->magnitude <= 8);
+ VERIFY_CHECK(b->magnitude <= 8);
+ secp256k1_fe_verify(a);
+ secp256k1_fe_verify(b);
+ VERIFY_CHECK(r != b);
+#endif
+ secp256k1_fe_mul_inner(r->n, a->n, b->n);
+#ifdef VERIFY
+ r->magnitude = 1;
+ r->normalized = 0;
+ secp256k1_fe_verify(r);
+#endif
+}
+
+static void secp256k1_fe_sqr(secp256k1_fe_t *r, const secp256k1_fe_t *a) {
+#ifdef VERIFY
+ VERIFY_CHECK(a->magnitude <= 8);
+ secp256k1_fe_verify(a);
+#endif
+ secp256k1_fe_sqr_inner(r->n, a->n);
+#ifdef VERIFY
+ r->magnitude = 1;
+ r->normalized = 0;
+ secp256k1_fe_verify(r);
+#endif
+}
+
+static SECP256K1_INLINE void secp256k1_fe_cmov(secp256k1_fe_t *r, const secp256k1_fe_t *a, int flag) {
+ uint32_t mask0, mask1;
+ mask0 = flag + ~((uint32_t)0);
+ mask1 = ~mask0;
+ r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1);
+ r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1);
+ r->n[2] = (r->n[2] & mask0) | (a->n[2] & mask1);
+ r->n[3] = (r->n[3] & mask0) | (a->n[3] & mask1);
+ r->n[4] = (r->n[4] & mask0) | (a->n[4] & mask1);
+ r->n[5] = (r->n[5] & mask0) | (a->n[5] & mask1);
+ r->n[6] = (r->n[6] & mask0) | (a->n[6] & mask1);
+ r->n[7] = (r->n[7] & mask0) | (a->n[7] & mask1);
+ r->n[8] = (r->n[8] & mask0) | (a->n[8] & mask1);
+ r->n[9] = (r->n[9] & mask0) | (a->n[9] & mask1);
+#ifdef VERIFY
+ r->magnitude = (r->magnitude & mask0) | (a->magnitude & mask1);
+ r->normalized = (r->normalized & mask0) | (a->normalized & mask1);
+#endif
+}
+
+static SECP256K1_INLINE void secp256k1_fe_storage_cmov(secp256k1_fe_storage_t *r, const secp256k1_fe_storage_t *a, int flag) {
+ uint32_t mask0, mask1;
+ mask0 = flag + ~((uint32_t)0);
+ mask1 = ~mask0;
+ r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1);
+ r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1);
+ r->n[2] = (r->n[2] & mask0) | (a->n[2] & mask1);
+ r->n[3] = (r->n[3] & mask0) | (a->n[3] & mask1);
+ r->n[4] = (r->n[4] & mask0) | (a->n[4] & mask1);
+ r->n[5] = (r->n[5] & mask0) | (a->n[5] & mask1);
+ r->n[6] = (r->n[6] & mask0) | (a->n[6] & mask1);
+ r->n[7] = (r->n[7] & mask0) | (a->n[7] & mask1);
+}
+
+static void secp256k1_fe_to_storage(secp256k1_fe_storage_t *r, const secp256k1_fe_t *a) {
+#ifdef VERIFY
+ VERIFY_CHECK(a->normalized);
+#endif
+ r->n[0] = a->n[0] | a->n[1] << 26;
+ r->n[1] = a->n[1] >> 6 | a->n[2] << 20;
+ r->n[2] = a->n[2] >> 12 | a->n[3] << 14;
+ r->n[3] = a->n[3] >> 18 | a->n[4] << 8;
+ r->n[4] = a->n[4] >> 24 | a->n[5] << 2 | a->n[6] << 28;
+ r->n[5] = a->n[6] >> 4 | a->n[7] << 22;
+ r->n[6] = a->n[7] >> 10 | a->n[8] << 16;
+ r->n[7] = a->n[8] >> 16 | a->n[9] << 10;
+}
+
+static SECP256K1_INLINE void secp256k1_fe_from_storage(secp256k1_fe_t *r, const secp256k1_fe_storage_t *a) {
+ r->n[0] = a->n[0] & 0x3FFFFFFUL;
+ r->n[1] = a->n[0] >> 26 | ((a->n[1] << 6) & 0x3FFFFFFUL);
+ r->n[2] = a->n[1] >> 20 | ((a->n[2] << 12) & 0x3FFFFFFUL);
+ r->n[3] = a->n[2] >> 14 | ((a->n[3] << 18) & 0x3FFFFFFUL);
+ r->n[4] = a->n[3] >> 8 | ((a->n[4] << 24) & 0x3FFFFFFUL);
+ r->n[5] = (a->n[4] >> 2) & 0x3FFFFFFUL;
+ r->n[6] = a->n[4] >> 28 | ((a->n[5] << 4) & 0x3FFFFFFUL);
+ r->n[7] = a->n[5] >> 22 | ((a->n[6] << 10) & 0x3FFFFFFUL);
+ r->n[8] = a->n[6] >> 16 | ((a->n[7] << 16) & 0x3FFFFFFUL);
+ r->n[9] = a->n[7] >> 10;
+#ifdef VERIFY
+ r->magnitude = 1;
+ r->normalized = 1;
+#endif
+}
+
+#endif
diff --git a/src/secp256k1/src/field_5x52.h b/src/secp256k1/src/field_5x52.h
new file mode 100644
index 0000000000..4513d36f49
--- /dev/null
+++ b/src/secp256k1/src/field_5x52.h
@@ -0,0 +1,47 @@
+/**********************************************************************
+ * Copyright (c) 2013, 2014 Pieter Wuille *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
+ **********************************************************************/
+
+#ifndef _SECP256K1_FIELD_REPR_
+#define _SECP256K1_FIELD_REPR_
+
+#include <stdint.h>
+
+typedef struct {
+ /* X = sum(i=0..4, elem[i]*2^52) mod n */
+ uint64_t n[5];
+#ifdef VERIFY
+ int magnitude;
+ int normalized;
+#endif
+} secp256k1_fe_t;
+
+/* Unpacks a constant into a overlapping multi-limbed FE element. */
+#define SECP256K1_FE_CONST_INNER(d7, d6, d5, d4, d3, d2, d1, d0) { \
+ (d0) | ((uint64_t)(d1) & 0xFFFFFUL) << 32, \
+ ((d1) >> 20) | ((uint64_t)(d2)) << 12 | ((uint64_t)(d3) & 0xFFUL) << 44, \
+ ((d3) >> 8) | ((uint64_t)(d4) & 0xFFFFFFFUL) << 24, \
+ ((d4) >> 28) | ((uint64_t)(d5)) << 4 | ((uint64_t)(d6) & 0xFFFFUL) << 36, \
+ ((d6) >> 16) | ((uint64_t)(d7)) << 16 \
+}
+
+#ifdef VERIFY
+#define SECP256K1_FE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {SECP256K1_FE_CONST_INNER((d7), (d6), (d5), (d4), (d3), (d2), (d1), (d0)), 1, 1}
+#else
+#define SECP256K1_FE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {SECP256K1_FE_CONST_INNER((d7), (d6), (d5), (d4), (d3), (d2), (d1), (d0))}
+#endif
+
+typedef struct {
+ uint64_t n[4];
+} secp256k1_fe_storage_t;
+
+#define SECP256K1_FE_STORAGE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{ \
+ (d0) | ((uint64_t)(d1)) << 32, \
+ (d2) | ((uint64_t)(d3)) << 32, \
+ (d4) | ((uint64_t)(d5)) << 32, \
+ (d6) | ((uint64_t)(d7)) << 32 \
+}}
+
+#endif
diff --git a/src/secp256k1/src/field_5x52_asm_impl.h b/src/secp256k1/src/field_5x52_asm_impl.h
new file mode 100644
index 0000000000..98cc004bf0
--- /dev/null
+++ b/src/secp256k1/src/field_5x52_asm_impl.h
@@ -0,0 +1,502 @@
+/**********************************************************************
+ * Copyright (c) 2013-2014 Diederik Huys, Pieter Wuille *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
+ **********************************************************************/
+
+/**
+ * Changelog:
+ * - March 2013, Diederik Huys: original version
+ * - November 2014, Pieter Wuille: updated to use Peter Dettman's parallel multiplication algorithm
+ * - December 2014, Pieter Wuille: converted from YASM to GCC inline assembly
+ */
+
+#ifndef _SECP256K1_FIELD_INNER5X52_IMPL_H_
+#define _SECP256K1_FIELD_INNER5X52_IMPL_H_
+
+SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint64_t *r, const uint64_t *a, const uint64_t * SECP256K1_RESTRICT b) {
+/**
+ * Registers: rdx:rax = multiplication accumulator
+ * r9:r8 = c
+ * r15:rcx = d
+ * r10-r14 = a0-a4
+ * rbx = b
+ * rdi = r
+ * rsi = a / t?
+ */
+ uint64_t tmp1, tmp2, tmp3;
+__asm__ __volatile__(
+ "movq 0(%%rsi),%%r10\n"
+ "movq 8(%%rsi),%%r11\n"
+ "movq 16(%%rsi),%%r12\n"
+ "movq 24(%%rsi),%%r13\n"
+ "movq 32(%%rsi),%%r14\n"
+
+ /* d += a3 * b0 */
+ "movq 0(%%rbx),%%rax\n"
+ "mulq %%r13\n"
+ "movq %%rax,%%rcx\n"
+ "movq %%rdx,%%r15\n"
+ /* d += a2 * b1 */
+ "movq 8(%%rbx),%%rax\n"
+ "mulq %%r12\n"
+ "addq %%rax,%%rcx\n"
+ "adcq %%rdx,%%r15\n"
+ /* d += a1 * b2 */
+ "movq 16(%%rbx),%%rax\n"
+ "mulq %%r11\n"
+ "addq %%rax,%%rcx\n"
+ "adcq %%rdx,%%r15\n"
+ /* d = a0 * b3 */
+ "movq 24(%%rbx),%%rax\n"
+ "mulq %%r10\n"
+ "addq %%rax,%%rcx\n"
+ "adcq %%rdx,%%r15\n"
+ /* c = a4 * b4 */
+ "movq 32(%%rbx),%%rax\n"
+ "mulq %%r14\n"
+ "movq %%rax,%%r8\n"
+ "movq %%rdx,%%r9\n"
+ /* d += (c & M) * R */
+ "movq $0xfffffffffffff,%%rdx\n"
+ "andq %%rdx,%%rax\n"
+ "movq $0x1000003d10,%%rdx\n"
+ "mulq %%rdx\n"
+ "addq %%rax,%%rcx\n"
+ "adcq %%rdx,%%r15\n"
+ /* c >>= 52 (%%r8 only) */
+ "shrdq $52,%%r9,%%r8\n"
+ /* t3 (tmp1) = d & M */
+ "movq %%rcx,%%rsi\n"
+ "movq $0xfffffffffffff,%%rdx\n"
+ "andq %%rdx,%%rsi\n"
+ "movq %%rsi,%q1\n"
+ /* d >>= 52 */
+ "shrdq $52,%%r15,%%rcx\n"
+ "xorq %%r15,%%r15\n"
+ /* d += a4 * b0 */
+ "movq 0(%%rbx),%%rax\n"
+ "mulq %%r14\n"
+ "addq %%rax,%%rcx\n"
+ "adcq %%rdx,%%r15\n"
+ /* d += a3 * b1 */
+ "movq 8(%%rbx),%%rax\n"
+ "mulq %%r13\n"
+ "addq %%rax,%%rcx\n"
+ "adcq %%rdx,%%r15\n"
+ /* d += a2 * b2 */
+ "movq 16(%%rbx),%%rax\n"
+ "mulq %%r12\n"
+ "addq %%rax,%%rcx\n"
+ "adcq %%rdx,%%r15\n"
+ /* d += a1 * b3 */
+ "movq 24(%%rbx),%%rax\n"
+ "mulq %%r11\n"
+ "addq %%rax,%%rcx\n"
+ "adcq %%rdx,%%r15\n"
+ /* d += a0 * b4 */
+ "movq 32(%%rbx),%%rax\n"
+ "mulq %%r10\n"
+ "addq %%rax,%%rcx\n"
+ "adcq %%rdx,%%r15\n"
+ /* d += c * R */
+ "movq %%r8,%%rax\n"
+ "movq $0x1000003d10,%%rdx\n"
+ "mulq %%rdx\n"
+ "addq %%rax,%%rcx\n"
+ "adcq %%rdx,%%r15\n"
+ /* t4 = d & M (%%rsi) */
+ "movq %%rcx,%%rsi\n"
+ "movq $0xfffffffffffff,%%rdx\n"
+ "andq %%rdx,%%rsi\n"
+ /* d >>= 52 */
+ "shrdq $52,%%r15,%%rcx\n"
+ "xorq %%r15,%%r15\n"
+ /* tx = t4 >> 48 (tmp3) */
+ "movq %%rsi,%%rax\n"
+ "shrq $48,%%rax\n"
+ "movq %%rax,%q3\n"
+ /* t4 &= (M >> 4) (tmp2) */
+ "movq $0xffffffffffff,%%rax\n"
+ "andq %%rax,%%rsi\n"
+ "movq %%rsi,%q2\n"
+ /* c = a0 * b0 */
+ "movq 0(%%rbx),%%rax\n"
+ "mulq %%r10\n"
+ "movq %%rax,%%r8\n"
+ "movq %%rdx,%%r9\n"
+ /* d += a4 * b1 */
+ "movq 8(%%rbx),%%rax\n"
+ "mulq %%r14\n"
+ "addq %%rax,%%rcx\n"
+ "adcq %%rdx,%%r15\n"
+ /* d += a3 * b2 */
+ "movq 16(%%rbx),%%rax\n"
+ "mulq %%r13\n"
+ "addq %%rax,%%rcx\n"
+ "adcq %%rdx,%%r15\n"
+ /* d += a2 * b3 */
+ "movq 24(%%rbx),%%rax\n"
+ "mulq %%r12\n"
+ "addq %%rax,%%rcx\n"
+ "adcq %%rdx,%%r15\n"
+ /* d += a1 * b4 */
+ "movq 32(%%rbx),%%rax\n"
+ "mulq %%r11\n"
+ "addq %%rax,%%rcx\n"
+ "adcq %%rdx,%%r15\n"
+ /* u0 = d & M (%%rsi) */
+ "movq %%rcx,%%rsi\n"
+ "movq $0xfffffffffffff,%%rdx\n"
+ "andq %%rdx,%%rsi\n"
+ /* d >>= 52 */
+ "shrdq $52,%%r15,%%rcx\n"
+ "xorq %%r15,%%r15\n"
+ /* u0 = (u0 << 4) | tx (%%rsi) */
+ "shlq $4,%%rsi\n"
+ "movq %q3,%%rax\n"
+ "orq %%rax,%%rsi\n"
+ /* c += u0 * (R >> 4) */
+ "movq $0x1000003d1,%%rax\n"
+ "mulq %%rsi\n"
+ "addq %%rax,%%r8\n"
+ "adcq %%rdx,%%r9\n"
+ /* r[0] = c & M */
+ "movq %%r8,%%rax\n"
+ "movq $0xfffffffffffff,%%rdx\n"
+ "andq %%rdx,%%rax\n"
+ "movq %%rax,0(%%rdi)\n"
+ /* c >>= 52 */
+ "shrdq $52,%%r9,%%r8\n"
+ "xorq %%r9,%%r9\n"
+ /* c += a1 * b0 */
+ "movq 0(%%rbx),%%rax\n"
+ "mulq %%r11\n"
+ "addq %%rax,%%r8\n"
+ "adcq %%rdx,%%r9\n"
+ /* c += a0 * b1 */
+ "movq 8(%%rbx),%%rax\n"
+ "mulq %%r10\n"
+ "addq %%rax,%%r8\n"
+ "adcq %%rdx,%%r9\n"
+ /* d += a4 * b2 */
+ "movq 16(%%rbx),%%rax\n"
+ "mulq %%r14\n"
+ "addq %%rax,%%rcx\n"
+ "adcq %%rdx,%%r15\n"
+ /* d += a3 * b3 */
+ "movq 24(%%rbx),%%rax\n"
+ "mulq %%r13\n"
+ "addq %%rax,%%rcx\n"
+ "adcq %%rdx,%%r15\n"
+ /* d += a2 * b4 */
+ "movq 32(%%rbx),%%rax\n"
+ "mulq %%r12\n"
+ "addq %%rax,%%rcx\n"
+ "adcq %%rdx,%%r15\n"
+ /* c += (d & M) * R */
+ "movq %%rcx,%%rax\n"
+ "movq $0xfffffffffffff,%%rdx\n"
+ "andq %%rdx,%%rax\n"
+ "movq $0x1000003d10,%%rdx\n"
+ "mulq %%rdx\n"
+ "addq %%rax,%%r8\n"
+ "adcq %%rdx,%%r9\n"
+ /* d >>= 52 */
+ "shrdq $52,%%r15,%%rcx\n"
+ "xorq %%r15,%%r15\n"
+ /* r[1] = c & M */
+ "movq %%r8,%%rax\n"
+ "movq $0xfffffffffffff,%%rdx\n"
+ "andq %%rdx,%%rax\n"
+ "movq %%rax,8(%%rdi)\n"
+ /* c >>= 52 */
+ "shrdq $52,%%r9,%%r8\n"
+ "xorq %%r9,%%r9\n"
+ /* c += a2 * b0 */
+ "movq 0(%%rbx),%%rax\n"
+ "mulq %%r12\n"
+ "addq %%rax,%%r8\n"
+ "adcq %%rdx,%%r9\n"
+ /* c += a1 * b1 */
+ "movq 8(%%rbx),%%rax\n"
+ "mulq %%r11\n"
+ "addq %%rax,%%r8\n"
+ "adcq %%rdx,%%r9\n"
+ /* c += a0 * b2 (last use of %%r10 = a0) */
+ "movq 16(%%rbx),%%rax\n"
+ "mulq %%r10\n"
+ "addq %%rax,%%r8\n"
+ "adcq %%rdx,%%r9\n"
+ /* fetch t3 (%%r10, overwrites a0), t4 (%%rsi) */
+ "movq %q2,%%rsi\n"
+ "movq %q1,%%r10\n"
+ /* d += a4 * b3 */
+ "movq 24(%%rbx),%%rax\n"
+ "mulq %%r14\n"
+ "addq %%rax,%%rcx\n"
+ "adcq %%rdx,%%r15\n"
+ /* d += a3 * b4 */
+ "movq 32(%%rbx),%%rax\n"
+ "mulq %%r13\n"
+ "addq %%rax,%%rcx\n"
+ "adcq %%rdx,%%r15\n"
+ /* c += (d & M) * R */
+ "movq %%rcx,%%rax\n"
+ "movq $0xfffffffffffff,%%rdx\n"
+ "andq %%rdx,%%rax\n"
+ "movq $0x1000003d10,%%rdx\n"
+ "mulq %%rdx\n"
+ "addq %%rax,%%r8\n"
+ "adcq %%rdx,%%r9\n"
+ /* d >>= 52 (%%rcx only) */
+ "shrdq $52,%%r15,%%rcx\n"
+ /* r[2] = c & M */
+ "movq %%r8,%%rax\n"
+ "movq $0xfffffffffffff,%%rdx\n"
+ "andq %%rdx,%%rax\n"
+ "movq %%rax,16(%%rdi)\n"
+ /* c >>= 52 */
+ "shrdq $52,%%r9,%%r8\n"
+ "xorq %%r9,%%r9\n"
+ /* c += t3 */
+ "addq %%r10,%%r8\n"
+ /* c += d * R */
+ "movq %%rcx,%%rax\n"
+ "movq $0x1000003d10,%%rdx\n"
+ "mulq %%rdx\n"
+ "addq %%rax,%%r8\n"
+ "adcq %%rdx,%%r9\n"
+ /* r[3] = c & M */
+ "movq %%r8,%%rax\n"
+ "movq $0xfffffffffffff,%%rdx\n"
+ "andq %%rdx,%%rax\n"
+ "movq %%rax,24(%%rdi)\n"
+ /* c >>= 52 (%%r8 only) */
+ "shrdq $52,%%r9,%%r8\n"
+ /* c += t4 (%%r8 only) */
+ "addq %%rsi,%%r8\n"
+ /* r[4] = c */
+ "movq %%r8,32(%%rdi)\n"
+: "+S"(a), "=m"(tmp1), "=m"(tmp2), "=m"(tmp3)
+: "b"(b), "D"(r)
+: "%rax", "%rcx", "%rdx", "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", "cc", "memory"
+);
+}
+
+SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint64_t *r, const uint64_t *a) {
+/**
+ * Registers: rdx:rax = multiplication accumulator
+ * r9:r8 = c
+ * rcx:rbx = d
+ * r10-r14 = a0-a4
+ * r15 = M (0xfffffffffffff)
+ * rdi = r
+ * rsi = a / t?
+ */
+ uint64_t tmp1, tmp2, tmp3;
+__asm__ __volatile__(
+ "movq 0(%%rsi),%%r10\n"
+ "movq 8(%%rsi),%%r11\n"
+ "movq 16(%%rsi),%%r12\n"
+ "movq 24(%%rsi),%%r13\n"
+ "movq 32(%%rsi),%%r14\n"
+ "movq $0xfffffffffffff,%%r15\n"
+
+ /* d = (a0*2) * a3 */
+ "leaq (%%r10,%%r10,1),%%rax\n"
+ "mulq %%r13\n"
+ "movq %%rax,%%rbx\n"
+ "movq %%rdx,%%rcx\n"
+ /* d += (a1*2) * a2 */
+ "leaq (%%r11,%%r11,1),%%rax\n"
+ "mulq %%r12\n"
+ "addq %%rax,%%rbx\n"
+ "adcq %%rdx,%%rcx\n"
+ /* c = a4 * a4 */
+ "movq %%r14,%%rax\n"
+ "mulq %%r14\n"
+ "movq %%rax,%%r8\n"
+ "movq %%rdx,%%r9\n"
+ /* d += (c & M) * R */
+ "andq %%r15,%%rax\n"
+ "movq $0x1000003d10,%%rdx\n"
+ "mulq %%rdx\n"
+ "addq %%rax,%%rbx\n"
+ "adcq %%rdx,%%rcx\n"
+ /* c >>= 52 (%%r8 only) */
+ "shrdq $52,%%r9,%%r8\n"
+ /* t3 (tmp1) = d & M */
+ "movq %%rbx,%%rsi\n"
+ "andq %%r15,%%rsi\n"
+ "movq %%rsi,%q1\n"
+ /* d >>= 52 */
+ "shrdq $52,%%rcx,%%rbx\n"
+ "xorq %%rcx,%%rcx\n"
+ /* a4 *= 2 */
+ "addq %%r14,%%r14\n"
+ /* d += a0 * a4 */
+ "movq %%r10,%%rax\n"
+ "mulq %%r14\n"
+ "addq %%rax,%%rbx\n"
+ "adcq %%rdx,%%rcx\n"
+ /* d+= (a1*2) * a3 */
+ "leaq (%%r11,%%r11,1),%%rax\n"
+ "mulq %%r13\n"
+ "addq %%rax,%%rbx\n"
+ "adcq %%rdx,%%rcx\n"
+ /* d += a2 * a2 */
+ "movq %%r12,%%rax\n"
+ "mulq %%r12\n"
+ "addq %%rax,%%rbx\n"
+ "adcq %%rdx,%%rcx\n"
+ /* d += c * R */
+ "movq %%r8,%%rax\n"
+ "movq $0x1000003d10,%%rdx\n"
+ "mulq %%rdx\n"
+ "addq %%rax,%%rbx\n"
+ "adcq %%rdx,%%rcx\n"
+ /* t4 = d & M (%%rsi) */
+ "movq %%rbx,%%rsi\n"
+ "andq %%r15,%%rsi\n"
+ /* d >>= 52 */
+ "shrdq $52,%%rcx,%%rbx\n"
+ "xorq %%rcx,%%rcx\n"
+ /* tx = t4 >> 48 (tmp3) */
+ "movq %%rsi,%%rax\n"
+ "shrq $48,%%rax\n"
+ "movq %%rax,%q3\n"
+ /* t4 &= (M >> 4) (tmp2) */
+ "movq $0xffffffffffff,%%rax\n"
+ "andq %%rax,%%rsi\n"
+ "movq %%rsi,%q2\n"
+ /* c = a0 * a0 */
+ "movq %%r10,%%rax\n"
+ "mulq %%r10\n"
+ "movq %%rax,%%r8\n"
+ "movq %%rdx,%%r9\n"
+ /* d += a1 * a4 */
+ "movq %%r11,%%rax\n"
+ "mulq %%r14\n"
+ "addq %%rax,%%rbx\n"
+ "adcq %%rdx,%%rcx\n"
+ /* d += (a2*2) * a3 */
+ "leaq (%%r12,%%r12,1),%%rax\n"
+ "mulq %%r13\n"
+ "addq %%rax,%%rbx\n"
+ "adcq %%rdx,%%rcx\n"
+ /* u0 = d & M (%%rsi) */
+ "movq %%rbx,%%rsi\n"
+ "andq %%r15,%%rsi\n"
+ /* d >>= 52 */
+ "shrdq $52,%%rcx,%%rbx\n"
+ "xorq %%rcx,%%rcx\n"
+ /* u0 = (u0 << 4) | tx (%%rsi) */
+ "shlq $4,%%rsi\n"
+ "movq %q3,%%rax\n"
+ "orq %%rax,%%rsi\n"
+ /* c += u0 * (R >> 4) */
+ "movq $0x1000003d1,%%rax\n"
+ "mulq %%rsi\n"
+ "addq %%rax,%%r8\n"
+ "adcq %%rdx,%%r9\n"
+ /* r[0] = c & M */
+ "movq %%r8,%%rax\n"
+ "andq %%r15,%%rax\n"
+ "movq %%rax,0(%%rdi)\n"
+ /* c >>= 52 */
+ "shrdq $52,%%r9,%%r8\n"
+ "xorq %%r9,%%r9\n"
+ /* a0 *= 2 */
+ "addq %%r10,%%r10\n"
+ /* c += a0 * a1 */
+ "movq %%r10,%%rax\n"
+ "mulq %%r11\n"
+ "addq %%rax,%%r8\n"
+ "adcq %%rdx,%%r9\n"
+ /* d += a2 * a4 */
+ "movq %%r12,%%rax\n"
+ "mulq %%r14\n"
+ "addq %%rax,%%rbx\n"
+ "adcq %%rdx,%%rcx\n"
+ /* d += a3 * a3 */
+ "movq %%r13,%%rax\n"
+ "mulq %%r13\n"
+ "addq %%rax,%%rbx\n"
+ "adcq %%rdx,%%rcx\n"
+ /* c += (d & M) * R */
+ "movq %%rbx,%%rax\n"
+ "andq %%r15,%%rax\n"
+ "movq $0x1000003d10,%%rdx\n"
+ "mulq %%rdx\n"
+ "addq %%rax,%%r8\n"
+ "adcq %%rdx,%%r9\n"
+ /* d >>= 52 */
+ "shrdq $52,%%rcx,%%rbx\n"
+ "xorq %%rcx,%%rcx\n"
+ /* r[1] = c & M */
+ "movq %%r8,%%rax\n"
+ "andq %%r15,%%rax\n"
+ "movq %%rax,8(%%rdi)\n"
+ /* c >>= 52 */
+ "shrdq $52,%%r9,%%r8\n"
+ "xorq %%r9,%%r9\n"
+ /* c += a0 * a2 (last use of %%r10) */
+ "movq %%r10,%%rax\n"
+ "mulq %%r12\n"
+ "addq %%rax,%%r8\n"
+ "adcq %%rdx,%%r9\n"
+ /* fetch t3 (%%r10, overwrites a0),t4 (%%rsi) */
+ "movq %q2,%%rsi\n"
+ "movq %q1,%%r10\n"
+ /* c += a1 * a1 */
+ "movq %%r11,%%rax\n"
+ "mulq %%r11\n"
+ "addq %%rax,%%r8\n"
+ "adcq %%rdx,%%r9\n"
+ /* d += a3 * a4 */
+ "movq %%r13,%%rax\n"
+ "mulq %%r14\n"
+ "addq %%rax,%%rbx\n"
+ "adcq %%rdx,%%rcx\n"
+ /* c += (d & M) * R */
+ "movq %%rbx,%%rax\n"
+ "andq %%r15,%%rax\n"
+ "movq $0x1000003d10,%%rdx\n"
+ "mulq %%rdx\n"
+ "addq %%rax,%%r8\n"
+ "adcq %%rdx,%%r9\n"
+ /* d >>= 52 (%%rbx only) */
+ "shrdq $52,%%rcx,%%rbx\n"
+ /* r[2] = c & M */
+ "movq %%r8,%%rax\n"
+ "andq %%r15,%%rax\n"
+ "movq %%rax,16(%%rdi)\n"
+ /* c >>= 52 */
+ "shrdq $52,%%r9,%%r8\n"
+ "xorq %%r9,%%r9\n"
+ /* c += t3 */
+ "addq %%r10,%%r8\n"
+ /* c += d * R */
+ "movq %%rbx,%%rax\n"
+ "movq $0x1000003d10,%%rdx\n"
+ "mulq %%rdx\n"
+ "addq %%rax,%%r8\n"
+ "adcq %%rdx,%%r9\n"
+ /* r[3] = c & M */
+ "movq %%r8,%%rax\n"
+ "andq %%r15,%%rax\n"
+ "movq %%rax,24(%%rdi)\n"
+ /* c >>= 52 (%%r8 only) */
+ "shrdq $52,%%r9,%%r8\n"
+ /* c += t4 (%%r8 only) */
+ "addq %%rsi,%%r8\n"
+ /* r[4] = c */
+ "movq %%r8,32(%%rdi)\n"
+: "+S"(a), "=m"(tmp1), "=m"(tmp2), "=m"(tmp3)
+: "D"(r)
+: "%rax", "%rbx", "%rcx", "%rdx", "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", "cc", "memory"
+);
+}
+
+#endif
diff --git a/src/secp256k1/src/field_5x52_impl.h b/src/secp256k1/src/field_5x52_impl.h
new file mode 100644
index 0000000000..bda4c3dfc2
--- /dev/null
+++ b/src/secp256k1/src/field_5x52_impl.h
@@ -0,0 +1,454 @@
+/**********************************************************************
+ * Copyright (c) 2013, 2014 Pieter Wuille *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
+ **********************************************************************/
+
+#ifndef _SECP256K1_FIELD_REPR_IMPL_H_
+#define _SECP256K1_FIELD_REPR_IMPL_H_
+
+#if defined HAVE_CONFIG_H
+#include "libsecp256k1-config.h"
+#endif
+
+#include <string.h>
+#include "util.h"
+#include "num.h"
+#include "field.h"
+
+#if defined(USE_ASM_X86_64)
+#include "field_5x52_asm_impl.h"
+#else
+#include "field_5x52_int128_impl.h"
+#endif
+
+/** Implements arithmetic modulo FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F,
+ * represented as 5 uint64_t's in base 2^52. The values are allowed to contain >52 each. In particular,
+ * each FieldElem has a 'magnitude' associated with it. Internally, a magnitude M means each element
+ * is at most M*(2^53-1), except the most significant one, which is limited to M*(2^49-1). All operations
+ * accept any input with magnitude at most M, and have different rules for propagating magnitude to their
+ * output.
+ */
+
+#ifdef VERIFY
+static void secp256k1_fe_verify(const secp256k1_fe_t *a) {
+ const uint64_t *d = a->n;
+ int m = a->normalized ? 1 : 2 * a->magnitude, r = 1;
+ /* secp256k1 'p' value defined in "Standards for Efficient Cryptography" (SEC2) 2.7.1. */
+ r &= (d[0] <= 0xFFFFFFFFFFFFFULL * m);
+ r &= (d[1] <= 0xFFFFFFFFFFFFFULL * m);
+ r &= (d[2] <= 0xFFFFFFFFFFFFFULL * m);
+ r &= (d[3] <= 0xFFFFFFFFFFFFFULL * m);
+ r &= (d[4] <= 0x0FFFFFFFFFFFFULL * m);
+ r &= (a->magnitude >= 0);
+ r &= (a->magnitude <= 2048);
+ if (a->normalized) {
+ r &= (a->magnitude <= 1);
+ if (r && (d[4] == 0x0FFFFFFFFFFFFULL) && ((d[3] & d[2] & d[1]) == 0xFFFFFFFFFFFFFULL)) {
+ r &= (d[0] < 0xFFFFEFFFFFC2FULL);
+ }
+ }
+ VERIFY_CHECK(r == 1);
+}
+#else
+static void secp256k1_fe_verify(const secp256k1_fe_t *a) {
+ (void)a;
+}
+#endif
+
+static void secp256k1_fe_normalize(secp256k1_fe_t *r) {
+ uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4];
+
+ /* Reduce t4 at the start so there will be at most a single carry from the first pass */
+ uint64_t m;
+ uint64_t x = t4 >> 48; t4 &= 0x0FFFFFFFFFFFFULL;
+
+ /* The first pass ensures the magnitude is 1, ... */
+ t0 += x * 0x1000003D1ULL;
+ t1 += (t0 >> 52); t0 &= 0xFFFFFFFFFFFFFULL;
+ t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL; m = t1;
+ t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL; m &= t2;
+ t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL; m &= t3;
+
+ /* ... except for a possible carry at bit 48 of t4 (i.e. bit 256 of the field element) */
+ VERIFY_CHECK(t4 >> 49 == 0);
+
+ /* At most a single final reduction is needed; check if the value is >= the field characteristic */
+ x = (t4 >> 48) | ((t4 == 0x0FFFFFFFFFFFFULL) & (m == 0xFFFFFFFFFFFFFULL)
+ & (t0 >= 0xFFFFEFFFFFC2FULL));
+
+ /* Apply the final reduction (for constant-time behaviour, we do it always) */
+ t0 += x * 0x1000003D1ULL;
+ t1 += (t0 >> 52); t0 &= 0xFFFFFFFFFFFFFULL;
+ t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL;
+ t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL;
+ t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL;
+
+ /* If t4 didn't carry to bit 48 already, then it should have after any final reduction */
+ VERIFY_CHECK(t4 >> 48 == x);
+
+ /* Mask off the possible multiple of 2^256 from the final reduction */
+ t4 &= 0x0FFFFFFFFFFFFULL;
+
+ r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4;
+
+#ifdef VERIFY
+ r->magnitude = 1;
+ r->normalized = 1;
+ secp256k1_fe_verify(r);
+#endif
+}
+
+static void secp256k1_fe_normalize_weak(secp256k1_fe_t *r) {
+ uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4];
+
+ /* Reduce t4 at the start so there will be at most a single carry from the first pass */
+ uint64_t x = t4 >> 48; t4 &= 0x0FFFFFFFFFFFFULL;
+
+ /* The first pass ensures the magnitude is 1, ... */
+ t0 += x * 0x1000003D1ULL;
+ t1 += (t0 >> 52); t0 &= 0xFFFFFFFFFFFFFULL;
+ t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL;
+ t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL;
+ t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL;
+
+ /* ... except for a possible carry at bit 48 of t4 (i.e. bit 256 of the field element) */
+ VERIFY_CHECK(t4 >> 49 == 0);
+
+ r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4;
+
+#ifdef VERIFY
+ r->magnitude = 1;
+ secp256k1_fe_verify(r);
+#endif
+}
+
+static void secp256k1_fe_normalize_var(secp256k1_fe_t *r) {
+ uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4];
+
+ /* Reduce t4 at the start so there will be at most a single carry from the first pass */
+ uint64_t m;
+ uint64_t x = t4 >> 48; t4 &= 0x0FFFFFFFFFFFFULL;
+
+ /* The first pass ensures the magnitude is 1, ... */
+ t0 += x * 0x1000003D1ULL;
+ t1 += (t0 >> 52); t0 &= 0xFFFFFFFFFFFFFULL;
+ t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL; m = t1;
+ t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL; m &= t2;
+ t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL; m &= t3;
+
+ /* ... except for a possible carry at bit 48 of t4 (i.e. bit 256 of the field element) */
+ VERIFY_CHECK(t4 >> 49 == 0);
+
+ /* At most a single final reduction is needed; check if the value is >= the field characteristic */
+ x = (t4 >> 48) | ((t4 == 0x0FFFFFFFFFFFFULL) & (m == 0xFFFFFFFFFFFFFULL)
+ & (t0 >= 0xFFFFEFFFFFC2FULL));
+
+ if (x) {
+ t0 += 0x1000003D1ULL;
+ t1 += (t0 >> 52); t0 &= 0xFFFFFFFFFFFFFULL;
+ t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL;
+ t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL;
+ t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL;
+
+ /* If t4 didn't carry to bit 48 already, then it should have after any final reduction */
+ VERIFY_CHECK(t4 >> 48 == x);
+
+ /* Mask off the possible multiple of 2^256 from the final reduction */
+ t4 &= 0x0FFFFFFFFFFFFULL;
+ }
+
+ r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4;
+
+#ifdef VERIFY
+ r->magnitude = 1;
+ r->normalized = 1;
+ secp256k1_fe_verify(r);
+#endif
+}
+
+static int secp256k1_fe_normalizes_to_zero(secp256k1_fe_t *r) {
+ uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4];
+
+ /* z0 tracks a possible raw value of 0, z1 tracks a possible raw value of P */
+ uint64_t z0, z1;
+
+ /* Reduce t4 at the start so there will be at most a single carry from the first pass */
+ uint64_t x = t4 >> 48; t4 &= 0x0FFFFFFFFFFFFULL;
+
+ /* The first pass ensures the magnitude is 1, ... */
+ t0 += x * 0x1000003D1ULL;
+ t1 += (t0 >> 52); t0 &= 0xFFFFFFFFFFFFFULL; z0 = t0; z1 = t0 ^ 0x1000003D0ULL;
+ t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL; z0 |= t1; z1 &= t1;
+ t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL; z0 |= t2; z1 &= t2;
+ t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL; z0 |= t3; z1 &= t3;
+ z0 |= t4; z1 &= t4 ^ 0xF000000000000ULL;
+
+ /* ... except for a possible carry at bit 48 of t4 (i.e. bit 256 of the field element) */
+ VERIFY_CHECK(t4 >> 49 == 0);
+
+ return (z0 == 0) | (z1 == 0xFFFFFFFFFFFFFULL);
+}
+
+static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe_t *r) {
+ uint64_t t0, t1, t2, t3, t4;
+ uint64_t z0, z1;
+ uint64_t x;
+
+ t0 = r->n[0];
+ t4 = r->n[4];
+
+ /* Reduce t4 at the start so there will be at most a single carry from the first pass */
+ x = t4 >> 48;
+
+ /* The first pass ensures the magnitude is 1, ... */
+ t0 += x * 0x1000003D1ULL;
+
+ /* z0 tracks a possible raw value of 0, z1 tracks a possible raw value of P */
+ z0 = t0 & 0xFFFFFFFFFFFFFULL;
+ z1 = z0 ^ 0x1000003D0ULL;
+
+ /* Fast return path should catch the majority of cases */
+ if ((z0 != 0ULL) & (z1 != 0xFFFFFFFFFFFFFULL)) {
+ return 0;
+ }
+
+ t1 = r->n[1];
+ t2 = r->n[2];
+ t3 = r->n[3];
+
+ t4 &= 0x0FFFFFFFFFFFFULL;
+
+ t1 += (t0 >> 52); t0 = z0;
+ t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL; z0 |= t1; z1 &= t1;
+ t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL; z0 |= t2; z1 &= t2;
+ t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL; z0 |= t3; z1 &= t3;
+ z0 |= t4; z1 &= t4 ^ 0xF000000000000ULL;
+
+ /* ... except for a possible carry at bit 48 of t4 (i.e. bit 256 of the field element) */
+ VERIFY_CHECK(t4 >> 49 == 0);
+
+ return (z0 == 0) | (z1 == 0xFFFFFFFFFFFFFULL);
+}
+
+SECP256K1_INLINE static void secp256k1_fe_set_int(secp256k1_fe_t *r, int a) {
+ r->n[0] = a;
+ r->n[1] = r->n[2] = r->n[3] = r->n[4] = 0;
+#ifdef VERIFY
+ r->magnitude = 1;
+ r->normalized = 1;
+ secp256k1_fe_verify(r);
+#endif
+}
+
+SECP256K1_INLINE static int secp256k1_fe_is_zero(const secp256k1_fe_t *a) {
+ const uint64_t *t = a->n;
+#ifdef VERIFY
+ VERIFY_CHECK(a->normalized);
+ secp256k1_fe_verify(a);
+#endif
+ return (t[0] | t[1] | t[2] | t[3] | t[4]) == 0;
+}
+
+SECP256K1_INLINE static int secp256k1_fe_is_odd(const secp256k1_fe_t *a) {
+#ifdef VERIFY
+ VERIFY_CHECK(a->normalized);
+ secp256k1_fe_verify(a);
+#endif
+ return a->n[0] & 1;
+}
+
+SECP256K1_INLINE static void secp256k1_fe_clear(secp256k1_fe_t *a) {
+ int i;
+#ifdef VERIFY
+ a->magnitude = 0;
+ a->normalized = 1;
+#endif
+ for (i=0; i<5; i++) {
+ a->n[i] = 0;
+ }
+}
+
+static int secp256k1_fe_cmp_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b) {
+ int i;
+#ifdef VERIFY
+ VERIFY_CHECK(a->normalized);
+ VERIFY_CHECK(b->normalized);
+ secp256k1_fe_verify(a);
+ secp256k1_fe_verify(b);
+#endif
+ for (i = 4; i >= 0; i--) {
+ if (a->n[i] > b->n[i]) {
+ return 1;
+ }
+ if (a->n[i] < b->n[i]) {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int secp256k1_fe_set_b32(secp256k1_fe_t *r, const unsigned char *a) {
+ int i;
+ r->n[0] = r->n[1] = r->n[2] = r->n[3] = r->n[4] = 0;
+ for (i=0; i<32; i++) {
+ int j;
+ for (j=0; j<2; j++) {
+ int limb = (8*i+4*j)/52;
+ int shift = (8*i+4*j)%52;
+ r->n[limb] |= (uint64_t)((a[31-i] >> (4*j)) & 0xF) << shift;
+ }
+ }
+ if (r->n[4] == 0x0FFFFFFFFFFFFULL && (r->n[3] & r->n[2] & r->n[1]) == 0xFFFFFFFFFFFFFULL && r->n[0] >= 0xFFFFEFFFFFC2FULL) {
+ return 0;
+ }
+#ifdef VERIFY
+ r->magnitude = 1;
+ r->normalized = 1;
+ secp256k1_fe_verify(r);
+#endif
+ return 1;
+}
+
+/** Convert a field element to a 32-byte big endian value. Requires the input to be normalized */
+static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe_t *a) {
+ int i;
+#ifdef VERIFY
+ VERIFY_CHECK(a->normalized);
+ secp256k1_fe_verify(a);
+#endif
+ for (i=0; i<32; i++) {
+ int j;
+ int c = 0;
+ for (j=0; j<2; j++) {
+ int limb = (8*i+4*j)/52;
+ int shift = (8*i+4*j)%52;
+ c |= ((a->n[limb] >> shift) & 0xF) << (4 * j);
+ }
+ r[31-i] = c;
+ }
+}
+
+SECP256K1_INLINE static void secp256k1_fe_negate(secp256k1_fe_t *r, const secp256k1_fe_t *a, int m) {
+#ifdef VERIFY
+ VERIFY_CHECK(a->magnitude <= m);
+ secp256k1_fe_verify(a);
+#endif
+ r->n[0] = 0xFFFFEFFFFFC2FULL * 2 * (m + 1) - a->n[0];
+ r->n[1] = 0xFFFFFFFFFFFFFULL * 2 * (m + 1) - a->n[1];
+ r->n[2] = 0xFFFFFFFFFFFFFULL * 2 * (m + 1) - a->n[2];
+ r->n[3] = 0xFFFFFFFFFFFFFULL * 2 * (m + 1) - a->n[3];
+ r->n[4] = 0x0FFFFFFFFFFFFULL * 2 * (m + 1) - a->n[4];
+#ifdef VERIFY
+ r->magnitude = m + 1;
+ r->normalized = 0;
+ secp256k1_fe_verify(r);
+#endif
+}
+
+SECP256K1_INLINE static void secp256k1_fe_mul_int(secp256k1_fe_t *r, int a) {
+ r->n[0] *= a;
+ r->n[1] *= a;
+ r->n[2] *= a;
+ r->n[3] *= a;
+ r->n[4] *= a;
+#ifdef VERIFY
+ r->magnitude *= a;
+ r->normalized = 0;
+ secp256k1_fe_verify(r);
+#endif
+}
+
+SECP256K1_INLINE static void secp256k1_fe_add(secp256k1_fe_t *r, const secp256k1_fe_t *a) {
+#ifdef VERIFY
+ secp256k1_fe_verify(a);
+#endif
+ r->n[0] += a->n[0];
+ r->n[1] += a->n[1];
+ r->n[2] += a->n[2];
+ r->n[3] += a->n[3];
+ r->n[4] += a->n[4];
+#ifdef VERIFY
+ r->magnitude += a->magnitude;
+ r->normalized = 0;
+ secp256k1_fe_verify(r);
+#endif
+}
+
+static void secp256k1_fe_mul(secp256k1_fe_t *r, const secp256k1_fe_t *a, const secp256k1_fe_t * SECP256K1_RESTRICT b) {
+#ifdef VERIFY
+ VERIFY_CHECK(a->magnitude <= 8);
+ VERIFY_CHECK(b->magnitude <= 8);
+ secp256k1_fe_verify(a);
+ secp256k1_fe_verify(b);
+ VERIFY_CHECK(r != b);
+#endif
+ secp256k1_fe_mul_inner(r->n, a->n, b->n);
+#ifdef VERIFY
+ r->magnitude = 1;
+ r->normalized = 0;
+ secp256k1_fe_verify(r);
+#endif
+}
+
+static void secp256k1_fe_sqr(secp256k1_fe_t *r, const secp256k1_fe_t *a) {
+#ifdef VERIFY
+ VERIFY_CHECK(a->magnitude <= 8);
+ secp256k1_fe_verify(a);
+#endif
+ secp256k1_fe_sqr_inner(r->n, a->n);
+#ifdef VERIFY
+ r->magnitude = 1;
+ r->normalized = 0;
+ secp256k1_fe_verify(r);
+#endif
+}
+
+static SECP256K1_INLINE void secp256k1_fe_cmov(secp256k1_fe_t *r, const secp256k1_fe_t *a, int flag) {
+ uint64_t mask0, mask1;
+ mask0 = flag + ~((uint64_t)0);
+ mask1 = ~mask0;
+ r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1);
+ r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1);
+ r->n[2] = (r->n[2] & mask0) | (a->n[2] & mask1);
+ r->n[3] = (r->n[3] & mask0) | (a->n[3] & mask1);
+ r->n[4] = (r->n[4] & mask0) | (a->n[4] & mask1);
+#ifdef VERIFY
+ r->magnitude = (r->magnitude & mask0) | (a->magnitude & mask1);
+ r->normalized = (r->normalized & mask0) | (a->normalized & mask1);
+#endif
+}
+
+static SECP256K1_INLINE void secp256k1_fe_storage_cmov(secp256k1_fe_storage_t *r, const secp256k1_fe_storage_t *a, int flag) {
+ uint64_t mask0, mask1;
+ mask0 = flag + ~((uint64_t)0);
+ mask1 = ~mask0;
+ r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1);
+ r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1);
+ r->n[2] = (r->n[2] & mask0) | (a->n[2] & mask1);
+ r->n[3] = (r->n[3] & mask0) | (a->n[3] & mask1);
+}
+
+static void secp256k1_fe_to_storage(secp256k1_fe_storage_t *r, const secp256k1_fe_t *a) {
+#ifdef VERIFY
+ VERIFY_CHECK(a->normalized);
+#endif
+ r->n[0] = a->n[0] | a->n[1] << 52;
+ r->n[1] = a->n[1] >> 12 | a->n[2] << 40;
+ r->n[2] = a->n[2] >> 24 | a->n[3] << 28;
+ r->n[3] = a->n[3] >> 36 | a->n[4] << 16;
+}
+
+static SECP256K1_INLINE void secp256k1_fe_from_storage(secp256k1_fe_t *r, const secp256k1_fe_storage_t *a) {
+ r->n[0] = a->n[0] & 0xFFFFFFFFFFFFFULL;
+ r->n[1] = a->n[0] >> 52 | ((a->n[1] << 12) & 0xFFFFFFFFFFFFFULL);
+ r->n[2] = a->n[1] >> 40 | ((a->n[2] << 24) & 0xFFFFFFFFFFFFFULL);
+ r->n[3] = a->n[2] >> 28 | ((a->n[3] << 36) & 0xFFFFFFFFFFFFFULL);
+ r->n[4] = a->n[3] >> 16;
+#ifdef VERIFY
+ r->magnitude = 1;
+ r->normalized = 1;
+#endif
+}
+
+#endif
diff --git a/src/secp256k1/src/field_5x52_int128_impl.h b/src/secp256k1/src/field_5x52_int128_impl.h
new file mode 100644
index 0000000000..9280bb5ea2
--- /dev/null
+++ b/src/secp256k1/src/field_5x52_int128_impl.h
@@ -0,0 +1,277 @@
+/**********************************************************************
+ * Copyright (c) 2013, 2014 Pieter Wuille *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
+ **********************************************************************/
+
+#ifndef _SECP256K1_FIELD_INNER5X52_IMPL_H_
+#define _SECP256K1_FIELD_INNER5X52_IMPL_H_
+
+#include <stdint.h>
+
+#ifdef VERIFY
+#define VERIFY_BITS(x, n) VERIFY_CHECK(((x) >> (n)) == 0)
+#else
+#define VERIFY_BITS(x, n) do { } while(0)
+#endif
+
+SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint64_t *r, const uint64_t *a, const uint64_t * SECP256K1_RESTRICT b) {
+ uint128_t c, d;
+ uint64_t t3, t4, tx, u0;
+ uint64_t a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4];
+ const uint64_t M = 0xFFFFFFFFFFFFFULL, R = 0x1000003D10ULL;
+
+ VERIFY_BITS(a[0], 56);
+ VERIFY_BITS(a[1], 56);
+ VERIFY_BITS(a[2], 56);
+ VERIFY_BITS(a[3], 56);
+ VERIFY_BITS(a[4], 52);
+ VERIFY_BITS(b[0], 56);
+ VERIFY_BITS(b[1], 56);
+ VERIFY_BITS(b[2], 56);
+ VERIFY_BITS(b[3], 56);
+ VERIFY_BITS(b[4], 52);
+ VERIFY_CHECK(r != b);
+
+ /* [... a b c] is a shorthand for ... + a<<104 + b<<52 + c<<0 mod n.
+ * px is a shorthand for sum(a[i]*b[x-i], i=0..x).
+ * Note that [x 0 0 0 0 0] = [x*R].
+ */
+
+ d = (uint128_t)a0 * b[3]
+ + (uint128_t)a1 * b[2]
+ + (uint128_t)a2 * b[1]
+ + (uint128_t)a3 * b[0];
+ VERIFY_BITS(d, 114);
+ /* [d 0 0 0] = [p3 0 0 0] */
+ c = (uint128_t)a4 * b[4];
+ VERIFY_BITS(c, 112);
+ /* [c 0 0 0 0 d 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */
+ d += (c & M) * R; c >>= 52;
+ VERIFY_BITS(d, 115);
+ VERIFY_BITS(c, 60);
+ /* [c 0 0 0 0 0 d 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */
+ t3 = d & M; d >>= 52;
+ VERIFY_BITS(t3, 52);
+ VERIFY_BITS(d, 63);
+ /* [c 0 0 0 0 d t3 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */
+
+ d += (uint128_t)a0 * b[4]
+ + (uint128_t)a1 * b[3]
+ + (uint128_t)a2 * b[2]
+ + (uint128_t)a3 * b[1]
+ + (uint128_t)a4 * b[0];
+ VERIFY_BITS(d, 115);
+ /* [c 0 0 0 0 d t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */
+ d += c * R;
+ VERIFY_BITS(d, 116);
+ /* [d t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */
+ t4 = d & M; d >>= 52;
+ VERIFY_BITS(t4, 52);
+ VERIFY_BITS(d, 64);
+ /* [d t4 t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */
+ tx = (t4 >> 48); t4 &= (M >> 4);
+ VERIFY_BITS(tx, 4);
+ VERIFY_BITS(t4, 48);
+ /* [d t4+(tx<<48) t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */
+
+ c = (uint128_t)a0 * b[0];
+ VERIFY_BITS(c, 112);
+ /* [d t4+(tx<<48) t3 0 0 c] = [p8 0 0 0 p4 p3 0 0 p0] */
+ d += (uint128_t)a1 * b[4]
+ + (uint128_t)a2 * b[3]
+ + (uint128_t)a3 * b[2]
+ + (uint128_t)a4 * b[1];
+ VERIFY_BITS(d, 115);
+ /* [d t4+(tx<<48) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */
+ u0 = d & M; d >>= 52;
+ VERIFY_BITS(u0, 52);
+ VERIFY_BITS(d, 63);
+ /* [d u0 t4+(tx<<48) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */
+ /* [d 0 t4+(tx<<48)+(u0<<52) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */
+ u0 = (u0 << 4) | tx;
+ VERIFY_BITS(u0, 56);
+ /* [d 0 t4+(u0<<48) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */
+ c += (uint128_t)u0 * (R >> 4);
+ VERIFY_BITS(c, 115);
+ /* [d 0 t4 t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */
+ r[0] = c & M; c >>= 52;
+ VERIFY_BITS(r[0], 52);
+ VERIFY_BITS(c, 61);
+ /* [d 0 t4 t3 0 c r0] = [p8 0 0 p5 p4 p3 0 0 p0] */
+
+ c += (uint128_t)a0 * b[1]
+ + (uint128_t)a1 * b[0];
+ VERIFY_BITS(c, 114);
+ /* [d 0 t4 t3 0 c r0] = [p8 0 0 p5 p4 p3 0 p1 p0] */
+ d += (uint128_t)a2 * b[4]
+ + (uint128_t)a3 * b[3]
+ + (uint128_t)a4 * b[2];
+ VERIFY_BITS(d, 114);
+ /* [d 0 t4 t3 0 c r0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */
+ c += (d & M) * R; d >>= 52;
+ VERIFY_BITS(c, 115);
+ VERIFY_BITS(d, 62);
+ /* [d 0 0 t4 t3 0 c r0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */
+ r[1] = c & M; c >>= 52;
+ VERIFY_BITS(r[1], 52);
+ VERIFY_BITS(c, 63);
+ /* [d 0 0 t4 t3 c r1 r0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */
+
+ c += (uint128_t)a0 * b[2]
+ + (uint128_t)a1 * b[1]
+ + (uint128_t)a2 * b[0];
+ VERIFY_BITS(c, 114);
+ /* [d 0 0 t4 t3 c r1 r0] = [p8 0 p6 p5 p4 p3 p2 p1 p0] */
+ d += (uint128_t)a3 * b[4]
+ + (uint128_t)a4 * b[3];
+ VERIFY_BITS(d, 114);
+ /* [d 0 0 t4 t3 c t1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+ c += (d & M) * R; d >>= 52;
+ VERIFY_BITS(c, 115);
+ VERIFY_BITS(d, 62);
+ /* [d 0 0 0 t4 t3 c r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+
+ /* [d 0 0 0 t4 t3 c r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+ r[2] = c & M; c >>= 52;
+ VERIFY_BITS(r[2], 52);
+ VERIFY_BITS(c, 63);
+ /* [d 0 0 0 t4 t3+c r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+ c += d * R + t3;;
+ VERIFY_BITS(c, 100);
+ /* [t4 c r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+ r[3] = c & M; c >>= 52;
+ VERIFY_BITS(r[3], 52);
+ VERIFY_BITS(c, 48);
+ /* [t4+c r3 r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+ c += t4;
+ VERIFY_BITS(c, 49);
+ /* [c r3 r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+ r[4] = c;
+ VERIFY_BITS(r[4], 49);
+ /* [r4 r3 r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+}
+
+SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint64_t *r, const uint64_t *a) {
+ uint128_t c, d;
+ uint64_t a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4];
+ int64_t t3, t4, tx, u0;
+ const uint64_t M = 0xFFFFFFFFFFFFFULL, R = 0x1000003D10ULL;
+
+ VERIFY_BITS(a[0], 56);
+ VERIFY_BITS(a[1], 56);
+ VERIFY_BITS(a[2], 56);
+ VERIFY_BITS(a[3], 56);
+ VERIFY_BITS(a[4], 52);
+
+ /** [... a b c] is a shorthand for ... + a<<104 + b<<52 + c<<0 mod n.
+ * px is a shorthand for sum(a[i]*a[x-i], i=0..x).
+ * Note that [x 0 0 0 0 0] = [x*R].
+ */
+
+ d = (uint128_t)(a0*2) * a3
+ + (uint128_t)(a1*2) * a2;
+ VERIFY_BITS(d, 114);
+ /* [d 0 0 0] = [p3 0 0 0] */
+ c = (uint128_t)a4 * a4;
+ VERIFY_BITS(c, 112);
+ /* [c 0 0 0 0 d 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */
+ d += (c & M) * R; c >>= 52;
+ VERIFY_BITS(d, 115);
+ VERIFY_BITS(c, 60);
+ /* [c 0 0 0 0 0 d 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */
+ t3 = d & M; d >>= 52;
+ VERIFY_BITS(t3, 52);
+ VERIFY_BITS(d, 63);
+ /* [c 0 0 0 0 d t3 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */
+
+ a4 *= 2;
+ d += (uint128_t)a0 * a4
+ + (uint128_t)(a1*2) * a3
+ + (uint128_t)a2 * a2;
+ VERIFY_BITS(d, 115);
+ /* [c 0 0 0 0 d t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */
+ d += c * R;
+ VERIFY_BITS(d, 116);
+ /* [d t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */
+ t4 = d & M; d >>= 52;
+ VERIFY_BITS(t4, 52);
+ VERIFY_BITS(d, 64);
+ /* [d t4 t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */
+ tx = (t4 >> 48); t4 &= (M >> 4);
+ VERIFY_BITS(tx, 4);
+ VERIFY_BITS(t4, 48);
+ /* [d t4+(tx<<48) t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */
+
+ c = (uint128_t)a0 * a0;
+ VERIFY_BITS(c, 112);
+ /* [d t4+(tx<<48) t3 0 0 c] = [p8 0 0 0 p4 p3 0 0 p0] */
+ d += (uint128_t)a1 * a4
+ + (uint128_t)(a2*2) * a3;
+ VERIFY_BITS(d, 114);
+ /* [d t4+(tx<<48) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */
+ u0 = d & M; d >>= 52;
+ VERIFY_BITS(u0, 52);
+ VERIFY_BITS(d, 62);
+ /* [d u0 t4+(tx<<48) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */
+ /* [d 0 t4+(tx<<48)+(u0<<52) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */
+ u0 = (u0 << 4) | tx;
+ VERIFY_BITS(u0, 56);
+ /* [d 0 t4+(u0<<48) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */
+ c += (uint128_t)u0 * (R >> 4);
+ VERIFY_BITS(c, 113);
+ /* [d 0 t4 t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */
+ r[0] = c & M; c >>= 52;
+ VERIFY_BITS(r[0], 52);
+ VERIFY_BITS(c, 61);
+ /* [d 0 t4 t3 0 c r0] = [p8 0 0 p5 p4 p3 0 0 p0] */
+
+ a0 *= 2;
+ c += (uint128_t)a0 * a1;
+ VERIFY_BITS(c, 114);
+ /* [d 0 t4 t3 0 c r0] = [p8 0 0 p5 p4 p3 0 p1 p0] */
+ d += (uint128_t)a2 * a4
+ + (uint128_t)a3 * a3;
+ VERIFY_BITS(d, 114);
+ /* [d 0 t4 t3 0 c r0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */
+ c += (d & M) * R; d >>= 52;
+ VERIFY_BITS(c, 115);
+ VERIFY_BITS(d, 62);
+ /* [d 0 0 t4 t3 0 c r0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */
+ r[1] = c & M; c >>= 52;
+ VERIFY_BITS(r[1], 52);
+ VERIFY_BITS(c, 63);
+ /* [d 0 0 t4 t3 c r1 r0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */
+
+ c += (uint128_t)a0 * a2
+ + (uint128_t)a1 * a1;
+ VERIFY_BITS(c, 114);
+ /* [d 0 0 t4 t3 c r1 r0] = [p8 0 p6 p5 p4 p3 p2 p1 p0] */
+ d += (uint128_t)a3 * a4;
+ VERIFY_BITS(d, 114);
+ /* [d 0 0 t4 t3 c r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+ c += (d & M) * R; d >>= 52;
+ VERIFY_BITS(c, 115);
+ VERIFY_BITS(d, 62);
+ /* [d 0 0 0 t4 t3 c r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+ r[2] = c & M; c >>= 52;
+ VERIFY_BITS(r[2], 52);
+ VERIFY_BITS(c, 63);
+ /* [d 0 0 0 t4 t3+c r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+
+ c += d * R + t3;;
+ VERIFY_BITS(c, 100);
+ /* [t4 c r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+ r[3] = c & M; c >>= 52;
+ VERIFY_BITS(r[3], 52);
+ VERIFY_BITS(c, 48);
+ /* [t4+c r3 r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+ c += t4;
+ VERIFY_BITS(c, 49);
+ /* [c r3 r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+ r[4] = c;
+ VERIFY_BITS(r[4], 49);
+ /* [r4 r3 r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+}
+
+#endif
diff --git a/src/secp256k1/src/field_impl.h b/src/secp256k1/src/field_impl.h
new file mode 100644
index 0000000000..e6ec11e8f2
--- /dev/null
+++ b/src/secp256k1/src/field_impl.h
@@ -0,0 +1,263 @@
+/**********************************************************************
+ * Copyright (c) 2013, 2014 Pieter Wuille *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
+ **********************************************************************/
+
+#ifndef _SECP256K1_FIELD_IMPL_H_
+#define _SECP256K1_FIELD_IMPL_H_
+
+#if defined HAVE_CONFIG_H
+#include "libsecp256k1-config.h"
+#endif
+
+#include "util.h"
+
+#if defined(USE_FIELD_10X26)
+#include "field_10x26_impl.h"
+#elif defined(USE_FIELD_5X52)
+#include "field_5x52_impl.h"
+#else
+#error "Please select field implementation"
+#endif
+
+SECP256K1_INLINE static int secp256k1_fe_equal_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b) {
+ secp256k1_fe_t na;
+ secp256k1_fe_negate(&na, a, 1);
+ secp256k1_fe_add(&na, b);
+ return secp256k1_fe_normalizes_to_zero_var(&na);
+}
+
+static int secp256k1_fe_sqrt_var(secp256k1_fe_t *r, const secp256k1_fe_t *a) {
+ secp256k1_fe_t x2, x3, x6, x9, x11, x22, x44, x88, x176, x220, x223, t1;
+ int j;
+
+ /** The binary representation of (p + 1)/4 has 3 blocks of 1s, with lengths in
+ * { 2, 22, 223 }. Use an addition chain to calculate 2^n - 1 for each block:
+ * 1, [2], 3, 6, 9, 11, [22], 44, 88, 176, 220, [223]
+ */
+
+ secp256k1_fe_sqr(&x2, a);
+ secp256k1_fe_mul(&x2, &x2, a);
+
+ secp256k1_fe_sqr(&x3, &x2);
+ secp256k1_fe_mul(&x3, &x3, a);
+
+ x6 = x3;
+ for (j=0; j<3; j++) {
+ secp256k1_fe_sqr(&x6, &x6);
+ }
+ secp256k1_fe_mul(&x6, &x6, &x3);
+
+ x9 = x6;
+ for (j=0; j<3; j++) {
+ secp256k1_fe_sqr(&x9, &x9);
+ }
+ secp256k1_fe_mul(&x9, &x9, &x3);
+
+ x11 = x9;
+ for (j=0; j<2; j++) {
+ secp256k1_fe_sqr(&x11, &x11);
+ }
+ secp256k1_fe_mul(&x11, &x11, &x2);
+
+ x22 = x11;
+ for (j=0; j<11; j++) {
+ secp256k1_fe_sqr(&x22, &x22);
+ }
+ secp256k1_fe_mul(&x22, &x22, &x11);
+
+ x44 = x22;
+ for (j=0; j<22; j++) {
+ secp256k1_fe_sqr(&x44, &x44);
+ }
+ secp256k1_fe_mul(&x44, &x44, &x22);
+
+ x88 = x44;
+ for (j=0; j<44; j++) {
+ secp256k1_fe_sqr(&x88, &x88);
+ }
+ secp256k1_fe_mul(&x88, &x88, &x44);
+
+ x176 = x88;
+ for (j=0; j<88; j++) {
+ secp256k1_fe_sqr(&x176, &x176);
+ }
+ secp256k1_fe_mul(&x176, &x176, &x88);
+
+ x220 = x176;
+ for (j=0; j<44; j++) {
+ secp256k1_fe_sqr(&x220, &x220);
+ }
+ secp256k1_fe_mul(&x220, &x220, &x44);
+
+ x223 = x220;
+ for (j=0; j<3; j++) {
+ secp256k1_fe_sqr(&x223, &x223);
+ }
+ secp256k1_fe_mul(&x223, &x223, &x3);
+
+ /* The final result is then assembled using a sliding window over the blocks. */
+
+ t1 = x223;
+ for (j=0; j<23; j++) {
+ secp256k1_fe_sqr(&t1, &t1);
+ }
+ secp256k1_fe_mul(&t1, &t1, &x22);
+ for (j=0; j<6; j++) {
+ secp256k1_fe_sqr(&t1, &t1);
+ }
+ secp256k1_fe_mul(&t1, &t1, &x2);
+ secp256k1_fe_sqr(&t1, &t1);
+ secp256k1_fe_sqr(r, &t1);
+
+ /* Check that a square root was actually calculated */
+
+ secp256k1_fe_sqr(&t1, r);
+ return secp256k1_fe_equal_var(&t1, a);
+}
+
+static void secp256k1_fe_inv(secp256k1_fe_t *r, const secp256k1_fe_t *a) {
+ secp256k1_fe_t x2, x3, x6, x9, x11, x22, x44, x88, x176, x220, x223, t1;
+ int j;
+
+ /** The binary representation of (p - 2) has 5 blocks of 1s, with lengths in
+ * { 1, 2, 22, 223 }. Use an addition chain to calculate 2^n - 1 for each block:
+ * [1], [2], 3, 6, 9, 11, [22], 44, 88, 176, 220, [223]
+ */
+
+ secp256k1_fe_sqr(&x2, a);
+ secp256k1_fe_mul(&x2, &x2, a);
+
+ secp256k1_fe_sqr(&x3, &x2);
+ secp256k1_fe_mul(&x3, &x3, a);
+
+ x6 = x3;
+ for (j=0; j<3; j++) {
+ secp256k1_fe_sqr(&x6, &x6);
+ }
+ secp256k1_fe_mul(&x6, &x6, &x3);
+
+ x9 = x6;
+ for (j=0; j<3; j++) {
+ secp256k1_fe_sqr(&x9, &x9);
+ }
+ secp256k1_fe_mul(&x9, &x9, &x3);
+
+ x11 = x9;
+ for (j=0; j<2; j++) {
+ secp256k1_fe_sqr(&x11, &x11);
+ }
+ secp256k1_fe_mul(&x11, &x11, &x2);
+
+ x22 = x11;
+ for (j=0; j<11; j++) {
+ secp256k1_fe_sqr(&x22, &x22);
+ }
+ secp256k1_fe_mul(&x22, &x22, &x11);
+
+ x44 = x22;
+ for (j=0; j<22; j++) {
+ secp256k1_fe_sqr(&x44, &x44);
+ }
+ secp256k1_fe_mul(&x44, &x44, &x22);
+
+ x88 = x44;
+ for (j=0; j<44; j++) {
+ secp256k1_fe_sqr(&x88, &x88);
+ }
+ secp256k1_fe_mul(&x88, &x88, &x44);
+
+ x176 = x88;
+ for (j=0; j<88; j++) {
+ secp256k1_fe_sqr(&x176, &x176);
+ }
+ secp256k1_fe_mul(&x176, &x176, &x88);
+
+ x220 = x176;
+ for (j=0; j<44; j++) {
+ secp256k1_fe_sqr(&x220, &x220);
+ }
+ secp256k1_fe_mul(&x220, &x220, &x44);
+
+ x223 = x220;
+ for (j=0; j<3; j++) {
+ secp256k1_fe_sqr(&x223, &x223);
+ }
+ secp256k1_fe_mul(&x223, &x223, &x3);
+
+ /* The final result is then assembled using a sliding window over the blocks. */
+
+ t1 = x223;
+ for (j=0; j<23; j++) {
+ secp256k1_fe_sqr(&t1, &t1);
+ }
+ secp256k1_fe_mul(&t1, &t1, &x22);
+ for (j=0; j<5; j++) {
+ secp256k1_fe_sqr(&t1, &t1);
+ }
+ secp256k1_fe_mul(&t1, &t1, a);
+ for (j=0; j<3; j++) {
+ secp256k1_fe_sqr(&t1, &t1);
+ }
+ secp256k1_fe_mul(&t1, &t1, &x2);
+ for (j=0; j<2; j++) {
+ secp256k1_fe_sqr(&t1, &t1);
+ }
+ secp256k1_fe_mul(r, a, &t1);
+}
+
+static void secp256k1_fe_inv_var(secp256k1_fe_t *r, const secp256k1_fe_t *a) {
+#if defined(USE_FIELD_INV_BUILTIN)
+ secp256k1_fe_inv(r, a);
+#elif defined(USE_FIELD_INV_NUM)
+ secp256k1_num_t n, m;
+ /* secp256k1 field prime, value p defined in "Standards for Efficient Cryptography" (SEC2) 2.7.1. */
+ static const unsigned char prime[32] = {
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F
+ };
+ unsigned char b[32];
+ secp256k1_fe_t c = *a;
+ secp256k1_fe_normalize_var(&c);
+ secp256k1_fe_get_b32(b, &c);
+ secp256k1_num_set_bin(&n, b, 32);
+ secp256k1_num_set_bin(&m, prime, 32);
+ secp256k1_num_mod_inverse(&n, &n, &m);
+ secp256k1_num_get_bin(b, 32, &n);
+ VERIFY_CHECK(secp256k1_fe_set_b32(r, b));
+#else
+#error "Please select field inverse implementation"
+#endif
+}
+
+static void secp256k1_fe_inv_all_var(size_t len, secp256k1_fe_t *r, const secp256k1_fe_t *a) {
+ secp256k1_fe_t u;
+ size_t i;
+ if (len < 1) {
+ return;
+ }
+
+ VERIFY_CHECK((r + len <= a) || (a + len <= r));
+
+ r[0] = a[0];
+
+ i = 0;
+ while (++i < len) {
+ secp256k1_fe_mul(&r[i], &r[i - 1], &a[i]);
+ }
+
+ secp256k1_fe_inv_var(&u, &r[--i]);
+
+ while (i > 0) {
+ int j = i--;
+ secp256k1_fe_mul(&r[j], &r[i], &u);
+ secp256k1_fe_mul(&u, &u, &a[j]);
+ }
+
+ r[0] = u;
+}
+
+#endif
diff --git a/src/secp256k1/src/group.h b/src/secp256k1/src/group.h
new file mode 100644
index 0000000000..0b08b3b991
--- /dev/null
+++ b/src/secp256k1/src/group.h
@@ -0,0 +1,121 @@
+/**********************************************************************
+ * Copyright (c) 2013, 2014 Pieter Wuille *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
+ **********************************************************************/
+
+#ifndef _SECP256K1_GROUP_
+#define _SECP256K1_GROUP_
+
+#include "num.h"
+#include "field.h"
+
+/** A group element of the secp256k1 curve, in affine coordinates. */
+typedef struct {
+ secp256k1_fe_t x;
+ secp256k1_fe_t y;
+ int infinity; /* whether this represents the point at infinity */
+} secp256k1_ge_t;
+
+#define SECP256K1_GE_CONST(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {SECP256K1_FE_CONST((a),(b),(c),(d),(e),(f),(g),(h)), SECP256K1_FE_CONST((i),(j),(k),(l),(m),(n),(o),(p)), 0}
+#define SECP256K1_GE_CONST_INFINITY {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), 1}
+
+/** A group element of the secp256k1 curve, in jacobian coordinates. */
+typedef struct {
+ secp256k1_fe_t x; /* actual X: x/z^2 */
+ secp256k1_fe_t y; /* actual Y: y/z^3 */
+ secp256k1_fe_t z;
+ int infinity; /* whether this represents the point at infinity */
+} secp256k1_gej_t;
+
+#define SECP256K1_GEJ_CONST(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {SECP256K1_FE_CONST((a),(b),(c),(d),(e),(f),(g),(h)), SECP256K1_FE_CONST((i),(j),(k),(l),(m),(n),(o),(p)), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 1), 0}
+#define SECP256K1_GEJ_CONST_INFINITY {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), 1}
+
+typedef struct {
+ secp256k1_fe_storage_t x;
+ secp256k1_fe_storage_t y;
+} secp256k1_ge_storage_t;
+
+#define SECP256K1_GE_STORAGE_CONST(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {SECP256K1_FE_STORAGE_CONST((a),(b),(c),(d),(e),(f),(g),(h)), SECP256K1_FE_STORAGE_CONST((i),(j),(k),(l),(m),(n),(o),(p))}
+
+/** Set a group element equal to the point at infinity */
+static void secp256k1_ge_set_infinity(secp256k1_ge_t *r);
+
+/** Set a group element equal to the point with given X and Y coordinates */
+static void secp256k1_ge_set_xy(secp256k1_ge_t *r, const secp256k1_fe_t *x, const secp256k1_fe_t *y);
+
+/** Set a group element (affine) equal to the point with the given X coordinate, and given oddness
+ * for Y. Return value indicates whether the result is valid. */
+static int secp256k1_ge_set_xo_var(secp256k1_ge_t *r, const secp256k1_fe_t *x, int odd);
+
+/** Check whether a group element is the point at infinity. */
+static int secp256k1_ge_is_infinity(const secp256k1_ge_t *a);
+
+/** Check whether a group element is valid (i.e., on the curve). */
+static int secp256k1_ge_is_valid_var(const secp256k1_ge_t *a);
+
+static void secp256k1_ge_neg(secp256k1_ge_t *r, const secp256k1_ge_t *a);
+
+/** Set a group element equal to another which is given in jacobian coordinates */
+static void secp256k1_ge_set_gej(secp256k1_ge_t *r, secp256k1_gej_t *a);
+
+/** Set a batch of group elements equal to the inputs given in jacobian coordinates */
+static void secp256k1_ge_set_all_gej_var(size_t len, secp256k1_ge_t *r, const secp256k1_gej_t *a);
+
+
+/** Set a group element (jacobian) equal to the point at infinity. */
+static void secp256k1_gej_set_infinity(secp256k1_gej_t *r);
+
+/** Set a group element (jacobian) equal to the point with given X and Y coordinates. */
+static void secp256k1_gej_set_xy(secp256k1_gej_t *r, const secp256k1_fe_t *x, const secp256k1_fe_t *y);
+
+/** Set a group element (jacobian) equal to another which is given in affine coordinates. */
+static void secp256k1_gej_set_ge(secp256k1_gej_t *r, const secp256k1_ge_t *a);
+
+/** Compare the X coordinate of a group element (jacobian). */
+static int secp256k1_gej_eq_x_var(const secp256k1_fe_t *x, const secp256k1_gej_t *a);
+
+/** Set r equal to the inverse of a (i.e., mirrored around the X axis) */
+static void secp256k1_gej_neg(secp256k1_gej_t *r, const secp256k1_gej_t *a);
+
+/** Check whether a group element is the point at infinity. */
+static int secp256k1_gej_is_infinity(const secp256k1_gej_t *a);
+
+/** Set r equal to the double of a. */
+static void secp256k1_gej_double_var(secp256k1_gej_t *r, const secp256k1_gej_t *a);
+
+/** Set r equal to the sum of a and b. */
+static void secp256k1_gej_add_var(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_gej_t *b);
+
+/** Set r equal to the sum of a and b (with b given in affine coordinates, and not infinity). */
+static void secp256k1_gej_add_ge(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_ge_t *b);
+
+/** Set r equal to the sum of a and b (with b given in affine coordinates). This is more efficient
+ than secp256k1_gej_add_var. It is identical to secp256k1_gej_add_ge but without constant-time
+ guarantee, and b is allowed to be infinity. */
+static void secp256k1_gej_add_ge_var(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_ge_t *b);
+
+#ifdef USE_ENDOMORPHISM
+/** Set r to be equal to lambda times a, where lambda is chosen in a way such that this is very fast. */
+static void secp256k1_gej_mul_lambda(secp256k1_gej_t *r, const secp256k1_gej_t *a);
+#endif
+
+/** Clear a secp256k1_gej_t to prevent leaking sensitive information. */
+static void secp256k1_gej_clear(secp256k1_gej_t *r);
+
+/** Clear a secp256k1_ge_t to prevent leaking sensitive information. */
+static void secp256k1_ge_clear(secp256k1_ge_t *r);
+
+/** Convert a group element to the storage type. */
+static void secp256k1_ge_to_storage(secp256k1_ge_storage_t *r, const secp256k1_ge_t*);
+
+/** Convert a group element back from the storage type. */
+static void secp256k1_ge_from_storage(secp256k1_ge_t *r, const secp256k1_ge_storage_t*);
+
+/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. */
+static void secp256k1_ge_storage_cmov(secp256k1_ge_storage_t *r, const secp256k1_ge_storage_t *a, int flag);
+
+/** Rescale a jacobian point by b which must be non-zero. Constant-time. */
+static void secp256k1_gej_rescale(secp256k1_gej_t *r, const secp256k1_fe_t *b);
+
+#endif
diff --git a/src/secp256k1/src/group_impl.h b/src/secp256k1/src/group_impl.h
new file mode 100644
index 0000000000..0f64576fbb
--- /dev/null
+++ b/src/secp256k1/src/group_impl.h
@@ -0,0 +1,443 @@
+/**********************************************************************
+ * Copyright (c) 2013, 2014 Pieter Wuille *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
+ **********************************************************************/
+
+#ifndef _SECP256K1_GROUP_IMPL_H_
+#define _SECP256K1_GROUP_IMPL_H_
+
+#include <string.h>
+
+#include "num.h"
+#include "field.h"
+#include "group.h"
+
+/** Generator for secp256k1, value 'g' defined in
+ * "Standards for Efficient Cryptography" (SEC2) 2.7.1.
+ */
+static const secp256k1_ge_t secp256k1_ge_const_g = SECP256K1_GE_CONST(
+ 0x79BE667EUL, 0xF9DCBBACUL, 0x55A06295UL, 0xCE870B07UL,
+ 0x029BFCDBUL, 0x2DCE28D9UL, 0x59F2815BUL, 0x16F81798UL,
+ 0x483ADA77UL, 0x26A3C465UL, 0x5DA4FBFCUL, 0x0E1108A8UL,
+ 0xFD17B448UL, 0xA6855419UL, 0x9C47D08FUL, 0xFB10D4B8UL
+);
+
+static void secp256k1_ge_set_infinity(secp256k1_ge_t *r) {
+ r->infinity = 1;
+}
+
+static void secp256k1_ge_set_xy(secp256k1_ge_t *r, const secp256k1_fe_t *x, const secp256k1_fe_t *y) {
+ r->infinity = 0;
+ r->x = *x;
+ r->y = *y;
+}
+
+static int secp256k1_ge_is_infinity(const secp256k1_ge_t *a) {
+ return a->infinity;
+}
+
+static void secp256k1_ge_neg(secp256k1_ge_t *r, const secp256k1_ge_t *a) {
+ *r = *a;
+ secp256k1_fe_normalize_weak(&r->y);
+ secp256k1_fe_negate(&r->y, &r->y, 1);
+}
+
+static void secp256k1_ge_set_gej(secp256k1_ge_t *r, secp256k1_gej_t *a) {
+ secp256k1_fe_t z2, z3;
+ r->infinity = a->infinity;
+ secp256k1_fe_inv(&a->z, &a->z);
+ secp256k1_fe_sqr(&z2, &a->z);
+ secp256k1_fe_mul(&z3, &a->z, &z2);
+ secp256k1_fe_mul(&a->x, &a->x, &z2);
+ secp256k1_fe_mul(&a->y, &a->y, &z3);
+ secp256k1_fe_set_int(&a->z, 1);
+ r->x = a->x;
+ r->y = a->y;
+}
+
+static void secp256k1_ge_set_gej_var(secp256k1_ge_t *r, secp256k1_gej_t *a) {
+ secp256k1_fe_t z2, z3;
+ r->infinity = a->infinity;
+ if (a->infinity) {
+ return;
+ }
+ secp256k1_fe_inv_var(&a->z, &a->z);
+ secp256k1_fe_sqr(&z2, &a->z);
+ secp256k1_fe_mul(&z3, &a->z, &z2);
+ secp256k1_fe_mul(&a->x, &a->x, &z2);
+ secp256k1_fe_mul(&a->y, &a->y, &z3);
+ secp256k1_fe_set_int(&a->z, 1);
+ r->x = a->x;
+ r->y = a->y;
+}
+
+static void secp256k1_ge_set_all_gej_var(size_t len, secp256k1_ge_t *r, const secp256k1_gej_t *a) {
+ secp256k1_fe_t *az;
+ secp256k1_fe_t *azi;
+ size_t i;
+ size_t count = 0;
+ az = (secp256k1_fe_t *)checked_malloc(sizeof(secp256k1_fe_t) * len);
+ for (i = 0; i < len; i++) {
+ if (!a[i].infinity) {
+ az[count++] = a[i].z;
+ }
+ }
+
+ azi = (secp256k1_fe_t *)checked_malloc(sizeof(secp256k1_fe_t) * count);
+ secp256k1_fe_inv_all_var(count, azi, az);
+ free(az);
+
+ count = 0;
+ for (i = 0; i < len; i++) {
+ r[i].infinity = a[i].infinity;
+ if (!a[i].infinity) {
+ secp256k1_fe_t zi2, zi3;
+ secp256k1_fe_t *zi = &azi[count++];
+ secp256k1_fe_sqr(&zi2, zi);
+ secp256k1_fe_mul(&zi3, &zi2, zi);
+ secp256k1_fe_mul(&r[i].x, &a[i].x, &zi2);
+ secp256k1_fe_mul(&r[i].y, &a[i].y, &zi3);
+ }
+ }
+ free(azi);
+}
+
+static void secp256k1_gej_set_infinity(secp256k1_gej_t *r) {
+ r->infinity = 1;
+ secp256k1_fe_set_int(&r->x, 0);
+ secp256k1_fe_set_int(&r->y, 0);
+ secp256k1_fe_set_int(&r->z, 0);
+}
+
+static void secp256k1_gej_set_xy(secp256k1_gej_t *r, const secp256k1_fe_t *x, const secp256k1_fe_t *y) {
+ r->infinity = 0;
+ r->x = *x;
+ r->y = *y;
+ secp256k1_fe_set_int(&r->z, 1);
+}
+
+static void secp256k1_gej_clear(secp256k1_gej_t *r) {
+ r->infinity = 0;
+ secp256k1_fe_clear(&r->x);
+ secp256k1_fe_clear(&r->y);
+ secp256k1_fe_clear(&r->z);
+}
+
+static void secp256k1_ge_clear(secp256k1_ge_t *r) {
+ r->infinity = 0;
+ secp256k1_fe_clear(&r->x);
+ secp256k1_fe_clear(&r->y);
+}
+
+static int secp256k1_ge_set_xo_var(secp256k1_ge_t *r, const secp256k1_fe_t *x, int odd) {
+ secp256k1_fe_t x2, x3, c;
+ r->x = *x;
+ secp256k1_fe_sqr(&x2, x);
+ secp256k1_fe_mul(&x3, x, &x2);
+ r->infinity = 0;
+ secp256k1_fe_set_int(&c, 7);
+ secp256k1_fe_add(&c, &x3);
+ if (!secp256k1_fe_sqrt_var(&r->y, &c)) {
+ return 0;
+ }
+ secp256k1_fe_normalize_var(&r->y);
+ if (secp256k1_fe_is_odd(&r->y) != odd) {
+ secp256k1_fe_negate(&r->y, &r->y, 1);
+ }
+ return 1;
+}
+
+static void secp256k1_gej_set_ge(secp256k1_gej_t *r, const secp256k1_ge_t *a) {
+ r->infinity = a->infinity;
+ r->x = a->x;
+ r->y = a->y;
+ secp256k1_fe_set_int(&r->z, 1);
+}
+
+static int secp256k1_gej_eq_x_var(const secp256k1_fe_t *x, const secp256k1_gej_t *a) {
+ secp256k1_fe_t r, r2;
+ VERIFY_CHECK(!a->infinity);
+ secp256k1_fe_sqr(&r, &a->z); secp256k1_fe_mul(&r, &r, x);
+ r2 = a->x; secp256k1_fe_normalize_weak(&r2);
+ return secp256k1_fe_equal_var(&r, &r2);
+}
+
+static void secp256k1_gej_neg(secp256k1_gej_t *r, const secp256k1_gej_t *a) {
+ r->infinity = a->infinity;
+ r->x = a->x;
+ r->y = a->y;
+ r->z = a->z;
+ secp256k1_fe_normalize_weak(&r->y);
+ secp256k1_fe_negate(&r->y, &r->y, 1);
+}
+
+static int secp256k1_gej_is_infinity(const secp256k1_gej_t *a) {
+ return a->infinity;
+}
+
+static int secp256k1_gej_is_valid_var(const secp256k1_gej_t *a) {
+ secp256k1_fe_t y2, x3, z2, z6;
+ if (a->infinity) {
+ return 0;
+ }
+ /** y^2 = x^3 + 7
+ * (Y/Z^3)^2 = (X/Z^2)^3 + 7
+ * Y^2 / Z^6 = X^3 / Z^6 + 7
+ * Y^2 = X^3 + 7*Z^6
+ */
+ secp256k1_fe_sqr(&y2, &a->y);
+ secp256k1_fe_sqr(&x3, &a->x); secp256k1_fe_mul(&x3, &x3, &a->x);
+ secp256k1_fe_sqr(&z2, &a->z);
+ secp256k1_fe_sqr(&z6, &z2); secp256k1_fe_mul(&z6, &z6, &z2);
+ secp256k1_fe_mul_int(&z6, 7);
+ secp256k1_fe_add(&x3, &z6);
+ secp256k1_fe_normalize_weak(&x3);
+ return secp256k1_fe_equal_var(&y2, &x3);
+}
+
+static int secp256k1_ge_is_valid_var(const secp256k1_ge_t *a) {
+ secp256k1_fe_t y2, x3, c;
+ if (a->infinity) {
+ return 0;
+ }
+ /* y^2 = x^3 + 7 */
+ secp256k1_fe_sqr(&y2, &a->y);
+ secp256k1_fe_sqr(&x3, &a->x); secp256k1_fe_mul(&x3, &x3, &a->x);
+ secp256k1_fe_set_int(&c, 7);
+ secp256k1_fe_add(&x3, &c);
+ secp256k1_fe_normalize_weak(&x3);
+ return secp256k1_fe_equal_var(&y2, &x3);
+}
+
+static void secp256k1_gej_double_var(secp256k1_gej_t *r, const secp256k1_gej_t *a) {
+ /* Operations: 3 mul, 4 sqr, 0 normalize, 12 mul_int/add/negate */
+ secp256k1_fe_t t1,t2,t3,t4;
+ /** For secp256k1, 2Q is infinity if and only if Q is infinity. This is because if 2Q = infinity,
+ * Q must equal -Q, or that Q.y == -(Q.y), or Q.y is 0. For a point on y^2 = x^3 + 7 to have
+ * y=0, x^3 must be -7 mod p. However, -7 has no cube root mod p.
+ */
+ r->infinity = a->infinity;
+ if (r->infinity) {
+ return;
+ }
+
+ secp256k1_fe_mul(&r->z, &a->z, &a->y);
+ secp256k1_fe_mul_int(&r->z, 2); /* Z' = 2*Y*Z (2) */
+ secp256k1_fe_sqr(&t1, &a->x);
+ secp256k1_fe_mul_int(&t1, 3); /* T1 = 3*X^2 (3) */
+ secp256k1_fe_sqr(&t2, &t1); /* T2 = 9*X^4 (1) */
+ secp256k1_fe_sqr(&t3, &a->y);
+ secp256k1_fe_mul_int(&t3, 2); /* T3 = 2*Y^2 (2) */
+ secp256k1_fe_sqr(&t4, &t3);
+ secp256k1_fe_mul_int(&t4, 2); /* T4 = 8*Y^4 (2) */
+ secp256k1_fe_mul(&t3, &t3, &a->x); /* T3 = 2*X*Y^2 (1) */
+ r->x = t3;
+ secp256k1_fe_mul_int(&r->x, 4); /* X' = 8*X*Y^2 (4) */
+ secp256k1_fe_negate(&r->x, &r->x, 4); /* X' = -8*X*Y^2 (5) */
+ secp256k1_fe_add(&r->x, &t2); /* X' = 9*X^4 - 8*X*Y^2 (6) */
+ secp256k1_fe_negate(&t2, &t2, 1); /* T2 = -9*X^4 (2) */
+ secp256k1_fe_mul_int(&t3, 6); /* T3 = 12*X*Y^2 (6) */
+ secp256k1_fe_add(&t3, &t2); /* T3 = 12*X*Y^2 - 9*X^4 (8) */
+ secp256k1_fe_mul(&r->y, &t1, &t3); /* Y' = 36*X^3*Y^2 - 27*X^6 (1) */
+ secp256k1_fe_negate(&t2, &t4, 2); /* T2 = -8*Y^4 (3) */
+ secp256k1_fe_add(&r->y, &t2); /* Y' = 36*X^3*Y^2 - 27*X^6 - 8*Y^4 (4) */
+}
+
+static void secp256k1_gej_add_var(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_gej_t *b) {
+ /* Operations: 12 mul, 4 sqr, 2 normalize, 12 mul_int/add/negate */
+ secp256k1_fe_t z22, z12, u1, u2, s1, s2, h, i, i2, h2, h3, t;
+ if (a->infinity) {
+ *r = *b;
+ return;
+ }
+ if (b->infinity) {
+ *r = *a;
+ return;
+ }
+ r->infinity = 0;
+ secp256k1_fe_sqr(&z22, &b->z);
+ secp256k1_fe_sqr(&z12, &a->z);
+ secp256k1_fe_mul(&u1, &a->x, &z22);
+ secp256k1_fe_mul(&u2, &b->x, &z12);
+ secp256k1_fe_mul(&s1, &a->y, &z22); secp256k1_fe_mul(&s1, &s1, &b->z);
+ secp256k1_fe_mul(&s2, &b->y, &z12); secp256k1_fe_mul(&s2, &s2, &a->z);
+ secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2);
+ secp256k1_fe_negate(&i, &s1, 1); secp256k1_fe_add(&i, &s2);
+ if (secp256k1_fe_normalizes_to_zero_var(&h)) {
+ if (secp256k1_fe_normalizes_to_zero_var(&i)) {
+ secp256k1_gej_double_var(r, a);
+ } else {
+ r->infinity = 1;
+ }
+ return;
+ }
+ secp256k1_fe_sqr(&i2, &i);
+ secp256k1_fe_sqr(&h2, &h);
+ secp256k1_fe_mul(&h3, &h, &h2);
+ secp256k1_fe_mul(&r->z, &a->z, &b->z); secp256k1_fe_mul(&r->z, &r->z, &h);
+ secp256k1_fe_mul(&t, &u1, &h2);
+ r->x = t; secp256k1_fe_mul_int(&r->x, 2); secp256k1_fe_add(&r->x, &h3); secp256k1_fe_negate(&r->x, &r->x, 3); secp256k1_fe_add(&r->x, &i2);
+ secp256k1_fe_negate(&r->y, &r->x, 5); secp256k1_fe_add(&r->y, &t); secp256k1_fe_mul(&r->y, &r->y, &i);
+ secp256k1_fe_mul(&h3, &h3, &s1); secp256k1_fe_negate(&h3, &h3, 1);
+ secp256k1_fe_add(&r->y, &h3);
+}
+
+static void secp256k1_gej_add_ge_var(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_ge_t *b) {
+ /* 8 mul, 3 sqr, 4 normalize, 12 mul_int/add/negate */
+ secp256k1_fe_t z12, u1, u2, s1, s2, h, i, i2, h2, h3, t;
+ if (a->infinity) {
+ r->infinity = b->infinity;
+ r->x = b->x;
+ r->y = b->y;
+ secp256k1_fe_set_int(&r->z, 1);
+ return;
+ }
+ if (b->infinity) {
+ *r = *a;
+ return;
+ }
+ r->infinity = 0;
+ secp256k1_fe_sqr(&z12, &a->z);
+ u1 = a->x; secp256k1_fe_normalize_weak(&u1);
+ secp256k1_fe_mul(&u2, &b->x, &z12);
+ s1 = a->y; secp256k1_fe_normalize_weak(&s1);
+ secp256k1_fe_mul(&s2, &b->y, &z12); secp256k1_fe_mul(&s2, &s2, &a->z);
+ secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2);
+ secp256k1_fe_negate(&i, &s1, 1); secp256k1_fe_add(&i, &s2);
+ if (secp256k1_fe_normalizes_to_zero_var(&h)) {
+ if (secp256k1_fe_normalizes_to_zero_var(&i)) {
+ secp256k1_gej_double_var(r, a);
+ } else {
+ r->infinity = 1;
+ }
+ return;
+ }
+ secp256k1_fe_sqr(&i2, &i);
+ secp256k1_fe_sqr(&h2, &h);
+ secp256k1_fe_mul(&h3, &h, &h2);
+ r->z = a->z; secp256k1_fe_mul(&r->z, &r->z, &h);
+ secp256k1_fe_mul(&t, &u1, &h2);
+ r->x = t; secp256k1_fe_mul_int(&r->x, 2); secp256k1_fe_add(&r->x, &h3); secp256k1_fe_negate(&r->x, &r->x, 3); secp256k1_fe_add(&r->x, &i2);
+ secp256k1_fe_negate(&r->y, &r->x, 5); secp256k1_fe_add(&r->y, &t); secp256k1_fe_mul(&r->y, &r->y, &i);
+ secp256k1_fe_mul(&h3, &h3, &s1); secp256k1_fe_negate(&h3, &h3, 1);
+ secp256k1_fe_add(&r->y, &h3);
+}
+
+static void secp256k1_gej_add_ge(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_ge_t *b) {
+ /* Operations: 7 mul, 5 sqr, 5 normalize, 17 mul_int/add/negate/cmov */
+ static const secp256k1_fe_t fe_1 = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 1);
+ secp256k1_fe_t zz, u1, u2, s1, s2, z, t, m, n, q, rr;
+ int infinity;
+ VERIFY_CHECK(!b->infinity);
+ VERIFY_CHECK(a->infinity == 0 || a->infinity == 1);
+
+ /** In:
+ * Eric Brier and Marc Joye, Weierstrass Elliptic Curves and Side-Channel Attacks.
+ * In D. Naccache and P. Paillier, Eds., Public Key Cryptography, vol. 2274 of Lecture Notes in Computer Science, pages 335-345. Springer-Verlag, 2002.
+ * we find as solution for a unified addition/doubling formula:
+ * lambda = ((x1 + x2)^2 - x1 * x2 + a) / (y1 + y2), with a = 0 for secp256k1's curve equation.
+ * x3 = lambda^2 - (x1 + x2)
+ * 2*y3 = lambda * (x1 + x2 - 2 * x3) - (y1 + y2).
+ *
+ * Substituting x_i = Xi / Zi^2 and yi = Yi / Zi^3, for i=1,2,3, gives:
+ * U1 = X1*Z2^2, U2 = X2*Z1^2
+ * S1 = Y1*Z2^3, S2 = Y2*Z1^3
+ * Z = Z1*Z2
+ * T = U1+U2
+ * M = S1+S2
+ * Q = T*M^2
+ * R = T^2-U1*U2
+ * X3 = 4*(R^2-Q)
+ * Y3 = 4*(R*(3*Q-2*R^2)-M^4)
+ * Z3 = 2*M*Z
+ * (Note that the paper uses xi = Xi / Zi and yi = Yi / Zi instead.)
+ */
+
+ secp256k1_fe_sqr(&zz, &a->z); /* z = Z1^2 */
+ u1 = a->x; secp256k1_fe_normalize_weak(&u1); /* u1 = U1 = X1*Z2^2 (1) */
+ secp256k1_fe_mul(&u2, &b->x, &zz); /* u2 = U2 = X2*Z1^2 (1) */
+ s1 = a->y; secp256k1_fe_normalize_weak(&s1); /* s1 = S1 = Y1*Z2^3 (1) */
+ secp256k1_fe_mul(&s2, &b->y, &zz); /* s2 = Y2*Z2^2 (1) */
+ secp256k1_fe_mul(&s2, &s2, &a->z); /* s2 = S2 = Y2*Z1^3 (1) */
+ z = a->z; /* z = Z = Z1*Z2 (8) */
+ t = u1; secp256k1_fe_add(&t, &u2); /* t = T = U1+U2 (2) */
+ m = s1; secp256k1_fe_add(&m, &s2); /* m = M = S1+S2 (2) */
+ secp256k1_fe_sqr(&n, &m); /* n = M^2 (1) */
+ secp256k1_fe_mul(&q, &n, &t); /* q = Q = T*M^2 (1) */
+ secp256k1_fe_sqr(&n, &n); /* n = M^4 (1) */
+ secp256k1_fe_sqr(&rr, &t); /* rr = T^2 (1) */
+ secp256k1_fe_mul(&t, &u1, &u2); secp256k1_fe_negate(&t, &t, 1); /* t = -U1*U2 (2) */
+ secp256k1_fe_add(&rr, &t); /* rr = R = T^2-U1*U2 (3) */
+ secp256k1_fe_sqr(&t, &rr); /* t = R^2 (1) */
+ secp256k1_fe_mul(&r->z, &m, &z); /* r->z = M*Z (1) */
+ infinity = secp256k1_fe_normalizes_to_zero(&r->z) * (1 - a->infinity);
+ secp256k1_fe_mul_int(&r->z, 2 * (1 - a->infinity)); /* r->z = Z3 = 2*M*Z (2) */
+ r->x = t; /* r->x = R^2 (1) */
+ secp256k1_fe_negate(&q, &q, 1); /* q = -Q (2) */
+ secp256k1_fe_add(&r->x, &q); /* r->x = R^2-Q (3) */
+ secp256k1_fe_normalize(&r->x);
+ secp256k1_fe_mul_int(&q, 3); /* q = -3*Q (6) */
+ secp256k1_fe_mul_int(&t, 2); /* t = 2*R^2 (2) */
+ secp256k1_fe_add(&t, &q); /* t = 2*R^2-3*Q (8) */
+ secp256k1_fe_mul(&t, &t, &rr); /* t = R*(2*R^2-3*Q) (1) */
+ secp256k1_fe_add(&t, &n); /* t = R*(2*R^2-3*Q)+M^4 (2) */
+ secp256k1_fe_negate(&r->y, &t, 2); /* r->y = R*(3*Q-2*R^2)-M^4 (3) */
+ secp256k1_fe_normalize_weak(&r->y);
+ secp256k1_fe_mul_int(&r->x, 4 * (1 - a->infinity)); /* r->x = X3 = 4*(R^2-Q) */
+ secp256k1_fe_mul_int(&r->y, 4 * (1 - a->infinity)); /* r->y = Y3 = 4*R*(3*Q-2*R^2)-4*M^4 (4) */
+
+ /** In case a->infinity == 1, the above code results in r->x, r->y, and r->z all equal to 0.
+ * Replace r with b->x, b->y, 1 in that case.
+ */
+ secp256k1_fe_cmov(&r->x, &b->x, a->infinity);
+ secp256k1_fe_cmov(&r->y, &b->y, a->infinity);
+ secp256k1_fe_cmov(&r->z, &fe_1, a->infinity);
+ r->infinity = infinity;
+}
+
+static void secp256k1_gej_rescale(secp256k1_gej_t *r, const secp256k1_fe_t *s) {
+ /* Operations: 4 mul, 1 sqr */
+ secp256k1_fe_t zz;
+ VERIFY_CHECK(!secp256k1_fe_is_zero(s));
+ secp256k1_fe_sqr(&zz, s);
+ secp256k1_fe_mul(&r->x, &r->x, &zz); /* r->x *= s^2 */
+ secp256k1_fe_mul(&r->y, &r->y, &zz);
+ secp256k1_fe_mul(&r->y, &r->y, s); /* r->y *= s^3 */
+ secp256k1_fe_mul(&r->z, &r->z, s); /* r->z *= s */
+}
+
+static void secp256k1_ge_to_storage(secp256k1_ge_storage_t *r, const secp256k1_ge_t *a) {
+ secp256k1_fe_t x, y;
+ VERIFY_CHECK(!a->infinity);
+ x = a->x;
+ secp256k1_fe_normalize(&x);
+ y = a->y;
+ secp256k1_fe_normalize(&y);
+ secp256k1_fe_to_storage(&r->x, &x);
+ secp256k1_fe_to_storage(&r->y, &y);
+}
+
+static void secp256k1_ge_from_storage(secp256k1_ge_t *r, const secp256k1_ge_storage_t *a) {
+ secp256k1_fe_from_storage(&r->x, &a->x);
+ secp256k1_fe_from_storage(&r->y, &a->y);
+ r->infinity = 0;
+}
+
+static SECP256K1_INLINE void secp256k1_ge_storage_cmov(secp256k1_ge_storage_t *r, const secp256k1_ge_storage_t *a, int flag) {
+ secp256k1_fe_storage_cmov(&r->x, &a->x, flag);
+ secp256k1_fe_storage_cmov(&r->y, &a->y, flag);
+}
+
+#ifdef USE_ENDOMORPHISM
+static void secp256k1_gej_mul_lambda(secp256k1_gej_t *r, const secp256k1_gej_t *a) {
+ static const secp256k1_fe_t beta = SECP256K1_FE_CONST(
+ 0x7ae96a2bul, 0x657c0710ul, 0x6e64479eul, 0xac3434e9ul,
+ 0x9cf04975ul, 0x12f58995ul, 0xc1396c28ul, 0x719501eeul
+ );
+ *r = *a;
+ secp256k1_fe_mul(&r->x, &r->x, &beta);
+}
+#endif
+
+#endif
diff --git a/src/secp256k1/src/hash.h b/src/secp256k1/src/hash.h
new file mode 100644
index 0000000000..843423d7f7
--- /dev/null
+++ b/src/secp256k1/src/hash.h
@@ -0,0 +1,41 @@
+/**********************************************************************
+ * Copyright (c) 2014 Pieter Wuille *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
+ **********************************************************************/
+
+#ifndef _SECP256K1_HASH_
+#define _SECP256K1_HASH_
+
+#include <stdlib.h>
+#include <stdint.h>
+
+typedef struct {
+ uint32_t s[32];
+ uint32_t buf[16]; /* In big endian */
+ size_t bytes;
+} secp256k1_sha256_t;
+
+static void secp256k1_sha256_initialize(secp256k1_sha256_t *hash);
+static void secp256k1_sha256_write(secp256k1_sha256_t *hash, const unsigned char *data, size_t size);
+static void secp256k1_sha256_finalize(secp256k1_sha256_t *hash, unsigned char *out32);
+
+typedef struct {
+ secp256k1_sha256_t inner, outer;
+} secp256k1_hmac_sha256_t;
+
+static void secp256k1_hmac_sha256_initialize(secp256k1_hmac_sha256_t *hash, const unsigned char *key, size_t size);
+static void secp256k1_hmac_sha256_write(secp256k1_hmac_sha256_t *hash, const unsigned char *data, size_t size);
+static void secp256k1_hmac_sha256_finalize(secp256k1_hmac_sha256_t *hash, unsigned char *out32);
+
+typedef struct {
+ unsigned char v[32];
+ unsigned char k[32];
+ int retry;
+} secp256k1_rfc6979_hmac_sha256_t;
+
+static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha256_t *rng, const unsigned char *key, size_t keylen, const unsigned char *msg, size_t msglen, const unsigned char *rnd, size_t rndlen);
+static void secp256k1_rfc6979_hmac_sha256_generate(secp256k1_rfc6979_hmac_sha256_t *rng, unsigned char *out, size_t outlen);
+static void secp256k1_rfc6979_hmac_sha256_finalize(secp256k1_rfc6979_hmac_sha256_t *rng);
+
+#endif
diff --git a/src/secp256k1/src/hash_impl.h b/src/secp256k1/src/hash_impl.h
new file mode 100644
index 0000000000..9828827bcd
--- /dev/null
+++ b/src/secp256k1/src/hash_impl.h
@@ -0,0 +1,293 @@
+/**********************************************************************
+ * Copyright (c) 2014 Pieter Wuille *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
+ **********************************************************************/
+
+#ifndef _SECP256K1_HASH_IMPL_H_
+#define _SECP256K1_HASH_IMPL_H_
+
+#include "hash.h"
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+#define Ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
+#define Maj(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
+#define Sigma0(x) (((x) >> 2 | (x) << 30) ^ ((x) >> 13 | (x) << 19) ^ ((x) >> 22 | (x) << 10))
+#define Sigma1(x) (((x) >> 6 | (x) << 26) ^ ((x) >> 11 | (x) << 21) ^ ((x) >> 25 | (x) << 7))
+#define sigma0(x) (((x) >> 7 | (x) << 25) ^ ((x) >> 18 | (x) << 14) ^ ((x) >> 3))
+#define sigma1(x) (((x) >> 17 | (x) << 15) ^ ((x) >> 19 | (x) << 13) ^ ((x) >> 10))
+
+#define Round(a,b,c,d,e,f,g,h,k,w) do { \
+ uint32_t t1 = (h) + Sigma1(e) + Ch((e), (f), (g)) + (k) + (w); \
+ uint32_t t2 = Sigma0(a) + Maj((a), (b), (c)); \
+ (d) += t1; \
+ (h) = t1 + t2; \
+} while(0)
+
+#ifdef WORDS_BIGENDIAN
+#define BE32(x) (x)
+#else
+#define BE32(p) ((((p) & 0xFF) << 24) | (((p) & 0xFF00) << 8) | (((p) & 0xFF0000) >> 8) | (((p) & 0xFF000000) >> 24))
+#endif
+
+static void secp256k1_sha256_initialize(secp256k1_sha256_t *hash) {
+ hash->s[0] = 0x6a09e667ul;
+ hash->s[1] = 0xbb67ae85ul;
+ hash->s[2] = 0x3c6ef372ul;
+ hash->s[3] = 0xa54ff53aul;
+ hash->s[4] = 0x510e527ful;
+ hash->s[5] = 0x9b05688cul;
+ hash->s[6] = 0x1f83d9abul;
+ hash->s[7] = 0x5be0cd19ul;
+ hash->bytes = 0;
+}
+
+/** Perform one SHA-256 transformation, processing 16 big endian 32-bit words. */
+static void secp256k1_sha256_transform(uint32_t* s, const uint32_t* chunk) {
+ uint32_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7];
+ uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
+
+ Round(a, b, c, d, e, f, g, h, 0x428a2f98, w0 = BE32(chunk[0]));
+ Round(h, a, b, c, d, e, f, g, 0x71374491, w1 = BE32(chunk[1]));
+ Round(g, h, a, b, c, d, e, f, 0xb5c0fbcf, w2 = BE32(chunk[2]));
+ Round(f, g, h, a, b, c, d, e, 0xe9b5dba5, w3 = BE32(chunk[3]));
+ Round(e, f, g, h, a, b, c, d, 0x3956c25b, w4 = BE32(chunk[4]));
+ Round(d, e, f, g, h, a, b, c, 0x59f111f1, w5 = BE32(chunk[5]));
+ Round(c, d, e, f, g, h, a, b, 0x923f82a4, w6 = BE32(chunk[6]));
+ Round(b, c, d, e, f, g, h, a, 0xab1c5ed5, w7 = BE32(chunk[7]));
+ Round(a, b, c, d, e, f, g, h, 0xd807aa98, w8 = BE32(chunk[8]));
+ Round(h, a, b, c, d, e, f, g, 0x12835b01, w9 = BE32(chunk[9]));
+ Round(g, h, a, b, c, d, e, f, 0x243185be, w10 = BE32(chunk[10]));
+ Round(f, g, h, a, b, c, d, e, 0x550c7dc3, w11 = BE32(chunk[11]));
+ Round(e, f, g, h, a, b, c, d, 0x72be5d74, w12 = BE32(chunk[12]));
+ Round(d, e, f, g, h, a, b, c, 0x80deb1fe, w13 = BE32(chunk[13]));
+ Round(c, d, e, f, g, h, a, b, 0x9bdc06a7, w14 = BE32(chunk[14]));
+ Round(b, c, d, e, f, g, h, a, 0xc19bf174, w15 = BE32(chunk[15]));
+
+ Round(a, b, c, d, e, f, g, h, 0xe49b69c1, w0 += sigma1(w14) + w9 + sigma0(w1));
+ Round(h, a, b, c, d, e, f, g, 0xefbe4786, w1 += sigma1(w15) + w10 + sigma0(w2));
+ Round(g, h, a, b, c, d, e, f, 0x0fc19dc6, w2 += sigma1(w0) + w11 + sigma0(w3));
+ Round(f, g, h, a, b, c, d, e, 0x240ca1cc, w3 += sigma1(w1) + w12 + sigma0(w4));
+ Round(e, f, g, h, a, b, c, d, 0x2de92c6f, w4 += sigma1(w2) + w13 + sigma0(w5));
+ Round(d, e, f, g, h, a, b, c, 0x4a7484aa, w5 += sigma1(w3) + w14 + sigma0(w6));
+ Round(c, d, e, f, g, h, a, b, 0x5cb0a9dc, w6 += sigma1(w4) + w15 + sigma0(w7));
+ Round(b, c, d, e, f, g, h, a, 0x76f988da, w7 += sigma1(w5) + w0 + sigma0(w8));
+ Round(a, b, c, d, e, f, g, h, 0x983e5152, w8 += sigma1(w6) + w1 + sigma0(w9));
+ Round(h, a, b, c, d, e, f, g, 0xa831c66d, w9 += sigma1(w7) + w2 + sigma0(w10));
+ Round(g, h, a, b, c, d, e, f, 0xb00327c8, w10 += sigma1(w8) + w3 + sigma0(w11));
+ Round(f, g, h, a, b, c, d, e, 0xbf597fc7, w11 += sigma1(w9) + w4 + sigma0(w12));
+ Round(e, f, g, h, a, b, c, d, 0xc6e00bf3, w12 += sigma1(w10) + w5 + sigma0(w13));
+ Round(d, e, f, g, h, a, b, c, 0xd5a79147, w13 += sigma1(w11) + w6 + sigma0(w14));
+ Round(c, d, e, f, g, h, a, b, 0x06ca6351, w14 += sigma1(w12) + w7 + sigma0(w15));
+ Round(b, c, d, e, f, g, h, a, 0x14292967, w15 += sigma1(w13) + w8 + sigma0(w0));
+
+ Round(a, b, c, d, e, f, g, h, 0x27b70a85, w0 += sigma1(w14) + w9 + sigma0(w1));
+ Round(h, a, b, c, d, e, f, g, 0x2e1b2138, w1 += sigma1(w15) + w10 + sigma0(w2));
+ Round(g, h, a, b, c, d, e, f, 0x4d2c6dfc, w2 += sigma1(w0) + w11 + sigma0(w3));
+ Round(f, g, h, a, b, c, d, e, 0x53380d13, w3 += sigma1(w1) + w12 + sigma0(w4));
+ Round(e, f, g, h, a, b, c, d, 0x650a7354, w4 += sigma1(w2) + w13 + sigma0(w5));
+ Round(d, e, f, g, h, a, b, c, 0x766a0abb, w5 += sigma1(w3) + w14 + sigma0(w6));
+ Round(c, d, e, f, g, h, a, b, 0x81c2c92e, w6 += sigma1(w4) + w15 + sigma0(w7));
+ Round(b, c, d, e, f, g, h, a, 0x92722c85, w7 += sigma1(w5) + w0 + sigma0(w8));
+ Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1, w8 += sigma1(w6) + w1 + sigma0(w9));
+ Round(h, a, b, c, d, e, f, g, 0xa81a664b, w9 += sigma1(w7) + w2 + sigma0(w10));
+ Round(g, h, a, b, c, d, e, f, 0xc24b8b70, w10 += sigma1(w8) + w3 + sigma0(w11));
+ Round(f, g, h, a, b, c, d, e, 0xc76c51a3, w11 += sigma1(w9) + w4 + sigma0(w12));
+ Round(e, f, g, h, a, b, c, d, 0xd192e819, w12 += sigma1(w10) + w5 + sigma0(w13));
+ Round(d, e, f, g, h, a, b, c, 0xd6990624, w13 += sigma1(w11) + w6 + sigma0(w14));
+ Round(c, d, e, f, g, h, a, b, 0xf40e3585, w14 += sigma1(w12) + w7 + sigma0(w15));
+ Round(b, c, d, e, f, g, h, a, 0x106aa070, w15 += sigma1(w13) + w8 + sigma0(w0));
+
+ Round(a, b, c, d, e, f, g, h, 0x19a4c116, w0 += sigma1(w14) + w9 + sigma0(w1));
+ Round(h, a, b, c, d, e, f, g, 0x1e376c08, w1 += sigma1(w15) + w10 + sigma0(w2));
+ Round(g, h, a, b, c, d, e, f, 0x2748774c, w2 += sigma1(w0) + w11 + sigma0(w3));
+ Round(f, g, h, a, b, c, d, e, 0x34b0bcb5, w3 += sigma1(w1) + w12 + sigma0(w4));
+ Round(e, f, g, h, a, b, c, d, 0x391c0cb3, w4 += sigma1(w2) + w13 + sigma0(w5));
+ Round(d, e, f, g, h, a, b, c, 0x4ed8aa4a, w5 += sigma1(w3) + w14 + sigma0(w6));
+ Round(c, d, e, f, g, h, a, b, 0x5b9cca4f, w6 += sigma1(w4) + w15 + sigma0(w7));
+ Round(b, c, d, e, f, g, h, a, 0x682e6ff3, w7 += sigma1(w5) + w0 + sigma0(w8));
+ Round(a, b, c, d, e, f, g, h, 0x748f82ee, w8 += sigma1(w6) + w1 + sigma0(w9));
+ Round(h, a, b, c, d, e, f, g, 0x78a5636f, w9 += sigma1(w7) + w2 + sigma0(w10));
+ Round(g, h, a, b, c, d, e, f, 0x84c87814, w10 += sigma1(w8) + w3 + sigma0(w11));
+ Round(f, g, h, a, b, c, d, e, 0x8cc70208, w11 += sigma1(w9) + w4 + sigma0(w12));
+ Round(e, f, g, h, a, b, c, d, 0x90befffa, w12 += sigma1(w10) + w5 + sigma0(w13));
+ Round(d, e, f, g, h, a, b, c, 0xa4506ceb, w13 += sigma1(w11) + w6 + sigma0(w14));
+ Round(c, d, e, f, g, h, a, b, 0xbef9a3f7, w14 + sigma1(w12) + w7 + sigma0(w15));
+ Round(b, c, d, e, f, g, h, a, 0xc67178f2, w15 + sigma1(w13) + w8 + sigma0(w0));
+
+ s[0] += a;
+ s[1] += b;
+ s[2] += c;
+ s[3] += d;
+ s[4] += e;
+ s[5] += f;
+ s[6] += g;
+ s[7] += h;
+}
+
+static void secp256k1_sha256_write(secp256k1_sha256_t *hash, const unsigned char *data, size_t len) {
+ size_t bufsize = hash->bytes & 0x3F;
+ hash->bytes += len;
+ while (bufsize + len >= 64) {
+ /* Fill the buffer, and process it. */
+ memcpy(((unsigned char*)hash->buf) + bufsize, data, 64 - bufsize);
+ data += 64 - bufsize;
+ len -= 64 - bufsize;
+ secp256k1_sha256_transform(hash->s, hash->buf);
+ bufsize = 0;
+ }
+ if (len) {
+ /* Fill the buffer with what remains. */
+ memcpy(((unsigned char*)hash->buf) + bufsize, data, len);
+ }
+}
+
+static void secp256k1_sha256_finalize(secp256k1_sha256_t *hash, unsigned char *out32) {
+ static const unsigned char pad[64] = {0x80, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ uint32_t sizedesc[2];
+ uint32_t out[8];
+ int i = 0;
+ sizedesc[0] = BE32(hash->bytes >> 29);
+ sizedesc[1] = BE32(hash->bytes << 3);
+ secp256k1_sha256_write(hash, pad, 1 + ((119 - (hash->bytes % 64)) % 64));
+ secp256k1_sha256_write(hash, (const unsigned char*)sizedesc, 8);
+ for (i = 0; i < 8; i++) {
+ out[i] = BE32(hash->s[i]);
+ hash->s[i] = 0;
+ }
+ memcpy(out32, (const unsigned char*)out, 32);
+}
+
+static void secp256k1_hmac_sha256_initialize(secp256k1_hmac_sha256_t *hash, const unsigned char *key, size_t keylen) {
+ int n;
+ unsigned char rkey[64];
+ if (keylen <= 64) {
+ memcpy(rkey, key, keylen);
+ memset(rkey + keylen, 0, 64 - keylen);
+ } else {
+ secp256k1_sha256_t sha256;
+ secp256k1_sha256_initialize(&sha256);
+ secp256k1_sha256_write(&sha256, key, keylen);
+ secp256k1_sha256_finalize(&sha256, rkey);
+ memset(rkey + 32, 0, 32);
+ }
+
+ secp256k1_sha256_initialize(&hash->outer);
+ for (n = 0; n < 64; n++) {
+ rkey[n] ^= 0x5c;
+ }
+ secp256k1_sha256_write(&hash->outer, rkey, 64);
+
+ secp256k1_sha256_initialize(&hash->inner);
+ for (n = 0; n < 64; n++) {
+ rkey[n] ^= 0x5c ^ 0x36;
+ }
+ secp256k1_sha256_write(&hash->inner, rkey, 64);
+ memset(rkey, 0, 64);
+}
+
+static void secp256k1_hmac_sha256_write(secp256k1_hmac_sha256_t *hash, const unsigned char *data, size_t size) {
+ secp256k1_sha256_write(&hash->inner, data, size);
+}
+
+static void secp256k1_hmac_sha256_finalize(secp256k1_hmac_sha256_t *hash, unsigned char *out32) {
+ unsigned char temp[32];
+ secp256k1_sha256_finalize(&hash->inner, temp);
+ secp256k1_sha256_write(&hash->outer, temp, 32);
+ memset(temp, 0, 32);
+ secp256k1_sha256_finalize(&hash->outer, out32);
+}
+
+
+static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha256_t *rng, const unsigned char *key, size_t keylen, const unsigned char *msg, size_t msglen, const unsigned char *rnd, size_t rndlen) {
+ secp256k1_hmac_sha256_t hmac;
+ static const unsigned char zero[1] = {0x00};
+ static const unsigned char one[1] = {0x01};
+
+ memset(rng->v, 0x01, 32); /* RFC6979 3.2.b. */
+ memset(rng->k, 0x00, 32); /* RFC6979 3.2.c. */
+
+ /* RFC6979 3.2.d. */
+ secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32);
+ secp256k1_hmac_sha256_write(&hmac, rng->v, 32);
+ secp256k1_hmac_sha256_write(&hmac, zero, 1);
+ secp256k1_hmac_sha256_write(&hmac, key, keylen);
+ secp256k1_hmac_sha256_write(&hmac, msg, msglen);
+ if (rnd && rndlen) {
+ /* RFC6979 3.6 "Additional data". */
+ secp256k1_hmac_sha256_write(&hmac, rnd, rndlen);
+ }
+ secp256k1_hmac_sha256_finalize(&hmac, rng->k);
+ secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32);
+ secp256k1_hmac_sha256_write(&hmac, rng->v, 32);
+ secp256k1_hmac_sha256_finalize(&hmac, rng->v);
+
+ /* RFC6979 3.2.f. */
+ secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32);
+ secp256k1_hmac_sha256_write(&hmac, rng->v, 32);
+ secp256k1_hmac_sha256_write(&hmac, one, 1);
+ secp256k1_hmac_sha256_write(&hmac, key, keylen);
+ secp256k1_hmac_sha256_write(&hmac, msg, msglen);
+ if (rnd && rndlen) {
+ /* RFC6979 3.6 "Additional data". */
+ secp256k1_hmac_sha256_write(&hmac, rnd, rndlen);
+ }
+ secp256k1_hmac_sha256_finalize(&hmac, rng->k);
+ secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32);
+ secp256k1_hmac_sha256_write(&hmac, rng->v, 32);
+ secp256k1_hmac_sha256_finalize(&hmac, rng->v);
+ rng->retry = 0;
+}
+
+static void secp256k1_rfc6979_hmac_sha256_generate(secp256k1_rfc6979_hmac_sha256_t *rng, unsigned char *out, size_t outlen) {
+ /* RFC6979 3.2.h. */
+ static const unsigned char zero[1] = {0x00};
+ if (rng->retry) {
+ secp256k1_hmac_sha256_t hmac;
+ secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32);
+ secp256k1_hmac_sha256_write(&hmac, rng->v, 32);
+ secp256k1_hmac_sha256_write(&hmac, zero, 1);
+ secp256k1_hmac_sha256_finalize(&hmac, rng->k);
+ secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32);
+ secp256k1_hmac_sha256_write(&hmac, rng->v, 32);
+ secp256k1_hmac_sha256_finalize(&hmac, rng->v);
+ }
+
+ while (outlen > 0) {
+ secp256k1_hmac_sha256_t hmac;
+ int now = outlen;
+ secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32);
+ secp256k1_hmac_sha256_write(&hmac, rng->v, 32);
+ secp256k1_hmac_sha256_finalize(&hmac, rng->v);
+ if (now > 32) {
+ now = 32;
+ }
+ memcpy(out, rng->v, now);
+ out += now;
+ outlen -= now;
+ }
+
+ rng->retry = 1;
+}
+
+static void secp256k1_rfc6979_hmac_sha256_finalize(secp256k1_rfc6979_hmac_sha256_t *rng) {
+ memset(rng->k, 0, 32);
+ memset(rng->v, 0, 32);
+ rng->retry = 0;
+}
+
+
+#undef Round
+#undef sigma0
+#undef sigma1
+#undef Sigma0
+#undef Sigma1
+#undef Ch
+#undef Maj
+#undef ReadBE32
+#undef WriteBE32
+
+#endif
diff --git a/src/secp256k1/src/java/org/bitcoin/NativeSecp256k1.java b/src/secp256k1/src/java/org/bitcoin/NativeSecp256k1.java
new file mode 100644
index 0000000000..90a498eaa2
--- /dev/null
+++ b/src/secp256k1/src/java/org/bitcoin/NativeSecp256k1.java
@@ -0,0 +1,60 @@
+package org.bitcoin;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+import com.google.common.base.Preconditions;
+
+
+/**
+ * This class holds native methods to handle ECDSA verification.
+ * You can find an example library that can be used for this at
+ * https://github.com/sipa/secp256k1
+ */
+public class NativeSecp256k1 {
+ public static final boolean enabled;
+ static {
+ boolean isEnabled = true;
+ try {
+ System.loadLibrary("javasecp256k1");
+ } catch (UnsatisfiedLinkError e) {
+ isEnabled = false;
+ }
+ enabled = isEnabled;
+ }
+
+ private static ThreadLocal<ByteBuffer> nativeECDSABuffer = new ThreadLocal<ByteBuffer>();
+ /**
+ * Verifies the given secp256k1 signature in native code.
+ * Calling when enabled == false is undefined (probably library not loaded)
+ *
+ * @param data The data which was signed, must be exactly 32 bytes
+ * @param signature The signature
+ * @param pub The public key which did the signing
+ */
+ public static boolean verify(byte[] data, byte[] signature, byte[] pub) {
+ Preconditions.checkArgument(data.length == 32 && signature.length <= 520 && pub.length <= 520);
+
+ ByteBuffer byteBuff = nativeECDSABuffer.get();
+ if (byteBuff == null) {
+ byteBuff = ByteBuffer.allocateDirect(32 + 8 + 520 + 520);
+ byteBuff.order(ByteOrder.nativeOrder());
+ nativeECDSABuffer.set(byteBuff);
+ }
+ byteBuff.rewind();
+ byteBuff.put(data);
+ byteBuff.putInt(signature.length);
+ byteBuff.putInt(pub.length);
+ byteBuff.put(signature);
+ byteBuff.put(pub);
+ return secp256k1_ecdsa_verify(byteBuff) == 1;
+ }
+
+ /**
+ * @param byteBuff signature format is byte[32] data,
+ * native-endian int signatureLength, native-endian int pubkeyLength,
+ * byte[signatureLength] signature, byte[pubkeyLength] pub
+ * @returns 1 for valid signature, anything else for invalid
+ */
+ private static native int secp256k1_ecdsa_verify(ByteBuffer byteBuff);
+}
diff --git a/src/secp256k1/src/java/org_bitcoin_NativeSecp256k1.c b/src/secp256k1/src/java/org_bitcoin_NativeSecp256k1.c
new file mode 100644
index 0000000000..bb4cd70728
--- /dev/null
+++ b/src/secp256k1/src/java/org_bitcoin_NativeSecp256k1.c
@@ -0,0 +1,23 @@
+#include "org_bitcoin_NativeSecp256k1.h"
+#include "include/secp256k1.h"
+
+JNIEXPORT jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdsa_1verify
+ (JNIEnv* env, jclass classObject, jobject byteBufferObject)
+{
+ unsigned char* data = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject);
+ int sigLen = *((int*)(data + 32));
+ int pubLen = *((int*)(data + 32 + 4));
+
+ return secp256k1_ecdsa_verify(data, 32, data+32+8, sigLen, data+32+8+sigLen, pubLen);
+}
+
+static void __javasecp256k1_attach(void) __attribute__((constructor));
+static void __javasecp256k1_detach(void) __attribute__((destructor));
+
+static void __javasecp256k1_attach(void) {
+ secp256k1_start(SECP256K1_START_VERIFY);
+}
+
+static void __javasecp256k1_detach(void) {
+ secp256k1_stop();
+}
diff --git a/src/secp256k1/src/java/org_bitcoin_NativeSecp256k1.h b/src/secp256k1/src/java/org_bitcoin_NativeSecp256k1.h
new file mode 100644
index 0000000000..d7fb004fa8
--- /dev/null
+++ b/src/secp256k1/src/java/org_bitcoin_NativeSecp256k1.h
@@ -0,0 +1,21 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class org_bitcoin_NativeSecp256k1 */
+
+#ifndef _Included_org_bitcoin_NativeSecp256k1
+#define _Included_org_bitcoin_NativeSecp256k1
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: org_bitcoin_NativeSecp256k1
+ * Method: secp256k1_ecdsa_verify
+ * Signature: (Ljava/nio/ByteBuffer;)I
+ */
+JNIEXPORT jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdsa_1verify
+ (JNIEnv *, jclass, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/secp256k1/src/num.h b/src/secp256k1/src/num.h
new file mode 100644
index 0000000000..339b6bb6ec
--- /dev/null
+++ b/src/secp256k1/src/num.h
@@ -0,0 +1,68 @@
+/**********************************************************************
+ * Copyright (c) 2013, 2014 Pieter Wuille *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
+ **********************************************************************/
+
+#ifndef _SECP256K1_NUM_
+#define _SECP256K1_NUM_
+
+#ifndef USE_NUM_NONE
+
+#if defined HAVE_CONFIG_H
+#include "libsecp256k1-config.h"
+#endif
+
+#if defined(USE_NUM_GMP)
+#include "num_gmp.h"
+#else
+#error "Please select num implementation"
+#endif
+
+/** Copy a number. */
+static void secp256k1_num_copy(secp256k1_num_t *r, const secp256k1_num_t *a);
+
+/** Convert a number's absolute value to a binary big-endian string.
+ * There must be enough place. */
+static void secp256k1_num_get_bin(unsigned char *r, unsigned int rlen, const secp256k1_num_t *a);
+
+/** Set a number to the value of a binary big-endian string. */
+static void secp256k1_num_set_bin(secp256k1_num_t *r, const unsigned char *a, unsigned int alen);
+
+/** Compute a modular inverse. The input must be less than the modulus. */
+static void secp256k1_num_mod_inverse(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *m);
+
+/** Compare the absolute value of two numbers. */
+static int secp256k1_num_cmp(const secp256k1_num_t *a, const secp256k1_num_t *b);
+
+/** Test whether two number are equal (including sign). */
+static int secp256k1_num_eq(const secp256k1_num_t *a, const secp256k1_num_t *b);
+
+/** Add two (signed) numbers. */
+static void secp256k1_num_add(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b);
+
+/** Subtract two (signed) numbers. */
+static void secp256k1_num_sub(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b);
+
+/** Multiply two (signed) numbers. */
+static void secp256k1_num_mul(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b);
+
+/** Replace a number by its remainder modulo m. M's sign is ignored. The result is a number between 0 and m-1,
+ even if r was negative. */
+static void secp256k1_num_mod(secp256k1_num_t *r, const secp256k1_num_t *m);
+
+/** Right-shift the passed number by bits bits. */
+static void secp256k1_num_shift(secp256k1_num_t *r, int bits);
+
+/** Check whether a number is zero. */
+static int secp256k1_num_is_zero(const secp256k1_num_t *a);
+
+/** Check whether a number is strictly negative. */
+static int secp256k1_num_is_neg(const secp256k1_num_t *a);
+
+/** Change a number's sign. */
+static void secp256k1_num_negate(secp256k1_num_t *r);
+
+#endif
+
+#endif
diff --git a/src/secp256k1/src/num_gmp.h b/src/secp256k1/src/num_gmp.h
new file mode 100644
index 0000000000..baa1f2bf2e
--- /dev/null
+++ b/src/secp256k1/src/num_gmp.h
@@ -0,0 +1,20 @@
+/**********************************************************************
+ * Copyright (c) 2013, 2014 Pieter Wuille *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
+ **********************************************************************/
+
+#ifndef _SECP256K1_NUM_REPR_
+#define _SECP256K1_NUM_REPR_
+
+#include <gmp.h>
+
+#define NUM_LIMBS ((256+GMP_NUMB_BITS-1)/GMP_NUMB_BITS)
+
+typedef struct {
+ mp_limb_t data[2*NUM_LIMBS];
+ int neg;
+ int limbs;
+} secp256k1_num_t;
+
+#endif
diff --git a/src/secp256k1/src/num_gmp_impl.h b/src/secp256k1/src/num_gmp_impl.h
new file mode 100644
index 0000000000..dbbc458d5d
--- /dev/null
+++ b/src/secp256k1/src/num_gmp_impl.h
@@ -0,0 +1,260 @@
+/**********************************************************************
+ * Copyright (c) 2013, 2014 Pieter Wuille *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
+ **********************************************************************/
+
+#ifndef _SECP256K1_NUM_REPR_IMPL_H_
+#define _SECP256K1_NUM_REPR_IMPL_H_
+
+#include <string.h>
+#include <stdlib.h>
+#include <gmp.h>
+
+#include "util.h"
+#include "num.h"
+
+#ifdef VERIFY
+static void secp256k1_num_sanity(const secp256k1_num_t *a) {
+ VERIFY_CHECK(a->limbs == 1 || (a->limbs > 1 && a->data[a->limbs-1] != 0));
+}
+#else
+#define secp256k1_num_sanity(a) do { } while(0)
+#endif
+
+static void secp256k1_num_copy(secp256k1_num_t *r, const secp256k1_num_t *a) {
+ *r = *a;
+}
+
+static void secp256k1_num_get_bin(unsigned char *r, unsigned int rlen, const secp256k1_num_t *a) {
+ unsigned char tmp[65];
+ int len = 0;
+ int shift = 0;
+ if (a->limbs>1 || a->data[0] != 0) {
+ len = mpn_get_str(tmp, 256, (mp_limb_t*)a->data, a->limbs);
+ }
+ while (shift < len && tmp[shift] == 0) shift++;
+ VERIFY_CHECK(len-shift <= (int)rlen);
+ memset(r, 0, rlen - len + shift);
+ if (len > shift) {
+ memcpy(r + rlen - len + shift, tmp + shift, len - shift);
+ }
+ memset(tmp, 0, sizeof(tmp));
+}
+
+static void secp256k1_num_set_bin(secp256k1_num_t *r, const unsigned char *a, unsigned int alen) {
+ int len;
+ VERIFY_CHECK(alen > 0);
+ VERIFY_CHECK(alen <= 64);
+ len = mpn_set_str(r->data, a, alen, 256);
+ if (len == 0) {
+ r->data[0] = 0;
+ len = 1;
+ }
+ VERIFY_CHECK(len <= NUM_LIMBS*2);
+ r->limbs = len;
+ r->neg = 0;
+ while (r->limbs > 1 && r->data[r->limbs-1]==0) {
+ r->limbs--;
+ }
+}
+
+static void secp256k1_num_add_abs(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b) {
+ mp_limb_t c = mpn_add(r->data, a->data, a->limbs, b->data, b->limbs);
+ r->limbs = a->limbs;
+ if (c != 0) {
+ VERIFY_CHECK(r->limbs < 2*NUM_LIMBS);
+ r->data[r->limbs++] = c;
+ }
+}
+
+static void secp256k1_num_sub_abs(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b) {
+ mp_limb_t c = mpn_sub(r->data, a->data, a->limbs, b->data, b->limbs);
+ VERIFY_CHECK(c == 0);
+ r->limbs = a->limbs;
+ while (r->limbs > 1 && r->data[r->limbs-1]==0) {
+ r->limbs--;
+ }
+}
+
+static void secp256k1_num_mod(secp256k1_num_t *r, const secp256k1_num_t *m) {
+ secp256k1_num_sanity(r);
+ secp256k1_num_sanity(m);
+
+ if (r->limbs >= m->limbs) {
+ mp_limb_t t[2*NUM_LIMBS];
+ mpn_tdiv_qr(t, r->data, 0, r->data, r->limbs, m->data, m->limbs);
+ memset(t, 0, sizeof(t));
+ r->limbs = m->limbs;
+ while (r->limbs > 1 && r->data[r->limbs-1]==0) {
+ r->limbs--;
+ }
+ }
+
+ if (r->neg && (r->limbs > 1 || r->data[0] != 0)) {
+ secp256k1_num_sub_abs(r, m, r);
+ r->neg = 0;
+ }
+}
+
+static void secp256k1_num_mod_inverse(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *m) {
+ int i;
+ mp_limb_t g[NUM_LIMBS+1];
+ mp_limb_t u[NUM_LIMBS+1];
+ mp_limb_t v[NUM_LIMBS+1];
+ mp_size_t sn;
+ mp_size_t gn;
+ secp256k1_num_sanity(a);
+ secp256k1_num_sanity(m);
+
+ /** mpn_gcdext computes: (G,S) = gcdext(U,V), where
+ * * G = gcd(U,V)
+ * * G = U*S + V*T
+ * * U has equal or more limbs than V, and V has no padding
+ * If we set U to be (a padded version of) a, and V = m:
+ * G = a*S + m*T
+ * G = a*S mod m
+ * Assuming G=1:
+ * S = 1/a mod m
+ */
+ VERIFY_CHECK(m->limbs <= NUM_LIMBS);
+ VERIFY_CHECK(m->data[m->limbs-1] != 0);
+ for (i = 0; i < m->limbs; i++) {
+ u[i] = (i < a->limbs) ? a->data[i] : 0;
+ v[i] = m->data[i];
+ }
+ sn = NUM_LIMBS+1;
+ gn = mpn_gcdext(g, r->data, &sn, u, m->limbs, v, m->limbs);
+ VERIFY_CHECK(gn == 1);
+ VERIFY_CHECK(g[0] == 1);
+ r->neg = a->neg ^ m->neg;
+ if (sn < 0) {
+ mpn_sub(r->data, m->data, m->limbs, r->data, -sn);
+ r->limbs = m->limbs;
+ while (r->limbs > 1 && r->data[r->limbs-1]==0) {
+ r->limbs--;
+ }
+ } else {
+ r->limbs = sn;
+ }
+ memset(g, 0, sizeof(g));
+ memset(u, 0, sizeof(u));
+ memset(v, 0, sizeof(v));
+}
+
+static int secp256k1_num_is_zero(const secp256k1_num_t *a) {
+ return (a->limbs == 1 && a->data[0] == 0);
+}
+
+static int secp256k1_num_is_neg(const secp256k1_num_t *a) {
+ return (a->limbs > 1 || a->data[0] != 0) && a->neg;
+}
+
+static int secp256k1_num_cmp(const secp256k1_num_t *a, const secp256k1_num_t *b) {
+ if (a->limbs > b->limbs) {
+ return 1;
+ }
+ if (a->limbs < b->limbs) {
+ return -1;
+ }
+ return mpn_cmp(a->data, b->data, a->limbs);
+}
+
+static int secp256k1_num_eq(const secp256k1_num_t *a, const secp256k1_num_t *b) {
+ if (a->limbs > b->limbs) {
+ return 0;
+ }
+ if (a->limbs < b->limbs) {
+ return 0;
+ }
+ if ((a->neg && !secp256k1_num_is_zero(a)) != (b->neg && !secp256k1_num_is_zero(b))) {
+ return 0;
+ }
+ return mpn_cmp(a->data, b->data, a->limbs) == 0;
+}
+
+static void secp256k1_num_subadd(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b, int bneg) {
+ if (!(b->neg ^ bneg ^ a->neg)) { /* a and b have the same sign */
+ r->neg = a->neg;
+ if (a->limbs >= b->limbs) {
+ secp256k1_num_add_abs(r, a, b);
+ } else {
+ secp256k1_num_add_abs(r, b, a);
+ }
+ } else {
+ if (secp256k1_num_cmp(a, b) > 0) {
+ r->neg = a->neg;
+ secp256k1_num_sub_abs(r, a, b);
+ } else {
+ r->neg = b->neg ^ bneg;
+ secp256k1_num_sub_abs(r, b, a);
+ }
+ }
+}
+
+static void secp256k1_num_add(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b) {
+ secp256k1_num_sanity(a);
+ secp256k1_num_sanity(b);
+ secp256k1_num_subadd(r, a, b, 0);
+}
+
+static void secp256k1_num_sub(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b) {
+ secp256k1_num_sanity(a);
+ secp256k1_num_sanity(b);
+ secp256k1_num_subadd(r, a, b, 1);
+}
+
+static void secp256k1_num_mul(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b) {
+ mp_limb_t tmp[2*NUM_LIMBS+1];
+ secp256k1_num_sanity(a);
+ secp256k1_num_sanity(b);
+
+ VERIFY_CHECK(a->limbs + b->limbs <= 2*NUM_LIMBS+1);
+ if ((a->limbs==1 && a->data[0]==0) || (b->limbs==1 && b->data[0]==0)) {
+ r->limbs = 1;
+ r->neg = 0;
+ r->data[0] = 0;
+ return;
+ }
+ if (a->limbs >= b->limbs) {
+ mpn_mul(tmp, a->data, a->limbs, b->data, b->limbs);
+ } else {
+ mpn_mul(tmp, b->data, b->limbs, a->data, a->limbs);
+ }
+ r->limbs = a->limbs + b->limbs;
+ if (r->limbs > 1 && tmp[r->limbs - 1]==0) {
+ r->limbs--;
+ }
+ VERIFY_CHECK(r->limbs <= 2*NUM_LIMBS);
+ mpn_copyi(r->data, tmp, r->limbs);
+ r->neg = a->neg ^ b->neg;
+ memset(tmp, 0, sizeof(tmp));
+}
+
+static void secp256k1_num_shift(secp256k1_num_t *r, int bits) {
+ int i;
+ if (bits % GMP_NUMB_BITS) {
+ /* Shift within limbs. */
+ mpn_rshift(r->data, r->data, r->limbs, bits % GMP_NUMB_BITS);
+ }
+ if (bits >= GMP_NUMB_BITS) {
+ /* Shift full limbs. */
+ for (i = 0; i < r->limbs; i++) {
+ int index = i + (bits / GMP_NUMB_BITS);
+ if (index < r->limbs && index < 2*NUM_LIMBS) {
+ r->data[i] = r->data[index];
+ } else {
+ r->data[i] = 0;
+ }
+ }
+ }
+ while (r->limbs>1 && r->data[r->limbs-1]==0) {
+ r->limbs--;
+ }
+}
+
+static void secp256k1_num_negate(secp256k1_num_t *r) {
+ r->neg ^= 1;
+}
+
+#endif
diff --git a/src/secp256k1/src/num_impl.h b/src/secp256k1/src/num_impl.h
new file mode 100644
index 0000000000..0b0e3a072a
--- /dev/null
+++ b/src/secp256k1/src/num_impl.h
@@ -0,0 +1,24 @@
+/**********************************************************************
+ * Copyright (c) 2013, 2014 Pieter Wuille *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
+ **********************************************************************/
+
+#ifndef _SECP256K1_NUM_IMPL_H_
+#define _SECP256K1_NUM_IMPL_H_
+
+#if defined HAVE_CONFIG_H
+#include "libsecp256k1-config.h"
+#endif
+
+#include "num.h"
+
+#if defined(USE_NUM_GMP)
+#include "num_gmp_impl.h"
+#elif defined(USE_NUM_NONE)
+/* Nothing. */
+#else
+#error "Please select num implementation"
+#endif
+
+#endif
diff --git a/src/secp256k1/src/scalar.h b/src/secp256k1/src/scalar.h
new file mode 100644
index 0000000000..f5d09f8d47
--- /dev/null
+++ b/src/secp256k1/src/scalar.h
@@ -0,0 +1,93 @@
+/**********************************************************************
+ * Copyright (c) 2014 Pieter Wuille *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
+ **********************************************************************/
+
+#ifndef _SECP256K1_SCALAR_
+#define _SECP256K1_SCALAR_
+
+#include "num.h"
+
+#if defined HAVE_CONFIG_H
+#include "libsecp256k1-config.h"
+#endif
+
+#if defined(USE_SCALAR_4X64)
+#include "scalar_4x64.h"
+#elif defined(USE_SCALAR_8X32)
+#include "scalar_8x32.h"
+#else
+#error "Please select scalar implementation"
+#endif
+
+/** Clear a scalar to prevent the leak of sensitive data. */
+static void secp256k1_scalar_clear(secp256k1_scalar_t *r);
+
+/** Access bits from a scalar. All requested bits must belong to the same 32-bit limb. */
+static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar_t *a, unsigned int offset, unsigned int count);
+
+/** Access bits from a scalar. Not constant time. */
+static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar_t *a, unsigned int offset, unsigned int count);
+
+/** Set a scalar from a big endian byte array. */
+static void secp256k1_scalar_set_b32(secp256k1_scalar_t *r, const unsigned char *bin, int *overflow);
+
+/** Set a scalar to an unsigned integer. */
+static void secp256k1_scalar_set_int(secp256k1_scalar_t *r, unsigned int v);
+
+/** Convert a scalar to a byte array. */
+static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar_t* a);
+
+/** Add two scalars together (modulo the group order). Returns whether it overflowed. */
+static int secp256k1_scalar_add(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b);
+
+/** Add a power of two to a scalar. The result is not allowed to overflow. */
+static void secp256k1_scalar_add_bit(secp256k1_scalar_t *r, unsigned int bit);
+
+/** Multiply two scalars (modulo the group order). */
+static void secp256k1_scalar_mul(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b);
+
+/** Compute the square of a scalar (modulo the group order). */
+static void secp256k1_scalar_sqr(secp256k1_scalar_t *r, const secp256k1_scalar_t *a);
+
+/** Compute the inverse of a scalar (modulo the group order). */
+static void secp256k1_scalar_inverse(secp256k1_scalar_t *r, const secp256k1_scalar_t *a);
+
+/** Compute the inverse of a scalar (modulo the group order), without constant-time guarantee. */
+static void secp256k1_scalar_inverse_var(secp256k1_scalar_t *r, const secp256k1_scalar_t *a);
+
+/** Compute the complement of a scalar (modulo the group order). */
+static void secp256k1_scalar_negate(secp256k1_scalar_t *r, const secp256k1_scalar_t *a);
+
+/** Check whether a scalar equals zero. */
+static int secp256k1_scalar_is_zero(const secp256k1_scalar_t *a);
+
+/** Check whether a scalar equals one. */
+static int secp256k1_scalar_is_one(const secp256k1_scalar_t *a);
+
+/** Check whether a scalar is higher than the group order divided by 2. */
+static int secp256k1_scalar_is_high(const secp256k1_scalar_t *a);
+
+#ifndef USE_NUM_NONE
+/** Convert a scalar to a number. */
+static void secp256k1_scalar_get_num(secp256k1_num_t *r, const secp256k1_scalar_t *a);
+
+/** Get the order of the group as a number. */
+static void secp256k1_scalar_order_get_num(secp256k1_num_t *r);
+#endif
+
+/** Compare two scalars. */
+static int secp256k1_scalar_eq(const secp256k1_scalar_t *a, const secp256k1_scalar_t *b);
+
+#ifdef USE_ENDOMORPHISM
+/** Find r1 and r2 such that r1+r2*2^128 = a. */
+static void secp256k1_scalar_split_128(secp256k1_scalar_t *r1, secp256k1_scalar_t *r2, const secp256k1_scalar_t *a);
+/** Find r1 and r2 such that r1+r2*lambda = a, and r1 and r2 are maximum 128 bits long (see secp256k1_gej_mul_lambda). */
+static void secp256k1_scalar_split_lambda_var(secp256k1_scalar_t *r1, secp256k1_scalar_t *r2, const secp256k1_scalar_t *a);
+#endif
+
+/** Multiply a and b (without taking the modulus!), divide by 2**shift, and round to the nearest integer. Shift must be at least 256. */
+static void secp256k1_scalar_mul_shift_var(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b, unsigned int shift);
+
+#endif
diff --git a/src/secp256k1/src/scalar_4x64.h b/src/secp256k1/src/scalar_4x64.h
new file mode 100644
index 0000000000..82899aa7b0
--- /dev/null
+++ b/src/secp256k1/src/scalar_4x64.h
@@ -0,0 +1,19 @@
+/**********************************************************************
+ * Copyright (c) 2014 Pieter Wuille *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
+ **********************************************************************/
+
+#ifndef _SECP256K1_SCALAR_REPR_
+#define _SECP256K1_SCALAR_REPR_
+
+#include <stdint.h>
+
+/** A scalar modulo the group order of the secp256k1 curve. */
+typedef struct {
+ uint64_t d[4];
+} secp256k1_scalar_t;
+
+#define SECP256K1_SCALAR_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{((uint64_t)(d1)) << 32 | (d0), ((uint64_t)(d3)) << 32 | (d2), ((uint64_t)(d5)) << 32 | (d4), ((uint64_t)(d7)) << 32 | (d6)}}
+
+#endif
diff --git a/src/secp256k1/src/scalar_4x64_impl.h b/src/secp256k1/src/scalar_4x64_impl.h
new file mode 100644
index 0000000000..ff365292f8
--- /dev/null
+++ b/src/secp256k1/src/scalar_4x64_impl.h
@@ -0,0 +1,920 @@
+/**********************************************************************
+ * Copyright (c) 2013, 2014 Pieter Wuille *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
+ **********************************************************************/
+
+#ifndef _SECP256K1_SCALAR_REPR_IMPL_H_
+#define _SECP256K1_SCALAR_REPR_IMPL_H_
+
+/* Limbs of the secp256k1 order. */
+#define SECP256K1_N_0 ((uint64_t)0xBFD25E8CD0364141ULL)
+#define SECP256K1_N_1 ((uint64_t)0xBAAEDCE6AF48A03BULL)
+#define SECP256K1_N_2 ((uint64_t)0xFFFFFFFFFFFFFFFEULL)
+#define SECP256K1_N_3 ((uint64_t)0xFFFFFFFFFFFFFFFFULL)
+
+/* Limbs of 2^256 minus the secp256k1 order. */
+#define SECP256K1_N_C_0 (~SECP256K1_N_0 + 1)
+#define SECP256K1_N_C_1 (~SECP256K1_N_1)
+#define SECP256K1_N_C_2 (1)
+
+/* Limbs of half the secp256k1 order. */
+#define SECP256K1_N_H_0 ((uint64_t)0xDFE92F46681B20A0ULL)
+#define SECP256K1_N_H_1 ((uint64_t)0x5D576E7357A4501DULL)
+#define SECP256K1_N_H_2 ((uint64_t)0xFFFFFFFFFFFFFFFFULL)
+#define SECP256K1_N_H_3 ((uint64_t)0x7FFFFFFFFFFFFFFFULL)
+
+SECP256K1_INLINE static void secp256k1_scalar_clear(secp256k1_scalar_t *r) {
+ r->d[0] = 0;
+ r->d[1] = 0;
+ r->d[2] = 0;
+ r->d[3] = 0;
+}
+
+SECP256K1_INLINE static void secp256k1_scalar_set_int(secp256k1_scalar_t *r, unsigned int v) {
+ r->d[0] = v;
+ r->d[1] = 0;
+ r->d[2] = 0;
+ r->d[3] = 0;
+}
+
+SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar_t *a, unsigned int offset, unsigned int count) {
+ VERIFY_CHECK((offset + count - 1) >> 6 == offset >> 6);
+ return (a->d[offset >> 6] >> (offset & 0x3F)) & ((((uint64_t)1) << count) - 1);
+}
+
+SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar_t *a, unsigned int offset, unsigned int count) {
+ VERIFY_CHECK(count < 32);
+ VERIFY_CHECK(offset + count <= 256);
+ if ((offset + count - 1) >> 6 == offset >> 6) {
+ return secp256k1_scalar_get_bits(a, offset, count);
+ } else {
+ VERIFY_CHECK((offset >> 6) + 1 < 4);
+ return ((a->d[offset >> 6] >> (offset & 0x3F)) | (a->d[(offset >> 6) + 1] << (64 - (offset & 0x3F)))) & ((((uint64_t)1) << count) - 1);
+ }
+}
+
+SECP256K1_INLINE static int secp256k1_scalar_check_overflow(const secp256k1_scalar_t *a) {
+ int yes = 0;
+ int no = 0;
+ no |= (a->d[3] < SECP256K1_N_3); /* No need for a > check. */
+ no |= (a->d[2] < SECP256K1_N_2);
+ yes |= (a->d[2] > SECP256K1_N_2) & ~no;
+ no |= (a->d[1] < SECP256K1_N_1);
+ yes |= (a->d[1] > SECP256K1_N_1) & ~no;
+ yes |= (a->d[0] >= SECP256K1_N_0) & ~no;
+ return yes;
+}
+
+SECP256K1_INLINE static int secp256k1_scalar_reduce(secp256k1_scalar_t *r, unsigned int overflow) {
+ uint128_t t;
+ VERIFY_CHECK(overflow <= 1);
+ t = (uint128_t)r->d[0] + overflow * SECP256K1_N_C_0;
+ r->d[0] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64;
+ t += (uint128_t)r->d[1] + overflow * SECP256K1_N_C_1;
+ r->d[1] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64;
+ t += (uint128_t)r->d[2] + overflow * SECP256K1_N_C_2;
+ r->d[2] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64;
+ t += (uint64_t)r->d[3];
+ r->d[3] = t & 0xFFFFFFFFFFFFFFFFULL;
+ return overflow;
+}
+
+static int secp256k1_scalar_add(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) {
+ int overflow;
+ uint128_t t = (uint128_t)a->d[0] + b->d[0];
+ r->d[0] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64;
+ t += (uint128_t)a->d[1] + b->d[1];
+ r->d[1] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64;
+ t += (uint128_t)a->d[2] + b->d[2];
+ r->d[2] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64;
+ t += (uint128_t)a->d[3] + b->d[3];
+ r->d[3] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64;
+ overflow = t + secp256k1_scalar_check_overflow(r);
+ VERIFY_CHECK(overflow == 0 || overflow == 1);
+ secp256k1_scalar_reduce(r, overflow);
+ return overflow;
+}
+
+static void secp256k1_scalar_add_bit(secp256k1_scalar_t *r, unsigned int bit) {
+ uint128_t t;
+ VERIFY_CHECK(bit < 256);
+ t = (uint128_t)r->d[0] + (((uint64_t)((bit >> 6) == 0)) << (bit & 0x3F));
+ r->d[0] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64;
+ t += (uint128_t)r->d[1] + (((uint64_t)((bit >> 6) == 1)) << (bit & 0x3F));
+ r->d[1] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64;
+ t += (uint128_t)r->d[2] + (((uint64_t)((bit >> 6) == 2)) << (bit & 0x3F));
+ r->d[2] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64;
+ t += (uint128_t)r->d[3] + (((uint64_t)((bit >> 6) == 3)) << (bit & 0x3F));
+ r->d[3] = t & 0xFFFFFFFFFFFFFFFFULL;
+#ifdef VERIFY
+ VERIFY_CHECK((t >> 64) == 0);
+ VERIFY_CHECK(secp256k1_scalar_check_overflow(r) == 0);
+#endif
+}
+
+static void secp256k1_scalar_set_b32(secp256k1_scalar_t *r, const unsigned char *b32, int *overflow) {
+ int over;
+ r->d[0] = (uint64_t)b32[31] | (uint64_t)b32[30] << 8 | (uint64_t)b32[29] << 16 | (uint64_t)b32[28] << 24 | (uint64_t)b32[27] << 32 | (uint64_t)b32[26] << 40 | (uint64_t)b32[25] << 48 | (uint64_t)b32[24] << 56;
+ r->d[1] = (uint64_t)b32[23] | (uint64_t)b32[22] << 8 | (uint64_t)b32[21] << 16 | (uint64_t)b32[20] << 24 | (uint64_t)b32[19] << 32 | (uint64_t)b32[18] << 40 | (uint64_t)b32[17] << 48 | (uint64_t)b32[16] << 56;
+ r->d[2] = (uint64_t)b32[15] | (uint64_t)b32[14] << 8 | (uint64_t)b32[13] << 16 | (uint64_t)b32[12] << 24 | (uint64_t)b32[11] << 32 | (uint64_t)b32[10] << 40 | (uint64_t)b32[9] << 48 | (uint64_t)b32[8] << 56;
+ r->d[3] = (uint64_t)b32[7] | (uint64_t)b32[6] << 8 | (uint64_t)b32[5] << 16 | (uint64_t)b32[4] << 24 | (uint64_t)b32[3] << 32 | (uint64_t)b32[2] << 40 | (uint64_t)b32[1] << 48 | (uint64_t)b32[0] << 56;
+ over = secp256k1_scalar_reduce(r, secp256k1_scalar_check_overflow(r));
+ if (overflow) {
+ *overflow = over;
+ }
+}
+
+static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar_t* a) {
+ bin[0] = a->d[3] >> 56; bin[1] = a->d[3] >> 48; bin[2] = a->d[3] >> 40; bin[3] = a->d[3] >> 32; bin[4] = a->d[3] >> 24; bin[5] = a->d[3] >> 16; bin[6] = a->d[3] >> 8; bin[7] = a->d[3];
+ bin[8] = a->d[2] >> 56; bin[9] = a->d[2] >> 48; bin[10] = a->d[2] >> 40; bin[11] = a->d[2] >> 32; bin[12] = a->d[2] >> 24; bin[13] = a->d[2] >> 16; bin[14] = a->d[2] >> 8; bin[15] = a->d[2];
+ bin[16] = a->d[1] >> 56; bin[17] = a->d[1] >> 48; bin[18] = a->d[1] >> 40; bin[19] = a->d[1] >> 32; bin[20] = a->d[1] >> 24; bin[21] = a->d[1] >> 16; bin[22] = a->d[1] >> 8; bin[23] = a->d[1];
+ bin[24] = a->d[0] >> 56; bin[25] = a->d[0] >> 48; bin[26] = a->d[0] >> 40; bin[27] = a->d[0] >> 32; bin[28] = a->d[0] >> 24; bin[29] = a->d[0] >> 16; bin[30] = a->d[0] >> 8; bin[31] = a->d[0];
+}
+
+SECP256K1_INLINE static int secp256k1_scalar_is_zero(const secp256k1_scalar_t *a) {
+ return (a->d[0] | a->d[1] | a->d[2] | a->d[3]) == 0;
+}
+
+static void secp256k1_scalar_negate(secp256k1_scalar_t *r, const secp256k1_scalar_t *a) {
+ uint64_t nonzero = 0xFFFFFFFFFFFFFFFFULL * (secp256k1_scalar_is_zero(a) == 0);
+ uint128_t t = (uint128_t)(~a->d[0]) + SECP256K1_N_0 + 1;
+ r->d[0] = t & nonzero; t >>= 64;
+ t += (uint128_t)(~a->d[1]) + SECP256K1_N_1;
+ r->d[1] = t & nonzero; t >>= 64;
+ t += (uint128_t)(~a->d[2]) + SECP256K1_N_2;
+ r->d[2] = t & nonzero; t >>= 64;
+ t += (uint128_t)(~a->d[3]) + SECP256K1_N_3;
+ r->d[3] = t & nonzero;
+}
+
+SECP256K1_INLINE static int secp256k1_scalar_is_one(const secp256k1_scalar_t *a) {
+ return ((a->d[0] ^ 1) | a->d[1] | a->d[2] | a->d[3]) == 0;
+}
+
+static int secp256k1_scalar_is_high(const secp256k1_scalar_t *a) {
+ int yes = 0;
+ int no = 0;
+ no |= (a->d[3] < SECP256K1_N_H_3);
+ yes |= (a->d[3] > SECP256K1_N_H_3) & ~no;
+ no |= (a->d[2] < SECP256K1_N_H_2) & ~yes; /* No need for a > check. */
+ no |= (a->d[1] < SECP256K1_N_H_1) & ~yes;
+ yes |= (a->d[1] > SECP256K1_N_H_1) & ~no;
+ yes |= (a->d[0] > SECP256K1_N_H_0) & ~no;
+ return yes;
+}
+
+/* Inspired by the macros in OpenSSL's crypto/bn/asm/x86_64-gcc.c. */
+
+/** Add a*b to the number defined by (c0,c1,c2). c2 must never overflow. */
+#define muladd(a,b) { \
+ uint64_t tl, th; \
+ { \
+ uint128_t t = (uint128_t)a * b; \
+ th = t >> 64; /* at most 0xFFFFFFFFFFFFFFFE */ \
+ tl = t; \
+ } \
+ c0 += tl; /* overflow is handled on the next line */ \
+ th += (c0 < tl) ? 1 : 0; /* at most 0xFFFFFFFFFFFFFFFF */ \
+ c1 += th; /* overflow is handled on the next line */ \
+ c2 += (c1 < th) ? 1 : 0; /* never overflows by contract (verified in the next line) */ \
+ VERIFY_CHECK((c1 >= th) || (c2 != 0)); \
+}
+
+/** Add a*b to the number defined by (c0,c1). c1 must never overflow. */
+#define muladd_fast(a,b) { \
+ uint64_t tl, th; \
+ { \
+ uint128_t t = (uint128_t)a * b; \
+ th = t >> 64; /* at most 0xFFFFFFFFFFFFFFFE */ \
+ tl = t; \
+ } \
+ c0 += tl; /* overflow is handled on the next line */ \
+ th += (c0 < tl) ? 1 : 0; /* at most 0xFFFFFFFFFFFFFFFF */ \
+ c1 += th; /* never overflows by contract (verified in the next line) */ \
+ VERIFY_CHECK(c1 >= th); \
+}
+
+/** Add 2*a*b to the number defined by (c0,c1,c2). c2 must never overflow. */
+#define muladd2(a,b) { \
+ uint64_t tl, th, th2, tl2; \
+ { \
+ uint128_t t = (uint128_t)a * b; \
+ th = t >> 64; /* at most 0xFFFFFFFFFFFFFFFE */ \
+ tl = t; \
+ } \
+ th2 = th + th; /* at most 0xFFFFFFFFFFFFFFFE (in case th was 0x7FFFFFFFFFFFFFFF) */ \
+ c2 += (th2 < th) ? 1 : 0; /* never overflows by contract (verified the next line) */ \
+ VERIFY_CHECK((th2 >= th) || (c2 != 0)); \
+ tl2 = tl + tl; /* at most 0xFFFFFFFFFFFFFFFE (in case the lowest 63 bits of tl were 0x7FFFFFFFFFFFFFFF) */ \
+ th2 += (tl2 < tl) ? 1 : 0; /* at most 0xFFFFFFFFFFFFFFFF */ \
+ c0 += tl2; /* overflow is handled on the next line */ \
+ th2 += (c0 < tl2) ? 1 : 0; /* second overflow is handled on the next line */ \
+ c2 += (c0 < tl2) & (th2 == 0); /* never overflows by contract (verified the next line) */ \
+ VERIFY_CHECK((c0 >= tl2) || (th2 != 0) || (c2 != 0)); \
+ c1 += th2; /* overflow is handled on the next line */ \
+ c2 += (c1 < th2) ? 1 : 0; /* never overflows by contract (verified the next line) */ \
+ VERIFY_CHECK((c1 >= th2) || (c2 != 0)); \
+}
+
+/** Add a to the number defined by (c0,c1,c2). c2 must never overflow. */
+#define sumadd(a) { \
+ unsigned int over; \
+ c0 += (a); /* overflow is handled on the next line */ \
+ over = (c0 < (a)) ? 1 : 0; \
+ c1 += over; /* overflow is handled on the next line */ \
+ c2 += (c1 < over) ? 1 : 0; /* never overflows by contract */ \
+}
+
+/** Add a to the number defined by (c0,c1). c1 must never overflow, c2 must be zero. */
+#define sumadd_fast(a) { \
+ c0 += (a); /* overflow is handled on the next line */ \
+ c1 += (c0 < (a)) ? 1 : 0; /* never overflows by contract (verified the next line) */ \
+ VERIFY_CHECK((c1 != 0) | (c0 >= (a))); \
+ VERIFY_CHECK(c2 == 0); \
+}
+
+/** Extract the lowest 64 bits of (c0,c1,c2) into n, and left shift the number 64 bits. */
+#define extract(n) { \
+ (n) = c0; \
+ c0 = c1; \
+ c1 = c2; \
+ c2 = 0; \
+}
+
+/** Extract the lowest 64 bits of (c0,c1,c2) into n, and left shift the number 64 bits. c2 is required to be zero. */
+#define extract_fast(n) { \
+ (n) = c0; \
+ c0 = c1; \
+ c1 = 0; \
+ VERIFY_CHECK(c2 == 0); \
+}
+
+static void secp256k1_scalar_reduce_512(secp256k1_scalar_t *r, const uint64_t *l) {
+#ifdef USE_ASM_X86_64
+ /* Reduce 512 bits into 385. */
+ uint64_t m0, m1, m2, m3, m4, m5, m6;
+ uint64_t p0, p1, p2, p3, p4;
+ uint64_t c;
+
+ __asm__ __volatile__(
+ /* Preload. */
+ "movq 32(%%rsi), %%r11\n"
+ "movq 40(%%rsi), %%r12\n"
+ "movq 48(%%rsi), %%r13\n"
+ "movq 56(%%rsi), %%r14\n"
+ /* Initialize r8,r9,r10 */
+ "movq 0(%%rsi), %%r8\n"
+ "movq $0, %%r9\n"
+ "movq $0, %%r10\n"
+ /* (r8,r9) += n0 * c0 */
+ "movq %8, %%rax\n"
+ "mulq %%r11\n"
+ "addq %%rax, %%r8\n"
+ "adcq %%rdx, %%r9\n"
+ /* extract m0 */
+ "movq %%r8, %q0\n"
+ "movq $0, %%r8\n"
+ /* (r9,r10) += l1 */
+ "addq 8(%%rsi), %%r9\n"
+ "adcq $0, %%r10\n"
+ /* (r9,r10,r8) += n1 * c0 */
+ "movq %8, %%rax\n"
+ "mulq %%r12\n"
+ "addq %%rax, %%r9\n"
+ "adcq %%rdx, %%r10\n"
+ "adcq $0, %%r8\n"
+ /* (r9,r10,r8) += n0 * c1 */
+ "movq %9, %%rax\n"
+ "mulq %%r11\n"
+ "addq %%rax, %%r9\n"
+ "adcq %%rdx, %%r10\n"
+ "adcq $0, %%r8\n"
+ /* extract m1 */
+ "movq %%r9, %q1\n"
+ "movq $0, %%r9\n"
+ /* (r10,r8,r9) += l2 */
+ "addq 16(%%rsi), %%r10\n"
+ "adcq $0, %%r8\n"
+ "adcq $0, %%r9\n"
+ /* (r10,r8,r9) += n2 * c0 */
+ "movq %8, %%rax\n"
+ "mulq %%r13\n"
+ "addq %%rax, %%r10\n"
+ "adcq %%rdx, %%r8\n"
+ "adcq $0, %%r9\n"
+ /* (r10,r8,r9) += n1 * c1 */
+ "movq %9, %%rax\n"
+ "mulq %%r12\n"
+ "addq %%rax, %%r10\n"
+ "adcq %%rdx, %%r8\n"
+ "adcq $0, %%r9\n"
+ /* (r10,r8,r9) += n0 */
+ "addq %%r11, %%r10\n"
+ "adcq $0, %%r8\n"
+ "adcq $0, %%r9\n"
+ /* extract m2 */
+ "movq %%r10, %q2\n"
+ "movq $0, %%r10\n"
+ /* (r8,r9,r10) += l3 */
+ "addq 24(%%rsi), %%r8\n"
+ "adcq $0, %%r9\n"
+ "adcq $0, %%r10\n"
+ /* (r8,r9,r10) += n3 * c0 */
+ "movq %8, %%rax\n"
+ "mulq %%r14\n"
+ "addq %%rax, %%r8\n"
+ "adcq %%rdx, %%r9\n"
+ "adcq $0, %%r10\n"
+ /* (r8,r9,r10) += n2 * c1 */
+ "movq %9, %%rax\n"
+ "mulq %%r13\n"
+ "addq %%rax, %%r8\n"
+ "adcq %%rdx, %%r9\n"
+ "adcq $0, %%r10\n"
+ /* (r8,r9,r10) += n1 */
+ "addq %%r12, %%r8\n"
+ "adcq $0, %%r9\n"
+ "adcq $0, %%r10\n"
+ /* extract m3 */
+ "movq %%r8, %q3\n"
+ "movq $0, %%r8\n"
+ /* (r9,r10,r8) += n3 * c1 */
+ "movq %9, %%rax\n"
+ "mulq %%r14\n"
+ "addq %%rax, %%r9\n"
+ "adcq %%rdx, %%r10\n"
+ "adcq $0, %%r8\n"
+ /* (r9,r10,r8) += n2 */
+ "addq %%r13, %%r9\n"
+ "adcq $0, %%r10\n"
+ "adcq $0, %%r8\n"
+ /* extract m4 */
+ "movq %%r9, %q4\n"
+ /* (r10,r8) += n3 */
+ "addq %%r14, %%r10\n"
+ "adcq $0, %%r8\n"
+ /* extract m5 */
+ "movq %%r10, %q5\n"
+ /* extract m6 */
+ "movq %%r8, %q6\n"
+ : "=g"(m0), "=g"(m1), "=g"(m2), "=g"(m3), "=g"(m4), "=g"(m5), "=g"(m6)
+ : "S"(l), "n"(SECP256K1_N_C_0), "n"(SECP256K1_N_C_1)
+ : "rax", "rdx", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "cc");
+
+ /* Reduce 385 bits into 258. */
+ __asm__ __volatile__(
+ /* Preload */
+ "movq %q9, %%r11\n"
+ "movq %q10, %%r12\n"
+ "movq %q11, %%r13\n"
+ /* Initialize (r8,r9,r10) */
+ "movq %q5, %%r8\n"
+ "movq $0, %%r9\n"
+ "movq $0, %%r10\n"
+ /* (r8,r9) += m4 * c0 */
+ "movq %12, %%rax\n"
+ "mulq %%r11\n"
+ "addq %%rax, %%r8\n"
+ "adcq %%rdx, %%r9\n"
+ /* extract p0 */
+ "movq %%r8, %q0\n"
+ "movq $0, %%r8\n"
+ /* (r9,r10) += m1 */
+ "addq %q6, %%r9\n"
+ "adcq $0, %%r10\n"
+ /* (r9,r10,r8) += m5 * c0 */
+ "movq %12, %%rax\n"
+ "mulq %%r12\n"
+ "addq %%rax, %%r9\n"
+ "adcq %%rdx, %%r10\n"
+ "adcq $0, %%r8\n"
+ /* (r9,r10,r8) += m4 * c1 */
+ "movq %13, %%rax\n"
+ "mulq %%r11\n"
+ "addq %%rax, %%r9\n"
+ "adcq %%rdx, %%r10\n"
+ "adcq $0, %%r8\n"
+ /* extract p1 */
+ "movq %%r9, %q1\n"
+ "movq $0, %%r9\n"
+ /* (r10,r8,r9) += m2 */
+ "addq %q7, %%r10\n"
+ "adcq $0, %%r8\n"
+ "adcq $0, %%r9\n"
+ /* (r10,r8,r9) += m6 * c0 */
+ "movq %12, %%rax\n"
+ "mulq %%r13\n"
+ "addq %%rax, %%r10\n"
+ "adcq %%rdx, %%r8\n"
+ "adcq $0, %%r9\n"
+ /* (r10,r8,r9) += m5 * c1 */
+ "movq %13, %%rax\n"
+ "mulq %%r12\n"
+ "addq %%rax, %%r10\n"
+ "adcq %%rdx, %%r8\n"
+ "adcq $0, %%r9\n"
+ /* (r10,r8,r9) += m4 */
+ "addq %%r11, %%r10\n"
+ "adcq $0, %%r8\n"
+ "adcq $0, %%r9\n"
+ /* extract p2 */
+ "movq %%r10, %q2\n"
+ /* (r8,r9) += m3 */
+ "addq %q8, %%r8\n"
+ "adcq $0, %%r9\n"
+ /* (r8,r9) += m6 * c1 */
+ "movq %13, %%rax\n"
+ "mulq %%r13\n"
+ "addq %%rax, %%r8\n"
+ "adcq %%rdx, %%r9\n"
+ /* (r8,r9) += m5 */
+ "addq %%r12, %%r8\n"
+ "adcq $0, %%r9\n"
+ /* extract p3 */
+ "movq %%r8, %q3\n"
+ /* (r9) += m6 */
+ "addq %%r13, %%r9\n"
+ /* extract p4 */
+ "movq %%r9, %q4\n"
+ : "=&g"(p0), "=&g"(p1), "=&g"(p2), "=g"(p3), "=g"(p4)
+ : "g"(m0), "g"(m1), "g"(m2), "g"(m3), "g"(m4), "g"(m5), "g"(m6), "n"(SECP256K1_N_C_0), "n"(SECP256K1_N_C_1)
+ : "rax", "rdx", "r8", "r9", "r10", "r11", "r12", "r13", "cc");
+
+ /* Reduce 258 bits into 256. */
+ __asm__ __volatile__(
+ /* Preload */
+ "movq %q5, %%r10\n"
+ /* (rax,rdx) = p4 * c0 */
+ "movq %7, %%rax\n"
+ "mulq %%r10\n"
+ /* (rax,rdx) += p0 */
+ "addq %q1, %%rax\n"
+ "adcq $0, %%rdx\n"
+ /* extract r0 */
+ "movq %%rax, 0(%q6)\n"
+ /* Move to (r8,r9) */
+ "movq %%rdx, %%r8\n"
+ "movq $0, %%r9\n"
+ /* (r8,r9) += p1 */
+ "addq %q2, %%r8\n"
+ "adcq $0, %%r9\n"
+ /* (r8,r9) += p4 * c1 */
+ "movq %8, %%rax\n"
+ "mulq %%r10\n"
+ "addq %%rax, %%r8\n"
+ "adcq %%rdx, %%r9\n"
+ /* Extract r1 */
+ "movq %%r8, 8(%q6)\n"
+ "movq $0, %%r8\n"
+ /* (r9,r8) += p4 */
+ "addq %%r10, %%r9\n"
+ "adcq $0, %%r8\n"
+ /* (r9,r8) += p2 */
+ "addq %q3, %%r9\n"
+ "adcq $0, %%r8\n"
+ /* Extract r2 */
+ "movq %%r9, 16(%q6)\n"
+ "movq $0, %%r9\n"
+ /* (r8,r9) += p3 */
+ "addq %q4, %%r8\n"
+ "adcq $0, %%r9\n"
+ /* Extract r3 */
+ "movq %%r8, 24(%q6)\n"
+ /* Extract c */
+ "movq %%r9, %q0\n"
+ : "=g"(c)
+ : "g"(p0), "g"(p1), "g"(p2), "g"(p3), "g"(p4), "D"(r), "n"(SECP256K1_N_C_0), "n"(SECP256K1_N_C_1)
+ : "rax", "rdx", "r8", "r9", "r10", "cc", "memory");
+#else
+ uint128_t c;
+ uint64_t c0, c1, c2;
+ uint64_t n0 = l[4], n1 = l[5], n2 = l[6], n3 = l[7];
+ uint64_t m0, m1, m2, m3, m4, m5;
+ uint32_t m6;
+ uint64_t p0, p1, p2, p3;
+ uint32_t p4;
+
+ /* Reduce 512 bits into 385. */
+ /* m[0..6] = l[0..3] + n[0..3] * SECP256K1_N_C. */
+ c0 = l[0]; c1 = 0; c2 = 0;
+ muladd_fast(n0, SECP256K1_N_C_0);
+ extract_fast(m0);
+ sumadd_fast(l[1]);
+ muladd(n1, SECP256K1_N_C_0);
+ muladd(n0, SECP256K1_N_C_1);
+ extract(m1);
+ sumadd(l[2]);
+ muladd(n2, SECP256K1_N_C_0);
+ muladd(n1, SECP256K1_N_C_1);
+ sumadd(n0);
+ extract(m2);
+ sumadd(l[3]);
+ muladd(n3, SECP256K1_N_C_0);
+ muladd(n2, SECP256K1_N_C_1);
+ sumadd(n1);
+ extract(m3);
+ muladd(n3, SECP256K1_N_C_1);
+ sumadd(n2);
+ extract(m4);
+ sumadd_fast(n3);
+ extract_fast(m5);
+ VERIFY_CHECK(c0 <= 1);
+ m6 = c0;
+
+ /* Reduce 385 bits into 258. */
+ /* p[0..4] = m[0..3] + m[4..6] * SECP256K1_N_C. */
+ c0 = m0; c1 = 0; c2 = 0;
+ muladd_fast(m4, SECP256K1_N_C_0);
+ extract_fast(p0);
+ sumadd_fast(m1);
+ muladd(m5, SECP256K1_N_C_0);
+ muladd(m4, SECP256K1_N_C_1);
+ extract(p1);
+ sumadd(m2);
+ muladd(m6, SECP256K1_N_C_0);
+ muladd(m5, SECP256K1_N_C_1);
+ sumadd(m4);
+ extract(p2);
+ sumadd_fast(m3);
+ muladd_fast(m6, SECP256K1_N_C_1);
+ sumadd_fast(m5);
+ extract_fast(p3);
+ p4 = c0 + m6;
+ VERIFY_CHECK(p4 <= 2);
+
+ /* Reduce 258 bits into 256. */
+ /* r[0..3] = p[0..3] + p[4] * SECP256K1_N_C. */
+ c = p0 + (uint128_t)SECP256K1_N_C_0 * p4;
+ r->d[0] = c & 0xFFFFFFFFFFFFFFFFULL; c >>= 64;
+ c += p1 + (uint128_t)SECP256K1_N_C_1 * p4;
+ r->d[1] = c & 0xFFFFFFFFFFFFFFFFULL; c >>= 64;
+ c += p2 + (uint128_t)p4;
+ r->d[2] = c & 0xFFFFFFFFFFFFFFFFULL; c >>= 64;
+ c += p3;
+ r->d[3] = c & 0xFFFFFFFFFFFFFFFFULL; c >>= 64;
+#endif
+
+ /* Final reduction of r. */
+ secp256k1_scalar_reduce(r, c + secp256k1_scalar_check_overflow(r));
+}
+
+static void secp256k1_scalar_mul_512(uint64_t l[8], const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) {
+#ifdef USE_ASM_X86_64
+ const uint64_t *pb = b->d;
+ __asm__ __volatile__(
+ /* Preload */
+ "movq 0(%%rdi), %%r15\n"
+ "movq 8(%%rdi), %%rbx\n"
+ "movq 16(%%rdi), %%rcx\n"
+ "movq 0(%%rdx), %%r11\n"
+ "movq 8(%%rdx), %%r12\n"
+ "movq 16(%%rdx), %%r13\n"
+ "movq 24(%%rdx), %%r14\n"
+ /* (rax,rdx) = a0 * b0 */
+ "movq %%r15, %%rax\n"
+ "mulq %%r11\n"
+ /* Extract l0 */
+ "movq %%rax, 0(%%rsi)\n"
+ /* (r8,r9,r10) = (rdx) */
+ "movq %%rdx, %%r8\n"
+ "xorq %%r9, %%r9\n"
+ "xorq %%r10, %%r10\n"
+ /* (r8,r9,r10) += a0 * b1 */
+ "movq %%r15, %%rax\n"
+ "mulq %%r12\n"
+ "addq %%rax, %%r8\n"
+ "adcq %%rdx, %%r9\n"
+ "adcq $0, %%r10\n"
+ /* (r8,r9,r10) += a1 * b0 */
+ "movq %%rbx, %%rax\n"
+ "mulq %%r11\n"
+ "addq %%rax, %%r8\n"
+ "adcq %%rdx, %%r9\n"
+ "adcq $0, %%r10\n"
+ /* Extract l1 */
+ "movq %%r8, 8(%%rsi)\n"
+ "xorq %%r8, %%r8\n"
+ /* (r9,r10,r8) += a0 * b2 */
+ "movq %%r15, %%rax\n"
+ "mulq %%r13\n"
+ "addq %%rax, %%r9\n"
+ "adcq %%rdx, %%r10\n"
+ "adcq $0, %%r8\n"
+ /* (r9,r10,r8) += a1 * b1 */
+ "movq %%rbx, %%rax\n"
+ "mulq %%r12\n"
+ "addq %%rax, %%r9\n"
+ "adcq %%rdx, %%r10\n"
+ "adcq $0, %%r8\n"
+ /* (r9,r10,r8) += a2 * b0 */
+ "movq %%rcx, %%rax\n"
+ "mulq %%r11\n"
+ "addq %%rax, %%r9\n"
+ "adcq %%rdx, %%r10\n"
+ "adcq $0, %%r8\n"
+ /* Extract l2 */
+ "movq %%r9, 16(%%rsi)\n"
+ "xorq %%r9, %%r9\n"
+ /* (r10,r8,r9) += a0 * b3 */
+ "movq %%r15, %%rax\n"
+ "mulq %%r14\n"
+ "addq %%rax, %%r10\n"
+ "adcq %%rdx, %%r8\n"
+ "adcq $0, %%r9\n"
+ /* Preload a3 */
+ "movq 24(%%rdi), %%r15\n"
+ /* (r10,r8,r9) += a1 * b2 */
+ "movq %%rbx, %%rax\n"
+ "mulq %%r13\n"
+ "addq %%rax, %%r10\n"
+ "adcq %%rdx, %%r8\n"
+ "adcq $0, %%r9\n"
+ /* (r10,r8,r9) += a2 * b1 */
+ "movq %%rcx, %%rax\n"
+ "mulq %%r12\n"
+ "addq %%rax, %%r10\n"
+ "adcq %%rdx, %%r8\n"
+ "adcq $0, %%r9\n"
+ /* (r10,r8,r9) += a3 * b0 */
+ "movq %%r15, %%rax\n"
+ "mulq %%r11\n"
+ "addq %%rax, %%r10\n"
+ "adcq %%rdx, %%r8\n"
+ "adcq $0, %%r9\n"
+ /* Extract l3 */
+ "movq %%r10, 24(%%rsi)\n"
+ "xorq %%r10, %%r10\n"
+ /* (r8,r9,r10) += a1 * b3 */
+ "movq %%rbx, %%rax\n"
+ "mulq %%r14\n"
+ "addq %%rax, %%r8\n"
+ "adcq %%rdx, %%r9\n"
+ "adcq $0, %%r10\n"
+ /* (r8,r9,r10) += a2 * b2 */
+ "movq %%rcx, %%rax\n"
+ "mulq %%r13\n"
+ "addq %%rax, %%r8\n"
+ "adcq %%rdx, %%r9\n"
+ "adcq $0, %%r10\n"
+ /* (r8,r9,r10) += a3 * b1 */
+ "movq %%r15, %%rax\n"
+ "mulq %%r12\n"
+ "addq %%rax, %%r8\n"
+ "adcq %%rdx, %%r9\n"
+ "adcq $0, %%r10\n"
+ /* Extract l4 */
+ "movq %%r8, 32(%%rsi)\n"
+ "xorq %%r8, %%r8\n"
+ /* (r9,r10,r8) += a2 * b3 */
+ "movq %%rcx, %%rax\n"
+ "mulq %%r14\n"
+ "addq %%rax, %%r9\n"
+ "adcq %%rdx, %%r10\n"
+ "adcq $0, %%r8\n"
+ /* (r9,r10,r8) += a3 * b2 */
+ "movq %%r15, %%rax\n"
+ "mulq %%r13\n"
+ "addq %%rax, %%r9\n"
+ "adcq %%rdx, %%r10\n"
+ "adcq $0, %%r8\n"
+ /* Extract l5 */
+ "movq %%r9, 40(%%rsi)\n"
+ /* (r10,r8) += a3 * b3 */
+ "movq %%r15, %%rax\n"
+ "mulq %%r14\n"
+ "addq %%rax, %%r10\n"
+ "adcq %%rdx, %%r8\n"
+ /* Extract l6 */
+ "movq %%r10, 48(%%rsi)\n"
+ /* Extract l7 */
+ "movq %%r8, 56(%%rsi)\n"
+ : "+d"(pb)
+ : "S"(l), "D"(a->d)
+ : "rax", "rbx", "rcx", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "cc", "memory");
+#else
+ /* 160 bit accumulator. */
+ uint64_t c0 = 0, c1 = 0;
+ uint32_t c2 = 0;
+
+ /* l[0..7] = a[0..3] * b[0..3]. */
+ muladd_fast(a->d[0], b->d[0]);
+ extract_fast(l[0]);
+ muladd(a->d[0], b->d[1]);
+ muladd(a->d[1], b->d[0]);
+ extract(l[1]);
+ muladd(a->d[0], b->d[2]);
+ muladd(a->d[1], b->d[1]);
+ muladd(a->d[2], b->d[0]);
+ extract(l[2]);
+ muladd(a->d[0], b->d[3]);
+ muladd(a->d[1], b->d[2]);
+ muladd(a->d[2], b->d[1]);
+ muladd(a->d[3], b->d[0]);
+ extract(l[3]);
+ muladd(a->d[1], b->d[3]);
+ muladd(a->d[2], b->d[2]);
+ muladd(a->d[3], b->d[1]);
+ extract(l[4]);
+ muladd(a->d[2], b->d[3]);
+ muladd(a->d[3], b->d[2]);
+ extract(l[5]);
+ muladd_fast(a->d[3], b->d[3]);
+ extract_fast(l[6]);
+ VERIFY_CHECK(c1 <= 0);
+ l[7] = c0;
+#endif
+}
+
+static void secp256k1_scalar_sqr_512(uint64_t l[8], const secp256k1_scalar_t *a) {
+#ifdef USE_ASM_X86_64
+ __asm__ __volatile__(
+ /* Preload */
+ "movq 0(%%rdi), %%r11\n"
+ "movq 8(%%rdi), %%r12\n"
+ "movq 16(%%rdi), %%r13\n"
+ "movq 24(%%rdi), %%r14\n"
+ /* (rax,rdx) = a0 * a0 */
+ "movq %%r11, %%rax\n"
+ "mulq %%r11\n"
+ /* Extract l0 */
+ "movq %%rax, 0(%%rsi)\n"
+ /* (r8,r9,r10) = (rdx,0) */
+ "movq %%rdx, %%r8\n"
+ "xorq %%r9, %%r9\n"
+ "xorq %%r10, %%r10\n"
+ /* (r8,r9,r10) += 2 * a0 * a1 */
+ "movq %%r11, %%rax\n"
+ "mulq %%r12\n"
+ "addq %%rax, %%r8\n"
+ "adcq %%rdx, %%r9\n"
+ "adcq $0, %%r10\n"
+ "addq %%rax, %%r8\n"
+ "adcq %%rdx, %%r9\n"
+ "adcq $0, %%r10\n"
+ /* Extract l1 */
+ "movq %%r8, 8(%%rsi)\n"
+ "xorq %%r8, %%r8\n"
+ /* (r9,r10,r8) += 2 * a0 * a2 */
+ "movq %%r11, %%rax\n"
+ "mulq %%r13\n"
+ "addq %%rax, %%r9\n"
+ "adcq %%rdx, %%r10\n"
+ "adcq $0, %%r8\n"
+ "addq %%rax, %%r9\n"
+ "adcq %%rdx, %%r10\n"
+ "adcq $0, %%r8\n"
+ /* (r9,r10,r8) += a1 * a1 */
+ "movq %%r12, %%rax\n"
+ "mulq %%r12\n"
+ "addq %%rax, %%r9\n"
+ "adcq %%rdx, %%r10\n"
+ "adcq $0, %%r8\n"
+ /* Extract l2 */
+ "movq %%r9, 16(%%rsi)\n"
+ "xorq %%r9, %%r9\n"
+ /* (r10,r8,r9) += 2 * a0 * a3 */
+ "movq %%r11, %%rax\n"
+ "mulq %%r14\n"
+ "addq %%rax, %%r10\n"
+ "adcq %%rdx, %%r8\n"
+ "adcq $0, %%r9\n"
+ "addq %%rax, %%r10\n"
+ "adcq %%rdx, %%r8\n"
+ "adcq $0, %%r9\n"
+ /* (r10,r8,r9) += 2 * a1 * a2 */
+ "movq %%r12, %%rax\n"
+ "mulq %%r13\n"
+ "addq %%rax, %%r10\n"
+ "adcq %%rdx, %%r8\n"
+ "adcq $0, %%r9\n"
+ "addq %%rax, %%r10\n"
+ "adcq %%rdx, %%r8\n"
+ "adcq $0, %%r9\n"
+ /* Extract l3 */
+ "movq %%r10, 24(%%rsi)\n"
+ "xorq %%r10, %%r10\n"
+ /* (r8,r9,r10) += 2 * a1 * a3 */
+ "movq %%r12, %%rax\n"
+ "mulq %%r14\n"
+ "addq %%rax, %%r8\n"
+ "adcq %%rdx, %%r9\n"
+ "adcq $0, %%r10\n"
+ "addq %%rax, %%r8\n"
+ "adcq %%rdx, %%r9\n"
+ "adcq $0, %%r10\n"
+ /* (r8,r9,r10) += a2 * a2 */
+ "movq %%r13, %%rax\n"
+ "mulq %%r13\n"
+ "addq %%rax, %%r8\n"
+ "adcq %%rdx, %%r9\n"
+ "adcq $0, %%r10\n"
+ /* Extract l4 */
+ "movq %%r8, 32(%%rsi)\n"
+ "xorq %%r8, %%r8\n"
+ /* (r9,r10,r8) += 2 * a2 * a3 */
+ "movq %%r13, %%rax\n"
+ "mulq %%r14\n"
+ "addq %%rax, %%r9\n"
+ "adcq %%rdx, %%r10\n"
+ "adcq $0, %%r8\n"
+ "addq %%rax, %%r9\n"
+ "adcq %%rdx, %%r10\n"
+ "adcq $0, %%r8\n"
+ /* Extract l5 */
+ "movq %%r9, 40(%%rsi)\n"
+ /* (r10,r8) += a3 * a3 */
+ "movq %%r14, %%rax\n"
+ "mulq %%r14\n"
+ "addq %%rax, %%r10\n"
+ "adcq %%rdx, %%r8\n"
+ /* Extract l6 */
+ "movq %%r10, 48(%%rsi)\n"
+ /* Extract l7 */
+ "movq %%r8, 56(%%rsi)\n"
+ :
+ : "S"(l), "D"(a->d)
+ : "rax", "rdx", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "cc", "memory");
+#else
+ /* 160 bit accumulator. */
+ uint64_t c0 = 0, c1 = 0;
+ uint32_t c2 = 0;
+
+ /* l[0..7] = a[0..3] * b[0..3]. */
+ muladd_fast(a->d[0], a->d[0]);
+ extract_fast(l[0]);
+ muladd2(a->d[0], a->d[1]);
+ extract(l[1]);
+ muladd2(a->d[0], a->d[2]);
+ muladd(a->d[1], a->d[1]);
+ extract(l[2]);
+ muladd2(a->d[0], a->d[3]);
+ muladd2(a->d[1], a->d[2]);
+ extract(l[3]);
+ muladd2(a->d[1], a->d[3]);
+ muladd(a->d[2], a->d[2]);
+ extract(l[4]);
+ muladd2(a->d[2], a->d[3]);
+ extract(l[5]);
+ muladd_fast(a->d[3], a->d[3]);
+ extract_fast(l[6]);
+ VERIFY_CHECK(c1 == 0);
+ l[7] = c0;
+#endif
+}
+
+#undef sumadd
+#undef sumadd_fast
+#undef muladd
+#undef muladd_fast
+#undef muladd2
+#undef extract
+#undef extract_fast
+
+static void secp256k1_scalar_mul(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) {
+ uint64_t l[8];
+ secp256k1_scalar_mul_512(l, a, b);
+ secp256k1_scalar_reduce_512(r, l);
+}
+
+static void secp256k1_scalar_sqr(secp256k1_scalar_t *r, const secp256k1_scalar_t *a) {
+ uint64_t l[8];
+ secp256k1_scalar_sqr_512(l, a);
+ secp256k1_scalar_reduce_512(r, l);
+}
+
+static void secp256k1_scalar_split_128(secp256k1_scalar_t *r1, secp256k1_scalar_t *r2, const secp256k1_scalar_t *a) {
+ r1->d[0] = a->d[0];
+ r1->d[1] = a->d[1];
+ r1->d[2] = 0;
+ r1->d[3] = 0;
+ r2->d[0] = a->d[2];
+ r2->d[1] = a->d[3];
+ r2->d[2] = 0;
+ r2->d[3] = 0;
+}
+
+SECP256K1_INLINE static int secp256k1_scalar_eq(const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) {
+ return ((a->d[0] ^ b->d[0]) | (a->d[1] ^ b->d[1]) | (a->d[2] ^ b->d[2]) | (a->d[3] ^ b->d[3])) == 0;
+}
+
+SECP256K1_INLINE static void secp256k1_scalar_mul_shift_var(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b, unsigned int shift) {
+ uint64_t l[8];
+ unsigned int shiftlimbs;
+ unsigned int shiftlow;
+ unsigned int shifthigh;
+ VERIFY_CHECK(shift >= 256);
+ secp256k1_scalar_mul_512(l, a, b);
+ shiftlimbs = shift >> 6;
+ shiftlow = shift & 0x3F;
+ shifthigh = 64 - shiftlow;
+ r->d[0] = shift < 512 ? (l[0 + shiftlimbs] >> shiftlow | (shift < 448 && shiftlow ? (l[1 + shiftlimbs] << shifthigh) : 0)) : 0;
+ r->d[1] = shift < 448 ? (l[1 + shiftlimbs] >> shiftlow | (shift < 384 && shiftlow ? (l[2 + shiftlimbs] << shifthigh) : 0)) : 0;
+ r->d[2] = shift < 384 ? (l[2 + shiftlimbs] >> shiftlow | (shift < 320 && shiftlow ? (l[3 + shiftlimbs] << shifthigh) : 0)) : 0;
+ r->d[3] = shift < 320 ? (l[3 + shiftlimbs] >> shiftlow) : 0;
+ if ((l[(shift - 1) >> 6] >> ((shift - 1) & 0x3f)) & 1) {
+ secp256k1_scalar_add_bit(r, 0);
+ }
+}
+
+#endif
diff --git a/src/secp256k1/src/scalar_8x32.h b/src/secp256k1/src/scalar_8x32.h
new file mode 100644
index 0000000000..f17017e24e
--- /dev/null
+++ b/src/secp256k1/src/scalar_8x32.h
@@ -0,0 +1,19 @@
+/**********************************************************************
+ * Copyright (c) 2014 Pieter Wuille *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
+ **********************************************************************/
+
+#ifndef _SECP256K1_SCALAR_REPR_
+#define _SECP256K1_SCALAR_REPR_
+
+#include <stdint.h>
+
+/** A scalar modulo the group order of the secp256k1 curve. */
+typedef struct {
+ uint32_t d[8];
+} secp256k1_scalar_t;
+
+#define SECP256K1_SCALAR_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{(d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7)}}
+
+#endif
diff --git a/src/secp256k1/src/scalar_8x32_impl.h b/src/secp256k1/src/scalar_8x32_impl.h
new file mode 100644
index 0000000000..22b31d4112
--- /dev/null
+++ b/src/secp256k1/src/scalar_8x32_impl.h
@@ -0,0 +1,681 @@
+/**********************************************************************
+ * Copyright (c) 2014 Pieter Wuille *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
+ **********************************************************************/
+
+#ifndef _SECP256K1_SCALAR_REPR_IMPL_H_
+#define _SECP256K1_SCALAR_REPR_IMPL_H_
+
+/* Limbs of the secp256k1 order. */
+#define SECP256K1_N_0 ((uint32_t)0xD0364141UL)
+#define SECP256K1_N_1 ((uint32_t)0xBFD25E8CUL)
+#define SECP256K1_N_2 ((uint32_t)0xAF48A03BUL)
+#define SECP256K1_N_3 ((uint32_t)0xBAAEDCE6UL)
+#define SECP256K1_N_4 ((uint32_t)0xFFFFFFFEUL)
+#define SECP256K1_N_5 ((uint32_t)0xFFFFFFFFUL)
+#define SECP256K1_N_6 ((uint32_t)0xFFFFFFFFUL)
+#define SECP256K1_N_7 ((uint32_t)0xFFFFFFFFUL)
+
+/* Limbs of 2^256 minus the secp256k1 order. */
+#define SECP256K1_N_C_0 (~SECP256K1_N_0 + 1)
+#define SECP256K1_N_C_1 (~SECP256K1_N_1)
+#define SECP256K1_N_C_2 (~SECP256K1_N_2)
+#define SECP256K1_N_C_3 (~SECP256K1_N_3)
+#define SECP256K1_N_C_4 (1)
+
+/* Limbs of half the secp256k1 order. */
+#define SECP256K1_N_H_0 ((uint32_t)0x681B20A0UL)
+#define SECP256K1_N_H_1 ((uint32_t)0xDFE92F46UL)
+#define SECP256K1_N_H_2 ((uint32_t)0x57A4501DUL)
+#define SECP256K1_N_H_3 ((uint32_t)0x5D576E73UL)
+#define SECP256K1_N_H_4 ((uint32_t)0xFFFFFFFFUL)
+#define SECP256K1_N_H_5 ((uint32_t)0xFFFFFFFFUL)
+#define SECP256K1_N_H_6 ((uint32_t)0xFFFFFFFFUL)
+#define SECP256K1_N_H_7 ((uint32_t)0x7FFFFFFFUL)
+
+SECP256K1_INLINE static void secp256k1_scalar_clear(secp256k1_scalar_t *r) {
+ r->d[0] = 0;
+ r->d[1] = 0;
+ r->d[2] = 0;
+ r->d[3] = 0;
+ r->d[4] = 0;
+ r->d[5] = 0;
+ r->d[6] = 0;
+ r->d[7] = 0;
+}
+
+SECP256K1_INLINE static void secp256k1_scalar_set_int(secp256k1_scalar_t *r, unsigned int v) {
+ r->d[0] = v;
+ r->d[1] = 0;
+ r->d[2] = 0;
+ r->d[3] = 0;
+ r->d[4] = 0;
+ r->d[5] = 0;
+ r->d[6] = 0;
+ r->d[7] = 0;
+}
+
+SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar_t *a, unsigned int offset, unsigned int count) {
+ VERIFY_CHECK((offset + count - 1) >> 5 == offset >> 5);
+ return (a->d[offset >> 5] >> (offset & 0x1F)) & ((1 << count) - 1);
+}
+
+SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar_t *a, unsigned int offset, unsigned int count) {
+ VERIFY_CHECK(count < 32);
+ VERIFY_CHECK(offset + count <= 256);
+ if ((offset + count - 1) >> 5 == offset >> 5) {
+ return secp256k1_scalar_get_bits(a, offset, count);
+ } else {
+ VERIFY_CHECK((offset >> 5) + 1 < 8);
+ return ((a->d[offset >> 5] >> (offset & 0x1F)) | (a->d[(offset >> 5) + 1] << (32 - (offset & 0x1F)))) & ((((uint32_t)1) << count) - 1);
+ }
+}
+
+SECP256K1_INLINE static int secp256k1_scalar_check_overflow(const secp256k1_scalar_t *a) {
+ int yes = 0;
+ int no = 0;
+ no |= (a->d[7] < SECP256K1_N_7); /* No need for a > check. */
+ no |= (a->d[6] < SECP256K1_N_6); /* No need for a > check. */
+ no |= (a->d[5] < SECP256K1_N_5); /* No need for a > check. */
+ no |= (a->d[4] < SECP256K1_N_4);
+ yes |= (a->d[4] > SECP256K1_N_4) & ~no;
+ no |= (a->d[3] < SECP256K1_N_3) & ~yes;
+ yes |= (a->d[3] > SECP256K1_N_3) & ~no;
+ no |= (a->d[2] < SECP256K1_N_2) & ~yes;
+ yes |= (a->d[2] > SECP256K1_N_2) & ~no;
+ no |= (a->d[1] < SECP256K1_N_1) & ~yes;
+ yes |= (a->d[1] > SECP256K1_N_1) & ~no;
+ yes |= (a->d[0] >= SECP256K1_N_0) & ~no;
+ return yes;
+}
+
+SECP256K1_INLINE static int secp256k1_scalar_reduce(secp256k1_scalar_t *r, uint32_t overflow) {
+ uint64_t t;
+ VERIFY_CHECK(overflow <= 1);
+ t = (uint64_t)r->d[0] + overflow * SECP256K1_N_C_0;
+ r->d[0] = t & 0xFFFFFFFFUL; t >>= 32;
+ t += (uint64_t)r->d[1] + overflow * SECP256K1_N_C_1;
+ r->d[1] = t & 0xFFFFFFFFUL; t >>= 32;
+ t += (uint64_t)r->d[2] + overflow * SECP256K1_N_C_2;
+ r->d[2] = t & 0xFFFFFFFFUL; t >>= 32;
+ t += (uint64_t)r->d[3] + overflow * SECP256K1_N_C_3;
+ r->d[3] = t & 0xFFFFFFFFUL; t >>= 32;
+ t += (uint64_t)r->d[4] + overflow * SECP256K1_N_C_4;
+ r->d[4] = t & 0xFFFFFFFFUL; t >>= 32;
+ t += (uint64_t)r->d[5];
+ r->d[5] = t & 0xFFFFFFFFUL; t >>= 32;
+ t += (uint64_t)r->d[6];
+ r->d[6] = t & 0xFFFFFFFFUL; t >>= 32;
+ t += (uint64_t)r->d[7];
+ r->d[7] = t & 0xFFFFFFFFUL;
+ return overflow;
+}
+
+static int secp256k1_scalar_add(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) {
+ int overflow;
+ uint64_t t = (uint64_t)a->d[0] + b->d[0];
+ r->d[0] = t & 0xFFFFFFFFULL; t >>= 32;
+ t += (uint64_t)a->d[1] + b->d[1];
+ r->d[1] = t & 0xFFFFFFFFULL; t >>= 32;
+ t += (uint64_t)a->d[2] + b->d[2];
+ r->d[2] = t & 0xFFFFFFFFULL; t >>= 32;
+ t += (uint64_t)a->d[3] + b->d[3];
+ r->d[3] = t & 0xFFFFFFFFULL; t >>= 32;
+ t += (uint64_t)a->d[4] + b->d[4];
+ r->d[4] = t & 0xFFFFFFFFULL; t >>= 32;
+ t += (uint64_t)a->d[5] + b->d[5];
+ r->d[5] = t & 0xFFFFFFFFULL; t >>= 32;
+ t += (uint64_t)a->d[6] + b->d[6];
+ r->d[6] = t & 0xFFFFFFFFULL; t >>= 32;
+ t += (uint64_t)a->d[7] + b->d[7];
+ r->d[7] = t & 0xFFFFFFFFULL; t >>= 32;
+ overflow = t + secp256k1_scalar_check_overflow(r);
+ VERIFY_CHECK(overflow == 0 || overflow == 1);
+ secp256k1_scalar_reduce(r, overflow);
+ return overflow;
+}
+
+static void secp256k1_scalar_add_bit(secp256k1_scalar_t *r, unsigned int bit) {
+ uint64_t t;
+ VERIFY_CHECK(bit < 256);
+ t = (uint64_t)r->d[0] + (((uint32_t)((bit >> 5) == 0)) << (bit & 0x1F));
+ r->d[0] = t & 0xFFFFFFFFULL; t >>= 32;
+ t += (uint64_t)r->d[1] + (((uint32_t)((bit >> 5) == 1)) << (bit & 0x1F));
+ r->d[1] = t & 0xFFFFFFFFULL; t >>= 32;
+ t += (uint64_t)r->d[2] + (((uint32_t)((bit >> 5) == 2)) << (bit & 0x1F));
+ r->d[2] = t & 0xFFFFFFFFULL; t >>= 32;
+ t += (uint64_t)r->d[3] + (((uint32_t)((bit >> 5) == 3)) << (bit & 0x1F));
+ r->d[3] = t & 0xFFFFFFFFULL; t >>= 32;
+ t += (uint64_t)r->d[4] + (((uint32_t)((bit >> 5) == 4)) << (bit & 0x1F));
+ r->d[4] = t & 0xFFFFFFFFULL; t >>= 32;
+ t += (uint64_t)r->d[5] + (((uint32_t)((bit >> 5) == 5)) << (bit & 0x1F));
+ r->d[5] = t & 0xFFFFFFFFULL; t >>= 32;
+ t += (uint64_t)r->d[6] + (((uint32_t)((bit >> 5) == 6)) << (bit & 0x1F));
+ r->d[6] = t & 0xFFFFFFFFULL; t >>= 32;
+ t += (uint64_t)r->d[7] + (((uint32_t)((bit >> 5) == 7)) << (bit & 0x1F));
+ r->d[7] = t & 0xFFFFFFFFULL;
+#ifdef VERIFY
+ VERIFY_CHECK((t >> 32) == 0);
+ VERIFY_CHECK(secp256k1_scalar_check_overflow(r) == 0);
+#endif
+}
+
+static void secp256k1_scalar_set_b32(secp256k1_scalar_t *r, const unsigned char *b32, int *overflow) {
+ int over;
+ r->d[0] = (uint32_t)b32[31] | (uint32_t)b32[30] << 8 | (uint32_t)b32[29] << 16 | (uint32_t)b32[28] << 24;
+ r->d[1] = (uint32_t)b32[27] | (uint32_t)b32[26] << 8 | (uint32_t)b32[25] << 16 | (uint32_t)b32[24] << 24;
+ r->d[2] = (uint32_t)b32[23] | (uint32_t)b32[22] << 8 | (uint32_t)b32[21] << 16 | (uint32_t)b32[20] << 24;
+ r->d[3] = (uint32_t)b32[19] | (uint32_t)b32[18] << 8 | (uint32_t)b32[17] << 16 | (uint32_t)b32[16] << 24;
+ r->d[4] = (uint32_t)b32[15] | (uint32_t)b32[14] << 8 | (uint32_t)b32[13] << 16 | (uint32_t)b32[12] << 24;
+ r->d[5] = (uint32_t)b32[11] | (uint32_t)b32[10] << 8 | (uint32_t)b32[9] << 16 | (uint32_t)b32[8] << 24;
+ r->d[6] = (uint32_t)b32[7] | (uint32_t)b32[6] << 8 | (uint32_t)b32[5] << 16 | (uint32_t)b32[4] << 24;
+ r->d[7] = (uint32_t)b32[3] | (uint32_t)b32[2] << 8 | (uint32_t)b32[1] << 16 | (uint32_t)b32[0] << 24;
+ over = secp256k1_scalar_reduce(r, secp256k1_scalar_check_overflow(r));
+ if (overflow) {
+ *overflow = over;
+ }
+}
+
+static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar_t* a) {
+ bin[0] = a->d[7] >> 24; bin[1] = a->d[7] >> 16; bin[2] = a->d[7] >> 8; bin[3] = a->d[7];
+ bin[4] = a->d[6] >> 24; bin[5] = a->d[6] >> 16; bin[6] = a->d[6] >> 8; bin[7] = a->d[6];
+ bin[8] = a->d[5] >> 24; bin[9] = a->d[5] >> 16; bin[10] = a->d[5] >> 8; bin[11] = a->d[5];
+ bin[12] = a->d[4] >> 24; bin[13] = a->d[4] >> 16; bin[14] = a->d[4] >> 8; bin[15] = a->d[4];
+ bin[16] = a->d[3] >> 24; bin[17] = a->d[3] >> 16; bin[18] = a->d[3] >> 8; bin[19] = a->d[3];
+ bin[20] = a->d[2] >> 24; bin[21] = a->d[2] >> 16; bin[22] = a->d[2] >> 8; bin[23] = a->d[2];
+ bin[24] = a->d[1] >> 24; bin[25] = a->d[1] >> 16; bin[26] = a->d[1] >> 8; bin[27] = a->d[1];
+ bin[28] = a->d[0] >> 24; bin[29] = a->d[0] >> 16; bin[30] = a->d[0] >> 8; bin[31] = a->d[0];
+}
+
+SECP256K1_INLINE static int secp256k1_scalar_is_zero(const secp256k1_scalar_t *a) {
+ return (a->d[0] | a->d[1] | a->d[2] | a->d[3] | a->d[4] | a->d[5] | a->d[6] | a->d[7]) == 0;
+}
+
+static void secp256k1_scalar_negate(secp256k1_scalar_t *r, const secp256k1_scalar_t *a) {
+ uint32_t nonzero = 0xFFFFFFFFUL * (secp256k1_scalar_is_zero(a) == 0);
+ uint64_t t = (uint64_t)(~a->d[0]) + SECP256K1_N_0 + 1;
+ r->d[0] = t & nonzero; t >>= 32;
+ t += (uint64_t)(~a->d[1]) + SECP256K1_N_1;
+ r->d[1] = t & nonzero; t >>= 32;
+ t += (uint64_t)(~a->d[2]) + SECP256K1_N_2;
+ r->d[2] = t & nonzero; t >>= 32;
+ t += (uint64_t)(~a->d[3]) + SECP256K1_N_3;
+ r->d[3] = t & nonzero; t >>= 32;
+ t += (uint64_t)(~a->d[4]) + SECP256K1_N_4;
+ r->d[4] = t & nonzero; t >>= 32;
+ t += (uint64_t)(~a->d[5]) + SECP256K1_N_5;
+ r->d[5] = t & nonzero; t >>= 32;
+ t += (uint64_t)(~a->d[6]) + SECP256K1_N_6;
+ r->d[6] = t & nonzero; t >>= 32;
+ t += (uint64_t)(~a->d[7]) + SECP256K1_N_7;
+ r->d[7] = t & nonzero;
+}
+
+SECP256K1_INLINE static int secp256k1_scalar_is_one(const secp256k1_scalar_t *a) {
+ return ((a->d[0] ^ 1) | a->d[1] | a->d[2] | a->d[3] | a->d[4] | a->d[5] | a->d[6] | a->d[7]) == 0;
+}
+
+static int secp256k1_scalar_is_high(const secp256k1_scalar_t *a) {
+ int yes = 0;
+ int no = 0;
+ no |= (a->d[7] < SECP256K1_N_H_7);
+ yes |= (a->d[7] > SECP256K1_N_H_7) & ~no;
+ no |= (a->d[6] < SECP256K1_N_H_6) & ~yes; /* No need for a > check. */
+ no |= (a->d[5] < SECP256K1_N_H_5) & ~yes; /* No need for a > check. */
+ no |= (a->d[4] < SECP256K1_N_H_4) & ~yes; /* No need for a > check. */
+ no |= (a->d[3] < SECP256K1_N_H_3) & ~yes;
+ yes |= (a->d[3] > SECP256K1_N_H_3) & ~no;
+ no |= (a->d[2] < SECP256K1_N_H_2) & ~yes;
+ yes |= (a->d[2] > SECP256K1_N_H_2) & ~no;
+ no |= (a->d[1] < SECP256K1_N_H_1) & ~yes;
+ yes |= (a->d[1] > SECP256K1_N_H_1) & ~no;
+ yes |= (a->d[0] > SECP256K1_N_H_0) & ~no;
+ return yes;
+}
+
+/* Inspired by the macros in OpenSSL's crypto/bn/asm/x86_64-gcc.c. */
+
+/** Add a*b to the number defined by (c0,c1,c2). c2 must never overflow. */
+#define muladd(a,b) { \
+ uint32_t tl, th; \
+ { \
+ uint64_t t = (uint64_t)a * b; \
+ th = t >> 32; /* at most 0xFFFFFFFE */ \
+ tl = t; \
+ } \
+ c0 += tl; /* overflow is handled on the next line */ \
+ th += (c0 < tl) ? 1 : 0; /* at most 0xFFFFFFFF */ \
+ c1 += th; /* overflow is handled on the next line */ \
+ c2 += (c1 < th) ? 1 : 0; /* never overflows by contract (verified in the next line) */ \
+ VERIFY_CHECK((c1 >= th) || (c2 != 0)); \
+}
+
+/** Add a*b to the number defined by (c0,c1). c1 must never overflow. */
+#define muladd_fast(a,b) { \
+ uint32_t tl, th; \
+ { \
+ uint64_t t = (uint64_t)a * b; \
+ th = t >> 32; /* at most 0xFFFFFFFE */ \
+ tl = t; \
+ } \
+ c0 += tl; /* overflow is handled on the next line */ \
+ th += (c0 < tl) ? 1 : 0; /* at most 0xFFFFFFFF */ \
+ c1 += th; /* never overflows by contract (verified in the next line) */ \
+ VERIFY_CHECK(c1 >= th); \
+}
+
+/** Add 2*a*b to the number defined by (c0,c1,c2). c2 must never overflow. */
+#define muladd2(a,b) { \
+ uint32_t tl, th, th2, tl2; \
+ { \
+ uint64_t t = (uint64_t)a * b; \
+ th = t >> 32; /* at most 0xFFFFFFFE */ \
+ tl = t; \
+ } \
+ th2 = th + th; /* at most 0xFFFFFFFE (in case th was 0x7FFFFFFF) */ \
+ c2 += (th2 < th) ? 1 : 0; /* never overflows by contract (verified the next line) */ \
+ VERIFY_CHECK((th2 >= th) || (c2 != 0)); \
+ tl2 = tl + tl; /* at most 0xFFFFFFFE (in case the lowest 63 bits of tl were 0x7FFFFFFF) */ \
+ th2 += (tl2 < tl) ? 1 : 0; /* at most 0xFFFFFFFF */ \
+ c0 += tl2; /* overflow is handled on the next line */ \
+ th2 += (c0 < tl2) ? 1 : 0; /* second overflow is handled on the next line */ \
+ c2 += (c0 < tl2) & (th2 == 0); /* never overflows by contract (verified the next line) */ \
+ VERIFY_CHECK((c0 >= tl2) || (th2 != 0) || (c2 != 0)); \
+ c1 += th2; /* overflow is handled on the next line */ \
+ c2 += (c1 < th2) ? 1 : 0; /* never overflows by contract (verified the next line) */ \
+ VERIFY_CHECK((c1 >= th2) || (c2 != 0)); \
+}
+
+/** Add a to the number defined by (c0,c1,c2). c2 must never overflow. */
+#define sumadd(a) { \
+ unsigned int over; \
+ c0 += (a); /* overflow is handled on the next line */ \
+ over = (c0 < (a)) ? 1 : 0; \
+ c1 += over; /* overflow is handled on the next line */ \
+ c2 += (c1 < over) ? 1 : 0; /* never overflows by contract */ \
+}
+
+/** Add a to the number defined by (c0,c1). c1 must never overflow, c2 must be zero. */
+#define sumadd_fast(a) { \
+ c0 += (a); /* overflow is handled on the next line */ \
+ c1 += (c0 < (a)) ? 1 : 0; /* never overflows by contract (verified the next line) */ \
+ VERIFY_CHECK((c1 != 0) | (c0 >= (a))); \
+ VERIFY_CHECK(c2 == 0); \
+}
+
+/** Extract the lowest 32 bits of (c0,c1,c2) into n, and left shift the number 32 bits. */
+#define extract(n) { \
+ (n) = c0; \
+ c0 = c1; \
+ c1 = c2; \
+ c2 = 0; \
+}
+
+/** Extract the lowest 32 bits of (c0,c1,c2) into n, and left shift the number 32 bits. c2 is required to be zero. */
+#define extract_fast(n) { \
+ (n) = c0; \
+ c0 = c1; \
+ c1 = 0; \
+ VERIFY_CHECK(c2 == 0); \
+}
+
+static void secp256k1_scalar_reduce_512(secp256k1_scalar_t *r, const uint32_t *l) {
+ uint64_t c;
+ uint32_t n0 = l[8], n1 = l[9], n2 = l[10], n3 = l[11], n4 = l[12], n5 = l[13], n6 = l[14], n7 = l[15];
+ uint32_t m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12;
+ uint32_t p0, p1, p2, p3, p4, p5, p6, p7, p8;
+
+ /* 96 bit accumulator. */
+ uint32_t c0, c1, c2;
+
+ /* Reduce 512 bits into 385. */
+ /* m[0..12] = l[0..7] + n[0..7] * SECP256K1_N_C. */
+ c0 = l[0]; c1 = 0; c2 = 0;
+ muladd_fast(n0, SECP256K1_N_C_0);
+ extract_fast(m0);
+ sumadd_fast(l[1]);
+ muladd(n1, SECP256K1_N_C_0);
+ muladd(n0, SECP256K1_N_C_1);
+ extract(m1);
+ sumadd(l[2]);
+ muladd(n2, SECP256K1_N_C_0);
+ muladd(n1, SECP256K1_N_C_1);
+ muladd(n0, SECP256K1_N_C_2);
+ extract(m2);
+ sumadd(l[3]);
+ muladd(n3, SECP256K1_N_C_0);
+ muladd(n2, SECP256K1_N_C_1);
+ muladd(n1, SECP256K1_N_C_2);
+ muladd(n0, SECP256K1_N_C_3);
+ extract(m3);
+ sumadd(l[4]);
+ muladd(n4, SECP256K1_N_C_0);
+ muladd(n3, SECP256K1_N_C_1);
+ muladd(n2, SECP256K1_N_C_2);
+ muladd(n1, SECP256K1_N_C_3);
+ sumadd(n0);
+ extract(m4);
+ sumadd(l[5]);
+ muladd(n5, SECP256K1_N_C_0);
+ muladd(n4, SECP256K1_N_C_1);
+ muladd(n3, SECP256K1_N_C_2);
+ muladd(n2, SECP256K1_N_C_3);
+ sumadd(n1);
+ extract(m5);
+ sumadd(l[6]);
+ muladd(n6, SECP256K1_N_C_0);
+ muladd(n5, SECP256K1_N_C_1);
+ muladd(n4, SECP256K1_N_C_2);
+ muladd(n3, SECP256K1_N_C_3);
+ sumadd(n2);
+ extract(m6);
+ sumadd(l[7]);
+ muladd(n7, SECP256K1_N_C_0);
+ muladd(n6, SECP256K1_N_C_1);
+ muladd(n5, SECP256K1_N_C_2);
+ muladd(n4, SECP256K1_N_C_3);
+ sumadd(n3);
+ extract(m7);
+ muladd(n7, SECP256K1_N_C_1);
+ muladd(n6, SECP256K1_N_C_2);
+ muladd(n5, SECP256K1_N_C_3);
+ sumadd(n4);
+ extract(m8);
+ muladd(n7, SECP256K1_N_C_2);
+ muladd(n6, SECP256K1_N_C_3);
+ sumadd(n5);
+ extract(m9);
+ muladd(n7, SECP256K1_N_C_3);
+ sumadd(n6);
+ extract(m10);
+ sumadd_fast(n7);
+ extract_fast(m11);
+ VERIFY_CHECK(c0 <= 1);
+ m12 = c0;
+
+ /* Reduce 385 bits into 258. */
+ /* p[0..8] = m[0..7] + m[8..12] * SECP256K1_N_C. */
+ c0 = m0; c1 = 0; c2 = 0;
+ muladd_fast(m8, SECP256K1_N_C_0);
+ extract_fast(p0);
+ sumadd_fast(m1);
+ muladd(m9, SECP256K1_N_C_0);
+ muladd(m8, SECP256K1_N_C_1);
+ extract(p1);
+ sumadd(m2);
+ muladd(m10, SECP256K1_N_C_0);
+ muladd(m9, SECP256K1_N_C_1);
+ muladd(m8, SECP256K1_N_C_2);
+ extract(p2);
+ sumadd(m3);
+ muladd(m11, SECP256K1_N_C_0);
+ muladd(m10, SECP256K1_N_C_1);
+ muladd(m9, SECP256K1_N_C_2);
+ muladd(m8, SECP256K1_N_C_3);
+ extract(p3);
+ sumadd(m4);
+ muladd(m12, SECP256K1_N_C_0);
+ muladd(m11, SECP256K1_N_C_1);
+ muladd(m10, SECP256K1_N_C_2);
+ muladd(m9, SECP256K1_N_C_3);
+ sumadd(m8);
+ extract(p4);
+ sumadd(m5);
+ muladd(m12, SECP256K1_N_C_1);
+ muladd(m11, SECP256K1_N_C_2);
+ muladd(m10, SECP256K1_N_C_3);
+ sumadd(m9);
+ extract(p5);
+ sumadd(m6);
+ muladd(m12, SECP256K1_N_C_2);
+ muladd(m11, SECP256K1_N_C_3);
+ sumadd(m10);
+ extract(p6);
+ sumadd_fast(m7);
+ muladd_fast(m12, SECP256K1_N_C_3);
+ sumadd_fast(m11);
+ extract_fast(p7);
+ p8 = c0 + m12;
+ VERIFY_CHECK(p8 <= 2);
+
+ /* Reduce 258 bits into 256. */
+ /* r[0..7] = p[0..7] + p[8] * SECP256K1_N_C. */
+ c = p0 + (uint64_t)SECP256K1_N_C_0 * p8;
+ r->d[0] = c & 0xFFFFFFFFUL; c >>= 32;
+ c += p1 + (uint64_t)SECP256K1_N_C_1 * p8;
+ r->d[1] = c & 0xFFFFFFFFUL; c >>= 32;
+ c += p2 + (uint64_t)SECP256K1_N_C_2 * p8;
+ r->d[2] = c & 0xFFFFFFFFUL; c >>= 32;
+ c += p3 + (uint64_t)SECP256K1_N_C_3 * p8;
+ r->d[3] = c & 0xFFFFFFFFUL; c >>= 32;
+ c += p4 + (uint64_t)p8;
+ r->d[4] = c & 0xFFFFFFFFUL; c >>= 32;
+ c += p5;
+ r->d[5] = c & 0xFFFFFFFFUL; c >>= 32;
+ c += p6;
+ r->d[6] = c & 0xFFFFFFFFUL; c >>= 32;
+ c += p7;
+ r->d[7] = c & 0xFFFFFFFFUL; c >>= 32;
+
+ /* Final reduction of r. */
+ secp256k1_scalar_reduce(r, c + secp256k1_scalar_check_overflow(r));
+}
+
+static void secp256k1_scalar_mul_512(uint32_t *l, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) {
+ /* 96 bit accumulator. */
+ uint32_t c0 = 0, c1 = 0, c2 = 0;
+
+ /* l[0..15] = a[0..7] * b[0..7]. */
+ muladd_fast(a->d[0], b->d[0]);
+ extract_fast(l[0]);
+ muladd(a->d[0], b->d[1]);
+ muladd(a->d[1], b->d[0]);
+ extract(l[1]);
+ muladd(a->d[0], b->d[2]);
+ muladd(a->d[1], b->d[1]);
+ muladd(a->d[2], b->d[0]);
+ extract(l[2]);
+ muladd(a->d[0], b->d[3]);
+ muladd(a->d[1], b->d[2]);
+ muladd(a->d[2], b->d[1]);
+ muladd(a->d[3], b->d[0]);
+ extract(l[3]);
+ muladd(a->d[0], b->d[4]);
+ muladd(a->d[1], b->d[3]);
+ muladd(a->d[2], b->d[2]);
+ muladd(a->d[3], b->d[1]);
+ muladd(a->d[4], b->d[0]);
+ extract(l[4]);
+ muladd(a->d[0], b->d[5]);
+ muladd(a->d[1], b->d[4]);
+ muladd(a->d[2], b->d[3]);
+ muladd(a->d[3], b->d[2]);
+ muladd(a->d[4], b->d[1]);
+ muladd(a->d[5], b->d[0]);
+ extract(l[5]);
+ muladd(a->d[0], b->d[6]);
+ muladd(a->d[1], b->d[5]);
+ muladd(a->d[2], b->d[4]);
+ muladd(a->d[3], b->d[3]);
+ muladd(a->d[4], b->d[2]);
+ muladd(a->d[5], b->d[1]);
+ muladd(a->d[6], b->d[0]);
+ extract(l[6]);
+ muladd(a->d[0], b->d[7]);
+ muladd(a->d[1], b->d[6]);
+ muladd(a->d[2], b->d[5]);
+ muladd(a->d[3], b->d[4]);
+ muladd(a->d[4], b->d[3]);
+ muladd(a->d[5], b->d[2]);
+ muladd(a->d[6], b->d[1]);
+ muladd(a->d[7], b->d[0]);
+ extract(l[7]);
+ muladd(a->d[1], b->d[7]);
+ muladd(a->d[2], b->d[6]);
+ muladd(a->d[3], b->d[5]);
+ muladd(a->d[4], b->d[4]);
+ muladd(a->d[5], b->d[3]);
+ muladd(a->d[6], b->d[2]);
+ muladd(a->d[7], b->d[1]);
+ extract(l[8]);
+ muladd(a->d[2], b->d[7]);
+ muladd(a->d[3], b->d[6]);
+ muladd(a->d[4], b->d[5]);
+ muladd(a->d[5], b->d[4]);
+ muladd(a->d[6], b->d[3]);
+ muladd(a->d[7], b->d[2]);
+ extract(l[9]);
+ muladd(a->d[3], b->d[7]);
+ muladd(a->d[4], b->d[6]);
+ muladd(a->d[5], b->d[5]);
+ muladd(a->d[6], b->d[4]);
+ muladd(a->d[7], b->d[3]);
+ extract(l[10]);
+ muladd(a->d[4], b->d[7]);
+ muladd(a->d[5], b->d[6]);
+ muladd(a->d[6], b->d[5]);
+ muladd(a->d[7], b->d[4]);
+ extract(l[11]);
+ muladd(a->d[5], b->d[7]);
+ muladd(a->d[6], b->d[6]);
+ muladd(a->d[7], b->d[5]);
+ extract(l[12]);
+ muladd(a->d[6], b->d[7]);
+ muladd(a->d[7], b->d[6]);
+ extract(l[13]);
+ muladd_fast(a->d[7], b->d[7]);
+ extract_fast(l[14]);
+ VERIFY_CHECK(c1 == 0);
+ l[15] = c0;
+}
+
+static void secp256k1_scalar_sqr_512(uint32_t *l, const secp256k1_scalar_t *a) {
+ /* 96 bit accumulator. */
+ uint32_t c0 = 0, c1 = 0, c2 = 0;
+
+ /* l[0..15] = a[0..7]^2. */
+ muladd_fast(a->d[0], a->d[0]);
+ extract_fast(l[0]);
+ muladd2(a->d[0], a->d[1]);
+ extract(l[1]);
+ muladd2(a->d[0], a->d[2]);
+ muladd(a->d[1], a->d[1]);
+ extract(l[2]);
+ muladd2(a->d[0], a->d[3]);
+ muladd2(a->d[1], a->d[2]);
+ extract(l[3]);
+ muladd2(a->d[0], a->d[4]);
+ muladd2(a->d[1], a->d[3]);
+ muladd(a->d[2], a->d[2]);
+ extract(l[4]);
+ muladd2(a->d[0], a->d[5]);
+ muladd2(a->d[1], a->d[4]);
+ muladd2(a->d[2], a->d[3]);
+ extract(l[5]);
+ muladd2(a->d[0], a->d[6]);
+ muladd2(a->d[1], a->d[5]);
+ muladd2(a->d[2], a->d[4]);
+ muladd(a->d[3], a->d[3]);
+ extract(l[6]);
+ muladd2(a->d[0], a->d[7]);
+ muladd2(a->d[1], a->d[6]);
+ muladd2(a->d[2], a->d[5]);
+ muladd2(a->d[3], a->d[4]);
+ extract(l[7]);
+ muladd2(a->d[1], a->d[7]);
+ muladd2(a->d[2], a->d[6]);
+ muladd2(a->d[3], a->d[5]);
+ muladd(a->d[4], a->d[4]);
+ extract(l[8]);
+ muladd2(a->d[2], a->d[7]);
+ muladd2(a->d[3], a->d[6]);
+ muladd2(a->d[4], a->d[5]);
+ extract(l[9]);
+ muladd2(a->d[3], a->d[7]);
+ muladd2(a->d[4], a->d[6]);
+ muladd(a->d[5], a->d[5]);
+ extract(l[10]);
+ muladd2(a->d[4], a->d[7]);
+ muladd2(a->d[5], a->d[6]);
+ extract(l[11]);
+ muladd2(a->d[5], a->d[7]);
+ muladd(a->d[6], a->d[6]);
+ extract(l[12]);
+ muladd2(a->d[6], a->d[7]);
+ extract(l[13]);
+ muladd_fast(a->d[7], a->d[7]);
+ extract_fast(l[14]);
+ VERIFY_CHECK(c1 == 0);
+ l[15] = c0;
+}
+
+#undef sumadd
+#undef sumadd_fast
+#undef muladd
+#undef muladd_fast
+#undef muladd2
+#undef extract
+#undef extract_fast
+
+static void secp256k1_scalar_mul(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) {
+ uint32_t l[16];
+ secp256k1_scalar_mul_512(l, a, b);
+ secp256k1_scalar_reduce_512(r, l);
+}
+
+static void secp256k1_scalar_sqr(secp256k1_scalar_t *r, const secp256k1_scalar_t *a) {
+ uint32_t l[16];
+ secp256k1_scalar_sqr_512(l, a);
+ secp256k1_scalar_reduce_512(r, l);
+}
+
+#ifdef USE_ENDOMORPHISM
+static void secp256k1_scalar_split_128(secp256k1_scalar_t *r1, secp256k1_scalar_t *r2, const secp256k1_scalar_t *a) {
+ r1->d[0] = a->d[0];
+ r1->d[1] = a->d[1];
+ r1->d[2] = a->d[2];
+ r1->d[3] = a->d[3];
+ r1->d[4] = 0;
+ r1->d[5] = 0;
+ r1->d[6] = 0;
+ r1->d[7] = 0;
+ r2->d[0] = a->d[4];
+ r2->d[1] = a->d[5];
+ r2->d[2] = a->d[6];
+ r2->d[3] = a->d[7];
+ r2->d[4] = 0;
+ r2->d[5] = 0;
+ r2->d[6] = 0;
+ r2->d[7] = 0;
+}
+#endif
+
+SECP256K1_INLINE static int secp256k1_scalar_eq(const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) {
+ return ((a->d[0] ^ b->d[0]) | (a->d[1] ^ b->d[1]) | (a->d[2] ^ b->d[2]) | (a->d[3] ^ b->d[3]) | (a->d[4] ^ b->d[4]) | (a->d[5] ^ b->d[5]) | (a->d[6] ^ b->d[6]) | (a->d[7] ^ b->d[7])) == 0;
+}
+
+SECP256K1_INLINE static void secp256k1_scalar_mul_shift_var(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b, unsigned int shift) {
+ uint32_t l[16];
+ unsigned int shiftlimbs;
+ unsigned int shiftlow;
+ unsigned int shifthigh;
+ VERIFY_CHECK(shift >= 256);
+ secp256k1_scalar_mul_512(l, a, b);
+ shiftlimbs = shift >> 5;
+ shiftlow = shift & 0x1F;
+ shifthigh = 32 - shiftlow;
+ r->d[0] = shift < 512 ? (l[0 + shiftlimbs] >> shiftlow | (shift < 480 && shiftlow ? (l[1 + shiftlimbs] << shifthigh) : 0)) : 0;
+ r->d[1] = shift < 480 ? (l[1 + shiftlimbs] >> shiftlow | (shift < 448 && shiftlow ? (l[2 + shiftlimbs] << shifthigh) : 0)) : 0;
+ r->d[2] = shift < 448 ? (l[2 + shiftlimbs] >> shiftlow | (shift < 416 && shiftlow ? (l[3 + shiftlimbs] << shifthigh) : 0)) : 0;
+ r->d[3] = shift < 416 ? (l[3 + shiftlimbs] >> shiftlow | (shift < 384 && shiftlow ? (l[4 + shiftlimbs] << shifthigh) : 0)) : 0;
+ r->d[4] = shift < 384 ? (l[4 + shiftlimbs] >> shiftlow | (shift < 352 && shiftlow ? (l[5 + shiftlimbs] << shifthigh) : 0)) : 0;
+ r->d[5] = shift < 352 ? (l[5 + shiftlimbs] >> shiftlow | (shift < 320 && shiftlow ? (l[6 + shiftlimbs] << shifthigh) : 0)) : 0;
+ r->d[6] = shift < 320 ? (l[6 + shiftlimbs] >> shiftlow | (shift < 288 && shiftlow ? (l[7 + shiftlimbs] << shifthigh) : 0)) : 0;
+ r->d[7] = shift < 288 ? (l[7 + shiftlimbs] >> shiftlow) : 0;
+ if ((l[(shift - 1) >> 5] >> ((shift - 1) & 0x1f)) & 1) {
+ secp256k1_scalar_add_bit(r, 0);
+ }
+}
+
+#endif
diff --git a/src/secp256k1/src/scalar_impl.h b/src/secp256k1/src/scalar_impl.h
new file mode 100644
index 0000000000..33824983e4
--- /dev/null
+++ b/src/secp256k1/src/scalar_impl.h
@@ -0,0 +1,327 @@
+/**********************************************************************
+ * Copyright (c) 2014 Pieter Wuille *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
+ **********************************************************************/
+
+#ifndef _SECP256K1_SCALAR_IMPL_H_
+#define _SECP256K1_SCALAR_IMPL_H_
+
+#include <string.h>
+
+#include "group.h"
+#include "scalar.h"
+
+#if defined HAVE_CONFIG_H
+#include "libsecp256k1-config.h"
+#endif
+
+#if defined(USE_SCALAR_4X64)
+#include "scalar_4x64_impl.h"
+#elif defined(USE_SCALAR_8X32)
+#include "scalar_8x32_impl.h"
+#else
+#error "Please select scalar implementation"
+#endif
+
+#ifndef USE_NUM_NONE
+static void secp256k1_scalar_get_num(secp256k1_num_t *r, const secp256k1_scalar_t *a) {
+ unsigned char c[32];
+ secp256k1_scalar_get_b32(c, a);
+ secp256k1_num_set_bin(r, c, 32);
+}
+
+/** secp256k1 curve order, see secp256k1_ecdsa_const_order_as_fe in ecdsa_impl.h */
+static void secp256k1_scalar_order_get_num(secp256k1_num_t *r) {
+ static const unsigned char order[32] = {
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,
+ 0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,
+ 0xBF,0xD2,0x5E,0x8C,0xD0,0x36,0x41,0x41
+ };
+ secp256k1_num_set_bin(r, order, 32);
+}
+#endif
+
+static void secp256k1_scalar_inverse(secp256k1_scalar_t *r, const secp256k1_scalar_t *x) {
+ secp256k1_scalar_t *t;
+ int i;
+ /* First compute x ^ (2^N - 1) for some values of N. */
+ secp256k1_scalar_t x2, x3, x4, x6, x7, x8, x15, x30, x60, x120, x127;
+
+ secp256k1_scalar_sqr(&x2, x);
+ secp256k1_scalar_mul(&x2, &x2, x);
+
+ secp256k1_scalar_sqr(&x3, &x2);
+ secp256k1_scalar_mul(&x3, &x3, x);
+
+ secp256k1_scalar_sqr(&x4, &x3);
+ secp256k1_scalar_mul(&x4, &x4, x);
+
+ secp256k1_scalar_sqr(&x6, &x4);
+ secp256k1_scalar_sqr(&x6, &x6);
+ secp256k1_scalar_mul(&x6, &x6, &x2);
+
+ secp256k1_scalar_sqr(&x7, &x6);
+ secp256k1_scalar_mul(&x7, &x7, x);
+
+ secp256k1_scalar_sqr(&x8, &x7);
+ secp256k1_scalar_mul(&x8, &x8, x);
+
+ secp256k1_scalar_sqr(&x15, &x8);
+ for (i = 0; i < 6; i++) {
+ secp256k1_scalar_sqr(&x15, &x15);
+ }
+ secp256k1_scalar_mul(&x15, &x15, &x7);
+
+ secp256k1_scalar_sqr(&x30, &x15);
+ for (i = 0; i < 14; i++) {
+ secp256k1_scalar_sqr(&x30, &x30);
+ }
+ secp256k1_scalar_mul(&x30, &x30, &x15);
+
+ secp256k1_scalar_sqr(&x60, &x30);
+ for (i = 0; i < 29; i++) {
+ secp256k1_scalar_sqr(&x60, &x60);
+ }
+ secp256k1_scalar_mul(&x60, &x60, &x30);
+
+ secp256k1_scalar_sqr(&x120, &x60);
+ for (i = 0; i < 59; i++) {
+ secp256k1_scalar_sqr(&x120, &x120);
+ }
+ secp256k1_scalar_mul(&x120, &x120, &x60);
+
+ secp256k1_scalar_sqr(&x127, &x120);
+ for (i = 0; i < 6; i++) {
+ secp256k1_scalar_sqr(&x127, &x127);
+ }
+ secp256k1_scalar_mul(&x127, &x127, &x7);
+
+ /* Then accumulate the final result (t starts at x127). */
+ t = &x127;
+ for (i = 0; i < 2; i++) { /* 0 */
+ secp256k1_scalar_sqr(t, t);
+ }
+ secp256k1_scalar_mul(t, t, x); /* 1 */
+ for (i = 0; i < 4; i++) { /* 0 */
+ secp256k1_scalar_sqr(t, t);
+ }
+ secp256k1_scalar_mul(t, t, &x3); /* 111 */
+ for (i = 0; i < 2; i++) { /* 0 */
+ secp256k1_scalar_sqr(t, t);
+ }
+ secp256k1_scalar_mul(t, t, x); /* 1 */
+ for (i = 0; i < 2; i++) { /* 0 */
+ secp256k1_scalar_sqr(t, t);
+ }
+ secp256k1_scalar_mul(t, t, x); /* 1 */
+ for (i = 0; i < 2; i++) { /* 0 */
+ secp256k1_scalar_sqr(t, t);
+ }
+ secp256k1_scalar_mul(t, t, x); /* 1 */
+ for (i = 0; i < 4; i++) { /* 0 */
+ secp256k1_scalar_sqr(t, t);
+ }
+ secp256k1_scalar_mul(t, t, &x3); /* 111 */
+ for (i = 0; i < 3; i++) { /* 0 */
+ secp256k1_scalar_sqr(t, t);
+ }
+ secp256k1_scalar_mul(t, t, &x2); /* 11 */
+ for (i = 0; i < 4; i++) { /* 0 */
+ secp256k1_scalar_sqr(t, t);
+ }
+ secp256k1_scalar_mul(t, t, &x3); /* 111 */
+ for (i = 0; i < 5; i++) { /* 00 */
+ secp256k1_scalar_sqr(t, t);
+ }
+ secp256k1_scalar_mul(t, t, &x3); /* 111 */
+ for (i = 0; i < 4; i++) { /* 00 */
+ secp256k1_scalar_sqr(t, t);
+ }
+ secp256k1_scalar_mul(t, t, &x2); /* 11 */
+ for (i = 0; i < 2; i++) { /* 0 */
+ secp256k1_scalar_sqr(t, t);
+ }
+ secp256k1_scalar_mul(t, t, x); /* 1 */
+ for (i = 0; i < 2; i++) { /* 0 */
+ secp256k1_scalar_sqr(t, t);
+ }
+ secp256k1_scalar_mul(t, t, x); /* 1 */
+ for (i = 0; i < 5; i++) { /* 0 */
+ secp256k1_scalar_sqr(t, t);
+ }
+ secp256k1_scalar_mul(t, t, &x4); /* 1111 */
+ for (i = 0; i < 2; i++) { /* 0 */
+ secp256k1_scalar_sqr(t, t);
+ }
+ secp256k1_scalar_mul(t, t, x); /* 1 */
+ for (i = 0; i < 3; i++) { /* 00 */
+ secp256k1_scalar_sqr(t, t);
+ }
+ secp256k1_scalar_mul(t, t, x); /* 1 */
+ for (i = 0; i < 4; i++) { /* 000 */
+ secp256k1_scalar_sqr(t, t);
+ }
+ secp256k1_scalar_mul(t, t, x); /* 1 */
+ for (i = 0; i < 2; i++) { /* 0 */
+ secp256k1_scalar_sqr(t, t);
+ }
+ secp256k1_scalar_mul(t, t, x); /* 1 */
+ for (i = 0; i < 10; i++) { /* 0000000 */
+ secp256k1_scalar_sqr(t, t);
+ }
+ secp256k1_scalar_mul(t, t, &x3); /* 111 */
+ for (i = 0; i < 4; i++) { /* 0 */
+ secp256k1_scalar_sqr(t, t);
+ }
+ secp256k1_scalar_mul(t, t, &x3); /* 111 */
+ for (i = 0; i < 9; i++) { /* 0 */
+ secp256k1_scalar_sqr(t, t);
+ }
+ secp256k1_scalar_mul(t, t, &x8); /* 11111111 */
+ for (i = 0; i < 2; i++) { /* 0 */
+ secp256k1_scalar_sqr(t, t);
+ }
+ secp256k1_scalar_mul(t, t, x); /* 1 */
+ for (i = 0; i < 3; i++) { /* 00 */
+ secp256k1_scalar_sqr(t, t);
+ }
+ secp256k1_scalar_mul(t, t, x); /* 1 */
+ for (i = 0; i < 3; i++) { /* 00 */
+ secp256k1_scalar_sqr(t, t);
+ }
+ secp256k1_scalar_mul(t, t, x); /* 1 */
+ for (i = 0; i < 5; i++) { /* 0 */
+ secp256k1_scalar_sqr(t, t);
+ }
+ secp256k1_scalar_mul(t, t, &x4); /* 1111 */
+ for (i = 0; i < 2; i++) { /* 0 */
+ secp256k1_scalar_sqr(t, t);
+ }
+ secp256k1_scalar_mul(t, t, x); /* 1 */
+ for (i = 0; i < 5; i++) { /* 000 */
+ secp256k1_scalar_sqr(t, t);
+ }
+ secp256k1_scalar_mul(t, t, &x2); /* 11 */
+ for (i = 0; i < 4; i++) { /* 00 */
+ secp256k1_scalar_sqr(t, t);
+ }
+ secp256k1_scalar_mul(t, t, &x2); /* 11 */
+ for (i = 0; i < 2; i++) { /* 0 */
+ secp256k1_scalar_sqr(t, t);
+ }
+ secp256k1_scalar_mul(t, t, x); /* 1 */
+ for (i = 0; i < 8; i++) { /* 000000 */
+ secp256k1_scalar_sqr(t, t);
+ }
+ secp256k1_scalar_mul(t, t, &x2); /* 11 */
+ for (i = 0; i < 3; i++) { /* 0 */
+ secp256k1_scalar_sqr(t, t);
+ }
+ secp256k1_scalar_mul(t, t, &x2); /* 11 */
+ for (i = 0; i < 3; i++) { /* 00 */
+ secp256k1_scalar_sqr(t, t);
+ }
+ secp256k1_scalar_mul(t, t, x); /* 1 */
+ for (i = 0; i < 6; i++) { /* 00000 */
+ secp256k1_scalar_sqr(t, t);
+ }
+ secp256k1_scalar_mul(t, t, x); /* 1 */
+ for (i = 0; i < 8; i++) { /* 00 */
+ secp256k1_scalar_sqr(t, t);
+ }
+ secp256k1_scalar_mul(r, t, &x6); /* 111111 */
+}
+
+static void secp256k1_scalar_inverse_var(secp256k1_scalar_t *r, const secp256k1_scalar_t *x) {
+#if defined(USE_SCALAR_INV_BUILTIN)
+ secp256k1_scalar_inverse(r, x);
+#elif defined(USE_SCALAR_INV_NUM)
+ unsigned char b[32];
+ secp256k1_num_t n, m;
+ secp256k1_scalar_get_b32(b, x);
+ secp256k1_num_set_bin(&n, b, 32);
+ secp256k1_scalar_order_get_num(&m);
+ secp256k1_num_mod_inverse(&n, &n, &m);
+ secp256k1_num_get_bin(b, 32, &n);
+ secp256k1_scalar_set_b32(r, b, NULL);
+#else
+#error "Please select scalar inverse implementation"
+#endif
+}
+
+#ifdef USE_ENDOMORPHISM
+/**
+ * The Secp256k1 curve has an endomorphism, where lambda * (x, y) = (beta * x, y), where
+ * lambda is {0x53,0x63,0xad,0x4c,0xc0,0x5c,0x30,0xe0,0xa5,0x26,0x1c,0x02,0x88,0x12,0x64,0x5a,
+ * 0x12,0x2e,0x22,0xea,0x20,0x81,0x66,0x78,0xdf,0x02,0x96,0x7c,0x1b,0x23,0xbd,0x72}
+ *
+ * "Guide to Elliptic Curve Cryptography" (Hankerson, Menezes, Vanstone) gives an algorithm
+ * (algorithm 3.74) to find k1 and k2 given k, such that k1 + k2 * lambda == k mod n, and k1
+ * and k2 have a small size.
+ * It relies on constants a1, b1, a2, b2. These constants for the value of lambda above are:
+ *
+ * - a1 = {0x30,0x86,0xd2,0x21,0xa7,0xd4,0x6b,0xcd,0xe8,0x6c,0x90,0xe4,0x92,0x84,0xeb,0x15}
+ * - b1 = -{0xe4,0x43,0x7e,0xd6,0x01,0x0e,0x88,0x28,0x6f,0x54,0x7f,0xa9,0x0a,0xbf,0xe4,0xc3}
+ * - a2 = {0x01,0x14,0xca,0x50,0xf7,0xa8,0xe2,0xf3,0xf6,0x57,0xc1,0x10,0x8d,0x9d,0x44,0xcf,0xd8}
+ * - b2 = {0x30,0x86,0xd2,0x21,0xa7,0xd4,0x6b,0xcd,0xe8,0x6c,0x90,0xe4,0x92,0x84,0xeb,0x15}
+ *
+ * The algorithm then computes c1 = round(b1 * k / n) and c2 = round(b2 * k / n), and gives
+ * k1 = k - (c1*a1 + c2*a2) and k2 = -(c1*b1 + c2*b2). Instead, we use modular arithmetic, and
+ * compute k1 as k - k2 * lambda, avoiding the need for constants a1 and a2.
+ *
+ * g1, g2 are precomputed constants used to replace division with a rounded multiplication
+ * when decomposing the scalar for an endomorphism-based point multiplication.
+ *
+ * The possibility of using precomputed estimates is mentioned in "Guide to Elliptic Curve
+ * Cryptography" (Hankerson, Menezes, Vanstone) in section 3.5.
+ *
+ * The derivation is described in the paper "Efficient Software Implementation of Public-Key
+ * Cryptography on Sensor Networks Using the MSP430X Microcontroller" (Gouvea, Oliveira, Lopez),
+ * Section 4.3 (here we use a somewhat higher-precision estimate):
+ * d = a1*b2 - b1*a2
+ * g1 = round((2^272)*b2/d)
+ * g2 = round((2^272)*b1/d)
+ *
+ * (Note that 'd' is also equal to the curve order here because [a1,b1] and [a2,b2] are found
+ * as outputs of the Extended Euclidean Algorithm on inputs 'order' and 'lambda').
+ *
+ * The function below splits a in r1 and r2, such that r1 + lambda * r2 == a (mod order).
+ */
+
+static void secp256k1_scalar_split_lambda_var(secp256k1_scalar_t *r1, secp256k1_scalar_t *r2, const secp256k1_scalar_t *a) {
+ secp256k1_scalar_t c1, c2;
+ static const secp256k1_scalar_t minus_lambda = SECP256K1_SCALAR_CONST(
+ 0xAC9C52B3UL, 0x3FA3CF1FUL, 0x5AD9E3FDUL, 0x77ED9BA4UL,
+ 0xA880B9FCUL, 0x8EC739C2UL, 0xE0CFC810UL, 0xB51283CFUL
+ );
+ static const secp256k1_scalar_t minus_b1 = SECP256K1_SCALAR_CONST(
+ 0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
+ 0xE4437ED6UL, 0x010E8828UL, 0x6F547FA9UL, 0x0ABFE4C3UL
+ );
+ static const secp256k1_scalar_t minus_b2 = SECP256K1_SCALAR_CONST(
+ 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFEUL,
+ 0x8A280AC5UL, 0x0774346DUL, 0xD765CDA8UL, 0x3DB1562CUL
+ );
+ static const secp256k1_scalar_t g1 = SECP256K1_SCALAR_CONST(
+ 0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00003086UL,
+ 0xD221A7D4UL, 0x6BCDE86CUL, 0x90E49284UL, 0xEB153DABUL
+ );
+ static const secp256k1_scalar_t g2 = SECP256K1_SCALAR_CONST(
+ 0x00000000UL, 0x00000000UL, 0x00000000UL, 0x0000E443UL,
+ 0x7ED6010EUL, 0x88286F54UL, 0x7FA90ABFUL, 0xE4C42212UL
+ );
+ VERIFY_CHECK(r1 != a);
+ VERIFY_CHECK(r2 != a);
+ secp256k1_scalar_mul_shift_var(&c1, a, &g1, 272);
+ secp256k1_scalar_mul_shift_var(&c2, a, &g2, 272);
+ secp256k1_scalar_mul(&c1, &c1, &minus_b1);
+ secp256k1_scalar_mul(&c2, &c2, &minus_b2);
+ secp256k1_scalar_add(r2, &c1, &c2);
+ secp256k1_scalar_mul(r1, r2, &minus_lambda);
+ secp256k1_scalar_add(r1, r1, a);
+}
+#endif
+
+#endif
diff --git a/src/secp256k1/src/secp256k1.c b/src/secp256k1/src/secp256k1.c
new file mode 100644
index 0000000000..d6192dc4ed
--- /dev/null
+++ b/src/secp256k1/src/secp256k1.c
@@ -0,0 +1,419 @@
+/**********************************************************************
+ * Copyright (c) 2013-2015 Pieter Wuille *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
+ **********************************************************************/
+
+#define SECP256K1_BUILD (1)
+
+#include "include/secp256k1.h"
+
+#include "util.h"
+#include "num_impl.h"
+#include "field_impl.h"
+#include "scalar_impl.h"
+#include "group_impl.h"
+#include "ecmult_impl.h"
+#include "ecmult_gen_impl.h"
+#include "ecdsa_impl.h"
+#include "eckey_impl.h"
+#include "hash_impl.h"
+
+struct secp256k1_context_struct {
+ secp256k1_ecmult_context_t ecmult_ctx;
+ secp256k1_ecmult_gen_context_t ecmult_gen_ctx;
+};
+
+secp256k1_context_t* secp256k1_context_create(int flags) {
+ secp256k1_context_t* ret = (secp256k1_context_t*)checked_malloc(sizeof(secp256k1_context_t));
+
+ secp256k1_ecmult_context_init(&ret->ecmult_ctx);
+ secp256k1_ecmult_gen_context_init(&ret->ecmult_gen_ctx);
+
+ if (flags & SECP256K1_CONTEXT_SIGN) {
+ secp256k1_ecmult_gen_context_build(&ret->ecmult_gen_ctx);
+ }
+ if (flags & SECP256K1_CONTEXT_VERIFY) {
+ secp256k1_ecmult_context_build(&ret->ecmult_ctx);
+ }
+
+ return ret;
+}
+
+secp256k1_context_t* secp256k1_context_clone(const secp256k1_context_t* ctx) {
+ secp256k1_context_t* ret = (secp256k1_context_t*)checked_malloc(sizeof(secp256k1_context_t));
+ secp256k1_ecmult_context_clone(&ret->ecmult_ctx, &ctx->ecmult_ctx);
+ secp256k1_ecmult_gen_context_clone(&ret->ecmult_gen_ctx, &ctx->ecmult_gen_ctx);
+ return ret;
+}
+
+void secp256k1_context_destroy(secp256k1_context_t* ctx) {
+ secp256k1_ecmult_context_clear(&ctx->ecmult_ctx);
+ secp256k1_ecmult_gen_context_clear(&ctx->ecmult_gen_ctx);
+
+ free(ctx);
+}
+
+int secp256k1_ecdsa_verify(const secp256k1_context_t* ctx, const unsigned char *msg32, const unsigned char *sig, int siglen, const unsigned char *pubkey, int pubkeylen) {
+ secp256k1_ge_t q;
+ secp256k1_ecdsa_sig_t s;
+ secp256k1_scalar_t m;
+ int ret = -3;
+ DEBUG_CHECK(ctx != NULL);
+ DEBUG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx));
+ DEBUG_CHECK(msg32 != NULL);
+ DEBUG_CHECK(sig != NULL);
+ DEBUG_CHECK(pubkey != NULL);
+
+ secp256k1_scalar_set_b32(&m, msg32, NULL);
+
+ if (secp256k1_eckey_pubkey_parse(&q, pubkey, pubkeylen)) {
+ if (secp256k1_ecdsa_sig_parse(&s, sig, siglen)) {
+ if (secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &s, &q, &m)) {
+ /* success is 1, all other values are fail */
+ ret = 1;
+ } else {
+ ret = 0;
+ }
+ } else {
+ ret = -2;
+ }
+ } else {
+ ret = -1;
+ }
+
+ return ret;
+}
+
+static int nonce_function_rfc6979(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, unsigned int counter, const void *data) {
+ secp256k1_rfc6979_hmac_sha256_t rng;
+ unsigned int i;
+ secp256k1_rfc6979_hmac_sha256_initialize(&rng, key32, 32, msg32, 32, (const unsigned char*)data, data != NULL ? 32 : 0);
+ for (i = 0; i <= counter; i++) {
+ secp256k1_rfc6979_hmac_sha256_generate(&rng, nonce32, 32);
+ }
+ secp256k1_rfc6979_hmac_sha256_finalize(&rng);
+ return 1;
+}
+
+const secp256k1_nonce_function_t secp256k1_nonce_function_rfc6979 = nonce_function_rfc6979;
+const secp256k1_nonce_function_t secp256k1_nonce_function_default = nonce_function_rfc6979;
+
+int secp256k1_ecdsa_sign(const secp256k1_context_t* ctx, const unsigned char *msg32, unsigned char *signature, int *signaturelen, const unsigned char *seckey, secp256k1_nonce_function_t noncefp, const void* noncedata) {
+ secp256k1_ecdsa_sig_t sig;
+ secp256k1_scalar_t sec, non, msg;
+ int ret = 0;
+ int overflow = 0;
+ unsigned int count = 0;
+ DEBUG_CHECK(ctx != NULL);
+ DEBUG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx));
+ DEBUG_CHECK(msg32 != NULL);
+ DEBUG_CHECK(signature != NULL);
+ DEBUG_CHECK(signaturelen != NULL);
+ DEBUG_CHECK(seckey != NULL);
+ if (noncefp == NULL) {
+ noncefp = secp256k1_nonce_function_default;
+ }
+
+ secp256k1_scalar_set_b32(&sec, seckey, &overflow);
+ /* Fail if the secret key is invalid. */
+ if (!overflow && !secp256k1_scalar_is_zero(&sec)) {
+ secp256k1_scalar_set_b32(&msg, msg32, NULL);
+ while (1) {
+ unsigned char nonce32[32];
+ ret = noncefp(nonce32, msg32, seckey, count, noncedata);
+ if (!ret) {
+ break;
+ }
+ secp256k1_scalar_set_b32(&non, nonce32, &overflow);
+ memset(nonce32, 0, 32);
+ if (!secp256k1_scalar_is_zero(&non) && !overflow) {
+ if (secp256k1_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, &sig, &sec, &msg, &non, NULL)) {
+ break;
+ }
+ }
+ count++;
+ }
+ if (ret) {
+ ret = secp256k1_ecdsa_sig_serialize(signature, signaturelen, &sig);
+ }
+ secp256k1_scalar_clear(&msg);
+ secp256k1_scalar_clear(&non);
+ secp256k1_scalar_clear(&sec);
+ }
+ if (!ret) {
+ *signaturelen = 0;
+ }
+ return ret;
+}
+
+int secp256k1_ecdsa_sign_compact(const secp256k1_context_t* ctx, const unsigned char *msg32, unsigned char *sig64, const unsigned char *seckey, secp256k1_nonce_function_t noncefp, const void* noncedata, int *recid) {
+ secp256k1_ecdsa_sig_t sig;
+ secp256k1_scalar_t sec, non, msg;
+ int ret = 0;
+ int overflow = 0;
+ unsigned int count = 0;
+ DEBUG_CHECK(ctx != NULL);
+ DEBUG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx));
+ DEBUG_CHECK(msg32 != NULL);
+ DEBUG_CHECK(sig64 != NULL);
+ DEBUG_CHECK(seckey != NULL);
+ if (noncefp == NULL) {
+ noncefp = secp256k1_nonce_function_default;
+ }
+
+ secp256k1_scalar_set_b32(&sec, seckey, &overflow);
+ /* Fail if the secret key is invalid. */
+ if (!overflow && !secp256k1_scalar_is_zero(&sec)) {
+ secp256k1_scalar_set_b32(&msg, msg32, NULL);
+ while (1) {
+ unsigned char nonce32[32];
+ ret = noncefp(nonce32, msg32, seckey, count, noncedata);
+ if (!ret) {
+ break;
+ }
+ secp256k1_scalar_set_b32(&non, nonce32, &overflow);
+ memset(nonce32, 0, 32);
+ if (!secp256k1_scalar_is_zero(&non) && !overflow) {
+ if (secp256k1_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, &sig, &sec, &msg, &non, recid)) {
+ break;
+ }
+ }
+ count++;
+ }
+ if (ret) {
+ secp256k1_scalar_get_b32(sig64, &sig.r);
+ secp256k1_scalar_get_b32(sig64 + 32, &sig.s);
+ }
+ secp256k1_scalar_clear(&msg);
+ secp256k1_scalar_clear(&non);
+ secp256k1_scalar_clear(&sec);
+ }
+ if (!ret) {
+ memset(sig64, 0, 64);
+ }
+ return ret;
+}
+
+int secp256k1_ecdsa_recover_compact(const secp256k1_context_t* ctx, const unsigned char *msg32, const unsigned char *sig64, unsigned char *pubkey, int *pubkeylen, int compressed, int recid) {
+ secp256k1_ge_t q;
+ secp256k1_ecdsa_sig_t sig;
+ secp256k1_scalar_t m;
+ int ret = 0;
+ int overflow = 0;
+ DEBUG_CHECK(ctx != NULL);
+ DEBUG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx));
+ DEBUG_CHECK(msg32 != NULL);
+ DEBUG_CHECK(sig64 != NULL);
+ DEBUG_CHECK(pubkey != NULL);
+ DEBUG_CHECK(pubkeylen != NULL);
+ DEBUG_CHECK(recid >= 0 && recid <= 3);
+
+ secp256k1_scalar_set_b32(&sig.r, sig64, &overflow);
+ if (!overflow) {
+ secp256k1_scalar_set_b32(&sig.s, sig64 + 32, &overflow);
+ if (!overflow) {
+ secp256k1_scalar_set_b32(&m, msg32, NULL);
+
+ if (secp256k1_ecdsa_sig_recover(&ctx->ecmult_ctx, &sig, &q, &m, recid)) {
+ ret = secp256k1_eckey_pubkey_serialize(&q, pubkey, pubkeylen, compressed);
+ }
+ }
+ }
+ return ret;
+}
+
+int secp256k1_ec_seckey_verify(const secp256k1_context_t* ctx, const unsigned char *seckey) {
+ secp256k1_scalar_t sec;
+ int ret;
+ int overflow;
+ DEBUG_CHECK(ctx != NULL);
+ DEBUG_CHECK(seckey != NULL);
+ (void)ctx;
+
+ secp256k1_scalar_set_b32(&sec, seckey, &overflow);
+ ret = !secp256k1_scalar_is_zero(&sec) && !overflow;
+ secp256k1_scalar_clear(&sec);
+ return ret;
+}
+
+int secp256k1_ec_pubkey_verify(const secp256k1_context_t* ctx, const unsigned char *pubkey, int pubkeylen) {
+ secp256k1_ge_t q;
+ DEBUG_CHECK(ctx != NULL);
+ DEBUG_CHECK(pubkey != NULL);
+ (void)ctx;
+
+ return secp256k1_eckey_pubkey_parse(&q, pubkey, pubkeylen);
+}
+
+int secp256k1_ec_pubkey_create(const secp256k1_context_t* ctx, unsigned char *pubkey, int *pubkeylen, const unsigned char *seckey, int compressed) {
+ secp256k1_gej_t pj;
+ secp256k1_ge_t p;
+ secp256k1_scalar_t sec;
+ int overflow;
+ int ret = 0;
+ DEBUG_CHECK(ctx != NULL);
+ DEBUG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx));
+ DEBUG_CHECK(pubkey != NULL);
+ DEBUG_CHECK(pubkeylen != NULL);
+ DEBUG_CHECK(seckey != NULL);
+
+ secp256k1_scalar_set_b32(&sec, seckey, &overflow);
+ if (!overflow) {
+ secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &pj, &sec);
+ secp256k1_scalar_clear(&sec);
+ secp256k1_ge_set_gej(&p, &pj);
+ ret = secp256k1_eckey_pubkey_serialize(&p, pubkey, pubkeylen, compressed);
+ }
+ if (!ret) {
+ *pubkeylen = 0;
+ }
+ return ret;
+}
+
+int secp256k1_ec_pubkey_decompress(const secp256k1_context_t* ctx, unsigned char *pubkey, int *pubkeylen) {
+ secp256k1_ge_t p;
+ int ret = 0;
+ DEBUG_CHECK(pubkey != NULL);
+ DEBUG_CHECK(pubkeylen != NULL);
+ (void)ctx;
+
+ if (secp256k1_eckey_pubkey_parse(&p, pubkey, *pubkeylen)) {
+ ret = secp256k1_eckey_pubkey_serialize(&p, pubkey, pubkeylen, 0);
+ }
+ return ret;
+}
+
+int secp256k1_ec_privkey_tweak_add(const secp256k1_context_t* ctx, unsigned char *seckey, const unsigned char *tweak) {
+ secp256k1_scalar_t term;
+ secp256k1_scalar_t sec;
+ int ret = 0;
+ int overflow = 0;
+ DEBUG_CHECK(ctx != NULL);
+ DEBUG_CHECK(seckey != NULL);
+ DEBUG_CHECK(tweak != NULL);
+ (void)ctx;
+
+ secp256k1_scalar_set_b32(&term, tweak, &overflow);
+ secp256k1_scalar_set_b32(&sec, seckey, NULL);
+
+ ret = secp256k1_eckey_privkey_tweak_add(&sec, &term) && !overflow;
+ if (ret) {
+ secp256k1_scalar_get_b32(seckey, &sec);
+ }
+
+ secp256k1_scalar_clear(&sec);
+ secp256k1_scalar_clear(&term);
+ return ret;
+}
+
+int secp256k1_ec_pubkey_tweak_add(const secp256k1_context_t* ctx, unsigned char *pubkey, int pubkeylen, const unsigned char *tweak) {
+ secp256k1_ge_t p;
+ secp256k1_scalar_t term;
+ int ret = 0;
+ int overflow = 0;
+ DEBUG_CHECK(ctx != NULL);
+ DEBUG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx));
+ DEBUG_CHECK(pubkey != NULL);
+ DEBUG_CHECK(tweak != NULL);
+
+ secp256k1_scalar_set_b32(&term, tweak, &overflow);
+ if (!overflow) {
+ ret = secp256k1_eckey_pubkey_parse(&p, pubkey, pubkeylen);
+ if (ret) {
+ ret = secp256k1_eckey_pubkey_tweak_add(&ctx->ecmult_ctx, &p, &term);
+ }
+ if (ret) {
+ int oldlen = pubkeylen;
+ ret = secp256k1_eckey_pubkey_serialize(&p, pubkey, &pubkeylen, oldlen <= 33);
+ VERIFY_CHECK(pubkeylen == oldlen);
+ }
+ }
+
+ return ret;
+}
+
+int secp256k1_ec_privkey_tweak_mul(const secp256k1_context_t* ctx, unsigned char *seckey, const unsigned char *tweak) {
+ secp256k1_scalar_t factor;
+ secp256k1_scalar_t sec;
+ int ret = 0;
+ int overflow = 0;
+ DEBUG_CHECK(ctx != NULL);
+ DEBUG_CHECK(seckey != NULL);
+ DEBUG_CHECK(tweak != NULL);
+ (void)ctx;
+
+ secp256k1_scalar_set_b32(&factor, tweak, &overflow);
+ secp256k1_scalar_set_b32(&sec, seckey, NULL);
+ ret = secp256k1_eckey_privkey_tweak_mul(&sec, &factor) && !overflow;
+ if (ret) {
+ secp256k1_scalar_get_b32(seckey, &sec);
+ }
+
+ secp256k1_scalar_clear(&sec);
+ secp256k1_scalar_clear(&factor);
+ return ret;
+}
+
+int secp256k1_ec_pubkey_tweak_mul(const secp256k1_context_t* ctx, unsigned char *pubkey, int pubkeylen, const unsigned char *tweak) {
+ secp256k1_ge_t p;
+ secp256k1_scalar_t factor;
+ int ret = 0;
+ int overflow = 0;
+ DEBUG_CHECK(ctx != NULL);
+ DEBUG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx));
+ DEBUG_CHECK(pubkey != NULL);
+ DEBUG_CHECK(tweak != NULL);
+
+ secp256k1_scalar_set_b32(&factor, tweak, &overflow);
+ if (!overflow) {
+ ret = secp256k1_eckey_pubkey_parse(&p, pubkey, pubkeylen);
+ if (ret) {
+ ret = secp256k1_eckey_pubkey_tweak_mul(&ctx->ecmult_ctx, &p, &factor);
+ }
+ if (ret) {
+ int oldlen = pubkeylen;
+ ret = secp256k1_eckey_pubkey_serialize(&p, pubkey, &pubkeylen, oldlen <= 33);
+ VERIFY_CHECK(pubkeylen == oldlen);
+ }
+ }
+
+ return ret;
+}
+
+int secp256k1_ec_privkey_export(const secp256k1_context_t* ctx, const unsigned char *seckey, unsigned char *privkey, int *privkeylen, int compressed) {
+ secp256k1_scalar_t key;
+ int ret = 0;
+ DEBUG_CHECK(seckey != NULL);
+ DEBUG_CHECK(privkey != NULL);
+ DEBUG_CHECK(privkeylen != NULL);
+ DEBUG_CHECK(ctx != NULL);
+ DEBUG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx));
+
+ secp256k1_scalar_set_b32(&key, seckey, NULL);
+ ret = secp256k1_eckey_privkey_serialize(&ctx->ecmult_gen_ctx, privkey, privkeylen, &key, compressed);
+ secp256k1_scalar_clear(&key);
+ return ret;
+}
+
+int secp256k1_ec_privkey_import(const secp256k1_context_t* ctx, unsigned char *seckey, const unsigned char *privkey, int privkeylen) {
+ secp256k1_scalar_t key;
+ int ret = 0;
+ DEBUG_CHECK(seckey != NULL);
+ DEBUG_CHECK(privkey != NULL);
+ (void)ctx;
+
+ ret = secp256k1_eckey_privkey_parse(&key, privkey, privkeylen);
+ if (ret) {
+ secp256k1_scalar_get_b32(seckey, &key);
+ }
+ secp256k1_scalar_clear(&key);
+ return ret;
+}
+
+int secp256k1_context_randomize(secp256k1_context_t* ctx, const unsigned char *seed32) {
+ DEBUG_CHECK(ctx != NULL);
+ DEBUG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx));
+ secp256k1_ecmult_gen_blind(&ctx->ecmult_gen_ctx, seed32);
+ return 1;
+}
diff --git a/src/secp256k1/src/testrand.h b/src/secp256k1/src/testrand.h
new file mode 100644
index 0000000000..041bb92c47
--- /dev/null
+++ b/src/secp256k1/src/testrand.h
@@ -0,0 +1,28 @@
+/**********************************************************************
+ * Copyright (c) 2013, 2014 Pieter Wuille *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
+ **********************************************************************/
+
+#ifndef _SECP256K1_TESTRAND_H_
+#define _SECP256K1_TESTRAND_H_
+
+#if defined HAVE_CONFIG_H
+#include "libsecp256k1-config.h"
+#endif
+
+/* A non-cryptographic RNG used only for test infrastructure. */
+
+/** Seed the pseudorandom number generator for testing. */
+SECP256K1_INLINE static void secp256k1_rand_seed(const unsigned char *seed16);
+
+/** Generate a pseudorandom 32-bit number. */
+static uint32_t secp256k1_rand32(void);
+
+/** Generate a pseudorandom 32-byte array. */
+static void secp256k1_rand256(unsigned char *b32);
+
+/** Generate a pseudorandom 32-byte array with long sequences of zero and one bits. */
+static void secp256k1_rand256_test(unsigned char *b32);
+
+#endif
diff --git a/src/secp256k1/src/testrand_impl.h b/src/secp256k1/src/testrand_impl.h
new file mode 100644
index 0000000000..21c69f1c51
--- /dev/null
+++ b/src/secp256k1/src/testrand_impl.h
@@ -0,0 +1,60 @@
+/**********************************************************************
+ * Copyright (c) 2013, 2014 Pieter Wuille *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
+ **********************************************************************/
+
+#ifndef _SECP256K1_TESTRAND_IMPL_H_
+#define _SECP256K1_TESTRAND_IMPL_H_
+
+#include <stdint.h>
+#include <string.h>
+
+#include "testrand.h"
+#include "hash.h"
+
+static secp256k1_rfc6979_hmac_sha256_t secp256k1_test_rng;
+static uint32_t secp256k1_test_rng_precomputed[8];
+static int secp256k1_test_rng_precomputed_used = 8;
+
+SECP256K1_INLINE static void secp256k1_rand_seed(const unsigned char *seed16) {
+ secp256k1_rfc6979_hmac_sha256_initialize(&secp256k1_test_rng, (const unsigned char*)"TestRNG", 7, seed16, 16, NULL, 0);
+}
+
+SECP256K1_INLINE static uint32_t secp256k1_rand32(void) {
+ if (secp256k1_test_rng_precomputed_used == 8) {
+ secp256k1_rfc6979_hmac_sha256_generate(&secp256k1_test_rng, (unsigned char*)(&secp256k1_test_rng_precomputed[0]), sizeof(secp256k1_test_rng_precomputed));
+ secp256k1_test_rng_precomputed_used = 0;
+ }
+ return secp256k1_test_rng_precomputed[secp256k1_test_rng_precomputed_used++];
+}
+
+static void secp256k1_rand256(unsigned char *b32) {
+ secp256k1_rfc6979_hmac_sha256_generate(&secp256k1_test_rng, b32, 32);
+}
+
+static void secp256k1_rand256_test(unsigned char *b32) {
+ int bits=0;
+ uint64_t ent = 0;
+ int entleft = 0;
+ memset(b32, 0, 32);
+ while (bits < 256) {
+ int now;
+ uint32_t val;
+ if (entleft < 12) {
+ ent |= ((uint64_t)secp256k1_rand32()) << entleft;
+ entleft += 32;
+ }
+ now = 1 + ((ent % 64)*((ent >> 6) % 32)+16)/31;
+ val = 1 & (ent >> 11);
+ ent >>= 12;
+ entleft -= 12;
+ while (now > 0 && bits < 256) {
+ b32[bits / 8] |= val << (bits % 8);
+ now--;
+ bits++;
+ }
+ }
+}
+
+#endif
diff --git a/src/secp256k1/src/tests.c b/src/secp256k1/src/tests.c
new file mode 100644
index 0000000000..d0e05057f2
--- /dev/null
+++ b/src/secp256k1/src/tests.c
@@ -0,0 +1,2083 @@
+/**********************************************************************
+ * Copyright (c) 2013, 2014, 2015 Pieter Wuille, Gregory Maxwell *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
+ **********************************************************************/
+
+#if defined HAVE_CONFIG_H
+#include "libsecp256k1-config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <time.h>
+
+#include "secp256k1.c"
+#include "testrand_impl.h"
+
+#ifdef ENABLE_OPENSSL_TESTS
+#include "openssl/bn.h"
+#include "openssl/ec.h"
+#include "openssl/ecdsa.h"
+#include "openssl/obj_mac.h"
+#endif
+
+static int count = 64;
+static secp256k1_context_t *ctx = NULL;
+
+void random_field_element_test(secp256k1_fe_t *fe) {
+ do {
+ unsigned char b32[32];
+ secp256k1_rand256_test(b32);
+ if (secp256k1_fe_set_b32(fe, b32)) {
+ break;
+ }
+ } while(1);
+}
+
+void random_field_element_magnitude(secp256k1_fe_t *fe) {
+ secp256k1_fe_t zero;
+ int n = secp256k1_rand32() % 9;
+ secp256k1_fe_normalize(fe);
+ if (n == 0) {
+ return;
+ }
+ secp256k1_fe_clear(&zero);
+ secp256k1_fe_negate(&zero, &zero, 0);
+ secp256k1_fe_mul_int(&zero, n - 1);
+ secp256k1_fe_add(fe, &zero);
+#ifdef VERIFY
+ CHECK(fe->magnitude == n);
+#endif
+}
+
+void random_group_element_test(secp256k1_ge_t *ge) {
+ secp256k1_fe_t fe;
+ do {
+ random_field_element_test(&fe);
+ if (secp256k1_ge_set_xo_var(ge, &fe, secp256k1_rand32() & 1)) {
+ break;
+ }
+ } while(1);
+}
+
+void random_group_element_jacobian_test(secp256k1_gej_t *gej, const secp256k1_ge_t *ge) {
+ secp256k1_fe_t z2, z3;
+ do {
+ random_field_element_test(&gej->z);
+ if (!secp256k1_fe_is_zero(&gej->z)) {
+ break;
+ }
+ } while(1);
+ secp256k1_fe_sqr(&z2, &gej->z);
+ secp256k1_fe_mul(&z3, &z2, &gej->z);
+ secp256k1_fe_mul(&gej->x, &ge->x, &z2);
+ secp256k1_fe_mul(&gej->y, &ge->y, &z3);
+ gej->infinity = ge->infinity;
+}
+
+void random_scalar_order_test(secp256k1_scalar_t *num) {
+ do {
+ unsigned char b32[32];
+ int overflow = 0;
+ secp256k1_rand256_test(b32);
+ secp256k1_scalar_set_b32(num, b32, &overflow);
+ if (overflow || secp256k1_scalar_is_zero(num)) {
+ continue;
+ }
+ break;
+ } while(1);
+}
+
+void random_scalar_order(secp256k1_scalar_t *num) {
+ do {
+ unsigned char b32[32];
+ int overflow = 0;
+ secp256k1_rand256(b32);
+ secp256k1_scalar_set_b32(num, b32, &overflow);
+ if (overflow || secp256k1_scalar_is_zero(num)) {
+ continue;
+ }
+ break;
+ } while(1);
+}
+
+void run_context_tests(void) {
+ secp256k1_context_t *none = secp256k1_context_create(0);
+ secp256k1_context_t *sign = secp256k1_context_create(SECP256K1_CONTEXT_SIGN);
+ secp256k1_context_t *vrfy = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY);
+ secp256k1_context_t *both = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
+
+ secp256k1_gej_t pubj;
+ secp256k1_ge_t pub;
+ secp256k1_scalar_t msg, key, nonce;
+ secp256k1_ecdsa_sig_t sig;
+
+ /*** clone and destroy all of them to make sure cloning was complete ***/
+ {
+ secp256k1_context_t *ctx_tmp;
+
+ ctx_tmp = none; none = secp256k1_context_clone(none); secp256k1_context_destroy(ctx_tmp);
+ ctx_tmp = sign; sign = secp256k1_context_clone(sign); secp256k1_context_destroy(ctx_tmp);
+ ctx_tmp = vrfy; vrfy = secp256k1_context_clone(vrfy); secp256k1_context_destroy(ctx_tmp);
+ ctx_tmp = both; both = secp256k1_context_clone(both); secp256k1_context_destroy(ctx_tmp);
+ }
+
+ /*** attempt to use them ***/
+ random_scalar_order_test(&msg);
+ random_scalar_order_test(&key);
+ secp256k1_ecmult_gen(&both->ecmult_gen_ctx, &pubj, &key);
+ secp256k1_ge_set_gej(&pub, &pubj);
+
+ /* obtain a working nonce */
+ do {
+ random_scalar_order_test(&nonce);
+ } while(!secp256k1_ecdsa_sig_sign(&both->ecmult_gen_ctx, &sig, &key, &msg, &nonce, NULL));
+
+ /* try signing */
+ CHECK(secp256k1_ecdsa_sig_sign(&sign->ecmult_gen_ctx, &sig, &key, &msg, &nonce, NULL));
+ CHECK(secp256k1_ecdsa_sig_sign(&both->ecmult_gen_ctx, &sig, &key, &msg, &nonce, NULL));
+
+ /* try verifying */
+ CHECK(secp256k1_ecdsa_sig_verify(&vrfy->ecmult_ctx, &sig, &pub, &msg));
+ CHECK(secp256k1_ecdsa_sig_verify(&both->ecmult_ctx, &sig, &pub, &msg));
+
+ /* cleanup */
+ secp256k1_context_destroy(none);
+ secp256k1_context_destroy(sign);
+ secp256k1_context_destroy(vrfy);
+ secp256k1_context_destroy(both);
+}
+
+/***** HASH TESTS *****/
+
+void run_sha256_tests(void) {
+ static const char *inputs[8] = {
+ "", "abc", "message digest", "secure hash algorithm", "SHA256 is considered to be safe",
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ "For this sample, this 63-byte string will be used as input data",
+ "This is exactly 64 bytes long, not counting the terminating byte"
+ };
+ static const unsigned char outputs[8][32] = {
+ {0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55},
+ {0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad},
+ {0xf7, 0x84, 0x6f, 0x55, 0xcf, 0x23, 0xe1, 0x4e, 0xeb, 0xea, 0xb5, 0xb4, 0xe1, 0x55, 0x0c, 0xad, 0x5b, 0x50, 0x9e, 0x33, 0x48, 0xfb, 0xc4, 0xef, 0xa3, 0xa1, 0x41, 0x3d, 0x39, 0x3c, 0xb6, 0x50},
+ {0xf3, 0x0c, 0xeb, 0x2b, 0xb2, 0x82, 0x9e, 0x79, 0xe4, 0xca, 0x97, 0x53, 0xd3, 0x5a, 0x8e, 0xcc, 0x00, 0x26, 0x2d, 0x16, 0x4c, 0xc0, 0x77, 0x08, 0x02, 0x95, 0x38, 0x1c, 0xbd, 0x64, 0x3f, 0x0d},
+ {0x68, 0x19, 0xd9, 0x15, 0xc7, 0x3f, 0x4d, 0x1e, 0x77, 0xe4, 0xe1, 0xb5, 0x2d, 0x1f, 0xa0, 0xf9, 0xcf, 0x9b, 0xea, 0xea, 0xd3, 0x93, 0x9f, 0x15, 0x87, 0x4b, 0xd9, 0x88, 0xe2, 0xa2, 0x36, 0x30},
+ {0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8, 0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39, 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67, 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1},
+ {0xf0, 0x8a, 0x78, 0xcb, 0xba, 0xee, 0x08, 0x2b, 0x05, 0x2a, 0xe0, 0x70, 0x8f, 0x32, 0xfa, 0x1e, 0x50, 0xc5, 0xc4, 0x21, 0xaa, 0x77, 0x2b, 0xa5, 0xdb, 0xb4, 0x06, 0xa2, 0xea, 0x6b, 0xe3, 0x42},
+ {0xab, 0x64, 0xef, 0xf7, 0xe8, 0x8e, 0x2e, 0x46, 0x16, 0x5e, 0x29, 0xf2, 0xbc, 0xe4, 0x18, 0x26, 0xbd, 0x4c, 0x7b, 0x35, 0x52, 0xf6, 0xb3, 0x82, 0xa9, 0xe7, 0xd3, 0xaf, 0x47, 0xc2, 0x45, 0xf8}
+ };
+ int i;
+ for (i = 0; i < 8; i++) {
+ unsigned char out[32];
+ secp256k1_sha256_t hasher;
+ secp256k1_sha256_initialize(&hasher);
+ secp256k1_sha256_write(&hasher, (const unsigned char*)(inputs[i]), strlen(inputs[i]));
+ secp256k1_sha256_finalize(&hasher, out);
+ CHECK(memcmp(out, outputs[i], 32) == 0);
+ if (strlen(inputs[i]) > 0) {
+ int split = secp256k1_rand32() % strlen(inputs[i]);
+ secp256k1_sha256_initialize(&hasher);
+ secp256k1_sha256_write(&hasher, (const unsigned char*)(inputs[i]), split);
+ secp256k1_sha256_write(&hasher, (const unsigned char*)(inputs[i] + split), strlen(inputs[i]) - split);
+ secp256k1_sha256_finalize(&hasher, out);
+ CHECK(memcmp(out, outputs[i], 32) == 0);
+ }
+ }
+}
+
+void run_hmac_sha256_tests(void) {
+ static const char *keys[6] = {
+ "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
+ "\x4a\x65\x66\x65",
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
+ "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19",
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ };
+ static const char *inputs[6] = {
+ "\x48\x69\x20\x54\x68\x65\x72\x65",
+ "\x77\x68\x61\x74\x20\x64\x6f\x20\x79\x61\x20\x77\x61\x6e\x74\x20\x66\x6f\x72\x20\x6e\x6f\x74\x68\x69\x6e\x67\x3f",
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd",
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd",
+ "\x54\x65\x73\x74\x20\x55\x73\x69\x6e\x67\x20\x4c\x61\x72\x67\x65\x72\x20\x54\x68\x61\x6e\x20\x42\x6c\x6f\x63\x6b\x2d\x53\x69\x7a\x65\x20\x4b\x65\x79\x20\x2d\x20\x48\x61\x73\x68\x20\x4b\x65\x79\x20\x46\x69\x72\x73\x74",
+ "\x54\x68\x69\x73\x20\x69\x73\x20\x61\x20\x74\x65\x73\x74\x20\x75\x73\x69\x6e\x67\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x6b\x65\x79\x20\x61\x6e\x64\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x64\x61\x74\x61\x2e\x20\x54\x68\x65\x20\x6b\x65\x79\x20\x6e\x65\x65\x64\x73\x20\x74\x6f\x20\x62\x65\x20\x68\x61\x73\x68\x65\x64\x20\x62\x65\x66\x6f\x72\x65\x20\x62\x65\x69\x6e\x67\x20\x75\x73\x65\x64\x20\x62\x79\x20\x74\x68\x65\x20\x48\x4d\x41\x43\x20\x61\x6c\x67\x6f\x72\x69\x74\x68\x6d\x2e"
+ };
+ static const unsigned char outputs[6][32] = {
+ {0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb, 0x38, 0x53, 0x5c, 0xa8, 0xaf, 0xce, 0xaf, 0x0b, 0xf1, 0x2b, 0x88, 0x1d, 0xc2, 0x00, 0xc9, 0x83, 0x3d, 0xa7, 0x26, 0xe9, 0x37, 0x6c, 0x2e, 0x32, 0xcf, 0xf7},
+ {0x5b, 0xdc, 0xc1, 0x46, 0xbf, 0x60, 0x75, 0x4e, 0x6a, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xc7, 0x5a, 0x00, 0x3f, 0x08, 0x9d, 0x27, 0x39, 0x83, 0x9d, 0xec, 0x58, 0xb9, 0x64, 0xec, 0x38, 0x43},
+ {0x77, 0x3e, 0xa9, 0x1e, 0x36, 0x80, 0x0e, 0x46, 0x85, 0x4d, 0xb8, 0xeb, 0xd0, 0x91, 0x81, 0xa7, 0x29, 0x59, 0x09, 0x8b, 0x3e, 0xf8, 0xc1, 0x22, 0xd9, 0x63, 0x55, 0x14, 0xce, 0xd5, 0x65, 0xfe},
+ {0x82, 0x55, 0x8a, 0x38, 0x9a, 0x44, 0x3c, 0x0e, 0xa4, 0xcc, 0x81, 0x98, 0x99, 0xf2, 0x08, 0x3a, 0x85, 0xf0, 0xfa, 0xa3, 0xe5, 0x78, 0xf8, 0x07, 0x7a, 0x2e, 0x3f, 0xf4, 0x67, 0x29, 0x66, 0x5b},
+ {0x60, 0xe4, 0x31, 0x59, 0x1e, 0xe0, 0xb6, 0x7f, 0x0d, 0x8a, 0x26, 0xaa, 0xcb, 0xf5, 0xb7, 0x7f, 0x8e, 0x0b, 0xc6, 0x21, 0x37, 0x28, 0xc5, 0x14, 0x05, 0x46, 0x04, 0x0f, 0x0e, 0xe3, 0x7f, 0x54},
+ {0x9b, 0x09, 0xff, 0xa7, 0x1b, 0x94, 0x2f, 0xcb, 0x27, 0x63, 0x5f, 0xbc, 0xd5, 0xb0, 0xe9, 0x44, 0xbf, 0xdc, 0x63, 0x64, 0x4f, 0x07, 0x13, 0x93, 0x8a, 0x7f, 0x51, 0x53, 0x5c, 0x3a, 0x35, 0xe2}
+ };
+ int i;
+ for (i = 0; i < 6; i++) {
+ secp256k1_hmac_sha256_t hasher;
+ unsigned char out[32];
+ secp256k1_hmac_sha256_initialize(&hasher, (const unsigned char*)(keys[i]), strlen(keys[i]));
+ secp256k1_hmac_sha256_write(&hasher, (const unsigned char*)(inputs[i]), strlen(inputs[i]));
+ secp256k1_hmac_sha256_finalize(&hasher, out);
+ CHECK(memcmp(out, outputs[i], 32) == 0);
+ if (strlen(inputs[i]) > 0) {
+ int split = secp256k1_rand32() % strlen(inputs[i]);
+ secp256k1_hmac_sha256_initialize(&hasher, (const unsigned char*)(keys[i]), strlen(keys[i]));
+ secp256k1_hmac_sha256_write(&hasher, (const unsigned char*)(inputs[i]), split);
+ secp256k1_hmac_sha256_write(&hasher, (const unsigned char*)(inputs[i] + split), strlen(inputs[i]) - split);
+ secp256k1_hmac_sha256_finalize(&hasher, out);
+ CHECK(memcmp(out, outputs[i], 32) == 0);
+ }
+ }
+}
+
+void run_rfc6979_hmac_sha256_tests(void) {
+ static const unsigned char key1[32] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x00};
+ static const unsigned char msg1[32] = {0x4b, 0xf5, 0x12, 0x2f, 0x34, 0x45, 0x54, 0xc5, 0x3b, 0xde, 0x2e, 0xbb, 0x8c, 0xd2, 0xb7, 0xe3, 0xd1, 0x60, 0x0a, 0xd6, 0x31, 0xc3, 0x85, 0xa5, 0xd7, 0xcc, 0xe2, 0x3c, 0x77, 0x85, 0x45, 0x9a};
+ static const unsigned char out1[3][32] = {
+ {0x4f, 0xe2, 0x95, 0x25, 0xb2, 0x08, 0x68, 0x09, 0x15, 0x9a, 0xcd, 0xf0, 0x50, 0x6e, 0xfb, 0x86, 0xb0, 0xec, 0x93, 0x2c, 0x7b, 0xa4, 0x42, 0x56, 0xab, 0x32, 0x1e, 0x42, 0x1e, 0x67, 0xe9, 0xfb},
+ {0x2b, 0xf0, 0xff, 0xf1, 0xd3, 0xc3, 0x78, 0xa2, 0x2d, 0xc5, 0xde, 0x1d, 0x85, 0x65, 0x22, 0x32, 0x5c, 0x65, 0xb5, 0x04, 0x49, 0x1a, 0x0c, 0xbd, 0x01, 0xcb, 0x8f, 0x3a, 0xa6, 0x7f, 0xfd, 0x4a},
+ {0xf5, 0x28, 0xb4, 0x10, 0xcb, 0x54, 0x1f, 0x77, 0x00, 0x0d, 0x7a, 0xfb, 0x6c, 0x5b, 0x53, 0xc5, 0xc4, 0x71, 0xea, 0xb4, 0x3e, 0x46, 0x6d, 0x9a, 0xc5, 0x19, 0x0c, 0x39, 0xc8, 0x2f, 0xd8, 0x2e}
+ };
+
+ static const unsigned char key2[32] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+ static const unsigned char msg2[32] = {0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55};
+ static const unsigned char out2[3][32] = {
+ {0x9c, 0x23, 0x6c, 0x16, 0x5b, 0x82, 0xae, 0x0c, 0xd5, 0x90, 0x65, 0x9e, 0x10, 0x0b, 0x6b, 0xab, 0x30, 0x36, 0xe7, 0xba, 0x8b, 0x06, 0x74, 0x9b, 0xaf, 0x69, 0x81, 0xe1, 0x6f, 0x1a, 0x2b, 0x95},
+ {0xdf, 0x47, 0x10, 0x61, 0x62, 0x5b, 0xc0, 0xea, 0x14, 0xb6, 0x82, 0xfe, 0xee, 0x2c, 0x9c, 0x02, 0xf2, 0x35, 0xda, 0x04, 0x20, 0x4c, 0x1d, 0x62, 0xa1, 0x53, 0x6c, 0x6e, 0x17, 0xae, 0xd7, 0xa9},
+ {0x75, 0x97, 0x88, 0x7c, 0xbd, 0x76, 0x32, 0x1f, 0x32, 0xe3, 0x04, 0x40, 0x67, 0x9a, 0x22, 0xcf, 0x7f, 0x8d, 0x9d, 0x2e, 0xac, 0x39, 0x0e, 0x58, 0x1f, 0xea, 0x09, 0x1c, 0xe2, 0x02, 0xba, 0x94}
+ };
+
+ secp256k1_rfc6979_hmac_sha256_t rng;
+ unsigned char out[32];
+ unsigned char zero[1] = {0};
+ int i;
+
+ secp256k1_rfc6979_hmac_sha256_initialize(&rng, key1, 32, msg1, 32, NULL, 1);
+ for (i = 0; i < 3; i++) {
+ secp256k1_rfc6979_hmac_sha256_generate(&rng, out, 32);
+ CHECK(memcmp(out, out1[i], 32) == 0);
+ }
+ secp256k1_rfc6979_hmac_sha256_finalize(&rng);
+
+ secp256k1_rfc6979_hmac_sha256_initialize(&rng, key1, 32, msg1, 32, zero, 1);
+ for (i = 0; i < 3; i++) {
+ secp256k1_rfc6979_hmac_sha256_generate(&rng, out, 32);
+ CHECK(memcmp(out, out1[i], 32) != 0);
+ }
+ secp256k1_rfc6979_hmac_sha256_finalize(&rng);
+
+ secp256k1_rfc6979_hmac_sha256_initialize(&rng, key2, 32, msg2, 32, zero, 0);
+ for (i = 0; i < 3; i++) {
+ secp256k1_rfc6979_hmac_sha256_generate(&rng, out, 32);
+ CHECK(memcmp(out, out2[i], 32) == 0);
+ }
+ secp256k1_rfc6979_hmac_sha256_finalize(&rng);
+}
+
+/***** NUM TESTS *****/
+
+#ifndef USE_NUM_NONE
+void random_num_negate(secp256k1_num_t *num) {
+ if (secp256k1_rand32() & 1) {
+ secp256k1_num_negate(num);
+ }
+}
+
+void random_num_order_test(secp256k1_num_t *num) {
+ secp256k1_scalar_t sc;
+ random_scalar_order_test(&sc);
+ secp256k1_scalar_get_num(num, &sc);
+}
+
+void random_num_order(secp256k1_num_t *num) {
+ secp256k1_scalar_t sc;
+ random_scalar_order(&sc);
+ secp256k1_scalar_get_num(num, &sc);
+}
+
+void test_num_negate(void) {
+ secp256k1_num_t n1;
+ secp256k1_num_t n2;
+ random_num_order_test(&n1); /* n1 = R */
+ random_num_negate(&n1);
+ secp256k1_num_copy(&n2, &n1); /* n2 = R */
+ secp256k1_num_sub(&n1, &n2, &n1); /* n1 = n2-n1 = 0 */
+ CHECK(secp256k1_num_is_zero(&n1));
+ secp256k1_num_copy(&n1, &n2); /* n1 = R */
+ secp256k1_num_negate(&n1); /* n1 = -R */
+ CHECK(!secp256k1_num_is_zero(&n1));
+ secp256k1_num_add(&n1, &n2, &n1); /* n1 = n2+n1 = 0 */
+ CHECK(secp256k1_num_is_zero(&n1));
+ secp256k1_num_copy(&n1, &n2); /* n1 = R */
+ secp256k1_num_negate(&n1); /* n1 = -R */
+ CHECK(secp256k1_num_is_neg(&n1) != secp256k1_num_is_neg(&n2));
+ secp256k1_num_negate(&n1); /* n1 = R */
+ CHECK(secp256k1_num_eq(&n1, &n2));
+}
+
+void test_num_add_sub(void) {
+ secp256k1_num_t n1;
+ secp256k1_num_t n2;
+ secp256k1_num_t n1p2, n2p1, n1m2, n2m1;
+ int r = secp256k1_rand32();
+ random_num_order_test(&n1); /* n1 = R1 */
+ if (r & 1) {
+ random_num_negate(&n1);
+ }
+ random_num_order_test(&n2); /* n2 = R2 */
+ if (r & 2) {
+ random_num_negate(&n2);
+ }
+ secp256k1_num_add(&n1p2, &n1, &n2); /* n1p2 = R1 + R2 */
+ secp256k1_num_add(&n2p1, &n2, &n1); /* n2p1 = R2 + R1 */
+ secp256k1_num_sub(&n1m2, &n1, &n2); /* n1m2 = R1 - R2 */
+ secp256k1_num_sub(&n2m1, &n2, &n1); /* n2m1 = R2 - R1 */
+ CHECK(secp256k1_num_eq(&n1p2, &n2p1));
+ CHECK(!secp256k1_num_eq(&n1p2, &n1m2));
+ secp256k1_num_negate(&n2m1); /* n2m1 = -R2 + R1 */
+ CHECK(secp256k1_num_eq(&n2m1, &n1m2));
+ CHECK(!secp256k1_num_eq(&n2m1, &n1));
+ secp256k1_num_add(&n2m1, &n2m1, &n2); /* n2m1 = -R2 + R1 + R2 = R1 */
+ CHECK(secp256k1_num_eq(&n2m1, &n1));
+ CHECK(!secp256k1_num_eq(&n2p1, &n1));
+ secp256k1_num_sub(&n2p1, &n2p1, &n2); /* n2p1 = R2 + R1 - R2 = R1 */
+ CHECK(secp256k1_num_eq(&n2p1, &n1));
+}
+
+void run_num_smalltests(void) {
+ int i;
+ for (i = 0; i < 100*count; i++) {
+ test_num_negate();
+ test_num_add_sub();
+ }
+}
+#endif
+
+/***** SCALAR TESTS *****/
+
+void scalar_test(void) {
+ secp256k1_scalar_t s;
+ secp256k1_scalar_t s1;
+ secp256k1_scalar_t s2;
+#ifndef USE_NUM_NONE
+ secp256k1_num_t snum, s1num, s2num;
+ secp256k1_num_t order, half_order;
+#endif
+ unsigned char c[32];
+
+ /* Set 's' to a random scalar, with value 'snum'. */
+ random_scalar_order_test(&s);
+
+ /* Set 's1' to a random scalar, with value 's1num'. */
+ random_scalar_order_test(&s1);
+
+ /* Set 's2' to a random scalar, with value 'snum2', and byte array representation 'c'. */
+ random_scalar_order_test(&s2);
+ secp256k1_scalar_get_b32(c, &s2);
+
+#ifndef USE_NUM_NONE
+ secp256k1_scalar_get_num(&snum, &s);
+ secp256k1_scalar_get_num(&s1num, &s1);
+ secp256k1_scalar_get_num(&s2num, &s2);
+
+ secp256k1_scalar_order_get_num(&order);
+ half_order = order;
+ secp256k1_num_shift(&half_order, 1);
+#endif
+
+ {
+ int i;
+ /* Test that fetching groups of 4 bits from a scalar and recursing n(i)=16*n(i-1)+p(i) reconstructs it. */
+ secp256k1_scalar_t n;
+ secp256k1_scalar_set_int(&n, 0);
+ for (i = 0; i < 256; i += 4) {
+ secp256k1_scalar_t t;
+ int j;
+ secp256k1_scalar_set_int(&t, secp256k1_scalar_get_bits(&s, 256 - 4 - i, 4));
+ for (j = 0; j < 4; j++) {
+ secp256k1_scalar_add(&n, &n, &n);
+ }
+ secp256k1_scalar_add(&n, &n, &t);
+ }
+ CHECK(secp256k1_scalar_eq(&n, &s));
+ }
+
+ {
+ /* Test that fetching groups of randomly-sized bits from a scalar and recursing n(i)=b*n(i-1)+p(i) reconstructs it. */
+ secp256k1_scalar_t n;
+ int i = 0;
+ secp256k1_scalar_set_int(&n, 0);
+ while (i < 256) {
+ secp256k1_scalar_t t;
+ int j;
+ int now = (secp256k1_rand32() % 15) + 1;
+ if (now + i > 256) {
+ now = 256 - i;
+ }
+ secp256k1_scalar_set_int(&t, secp256k1_scalar_get_bits_var(&s, 256 - now - i, now));
+ for (j = 0; j < now; j++) {
+ secp256k1_scalar_add(&n, &n, &n);
+ }
+ secp256k1_scalar_add(&n, &n, &t);
+ i += now;
+ }
+ CHECK(secp256k1_scalar_eq(&n, &s));
+ }
+
+#ifndef USE_NUM_NONE
+ {
+ /* Test that adding the scalars together is equal to adding their numbers together modulo the order. */
+ secp256k1_num_t rnum;
+ secp256k1_num_t r2num;
+ secp256k1_scalar_t r;
+ secp256k1_num_add(&rnum, &snum, &s2num);
+ secp256k1_num_mod(&rnum, &order);
+ secp256k1_scalar_add(&r, &s, &s2);
+ secp256k1_scalar_get_num(&r2num, &r);
+ CHECK(secp256k1_num_eq(&rnum, &r2num));
+ }
+
+ {
+ /* Test that multipying the scalars is equal to multiplying their numbers modulo the order. */
+ secp256k1_scalar_t r;
+ secp256k1_num_t r2num;
+ secp256k1_num_t rnum;
+ secp256k1_num_mul(&rnum, &snum, &s2num);
+ secp256k1_num_mod(&rnum, &order);
+ secp256k1_scalar_mul(&r, &s, &s2);
+ secp256k1_scalar_get_num(&r2num, &r);
+ CHECK(secp256k1_num_eq(&rnum, &r2num));
+ /* The result can only be zero if at least one of the factors was zero. */
+ CHECK(secp256k1_scalar_is_zero(&r) == (secp256k1_scalar_is_zero(&s) || secp256k1_scalar_is_zero(&s2)));
+ /* The results can only be equal to one of the factors if that factor was zero, or the other factor was one. */
+ CHECK(secp256k1_num_eq(&rnum, &snum) == (secp256k1_scalar_is_zero(&s) || secp256k1_scalar_is_one(&s2)));
+ CHECK(secp256k1_num_eq(&rnum, &s2num) == (secp256k1_scalar_is_zero(&s2) || secp256k1_scalar_is_one(&s)));
+ }
+
+ {
+ secp256k1_scalar_t neg;
+ secp256k1_num_t negnum;
+ secp256k1_num_t negnum2;
+ /* Check that comparison with zero matches comparison with zero on the number. */
+ CHECK(secp256k1_num_is_zero(&snum) == secp256k1_scalar_is_zero(&s));
+ /* Check that comparison with the half order is equal to testing for high scalar. */
+ CHECK(secp256k1_scalar_is_high(&s) == (secp256k1_num_cmp(&snum, &half_order) > 0));
+ secp256k1_scalar_negate(&neg, &s);
+ secp256k1_num_sub(&negnum, &order, &snum);
+ secp256k1_num_mod(&negnum, &order);
+ /* Check that comparison with the half order is equal to testing for high scalar after negation. */
+ CHECK(secp256k1_scalar_is_high(&neg) == (secp256k1_num_cmp(&negnum, &half_order) > 0));
+ /* Negating should change the high property, unless the value was already zero. */
+ CHECK((secp256k1_scalar_is_high(&s) == secp256k1_scalar_is_high(&neg)) == secp256k1_scalar_is_zero(&s));
+ secp256k1_scalar_get_num(&negnum2, &neg);
+ /* Negating a scalar should be equal to (order - n) mod order on the number. */
+ CHECK(secp256k1_num_eq(&negnum, &negnum2));
+ secp256k1_scalar_add(&neg, &neg, &s);
+ /* Adding a number to its negation should result in zero. */
+ CHECK(secp256k1_scalar_is_zero(&neg));
+ secp256k1_scalar_negate(&neg, &neg);
+ /* Negating zero should still result in zero. */
+ CHECK(secp256k1_scalar_is_zero(&neg));
+ }
+
+ {
+ /* Test secp256k1_scalar_mul_shift_var. */
+ secp256k1_scalar_t r;
+ secp256k1_num_t one;
+ secp256k1_num_t rnum;
+ secp256k1_num_t rnum2;
+ unsigned char cone[1] = {0x01};
+ unsigned int shift = 256 + (secp256k1_rand32() % 257);
+ secp256k1_scalar_mul_shift_var(&r, &s1, &s2, shift);
+ secp256k1_num_mul(&rnum, &s1num, &s2num);
+ secp256k1_num_shift(&rnum, shift - 1);
+ secp256k1_num_set_bin(&one, cone, 1);
+ secp256k1_num_add(&rnum, &rnum, &one);
+ secp256k1_num_shift(&rnum, 1);
+ secp256k1_scalar_get_num(&rnum2, &r);
+ CHECK(secp256k1_num_eq(&rnum, &rnum2));
+ }
+#endif
+
+ {
+ /* Test that scalar inverses are equal to the inverse of their number modulo the order. */
+ if (!secp256k1_scalar_is_zero(&s)) {
+ secp256k1_scalar_t inv;
+#ifndef USE_NUM_NONE
+ secp256k1_num_t invnum;
+ secp256k1_num_t invnum2;
+#endif
+ secp256k1_scalar_inverse(&inv, &s);
+#ifndef USE_NUM_NONE
+ secp256k1_num_mod_inverse(&invnum, &snum, &order);
+ secp256k1_scalar_get_num(&invnum2, &inv);
+ CHECK(secp256k1_num_eq(&invnum, &invnum2));
+#endif
+ secp256k1_scalar_mul(&inv, &inv, &s);
+ /* Multiplying a scalar with its inverse must result in one. */
+ CHECK(secp256k1_scalar_is_one(&inv));
+ secp256k1_scalar_inverse(&inv, &inv);
+ /* Inverting one must result in one. */
+ CHECK(secp256k1_scalar_is_one(&inv));
+ }
+ }
+
+ {
+ /* Test commutativity of add. */
+ secp256k1_scalar_t r1, r2;
+ secp256k1_scalar_add(&r1, &s1, &s2);
+ secp256k1_scalar_add(&r2, &s2, &s1);
+ CHECK(secp256k1_scalar_eq(&r1, &r2));
+ }
+
+ {
+ secp256k1_scalar_t r1, r2;
+ secp256k1_scalar_t b;
+ int i;
+ /* Test add_bit. */
+ int bit = secp256k1_rand32() % 256;
+ secp256k1_scalar_set_int(&b, 1);
+ CHECK(secp256k1_scalar_is_one(&b));
+ for (i = 0; i < bit; i++) {
+ secp256k1_scalar_add(&b, &b, &b);
+ }
+ r1 = s1;
+ r2 = s1;
+ if (!secp256k1_scalar_add(&r1, &r1, &b)) {
+ /* No overflow happened. */
+ secp256k1_scalar_add_bit(&r2, bit);
+ CHECK(secp256k1_scalar_eq(&r1, &r2));
+ }
+ }
+
+ {
+ /* Test commutativity of mul. */
+ secp256k1_scalar_t r1, r2;
+ secp256k1_scalar_mul(&r1, &s1, &s2);
+ secp256k1_scalar_mul(&r2, &s2, &s1);
+ CHECK(secp256k1_scalar_eq(&r1, &r2));
+ }
+
+ {
+ /* Test associativity of add. */
+ secp256k1_scalar_t r1, r2;
+ secp256k1_scalar_add(&r1, &s1, &s2);
+ secp256k1_scalar_add(&r1, &r1, &s);
+ secp256k1_scalar_add(&r2, &s2, &s);
+ secp256k1_scalar_add(&r2, &s1, &r2);
+ CHECK(secp256k1_scalar_eq(&r1, &r2));
+ }
+
+ {
+ /* Test associativity of mul. */
+ secp256k1_scalar_t r1, r2;
+ secp256k1_scalar_mul(&r1, &s1, &s2);
+ secp256k1_scalar_mul(&r1, &r1, &s);
+ secp256k1_scalar_mul(&r2, &s2, &s);
+ secp256k1_scalar_mul(&r2, &s1, &r2);
+ CHECK(secp256k1_scalar_eq(&r1, &r2));
+ }
+
+ {
+ /* Test distributitivity of mul over add. */
+ secp256k1_scalar_t r1, r2, t;
+ secp256k1_scalar_add(&r1, &s1, &s2);
+ secp256k1_scalar_mul(&r1, &r1, &s);
+ secp256k1_scalar_mul(&r2, &s1, &s);
+ secp256k1_scalar_mul(&t, &s2, &s);
+ secp256k1_scalar_add(&r2, &r2, &t);
+ CHECK(secp256k1_scalar_eq(&r1, &r2));
+ }
+
+ {
+ /* Test square. */
+ secp256k1_scalar_t r1, r2;
+ secp256k1_scalar_sqr(&r1, &s1);
+ secp256k1_scalar_mul(&r2, &s1, &s1);
+ CHECK(secp256k1_scalar_eq(&r1, &r2));
+ }
+
+ {
+ /* Test multiplicative identity. */
+ secp256k1_scalar_t r1, v1;
+ secp256k1_scalar_set_int(&v1,1);
+ secp256k1_scalar_mul(&r1, &s1, &v1);
+ CHECK(secp256k1_scalar_eq(&r1, &s1));
+ }
+
+ {
+ /* Test additive identity. */
+ secp256k1_scalar_t r1, v0;
+ secp256k1_scalar_set_int(&v0,0);
+ secp256k1_scalar_add(&r1, &s1, &v0);
+ CHECK(secp256k1_scalar_eq(&r1, &s1));
+ }
+
+ {
+ /* Test zero product property. */
+ secp256k1_scalar_t r1, v0;
+ secp256k1_scalar_set_int(&v0,0);
+ secp256k1_scalar_mul(&r1, &s1, &v0);
+ CHECK(secp256k1_scalar_eq(&r1, &v0));
+ }
+
+}
+
+void run_scalar_tests(void) {
+ int i;
+ for (i = 0; i < 128 * count; i++) {
+ scalar_test();
+ }
+
+ {
+ /* (-1)+1 should be zero. */
+ secp256k1_scalar_t s, o;
+ secp256k1_scalar_set_int(&s, 1);
+ CHECK(secp256k1_scalar_is_one(&s));
+ secp256k1_scalar_negate(&o, &s);
+ secp256k1_scalar_add(&o, &o, &s);
+ CHECK(secp256k1_scalar_is_zero(&o));
+ secp256k1_scalar_negate(&o, &o);
+ CHECK(secp256k1_scalar_is_zero(&o));
+ }
+
+#ifndef USE_NUM_NONE
+ {
+ /* A scalar with value of the curve order should be 0. */
+ secp256k1_num_t order;
+ secp256k1_scalar_t zero;
+ unsigned char bin[32];
+ int overflow = 0;
+ secp256k1_scalar_order_get_num(&order);
+ secp256k1_num_get_bin(bin, 32, &order);
+ secp256k1_scalar_set_b32(&zero, bin, &overflow);
+ CHECK(overflow == 1);
+ CHECK(secp256k1_scalar_is_zero(&zero));
+ }
+#endif
+}
+
+/***** FIELD TESTS *****/
+
+void random_fe(secp256k1_fe_t *x) {
+ unsigned char bin[32];
+ do {
+ secp256k1_rand256(bin);
+ if (secp256k1_fe_set_b32(x, bin)) {
+ return;
+ }
+ } while(1);
+}
+
+void random_fe_non_zero(secp256k1_fe_t *nz) {
+ int tries = 10;
+ while (--tries >= 0) {
+ random_fe(nz);
+ secp256k1_fe_normalize(nz);
+ if (!secp256k1_fe_is_zero(nz)) {
+ break;
+ }
+ }
+ /* Infinitesimal probability of spurious failure here */
+ CHECK(tries >= 0);
+}
+
+void random_fe_non_square(secp256k1_fe_t *ns) {
+ secp256k1_fe_t r;
+ random_fe_non_zero(ns);
+ if (secp256k1_fe_sqrt_var(&r, ns)) {
+ secp256k1_fe_negate(ns, ns, 1);
+ }
+}
+
+int check_fe_equal(const secp256k1_fe_t *a, const secp256k1_fe_t *b) {
+ secp256k1_fe_t an = *a;
+ secp256k1_fe_t bn = *b;
+ secp256k1_fe_normalize_weak(&an);
+ secp256k1_fe_normalize_var(&bn);
+ return secp256k1_fe_equal_var(&an, &bn);
+}
+
+int check_fe_inverse(const secp256k1_fe_t *a, const secp256k1_fe_t *ai) {
+ secp256k1_fe_t x;
+ secp256k1_fe_t one = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 1);
+ secp256k1_fe_mul(&x, a, ai);
+ return check_fe_equal(&x, &one);
+}
+
+void run_field_convert(void) {
+ static const unsigned char b32[32] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
+ 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29,
+ 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x40
+ };
+ static const secp256k1_fe_storage_t fes = SECP256K1_FE_STORAGE_CONST(
+ 0x00010203UL, 0x04050607UL, 0x11121314UL, 0x15161718UL,
+ 0x22232425UL, 0x26272829UL, 0x33343536UL, 0x37383940UL
+ );
+ static const secp256k1_fe_t fe = SECP256K1_FE_CONST(
+ 0x00010203UL, 0x04050607UL, 0x11121314UL, 0x15161718UL,
+ 0x22232425UL, 0x26272829UL, 0x33343536UL, 0x37383940UL
+ );
+ secp256k1_fe_t fe2;
+ unsigned char b322[32];
+ secp256k1_fe_storage_t fes2;
+ /* Check conversions to fe. */
+ CHECK(secp256k1_fe_set_b32(&fe2, b32));
+ CHECK(secp256k1_fe_equal_var(&fe, &fe2));
+ secp256k1_fe_from_storage(&fe2, &fes);
+ CHECK(secp256k1_fe_equal_var(&fe, &fe2));
+ /* Check conversion from fe. */
+ secp256k1_fe_get_b32(b322, &fe);
+ CHECK(memcmp(b322, b32, 32) == 0);
+ secp256k1_fe_to_storage(&fes2, &fe);
+ CHECK(memcmp(&fes2, &fes, sizeof(fes)) == 0);
+}
+
+void run_field_misc(void) {
+ secp256k1_fe_t x;
+ secp256k1_fe_t y;
+ secp256k1_fe_t z;
+ secp256k1_fe_t q;
+ secp256k1_fe_t fe5 = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 5);
+ int i;
+ for (i = 0; i < 5*count; i++) {
+ secp256k1_fe_storage_t xs, ys, zs;
+ random_fe(&x);
+ random_fe_non_zero(&y);
+ /* Test the fe equality and comparison operations. */
+ CHECK(secp256k1_fe_cmp_var(&x, &x) == 0);
+ CHECK(secp256k1_fe_equal_var(&x, &x));
+ z = x;
+ secp256k1_fe_add(&z,&y);
+ /* Test fe conditional move; z is not normalized here. */
+ q = x;
+ secp256k1_fe_cmov(&x, &z, 0);
+ secp256k1_fe_cmov(&x, &x, 1);
+ CHECK(memcmp(&x, &z, sizeof(x)) != 0);
+ CHECK(memcmp(&x, &q, sizeof(x)) == 0);
+ secp256k1_fe_cmov(&q, &z, 1);
+ CHECK(memcmp(&q, &z, sizeof(q)) == 0);
+ /* Test storage conversion and conditional moves. */
+ secp256k1_fe_normalize(&z);
+ CHECK(!secp256k1_fe_equal_var(&x, &z));
+ secp256k1_fe_to_storage(&xs, &x);
+ secp256k1_fe_to_storage(&ys, &y);
+ secp256k1_fe_to_storage(&zs, &z);
+ secp256k1_fe_storage_cmov(&zs, &xs, 0);
+ secp256k1_fe_storage_cmov(&zs, &zs, 1);
+ CHECK(memcmp(&xs, &zs, sizeof(xs)) != 0);
+ secp256k1_fe_storage_cmov(&ys, &xs, 1);
+ CHECK(memcmp(&xs, &ys, sizeof(xs)) == 0);
+ secp256k1_fe_from_storage(&x, &xs);
+ secp256k1_fe_from_storage(&y, &ys);
+ secp256k1_fe_from_storage(&z, &zs);
+ /* Test that mul_int, mul, and add agree. */
+ secp256k1_fe_add(&y, &x);
+ secp256k1_fe_add(&y, &x);
+ z = x;
+ secp256k1_fe_mul_int(&z, 3);
+ CHECK(check_fe_equal(&y, &z));
+ secp256k1_fe_add(&y, &x);
+ secp256k1_fe_add(&z, &x);
+ CHECK(check_fe_equal(&z, &y));
+ z = x;
+ secp256k1_fe_mul_int(&z, 5);
+ secp256k1_fe_mul(&q, &x, &fe5);
+ CHECK(check_fe_equal(&z, &q));
+ secp256k1_fe_negate(&x, &x, 1);
+ secp256k1_fe_add(&z, &x);
+ secp256k1_fe_add(&q, &x);
+ CHECK(check_fe_equal(&y, &z));
+ CHECK(check_fe_equal(&q, &y));
+ }
+}
+
+void run_field_inv(void) {
+ secp256k1_fe_t x, xi, xii;
+ int i;
+ for (i = 0; i < 10*count; i++) {
+ random_fe_non_zero(&x);
+ secp256k1_fe_inv(&xi, &x);
+ CHECK(check_fe_inverse(&x, &xi));
+ secp256k1_fe_inv(&xii, &xi);
+ CHECK(check_fe_equal(&x, &xii));
+ }
+}
+
+void run_field_inv_var(void) {
+ secp256k1_fe_t x, xi, xii;
+ int i;
+ for (i = 0; i < 10*count; i++) {
+ random_fe_non_zero(&x);
+ secp256k1_fe_inv_var(&xi, &x);
+ CHECK(check_fe_inverse(&x, &xi));
+ secp256k1_fe_inv_var(&xii, &xi);
+ CHECK(check_fe_equal(&x, &xii));
+ }
+}
+
+void run_field_inv_all_var(void) {
+ secp256k1_fe_t x[16], xi[16], xii[16];
+ int i;
+ /* Check it's safe to call for 0 elements */
+ secp256k1_fe_inv_all_var(0, xi, x);
+ for (i = 0; i < count; i++) {
+ size_t j;
+ size_t len = (secp256k1_rand32() & 15) + 1;
+ for (j = 0; j < len; j++) {
+ random_fe_non_zero(&x[j]);
+ }
+ secp256k1_fe_inv_all_var(len, xi, x);
+ for (j = 0; j < len; j++) {
+ CHECK(check_fe_inverse(&x[j], &xi[j]));
+ }
+ secp256k1_fe_inv_all_var(len, xii, xi);
+ for (j = 0; j < len; j++) {
+ CHECK(check_fe_equal(&x[j], &xii[j]));
+ }
+ }
+}
+
+void run_sqr(void) {
+ secp256k1_fe_t x, s;
+
+ {
+ int i;
+ secp256k1_fe_set_int(&x, 1);
+ secp256k1_fe_negate(&x, &x, 1);
+
+ for (i = 1; i <= 512; ++i) {
+ secp256k1_fe_mul_int(&x, 2);
+ secp256k1_fe_normalize(&x);
+ secp256k1_fe_sqr(&s, &x);
+ }
+ }
+}
+
+void test_sqrt(const secp256k1_fe_t *a, const secp256k1_fe_t *k) {
+ secp256k1_fe_t r1, r2;
+ int v = secp256k1_fe_sqrt_var(&r1, a);
+ CHECK((v == 0) == (k == NULL));
+
+ if (k != NULL) {
+ /* Check that the returned root is +/- the given known answer */
+ secp256k1_fe_negate(&r2, &r1, 1);
+ secp256k1_fe_add(&r1, k); secp256k1_fe_add(&r2, k);
+ secp256k1_fe_normalize(&r1); secp256k1_fe_normalize(&r2);
+ CHECK(secp256k1_fe_is_zero(&r1) || secp256k1_fe_is_zero(&r2));
+ }
+}
+
+void run_sqrt(void) {
+ secp256k1_fe_t ns, x, s, t;
+ int i;
+
+ /* Check sqrt(0) is 0 */
+ secp256k1_fe_set_int(&x, 0);
+ secp256k1_fe_sqr(&s, &x);
+ test_sqrt(&s, &x);
+
+ /* Check sqrt of small squares (and their negatives) */
+ for (i = 1; i <= 100; i++) {
+ secp256k1_fe_set_int(&x, i);
+ secp256k1_fe_sqr(&s, &x);
+ test_sqrt(&s, &x);
+ secp256k1_fe_negate(&t, &s, 1);
+ test_sqrt(&t, NULL);
+ }
+
+ /* Consistency checks for large random values */
+ for (i = 0; i < 10; i++) {
+ int j;
+ random_fe_non_square(&ns);
+ for (j = 0; j < count; j++) {
+ random_fe(&x);
+ secp256k1_fe_sqr(&s, &x);
+ test_sqrt(&s, &x);
+ secp256k1_fe_negate(&t, &s, 1);
+ test_sqrt(&t, NULL);
+ secp256k1_fe_mul(&t, &s, &ns);
+ test_sqrt(&t, NULL);
+ }
+ }
+}
+
+/***** GROUP TESTS *****/
+
+void ge_equals_ge(const secp256k1_ge_t *a, const secp256k1_ge_t *b) {
+ CHECK(a->infinity == b->infinity);
+ if (a->infinity) {
+ return;
+ }
+ CHECK(secp256k1_fe_equal_var(&a->x, &b->x));
+ CHECK(secp256k1_fe_equal_var(&b->y, &b->y));
+}
+
+/* This compares jacobian points including their Z, not just their geometric meaning. */
+int gej_xyz_equals_gej(const secp256k1_gej_t *a, const secp256k1_gej_t *b) {
+ secp256k1_gej_t a2;
+ secp256k1_gej_t b2;
+ int ret = 1;
+ ret &= a->infinity == b->infinity;
+ if (ret && !a->infinity) {
+ a2 = *a;
+ b2 = *b;
+ secp256k1_fe_normalize(&a2.x);
+ secp256k1_fe_normalize(&a2.y);
+ secp256k1_fe_normalize(&a2.z);
+ secp256k1_fe_normalize(&b2.x);
+ secp256k1_fe_normalize(&b2.y);
+ secp256k1_fe_normalize(&b2.z);
+ ret &= secp256k1_fe_cmp_var(&a2.x, &b2.x) == 0;
+ ret &= secp256k1_fe_cmp_var(&a2.y, &b2.y) == 0;
+ ret &= secp256k1_fe_cmp_var(&a2.z, &b2.z) == 0;
+ }
+ return ret;
+}
+
+void ge_equals_gej(const secp256k1_ge_t *a, const secp256k1_gej_t *b) {
+ secp256k1_fe_t z2s;
+ secp256k1_fe_t u1, u2, s1, s2;
+ CHECK(a->infinity == b->infinity);
+ if (a->infinity) {
+ return;
+ }
+ /* Check a.x * b.z^2 == b.x && a.y * b.z^3 == b.y, to avoid inverses. */
+ secp256k1_fe_sqr(&z2s, &b->z);
+ secp256k1_fe_mul(&u1, &a->x, &z2s);
+ u2 = b->x; secp256k1_fe_normalize_weak(&u2);
+ secp256k1_fe_mul(&s1, &a->y, &z2s); secp256k1_fe_mul(&s1, &s1, &b->z);
+ s2 = b->y; secp256k1_fe_normalize_weak(&s2);
+ CHECK(secp256k1_fe_equal_var(&u1, &u2));
+ CHECK(secp256k1_fe_equal_var(&s1, &s2));
+}
+
+void test_ge(void) {
+ int i, i1;
+ int runs = 4;
+ /* Points: (infinity, p1, p1, -p1, -p1, p2, p2, -p2, -p2, p3, p3, -p3, -p3, p4, p4, -p4, -p4).
+ * The second in each pair of identical points uses a random Z coordinate in the Jacobian form.
+ * All magnitudes are randomized.
+ * All 17*17 combinations of points are added to eachother, using all applicable methods.
+ */
+ secp256k1_ge_t *ge = (secp256k1_ge_t *)malloc(sizeof(secp256k1_ge_t) * (1 + 4 * runs));
+ secp256k1_gej_t *gej = (secp256k1_gej_t *)malloc(sizeof(secp256k1_gej_t) * (1 + 4 * runs));
+ secp256k1_gej_set_infinity(&gej[0]);
+ secp256k1_ge_clear(&ge[0]);
+ secp256k1_ge_set_gej_var(&ge[0], &gej[0]);
+ for (i = 0; i < runs; i++) {
+ int j;
+ secp256k1_ge_t g;
+ random_group_element_test(&g);
+ ge[1 + 4 * i] = g;
+ ge[2 + 4 * i] = g;
+ secp256k1_ge_neg(&ge[3 + 4 * i], &g);
+ secp256k1_ge_neg(&ge[4 + 4 * i], &g);
+ secp256k1_gej_set_ge(&gej[1 + 4 * i], &ge[1 + 4 * i]);
+ random_group_element_jacobian_test(&gej[2 + 4 * i], &ge[2 + 4 * i]);
+ secp256k1_gej_set_ge(&gej[3 + 4 * i], &ge[3 + 4 * i]);
+ random_group_element_jacobian_test(&gej[4 + 4 * i], &ge[4 + 4 * i]);
+ for (j = 0; j < 4; j++) {
+ random_field_element_magnitude(&ge[1 + j + 4 * i].x);
+ random_field_element_magnitude(&ge[1 + j + 4 * i].y);
+ random_field_element_magnitude(&gej[1 + j + 4 * i].x);
+ random_field_element_magnitude(&gej[1 + j + 4 * i].y);
+ random_field_element_magnitude(&gej[1 + j + 4 * i].z);
+ }
+ }
+
+ for (i1 = 0; i1 < 1 + 4 * runs; i1++) {
+ int i2;
+ for (i2 = 0; i2 < 1 + 4 * runs; i2++) {
+ /* Compute reference result using gej + gej (var). */
+ secp256k1_gej_t refj, resj;
+ secp256k1_ge_t ref;
+ secp256k1_gej_add_var(&refj, &gej[i1], &gej[i2]);
+ secp256k1_ge_set_gej_var(&ref, &refj);
+
+ /* Test gej + ge (var). */
+ secp256k1_gej_add_ge_var(&resj, &gej[i1], &ge[i2]);
+ ge_equals_gej(&ref, &resj);
+
+ /* Test gej + ge (const). */
+ if (i2 != 0) {
+ /* secp256k1_gej_add_ge does not support its second argument being infinity. */
+ secp256k1_gej_add_ge(&resj, &gej[i1], &ge[i2]);
+ ge_equals_gej(&ref, &resj);
+ }
+
+ /* Test doubling (var). */
+ if ((i1 == 0 && i2 == 0) || ((i1 + 3)/4 == (i2 + 3)/4 && ((i1 + 3)%4)/2 == ((i2 + 3)%4)/2)) {
+ /* Normal doubling. */
+ secp256k1_gej_double_var(&resj, &gej[i1]);
+ ge_equals_gej(&ref, &resj);
+ secp256k1_gej_double_var(&resj, &gej[i2]);
+ ge_equals_gej(&ref, &resj);
+ }
+
+ /* Test adding opposites. */
+ if ((i1 == 0 && i2 == 0) || ((i1 + 3)/4 == (i2 + 3)/4 && ((i1 + 3)%4)/2 != ((i2 + 3)%4)/2)) {
+ CHECK(secp256k1_ge_is_infinity(&ref));
+ }
+
+ /* Test adding infinity. */
+ if (i1 == 0) {
+ CHECK(secp256k1_ge_is_infinity(&ge[i1]));
+ CHECK(secp256k1_gej_is_infinity(&gej[i1]));
+ ge_equals_gej(&ref, &gej[i2]);
+ }
+ if (i2 == 0) {
+ CHECK(secp256k1_ge_is_infinity(&ge[i2]));
+ CHECK(secp256k1_gej_is_infinity(&gej[i2]));
+ ge_equals_gej(&ref, &gej[i1]);
+ }
+ }
+ }
+
+ /* Test adding all points together in random order equals infinity. */
+ {
+ secp256k1_gej_t sum = SECP256K1_GEJ_CONST_INFINITY;
+ secp256k1_gej_t *gej_shuffled = (secp256k1_gej_t *)malloc((4 * runs + 1) * sizeof(secp256k1_gej_t));
+ for (i = 0; i < 4 * runs + 1; i++) {
+ gej_shuffled[i] = gej[i];
+ }
+ for (i = 0; i < 4 * runs + 1; i++) {
+ int swap = i + secp256k1_rand32() % (4 * runs + 1 - i);
+ if (swap != i) {
+ secp256k1_gej_t t = gej_shuffled[i];
+ gej_shuffled[i] = gej_shuffled[swap];
+ gej_shuffled[swap] = t;
+ }
+ }
+ for (i = 0; i < 4 * runs + 1; i++) {
+ secp256k1_gej_add_var(&sum, &sum, &gej_shuffled[i]);
+ }
+ CHECK(secp256k1_gej_is_infinity(&sum));
+ free(gej_shuffled);
+ }
+
+ /* Test batch gej -> ge conversion. */
+ {
+ secp256k1_ge_t *ge_set_all = (secp256k1_ge_t *)malloc((4 * runs + 1) * sizeof(secp256k1_ge_t));
+ secp256k1_ge_set_all_gej_var(4 * runs + 1, ge_set_all, gej);
+ for (i = 0; i < 4 * runs + 1; i++) {
+ secp256k1_fe_t s;
+ random_fe_non_zero(&s);
+ secp256k1_gej_rescale(&gej[i], &s);
+ ge_equals_gej(&ge_set_all[i], &gej[i]);
+ }
+ free(ge_set_all);
+ }
+
+ free(ge);
+ free(gej);
+}
+
+void run_ge(void) {
+ int i;
+ for (i = 0; i < count * 32; i++) {
+ test_ge();
+ }
+}
+
+/***** ECMULT TESTS *****/
+
+void run_ecmult_chain(void) {
+ /* random starting point A (on the curve) */
+ secp256k1_gej_t a = SECP256K1_GEJ_CONST(
+ 0x8b30bbe9, 0xae2a9906, 0x96b22f67, 0x0709dff3,
+ 0x727fd8bc, 0x04d3362c, 0x6c7bf458, 0xe2846004,
+ 0xa357ae91, 0x5c4a6528, 0x1309edf2, 0x0504740f,
+ 0x0eb33439, 0x90216b4f, 0x81063cb6, 0x5f2f7e0f
+ );
+ /* two random initial factors xn and gn */
+ secp256k1_scalar_t xn = SECP256K1_SCALAR_CONST(
+ 0x84cc5452, 0xf7fde1ed, 0xb4d38a8c, 0xe9b1b84c,
+ 0xcef31f14, 0x6e569be9, 0x705d357a, 0x42985407
+ );
+ secp256k1_scalar_t gn = SECP256K1_SCALAR_CONST(
+ 0xa1e58d22, 0x553dcd42, 0xb2398062, 0x5d4c57a9,
+ 0x6e9323d4, 0x2b3152e5, 0xca2c3990, 0xedc7c9de
+ );
+ /* two small multipliers to be applied to xn and gn in every iteration: */
+ static const secp256k1_scalar_t xf = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0x1337);
+ static const secp256k1_scalar_t gf = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0x7113);
+ /* accumulators with the resulting coefficients to A and G */
+ secp256k1_scalar_t ae = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 1);
+ secp256k1_scalar_t ge = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0);
+ /* actual points */
+ secp256k1_gej_t x = a;
+ secp256k1_gej_t x2;
+ int i;
+
+ /* the point being computed */
+ x = a;
+ for (i = 0; i < 200*count; i++) {
+ /* in each iteration, compute X = xn*X + gn*G; */
+ secp256k1_ecmult(&ctx->ecmult_ctx, &x, &x, &xn, &gn);
+ /* also compute ae and ge: the actual accumulated factors for A and G */
+ /* if X was (ae*A+ge*G), xn*X + gn*G results in (xn*ae*A + (xn*ge+gn)*G) */
+ secp256k1_scalar_mul(&ae, &ae, &xn);
+ secp256k1_scalar_mul(&ge, &ge, &xn);
+ secp256k1_scalar_add(&ge, &ge, &gn);
+ /* modify xn and gn */
+ secp256k1_scalar_mul(&xn, &xn, &xf);
+ secp256k1_scalar_mul(&gn, &gn, &gf);
+
+ /* verify */
+ if (i == 19999) {
+ /* expected result after 19999 iterations */
+ secp256k1_gej_t rp = SECP256K1_GEJ_CONST(
+ 0xD6E96687, 0xF9B10D09, 0x2A6F3543, 0x9D86CEBE,
+ 0xA4535D0D, 0x409F5358, 0x6440BD74, 0xB933E830,
+ 0xB95CBCA2, 0xC77DA786, 0x539BE8FD, 0x53354D2D,
+ 0x3B4F566A, 0xE6580454, 0x07ED6015, 0xEE1B2A88
+ );
+
+ secp256k1_gej_neg(&rp, &rp);
+ secp256k1_gej_add_var(&rp, &rp, &x);
+ CHECK(secp256k1_gej_is_infinity(&rp));
+ }
+ }
+ /* redo the computation, but directly with the resulting ae and ge coefficients: */
+ secp256k1_ecmult(&ctx->ecmult_ctx, &x2, &a, &ae, &ge);
+ secp256k1_gej_neg(&x2, &x2);
+ secp256k1_gej_add_var(&x2, &x2, &x);
+ CHECK(secp256k1_gej_is_infinity(&x2));
+}
+
+void test_point_times_order(const secp256k1_gej_t *point) {
+ /* X * (point + G) + (order-X) * (pointer + G) = 0 */
+ secp256k1_scalar_t x;
+ secp256k1_scalar_t nx;
+ secp256k1_gej_t res1, res2;
+ secp256k1_ge_t res3;
+ unsigned char pub[65];
+ int psize = 65;
+ random_scalar_order_test(&x);
+ secp256k1_scalar_negate(&nx, &x);
+ secp256k1_ecmult(&ctx->ecmult_ctx, &res1, point, &x, &x); /* calc res1 = x * point + x * G; */
+ secp256k1_ecmult(&ctx->ecmult_ctx, &res2, point, &nx, &nx); /* calc res2 = (order - x) * point + (order - x) * G; */
+ secp256k1_gej_add_var(&res1, &res1, &res2);
+ CHECK(secp256k1_gej_is_infinity(&res1));
+ CHECK(secp256k1_gej_is_valid_var(&res1) == 0);
+ secp256k1_ge_set_gej(&res3, &res1);
+ CHECK(secp256k1_ge_is_infinity(&res3));
+ CHECK(secp256k1_ge_is_valid_var(&res3) == 0);
+ CHECK(secp256k1_eckey_pubkey_serialize(&res3, pub, &psize, 0) == 0);
+ psize = 65;
+ CHECK(secp256k1_eckey_pubkey_serialize(&res3, pub, &psize, 1) == 0);
+}
+
+void run_point_times_order(void) {
+ int i;
+ secp256k1_fe_t x = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 2);
+ static const secp256k1_fe_t xr = SECP256K1_FE_CONST(
+ 0x7603CB59, 0xB0EF6C63, 0xFE608479, 0x2A0C378C,
+ 0xDB3233A8, 0x0F8A9A09, 0xA877DEAD, 0x31B38C45
+ );
+ for (i = 0; i < 500; i++) {
+ secp256k1_ge_t p;
+ if (secp256k1_ge_set_xo_var(&p, &x, 1)) {
+ secp256k1_gej_t j;
+ CHECK(secp256k1_ge_is_valid_var(&p));
+ secp256k1_gej_set_ge(&j, &p);
+ CHECK(secp256k1_gej_is_valid_var(&j));
+ test_point_times_order(&j);
+ }
+ secp256k1_fe_sqr(&x, &x);
+ }
+ secp256k1_fe_normalize_var(&x);
+ CHECK(secp256k1_fe_equal_var(&x, &xr));
+}
+
+void test_wnaf(const secp256k1_scalar_t *number, int w) {
+ secp256k1_scalar_t x, two, t;
+ int wnaf[256];
+ int zeroes = -1;
+ int i;
+ int bits;
+ secp256k1_scalar_set_int(&x, 0);
+ secp256k1_scalar_set_int(&two, 2);
+ bits = secp256k1_ecmult_wnaf(wnaf, number, w);
+ CHECK(bits <= 256);
+ for (i = bits-1; i >= 0; i--) {
+ int v = wnaf[i];
+ secp256k1_scalar_mul(&x, &x, &two);
+ if (v) {
+ CHECK(zeroes == -1 || zeroes >= w-1); /* check that distance between non-zero elements is at least w-1 */
+ zeroes=0;
+ CHECK((v & 1) == 1); /* check non-zero elements are odd */
+ CHECK(v <= (1 << (w-1)) - 1); /* check range below */
+ CHECK(v >= -(1 << (w-1)) - 1); /* check range above */
+ } else {
+ CHECK(zeroes != -1); /* check that no unnecessary zero padding exists */
+ zeroes++;
+ }
+ if (v >= 0) {
+ secp256k1_scalar_set_int(&t, v);
+ } else {
+ secp256k1_scalar_set_int(&t, -v);
+ secp256k1_scalar_negate(&t, &t);
+ }
+ secp256k1_scalar_add(&x, &x, &t);
+ }
+ CHECK(secp256k1_scalar_eq(&x, number)); /* check that wnaf represents number */
+}
+
+void run_wnaf(void) {
+ int i;
+ secp256k1_scalar_t n;
+ for (i = 0; i < count; i++) {
+ random_scalar_order(&n);
+ test_wnaf(&n, 4+(i%10));
+ }
+}
+
+void test_ecmult_constants(void) {
+ /* Test ecmult_gen() for [0..36) and [order-36..0). */
+ secp256k1_scalar_t x;
+ secp256k1_gej_t r;
+ secp256k1_ge_t ng;
+ int i;
+ int j;
+ secp256k1_ge_neg(&ng, &secp256k1_ge_const_g);
+ for (i = 0; i < 36; i++ ) {
+ secp256k1_scalar_set_int(&x, i);
+ secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &r, &x);
+ for (j = 0; j < i; j++) {
+ if (j == i - 1) {
+ ge_equals_gej(&secp256k1_ge_const_g, &r);
+ }
+ secp256k1_gej_add_ge(&r, &r, &ng);
+ }
+ CHECK(secp256k1_gej_is_infinity(&r));
+ }
+ for (i = 1; i <= 36; i++ ) {
+ secp256k1_scalar_set_int(&x, i);
+ secp256k1_scalar_negate(&x, &x);
+ secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &r, &x);
+ for (j = 0; j < i; j++) {
+ if (j == i - 1) {
+ ge_equals_gej(&ng, &r);
+ }
+ secp256k1_gej_add_ge(&r, &r, &secp256k1_ge_const_g);
+ }
+ CHECK(secp256k1_gej_is_infinity(&r));
+ }
+}
+
+void run_ecmult_constants(void) {
+ test_ecmult_constants();
+}
+
+void test_ecmult_gen_blind(void) {
+ /* Test ecmult_gen() blinding and confirm that the blinding changes, the affline points match, and the z's don't match. */
+ secp256k1_scalar_t key;
+ secp256k1_scalar_t b;
+ unsigned char seed32[32];
+ secp256k1_gej_t pgej;
+ secp256k1_gej_t pgej2;
+ secp256k1_gej_t i;
+ secp256k1_ge_t pge;
+ random_scalar_order_test(&key);
+ secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &pgej, &key);
+ secp256k1_rand256(seed32);
+ b = ctx->ecmult_gen_ctx.blind;
+ i = ctx->ecmult_gen_ctx.initial;
+ secp256k1_ecmult_gen_blind(&ctx->ecmult_gen_ctx, seed32);
+ CHECK(!secp256k1_scalar_eq(&b, &ctx->ecmult_gen_ctx.blind));
+ secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &pgej2, &key);
+ CHECK(!gej_xyz_equals_gej(&pgej, &pgej2));
+ CHECK(!gej_xyz_equals_gej(&i, &ctx->ecmult_gen_ctx.initial));
+ secp256k1_ge_set_gej(&pge, &pgej);
+ ge_equals_gej(&pge, &pgej2);
+}
+
+void test_ecmult_gen_blind_reset(void) {
+ /* Test ecmult_gen() blinding reset and confirm that the blinding is consistent. */
+ secp256k1_scalar_t b;
+ secp256k1_gej_t initial;
+ secp256k1_ecmult_gen_blind(&ctx->ecmult_gen_ctx, 0);
+ b = ctx->ecmult_gen_ctx.blind;
+ initial = ctx->ecmult_gen_ctx.initial;
+ secp256k1_ecmult_gen_blind(&ctx->ecmult_gen_ctx, 0);
+ CHECK(secp256k1_scalar_eq(&b, &ctx->ecmult_gen_ctx.blind));
+ CHECK(gej_xyz_equals_gej(&initial, &ctx->ecmult_gen_ctx.initial));
+}
+
+void run_ecmult_gen_blind(void) {
+ int i;
+ test_ecmult_gen_blind_reset();
+ for (i = 0; i < 10; i++) {
+ test_ecmult_gen_blind();
+ }
+}
+
+
+void random_sign(secp256k1_ecdsa_sig_t *sig, const secp256k1_scalar_t *key, const secp256k1_scalar_t *msg, int *recid) {
+ secp256k1_scalar_t nonce;
+ do {
+ random_scalar_order_test(&nonce);
+ } while(!secp256k1_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, sig, key, msg, &nonce, recid));
+}
+
+void test_ecdsa_sign_verify(void) {
+ secp256k1_gej_t pubj;
+ secp256k1_ge_t pub;
+ secp256k1_scalar_t one;
+ secp256k1_scalar_t msg, key;
+ secp256k1_ecdsa_sig_t sig;
+ int recid;
+ int getrec;
+ random_scalar_order_test(&msg);
+ random_scalar_order_test(&key);
+ secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &pubj, &key);
+ secp256k1_ge_set_gej(&pub, &pubj);
+ getrec = secp256k1_rand32()&1;
+ random_sign(&sig, &key, &msg, getrec?&recid:NULL);
+ if (getrec) {
+ CHECK(recid >= 0 && recid < 4);
+ }
+ CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sig, &pub, &msg));
+ secp256k1_scalar_set_int(&one, 1);
+ secp256k1_scalar_add(&msg, &msg, &one);
+ CHECK(!secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sig, &pub, &msg));
+}
+
+void run_ecdsa_sign_verify(void) {
+ int i;
+ for (i = 0; i < 10*count; i++) {
+ test_ecdsa_sign_verify();
+ }
+}
+
+/** Dummy nonce generation function that just uses a precomputed nonce, and fails if it is not accepted. Use only for testing. */
+static int precomputed_nonce_function(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, unsigned int counter, const void *data) {
+ (void)msg32;
+ (void)key32;
+ memcpy(nonce32, data, 32);
+ return (counter == 0);
+}
+
+static int nonce_function_test_fail(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, unsigned int counter, const void *data) {
+ /* Dummy nonce generator that has a fatal error on the first counter value. */
+ if (counter == 0) {
+ return 0;
+ }
+ return nonce_function_rfc6979(nonce32, msg32, key32, counter - 1, data);
+}
+
+static int nonce_function_test_retry(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, unsigned int counter, const void *data) {
+ /* Dummy nonce generator that produces unacceptable nonces for the first several counter values. */
+ if (counter < 3) {
+ memset(nonce32, counter==0 ? 0 : 255, 32);
+ if (counter == 2) {
+ nonce32[31]--;
+ }
+ return 1;
+ }
+ if (counter < 5) {
+ static const unsigned char order[] = {
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,
+ 0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,
+ 0xBF,0xD2,0x5E,0x8C,0xD0,0x36,0x41,0x41
+ };
+ memcpy(nonce32, order, 32);
+ if (counter == 4) {
+ nonce32[31]++;
+ }
+ return 1;
+ }
+ /* Retry rate of 6979 is negligible esp. as we only call this in determinstic tests. */
+ /* If someone does fine a case where it retries for secp256k1, we'd like to know. */
+ if (counter > 5) {
+ return 0;
+ }
+ return nonce_function_rfc6979(nonce32, msg32, key32, counter - 5, data);
+}
+
+int is_empty_compact_signature(const unsigned char *sig64) {
+ static const unsigned char res[64] = {0};
+ return memcmp(sig64, res, 64) == 0;
+}
+
+void test_ecdsa_end_to_end(void) {
+ unsigned char extra[32] = {0x00};
+ unsigned char privkey[32];
+ unsigned char message[32];
+ unsigned char privkey2[32];
+ unsigned char csignature[64];
+ unsigned char signature[72];
+ unsigned char signature2[72];
+ unsigned char signature3[72];
+ unsigned char signature4[72];
+ unsigned char pubkey[65];
+ unsigned char recpubkey[65];
+ unsigned char seckey[300];
+ int signaturelen = 72;
+ int signaturelen2 = 72;
+ int signaturelen3 = 72;
+ int signaturelen4 = 72;
+ int recid = 0;
+ int recpubkeylen = 0;
+ int pubkeylen = 65;
+ int seckeylen = 300;
+
+ /* Generate a random key and message. */
+ {
+ secp256k1_scalar_t msg, key;
+ random_scalar_order_test(&msg);
+ random_scalar_order_test(&key);
+ secp256k1_scalar_get_b32(privkey, &key);
+ secp256k1_scalar_get_b32(message, &msg);
+ }
+
+ /* Construct and verify corresponding public key. */
+ CHECK(secp256k1_ec_seckey_verify(ctx, privkey) == 1);
+ CHECK(secp256k1_ec_pubkey_create(ctx, pubkey, &pubkeylen, privkey, (secp256k1_rand32() & 3) != 0) == 1);
+ if (secp256k1_rand32() & 1) {
+ CHECK(secp256k1_ec_pubkey_decompress(ctx, pubkey, &pubkeylen));
+ }
+ CHECK(secp256k1_ec_pubkey_verify(ctx, pubkey, pubkeylen));
+
+ /* Verify private key import and export. */
+ CHECK(secp256k1_ec_privkey_export(ctx, privkey, seckey, &seckeylen, secp256k1_rand32() % 2) == 1);
+ CHECK(secp256k1_ec_privkey_import(ctx, privkey2, seckey, seckeylen) == 1);
+ CHECK(memcmp(privkey, privkey2, 32) == 0);
+
+ /* Optionally tweak the keys using addition. */
+ if (secp256k1_rand32() % 3 == 0) {
+ int ret1;
+ int ret2;
+ unsigned char rnd[32];
+ unsigned char pubkey2[65];
+ int pubkeylen2 = 65;
+ secp256k1_rand256_test(rnd);
+ ret1 = secp256k1_ec_privkey_tweak_add(ctx, privkey, rnd);
+ ret2 = secp256k1_ec_pubkey_tweak_add(ctx, pubkey, pubkeylen, rnd);
+ CHECK(ret1 == ret2);
+ if (ret1 == 0) {
+ return;
+ }
+ CHECK(secp256k1_ec_pubkey_create(ctx, pubkey2, &pubkeylen2, privkey, pubkeylen == 33) == 1);
+ CHECK(memcmp(pubkey, pubkey2, pubkeylen) == 0);
+ }
+
+ /* Optionally tweak the keys using multiplication. */
+ if (secp256k1_rand32() % 3 == 0) {
+ int ret1;
+ int ret2;
+ unsigned char rnd[32];
+ unsigned char pubkey2[65];
+ int pubkeylen2 = 65;
+ secp256k1_rand256_test(rnd);
+ ret1 = secp256k1_ec_privkey_tweak_mul(ctx, privkey, rnd);
+ ret2 = secp256k1_ec_pubkey_tweak_mul(ctx, pubkey, pubkeylen, rnd);
+ CHECK(ret1 == ret2);
+ if (ret1 == 0) {
+ return;
+ }
+ CHECK(secp256k1_ec_pubkey_create(ctx, pubkey2, &pubkeylen2, privkey, pubkeylen == 33) == 1);
+ CHECK(memcmp(pubkey, pubkey2, pubkeylen) == 0);
+ }
+
+ /* Sign. */
+ CHECK(secp256k1_ecdsa_sign(ctx, message, signature, &signaturelen, privkey, NULL, NULL) == 1);
+ CHECK(signaturelen > 0);
+ CHECK(secp256k1_ecdsa_sign(ctx, message, signature2, &signaturelen2, privkey, NULL, extra) == 1);
+ CHECK(signaturelen2 > 0);
+ extra[31] = 1;
+ CHECK(secp256k1_ecdsa_sign(ctx, message, signature3, &signaturelen3, privkey, NULL, extra) == 1);
+ CHECK(signaturelen3 > 0);
+ extra[31] = 0;
+ extra[0] = 1;
+ CHECK(secp256k1_ecdsa_sign(ctx, message, signature4, &signaturelen4, privkey, NULL, extra) == 1);
+ CHECK(signaturelen3 > 0);
+ CHECK((signaturelen != signaturelen2) || (memcmp(signature, signature2, signaturelen) != 0));
+ CHECK((signaturelen != signaturelen3) || (memcmp(signature, signature3, signaturelen) != 0));
+ CHECK((signaturelen3 != signaturelen2) || (memcmp(signature3, signature2, signaturelen3) != 0));
+ CHECK((signaturelen4 != signaturelen3) || (memcmp(signature4, signature3, signaturelen4) != 0));
+ CHECK((signaturelen4 != signaturelen2) || (memcmp(signature4, signature2, signaturelen4) != 0));
+ CHECK((signaturelen4 != signaturelen) || (memcmp(signature4, signature, signaturelen4) != 0));
+ /* Verify. */
+ CHECK(secp256k1_ecdsa_verify(ctx, message, signature, signaturelen, pubkey, pubkeylen) == 1);
+ CHECK(secp256k1_ecdsa_verify(ctx, message, signature2, signaturelen2, pubkey, pubkeylen) == 1);
+ CHECK(secp256k1_ecdsa_verify(ctx, message, signature3, signaturelen3, pubkey, pubkeylen) == 1);
+ CHECK(secp256k1_ecdsa_verify(ctx, message, signature4, signaturelen4, pubkey, pubkeylen) == 1);
+ /* Destroy signature and verify again. */
+ signature[signaturelen - 1 - secp256k1_rand32() % 20] += 1 + (secp256k1_rand32() % 255);
+ CHECK(secp256k1_ecdsa_verify(ctx, message, signature, signaturelen, pubkey, pubkeylen) != 1);
+
+ /* Compact sign. */
+ CHECK(secp256k1_ecdsa_sign_compact(ctx, message, csignature, privkey, NULL, NULL, &recid) == 1);
+ CHECK(!is_empty_compact_signature(csignature));
+ /* Recover. */
+ CHECK(secp256k1_ecdsa_recover_compact(ctx, message, csignature, recpubkey, &recpubkeylen, pubkeylen == 33, recid) == 1);
+ CHECK(recpubkeylen == pubkeylen);
+ CHECK(memcmp(pubkey, recpubkey, pubkeylen) == 0);
+ /* Destroy signature and verify again. */
+ csignature[secp256k1_rand32() % 64] += 1 + (secp256k1_rand32() % 255);
+ CHECK(secp256k1_ecdsa_recover_compact(ctx, message, csignature, recpubkey, &recpubkeylen, pubkeylen == 33, recid) != 1 ||
+ memcmp(pubkey, recpubkey, pubkeylen) != 0);
+ CHECK(recpubkeylen == pubkeylen);
+
+}
+
+void test_random_pubkeys(void) {
+ secp256k1_ge_t elem;
+ secp256k1_ge_t elem2;
+ unsigned char in[65];
+ /* Generate some randomly sized pubkeys. */
+ uint32_t r = secp256k1_rand32();
+ int len = (r & 3) == 0 ? 65 : 33;
+ r>>=2;
+ if ((r & 3) == 0) {
+ len = (r & 252) >> 3;
+ }
+ r>>=8;
+ if (len == 65) {
+ in[0] = (r & 2) ? 4 : (r & 1? 6 : 7);
+ } else {
+ in[0] = (r & 1) ? 2 : 3;
+ }
+ r>>=2;
+ if ((r & 7) == 0) {
+ in[0] = (r & 2040) >> 3;
+ }
+ r>>=11;
+ if (len > 1) {
+ secp256k1_rand256(&in[1]);
+ }
+ if (len > 33) {
+ secp256k1_rand256(&in[33]);
+ }
+ if (secp256k1_eckey_pubkey_parse(&elem, in, len)) {
+ unsigned char out[65];
+ unsigned char firstb;
+ int res;
+ int size = len;
+ firstb = in[0];
+ /* If the pubkey can be parsed, it should round-trip... */
+ CHECK(secp256k1_eckey_pubkey_serialize(&elem, out, &size, len == 33));
+ CHECK(size == len);
+ CHECK(memcmp(&in[1], &out[1], len-1) == 0);
+ /* ... except for the type of hybrid inputs. */
+ if ((in[0] != 6) && (in[0] != 7)) {
+ CHECK(in[0] == out[0]);
+ }
+ size = 65;
+ CHECK(secp256k1_eckey_pubkey_serialize(&elem, in, &size, 0));
+ CHECK(size == 65);
+ CHECK(secp256k1_eckey_pubkey_parse(&elem2, in, size));
+ ge_equals_ge(&elem,&elem2);
+ /* Check that the X9.62 hybrid type is checked. */
+ in[0] = (r & 1) ? 6 : 7;
+ res = secp256k1_eckey_pubkey_parse(&elem2, in, size);
+ if (firstb == 2 || firstb == 3) {
+ if (in[0] == firstb + 4) {
+ CHECK(res);
+ } else {
+ CHECK(!res);
+ }
+ }
+ if (res) {
+ ge_equals_ge(&elem,&elem2);
+ CHECK(secp256k1_eckey_pubkey_serialize(&elem, out, &size, 0));
+ CHECK(memcmp(&in[1], &out[1], 64) == 0);
+ }
+ }
+}
+
+void run_random_pubkeys(void) {
+ int i;
+ for (i = 0; i < 10*count; i++) {
+ test_random_pubkeys();
+ }
+}
+
+void run_ecdsa_end_to_end(void) {
+ int i;
+ for (i = 0; i < 64*count; i++) {
+ test_ecdsa_end_to_end();
+ }
+}
+
+/* Tests several edge cases. */
+void test_ecdsa_edge_cases(void) {
+ const unsigned char msg32[32] = {
+ 'T', 'h', 'i', 's', ' ', 'i', 's', ' ',
+ 'a', ' ', 'v', 'e', 'r', 'y', ' ', 's',
+ 'e', 'c', 'r', 'e', 't', ' ', 'm', 'e',
+ 's', 's', 'a', 'g', 'e', '.', '.', '.'
+ };
+ const unsigned char sig64[64] = {
+ /* Generated by signing the above message with nonce 'This is the nonce we will use...'
+ * and secret key 0 (which is not valid), resulting in recid 0. */
+ 0x67, 0xCB, 0x28, 0x5F, 0x9C, 0xD1, 0x94, 0xE8,
+ 0x40, 0xD6, 0x29, 0x39, 0x7A, 0xF5, 0x56, 0x96,
+ 0x62, 0xFD, 0xE4, 0x46, 0x49, 0x99, 0x59, 0x63,
+ 0x17, 0x9A, 0x7D, 0xD1, 0x7B, 0xD2, 0x35, 0x32,
+ 0x4B, 0x1B, 0x7D, 0xF3, 0x4C, 0xE1, 0xF6, 0x8E,
+ 0x69, 0x4F, 0xF6, 0xF1, 0x1A, 0xC7, 0x51, 0xDD,
+ 0x7D, 0xD7, 0x3E, 0x38, 0x7E, 0xE4, 0xFC, 0x86,
+ 0x6E, 0x1B, 0xE8, 0xEC, 0xC7, 0xDD, 0x95, 0x57
+ };
+ unsigned char pubkey[65];
+ int t;
+ int pubkeylen = 65;
+ /* signature (r,s) = (4,4), which can be recovered with all 4 recids. */
+ const unsigned char sigb64[64] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+ };
+ unsigned char pubkeyb[33];
+ int pubkeyblen = 33;
+ int recid;
+
+ CHECK(!secp256k1_ecdsa_recover_compact(ctx, msg32, sig64, pubkey, &pubkeylen, 0, 0));
+ CHECK(secp256k1_ecdsa_recover_compact(ctx, msg32, sig64, pubkey, &pubkeylen, 0, 1));
+ CHECK(!secp256k1_ecdsa_recover_compact(ctx, msg32, sig64, pubkey, &pubkeylen, 0, 2));
+ CHECK(!secp256k1_ecdsa_recover_compact(ctx, msg32, sig64, pubkey, &pubkeylen, 0, 3));
+
+ for (recid = 0; recid < 4; recid++) {
+ int i;
+ int recid2;
+ /* (4,4) encoded in DER. */
+ unsigned char sigbder[8] = {0x30, 0x06, 0x02, 0x01, 0x04, 0x02, 0x01, 0x04};
+ unsigned char sigcder_zr[7] = {0x30, 0x05, 0x02, 0x00, 0x02, 0x01, 0x01};
+ unsigned char sigcder_zs[7] = {0x30, 0x05, 0x02, 0x01, 0x01, 0x02, 0x00};
+ unsigned char sigbderalt1[39] = {
+ 0x30, 0x25, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x04, 0x02, 0x01, 0x04,
+ };
+ unsigned char sigbderalt2[39] = {
+ 0x30, 0x25, 0x02, 0x01, 0x04, 0x02, 0x20, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+ };
+ unsigned char sigbderalt3[40] = {
+ 0x30, 0x26, 0x02, 0x21, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x01, 0x04,
+ };
+ unsigned char sigbderalt4[40] = {
+ 0x30, 0x26, 0x02, 0x01, 0x04, 0x02, 0x21, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+ };
+ /* (order + r,4) encoded in DER. */
+ unsigned char sigbderlong[40] = {
+ 0x30, 0x26, 0x02, 0x21, 0x00, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC,
+ 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E,
+ 0x8C, 0xD0, 0x36, 0x41, 0x45, 0x02, 0x01, 0x04
+ };
+ CHECK(secp256k1_ecdsa_recover_compact(ctx, msg32, sigb64, pubkeyb, &pubkeyblen, 1, recid));
+ CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbder, sizeof(sigbder), pubkeyb, pubkeyblen) == 1);
+ for (recid2 = 0; recid2 < 4; recid2++) {
+ unsigned char pubkey2b[33];
+ int pubkey2blen = 33;
+ CHECK(secp256k1_ecdsa_recover_compact(ctx, msg32, sigb64, pubkey2b, &pubkey2blen, 1, recid2));
+ /* Verifying with (order + r,4) should always fail. */
+ CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbderlong, sizeof(sigbderlong), pubkey2b, pubkey2blen) != 1);
+ }
+ /* DER parsing tests. */
+ /* Zero length r/s. */
+ CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigcder_zr, sizeof(sigcder_zr), pubkeyb, pubkeyblen) == -2);
+ CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigcder_zs, sizeof(sigcder_zs), pubkeyb, pubkeyblen) == -2);
+ /* Leading zeros. */
+ CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbderalt1, sizeof(sigbderalt1), pubkeyb, pubkeyblen) == 1);
+ CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbderalt2, sizeof(sigbderalt2), pubkeyb, pubkeyblen) == 1);
+ CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbderalt3, sizeof(sigbderalt3), pubkeyb, pubkeyblen) == 1);
+ CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbderalt4, sizeof(sigbderalt4), pubkeyb, pubkeyblen) == 1);
+ sigbderalt3[4] = 1;
+ CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbderalt3, sizeof(sigbderalt3), pubkeyb, pubkeyblen) == -2);
+ sigbderalt4[7] = 1;
+ CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbderalt4, sizeof(sigbderalt4), pubkeyb, pubkeyblen) == -2);
+ /* Damage signature. */
+ sigbder[7]++;
+ CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbder, sizeof(sigbder), pubkeyb, pubkeyblen) == 0);
+ sigbder[7]--;
+ CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbder, 6, pubkeyb, pubkeyblen) == -2);
+ CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbder, sizeof(sigbder)-1, pubkeyb, pubkeyblen) == -2);
+ for(i = 0; i < 8; i++) {
+ int c;
+ unsigned char orig = sigbder[i];
+ /*Try every single-byte change.*/
+ for (c = 0; c < 256; c++) {
+ if (c == orig ) {
+ continue;
+ }
+ sigbder[i] = c;
+ CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbder, sizeof(sigbder), pubkeyb, pubkeyblen) ==
+ (i==4 || i==7) ? 0 : -2 );
+ }
+ sigbder[i] = orig;
+ }
+ }
+
+ /* Test the case where ECDSA recomputes a point that is infinity. */
+ {
+ secp256k1_gej_t keyj;
+ secp256k1_ge_t key;
+ secp256k1_scalar_t msg;
+ secp256k1_ecdsa_sig_t sig;
+ secp256k1_scalar_set_int(&sig.s, 1);
+ secp256k1_scalar_negate(&sig.s, &sig.s);
+ secp256k1_scalar_inverse(&sig.s, &sig.s);
+ secp256k1_scalar_set_int(&sig.r, 1);
+ secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &keyj, &sig.r);
+ secp256k1_ge_set_gej(&key, &keyj);
+ msg = sig.s;
+ CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sig, &key, &msg) == 0);
+ }
+
+ /* Test r/s equal to zero */
+ {
+ /* (1,1) encoded in DER. */
+ unsigned char sigcder[8] = {0x30, 0x06, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01};
+ unsigned char sigc64[64] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ };
+ unsigned char pubkeyc[65];
+ int pubkeyclen = 65;
+ CHECK(secp256k1_ecdsa_recover_compact(ctx, msg32, sigc64, pubkeyc, &pubkeyclen, 0, 0) == 1);
+ CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigcder, sizeof(sigcder), pubkeyc, pubkeyclen) == 1);
+ sigcder[4] = 0;
+ sigc64[31] = 0;
+ CHECK(secp256k1_ecdsa_recover_compact(ctx, msg32, sigc64, pubkeyb, &pubkeyblen, 1, 0) == 0);
+ CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigcder, sizeof(sigcder), pubkeyc, pubkeyclen) == 0);
+ sigcder[4] = 1;
+ sigcder[7] = 0;
+ sigc64[31] = 1;
+ sigc64[63] = 0;
+ CHECK(secp256k1_ecdsa_recover_compact(ctx, msg32, sigc64, pubkeyb, &pubkeyblen, 1, 0) == 0);
+ CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigcder, sizeof(sigcder), pubkeyc, pubkeyclen) == 0);
+ }
+
+ /*Signature where s would be zero.*/
+ {
+ const unsigned char nonce[32] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ };
+ static const unsigned char nonce2[32] = {
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,
+ 0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,
+ 0xBF,0xD2,0x5E,0x8C,0xD0,0x36,0x41,0x40
+ };
+ const unsigned char key[32] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ };
+ unsigned char msg[32] = {
+ 0x86, 0x41, 0x99, 0x81, 0x06, 0x23, 0x44, 0x53,
+ 0xaa, 0x5f, 0x9d, 0x6a, 0x31, 0x78, 0xf4, 0xf7,
+ 0xb8, 0x12, 0xe0, 0x0b, 0x81, 0x7a, 0x77, 0x62,
+ 0x65, 0xdf, 0xdd, 0x31, 0xb9, 0x3e, 0x29, 0xa9,
+ };
+ unsigned char sig[72];
+ int siglen = 72;
+ CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, precomputed_nonce_function, nonce) == 0);
+ CHECK(siglen == 0);
+ CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, precomputed_nonce_function, nonce2) == 0);
+ CHECK(siglen == 0);
+ msg[31] = 0xaa;
+ siglen = 72;
+ CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, precomputed_nonce_function, nonce) == 1);
+ CHECK(siglen > 0);
+ CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, precomputed_nonce_function, nonce2) == 1);
+ CHECK(siglen > 0);
+ siglen = 10;
+ CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, precomputed_nonce_function, nonce) != 1);
+ CHECK(siglen == 0);
+ }
+
+ /* Nonce function corner cases. */
+ for (t = 0; t < 2; t++) {
+ static const unsigned char zero[32] = {0x00};
+ int i;
+ unsigned char key[32];
+ unsigned char msg[32];
+ unsigned char sig[72];
+ unsigned char sig2[72];
+ secp256k1_ecdsa_sig_t s[512];
+ int siglen = 72;
+ int siglen2 = 72;
+ int recid2;
+ const unsigned char *extra;
+ extra = t == 0 ? NULL : zero;
+ memset(msg, 0, 32);
+ msg[31] = 1;
+ /* High key results in signature failure. */
+ memset(key, 0xFF, 32);
+ CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, NULL, extra) == 0);
+ CHECK(siglen == 0);
+ /* Zero key results in signature failure. */
+ memset(key, 0, 32);
+ CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, NULL, extra) == 0);
+ CHECK(siglen == 0);
+ /* Nonce function failure results in signature failure. */
+ key[31] = 1;
+ CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, nonce_function_test_fail, extra) == 0);
+ CHECK(siglen == 0);
+ CHECK(secp256k1_ecdsa_sign_compact(ctx, msg, sig, key, nonce_function_test_fail, extra, &recid) == 0);
+ CHECK(is_empty_compact_signature(sig));
+ /* The retry loop successfully makes its way to the first good value. */
+ siglen = 72;
+ CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, nonce_function_test_retry, extra) == 1);
+ CHECK(siglen > 0);
+ CHECK(secp256k1_ecdsa_sign(ctx, msg, sig2, &siglen2, key, nonce_function_rfc6979, extra) == 1);
+ CHECK(siglen > 0);
+ CHECK((siglen == siglen2) && (memcmp(sig, sig2, siglen) == 0));
+ CHECK(secp256k1_ecdsa_sign_compact(ctx, msg, sig, key, nonce_function_test_retry, extra, &recid) == 1);
+ CHECK(!is_empty_compact_signature(sig));
+ CHECK(secp256k1_ecdsa_sign_compact(ctx, msg, sig2, key, nonce_function_rfc6979, extra, &recid2) == 1);
+ CHECK(!is_empty_compact_signature(sig2));
+ CHECK((recid == recid2) && (memcmp(sig, sig2, 64) == 0));
+ /* The default nonce function is determinstic. */
+ siglen = 72;
+ siglen2 = 72;
+ CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, NULL, extra) == 1);
+ CHECK(siglen > 0);
+ CHECK(secp256k1_ecdsa_sign(ctx, msg, sig2, &siglen2, key, NULL, extra) == 1);
+ CHECK(siglen2 > 0);
+ CHECK((siglen == siglen2) && (memcmp(sig, sig2, siglen) == 0));
+ CHECK(secp256k1_ecdsa_sign_compact(ctx, msg, sig, key, NULL, extra, &recid) == 1);
+ CHECK(!is_empty_compact_signature(sig));
+ CHECK(secp256k1_ecdsa_sign_compact(ctx, msg, sig2, key, NULL, extra, &recid2) == 1);
+ CHECK(!is_empty_compact_signature(sig));
+ CHECK((recid == recid2) && (memcmp(sig, sig2, 64) == 0));
+ /* The default nonce function changes output with different messages. */
+ for(i = 0; i < 256; i++) {
+ int j;
+ siglen2 = 72;
+ msg[0] = i;
+ CHECK(secp256k1_ecdsa_sign(ctx, msg, sig2, &siglen2, key, NULL, extra) == 1);
+ CHECK(!is_empty_compact_signature(sig));
+ CHECK(secp256k1_ecdsa_sig_parse(&s[i], sig2, siglen2));
+ for (j = 0; j < i; j++) {
+ CHECK(!secp256k1_scalar_eq(&s[i].r, &s[j].r));
+ }
+ }
+ msg[0] = 0;
+ msg[31] = 2;
+ /* The default nonce function changes output with different keys. */
+ for(i = 256; i < 512; i++) {
+ int j;
+ siglen2 = 72;
+ key[0] = i - 256;
+ CHECK(secp256k1_ecdsa_sign(ctx, msg, sig2, &siglen2, key, NULL, extra) == 1);
+ CHECK(secp256k1_ecdsa_sig_parse(&s[i], sig2, siglen2));
+ for (j = 0; j < i; j++) {
+ CHECK(!secp256k1_scalar_eq(&s[i].r, &s[j].r));
+ }
+ }
+ key[0] = 0;
+ }
+
+ /* Privkey export where pubkey is the point at infinity. */
+ {
+ unsigned char privkey[300];
+ unsigned char seckey[32] = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
+ 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b,
+ 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x41,
+ };
+ int outlen = 300;
+ CHECK(!secp256k1_ec_privkey_export(ctx, seckey, privkey, &outlen, 0));
+ CHECK(!secp256k1_ec_privkey_export(ctx, seckey, privkey, &outlen, 1));
+ }
+}
+
+void run_ecdsa_edge_cases(void) {
+ test_ecdsa_edge_cases();
+}
+
+#ifdef ENABLE_OPENSSL_TESTS
+EC_KEY *get_openssl_key(const secp256k1_scalar_t *key) {
+ unsigned char privkey[300];
+ int privkeylen;
+ const unsigned char* pbegin = privkey;
+ int compr = secp256k1_rand32() & 1;
+ EC_KEY *ec_key = EC_KEY_new_by_curve_name(NID_secp256k1);
+ CHECK(secp256k1_eckey_privkey_serialize(&ctx->ecmult_gen_ctx, privkey, &privkeylen, key, compr));
+ CHECK(d2i_ECPrivateKey(&ec_key, &pbegin, privkeylen));
+ CHECK(EC_KEY_check_key(ec_key));
+ return ec_key;
+}
+
+void test_ecdsa_openssl(void) {
+ secp256k1_gej_t qj;
+ secp256k1_ge_t q;
+ secp256k1_ecdsa_sig_t sig;
+ secp256k1_scalar_t one;
+ secp256k1_scalar_t msg2;
+ secp256k1_scalar_t key, msg;
+ EC_KEY *ec_key;
+ unsigned int sigsize = 80;
+ int secp_sigsize = 80;
+ unsigned char message[32];
+ unsigned char signature[80];
+ secp256k1_rand256_test(message);
+ secp256k1_scalar_set_b32(&msg, message, NULL);
+ random_scalar_order_test(&key);
+ secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &qj, &key);
+ secp256k1_ge_set_gej(&q, &qj);
+ ec_key = get_openssl_key(&key);
+ CHECK(ec_key);
+ CHECK(ECDSA_sign(0, message, sizeof(message), signature, &sigsize, ec_key));
+ CHECK(secp256k1_ecdsa_sig_parse(&sig, signature, sigsize));
+ CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sig, &q, &msg));
+ secp256k1_scalar_set_int(&one, 1);
+ secp256k1_scalar_add(&msg2, &msg, &one);
+ CHECK(!secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sig, &q, &msg2));
+
+ random_sign(&sig, &key, &msg, NULL);
+ CHECK(secp256k1_ecdsa_sig_serialize(signature, &secp_sigsize, &sig));
+ CHECK(ECDSA_verify(0, message, sizeof(message), signature, secp_sigsize, ec_key) == 1);
+
+ EC_KEY_free(ec_key);
+}
+
+void run_ecdsa_openssl(void) {
+ int i;
+ for (i = 0; i < 10*count; i++) {
+ test_ecdsa_openssl();
+ }
+}
+#endif
+
+int main(int argc, char **argv) {
+ unsigned char seed16[16] = {0};
+ unsigned char run32[32] = {0};
+ /* find iteration count */
+ if (argc > 1) {
+ count = strtol(argv[1], NULL, 0);
+ }
+
+ /* find random seed */
+ if (argc > 2) {
+ int pos = 0;
+ const char* ch = argv[2];
+ while (pos < 16 && ch[0] != 0 && ch[1] != 0) {
+ unsigned short sh;
+ if (sscanf(ch, "%2hx", &sh)) {
+ seed16[pos] = sh;
+ } else {
+ break;
+ }
+ ch += 2;
+ pos++;
+ }
+ } else {
+ FILE *frand = fopen("/dev/urandom", "r");
+ if (!frand || !fread(&seed16, sizeof(seed16), 1, frand)) {
+ uint64_t t = time(NULL) * (uint64_t)1337;
+ seed16[0] ^= t;
+ seed16[1] ^= t >> 8;
+ seed16[2] ^= t >> 16;
+ seed16[3] ^= t >> 24;
+ seed16[4] ^= t >> 32;
+ seed16[5] ^= t >> 40;
+ seed16[6] ^= t >> 48;
+ seed16[7] ^= t >> 56;
+ }
+ fclose(frand);
+ }
+ secp256k1_rand_seed(seed16);
+
+ printf("test count = %i\n", count);
+ printf("random seed = %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", seed16[0], seed16[1], seed16[2], seed16[3], seed16[4], seed16[5], seed16[6], seed16[7], seed16[8], seed16[9], seed16[10], seed16[11], seed16[12], seed16[13], seed16[14], seed16[15]);
+
+ /* initialize */
+ run_context_tests();
+ ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
+
+ if (secp256k1_rand32() & 1) {
+ secp256k1_rand256(run32);
+ CHECK(secp256k1_context_randomize(ctx, secp256k1_rand32() & 1 ? run32 : NULL));
+ }
+
+ run_sha256_tests();
+ run_hmac_sha256_tests();
+ run_rfc6979_hmac_sha256_tests();
+
+#ifndef USE_NUM_NONE
+ /* num tests */
+ run_num_smalltests();
+#endif
+
+ /* scalar tests */
+ run_scalar_tests();
+
+ /* field tests */
+ run_field_inv();
+ run_field_inv_var();
+ run_field_inv_all_var();
+ run_field_misc();
+ run_field_convert();
+ run_sqr();
+ run_sqrt();
+
+ /* group tests */
+ run_ge();
+
+ /* ecmult tests */
+ run_wnaf();
+ run_point_times_order();
+ run_ecmult_chain();
+ run_ecmult_constants();
+ run_ecmult_gen_blind();
+
+ /* ecdsa tests */
+ run_random_pubkeys();
+ run_ecdsa_sign_verify();
+ run_ecdsa_end_to_end();
+ run_ecdsa_edge_cases();
+#ifdef ENABLE_OPENSSL_TESTS
+ run_ecdsa_openssl();
+#endif
+
+ secp256k1_rand256(run32);
+ printf("random run = %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", run32[0], run32[1], run32[2], run32[3], run32[4], run32[5], run32[6], run32[7], run32[8], run32[9], run32[10], run32[11], run32[12], run32[13], run32[14], run32[15]);
+
+ /* shutdown */
+ secp256k1_context_destroy(ctx);
+ return 0;
+}
diff --git a/src/secp256k1/src/util.h b/src/secp256k1/src/util.h
new file mode 100644
index 0000000000..ae98639f7c
--- /dev/null
+++ b/src/secp256k1/src/util.h
@@ -0,0 +1,104 @@
+/**********************************************************************
+ * Copyright (c) 2013, 2014 Pieter Wuille *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
+ **********************************************************************/
+
+#ifndef _SECP256K1_UTIL_H_
+#define _SECP256K1_UTIL_H_
+
+#if defined HAVE_CONFIG_H
+#include "libsecp256k1-config.h"
+#endif
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdio.h>
+
+#ifdef DETERMINISTIC
+#define TEST_FAILURE(msg) do { \
+ fprintf(stderr, "%s\n", msg); \
+ abort(); \
+} while(0);
+#else
+#define TEST_FAILURE(msg) do { \
+ fprintf(stderr, "%s:%d: %s\n", __FILE__, __LINE__, msg); \
+ abort(); \
+} while(0)
+#endif
+
+#ifdef HAVE_BUILTIN_EXPECT
+#define EXPECT(x,c) __builtin_expect((x),(c))
+#else
+#define EXPECT(x,c) (x)
+#endif
+
+#ifdef DETERMINISTIC
+#define CHECK(cond) do { \
+ if (EXPECT(!(cond), 0)) { \
+ TEST_FAILURE("test condition failed"); \
+ } \
+} while(0)
+#else
+#define CHECK(cond) do { \
+ if (EXPECT(!(cond), 0)) { \
+ TEST_FAILURE("test condition failed: " #cond); \
+ } \
+} while(0)
+#endif
+
+/* Like assert(), but safe to use on expressions with side effects. */
+#ifndef NDEBUG
+#define DEBUG_CHECK CHECK
+#else
+#define DEBUG_CHECK(cond) do { (void)(cond); } while(0)
+#endif
+
+/* Like DEBUG_CHECK(), but when VERIFY is defined instead of NDEBUG not defined. */
+#ifdef VERIFY
+#define VERIFY_CHECK CHECK
+#else
+#define VERIFY_CHECK(cond) do { (void)(cond); } while(0)
+#endif
+
+static SECP256K1_INLINE void *checked_malloc(size_t size) {
+ void *ret = malloc(size);
+ CHECK(ret != NULL);
+ return ret;
+}
+
+/* Macro for restrict, when available and not in a VERIFY build. */
+#if defined(SECP256K1_BUILD) && defined(VERIFY)
+# define SECP256K1_RESTRICT
+#else
+# if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) )
+# if SECP256K1_GNUC_PREREQ(3,0)
+# define SECP256K1_RESTRICT __restrict__
+# elif (defined(_MSC_VER) && _MSC_VER >= 1400)
+# define SECP256K1_RESTRICT __restrict
+# else
+# define SECP256K1_RESTRICT
+# endif
+# else
+# define SECP256K1_RESTRICT restrict
+# endif
+#endif
+
+#if defined(_WIN32)
+# define I64FORMAT "I64d"
+# define I64uFORMAT "I64u"
+#else
+# define I64FORMAT "lld"
+# define I64uFORMAT "llu"
+#endif
+
+#if defined(HAVE___INT128)
+# if defined(__GNUC__)
+# define SECP256K1_GNUC_EXT __extension__
+# else
+# define SECP256K1_GNUC_EXT
+# endif
+SECP256K1_GNUC_EXT typedef unsigned __int128 uint128_t;
+#endif
+
+#endif
diff --git a/src/serialize.h b/src/serialize.h
new file mode 100644
index 0000000000..53d8af142f
--- /dev/null
+++ b/src/serialize.h
@@ -0,0 +1,860 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT 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 "compat/endian.h"
+
+#include <algorithm>
+#include <assert.h>
+#include <ios>
+#include <limits>
+#include <map>
+#include <set>
+#include <stdint.h>
+#include <string>
+#include <string.h>
+#include <utility>
+#include <vector>
+
+class CScript;
+
+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<typename T>
+inline T& REF(const T& val)
+{
+ return const_cast<T&>(val);
+}
+
+/**
+ * Used to acquire a non-const pointer "this" to generate bodies
+ * of const serialization operations from a template
+ */
+template<typename T>
+inline T* NCONST_PTR(const T* val)
+{
+ return const_cast<T*>(val);
+}
+
+/**
+ * Get begin pointer of vector (non-const version).
+ * @note These functions avoid the undefined case of indexing into an empty
+ * vector, as well as that of indexing after the end of the vector.
+ */
+template <class T, class TAl>
+inline T* begin_ptr(std::vector<T,TAl>& v)
+{
+ return v.empty() ? NULL : &v[0];
+}
+/** Get begin pointer of vector (const version) */
+template <class T, class TAl>
+inline const T* begin_ptr(const std::vector<T,TAl>& v)
+{
+ return v.empty() ? NULL : &v[0];
+}
+/** Get end pointer of vector (non-const version) */
+template <class T, class TAl>
+inline T* end_ptr(std::vector<T,TAl>& v)
+{
+ return v.empty() ? NULL : (&v[0] + v.size());
+}
+/** Get end pointer of vector (const version) */
+template <class T, class TAl>
+inline const T* end_ptr(const std::vector<T,TAl>& v)
+{
+ return v.empty() ? NULL : (&v[0] + v.size());
+}
+
+/*
+ * Lowest-level serialization and conversion.
+ * @note Sizes of these types are verified in the tests
+ */
+template<typename Stream> inline void ser_writedata8(Stream &s, uint8_t obj)
+{
+ s.write((char*)&obj, 1);
+}
+template<typename Stream> inline void ser_writedata16(Stream &s, uint16_t obj)
+{
+ obj = htole16(obj);
+ s.write((char*)&obj, 2);
+}
+template<typename Stream> inline void ser_writedata32(Stream &s, uint32_t obj)
+{
+ obj = htole32(obj);
+ s.write((char*)&obj, 4);
+}
+template<typename Stream> inline void ser_writedata64(Stream &s, uint64_t obj)
+{
+ obj = htole64(obj);
+ s.write((char*)&obj, 8);
+}
+template<typename Stream> inline uint8_t ser_readdata8(Stream &s)
+{
+ uint8_t obj;
+ s.read((char*)&obj, 1);
+ return obj;
+}
+template<typename Stream> inline uint16_t ser_readdata16(Stream &s)
+{
+ uint16_t obj;
+ s.read((char*)&obj, 2);
+ return le16toh(obj);
+}
+template<typename Stream> inline uint32_t ser_readdata32(Stream &s)
+{
+ uint32_t obj;
+ s.read((char*)&obj, 4);
+ return le32toh(obj);
+}
+template<typename Stream> inline uint64_t ser_readdata64(Stream &s)
+{
+ uint64_t obj;
+ s.read((char*)&obj, 8);
+ return le64toh(obj);
+}
+inline uint64_t ser_double_to_uint64(double x)
+{
+ union { double x; uint64_t y; } tmp;
+ tmp.x = x;
+ return tmp.y;
+}
+inline uint32_t ser_float_to_uint32(float x)
+{
+ union { float x; uint32_t y; } tmp;
+ tmp.x = x;
+ return tmp.y;
+}
+inline double ser_uint64_to_double(uint64_t y)
+{
+ union { double x; uint64_t y; } tmp;
+ tmp.y = y;
+ return tmp.x;
+}
+inline float ser_uint32_to_float(uint32_t y)
+{
+ union { float x; uint32_t y; } tmp;
+ tmp.y = y;
+ return tmp.x;
+}
+
+
+/////////////////////////////////////////////////////////////////
+//
+// Templates for serializing to anything that looks like a stream,
+// i.e. anything that supports .read(char*, size_t) and .write(char*, size_t)
+//
+
+enum
+{
+ // primary actions
+ SER_NETWORK = (1 << 0),
+ SER_DISK = (1 << 1),
+ SER_GETHASH = (1 << 2),
+};
+
+#define READWRITE(obj) (::SerReadWrite(s, (obj), nType, nVersion, ser_action))
+
+/**
+ * Implement three methods for serializable objects. These are actually wrappers over
+ * "SerializationOp" template, which implements the body of each class' serialization
+ * code. Adding "ADD_SERIALIZE_METHODS" in the body of the class causes these wrappers to be
+ * added as members.
+ */
+#define ADD_SERIALIZE_METHODS \
+ size_t GetSerializeSize(int nType, int nVersion) const { \
+ CSizeComputer s(nType, nVersion); \
+ NCONST_PTR(this)->SerializationOp(s, CSerActionSerialize(), nType, nVersion);\
+ return s.size(); \
+ } \
+ template<typename Stream> \
+ void Serialize(Stream& s, int nType, int nVersion) const { \
+ NCONST_PTR(this)->SerializationOp(s, CSerActionSerialize(), nType, nVersion);\
+ } \
+ template<typename Stream> \
+ void Unserialize(Stream& s, int nType, int nVersion) { \
+ SerializationOp(s, CSerActionUnserialize(), nType, nVersion); \
+ }
+
+/*
+ * Basic Types
+ */
+inline unsigned int GetSerializeSize(char a, int, int=0) { return 1; }
+inline unsigned int GetSerializeSize(int8_t a, int, int=0) { return 1; }
+inline unsigned int GetSerializeSize(uint8_t a, int, int=0) { return 1; }
+inline unsigned int GetSerializeSize(int16_t a, int, int=0) { return 2; }
+inline unsigned int GetSerializeSize(uint16_t a, int, int=0) { return 2; }
+inline unsigned int GetSerializeSize(int32_t a, int, int=0) { return 4; }
+inline unsigned int GetSerializeSize(uint32_t a, int, int=0) { return 4; }
+inline unsigned int GetSerializeSize(int64_t a, int, int=0) { return 8; }
+inline unsigned int GetSerializeSize(uint64_t a, int, int=0) { return 8; }
+inline unsigned int GetSerializeSize(float a, int, int=0) { return 4; }
+inline unsigned int GetSerializeSize(double a, int, int=0) { return 8; }
+
+template<typename Stream> inline void Serialize(Stream& s, char a, int, int=0) { ser_writedata8(s, a); } // TODO Get rid of bare char
+template<typename Stream> inline void Serialize(Stream& s, int8_t a, int, int=0) { ser_writedata8(s, a); }
+template<typename Stream> inline void Serialize(Stream& s, uint8_t a, int, int=0) { ser_writedata8(s, a); }
+template<typename Stream> inline void Serialize(Stream& s, int16_t a, int, int=0) { ser_writedata16(s, a); }
+template<typename Stream> inline void Serialize(Stream& s, uint16_t a, int, int=0) { ser_writedata16(s, a); }
+template<typename Stream> inline void Serialize(Stream& s, int32_t a, int, int=0) { ser_writedata32(s, a); }
+template<typename Stream> inline void Serialize(Stream& s, uint32_t a, int, int=0) { ser_writedata32(s, a); }
+template<typename Stream> inline void Serialize(Stream& s, int64_t a, int, int=0) { ser_writedata64(s, a); }
+template<typename Stream> inline void Serialize(Stream& s, uint64_t a, int, int=0) { ser_writedata64(s, a); }
+template<typename Stream> inline void Serialize(Stream& s, float a, int, int=0) { ser_writedata32(s, ser_float_to_uint32(a)); }
+template<typename Stream> inline void Serialize(Stream& s, double a, int, int=0) { ser_writedata64(s, ser_double_to_uint64(a)); }
+
+template<typename Stream> inline void Unserialize(Stream& s, char& a, int, int=0) { a = ser_readdata8(s); } // TODO Get rid of bare char
+template<typename Stream> inline void Unserialize(Stream& s, int8_t& a, int, int=0) { a = ser_readdata8(s); }
+template<typename Stream> inline void Unserialize(Stream& s, uint8_t& a, int, int=0) { a = ser_readdata8(s); }
+template<typename Stream> inline void Unserialize(Stream& s, int16_t& a, int, int=0) { a = ser_readdata16(s); }
+template<typename Stream> inline void Unserialize(Stream& s, uint16_t& a, int, int=0) { a = ser_readdata16(s); }
+template<typename Stream> inline void Unserialize(Stream& s, int32_t& a, int, int=0) { a = ser_readdata32(s); }
+template<typename Stream> inline void Unserialize(Stream& s, uint32_t& a, int, int=0) { a = ser_readdata32(s); }
+template<typename Stream> inline void Unserialize(Stream& s, int64_t& a, int, int=0) { a = ser_readdata64(s); }
+template<typename Stream> inline void Unserialize(Stream& s, uint64_t& a, int, int=0) { a = ser_readdata64(s); }
+template<typename Stream> inline void Unserialize(Stream& s, float& a, int, int=0) { a = ser_uint32_to_float(ser_readdata32(s)); }
+template<typename Stream> inline void Unserialize(Stream& s, double& a, int, int=0) { a = ser_uint64_to_double(ser_readdata64(s)); }
+
+inline unsigned int GetSerializeSize(bool a, int, int=0) { return sizeof(char); }
+template<typename Stream> inline void Serialize(Stream& s, bool a, int, int=0) { char f=a; ser_writedata8(s, f); }
+template<typename Stream> inline void Unserialize(Stream& s, bool& a, int, int=0) { char f=ser_readdata8(s); 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_t nSize)
+{
+ if (nSize < 253) return sizeof(unsigned char);
+ else if (nSize <= std::numeric_limits<unsigned short>::max()) return sizeof(unsigned char) + sizeof(unsigned short);
+ else if (nSize <= std::numeric_limits<unsigned int>::max()) return sizeof(unsigned char) + sizeof(unsigned int);
+ else return sizeof(unsigned char) + sizeof(uint64_t);
+}
+
+template<typename Stream>
+void WriteCompactSize(Stream& os, uint64_t nSize)
+{
+ if (nSize < 253)
+ {
+ ser_writedata8(os, nSize);
+ }
+ else if (nSize <= std::numeric_limits<unsigned short>::max())
+ {
+ ser_writedata8(os, 253);
+ ser_writedata16(os, nSize);
+ }
+ else if (nSize <= std::numeric_limits<unsigned int>::max())
+ {
+ ser_writedata8(os, 254);
+ ser_writedata32(os, nSize);
+ }
+ else
+ {
+ ser_writedata8(os, 255);
+ ser_writedata64(os, nSize);
+ }
+ return;
+}
+
+template<typename Stream>
+uint64_t ReadCompactSize(Stream& is)
+{
+ uint8_t chSize = ser_readdata8(is);
+ uint64_t nSizeRet = 0;
+ if (chSize < 253)
+ {
+ nSizeRet = chSize;
+ }
+ else if (chSize == 253)
+ {
+ nSizeRet = ser_readdata16(is);
+ if (nSizeRet < 253)
+ throw std::ios_base::failure("non-canonical ReadCompactSize()");
+ }
+ else if (chSize == 254)
+ {
+ nSizeRet = ser_readdata32(is);
+ if (nSizeRet < 0x10000u)
+ throw std::ios_base::failure("non-canonical ReadCompactSize()");
+ }
+ else
+ {
+ nSizeRet = ser_readdata64(is);
+ if (nSizeRet < 0x100000000ULL)
+ throw std::ios_base::failure("non-canonical ReadCompactSize()");
+ }
+ if (nSizeRet > (uint64_t)MAX_SIZE)
+ throw std::ios_base::failure("ReadCompactSize(): size too large");
+ return nSizeRet;
+}
+
+/**
+ * Variable-length integers: bytes are a MSB base-128 encoding of the number.
+ * The high bit in each byte signifies whether another digit follows. To make
+ * sure the encoding is one-to-one, one is subtracted from all but the last digit.
+ * Thus, the byte sequence a[] with length len, where all but the last byte
+ * has bit 128 set, encodes the number:
+ *
+ * (a[len-1] & 0x7F) + sum(i=1..len-1, 128^i*((a[len-i-1] & 0x7F)+1))
+ *
+ * Properties:
+ * * Very small (0-127: 1 byte, 128-16511: 2 bytes, 16512-2113663: 3 bytes)
+ * * Every integer has exactly one encoding
+ * * Encoding does not depend on size of original integer type
+ * * No redundancy: every (infinite) byte sequence corresponds to a list
+ * of encoded integers.
+ *
+ * 0: [0x00] 256: [0x81 0x00]
+ * 1: [0x01] 16383: [0xFE 0x7F]
+ * 127: [0x7F] 16384: [0xFF 0x00]
+ * 128: [0x80 0x00] 16511: [0x80 0xFF 0x7F]
+ * 255: [0x80 0x7F] 65535: [0x82 0xFD 0x7F]
+ * 2^32: [0x8E 0xFE 0xFE 0xFF 0x00]
+ */
+
+template<typename I>
+inline unsigned int GetSizeOfVarInt(I n)
+{
+ int nRet = 0;
+ while(true) {
+ nRet++;
+ if (n <= 0x7F)
+ break;
+ n = (n >> 7) - 1;
+ }
+ return nRet;
+}
+
+template<typename Stream, typename I>
+void WriteVarInt(Stream& os, I n)
+{
+ unsigned char tmp[(sizeof(n)*8+6)/7];
+ int len=0;
+ while(true) {
+ tmp[len] = (n & 0x7F) | (len ? 0x80 : 0x00);
+ if (n <= 0x7F)
+ break;
+ n = (n >> 7) - 1;
+ len++;
+ }
+ do {
+ ser_writedata8(os, tmp[len]);
+ } while(len--);
+}
+
+template<typename Stream, typename I>
+I ReadVarInt(Stream& is)
+{
+ I n = 0;
+ while(true) {
+ unsigned char chData = ser_readdata8(is);
+ n = (n << 7) | (chData & 0x7F);
+ if (chData & 0x80)
+ n++;
+ else
+ return n;
+ }
+}
+
+#define FLATDATA(obj) REF(CFlatData((char*)&(obj), (char*)&(obj) + sizeof(obj)))
+#define VARINT(obj) REF(WrapVarInt(REF(obj)))
+#define LIMITED_STRING(obj,n) REF(LimitedString< n >(REF(obj)))
+
+/**
+ * Wrapper for serializing arrays and POD.
+ */
+class CFlatData
+{
+protected:
+ char* pbegin;
+ char* pend;
+public:
+ CFlatData(void* pbeginIn, void* pendIn) : pbegin((char*)pbeginIn), pend((char*)pendIn) { }
+ template <class T, class TAl>
+ explicit CFlatData(std::vector<T,TAl> &v)
+ {
+ pbegin = (char*)begin_ptr(v);
+ pend = (char*)end_ptr(v);
+ }
+ 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<typename Stream>
+ void Serialize(Stream& s, int, int=0) const
+ {
+ s.write(pbegin, pend - pbegin);
+ }
+
+ template<typename Stream>
+ void Unserialize(Stream& s, int, int=0)
+ {
+ s.read(pbegin, pend - pbegin);
+ }
+};
+
+template<typename I>
+class CVarInt
+{
+protected:
+ I &n;
+public:
+ CVarInt(I& nIn) : n(nIn) { }
+
+ unsigned int GetSerializeSize(int, int) const {
+ return GetSizeOfVarInt<I>(n);
+ }
+
+ template<typename Stream>
+ void Serialize(Stream &s, int, int) const {
+ WriteVarInt<Stream,I>(s, n);
+ }
+
+ template<typename Stream>
+ void Unserialize(Stream& s, int, int) {
+ n = ReadVarInt<Stream,I>(s);
+ }
+};
+
+template<size_t Limit>
+class LimitedString
+{
+protected:
+ std::string& string;
+public:
+ LimitedString(std::string& string) : string(string) {}
+
+ template<typename Stream>
+ void Unserialize(Stream& s, int, int=0)
+ {
+ size_t size = ReadCompactSize(s);
+ if (size > Limit) {
+ throw std::ios_base::failure("String length limit exceeded");
+ }
+ string.resize(size);
+ if (size != 0)
+ s.read((char*)&string[0], size);
+ }
+
+ template<typename Stream>
+ void Serialize(Stream& s, int, int=0) const
+ {
+ WriteCompactSize(s, string.size());
+ if (!string.empty())
+ s.write((char*)&string[0], string.size());
+ }
+
+ unsigned int GetSerializeSize(int, int=0) const
+ {
+ return GetSizeOfCompactSize(string.size()) + string.size();
+ }
+};
+
+template<typename I>
+CVarInt<I> WrapVarInt(I& n) { return CVarInt<I>(n); }
+
+/**
+ * Forward declarations
+ */
+
+/**
+ * string
+ */
+template<typename C> unsigned int GetSerializeSize(const std::basic_string<C>& str, int, int=0);
+template<typename Stream, typename C> void Serialize(Stream& os, const std::basic_string<C>& str, int, int=0);
+template<typename Stream, typename C> void Unserialize(Stream& is, std::basic_string<C>& str, int, int=0);
+
+/**
+ * vector
+ * vectors of unsigned char are a special case and are intended to be serialized as a single opaque blob.
+ */
+template<typename T, typename A> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const unsigned char&);
+template<typename T, typename A, typename V> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const V&);
+template<typename T, typename A> inline unsigned int GetSerializeSize(const std::vector<T, A>& v, int nType, int nVersion);
+template<typename Stream, typename T, typename A> void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const unsigned char&);
+template<typename Stream, typename T, typename A, typename V> void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const V&);
+template<typename Stream, typename T, typename A> inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int nVersion);
+template<typename Stream, typename T, typename A> void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const unsigned char&);
+template<typename Stream, typename T, typename A, typename V> void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const V&);
+template<typename Stream, typename T, typename A> inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion);
+
+/**
+ * others derived from vector
+ */
+extern inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion);
+template<typename Stream> void Serialize(Stream& os, const CScript& v, int nType, int nVersion);
+template<typename Stream> void Unserialize(Stream& is, CScript& v, int nType, int nVersion);
+
+/**
+ * pair
+ */
+template<typename K, typename T> unsigned int GetSerializeSize(const std::pair<K, T>& item, int nType, int nVersion);
+template<typename Stream, typename K, typename T> void Serialize(Stream& os, const std::pair<K, T>& item, int nType, int nVersion);
+template<typename Stream, typename K, typename T> void Unserialize(Stream& is, std::pair<K, T>& item, int nType, int nVersion);
+
+/**
+ * map
+ */
+template<typename K, typename T, typename Pred, typename A> unsigned int GetSerializeSize(const std::map<K, T, Pred, A>& m, int nType, int nVersion);
+template<typename Stream, typename K, typename T, typename Pred, typename A> void Serialize(Stream& os, const std::map<K, T, Pred, A>& m, int nType, int nVersion);
+template<typename Stream, typename K, typename T, typename Pred, typename A> void Unserialize(Stream& is, std::map<K, T, Pred, A>& m, int nType, int nVersion);
+
+/**
+ * set
+ */
+template<typename K, typename Pred, typename A> unsigned int GetSerializeSize(const std::set<K, Pred, A>& m, int nType, int nVersion);
+template<typename Stream, typename K, typename Pred, typename A> void Serialize(Stream& os, const std::set<K, Pred, A>& m, int nType, int nVersion);
+template<typename Stream, typename K, typename Pred, typename A> void Unserialize(Stream& is, std::set<K, Pred, A>& 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<typename T>
+inline unsigned int GetSerializeSize(const T& a, long nType, int nVersion)
+{
+ return a.GetSerializeSize((int)nType, nVersion);
+}
+
+template<typename Stream, typename T>
+inline void Serialize(Stream& os, const T& a, long nType, int nVersion)
+{
+ a.Serialize(os, (int)nType, nVersion);
+}
+
+template<typename Stream, typename T>
+inline void Unserialize(Stream& is, T& a, long nType, int nVersion)
+{
+ a.Unserialize(is, (int)nType, nVersion);
+}
+
+
+
+
+
+/**
+ * string
+ */
+template<typename C>
+unsigned int GetSerializeSize(const std::basic_string<C>& str, int, int)
+{
+ return GetSizeOfCompactSize(str.size()) + str.size() * sizeof(str[0]);
+}
+
+template<typename Stream, typename C>
+void Serialize(Stream& os, const std::basic_string<C>& str, int, int)
+{
+ WriteCompactSize(os, str.size());
+ if (!str.empty())
+ os.write((char*)&str[0], str.size() * sizeof(str[0]));
+}
+
+template<typename Stream, typename C>
+void Unserialize(Stream& is, std::basic_string<C>& 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<typename T, typename A>
+unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const unsigned char&)
+{
+ return (GetSizeOfCompactSize(v.size()) + v.size() * sizeof(T));
+}
+
+template<typename T, typename A, typename V>
+unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const V&)
+{
+ unsigned int nSize = GetSizeOfCompactSize(v.size());
+ for (typename std::vector<T, A>::const_iterator vi = v.begin(); vi != v.end(); ++vi)
+ nSize += GetSerializeSize((*vi), nType, nVersion);
+ return nSize;
+}
+
+template<typename T, typename A>
+inline unsigned int GetSerializeSize(const std::vector<T, A>& v, int nType, int nVersion)
+{
+ return GetSerializeSize_impl(v, nType, nVersion, T());
+}
+
+
+template<typename Stream, typename T, typename A>
+void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const unsigned char&)
+{
+ WriteCompactSize(os, v.size());
+ if (!v.empty())
+ os.write((char*)&v[0], v.size() * sizeof(T));
+}
+
+template<typename Stream, typename T, typename A, typename V>
+void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const V&)
+{
+ WriteCompactSize(os, v.size());
+ for (typename std::vector<T, A>::const_iterator vi = v.begin(); vi != v.end(); ++vi)
+ ::Serialize(os, (*vi), nType, nVersion);
+}
+
+template<typename Stream, typename T, typename A>
+inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int nVersion)
+{
+ Serialize_impl(os, v, nType, nVersion, T());
+}
+
+
+template<typename Stream, typename T, typename A>
+void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const unsigned char&)
+{
+ // 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<typename Stream, typename T, typename A, typename V>
+void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const V&)
+{
+ 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<typename Stream, typename T, typename A>
+inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion)
+{
+ Unserialize_impl(is, v, nType, nVersion, T());
+}
+
+
+
+/**
+ * others derived from vector
+ */
+inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion)
+{
+ return GetSerializeSize((const std::vector<unsigned char>&)v, nType, nVersion);
+}
+
+template<typename Stream>
+void Serialize(Stream& os, const CScript& v, int nType, int nVersion)
+{
+ Serialize(os, (const std::vector<unsigned char>&)v, nType, nVersion);
+}
+
+template<typename Stream>
+void Unserialize(Stream& is, CScript& v, int nType, int nVersion)
+{
+ Unserialize(is, (std::vector<unsigned char>&)v, nType, nVersion);
+}
+
+
+
+/**
+ * pair
+ */
+template<typename K, typename T>
+unsigned int GetSerializeSize(const std::pair<K, T>& item, int nType, int nVersion)
+{
+ return GetSerializeSize(item.first, nType, nVersion) + GetSerializeSize(item.second, nType, nVersion);
+}
+
+template<typename Stream, typename K, typename T>
+void Serialize(Stream& os, const std::pair<K, T>& item, int nType, int nVersion)
+{
+ Serialize(os, item.first, nType, nVersion);
+ Serialize(os, item.second, nType, nVersion);
+}
+
+template<typename Stream, typename K, typename T>
+void Unserialize(Stream& is, std::pair<K, T>& item, int nType, int nVersion)
+{
+ Unserialize(is, item.first, nType, nVersion);
+ Unserialize(is, item.second, nType, nVersion);
+}
+
+
+
+/**
+ * map
+ */
+template<typename K, typename T, typename Pred, typename A>
+unsigned int GetSerializeSize(const std::map<K, T, Pred, A>& m, int nType, int nVersion)
+{
+ unsigned int nSize = GetSizeOfCompactSize(m.size());
+ for (typename std::map<K, T, Pred, A>::const_iterator mi = m.begin(); mi != m.end(); ++mi)
+ nSize += GetSerializeSize((*mi), nType, nVersion);
+ return nSize;
+}
+
+template<typename Stream, typename K, typename T, typename Pred, typename A>
+void Serialize(Stream& os, const std::map<K, T, Pred, A>& m, int nType, int nVersion)
+{
+ WriteCompactSize(os, m.size());
+ for (typename std::map<K, T, Pred, A>::const_iterator mi = m.begin(); mi != m.end(); ++mi)
+ Serialize(os, (*mi), nType, nVersion);
+}
+
+template<typename Stream, typename K, typename T, typename Pred, typename A>
+void Unserialize(Stream& is, std::map<K, T, Pred, A>& m, int nType, int nVersion)
+{
+ m.clear();
+ unsigned int nSize = ReadCompactSize(is);
+ typename std::map<K, T, Pred, A>::iterator mi = m.begin();
+ for (unsigned int i = 0; i < nSize; i++)
+ {
+ std::pair<K, T> item;
+ Unserialize(is, item, nType, nVersion);
+ mi = m.insert(mi, item);
+ }
+}
+
+
+
+/**
+ * set
+ */
+template<typename K, typename Pred, typename A>
+unsigned int GetSerializeSize(const std::set<K, Pred, A>& m, int nType, int nVersion)
+{
+ unsigned int nSize = GetSizeOfCompactSize(m.size());
+ for (typename std::set<K, Pred, A>::const_iterator it = m.begin(); it != m.end(); ++it)
+ nSize += GetSerializeSize((*it), nType, nVersion);
+ return nSize;
+}
+
+template<typename Stream, typename K, typename Pred, typename A>
+void Serialize(Stream& os, const std::set<K, Pred, A>& m, int nType, int nVersion)
+{
+ WriteCompactSize(os, m.size());
+ for (typename std::set<K, Pred, A>::const_iterator it = m.begin(); it != m.end(); ++it)
+ Serialize(os, (*it), nType, nVersion);
+}
+
+template<typename Stream, typename K, typename Pred, typename A>
+void Unserialize(Stream& is, std::set<K, Pred, A>& m, int nType, int nVersion)
+{
+ m.clear();
+ unsigned int nSize = ReadCompactSize(is);
+ typename std::set<K, Pred, A>::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 ADD_SERIALIZE_METHODS and READWRITE macro
+ */
+struct CSerActionSerialize
+{
+ bool ForRead() const { return false; }
+};
+struct CSerActionUnserialize
+{
+ bool ForRead() const { return true; }
+};
+
+template<typename Stream, typename T>
+inline void SerReadWrite(Stream& s, const T& obj, int nType, int nVersion, CSerActionSerialize ser_action)
+{
+ ::Serialize(s, obj, nType, nVersion);
+}
+
+template<typename Stream, typename T>
+inline void SerReadWrite(Stream& s, T& obj, int nType, int nVersion, CSerActionUnserialize ser_action)
+{
+ ::Unserialize(s, obj, nType, nVersion);
+}
+
+
+
+
+
+
+
+
+
+class CSizeComputer
+{
+protected:
+ size_t nSize;
+
+public:
+ int nType;
+ int nVersion;
+
+ CSizeComputer(int nTypeIn, int nVersionIn) : nSize(0), nType(nTypeIn), nVersion(nVersionIn) {}
+
+ CSizeComputer& write(const char *psz, size_t nSize)
+ {
+ this->nSize += nSize;
+ return *this;
+ }
+
+ template<typename T>
+ CSizeComputer& operator<<(const T& obj)
+ {
+ ::Serialize(*this, obj, nType, nVersion);
+ return (*this);
+ }
+
+ size_t size() const {
+ return nSize;
+ }
+};
+
+#endif // BITCOIN_SERIALIZE_H
diff --git a/src/streams.h b/src/streams.h
new file mode 100644
index 0000000000..fa1e18defe
--- /dev/null
+++ b/src/streams.h
@@ -0,0 +1,572 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_STREAMS_H
+#define BITCOIN_STREAMS_H
+
+#include "support/allocators/zeroafterfree.h"
+#include "serialize.h"
+
+#include <algorithm>
+#include <assert.h>
+#include <ios>
+#include <limits>
+#include <map>
+#include <set>
+#include <stdint.h>
+#include <stdio.h>
+#include <string>
+#include <string.h>
+#include <utility>
+#include <vector>
+
+/** 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 CSerializeData vector_type;
+ vector_type vch;
+ unsigned int nReadPos;
+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<char>& vchIn, int nTypeIn, int nVersionIn) : vch(vchIn.begin(), vchIn.end())
+ {
+ Init(nTypeIn, nVersionIn);
+ }
+
+ CDataStream(const std::vector<unsigned char>& vchIn, int nTypeIn, int nVersionIn) : vch(vchIn.begin(), vchIn.end())
+ {
+ Init(nTypeIn, nVersionIn);
+ }
+
+ void Init(int nTypeIn, int nVersionIn)
+ {
+ nReadPos = 0;
+ nType = nTypeIn;
+ nVersion = nVersionIn;
+ }
+
+ 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, std::vector<char>::const_iterator first, std::vector<char>::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
+ //
+ bool eof() const { return size() == 0; }
+ 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, size_t nSize)
+ {
+ // Read from the beginning of the buffer
+ unsigned int nReadPosNext = nReadPos + nSize;
+ if (nReadPosNext >= vch.size())
+ {
+ if (nReadPosNext > vch.size())
+ {
+ throw std::ios_base::failure("CDataStream::read(): end of data");
+ }
+ 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())
+ throw std::ios_base::failure("CDataStream::ignore(): end of data");
+ nReadPos = 0;
+ vch.clear();
+ return (*this);
+ }
+ nReadPos = nReadPosNext;
+ return (*this);
+ }
+
+ CDataStream& write(const char* pch, size_t nSize)
+ {
+ // Write to the end of the buffer
+ vch.insert(vch.end(), pch, pch + nSize);
+ return (*this);
+ }
+
+ template<typename Stream>
+ 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<typename T>
+ unsigned int GetSerializeSize(const T& obj)
+ {
+ // Tells the size of the object if serialized to this stream
+ return ::GetSerializeSize(obj, nType, nVersion);
+ }
+
+ template<typename T>
+ CDataStream& operator<<(const T& obj)
+ {
+ // Serialize to this stream
+ ::Serialize(*this, obj, nType, nVersion);
+ return (*this);
+ }
+
+ template<typename T>
+ CDataStream& operator>>(T& obj)
+ {
+ // Unserialize from this stream
+ ::Unserialize(*this, obj, nType, nVersion);
+ return (*this);
+ }
+
+ void GetAndClear(CSerializeData &data) {
+ data.insert(data.end(), begin(), end());
+ clear();
+ }
+};
+
+
+
+
+
+
+
+
+
+
+/** Non-refcounted 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
+{
+private:
+ // Disallow copies
+ CAutoFile(const CAutoFile&);
+ CAutoFile& operator=(const CAutoFile&);
+
+ int nType;
+ int nVersion;
+
+ FILE* file;
+
+public:
+ CAutoFile(FILE* filenew, int nTypeIn, int nVersionIn)
+ {
+ file = filenew;
+ nType = nTypeIn;
+ nVersion = nVersionIn;
+ }
+
+ ~CAutoFile()
+ {
+ fclose();
+ }
+
+ void fclose()
+ {
+ if (file) {
+ ::fclose(file);
+ file = NULL;
+ }
+ }
+
+ /** Get wrapped FILE* with transfer of ownership.
+ * @note This will invalidate the CAutoFile object, and makes it the responsibility of the caller
+ * of this function to clean up the returned FILE*.
+ */
+ FILE* release() { FILE* ret = file; file = NULL; return ret; }
+
+ /** Get wrapped FILE* without transfer of ownership.
+ * @note Ownership of the FILE* will remain with this class. Use this only if the scope of the
+ * CAutoFile outlives use of the passed pointer.
+ */
+ FILE* Get() const { return file; }
+
+ /** Return true if the wrapped FILE* is NULL, false otherwise.
+ */
+ bool IsNull() const { return (file == NULL); }
+
+ //
+ // Stream subset
+ //
+ 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)
+ throw std::ios_base::failure(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)
+ throw std::ios_base::failure("CAutoFile::write: write failed");
+ return (*this);
+ }
+
+ template<typename T>
+ unsigned int GetSerializeSize(const T& obj)
+ {
+ // Tells the size of the object if serialized to this stream
+ return ::GetSerializeSize(obj, nType, nVersion);
+ }
+
+ template<typename T>
+ 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<typename T>
+ 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);
+ }
+};
+
+/** Non-refcounted RAII wrapper around a FILE* that implements a ring buffer to
+ * deserialize from. It guarantees the ability to rewind a given number of bytes.
+ *
+ * Will automatically close the file when it goes out of scope if not null.
+ * If you need to close the file early, use file.fclose() instead of fclose(file).
+ */
+class CBufferedFile
+{
+private:
+ // Disallow copies
+ CBufferedFile(const CBufferedFile&);
+ CBufferedFile& operator=(const CBufferedFile&);
+
+ int nType;
+ int nVersion;
+
+ FILE *src; // source file
+ uint64_t nSrcPos; // how many bytes have been read from source
+ uint64_t nReadPos; // how many bytes have been read from this
+ uint64_t nReadLimit; // up to which position we're allowed to read
+ uint64_t nRewind; // how many bytes we guarantee to rewind
+ std::vector<char> vchBuf; // the buffer
+
+protected:
+ // read data from the source to fill the buffer
+ bool Fill() {
+ unsigned int pos = nSrcPos % vchBuf.size();
+ unsigned int readNow = vchBuf.size() - pos;
+ unsigned int nAvail = vchBuf.size() - (nSrcPos - nReadPos) - nRewind;
+ if (nAvail < readNow)
+ readNow = nAvail;
+ if (readNow == 0)
+ return false;
+ size_t read = fread((void*)&vchBuf[pos], 1, readNow, src);
+ if (read == 0) {
+ throw std::ios_base::failure(feof(src) ? "CBufferedFile::Fill: end of file" : "CBufferedFile::Fill: fread failed");
+ } else {
+ nSrcPos += read;
+ return true;
+ }
+ }
+
+public:
+ CBufferedFile(FILE *fileIn, uint64_t nBufSize, uint64_t nRewindIn, int nTypeIn, int nVersionIn) :
+ nSrcPos(0), nReadPos(0), nReadLimit((uint64_t)(-1)), nRewind(nRewindIn), vchBuf(nBufSize, 0)
+ {
+ src = fileIn;
+ nType = nTypeIn;
+ nVersion = nVersionIn;
+ }
+
+ ~CBufferedFile()
+ {
+ fclose();
+ }
+
+ void fclose()
+ {
+ if (src) {
+ ::fclose(src);
+ src = NULL;
+ }
+ }
+
+ // check whether we're at the end of the source file
+ bool eof() const {
+ return nReadPos == nSrcPos && feof(src);
+ }
+
+ // read a number of bytes
+ CBufferedFile& read(char *pch, size_t nSize) {
+ if (nSize + nReadPos > nReadLimit)
+ throw std::ios_base::failure("Read attempted past buffer limit");
+ if (nSize + nRewind > vchBuf.size())
+ throw std::ios_base::failure("Read larger than buffer size");
+ while (nSize > 0) {
+ if (nReadPos == nSrcPos)
+ Fill();
+ unsigned int pos = nReadPos % vchBuf.size();
+ size_t nNow = nSize;
+ if (nNow + pos > vchBuf.size())
+ nNow = vchBuf.size() - pos;
+ if (nNow + nReadPos > nSrcPos)
+ nNow = nSrcPos - nReadPos;
+ memcpy(pch, &vchBuf[pos], nNow);
+ nReadPos += nNow;
+ pch += nNow;
+ nSize -= nNow;
+ }
+ return (*this);
+ }
+
+ // return the current reading position
+ uint64_t GetPos() {
+ return nReadPos;
+ }
+
+ // rewind to a given reading position
+ bool SetPos(uint64_t nPos) {
+ nReadPos = nPos;
+ if (nReadPos + nRewind < nSrcPos) {
+ nReadPos = nSrcPos - nRewind;
+ return false;
+ } else if (nReadPos > nSrcPos) {
+ nReadPos = nSrcPos;
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ bool Seek(uint64_t nPos) {
+ long nLongPos = nPos;
+ if (nPos != (uint64_t)nLongPos)
+ return false;
+ if (fseek(src, nLongPos, SEEK_SET))
+ return false;
+ nLongPos = ftell(src);
+ nSrcPos = nLongPos;
+ nReadPos = nLongPos;
+ return true;
+ }
+
+ // prevent reading beyond a certain position
+ // no argument removes the limit
+ bool SetLimit(uint64_t nPos = (uint64_t)(-1)) {
+ if (nPos < nReadPos)
+ return false;
+ nReadLimit = nPos;
+ return true;
+ }
+
+ template<typename T>
+ CBufferedFile& operator>>(T& obj) {
+ // Unserialize from this stream
+ ::Unserialize(*this, obj, nType, nVersion);
+ return (*this);
+ }
+
+ // search for a given byte in the stream, and remain positioned on it
+ void FindByte(char ch) {
+ while (true) {
+ if (nReadPos == nSrcPos)
+ Fill();
+ if (vchBuf[nReadPos % vchBuf.size()] == ch)
+ break;
+ nReadPos++;
+ }
+ }
+};
+
+#endif // BITCOIN_STREAMS_H
diff --git a/src/support/allocators/secure.h b/src/support/allocators/secure.h
new file mode 100644
index 0000000000..5e7bb66ea2
--- /dev/null
+++ b/src/support/allocators/secure.h
@@ -0,0 +1,62 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_SUPPORT_ALLOCATORS_SECURE_H
+#define BITCOIN_SUPPORT_ALLOCATORS_SECURE_H
+
+#include "support/pagelocker.h"
+
+#include <string>
+
+//
+// Allocator that locks its contents from being paged
+// out of memory and clears its contents before deletion.
+//
+template <typename T>
+struct secure_allocator : public std::allocator<T> {
+ // MSVC8 default copy constructor is broken
+ typedef std::allocator<T> 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 <typename U>
+ secure_allocator(const secure_allocator<U>& a) throw() : base(a)
+ {
+ }
+ ~secure_allocator() throw() {}
+ template <typename _Other>
+ struct rebind {
+ typedef secure_allocator<_Other> other;
+ };
+
+ T* allocate(std::size_t n, const void* hint = 0)
+ {
+ T* p;
+ p = std::allocator<T>::allocate(n, hint);
+ if (p != NULL)
+ LockedPageManager::Instance().LockRange(p, sizeof(T) * n);
+ return p;
+ }
+
+ void deallocate(T* p, std::size_t n)
+ {
+ if (p != NULL) {
+ memory_cleanse(p, sizeof(T) * n);
+ LockedPageManager::Instance().UnlockRange(p, sizeof(T) * n);
+ }
+ std::allocator<T>::deallocate(p, n);
+ }
+};
+
+// This is exactly like std::string, but with a custom allocator.
+typedef std::basic_string<char, std::char_traits<char>, secure_allocator<char> > SecureString;
+
+#endif // BITCOIN_SUPPORT_ALLOCATORS_SECURE_H
diff --git a/src/support/allocators/zeroafterfree.h b/src/support/allocators/zeroafterfree.h
new file mode 100644
index 0000000000..41e23392e8
--- /dev/null
+++ b/src/support/allocators/zeroafterfree.h
@@ -0,0 +1,48 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_SUPPORT_ALLOCATORS_ZEROAFTERFREE_H
+#define BITCOIN_SUPPORT_ALLOCATORS_ZEROAFTERFREE_H
+
+#include "support/cleanse.h"
+
+#include <memory>
+#include <vector>
+
+template <typename T>
+struct zero_after_free_allocator : public std::allocator<T> {
+ // MSVC8 default copy constructor is broken
+ typedef std::allocator<T> 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 <typename U>
+ zero_after_free_allocator(const zero_after_free_allocator<U>& a) throw() : base(a)
+ {
+ }
+ ~zero_after_free_allocator() throw() {}
+ template <typename _Other>
+ struct rebind {
+ typedef zero_after_free_allocator<_Other> other;
+ };
+
+ void deallocate(T* p, std::size_t n)
+ {
+ if (p != NULL)
+ memory_cleanse(p, sizeof(T) * n);
+ std::allocator<T>::deallocate(p, n);
+ }
+};
+
+// Byte-vector that clears its contents before deletion.
+typedef std::vector<char, zero_after_free_allocator<char> > CSerializeData;
+
+#endif // BITCOIN_SUPPORT_ALLOCATORS_ZEROAFTERFREE_H
diff --git a/src/support/cleanse.cpp b/src/support/cleanse.cpp
new file mode 100644
index 0000000000..a2141b2449
--- /dev/null
+++ b/src/support/cleanse.cpp
@@ -0,0 +1,13 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2015 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "cleanse.h"
+
+#include <openssl/crypto.h>
+
+void memory_cleanse(void *ptr, size_t len)
+{
+ OPENSSL_cleanse(ptr, len);
+}
diff --git a/src/support/cleanse.h b/src/support/cleanse.h
new file mode 100644
index 0000000000..3e02aa8fd1
--- /dev/null
+++ b/src/support/cleanse.h
@@ -0,0 +1,13 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2015 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_SUPPORT_CLEANSE_H
+#define BITCOIN_SUPPORT_CLEANSE_H
+
+#include <stdlib.h>
+
+void memory_cleanse(void *ptr, size_t len);
+
+#endif // BITCOIN_SUPPORT_CLEANSE_H
diff --git a/src/support/pagelocker.cpp b/src/support/pagelocker.cpp
new file mode 100644
index 0000000000..440e0a5193
--- /dev/null
+++ b/src/support/pagelocker.cpp
@@ -0,0 +1,70 @@
+// Copyright (c) 2009-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "support/pagelocker.h"
+
+#if defined(HAVE_CONFIG_H)
+#include "config/bitcoin-config.h"
+#endif
+
+#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 <windows.h>
+// 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.
+#else
+#include <sys/mman.h>
+#include <limits.h> // for PAGESIZE
+#include <unistd.h> // for sysconf
+#endif
+
+LockedPageManager* LockedPageManager::_instance = NULL;
+boost::once_flag LockedPageManager::init_flag = BOOST_ONCE_INIT;
+
+/** Determine system page size in bytes */
+static inline size_t GetSystemPageSize()
+{
+ size_t page_size;
+#if defined(WIN32)
+ SYSTEM_INFO sSysInfo;
+ GetSystemInfo(&sSysInfo);
+ page_size = sSysInfo.dwPageSize;
+#elif defined(PAGESIZE) // defined in limits.h
+ page_size = PAGESIZE;
+#else // assume some POSIX OS
+ page_size = sysconf(_SC_PAGESIZE);
+#endif
+ return page_size;
+}
+
+bool MemoryPageLocker::Lock(const void* addr, size_t len)
+{
+#ifdef WIN32
+ return VirtualLock(const_cast<void*>(addr), len) != 0;
+#else
+ return mlock(addr, len) == 0;
+#endif
+}
+
+bool MemoryPageLocker::Unlock(const void* addr, size_t len)
+{
+#ifdef WIN32
+ return VirtualUnlock(const_cast<void*>(addr), len) != 0;
+#else
+ return munlock(addr, len) == 0;
+#endif
+}
+
+LockedPageManager::LockedPageManager() : LockedPageManagerBase<MemoryPageLocker>(GetSystemPageSize())
+{
+}
diff --git a/src/support/pagelocker.h b/src/support/pagelocker.h
new file mode 100644
index 0000000000..88b95cce73
--- /dev/null
+++ b/src/support/pagelocker.h
@@ -0,0 +1,177 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_SUPPORT_PAGELOCKER_H
+#define BITCOIN_SUPPORT_PAGELOCKER_H
+
+#include "support/cleanse.h"
+
+#include <map>
+
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/once.hpp>
+
+/**
+ * Thread-safe class to keep track of locked (ie, non-swappable) memory pages.
+ *
+ * Memory locks do not stack, that is, pages which have been locked several times by calls to mlock()
+ * will be unlocked by a single call to munlock(). This can result in keying material ending up in swap when
+ * those functions are used naively. This class simulates stacking memory locks by keeping a counter per page.
+ *
+ * @note By using a map from each page base address to lock count, this class is optimized for
+ * small objects that span up to a few pages, mostly smaller than a page. To support large allocations,
+ * something like an interval tree would be the preferred data structure.
+ */
+template <class Locker>
+class LockedPageManagerBase
+{
+public:
+ LockedPageManagerBase(size_t page_size) : page_size(page_size)
+ {
+ // Determine bitmask for extracting page from address
+ assert(!(page_size & (page_size - 1))); // size must be power of two
+ page_mask = ~(page_size - 1);
+ }
+
+ ~LockedPageManagerBase()
+ {
+ }
+
+
+ // For all pages in affected range, increase lock count
+ void LockRange(void* p, size_t size)
+ {
+ boost::mutex::scoped_lock lock(mutex);
+ if (!size)
+ return;
+ const size_t base_addr = reinterpret_cast<size_t>(p);
+ const size_t start_page = base_addr & page_mask;
+ const size_t end_page = (base_addr + size - 1) & page_mask;
+ for (size_t page = start_page; page <= end_page; page += page_size) {
+ Histogram::iterator it = histogram.find(page);
+ if (it == histogram.end()) // Newly locked page
+ {
+ locker.Lock(reinterpret_cast<void*>(page), page_size);
+ histogram.insert(std::make_pair(page, 1));
+ } else // Page was already locked; increase counter
+ {
+ it->second += 1;
+ }
+ }
+ }
+
+ // For all pages in affected range, decrease lock count
+ void UnlockRange(void* p, size_t size)
+ {
+ boost::mutex::scoped_lock lock(mutex);
+ if (!size)
+ return;
+ const size_t base_addr = reinterpret_cast<size_t>(p);
+ const size_t start_page = base_addr & page_mask;
+ const size_t end_page = (base_addr + size - 1) & page_mask;
+ for (size_t page = start_page; page <= end_page; page += page_size) {
+ Histogram::iterator it = histogram.find(page);
+ assert(it != histogram.end()); // Cannot unlock an area that was not locked
+ // Decrease counter for page, when it is zero, the page will be unlocked
+ it->second -= 1;
+ if (it->second == 0) // Nothing on the page anymore that keeps it locked
+ {
+ // Unlock page and remove the count from histogram
+ locker.Unlock(reinterpret_cast<void*>(page), page_size);
+ histogram.erase(it);
+ }
+ }
+ }
+
+ // Get number of locked pages for diagnostics
+ int GetLockedPageCount()
+ {
+ boost::mutex::scoped_lock lock(mutex);
+ return histogram.size();
+ }
+
+private:
+ Locker locker;
+ boost::mutex mutex;
+ size_t page_size, page_mask;
+ // map of page base address to lock count
+ typedef std::map<size_t, int> Histogram;
+ Histogram histogram;
+};
+
+
+/**
+ * OS-dependent memory page locking/unlocking.
+ * Defined as policy class to make stubbing for test possible.
+ */
+class MemoryPageLocker
+{
+public:
+ /** Lock memory pages.
+ * addr and len must be a multiple of the system page size
+ */
+ bool Lock(const void* addr, size_t len);
+ /** Unlock memory pages.
+ * addr and len must be a multiple of the system page size
+ */
+ bool Unlock(const void* addr, size_t len);
+};
+
+/**
+ * Singleton class to keep track of locked (ie, non-swappable) memory pages, for use in
+ * std::allocator templates.
+ *
+ * Some implementations of the STL allocate memory in some constructors (i.e., see
+ * MSVC's vector<T> implementation where it allocates 1 byte of memory in the allocator.)
+ * Due to the unpredictable order of static initializers, we have to make sure the
+ * LockedPageManager instance exists before any other STL-based objects that use
+ * secure_allocator are created. So instead of having LockedPageManager also be
+ * static-initialized, it is created on demand.
+ */
+class LockedPageManager : public LockedPageManagerBase<MemoryPageLocker>
+{
+public:
+ static LockedPageManager& Instance()
+ {
+ boost::call_once(LockedPageManager::CreateInstance, LockedPageManager::init_flag);
+ return *LockedPageManager::_instance;
+ }
+
+private:
+ LockedPageManager();
+
+ static void CreateInstance()
+ {
+ // Using a local static instance guarantees that the object is initialized
+ // when it's first needed and also deinitialized after all objects that use
+ // it are done with it. I can think of one unlikely scenario where we may
+ // have a static deinitialization order/problem, but the check in
+ // LockedPageManagerBase's destructor helps us detect if that ever happens.
+ static LockedPageManager instance;
+ LockedPageManager::_instance = &instance;
+ }
+
+ static LockedPageManager* _instance;
+ static boost::once_flag init_flag;
+};
+
+//
+// Functions for directly locking/unlocking memory objects.
+// Intended for non-dynamically allocated structures.
+//
+template <typename T>
+void LockObject(const T& t)
+{
+ LockedPageManager::Instance().LockRange((void*)(&t), sizeof(T));
+}
+
+template <typename T>
+void UnlockObject(const T& t)
+{
+ memory_cleanse((void*)(&t), sizeof(T));
+ LockedPageManager::Instance().UnlockRange((void*)(&t), sizeof(T));
+}
+
+#endif // BITCOIN_SUPPORT_PAGELOCKER_H
diff --git a/src/sync.cpp b/src/sync.cpp
new file mode 100644
index 0000000000..a422939964
--- /dev/null
+++ b/src/sync.cpp
@@ -0,0 +1,147 @@
+// Copyright (c) 2011-2012 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "sync.h"
+
+#include "util.h"
+#include "utilstrencodings.h"
+
+#include <stdio.h>
+
+#include <boost/foreach.hpp>
+#include <boost/thread.hpp>
+
+#ifdef DEBUG_LOCKCONTENTION
+void PrintLockContention(const char* pszName, const char* pszFile, int nLine)
+{
+ LogPrintf("LOCKCONTENTION: %s\n", pszName);
+ LogPrintf("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);
+ }
+
+ std::string MutexName() const { return mutexName; }
+
+private:
+ std::string mutexName;
+ std::string sourceFile;
+ int sourceLine;
+};
+
+typedef std::vector<std::pair<void*, CLockLocation> > LockStack;
+
+static boost::mutex dd_mutex;
+static std::map<std::pair<void*, void*>, LockStack> lockorders;
+static boost::thread_specific_ptr<LockStack> lockstack;
+
+
+static void potential_deadlock_detected(const std::pair<void*, void*>& mismatch, const LockStack& s1, const LockStack& s2)
+{
+ LogPrintf("POTENTIAL DEADLOCK DETECTED\n");
+ LogPrintf("Previous lock order was:\n");
+ BOOST_FOREACH (const PAIRTYPE(void*, CLockLocation) & i, s2) {
+ if (i.first == mismatch.first)
+ LogPrintf(" (1)");
+ if (i.first == mismatch.second)
+ LogPrintf(" (2)");
+ LogPrintf(" %s\n", i.second.ToString());
+ }
+ LogPrintf("Current lock order is:\n");
+ BOOST_FOREACH (const PAIRTYPE(void*, CLockLocation) & i, s1) {
+ if (i.first == mismatch.first)
+ LogPrintf(" (1)");
+ if (i.first == mismatch.second)
+ LogPrintf(" (2)");
+ LogPrintf(" %s\n", i.second.ToString());
+ }
+}
+
+static void push_lock(void* c, const CLockLocation& locklocation, bool fTry)
+{
+ if (lockstack.get() == NULL)
+ lockstack.reset(new LockStack);
+
+ 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<void*, void*> p1 = std::make_pair(i.first, c);
+ if (lockorders.count(p1))
+ continue;
+ lockorders[p1] = (*lockstack);
+
+ std::pair<void*, void*> 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()
+{
+ 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();
+}
+
+std::string LocksHeld()
+{
+ std::string result;
+ BOOST_FOREACH (const PAIRTYPE(void*, CLockLocation) & i, *lockstack)
+ result += i.second.ToString() + std::string("\n");
+ return result;
+}
+
+void AssertLockHeldInternal(const char* pszName, const char* pszFile, int nLine, void* cs)
+{
+ BOOST_FOREACH (const PAIRTYPE(void*, CLockLocation) & i, *lockstack)
+ if (i.first == cs)
+ return;
+ fprintf(stderr, "Assertion failed: lock %s not held in %s:%i; locks held:\n%s", pszName, pszFile, nLine, LocksHeld().c_str());
+ abort();
+}
+
+#endif /* DEBUG_LOCKORDER */
diff --git a/src/sync.h b/src/sync.h
new file mode 100644
index 0000000000..5c15165346
--- /dev/null
+++ b/src/sync.h
@@ -0,0 +1,280 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2013 The Bitcoin Core developers
+// Distributed under the MIT 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 "threadsafety.h"
+
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/recursive_mutex.hpp>
+
+
+////////////////////////////////////////////////
+// //
+// THE SIMPLE DEFINITION, EXCLUDING DEBUG CODE //
+// //
+////////////////////////////////////////////////
+
+/*
+CCriticalSection mutex;
+ boost::recursive_mutex mutex;
+
+LOCK(mutex);
+ boost::unique_lock<boost::recursive_mutex> criticalblock(mutex);
+
+LOCK2(mutex1, mutex2);
+ boost::unique_lock<boost::recursive_mutex> criticalblock1(mutex1);
+ boost::unique_lock<boost::recursive_mutex> criticalblock2(mutex2);
+
+TRY_LOCK(mutex, name);
+ boost::unique_lock<boost::recursive_mutex> name(mutex, boost::try_to_lock_t);
+
+ENTER_CRITICAL_SECTION(mutex); // no RAII
+ mutex.lock();
+
+LEAVE_CRITICAL_SECTION(mutex); // no RAII
+ mutex.unlock();
+ */
+
+///////////////////////////////
+// //
+// THE ACTUAL IMPLEMENTATION //
+// //
+///////////////////////////////
+
+/**
+ * Template mixin that adds -Wthread-safety locking
+ * annotations to a subset of the mutex API.
+ */
+template <typename PARENT>
+class LOCKABLE AnnotatedMixin : public PARENT
+{
+public:
+ void lock() EXCLUSIVE_LOCK_FUNCTION()
+ {
+ PARENT::lock();
+ }
+
+ void unlock() UNLOCK_FUNCTION()
+ {
+ PARENT::unlock();
+ }
+
+ bool try_lock() EXCLUSIVE_TRYLOCK_FUNCTION(true)
+ {
+ return PARENT::try_lock();
+ }
+};
+
+/**
+ * Wrapped boost mutex: supports recursive locking, but no waiting
+ * TODO: We should move away from using the recursive lock by default.
+ */
+typedef AnnotatedMixin<boost::recursive_mutex> CCriticalSection;
+
+/** Wrapped boost mutex: supports waiting but not recursive locking */
+typedef AnnotatedMixin<boost::mutex> CWaitableCriticalSection;
+
+/** Just a typedef for boost::condition_variable, can be wrapped later if desired */
+typedef boost::condition_variable CConditionVariable;
+
+#ifdef DEBUG_LOCKORDER
+void EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry = false);
+void LeaveCritical();
+std::string LocksHeld();
+void AssertLockHeldInternal(const char* pszName, const char* pszFile, int nLine, void* cs);
+#else
+void static inline EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry = false) {}
+void static inline LeaveCritical() {}
+void static inline AssertLockHeldInternal(const char* pszName, const char* pszFile, int nLine, void* cs) {}
+#endif
+#define AssertLockHeld(cs) AssertLockHeldInternal(#cs, __FILE__, __LINE__, &cs)
+
+#ifdef DEBUG_LOCKCONTENTION
+void PrintLockContention(const char* pszName, const char* pszFile, int nLine);
+#endif
+
+/** Wrapper around boost::unique_lock<Mutex> */
+template <typename Mutex>
+class CMutexLock
+{
+private:
+ boost::unique_lock<Mutex> lock;
+
+ void Enter(const char* pszName, const char* pszFile, int nLine)
+ {
+ 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
+ }
+
+ bool TryEnter(const char* pszName, const char* pszFile, int nLine)
+ {
+ EnterCritical(pszName, pszFile, nLine, (void*)(lock.mutex()), true);
+ lock.try_lock();
+ if (!lock.owns_lock())
+ LeaveCritical();
+ return lock.owns_lock();
+ }
+
+public:
+ 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(Mutex* pmutexIn, const char* pszName, const char* pszFile, int nLine, bool fTry = false)
+ {
+ if (!pmutexIn) return;
+
+ lock = boost::unique_lock<Mutex>(*pmutexIn, 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();
+ }
+};
+
+typedef CMutexLock<CCriticalSection> 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<boost::mutex> lock(mutex);
+ while (value < 1) {
+ condition.wait(lock);
+ }
+ value--;
+ }
+
+ bool try_wait()
+ {
+ boost::unique_lock<boost::mutex> lock(mutex);
+ if (value < 1)
+ return false;
+ value--;
+ return true;
+ }
+
+ void post()
+ {
+ {
+ boost::unique_lock<boost::mutex> 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 // BITCOIN_SYNC_H
diff --git a/src/test/Checkpoints_tests.cpp b/src/test/Checkpoints_tests.cpp
new file mode 100644
index 0000000000..642ce13bcd
--- /dev/null
+++ b/src/test/Checkpoints_tests.cpp
@@ -0,0 +1,41 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+//
+// Unit tests for block-chain checkpoints
+//
+
+#include "checkpoints.h"
+
+#include "uint256.h"
+#include "test/test_bitcoin.h"
+#include "chainparams.h"
+
+#include <boost/test/unit_test.hpp>
+
+using namespace std;
+
+BOOST_FIXTURE_TEST_SUITE(Checkpoints_tests, BasicTestingSetup)
+
+BOOST_AUTO_TEST_CASE(sanity)
+{
+ const Checkpoints::CCheckpointData& checkpoints = Params(CBaseChainParams::MAIN).Checkpoints();
+ uint256 p11111 = uint256S("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d");
+ uint256 p134444 = uint256S("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe");
+ BOOST_CHECK(Checkpoints::CheckBlock(checkpoints, 11111, p11111));
+ BOOST_CHECK(Checkpoints::CheckBlock(checkpoints, 134444, p134444));
+
+
+ // Wrong hashes at checkpoints should fail:
+ BOOST_CHECK(!Checkpoints::CheckBlock(checkpoints, 11111, p134444));
+ BOOST_CHECK(!Checkpoints::CheckBlock(checkpoints, 134444, p11111));
+
+ // ... but any hash not at a checkpoint should succeed:
+ BOOST_CHECK(Checkpoints::CheckBlock(checkpoints, 11111+1, p134444));
+ BOOST_CHECK(Checkpoints::CheckBlock(checkpoints, 134444+1, p11111));
+
+ BOOST_CHECK(Checkpoints::GetTotalBlocksEstimate(checkpoints) >= 134444);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp
new file mode 100644
index 0000000000..bf25548755
--- /dev/null
+++ b/src/test/DoS_tests.cpp
@@ -0,0 +1,201 @@
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+//
+// Unit tests for denial-of-service detection/prevention code
+//
+
+
+
+#include "keystore.h"
+#include "main.h"
+#include "net.h"
+#include "pow.h"
+#include "script/sign.h"
+#include "serialize.h"
+#include "util.h"
+
+#include "test/test_bitcoin.h"
+
+#include <stdint.h>
+
+#include <boost/assign/list_of.hpp> // for 'map_list_of()'
+#include <boost/date_time/posix_time/posix_time_types.hpp>
+#include <boost/foreach.hpp>
+#include <boost/test/unit_test.hpp>
+
+// Tests this internal-to-main.cpp method:
+extern bool AddOrphanTx(const CTransaction& tx, NodeId peer);
+extern void EraseOrphansFor(NodeId peer);
+extern unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans);
+struct COrphanTx {
+ CTransaction tx;
+ NodeId fromPeer;
+};
+extern std::map<uint256, COrphanTx> mapOrphanTransactions;
+extern std::map<uint256, std::set<uint256> > mapOrphanTransactionsByPrev;
+
+CService ip(uint32_t i)
+{
+ struct in_addr s;
+ s.s_addr = i;
+ return CService(CNetAddr(s), Params().GetDefaultPort());
+}
+
+BOOST_FIXTURE_TEST_SUITE(DoS_tests, TestingSetup)
+
+BOOST_AUTO_TEST_CASE(DoS_banning)
+{
+ CNode::ClearBanned();
+ CAddress addr1(ip(0xa0b0c001));
+ CNode dummyNode1(INVALID_SOCKET, addr1, "", true);
+ dummyNode1.nVersion = 1;
+ Misbehaving(dummyNode1.GetId(), 100); // Should get banned
+ SendMessages(&dummyNode1, false);
+ 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.nVersion = 1;
+ Misbehaving(dummyNode2.GetId(), 50);
+ SendMessages(&dummyNode2, false);
+ BOOST_CHECK(!CNode::IsBanned(addr2)); // 2 not banned yet...
+ BOOST_CHECK(CNode::IsBanned(addr1)); // ... but 1 still should be
+ Misbehaving(dummyNode2.GetId(), 50);
+ SendMessages(&dummyNode2, false);
+ 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.nVersion = 1;
+ Misbehaving(dummyNode1.GetId(), 100);
+ SendMessages(&dummyNode1, false);
+ BOOST_CHECK(!CNode::IsBanned(addr1));
+ Misbehaving(dummyNode1.GetId(), 10);
+ SendMessages(&dummyNode1, false);
+ BOOST_CHECK(!CNode::IsBanned(addr1));
+ Misbehaving(dummyNode1.GetId(), 1);
+ SendMessages(&dummyNode1, false);
+ BOOST_CHECK(CNode::IsBanned(addr1));
+ mapArgs.erase("-banscore");
+}
+
+BOOST_AUTO_TEST_CASE(DoS_bantime)
+{
+ CNode::ClearBanned();
+ int64_t nStartTime = GetTime();
+ SetMockTime(nStartTime); // Overrides future calls to GetTime()
+
+ CAddress addr(ip(0xa0b0c001));
+ CNode dummyNode(INVALID_SOCKET, addr, "", true);
+ dummyNode.nVersion = 1;
+
+ Misbehaving(dummyNode.GetId(), 100);
+ SendMessages(&dummyNode, false);
+ 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));
+}
+
+CTransaction RandomOrphan()
+{
+ std::map<uint256, COrphanTx>::iterator it;
+ it = mapOrphanTransactions.lower_bound(GetRandHash());
+ if (it == mapOrphanTransactions.end())
+ it = mapOrphanTransactions.begin();
+ return it->second.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++)
+ {
+ CMutableTransaction 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 = GetScriptForDestination(key.GetPubKey().GetID());
+
+ AddOrphanTx(tx, i);
+ }
+
+ // ... and 50 that depend on other orphans:
+ for (int i = 0; i < 50; i++)
+ {
+ CTransaction txPrev = RandomOrphan();
+
+ CMutableTransaction 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 = GetScriptForDestination(key.GetPubKey().GetID());
+ SignSignature(keystore, txPrev, tx, 0);
+
+ AddOrphanTx(tx, i);
+ }
+
+ // This really-big orphan should be ignored:
+ for (int i = 0; i < 10; i++)
+ {
+ CTransaction txPrev = RandomOrphan();
+
+ CMutableTransaction tx;
+ tx.vout.resize(1);
+ tx.vout[0].nValue = 1*CENT;
+ tx.vout[0].scriptPubKey = GetScriptForDestination(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;
+
+ BOOST_CHECK(!AddOrphanTx(tx, i));
+ }
+
+ // Test EraseOrphansFor:
+ for (NodeId i = 0; i < 3; i++)
+ {
+ size_t sizeBefore = mapOrphanTransactions.size();
+ EraseOrphansFor(i);
+ BOOST_CHECK(mapOrphanTransactions.size() < sizeBefore);
+ }
+
+ // 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_SUITE_END()
diff --git a/src/test/Makefile b/src/test/Makefile
new file mode 100644
index 0000000000..87bf73fec9
--- /dev/null
+++ b/src/test/Makefile
@@ -0,0 +1,6 @@
+all:
+ $(MAKE) -C .. bitcoin_test
+clean:
+ $(MAKE) -C .. bitcoin_test_clean
+check:
+ $(MAKE) -C .. bitcoin_test_check
diff --git a/src/test/README.md b/src/test/README.md
new file mode 100644
index 0000000000..7efce6f052
--- /dev/null
+++ b/src/test/README.md
@@ -0,0 +1,21 @@
+# Notes
+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 "<source_filename>_tests.cpp" and such files should wrap
+their tests in a test suite called "<source_filename>_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/](http://www.alittlemadness.com/2009/03/31/c-unit-testing-with-boosttest/). \ No newline at end of file
diff --git a/src/test/accounting_tests.cpp b/src/test/accounting_tests.cpp
new file mode 100644
index 0000000000..0c2ade48d6
--- /dev/null
+++ b/src/test/accounting_tests.cpp
@@ -0,0 +1,141 @@
+// Copyright (c) 2012-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "wallet/wallet.h"
+#include "wallet/walletdb.h"
+
+#include "test/test_bitcoin.h"
+
+#include <stdint.h>
+
+#include <boost/foreach.hpp>
+#include <boost/test/unit_test.hpp>
+
+extern CWallet* pwalletMain;
+
+BOOST_FIXTURE_TEST_SUITE(accounting_tests, TestingSetup)
+
+static void
+GetResults(CWalletDB& walletdb, std::map<CAmount, CAccountingEntry>& results)
+{
+ std::list<CAccountingEntry> aes;
+
+ results.clear();
+ BOOST_CHECK(walletdb.ReorderTransactions(pwalletMain) == DB_LOAD_OK);
+ walletdb.ListAccountCreditDebit("", aes);
+ BOOST_FOREACH(CAccountingEntry& ae, aes)
+ {
+ results[ae.nOrderPos] = ae;
+ }
+}
+
+BOOST_AUTO_TEST_CASE(acc_orderupgrade)
+{
+ CWalletDB walletdb(pwalletMain->strWalletFile);
+ std::vector<CWalletTx*> vpwtx;
+ CWalletTx wtx;
+ CAccountingEntry ae;
+ std::map<CAmount, CAccountingEntry> results;
+
+ LOCK(pwalletMain->cs_wallet);
+
+ ae.strAccount = "";
+ ae.nCreditDebit = 1;
+ ae.nTime = 1333333333;
+ ae.strOtherAccount = "b";
+ ae.strComment = "";
+ walletdb.WriteAccountingEntry(ae);
+
+ wtx.mapValue["comment"] = "z";
+ pwalletMain->AddToWallet(wtx, false, &walletdb);
+ vpwtx.push_back(&pwalletMain->mapWallet[wtx.GetHash()]);
+ vpwtx[0]->nTimeReceived = (unsigned int)1333333335;
+ vpwtx[0]->nOrderPos = -1;
+
+ ae.nTime = 1333333336;
+ ae.strOtherAccount = "c";
+ walletdb.WriteAccountingEntry(ae);
+
+ GetResults(walletdb, results);
+
+ BOOST_CHECK(pwalletMain->nOrderPosNext == 3);
+ BOOST_CHECK(2 == results.size());
+ BOOST_CHECK(results[0].nTime == 1333333333);
+ BOOST_CHECK(results[0].strComment.empty());
+ BOOST_CHECK(1 == vpwtx[0]->nOrderPos);
+ BOOST_CHECK(results[2].nTime == 1333333336);
+ BOOST_CHECK(results[2].strOtherAccount == "c");
+
+
+ ae.nTime = 1333333330;
+ ae.strOtherAccount = "d";
+ ae.nOrderPos = pwalletMain->IncOrderPosNext();
+ walletdb.WriteAccountingEntry(ae);
+
+ GetResults(walletdb, results);
+
+ BOOST_CHECK(results.size() == 3);
+ BOOST_CHECK(pwalletMain->nOrderPosNext == 4);
+ BOOST_CHECK(results[0].nTime == 1333333333);
+ BOOST_CHECK(1 == vpwtx[0]->nOrderPos);
+ BOOST_CHECK(results[2].nTime == 1333333336);
+ BOOST_CHECK(results[3].nTime == 1333333330);
+ BOOST_CHECK(results[3].strComment.empty());
+
+
+ wtx.mapValue["comment"] = "y";
+ {
+ CMutableTransaction tx(wtx);
+ --tx.nLockTime; // Just to change the hash :)
+ *static_cast<CTransaction*>(&wtx) = CTransaction(tx);
+ }
+ pwalletMain->AddToWallet(wtx, false, &walletdb);
+ vpwtx.push_back(&pwalletMain->mapWallet[wtx.GetHash()]);
+ vpwtx[1]->nTimeReceived = (unsigned int)1333333336;
+
+ wtx.mapValue["comment"] = "x";
+ {
+ CMutableTransaction tx(wtx);
+ --tx.nLockTime; // Just to change the hash :)
+ *static_cast<CTransaction*>(&wtx) = CTransaction(tx);
+ }
+ pwalletMain->AddToWallet(wtx, false, &walletdb);
+ vpwtx.push_back(&pwalletMain->mapWallet[wtx.GetHash()]);
+ vpwtx[2]->nTimeReceived = (unsigned int)1333333329;
+ vpwtx[2]->nOrderPos = -1;
+
+ GetResults(walletdb, results);
+
+ BOOST_CHECK(results.size() == 3);
+ BOOST_CHECK(pwalletMain->nOrderPosNext == 6);
+ BOOST_CHECK(0 == vpwtx[2]->nOrderPos);
+ BOOST_CHECK(results[1].nTime == 1333333333);
+ BOOST_CHECK(2 == vpwtx[0]->nOrderPos);
+ BOOST_CHECK(results[3].nTime == 1333333336);
+ BOOST_CHECK(results[4].nTime == 1333333330);
+ BOOST_CHECK(results[4].strComment.empty());
+ BOOST_CHECK(5 == vpwtx[1]->nOrderPos);
+
+
+ ae.nTime = 1333333334;
+ ae.strOtherAccount = "e";
+ ae.nOrderPos = -1;
+ walletdb.WriteAccountingEntry(ae);
+
+ GetResults(walletdb, results);
+
+ BOOST_CHECK(results.size() == 4);
+ BOOST_CHECK(pwalletMain->nOrderPosNext == 7);
+ BOOST_CHECK(0 == vpwtx[2]->nOrderPos);
+ BOOST_CHECK(results[1].nTime == 1333333333);
+ BOOST_CHECK(2 == vpwtx[0]->nOrderPos);
+ BOOST_CHECK(results[3].nTime == 1333333336);
+ BOOST_CHECK(results[3].strComment.empty());
+ BOOST_CHECK(results[4].nTime == 1333333330);
+ BOOST_CHECK(results[4].strComment.empty());
+ BOOST_CHECK(results[5].nTime == 1333333334);
+ BOOST_CHECK(6 == vpwtx[1]->nOrderPos);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/alert_tests.cpp b/src/test/alert_tests.cpp
new file mode 100644
index 0000000000..73481dd802
--- /dev/null
+++ b/src/test/alert_tests.cpp
@@ -0,0 +1,257 @@
+// Copyright (c) 2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+//
+// Unit tests for alert system
+//
+
+#include "alert.h"
+#include "chain.h"
+#include "chainparams.h"
+#include "clientversion.h"
+#include "data/alertTests.raw.h"
+
+#include "main.h"
+#include "serialize.h"
+#include "streams.h"
+#include "util.h"
+#include "utilstrencodings.h"
+
+#include "test/test_bitcoin.h"
+
+#include <fstream>
+
+#include <boost/filesystem/operations.hpp>
+#include <boost/foreach.hpp>
+#include <boost/test/unit_test.hpp>
+
+#if 0
+//
+// alertTests contains 7 alerts, generated with this code:
+// (SignAndSave code not shown, alert signing key is secret)
+//
+{
+ CAlert alert;
+ alert.nRelayUntil = 60;
+ alert.nExpiration = 24 * 60 * 60;
+ alert.nID = 1;
+ alert.nCancel = 0; // cancels previous messages up to this ID number
+ alert.nMinVer = 0; // These versions are protocol versions
+ alert.nMaxVer = 999001;
+ alert.nPriority = 1;
+ alert.strComment = "Alert comment";
+ alert.strStatusBar = "Alert 1";
+
+ SignAndSave(alert, "test/alertTests");
+
+ alert.setSubVer.insert(std::string("/Satoshi:0.1.0/"));
+ alert.strStatusBar = "Alert 1 for Satoshi 0.1.0";
+ SignAndSave(alert, "test/alertTests");
+
+ alert.setSubVer.insert(std::string("/Satoshi:0.2.0/"));
+ alert.strStatusBar = "Alert 1 for Satoshi 0.1.0, 0.2.0";
+ SignAndSave(alert, "test/alertTests");
+
+ alert.setSubVer.clear();
+ ++alert.nID;
+ alert.nCancel = 1;
+ alert.nPriority = 100;
+ alert.strStatusBar = "Alert 2, cancels 1";
+ SignAndSave(alert, "test/alertTests");
+
+ alert.nExpiration += 60;
+ ++alert.nID;
+ SignAndSave(alert, "test/alertTests");
+
+ ++alert.nID;
+ alert.nMinVer = 11;
+ alert.nMaxVer = 22;
+ SignAndSave(alert, "test/alertTests");
+
+ ++alert.nID;
+ alert.strStatusBar = "Alert 2 for Satoshi 0.1.0";
+ alert.setSubVer.insert(std::string("/Satoshi:0.1.0/"));
+ SignAndSave(alert, "test/alertTests");
+
+ ++alert.nID;
+ alert.nMinVer = 0;
+ alert.nMaxVer = 999999;
+ alert.strStatusBar = "Evil Alert'; /bin/ls; echo '";
+ alert.setSubVer.clear();
+ SignAndSave(alert, "test/alertTests");
+}
+#endif
+
+struct ReadAlerts : public TestingSetup
+{
+ ReadAlerts()
+ {
+ std::vector<unsigned char> vch(alert_tests::alertTests, alert_tests::alertTests + sizeof(alert_tests::alertTests));
+ CDataStream stream(vch, SER_DISK, CLIENT_VERSION);
+ try {
+ while (!stream.eof())
+ {
+ CAlert alert;
+ stream >> alert;
+ alerts.push_back(alert);
+ }
+ }
+ catch (const std::exception&) { }
+ }
+ ~ReadAlerts() { }
+
+ static std::vector<std::string> read_lines(boost::filesystem::path filepath)
+ {
+ std::vector<std::string> result;
+
+ std::ifstream f(filepath.string().c_str());
+ std::string line;
+ while (std::getline(f,line))
+ result.push_back(line);
+
+ return result;
+ }
+
+ std::vector<CAlert> alerts;
+};
+
+BOOST_FIXTURE_TEST_SUITE(Alert_tests, ReadAlerts)
+
+
+BOOST_AUTO_TEST_CASE(AlertApplies)
+{
+ SetMockTime(11);
+ const std::vector<unsigned char>& alertKey = Params(CBaseChainParams::MAIN).AlertKey();
+
+ BOOST_FOREACH(const CAlert& alert, alerts)
+ {
+ BOOST_CHECK(alert.CheckSignature(alertKey));
+ }
+
+ BOOST_CHECK(alerts.size() >= 3);
+
+ // Matches:
+ BOOST_CHECK(alerts[0].AppliesTo(1, ""));
+ BOOST_CHECK(alerts[0].AppliesTo(999001, ""));
+ BOOST_CHECK(alerts[0].AppliesTo(1, "/Satoshi:11.11.11/"));
+
+ BOOST_CHECK(alerts[1].AppliesTo(1, "/Satoshi:0.1.0/"));
+ BOOST_CHECK(alerts[1].AppliesTo(999001, "/Satoshi:0.1.0/"));
+
+ BOOST_CHECK(alerts[2].AppliesTo(1, "/Satoshi:0.1.0/"));
+ BOOST_CHECK(alerts[2].AppliesTo(1, "/Satoshi:0.2.0/"));
+
+ // Don't match:
+ BOOST_CHECK(!alerts[0].AppliesTo(-1, ""));
+ BOOST_CHECK(!alerts[0].AppliesTo(999002, ""));
+
+ BOOST_CHECK(!alerts[1].AppliesTo(1, ""));
+ BOOST_CHECK(!alerts[1].AppliesTo(1, "Satoshi:0.1.0"));
+ BOOST_CHECK(!alerts[1].AppliesTo(1, "/Satoshi:0.1.0"));
+ BOOST_CHECK(!alerts[1].AppliesTo(1, "Satoshi:0.1.0/"));
+ BOOST_CHECK(!alerts[1].AppliesTo(-1, "/Satoshi:0.1.0/"));
+ BOOST_CHECK(!alerts[1].AppliesTo(999002, "/Satoshi:0.1.0/"));
+ BOOST_CHECK(!alerts[1].AppliesTo(1, "/Satoshi:0.2.0/"));
+
+ BOOST_CHECK(!alerts[2].AppliesTo(1, "/Satoshi:0.3.0/"));
+
+ SetMockTime(0);
+}
+
+
+BOOST_AUTO_TEST_CASE(AlertNotify)
+{
+ SetMockTime(11);
+ const std::vector<unsigned char>& alertKey = Params(CBaseChainParams::MAIN).AlertKey();
+
+ boost::filesystem::path temp = GetTempPath() /
+ boost::filesystem::unique_path("alertnotify-%%%%.txt");
+
+ mapArgs["-alertnotify"] = std::string("echo %s >> ") + temp.string();
+
+ BOOST_FOREACH(CAlert alert, alerts)
+ alert.ProcessAlert(alertKey, false);
+
+ std::vector<std::string> r = read_lines(temp);
+ BOOST_CHECK_EQUAL(r.size(), 4u);
+
+// Windows built-in echo semantics are different than posixy shells. Quotes and
+// whitespace are printed literally.
+
+#ifndef WIN32
+ BOOST_CHECK_EQUAL(r[0], "Alert 1");
+ BOOST_CHECK_EQUAL(r[1], "Alert 2, cancels 1");
+ BOOST_CHECK_EQUAL(r[2], "Alert 2, cancels 1");
+ BOOST_CHECK_EQUAL(r[3], "Evil Alert; /bin/ls; echo "); // single-quotes should be removed
+#else
+ BOOST_CHECK_EQUAL(r[0], "'Alert 1' ");
+ BOOST_CHECK_EQUAL(r[1], "'Alert 2, cancels 1' ");
+ BOOST_CHECK_EQUAL(r[2], "'Alert 2, cancels 1' ");
+ BOOST_CHECK_EQUAL(r[3], "'Evil Alert; /bin/ls; echo ' ");
+#endif
+ boost::filesystem::remove(temp);
+
+ SetMockTime(0);
+}
+
+static bool falseFunc() { return false; }
+
+BOOST_AUTO_TEST_CASE(PartitionAlert)
+{
+ // Test PartitionCheck
+ CCriticalSection csDummy;
+ CBlockIndex indexDummy[100];
+ CChainParams& params = Params(CBaseChainParams::MAIN);
+ int64_t nPowTargetSpacing = params.GetConsensus().nPowTargetSpacing;
+
+ // Generate fake blockchain timestamps relative to
+ // an arbitrary time:
+ int64_t now = 1427379054;
+ SetMockTime(now);
+ for (int i = 0; i < 100; i++)
+ {
+ indexDummy[i].phashBlock = NULL;
+ if (i == 0) indexDummy[i].pprev = NULL;
+ else indexDummy[i].pprev = &indexDummy[i-1];
+ indexDummy[i].nHeight = i;
+ indexDummy[i].nTime = now - (100-i)*nPowTargetSpacing;
+ // Other members don't matter, the partition check code doesn't
+ // use them
+ }
+
+ // Test 1: chain with blocks every nPowTargetSpacing seconds,
+ // as normal, no worries:
+ PartitionCheck(falseFunc, csDummy, &indexDummy[99], nPowTargetSpacing);
+ BOOST_CHECK(strMiscWarning.empty());
+
+ // Test 2: go 3.5 hours without a block, expect a warning:
+ now += 3*60*60+30*60;
+ SetMockTime(now);
+ PartitionCheck(falseFunc, csDummy, &indexDummy[99], nPowTargetSpacing);
+ BOOST_CHECK(!strMiscWarning.empty());
+ BOOST_TEST_MESSAGE(std::string("Got alert text: ")+strMiscWarning);
+ strMiscWarning = "";
+
+ // Test 3: test the "partition alerts only go off once per day"
+ // code:
+ now += 60*10;
+ SetMockTime(now);
+ PartitionCheck(falseFunc, csDummy, &indexDummy[99], nPowTargetSpacing);
+ BOOST_CHECK(strMiscWarning.empty());
+
+ // Test 4: get 2.5 times as many blocks as expected:
+ now += 60*60*24; // Pretend it is a day later
+ SetMockTime(now);
+ int64_t quickSpacing = nPowTargetSpacing*2/5;
+ for (int i = 0; i < 100; i++) // Tweak chain timestamps:
+ indexDummy[i].nTime = now - (100-i)*quickSpacing;
+ PartitionCheck(falseFunc, csDummy, &indexDummy[99], nPowTargetSpacing);
+ BOOST_CHECK(!strMiscWarning.empty());
+ BOOST_TEST_MESSAGE(std::string("Got alert text: ")+strMiscWarning);
+ strMiscWarning = "";
+
+ SetMockTime(0);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/allocator_tests.cpp b/src/test/allocator_tests.cpp
new file mode 100644
index 0000000000..2108efece5
--- /dev/null
+++ b/src/test/allocator_tests.cpp
@@ -0,0 +1,120 @@
+// Copyright (c) 2012-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "util.h"
+
+#include "support/allocators/secure.h"
+#include "test/test_bitcoin.h"
+
+#include <boost/test/unit_test.hpp>
+
+BOOST_FIXTURE_TEST_SUITE(allocator_tests, BasicTestingSetup)
+
+// Dummy memory page locker for platform independent tests
+static const void *last_lock_addr, *last_unlock_addr;
+static size_t last_lock_len, last_unlock_len;
+class TestLocker
+{
+public:
+ bool Lock(const void *addr, size_t len)
+ {
+ last_lock_addr = addr;
+ last_lock_len = len;
+ return true;
+ }
+ bool Unlock(const void *addr, size_t len)
+ {
+ last_unlock_addr = addr;
+ last_unlock_len = len;
+ return true;
+ }
+};
+
+BOOST_AUTO_TEST_CASE(test_LockedPageManagerBase)
+{
+ const size_t test_page_size = 4096;
+ LockedPageManagerBase<TestLocker> lpm(test_page_size);
+ size_t addr;
+ last_lock_addr = last_unlock_addr = 0;
+ last_lock_len = last_unlock_len = 0;
+
+ /* Try large number of small objects */
+ addr = 0;
+ for(int i=0; i<1000; ++i)
+ {
+ lpm.LockRange(reinterpret_cast<void*>(addr), 33);
+ addr += 33;
+ }
+ /* Try small number of page-sized objects, straddling two pages */
+ addr = test_page_size*100 + 53;
+ for(int i=0; i<100; ++i)
+ {
+ lpm.LockRange(reinterpret_cast<void*>(addr), test_page_size);
+ addr += test_page_size;
+ }
+ /* Try small number of page-sized objects aligned to exactly one page */
+ addr = test_page_size*300;
+ for(int i=0; i<100; ++i)
+ {
+ lpm.LockRange(reinterpret_cast<void*>(addr), test_page_size);
+ addr += test_page_size;
+ }
+ /* one very large object, straddling pages */
+ lpm.LockRange(reinterpret_cast<void*>(test_page_size*600+1), test_page_size*500);
+ BOOST_CHECK(last_lock_addr == reinterpret_cast<void*>(test_page_size*(600+500)));
+ /* one very large object, page aligned */
+ lpm.LockRange(reinterpret_cast<void*>(test_page_size*1200), test_page_size*500-1);
+ BOOST_CHECK(last_lock_addr == reinterpret_cast<void*>(test_page_size*(1200+500-1)));
+
+ BOOST_CHECK(lpm.GetLockedPageCount() == (
+ (1000*33+test_page_size-1)/test_page_size + // small objects
+ 101 + 100 + // page-sized objects
+ 501 + 500)); // large objects
+ BOOST_CHECK((last_lock_len & (test_page_size-1)) == 0); // always lock entire pages
+ BOOST_CHECK(last_unlock_len == 0); // nothing unlocked yet
+
+ /* And unlock again */
+ addr = 0;
+ for(int i=0; i<1000; ++i)
+ {
+ lpm.UnlockRange(reinterpret_cast<void*>(addr), 33);
+ addr += 33;
+ }
+ addr = test_page_size*100 + 53;
+ for(int i=0; i<100; ++i)
+ {
+ lpm.UnlockRange(reinterpret_cast<void*>(addr), test_page_size);
+ addr += test_page_size;
+ }
+ addr = test_page_size*300;
+ for(int i=0; i<100; ++i)
+ {
+ lpm.UnlockRange(reinterpret_cast<void*>(addr), test_page_size);
+ addr += test_page_size;
+ }
+ lpm.UnlockRange(reinterpret_cast<void*>(test_page_size*600+1), test_page_size*500);
+ lpm.UnlockRange(reinterpret_cast<void*>(test_page_size*1200), test_page_size*500-1);
+
+ /* Check that everything is released */
+ BOOST_CHECK(lpm.GetLockedPageCount() == 0);
+
+ /* A few and unlocks of size zero (should have no effect) */
+ addr = 0;
+ for(int i=0; i<1000; ++i)
+ {
+ lpm.LockRange(reinterpret_cast<void*>(addr), 0);
+ addr += 1;
+ }
+ BOOST_CHECK(lpm.GetLockedPageCount() == 0);
+ addr = 0;
+ for(int i=0; i<1000; ++i)
+ {
+ lpm.UnlockRange(reinterpret_cast<void*>(addr), 0);
+ addr += 1;
+ }
+ BOOST_CHECK(lpm.GetLockedPageCount() == 0);
+ BOOST_CHECK((last_unlock_len & (test_page_size-1)) == 0); // always unlock entire pages
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/arith_uint256_tests.cpp b/src/test/arith_uint256_tests.cpp
new file mode 100644
index 0000000000..17d6bed6d2
--- /dev/null
+++ b/src/test/arith_uint256_tests.cpp
@@ -0,0 +1,567 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include <boost/test/unit_test.hpp>
+#include <stdint.h>
+#include <sstream>
+#include <iomanip>
+#include <limits>
+#include <cmath>
+#include "uint256.h"
+#include "arith_uint256.h"
+#include <string>
+#include "version.h"
+#include "test/test_bitcoin.h"
+
+BOOST_FIXTURE_TEST_SUITE(arith_uint256_tests, BasicTestingSetup)
+
+/// Convert vector to arith_uint256, via uint256 blob
+inline arith_uint256 arith_uint256V(const std::vector<unsigned char>& vch)
+{
+ return UintToArith256(uint256(vch));
+}
+
+const unsigned char R1Array[] =
+ "\x9c\x52\x4a\xdb\xcf\x56\x11\x12\x2b\x29\x12\x5e\x5d\x35\xd2\xd2"
+ "\x22\x81\xaa\xb5\x33\xf0\x08\x32\xd5\x56\xb1\xf9\xea\xe5\x1d\x7d";
+const char R1ArrayHex[] = "7D1DE5EAF9B156D53208F033B5AA8122D2d2355d5e12292b121156cfdb4a529c";
+const double R1Ldouble = 0.4887374590559308955; // R1L equals roughly R1Ldouble * 2^256
+const arith_uint256 R1L = arith_uint256V(std::vector<unsigned char>(R1Array,R1Array+32));
+const uint64_t R1LLow64 = 0x121156cfdb4a529cULL;
+
+const unsigned char R2Array[] =
+ "\x70\x32\x1d\x7c\x47\xa5\x6b\x40\x26\x7e\x0a\xc3\xa6\x9c\xb6\xbf"
+ "\x13\x30\x47\xa3\x19\x2d\xda\x71\x49\x13\x72\xf0\xb4\xca\x81\xd7";
+const arith_uint256 R2L = arith_uint256V(std::vector<unsigned char>(R2Array,R2Array+32));
+
+const char R1LplusR2L[] = "549FB09FEA236A1EA3E31D4D58F1B1369288D204211CA751527CFC175767850C";
+
+const unsigned char ZeroArray[] =
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
+const arith_uint256 ZeroL = arith_uint256V(std::vector<unsigned char>(ZeroArray,ZeroArray+32));
+
+const unsigned char OneArray[] =
+ "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
+const arith_uint256 OneL = arith_uint256V(std::vector<unsigned char>(OneArray,OneArray+32));
+
+const unsigned char MaxArray[] =
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff";
+const arith_uint256 MaxL = arith_uint256V(std::vector<unsigned char>(MaxArray,MaxArray+32));
+
+const arith_uint256 HalfL = (OneL << 255);
+std::string ArrayToString(const unsigned char A[], unsigned int width)
+{
+ std::stringstream Stream;
+ Stream << std::hex;
+ for (unsigned int i = 0; i < width; ++i)
+ {
+ Stream<<std::setw(2)<<std::setfill('0')<<(unsigned int)A[width-i-1];
+ }
+ return Stream.str();
+}
+
+BOOST_AUTO_TEST_CASE( basics ) // constructors, equality, inequality
+{
+ BOOST_CHECK(1 == 0+1);
+ // constructor arith_uint256(vector<char>):
+ BOOST_CHECK(R1L.ToString() == ArrayToString(R1Array,32));
+ BOOST_CHECK(R2L.ToString() == ArrayToString(R2Array,32));
+ BOOST_CHECK(ZeroL.ToString() == ArrayToString(ZeroArray,32));
+ BOOST_CHECK(OneL.ToString() == ArrayToString(OneArray,32));
+ BOOST_CHECK(MaxL.ToString() == ArrayToString(MaxArray,32));
+ BOOST_CHECK(OneL.ToString() != ArrayToString(ZeroArray,32));
+
+ // == and !=
+ BOOST_CHECK(R1L != R2L);
+ BOOST_CHECK(ZeroL != OneL);
+ BOOST_CHECK(OneL != ZeroL);
+ BOOST_CHECK(MaxL != ZeroL);
+ BOOST_CHECK(~MaxL == ZeroL);
+ BOOST_CHECK( ((R1L ^ R2L) ^ R1L) == R2L);
+
+ uint64_t Tmp64 = 0xc4dab720d9c7acaaULL;
+ for (unsigned int i = 0; i < 256; ++i)
+ {
+ BOOST_CHECK(ZeroL != (OneL << i));
+ BOOST_CHECK((OneL << i) != ZeroL);
+ BOOST_CHECK(R1L != (R1L ^ (OneL << i)));
+ BOOST_CHECK(((arith_uint256(Tmp64) ^ (OneL << i) ) != Tmp64 ));
+ }
+ BOOST_CHECK(ZeroL == (OneL << 256));
+
+ // String Constructor and Copy Constructor
+ BOOST_CHECK(arith_uint256("0x"+R1L.ToString()) == R1L);
+ BOOST_CHECK(arith_uint256("0x"+R2L.ToString()) == R2L);
+ BOOST_CHECK(arith_uint256("0x"+ZeroL.ToString()) == ZeroL);
+ BOOST_CHECK(arith_uint256("0x"+OneL.ToString()) == OneL);
+ BOOST_CHECK(arith_uint256("0x"+MaxL.ToString()) == MaxL);
+ BOOST_CHECK(arith_uint256(R1L.ToString()) == R1L);
+ BOOST_CHECK(arith_uint256(" 0x"+R1L.ToString()+" ") == R1L);
+ BOOST_CHECK(arith_uint256("") == ZeroL);
+ BOOST_CHECK(R1L == arith_uint256(R1ArrayHex));
+ BOOST_CHECK(arith_uint256(R1L) == R1L);
+ BOOST_CHECK((arith_uint256(R1L^R2L)^R2L) == R1L);
+ BOOST_CHECK(arith_uint256(ZeroL) == ZeroL);
+ BOOST_CHECK(arith_uint256(OneL) == OneL);
+
+ // uint64_t constructor
+ BOOST_CHECK( (R1L & arith_uint256("0xffffffffffffffff")) == arith_uint256(R1LLow64));
+ BOOST_CHECK(ZeroL == arith_uint256(0));
+ BOOST_CHECK(OneL == arith_uint256(1));
+ BOOST_CHECK(arith_uint256("0xffffffffffffffff") = arith_uint256(0xffffffffffffffffULL));
+
+ // Assignment (from base_uint)
+ arith_uint256 tmpL = ~ZeroL; BOOST_CHECK(tmpL == ~ZeroL);
+ tmpL = ~OneL; BOOST_CHECK(tmpL == ~OneL);
+ tmpL = ~R1L; BOOST_CHECK(tmpL == ~R1L);
+ tmpL = ~R2L; BOOST_CHECK(tmpL == ~R2L);
+ tmpL = ~MaxL; BOOST_CHECK(tmpL == ~MaxL);
+}
+
+void shiftArrayRight(unsigned char* to, const unsigned char* from, unsigned int arrayLength, unsigned int bitsToShift)
+{
+ for (unsigned int T=0; T < arrayLength; ++T)
+ {
+ unsigned int F = (T+bitsToShift/8);
+ if (F < arrayLength)
+ to[T] = from[F] >> (bitsToShift%8);
+ else
+ to[T] = 0;
+ if (F + 1 < arrayLength)
+ to[T] |= from[(F+1)] << (8-bitsToShift%8);
+ }
+}
+
+void shiftArrayLeft(unsigned char* to, const unsigned char* from, unsigned int arrayLength, unsigned int bitsToShift)
+{
+ for (unsigned int T=0; T < arrayLength; ++T)
+ {
+ if (T >= bitsToShift/8)
+ {
+ unsigned int F = T-bitsToShift/8;
+ to[T] = from[F] << (bitsToShift%8);
+ if (T >= bitsToShift/8+1)
+ to[T] |= from[F-1] >> (8-bitsToShift%8);
+ }
+ else {
+ to[T] = 0;
+ }
+ }
+}
+
+BOOST_AUTO_TEST_CASE( shifts ) { // "<<" ">>" "<<=" ">>="
+ unsigned char TmpArray[32];
+ arith_uint256 TmpL;
+ for (unsigned int i = 0; i < 256; ++i)
+ {
+ shiftArrayLeft(TmpArray, OneArray, 32, i);
+ BOOST_CHECK(arith_uint256V(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (OneL << i));
+ TmpL = OneL; TmpL <<= i;
+ BOOST_CHECK(TmpL == (OneL << i));
+ BOOST_CHECK((HalfL >> (255-i)) == (OneL << i));
+ TmpL = HalfL; TmpL >>= (255-i);
+ BOOST_CHECK(TmpL == (OneL << i));
+
+ shiftArrayLeft(TmpArray, R1Array, 32, i);
+ BOOST_CHECK(arith_uint256V(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (R1L << i));
+ TmpL = R1L; TmpL <<= i;
+ BOOST_CHECK(TmpL == (R1L << i));
+
+ shiftArrayRight(TmpArray, R1Array, 32, i);
+ BOOST_CHECK(arith_uint256V(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (R1L >> i));
+ TmpL = R1L; TmpL >>= i;
+ BOOST_CHECK(TmpL == (R1L >> i));
+
+ shiftArrayLeft(TmpArray, MaxArray, 32, i);
+ BOOST_CHECK(arith_uint256V(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (MaxL << i));
+ TmpL = MaxL; TmpL <<= i;
+ BOOST_CHECK(TmpL == (MaxL << i));
+
+ shiftArrayRight(TmpArray, MaxArray, 32, i);
+ BOOST_CHECK(arith_uint256V(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (MaxL >> i));
+ TmpL = MaxL; TmpL >>= i;
+ BOOST_CHECK(TmpL == (MaxL >> i));
+ }
+ arith_uint256 c1L = arith_uint256(0x0123456789abcdefULL);
+ arith_uint256 c2L = c1L << 128;
+ for (unsigned int i = 0; i < 128; ++i) {
+ BOOST_CHECK((c1L << i) == (c2L >> (128-i)));
+ }
+ for (unsigned int i = 128; i < 256; ++i) {
+ BOOST_CHECK((c1L << i) == (c2L << (i-128)));
+ }
+}
+
+BOOST_AUTO_TEST_CASE( unaryOperators ) // ! ~ -
+{
+ BOOST_CHECK(!ZeroL);
+ BOOST_CHECK(!(!OneL));
+ for (unsigned int i = 0; i < 256; ++i)
+ BOOST_CHECK(!(!(OneL<<i)));
+ BOOST_CHECK(!(!R1L));
+ BOOST_CHECK(!(!MaxL));
+
+ BOOST_CHECK(~ZeroL == MaxL);
+
+ unsigned char TmpArray[32];
+ for (unsigned int i = 0; i < 32; ++i) { TmpArray[i] = ~R1Array[i]; }
+ BOOST_CHECK(arith_uint256V(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (~R1L));
+
+ BOOST_CHECK(-ZeroL == ZeroL);
+ BOOST_CHECK(-R1L == (~R1L)+1);
+ for (unsigned int i = 0; i < 256; ++i)
+ BOOST_CHECK(-(OneL<<i) == (MaxL << i));
+}
+
+
+// Check if doing _A_ _OP_ _B_ results in the same as applying _OP_ onto each
+// element of Aarray and Barray, and then converting the result into a arith_uint256.
+#define CHECKBITWISEOPERATOR(_A_,_B_,_OP_) \
+ for (unsigned int i = 0; i < 32; ++i) { TmpArray[i] = _A_##Array[i] _OP_ _B_##Array[i]; } \
+ BOOST_CHECK(arith_uint256V(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (_A_##L _OP_ _B_##L));
+
+#define CHECKASSIGNMENTOPERATOR(_A_,_B_,_OP_) \
+ TmpL = _A_##L; TmpL _OP_##= _B_##L; BOOST_CHECK(TmpL == (_A_##L _OP_ _B_##L));
+
+BOOST_AUTO_TEST_CASE( bitwiseOperators )
+{
+ unsigned char TmpArray[32];
+
+ CHECKBITWISEOPERATOR(R1,R2,|)
+ CHECKBITWISEOPERATOR(R1,R2,^)
+ CHECKBITWISEOPERATOR(R1,R2,&)
+ CHECKBITWISEOPERATOR(R1,Zero,|)
+ CHECKBITWISEOPERATOR(R1,Zero,^)
+ CHECKBITWISEOPERATOR(R1,Zero,&)
+ CHECKBITWISEOPERATOR(R1,Max,|)
+ CHECKBITWISEOPERATOR(R1,Max,^)
+ CHECKBITWISEOPERATOR(R1,Max,&)
+ CHECKBITWISEOPERATOR(Zero,R1,|)
+ CHECKBITWISEOPERATOR(Zero,R1,^)
+ CHECKBITWISEOPERATOR(Zero,R1,&)
+ CHECKBITWISEOPERATOR(Max,R1,|)
+ CHECKBITWISEOPERATOR(Max,R1,^)
+ CHECKBITWISEOPERATOR(Max,R1,&)
+
+ arith_uint256 TmpL;
+ CHECKASSIGNMENTOPERATOR(R1,R2,|)
+ CHECKASSIGNMENTOPERATOR(R1,R2,^)
+ CHECKASSIGNMENTOPERATOR(R1,R2,&)
+ CHECKASSIGNMENTOPERATOR(R1,Zero,|)
+ CHECKASSIGNMENTOPERATOR(R1,Zero,^)
+ CHECKASSIGNMENTOPERATOR(R1,Zero,&)
+ CHECKASSIGNMENTOPERATOR(R1,Max,|)
+ CHECKASSIGNMENTOPERATOR(R1,Max,^)
+ CHECKASSIGNMENTOPERATOR(R1,Max,&)
+ CHECKASSIGNMENTOPERATOR(Zero,R1,|)
+ CHECKASSIGNMENTOPERATOR(Zero,R1,^)
+ CHECKASSIGNMENTOPERATOR(Zero,R1,&)
+ CHECKASSIGNMENTOPERATOR(Max,R1,|)
+ CHECKASSIGNMENTOPERATOR(Max,R1,^)
+ CHECKASSIGNMENTOPERATOR(Max,R1,&)
+
+ uint64_t Tmp64 = 0xe1db685c9a0b47a2ULL;
+ TmpL = R1L; TmpL |= Tmp64; BOOST_CHECK(TmpL == (R1L | arith_uint256(Tmp64)));
+ TmpL = R1L; TmpL |= 0; BOOST_CHECK(TmpL == R1L);
+ TmpL ^= 0; BOOST_CHECK(TmpL == R1L);
+ TmpL ^= Tmp64; BOOST_CHECK(TmpL == (R1L ^ arith_uint256(Tmp64)));
+}
+
+BOOST_AUTO_TEST_CASE( comparison ) // <= >= < >
+{
+ arith_uint256 TmpL;
+ for (unsigned int i = 0; i < 256; ++i) {
+ TmpL= OneL<< i;
+ BOOST_CHECK( TmpL >= ZeroL && TmpL > ZeroL && ZeroL < TmpL && ZeroL <= TmpL);
+ BOOST_CHECK( TmpL >= 0 && TmpL > 0 && 0 < TmpL && 0 <= TmpL);
+ TmpL |= R1L;
+ BOOST_CHECK( TmpL >= R1L ); BOOST_CHECK( (TmpL == R1L) != (TmpL > R1L)); BOOST_CHECK( (TmpL == R1L) || !( TmpL <= R1L));
+ BOOST_CHECK( R1L <= TmpL ); BOOST_CHECK( (R1L == TmpL) != (R1L < TmpL)); BOOST_CHECK( (TmpL == R1L) || !( R1L >= TmpL));
+ BOOST_CHECK(! (TmpL < R1L)); BOOST_CHECK(! (R1L > TmpL));
+ }
+}
+
+BOOST_AUTO_TEST_CASE( plusMinus )
+{
+ arith_uint256 TmpL = 0;
+ BOOST_CHECK(R1L+R2L == arith_uint256(R1LplusR2L));
+ TmpL += R1L;
+ BOOST_CHECK(TmpL == R1L);
+ TmpL += R2L;
+ BOOST_CHECK(TmpL == R1L + R2L);
+ BOOST_CHECK(OneL+MaxL == ZeroL);
+ BOOST_CHECK(MaxL+OneL == ZeroL);
+ for (unsigned int i = 1; i < 256; ++i) {
+ BOOST_CHECK( (MaxL >> i) + OneL == (HalfL >> (i-1)) );
+ BOOST_CHECK( OneL + (MaxL >> i) == (HalfL >> (i-1)) );
+ TmpL = (MaxL>>i); TmpL += OneL;
+ BOOST_CHECK( TmpL == (HalfL >> (i-1)) );
+ TmpL = (MaxL>>i); TmpL += 1;
+ BOOST_CHECK( TmpL == (HalfL >> (i-1)) );
+ TmpL = (MaxL>>i);
+ BOOST_CHECK( TmpL++ == (MaxL>>i) );
+ BOOST_CHECK( TmpL == (HalfL >> (i-1)));
+ }
+ BOOST_CHECK(arith_uint256(0xbedc77e27940a7ULL) + 0xee8d836fce66fbULL == arith_uint256(0xbedc77e27940a7ULL + 0xee8d836fce66fbULL));
+ TmpL = arith_uint256(0xbedc77e27940a7ULL); TmpL += 0xee8d836fce66fbULL;
+ BOOST_CHECK(TmpL == arith_uint256(0xbedc77e27940a7ULL+0xee8d836fce66fbULL));
+ TmpL -= 0xee8d836fce66fbULL; BOOST_CHECK(TmpL == 0xbedc77e27940a7ULL);
+ TmpL = R1L;
+ BOOST_CHECK(++TmpL == R1L+1);
+
+ BOOST_CHECK(R1L -(-R2L) == R1L+R2L);
+ BOOST_CHECK(R1L -(-OneL) == R1L+OneL);
+ BOOST_CHECK(R1L - OneL == R1L+(-OneL));
+ for (unsigned int i = 1; i < 256; ++i) {
+ BOOST_CHECK((MaxL>>i) - (-OneL) == (HalfL >> (i-1)));
+ BOOST_CHECK((HalfL >> (i-1)) - OneL == (MaxL>>i));
+ TmpL = (HalfL >> (i-1));
+ BOOST_CHECK(TmpL-- == (HalfL >> (i-1)));
+ BOOST_CHECK(TmpL == (MaxL >> i));
+ TmpL = (HalfL >> (i-1));
+ BOOST_CHECK(--TmpL == (MaxL >> i));
+ }
+ TmpL = R1L;
+ BOOST_CHECK(--TmpL == R1L-1);
+}
+
+BOOST_AUTO_TEST_CASE( multiply )
+{
+ BOOST_CHECK((R1L * R1L).ToString() == "62a38c0486f01e45879d7910a7761bf30d5237e9873f9bff3642a732c4d84f10");
+ BOOST_CHECK((R1L * R2L).ToString() == "de37805e9986996cfba76ff6ba51c008df851987d9dd323f0e5de07760529c40");
+ BOOST_CHECK((R1L * ZeroL) == ZeroL);
+ BOOST_CHECK((R1L * OneL) == R1L);
+ BOOST_CHECK((R1L * MaxL) == -R1L);
+ BOOST_CHECK((R2L * R1L) == (R1L * R2L));
+ BOOST_CHECK((R2L * R2L).ToString() == "ac8c010096767d3cae5005dec28bb2b45a1d85ab7996ccd3e102a650f74ff100");
+ BOOST_CHECK((R2L * ZeroL) == ZeroL);
+ BOOST_CHECK((R2L * OneL) == R2L);
+ BOOST_CHECK((R2L * MaxL) == -R2L);
+
+ BOOST_CHECK(MaxL * MaxL == OneL);
+
+ BOOST_CHECK((R1L * 0) == 0);
+ BOOST_CHECK((R1L * 1) == R1L);
+ BOOST_CHECK((R1L * 3).ToString() == "7759b1c0ed14047f961ad09b20ff83687876a0181a367b813634046f91def7d4");
+ BOOST_CHECK((R2L * 0x87654321UL).ToString() == "23f7816e30c4ae2017257b7a0fa64d60402f5234d46e746b61c960d09a26d070");
+}
+
+BOOST_AUTO_TEST_CASE( divide )
+{
+ arith_uint256 D1L("AD7133AC1977FA2B7");
+ arith_uint256 D2L("ECD751716");
+ BOOST_CHECK((R1L / D1L).ToString() == "00000000000000000b8ac01106981635d9ed112290f8895545a7654dde28fb3a");
+ BOOST_CHECK((R1L / D2L).ToString() == "000000000873ce8efec5b67150bad3aa8c5fcb70e947586153bf2cec7c37c57a");
+ BOOST_CHECK(R1L / OneL == R1L);
+ BOOST_CHECK(R1L / MaxL == ZeroL);
+ BOOST_CHECK(MaxL / R1L == 2);
+ BOOST_CHECK_THROW(R1L / ZeroL, uint_error);
+ BOOST_CHECK((R2L / D1L).ToString() == "000000000000000013e1665895a1cc981de6d93670105a6b3ec3b73141b3a3c5");
+ BOOST_CHECK((R2L / D2L).ToString() == "000000000e8f0abe753bb0afe2e9437ee85d280be60882cf0bd1aaf7fa3cc2c4");
+ BOOST_CHECK(R2L / OneL == R2L);
+ BOOST_CHECK(R2L / MaxL == ZeroL);
+ BOOST_CHECK(MaxL / R2L == 1);
+ BOOST_CHECK_THROW(R2L / ZeroL, uint_error);
+}
+
+
+bool almostEqual(double d1, double d2)
+{
+ return fabs(d1-d2) <= 4*fabs(d1)*std::numeric_limits<double>::epsilon();
+}
+
+BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex size() GetLow64 GetSerializeSize, Serialize, Unserialize
+{
+ BOOST_CHECK(R1L.GetHex() == R1L.ToString());
+ BOOST_CHECK(R2L.GetHex() == R2L.ToString());
+ BOOST_CHECK(OneL.GetHex() == OneL.ToString());
+ BOOST_CHECK(MaxL.GetHex() == MaxL.ToString());
+ arith_uint256 TmpL(R1L);
+ BOOST_CHECK(TmpL == R1L);
+ TmpL.SetHex(R2L.ToString()); BOOST_CHECK(TmpL == R2L);
+ TmpL.SetHex(ZeroL.ToString()); BOOST_CHECK(TmpL == 0);
+ TmpL.SetHex(HalfL.ToString()); BOOST_CHECK(TmpL == HalfL);
+
+ TmpL.SetHex(R1L.ToString());
+ BOOST_CHECK(R1L.size() == 32);
+ BOOST_CHECK(R2L.size() == 32);
+ BOOST_CHECK(ZeroL.size() == 32);
+ BOOST_CHECK(MaxL.size() == 32);
+ BOOST_CHECK(R1L.GetLow64() == R1LLow64);
+ BOOST_CHECK(HalfL.GetLow64() ==0x0000000000000000ULL);
+ BOOST_CHECK(OneL.GetLow64() ==0x0000000000000001ULL);
+
+ for (unsigned int i = 0; i < 255; ++i)
+ {
+ BOOST_CHECK((OneL << i).getdouble() == ldexp(1.0,i));
+ }
+ BOOST_CHECK(ZeroL.getdouble() == 0.0);
+ for (int i = 256; i > 53; --i)
+ BOOST_CHECK(almostEqual((R1L>>(256-i)).getdouble(), ldexp(R1Ldouble,i)));
+ uint64_t R1L64part = (R1L>>192).GetLow64();
+ for (int i = 53; i > 0; --i) // doubles can store all integers in {0,...,2^54-1} exactly
+ {
+ BOOST_CHECK((R1L>>(256-i)).getdouble() == (double)(R1L64part >> (64-i)));
+ }
+}
+
+BOOST_AUTO_TEST_CASE(bignum_SetCompact)
+{
+ arith_uint256 num;
+ bool fNegative;
+ bool fOverflow;
+ num.SetCompact(0, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x00123456, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x01003456, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x02000056, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x03000000, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x04000000, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x00923456, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x01803456, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x02800056, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x03800000, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x04800000, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x01123456, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000012");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0x01120000U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ // Make sure that we don't generate compacts with the 0x00800000 bit set
+ num = 0x80;
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0x02008000U);
+
+ num.SetCompact(0x01fedcba, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "000000000000000000000000000000000000000000000000000000000000007e");
+ BOOST_CHECK_EQUAL(num.GetCompact(true), 0x01fe0000U);
+ BOOST_CHECK_EQUAL(fNegative, true);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x02123456, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000001234");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0x02123400U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x03123456, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000123456");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0x03123456U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x04123456, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000012345600");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0x04123456U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x04923456, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000012345600");
+ BOOST_CHECK_EQUAL(num.GetCompact(true), 0x04923456U);
+ BOOST_CHECK_EQUAL(fNegative, true);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x05009234, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000092340000");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0x05009234U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x20123456, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "1234560000000000000000000000000000000000000000000000000000000000");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0x20123456U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0xff123456, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, true);
+}
+
+
+BOOST_AUTO_TEST_CASE( getmaxcoverage ) // some more tests just to get 100% coverage
+{
+ // ~R1L give a base_uint<256>
+ BOOST_CHECK((~~R1L >> 10) == (R1L >> 10));
+ BOOST_CHECK((~~R1L << 10) == (R1L << 10));
+ BOOST_CHECK(!(~~R1L < R1L));
+ BOOST_CHECK(~~R1L <= R1L);
+ BOOST_CHECK(!(~~R1L > R1L));
+ BOOST_CHECK(~~R1L >= R1L);
+ BOOST_CHECK(!(R1L < ~~R1L));
+ BOOST_CHECK(R1L <= ~~R1L);
+ BOOST_CHECK(!(R1L > ~~R1L));
+ BOOST_CHECK(R1L >= ~~R1L);
+
+ BOOST_CHECK(~~R1L + R2L == R1L + ~~R2L);
+ BOOST_CHECK(~~R1L - R2L == R1L - ~~R2L);
+ BOOST_CHECK(~R1L != R1L); BOOST_CHECK(R1L != ~R1L);
+ unsigned char TmpArray[32];
+ CHECKBITWISEOPERATOR(~R1,R2,|)
+ CHECKBITWISEOPERATOR(~R1,R2,^)
+ CHECKBITWISEOPERATOR(~R1,R2,&)
+ CHECKBITWISEOPERATOR(R1,~R2,|)
+ CHECKBITWISEOPERATOR(R1,~R2,^)
+ CHECKBITWISEOPERATOR(R1,~R2,&)
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/base32_tests.cpp b/src/test/base32_tests.cpp
new file mode 100644
index 0000000000..8ec8861425
--- /dev/null
+++ b/src/test/base32_tests.cpp
@@ -0,0 +1,25 @@
+// Copyright (c) 2012-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "utilstrencodings.h"
+#include "test/test_bitcoin.h"
+
+#include <boost/test/unit_test.hpp>
+
+BOOST_FIXTURE_TEST_SUITE(base32_tests, BasicTestingSetup)
+
+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<sizeof(vstrIn)/sizeof(vstrIn[0]); i++)
+ {
+ std::string strEnc = EncodeBase32(vstrIn[i]);
+ BOOST_CHECK(strEnc == vstrOut[i]);
+ std::string strDec = DecodeBase32(vstrOut[i]);
+ BOOST_CHECK(strDec == vstrIn[i]);
+ }
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/base58_tests.cpp b/src/test/base58_tests.cpp
new file mode 100644
index 0000000000..f07dd7a7db
--- /dev/null
+++ b/src/test/base58_tests.cpp
@@ -0,0 +1,280 @@
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "base58.h"
+
+#include "data/base58_encode_decode.json.h"
+#include "data/base58_keys_invalid.json.h"
+#include "data/base58_keys_valid.json.h"
+
+#include "key.h"
+#include "script/script.h"
+#include "uint256.h"
+#include "util.h"
+#include "utilstrencodings.h"
+#include "test/test_bitcoin.h"
+
+#include <boost/foreach.hpp>
+#include <boost/test/unit_test.hpp>
+#include "json/json_spirit_reader_template.h"
+#include "json/json_spirit_utils.h"
+#include "json/json_spirit_writer_template.h"
+
+using namespace json_spirit;
+extern Array read_json(const std::string& jsondata);
+
+BOOST_FIXTURE_TEST_SUITE(base58_tests, BasicTestingSetup)
+
+// Goal: test low-level base58 encoding functionality
+BOOST_AUTO_TEST_CASE(base58_EncodeBase58)
+{
+ Array tests = read_json(std::string(json_tests::base58_encode_decode, json_tests::base58_encode_decode + sizeof(json_tests::base58_encode_decode)));
+ BOOST_FOREACH(Value& tv, tests)
+ {
+ Array test = tv.get_array();
+ std::string strTest = write_string(tv, false);
+ if (test.size() < 2) // Allow for extra stuff (useful for comments)
+ {
+ BOOST_ERROR("Bad test: " << strTest);
+ continue;
+ }
+ std::vector<unsigned char> sourcedata = ParseHex(test[0].get_str());
+ std::string base58string = test[1].get_str();
+ BOOST_CHECK_MESSAGE(
+ EncodeBase58(begin_ptr(sourcedata), end_ptr(sourcedata)) == base58string,
+ strTest);
+ }
+}
+
+// Goal: test low-level base58 decoding functionality
+BOOST_AUTO_TEST_CASE(base58_DecodeBase58)
+{
+ Array tests = read_json(std::string(json_tests::base58_encode_decode, json_tests::base58_encode_decode + sizeof(json_tests::base58_encode_decode)));
+ std::vector<unsigned char> result;
+
+ BOOST_FOREACH(Value& tv, tests)
+ {
+ Array test = tv.get_array();
+ std::string strTest = write_string(tv, false);
+ if (test.size() < 2) // Allow for extra stuff (useful for comments)
+ {
+ BOOST_ERROR("Bad test: " << strTest);
+ continue;
+ }
+ std::vector<unsigned char> expected = ParseHex(test[0].get_str());
+ std::string base58string = test[1].get_str();
+ BOOST_CHECK_MESSAGE(DecodeBase58(base58string, result), strTest);
+ BOOST_CHECK_MESSAGE(result.size() == expected.size() && std::equal(result.begin(), result.end(), expected.begin()), strTest);
+ }
+
+ BOOST_CHECK(!DecodeBase58("invalid", result));
+
+ // check that DecodeBase58 skips whitespace, but still fails with unexpected non-whitespace at the end.
+ BOOST_CHECK(!DecodeBase58(" \t\n\v\f\r skip \r\f\v\n\t a", result));
+ BOOST_CHECK( DecodeBase58(" \t\n\v\f\r skip \r\f\v\n\t ", result));
+ std::vector<unsigned char> expected = ParseHex("971a55");
+ BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end());
+}
+
+// Visitor to check address type
+class TestAddrTypeVisitor : public boost::static_visitor<bool>
+{
+private:
+ std::string exp_addrType;
+public:
+ TestAddrTypeVisitor(const std::string &exp_addrType) : exp_addrType(exp_addrType) { }
+ bool operator()(const CKeyID &id) const
+ {
+ return (exp_addrType == "pubkey");
+ }
+ bool operator()(const CScriptID &id) const
+ {
+ return (exp_addrType == "script");
+ }
+ bool operator()(const CNoDestination &no) const
+ {
+ return (exp_addrType == "none");
+ }
+};
+
+// Visitor to check address payload
+class TestPayloadVisitor : public boost::static_visitor<bool>
+{
+private:
+ std::vector<unsigned char> exp_payload;
+public:
+ TestPayloadVisitor(std::vector<unsigned char> &exp_payload) : exp_payload(exp_payload) { }
+ bool operator()(const CKeyID &id) const
+ {
+ uint160 exp_key(exp_payload);
+ return exp_key == id;
+ }
+ bool operator()(const CScriptID &id) const
+ {
+ uint160 exp_key(exp_payload);
+ return exp_key == id;
+ }
+ bool operator()(const CNoDestination &no) const
+ {
+ return exp_payload.size() == 0;
+ }
+};
+
+// Goal: check that parsed keys match test payload
+BOOST_AUTO_TEST_CASE(base58_keys_valid_parse)
+{
+ Array tests = read_json(std::string(json_tests::base58_keys_valid, json_tests::base58_keys_valid + sizeof(json_tests::base58_keys_valid)));
+ std::vector<unsigned char> result;
+ CBitcoinSecret secret;
+ CBitcoinAddress addr;
+ SelectParams(CBaseChainParams::MAIN);
+
+ BOOST_FOREACH(Value& tv, tests)
+ {
+ Array test = tv.get_array();
+ std::string strTest = write_string(tv, false);
+ if (test.size() < 3) // Allow for extra stuff (useful for comments)
+ {
+ BOOST_ERROR("Bad test: " << strTest);
+ continue;
+ }
+ std::string exp_base58string = test[0].get_str();
+ std::vector<unsigned char> exp_payload = ParseHex(test[1].get_str());
+ const Object &metadata = test[2].get_obj();
+ bool isPrivkey = find_value(metadata, "isPrivkey").get_bool();
+ bool isTestnet = find_value(metadata, "isTestnet").get_bool();
+ if (isTestnet)
+ SelectParams(CBaseChainParams::TESTNET);
+ else
+ SelectParams(CBaseChainParams::MAIN);
+ if(isPrivkey)
+ {
+ bool isCompressed = find_value(metadata, "isCompressed").get_bool();
+ // Must be valid private key
+ // Note: CBitcoinSecret::SetString tests isValid, whereas CBitcoinAddress does not!
+ BOOST_CHECK_MESSAGE(secret.SetString(exp_base58string), "!SetString:"+ strTest);
+ BOOST_CHECK_MESSAGE(secret.IsValid(), "!IsValid:" + strTest);
+ CKey privkey = secret.GetKey();
+ BOOST_CHECK_MESSAGE(privkey.IsCompressed() == isCompressed, "compressed mismatch:" + strTest);
+ BOOST_CHECK_MESSAGE(privkey.size() == exp_payload.size() && std::equal(privkey.begin(), privkey.end(), exp_payload.begin()), "key mismatch:" + strTest);
+
+ // Private key must be invalid public key
+ addr.SetString(exp_base58string);
+ BOOST_CHECK_MESSAGE(!addr.IsValid(), "IsValid privkey as pubkey:" + strTest);
+ }
+ else
+ {
+ std::string exp_addrType = find_value(metadata, "addrType").get_str(); // "script" or "pubkey"
+ // Must be valid public key
+ BOOST_CHECK_MESSAGE(addr.SetString(exp_base58string), "SetString:" + strTest);
+ BOOST_CHECK_MESSAGE(addr.IsValid(), "!IsValid:" + strTest);
+ BOOST_CHECK_MESSAGE(addr.IsScript() == (exp_addrType == "script"), "isScript mismatch" + strTest);
+ CTxDestination dest = addr.Get();
+ BOOST_CHECK_MESSAGE(boost::apply_visitor(TestAddrTypeVisitor(exp_addrType), dest), "addrType mismatch" + strTest);
+
+ // Public key must be invalid private key
+ secret.SetString(exp_base58string);
+ BOOST_CHECK_MESSAGE(!secret.IsValid(), "IsValid pubkey as privkey:" + strTest);
+ }
+ }
+}
+
+// Goal: check that generated keys match test vectors
+BOOST_AUTO_TEST_CASE(base58_keys_valid_gen)
+{
+ Array tests = read_json(std::string(json_tests::base58_keys_valid, json_tests::base58_keys_valid + sizeof(json_tests::base58_keys_valid)));
+ std::vector<unsigned char> result;
+ BOOST_FOREACH(Value& tv, tests)
+ {
+ Array test = tv.get_array();
+ std::string strTest = write_string(tv, false);
+ if (test.size() < 3) // Allow for extra stuff (useful for comments)
+ {
+ BOOST_ERROR("Bad test: " << strTest);
+ continue;
+ }
+ std::string exp_base58string = test[0].get_str();
+ std::vector<unsigned char> exp_payload = ParseHex(test[1].get_str());
+ const Object &metadata = test[2].get_obj();
+ bool isPrivkey = find_value(metadata, "isPrivkey").get_bool();
+ bool isTestnet = find_value(metadata, "isTestnet").get_bool();
+ if (isTestnet)
+ SelectParams(CBaseChainParams::TESTNET);
+ else
+ SelectParams(CBaseChainParams::MAIN);
+ if(isPrivkey)
+ {
+ bool isCompressed = find_value(metadata, "isCompressed").get_bool();
+ CKey key;
+ key.Set(exp_payload.begin(), exp_payload.end(), isCompressed);
+ assert(key.IsValid());
+ CBitcoinSecret secret;
+ secret.SetKey(key);
+ BOOST_CHECK_MESSAGE(secret.ToString() == exp_base58string, "result mismatch: " + strTest);
+ }
+ else
+ {
+ std::string exp_addrType = find_value(metadata, "addrType").get_str();
+ CTxDestination dest;
+ if(exp_addrType == "pubkey")
+ {
+ dest = CKeyID(uint160(exp_payload));
+ }
+ else if(exp_addrType == "script")
+ {
+ dest = CScriptID(uint160(exp_payload));
+ }
+ else if(exp_addrType == "none")
+ {
+ dest = CNoDestination();
+ }
+ else
+ {
+ BOOST_ERROR("Bad addrtype: " << strTest);
+ continue;
+ }
+ CBitcoinAddress addrOut;
+ BOOST_CHECK_MESSAGE(addrOut.Set(dest), "encode dest: " + strTest);
+ BOOST_CHECK_MESSAGE(addrOut.ToString() == exp_base58string, "mismatch: " + strTest);
+ }
+ }
+
+ // Visiting a CNoDestination must fail
+ CBitcoinAddress dummyAddr;
+ CTxDestination nodest = CNoDestination();
+ BOOST_CHECK(!dummyAddr.Set(nodest));
+
+ SelectParams(CBaseChainParams::MAIN);
+}
+
+// Goal: check that base58 parsing code is robust against a variety of corrupted data
+BOOST_AUTO_TEST_CASE(base58_keys_invalid)
+{
+ Array tests = read_json(std::string(json_tests::base58_keys_invalid, json_tests::base58_keys_invalid + sizeof(json_tests::base58_keys_invalid))); // Negative testcases
+ std::vector<unsigned char> result;
+ CBitcoinSecret secret;
+ CBitcoinAddress addr;
+
+ BOOST_FOREACH(Value& tv, tests)
+ {
+ Array test = tv.get_array();
+ std::string strTest = write_string(tv, false);
+ if (test.size() < 1) // Allow for extra stuff (useful for comments)
+ {
+ BOOST_ERROR("Bad test: " << strTest);
+ continue;
+ }
+ std::string exp_base58string = test[0].get_str();
+
+ // must be invalid as public and as private key
+ addr.SetString(exp_base58string);
+ BOOST_CHECK_MESSAGE(!addr.IsValid(), "IsValid pubkey:" + strTest);
+ secret.SetString(exp_base58string);
+ BOOST_CHECK_MESSAGE(!secret.IsValid(), "IsValid privkey:" + strTest);
+ }
+}
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
diff --git a/src/test/base64_tests.cpp b/src/test/base64_tests.cpp
new file mode 100644
index 0000000000..54c081b0ef
--- /dev/null
+++ b/src/test/base64_tests.cpp
@@ -0,0 +1,25 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "utilstrencodings.h"
+#include "test/test_bitcoin.h"
+
+#include <boost/test/unit_test.hpp>
+
+BOOST_FIXTURE_TEST_SUITE(base64_tests, BasicTestingSetup)
+
+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<sizeof(vstrIn)/sizeof(vstrIn[0]); i++)
+ {
+ std::string strEnc = EncodeBase64(vstrIn[i]);
+ BOOST_CHECK(strEnc == vstrOut[i]);
+ std::string strDec = DecodeBase64(strEnc);
+ BOOST_CHECK(strDec == vstrIn[i]);
+ }
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/bctest.py b/src/test/bctest.py
new file mode 100644
index 0000000000..3a8d0ea51b
--- /dev/null
+++ b/src/test/bctest.py
@@ -0,0 +1,54 @@
+# Copyright 2014 BitPay, Inc.
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+import subprocess
+import os
+import json
+import sys
+
+def bctest(testDir, testObj, exeext):
+
+ execprog = testObj['exec'] + exeext
+ execargs = testObj['args']
+ execrun = [execprog] + execargs
+ stdinCfg = None
+ inputData = None
+ if "input" in testObj:
+ filename = testDir + "/" + testObj['input']
+ inputData = open(filename).read()
+ stdinCfg = subprocess.PIPE
+
+ outputFn = None
+ outputData = None
+ if "output_cmp" in testObj:
+ outputFn = testObj['output_cmp']
+ outputData = open(testDir + "/" + outputFn).read()
+ proc = subprocess.Popen(execrun, stdin=stdinCfg, stdout=subprocess.PIPE, stderr=subprocess.PIPE,universal_newlines=True)
+ try:
+ outs = proc.communicate(input=inputData)
+ except OSError:
+ print("OSError, Failed to execute " + execprog)
+ sys.exit(1)
+
+ if outputData and (outs[0] != outputData):
+ print("Output data mismatch for " + outputFn)
+ sys.exit(1)
+
+ wantRC = 0
+ if "return_code" in testObj:
+ wantRC = testObj['return_code']
+ if proc.returncode != wantRC:
+ print("Return code mismatch for " + outputFn)
+ sys.exit(1)
+
+def bctester(testDir, input_basename, buildenv):
+ input_filename = testDir + "/" + input_basename
+ raw_data = open(input_filename).read()
+ input_data = json.loads(raw_data)
+
+ for testObj in input_data:
+ bctest(testDir, testObj, buildenv.exeext)
+
+ sys.exit(0)
+
diff --git a/src/test/bignum.h b/src/test/bignum.h
new file mode 100644
index 0000000000..e7aeee9db6
--- /dev/null
+++ b/src/test/bignum.h
@@ -0,0 +1,180 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_TEST_BIGNUM_H
+#define BITCOIN_TEST_BIGNUM_H
+
+#include <algorithm>
+#include <limits>
+#include <stdexcept>
+#include <stdint.h>
+#include <string>
+#include <vector>
+
+#include <openssl/bn.h>
+
+class bignum_error : public std::runtime_error
+{
+public:
+ explicit bignum_error(const std::string& str) : std::runtime_error(str) {}
+};
+
+
+/** 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(long long n) { BN_init(this); setint64(n); }
+
+ explicit CBigNum(const std::vector<unsigned char>& vch)
+ {
+ BN_init(this);
+ setvch(vch);
+ }
+
+ int getint() const
+ {
+ BN_ULONG n = BN_get_word(this);
+ if (!BN_is_negative(this))
+ return (n > (BN_ULONG)std::numeric_limits<int>::max() ? std::numeric_limits<int>::max() : n);
+ else
+ return (n > (BN_ULONG)std::numeric_limits<int>::max() ? std::numeric_limits<int>::min() : -(int)n);
+ }
+
+ void setint64(int64_t sn)
+ {
+ unsigned char pch[sizeof(sn) + 6];
+ unsigned char* p = pch + 4;
+ bool fNegative;
+ uint64_t n;
+
+ if (sn < (int64_t)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 setvch(const std::vector<unsigned char>& vch)
+ {
+ std::vector<unsigned char> 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<unsigned char> getvch() const
+ {
+ unsigned int nSize = BN_bn2mpi(this, NULL);
+ if (nSize <= 4)
+ return std::vector<unsigned char>();
+ std::vector<unsigned char> vch(nSize);
+ BN_bn2mpi(this, &vch[0]);
+ vch.erase(vch.begin(), vch.begin() + 4);
+ reverse(vch.begin(), vch.end());
+ return vch;
+ }
+
+ 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 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 // BITCOIN_TEST_BIGNUM_H
diff --git a/src/test/bip32_tests.cpp b/src/test/bip32_tests.cpp
new file mode 100644
index 0000000000..0d815c27fd
--- /dev/null
+++ b/src/test/bip32_tests.cpp
@@ -0,0 +1,122 @@
+// Copyright (c) 2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include <boost/test/unit_test.hpp>
+
+#include "base58.h"
+#include "key.h"
+#include "uint256.h"
+#include "util.h"
+#include "utilstrencodings.h"
+#include "test/test_bitcoin.h"
+
+#include <string>
+#include <vector>
+
+struct TestDerivation {
+ std::string pub;
+ std::string prv;
+ unsigned int nChild;
+};
+
+struct TestVector {
+ std::string strHexMaster;
+ std::vector<TestDerivation> vDerive;
+
+ TestVector(std::string strHexMasterIn) : strHexMaster(strHexMasterIn) {}
+
+ TestVector& operator()(std::string pub, std::string prv, unsigned int nChild) {
+ vDerive.push_back(TestDerivation());
+ TestDerivation &der = vDerive.back();
+ der.pub = pub;
+ der.prv = prv;
+ der.nChild = nChild;
+ return *this;
+ }
+};
+
+TestVector test1 =
+ TestVector("000102030405060708090a0b0c0d0e0f")
+ ("xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8",
+ "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi",
+ 0x80000000)
+ ("xpub68Gmy5EdvgibQVfPdqkBBCHxA5htiqg55crXYuXoQRKfDBFA1WEjWgP6LHhwBZeNK1VTsfTFUHCdrfp1bgwQ9xv5ski8PX9rL2dZXvgGDnw",
+ "xprv9uHRZZhk6KAJC1avXpDAp4MDc3sQKNxDiPvvkX8Br5ngLNv1TxvUxt4cV1rGL5hj6KCesnDYUhd7oWgT11eZG7XnxHrnYeSvkzY7d2bhkJ7",
+ 1)
+ ("xpub6ASuArnXKPbfEwhqN6e3mwBcDTgzisQN1wXN9BJcM47sSikHjJf3UFHKkNAWbWMiGj7Wf5uMash7SyYq527Hqck2AxYysAA7xmALppuCkwQ",
+ "xprv9wTYmMFdV23N2TdNG573QoEsfRrWKQgWeibmLntzniatZvR9BmLnvSxqu53Kw1UmYPxLgboyZQaXwTCg8MSY3H2EU4pWcQDnRnrVA1xe8fs",
+ 0x80000002)
+ ("xpub6D4BDPcP2GT577Vvch3R8wDkScZWzQzMMUm3PWbmWvVJrZwQY4VUNgqFJPMM3No2dFDFGTsxxpG5uJh7n7epu4trkrX7x7DogT5Uv6fcLW5",
+ "xprv9z4pot5VBttmtdRTWfWQmoH1taj2axGVzFqSb8C9xaxKymcFzXBDptWmT7FwuEzG3ryjH4ktypQSAewRiNMjANTtpgP4mLTj34bhnZX7UiM",
+ 2)
+ ("xpub6FHa3pjLCk84BayeJxFW2SP4XRrFd1JYnxeLeU8EqN3vDfZmbqBqaGJAyiLjTAwm6ZLRQUMv1ZACTj37sR62cfN7fe5JnJ7dh8zL4fiyLHV",
+ "xprvA2JDeKCSNNZky6uBCviVfJSKyQ1mDYahRjijr5idH2WwLsEd4Hsb2Tyh8RfQMuPh7f7RtyzTtdrbdqqsunu5Mm3wDvUAKRHSC34sJ7in334",
+ 1000000000)
+ ("xpub6H1LXWLaKsWFhvm6RVpEL9P4KfRZSW7abD2ttkWP3SSQvnyA8FSVqNTEcYFgJS2UaFcxupHiYkro49S8yGasTvXEYBVPamhGW6cFJodrTHy",
+ "xprvA41z7zogVVwxVSgdKUHDy1SKmdb533PjDz7J6N6mV6uS3ze1ai8FHa8kmHScGpWmj4WggLyQjgPie1rFSruoUihUZREPSL39UNdE3BBDu76",
+ 0);
+
+TestVector test2 =
+ TestVector("fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542")
+ ("xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB",
+ "xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U",
+ 0)
+ ("xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH",
+ "xprv9vHkqa6EV4sPZHYqZznhT2NPtPCjKuDKGY38FBWLvgaDx45zo9WQRUT3dKYnjwih2yJD9mkrocEZXo1ex8G81dwSM1fwqWpWkeS3v86pgKt",
+ 0xFFFFFFFF)
+ ("xpub6ASAVgeehLbnwdqV6UKMHVzgqAG8Gr6riv3Fxxpj8ksbH9ebxaEyBLZ85ySDhKiLDBrQSARLq1uNRts8RuJiHjaDMBU4Zn9h8LZNnBC5y4a",
+ "xprv9wSp6B7kry3Vj9m1zSnLvN3xH8RdsPP1Mh7fAaR7aRLcQMKTR2vidYEeEg2mUCTAwCd6vnxVrcjfy2kRgVsFawNzmjuHc2YmYRmagcEPdU9",
+ 1)
+ ("xpub6DF8uhdarytz3FWdA8TvFSvvAh8dP3283MY7p2V4SeE2wyWmG5mg5EwVvmdMVCQcoNJxGoWaU9DCWh89LojfZ537wTfunKau47EL2dhHKon",
+ "xprv9zFnWC6h2cLgpmSA46vutJzBcfJ8yaJGg8cX1e5StJh45BBciYTRXSd25UEPVuesF9yog62tGAQtHjXajPPdbRCHuWS6T8XA2ECKADdw4Ef",
+ 0xFFFFFFFE)
+ ("xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL",
+ "xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc",
+ 2)
+ ("xpub6FnCn6nSzZAw5Tw7cgR9bi15UV96gLZhjDstkXXxvCLsUXBGXPdSnLFbdpq8p9HmGsApME5hQTZ3emM2rnY5agb9rXpVGyy3bdW6EEgAtqt",
+ "xprvA2nrNbFZABcdryreWet9Ea4LvTJcGsqrMzxHx98MMrotbir7yrKCEXw7nadnHM8Dq38EGfSh6dqA9QWTyefMLEcBYJUuekgW4BYPJcr9E7j",
+ 0);
+
+void RunTest(const TestVector &test) {
+ std::vector<unsigned char> seed = ParseHex(test.strHexMaster);
+ CExtKey key;
+ CExtPubKey pubkey;
+ key.SetMaster(&seed[0], seed.size());
+ pubkey = key.Neuter();
+ BOOST_FOREACH(const TestDerivation &derive, test.vDerive) {
+ unsigned char data[74];
+ key.Encode(data);
+ pubkey.Encode(data);
+ // Test private key
+ CBitcoinExtKey b58key; b58key.SetKey(key);
+ BOOST_CHECK(b58key.ToString() == derive.prv);
+ // Test public key
+ CBitcoinExtPubKey b58pubkey; b58pubkey.SetKey(pubkey);
+ BOOST_CHECK(b58pubkey.ToString() == derive.pub);
+ // Derive new keys
+ CExtKey keyNew;
+ BOOST_CHECK(key.Derive(keyNew, derive.nChild));
+ CExtPubKey pubkeyNew = keyNew.Neuter();
+ if (!(derive.nChild & 0x80000000)) {
+ // Compare with public derivation
+ CExtPubKey pubkeyNew2;
+ BOOST_CHECK(pubkey.Derive(pubkeyNew2, derive.nChild));
+ BOOST_CHECK(pubkeyNew == pubkeyNew2);
+ }
+ key = keyNew;
+ pubkey = pubkeyNew;
+ }
+}
+
+BOOST_FIXTURE_TEST_SUITE(bip32_tests, BasicTestingSetup)
+
+BOOST_AUTO_TEST_CASE(bip32_test1) {
+ RunTest(test1);
+}
+
+BOOST_AUTO_TEST_CASE(bip32_test2) {
+ RunTest(test2);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/bitcoin-util-test.py b/src/test/bitcoin-util-test.py
new file mode 100755
index 0000000000..20afb16a9e
--- /dev/null
+++ b/src/test/bitcoin-util-test.py
@@ -0,0 +1,13 @@
+#!/usr/bin/python
+# Copyright 2014 BitPay, Inc.
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+import os
+import bctest
+import buildenv
+
+if __name__ == '__main__':
+ bctest.bctester(os.environ["srcdir"] + "/test/data",
+ "bitcoin-util-test.json",buildenv)
+
diff --git a/src/test/bloom_tests.cpp b/src/test/bloom_tests.cpp
new file mode 100644
index 0000000000..6b30d6aa8a
--- /dev/null
+++ b/src/test/bloom_tests.cpp
@@ -0,0 +1,540 @@
+// Copyright (c) 2012-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "bloom.h"
+
+#include "base58.h"
+#include "clientversion.h"
+#include "key.h"
+#include "merkleblock.h"
+#include "random.h"
+#include "serialize.h"
+#include "streams.h"
+#include "uint256.h"
+#include "util.h"
+#include "utilstrencodings.h"
+#include "test/test_bitcoin.h"
+
+#include <vector>
+
+#include <boost/test/unit_test.hpp>
+#include <boost/tuple/tuple.hpp>
+
+using namespace std;
+
+BOOST_FIXTURE_TEST_SUITE(bloom_tests, BasicTestingSetup)
+
+BOOST_AUTO_TEST_CASE(bloom_create_insert_serialize)
+{
+ CBloomFilter filter(3, 0.01, 0, BLOOM_UPDATE_ALL);
+
+ filter.insert(ParseHex("99108ad8ed9bb6274d3980bab5a85c048f0950c8"));
+ BOOST_CHECK_MESSAGE( filter.contains(ParseHex("99108ad8ed9bb6274d3980bab5a85c048f0950c8")), "BloomFilter doesn't contain just-inserted object!");
+ // One bit different in first byte
+ BOOST_CHECK_MESSAGE(!filter.contains(ParseHex("19108ad8ed9bb6274d3980bab5a85c048f0950c8")), "BloomFilter contains something it shouldn't!");
+
+ filter.insert(ParseHex("b5a2c786d9ef4658287ced5914b37a1b4aa32eee"));
+ BOOST_CHECK_MESSAGE(filter.contains(ParseHex("b5a2c786d9ef4658287ced5914b37a1b4aa32eee")), "BloomFilter doesn't contain just-inserted object (2)!");
+
+ filter.insert(ParseHex("b9300670b4c5366e95b2699e8b18bc75e5f729c5"));
+ BOOST_CHECK_MESSAGE(filter.contains(ParseHex("b9300670b4c5366e95b2699e8b18bc75e5f729c5")), "BloomFilter doesn't contain just-inserted object (3)!");
+
+ CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
+ filter.Serialize(stream, SER_NETWORK, PROTOCOL_VERSION);
+
+ vector<unsigned char> vch = ParseHex("03614e9b050000000000000001");
+ vector<char> expected(vch.size());
+
+ for (unsigned int i = 0; i < vch.size(); i++)
+ expected[i] = (char)vch[i];
+
+ BOOST_CHECK_EQUAL_COLLECTIONS(stream.begin(), stream.end(), expected.begin(), expected.end());
+
+ BOOST_CHECK_MESSAGE( filter.contains(ParseHex("99108ad8ed9bb6274d3980bab5a85c048f0950c8")), "BloomFilter doesn't contain just-inserted object!");
+ filter.clear();
+ BOOST_CHECK_MESSAGE( !filter.contains(ParseHex("99108ad8ed9bb6274d3980bab5a85c048f0950c8")), "BloomFilter should be empty!");
+}
+
+BOOST_AUTO_TEST_CASE(bloom_create_insert_serialize_with_tweak)
+{
+ // Same test as bloom_create_insert_serialize, but we add a nTweak of 100
+ CBloomFilter filter(3, 0.01, 2147483649UL, BLOOM_UPDATE_ALL);
+
+ filter.insert(ParseHex("99108ad8ed9bb6274d3980bab5a85c048f0950c8"));
+ BOOST_CHECK_MESSAGE( filter.contains(ParseHex("99108ad8ed9bb6274d3980bab5a85c048f0950c8")), "BloomFilter doesn't contain just-inserted object!");
+ // One bit different in first byte
+ BOOST_CHECK_MESSAGE(!filter.contains(ParseHex("19108ad8ed9bb6274d3980bab5a85c048f0950c8")), "BloomFilter contains something it shouldn't!");
+
+ filter.insert(ParseHex("b5a2c786d9ef4658287ced5914b37a1b4aa32eee"));
+ BOOST_CHECK_MESSAGE(filter.contains(ParseHex("b5a2c786d9ef4658287ced5914b37a1b4aa32eee")), "BloomFilter doesn't contain just-inserted object (2)!");
+
+ filter.insert(ParseHex("b9300670b4c5366e95b2699e8b18bc75e5f729c5"));
+ BOOST_CHECK_MESSAGE(filter.contains(ParseHex("b9300670b4c5366e95b2699e8b18bc75e5f729c5")), "BloomFilter doesn't contain just-inserted object (3)!");
+
+ CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
+ filter.Serialize(stream, SER_NETWORK, PROTOCOL_VERSION);
+
+ vector<unsigned char> vch = ParseHex("03ce4299050000000100008001");
+ vector<char> expected(vch.size());
+
+ for (unsigned int i = 0; i < vch.size(); i++)
+ expected[i] = (char)vch[i];
+
+ BOOST_CHECK_EQUAL_COLLECTIONS(stream.begin(), stream.end(), expected.begin(), expected.end());
+}
+
+BOOST_AUTO_TEST_CASE(bloom_create_insert_key)
+{
+ string strSecret = string("5Kg1gnAjaLfKiwhhPpGS3QfRg2m6awQvaj98JCZBZQ5SuS2F15C");
+ CBitcoinSecret vchSecret;
+ BOOST_CHECK(vchSecret.SetString(strSecret));
+
+ CKey key = vchSecret.GetKey();
+ CPubKey pubkey = key.GetPubKey();
+ vector<unsigned char> vchPubKey(pubkey.begin(), pubkey.end());
+
+ CBloomFilter filter(2, 0.001, 0, BLOOM_UPDATE_ALL);
+ filter.insert(vchPubKey);
+ uint160 hash = pubkey.GetID();
+ filter.insert(vector<unsigned char>(hash.begin(), hash.end()));
+
+ CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
+ filter.Serialize(stream, SER_NETWORK, PROTOCOL_VERSION);
+
+ vector<unsigned char> vch = ParseHex("038fc16b080000000000000001");
+ vector<char> expected(vch.size());
+
+ for (unsigned int i = 0; i < vch.size(); i++)
+ expected[i] = (char)vch[i];
+
+ BOOST_CHECK_EQUAL_COLLECTIONS(stream.begin(), stream.end(), expected.begin(), expected.end());
+}
+
+BOOST_AUTO_TEST_CASE(bloom_match)
+{
+ // Random real transaction (b4749f017444b051c44dfd2720e88f314ff94f3dd6d56d40ef65854fcd7fff6b)
+ CTransaction tx;
+ CDataStream stream(ParseHex("01000000010b26e9b7735eb6aabdf358bab62f9816a21ba9ebdb719d5299e88607d722c190000000008b4830450220070aca44506c5cef3a16ed519d7c3c39f8aab192c4e1c90d065f37b8a4af6141022100a8e160b856c2d43d27d8fba71e5aef6405b8643ac4cb7cb3c462aced7f14711a0141046d11fee51b0e60666d5049a9101a72741df480b96ee26488a4d3466b95c9a40ac5eeef87e10a5cd336c19a84565f80fa6c547957b7700ff4dfbdefe76036c339ffffffff021bff3d11000000001976a91404943fdd508053c75000106d3bc6e2754dbcff1988ac2f15de00000000001976a914a266436d2965547608b9e15d9032a7b9d64fa43188ac00000000"), SER_DISK, CLIENT_VERSION);
+ stream >> tx;
+
+ // and one which spends it (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<unsigned char> vch(ch, ch + sizeof(ch) -1);
+ CDataStream spendStream(vch, SER_DISK, CLIENT_VERSION);
+ CTransaction spendingTx;
+ spendStream >> spendingTx;
+
+ CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
+ filter.insert(uint256S("0xb4749f017444b051c44dfd2720e88f314ff94f3dd6d56d40ef65854fcd7fff6b"));
+ BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(tx), "Simple Bloom filter didn't match tx hash");
+
+ filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
+ // byte-reversed tx hash
+ filter.insert(ParseHex("6bff7fcd4f8565ef406dd5d63d4ff94f318fe82027fd4dc451b04474019f74b4"));
+ BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(tx), "Simple Bloom filter didn't match manually serialized tx hash");
+
+ filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
+ filter.insert(ParseHex("30450220070aca44506c5cef3a16ed519d7c3c39f8aab192c4e1c90d065f37b8a4af6141022100a8e160b856c2d43d27d8fba71e5aef6405b8643ac4cb7cb3c462aced7f14711a01"));
+ BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(tx), "Simple Bloom filter didn't match input signature");
+
+ filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
+ filter.insert(ParseHex("046d11fee51b0e60666d5049a9101a72741df480b96ee26488a4d3466b95c9a40ac5eeef87e10a5cd336c19a84565f80fa6c547957b7700ff4dfbdefe76036c339"));
+ BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(tx), "Simple Bloom filter didn't match input pub key");
+
+ filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
+ filter.insert(ParseHex("04943fdd508053c75000106d3bc6e2754dbcff19"));
+ BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(tx), "Simple Bloom filter didn't match output address");
+ BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(spendingTx), "Simple Bloom filter didn't add output");
+
+ filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
+ filter.insert(ParseHex("a266436d2965547608b9e15d9032a7b9d64fa431"));
+ BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(tx), "Simple Bloom filter didn't match output address");
+
+ filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
+ filter.insert(COutPoint(uint256S("0x90c122d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 0));
+ BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(tx), "Simple Bloom filter didn't match COutPoint");
+
+ filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
+ COutPoint prevOutPoint(uint256S("0x90c122d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 0);
+ {
+ vector<unsigned char> data(32 + sizeof(unsigned int));
+ memcpy(&data[0], prevOutPoint.hash.begin(), 32);
+ memcpy(&data[32], &prevOutPoint.n, sizeof(unsigned int));
+ filter.insert(data);
+ }
+ BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(tx), "Simple Bloom filter didn't match manually serialized COutPoint");
+
+ filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
+ filter.insert(uint256S("00000009e784f32f62ef849763d4f45b98e07ba658647343b915ff832b110436"));
+ BOOST_CHECK_MESSAGE(!filter.IsRelevantAndUpdate(tx), "Simple Bloom filter matched random tx hash");
+
+ filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
+ filter.insert(ParseHex("0000006d2965547608b9e15d9032a7b9d64fa431"));
+ BOOST_CHECK_MESSAGE(!filter.IsRelevantAndUpdate(tx), "Simple Bloom filter matched random address");
+
+ filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
+ filter.insert(COutPoint(uint256S("0x90c122d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 1));
+ BOOST_CHECK_MESSAGE(!filter.IsRelevantAndUpdate(tx), "Simple Bloom filter matched COutPoint for an output we didn't care about");
+
+ filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
+ filter.insert(COutPoint(uint256S("0x000000d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 0));
+ BOOST_CHECK_MESSAGE(!filter.IsRelevantAndUpdate(tx), "Simple Bloom filter matched COutPoint for an output we didn't care about");
+}
+
+BOOST_AUTO_TEST_CASE(merkle_block_1)
+{
+ // Random real block (0000000000013b8ab2cd513b0261a14096412195a72a0c4827d229dcc7e0f7af)
+ // With 9 txes
+ CBlock block;
+ CDataStream stream(ParseHex("0100000090f0a9f110702f808219ebea1173056042a714bad51b916cb6800000000000005275289558f51c9966699404ae2294730c3c9f9bda53523ce50e9b95e558da2fdb261b4d4c86041b1ab1bf930901000000010000000000000000000000000000000000000000000000000000000000000000ffffffff07044c86041b0146ffffffff0100f2052a01000000434104e18f7afbe4721580e81e8414fc8c24d7cfacf254bb5c7b949450c3e997c2dc1242487a8169507b631eb3771f2b425483fb13102c4eb5d858eef260fe70fbfae0ac00000000010000000196608ccbafa16abada902780da4dc35dafd7af05fa0da08cf833575f8cf9e836000000004a493046022100dab24889213caf43ae6adc41cf1c9396c08240c199f5225acf45416330fd7dbd022100fe37900e0644bf574493a07fc5edba06dbc07c311b947520c2d514bc5725dcb401ffffffff0100f2052a010000001976a914f15d1921f52e4007b146dfa60f369ed2fc393ce288ac000000000100000001fb766c1288458c2bafcfec81e48b24d98ec706de6b8af7c4e3c29419bfacb56d000000008c493046022100f268ba165ce0ad2e6d93f089cfcd3785de5c963bb5ea6b8c1b23f1ce3e517b9f022100da7c0f21adc6c401887f2bfd1922f11d76159cbc597fbd756a23dcbb00f4d7290141042b4e8625a96127826915a5b109852636ad0da753c9e1d5606a50480cd0c40f1f8b8d898235e571fe9357d9ec842bc4bba1827daaf4de06d71844d0057707966affffffff0280969800000000001976a9146963907531db72d0ed1a0cfb471ccb63923446f388ac80d6e34c000000001976a914f0688ba1c0d1ce182c7af6741e02658c7d4dfcd388ac000000000100000002c40297f730dd7b5a99567eb8d27b78758f607507c52292d02d4031895b52f2ff010000008b483045022100f7edfd4b0aac404e5bab4fd3889e0c6c41aa8d0e6fa122316f68eddd0a65013902205b09cc8b2d56e1cd1f7f2fafd60a129ed94504c4ac7bdc67b56fe67512658b3e014104732012cb962afa90d31b25d8fb0e32c94e513ab7a17805c14ca4c3423e18b4fb5d0e676841733cb83abaf975845c9f6f2a8097b7d04f4908b18368d6fc2d68ecffffffffca5065ff9617cbcba45eb23726df6498a9b9cafed4f54cbab9d227b0035ddefb000000008a473044022068010362a13c7f9919fa832b2dee4e788f61f6f5d344a7c2a0da6ae740605658022006d1af525b9a14a35c003b78b72bd59738cd676f845d1ff3fc25049e01003614014104732012cb962afa90d31b25d8fb0e32c94e513ab7a17805c14ca4c3423e18b4fb5d0e676841733cb83abaf975845c9f6f2a8097b7d04f4908b18368d6fc2d68ecffffffff01001ec4110200000043410469ab4181eceb28985b9b4e895c13fa5e68d85761b7eee311db5addef76fa8621865134a221bd01f28ec9999ee3e021e60766e9d1f3458c115fb28650605f11c9ac000000000100000001cdaf2f758e91c514655e2dc50633d1e4c84989f8aa90a0dbc883f0d23ed5c2fa010000008b48304502207ab51be6f12a1962ba0aaaf24a20e0b69b27a94fac5adf45aa7d2d18ffd9236102210086ae728b370e5329eead9accd880d0cb070aea0c96255fae6c4f1ddcce1fd56e014104462e76fd4067b3a0aa42070082dcb0bf2f388b6495cf33d789904f07d0f55c40fbd4b82963c69b3dc31895d0c772c812b1d5fbcade15312ef1c0e8ebbb12dcd4ffffffff02404b4c00000000001976a9142b6ba7c9d796b75eef7942fc9288edd37c32f5c388ac002d3101000000001976a9141befba0cdc1ad56529371864d9f6cb042faa06b588ac000000000100000001b4a47603e71b61bc3326efd90111bf02d2f549b067f4c4a8fa183b57a0f800cb010000008a4730440220177c37f9a505c3f1a1f0ce2da777c339bd8339ffa02c7cb41f0a5804f473c9230220585b25a2ee80eb59292e52b987dad92acb0c64eced92ed9ee105ad153cdb12d001410443bd44f683467e549dae7d20d1d79cbdb6df985c6e9c029c8d0c6cb46cc1a4d3cf7923c5021b27f7a0b562ada113bc85d5fda5a1b41e87fe6e8802817cf69996ffffffff0280651406000000001976a9145505614859643ab7b547cd7f1f5e7e2a12322d3788ac00aa0271000000001976a914ea4720a7a52fc166c55ff2298e07baf70ae67e1b88ac00000000010000000586c62cd602d219bb60edb14a3e204de0705176f9022fe49a538054fb14abb49e010000008c493046022100f2bc2aba2534becbdf062eb993853a42bbbc282083d0daf9b4b585bd401aa8c9022100b1d7fd7ee0b95600db8535bbf331b19eed8d961f7a8e54159c53675d5f69df8c014104462e76fd4067b3a0aa42070082dcb0bf2f388b6495cf33d789904f07d0f55c40fbd4b82963c69b3dc31895d0c772c812b1d5fbcade15312ef1c0e8ebbb12dcd4ffffffff03ad0e58ccdac3df9dc28a218bcf6f1997b0a93306faaa4b3a28ae83447b2179010000008b483045022100be12b2937179da88599e27bb31c3525097a07cdb52422d165b3ca2f2020ffcf702200971b51f853a53d644ebae9ec8f3512e442b1bcb6c315a5b491d119d10624c83014104462e76fd4067b3a0aa42070082dcb0bf2f388b6495cf33d789904f07d0f55c40fbd4b82963c69b3dc31895d0c772c812b1d5fbcade15312ef1c0e8ebbb12dcd4ffffffff2acfcab629bbc8685792603762c921580030ba144af553d271716a95089e107b010000008b483045022100fa579a840ac258871365dd48cd7552f96c8eea69bd00d84f05b283a0dab311e102207e3c0ee9234814cfbb1b659b83671618f45abc1326b9edcc77d552a4f2a805c0014104462e76fd4067b3a0aa42070082dcb0bf2f388b6495cf33d789904f07d0f55c40fbd4b82963c69b3dc31895d0c772c812b1d5fbcade15312ef1c0e8ebbb12dcd4ffffffffdcdc6023bbc9944a658ddc588e61eacb737ddf0a3cd24f113b5a8634c517fcd2000000008b4830450221008d6df731df5d32267954bd7d2dda2302b74c6c2a6aa5c0ca64ecbabc1af03c75022010e55c571d65da7701ae2da1956c442df81bbf076cdbac25133f99d98a9ed34c014104462e76fd4067b3a0aa42070082dcb0bf2f388b6495cf33d789904f07d0f55c40fbd4b82963c69b3dc31895d0c772c812b1d5fbcade15312ef1c0e8ebbb12dcd4ffffffffe15557cd5ce258f479dfd6dc6514edf6d7ed5b21fcfa4a038fd69f06b83ac76e010000008b483045022023b3e0ab071eb11de2eb1cc3a67261b866f86bf6867d4558165f7c8c8aca2d86022100dc6e1f53a91de3efe8f63512850811f26284b62f850c70ca73ed5de8771fb451014104462e76fd4067b3a0aa42070082dcb0bf2f388b6495cf33d789904f07d0f55c40fbd4b82963c69b3dc31895d0c772c812b1d5fbcade15312ef1c0e8ebbb12dcd4ffffffff01404b4c00000000001976a9142b6ba7c9d796b75eef7942fc9288edd37c32f5c388ac00000000010000000166d7577163c932b4f9690ca6a80b6e4eb001f0a2fa9023df5595602aae96ed8d000000008a4730440220262b42546302dfb654a229cefc86432b89628ff259dc87edd1154535b16a67e102207b4634c020a97c3e7bbd0d4d19da6aa2269ad9dded4026e896b213d73ca4b63f014104979b82d02226b3a4597523845754d44f13639e3bf2df5e82c6aab2bdc79687368b01b1ab8b19875ae3c90d661a3d0a33161dab29934edeb36aa01976be3baf8affffffff02404b4c00000000001976a9144854e695a02af0aeacb823ccbc272134561e0a1688ac40420f00000000001976a914abee93376d6b37b5c2940655a6fcaf1c8e74237988ac0000000001000000014e3f8ef2e91349a9059cb4f01e54ab2597c1387161d3da89919f7ea6acdbb371010000008c49304602210081f3183471a5ca22307c0800226f3ef9c353069e0773ac76bb580654d56aa523022100d4c56465bdc069060846f4fbf2f6b20520b2a80b08b168b31e66ddb9c694e240014104976c79848e18251612f8940875b2b08d06e6dc73b9840e8860c066b7e87432c477e9a59a453e71e6d76d5fe34058b800a098fc1740ce3012e8fc8a00c96af966ffffffff02c0e1e400000000001976a9144134e75a6fcb6042034aab5e18570cf1f844f54788ac404b4c00000000001976a9142b6ba7c9d796b75eef7942fc9288edd37c32f5c388ac00000000"), SER_NETWORK, PROTOCOL_VERSION);
+ stream >> block;
+
+ CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
+ // Match the last transaction
+ filter.insert(uint256S("0x74d681e0e03bafa802c8aa084379aa98d9fcd632ddc2ed9782b586ec87451f20"));
+
+ CMerkleBlock merkleBlock(block, filter);
+ BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
+
+ BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1);
+ pair<unsigned int, uint256> pair = merkleBlock.vMatchedTxn[0];
+
+ BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0x74d681e0e03bafa802c8aa084379aa98d9fcd632ddc2ed9782b586ec87451f20"));
+ BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 8);
+
+ vector<uint256> vMatched;
+ BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched) == block.hashMerkleRoot);
+ BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size());
+ for (unsigned int i = 0; i < vMatched.size(); i++)
+ BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second);
+
+ // Also match the 8th transaction
+ filter.insert(uint256S("0xdd1fd2a6fc16404faf339881a90adbde7f4f728691ac62e8f168809cdfae1053"));
+ merkleBlock = CMerkleBlock(block, filter);
+ BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
+
+ BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 2);
+
+ BOOST_CHECK(merkleBlock.vMatchedTxn[1] == pair);
+
+ BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0xdd1fd2a6fc16404faf339881a90adbde7f4f728691ac62e8f168809cdfae1053"));
+ BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 7);
+
+ BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched) == block.hashMerkleRoot);
+ BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size());
+ for (unsigned int i = 0; i < vMatched.size(); i++)
+ BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second);
+}
+
+BOOST_AUTO_TEST_CASE(merkle_block_2)
+{
+ // Random real block (000000005a4ded781e667e06ceefafb71410b511fe0d5adc3e5a27ecbec34ae6)
+ // With 4 txes
+ CBlock block;
+ CDataStream stream(ParseHex("0100000075616236cc2126035fadb38deb65b9102cc2c41c09cdf29fc051906800000000fe7d5e12ef0ff901f6050211249919b1c0653771832b3a80c66cea42847f0ae1d4d26e49ffff001d00f0a4410401000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0804ffff001d029105ffffffff0100f2052a010000004341046d8709a041d34357697dfcb30a9d05900a6294078012bf3bb09c6f9b525f1d16d5503d7905db1ada9501446ea00728668fc5719aa80be2fdfc8a858a4dbdd4fbac00000000010000000255605dc6f5c3dc148b6da58442b0b2cd422be385eab2ebea4119ee9c268d28350000000049483045022100aa46504baa86df8a33b1192b1b9367b4d729dc41e389f2c04f3e5c7f0559aae702205e82253a54bf5c4f65b7428551554b2045167d6d206dfe6a2e198127d3f7df1501ffffffff55605dc6f5c3dc148b6da58442b0b2cd422be385eab2ebea4119ee9c268d2835010000004847304402202329484c35fa9d6bb32a55a70c0982f606ce0e3634b69006138683bcd12cbb6602200c28feb1e2555c3210f1dddb299738b4ff8bbe9667b68cb8764b5ac17b7adf0001ffffffff0200e1f505000000004341046a0765b5865641ce08dd39690aade26dfbf5511430ca428a3089261361cef170e3929a68aee3d8d4848b0c5111b0a37b82b86ad559fd2a745b44d8e8d9dfdc0cac00180d8f000000004341044a656f065871a353f216ca26cef8dde2f03e8c16202d2e8ad769f02032cb86a5eb5e56842e92e19141d60a01928f8dd2c875a390f67c1f6c94cfc617c0ea45afac0000000001000000025f9a06d3acdceb56be1bfeaa3e8a25e62d182fa24fefe899d1c17f1dad4c2028000000004847304402205d6058484157235b06028c30736c15613a28bdb768ee628094ca8b0030d4d6eb0220328789c9a2ec27ddaec0ad5ef58efded42e6ea17c2e1ce838f3d6913f5e95db601ffffffff5f9a06d3acdceb56be1bfeaa3e8a25e62d182fa24fefe899d1c17f1dad4c2028010000004a493046022100c45af050d3cea806cedd0ab22520c53ebe63b987b8954146cdca42487b84bdd6022100b9b027716a6b59e640da50a864d6dd8a0ef24c76ce62391fa3eabaf4d2886d2d01ffffffff0200e1f505000000004341046a0765b5865641ce08dd39690aade26dfbf5511430ca428a3089261361cef170e3929a68aee3d8d4848b0c5111b0a37b82b86ad559fd2a745b44d8e8d9dfdc0cac00180d8f000000004341046a0765b5865641ce08dd39690aade26dfbf5511430ca428a3089261361cef170e3929a68aee3d8d4848b0c5111b0a37b82b86ad559fd2a745b44d8e8d9dfdc0cac000000000100000002e2274e5fea1bf29d963914bd301aa63b64daaf8a3e88f119b5046ca5738a0f6b0000000048473044022016e7a727a061ea2254a6c358376aaa617ac537eb836c77d646ebda4c748aac8b0220192ce28bf9f2c06a6467e6531e27648d2b3e2e2bae85159c9242939840295ba501ffffffffe2274e5fea1bf29d963914bd301aa63b64daaf8a3e88f119b5046ca5738a0f6b010000004a493046022100b7a1a755588d4190118936e15cd217d133b0e4a53c3c15924010d5648d8925c9022100aaef031874db2114f2d869ac2de4ae53908fbfea5b2b1862e181626bb9005c9f01ffffffff0200e1f505000000004341044a656f065871a353f216ca26cef8dde2f03e8c16202d2e8ad769f02032cb86a5eb5e56842e92e19141d60a01928f8dd2c875a390f67c1f6c94cfc617c0ea45afac00180d8f000000004341046a0765b5865641ce08dd39690aade26dfbf5511430ca428a3089261361cef170e3929a68aee3d8d4848b0c5111b0a37b82b86ad559fd2a745b44d8e8d9dfdc0cac00000000"), SER_NETWORK, PROTOCOL_VERSION);
+ stream >> block;
+
+ CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
+ // Match the first transaction
+ filter.insert(uint256S("0xe980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70"));
+
+ CMerkleBlock merkleBlock(block, filter);
+ BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
+
+ BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1);
+ pair<unsigned int, uint256> pair = merkleBlock.vMatchedTxn[0];
+
+ BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0xe980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70"));
+ BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 0);
+
+ vector<uint256> vMatched;
+ BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched) == block.hashMerkleRoot);
+ BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size());
+ for (unsigned int i = 0; i < vMatched.size(); i++)
+ BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second);
+
+ // Match an output from the second transaction (the pubkey for address 1DZTzaBHUDM7T3QvUKBz4qXMRpkg8jsfB5)
+ // This should match the third transaction because it spends the output matched
+ // It also matches the fourth transaction, which spends to the pubkey again
+ filter.insert(ParseHex("044a656f065871a353f216ca26cef8dde2f03e8c16202d2e8ad769f02032cb86a5eb5e56842e92e19141d60a01928f8dd2c875a390f67c1f6c94cfc617c0ea45af"));
+
+ merkleBlock = CMerkleBlock(block, filter);
+ BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
+
+ BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 4);
+
+ BOOST_CHECK(pair == merkleBlock.vMatchedTxn[0]);
+
+ BOOST_CHECK(merkleBlock.vMatchedTxn[1].second == uint256S("0x28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f"));
+ BOOST_CHECK(merkleBlock.vMatchedTxn[1].first == 1);
+
+ BOOST_CHECK(merkleBlock.vMatchedTxn[2].second == uint256S("0x6b0f8a73a56c04b519f1883e8aafda643ba61a30bd1439969df21bea5f4e27e2"));
+ BOOST_CHECK(merkleBlock.vMatchedTxn[2].first == 2);
+
+ BOOST_CHECK(merkleBlock.vMatchedTxn[3].second == uint256S("0x3c1d7e82342158e4109df2e0b6348b6e84e403d8b4046d7007663ace63cddb23"));
+ BOOST_CHECK(merkleBlock.vMatchedTxn[3].first == 3);
+
+ BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched) == block.hashMerkleRoot);
+ BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size());
+ for (unsigned int i = 0; i < vMatched.size(); i++)
+ BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second);
+}
+
+BOOST_AUTO_TEST_CASE(merkle_block_2_with_update_none)
+{
+ // Random real block (000000005a4ded781e667e06ceefafb71410b511fe0d5adc3e5a27ecbec34ae6)
+ // With 4 txes
+ CBlock block;
+ CDataStream stream(ParseHex("0100000075616236cc2126035fadb38deb65b9102cc2c41c09cdf29fc051906800000000fe7d5e12ef0ff901f6050211249919b1c0653771832b3a80c66cea42847f0ae1d4d26e49ffff001d00f0a4410401000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0804ffff001d029105ffffffff0100f2052a010000004341046d8709a041d34357697dfcb30a9d05900a6294078012bf3bb09c6f9b525f1d16d5503d7905db1ada9501446ea00728668fc5719aa80be2fdfc8a858a4dbdd4fbac00000000010000000255605dc6f5c3dc148b6da58442b0b2cd422be385eab2ebea4119ee9c268d28350000000049483045022100aa46504baa86df8a33b1192b1b9367b4d729dc41e389f2c04f3e5c7f0559aae702205e82253a54bf5c4f65b7428551554b2045167d6d206dfe6a2e198127d3f7df1501ffffffff55605dc6f5c3dc148b6da58442b0b2cd422be385eab2ebea4119ee9c268d2835010000004847304402202329484c35fa9d6bb32a55a70c0982f606ce0e3634b69006138683bcd12cbb6602200c28feb1e2555c3210f1dddb299738b4ff8bbe9667b68cb8764b5ac17b7adf0001ffffffff0200e1f505000000004341046a0765b5865641ce08dd39690aade26dfbf5511430ca428a3089261361cef170e3929a68aee3d8d4848b0c5111b0a37b82b86ad559fd2a745b44d8e8d9dfdc0cac00180d8f000000004341044a656f065871a353f216ca26cef8dde2f03e8c16202d2e8ad769f02032cb86a5eb5e56842e92e19141d60a01928f8dd2c875a390f67c1f6c94cfc617c0ea45afac0000000001000000025f9a06d3acdceb56be1bfeaa3e8a25e62d182fa24fefe899d1c17f1dad4c2028000000004847304402205d6058484157235b06028c30736c15613a28bdb768ee628094ca8b0030d4d6eb0220328789c9a2ec27ddaec0ad5ef58efded42e6ea17c2e1ce838f3d6913f5e95db601ffffffff5f9a06d3acdceb56be1bfeaa3e8a25e62d182fa24fefe899d1c17f1dad4c2028010000004a493046022100c45af050d3cea806cedd0ab22520c53ebe63b987b8954146cdca42487b84bdd6022100b9b027716a6b59e640da50a864d6dd8a0ef24c76ce62391fa3eabaf4d2886d2d01ffffffff0200e1f505000000004341046a0765b5865641ce08dd39690aade26dfbf5511430ca428a3089261361cef170e3929a68aee3d8d4848b0c5111b0a37b82b86ad559fd2a745b44d8e8d9dfdc0cac00180d8f000000004341046a0765b5865641ce08dd39690aade26dfbf5511430ca428a3089261361cef170e3929a68aee3d8d4848b0c5111b0a37b82b86ad559fd2a745b44d8e8d9dfdc0cac000000000100000002e2274e5fea1bf29d963914bd301aa63b64daaf8a3e88f119b5046ca5738a0f6b0000000048473044022016e7a727a061ea2254a6c358376aaa617ac537eb836c77d646ebda4c748aac8b0220192ce28bf9f2c06a6467e6531e27648d2b3e2e2bae85159c9242939840295ba501ffffffffe2274e5fea1bf29d963914bd301aa63b64daaf8a3e88f119b5046ca5738a0f6b010000004a493046022100b7a1a755588d4190118936e15cd217d133b0e4a53c3c15924010d5648d8925c9022100aaef031874db2114f2d869ac2de4ae53908fbfea5b2b1862e181626bb9005c9f01ffffffff0200e1f505000000004341044a656f065871a353f216ca26cef8dde2f03e8c16202d2e8ad769f02032cb86a5eb5e56842e92e19141d60a01928f8dd2c875a390f67c1f6c94cfc617c0ea45afac00180d8f000000004341046a0765b5865641ce08dd39690aade26dfbf5511430ca428a3089261361cef170e3929a68aee3d8d4848b0c5111b0a37b82b86ad559fd2a745b44d8e8d9dfdc0cac00000000"), SER_NETWORK, PROTOCOL_VERSION);
+ stream >> block;
+
+ CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_NONE);
+ // Match the first transaction
+ filter.insert(uint256S("0xe980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70"));
+
+ CMerkleBlock merkleBlock(block, filter);
+ BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
+
+ BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1);
+ pair<unsigned int, uint256> pair = merkleBlock.vMatchedTxn[0];
+
+ BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0xe980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70"));
+ BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 0);
+
+ vector<uint256> vMatched;
+ BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched) == block.hashMerkleRoot);
+ BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size());
+ for (unsigned int i = 0; i < vMatched.size(); i++)
+ BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second);
+
+ // Match an output from the second transaction (the pubkey for address 1DZTzaBHUDM7T3QvUKBz4qXMRpkg8jsfB5)
+ // This should not match the third transaction though it spends the output matched
+ // It will match the fourth transaction, which has another pay-to-pubkey output to the same address
+ filter.insert(ParseHex("044a656f065871a353f216ca26cef8dde2f03e8c16202d2e8ad769f02032cb86a5eb5e56842e92e19141d60a01928f8dd2c875a390f67c1f6c94cfc617c0ea45af"));
+
+ merkleBlock = CMerkleBlock(block, filter);
+ BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
+
+ BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 3);
+
+ BOOST_CHECK(pair == merkleBlock.vMatchedTxn[0]);
+
+ BOOST_CHECK(merkleBlock.vMatchedTxn[1].second == uint256S("0x28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f"));
+ BOOST_CHECK(merkleBlock.vMatchedTxn[1].first == 1);
+
+ BOOST_CHECK(merkleBlock.vMatchedTxn[2].second == uint256S("0x3c1d7e82342158e4109df2e0b6348b6e84e403d8b4046d7007663ace63cddb23"));
+ BOOST_CHECK(merkleBlock.vMatchedTxn[2].first == 3);
+
+ BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched) == block.hashMerkleRoot);
+ BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size());
+ for (unsigned int i = 0; i < vMatched.size(); i++)
+ BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second);
+}
+
+BOOST_AUTO_TEST_CASE(merkle_block_3_and_serialize)
+{
+ // Random real block (000000000000dab0130bbcc991d3d7ae6b81aa6f50a798888dfe62337458dc45)
+ // With one tx
+ CBlock block;
+ CDataStream stream(ParseHex("0100000079cda856b143d9db2c1caff01d1aecc8630d30625d10e8b4b8b0000000000000b50cc069d6a3e33e3ff84a5c41d9d3febe7c770fdcc96b2c3ff60abe184f196367291b4d4c86041b8fa45d630101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff08044c86041b020a02ffffffff0100f2052a01000000434104ecd3229b0571c3be876feaac0442a9f13c5a572742927af1dc623353ecf8c202225f64868137a18cdd85cbbb4c74fbccfd4f49639cf1bdc94a5672bb15ad5d4cac00000000"), SER_NETWORK, PROTOCOL_VERSION);
+ stream >> block;
+
+ CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
+ // Match the only transaction
+ filter.insert(uint256S("0x63194f18be0af63f2c6bc9dc0f777cbefed3d9415c4af83f3ee3a3d669c00cb5"));
+
+ CMerkleBlock merkleBlock(block, filter);
+ BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
+
+ BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1);
+
+ BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0x63194f18be0af63f2c6bc9dc0f777cbefed3d9415c4af83f3ee3a3d669c00cb5"));
+ BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 0);
+
+ vector<uint256> vMatched;
+ BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched) == block.hashMerkleRoot);
+ BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size());
+ for (unsigned int i = 0; i < vMatched.size(); i++)
+ BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second);
+
+ CDataStream merkleStream(SER_NETWORK, PROTOCOL_VERSION);
+ merkleStream << merkleBlock;
+
+ vector<unsigned char> vch = ParseHex("0100000079cda856b143d9db2c1caff01d1aecc8630d30625d10e8b4b8b0000000000000b50cc069d6a3e33e3ff84a5c41d9d3febe7c770fdcc96b2c3ff60abe184f196367291b4d4c86041b8fa45d630100000001b50cc069d6a3e33e3ff84a5c41d9d3febe7c770fdcc96b2c3ff60abe184f19630101");
+ vector<char> expected(vch.size());
+
+ for (unsigned int i = 0; i < vch.size(); i++)
+ expected[i] = (char)vch[i];
+
+ BOOST_CHECK_EQUAL_COLLECTIONS(expected.begin(), expected.end(), merkleStream.begin(), merkleStream.end());
+}
+
+BOOST_AUTO_TEST_CASE(merkle_block_4)
+{
+ // Random real block (000000000000b731f2eef9e8c63173adfb07e41bd53eb0ef0a6b720d6cb6dea4)
+ // With 7 txes
+ CBlock block;
+ CDataStream stream(ParseHex("0100000082bb869cf3a793432a66e826e05a6fc37469f8efb7421dc880670100000000007f16c5962e8bd963659c793ce370d95f093bc7e367117b3c30c1f8fdd0d9728776381b4d4c86041b554b85290701000000010000000000000000000000000000000000000000000000000000000000000000ffffffff07044c86041b0136ffffffff0100f2052a01000000434104eaafc2314def4ca98ac970241bcab022b9c1e1f4ea423a20f134c876f2c01ec0f0dd5b2e86e7168cefe0d81113c3807420ce13ad1357231a2252247d97a46a91ac000000000100000001bcad20a6a29827d1424f08989255120bf7f3e9e3cdaaa6bb31b0737fe048724300000000494830450220356e834b046cadc0f8ebb5a8a017b02de59c86305403dad52cd77b55af062ea10221009253cd6c119d4729b77c978e1e2aa19f5ea6e0e52b3f16e32fa608cd5bab753901ffffffff02008d380c010000001976a9142b4b8072ecbba129b6453c63e129e643207249ca88ac0065cd1d000000001976a9141b8dd13b994bcfc787b32aeadf58ccb3615cbd5488ac000000000100000003fdacf9b3eb077412e7a968d2e4f11b9a9dee312d666187ed77ee7d26af16cb0b000000008c493046022100ea1608e70911ca0de5af51ba57ad23b9a51db8d28f82c53563c56a05c20f5a87022100a8bdc8b4a8acc8634c6b420410150775eb7f2474f5615f7fccd65af30f310fbf01410465fdf49e29b06b9a1582287b6279014f834edc317695d125ef623c1cc3aaece245bd69fcad7508666e9c74a49dc9056d5fc14338ef38118dc4afae5fe2c585caffffffff309e1913634ecb50f3c4f83e96e70b2df071b497b8973a3e75429df397b5af83000000004948304502202bdb79c596a9ffc24e96f4386199aba386e9bc7b6071516e2b51dda942b3a1ed022100c53a857e76b724fc14d45311eac5019650d415c3abb5428f3aae16d8e69bec2301ffffffff2089e33491695080c9edc18a428f7d834db5b6d372df13ce2b1b0e0cbcb1e6c10000000049483045022100d4ce67c5896ee251c810ac1ff9ceccd328b497c8f553ab6e08431e7d40bad6b5022033119c0c2b7d792d31f1187779c7bd95aefd93d90a715586d73801d9b47471c601ffffffff0100714460030000001976a914c7b55141d097ea5df7a0ed330cf794376e53ec8d88ac0000000001000000045bf0e214aa4069a3e792ecee1e1bf0c1d397cde8dd08138f4b72a00681743447000000008b48304502200c45de8c4f3e2c1821f2fc878cba97b1e6f8807d94930713aa1c86a67b9bf1e40221008581abfef2e30f957815fc89978423746b2086375ca8ecf359c85c2a5b7c88ad01410462bb73f76ca0994fcb8b4271e6fb7561f5c0f9ca0cf6485261c4a0dc894f4ab844c6cdfb97cd0b60ffb5018ffd6238f4d87270efb1d3ae37079b794a92d7ec95ffffffffd669f7d7958d40fc59d2253d88e0f248e29b599c80bbcec344a83dda5f9aa72c000000008a473044022078124c8beeaa825f9e0b30bff96e564dd859432f2d0cb3b72d3d5d93d38d7e930220691d233b6c0f995be5acb03d70a7f7a65b6bc9bdd426260f38a1346669507a3601410462bb73f76ca0994fcb8b4271e6fb7561f5c0f9ca0cf6485261c4a0dc894f4ab844c6cdfb97cd0b60ffb5018ffd6238f4d87270efb1d3ae37079b794a92d7ec95fffffffff878af0d93f5229a68166cf051fd372bb7a537232946e0a46f53636b4dafdaa4000000008c493046022100c717d1714551663f69c3c5759bdbb3a0fcd3fab023abc0e522fe6440de35d8290221008d9cbe25bffc44af2b18e81c58eb37293fd7fe1c2e7b46fc37ee8c96c50ab1e201410462bb73f76ca0994fcb8b4271e6fb7561f5c0f9ca0cf6485261c4a0dc894f4ab844c6cdfb97cd0b60ffb5018ffd6238f4d87270efb1d3ae37079b794a92d7ec95ffffffff27f2b668859cd7f2f894aa0fd2d9e60963bcd07c88973f425f999b8cbfd7a1e2000000008c493046022100e00847147cbf517bcc2f502f3ddc6d284358d102ed20d47a8aa788a62f0db780022100d17b2d6fa84dcaf1c95d88d7e7c30385aecf415588d749afd3ec81f6022cecd701410462bb73f76ca0994fcb8b4271e6fb7561f5c0f9ca0cf6485261c4a0dc894f4ab844c6cdfb97cd0b60ffb5018ffd6238f4d87270efb1d3ae37079b794a92d7ec95ffffffff0100c817a8040000001976a914b6efd80d99179f4f4ff6f4dd0a007d018c385d2188ac000000000100000001834537b2f1ce8ef9373a258e10545ce5a50b758df616cd4356e0032554ebd3c4000000008b483045022100e68f422dd7c34fdce11eeb4509ddae38201773dd62f284e8aa9d96f85099d0b002202243bd399ff96b649a0fad05fa759d6a882f0af8c90cf7632c2840c29070aec20141045e58067e815c2f464c6a2a15f987758374203895710c2d452442e28496ff38ba8f5fd901dc20e29e88477167fe4fc299bf818fd0d9e1632d467b2a3d9503b1aaffffffff0280d7e636030000001976a914f34c3e10eb387efe872acb614c89e78bfca7815d88ac404b4c00000000001976a914a84e272933aaf87e1715d7786c51dfaeb5b65a6f88ac00000000010000000143ac81c8e6f6ef307dfe17f3d906d999e23e0189fda838c5510d850927e03ae7000000008c4930460221009c87c344760a64cb8ae6685a3eec2c1ac1bed5b88c87de51acd0e124f266c16602210082d07c037359c3a257b5c63ebd90f5a5edf97b2ac1c434b08ca998839f346dd40141040ba7e521fa7946d12edbb1d1e95a15c34bd4398195e86433c92b431cd315f455fe30032ede69cad9d1e1ed6c3c4ec0dbfced53438c625462afb792dcb098544bffffffff0240420f00000000001976a9144676d1b820d63ec272f1900d59d43bc6463d96f888ac40420f00000000001976a914648d04341d00d7968b3405c034adc38d4d8fb9bd88ac00000000010000000248cc917501ea5c55f4a8d2009c0567c40cfe037c2e71af017d0a452ff705e3f1000000008b483045022100bf5fdc86dc5f08a5d5c8e43a8c9d5b1ed8c65562e280007b52b133021acd9acc02205e325d613e555f772802bf413d36ba807892ed1a690a77811d3033b3de226e0a01410429fa713b124484cb2bd7b5557b2c0b9df7b2b1fee61825eadc5ae6c37a9920d38bfccdc7dc3cb0c47d7b173dbc9db8d37db0a33ae487982c59c6f8606e9d1791ffffffff41ed70551dd7e841883ab8f0b16bf04176b7d1480e4f0af9f3d4c3595768d068000000008b4830450221008513ad65187b903aed1102d1d0c47688127658c51106753fed0151ce9c16b80902201432b9ebcb87bd04ceb2de66035fbbaf4bf8b00d1cfe41f1a1f7338f9ad79d210141049d4cf80125bf50be1709f718c07ad15d0fc612b7da1f5570dddc35f2a352f0f27c978b06820edca9ef982c35fda2d255afba340068c5035552368bc7200c1488ffffffff0100093d00000000001976a9148edb68822f1ad580b043c7b3df2e400f8699eb4888ac00000000"), SER_NETWORK, PROTOCOL_VERSION);
+ stream >> block;
+
+ CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
+ // Match the last transaction
+ filter.insert(uint256S("0x0a2a92f0bda4727d0a13eaddf4dd9ac6b5c61a1429e6b2b818f19b15df0ac154"));
+
+ CMerkleBlock merkleBlock(block, filter);
+ BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
+
+ BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1);
+ pair<unsigned int, uint256> pair = merkleBlock.vMatchedTxn[0];
+
+ BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0x0a2a92f0bda4727d0a13eaddf4dd9ac6b5c61a1429e6b2b818f19b15df0ac154"));
+ BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 6);
+
+ vector<uint256> vMatched;
+ BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched) == block.hashMerkleRoot);
+ BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size());
+ for (unsigned int i = 0; i < vMatched.size(); i++)
+ BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second);
+
+ // Also match the 4th transaction
+ filter.insert(uint256S("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041"));
+ merkleBlock = CMerkleBlock(block, filter);
+ BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
+
+ BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 2);
+
+ BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041"));
+ BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 3);
+
+ BOOST_CHECK(merkleBlock.vMatchedTxn[1] == pair);
+
+ BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched) == block.hashMerkleRoot);
+ BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size());
+ for (unsigned int i = 0; i < vMatched.size(); i++)
+ BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second);
+}
+
+BOOST_AUTO_TEST_CASE(merkle_block_4_test_p2pubkey_only)
+{
+ // Random real block (000000000000b731f2eef9e8c63173adfb07e41bd53eb0ef0a6b720d6cb6dea4)
+ // With 7 txes
+ CBlock block;
+ CDataStream stream(ParseHex("0100000082bb869cf3a793432a66e826e05a6fc37469f8efb7421dc880670100000000007f16c5962e8bd963659c793ce370d95f093bc7e367117b3c30c1f8fdd0d9728776381b4d4c86041b554b85290701000000010000000000000000000000000000000000000000000000000000000000000000ffffffff07044c86041b0136ffffffff0100f2052a01000000434104eaafc2314def4ca98ac970241bcab022b9c1e1f4ea423a20f134c876f2c01ec0f0dd5b2e86e7168cefe0d81113c3807420ce13ad1357231a2252247d97a46a91ac000000000100000001bcad20a6a29827d1424f08989255120bf7f3e9e3cdaaa6bb31b0737fe048724300000000494830450220356e834b046cadc0f8ebb5a8a017b02de59c86305403dad52cd77b55af062ea10221009253cd6c119d4729b77c978e1e2aa19f5ea6e0e52b3f16e32fa608cd5bab753901ffffffff02008d380c010000001976a9142b4b8072ecbba129b6453c63e129e643207249ca88ac0065cd1d000000001976a9141b8dd13b994bcfc787b32aeadf58ccb3615cbd5488ac000000000100000003fdacf9b3eb077412e7a968d2e4f11b9a9dee312d666187ed77ee7d26af16cb0b000000008c493046022100ea1608e70911ca0de5af51ba57ad23b9a51db8d28f82c53563c56a05c20f5a87022100a8bdc8b4a8acc8634c6b420410150775eb7f2474f5615f7fccd65af30f310fbf01410465fdf49e29b06b9a1582287b6279014f834edc317695d125ef623c1cc3aaece245bd69fcad7508666e9c74a49dc9056d5fc14338ef38118dc4afae5fe2c585caffffffff309e1913634ecb50f3c4f83e96e70b2df071b497b8973a3e75429df397b5af83000000004948304502202bdb79c596a9ffc24e96f4386199aba386e9bc7b6071516e2b51dda942b3a1ed022100c53a857e76b724fc14d45311eac5019650d415c3abb5428f3aae16d8e69bec2301ffffffff2089e33491695080c9edc18a428f7d834db5b6d372df13ce2b1b0e0cbcb1e6c10000000049483045022100d4ce67c5896ee251c810ac1ff9ceccd328b497c8f553ab6e08431e7d40bad6b5022033119c0c2b7d792d31f1187779c7bd95aefd93d90a715586d73801d9b47471c601ffffffff0100714460030000001976a914c7b55141d097ea5df7a0ed330cf794376e53ec8d88ac0000000001000000045bf0e214aa4069a3e792ecee1e1bf0c1d397cde8dd08138f4b72a00681743447000000008b48304502200c45de8c4f3e2c1821f2fc878cba97b1e6f8807d94930713aa1c86a67b9bf1e40221008581abfef2e30f957815fc89978423746b2086375ca8ecf359c85c2a5b7c88ad01410462bb73f76ca0994fcb8b4271e6fb7561f5c0f9ca0cf6485261c4a0dc894f4ab844c6cdfb97cd0b60ffb5018ffd6238f4d87270efb1d3ae37079b794a92d7ec95ffffffffd669f7d7958d40fc59d2253d88e0f248e29b599c80bbcec344a83dda5f9aa72c000000008a473044022078124c8beeaa825f9e0b30bff96e564dd859432f2d0cb3b72d3d5d93d38d7e930220691d233b6c0f995be5acb03d70a7f7a65b6bc9bdd426260f38a1346669507a3601410462bb73f76ca0994fcb8b4271e6fb7561f5c0f9ca0cf6485261c4a0dc894f4ab844c6cdfb97cd0b60ffb5018ffd6238f4d87270efb1d3ae37079b794a92d7ec95fffffffff878af0d93f5229a68166cf051fd372bb7a537232946e0a46f53636b4dafdaa4000000008c493046022100c717d1714551663f69c3c5759bdbb3a0fcd3fab023abc0e522fe6440de35d8290221008d9cbe25bffc44af2b18e81c58eb37293fd7fe1c2e7b46fc37ee8c96c50ab1e201410462bb73f76ca0994fcb8b4271e6fb7561f5c0f9ca0cf6485261c4a0dc894f4ab844c6cdfb97cd0b60ffb5018ffd6238f4d87270efb1d3ae37079b794a92d7ec95ffffffff27f2b668859cd7f2f894aa0fd2d9e60963bcd07c88973f425f999b8cbfd7a1e2000000008c493046022100e00847147cbf517bcc2f502f3ddc6d284358d102ed20d47a8aa788a62f0db780022100d17b2d6fa84dcaf1c95d88d7e7c30385aecf415588d749afd3ec81f6022cecd701410462bb73f76ca0994fcb8b4271e6fb7561f5c0f9ca0cf6485261c4a0dc894f4ab844c6cdfb97cd0b60ffb5018ffd6238f4d87270efb1d3ae37079b794a92d7ec95ffffffff0100c817a8040000001976a914b6efd80d99179f4f4ff6f4dd0a007d018c385d2188ac000000000100000001834537b2f1ce8ef9373a258e10545ce5a50b758df616cd4356e0032554ebd3c4000000008b483045022100e68f422dd7c34fdce11eeb4509ddae38201773dd62f284e8aa9d96f85099d0b002202243bd399ff96b649a0fad05fa759d6a882f0af8c90cf7632c2840c29070aec20141045e58067e815c2f464c6a2a15f987758374203895710c2d452442e28496ff38ba8f5fd901dc20e29e88477167fe4fc299bf818fd0d9e1632d467b2a3d9503b1aaffffffff0280d7e636030000001976a914f34c3e10eb387efe872acb614c89e78bfca7815d88ac404b4c00000000001976a914a84e272933aaf87e1715d7786c51dfaeb5b65a6f88ac00000000010000000143ac81c8e6f6ef307dfe17f3d906d999e23e0189fda838c5510d850927e03ae7000000008c4930460221009c87c344760a64cb8ae6685a3eec2c1ac1bed5b88c87de51acd0e124f266c16602210082d07c037359c3a257b5c63ebd90f5a5edf97b2ac1c434b08ca998839f346dd40141040ba7e521fa7946d12edbb1d1e95a15c34bd4398195e86433c92b431cd315f455fe30032ede69cad9d1e1ed6c3c4ec0dbfced53438c625462afb792dcb098544bffffffff0240420f00000000001976a9144676d1b820d63ec272f1900d59d43bc6463d96f888ac40420f00000000001976a914648d04341d00d7968b3405c034adc38d4d8fb9bd88ac00000000010000000248cc917501ea5c55f4a8d2009c0567c40cfe037c2e71af017d0a452ff705e3f1000000008b483045022100bf5fdc86dc5f08a5d5c8e43a8c9d5b1ed8c65562e280007b52b133021acd9acc02205e325d613e555f772802bf413d36ba807892ed1a690a77811d3033b3de226e0a01410429fa713b124484cb2bd7b5557b2c0b9df7b2b1fee61825eadc5ae6c37a9920d38bfccdc7dc3cb0c47d7b173dbc9db8d37db0a33ae487982c59c6f8606e9d1791ffffffff41ed70551dd7e841883ab8f0b16bf04176b7d1480e4f0af9f3d4c3595768d068000000008b4830450221008513ad65187b903aed1102d1d0c47688127658c51106753fed0151ce9c16b80902201432b9ebcb87bd04ceb2de66035fbbaf4bf8b00d1cfe41f1a1f7338f9ad79d210141049d4cf80125bf50be1709f718c07ad15d0fc612b7da1f5570dddc35f2a352f0f27c978b06820edca9ef982c35fda2d255afba340068c5035552368bc7200c1488ffffffff0100093d00000000001976a9148edb68822f1ad580b043c7b3df2e400f8699eb4888ac00000000"), SER_NETWORK, PROTOCOL_VERSION);
+ stream >> block;
+
+ CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_P2PUBKEY_ONLY);
+ // Match the generation pubkey
+ filter.insert(ParseHex("04eaafc2314def4ca98ac970241bcab022b9c1e1f4ea423a20f134c876f2c01ec0f0dd5b2e86e7168cefe0d81113c3807420ce13ad1357231a2252247d97a46a91"));
+ // ...and the output address of the 4th transaction
+ filter.insert(ParseHex("b6efd80d99179f4f4ff6f4dd0a007d018c385d21"));
+
+ CMerkleBlock merkleBlock(block, filter);
+ BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
+
+ // We should match the generation outpoint
+ BOOST_CHECK(filter.contains(COutPoint(uint256S("0x147caa76786596590baa4e98f5d9f48b86c7765e489f7a6ff3360fe5c674360b"), 0)));
+ // ... but not the 4th transaction's output (its not pay-2-pubkey)
+ BOOST_CHECK(!filter.contains(COutPoint(uint256S("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041"), 0)));
+}
+
+BOOST_AUTO_TEST_CASE(merkle_block_4_test_update_none)
+{
+ // Random real block (000000000000b731f2eef9e8c63173adfb07e41bd53eb0ef0a6b720d6cb6dea4)
+ // With 7 txes
+ CBlock block;
+ CDataStream stream(ParseHex("0100000082bb869cf3a793432a66e826e05a6fc37469f8efb7421dc880670100000000007f16c5962e8bd963659c793ce370d95f093bc7e367117b3c30c1f8fdd0d9728776381b4d4c86041b554b85290701000000010000000000000000000000000000000000000000000000000000000000000000ffffffff07044c86041b0136ffffffff0100f2052a01000000434104eaafc2314def4ca98ac970241bcab022b9c1e1f4ea423a20f134c876f2c01ec0f0dd5b2e86e7168cefe0d81113c3807420ce13ad1357231a2252247d97a46a91ac000000000100000001bcad20a6a29827d1424f08989255120bf7f3e9e3cdaaa6bb31b0737fe048724300000000494830450220356e834b046cadc0f8ebb5a8a017b02de59c86305403dad52cd77b55af062ea10221009253cd6c119d4729b77c978e1e2aa19f5ea6e0e52b3f16e32fa608cd5bab753901ffffffff02008d380c010000001976a9142b4b8072ecbba129b6453c63e129e643207249ca88ac0065cd1d000000001976a9141b8dd13b994bcfc787b32aeadf58ccb3615cbd5488ac000000000100000003fdacf9b3eb077412e7a968d2e4f11b9a9dee312d666187ed77ee7d26af16cb0b000000008c493046022100ea1608e70911ca0de5af51ba57ad23b9a51db8d28f82c53563c56a05c20f5a87022100a8bdc8b4a8acc8634c6b420410150775eb7f2474f5615f7fccd65af30f310fbf01410465fdf49e29b06b9a1582287b6279014f834edc317695d125ef623c1cc3aaece245bd69fcad7508666e9c74a49dc9056d5fc14338ef38118dc4afae5fe2c585caffffffff309e1913634ecb50f3c4f83e96e70b2df071b497b8973a3e75429df397b5af83000000004948304502202bdb79c596a9ffc24e96f4386199aba386e9bc7b6071516e2b51dda942b3a1ed022100c53a857e76b724fc14d45311eac5019650d415c3abb5428f3aae16d8e69bec2301ffffffff2089e33491695080c9edc18a428f7d834db5b6d372df13ce2b1b0e0cbcb1e6c10000000049483045022100d4ce67c5896ee251c810ac1ff9ceccd328b497c8f553ab6e08431e7d40bad6b5022033119c0c2b7d792d31f1187779c7bd95aefd93d90a715586d73801d9b47471c601ffffffff0100714460030000001976a914c7b55141d097ea5df7a0ed330cf794376e53ec8d88ac0000000001000000045bf0e214aa4069a3e792ecee1e1bf0c1d397cde8dd08138f4b72a00681743447000000008b48304502200c45de8c4f3e2c1821f2fc878cba97b1e6f8807d94930713aa1c86a67b9bf1e40221008581abfef2e30f957815fc89978423746b2086375ca8ecf359c85c2a5b7c88ad01410462bb73f76ca0994fcb8b4271e6fb7561f5c0f9ca0cf6485261c4a0dc894f4ab844c6cdfb97cd0b60ffb5018ffd6238f4d87270efb1d3ae37079b794a92d7ec95ffffffffd669f7d7958d40fc59d2253d88e0f248e29b599c80bbcec344a83dda5f9aa72c000000008a473044022078124c8beeaa825f9e0b30bff96e564dd859432f2d0cb3b72d3d5d93d38d7e930220691d233b6c0f995be5acb03d70a7f7a65b6bc9bdd426260f38a1346669507a3601410462bb73f76ca0994fcb8b4271e6fb7561f5c0f9ca0cf6485261c4a0dc894f4ab844c6cdfb97cd0b60ffb5018ffd6238f4d87270efb1d3ae37079b794a92d7ec95fffffffff878af0d93f5229a68166cf051fd372bb7a537232946e0a46f53636b4dafdaa4000000008c493046022100c717d1714551663f69c3c5759bdbb3a0fcd3fab023abc0e522fe6440de35d8290221008d9cbe25bffc44af2b18e81c58eb37293fd7fe1c2e7b46fc37ee8c96c50ab1e201410462bb73f76ca0994fcb8b4271e6fb7561f5c0f9ca0cf6485261c4a0dc894f4ab844c6cdfb97cd0b60ffb5018ffd6238f4d87270efb1d3ae37079b794a92d7ec95ffffffff27f2b668859cd7f2f894aa0fd2d9e60963bcd07c88973f425f999b8cbfd7a1e2000000008c493046022100e00847147cbf517bcc2f502f3ddc6d284358d102ed20d47a8aa788a62f0db780022100d17b2d6fa84dcaf1c95d88d7e7c30385aecf415588d749afd3ec81f6022cecd701410462bb73f76ca0994fcb8b4271e6fb7561f5c0f9ca0cf6485261c4a0dc894f4ab844c6cdfb97cd0b60ffb5018ffd6238f4d87270efb1d3ae37079b794a92d7ec95ffffffff0100c817a8040000001976a914b6efd80d99179f4f4ff6f4dd0a007d018c385d2188ac000000000100000001834537b2f1ce8ef9373a258e10545ce5a50b758df616cd4356e0032554ebd3c4000000008b483045022100e68f422dd7c34fdce11eeb4509ddae38201773dd62f284e8aa9d96f85099d0b002202243bd399ff96b649a0fad05fa759d6a882f0af8c90cf7632c2840c29070aec20141045e58067e815c2f464c6a2a15f987758374203895710c2d452442e28496ff38ba8f5fd901dc20e29e88477167fe4fc299bf818fd0d9e1632d467b2a3d9503b1aaffffffff0280d7e636030000001976a914f34c3e10eb387efe872acb614c89e78bfca7815d88ac404b4c00000000001976a914a84e272933aaf87e1715d7786c51dfaeb5b65a6f88ac00000000010000000143ac81c8e6f6ef307dfe17f3d906d999e23e0189fda838c5510d850927e03ae7000000008c4930460221009c87c344760a64cb8ae6685a3eec2c1ac1bed5b88c87de51acd0e124f266c16602210082d07c037359c3a257b5c63ebd90f5a5edf97b2ac1c434b08ca998839f346dd40141040ba7e521fa7946d12edbb1d1e95a15c34bd4398195e86433c92b431cd315f455fe30032ede69cad9d1e1ed6c3c4ec0dbfced53438c625462afb792dcb098544bffffffff0240420f00000000001976a9144676d1b820d63ec272f1900d59d43bc6463d96f888ac40420f00000000001976a914648d04341d00d7968b3405c034adc38d4d8fb9bd88ac00000000010000000248cc917501ea5c55f4a8d2009c0567c40cfe037c2e71af017d0a452ff705e3f1000000008b483045022100bf5fdc86dc5f08a5d5c8e43a8c9d5b1ed8c65562e280007b52b133021acd9acc02205e325d613e555f772802bf413d36ba807892ed1a690a77811d3033b3de226e0a01410429fa713b124484cb2bd7b5557b2c0b9df7b2b1fee61825eadc5ae6c37a9920d38bfccdc7dc3cb0c47d7b173dbc9db8d37db0a33ae487982c59c6f8606e9d1791ffffffff41ed70551dd7e841883ab8f0b16bf04176b7d1480e4f0af9f3d4c3595768d068000000008b4830450221008513ad65187b903aed1102d1d0c47688127658c51106753fed0151ce9c16b80902201432b9ebcb87bd04ceb2de66035fbbaf4bf8b00d1cfe41f1a1f7338f9ad79d210141049d4cf80125bf50be1709f718c07ad15d0fc612b7da1f5570dddc35f2a352f0f27c978b06820edca9ef982c35fda2d255afba340068c5035552368bc7200c1488ffffffff0100093d00000000001976a9148edb68822f1ad580b043c7b3df2e400f8699eb4888ac00000000"), SER_NETWORK, PROTOCOL_VERSION);
+ stream >> block;
+
+ CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_NONE);
+ // Match the generation pubkey
+ filter.insert(ParseHex("04eaafc2314def4ca98ac970241bcab022b9c1e1f4ea423a20f134c876f2c01ec0f0dd5b2e86e7168cefe0d81113c3807420ce13ad1357231a2252247d97a46a91"));
+ // ...and the output address of the 4th transaction
+ filter.insert(ParseHex("b6efd80d99179f4f4ff6f4dd0a007d018c385d21"));
+
+ CMerkleBlock merkleBlock(block, filter);
+ BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
+
+ // We shouldn't match any outpoints (UPDATE_NONE)
+ BOOST_CHECK(!filter.contains(COutPoint(uint256S("0x147caa76786596590baa4e98f5d9f48b86c7765e489f7a6ff3360fe5c674360b"), 0)));
+ BOOST_CHECK(!filter.contains(COutPoint(uint256S("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041"), 0)));
+}
+
+static std::vector<unsigned char> RandomData()
+{
+ uint256 r = GetRandHash();
+ return std::vector<unsigned char>(r.begin(), r.end());
+}
+
+BOOST_AUTO_TEST_CASE(rolling_bloom)
+{
+ // last-100-entry, 1% false positive:
+ CRollingBloomFilter rb1(100, 0.01);
+
+ // Overfill:
+ static const int DATASIZE=399;
+ std::vector<unsigned char> data[DATASIZE];
+ for (int i = 0; i < DATASIZE; i++) {
+ data[i] = RandomData();
+ rb1.insert(data[i]);
+ }
+ // Last 100 guaranteed to be remembered:
+ for (int i = 299; i < DATASIZE; i++) {
+ BOOST_CHECK(rb1.contains(data[i]));
+ }
+
+ // false positive rate is 1%, so we should get about 100 hits if
+ // testing 10,000 random keys. We get worst-case false positive
+ // behavior when the filter is as full as possible, which is
+ // when we've inserted one minus an integer multiple of nElement*2.
+ unsigned int nHits = 0;
+ for (int i = 0; i < 10000; i++) {
+ if (rb1.contains(RandomData()))
+ ++nHits;
+ }
+ // Run test_bitcoin with --log_level=message to see BOOST_TEST_MESSAGEs:
+ BOOST_TEST_MESSAGE("RollingBloomFilter got " << nHits << " false positives (~100 expected)");
+
+ // Insanely unlikely to get a fp count outside this range:
+ BOOST_CHECK(nHits > 25);
+ BOOST_CHECK(nHits < 175);
+
+ BOOST_CHECK(rb1.contains(data[DATASIZE-1]));
+ rb1.reset();
+ BOOST_CHECK(!rb1.contains(data[DATASIZE-1]));
+
+ // Now roll through data, make sure last 100 entries
+ // are always remembered:
+ for (int i = 0; i < DATASIZE; i++) {
+ if (i >= 100)
+ BOOST_CHECK(rb1.contains(data[i-100]));
+ rb1.insert(data[i]);
+ }
+
+ // Insert 999 more random entries:
+ for (int i = 0; i < 999; i++) {
+ rb1.insert(RandomData());
+ }
+ // Sanity check to make sure the filter isn't just filling up:
+ nHits = 0;
+ for (int i = 0; i < DATASIZE; i++) {
+ if (rb1.contains(data[i]))
+ ++nHits;
+ }
+ // Expect about 5 false positives, more than 100 means
+ // something is definitely broken.
+ BOOST_TEST_MESSAGE("RollingBloomFilter got " << nHits << " false positives (~5 expected)");
+ BOOST_CHECK(nHits < 100);
+
+ // last-1000-entry, 0.01% false positive:
+ CRollingBloomFilter rb2(1000, 0.001);
+ for (int i = 0; i < DATASIZE; i++) {
+ rb2.insert(data[i]);
+ }
+ // ... room for all of them:
+ for (int i = 0; i < DATASIZE; i++) {
+ BOOST_CHECK(rb2.contains(data[i]));
+ }
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/buildenv.py.in b/src/test/buildenv.py.in
new file mode 100644
index 0000000000..1618bdeb76
--- /dev/null
+++ b/src/test/buildenv.py.in
@@ -0,0 +1,2 @@
+#!/usr/bin/python
+exeext="@EXEEXT@"
diff --git a/src/test/checkblock_tests.cpp b/src/test/checkblock_tests.cpp
new file mode 100644
index 0000000000..51530c4de5
--- /dev/null
+++ b/src/test/checkblock_tests.cpp
@@ -0,0 +1,65 @@
+// Copyright (c) 2013-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "clientversion.h"
+#include "consensus/validation.h"
+#include "main.h"
+#include "test/test_bitcoin.h"
+#include "utiltime.h"
+
+#include <cstdio>
+
+#include <boost/filesystem/operations.hpp>
+#include <boost/filesystem/path.hpp>
+#include <boost/test/unit_test.hpp>
+
+
+BOOST_FIXTURE_TEST_SUITE(CheckBlock_tests, BasicTestingSetup)
+
+bool read_block(const std::string& filename, CBlock& block)
+{
+ namespace fs = boost::filesystem;
+ fs::path testFile = fs::current_path() / "data" / filename;
+#ifdef TEST_DATA_DIR
+ if (!fs::exists(testFile))
+ {
+ testFile = fs::path(BOOST_PP_STRINGIZE(TEST_DATA_DIR)) / filename;
+ }
+#endif
+ FILE* fp = fopen(testFile.string().c_str(), "rb");
+ if (!fp) return false;
+
+ fseek(fp, 8, SEEK_SET); // skip msgheader/size
+
+ CAutoFile filein(fp, SER_DISK, CLIENT_VERSION);
+ if (filein.IsNull()) return false;
+
+ filein >> block;
+
+ return true;
+}
+
+BOOST_AUTO_TEST_CASE(May15)
+{
+ // Putting a 1MB binary file in the git repository is not a great
+ // idea, so this test is only run if you manually download
+ // test/data/Mar12Fork.dat from
+ // http://sourceforge.net/projects/bitcoin/files/Bitcoin/blockchain/Mar12Fork.dat/download
+ unsigned int tMay15 = 1368576000;
+ SetMockTime(tMay15); // Test as if it was right at May 15
+
+ CBlock forkingBlock;
+ if (read_block("Mar12Fork.dat", forkingBlock))
+ {
+ CValidationState state;
+
+ // After May 15'th, big blocks are OK:
+ forkingBlock.nTime = tMay15; // Invalidates PoW
+ BOOST_CHECK(CheckBlock(forkingBlock, state, false, false));
+ }
+
+ SetMockTime(0);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp
new file mode 100644
index 0000000000..34b311b804
--- /dev/null
+++ b/src/test/coins_tests.cpp
@@ -0,0 +1,200 @@
+// Copyright (c) 2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "coins.h"
+#include "random.h"
+#include "uint256.h"
+#include "test/test_bitcoin.h"
+
+#include <vector>
+#include <map>
+
+#include <boost/test/unit_test.hpp>
+
+namespace
+{
+class CCoinsViewTest : public CCoinsView
+{
+ uint256 hashBestBlock_;
+ std::map<uint256, CCoins> map_;
+
+public:
+ bool GetCoins(const uint256& txid, CCoins& coins) const
+ {
+ std::map<uint256, CCoins>::const_iterator it = map_.find(txid);
+ if (it == map_.end()) {
+ return false;
+ }
+ coins = it->second;
+ if (coins.IsPruned() && insecure_rand() % 2 == 0) {
+ // Randomly return false in case of an empty entry.
+ return false;
+ }
+ return true;
+ }
+
+ bool HaveCoins(const uint256& txid) const
+ {
+ CCoins coins;
+ return GetCoins(txid, coins);
+ }
+
+ uint256 GetBestBlock() const { return hashBestBlock_; }
+
+ bool BatchWrite(CCoinsMap& mapCoins, const uint256& hashBlock)
+ {
+ for (CCoinsMap::iterator it = mapCoins.begin(); it != mapCoins.end(); ) {
+ map_[it->first] = it->second.coins;
+ if (it->second.coins.IsPruned() && insecure_rand() % 3 == 0) {
+ // Randomly delete empty entries on write.
+ map_.erase(it->first);
+ }
+ mapCoins.erase(it++);
+ }
+ mapCoins.clear();
+ hashBestBlock_ = hashBlock;
+ return true;
+ }
+
+ bool GetStats(CCoinsStats& stats) const { return false; }
+};
+
+class CCoinsViewCacheTest : public CCoinsViewCache
+{
+public:
+ CCoinsViewCacheTest(CCoinsView* base) : CCoinsViewCache(base) {}
+
+ void SelfTest() const
+ {
+ // Manually recompute the dynamic usage of the whole data, and compare it.
+ size_t ret = memusage::DynamicUsage(cacheCoins);
+ for (CCoinsMap::iterator it = cacheCoins.begin(); it != cacheCoins.end(); it++) {
+ ret += memusage::DynamicUsage(it->second.coins);
+ }
+ BOOST_CHECK_EQUAL(memusage::DynamicUsage(*this), ret);
+ }
+
+};
+
+}
+
+BOOST_FIXTURE_TEST_SUITE(coins_tests, BasicTestingSetup)
+
+static const unsigned int NUM_SIMULATION_ITERATIONS = 40000;
+
+// This is a large randomized insert/remove simulation test on a variable-size
+// stack of caches on top of CCoinsViewTest.
+//
+// It will randomly create/update/delete CCoins entries to a tip of caches, with
+// txids picked from a limited list of random 256-bit hashes. Occasionally, a
+// new tip is added to the stack of caches, or the tip is flushed and removed.
+//
+// During the process, booleans are kept to make sure that the randomized
+// operation hits all branches.
+BOOST_AUTO_TEST_CASE(coins_cache_simulation_test)
+{
+ // Various coverage trackers.
+ bool removed_all_caches = false;
+ bool reached_4_caches = false;
+ bool added_an_entry = false;
+ bool removed_an_entry = false;
+ bool updated_an_entry = false;
+ bool found_an_entry = false;
+ bool missed_an_entry = false;
+
+ // A simple map to track what we expect the cache stack to represent.
+ std::map<uint256, CCoins> result;
+
+ // The cache stack.
+ CCoinsViewTest base; // A CCoinsViewTest at the bottom.
+ std::vector<CCoinsViewCacheTest*> stack; // A stack of CCoinsViewCaches on top.
+ stack.push_back(new CCoinsViewCacheTest(&base)); // Start with one cache.
+
+ // Use a limited set of random transaction ids, so we do test overwriting entries.
+ std::vector<uint256> txids;
+ txids.resize(NUM_SIMULATION_ITERATIONS / 8);
+ for (unsigned int i = 0; i < txids.size(); i++) {
+ txids[i] = GetRandHash();
+ }
+
+ for (unsigned int i = 0; i < NUM_SIMULATION_ITERATIONS; i++) {
+ // Do a random modification.
+ {
+ uint256 txid = txids[insecure_rand() % txids.size()]; // txid we're going to modify in this iteration.
+ CCoins& coins = result[txid];
+ CCoinsModifier entry = stack.back()->ModifyCoins(txid);
+ BOOST_CHECK(coins == *entry);
+ if (insecure_rand() % 5 == 0 || coins.IsPruned()) {
+ if (coins.IsPruned()) {
+ added_an_entry = true;
+ } else {
+ updated_an_entry = true;
+ }
+ coins.nVersion = insecure_rand();
+ coins.vout.resize(1);
+ coins.vout[0].nValue = insecure_rand();
+ *entry = coins;
+ } else {
+ coins.Clear();
+ entry->Clear();
+ removed_an_entry = true;
+ }
+ }
+
+ // Once every 1000 iterations and at the end, verify the full cache.
+ if (insecure_rand() % 1000 == 1 || i == NUM_SIMULATION_ITERATIONS - 1) {
+ for (std::map<uint256, CCoins>::iterator it = result.begin(); it != result.end(); it++) {
+ const CCoins* coins = stack.back()->AccessCoins(it->first);
+ if (coins) {
+ BOOST_CHECK(*coins == it->second);
+ found_an_entry = true;
+ } else {
+ BOOST_CHECK(it->second.IsPruned());
+ missed_an_entry = true;
+ }
+ }
+ BOOST_FOREACH(const CCoinsViewCacheTest *test, stack) {
+ test->SelfTest();
+ }
+ }
+
+ if (insecure_rand() % 100 == 0) {
+ // Every 100 iterations, change the cache stack.
+ if (stack.size() > 0 && insecure_rand() % 2 == 0) {
+ stack.back()->Flush();
+ delete stack.back();
+ stack.pop_back();
+ }
+ if (stack.size() == 0 || (stack.size() < 4 && insecure_rand() % 2)) {
+ CCoinsView* tip = &base;
+ if (stack.size() > 0) {
+ tip = stack.back();
+ } else {
+ removed_all_caches = true;
+ }
+ stack.push_back(new CCoinsViewCacheTest(tip));
+ if (stack.size() == 4) {
+ reached_4_caches = true;
+ }
+ }
+ }
+ }
+
+ // Clean up the stack.
+ while (stack.size() > 0) {
+ delete stack.back();
+ stack.pop_back();
+ }
+
+ // Verify coverage.
+ BOOST_CHECK(removed_all_caches);
+ BOOST_CHECK(reached_4_caches);
+ BOOST_CHECK(added_an_entry);
+ BOOST_CHECK(removed_an_entry);
+ BOOST_CHECK(updated_an_entry);
+ BOOST_CHECK(found_an_entry);
+ BOOST_CHECK(missed_an_entry);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/compress_tests.cpp b/src/test/compress_tests.cpp
new file mode 100644
index 0000000000..376ae93681
--- /dev/null
+++ b/src/test/compress_tests.cpp
@@ -0,0 +1,65 @@
+// Copyright (c) 2012-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "compressor.h"
+#include "util.h"
+#include "test/test_bitcoin.h"
+
+#include <stdint.h>
+
+#include <boost/test/unit_test.hpp>
+
+// amounts 0.00000001 .. 0.00100000
+#define NUM_MULTIPLES_UNIT 100000
+
+// amounts 0.01 .. 100.00
+#define NUM_MULTIPLES_CENT 10000
+
+// amounts 1 .. 10000
+#define NUM_MULTIPLES_1BTC 10000
+
+// amounts 50 .. 21000000
+#define NUM_MULTIPLES_50BTC 420000
+
+BOOST_FIXTURE_TEST_SUITE(compress_tests, BasicTestingSetup)
+
+bool static TestEncode(uint64_t in) {
+ return in == CTxOutCompressor::DecompressAmount(CTxOutCompressor::CompressAmount(in));
+}
+
+bool static TestDecode(uint64_t in) {
+ return in == CTxOutCompressor::CompressAmount(CTxOutCompressor::DecompressAmount(in));
+}
+
+bool static TestPair(uint64_t dec, uint64_t enc) {
+ return CTxOutCompressor::CompressAmount(dec) == enc &&
+ CTxOutCompressor::DecompressAmount(enc) == dec;
+}
+
+BOOST_AUTO_TEST_CASE(compress_amounts)
+{
+ BOOST_CHECK(TestPair( 0, 0x0));
+ BOOST_CHECK(TestPair( 1, 0x1));
+ BOOST_CHECK(TestPair( CENT, 0x7));
+ BOOST_CHECK(TestPair( COIN, 0x9));
+ BOOST_CHECK(TestPair( 50*COIN, 0x32));
+ BOOST_CHECK(TestPair(21000000*COIN, 0x1406f40));
+
+ for (uint64_t i = 1; i <= NUM_MULTIPLES_UNIT; i++)
+ BOOST_CHECK(TestEncode(i));
+
+ for (uint64_t i = 1; i <= NUM_MULTIPLES_CENT; i++)
+ BOOST_CHECK(TestEncode(i * CENT));
+
+ for (uint64_t i = 1; i <= NUM_MULTIPLES_1BTC; i++)
+ BOOST_CHECK(TestEncode(i * COIN));
+
+ for (uint64_t i = 1; i <= NUM_MULTIPLES_50BTC; i++)
+ BOOST_CHECK(TestEncode(i * 50 * COIN));
+
+ for (uint64_t i = 0; i < 100000; i++)
+ BOOST_CHECK(TestDecode(i));
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/crypto_tests.cpp b/src/test/crypto_tests.cpp
new file mode 100644
index 0000000000..aeb2a5caa3
--- /dev/null
+++ b/src/test/crypto_tests.cpp
@@ -0,0 +1,251 @@
+// Copyright (c) 2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "crypto/ripemd160.h"
+#include "crypto/sha1.h"
+#include "crypto/sha256.h"
+#include "crypto/sha512.h"
+#include "crypto/hmac_sha256.h"
+#include "crypto/hmac_sha512.h"
+#include "random.h"
+#include "utilstrencodings.h"
+#include "test/test_bitcoin.h"
+
+#include <vector>
+
+#include <boost/assign/list_of.hpp>
+#include <boost/test/unit_test.hpp>
+
+BOOST_FIXTURE_TEST_SUITE(crypto_tests, BasicTestingSetup)
+
+template<typename Hasher, typename In, typename Out>
+void TestVector(const Hasher &h, const In &in, const Out &out) {
+ Out hash;
+ BOOST_CHECK(out.size() == h.OUTPUT_SIZE);
+ hash.resize(out.size());
+ {
+ // Test that writing the whole input string at once works.
+ Hasher(h).Write((unsigned char*)&in[0], in.size()).Finalize(&hash[0]);
+ BOOST_CHECK(hash == out);
+ }
+ for (int i=0; i<32; i++) {
+ // Test that writing the string broken up in random pieces works.
+ Hasher hasher(h);
+ size_t pos = 0;
+ while (pos < in.size()) {
+ size_t len = insecure_rand() % ((in.size() - pos + 1) / 2 + 1);
+ hasher.Write((unsigned char*)&in[pos], len);
+ pos += len;
+ if (pos > 0 && pos + 2 * out.size() > in.size() && pos < in.size()) {
+ // Test that writing the rest at once to a copy of a hasher works.
+ Hasher(hasher).Write((unsigned char*)&in[pos], in.size() - pos).Finalize(&hash[0]);
+ BOOST_CHECK(hash == out);
+ }
+ }
+ hasher.Finalize(&hash[0]);
+ BOOST_CHECK(hash == out);
+ }
+}
+
+void TestSHA1(const std::string &in, const std::string &hexout) { TestVector(CSHA1(), in, ParseHex(hexout));}
+void TestSHA256(const std::string &in, const std::string &hexout) { TestVector(CSHA256(), in, ParseHex(hexout));}
+void TestSHA512(const std::string &in, const std::string &hexout) { TestVector(CSHA512(), in, ParseHex(hexout));}
+void TestRIPEMD160(const std::string &in, const std::string &hexout) { TestVector(CRIPEMD160(), in, ParseHex(hexout));}
+
+void TestHMACSHA256(const std::string &hexkey, const std::string &hexin, const std::string &hexout) {
+ std::vector<unsigned char> key = ParseHex(hexkey);
+ TestVector(CHMAC_SHA256(&key[0], key.size()), ParseHex(hexin), ParseHex(hexout));
+}
+
+void TestHMACSHA512(const std::string &hexkey, const std::string &hexin, const std::string &hexout) {
+ std::vector<unsigned char> key = ParseHex(hexkey);
+ TestVector(CHMAC_SHA512(&key[0], key.size()), ParseHex(hexin), ParseHex(hexout));
+}
+
+std::string LongTestString(void) {
+ std::string ret;
+ for (int i=0; i<200000; i++) {
+ ret += (unsigned char)(i);
+ ret += (unsigned char)(i >> 4);
+ ret += (unsigned char)(i >> 8);
+ ret += (unsigned char)(i >> 12);
+ ret += (unsigned char)(i >> 16);
+ }
+ return ret;
+}
+
+const std::string test1 = LongTestString();
+
+BOOST_AUTO_TEST_CASE(ripemd160_testvectors) {
+ TestRIPEMD160("", "9c1185a5c5e9fc54612808977ee8f548b2258d31");
+ TestRIPEMD160("abc", "8eb208f7e05d987a9b044a8e98c6b087f15a0bfc");
+ TestRIPEMD160("message digest", "5d0689ef49d2fae572b881b123a85ffa21595f36");
+ TestRIPEMD160("secure hash algorithm", "20397528223b6a5f4cbc2808aba0464e645544f9");
+ TestRIPEMD160("RIPEMD160 is considered to be safe", "a7d78608c7af8a8e728778e81576870734122b66");
+ TestRIPEMD160("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ "12a053384a9c0c88e405a06c27dcf49ada62eb2b");
+ TestRIPEMD160("For this sample, this 63-byte string will be used as input data",
+ "de90dbfee14b63fb5abf27c2ad4a82aaa5f27a11");
+ TestRIPEMD160("This is exactly 64 bytes long, not counting the terminating byte",
+ "eda31d51d3a623b81e19eb02e24ff65d27d67b37");
+ TestRIPEMD160(std::string(1000000, 'a'), "52783243c1697bdbe16d37f97f68f08325dc1528");
+ TestRIPEMD160(test1, "464243587bd146ea835cdf57bdae582f25ec45f1");
+}
+
+BOOST_AUTO_TEST_CASE(sha1_testvectors) {
+ TestSHA1("", "da39a3ee5e6b4b0d3255bfef95601890afd80709");
+ TestSHA1("abc", "a9993e364706816aba3e25717850c26c9cd0d89d");
+ TestSHA1("message digest", "c12252ceda8be8994d5fa0290a47231c1d16aae3");
+ TestSHA1("secure hash algorithm", "d4d6d2f0ebe317513bbd8d967d89bac5819c2f60");
+ TestSHA1("SHA1 is considered to be safe", "f2b6650569ad3a8720348dd6ea6c497dee3a842a");
+ TestSHA1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ "84983e441c3bd26ebaae4aa1f95129e5e54670f1");
+ TestSHA1("For this sample, this 63-byte string will be used as input data",
+ "4f0ea5cd0585a23d028abdc1a6684e5a8094dc49");
+ TestSHA1("This is exactly 64 bytes long, not counting the terminating byte",
+ "fb679f23e7d1ce053313e66e127ab1b444397057");
+ TestSHA1(std::string(1000000, 'a'), "34aa973cd4c4daa4f61eeb2bdbad27316534016f");
+ TestSHA1(test1, "b7755760681cbfd971451668f32af5774f4656b5");
+}
+
+BOOST_AUTO_TEST_CASE(sha256_testvectors) {
+ TestSHA256("", "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855");
+ TestSHA256("abc", "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad");
+ TestSHA256("message digest",
+ "f7846f55cf23e14eebeab5b4e1550cad5b509e3348fbc4efa3a1413d393cb650");
+ TestSHA256("secure hash algorithm",
+ "f30ceb2bb2829e79e4ca9753d35a8ecc00262d164cc077080295381cbd643f0d");
+ TestSHA256("SHA256 is considered to be safe",
+ "6819d915c73f4d1e77e4e1b52d1fa0f9cf9beaead3939f15874bd988e2a23630");
+ TestSHA256("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1");
+ TestSHA256("For this sample, this 63-byte string will be used as input data",
+ "f08a78cbbaee082b052ae0708f32fa1e50c5c421aa772ba5dbb406a2ea6be342");
+ TestSHA256("This is exactly 64 bytes long, not counting the terminating byte",
+ "ab64eff7e88e2e46165e29f2bce41826bd4c7b3552f6b382a9e7d3af47c245f8");
+ TestSHA256("As Bitcoin relies on 80 byte header hashes, we want to have an example for that.",
+ "7406e8de7d6e4fffc573daef05aefb8806e7790f55eab5576f31349743cca743");
+ TestSHA256(std::string(1000000, 'a'),
+ "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0");
+ TestSHA256(test1, "a316d55510b49662420f49d145d42fb83f31ef8dc016aa4e32df049991a91e26");
+}
+
+BOOST_AUTO_TEST_CASE(sha512_testvectors) {
+ TestSHA512("",
+ "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce"
+ "47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e");
+ TestSHA512("abc",
+ "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a"
+ "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f");
+ TestSHA512("message digest",
+ "107dbf389d9e9f71a3a95f6c055b9251bc5268c2be16d6c13492ea45b0199f33"
+ "09e16455ab1e96118e8a905d5597b72038ddb372a89826046de66687bb420e7c");
+ TestSHA512("secure hash algorithm",
+ "7746d91f3de30c68cec0dd693120a7e8b04d8073cb699bdce1a3f64127bca7a3"
+ "d5db502e814bb63c063a7a5043b2df87c61133395f4ad1edca7fcf4b30c3236e");
+ TestSHA512("SHA512 is considered to be safe",
+ "099e6468d889e1c79092a89ae925a9499b5408e01b66cb5b0a3bd0dfa51a9964"
+ "6b4a3901caab1318189f74cd8cf2e941829012f2449df52067d3dd5b978456c2");
+ TestSHA512("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ "204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c335"
+ "96fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445");
+ TestSHA512("For this sample, this 63-byte string will be used as input data",
+ "b3de4afbc516d2478fe9b518d063bda6c8dd65fc38402dd81d1eb7364e72fb6e"
+ "6663cf6d2771c8f5a6da09601712fb3d2a36c6ffea3e28b0818b05b0a8660766");
+ TestSHA512("This is exactly 64 bytes long, not counting the terminating byte",
+ "70aefeaa0e7ac4f8fe17532d7185a289bee3b428d950c14fa8b713ca09814a38"
+ "7d245870e007a80ad97c369d193e41701aa07f3221d15f0e65a1ff970cedf030");
+ TestSHA512("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmno"
+ "ijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
+ "8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018"
+ "501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909");
+ TestSHA512(std::string(1000000, 'a'),
+ "e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973eb"
+ "de0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b");
+ TestSHA512(test1,
+ "40cac46c147e6131c5193dd5f34e9d8bb4951395f27b08c558c65ff4ba2de594"
+ "37de8c3ef5459d76a52cedc02dc499a3c9ed9dedbfb3281afd9653b8a112fafc");
+}
+
+BOOST_AUTO_TEST_CASE(hmac_sha256_testvectors) {
+ // test cases 1, 2, 3, 4, 6 and 7 of RFC 4231
+ TestHMACSHA256("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b",
+ "4869205468657265",
+ "b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7");
+ TestHMACSHA256("4a656665",
+ "7768617420646f2079612077616e7420666f72206e6f7468696e673f",
+ "5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843");
+ TestHMACSHA256("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"
+ "dddddddddddddddddddddddddddddddddddd",
+ "773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe");
+ TestHMACSHA256("0102030405060708090a0b0c0d0e0f10111213141516171819",
+ "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"
+ "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b");
+ TestHMACSHA256("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaa",
+ "54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a"
+ "65204b6579202d2048617368204b6579204669727374",
+ "60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f0ee37f54");
+ TestHMACSHA256("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaa",
+ "5468697320697320612074657374207573696e672061206c6172676572207468"
+ "616e20626c6f636b2d73697a65206b657920616e642061206c61726765722074"
+ "68616e20626c6f636b2d73697a6520646174612e20546865206b6579206e6565"
+ "647320746f20626520686173686564206265666f7265206265696e6720757365"
+ "642062792074686520484d414320616c676f726974686d2e",
+ "9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f51535c3a35e2");
+}
+
+BOOST_AUTO_TEST_CASE(hmac_sha512_testvectors) {
+ // test cases 1, 2, 3, 4, 6 and 7 of RFC 4231
+ TestHMACSHA512("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b",
+ "4869205468657265",
+ "87aa7cdea5ef619d4ff0b4241a1d6cb02379f4e2ce4ec2787ad0b30545e17cde"
+ "daa833b7d6b8a702038b274eaea3f4e4be9d914eeb61f1702e696c203a126854");
+ TestHMACSHA512("4a656665",
+ "7768617420646f2079612077616e7420666f72206e6f7468696e673f",
+ "164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7ea250554"
+ "9758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b636e070a38bce737");
+ TestHMACSHA512("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"
+ "dddddddddddddddddddddddddddddddddddd",
+ "fa73b0089d56a284efb0f0756c890be9b1b5dbdd8ee81a3655f83e33b2279d39"
+ "bf3e848279a722c806b485a47e67c807b946a337bee8942674278859e13292fb");
+ TestHMACSHA512("0102030405060708090a0b0c0d0e0f10111213141516171819",
+ "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"
+ "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "b0ba465637458c6990e5a8c5f61d4af7e576d97ff94b872de76f8050361ee3db"
+ "a91ca5c11aa25eb4d679275cc5788063a5f19741120c4f2de2adebeb10a298dd");
+ TestHMACSHA512("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaa",
+ "54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a"
+ "65204b6579202d2048617368204b6579204669727374",
+ "80b24263c7c1a3ebb71493c1dd7be8b49b46d1f41b4aeec1121b013783f8f352"
+ "6b56d037e05f2598bd0fd2215d6a1e5295e64f73f63f0aec8b915a985d786598");
+ TestHMACSHA512("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaa",
+ "5468697320697320612074657374207573696e672061206c6172676572207468"
+ "616e20626c6f636b2d73697a65206b657920616e642061206c61726765722074"
+ "68616e20626c6f636b2d73697a6520646174612e20546865206b6579206e6565"
+ "647320746f20626520686173686564206265666f7265206265696e6720757365"
+ "642062792074686520484d414320616c676f726974686d2e",
+ "e37b6a775dc87dbaa4dfa9f96e5e3ffddebd71f8867289865df5a32d20cdc944"
+ "b6022cac3c4982b10d5eeb55c3e4de15134676fb6de0446065c97440fa8c6a58");
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/data/README.md b/src/test/data/README.md
new file mode 100644
index 0000000000..2463daa42a
--- /dev/null
+++ b/src/test/data/README.md
@@ -0,0 +1,12 @@
+Description
+------------
+
+This directory contains data-driven tests for various aspects of Bitcoin.
+
+License
+--------
+
+The data files in this directory are distributed under the MIT software
+license, see the accompanying file COPYING or
+http://www.opensource.org/licenses/mit-license.php.
+
diff --git a/src/test/data/alertTests.raw b/src/test/data/alertTests.raw
new file mode 100644
index 0000000000..01f50680b9
--- /dev/null
+++ b/src/test/data/alertTests.raw
Binary files differ
diff --git a/src/test/data/base58_encode_decode.json b/src/test/data/base58_encode_decode.json
new file mode 100644
index 0000000000..9448f256d9
--- /dev/null
+++ b/src/test/data/base58_encode_decode.json
@@ -0,0 +1,14 @@
+[
+["", ""],
+["61", "2g"],
+["626262", "a3gV"],
+["636363", "aPEr"],
+["73696d706c792061206c6f6e6720737472696e67", "2cFupjhnEsSn59qHXstmK2ffpLv2"],
+["00eb15231dfceb60925886b67d065299925915aeb172c06647", "1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L"],
+["516b6fcd0f", "ABnLTmg"],
+["bf4f89001e670274dd", "3SEo3LWLoPntC"],
+["572e4794", "3EFU7m"],
+["ecac89cad93923c02321", "EJDM8drfXA6uyA"],
+["10c8511e", "Rt5zm"],
+["00000000000000000000", "1111111111"]
+]
diff --git a/src/test/data/base58_keys_invalid.json b/src/test/data/base58_keys_invalid.json
new file mode 100644
index 0000000000..a088620f1b
--- /dev/null
+++ b/src/test/data/base58_keys_invalid.json
@@ -0,0 +1,152 @@
+[
+ [
+ ""
+ ],
+ [
+ "x"
+ ],
+ [
+ "37qgekLpCCHrQuSjvX3fs496FWTGsHFHizjJAs6NPcR47aefnnCWECAhHV6E3g4YN7u7Yuwod5Y"
+ ],
+ [
+ "dzb7VV1Ui55BARxv7ATxAtCUeJsANKovDGWFVgpTbhq9gvPqP3yv"
+ ],
+ [
+ "MuNu7ZAEDFiHthiunm7dPjwKqrVNCM3mAz6rP9zFveQu14YA8CxExSJTHcVP9DErn6u84E6Ej7S"
+ ],
+ [
+ "rPpQpYknyNQ5AEHuY6H8ijJJrYc2nDKKk9jjmKEXsWzyAQcFGpDLU2Zvsmoi8JLR7hAwoy3RQWf"
+ ],
+ [
+ "4Uc3FmN6NQ6zLBK5QQBXRBUREaaHwCZYsGCueHauuDmJpZKn6jkEskMB2Zi2CNgtb5r6epWEFfUJq"
+ ],
+ [
+ "7aQgR5DFQ25vyXmqZAWmnVCjL3PkBcdVkBUpjrjMTcghHx3E8wb"
+ ],
+ [
+ "17QpPprjeg69fW1DV8DcYYCKvWjYhXvWkov6MJ1iTTvMFj6weAqW7wybZeH57WTNxXVCRH4veVs"
+ ],
+ [
+ "KxuACDviz8Xvpn1xAh9MfopySZNuyajYMZWz16Dv2mHHryznWUp3"
+ ],
+ [
+ "7nK3GSmqdXJQtdohvGfJ7KsSmn3TmGqExug49583bDAL91pVSGq5xS9SHoAYL3Wv3ijKTit65th"
+ ],
+ [
+ "cTivdBmq7bay3RFGEBBuNfMh2P1pDCgRYN2Wbxmgwr4ki3jNUL2va"
+ ],
+ [
+ "gjMV4vjNjyMrna4fsAr8bWxAbwtmMUBXJS3zL4NJt5qjozpbQLmAfK1uA3CquSqsZQMpoD1g2nk"
+ ],
+ [
+ "emXm1naBMoVzPjbk7xpeTVMFy4oDEe25UmoyGgKEB1gGWsK8kRGs"
+ ],
+ [
+ "7VThQnNRj1o3Zyvc7XHPRrjDf8j2oivPTeDXnRPYWeYGE4pXeRJDZgf28ppti5hsHWXS2GSobdqyo"
+ ],
+ [
+ "1G9u6oCVCPh2o8m3t55ACiYvG1y5BHewUkDSdiQarDcYXXhFHYdzMdYfUAhfxn5vNZBwpgUNpso"
+ ],
+ [
+ "31QQ7ZMLkScDiB4VyZjuptr7AEc9j1SjstF7pRoLhHTGkW4Q2y9XELobQmhhWxeRvqcukGd1XCq"
+ ],
+ [
+ "DHqKSnpxa8ZdQyH8keAhvLTrfkyBMQxqngcQA5N8LQ9KVt25kmGN"
+ ],
+ [
+ "2LUHcJPbwLCy9GLH1qXmfmAwvadWw4bp4PCpDfduLqV17s6iDcy1imUwhQJhAoNoN1XNmweiJP4i"
+ ],
+ [
+ "7USRzBXAnmck8fX9HmW7RAb4qt92VFX6soCnts9s74wxm4gguVhtG5of8fZGbNPJA83irHVY6bCos"
+ ],
+ [
+ "1DGezo7BfVebZxAbNT3XGujdeHyNNBF3vnficYoTSp4PfK2QaML9bHzAMxke3wdKdHYWmsMTJVu"
+ ],
+ [
+ "2D12DqDZKwCxxkzs1ZATJWvgJGhQ4cFi3WrizQ5zLAyhN5HxuAJ1yMYaJp8GuYsTLLxTAz6otCfb"
+ ],
+ [
+ "8AFJzuTujXjw1Z6M3fWhQ1ujDW7zsV4ePeVjVo7D1egERqSW9nZ"
+ ],
+ [
+ "163Q17qLbTCue8YY3AvjpUhotuaodLm2uqMhpYirsKjVqnxJRWTEoywMVY3NbBAHuhAJ2cF9GAZ"
+ ],
+ [
+ "2MnmgiRH4eGLyLc9eAqStzk7dFgBjFtUCtu"
+ ],
+ [
+ "461QQ2sYWxU7H2PV4oBwJGNch8XVTYYbZxU"
+ ],
+ [
+ "2UCtv53VttmQYkVU4VMtXB31REvQg4ABzs41AEKZ8UcB7DAfVzdkV9JDErwGwyj5AUHLkmgZeobs"
+ ],
+ [
+ "cSNjAsnhgtiFMi6MtfvgscMB2Cbhn2v1FUYfviJ1CdjfidvmeW6mn"
+ ],
+ [
+ "gmsow2Y6EWAFDFE1CE4Hd3Tpu2BvfmBfG1SXsuRARbnt1WjkZnFh1qGTiptWWbjsq2Q6qvpgJVj"
+ ],
+ [
+ "nksUKSkzS76v8EsSgozXGMoQFiCoCHzCVajFKAXqzK5on9ZJYVHMD5CKwgmX3S3c7M1U3xabUny"
+ ],
+ [
+ "L3favK1UzFGgdzYBF2oBT5tbayCo4vtVBLJhg2iYuMeePxWG8SQc"
+ ],
+ [
+ "7VxLxGGtYT6N99GdEfi6xz56xdQ8nP2dG1CavuXx7Rf2PrvNMTBNevjkfgs9JmkcGm6EXpj8ipyPZ"
+ ],
+ [
+ "2mbZwFXF6cxShaCo2czTRB62WTx9LxhTtpP"
+ ],
+ [
+ "dB7cwYdcPSgiyAwKWL3JwCVwSk6epU2txw"
+ ],
+ [
+ "HPhFUhUAh8ZQQisH8QQWafAxtQYju3SFTX"
+ ],
+ [
+ "4ctAH6AkHzq5ioiM1m9T3E2hiYEev5mTsB"
+ ],
+ [
+ "Hn1uFi4dNexWrqARpjMqgT6cX1UsNPuV3cHdGg9ExyXw8HTKadbktRDtdeVmY3M1BxJStiL4vjJ"
+ ],
+ [
+ "Sq3fDbvutABmnAHHExJDgPLQn44KnNC7UsXuT7KZecpaYDMU9Txs"
+ ],
+ [
+ "6TqWyrqdgUEYDQU1aChMuFMMEimHX44qHFzCUgGfqxGgZNMUVWJ"
+ ],
+ [
+ "giqJo7oWqFxNKWyrgcBxAVHXnjJ1t6cGoEffce5Y1y7u649Noj5wJ4mmiUAKEVVrYAGg2KPB3Y4"
+ ],
+ [
+ "cNzHY5e8vcmM3QVJUcjCyiKMYfeYvyueq5qCMV3kqcySoLyGLYUK"
+ ],
+ [
+ "37uTe568EYc9WLoHEd9jXEvUiWbq5LFLscNyqvAzLU5vBArUJA6eydkLmnMwJDjkL5kXc2VK7ig"
+ ],
+ [
+ "EsYbG4tWWWY45G31nox838qNdzksbPySWc"
+ ],
+ [
+ "nbuzhfwMoNzA3PaFnyLcRxE9bTJPDkjZ6Rf6Y6o2ckXZfzZzXBT"
+ ],
+ [
+ "cQN9PoxZeCWK1x56xnz6QYAsvR11XAce3Ehp3gMUdfSQ53Y2mPzx"
+ ],
+ [
+ "1Gm3N3rkef6iMbx4voBzaxtXcmmiMTqZPhcuAepRzYUJQW4qRpEnHvMojzof42hjFRf8PE2jPde"
+ ],
+ [
+ "2TAq2tuN6x6m233bpT7yqdYQPELdTDJn1eU"
+ ],
+ [
+ "ntEtnnGhqPii4joABvBtSEJG6BxjT2tUZqE8PcVYgk3RHpgxgHDCQxNbLJf7ardf1dDk2oCQ7Cf"
+ ],
+ [
+ "Ky1YjoZNgQ196HJV3HpdkecfhRBmRZdMJk89Hi5KGfpfPwS2bUbfd"
+ ],
+ [
+ "2A1q1YsMZowabbvta7kTy2Fd6qN4r5ZCeG3qLpvZBMzCixMUdkN2Y4dHB1wPsZAeVXUGD83MfRED"
+ ]
+]
diff --git a/src/test/data/base58_keys_valid.json b/src/test/data/base58_keys_valid.json
new file mode 100644
index 0000000000..e1e252e22d
--- /dev/null
+++ b/src/test/data/base58_keys_valid.json
@@ -0,0 +1,452 @@
+[
+ [
+ "1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i",
+ "65a16059864a2fdbc7c99a4723a8395bc6f188eb",
+ {
+ "addrType": "pubkey",
+ "isPrivkey": false,
+ "isTestnet": false
+ }
+ ],
+ [
+ "3CMNFxN1oHBc4R1EpboAL5yzHGgE611Xou",
+ "74f209f6ea907e2ea48f74fae05782ae8a665257",
+ {
+ "addrType": "script",
+ "isPrivkey": false,
+ "isTestnet": false
+ }
+ ],
+ [
+ "mo9ncXisMeAoXwqcV5EWuyncbmCcQN4rVs",
+ "53c0307d6851aa0ce7825ba883c6bd9ad242b486",
+ {
+ "addrType": "pubkey",
+ "isPrivkey": false,
+ "isTestnet": true
+ }
+ ],
+ [
+ "2N2JD6wb56AfK4tfmM6PwdVmoYk2dCKf4Br",
+ "6349a418fc4578d10a372b54b45c280cc8c4382f",
+ {
+ "addrType": "script",
+ "isPrivkey": false,
+ "isTestnet": true
+ }
+ ],
+ [
+ "5Kd3NBUAdUnhyzenEwVLy9pBKxSwXvE9FMPyR4UKZvpe6E3AgLr",
+ "eddbdc1168f1daeadbd3e44c1e3f8f5a284c2029f78ad26af98583a499de5b19",
+ {
+ "isCompressed": false,
+ "isPrivkey": true,
+ "isTestnet": false
+ }
+ ],
+ [
+ "Kz6UJmQACJmLtaQj5A3JAge4kVTNQ8gbvXuwbmCj7bsaabudb3RD",
+ "55c9bccb9ed68446d1b75273bbce89d7fe013a8acd1625514420fb2aca1a21c4",
+ {
+ "isCompressed": true,
+ "isPrivkey": true,
+ "isTestnet": false
+ }
+ ],
+ [
+ "9213qJab2HNEpMpYNBa7wHGFKKbkDn24jpANDs2huN3yi4J11ko",
+ "36cb93b9ab1bdabf7fb9f2c04f1b9cc879933530ae7842398eef5a63a56800c2",
+ {
+ "isCompressed": false,
+ "isPrivkey": true,
+ "isTestnet": true
+ }
+ ],
+ [
+ "cTpB4YiyKiBcPxnefsDpbnDxFDffjqJob8wGCEDXxgQ7zQoMXJdH",
+ "b9f4892c9e8282028fea1d2667c4dc5213564d41fc5783896a0d843fc15089f3",
+ {
+ "isCompressed": true,
+ "isPrivkey": true,
+ "isTestnet": true
+ }
+ ],
+ [
+ "1Ax4gZtb7gAit2TivwejZHYtNNLT18PUXJ",
+ "6d23156cbbdcc82a5a47eee4c2c7c583c18b6bf4",
+ {
+ "addrType": "pubkey",
+ "isPrivkey": false,
+ "isTestnet": false
+ }
+ ],
+ [
+ "3QjYXhTkvuj8qPaXHTTWb5wjXhdsLAAWVy",
+ "fcc5460dd6e2487c7d75b1963625da0e8f4c5975",
+ {
+ "addrType": "script",
+ "isPrivkey": false,
+ "isTestnet": false
+ }
+ ],
+ [
+ "n3ZddxzLvAY9o7184TB4c6FJasAybsw4HZ",
+ "f1d470f9b02370fdec2e6b708b08ac431bf7a5f7",
+ {
+ "addrType": "pubkey",
+ "isPrivkey": false,
+ "isTestnet": true
+ }
+ ],
+ [
+ "2NBFNJTktNa7GZusGbDbGKRZTxdK9VVez3n",
+ "c579342c2c4c9220205e2cdc285617040c924a0a",
+ {
+ "addrType": "script",
+ "isPrivkey": false,
+ "isTestnet": true
+ }
+ ],
+ [
+ "5K494XZwps2bGyeL71pWid4noiSNA2cfCibrvRWqcHSptoFn7rc",
+ "a326b95ebae30164217d7a7f57d72ab2b54e3be64928a19da0210b9568d4015e",
+ {
+ "isCompressed": false,
+ "isPrivkey": true,
+ "isTestnet": false
+ }
+ ],
+ [
+ "L1RrrnXkcKut5DEMwtDthjwRcTTwED36thyL1DebVrKuwvohjMNi",
+ "7d998b45c219a1e38e99e7cbd312ef67f77a455a9b50c730c27f02c6f730dfb4",
+ {
+ "isCompressed": true,
+ "isPrivkey": true,
+ "isTestnet": false
+ }
+ ],
+ [
+ "93DVKyFYwSN6wEo3E2fCrFPUp17FtrtNi2Lf7n4G3garFb16CRj",
+ "d6bca256b5abc5602ec2e1c121a08b0da2556587430bcf7e1898af2224885203",
+ {
+ "isCompressed": false,
+ "isPrivkey": true,
+ "isTestnet": true
+ }
+ ],
+ [
+ "cTDVKtMGVYWTHCb1AFjmVbEbWjvKpKqKgMaR3QJxToMSQAhmCeTN",
+ "a81ca4e8f90181ec4b61b6a7eb998af17b2cb04de8a03b504b9e34c4c61db7d9",
+ {
+ "isCompressed": true,
+ "isPrivkey": true,
+ "isTestnet": true
+ }
+ ],
+ [
+ "1C5bSj1iEGUgSTbziymG7Cn18ENQuT36vv",
+ "7987ccaa53d02c8873487ef919677cd3db7a6912",
+ {
+ "addrType": "pubkey",
+ "isPrivkey": false,
+ "isTestnet": false
+ }
+ ],
+ [
+ "3AnNxabYGoTxYiTEZwFEnerUoeFXK2Zoks",
+ "63bcc565f9e68ee0189dd5cc67f1b0e5f02f45cb",
+ {
+ "addrType": "script",
+ "isPrivkey": false,
+ "isTestnet": false
+ }
+ ],
+ [
+ "n3LnJXCqbPjghuVs8ph9CYsAe4Sh4j97wk",
+ "ef66444b5b17f14e8fae6e7e19b045a78c54fd79",
+ {
+ "addrType": "pubkey",
+ "isPrivkey": false,
+ "isTestnet": true
+ }
+ ],
+ [
+ "2NB72XtkjpnATMggui83aEtPawyyKvnbX2o",
+ "c3e55fceceaa4391ed2a9677f4a4d34eacd021a0",
+ {
+ "addrType": "script",
+ "isPrivkey": false,
+ "isTestnet": true
+ }
+ ],
+ [
+ "5KaBW9vNtWNhc3ZEDyNCiXLPdVPHCikRxSBWwV9NrpLLa4LsXi9",
+ "e75d936d56377f432f404aabb406601f892fd49da90eb6ac558a733c93b47252",
+ {
+ "isCompressed": false,
+ "isPrivkey": true,
+ "isTestnet": false
+ }
+ ],
+ [
+ "L1axzbSyynNYA8mCAhzxkipKkfHtAXYF4YQnhSKcLV8YXA874fgT",
+ "8248bd0375f2f75d7e274ae544fb920f51784480866b102384190b1addfbaa5c",
+ {
+ "isCompressed": true,
+ "isPrivkey": true,
+ "isTestnet": false
+ }
+ ],
+ [
+ "927CnUkUbasYtDwYwVn2j8GdTuACNnKkjZ1rpZd2yBB1CLcnXpo",
+ "44c4f6a096eac5238291a94cc24c01e3b19b8d8cef72874a079e00a242237a52",
+ {
+ "isCompressed": false,
+ "isPrivkey": true,
+ "isTestnet": true
+ }
+ ],
+ [
+ "cUcfCMRjiQf85YMzzQEk9d1s5A4K7xL5SmBCLrezqXFuTVefyhY7",
+ "d1de707020a9059d6d3abaf85e17967c6555151143db13dbb06db78df0f15c69",
+ {
+ "isCompressed": true,
+ "isPrivkey": true,
+ "isTestnet": true
+ }
+ ],
+ [
+ "1Gqk4Tv79P91Cc1STQtU3s1W6277M2CVWu",
+ "adc1cc2081a27206fae25792f28bbc55b831549d",
+ {
+ "addrType": "pubkey",
+ "isPrivkey": false,
+ "isTestnet": false
+ }
+ ],
+ [
+ "33vt8ViH5jsr115AGkW6cEmEz9MpvJSwDk",
+ "188f91a931947eddd7432d6e614387e32b244709",
+ {
+ "addrType": "script",
+ "isPrivkey": false,
+ "isTestnet": false
+ }
+ ],
+ [
+ "mhaMcBxNh5cqXm4aTQ6EcVbKtfL6LGyK2H",
+ "1694f5bc1a7295b600f40018a618a6ea48eeb498",
+ {
+ "addrType": "pubkey",
+ "isPrivkey": false,
+ "isTestnet": true
+ }
+ ],
+ [
+ "2MxgPqX1iThW3oZVk9KoFcE5M4JpiETssVN",
+ "3b9b3fd7a50d4f08d1a5b0f62f644fa7115ae2f3",
+ {
+ "addrType": "script",
+ "isPrivkey": false,
+ "isTestnet": true
+ }
+ ],
+ [
+ "5HtH6GdcwCJA4ggWEL1B3jzBBUB8HPiBi9SBc5h9i4Wk4PSeApR",
+ "091035445ef105fa1bb125eccfb1882f3fe69592265956ade751fd095033d8d0",
+ {
+ "isCompressed": false,
+ "isPrivkey": true,
+ "isTestnet": false
+ }
+ ],
+ [
+ "L2xSYmMeVo3Zek3ZTsv9xUrXVAmrWxJ8Ua4cw8pkfbQhcEFhkXT8",
+ "ab2b4bcdfc91d34dee0ae2a8c6b6668dadaeb3a88b9859743156f462325187af",
+ {
+ "isCompressed": true,
+ "isPrivkey": true,
+ "isTestnet": false
+ }
+ ],
+ [
+ "92xFEve1Z9N8Z641KQQS7ByCSb8kGjsDzw6fAmjHN1LZGKQXyMq",
+ "b4204389cef18bbe2b353623cbf93e8678fbc92a475b664ae98ed594e6cf0856",
+ {
+ "isCompressed": false,
+ "isPrivkey": true,
+ "isTestnet": true
+ }
+ ],
+ [
+ "cVM65tdYu1YK37tNoAyGoJTR13VBYFva1vg9FLuPAsJijGvG6NEA",
+ "e7b230133f1b5489843260236b06edca25f66adb1be455fbd38d4010d48faeef",
+ {
+ "isCompressed": true,
+ "isPrivkey": true,
+ "isTestnet": true
+ }
+ ],
+ [
+ "1JwMWBVLtiqtscbaRHai4pqHokhFCbtoB4",
+ "c4c1b72491ede1eedaca00618407ee0b772cad0d",
+ {
+ "addrType": "pubkey",
+ "isPrivkey": false,
+ "isTestnet": false
+ }
+ ],
+ [
+ "3QCzvfL4ZRvmJFiWWBVwxfdaNBT8EtxB5y",
+ "f6fe69bcb548a829cce4c57bf6fff8af3a5981f9",
+ {
+ "addrType": "script",
+ "isPrivkey": false,
+ "isTestnet": false
+ }
+ ],
+ [
+ "mizXiucXRCsEriQCHUkCqef9ph9qtPbZZ6",
+ "261f83568a098a8638844bd7aeca039d5f2352c0",
+ {
+ "addrType": "pubkey",
+ "isPrivkey": false,
+ "isTestnet": true
+ }
+ ],
+ [
+ "2NEWDzHWwY5ZZp8CQWbB7ouNMLqCia6YRda",
+ "e930e1834a4d234702773951d627cce82fbb5d2e",
+ {
+ "addrType": "script",
+ "isPrivkey": false,
+ "isTestnet": true
+ }
+ ],
+ [
+ "5KQmDryMNDcisTzRp3zEq9e4awRmJrEVU1j5vFRTKpRNYPqYrMg",
+ "d1fab7ab7385ad26872237f1eb9789aa25cc986bacc695e07ac571d6cdac8bc0",
+ {
+ "isCompressed": false,
+ "isPrivkey": true,
+ "isTestnet": false
+ }
+ ],
+ [
+ "L39Fy7AC2Hhj95gh3Yb2AU5YHh1mQSAHgpNixvm27poizcJyLtUi",
+ "b0bbede33ef254e8376aceb1510253fc3550efd0fcf84dcd0c9998b288f166b3",
+ {
+ "isCompressed": true,
+ "isPrivkey": true,
+ "isTestnet": false
+ }
+ ],
+ [
+ "91cTVUcgydqyZLgaANpf1fvL55FH53QMm4BsnCADVNYuWuqdVys",
+ "037f4192c630f399d9271e26c575269b1d15be553ea1a7217f0cb8513cef41cb",
+ {
+ "isCompressed": false,
+ "isPrivkey": true,
+ "isTestnet": true
+ }
+ ],
+ [
+ "cQspfSzsgLeiJGB2u8vrAiWpCU4MxUT6JseWo2SjXy4Qbzn2fwDw",
+ "6251e205e8ad508bab5596bee086ef16cd4b239e0cc0c5d7c4e6035441e7d5de",
+ {
+ "isCompressed": true,
+ "isPrivkey": true,
+ "isTestnet": true
+ }
+ ],
+ [
+ "19dcawoKcZdQz365WpXWMhX6QCUpR9SY4r",
+ "5eadaf9bb7121f0f192561a5a62f5e5f54210292",
+ {
+ "addrType": "pubkey",
+ "isPrivkey": false,
+ "isTestnet": false
+ }
+ ],
+ [
+ "37Sp6Rv3y4kVd1nQ1JV5pfqXccHNyZm1x3",
+ "3f210e7277c899c3a155cc1c90f4106cbddeec6e",
+ {
+ "addrType": "script",
+ "isPrivkey": false,
+ "isTestnet": false
+ }
+ ],
+ [
+ "myoqcgYiehufrsnnkqdqbp69dddVDMopJu",
+ "c8a3c2a09a298592c3e180f02487cd91ba3400b5",
+ {
+ "addrType": "pubkey",
+ "isPrivkey": false,
+ "isTestnet": true
+ }
+ ],
+ [
+ "2N7FuwuUuoTBrDFdrAZ9KxBmtqMLxce9i1C",
+ "99b31df7c9068d1481b596578ddbb4d3bd90baeb",
+ {
+ "addrType": "script",
+ "isPrivkey": false,
+ "isTestnet": true
+ }
+ ],
+ [
+ "5KL6zEaMtPRXZKo1bbMq7JDjjo1bJuQcsgL33je3oY8uSJCR5b4",
+ "c7666842503db6dc6ea061f092cfb9c388448629a6fe868d068c42a488b478ae",
+ {
+ "isCompressed": false,
+ "isPrivkey": true,
+ "isTestnet": false
+ }
+ ],
+ [
+ "KwV9KAfwbwt51veZWNscRTeZs9CKpojyu1MsPnaKTF5kz69H1UN2",
+ "07f0803fc5399e773555ab1e8939907e9badacc17ca129e67a2f5f2ff84351dd",
+ {
+ "isCompressed": true,
+ "isPrivkey": true,
+ "isTestnet": false
+ }
+ ],
+ [
+ "93N87D6uxSBzwXvpokpzg8FFmfQPmvX4xHoWQe3pLdYpbiwT5YV",
+ "ea577acfb5d1d14d3b7b195c321566f12f87d2b77ea3a53f68df7ebf8604a801",
+ {
+ "isCompressed": false,
+ "isPrivkey": true,
+ "isTestnet": true
+ }
+ ],
+ [
+ "cMxXusSihaX58wpJ3tNuuUcZEQGt6DKJ1wEpxys88FFaQCYjku9h",
+ "0b3b34f0958d8a268193a9814da92c3e8b58b4a4378a542863e34ac289cd830c",
+ {
+ "isCompressed": true,
+ "isPrivkey": true,
+ "isTestnet": true
+ }
+ ],
+ [
+ "13p1ijLwsnrcuyqcTvJXkq2ASdXqcnEBLE",
+ "1ed467017f043e91ed4c44b4e8dd674db211c4e6",
+ {
+ "addrType": "pubkey",
+ "isPrivkey": false,
+ "isTestnet": false
+ }
+ ],
+ [
+ "3ALJH9Y951VCGcVZYAdpA3KchoP9McEj1G",
+ "5ece0cadddc415b1980f001785947120acdb36fc",
+ {
+ "addrType": "script",
+ "isPrivkey": false,
+ "isTestnet": false
+ }
+ ]
+]
diff --git a/src/test/data/bitcoin-util-test.json b/src/test/data/bitcoin-util-test.json
new file mode 100644
index 0000000000..6090421cb6
--- /dev/null
+++ b/src/test/data/bitcoin-util-test.json
@@ -0,0 +1,60 @@
+[
+ { "exec": "././bitcoin-tx",
+ "args": ["-create"],
+ "output_cmp": "blanktx.hex"
+ },
+ { "exec": "./bitcoin-tx",
+ "args": ["-"],
+ "input": "blanktx.hex",
+ "output_cmp": "blanktx.hex"
+ },
+ { "exec": "./bitcoin-tx",
+ "args": ["-", "delin=1"],
+ "input": "tx394b54bb.hex",
+ "output_cmp": "tt-delin1-out.hex"
+ },
+ { "exec": "./bitcoin-tx",
+ "args": ["-", "delin=31"],
+ "input": "tx394b54bb.hex",
+ "return_code": 1
+ },
+ { "exec": "./bitcoin-tx",
+ "args": ["-", "delout=1"],
+ "input": "tx394b54bb.hex",
+ "output_cmp": "tt-delout1-out.hex"
+ },
+ { "exec": "./bitcoin-tx",
+ "args": ["-", "delout=2"],
+ "input": "tx394b54bb.hex",
+ "return_code": 1
+ },
+ { "exec": "./bitcoin-tx",
+ "args": ["-", "locktime=317000"],
+ "input": "tx394b54bb.hex",
+ "output_cmp": "tt-locktime317000-out.hex"
+ },
+ { "exec": "./bitcoin-tx",
+ "args":
+ ["-create",
+ "in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0",
+ "in=bf829c6bcf84579331337659d31f89dfd138f7f7785802d5501c92333145ca7c:18",
+ "in=22a6f904655d53ae2ff70e701a0bbd90aa3975c0f40bfc6cc996a9049e31cdfc:1",
+ "outaddr=0.18:13tuJJDR2RgArmgfv6JScSdreahzgc4T6o",
+ "outaddr=4:1P8yWvZW8jVihP1bzHeqfE4aoXNX8AVa46"],
+ "output_cmp": "txcreate1.hex"
+ },
+ { "exec": "./bitcoin-tx",
+ "args": ["-create", "outscript=0:"],
+ "output_cmp": "txcreate2.hex"
+ },
+ { "exec": "./bitcoin-tx",
+ "args":
+ ["-create",
+ "in=4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485:0",
+ "set=privatekeys:[\"5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAnchuDf\"]",
+ "set=prevtxs:[{\"txid\":\"4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485\",\"vout\":0,\"scriptPubKey\":\"4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485\"}]",
+ "sign=ALL",
+ "outaddr=0.001:193P6LtvS4nCnkDvM9uXn1gsSRqh4aDAz7"],
+ "output_cmp": "txcreatesign.hex"
+ }
+]
diff --git a/src/test/data/blanktx.hex b/src/test/data/blanktx.hex
new file mode 100644
index 0000000000..36b6f00fb6
--- /dev/null
+++ b/src/test/data/blanktx.hex
@@ -0,0 +1 @@
+01000000000000000000
diff --git a/src/test/data/script_invalid.json b/src/test/data/script_invalid.json
new file mode 100644
index 0000000000..7afa2abf49
--- /dev/null
+++ b/src/test/data/script_invalid.json
@@ -0,0 +1,814 @@
+[
+["Format is: [scriptSig, scriptPubKey, flags, ... comments]"],
+["It is evaluated as if there was a crediting coinbase transaction with two 0"],
+["pushes as scriptSig, and one output of 0 satoshi and given scriptPubKey,"],
+["followed by a spending transaction which spends this output as only input (and"],
+["correct prevout hash), using the given scriptSig. All nLockTimes are 0, all"],
+["nSequences are max."],
+
+["", "DEPTH", "P2SH,STRICTENC", "Test the test: we should have an empty stack after scriptSig evaluation"],
+[" ", "DEPTH", "P2SH,STRICTENC", "and multiple spaces should not change that."],
+[" ", "DEPTH", "P2SH,STRICTENC"],
+[" ", "DEPTH", "P2SH,STRICTENC"],
+
+["", "", "P2SH,STRICTENC"],
+["", "NOP", "P2SH,STRICTENC"],
+["", "NOP DEPTH", "P2SH,STRICTENC"],
+["NOP", "", "P2SH,STRICTENC"],
+["NOP", "DEPTH", "P2SH,STRICTENC"],
+["NOP","NOP", "P2SH,STRICTENC"],
+["NOP","NOP DEPTH", "P2SH,STRICTENC"],
+
+["DEPTH", "", "P2SH,STRICTENC"],
+
+["0x4c01","0x01 NOP", "P2SH,STRICTENC", "PUSHDATA1 with not enough bytes"],
+["0x4d0200ff","0x01 NOP", "P2SH,STRICTENC", "PUSHDATA2 with not enough bytes"],
+["0x4e03000000ffff","0x01 NOP", "P2SH,STRICTENC", "PUSHDATA4 with not enough bytes"],
+
+["1", "IF 0x50 ENDIF 1", "P2SH,STRICTENC", "0x50 is reserved"],
+["0x52", "0x5f ADD 0x60 EQUAL", "P2SH,STRICTENC", "0x51 through 0x60 push 1 through 16 onto stack"],
+["0","NOP", "P2SH,STRICTENC"],
+["1", "IF VER ELSE 1 ENDIF", "P2SH,STRICTENC", "VER non-functional"],
+["0", "IF VERIF ELSE 1 ENDIF", "P2SH,STRICTENC", "VERIF illegal everywhere"],
+["0", "IF ELSE 1 ELSE VERIF ENDIF", "P2SH,STRICTENC", "VERIF illegal everywhere"],
+["0", "IF VERNOTIF ELSE 1 ENDIF", "P2SH,STRICTENC", "VERNOTIF illegal everywhere"],
+["0", "IF ELSE 1 ELSE VERNOTIF ENDIF", "P2SH,STRICTENC", "VERNOTIF illegal everywhere"],
+
+["1 IF", "1 ENDIF", "P2SH,STRICTENC", "IF/ENDIF can't span scriptSig/scriptPubKey"],
+["1 IF 0 ENDIF", "1 ENDIF", "P2SH,STRICTENC"],
+["1 ELSE 0 ENDIF", "1", "P2SH,STRICTENC"],
+["0 NOTIF", "123", "P2SH,STRICTENC"],
+
+["0", "DUP IF ENDIF", "P2SH,STRICTENC"],
+["0", "IF 1 ENDIF", "P2SH,STRICTENC"],
+["0", "DUP IF ELSE ENDIF", "P2SH,STRICTENC"],
+["0", "IF 1 ELSE ENDIF", "P2SH,STRICTENC"],
+["0", "NOTIF ELSE 1 ENDIF", "P2SH,STRICTENC"],
+
+["0 1", "IF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC"],
+["0 0", "IF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC"],
+["1 0", "IF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC"],
+["0 1", "IF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC"],
+
+["0 0", "NOTIF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC"],
+["0 1", "NOTIF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC"],
+["1 1", "NOTIF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC"],
+["0 0", "NOTIF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC"],
+
+["1", "IF RETURN ELSE ELSE 1 ENDIF", "P2SH,STRICTENC", "Multiple ELSEs"],
+["1", "IF 1 ELSE ELSE RETURN ENDIF", "P2SH,STRICTENC"],
+
+["1", "ENDIF", "P2SH,STRICTENC", "Malformed IF/ELSE/ENDIF sequence"],
+["1", "ELSE ENDIF", "P2SH,STRICTENC"],
+["1", "ENDIF ELSE", "P2SH,STRICTENC"],
+["1", "ENDIF ELSE IF", "P2SH,STRICTENC"],
+["1", "IF ELSE ENDIF ELSE", "P2SH,STRICTENC"],
+["1", "IF ELSE ENDIF ELSE ENDIF", "P2SH,STRICTENC"],
+["1", "IF ENDIF ENDIF", "P2SH,STRICTENC"],
+["1", "IF ELSE ELSE ENDIF ENDIF", "P2SH,STRICTENC"],
+
+["1", "RETURN", "P2SH,STRICTENC"],
+["1", "DUP IF RETURN ENDIF", "P2SH,STRICTENC"],
+
+["1", "RETURN 'data'", "P2SH,STRICTENC", "canonical prunable txout format"],
+["0 IF", "RETURN ENDIF 1", "P2SH,STRICTENC", "still prunable because IF/ENDIF can't span scriptSig/scriptPubKey"],
+
+["0", "VERIFY 1", "P2SH,STRICTENC"],
+["1", "VERIFY", "P2SH,STRICTENC"],
+["1", "VERIFY 0", "P2SH,STRICTENC"],
+
+["1 TOALTSTACK", "FROMALTSTACK 1", "P2SH,STRICTENC", "alt stack not shared between sig/pubkey"],
+
+["IFDUP", "DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+["DROP", "DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+["DUP", "DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+["1", "DUP 1 ADD 2 EQUALVERIFY 0 EQUAL", "P2SH,STRICTENC"],
+["NOP", "NIP", "P2SH,STRICTENC"],
+["NOP", "1 NIP", "P2SH,STRICTENC"],
+["NOP", "1 0 NIP", "P2SH,STRICTENC"],
+["NOP", "OVER 1", "P2SH,STRICTENC"],
+["1", "OVER", "P2SH,STRICTENC"],
+["0 1", "OVER DEPTH 3 EQUALVERIFY", "P2SH,STRICTENC"],
+["19 20 21", "PICK 19 EQUALVERIFY DEPTH 2 EQUAL", "P2SH,STRICTENC"],
+["NOP", "0 PICK", "P2SH,STRICTENC"],
+["1", "-1 PICK", "P2SH,STRICTENC"],
+["19 20 21", "0 PICK 20 EQUALVERIFY DEPTH 3 EQUAL", "P2SH,STRICTENC"],
+["19 20 21", "1 PICK 21 EQUALVERIFY DEPTH 3 EQUAL", "P2SH,STRICTENC"],
+["19 20 21", "2 PICK 22 EQUALVERIFY DEPTH 3 EQUAL", "P2SH,STRICTENC"],
+["NOP", "0 ROLL", "P2SH,STRICTENC"],
+["1", "-1 ROLL", "P2SH,STRICTENC"],
+["19 20 21", "0 ROLL 20 EQUALVERIFY DEPTH 2 EQUAL", "P2SH,STRICTENC"],
+["19 20 21", "1 ROLL 21 EQUALVERIFY DEPTH 2 EQUAL", "P2SH,STRICTENC"],
+["19 20 21", "2 ROLL 22 EQUALVERIFY DEPTH 2 EQUAL", "P2SH,STRICTENC"],
+["NOP", "ROT 1", "P2SH,STRICTENC"],
+["NOP", "1 ROT 1", "P2SH,STRICTENC"],
+["NOP", "1 2 ROT 1", "P2SH,STRICTENC"],
+["NOP", "0 1 2 ROT", "P2SH,STRICTENC"],
+["NOP", "SWAP 1", "P2SH,STRICTENC"],
+["1", "SWAP 1", "P2SH,STRICTENC"],
+["0 1", "SWAP 1 EQUALVERIFY", "P2SH,STRICTENC"],
+["NOP", "TUCK 1", "P2SH,STRICTENC"],
+["1", "TUCK 1", "P2SH,STRICTENC"],
+["1 0", "TUCK DEPTH 3 EQUALVERIFY SWAP 2DROP", "P2SH,STRICTENC"],
+["NOP", "2DUP 1", "P2SH,STRICTENC"],
+["1", "2DUP 1", "P2SH,STRICTENC"],
+["NOP", "3DUP 1", "P2SH,STRICTENC"],
+["1", "3DUP 1", "P2SH,STRICTENC"],
+["1 2", "3DUP 1", "P2SH,STRICTENC"],
+["NOP", "2OVER 1", "P2SH,STRICTENC"],
+["1", "2 3 2OVER 1", "P2SH,STRICTENC"],
+["NOP", "2SWAP 1", "P2SH,STRICTENC"],
+["1", "2 3 2SWAP 1", "P2SH,STRICTENC"],
+
+["'a' 'b'", "CAT", "P2SH,STRICTENC", "CAT disabled"],
+["'a' 'b' 0", "IF CAT ELSE 1 ENDIF", "P2SH,STRICTENC", "CAT disabled"],
+["'abc' 1 1", "SUBSTR", "P2SH,STRICTENC", "SUBSTR disabled"],
+["'abc' 1 1 0", "IF SUBSTR ELSE 1 ENDIF", "P2SH,STRICTENC", "SUBSTR disabled"],
+["'abc' 2 0", "IF LEFT ELSE 1 ENDIF", "P2SH,STRICTENC", "LEFT disabled"],
+["'abc' 2 0", "IF RIGHT ELSE 1 ENDIF", "P2SH,STRICTENC", "RIGHT disabled"],
+
+["NOP", "SIZE 1", "P2SH,STRICTENC"],
+
+["'abc'", "IF INVERT ELSE 1 ENDIF", "P2SH,STRICTENC", "INVERT disabled"],
+["1 2 0 IF AND ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "AND disabled"],
+["1 2 0 IF OR ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "OR disabled"],
+["1 2 0 IF XOR ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "XOR disabled"],
+["2 0 IF 2MUL ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "2MUL disabled"],
+["2 0 IF 2DIV ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "2DIV disabled"],
+["2 2 0 IF MUL ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "MUL disabled"],
+["2 2 0 IF DIV ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "DIV disabled"],
+["2 2 0 IF MOD ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "MOD disabled"],
+["2 2 0 IF LSHIFT ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "LSHIFT disabled"],
+["2 2 0 IF RSHIFT ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "RSHIFT disabled"],
+
+["", "EQUAL NOT", "P2SH,STRICTENC", "EQUAL must error when there are no stack items"],
+["0", "EQUAL NOT", "P2SH,STRICTENC", "EQUAL must error when there are not 2 stack items"],
+["0 1","EQUAL", "P2SH,STRICTENC"],
+["1 1 ADD", "0 EQUAL", "P2SH,STRICTENC"],
+["11 1 ADD 12 SUB", "11 EQUAL", "P2SH,STRICTENC"],
+
+["2147483648 0 ADD", "NOP", "P2SH,STRICTENC", "arithmetic operands must be in range [-2^31...2^31] "],
+["-2147483648 0 ADD", "NOP", "P2SH,STRICTENC", "arithmetic operands must be in range [-2^31...2^31] "],
+["2147483647 DUP ADD", "4294967294 NUMEQUAL", "P2SH,STRICTENC", "NUMEQUAL must be in numeric range"],
+["'abcdef' NOT", "0 EQUAL", "P2SH,STRICTENC", "NOT is an arithmetic operand"],
+
+["2 DUP MUL", "4 EQUAL", "P2SH,STRICTENC", "disabled"],
+["2 DUP DIV", "1 EQUAL", "P2SH,STRICTENC", "disabled"],
+["2 2MUL", "4 EQUAL", "P2SH,STRICTENC", "disabled"],
+["2 2DIV", "1 EQUAL", "P2SH,STRICTENC", "disabled"],
+["7 3 MOD", "1 EQUAL", "P2SH,STRICTENC", "disabled"],
+["2 2 LSHIFT", "8 EQUAL", "P2SH,STRICTENC", "disabled"],
+["2 1 RSHIFT", "1 EQUAL", "P2SH,STRICTENC", "disabled"],
+
+["1","NOP1 NOP2 NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 2 EQUAL", "P2SH,STRICTENC"],
+["'NOP_1_to_10' NOP1 NOP2 NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_11' EQUAL", "P2SH,STRICTENC"],
+
+["Ensure 100% coverage of discouraged NOPS"],
+["1", "NOP1", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"],
+["1", "NOP2", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"],
+["1", "NOP3", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"],
+["1", "NOP4", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"],
+["1", "NOP5", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"],
+["1", "NOP6", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"],
+["1", "NOP7", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"],
+["1", "NOP8", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"],
+["1", "NOP9", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"],
+["1", "NOP10", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"],
+
+["NOP10", "1", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "Discouraged NOP10 in scriptSig"],
+
+["1 0x01 0xb9", "HASH160 0x14 0x15727299b05b45fdaf9ac9ecf7565cfe27c3e567 EQUAL",
+ "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "Discouraged NOP10 in redeemScript"],
+
+["0x50","1", "P2SH,STRICTENC", "opcode 0x50 is reserved"],
+["1", "IF 0xba ELSE 1 ENDIF", "P2SH,STRICTENC", "opcodes above NOP10 invalid if executed"],
+["1", "IF 0xbb ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xbc ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xbd ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xbe ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xbf ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xc0 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xc1 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xc2 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xc3 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xc4 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xc5 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xc6 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xc7 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xc8 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xc9 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xca ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xcb ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xcc ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xcd ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xce ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xcf ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xd0 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xd1 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xd2 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xd3 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xd4 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xd5 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xd6 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xd7 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xd8 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xd9 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xda ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xdb ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xdc ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xdd ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xde ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xdf ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xe0 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xe1 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xe2 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xe3 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xe4 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xe5 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xe6 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xe7 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xe8 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xe9 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xea ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xeb ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xec ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xed ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xee ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xef ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xf0 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xf1 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xf2 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xf3 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xf4 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xf5 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xf6 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xf7 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xf8 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xf9 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xfa ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xfb ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xfc ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xfd ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xfe ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 0xff ELSE 1 ENDIF", "P2SH,STRICTENC"],
+
+["1 IF 1 ELSE", "0xff ENDIF", "P2SH,STRICTENC", "invalid because scriptSig and scriptPubKey are processed separately"],
+
+["NOP", "RIPEMD160", "P2SH,STRICTENC"],
+["NOP", "SHA1", "P2SH,STRICTENC"],
+["NOP", "SHA256", "P2SH,STRICTENC"],
+["NOP", "HASH160", "P2SH,STRICTENC"],
+["NOP", "HASH256", "P2SH,STRICTENC"],
+
+["NOP",
+"'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'",
+"P2SH,STRICTENC",
+">520 byte push"],
+["0",
+"IF 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' ENDIF 1",
+"P2SH,STRICTENC",
+">520 byte push in non-executed IF branch"],
+["1",
+"0x61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161",
+"P2SH,STRICTENC",
+">201 opcodes executed. 0x61 is NOP"],
+["0",
+"IF 0x6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 ENDIF 1",
+"P2SH,STRICTENC",
+">201 opcodes including non-executed IF branch. 0x61 is NOP"],
+["1 2 3 4 5 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f",
+"1 2 3 4 5 6 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f",
+"P2SH,STRICTENC",
+">1,000 stack size (0x6f is 3DUP)"],
+["1 2 3 4 5 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f",
+"1 TOALTSTACK 2 TOALTSTACK 3 4 5 6 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f",
+"P2SH,STRICTENC",
+">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",
+"P2SH,STRICTENC",
+"10,001-byte scriptPubKey"],
+
+["NOP1","NOP10", "P2SH,STRICTENC"],
+
+["1","VER", "P2SH,STRICTENC", "OP_VER is reserved"],
+["1","VERIF", "P2SH,STRICTENC", "OP_VERIF is reserved"],
+["1","VERNOTIF", "P2SH,STRICTENC", "OP_VERNOTIF is reserved"],
+["1","RESERVED", "P2SH,STRICTENC", "OP_RESERVED is reserved"],
+["1","RESERVED1", "P2SH,STRICTENC", "OP_RESERVED1 is reserved"],
+["1","RESERVED2", "P2SH,STRICTENC", "OP_RESERVED2 is reserved"],
+["1","0xba", "P2SH,STRICTENC", "0xba == OP_NOP10 + 1"],
+
+["2147483648", "1ADD 1", "P2SH,STRICTENC", "We cannot do math on 5-byte integers"],
+["2147483648", "NEGATE 1", "P2SH,STRICTENC", "We cannot do math on 5-byte integers"],
+["-2147483648", "1ADD 1", "P2SH,STRICTENC", "Because we use a sign bit, -2147483648 is also 5 bytes"],
+["2147483647", "1ADD 1SUB 1", "P2SH,STRICTENC", "We cannot do math on 5-byte integers, even if the result is 4-bytes"],
+["2147483648", "1SUB 1", "P2SH,STRICTENC", "We cannot do math on 5-byte integers, even if the result is 4-bytes"],
+
+["2147483648 1", "BOOLOR 1", "P2SH,STRICTENC", "We cannot do BOOLOR on 5-byte integers (but we can still do IF etc)"],
+["2147483648 1", "BOOLAND 1", "P2SH,STRICTENC", "We cannot do BOOLAND on 5-byte integers"],
+
+["1", "1 ENDIF", "P2SH,STRICTENC", "ENDIF without IF"],
+["1", "IF 1", "P2SH,STRICTENC", "IF without ENDIF"],
+["1 IF 1", "ENDIF", "P2SH,STRICTENC", "IFs don't carry over"],
+
+["NOP", "IF 1 ENDIF", "P2SH,STRICTENC", "The following tests check the if(stack.size() < N) tests in each opcode"],
+["NOP", "NOTIF 1 ENDIF", "P2SH,STRICTENC", "They are here to catch copy-and-paste errors"],
+["NOP", "VERIFY 1", "P2SH,STRICTENC", "Most of them are duplicated elsewhere,"],
+
+["NOP", "TOALTSTACK 1", "P2SH,STRICTENC", "but, hey, more is always better, right?"],
+["1", "FROMALTSTACK", "P2SH,STRICTENC"],
+["1", "2DROP 1", "P2SH,STRICTENC"],
+["1", "2DUP", "P2SH,STRICTENC"],
+["1 1", "3DUP", "P2SH,STRICTENC"],
+["1 1 1", "2OVER", "P2SH,STRICTENC"],
+["1 1 1 1 1", "2ROT", "P2SH,STRICTENC"],
+["1 1 1", "2SWAP", "P2SH,STRICTENC"],
+["NOP", "IFDUP 1", "P2SH,STRICTENC"],
+["NOP", "DROP 1", "P2SH,STRICTENC"],
+["NOP", "DUP 1", "P2SH,STRICTENC"],
+["1", "NIP", "P2SH,STRICTENC"],
+["1", "OVER", "P2SH,STRICTENC"],
+["1 1 1 3", "PICK", "P2SH,STRICTENC"],
+["0", "PICK 1", "P2SH,STRICTENC"],
+["1 1 1 3", "ROLL", "P2SH,STRICTENC"],
+["0", "ROLL 1", "P2SH,STRICTENC"],
+["1 1", "ROT", "P2SH,STRICTENC"],
+["1", "SWAP", "P2SH,STRICTENC"],
+["1", "TUCK", "P2SH,STRICTENC"],
+
+["NOP", "SIZE 1", "P2SH,STRICTENC"],
+
+["1", "EQUAL 1", "P2SH,STRICTENC"],
+["1", "EQUALVERIFY 1", "P2SH,STRICTENC"],
+
+["NOP", "1ADD 1", "P2SH,STRICTENC"],
+["NOP", "1SUB 1", "P2SH,STRICTENC"],
+["NOP", "NEGATE 1", "P2SH,STRICTENC"],
+["NOP", "ABS 1", "P2SH,STRICTENC"],
+["NOP", "NOT 1", "P2SH,STRICTENC"],
+["NOP", "0NOTEQUAL 1", "P2SH,STRICTENC"],
+
+["1", "ADD", "P2SH,STRICTENC"],
+["1", "SUB", "P2SH,STRICTENC"],
+["1", "BOOLAND", "P2SH,STRICTENC"],
+["1", "BOOLOR", "P2SH,STRICTENC"],
+["1", "NUMEQUAL", "P2SH,STRICTENC"],
+["1", "NUMEQUALVERIFY 1", "P2SH,STRICTENC"],
+["1", "NUMNOTEQUAL", "P2SH,STRICTENC"],
+["1", "LESSTHAN", "P2SH,STRICTENC"],
+["1", "GREATERTHAN", "P2SH,STRICTENC"],
+["1", "LESSTHANOREQUAL", "P2SH,STRICTENC"],
+["1", "GREATERTHANOREQUAL", "P2SH,STRICTENC"],
+["1", "MIN", "P2SH,STRICTENC"],
+["1", "MAX", "P2SH,STRICTENC"],
+["1 1", "WITHIN", "P2SH,STRICTENC"],
+
+["NOP", "RIPEMD160 1", "P2SH,STRICTENC"],
+["NOP", "SHA1 1", "P2SH,STRICTENC"],
+["NOP", "SHA256 1", "P2SH,STRICTENC"],
+["NOP", "HASH160 1", "P2SH,STRICTENC"],
+["NOP", "HASH256 1", "P2SH,STRICTENC"],
+
+["Increase CHECKSIG and CHECKMULTISIG negative test coverage"],
+["", "CHECKSIG NOT", "STRICTENC", "CHECKSIG must error when there are no stack items"],
+["0", "CHECKSIG NOT", "STRICTENC", "CHECKSIG must error when there are not 2 stack items"],
+["", "CHECKMULTISIG NOT", "STRICTENC", "CHECKMULTISIG must error when there are no stack items"],
+["", "-1 CHECKMULTISIG NOT", "STRICTENC", "CHECKMULTISIG must error when the specified number of pubkeys is negative"],
+["", "1 CHECKMULTISIG NOT", "STRICTENC", "CHECKMULTISIG must error when there are not enough pubkeys on the stack"],
+["", "-1 0 CHECKMULTISIG NOT", "STRICTENC", "CHECKMULTISIG must error when the specified number of signatures is negative"],
+["", "1 'pk1' 1 CHECKMULTISIG NOT", "STRICTENC", "CHECKMULTISIG must error when there are not enough signatures on the stack"],
+["", "'dummy' 'sig1' 1 'pk1' 1 CHECKMULTISIG IF 1 ENDIF", "", "CHECKMULTISIG must push false to stack when signature is invalid when NOT in strict enc mode"],
+
+["",
+"0 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG",
+"P2SH,STRICTENC",
+"202 CHECKMULTISIGS, fails due to 201 op limit"],
+
+["1",
+"0 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY 0 0 CHECKMULTISIGVERIFY",
+"P2SH,STRICTENC"],
+
+["",
+"NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG",
+"P2SH,STRICTENC",
+"Fails due to 201 sig op limit"],
+
+["1",
+"NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY",
+"P2SH,STRICTENC"],
+
+
+["0 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21", "21 CHECKMULTISIG 1", "P2SH,STRICTENC", "nPubKeys > 20"],
+["0 'sig' 1 0", "CHECKMULTISIG 1", "P2SH,STRICTENC", "nSigs > nPubKeys"],
+
+
+["NOP 0x01 1", "HASH160 0x14 0xda1745e9b549bd0bfa1a569971c77eba30cd5a4b EQUAL", "P2SH,STRICTENC", "Tests for Script.IsPushOnly()"],
+["NOP1 0x01 1", "HASH160 0x14 0xda1745e9b549bd0bfa1a569971c77eba30cd5a4b EQUAL", "P2SH,STRICTENC"],
+
+["0 0x01 0x50", "HASH160 0x14 0xece424a6bb6ddf4db592c0faed60685047a361b1 EQUAL", "P2SH,STRICTENC", "OP_RESERVED in P2SH should fail"],
+["0 0x01 VER", "HASH160 0x14 0x0f4d7845db968f2a81b530b6f3c1d6246d4c7e01 EQUAL", "P2SH,STRICTENC", "OP_VER in P2SH should fail"],
+
+["0x00", "'00' EQUAL", "P2SH,STRICTENC", "Basic OP_0 execution"],
+
+["MINIMALDATA enforcement for PUSHDATAs"],
+
+["0x4c 0x00", "DROP 1", "MINIMALDATA", "Empty vector minimally represented by OP_0"],
+["0x01 0x81", "DROP 1", "MINIMALDATA", "-1 minimally represented by OP_1NEGATE"],
+["0x01 0x01", "DROP 1", "MINIMALDATA", "1 to 16 minimally represented by OP_1 to OP_16"],
+["0x01 0x02", "DROP 1", "MINIMALDATA"],
+["0x01 0x03", "DROP 1", "MINIMALDATA"],
+["0x01 0x04", "DROP 1", "MINIMALDATA"],
+["0x01 0x05", "DROP 1", "MINIMALDATA"],
+["0x01 0x06", "DROP 1", "MINIMALDATA"],
+["0x01 0x07", "DROP 1", "MINIMALDATA"],
+["0x01 0x08", "DROP 1", "MINIMALDATA"],
+["0x01 0x09", "DROP 1", "MINIMALDATA"],
+["0x01 0x0a", "DROP 1", "MINIMALDATA"],
+["0x01 0x0b", "DROP 1", "MINIMALDATA"],
+["0x01 0x0c", "DROP 1", "MINIMALDATA"],
+["0x01 0x0d", "DROP 1", "MINIMALDATA"],
+["0x01 0x0e", "DROP 1", "MINIMALDATA"],
+["0x01 0x0f", "DROP 1", "MINIMALDATA"],
+["0x01 0x10", "DROP 1", "MINIMALDATA"],
+
+["0x4c 0x48 0x111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", "DROP 1", "MINIMALDATA",
+ "PUSHDATA1 of 72 bytes minimally represented by direct push"],
+
+["0x4d 0xFF00 0x111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", "DROP 1", "MINIMALDATA",
+ "PUSHDATA2 of 255 bytes minimally represented by PUSHDATA1"],
+
+["0x4e 0x00010000 0x11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", "DROP 1", "MINIMALDATA",
+ "PUSHDATA4 of 256 bytes minimally represented by PUSHDATA2"],
+
+
+["MINIMALDATA enforcement for numeric arguments"],
+
+["0x01 0x00", "NOT DROP 1", "MINIMALDATA", "numequals 0"],
+["0x02 0x0000", "NOT DROP 1", "MINIMALDATA", "numequals 0"],
+["0x01 0x80", "NOT DROP 1", "MINIMALDATA", "0x80 (negative zero) numequals 0"],
+["0x02 0x0080", "NOT DROP 1", "MINIMALDATA", "numequals 0"],
+["0x02 0x0500", "NOT DROP 1", "MINIMALDATA", "numequals 5"],
+["0x03 0x050000", "NOT DROP 1", "MINIMALDATA", "numequals 5"],
+["0x02 0x0580", "NOT DROP 1", "MINIMALDATA", "numequals -5"],
+["0x03 0x050080", "NOT DROP 1", "MINIMALDATA", "numequals -5"],
+["0x03 0xff7f80", "NOT DROP 1", "MINIMALDATA", "Minimal encoding is 0xffff"],
+["0x03 0xff7f00", "NOT DROP 1", "MINIMALDATA", "Minimal encoding is 0xff7f"],
+["0x04 0xffff7f80", "NOT DROP 1", "MINIMALDATA", "Minimal encoding is 0xffffff"],
+["0x04 0xffff7f00", "NOT DROP 1", "MINIMALDATA", "Minimal encoding is 0xffff7f"],
+
+["Test every numeric-accepting opcode for correct handling of the numeric minimal encoding rule"],
+
+["1 0x02 0x0000", "PICK DROP", "MINIMALDATA"],
+["1 0x02 0x0000", "ROLL DROP 1", "MINIMALDATA"],
+["0x02 0x0000", "1ADD DROP 1", "MINIMALDATA"],
+["0x02 0x0000", "1SUB DROP 1", "MINIMALDATA"],
+["0x02 0x0000", "NEGATE DROP 1", "MINIMALDATA"],
+["0x02 0x0000", "ABS DROP 1", "MINIMALDATA"],
+["0x02 0x0000", "NOT DROP 1", "MINIMALDATA"],
+["0x02 0x0000", "0NOTEQUAL DROP 1", "MINIMALDATA"],
+
+["0 0x02 0x0000", "ADD DROP 1", "MINIMALDATA"],
+["0x02 0x0000 0", "ADD DROP 1", "MINIMALDATA"],
+["0 0x02 0x0000", "SUB DROP 1", "MINIMALDATA"],
+["0x02 0x0000 0", "SUB DROP 1", "MINIMALDATA"],
+["0 0x02 0x0000", "BOOLAND DROP 1", "MINIMALDATA"],
+["0x02 0x0000 0", "BOOLAND DROP 1", "MINIMALDATA"],
+["0 0x02 0x0000", "BOOLOR DROP 1", "MINIMALDATA"],
+["0x02 0x0000 0", "BOOLOR DROP 1", "MINIMALDATA"],
+["0 0x02 0x0000", "NUMEQUAL DROP 1", "MINIMALDATA"],
+["0x02 0x0000 1", "NUMEQUAL DROP 1", "MINIMALDATA"],
+["0 0x02 0x0000", "NUMEQUALVERIFY 1", "MINIMALDATA"],
+["0x02 0x0000 0", "NUMEQUALVERIFY 1", "MINIMALDATA"],
+["0 0x02 0x0000", "NUMNOTEQUAL DROP 1", "MINIMALDATA"],
+["0x02 0x0000 0", "NUMNOTEQUAL DROP 1", "MINIMALDATA"],
+["0 0x02 0x0000", "LESSTHAN DROP 1", "MINIMALDATA"],
+["0x02 0x0000 0", "LESSTHAN DROP 1", "MINIMALDATA"],
+["0 0x02 0x0000", "GREATERTHAN DROP 1", "MINIMALDATA"],
+["0x02 0x0000 0", "GREATERTHAN DROP 1", "MINIMALDATA"],
+["0 0x02 0x0000", "LESSTHANOREQUAL DROP 1", "MINIMALDATA"],
+["0x02 0x0000 0", "LESSTHANOREQUAL DROP 1", "MINIMALDATA"],
+["0 0x02 0x0000", "GREATERTHANOREQUAL DROP 1", "MINIMALDATA"],
+["0x02 0x0000 0", "GREATERTHANOREQUAL DROP 1", "MINIMALDATA"],
+["0 0x02 0x0000", "MIN DROP 1", "MINIMALDATA"],
+["0x02 0x0000 0", "MIN DROP 1", "MINIMALDATA"],
+["0 0x02 0x0000", "MAX DROP 1", "MINIMALDATA"],
+["0x02 0x0000 0", "MAX DROP 1", "MINIMALDATA"],
+
+["0x02 0x0000 0 0", "WITHIN DROP 1", "MINIMALDATA"],
+["0 0x02 0x0000 0", "WITHIN DROP 1", "MINIMALDATA"],
+["0 0 0x02 0x0000", "WITHIN DROP 1", "MINIMALDATA"],
+
+["0 0 0x02 0x0000", "CHECKMULTISIG DROP 1", "MINIMALDATA"],
+["0 0x02 0x0000 0", "CHECKMULTISIG DROP 1", "MINIMALDATA"],
+["0 0x02 0x0000 0 1", "CHECKMULTISIG DROP 1", "MINIMALDATA"],
+["0 0 0x02 0x0000", "CHECKMULTISIGVERIFY 1", "MINIMALDATA"],
+["0 0x02 0x0000 0", "CHECKMULTISIGVERIFY 1", "MINIMALDATA"],
+
+
+["Order of CHECKMULTISIG evaluation tests, inverted by swapping the order of"],
+["pubkeys/signatures so they fail due to the STRICTENC rules on validly encoded"],
+["signatures and pubkeys."],
+[
+ "0 0x47 0x3044022044dc17b0887c161bb67ba9635bf758735bdde503e4b0a0987f587f14a4e1143d022009a215772d49a85dae40d8ca03955af26ad3978a0ff965faa12915e9586249a501 0x47 0x3044022044dc17b0887c161bb67ba9635bf758735bdde503e4b0a0987f587f14a4e1143d022009a215772d49a85dae40d8ca03955af26ad3978a0ff965faa12915e9586249a501",
+ "2 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 0 2 CHECKMULTISIG NOT",
+ "STRICTENC",
+ "2-of-2 CHECKMULTISIG NOT with the first pubkey invalid, and both signatures validly encoded."
+],
+[
+ "0 0x47 0x3044022044dc17b0887c161bb67ba9635bf758735bdde503e4b0a0987f587f14a4e1143d022009a215772d49a85dae40d8ca03955af26ad3978a0ff965faa12915e9586249a501 1",
+ "2 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 2 CHECKMULTISIG NOT",
+ "STRICTENC",
+ "2-of-2 CHECKMULTISIG NOT with both pubkeys valid, but first signature invalid."
+],
+
+["Increase DERSIG test coverage"],
+["0x4a 0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "DERSIG", "Overly long signature is incorrectly encoded for DERSIG"],
+["0x25 0x30220220000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "DERSIG", "Missing S is incorrectly encoded for DERSIG"],
+["0x27 0x3024021077777777777777777777777777777777020a7777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "S with invalid S length is incorrectly encoded for DERSIG"],
+["0x27 0x302403107777777777777777777777777777777702107777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "Non-integer R is incorrectly encoded for DERSIG"],
+["0x27 0x302402107777777777777777777777777777777703107777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "Non-integer S is incorrectly encoded for DERSIG"],
+["0x17 0x3014020002107777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "Zero-length R is incorrectly encoded for DERSIG"],
+["0x17 0x3014021077777777777777777777777777777777020001", "0 CHECKSIG NOT", "DERSIG", "Zero-length S is incorrectly encoded for DERSIG"],
+["0x27 0x302402107777777777777777777777777777777702108777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "Negative S is incorrectly encoded for DERSIG"],
+
+["Automatically generated test cases"],
+[
+ "0x47 0x304402200a5c6163f07b8c3b013c4d1d6dba25e780b39658d79ba37af7057a3b7f15ffa102201fd9b4eaa9943f734928b99a83592c2e7bf342ea2680f6a2bb705167966b742001",
+ "0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG",
+ "",
+ "P2PK, bad sig"
+],
+[
+ "0x47 0x3044022034bb0494b50b8ef130e2185bb220265b9284ef5b4b8a8da4d8415df489c83b5102206259a26d9cc0a125ac26af6153b17c02956855ebe1467412f066e402f5f05d1201 0x21 0x03363d90d446b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640",
+ "DUP HASH160 0x14 0xc0834c0c158f53be706d234c38fd52de7eece656 EQUALVERIFY CHECKSIG",
+ "",
+ "P2PKH, bad pubkey"
+],
+[
+ "0x47 0x304402204710a85181663b32d25c70ec2bbd14adff5ddfff6cb50d09e155ef5f541fc86c0220056b0cc949be9386ecc5f6c2ac0493269031dbb185781db90171b54ac127790201",
+ "0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG",
+ "",
+ "P2PK anyonecanpay marked with normal hashtype"
+],
+[
+ "0x47 0x3044022003fef42ed6c7be8917441218f525a60e2431be978e28b7aca4d7a532cc413ae8022067a1f82c74e8d69291b90d148778405c6257bbcfc2353cc38a3e1f22bf44254601 0x23 0x210279be667ef9dcbbac54a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac",
+ "HASH160 0x14 0x23b0ad3477f2178bc0b3eed26e4e6316f4e83aa1 EQUAL",
+ "P2SH",
+ "P2SH(P2PK), bad redeemscript"
+],
+[
+ "0x47 0x304402204e2eb034be7b089534ac9e798cf6a2c79f38bcb34d1b179efd6f2de0841735db022071461beb056b5a7be1819da6a3e3ce3662831ecc298419ca101eb6887b5dd6a401 0x19 0x76a9147cf9c846cd4882efec4bf07e44ebdad495c94f4b88ac",
+ "HASH160 0x14 0x2df519943d5acc0ef5222091f9dfe3543f489a82 EQUAL",
+ "P2SH",
+ "P2SH(P2PKH), bad sig"
+],
+[
+ "0 0x47 0x3044022051254b9fb476a52d85530792b578f86fea70ec1ffb4393e661bcccb23d8d63d3022076505f94a403c86097841944e044c70c2045ce90e36de51f7e9d3828db98a07501 0x47 0x304402200a358f750934b3feb822f1966bfcd8bbec9eeaa3a8ca941e11ee5960e181fa01022050bf6b5a8e7750f70354ae041cb68a7bade67ec6c3ab19eb359638974410626e01 0",
+ "3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG",
+ "",
+ "3-of-3, 2 sigs"
+],
+[
+ "0 0x47 0x304402205b7d2c2f177ae76cfbbf14d589c113b0b35db753d305d5562dd0b61cbf366cfb02202e56f93c4f08a27f986cd424ffc48a462c3202c4902104d4d0ff98ed28f4bf8001 0 0x4c69 0x52210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179821038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f515082103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff464053ae",
+ "HASH160 0x14 0xc9e4a896d149702d0d1695434feddd52e24ad78d EQUAL",
+ "P2SH",
+ "P2SH(2-of-3), 1 sig"
+],
+[
+ "0x47 0x304402200060558477337b9022e70534f1fea71a318caf836812465a2509931c5e7c4987022078ec32bd50ac9e03a349ba953dfd9fe1c8d2dd8bdb1d38ddca844d3d5c78c11801",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG",
+ "DERSIG",
+ "P2PK with too much R padding"
+],
+[
+ "0x48 0x304502202de8c03fc525285c9c535631019a5f2af7c6454fa9eb392a3756a4917c420edd02210046130bf2baf7cfc065067c8b9e33a066d9c15edcea9feb0ca2d233e3597925b401",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG",
+ "DERSIG",
+ "P2PK with too much S padding"
+],
+[
+ "0x47 0x30440220d7a0417c3f6d1a15094d1cf2a3378ca0503eb8a57630953a9e2987e21ddd0a6502207a6266d686c99090920249991d3d42065b6d43eb70187b219c0db82e4f94d1a201",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG",
+ "DERSIG",
+ "P2PK with too little R padding"
+],
+[
+ "0x47 0x30440220005ece1335e7f757a1a1f476a7fb5bd90964e8a022489f890614a04acfb734c002206c12b8294a6513c7710e8c82d3c23d75cdbfe83200eb7efb495701958501a5d601",
+ "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG NOT",
+ "DERSIG",
+ "P2PK NOT with bad sig with too much R padding"
+],
+[
+ "0x47 0x30440220005ece1335e7f657a1a1f476a7fb5bd90964e8a022489f890614a04acfb734c002206c12b8294a6513c7710e8c82d3c23d75cdbfe83200eb7efb495701958501a5d601",
+ "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG NOT",
+ "",
+ "P2PK NOT with too much R padding but no DERSIG"
+],
+[
+ "0x47 0x30440220005ece1335e7f657a1a1f476a7fb5bd90964e8a022489f890614a04acfb734c002206c12b8294a6513c7710e8c82d3c23d75cdbfe83200eb7efb495701958501a5d601",
+ "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG NOT",
+ "DERSIG",
+ "P2PK NOT with too much R padding"
+],
+[
+ "0x47 0x30440220d7a0417c3f6d1a15094d1cf2a3378ca0503eb8a57630953a9e2987e21ddd0a6502207a6266d686c99090920249991d3d42065b6d43eb70187b219c0db82e4f94d1a201",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG",
+ "DERSIG",
+ "BIP66 example 1, with DERSIG"
+],
+[
+ "0x47 0x304402208e43c0b91f7c1e5bc58e41c8185f8a6086e111b0090187968a86f2822462d3c902200a58f4076b1133b18ff1dc83ee51676e44c60cc608d9534e0df5ace0424fc0be01",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT",
+ "",
+ "BIP66 example 2, without DERSIG"
+],
+[
+ "0x47 0x304402208e43c0b91f7c1e5bc58e41c8185f8a6086e111b0090187968a86f2822462d3c902200a58f4076b1133b18ff1dc83ee51676e44c60cc608d9534e0df5ace0424fc0be01",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT",
+ "DERSIG",
+ "BIP66 example 2, with DERSIG"
+],
+[
+ "0",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG",
+ "",
+ "BIP66 example 3, without DERSIG"
+],
+[
+ "0",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG",
+ "DERSIG",
+ "BIP66 example 3, with DERSIG"
+],
+[
+ "1",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG",
+ "",
+ "BIP66 example 5, without DERSIG"
+],
+[
+ "1",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG",
+ "DERSIG",
+ "BIP66 example 5, with DERSIG"
+],
+[
+ "1",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT",
+ "DERSIG",
+ "BIP66 example 6, with DERSIG"
+],
+[
+ "0 0x47 0x30440220cae00b1444babfbf6071b0ba8707f6bd373da3df494d6e74119b0430c5db810502205d5231b8c5939c8ff0c82242656d6e06edb073d42af336c99fe8837c36ea39d501 0x47 0x3044022027c2714269ca5aeecc4d70edc88ba5ee0e3da4986e9216028f489ab4f1b8efce022022bd545b4951215267e4c5ceabd4c5350331b2e4a0b6494c56f361fa5a57a1a201",
+ "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG",
+ "DERSIG",
+ "BIP66 example 7, with DERSIG"
+],
+[
+ "0 0x47 0x30440220b119d67d389315308d1745f734a51ff3ec72e06081e84e236fdf9dc2f5d2a64802204b04e3bc38674c4422ea317231d642b56dc09d214a1ecbbf16ecca01ed996e2201 0x47 0x3044022079ea80afd538d9ada421b5101febeb6bc874e01dde5bca108c1d0479aec339a4022004576db8f66130d1df686ccf00935703689d69cf539438da1edab208b0d63c4801",
+ "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT",
+ "",
+ "BIP66 example 8, without DERSIG"
+],
+[
+ "0 0x47 0x30440220b119d67d389315308d1745f734a51ff3ec72e06081e84e236fdf9dc2f5d2a64802204b04e3bc38674c4422ea317231d642b56dc09d214a1ecbbf16ecca01ed996e2201 0x47 0x3044022079ea80afd538d9ada421b5101febeb6bc874e01dde5bca108c1d0479aec339a4022004576db8f66130d1df686ccf00935703689d69cf539438da1edab208b0d63c4801",
+ "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT",
+ "DERSIG",
+ "BIP66 example 8, with DERSIG"
+],
+[
+ "0 0 0x47 0x3044022081aa9d436f2154e8b6d600516db03d78de71df685b585a9807ead4210bd883490220534bb6bdf318a419ac0749660b60e78d17d515558ef369bf872eff405b676b2e01",
+ "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG",
+ "",
+ "BIP66 example 9, without DERSIG"
+],
+[
+ "0 0 0x47 0x3044022081aa9d436f2154e8b6d600516db03d78de71df685b585a9807ead4210bd883490220534bb6bdf318a419ac0749660b60e78d17d515558ef369bf872eff405b676b2e01",
+ "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG",
+ "DERSIG",
+ "BIP66 example 9, with DERSIG"
+],
+[
+ "0 0 0x47 0x30440220da6f441dc3b4b2c84cfa8db0cd5b34ed92c9e01686de5a800d40498b70c0dcac02207c2cf91b0c32b860c4cd4994be36cfb84caf8bb7c3a8e4d96a31b2022c5299c501",
+ "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT",
+ "DERSIG",
+ "BIP66 example 10, with DERSIG"
+],
+[
+ "0 0x47 0x30440220cae00b1444babfbf6071b0ba8707f6bd373da3df494d6e74119b0430c5db810502205d5231b8c5939c8ff0c82242656d6e06edb073d42af336c99fe8837c36ea39d501 0",
+ "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG",
+ "",
+ "BIP66 example 11, without DERSIG"
+],
+[
+ "0 0x47 0x30440220cae00b1444babfbf6071b0ba8707f6bd373da3df494d6e74119b0430c5db810502205d5231b8c5939c8ff0c82242656d6e06edb073d42af336c99fe8837c36ea39d501 0",
+ "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG",
+ "DERSIG",
+ "BIP66 example 11, with DERSIG"
+],
+[
+ "0x48 0x304402203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022054e1c258c2981cdfba5df1f46661fb6541c44f77ca0092f3600331abfffb12510101",
+ "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG",
+ "DERSIG",
+ "P2PK with multi-byte hashtype, with DERSIG"
+],
+[
+ "0x48 0x304502203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022100ab1e3da73d67e32045a20e0b999e049978ea8d6ee5480d485fcf2ce0d03b2ef001",
+ "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG",
+ "LOW_S",
+ "P2PK with high S"
+],
+[
+ "0x47 0x3044022057292e2d4dfe775becdd0a9e6547997c728cdf35390f6a017da56d654d374e4902206b643be2fc53763b4e284845bfea2c597d2dc7759941dce937636c9d341b71ed01",
+ "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG",
+ "STRICTENC",
+ "P2PK with hybrid pubkey"
+],
+[
+ "0x47 0x30440220035d554e3153c14950c9993f41c496607a8e24093db0595be7bf875cf64fcf1f02204731c8c4e5daf15e706cec19cdd8f2c5b1d05490e11dab8465ed426569b6e92101",
+ "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG NOT",
+ "",
+ "P2PK NOT with hybrid pubkey but no STRICTENC"
+],
+[
+ "0x47 0x30440220035d554e3153c14950c9993f41c496607a8e24093db0595be7bf875cf64fcf1f02204731c8c4e5daf15e706cec19cdd8f2c5b1d05490e11dab8465ed426569b6e92101",
+ "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG NOT",
+ "STRICTENC",
+ "P2PK NOT with hybrid pubkey"
+],
+[
+ "0x47 0x30440220035d554e3153c04950c9993f41c496607a8e24093db0595be7bf875cf64fcf1f02204731c8c4e5daf15e706cec19cdd8f2c5b1d05490e11dab8465ed426569b6e92101",
+ "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG NOT",
+ "STRICTENC",
+ "P2PK NOT with invalid hybrid pubkey"
+],
+[
+ "0 0x47 0x3044022079c7824d6c868e0e1a273484e28c2654a27d043c8a27f49f52cb72efed0759090220452bbbf7089574fa082095a4fc1b3a16bafcf97a3a34d745fafc922cce66b27201",
+ "1 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 2 CHECKMULTISIG",
+ "STRICTENC",
+ "1-of-2 with the first 1 hybrid pubkey"
+],
+[
+ "0x47 0x304402206177d513ec2cda444c021a1f4f656fc4c72ba108ae063e157eb86dc3575784940220666fc66702815d0e5413bb9b1df22aed44f5f1efb8b99d41dd5dc9a5be6d205205",
+ "0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG",
+ "STRICTENC",
+ "P2PK with undefined hashtype"
+],
+[
+ "0x47 0x304402207409b5b320296e5e2136a7b281a7f803028ca4ca44e2b83eebd46932677725de02202d4eea1c8d3c98e6f42614f54764e6e5e6542e213eb4d079737e9a8b6e9812ec05",
+ "0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG NOT",
+ "STRICTENC",
+ "P2PK NOT with invalid sig and undefined hashtype"
+],
+[
+ "1 0x47 0x3044022051254b9fb476a52d85530792b578f86fea70ec1ffb4393e661bcccb23d8d63d3022076505f94a403c86097841944e044c70c2045ce90e36de51f7e9d3828db98a07501 0x47 0x304402200a358f750934b3feb822f1966bfcd8bbec9eeaa3a8ca941e11ee5960e181fa01022050bf6b5a8e7750f70354ae041cb68a7bade67ec6c3ab19eb359638974410626e01 0x47 0x304402200955d031fff71d8653221e85e36c3c85533d2312fc3045314b19650b7ae2f81002202a6bb8505e36201909d0921f01abff390ae6b7ff97bbf959f98aedeb0a56730901",
+ "3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG",
+ "NULLDUMMY",
+ "3-of-3 with nonzero dummy"
+],
+[
+ "1 0x47 0x304402201bb2edab700a5d020236df174fefed78087697143731f659bea59642c759c16d022061f42cdbae5bcd3e8790f20bf76687443436e94a634321c16a72aa54cbc7c2ea01 0x47 0x304402204bb4a64f2a6e5c7fb2f07fef85ee56fde5e6da234c6a984262307a20e99842d702206f8303aaba5e625d223897e2ffd3f88ef1bcffef55f38dc3768e5f2e94c923f901 0x47 0x3044022040c2809b71fffb155ec8b82fe7a27f666bd97f941207be4e14ade85a1249dd4d02204d56c85ec525dd18e29a0533d5ddf61b6b1bb32980c2f63edf951aebf7a27bfe01",
+ "3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG NOT",
+ "NULLDUMMY",
+ "3-of-3 NOT with invalid sig with nonzero dummy"
+],
+[
+ "0 0x47 0x304402200abeb4bd07f84222f474aed558cfbdfc0b4e96cde3c2935ba7098b1ff0bd74c302204a04c1ca67b2a20abee210cf9a21023edccbbf8024b988812634233115c6b73901 DUP",
+ "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 2 CHECKMULTISIG",
+ "SIGPUSHONLY",
+ "2-of-2 with two identical keys and sigs pushed using OP_DUP"
+],
+[
+ "0x47 0x304402203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022054e1c258c2981cdfba5df1f46661fb6541c44f77ca0092f3600331abfffb125101 0x23 0x2103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640ac",
+ "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG",
+ "",
+ "P2SH(P2PK) with non-push scriptSig but no SIGPUSHONLY"
+],
+[
+ "0x47 0x304402203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022054e1c258c2981cdfba5df1f46661fb6541c44f77ca0092f3600331abfffb125101 0x23 0x2103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640ac",
+ "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG",
+ "SIGPUSHONLY",
+ "P2SH(P2PK) with non-push scriptSig"
+],
+[
+ "0 0x47 0x304402205451ce65ad844dbb978b8bdedf5082e33b43cae8279c30f2c74d9e9ee49a94f802203fe95a7ccf74da7a232ee523ef4a53cb4d14bdd16289680cdb97a63819b8f42f01 0x46 0x304402205451ce65ad844dbb978b8bdedf5082e33b43cae8279c30f2c74d9e9ee49a94f802203fe95a7ccf74da7a232ee523ef4a53cb4d14bdd16289680cdb97a63819b8f42f",
+ "2 0x21 0x02a673638cb9587cb68ea08dbef685c6f2d2a751a8b3c6f2a7e9a4999e6e4bfaf5 0x21 0x02a673638cb9587cb68ea08dbef685c6f2d2a751a8b3c6f2a7e9a4999e6e4bfaf5 0x21 0x02a673638cb9587cb68ea08dbef685c6f2d2a751a8b3c6f2a7e9a4999e6e4bfaf5 3 CHECKMULTISIG",
+ "P2SH,STRICTENC",
+ "2-of-3 with one valid and one invalid signature due to parse error, nSigs > validSigs"
+],
+[
+ "11 0x47 0x304402200a5c6163f07b8d3b013c4d1d6dba25e780b39658d79ba37af7057a3b7f15ffa102201fd9b4eaa9943f734928b99a83592c2e7bf342ea2680f6a2bb705167966b742001",
+ "0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG",
+ "CLEANSTACK,P2SH",
+ "P2PK with unnecessary input"
+],
+[
+ "11 0x47 0x304402202f7505132be14872581f35d74b759212d9da40482653f1ffa3116c3294a4a51702206adbf347a2240ca41c66522b1a22a41693610b76a8e7770645dc721d1635854f01 0x43 0x410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac",
+ "HASH160 0x14 0x31edc23bdafda4639e669f89ad6b2318dd79d032 EQUAL",
+ "CLEANSTACK,P2SH",
+ "P2SH with unnecessary input"
+],
+
+["The End"]
+]
diff --git a/src/test/data/script_valid.json b/src/test/data/script_valid.json
new file mode 100644
index 0000000000..a4e15faeaf
--- /dev/null
+++ b/src/test/data/script_valid.json
@@ -0,0 +1,911 @@
+[
+["Format is: [scriptSig, scriptPubKey, flags, ... comments]"],
+["It is evaluated as if there was a crediting coinbase transaction with two 0"],
+["pushes as scriptSig, and one output of 0 satoshi and given scriptPubKey,"],
+["followed by a spending transaction which spends this output as only input (and"],
+["correct prevout hash), using the given scriptSig. All nLockTimes are 0, all"],
+["nSequences are max."],
+
+["", "DEPTH 0 EQUAL", "P2SH,STRICTENC", "Test the test: we should have an empty stack after scriptSig evaluation"],
+[" ", "DEPTH 0 EQUAL", "P2SH,STRICTENC", "and multiple spaces should not change that."],
+[" ", "DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+[" ", "DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+["1 2", "2 EQUALVERIFY 1 EQUAL", "P2SH,STRICTENC", "Similarly whitespace around and between symbols"],
+["1 2", "2 EQUALVERIFY 1 EQUAL", "P2SH,STRICTENC"],
+[" 1 2", "2 EQUALVERIFY 1 EQUAL", "P2SH,STRICTENC"],
+["1 2 ", "2 EQUALVERIFY 1 EQUAL", "P2SH,STRICTENC"],
+[" 1 2 ", "2 EQUALVERIFY 1 EQUAL", "P2SH,STRICTENC"],
+
+["1", "", "P2SH,STRICTENC"],
+["0x02 0x01 0x00", "", "P2SH,STRICTENC", "all bytes are significant, not only the last one"],
+["0x09 0x00000000 0x00000000 0x10", "", "P2SH,STRICTENC", "equals zero when cast to Int64"],
+
+["0x01 0x0b", "11 EQUAL", "P2SH,STRICTENC", "push 1 byte"],
+["0x02 0x417a", "'Az' EQUAL", "P2SH,STRICTENC"],
+["0x4b 0x417a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a",
+ "'Azzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz' EQUAL", "P2SH,STRICTENC", "push 75 bytes"],
+
+["0x4c 0x01 0x07","7 EQUAL", "P2SH,STRICTENC", "0x4c is OP_PUSHDATA1"],
+["0x4d 0x0100 0x08","8 EQUAL", "P2SH,STRICTENC", "0x4d is OP_PUSHDATA2"],
+["0x4e 0x01000000 0x09","9 EQUAL", "P2SH,STRICTENC", "0x4e is OP_PUSHDATA4"],
+
+["0x4c 0x00","0 EQUAL", "P2SH,STRICTENC"],
+["0x4d 0x0000","0 EQUAL", "P2SH,STRICTENC"],
+["0x4e 0x00000000","0 EQUAL", "P2SH,STRICTENC"],
+["0x4f 1000 ADD","999 EQUAL", "P2SH,STRICTENC"],
+["0", "IF 0x50 ENDIF 1", "P2SH,STRICTENC", "0x50 is reserved (ok if not executed)"],
+["0x51", "0x5f ADD 0x60 EQUAL", "P2SH,STRICTENC", "0x51 through 0x60 push 1 through 16 onto stack"],
+["1","NOP", "P2SH,STRICTENC"],
+["0", "IF VER ELSE 1 ENDIF", "P2SH,STRICTENC", "VER non-functional (ok if not executed)"],
+["0", "IF RESERVED RESERVED1 RESERVED2 ELSE 1 ENDIF", "P2SH,STRICTENC", "RESERVED ok in un-executed IF"],
+
+["1", "DUP IF ENDIF", "P2SH,STRICTENC"],
+["1", "IF 1 ENDIF", "P2SH,STRICTENC"],
+["1", "DUP IF ELSE ENDIF", "P2SH,STRICTENC"],
+["1", "IF 1 ELSE ENDIF", "P2SH,STRICTENC"],
+["0", "IF ELSE 1 ENDIF", "P2SH,STRICTENC"],
+
+["1 1", "IF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC"],
+["1 0", "IF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC"],
+["1 1", "IF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC"],
+["0 0", "IF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC"],
+
+["1 0", "NOTIF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC"],
+["1 1", "NOTIF IF 1 ELSE 0 ENDIF ENDIF", "P2SH,STRICTENC"],
+["1 0", "NOTIF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC"],
+["0 1", "NOTIF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF", "P2SH,STRICTENC"],
+
+["0", "IF 0 ELSE 1 ELSE 0 ENDIF", "P2SH,STRICTENC", "Multiple ELSE's are valid and executed inverts on each ELSE encountered"],
+["1", "IF 1 ELSE 0 ELSE ENDIF", "P2SH,STRICTENC"],
+["1", "IF ELSE 0 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["1", "IF 1 ELSE 0 ELSE 1 ENDIF ADD 2 EQUAL", "P2SH,STRICTENC"],
+["'' 1", "IF SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ENDIF 0x14 0x68ca4fec736264c13b859bac43d5173df6871682 EQUAL", "P2SH,STRICTENC"],
+
+["1", "NOTIF 0 ELSE 1 ELSE 0 ENDIF", "P2SH,STRICTENC", "Multiple ELSE's are valid and execution inverts on each ELSE encountered"],
+["0", "NOTIF 1 ELSE 0 ELSE ENDIF", "P2SH,STRICTENC"],
+["0", "NOTIF ELSE 0 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "NOTIF 1 ELSE 0 ELSE 1 ENDIF ADD 2 EQUAL", "P2SH,STRICTENC"],
+["'' 0", "NOTIF SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ENDIF 0x14 0x68ca4fec736264c13b859bac43d5173df6871682 EQUAL", "P2SH,STRICTENC"],
+
+["0", "IF 1 IF RETURN ELSE RETURN ELSE RETURN ENDIF ELSE 1 IF 1 ELSE RETURN ELSE 1 ENDIF ELSE RETURN ENDIF ADD 2 EQUAL", "P2SH,STRICTENC", "Nested ELSE ELSE"],
+["1", "NOTIF 0 NOTIF RETURN ELSE RETURN ELSE RETURN ENDIF ELSE 0 NOTIF 1 ELSE RETURN ELSE 1 ENDIF ELSE RETURN ENDIF ADD 2 EQUAL", "P2SH,STRICTENC"],
+
+["0", "IF RETURN ENDIF 1", "P2SH,STRICTENC", "RETURN only works if executed"],
+
+["1 1", "VERIFY", "P2SH,STRICTENC"],
+["1 0x05 0x01 0x00 0x00 0x00 0x00", "VERIFY", "P2SH,STRICTENC", "values >4 bytes can be cast to boolean"],
+["1 0x01 0x80", "IF 0 ENDIF", "P2SH,STRICTENC", "negative 0 is false"],
+
+["10 0 11 TOALTSTACK DROP FROMALTSTACK", "ADD 21 EQUAL", "P2SH,STRICTENC"],
+["'gavin_was_here' TOALTSTACK 11 FROMALTSTACK", "'gavin_was_here' EQUALVERIFY 11 EQUAL", "P2SH,STRICTENC"],
+
+["0 IFDUP", "DEPTH 1 EQUALVERIFY 0 EQUAL", "P2SH,STRICTENC"],
+["1 IFDUP", "DEPTH 2 EQUALVERIFY 1 EQUALVERIFY 1 EQUAL", "P2SH,STRICTENC"],
+["0x05 0x0100000000 IFDUP", "DEPTH 2 EQUALVERIFY 0x05 0x0100000000 EQUAL", "P2SH,STRICTENC", "IFDUP dups non ints"],
+["0 DROP", "DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+["0", "DUP 1 ADD 1 EQUALVERIFY 0 EQUAL", "P2SH,STRICTENC"],
+["0 1", "NIP", "P2SH,STRICTENC"],
+["1 0", "OVER DEPTH 3 EQUALVERIFY", "P2SH,STRICTENC"],
+["22 21 20", "0 PICK 20 EQUALVERIFY DEPTH 3 EQUAL", "P2SH,STRICTENC"],
+["22 21 20", "1 PICK 21 EQUALVERIFY DEPTH 3 EQUAL", "P2SH,STRICTENC"],
+["22 21 20", "2 PICK 22 EQUALVERIFY DEPTH 3 EQUAL", "P2SH,STRICTENC"],
+["22 21 20", "0 ROLL 20 EQUALVERIFY DEPTH 2 EQUAL", "P2SH,STRICTENC"],
+["22 21 20", "1 ROLL 21 EQUALVERIFY DEPTH 2 EQUAL", "P2SH,STRICTENC"],
+["22 21 20", "2 ROLL 22 EQUALVERIFY DEPTH 2 EQUAL", "P2SH,STRICTENC"],
+["22 21 20", "ROT 22 EQUAL", "P2SH,STRICTENC"],
+["22 21 20", "ROT DROP 20 EQUAL", "P2SH,STRICTENC"],
+["22 21 20", "ROT DROP DROP 21 EQUAL", "P2SH,STRICTENC"],
+["22 21 20", "ROT ROT 21 EQUAL", "P2SH,STRICTENC"],
+["22 21 20", "ROT ROT ROT 20 EQUAL", "P2SH,STRICTENC"],
+["25 24 23 22 21 20", "2ROT 24 EQUAL", "P2SH,STRICTENC"],
+["25 24 23 22 21 20", "2ROT DROP 25 EQUAL", "P2SH,STRICTENC"],
+["25 24 23 22 21 20", "2ROT 2DROP 20 EQUAL", "P2SH,STRICTENC"],
+["25 24 23 22 21 20", "2ROT 2DROP DROP 21 EQUAL", "P2SH,STRICTENC"],
+["25 24 23 22 21 20", "2ROT 2DROP 2DROP 22 EQUAL", "P2SH,STRICTENC"],
+["25 24 23 22 21 20", "2ROT 2DROP 2DROP DROP 23 EQUAL", "P2SH,STRICTENC"],
+["25 24 23 22 21 20", "2ROT 2ROT 22 EQUAL", "P2SH,STRICTENC"],
+["25 24 23 22 21 20", "2ROT 2ROT 2ROT 20 EQUAL", "P2SH,STRICTENC"],
+["1 0", "SWAP 1 EQUALVERIFY 0 EQUAL", "P2SH,STRICTENC"],
+["0 1", "TUCK DEPTH 3 EQUALVERIFY SWAP 2DROP", "P2SH,STRICTENC"],
+["13 14", "2DUP ROT EQUALVERIFY EQUAL", "P2SH,STRICTENC"],
+["-1 0 1 2", "3DUP DEPTH 7 EQUALVERIFY ADD ADD 3 EQUALVERIFY 2DROP 0 EQUALVERIFY", "P2SH,STRICTENC"],
+["1 2 3 5", "2OVER ADD ADD 8 EQUALVERIFY ADD ADD 6 EQUAL", "P2SH,STRICTENC"],
+["1 3 5 7", "2SWAP ADD 4 EQUALVERIFY ADD 12 EQUAL", "P2SH,STRICTENC"],
+["0", "SIZE 0 EQUAL", "P2SH,STRICTENC"],
+["1", "SIZE 1 EQUAL", "P2SH,STRICTENC"],
+["127", "SIZE 1 EQUAL", "P2SH,STRICTENC"],
+["128", "SIZE 2 EQUAL", "P2SH,STRICTENC"],
+["32767", "SIZE 2 EQUAL", "P2SH,STRICTENC"],
+["32768", "SIZE 3 EQUAL", "P2SH,STRICTENC"],
+["8388607", "SIZE 3 EQUAL", "P2SH,STRICTENC"],
+["8388608", "SIZE 4 EQUAL", "P2SH,STRICTENC"],
+["2147483647", "SIZE 4 EQUAL", "P2SH,STRICTENC"],
+["2147483648", "SIZE 5 EQUAL", "P2SH,STRICTENC"],
+["549755813887", "SIZE 5 EQUAL", "P2SH,STRICTENC"],
+["549755813888", "SIZE 6 EQUAL", "P2SH,STRICTENC"],
+["9223372036854775807", "SIZE 8 EQUAL", "P2SH,STRICTENC"],
+["-1", "SIZE 1 EQUAL", "P2SH,STRICTENC"],
+["-127", "SIZE 1 EQUAL", "P2SH,STRICTENC"],
+["-128", "SIZE 2 EQUAL", "P2SH,STRICTENC"],
+["-32767", "SIZE 2 EQUAL", "P2SH,STRICTENC"],
+["-32768", "SIZE 3 EQUAL", "P2SH,STRICTENC"],
+["-8388607", "SIZE 3 EQUAL", "P2SH,STRICTENC"],
+["-8388608", "SIZE 4 EQUAL", "P2SH,STRICTENC"],
+["-2147483647", "SIZE 4 EQUAL", "P2SH,STRICTENC"],
+["-2147483648", "SIZE 5 EQUAL", "P2SH,STRICTENC"],
+["-549755813887", "SIZE 5 EQUAL", "P2SH,STRICTENC"],
+["-549755813888", "SIZE 6 EQUAL", "P2SH,STRICTENC"],
+["-9223372036854775807", "SIZE 8 EQUAL", "P2SH,STRICTENC"],
+["'abcdefghijklmnopqrstuvwxyz'", "SIZE 26 EQUAL", "P2SH,STRICTENC"],
+
+["42", "SIZE 1 EQUALVERIFY 42 EQUAL", "P2SH,STRICTENC", "SIZE does not consume argument"],
+
+["2 -2 ADD", "0 EQUAL", "P2SH,STRICTENC"],
+["2147483647 -2147483647 ADD", "0 EQUAL", "P2SH,STRICTENC"],
+["-1 -1 ADD", "-2 EQUAL", "P2SH,STRICTENC"],
+
+["0 0","EQUAL", "P2SH,STRICTENC"],
+["1 1 ADD", "2 EQUAL", "P2SH,STRICTENC"],
+["1 1ADD", "2 EQUAL", "P2SH,STRICTENC"],
+["111 1SUB", "110 EQUAL", "P2SH,STRICTENC"],
+["111 1 ADD 12 SUB", "100 EQUAL", "P2SH,STRICTENC"],
+["0 ABS", "0 EQUAL", "P2SH,STRICTENC"],
+["16 ABS", "16 EQUAL", "P2SH,STRICTENC"],
+["-16 ABS", "-16 NEGATE EQUAL", "P2SH,STRICTENC"],
+["0 NOT", "NOP", "P2SH,STRICTENC"],
+["1 NOT", "0 EQUAL", "P2SH,STRICTENC"],
+["11 NOT", "0 EQUAL", "P2SH,STRICTENC"],
+["0 0NOTEQUAL", "0 EQUAL", "P2SH,STRICTENC"],
+["1 0NOTEQUAL", "1 EQUAL", "P2SH,STRICTENC"],
+["111 0NOTEQUAL", "1 EQUAL", "P2SH,STRICTENC"],
+["-111 0NOTEQUAL", "1 EQUAL", "P2SH,STRICTENC"],
+["1 1 BOOLAND", "NOP", "P2SH,STRICTENC"],
+["1 0 BOOLAND", "NOT", "P2SH,STRICTENC"],
+["0 1 BOOLAND", "NOT", "P2SH,STRICTENC"],
+["0 0 BOOLAND", "NOT", "P2SH,STRICTENC"],
+["16 17 BOOLAND", "NOP", "P2SH,STRICTENC"],
+["1 1 BOOLOR", "NOP", "P2SH,STRICTENC"],
+["1 0 BOOLOR", "NOP", "P2SH,STRICTENC"],
+["0 1 BOOLOR", "NOP", "P2SH,STRICTENC"],
+["0 0 BOOLOR", "NOT", "P2SH,STRICTENC"],
+["16 17 BOOLOR", "NOP", "P2SH,STRICTENC"],
+["11 10 1 ADD", "NUMEQUAL", "P2SH,STRICTENC"],
+["11 10 1 ADD", "NUMEQUALVERIFY 1", "P2SH,STRICTENC"],
+["11 10 1 ADD", "NUMNOTEQUAL NOT", "P2SH,STRICTENC"],
+["111 10 1 ADD", "NUMNOTEQUAL", "P2SH,STRICTENC"],
+["11 10", "LESSTHAN NOT", "P2SH,STRICTENC"],
+["4 4", "LESSTHAN NOT", "P2SH,STRICTENC"],
+["10 11", "LESSTHAN", "P2SH,STRICTENC"],
+["-11 11", "LESSTHAN", "P2SH,STRICTENC"],
+["-11 -10", "LESSTHAN", "P2SH,STRICTENC"],
+["11 10", "GREATERTHAN", "P2SH,STRICTENC"],
+["4 4", "GREATERTHAN NOT", "P2SH,STRICTENC"],
+["10 11", "GREATERTHAN NOT", "P2SH,STRICTENC"],
+["-11 11", "GREATERTHAN NOT", "P2SH,STRICTENC"],
+["-11 -10", "GREATERTHAN NOT", "P2SH,STRICTENC"],
+["11 10", "LESSTHANOREQUAL NOT", "P2SH,STRICTENC"],
+["4 4", "LESSTHANOREQUAL", "P2SH,STRICTENC"],
+["10 11", "LESSTHANOREQUAL", "P2SH,STRICTENC"],
+["-11 11", "LESSTHANOREQUAL", "P2SH,STRICTENC"],
+["-11 -10", "LESSTHANOREQUAL", "P2SH,STRICTENC"],
+["11 10", "GREATERTHANOREQUAL", "P2SH,STRICTENC"],
+["4 4", "GREATERTHANOREQUAL", "P2SH,STRICTENC"],
+["10 11", "GREATERTHANOREQUAL NOT", "P2SH,STRICTENC"],
+["-11 11", "GREATERTHANOREQUAL NOT", "P2SH,STRICTENC"],
+["-11 -10", "GREATERTHANOREQUAL NOT", "P2SH,STRICTENC"],
+["1 0 MIN", "0 NUMEQUAL", "P2SH,STRICTENC"],
+["0 1 MIN", "0 NUMEQUAL", "P2SH,STRICTENC"],
+["-1 0 MIN", "-1 NUMEQUAL", "P2SH,STRICTENC"],
+["0 -2147483647 MIN", "-2147483647 NUMEQUAL", "P2SH,STRICTENC"],
+["2147483647 0 MAX", "2147483647 NUMEQUAL", "P2SH,STRICTENC"],
+["0 100 MAX", "100 NUMEQUAL", "P2SH,STRICTENC"],
+["-100 0 MAX", "0 NUMEQUAL", "P2SH,STRICTENC"],
+["0 -2147483647 MAX", "0 NUMEQUAL", "P2SH,STRICTENC"],
+["0 0 1", "WITHIN", "P2SH,STRICTENC"],
+["1 0 1", "WITHIN NOT", "P2SH,STRICTENC"],
+["0 -2147483647 2147483647", "WITHIN", "P2SH,STRICTENC"],
+["-1 -100 100", "WITHIN", "P2SH,STRICTENC"],
+["11 -100 100", "WITHIN", "P2SH,STRICTENC"],
+["-2147483647 -100 100", "WITHIN NOT", "P2SH,STRICTENC"],
+["2147483647 -100 100", "WITHIN NOT", "P2SH,STRICTENC"],
+
+["2147483647 2147483647 SUB", "0 EQUAL", "P2SH,STRICTENC"],
+["2147483647 DUP ADD", "4294967294 EQUAL", "P2SH,STRICTENC", ">32 bit EQUAL is valid"],
+["2147483647 NEGATE DUP ADD", "-4294967294 EQUAL", "P2SH,STRICTENC"],
+
+["''", "RIPEMD160 0x14 0x9c1185a5c5e9fc54612808977ee8f548b2258d31 EQUAL", "P2SH,STRICTENC"],
+["'a'", "RIPEMD160 0x14 0x0bdc9d2d256b3ee9daae347be6f4dc835a467ffe EQUAL", "P2SH,STRICTENC"],
+["'abcdefghijklmnopqrstuvwxyz'", "RIPEMD160 0x14 0xf71c27109c692c1b56bbdceb5b9d2865b3708dbc EQUAL", "P2SH,STRICTENC"],
+["''", "SHA1 0x14 0xda39a3ee5e6b4b0d3255bfef95601890afd80709 EQUAL", "P2SH,STRICTENC"],
+["'a'", "SHA1 0x14 0x86f7e437faa5a7fce15d1ddcb9eaeaea377667b8 EQUAL", "P2SH,STRICTENC"],
+["'abcdefghijklmnopqrstuvwxyz'", "SHA1 0x14 0x32d10c7b8cf96570ca04ce37f2a19d84240d3a89 EQUAL", "P2SH,STRICTENC"],
+["''", "SHA256 0x20 0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 EQUAL", "P2SH,STRICTENC"],
+["'a'", "SHA256 0x20 0xca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb EQUAL", "P2SH,STRICTENC"],
+["'abcdefghijklmnopqrstuvwxyz'", "SHA256 0x20 0x71c480df93d6ae2f1efad1447c66c9525e316218cf51fc8d9ed832f2daf18b73 EQUAL", "P2SH,STRICTENC"],
+["''", "DUP HASH160 SWAP SHA256 RIPEMD160 EQUAL", "P2SH,STRICTENC"],
+["''", "DUP HASH256 SWAP SHA256 SHA256 EQUAL", "P2SH,STRICTENC"],
+["''", "NOP HASH160 0x14 0xb472a266d0bd89c13706a4132ccfb16f7c3b9fcb EQUAL", "P2SH,STRICTENC"],
+["'a'", "HASH160 NOP 0x14 0x994355199e516ff76c4fa4aab39337b9d84cf12b EQUAL", "P2SH,STRICTENC"],
+["'abcdefghijklmnopqrstuvwxyz'", "HASH160 0x4c 0x14 0xc286a1af0947f58d1ad787385b1c2c4a976f9e71 EQUAL", "P2SH,STRICTENC"],
+["''", "HASH256 0x20 0x5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456 EQUAL", "P2SH,STRICTENC"],
+["'a'", "HASH256 0x20 0xbf5d3affb73efd2ec6c36ad3112dd933efed63c4e1cbffcfa88e2759c144f2d8 EQUAL", "P2SH,STRICTENC"],
+["'abcdefghijklmnopqrstuvwxyz'", "HASH256 0x4c 0x20 0xca139bc10c2f660da42666f72e89a225936fc60f193c161124a672050c434671 EQUAL", "P2SH,STRICTENC"],
+
+
+["1","NOP1 NOP2 NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 1 EQUAL", "P2SH,STRICTENC"],
+["'NOP_1_to_10' NOP1 NOP2 NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_10' EQUAL", "P2SH,STRICTENC"],
+
+["1", "NOP", "P2SH,STRICTENC,DISCOURAGE_UPGRADABLE_NOPS", "Discourage NOPx flag allows OP_NOP"],
+
+["0", "IF NOP10 ENDIF 1", "P2SH,STRICTENC,DISCOURAGE_UPGRADABLE_NOPS",
+ "Discouraged NOPs are allowed if not executed"],
+
+["0", "IF 0xba ELSE 1 ENDIF", "P2SH,STRICTENC", "opcodes above NOP10 invalid if executed"],
+["0", "IF 0xbb ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xbc ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xbd ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xbe ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xbf ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xc0 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xc1 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xc2 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xc3 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xc4 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xc5 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xc6 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xc7 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xc8 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xc9 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xca ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xcb ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xcc ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xcd ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xce ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xcf ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xd0 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xd1 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xd2 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xd3 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xd4 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xd5 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xd6 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xd7 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xd8 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xd9 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xda ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xdb ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xdc ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xdd ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xde ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xdf ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xe0 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xe1 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xe2 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xe3 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xe4 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xe5 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xe6 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xe7 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xe8 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xe9 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xea ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xeb ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xec ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xed ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xee ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xef ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xf0 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xf1 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xf2 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xf3 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xf4 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xf5 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xf6 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xf7 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xf8 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xf9 ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xfa ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xfb ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xfc ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xfd ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xfe ELSE 1 ENDIF", "P2SH,STRICTENC"],
+["0", "IF 0xff ELSE 1 ENDIF", "P2SH,STRICTENC"],
+
+["NOP",
+"'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'",
+"P2SH,STRICTENC",
+"520 byte push"],
+["1",
+"0x616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161",
+"P2SH,STRICTENC",
+"201 opcodes executed. 0x61 is NOP"],
+["1 2 3 4 5 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f",
+"1 2 3 4 5 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f",
+"P2SH,STRICTENC",
+"1,000 stack size (0x6f is 3DUP)"],
+["1 TOALTSTACK 2 TOALTSTACK 3 4 5 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f",
+"1 2 3 4 5 6 7 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f",
+"P2SH,STRICTENC",
+"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",
+"P2SH,STRICTENC",
+"Max-size (10,000-byte), max-push(520 bytes), max-opcodes(201), max stack size(1,000 items). 0x6f is 3DUP, 0x61 is NOP"],
+
+["0",
+"IF 0x5050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050 ENDIF 1",
+"P2SH,STRICTENC",
+">201 opcodes, but RESERVED (0x50) doesn't count towards opcode limit."],
+
+["NOP","1", "P2SH,STRICTENC"],
+
+["1", "0x01 0x01 EQUAL", "P2SH,STRICTENC", "The following is useful for checking implementations of BN_bn2mpi"],
+["127", "0x01 0x7F EQUAL", "P2SH,STRICTENC"],
+["128", "0x02 0x8000 EQUAL", "P2SH,STRICTENC", "Leave room for the sign bit"],
+["32767", "0x02 0xFF7F EQUAL", "P2SH,STRICTENC"],
+["32768", "0x03 0x008000 EQUAL", "P2SH,STRICTENC"],
+["8388607", "0x03 0xFFFF7F EQUAL", "P2SH,STRICTENC"],
+["8388608", "0x04 0x00008000 EQUAL", "P2SH,STRICTENC"],
+["2147483647", "0x04 0xFFFFFF7F EQUAL", "P2SH,STRICTENC"],
+["2147483648", "0x05 0x0000008000 EQUAL", "P2SH,STRICTENC"],
+["549755813887", "0x05 0xFFFFFFFF7F EQUAL", "P2SH,STRICTENC"],
+["549755813888", "0x06 0xFFFFFFFF7F EQUAL", "P2SH,STRICTENC"],
+["9223372036854775807", "0x08 0xFFFFFFFFFFFFFF7F EQUAL", "P2SH,STRICTENC"],
+["-1", "0x01 0x81 EQUAL", "P2SH,STRICTENC", "Numbers are little-endian with the MSB being a sign bit"],
+["-127", "0x01 0xFF EQUAL", "P2SH,STRICTENC"],
+["-128", "0x02 0x8080 EQUAL", "P2SH,STRICTENC"],
+["-32767", "0x02 0xFFFF EQUAL", "P2SH,STRICTENC"],
+["-32768", "0x03 0x008080 EQUAL", "P2SH,STRICTENC"],
+["-8388607", "0x03 0xFFFFFF EQUAL", "P2SH,STRICTENC"],
+["-8388608", "0x04 0x00008080 EQUAL", "P2SH,STRICTENC"],
+["-2147483647", "0x04 0xFFFFFFFF EQUAL", "P2SH,STRICTENC"],
+["-2147483648", "0x05 0x0000008080 EQUAL", "P2SH,STRICTENC"],
+["-4294967295", "0x05 0xFFFFFFFF80 EQUAL", "P2SH,STRICTENC"],
+["-549755813887", "0x05 0xFFFFFFFFFF EQUAL", "P2SH,STRICTENC"],
+["-549755813888", "0x06 0x000000008080 EQUAL", "P2SH,STRICTENC"],
+["-9223372036854775807", "0x08 0xFFFFFFFFFFFFFFFF EQUAL", "P2SH,STRICTENC"],
+
+["2147483647", "1ADD 2147483648 EQUAL", "P2SH,STRICTENC", "We can do math on 4-byte integers, and compare 5-byte ones"],
+["2147483647", "1ADD 1", "P2SH,STRICTENC"],
+["-2147483647", "1ADD 1", "P2SH,STRICTENC"],
+
+["1", "0x02 0x0100 EQUAL NOT", "P2SH,STRICTENC", "Not the same byte array..."],
+["1", "0x02 0x0100 NUMEQUAL", "P2SH,STRICTENC", "... but they are numerically equal"],
+["11", "0x4c 0x03 0x0b0000 NUMEQUAL", "P2SH,STRICTENC"],
+["0", "0x01 0x80 EQUAL NOT", "P2SH,STRICTENC"],
+["0", "0x01 0x80 NUMEQUAL", "P2SH,STRICTENC", "Zero numerically equals negative zero"],
+["0", "0x02 0x0080 NUMEQUAL", "P2SH,STRICTENC"],
+["0x03 0x000080", "0x04 0x00000080 NUMEQUAL", "P2SH,STRICTENC"],
+["0x03 0x100080", "0x04 0x10000080 NUMEQUAL", "P2SH,STRICTENC"],
+["0x03 0x100000", "0x04 0x10000000 NUMEQUAL", "P2SH,STRICTENC"],
+
+["NOP", "NOP 1", "P2SH,STRICTENC", "The following tests check the if(stack.size() < N) tests in each opcode"],
+["1", "IF 1 ENDIF", "P2SH,STRICTENC", "They are here to catch copy-and-paste errors"],
+["0", "NOTIF 1 ENDIF", "P2SH,STRICTENC", "Most of them are duplicated elsewhere,"],
+["1", "VERIFY 1", "P2SH,STRICTENC", "but, hey, more is always better, right?"],
+
+["0", "TOALTSTACK 1", "P2SH,STRICTENC"],
+["1", "TOALTSTACK FROMALTSTACK", "P2SH,STRICTENC"],
+["0 0", "2DROP 1", "P2SH,STRICTENC"],
+["0 1", "2DUP", "P2SH,STRICTENC"],
+["0 0 1", "3DUP", "P2SH,STRICTENC"],
+["0 1 0 0", "2OVER", "P2SH,STRICTENC"],
+["0 1 0 0 0 0", "2ROT", "P2SH,STRICTENC"],
+["0 1 0 0", "2SWAP", "P2SH,STRICTENC"],
+["1", "IFDUP", "P2SH,STRICTENC"],
+["NOP", "DEPTH 1", "P2SH,STRICTENC"],
+["0", "DROP 1", "P2SH,STRICTENC"],
+["1", "DUP", "P2SH,STRICTENC"],
+["0 1", "NIP", "P2SH,STRICTENC"],
+["1 0", "OVER", "P2SH,STRICTENC"],
+["1 0 0 0 3", "PICK", "P2SH,STRICTENC"],
+["1 0", "PICK", "P2SH,STRICTENC"],
+["1 0 0 0 3", "ROLL", "P2SH,STRICTENC"],
+["1 0", "ROLL", "P2SH,STRICTENC"],
+["1 0 0", "ROT", "P2SH,STRICTENC"],
+["1 0", "SWAP", "P2SH,STRICTENC"],
+["0 1", "TUCK", "P2SH,STRICTENC"],
+
+["1", "SIZE", "P2SH,STRICTENC"],
+
+["0 0", "EQUAL", "P2SH,STRICTENC"],
+["0 0", "EQUALVERIFY 1", "P2SH,STRICTENC"],
+["0 0 1", "EQUAL EQUAL", "P2SH,STRICTENC", "OP_0 and bools must have identical byte representations"],
+
+["0", "1ADD", "P2SH,STRICTENC"],
+["2", "1SUB", "P2SH,STRICTENC"],
+["-1", "NEGATE", "P2SH,STRICTENC"],
+["-1", "ABS", "P2SH,STRICTENC"],
+["0", "NOT", "P2SH,STRICTENC"],
+["-1", "0NOTEQUAL", "P2SH,STRICTENC"],
+
+["1 0", "ADD", "P2SH,STRICTENC"],
+["1 0", "SUB", "P2SH,STRICTENC"],
+["-1 -1", "BOOLAND", "P2SH,STRICTENC"],
+["-1 0", "BOOLOR", "P2SH,STRICTENC"],
+["0 0", "NUMEQUAL", "P2SH,STRICTENC"],
+["0 0", "NUMEQUALVERIFY 1", "P2SH,STRICTENC"],
+["-1 0", "NUMNOTEQUAL", "P2SH,STRICTENC"],
+["-1 0", "LESSTHAN", "P2SH,STRICTENC"],
+["1 0", "GREATERTHAN", "P2SH,STRICTENC"],
+["0 0", "LESSTHANOREQUAL", "P2SH,STRICTENC"],
+["0 0", "GREATERTHANOREQUAL", "P2SH,STRICTENC"],
+["-1 0", "MIN", "P2SH,STRICTENC"],
+["1 0", "MAX", "P2SH,STRICTENC"],
+["-1 -1 0", "WITHIN", "P2SH,STRICTENC"],
+
+["0", "RIPEMD160", "P2SH,STRICTENC"],
+["0", "SHA1", "P2SH,STRICTENC"],
+["0", "SHA256", "P2SH,STRICTENC"],
+["0", "HASH160", "P2SH,STRICTENC"],
+["0", "HASH256", "P2SH,STRICTENC"],
+["NOP", "CODESEPARATOR 1", "P2SH,STRICTENC"],
+
+["NOP", "NOP1 1", "P2SH,STRICTENC"],
+["NOP", "NOP2 1", "P2SH,STRICTENC"],
+["NOP", "NOP3 1", "P2SH,STRICTENC"],
+["NOP", "NOP4 1", "P2SH,STRICTENC"],
+["NOP", "NOP5 1", "P2SH,STRICTENC"],
+["NOP", "NOP6 1", "P2SH,STRICTENC"],
+["NOP", "NOP7 1", "P2SH,STRICTENC"],
+["NOP", "NOP8 1", "P2SH,STRICTENC"],
+["NOP", "NOP9 1", "P2SH,STRICTENC"],
+["NOP", "NOP10 1", "P2SH,STRICTENC"],
+
+["", "0 0 0 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "CHECKMULTISIG is allowed to have zero keys and/or sigs"],
+["", "0 0 0 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+["", "0 0 0 1 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "Zero sigs means no sigs are checked"],
+["", "0 0 0 1 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+
+["", "0 0 0 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "CHECKMULTISIG is allowed to have zero keys and/or sigs"],
+["", "0 0 0 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+["", "0 0 0 1 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "Zero sigs means no sigs are checked"],
+["", "0 0 0 1 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+
+["", "0 0 'a' 'b' 2 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC", "Test from up to 20 pubkeys, all not checked"],
+["", "0 0 'a' 'b' 'c' 3 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+["", "0 0 'a' 'b' 'c' 'd' 4 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+["", "0 0 'a' 'b' 'c' 'd' 'e' 5 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 6 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 7 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 8 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 9 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 10 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 11 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 12 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 13 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 14 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 15 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 16 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 17 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 18 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 19 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG VERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+["", "0 0 'a' 1 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+["", "0 0 'a' 'b' 2 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+["", "0 0 'a' 'b' 'c' 3 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+["", "0 0 'a' 'b' 'c' 'd' 4 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+["", "0 0 'a' 'b' 'c' 'd' 'e' 5 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 6 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 7 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 8 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 9 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 10 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 11 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 12 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 13 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 14 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 15 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 16 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 17 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 18 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 19 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+["", "0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY DEPTH 0 EQUAL", "P2SH,STRICTENC"],
+
+["",
+"0 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG 0 0 CHECKMULTISIG",
+"P2SH,STRICTENC",
+"nOpCount is incremented by the number of keys evaluated in addition to the usual one op per op. In this case we have zero keys, so we can execute 201 CHECKMULTISIGS"],
+
+["1",
+"0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY 0 0 0 CHECKMULTISIGVERIFY",
+"P2SH,STRICTENC"],
+
+["",
+"NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIG",
+"P2SH,STRICTENC",
+"Even though there are no signatures being checked nOpCount is incremented by the number of keys."],
+
+["1",
+"NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY 0 0 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 20 CHECKMULTISIGVERIFY",
+"P2SH,STRICTENC"],
+
+["0 0x01 1", "HASH160 0x14 0xda1745e9b549bd0bfa1a569971c77eba30cd5a4b EQUAL", "P2SH,STRICTENC", "Very basic P2SH"],
+["0x4c 0 0x01 1", "HASH160 0x14 0xda1745e9b549bd0bfa1a569971c77eba30cd5a4b EQUAL", "P2SH,STRICTENC"],
+
+["0x40 0x42424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242",
+"0x4d 0x4000 0x42424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242 EQUAL",
+"P2SH,STRICTENC",
+"Basic PUSH signedness check"],
+
+["0x4c 0x40 0x42424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242",
+"0x4d 0x4000 0x42424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242 EQUAL",
+"P2SH,STRICTENC",
+"Basic PUSHDATA1 signedness check"],
+
+["all PUSHDATA forms are equivalent"],
+
+["0x4c 0x4b 0x111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", "0x4b 0x111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 EQUAL", "", "PUSHDATA1 of 75 bytes equals direct push of it"],
+["0x4d 0xFF00 0x111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", "0x4c 0xFF 0x111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 EQUAL", "", "PUSHDATA2 of 255 bytes equals PUSHDATA1 of it"],
+
+["0x00", "SIZE 0 EQUAL", "P2SH,STRICTENC", "Basic OP_0 execution"],
+
+["Numeric pushes"],
+
+["0x01 0x81", "0x4f EQUAL", "", "OP1_NEGATE pushes 0x81"],
+["0x01 0x01", "0x51 EQUAL", "", "OP_1 pushes 0x01"],
+["0x01 0x02", "0x52 EQUAL", "", "OP_2 pushes 0x02"],
+["0x01 0x03", "0x53 EQUAL", "", "OP_3 pushes 0x03"],
+["0x01 0x04", "0x54 EQUAL", "", "OP_4 pushes 0x04"],
+["0x01 0x05", "0x55 EQUAL", "", "OP_5 pushes 0x05"],
+["0x01 0x06", "0x56 EQUAL", "", "OP_6 pushes 0x06"],
+["0x01 0x07", "0x57 EQUAL", "", "OP_7 pushes 0x07"],
+["0x01 0x08", "0x58 EQUAL", "", "OP_8 pushes 0x08"],
+["0x01 0x09", "0x59 EQUAL", "", "OP_9 pushes 0x09"],
+["0x01 0x0a", "0x5a EQUAL", "", "OP_10 pushes 0x0a"],
+["0x01 0x0b", "0x5b EQUAL", "", "OP_11 pushes 0x0b"],
+["0x01 0x0c", "0x5c EQUAL", "", "OP_12 pushes 0x0c"],
+["0x01 0x0d", "0x5d EQUAL", "", "OP_13 pushes 0x0d"],
+["0x01 0x0e", "0x5e EQUAL", "", "OP_14 pushes 0x0e"],
+["0x01 0x0f", "0x5f EQUAL", "", "OP_15 pushes 0x0f"],
+["0x01 0x10", "0x60 EQUAL", "", "OP_16 pushes 0x10"],
+
+["Equivalency of different numeric encodings"],
+
+["0x02 0x8000", "128 NUMEQUAL", "", "0x8000 equals 128"],
+["0x01 0x00", "0 NUMEQUAL", "", "0x00 numequals 0"],
+["0x01 0x80", "0 NUMEQUAL", "", "0x80 (negative zero) numequals 0"],
+["0x02 0x0080", "0 NUMEQUAL", "", "0x0080 numequals 0"],
+["0x02 0x0500", "5 NUMEQUAL", "", "0x0500 numequals 5"],
+["0x03 0xff7f80", "0x02 0xffff NUMEQUAL", "", ""],
+["0x03 0xff7f00", "0x02 0xff7f NUMEQUAL", "", ""],
+["0x04 0xffff7f80", "0x03 0xffffff NUMEQUAL", "", ""],
+["0x04 0xffff7f00", "0x03 0xffff7f NUMEQUAL", "", ""],
+
+["Unevaluated non-minimal pushes are ignored"],
+
+["0 IF 0x4c 0x00 ENDIF 1", "", "MINIMALDATA", "non-minimal PUSHDATA1 ignored"],
+["0 IF 0x4d 0x0000 ENDIF 1", "", "MINIMALDATA", "non-minimal PUSHDATA2 ignored"],
+["0 IF 0x4c 0x00000000 ENDIF 1", "", "MINIMALDATA", "non-minimal PUSHDATA4 ignored"],
+["0 IF 0x01 0x81 ENDIF 1", "", "MINIMALDATA", "1NEGATE equiv"],
+["0 IF 0x01 0x01 ENDIF 1", "", "MINIMALDATA", "OP_1 equiv"],
+["0 IF 0x01 0x02 ENDIF 1", "", "MINIMALDATA", "OP_2 equiv"],
+["0 IF 0x01 0x03 ENDIF 1", "", "MINIMALDATA", "OP_3 equiv"],
+["0 IF 0x01 0x04 ENDIF 1", "", "MINIMALDATA", "OP_4 equiv"],
+["0 IF 0x01 0x05 ENDIF 1", "", "MINIMALDATA", "OP_5 equiv"],
+["0 IF 0x01 0x06 ENDIF 1", "", "MINIMALDATA", "OP_6 equiv"],
+["0 IF 0x01 0x07 ENDIF 1", "", "MINIMALDATA", "OP_7 equiv"],
+["0 IF 0x01 0x08 ENDIF 1", "", "MINIMALDATA", "OP_8 equiv"],
+["0 IF 0x01 0x09 ENDIF 1", "", "MINIMALDATA", "OP_9 equiv"],
+["0 IF 0x01 0x0a ENDIF 1", "", "MINIMALDATA", "OP_10 equiv"],
+["0 IF 0x01 0x0b ENDIF 1", "", "MINIMALDATA", "OP_11 equiv"],
+["0 IF 0x01 0x0c ENDIF 1", "", "MINIMALDATA", "OP_12 equiv"],
+["0 IF 0x01 0x0d ENDIF 1", "", "MINIMALDATA", "OP_13 equiv"],
+["0 IF 0x01 0x0e ENDIF 1", "", "MINIMALDATA", "OP_14 equiv"],
+["0 IF 0x01 0x0f ENDIF 1", "", "MINIMALDATA", "OP_15 equiv"],
+["0 IF 0x01 0x10 ENDIF 1", "", "MINIMALDATA", "OP_16 equiv"],
+
+["Numeric minimaldata rules are only applied when a stack item is numerically evaluated; the push itself is allowed"],
+
+["0x01 0x00", "1", "MINIMALDATA"],
+["0x01 0x80", "1", "MINIMALDATA"],
+["0x02 0x0180", "1", "MINIMALDATA"],
+["0x02 0x0100", "1", "MINIMALDATA"],
+["0x02 0x0200", "1", "MINIMALDATA"],
+["0x02 0x0300", "1", "MINIMALDATA"],
+["0x02 0x0400", "1", "MINIMALDATA"],
+["0x02 0x0500", "1", "MINIMALDATA"],
+["0x02 0x0600", "1", "MINIMALDATA"],
+["0x02 0x0700", "1", "MINIMALDATA"],
+["0x02 0x0800", "1", "MINIMALDATA"],
+["0x02 0x0900", "1", "MINIMALDATA"],
+["0x02 0x0a00", "1", "MINIMALDATA"],
+["0x02 0x0b00", "1", "MINIMALDATA"],
+["0x02 0x0c00", "1", "MINIMALDATA"],
+["0x02 0x0d00", "1", "MINIMALDATA"],
+["0x02 0x0e00", "1", "MINIMALDATA"],
+["0x02 0x0f00", "1", "MINIMALDATA"],
+["0x02 0x1000", "1", "MINIMALDATA"],
+
+["Valid version of the 'Test every numeric-accepting opcode for correct handling of the numeric minimal encoding rule' script_invalid test"],
+
+["1 0x02 0x0000", "PICK DROP", ""],
+["1 0x02 0x0000", "ROLL DROP 1", ""],
+["0x02 0x0000", "1ADD DROP 1", ""],
+["0x02 0x0000", "1SUB DROP 1", ""],
+["0x02 0x0000", "NEGATE DROP 1", ""],
+["0x02 0x0000", "ABS DROP 1", ""],
+["0x02 0x0000", "NOT DROP 1", ""],
+["0x02 0x0000", "0NOTEQUAL DROP 1", ""],
+
+["0 0x02 0x0000", "ADD DROP 1", ""],
+["0x02 0x0000 0", "ADD DROP 1", ""],
+["0 0x02 0x0000", "SUB DROP 1", ""],
+["0x02 0x0000 0", "SUB DROP 1", ""],
+["0 0x02 0x0000", "BOOLAND DROP 1", ""],
+["0x02 0x0000 0", "BOOLAND DROP 1", ""],
+["0 0x02 0x0000", "BOOLOR DROP 1", ""],
+["0x02 0x0000 0", "BOOLOR DROP 1", ""],
+["0 0x02 0x0000", "NUMEQUAL DROP 1", ""],
+["0x02 0x0000 1", "NUMEQUAL DROP 1", ""],
+["0 0x02 0x0000", "NUMEQUALVERIFY 1", ""],
+["0x02 0x0000 0", "NUMEQUALVERIFY 1", ""],
+["0 0x02 0x0000", "NUMNOTEQUAL DROP 1", ""],
+["0x02 0x0000 0", "NUMNOTEQUAL DROP 1", ""],
+["0 0x02 0x0000", "LESSTHAN DROP 1", ""],
+["0x02 0x0000 0", "LESSTHAN DROP 1", ""],
+["0 0x02 0x0000", "GREATERTHAN DROP 1", ""],
+["0x02 0x0000 0", "GREATERTHAN DROP 1", ""],
+["0 0x02 0x0000", "LESSTHANOREQUAL DROP 1", ""],
+["0x02 0x0000 0", "LESSTHANOREQUAL DROP 1", ""],
+["0 0x02 0x0000", "GREATERTHANOREQUAL DROP 1", ""],
+["0x02 0x0000 0", "GREATERTHANOREQUAL DROP 1", ""],
+["0 0x02 0x0000", "MIN DROP 1", ""],
+["0x02 0x0000 0", "MIN DROP 1", ""],
+["0 0x02 0x0000", "MAX DROP 1", ""],
+["0x02 0x0000 0", "MAX DROP 1", ""],
+
+["0x02 0x0000 0 0", "WITHIN DROP 1", ""],
+["0 0x02 0x0000 0", "WITHIN DROP 1", ""],
+["0 0 0x02 0x0000", "WITHIN DROP 1", ""],
+
+["0 0 0x02 0x0000", "CHECKMULTISIG DROP 1", ""],
+["0 0x02 0x0000 0", "CHECKMULTISIG DROP 1", ""],
+["0 0x02 0x0000 0 1", "CHECKMULTISIG DROP 1", ""],
+["0 0 0x02 0x0000", "CHECKMULTISIGVERIFY 1", ""],
+["0 0x02 0x0000 0", "CHECKMULTISIGVERIFY 1", ""],
+
+["While not really correctly DER encoded, the empty signature is allowed by"],
+["STRICTENC to provide a compact way to provide a delibrately invalid signature."],
+["0", "0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 CHECKSIG NOT", "STRICTENC"],
+["0 0", "1 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 1 CHECKMULTISIG NOT", "STRICTENC"],
+
+["CHECKMULTISIG evaluation order tests. CHECKMULTISIG evaluates signatures and"],
+["pubkeys in a specific order, and will exit early if the number of signatures"],
+["left to check is greater than the number of keys left. As STRICTENC fails the"],
+["script when it reaches an invalidly encoded signature or pubkey, we can use it"],
+["to test the exact order in which signatures and pubkeys are evaluated by"],
+["distinguishing CHECKMULTISIG returning false on the stack and the script as a"],
+["whole failing."],
+["See also the corresponding inverted versions of these tests in script_invalid.json"],
+[
+ "0 0x47 0x3044022044dc17b0887c161bb67ba9635bf758735bdde503e4b0a0987f587f14a4e1143d022009a215772d49a85dae40d8ca03955af26ad3978a0ff965faa12915e9586249a501 0x47 0x3044022044dc17b0887c161bb67ba9635bf758735bdde503e4b0a0987f587f14a4e1143d022009a215772d49a85dae40d8ca03955af26ad3978a0ff965faa12915e9586249a501",
+ "2 0 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 2 CHECKMULTISIG NOT",
+ "STRICTENC",
+ "2-of-2 CHECKMULTISIG NOT with the second pubkey invalid, and both signatures validly encoded. Valid pubkey fails, and CHECKMULTISIG exits early, prior to evaluation of second invalid pubkey."
+],
+[
+ "0 0 0x47 0x3044022044dc17b0887c161bb67ba9635bf758735bdde503e4b0a0987f587f14a4e1143d022009a215772d49a85dae40d8ca03955af26ad3978a0ff965faa12915e9586249a501",
+ "2 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 2 CHECKMULTISIG NOT",
+ "STRICTENC",
+ "2-of-2 CHECKMULTISIG NOT with both pubkeys valid, but second signature invalid. Valid pubkey fails, and CHECKMULTISIG exits early, prior to evaluation of second invalid signature."
+],
+
+["Increase test coverage for DERSIG"],
+["0x4a 0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "", "Overly long signature is correctly encoded"],
+["0x25 0x30220220000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "", "Missing S is correctly encoded"],
+["0x27 0x3024021077777777777777777777777777777777020a7777777777777777777777777777777701", "0 CHECKSIG NOT", "", "S with invalid S length is correctly encoded"],
+["0x27 0x302403107777777777777777777777777777777702107777777777777777777777777777777701", "0 CHECKSIG NOT", "", "Non-integer R is correctly encoded"],
+["0x27 0x302402107777777777777777777777777777777703107777777777777777777777777777777701", "0 CHECKSIG NOT", "", "Non-integer S is correctly encoded"],
+["0x17 0x3014020002107777777777777777777777777777777701", "0 CHECKSIG NOT", "", "Zero-length R is correctly encoded"],
+["0x17 0x3014021077777777777777777777777777777777020001", "0 CHECKSIG NOT", "", "Zero-length S is correctly encoded for DERSIG"],
+["0x27 0x302402107777777777777777777777777777777702108777777777777777777777777777777701", "0 CHECKSIG NOT", "", "Negative S is correctly encoded"],
+
+["Automatically generated test cases"],
+[
+ "0x47 0x304402200a5c6163f07b8d3b013c4d1d6dba25e780b39658d79ba37af7057a3b7f15ffa102201fd9b4eaa9943f734928b99a83592c2e7bf342ea2680f6a2bb705167966b742001",
+ "0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG",
+ "",
+ "P2PK"
+],
+[
+ "0x47 0x304402206e05a6fe23c59196ffe176c9ddc31e73a9885638f9d1328d47c0c703863b8876022076feb53811aa5b04e0e79f938eb19906cc5e67548bc555a8e8b8b0fc603d840c01 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508",
+ "DUP HASH160 0x14 0x1018853670f9f3b0582c5b9ee8ce93764ac32b93 EQUALVERIFY CHECKSIG",
+ "",
+ "P2PKH"
+],
+[
+ "0x47 0x304402204710a85181663b32d25c70ec2bbd14adff5ddfff6cb50d09e155ef5f541fc86c0220056b0cc949be9386ecc5f6c2ac0493269031dbb185781db90171b54ac127790281",
+ "0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG",
+ "",
+ "P2PK anyonecanpay"
+],
+[
+ "0x47 0x3044022003fef42ed6c7be8917441218f525a60e2431be978e28b7aca4d7a532cc413ae8022067a1f82c74e8d69291b90d148778405c6257bbcfc2353cc38a3e1f22bf44254601 0x23 0x210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac",
+ "HASH160 0x14 0x23b0ad3477f2178bc0b3eed26e4e6316f4e83aa1 EQUAL",
+ "P2SH",
+ "P2SH(P2PK)"
+],
+[
+ "0x47 0x304402204e2eb034be7b089534ac9e798cf6a2c79f38bcb34d1b179efd6f2de0841735db022071461beb056b5a7be1819da6a3e3ce3662831ecc298419ca101eb6887b5dd6a401 0x19 0x76a9147cf9c846cd4882efec4bf07e44ebdad495c94f4b88ac",
+ "HASH160 0x14 0x2df519943d5acc0ef5222091f9dfe3543f489a82 EQUAL",
+ "",
+ "P2SH(P2PKH), bad sig but no VERIFY_P2SH"
+],
+[
+ "0 0x47 0x3044022051254b9fb476a52d85530792b578f86fea70ec1ffb4393e661bcccb23d8d63d3022076505f94a403c86097841944e044c70c2045ce90e36de51f7e9d3828db98a07501 0x47 0x304402200a358f750934b3feb822f1966bfcd8bbec9eeaa3a8ca941e11ee5960e181fa01022050bf6b5a8e7750f70354ae041cb68a7bade67ec6c3ab19eb359638974410626e01 0x47 0x304402200955d031fff71d8653221e85e36c3c85533d2312fc3045314b19650b7ae2f81002202a6bb8505e36201909d0921f01abff390ae6b7ff97bbf959f98aedeb0a56730901",
+ "3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG",
+ "",
+ "3-of-3"
+],
+[
+ "0 0x47 0x304402205b7d2c2f177ae76cfbbf14d589c113b0b35db753d305d5562dd0b61cbf366cfb02202e56f93c4f08a27f986cd424ffc48a462c3202c4902104d4d0ff98ed28f4bf8001 0x47 0x30440220563e5b3b1fc11662a84bc5ea2a32cc3819703254060ba30d639a1aaf2d5068ad0220601c1f47ddc76d93284dd9ed68f7c9974c4a0ea7cbe8a247d6bc3878567a5fca01 0x4c69 0x52210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179821038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f515082103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff464053ae",
+ "HASH160 0x14 0xc9e4a896d149702d0d1695434feddd52e24ad78d EQUAL",
+ "P2SH",
+ "P2SH(2-of-3)"
+],
+[
+ "0x47 0x304402200060558477337b9022e70534f1fea71a318caf836812465a2509931c5e7c4987022078ec32bd50ac9e03a349ba953dfd9fe1c8d2dd8bdb1d38ddca844d3d5c78c11801",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG",
+ "",
+ "P2PK with too much R padding but no DERSIG"
+],
+[
+ "0x48 0x304502202de8c03fc525285c9c535631019a5f2af7c6454fa9eb392a3756a4917c420edd02210046130bf2baf7cfc065067c8b9e33a066d9c15edcea9feb0ca2d233e3597925b401",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG",
+ "",
+ "P2PK with too much S padding but no DERSIG"
+],
+[
+ "0x47 0x30440220d7a0417c3f6d1a15094d1cf2a3378ca0503eb8a57630953a9e2987e21ddd0a6502207a6266d686c99090920249991d3d42065b6d43eb70187b219c0db82e4f94d1a201",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG",
+ "",
+ "P2PK with too little R padding but no DERSIG"
+],
+[
+ "0x47 0x30440220005ece1335e7f757a1a1f476a7fb5bd90964e8a022489f890614a04acfb734c002206c12b8294a6513c7710e8c82d3c23d75cdbfe83200eb7efb495701958501a5d601",
+ "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG NOT",
+ "",
+ "P2PK NOT with bad sig with too much R padding but no DERSIG"
+],
+[
+ "0x47 0x30440220d7a0417c3f6d1a15094d1cf2a3378ca0503eb8a57630953a9e2987e21ddd0a6502207a6266d686c99090920249991d3d42065b6d43eb70187b219c0db82e4f94d1a201",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG",
+ "",
+ "BIP66 example 1, without DERSIG"
+],
+[
+ "0",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT",
+ "",
+ "BIP66 example 4, without DERSIG"
+],
+[
+ "0",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT",
+ "DERSIG",
+ "BIP66 example 4, with DERSIG"
+],
+[
+ "1",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT",
+ "",
+ "BIP66 example 6, without DERSIG"
+],
+[
+ "0 0x47 0x30440220cae00b1444babfbf6071b0ba8707f6bd373da3df494d6e74119b0430c5db810502205d5231b8c5939c8ff0c82242656d6e06edb073d42af336c99fe8837c36ea39d501 0x47 0x3044022027c2714269ca5aeecc4d70edc88ba5ee0e3da4986e9216028f489ab4f1b8efce022022bd545b4951215267e4c5ceabd4c5350331b2e4a0b6494c56f361fa5a57a1a201",
+ "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG",
+ "",
+ "BIP66 example 7, without DERSIG"
+],
+[
+ "0 0 0x47 0x30440220da6f441dc3b4b2c84cfa8db0cd5b34ed92c9e01686de5a800d40498b70c0dcac02207c2cf91b0c32b860c4cd4994be36cfb84caf8bb7c3a8e4d96a31b2022c5299c501",
+ "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT",
+ "",
+ "BIP66 example 10, without DERSIG"
+],
+[
+ "0 0x47 0x30440220b119d67d389315308d1745f734a51ff3ec72e06081e84e236fdf9dc2f5d2a64802204b04e3bc38674c4422ea317231d642b56dc09d214a1ecbbf16ecca01ed996e2201 0",
+ "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT",
+ "",
+ "BIP66 example 12, without DERSIG"
+],
+[
+ "0 0x47 0x30440220b119d67d389315308d1745f734a51ff3ec72e06081e84e236fdf9dc2f5d2a64802204b04e3bc38674c4422ea317231d642b56dc09d214a1ecbbf16ecca01ed996e2201 0",
+ "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT",
+ "DERSIG",
+ "BIP66 example 12, with DERSIG"
+],
+[
+ "0x48 0x304402203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022054e1c258c2981cdfba5df1f46661fb6541c44f77ca0092f3600331abfffb12510101",
+ "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG",
+ "",
+ "P2PK with multi-byte hashtype, without DERSIG"
+],
+[
+ "0x48 0x304502203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022100ab1e3da73d67e32045a20e0b999e049978ea8d6ee5480d485fcf2ce0d03b2ef001",
+ "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG",
+ "",
+ "P2PK with high S but no LOW_S"
+],
+[
+ "0x47 0x3044022057292e2d4dfe775becdd0a9e6547997c728cdf35390f6a017da56d654d374e4902206b643be2fc53763b4e284845bfea2c597d2dc7759941dce937636c9d341b71ed01",
+ "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG",
+ "",
+ "P2PK with hybrid pubkey but no STRICTENC"
+],
+[
+ "0x47 0x30440220035d554e3153c04950c9993f41c496607a8e24093db0595be7bf875cf64fcf1f02204731c8c4e5daf15e706cec19cdd8f2c5b1d05490e11dab8465ed426569b6e92101",
+ "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG NOT",
+ "",
+ "P2PK NOT with invalid hybrid pubkey but no STRICTENC"
+],
+[
+ "0 0x47 0x304402202e79441ad1baf5a07fb86bae3753184f6717d9692680947ea8b6e8b777c69af1022079a262e13d868bb5a0964fefe3ba26942e1b0669af1afb55ef3344bc9d4fc4c401",
+ "1 0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 2 CHECKMULTISIG",
+ "",
+ "1-of-2 with the second 1 hybrid pubkey and no STRICTENC"
+],
+[
+ "0 0x47 0x304402202e79441ad1baf5a07fb86bae3753184f6717d9692680947ea8b6e8b777c69af1022079a262e13d868bb5a0964fefe3ba26942e1b0669af1afb55ef3344bc9d4fc4c401",
+ "1 0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 2 CHECKMULTISIG",
+ "STRICTENC",
+ "1-of-2 with the second 1 hybrid pubkey"
+],
+[
+ "0x47 0x304402206177d513ec2cda444c021a1f4f656fc4c72ba108ae063e157eb86dc3575784940220666fc66702815d0e5413bb9b1df22aed44f5f1efb8b99d41dd5dc9a5be6d205205",
+ "0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG",
+ "",
+ "P2PK with undefined hashtype but no STRICTENC"
+],
+[
+ "0x47 0x304402207409b5b320296e5e2136a7b281a7f803028ca4ca44e2b83eebd46932677725de02202d4eea1c8d3c98e6f42614f54764e6e5e6542e213eb4d079737e9a8b6e9812ec05",
+ "0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG NOT",
+ "",
+ "P2PK NOT with invalid sig and undefined hashtype but no STRICTENC"
+],
+[
+ "1 0x47 0x3044022051254b9fb476a52d85530792b578f86fea70ec1ffb4393e661bcccb23d8d63d3022076505f94a403c86097841944e044c70c2045ce90e36de51f7e9d3828db98a07501 0x47 0x304402200a358f750934b3feb822f1966bfcd8bbec9eeaa3a8ca941e11ee5960e181fa01022050bf6b5a8e7750f70354ae041cb68a7bade67ec6c3ab19eb359638974410626e01 0x47 0x304402200955d031fff71d8653221e85e36c3c85533d2312fc3045314b19650b7ae2f81002202a6bb8505e36201909d0921f01abff390ae6b7ff97bbf959f98aedeb0a56730901",
+ "3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG",
+ "",
+ "3-of-3 with nonzero dummy but no NULLDUMMY"
+],
+[
+ "1 0x47 0x304402201bb2edab700a5d020236df174fefed78087697143731f659bea59642c759c16d022061f42cdbae5bcd3e8790f20bf76687443436e94a634321c16a72aa54cbc7c2ea01 0x47 0x304402204bb4a64f2a6e5c7fb2f07fef85ee56fde5e6da234c6a984262307a20e99842d702206f8303aaba5e625d223897e2ffd3f88ef1bcffef55f38dc3768e5f2e94c923f901 0x47 0x3044022040c2809b71fffb155ec8b82fe7a27f666bd97f941207be4e14ade85a1249dd4d02204d56c85ec525dd18e29a0533d5ddf61b6b1bb32980c2f63edf951aebf7a27bfe01",
+ "3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG NOT",
+ "",
+ "3-of-3 NOT with invalid sig and nonzero dummy but no NULLDUMMY"
+],
+[
+ "0 0x47 0x304402200abeb4bd07f84222f474aed558cfbdfc0b4e96cde3c2935ba7098b1ff0bd74c302204a04c1ca67b2a20abee210cf9a21023edccbbf8024b988812634233115c6b73901 DUP",
+ "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 2 CHECKMULTISIG",
+ "",
+ "2-of-2 with two identical keys and sigs pushed using OP_DUP but no SIGPUSHONLY"
+],
+[
+ "0 0x47 0x304402200abeb4bd07f84222f474aed558cfbdfc0b4e96cde3c2935ba7098b1ff0bd74c302204a04c1ca67b2a20abee210cf9a21023edccbbf8024b988812634233115c6b73901 0x47 0x304402200abeb4bd07f84222f474aed558cfbdfc0b4e96cde3c2935ba7098b1ff0bd74c302204a04c1ca67b2a20abee210cf9a21023edccbbf8024b988812634233115c6b73901",
+ "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 2 CHECKMULTISIG",
+ "SIGPUSHONLY",
+ "2-of-2 with two identical keys and sigs pushed"
+],
+[
+ "11 0x47 0x304402200a5c6163f07b8d3b013c4d1d6dba25e780b39658d79ba37af7057a3b7f15ffa102201fd9b4eaa9943f734928b99a83592c2e7bf342ea2680f6a2bb705167966b742001",
+ "0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG",
+ "P2SH",
+ "P2PK with unnecessary input but no CLEANSTACK"
+],
+[
+ "11 0x47 0x304402202f7505132be14872581f35d74b759212d9da40482653f1ffa3116c3294a4a51702206adbf347a2240ca41c66522b1a22a41693610b76a8e7770645dc721d1635854f01 0x43 0x410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac",
+ "HASH160 0x14 0x31edc23bdafda4639e669f89ad6b2318dd79d032 EQUAL",
+ "P2SH",
+ "P2SH with unnecessary input but no CLEANSTACK"
+],
+[
+ "0x47 0x304402202f7505132be14872581f35d74b759212d9da40482653f1ffa3116c3294a4a51702206adbf347a2240ca41c66522b1a22a41693610b76a8e7770645dc721d1635854f01 0x43 0x410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac",
+ "HASH160 0x14 0x31edc23bdafda4639e669f89ad6b2318dd79d032 EQUAL",
+ "CLEANSTACK,P2SH",
+ "P2SH with CLEANSTACK"
+],
+
+["The End"]
+]
diff --git a/src/test/data/sighash.json b/src/test/data/sighash.json
new file mode 100644
index 0000000000..d66a56ac35
--- /dev/null
+++ b/src/test/data/sighash.json
@@ -0,0 +1,503 @@
+[
+ ["raw_transaction, script, input_index, hashType, signature_hash (result)"],
+ ["907c2bc503ade11cc3b04eb2918b6f547b0630ab569273824748c87ea14b0696526c66ba740200000004ab65ababfd1f9bdd4ef073c7afc4ae00da8a66f429c917a0081ad1e1dabce28d373eab81d8628de802000000096aab5253ab52000052ad042b5f25efb33beec9f3364e8a9139e8439d9d7e26529c3c30b6c3fd89f8684cfd68ea0200000009ab53526500636a52ab599ac2fe02a526ed040000000008535300516352515164370e010000000003006300ab2ec229", "", 2, 1864164639, "31af167a6cf3f9d5f6875caa4d31704ceb0eba078d132b78dab52c3b8997317e"],
+ ["a0aa3126041621a6dea5b800141aa696daf28408959dfb2df96095db9fa425ad3f427f2f6103000000015360290e9c6063fa26912c2e7fb6a0ad80f1c5fea1771d42f12976092e7a85a4229fdb6e890000000001abc109f6e47688ac0e4682988785744602b8c87228fcef0695085edf19088af1a9db126e93000000000665516aac536affffffff8fe53e0806e12dfd05d67ac68f4768fdbe23fc48ace22a5aa8ba04c96d58e2750300000009ac51abac63ab5153650524aa680455ce7b000000000000499e50030000000008636a00ac526563ac5051ee030000000003abacabd2b6fe000000000003516563910fb6b5", "65", 0, -1391424484, "48d6a1bd2cd9eec54eb866fc71209418a950402b5d7e52363bfb75c98e141175"],
+ ["6e7e9d4b04ce17afa1e8546b627bb8d89a6a7fefd9d892ec8a192d79c2ceafc01694a6a7e7030000000953ac6a51006353636a33bced1544f797f08ceed02f108da22cd24c9e7809a446c61eb3895914508ac91f07053a01000000055163ab516affffffff11dc54eee8f9e4ff0bcf6b1a1a35b1cd10d63389571375501af7444073bcec3c02000000046aab53514a821f0ce3956e235f71e4c69d91abe1e93fb703bd33039ac567249ed339bf0ba0883ef300000000090063ab65000065ac654bec3cc504bcf499020000000005ab6a52abac64eb060100000000076a6a5351650053bbbc130100000000056a6aab53abd6e1380100000000026a51c4e509b8", "acab655151", 0, 479279909, "2a3d95b09237b72034b23f2d2bb29fa32a58ab5c6aa72f6aafdfa178ab1dd01c"],
+ ["73107cbd025c22ebc8c3e0a47b2a760739216a528de8d4dab5d45cbeb3051cebae73b01ca10200000007ab6353656a636affffffffe26816dffc670841e6a6c8c61c586da401df1261a330a6c6b3dd9f9a0789bc9e000000000800ac6552ac6aac51ffffffff0174a8f0010000000004ac52515100000000", "5163ac63635151ac", 1, 1190874345, "06e328de263a87b09beabe222a21627a6ea5c7f560030da31610c4611f4a46bc"],
+ ["e93bbf6902be872933cb987fc26ba0f914fcfc2f6ce555258554dd9939d12032a8536c8802030000000453ac5353eabb6451e074e6fef9de211347d6a45900ea5aaf2636ef7967f565dce66fa451805c5cd10000000003525253ffffffff047dc3e6020000000007516565ac656aabec9eea010000000001633e46e600000000000015080a030000000001ab00000000", "5300ac6a53ab6a", 1, -886562767, "f03aa4fc5f97e826323d0daa03343ebf8a34ed67a1ce18631f8b88e5c992e798"],
+ ["50818f4c01b464538b1e7e7f5ae4ed96ad23c68c830e78da9a845bc19b5c3b0b20bb82e5e9030000000763526a63655352ffffffff023b3f9c040000000008630051516a6a5163a83caf01000000000553ab65510000000000", "6aac", 0, 946795545, "746306f322de2b4b58ffe7faae83f6a72433c22f88062cdde881d4dd8a5a4e2d"],
+ ["a93e93440250f97012d466a6cc24839f572def241c814fe6ae94442cf58ea33eb0fdd9bcc1030000000600636a0065acffffffff5dee3a6e7e5ad6310dea3e5b3ddda1a56bf8de7d3b75889fc024b5e233ec10f80300000007ac53635253ab53ffffffff0160468b04000000000800526a5300ac526a00000000", "ac00636a53", 1, 1773442520, "5c9d3a2ce9365bb72cfabbaa4579c843bb8abf200944612cf8ae4b56a908bcbd"],
+ ["ce7d371f0476dda8b811d4bf3b64d5f86204725deeaa3937861869d5b2766ea7d17c57e40b0100000003535265ffffffff7e7e9188f76c34a46d0bbe856bde5cb32f089a07a70ea96e15e92abb37e479a10100000006ab6552ab655225bcab06d1c2896709f364b1e372814d842c9c671356a1aa5ca4e060462c65ae55acc02d0000000006abac0063ac5281b33e332f96beebdbc6a379ebe6aea36af115c067461eb99d22ba1afbf59462b59ae0bd0200000004ab635365be15c23801724a1704000000000965006a65ac00000052ca555572", "53ab530051ab", 1, 2030598449, "c336b2f7d3702fbbdeffc014d106c69e3413c7c71e436ba7562d8a7a2871f181"],
+ ["d3b7421e011f4de0f1cea9ba7458bf3486bee722519efab711a963fa8c100970cf7488b7bb0200000003525352dcd61b300148be5d05000000000000000000", "535251536aac536a", 0, -1960128125, "29aa6d2d752d3310eba20442770ad345b7f6a35f96161ede5f07b33e92053e2a"],
+ ["04bac8c5033460235919a9c63c42b2db884c7c8f2ed8fcd69ff683a0a2cccd9796346a04050200000003655351fcad3a2c5a7cbadeb4ec7acc9836c3f5c3e776e5c566220f7f965cf194f8ef98efb5e3530200000007526a006552526526a2f55ba5f69699ece76692552b399ba908301907c5763d28a15b08581b23179cb01eac03000000075363ab6a516351073942c2025aa98a05000000000765006aabac65abd7ffa6030000000004516a655200000000", "53ac6365ac526a", 1, 764174870, "bf5fdc314ded2372a0ad078568d76c5064bf2affbde0764c335009e56634481b"],
+ ["c363a70c01ab174230bbe4afe0c3efa2d7f2feaf179431359adedccf30d1f69efe0c86ed390200000002ab51558648fe0231318b04000000000151662170000000000008ac5300006a63acac00000000", "", 0, 2146479410, "191ab180b0d753763671717d051f138d4866b7cb0d1d4811472e64de595d2c70"],
+ ["8d437a7304d8772210a923fd81187c425fc28c17a5052571501db05c7e89b11448b36618cd02000000026a6340fec14ad2c9298fde1477f1e8325e5747b61b7e2ff2a549f3d132689560ab6c45dd43c3010000000963ac00ac000051516a447ed907a7efffebeb103988bf5f947fc688aab2c6a7914f48238cf92c337fad4a79348102000000085352ac526a5152517436edf2d80e3ef06725227c970a816b25d0b58d2cd3c187a7af2cea66d6b27ba69bf33a0300000007000063ab526553f3f0d6140386815d030000000003ab6300de138f00000000000900525153515265abac1f87040300000000036aac6500000000", "51", 3, -315779667, "b6632ac53578a741ae8c36d8b69e79f39b89913a2c781cdf1bf47a8c29d997a5"],
+ ["fd878840031e82fdbe1ad1d745d1185622b0060ac56638290ec4f66b1beef4450817114a2c0000000009516a63ab53650051abffffffff37b7a10322b5418bfd64fb09cd8a27ddf57731aeb1f1f920ffde7cb2dfb6cdb70300000008536a5365ac53515369ecc034f1594690dbe189094dc816d6d57ea75917de764cbf8eccce4632cbabe7e116cd0100000003515352ffffffff035777fc000000000003515200abe9140300000000050063005165bed6d10200000000076300536363ab65195e9110", "635265", 0, 1729787658, "6e3735d37a4b28c45919543aabcb732e7a3e1874db5315abb7cc6b143d62ff10"],
+ ["f40a750702af06efff3ea68e5d56e42bc41cdb8b6065c98f1221fe04a325a898cb61f3d7ee030000000363acacffffffffb5788174aef79788716f96af779d7959147a0c2e0e5bfb6c2dba2df5b4b97894030000000965510065535163ac6affffffff0445e6fd0200000000096aac536365526a526aa6546b000000000008acab656a6552535141a0fd010000000000c897ea030000000008526500ab526a6a631b39dba3", "00abab5163ac", 1, -1778064747, "d76d0fc0abfa72d646df888bce08db957e627f72962647016eeae5a8412354cf"],
+ ["a63bc673049c75211aa2c09ecc38e360eaa571435fedd2af1116b5c1fa3d0629c269ecccbf0000000008ac65ab516352ac52ffffffffbf1a76fdda7f451a5f0baff0f9ccd0fe9136444c094bb8c544b1af0fa2774b06010000000463535253ffffffff13d6b7c3ddceef255d680d87181e100864eeb11a5bb6a3528cb0d70d7ee2bbbc02000000056a0052abab951241809623313b198bb520645c15ec96bfcc74a2b0f3db7ad61d455cc32db04afc5cc702000000016309c9ae25014d9473020000000004abab6aac3bb1e803", "", 3, -232881718, "6e48f3da3a4ac07eb4043a232df9f84e110485d7c7669dd114f679c27d15b97e"],
+ ["4c565efe04e7d32bac03ae358d63140c1cfe95de15e30c5b84f31bb0b65bb542d637f49e0f010000000551abab536348ae32b31c7d3132030a510a1b1aacf7b7c3f19ce8dc49944ef93e5fa5fe2d356b4a73a00100000009abac635163ac00ab514c8bc57b6b844e04555c0a4f4fb426df139475cd2396ae418bc7015820e852f711519bc202000000086a00510000abac52488ff4aec72cbcfcc98759c58e20a8d2d9725aa4a80f83964e69bc4e793a4ff25cd75dc701000000086a52ac6aac5351532ec6b10802463e0200000000000553005265523e08680100000000002f39a6b0", "", 3, 70712784, "c6076b6a45e6fcfba14d3df47a34f6aadbacfba107e95621d8d7c9c0e40518ed"],
+ ["1233d5e703403b3b8b4dae84510ddfc126b4838dcb47d3b23df815c0b3a07b55bf3098110e010000000163c5c55528041f480f40cf68a8762d6ed3efe2bd402795d5233e5d94bf5ddee71665144898030000000965525165655151656affffffff6381667e78bb74d0880625993bec0ea3bd41396f2bcccc3cc097b240e5e92d6a01000000096363acac6a63536365ffffffff04610ad60200000000065251ab65ab52e90d680200000000046351516ae30e98010000000008abab52520063656a671856010000000004ac6aac514c84e383", "6aabab636300", 1, -114996813, "aeb8c5a62e8a0b572c28f2029db32854c0b614dbecef0eaa726abebb42eebb8d"],
+ ["0c69702103b25ceaed43122cc2672de84a3b9aa49872f2a5bb458e19a52f8cc75973abb9f102000000055365656aacffffffff3ffb1cf0f76d9e3397de0942038c856b0ebbea355dc9d8f2b06036e19044b0450100000000ffffffff4b7793f4169617c54b734f2cd905ed65f1ce3d396ecd15b6c426a677186ca0620200000008655263526551006a181a25b703240cce0100000000046352ab53dee22903000000000865526a6a516a51005e121602000000000852ab52ababac655200000000", "6a516aab63", 1, -2040012771, "a6e6cb69f409ec14e10dd476f39167c29e586e99bfac93a37ed2c230fcc1dbbe"],
+ ["fd22692802db8ae6ab095aeae3867305a954278f7c076c542f0344b2591789e7e33e4d29f4020000000151ffffffffb9409129cfed9d3226f3b6bab7a2c83f99f48d039100eeb5796f00903b0e5e5e0100000006656552ac63abd226abac0403e649000000000007abab51ac5100ac8035f10000000000095165006a63526a52510d42db030000000007635365ac6a63ab24ef5901000000000453ab6a0000000000", "536a52516aac6a", 1, 309309168, "7ca0f75e6530ec9f80d031fc3513ca4ecd67f20cb38b4dacc6a1d825c3cdbfdb"],
+ ["a43f85f701ffa54a3cc57177510f3ea28ecb6db0d4431fc79171cad708a6054f6e5b4f89170000000008ac6a006a536551652bebeaa2013e779c05000000000665ac5363635100000000", "ac", 0, 2028978692, "58294f0d7f2e68fe1fd30c01764fe1619bcc7961d68968944a0e263af6550437"],
+ ["c2b0b99001acfecf7da736de0ffaef8134a9676811602a6299ba5a2563a23bb09e8cbedf9300000000026300ffffffff042997c50300000000045252536a272437030000000007655353ab6363ac663752030000000002ab6a6d5c900000000000066a6a5265abab00000000", "52ac525163515251", 0, -894181723, "8b300032a1915a4ac05cea2f7d44c26f2a08d109a71602636f15866563eaafdc"],
+ ["82f9f10304c17a9d954cf3380db817814a8c738d2c811f0412284b2c791ec75515f38c4f8c020000000265ab5729ca7db1b79abee66c8a757221f29280d0681355cb522149525f36da760548dbd7080a0100000001510b477bd9ce9ad5bb81c0306273a3a7d051e053f04ecf3a1dbeda543e20601a5755c0cfae030000000451ac656affffffff71141a04134f6c292c2e0d415e6705dfd8dcee892b0d0807828d5aeb7d11f5ef0300000001520b6c6dc802a6f3dd0000000000056aab515163bfb6800300000000015300000000", "", 3, -635779440, "d55ed1e6c53510f2608716c12132a11fb5e662ec67421a513c074537eeccc34b"],
+ ["8edcf5a1014b604e53f0d12fe143cf4284f86dc79a634a9f17d7e9f8725f7beb95e8ffcd2403000000046aabac52ffffffff01c402b5040000000005ab6a63525100000000", "6351525251acabab6a", 0, 1520147826, "2765bbdcd3ebb8b1a316c04656b28d637f80bffbe9b040661481d3dc83eea6d6"],
+ ["2074bad5011847f14df5ea7b4afd80cd56b02b99634893c6e3d5aaad41ca7c8ee8e5098df003000000026a6affffffff018ad59700000000000900ac656a526551635300000000", "65635265", 0, -1804671183, "663c999a52288c9999bff36c9da2f8b78d5c61b8347538f76c164ccba9868d0a"],
+ ["7100b11302e554d4ef249ee416e7510a485e43b2ba4b8812d8fe5529fe33ea75f36d392c4403000000020000ffffffff3d01a37e075e9a7715a657ae1bdf1e44b46e236ad16fd2f4c74eb9bf370368810000000007636553ac536365ffffffff01db696a0400000000065200ac656aac00000000", "63005151", 0, -1210499507, "b9c3aee8515a4a3b439de1ffc9c156824bda12cb75bfe5bc863164e8fd31bd7a"],
+ ["02c1017802091d1cb08fec512db7b012fe4220d57a5f15f9e7676358b012786e1209bcff950100000004acab6352ffffffff799bc282724a970a6fea1828984d0aeb0f16b67776fa213cbdc4838a2f1961a3010000000951516a536552ab6aabffffffff016c7b4b03000000000865abac5253ac5352b70195ad", "65655200516a", 0, -241626954, "be567cb47170b34ff81c66c1142cb9d27f9b6898a384d6dfc4fce16b75b6cb14"],
+ ["cb3178520136cd294568b83bb2520f78fecc507898f4a2db2674560d72fd69b9858f75b3b502000000066aac00515100ffffffff03ab005a01000000000563526363006e3836030000000001abfbda3200000000000665ab0065006500000000", "ab516a0063006a5300", 0, 1182109299, "2149e79c3f4513da4e4378608e497dcfdfc7f27c21a826868f728abd2b8a637a"],
+ ["18a4b0c004702cf0e39686ac98aab78ad788308f1d484b1ddfe70dc1997148ba0e28515c310300000000ffffffff05275a52a23c59da91129093364e275da5616c4070d8a05b96df5a2080ef259500000000096aac51656a6aac53ab66e64966b3b36a07dd2bb40242dd4a3743d3026e7e1e0d9e9e18f11d068464b989661321030000000265ac383339c4fae63379cafb63b0bab2eca70e1f5fc7d857eb5c88ccd6c0465093924bba8b2a000000000300636ab5e0545402bc2c4c010000000000cd41c002000000000000000000", "abac635253656a00", 3, 2052372230, "32db877b6b1ca556c9e859442329406f0f8246706522369839979a9f7a235a32"],
+ ["1d9c5df20139904c582285e1ea63dec934251c0f9cf5c47e86abfb2b394ebc57417a81f67c010000000353515222ba722504800d3402000000000353656a3c0b4a0200000000000fb8d20500000000076300ab005200516462f30400000000015200000000", "ab65", 0, -210854112, "edf73e2396694e58f6b619f68595b0c1cdcb56a9b3147845b6d6afdb5a80b736"],
+ ["4504cb1904c7a4acf375ddae431a74de72d5436efc73312cf8e9921f431267ea6852f9714a01000000066a656a656553a2fbd587c098b3a1c5bd1d6480f730a0d6d9b537966e20efc0e352d971576d0f87df0d6d01000000016321aeec3c4dcc819f1290edb463a737118f39ab5765800547522708c425306ebfca3f396603000000055300ac656a1d09281d05bfac57b5eb17eb3fa81ffcedfbcd3a917f1be0985c944d473d2c34d245eb350300000007656a51525152ac263078d9032f470f0500000000066aac00000052e12da60200000000003488410200000000076365006300ab539981e432", "52536a52526a", 1, -31909119, "f0a2deee7fd8a3a9fad6927e763ded11c940ee47e9e6d410f94fda5001f82e0c"],
+ ["14bc7c3e03322ec0f1311f4327e93059c996275302554473104f3f7b46ca179bfac9ef753503000000016affffffff9d405eaeffa1ca54d9a05441a296e5cc3a3e32bb8307afaf167f7b57190b07e00300000008abab51ab5263abab45533aa242c61bca90dd15d46079a0ab0841d85df67b29ba87f2393cd764a6997c372b55030000000452005263ffffffff0250f40e02000000000651516a0063630e95ab0000000000046a5151ac00000000", "6a65005151", 0, -1460947095, "aa418d096929394c9147be8818d8c9dafe6d105945ab9cd7ec682df537b5dd79"],
+ ["2b3bd0dd04a1832f893bf49a776cd567ec4b43945934f4786b615d6cb850dfc0349b33301a000000000565ac000051cf80c670f6ddafab63411adb4d91a69c11d9ac588898cbfb4cb16061821cc104325c895103000000025163ffffffffa9e2d7506d2d7d53b882bd377bbcc941f7a0f23fd15d2edbef3cd9df8a4c39d10200000009ac63006a52526a5265ffffffff44c099cdf10b10ce87d4b38658d002fd6ea17ae4a970053c05401d86d6e75f99000000000963ab53526a5252ab63ffffffff035af69c01000000000100ba9b8b0400000000004cead10500000000026a520b77d667", "ab52abac526553", 3, -1955078165, "eb9ceecc3b401224cb79a44d23aa8f428e29f1405daf69b4e01910b848ef1523"],
+ ["35df11f004a48ba439aba878fe9df20cc935b4a761c262b1b707e6f2b33e2bb7565cd68b130000000000ffffffffb2a2f99abf64163bb57ca900500b863f40c02632dfd9ea2590854c5fb4811da90200000006ac006363636affffffffaf9d89b2a8d2670ca37c8f7c140600b81259f2e037cb4590578ec6e37af8bf200000000005abac6a655270a4751eb551f058a93301ffeda2e252b6614a1fdd0e283e1d9fe53c96c5bbaafaac57b8030000000153ffffffff020d9f3b02000000000100ed7008030000000004abac000000000000", "abac", 3, 593793071, "88fdee1c2d4aeead71d62396e28dc4d00e5a23498eea66844b9f5d26d1f21042"],
+ ["a08ff466049fb7619e25502ec22fedfb229eaa1fe275aa0b5a23154b318441bf547989d0510000000005ab5363636affffffff2b0e335cb5383886751cdbd993dc0720817745a6b1c9b8ab3d15547fc9aafd03000000000965656a536a52656a532b53d10584c290d3ac1ab74ab0a19201a4a039cb59dc58719821c024f6bf2eb26322b33f010000000965ac6aac0053ab6353ffffffff048decba6ebbd2db81e416e39dde1f821ba69329725e702bcdea20c5cc0ecc6402000000086363ab5351ac6551466e377b0468c0fa00000000000651ab53ac6a513461c6010000000008636a636365535100eeb3dc010000000006526a52ac516a43f362010000000005000063536500000000", "0063516a", 1, -1158911348, "f6a1ecb50bd7c2594ebecea5a1aa23c905087553e40486dade793c2f127fdfae"],
+ ["5ac2f17d03bc902e2bac2469907ec7d01a62b5729340bc58c343b7145b66e6b97d434b30fa000000000163ffffffff44028aa674192caa0d0b4ebfeb969c284cb16b80c312d096efd80c6c6b094cca000000000763acabac516a52ffffffff10c809106e04b10f9b43085855521270fb48ab579266e7474657c6c625062d2d030000000351636595a0a97004a1b69603000000000465ab005352ad68010000000008636a5263acac5100da7105010000000002acab90325200000000000000000000", "6a6aab516a63526353", 2, 1518400956, "f7efb74b1dcc49d316b49c632301bc46f98d333c427e55338be60c7ef0d953be"],
+ ["aeb2e11902dc3770c218b97f0b1960d6ee70459ecb6a95eff3f05295dc1ef4a0884f10ba460300000005516352526393e9b1b3e6ae834102d699ddd3845a1e159aa7cf7635edb5c02003f7830fee3788b795f20100000009ab006a526553ac006ad8809c570469290e0400000000050000abab00b10fd5040000000008ab655263abac53ab630b180300000000009d9993040000000002516300000000", "5351ababac6a65", 0, 1084852870, "f2286001af0b0170cbdad92693d0a5ebaa8262a4a9d66e002f6d79a8c94026d1"],
+ ["9860ca9a0294ff4812534def8c3a3e3db35b817e1a2ddb7f0bf673f70eab71bb79e90a2f3100000000086a636551acac5165ffffffffed4d6d3cd9ff9b2d490e0c089739121161a1445844c3e204296816ab06e0a83702000000035100ac88d0db5201c3b59a050000000005ac6a0051ab00000000", "535263ab006a526aab", 1, -962088116, "30df2473e1403e2b8e637e576825f785528d998af127d501556e5f7f5ed89a2a"],
+ ["4ddaa680026ec4d8060640304b86823f1ac760c260cef81d85bd847952863d629a3002b54b0200000008526365636a656aab65457861fc6c24bdc760c8b2e906b6656edaf9ed22b5f50e1fb29ec076ceadd9e8ebcb6b000000000152ffffffff033ff04f00000000000551526a00657a1d900300000000002153af040000000003006a6300000000", "ab526a53acabab", 0, 1055317633, "7f21b62267ed52462e371a917eb3542569a4049b9dfca2de3c75872b39510b26"],
+ ["01e76dcd02ad54cbc8c71d68eaf3fa7c883b65d74217b30ba81f1f5144ef80b706c0dc82ca000000000352ab6a078ec18bcd0514825feced2e8b8ea1ccb34429fae41c70cc0b73a2799e85603613c6870002000000086363ab6365536a53ffffffff043acea90000000000016ad20e1803000000000100fa00830200000000056352515351e864ee00000000000865535253ab6a6551d0c46672", "6a6365abacab", 0, -1420559003, "8af0b4cbdbc011be848edf4dbd2cde96f0578d662cfebc42252495387114224a"],
+ ["fa00b26402670b97906203434aa967ce1559d9bd097d56dbe760469e6032e7ab61accb54160100000006635163630052fffffffffe0d3f4f0f808fd9cfb162e9f0c004601acf725cd7ea5683bbdc9a9a433ef15a0200000005ab52536563d09c7bef049040f305000000000153a7c7b9020000000004ac63ab52847a2503000000000553ab00655390ed80010000000005006553ab52860671d4", "536565ab52", 0, 799022412, "40ed8e7bbbd893e15f3cce210ae02c97669818de5946ca37eefc7541116e2c78"],
+ ["cb5c06dc01b022ee6105ba410f0eb12b9ce5b5aa185b28532492d839a10cef33d06134b91b010000000153ffffffff02cec0530400000000005e1e4504000000000865656551acacac6a00000000", "ab53", 0, -1514251329, "136beb95459fe6b126cd6cefd54eb5d971524b0e883e41a292a78f78015cb8d5"],
+ ["f10a0356031cd569d652dbca8e7a4d36c8da33cdff428d003338602b7764fe2c96c505175b010000000465ac516affffffffbb54563c71136fa944ee20452d78dc87073ac2365ba07e638dce29a5d179da600000000003635152ffffffff9a411d8e2d421b1e6085540ee2809901e590940bbb41532fa38bd7a16b68cc350100000007535251635365636195df1603b61c45010000000002ab65bf6a310400000000026352fcbba10200000000016aa30b7ff0", "5351", 0, 1552495929, "9eb8adf2caecb4bf9ac59d7f46bd20e83258472db2f569ee91aba4cf5ee78e29"],
+ ["c3325c9b012f659466626ca8f3c61dfd36f34670abc054476b7516a1839ec43cd0870aa0c0000000000753525265005351e7e3f04b0112650500000000000363ac6300000000", "acac", 0, -68961433, "5ca70e727d91b1a42b78488af2ed551642c32d3de4712a51679f60f1456a8647"],
+ ["2333e54c044370a8af16b9750ac949b151522ea6029bacc9a34261599549581c7b4e5ece470000000007510052006563abffffffff80630fc0155c750ce20d0ca4a3d0c8e8d83b014a5b40f0b0be0dd4c63ac28126020000000465000000ffffffff1b5f1433d38cdc494093bb1d62d84b10abbdae57e3d04e82e600857ab3b1dc990300000003515100b76564be13e4890a908ea7508afdad92ec1b200a9a67939fadce6eb7a29eb4550a0a28cb0300000001acffffffff02926c930300000000016373800201000000000153d27ee740", "ab6365ab516a53", 3, 598653797, "2be27a686eb7940dd32c44ff3a97c1b28feb7ab9c5c0b1593b2d762361cfc2db"],
+ ["b500ca48011ec57c2e5252e5da6432089130603245ffbafb0e4c5ffe6090feb629207eeb0e010000000652ab6a636aab8302c9d2042b44f40500000000015278c05a050000000004ac5251524be080020000000007636aac63ac5252c93a9a04000000000965ab6553636aab5352d91f9ddb", "52005100", 0, -2024394677, "49c8a6940a461cc7225637f1e512cdd174c99f96ec05935a59637ededc77124c"],
+ ["f52ff64b02ee91adb01f3936cc42e41e1672778962b68cf013293d649536b519bc3271dd2c00000000020065afee11313784849a7c15f44a61cd5fd51ccfcdae707e5896d131b082dc9322a19e12858501000000036aac654e8ca882022deb7c020000000006006a515352abd3defc0000000000016300000000", "63520063", 0, 1130989496, "7f208df9a5507e98c62cebc5c1e2445eb632e95527594929b9577b53363e96f6"],
+ ["ab7d6f36027a7adc36a5cf7528fe4fb5d94b2c96803a4b38a83a675d7806dda62b380df86a0000000003000000ffffffff5bc00131e29e22057c04be854794b4877dda42e416a7a24706b802ff9da521b20000000007ac6a0065ac52ac957cf45501b9f06501000000000500ac6363ab25f1110b", "00526500536a635253", 0, 911316637, "5fa09d43c8aef6f6fa01c383a69a5a61a609cd06e37dce35a39dc9eae3ddfe6c"],
+ ["f940888f023dce6360263c850372eb145b864228fdbbb4c1186174fa83aab890ff38f8c9a90300000000ffffffff01e80ccdb081e7bbae1c776531adcbfb77f2e5a7d0e5d0d0e2e6c8758470e85f00000000020053ffffffff03b49088050000000004656a52ab428bd604000000000951630065ab63ac636a0cbacf0400000000070063ac5265ac53d6e16604", "ac63", 0, 39900215, "713ddeeefcfe04929e7b6593c792a4efbae88d2b5280d1f0835d2214eddcbad6"],
+ ["530ecd0b01ec302d97ef6f1b5a6420b9a239714013e20d39aa3789d191ef623fc215aa8b940200000005ac5351ab6a3823ab8202572eaa04000000000752ab6a51526563fd8a270100000000036a006581a798f0", "525153656a0063", 0, 1784562684, "fe42f73a8742676e640698222b1bd6b9c338ff1ccd766d3d88d7d3c6c6ac987e"],
+ ["5d781d9303acfcce964f50865ddfddab527ea971aee91234c88e184979985c00b4de15204b0100000003ab6352a009c8ab01f93c8ef2447386c434b4498538f061845862c3f9d5751ad0fce52af442b3a902000000045165ababb909c66b5a3e7c81b3c45396b944be13b8aacfc0204f3f3c105a66fa8fa6402f1b5efddb01000000096a65ac636aacab656ac3c677c402b79fa4050000000004006aab5133e35802000000000751ab635163ab0078c2e025", "6aac51636a6a005265", 0, -882306874, "551ce975d58647f10adefb3e529d9bf9cda34751627ec45e690f135ef0034b95"],
+ ["25ee54ef0187387564bb86e0af96baec54289ca8d15e81a507a2ed6668dc92683111dfb7a50100000004005263634cecf17d0429aa4d000000000007636a6aabab5263daa75601000000000251ab4df70a01000000000151980a890400000000065253ac6a006377fd24e3", "65ab", 0, 797877378, "069f38fd5d47abff46f04ee3ae27db03275e9aa4737fa0d2f5394779f9654845"],
+ ["a9c57b1a018551bcbc781b256642532bbc09967f1cbe30a227d352a19365d219d3f11649a3030000000451655352b140942203182894030000000006ab00ac6aab654add350400000000003d379505000000000553abacac00e1739d36", "5363", 0, -1069721025, "6da32416deb45a0d720a1dbe6d357886eabc44029dd5db74d50feaffbe763245"],
+ ["05c4fb94040f5119dc0b10aa9df054871ed23c98c890f1e931a98ffb0683dac45e98619fdc0200000007acab6a525263513e7495651c9794c4d60da835d303eb4ee6e871f8292f6ad0b32e85ef08c9dc7aa4e03c9c010000000500ab52acacfffffffffee953259cf14ced323fe8d567e4c57ba331021a1ef5ac2fa90f7789340d7c550100000007ac6aacac6a6a53ffffffff08d9dc820d00f18998af247319f9de5c0bbd52a475ea587f16101af3afab7c210100000003535363569bca7c0468e34f00000000000863536353ac51ac6584e319010000000006650052ab6a533debea030000000003ac0053ee7070020000000006ac52005253ac00000000", "6351005253", 2, 1386916157, "76c4013c40bfa1481badd9d342b6d4b8118de5ab497995fafbf73144469e5ff0"],
+ ["c95ab19104b63986d7303f4363ca8f5d2fa87c21e3c5d462b99f1ebcb7c402fc012f5034780000000009006aac63ac65655265ffffffffbe91afa68af40a8700fd579c86d4b706c24e47f7379dad6133de389f815ef7f501000000046aac00abffffffff1520db0d81be4c631878494668d258369f30b8f2b7a71e257764e9a27f24b48701000000076a515100535300b0a989e1164db9499845bac01d07a3a7d6d2c2a76e4c04abe68f808b6e2ef5068ce6540e0100000009ac53636a63ab65656affffffff0309aac6050000000005ab6563656a6067e8020000000003ac536aec91c8030000000009655251ab65ac6a53acc7a45bc5", "63526a65abac", 1, 512079270, "fb7eca81d816354b6aedec8cafc721d5b107336657acafd0d246049556f9e04b"],
+ ["ca66ae10049533c2b39f1449791bd6d3f039efe0a121ab7339d39ef05d6dcb200ec3fb2b3b020000000465006a53ffffffff534b8f97f15cc7fb4f4cea9bf798472dc93135cd5b809e4ca7fe4617a61895980100000000ddd83c1dc96f640929dd5e6f1151dab1aa669128591f153310d3993e562cc7725b6ae3d903000000046a52536582f8ccddb8086d8550f09128029e1782c3f2624419abdeaf74ecb24889cc45ac1a64492a0100000002516a4867b41502ee6ccf03000000000752acacab52ab6a4b7ba80000000000075151ab0052536300000000", "6553", 2, -62969257, "8085e904164ab9a8c20f58f0d387f6adb3df85532e11662c03b53c3df8c943cb"],
+ ["ba646d0b0453999f0c70cb0430d4cab0e2120457bb9128ed002b6e9500e9c7f8d7baa20abe0200000001652a4e42935b21db02b56bf6f08ef4be5adb13c38bc6a0c3187ed7f6197607ba6a2c47bc8a03000000040052516affffffffa55c3cbfc19b1667594ac8681ba5d159514b623d08ed4697f56ce8fcd9ca5b0b00000000096a6a5263ac655263ab66728c2720fdeabdfdf8d9fb2bfe88b295d3b87590e26a1e456bad5991964165f888c03a0200000006630051ac00acffffffff0176fafe0100000000070063acac65515200000000", "63", 1, 2002322280, "9db4e320208185ee70edb4764ee195deca00ba46412d5527d9700c1cf1c3d057"],
+ ["2ddb8f84039f983b45f64a7a79b74ff939e3b598b38f436def7edd57282d0803c7ef34968d02000000026a537eb00c4187de96e6e397c05f11915270bcc383959877868ba93bac417d9f6ed9f627a7930300000004516551abffffffffacc12f1bb67be3ae9f1d43e55fda8b885340a0df1175392a8bbd9f959ad3605003000000025163ffffffff02ff0f4700000000000070bd99040000000003ac53abf8440b42", "", 2, -393923011, "0133f1a161363b71dfb3a90065c7128c56bd0028b558b610142df79e055ab5c7"],
+ ["b21fc15403b4bdaa994204444b59323a7b8714dd471bd7f975a4e4b7b48787e720cbd1f5f00000000000ffffffff311533001cb85c98c1d58de0a5fbf27684a69af850d52e22197b0dc941bc6ca9030000000765ab6363ab5351a8ae2c2c7141ece9a4ff75c43b7ea9d94ec79b7e28f63e015ac584d984a526a73fe1e04e0100000007526352536a5365ffffffff02a0a9ea030000000002ab52cfc4f300000000000465525253e8e0f342", "000000", 1, 1305253970, "d1df1f4bba2484cff8a816012bb6ec91c693e8ca69fe85255e0031711081c46a"],
+ ["d1704d6601acf710b19fa753e307cfcee2735eada0d982b5df768573df690f460281aad12d0000000007656300005100acffffffff0232205505000000000351ab632ca1bc0300000000016300000000", "ac65ab65ab51", 0, 165179664, "40b4f03c68288bdc996011b0f0ddb4b48dc3be6762db7388bdc826113266cd6c"],
+ ["d2f6c096025cc909952c2400bd83ac3d532bfa8a1f8f3e73c69b1fd7b8913379793f3ce92202000000076a00ab6a53516ade5332d81d58b22ed47b2a249ab3a2cb3a6ce9a6b5a6810e18e3e1283c1a1b3bd73e3ab00300000002acabffffffff01a9b2d40500000000056352abab00dc4b7f69", "ab0065", 0, -78019184, "2ef025e907f0fa454a2b48a4f3b81346ba2b252769b5c35d742d0c8985e0bf5e"],
+ ["3e6db1a1019444dba461247224ad5933c997256d15c5d37ade3d700506a0ba0a57824930d7010000000852ab6500ab00ac00ffffffff03389242020000000001aba8465a0200000000086a6a636a5100ab52394e6003000000000953ac51526351000053d21d9800", "abababacab53ab65", 0, 1643661850, "1f8a3aca573a609f4aea0c69522a82fcb4e15835449da24a05886ddc601f4f6a"],
+ ["f821a042036ad43634d29913b77c0fc87b4af593ac86e9a816a9d83fd18dfcfc84e1e1d57102000000076a63ac52006351ffffffffbcdaf490fc75086109e2f832c8985716b3a624a422cf9412fe6227c10585d21203000000095252abab5352ac526affffffff2efed01a4b73ad46c7f7bc7fa3bc480f8e32d741252f389eaca889a2e9d2007e000000000353ac53ffffffff032ac8b3020000000009636300000063516300d3d9f2040000000006510065ac656aafa5de0000000000066352ab5300ac9042b57d", "525365", 1, 667065611, "0d17a92c8d5041ba09b506ddf9fd48993be389d000aad54f9cc2a44fcc70426b"],
+ ["58e3f0f704a186ef55d3919061459910df5406a9121f375e7502f3be872a449c3f2bb058380100000000f0e858da3ac57b6c973f889ad879ffb2bd645e91b774006dfa366c74e2794aafc8bbc871010000000751ac65516a515131a68f120fd88ca08687ceb4800e1e3fbfea7533d34c84fef70cc5a96b648d580369526d000000000600ac00515363f6191d5b3e460fa541a30a6e83345dedfa3ed31ad8574d46d7bbecd3c9074e6ba5287c24020000000151e3e19d6604162602010000000004005100ac71e17101000000000065b5e90300000000040053ab53f6b7d101000000000200ac00000000", "6563ab", 1, -669018604, "8221d5dfb75fc301a80e919e158e0b1d1e86ffb08870a326c89408d9bc17346b"],
+ ["efec1cce044a676c1a3d973f810edb5a9706eb4cf888a240f2b5fb08636bd2db482327cf500000000005ab51656a52ffffffff46ef019d7c03d9456e5134eb0a7b5408d274bd8e33e83df44fab94101f7c5b650200000009ac5100006353630051407aadf6f5aaffbd318fdbbc9cae4bd883e67d524df06bb006ce2f7c7e2725744afb76960100000005536aab53acec0d64eae09e2fa1a7c4960354230d51146cf6dc45ee8a51f489e20508a785cbe6ca86fc000000000651536a516300ffffffff014ef598020000000006636aac655265a6ae1b75", "53516a5363526563ab", 2, -1823982010, "13e8b5ab4e5b2ceeff0045c625e19898bda2d39fd7af682e2d1521303cfe1154"],
+ ["3c436c2501442a5b700cbc0622ee5143b34b1b8021ea7bbc29e4154ab1f5bdfb3dff9d640501000000086aab5251ac5252acffffffff0170b9a20300000000066aab6351525114b13791", "63acabab52ab51ac65", 0, -2140612788, "87ddf1f9acb6640448e955bd1968f738b4b3e073983af7b83394ab7557f5cd61"],
+ ["d62f183e037e0d52dcf73f9b31f70554bce4f693d36d17552d0e217041e01f15ad3840c838000000000963acac6a6a6a63ab63ffffffffabdfb395b6b4e63e02a763830f536fc09a35ff8a0cf604021c3c751fe4c88f4d0300000006ab63ab65ac53aa4d30de95a2327bccf9039fb1ad976f84e0b4a0936d82e67eafebc108993f1e57d8ae39000000000165ffffffff04364ad30500000000036a005179fd84010000000007ab636aac6363519b9023030000000008510065006563ac6acd2a4a02000000000000000000", "52", 1, 595020383, "da8405db28726dc4e0f82b61b2bfd82b1baa436b4e59300305cc3b090b157504"],
+ ["44c200a5021238de8de7d80e7cce905606001524e21c8d8627e279335554ca886454d692e6000000000500acac52abbb8d1dc876abb1f514e96b21c6e83f429c66accd961860dc3aed5071e153e556e6cf076d02000000056553526a51870a928d0360a580040000000004516a535290e1e302000000000851ab6a00510065acdd7fc5040000000007515363ab65636abb1ec182", "6363", 0, -785766894, "ed53cc766cf7cb8071cec9752460763b504b2183442328c5a9761eb005c69501"],
+ ["d682d52d034e9b062544e5f8c60f860c18f029df8b47716cabb6c1b4a4b310a0705e754556020000000400656a0016eeb88eef6924fed207fba7ddd321ff3d84f09902ff958c815a2bf2bb692eb52032c4d803000000076365ac516a520099788831f8c8eb2552389839cfb81a9dc55ecd25367acad4e03cfbb06530f8cccf82802701000000085253655300656a53ffffffff02d543200500000000056a510052ac03978b05000000000700ac51525363acfdc4f784", "", 2, -696035135, "e1a256854099907050cfee7778f2018082e735a1f1a3d91437584850a74c87bb"],
+ ["e8c0dec5026575ddf31343c20aeeca8770afb33d4e562aa8ee52eeda6b88806fdfd4fe0a97030000000953acabab65ab516552ffffffffdde122c2c3e9708874286465f8105f43019e837746686f442666629088a970e0010000000153ffffffff01f98eee0100000000025251fe87379a", "63", 1, 633826334, "abe441209165d25bc6d8368f2e7e7dc21019056719fef1ace45542aa2ef282e2"],
+ ["b288c331011c17569293c1e6448e33a64205fc9dc6e35bc756a1ac8b97d18e912ea88dc0770200000007635300ac6aacabfc3c890903a3ccf8040000000004656500ac9c65c9040000000009ab6a6aabab65abac63ac5f7702000000000365005200000000", "526a63", 0, 1574937329, "0dd1bd5c25533bf5f268aa316ce40f97452cca2061f0b126a59094ca5b65f7a0"],
+ ["fc0a092003cb275fa9a25a72cf85d69c19e4590bfde36c2b91cd2c9c56385f51cc545530210000000004ab530063ffffffff729b006eb6d14d6e5e32b1c376acf1c62830a5d9246da38dbdb4db9f51fd1c74020000000463636500ffffffff0ae695c6d12ab7dcb8d3d4b547b03f178c7268765d1de9af8523d244e3836b12030000000151ffffffff0115c1e20100000000066a6aabac6a6a1ff59aec", "ab0053ac", 0, 931831026, "73fe22099c826c34a74edf45591f5d7b3a888c8178cd08facdfd96a9a681261c"],
+ ["0fcae7e004a71a4a7c8f66e9450c0c1785268679f5f1a2ee0fb3e72413d70a9049ecff75de020000000452005251ffffffff99c8363c4b95e7ec13b8c017d7bb6e80f7c04b1187d6072961e1c2479b1dc0320200000000ffffffff7cf03b3d66ab53ed740a70c5c392b84f780fff5472aee82971ac3bfeeb09b2df0200000006ab5265636a0058e4fe9257d7c7c7e82ff187757c6eadc14cceb6664dba2de03a018095fd3006682a5b9600000000056353536a636de26b2303ff76de010000000001acdc0a2e020000000001ab0a53ed020000000007530063ab51510088417307", "ac6aacab5165535253", 2, -902160694, "eea96a48ee572aea33d75d0587ce954fcfb425531a7da39df26ef9a6635201be"],
+ ["612701500414271138e30a46b7a5d95c70c78cc45bf8e40491dac23a6a1b65a51af04e6b94020000000451655153ffffffffeb72dc0e49b2fad3075c19e1e6e4b387f1365dca43d510f6a02136318ddecb7f0200000003536352e115ffc4f9bae25ef5baf534a890d18106fb07055c4d7ec9553ba89ed1ac2101724e507303000000080063006563acabac2ff07f69a080cf61a9d19f868239e6a4817c0eeb6a4f33fe254045d8af2bca289a8695de0300000000430736c404d317840500000000086a00abac5351ab65306e0503000000000963ab0051536aabab6a6c8aca01000000000565516351ab5dcf960100000000016a00000000", "ab", 2, -604581431, "5ec805e74ee934aa815ca5f763425785ae390282d46b5f6ea076b6ad6255a842"],
+ ["6b68ba00023bb4f446365ea04d68d48539aae66f5b04e31e6b38b594d2723ab82d44512460000000000200acffffffff5dfc6febb484fff69c9eeb7c7eb972e91b6d949295571b8235b1da8955f3137b020000000851ac6352516a535325828c8a03365da801000000000800636aabac6551ab0f594d03000000000963ac536365ac63636a45329e010000000005abac53526a00000000", "005151", 0, 1317038910, "42f5ba6f5fe1e00e652a08c46715871dc4b40d89d9799fd7c0ea758f86eab6a7"],
+ ["aff5850c0168a67296cc790c1b04a9ed9ad1ba0469263a9432fcb53676d1bb4e0eea8ea1410100000005ac65526a537d5fcb1d01d9c26d0200000000065265ab5153acc0617ca1", "51ab650063", 0, 1712981774, "8449d5247071325e5f8edcc93cb9666c0fecabb130ce0e5bef050575488477eb"],
+ ["e6d6b9d8042c27aec99af8c12b6c1f7a80453e2252c02515e1f391da185df0874e133696b50300000006ac5165650065ffffffff6a4b60a5bfe7af72b198eaa3cde2e02aa5fa36bdf5f24ebce79f6ecb51f3b554000000000652656aababac2ec4c5a6cebf86866b1fcc4c5bd5f4b19785a8eea2cdfe58851febf87feacf6f355324a80100000001537100145149ac1e287cef62f6f5343579189fad849dd33f25c25bfca841cb696f10c5a34503000000046a636a63df9d7c4c018d96e20100000000015100000000", "53ab", 1, -1924777542, "f98f95d0c5ec3ac3e699d81f6c440d2e7843eab15393eb023bc5a62835d6dcea"],
+ ["046ac25e030a344116489cc48025659a363da60bc36b3a8784df137a93b9afeab91a04c1ed020000000951ab0000526a65ac51ffffffff6c094a03869fde55b9a8c4942a9906683f0a96e2d3e5a03c73614ea3223b2c29020000000500ab636a6affffffff3da7aa5ecef9071600866267674b54af1740c5aeb88a290c459caa257a2683cb0000000004ab6565ab7e2a1b900301b916030000000005abac63656308f4ed03000000000852ab53ac63ac51ac73d620020000000003ab00008deb1285", "6a", 2, 1299505108, "f79e6b776e2592bad45ca328c54abf14050c241d8f822d982c36ea890fd45757"],
+ ["bd515acd0130b0ac47c2d87f8d65953ec7d657af8d96af584fc13323d0c182a2e5f9a96573000000000652ac51acac65ffffffff0467aade000000000003655363dc577d050000000006515252ab5300137f60030000000007535163530065004cdc860500000000036a5265241bf53e", "acab", 0, 621090621, "771d4d87f1591a13d77e51858c16d78f1956712fe09a46ff1abcabbc1e7af711"],
+ ["ff1ae37103397245ac0fa1c115b079fa20930757f5b6623db3579cb7663313c2dc4a3ffdb300000000076353656a000053ffffffff83c59e38e5ad91216ee1a312d15b4267bae2dd2e57d1a3fd5c2f0f809eeb5d46010000000800abab6a6a53ab51ffffffff9d5e706c032c1e0ca75915f8c6686f64ec995ebcd2539508b7dd8abc3e4d7d2a01000000006b2bdcda02a8fe070500000000045253000019e31d04000000000700ab63acab526a00000000", "53656aab6a525251", 0, 881938872, "726bb88cdf3af2f7603a31f33d2612562306d08972a4412a55dbbc0e3363721c"],
+ ["ff5400dd02fec5beb9a396e1cbedc82bedae09ed44bae60ba9bef2ff375a6858212478844b03000000025253ffffffff01e46c203577a79d1172db715e9cc6316b9cfc59b5e5e4d9199fef201c6f9f0f000000000900ab6552656a5165acffffffff02e8ce62040000000002515312ce3e00000000000251513f119316", "", 0, 1541581667, "1e0da47eedbbb381b0e0debbb76e128d042e02e65b11125e17fd127305fc65cd"],
+ ["28e3daa603c03626ad91ffd0ff927a126e28d29db5012588b829a06a652ea4a8a5732407030200000004ab6552acffffffff8e643146d3d0568fc2ad854fd7864d43f6f16b84e395db82b739f6f5c84d97b40000000004515165526b01c2dc1469db0198bd884e95d8f29056c48d7e74ff9fd37a9dec53e44b8769a6c99c030200000009ab006a516a53630065eea8738901002398000000000007ac5363516a51abeaef12f5", "52ab52515253ab", 2, 1687390463, "55591346aec652980885a558cc5fc2e3f8d21cbd09f314a798e5a7ead5113ea6"],
+ ["b54bf5ac043b62e97817abb892892269231b9b220ba08bc8dbc570937cd1ea7cdc13d9676c010000000451ab5365a10adb7b35189e1e8c00b86250f769319668189b7993d6bdac012800f1749150415b2deb0200000003655300ffffffff60b9f4fb9a7e17069fd00416d421f804e2ef2f2c67de4ca04e0241b9f9c1cc5d0200000003ab6aacfffffffff048168461cce1d40601b42fbc5c4f904ace0d35654b7cc1937ccf53fe78505a0100000008526563525265abacffffffff01dbf4e6040000000007acac656553636500000000", "63", 2, 882302077, "f5b38b0f06e246e47ce622e5ee27d5512c509f8ac0e39651b3389815eff2ab93"],
+ ["ebf628b30360bab3fa4f47ce9e0dcbe9ceaf6675350e638baff0c2c197b2419f8e4fb17e16000000000452516365ac4d909a79be207c6e5fb44fbe348acc42fc7fe7ef1d0baa0e4771a3c4a6efdd7e2c118b0100000003acacacffffffffa6166e9101f03975721a3067f1636cc390d72617be72e5c3c4f73057004ee0ee010000000863636a6a516a5252c1b1e82102d8d54500000000000153324c900400000000015308384913", "0063516a51", 1, -1658428367, "eb2d8dea38e9175d4d33df41f4087c6fea038a71572e3bad1ea166353bf22184"],
+ ["d6a8500303f1507b1221a91adb6462fb62d741b3052e5e7684ea7cd061a5fc0b0e93549fa50100000004acab65acfffffffffdec79bf7e139c428c7cfd4b35435ae94336367c7b5e1f8e9826fcb0ebaaaea30300000000ffffffffd115fdc00713d52c35ea92805414bd57d1e59d0e6d3b79a77ee18a3228278ada020000000453005151ffffffff040231510300000000085100ac6a6a000063c6041c0400000000080000536a6563acac138a0b04000000000263abd25fbe03000000000900656a00656aac510000000000", "ac526aac6a00", 1, -2007972591, "13d12a51598b34851e7066cd93ab8c5212d60c6ed2dae09d91672c10ccd7f87c"],
+ ["658cb1c1049564e728291a56fa79987a4ed3146775fce078bd2e875d1a5ca83baf6166a82302000000056a656351ab2170e7d0826cbdb45fda0457ca7689745fd70541e2137bb4f52e7b432dcfe2112807bd720300000007006a0052536351ffffffff8715ca2977696abf86d433d5c920ef26974f50e9f4a20c584fecbb68e530af5101000000009e49d864155bf1d3c757186d29f3388fd89c7f55cc4d9158b4cf74ca27a35a1dd93f945502000000096a535353ac656351510d29fa870230b809040000000006ab6a6a526a633b41da050000000004ab6a6a65ed63bf62", "52acabac", 2, -1774073281, "53ab197fa7e27b8a3f99ff48305e67081eb90e95d89d7e92d80cee25a03a6689"],
+ ["e92492cc01aec4e62df67ea3bc645e2e3f603645b3c5b353e4ae967b562d23d6e043badecd0100000003acab65ffffffff02c7e5ea040000000002ab52e1e584010000000005536365515195d16047", "6551", 0, -424930556, "93c34627f526d73f4bea044392d1a99776b4409f7d3d835f23b03c358f5a61c2"],
+ ["02e242db04be2d8ced9179957e98cee395d4767966f71448dd084426844cbc6d15f2182e85030000000200650c8ffce3db9de9c3f9cdb9104c7cb26647a7531ad1ebf7591c259a9c9985503be50f8de30000000007ac6a51636a6353ffffffffa2e33e7ff06fd6469987ddf8a626853dbf30c01719efb259ae768f051f803cd30300000000fffffffffd69d8aead941683ca0b1ee235d09eade960e0b1df3cd99f850afc0af1b73e070300000001ab60bb602a011659670100000000076363526300acac00000000", "6353ab515251", 3, 1451100552, "bbc9069b8615f3a52ac8a77359098dcc6c1ba88c8372d5d5fe080b99eb781e55"],
+ ["b28d5f5e015a7f24d5f9e7b04a83cd07277d452e898f78b50aae45393dfb87f94a26ef57720200000008ababac630053ac52ffffffff046475ed040000000008ab5100526363ac65c9834a04000000000251abae26b30100000000040000ac65ceefb900000000000000000000", "ac6551ac6a536553", 0, -1756558188, "5848d93491044d7f21884eef7a244fe7d38886f8ae60df49ce0dfb2a342cd51a"],
+ ["efb8b09801f647553b91922a5874f8e4bb2ed8ddb3536ed2d2ed0698fac5e0e3a298012391030000000952ac005263ac52006affffffff04cdfa0f050000000007ac53ab51abac65b68d1b02000000000553ab65ac00d057d50000000000016a9e1fda010000000007ac63ac536552ac00000000", "6aac", 0, 1947322973, "603a9b61cd30fcea43ef0a5c18b88ca372690b971b379ee9e01909c336280511"],
+ ["68a59fb901c21946797e7d07a4a3ea86978ce43df0479860d7116ac514ba955460bae78fff0000000001abffffffff03979be80100000000036553639300bc040000000008006552006a656565cfa78d0000000000076552acab63ab5100000000", "ab65ab", 0, 995583673, "3b320dd47f2702452a49a1288bdc74a19a4b849b132b6cad9a1d945d87dfbb23"],
+ ["67761f2a014a16f3940dcb14a22ba5dc057fcffdcd2cf6150b01d516be00ef55ef7eb07a830100000004636a6a51ffffffff01af67bd050000000008526553526300510000000000", "6a00", 0, 1570943676, "079fa62e9d9d7654da8b74b065da3154f3e63c315f25751b4d896733a1d67807"],
+ ["e20fe96302496eb436eee98cd5a32e1c49f2a379ceb71ada8a48c5382df7c8cd88bdc47ced03000000016556aa0e180660925a841b457aed0aae47fca2a92fa1d7afeda647abf67198a3902a7c80dd00000000085152ac636a535265bd18335e01803c810100000000046500ac52f371025e", "6363ab", 1, -651254218, "2921a0e5e3ba83c57ba57c25569380c17986bf34c366ec216d4188d5ba8b0b47"],
+ ["4e1bd9fa011fe7aa14eee8e78f27c9fde5127f99f53d86bc67bdab23ca8901054ee8a8b6eb0300000009ac535153006a6a0063ffffffff044233670500000000000a667205000000000652ab636a51abe5bf35030000000003535351d579e505000000000700630065ab51ac3419ac30", "52abac52", 0, -1807563680, "4aae6648f856994bed252d319932d78db55da50d32b9008216d5366b44bfdf8a"],
+ ["ec02fbee03120d02fde12574649660c441b40d330439183430c6feb404064d4f507e704f3c0100000000ffffffffe108d99c7a4e5f75cc35c05debb615d52fac6e3240a6964a29c1704d98017fb60200000002ab63fffffffff726ec890038977adfc9dadbeaf5e486d5fcb65dc23acff0dd90b61b8e2773410000000002ac65e9dace55010f881b010000000005ac00ab650000000000", "51ac525152ac6552", 2, -1564046020, "3f988922d8cd11c7adff1a83ce9499019e5ab5f424752d8d361cf1762e04269b"],
+ ["23dbdcc1039c99bf11938d8e3ccec53b60c6c1d10c8eb6c31197d62c6c4e2af17f52115c3a0300000008636352000063ababffffffff17823880e1df93e63ad98c29bfac12e36efd60254346cac9d3f8ada020afc0620300000003ab63631c26f002ac66e86cd22a25e3ed3cb39d982f47c5118f03253054842daadc88a6c41a2e1500000000096a00ab636a53635163195314de015570fd0100000000096a5263acab5200005300000000", "ababac6a6553", 1, 11586329, "bd36a50e0e0a4ecbf2709e68daef41eddc1c0c9769efaee57910e99c0a1d1343"],
+ ["33b03bf00222c7ca35c2f8870bbdef2a543b70677e413ce50494ac9b22ea673287b6aa55c50000000005ab00006a52ee4d97b527eb0b427e4514ea4a76c81e68c34900a23838d3e57d0edb5410e62eeb8c92b6000000000553ac6aacac42e59e170326245c000000000009656553536aab516aabb1a10603000000000852ab52ab6a516500cc89c802000000000763ac6a63ac516300000000", "", 0, 557416556, "41bead1b073e1e9fee065dd612a617ca0689e8f9d3fed9d0acfa97398ebb404c"],
+ ["813eda1103ac8159850b4524ef65e4644e0fc30efe57a5db0c0365a30446d518d9b9aa8fdd0000000003656565c2f1e89448b374b8f12055557927d5b33339c52228f7108228149920e0b77ef0bcd69da60000000006abac00ab63ab82cdb7978d28630c5e1dc630f332c4245581f787936f0b1e84d38d33892141974c75b4750300000004ac53ab65ffffffff0137edfb02000000000000000000", "0063", 1, -1948560575, "71dfcd2eb7f2e6473aed47b16a6d5fcbd0af22813d892e9765023151e07771ec"],
+ ["9e45d9aa0248c16dbd7f435e8c54ae1ad086de50c7b25795a704f3d8e45e1886386c653fbf01000000025352fb4a1acefdd27747b60d1fb79b96d14fb88770c75e0da941b7803a513e6d4c908c6445c7010000000163ffffffff014069a8010000000001520a794fb3", "51ac005363", 1, -719113284, "0d31a221c69bd322ef7193dd7359ddfefec9e0a1521d4a8740326d46e44a5d6a"],
+ ["36e42018044652286b19a90e5dd4f8d9f361d0760d080c5c5add1970296ff0f1de630233c8010000000200ac39260c7606017d2246ee14ddb7611586178067e6a4be38e788e33f39a3a95a55a13a6775010000000352ac638bea784f7c2354ed02ea0b93f0240cdfb91796fa77649beee6f7027caa70778b091deee700000000066a65ac656363ffffffff4d9d77ab676d711267ef65363f2d192e1bd55d3cd37f2280a34c72e8b4c559d700000000056a006aab00001764e1020d30220100000000085252516aacab0053472097040000000009635353ab6a636a5100a56407a1", "006a536551ab53ab", 0, 827296034, "daec2af5622bbe220c762da77bab14dc75e7d28aa1ade9b7f100798f7f0fd97a"],
+ ["5e06159a02762b5f3a5edcdfc91fd88c3bff08b202e69eb5ba74743e9f4291c4059ab008200000000001ac348f5446bb069ef977f89dbe925795d59fb5d98562679bafd61f5f5f3150c3559582992d0000000008ab5165515353abac762fc67703847ec6010000000000e200cf040000000002abaca64b86010000000008520000515363acabb82b491b", "ab53525352ab6a", 0, -61819505, "75a7db0df41485a28bf6a77a37ca15fa8eccc95b5d6014a731fd8adb9ada0f12"],
+ ["a1948872013b543d6d902ccdeead231c585195214ccf5d39f136023855958436a43266911501000000086aac006a6a6a51514951c9b2038a538a04000000000452526563c0f345050000000007526a5252ac526af9be8e03000000000752acac51ab006306198db2", "ab6353", 0, -326384076, "ced7ef84aad4097e1eb96310e0d1c8e512cfcb392a01d9010713459b23bc0cf4"],
+ ["c3efabba03cb656f154d1e159aa4a1a4bf9423a50454ebcef07bc3c42a35fb8ad84014864d0000000000d1cc73d260980775650caa272e9103dc6408bdacaddada6b9c67c88ceba6abaa9caa2f7d020000000553536a5265ffffffff9f946e8176d9b11ff854b76efcca0a4c236d29b69fb645ba29d406480427438e01000000066a0065005300ffffffff040419c0010000000003ab6a63cdb5b6010000000009006300ab5352656a63f9fe5e050000000004acac5352611b980100000000086a00acac00006a512d7f0c40", "0053", 0, -59089911, "c503001c16fbff82a99a18d88fe18720af63656fccd8511bca1c3d0d69bd7fc0"],
+ ["efb55c2e04b21a0c25e0e29f6586be9ef09f2008389e5257ebf2f5251051cdc6a79fce2dac020000000351006affffffffaba73e5b6e6c62048ba5676d18c33ccbcb59866470bb7911ccafb2238cfd493802000000026563ffffffffe62d7cb8658a6eca8a8babeb0f1f4fa535b62f5fc0ec70eb0111174e72bbec5e0300000009abababac516365526affffffffbf568789e681032d3e3be761642f25e46c20322fa80346c1146cb47ac999cf1b0300000000b3dbd55902528828010000000001ab0aac7b0100000000015300000000", "acac52", 3, 1638140535, "e84444d91580da41c8a7dcf6d32229bb106f1be0c811b2292967ead5a96ce9d4"],
+ ["91d3b21903629209b877b3e1aef09cd59aca6a5a0db9b83e6b3472aceec3bc2109e64ab85a0200000003530065ffffffffca5f92de2f1b7d8478b8261eaf32e5656b9eabbc58dcb2345912e9079a33c4cd010000000700ab65ab00536ad530611da41bbd51a389788c46678a265fe85737b8d317a83a8ff7a839debd18892ae5c80300000007ab6aac65ab51008b86c501038b8a9a05000000000263525b3f7a040000000007ab535353ab00abd4e3ff04000000000665ac51ab65630b7b656f", "6551525151516a00", 2, 499657927, "ef4bd7622eb7b2bbbbdc48663c1bc90e01d5bde90ff4cb946596f781eb420a0c"],
+ ["5d5c41ad0317aa7e40a513f5141ad5fc6e17d3916eebee4ddb400ddab596175b41a111ead20100000005536a5265acffffffff900ecb5e355c5c9f278c2c6ea15ac1558b041738e4bffe5ae06a9346d66d5b2b00000000080000ab636a65ab6affffffff99f4e08305fa5bd8e38fb9ca18b73f7a33c61ff7b3c68e696b30a04fea87f3ca000000000163d3d1760d019fc13a00000000000000000000", "ab53acabab6aac6a52", 2, 1007461922, "4012f5ff2f1238a0eb84854074670b4703238ebc15bfcdcd47ffa8498105fcd9"],
+ ["ceecfa6c02b7e3345445b82226b15b7a097563fa7d15f3b0c979232b138124b62c0be007890200000009abac51536a63525253ffffffffbae481ccb4f15d94db5ec0d8854c24c1cc8642bd0c6300ede98a91ca13a4539a0200000001ac50b0813d023110f5020000000006acabac526563e2b0d0040000000009656aac0063516a536300000000", "0063526500", 0, -1862053821, "e1600e6df8a6160a79ac32aa40bb4644daa88b5f76c0d7d13bf003327223f70c"],
+ ["ae62d5fd0380c4083a26642159f51af24bf55dc69008e6b7769442b6a69a603edd980a33000000000005ab5100ab53ffffffff49d048324d899d4b8ed5e739d604f5806a1104fede4cb9f92cc825a7fa7b4bfe0200000005536a000053ffffffff42e5cea5673c650881d0b4005fa4550fd86de5f21509c4564a379a0b7252ac0e0000000007530000526a53525f26a68a03bfacc3010000000000e2496f000000000009ab5253acac52636563b11cc600000000000700510065526a6a00000000", "abab", 1, -1600104856, "05cf0ec9c61f1a15f651a0b3c5c221aa543553ce6c804593f43bb5c50bb91ffb"],
+ ["f06f64af04fdcb830464b5efdb3d5ee25869b0744005375481d7b9d7136a0eb8828ad1f0240200000003516563fffffffffd3ba192dabe9c4eb634a1e3079fca4f072ee5ceb4b57deb6ade5527053a92c5000000000165ffffffff39f43401a36ba13a5c6dd7f1190e793933ae32ee3bf3e7bfb967be51e681af760300000009650000536552636a528e34f50b21183952cad945a83d4d56294b55258183e1627d6e8fb3beb8457ec36cadb0630000000005abab530052334a7128014bbfd10100000000085352ab006a63656afc424a7c", "53650051635253ac00", 2, 313255000, "d309da5afd91b7afa257cfd62df3ca9df036b6a9f4b38f5697d1daa1f587312b"],
+ ["6dfd2f98046b08e7e2ef5fff153e00545faf7076699012993c7a30cb1a50ec528281a9022f030000000152ffffffff1f535e4851920b968e6c437d84d6ecf586984ebddb7d5db6ae035bd02ba222a8010000000651006a53ab51605072acb3e17939fa0737bc3ee43bc393b4acd58451fc4ffeeedc06df9fc649828822d5010000000253525a4955221715f27788d302382112cf60719be9ae159c51f394519bd5f7e70a4f9816c7020200000009526a6a51636aab656a36d3a5ff0445548e0100000000086a6a00516a52655167030b050000000004ac6a63525cfda8030000000000e158200000000000010000000000", "535263ac6a65515153", 3, 585774166, "72b7da10704c3ca7d1deb60c31b718ee12c70dc9dfb9ae3461edce50789fe2ba"],
+ ["187eafed01389a45e75e9dda526d3acbbd41e6414936b3356473d1f9793d161603efdb45670100000002ab00ffffffff04371c8202000000000563630063523b3bde02000000000753516563006300e9e765010000000005516aac656a373f9805000000000665525352acab08d46763", "ab", 0, 122457992, "393aa6c758e0eed15fa4af6d9e2d7c63f49057246dbb92b4268ec24fc87301ca"],
+ ["7d50b977035d50411d814d296da9f7965ddc56f3250961ca5ba805cadd0454e7c521e31b0300000000003d0416c2cf115a397bacf615339f0e54f6c35ffec95aa009284d38390bdde1595cc7aa7c0100000005ab52ac5365ffffffff4232c6e796544d5ac848c9dc8d25cfa74e32e847a5fc74c74d8f38ca51188562030000000653ac51006a51ffffffff016bd8bb00000000000465ab5253163526f3", "51ab526a00005353", 1, -1311316785, "60b7544319b42e4159976c35c32c2644f0adf42eff13be1dc2f726fc0b6bb492"],
+ ["2a45cd1001bf642a2315d4a427eddcc1e2b0209b1c6abd2db81a800c5f1af32812de42032702000000050051525200ffffffff032177db050000000005530051abac49186f000000000004ab6aab00645c0000000000000765655263acabac00000000", "6a65", 0, -1774715722, "6a9ac3f7da4c7735fbc91f728b52ecbd602233208f96ac5592656074a5db118a"],
+ ["479358c202427f3c8d19e2ea3def6d6d3ef2281b4a93cd76214f0c7d8f040aa042fe19f71f0300000001abffffffffa2709be556cf6ecaa5ef530df9e4d056d0ed57ce96de55a5b1f369fa40d4e74a020000000700006a51635365c426be3f02af578505000000000363ab63fd8f590500000000065153abac53632dfb14b3", "520063ab51", 1, -763226778, "cfe147982afacde044ce66008cbc5b1e9f0fd9b8ed52b59fc7c0fecf95a39b0e"],
+ ["76179a8e03bec40747ad65ab0f8a21bc0d125b5c3c17ad5565556d5cb03ade7c83b4f32d98030000000151ffffffff99b900504e0c02b97a65e24f3ad8435dfa54e3c368f4e654803b756d011d24150200000003ac5353617a04ac61bb6cf697cfa4726657ba35ed0031432da8c0ffb252a190278830f9bd54f0320100000006656551005153c8e8fc8803677c77020000000007ac6553535253ac70f442030000000001535be0f20200000000026300bf46cb3a", "6aab52", 1, -58495673, "35e94b3776a6729d20aa2f3ddeeb06d3aad1c14cc4cde52fd21a4efc212ea16c"],
+ ["75ae53c2042f7546223ce5d5f9e00a968ddc68d52e8932ef2013fa40ce4e8c6ed0b6195cde01000000056563ac630079da0452c20697382e3dba6f4fc300da5f52e95a9dca379bb792907db872ba751b8024ee0300000009655151536500005163ffffffffe091b6d43f51ff00eff0ccfbc99b72d3aff208e0f44b44dfa5e1c7322cfc0c5f01000000075200005363ab63ffffffff7e96c3b83443260ac5cfd18258574fbc4225c630d3950df812bf51dceaeb0f9103000000065365655165639a6bf70b01b3e14305000000000563530063ac00000000", "6300ab00ac", 2, 982422189, "ee4ea49d2aae0dbba05f0b9785172da54408eb1ec67d36759ff7ed25bfc28766"],
+ ["1cdfa01e01e1b8078e9c2b0ca5082249bd18fdb8b629ead659adedf9a0dd5a04031871ba120200000008525351536565ab6affffffff011e28430200000000076a5363636aac52b2febd4a", "abacac63656300", 0, 387396350, "299dcaac2bdaa627eba0dfd74767ee6c6f27c9200b49da8ff6270b1041669e7e"],
+ ["cc28c1810113dfa6f0fcd9c7d9c9a30fb6f1d774356abeb527a8651f24f4e6b25cf763c4e00300000003ab636affffffff02dfc6050000000000080053636351ab0052afd56903000000000453ab5265f6c90d99", "006551abacacac", 0, 1299280838, "a4c0773204ab418a939e23f493bd4b3e817375d133d307609e9782f2cc38dbcf"],
+ ["ca816e7802cd43d66b9374cd9bf99a8da09402d69c688d8dcc5283ace8f147e1672b757e020200000005516aabab5240fb06c95c922342279fcd88ba6cd915933e320d7becac03192e0941e0345b79223e89570300000004005151ac353ecb5d0264dfbd010000000005ac6aacababd5d70001000000000752ac53ac6a5151ec257f71", "63ac", 1, 774695685, "cc180c4f797c16a639962e7aec58ec4b209853d842010e4d090895b22e7a7863"],
+ ["b42b955303942fedd7dc77bbd9040aa0de858afa100f399d63c7f167b7986d6c2377f66a7403000000066aac00525100ffffffff0577d04b64880425a3174055f94191031ad6b4ca6f34f6da9be7c3411d8b51fc000000000300526a6391e1cf0f22e45ef1c44298523b516b3e1249df153590f592fcb5c5fc432dc66f3b57cb03000000046a6aac65ffffffff0393a6c9000000000004516a65aca674ac0400000000046a525352c82c370000000000030053538e577f89", "", 1, -1237094944, "566953eb806d40a9fb684d46c1bf8c69dea86273424d562bd407b9461c8509af"],
+ ["92c9fe210201e781b72554a0ed5e22507fb02434ddbaa69aff6e74ea8bad656071f1923f3f02000000056a63ac6a514470cef985ba83dcb8eee2044807bedbf0d983ae21286421506ae276142359c8c6a34d68020000000863ac63525265006aa796dd0102ca3f9d05000000000800abab52ab535353cd5c83010000000007ac00525252005322ac75ee", "5165", 0, 97879971, "6e6307cef4f3a9b386f751a6f40acebab12a0e7e17171d2989293cbec7fd45c2"],
+ ["ccca1d5b01e40fe2c6b3ee24c660252134601dab785b8f55bd6201ffaf2fddc7b3e2192325030000000365535100496d4703b4b66603000000000665535253ac633013240000000000015212d2a502000000000951abac636353636a5337b82426", "0052", 0, -1691630172, "577bf2b3520b40aef44899a20d37833f1cded6b167e4d648fc5abe203e43b649"],
+ ["bc1a7a3c01691e2d0c4266136f12e391422f93655c71831d90935fbda7e840e50770c61da20000000008635253abac516353ffffffff031f32aa020000000003636563786dbc0200000000003e950f00000000000563516a655184b8a1de", "51536a", 0, -1627072905, "730bc25699b46703d7718fd5f5c34c4b5f00f594a9968ddc247fa7d5175124ed"],
+ ["076d209e02d904a6c40713c7225d23e7c25d4133c3c3477828f98c7d6dbd68744023dbb66b030000000753ab00536565acffffffff10975f1b8db8861ca94c8cc7c7cff086ddcd83e10b5fffd4fc8f2bdb03f9463c0100000000ffffffff029dff76010000000006526365530051a3be6004000000000000000000", "515253ac65acacac", 1, -1207502445, "66c488603b2bc53f0d22994a1f0f66fb2958203102eba30fe1d37b27a55de7a5"],
+ ["690fd1f80476db1f9eebe91317f2f130a60cbc1f4feadd9d6474d438e9cb7f91e4994600af0300000004ab536a63a15ce9fa6622d0c4171d895b42bff884dc6e8a7452f827fdc68a29c3c88e6fdee364eaf50000000002ab52ffffffff022dc39d3c0956b24d7f410b1e387859e7a72955f45d6ffb1e884d77888d18fe0300000005ac6a63656afffffffff10b06bce1800f5c49153d24748fdefb0bf514c12863247d1042d56018c3e25c03000000086a63ac6365536a52ffffffff031f162f0500000000060000655265abffbcd40500000000045151ac001a9c8c05000000000652ac53656a6300000000", "ac51ab63acac", 0, -67986012, "051c0df7ac688c2c930808dabde1f50300aea115f2bb3334f4753d5169b51e46"],
+ ["49ac2af00216c0307a29e83aa5de19770e6b20845de329290bd69cf0e0db7aed61ae41b39002000000035163ac8b2558ef84635bfc59635150e90b61fc753d34acfd10d97531043053e229cd720133cd95000000000463516a51ffffffff02458471040000000008abab636a51ac0065545aa80000000000096a6553516a5263ac6a00000000", "51526300ab5363", 1, 1449668540, "ddfd902bba312a06197810da96a0ddccb595f96670b28ded7dba88d8cd0469b8"],
+ ["fa4d868b024b010bd5dce46576c2fb489aa60bb797dac3c72a4836f49812c5c564c258414f03000000007a9b3a585e05027bdd89edbadf3c85ac61f8c3a04c773fa746517ae600ff1a9d6b6c02fb0200000004515163abffffffff01b17d020500000000046a65520000000000", "536565ab65635363", 0, -1718953372, "96c2b32f0a00a5925db7ba72d0b5d39922f30ea0f7443b22bc1b734808513c47"],
+ ["cac6382d0462375e83b67c7a86c922b569a7473bfced67f17afd96c3cd2d896cf113febf9e0300000003006a53ffffffffaa4913b7eae6821487dd3ca43a514e94dcbbf350f8cc4cafff9c1a88720711b800000000096a6a525300acac6353ffffffff184fc4109c34ea27014cc2c1536ef7ed1821951797a7141ddacdd6e429fae6ff01000000055251655200ffffffff9e7b79b4e6836e290d7b489ead931cba65d1030ccc06f20bd4ca46a40195b33c030000000008f6bc8304a09a2704000000000563655353511dbc73050000000000cf34c500000000000091f76e0000000000085200ab00005100abd07208cb", "0063656a", 2, -1488731031, "bf078519fa87b79f40abc38f1831731422722c59f88d86775535f209cb41b9b1"],
+ ["1711146502c1a0b82eaa7893976fefe0fb758c3f0e560447cef6e1bde11e42de91a125f71c030000000015bd8c04703b4030496c7461482481f290c623be3e76ad23d57a955807c9e851aaaa20270300000000d04abaf20326dcb7030000000001632225350400000000075263ac00520063dddad9020000000000af23d148", "52520053510063", 0, 1852122830, "e33d5ee08c0f3c130a44d7ce29606450271b676f4a80c52ab9ffab00cecf67f8"],
+ ["8d5b124d0231fbfc640c706ddb1d57bb49a18ba8ca0e1101e32c7e6e65a0d4c7971d93ea360100000008acabac0000abac65ffffffff8fe0fd7696597b845c079c3e7b87d4a44110c445a330d70342a5501955e17dd70100000004ab525363ef22e8a90346629f030000000009516a00ac63acac51657bd57b05000000000200acfd4288050000000009acab5352ab00ab636300000000", "53ac526553ab65", 0, 1253152975, "8b57a7c3170c6c02dd14ae1d392ce3d828197b20e9145c89c1cfd5de050e1562"],
+ ["38146dc502c7430e92b6708e9e107b61cd38e5e773d9395e5c8ad8986e7e4c03ee1c1e1e760100000000c8962ce2ac1bb3b1285c0b9ba07f4d2e5ce87c738c42ac0548cd8cec1100e6928cd6b0b6010000000763ab636aab52527cccefbd04e5f6f8020000000006006aabacac65ab2c4a00000000000351635209a6f40100000000026aacce57dc040000000008ab5353ab516a516a00000000", "ab", 0, -1205978252, "3cb5b030e7da0b60ccce5b4a7f3793e6ca56f03e3799fe2d6c3cc22d6d841dcb"],
+ ["22d81c740469695a6a83a9a4824f77ecff8804d020df23713990afce2b72591ed7de98500502000000065352526a6a6affffffff90dc85e118379b1005d7bbc7d2b8b0bab104dad7eaa49ff5bead892f17d8c3ba010000000665656300ab51ffffffff965193879e1d5628b52005d8560a35a2ba57a7f19201a4045b7cbab85133311d0200000003ac005348af21a13f9b4e0ad90ed20bf84e4740c8a9d7129632590349afc03799414b76fd6e826200000000025353ffffffff04a0d40d04000000000060702700000000000652655151516ad31f1502000000000365ac0069a1ac0500000000095100655300ab53525100000000", "51636a52ac", 0, -1644680765, "add7f5da27262f13da6a1e2cc2feafdc809bd66a67fb8ae2a6f5e6be95373b6f"],
+ ["a27dcbc801e3475174a183586082e0914c314bc9d79d1570f29b54591e5e0dff07fbb45a7f0000000004ac53ab51ffffffff027347f5020000000005535351ab63d0e5c9030000000009ac65ab6a63515200ab7cd632ed", "ac63636553", 0, -686435306, "883a6ea3b2cc53fe8a803c229106366ca14d25ffbab9fef8367340f65b201da6"],
+ ["b123ed2204410d4e8aaaa8cdb95234ca86dad9ff77fb4ae0fd4c06ebed36794f0215ede0040100000002ac63ffffffff3b58b81b19b90d8f402701389b238c3a84ff9ba9aeea298bbf15b41a6766d27a01000000056a6553ab00151824d401786153b819831fb15926ff1944ea7b03d884935a8bde01ed069d5fd80220310200000000ffffffffa9c9d246f1eb8b7b382a9032b55567e9a93f86c77f4e32c092aa1738f7f756c30100000002ab65ffffffff011a2b48000000000000ed44d1fb", "630051ab63", 2, -1118263883, "b5dab912bcabedff5f63f6dd395fc2cf030d83eb4dd28214baba68a45b4bfff0"],
+ ["1339051503e196f730955c5a39acd6ed28dec89b4dadc3f7c79b203b344511270e5747fa9900000000045151636affffffff378c6090e08a3895cedf1d25453bbe955a274657172491fd2887ed5c9aceca7b0100000000ffffffffcf7cc3c36ddf9d4749edfa9cefed496d2f86e870deb814bfcd3b5637a5496461030000000451006300ffffffff04dcf3fa010000000008526a63005263acabb41d84040000000004abac5153800eff020000000005656a535365106c5e00000000000000000000", "abac5300", 2, 2013719928, "7fc74de39ce6ca46ca25d760d3cec7bb21fd14f7efe1c443b5aa294f2cb5f546"],
+ ["0728c606014c1fd6005ccf878196ba71a54e86cc8c53d6db500c3cc0ac369a26fac6fcbc210000000005ab53ac5365ba9668290182d7870100000000066a000053655100000000", "65", 0, 1789961588, "ab6baa6da3b2bc853868d166f8996ad31d63ef981179f9104f49968fd61c8427"],
+ ["a1134397034bf4067b6c81c581e2b73fb63835a08819ba24e4e92df73074bf773c94577df7000000000465525251ffffffff8b6608feaa3c1f35f49c6330a769716fa01c5c6f6e0cdc2eb10dfc99bbc21e77010000000952656aac005352655180a0bda4bc72002c2ea8262e26e03391536ec36867258cab968a6fd6ec7523b64fa1d8c001000000056a53ac6353ffffffff04dbeeed05000000000553650052abcd5d0e01000000000463abab51104b2e0500000000066aac53ac5165283ca7010000000004535252ab00000000", "ab515151516552ab", 1, -324598676, "91178482112f94d1c8e929de443e4b9c893e18682998d393ca9ca77950412586"],
+ ["bcdafbae04aa18eb75855aeb1f5124f30044741351b33794254a80070940cb10552fa4fa8e0300000001acd0423fe6e3f3f88ae606f2e8cfab7a5ef87caa2a8f0401765ff9a47d718afcfb40c0099b0000000008ac6565ab53ac6aac645308009d680202d600e492b31ee0ab77c7c5883ebad5065f1ce87e4dfe6453e54023a0010000000151ffffffffb9d818b14245899e1d440152827c95268a676f14c3389fc47f5a11a7b38b1bde03000000026300ffffffff03cda22102000000000751ac535263005100a4d20400000000045200536ac8bef405000000000700ab51ab6563ac00000000", "6553516a526aab", 1, -2111409753, "5e1849e7368cf4f042718586d9bd831d61479b775bab97aba9f450042bd9876a"],
+ ["ed3bb93802ddbd08cb030ef60a2247f715a0226de390c9c1a81d52e83f8674879065b5f87d0300000003ab6552ffffffff04d2c5e60a21fb6da8de20bf206db43b720e2a24ce26779bca25584c3f765d1e0200000008ab656a6aacab00ab6e946ded025a811d04000000000951abac6352ac00ab5143cfa3030000000005635200636a00000000", "5352ac650065535300", 1, -668727133, "e9995065e1fddef72a796eef5274de62012249660dc9d233a4f24e02a2979c87"],
+ ["59f4629d030fa5d115c33e8d55a79ea3cba8c209821f979ed0e285299a9c72a73c5bba00150200000002636affffffffd8aca2176df3f7a96d0dc4ee3d24e6cecde1582323eec2ebef9a11f8162f17ac0000000007ab6565acab6553ffffffffeebc10af4f99c7a21cbc1d1074bd9f0ee032482a71800f44f26ee67491208e0403000000065352ac656351ffffffff0434e955040000000004ab515152caf2b305000000000365ac007b1473030000000003ab530033da970500000000060051536a5253bb08ab51", "", 2, 396340944, "0e9c47973ef2c292b2252c623f465bbb92046fe0b893eebf4e1c9e02cb01c397"],
+ ["286e3eb7043902bae5173ac3b39b44c5950bc363f474386a50b98c7bdab26f98dc83449c4a020000000752ac6a00510051ffffffff4339cd6a07f5a5a2cb5815e5845da70300f5c7833788363bf7fe67595d3225520100000000fffffffff9c2dd8b06ad910365ffdee1a966f124378a2b8021065c8764f6138bb1e951380200000005ab5153ac6affffffff0370202aba7a68df85436ea7c945139513384ef391fa33d16020420b8ad40e9a000000000900ab5165526353abacffffffff020c1907000000000004abac526a1b490b040000000000df1528f7", "5353ab", 3, -1407529517, "32154c09174a9906183abf26538c39e78468344ca0848bbd0785e24a3565d932"],
+ ["2e245cf80179e2e95cd1b34995c2aff49fe4519cd7cee93ad7587f7f7e8105fc2dff206cd30200000009006a63516a6553ab52350435a201d5ed2d02000000000352ab6558552c89", "00ab53", 0, -233917810, "4605ae5fd3d50f9c45d37db7118a81a9ef6eb475d2333f59df5d3e216f150d49"],
+ ["33a98004029d262f951881b20a8d746c8c707ea802cd2c8b02a33b7e907c58699f97e42be80100000007ac53536552abacdee04cc01d205fd8a3687fdf265b064d42ab38046d76c736aad8865ca210824b7c622ecf02000000070065006a536a6affffffff01431c5d010000000000270d48ee", "", 1, 921554116, "ff9d7394002f3f196ea25472ea6c46f753bd879a7244795157bb7235c9322902"],
+ ["aac18f2b02b144ed481557c53f2146ae523f24fcde40f3445ab0193b6b276c315dc2894d2300000000075165650000636a233526947dbffc76aec7db1e1baa6868ad4799c76e14794dcbaaec9e713a83967f6a65170200000005abac6551ab27d518be01b652a30000000000015300000000", "52ac5353", 1, 1559377136, "59fc2959bb7bb24576cc8a237961ed95bbb900679d94da6567734c4390cb6ef5"],
+ ["5ab79881033555b65fe58c928883f70ce7057426fbdd5c67d7260da0fe8b1b9e6a2674cb850300000009ac516aac6aac006a6affffffffa5be9223b43c2b1a4d120b5c5b6ec0484f637952a3252181d0f8e813e76e11580200000000e4b5ceb8118cb77215bbeedc9a076a4d087bb9cd1473ea32368b71daeeeacc451ec209010000000005acac5153aced7dc34e02bc5d11030000000005ac5363006a54185803000000000552ab00636a00000000", "5100", 1, 1927062711, "e9f53d531c12cce1c50abed4ac521a372b4449b6a12f9327c80020df6bff66c0"],
+ ["6c2c8fac0124b0b7d4b610c3c5b91dee32b7c927ac71abdf2d008990ca1ac40de0dfd530660300000006ababac5253656bd7eada01d847ec000000000004ac52006af4232ec8", "6a6a6a0051", 0, -340809707, "fb51eb9d7e47d32ff2086205214f90c7c139e08c257a64829ae4d2b301071c6a"],
+ ["6e3880af031735a0059c0bb5180574a7dcc88e522c8b56746d130f8d45a52184045f96793e0100000008acabac6a526a6553fffffffffe05f14cdef7d12a9169ec0fd37524b5fcd3295f73f48ca35a36e671da4a2f560000000008006a526a6351ab63ffffffffdfbd869ac9e472640a84caf28bdd82e8c6797f42d03b99817a705a24fde2736600000000010090a090a503db956b04000000000952ac53ab6a536a63ab358390010000000009656a5200525153ac65353ee204000000000763530052526aaba6ad83fb", "535151ab6300", 2, 222014018, "57a34ddeb1bf36d28c7294dda0432e9228a9c9e5cc5c692db98b6ed2e218d825"],
+ ["8df1cd19027db4240718dcaf70cdee33b26ea3dece49ae6917331a028c85c5a1fb7ee3e475020000000865ab6a00510063636157988bc84d8d55a8ba93cdea001b9bf9d0fa65b5db42be6084b5b1e1556f3602f65d4d0100000005ac00ab0052206c852902b2fb54030000000008ac5252536aacac5378c4a5050000000007acabac535163532784439e", "acab6a", 0, 1105620132, "edb7c74223d1f10f9b3b9c1db8064bc487321ff7bb346f287c6bc2fad83682de"],
+ ["0e803682024f79337b25c98f276d412bc27e56a300aa422c42994004790cee213008ff1b8303000000080051ac65ac655165f421a331892b19a44c9f88413d057fea03c3c4a6c7de4911fe6fe79cf2e9b3b10184b1910200000005525163630096cb1c670398277204000000000253acf7d5d502000000000963536a6a636a5363ab381092020000000002ac6a911ccf32", "6565", 1, -1492094009, "f0672638a0e568a919e9d8a9cbd7c0189a3e132940beeb52f111a89dcc2daa2c"],
+ ["7d71669d03022f9dd90edac323cde9e56354c6804c6b8e687e9ae699f46805aafb8bcaa636000000000253abffffffff698a5fdd3d7f2b8b000c68333e4dd58fa8045b3e2f689b889beeb3156cecdb490300000009525353abab0051acabc53f0aa821cdd69b473ec6e6cf45cf9b38996e1c8f52c27878a01ec8bb02e8cb31ad24e500000000055353ab0052ffffffff0447a23401000000000565ab53ab5133aaa0030000000006515163656563057d110300000000056a6aacac52cf13b5000000000003526a5100000000", "6a6a51", 1, -1349253507, "722efdd69a7d51d3d77bed0ac5544502da67e475ea5857cd5af6bdf640a69945"],
+ ["9ff618e60136f8e6bb7eabaaac7d6e2535f5fba95854be6d2726f986eaa9537cb283c701ff02000000026a65ffffffff012d1c0905000000000865ab00ac6a516a652f9ad240", "51515253635351ac", 0, 1571304387, "659cd3203095d4a8672646add7d77831a1926fc5b66128801979939383695a79"],
+ ["9fbd43ac025e1462ecd10b1a9182a8e0c542f6d1089322a41822ab94361e214ed7e1dfdd8a020000000263519d0437581538e8e0b6aea765beff5b4f3a4a202fca6e5d19b34c141078c6688f71ba5b8e0100000003ac6552ffffffff02077774050000000009655153655263acab6a0ae4e10100000000035152524c97136b", "635152ab", 0, 1969622955, "d82d4ccd9b67810f26a378ad9592eb7a30935cbbd27e859b00981aefd0a72e08"],
+ ["0117c92004314b84ed228fc11e2999e657f953b6de3b233331b5f0d0cf40d5cc149b93c7b30300000005515263516a083e8af1bd540e54bf5b309d36ba80ed361d77bbf4a1805c7aa73667ad9df4f97e2da410020000000600ab6351ab524d04f2179455e794b2fcb3d214670001c885f0802e4b5e015ed13a917514a7618f5f332203000000086a536aab51000063ecf029e65a4a009a5d67796c9f1eb358b0d4bd2620c8ad7330fb98f5a802ab92d0038b1002000000036a6551a184a88804b04490000000000009ab6a5152535165526a33d1ab020000000001518e92320000000000002913df04000000000952abac6353525353ac8b19bfdf", "000051ab0000", 0, 489433059, "8eebac87e60da524bbccaf285a44043e2c9232868dda6c6271a53c153e7f3a55"],
+ ["e7f5482903f98f0299e0984b361efb2fddcd9979869102281e705d3001a9d283fe9f3f3a1e02000000025365ffffffffcc5c7fe82feebad32a22715fc30bc584efc9cd9cadd57e5bc4b6a265547e676e0000000001ab579d21235bc2281e08bf5e7f8f64d3afb552839b9aa5c77cf762ba2366fffd7ebb74e49400000000055263ab63633df82cf40100982e05000000000453ac535300000000", "acacab", 2, -1362931214, "046de666545330e50d53083eb78c9336416902f9b96c77cc8d8e543da6dfc7e4"],
+ ["09adb2e90175ca0e816326ae2dce7750c1b27941b16f6278023dbc294632ab97977852a09d030000000465ab006affffffff027739cf0100000000075151ab63ac65ab8a5bb601000000000653ac5151520011313cdc", "ac", 0, -76831756, "478ee06501b4965b40bdba6cbaad9b779b38555a970912bb791b86b7191c54bc"],
+ ["f973867602e30f857855cd0364b5bbb894c049f44abbfd661d7ae5dbfeaafca89fac8959c20100000005ab52536a51ffffffffbeceb68a4715f99ba50e131884d8d20f4a179313691150adf0ebf29d05f8770303000000066352ab00ac63ffffffff021fddb90000000000036a656322a177000000000008526500ac5100acac84839083", "52acab53ac", 0, 1407879325, "db0329439490efc64b7104d6d009b03fbc6fac597cf54fd786fbbb5fd73b92b4"],
+ ["fd22ebaa03bd588ad16795bea7d4aa7f7d48df163d75ea3afebe7017ce2f350f6a0c1cb0bb00000000086aabac5153526363ffffffff488e0bb22e26a565d77ba07178d17d8f85702630ee665ec35d152fa05af3bda10200000004515163abffffffffeb21035849e85ad84b2805e1069a91bb36c425dc9c212d9bae50a95b6bfde1200300000001ab5df262fd02b69848040000000008ab6363636a6363ace23bf2010000000007655263635253534348c1da", "006353526563516a00", 0, -1491036196, "92364ba3c7a85d4e88885b8cb9b520dd81fc29e9d2b750d0790690e9c1246673"],
+ ["130b462d01dd49fac019dc4442d0fb54eaa6b1c2d1ad0197590b7df26969a67abd7f3fbb4f0100000008ac65abac53ab6563ffffffff0345f825000000000004ac53acac9d5816020000000002ababeff8e90500000000086aab006552ac6a53a892dc55", "ab0065ac530052", 0, 944483412, "1f4209fd4ce7f13d175fdd522474ae9b34776fe11a5f17a27d0796c77a2a7a9d"],
+ ["f8e50c2604609be2a95f6d0f31553081f4e1a49a0a30777fe51eb1c596c1a9a92c053cf28c0300000009656a51ac5252630052fffffffff792ed0132ae2bd2f11d4a2aab9d0c4fbdf9a66d9ae2dc4108afccdc14d2b1700100000007ab6a6563ac636a7bfb2fa116122b539dd6a2ab089f88f3bc5923e5050c8262c112ff9ce0a3cd51c6e3e84f02000000066551ac5352650d5e687ddf4cc9a497087cabecf74d236aa4fc3081c3f67b6d323cba795e10e7a171b725000000000852635351ab635100ffffffff02df5409020000000008ac6a53acab5151004156990200000000045163655200000000", "ac53abac65005300", 0, -173065000, "b596f206d7eba22b7e2d1b7a4f4cf69c7c541b6c84dcc943f84e19a99a923310"],
+ ["18020dd1017f149eec65b2ec23300d8df0a7dd64fc8558b36907723c03cd1ba672bbb0f51d0300000005ab65ab6a63ffffffff037cd7ae000000000009ab516a65005352ac65f1e4360400000000056353530053f118f0040000000009536363ab006500abac00000000", "63ab51acab52ac", 0, -550412404, "e19b796c14a0373674968e342f2741d8b51092a5f8409e9bff7dcd52e56fcbcb"],
+ ["b04154610363fdade55ceb6942d5e5a723323863b48a0cb04fdcf56210717955763f56b08d0300000009ac526a525151635151ffffffff93a176e76151a9eabdd7af00ef2af72f9e7af5ecb0aa4d45d00618f394cdd03c030000000074d818b332ebe05dc24c44d776cf9d275c61f471cc01efce12fd5a16464157f1842c65cb00000000066a0000ac6352d3c4134f01d8a1c0030000000005520000005200000000", "5200656a656351", 2, -9757957, "6e3e5ba77f760b6b5b5557b13043f1262418f3dd2ce7f0298b012811fc8ad5bc"],
+ ["9794b3ce033df7b1e32db62d2f0906b589eacdacf5743963dc2255b6b9a6cba211fadd0d41020000000600ab00650065ffffffffaae00687a6a4131152bbcaafedfaed461c86754b0bde39e2bef720e6d1860a0302000000070065516aac6552ffffffff50e4ef784d6230df7486e972e8918d919f005025bc2d9aacba130f58bed7056703000000075265ab52656a52ffffffff02c6f1a9000000000006005251006363cf450c040000000008abab63510053abac00000000", "ac0063ababab515353", 1, 2063905082, "fad092fc98f17c2c20e10ba9a8eb44cc2bcc964b006f4da45cb9ceb249c69698"],
+ ["94533db7015e70e8df715066efa69dbb9c3a42ff733367c18c22ff070392f988f3b93920820000000006535363636300ce4dac3e03169af80300000000080065ac6a53ac65ac39c050020000000006abacab6aacac708a02050000000005ac5251520000000000", "6553", 0, -360458507, "5418cf059b5f15774836edd93571e0eed3855ba67b2b08c99dccab69dc87d3e9"],
+ ["c8597ada04f59836f06c224a2640b79f3a8a7b41ef3efa2602592ddda38e7597da6c639fee0300000009005251635351acabacffffffff4c518f347ee694884b9d4072c9e916b1a1f0a7fc74a1c90c63fdf8e5a185b6ae02000000007113af55afb41af7518ea6146786c7c726641c68c8829a52925e8d4afd07d8945f68e7230300000008ab00ab65ab650063ffffffffc28e46d7598312c420e11dfaae12add68b4d85adb182ae5b28f8340185394b63000000000165ffffffff04dbabb7010000000000ee2f6000000000000852ab6500ab6a51acb62a27000000000009ac53515300ac006a6345fb7505000000000752516a0051636a00000000", "", 3, 15199787, "0d66003aff5bf78cf492ecbc8fd40c92891acd58d0a271be9062e035897f317e"],
+ ["1a28c4f702c8efaad96d879b38ec65c5283b5c084b819ad7db1c086e85e32446c7818dc7a90300000008656351536a525165fa78cef86c982f1aac9c5eb8b707aee8366f74574c8f42ef240599c955ef4401cf578be30200000002ab518893292204c430eb0100000000016503138a0300000000040053abac60e0eb010000000005525200ab63567c2d030000000004abab52006cf81e85", "ab51525152", 1, 2118315905, "4e4c9a781f626b59b1d3ad8f2c488eb6dee8bb19b9bc138bf0dc33e7799210d4"],
+ ["c6c7a87003f772bcae9f3a0ac5e499000b68703e1804b9ddc3e73099663564d53ddc4e1c6e01000000076a536a6aac63636e3102122f4c30056ef8711a6bf11f641ddfa6984c25ac38c3b3e286e74e839198a80a34010000000165867195cd425821dfa2f279cb1390029834c06f018b1e6af73823c867bf3a0524d1d6923b0300000005acab53ab65ffffffff02fa4c49010000000008ab656a0052650053e001100400000000008836d972", "ac526351acab", 1, 978122815, "a869c18a0edf563d6e5eddd5d5ae8686f41d07f394f95c9feb8b7e52761531ca"],
+ ["0ea580ac04c9495ab6af3b8d59108bb4194fcb9af90b3511c83f7bb046d87aedbf8423218e02000000085152acac006363ab9063d7dc25704e0caa5edde1c6f2dd137ded379ff597e055b2977b9c559b07a7134fcef2000000000200aca89e50181f86e9854ae3b453f239e2847cf67300fff802707c8e3867ae421df69274449402000000056365abababffffffff47a4760c881a4d7e51c69b69977707bd2fb3bcdc300f0efc61f5840e1ac72cee0000000000ffffffff0460179a020000000004ab53ab52a5250c0500000000096565acac6365ab52ab6c281e02000000000952635100ac006563654e55070400000000046552526500000000", "ab526563acac53ab", 2, 1426964167, "b1c50d58b753e8f6c7513752158e9802cf0a729ebe432b99acc0fe5d9b4e9980"],
+ ["c33028b301d5093e1e8397270d75a0b009b2a6509a01861061ab022ca122a6ba935b8513320200000000ffffffff013bcf5a0500000000015200000000", "", 0, -513413204, "6b1459536f51482f5dbf42d7e561896557461e1e3b6bf67871e2b51faae2832c"],
+ ["43b2727901a7dd06dd2abf690a1ccedc0b0739cb551200796669d9a25f24f71d8d101379f50300000000ffffffff0418e031040000000000863d770000000000085352ac526563ac5174929e040000000004ac65ac00ec31ac0100000000066a51ababab5300000000", "65", 0, -492874289, "154ff7a9f0875edcfb9f8657a0b98dd9600fabee3c43eb88af37cf99286d516c"],
+ ["4763ed4401c3e6ab204bed280528e84d5288f9cac5fb8a2e7bd699c7b98d4df4ac0c40e55303000000066a6aacab5165ffffffff015b57f80400000000046a63535100000000", "ac51abab53", 0, -592611747, "849033a2321b5755e56ef4527ae6f51e30e3bca50149d5707368479723d744f8"],
+ ["d24f647b02f71708a880e6819a1dc929c1a50b16447e158f8ff62f9ccd644e0ca3c592593702000000050053536a00ffffffff67868cd5414b6ca792030b18d649de5450a456407242b296d936bcf3db79e07b02000000005af6319c016022f50100000000036a516300000000", "6aab526353516a6a", 0, 1350782301, "8556fe52d1d0782361dc28baaf8774b13f3ce5ed486ae0f124b665111e08e3e3"],
+ ["fe6ddf3a02657e42a7496ef170b4a8caf245b925b91c7840fd28e4a22c03cb459cb498b8d603000000065263656a650071ce6bf8d905106f9f1faf6488164f3decac65bf3c5afe1dcee20e6bc3cb6d052561985a030000000163295b117601343dbb0000000000026563dba521df", "", 1, -1696179931, "d9684685c99ce48f398fb467a91a1a59629a850c429046fb3071f1fa9a5fe816"],
+ ["c61523ef0129bb3952533cbf22ed797fa2088f307837dd0be1849f20decf709cf98c6f032f03000000026563c0f1d378044338310400000000066363516a5165a14fcb0400000000095163536a6a00ab53657271d60200000000001d953f0500000000010000000000", "53516353005153", 0, 1141615707, "7e975a72db5adaa3c48d525d9c28ac11cf116d0f8b16ce08f735ad75a80aec66"],
+ ["ba3dac6c0182562b0a26d475fe1e36315f0913b6869bdad0ecf21f1339a5fcbccd32056c840200000000ffffffff04300351050000000000220ed405000000000851abac636565ac53dbbd19020000000007636363ac6a52acbb005a0500000000016abd0c78a8", "63006a635151005352", 0, 1359658828, "47bc8ab070273e1f4a0789c37b45569a6e16f3f3092d1ce94dddc3c34a28f9f4"],
+ ["ac27e7f5025fc877d1d99f7fc18dd4cadbafa50e34e1676748cc89c202f93abf36ed46362101000000036300abffffffff958cd5381962b765e14d87fc9524d751e4752dd66471f973ed38b9d562e525620100000003006500ffffffff02b67120050000000004ac51516adc330c0300000000015200000000", "656352", 1, 15049991, "f3374253d64ac264055bdbcc32e27426416bd595b7c7915936c70f839e504010"],
+ ["edb30140029182b80c8c3255b888f7c7f061c4174d1db45879dca98c9aab8c8fed647a6ffc03000000086a53510052ab6300ffffffff82f65f261db62d517362c886c429c8fbbea250bcaad93356be6f86ba573e9d930100000000ffffffff04daaf150400000000016a86d1300100000000096a6353535252ac5165d4ddaf000000000002abab5f1c6201000000000000000000", "ab6a6a00ac", 0, -2058017816, "8d7794703dad18e2e40d83f3e65269834bb293e2d2b8525932d6921884b8f368"],
+ ["7e50207303146d1f7ad62843ae8017737a698498d4b9118c7a89bb02e8370307fa4fada41d000000000753006300005152b7afefc85674b1104ba33ef2bf37c6ed26316badbc0b4aa6cb8b00722da4f82ff3555a6c020000000900ac656363ac51ac52ffffffff93fab89973bd322c5d7ad7e2b929315453e5f7ada3072a36d8e33ca8bebee6e0020000000300acab930da52b04384b04000000000004650052ac435e380200000000076a6a515263ab6aa9494705000000000600ab6a525252af8ba90100000000096565acab526353536a279b17ad", "acac005263536aac63", 1, -34754133, "4e6357da0057fb7ff79da2cc0f20c5df27ff8b2f8af4c1709e6530459f7972b0"],
+ ["c05764f40244fb4ebe4c54f2c5298c7c798aa90e62c29709acca0b4c2c6ec08430b26167440100000008acab6a6565005253ffffffffc02c2418f398318e7f34a3cf669d034eef2111ea95b9f0978b01493293293a870100000000e563e2e00238ee8d040000000002acab03fb060200000000076500ac656a516aa37f5534", "52ab6a0065", 1, -2033176648, "83deef4a698b62a79d4877dd9afebc3011a5275dbe06e89567e9ef84e8a4ee19"],
+ ["5a59e0b9040654a3596d6dab8146462363cd6549898c26e2476b1f6ae42915f73fd9aedfda00000000036363abffffffff9ac9e9ca90be0187be2214251ff08ba118e6bf5e2fd1ba55229d24e50a510d53010000000165ffffffff41d42d799ac4104644969937522873c0834cc2fcdab7cdbecd84d213c0e96fd60000000000ffffffffd838db2c1a4f30e2eaa7876ef778470f8729fcf258ad228b388df2488709f8410300000000fdf2ace002ceb6d903000000000265654c1310040000000003ac00657e91c0ec", "536a63ac", 0, 82144555, "98ccde2dc14d14f5d8b1eeea5364bd18fc84560fec2fcea8de4d88b49c00695e"],
+ ["156ebc8202065d0b114984ee98c097600c75c859bfee13af75dc93f57c313a877efb09f230010000000463536a51ffffffff81114e8a697be3ead948b43b5005770dd87ffb1d5ccd4089fa6c8b33d3029e9c03000000066a5251656351ffffffff01a87f140000000000050000ac51ac00000000", "00", 0, -362221092, "a903c84d8c5e71134d1ab6dc1e21ac307c4c1a32c90c90f556f257b8a0ec1bf5"],
+ ["15e37793023c7cbf46e073428908fce0331e49550f2a42b92468827852693f0532a01c29f70200000007005353636351acffffffff38426d9cec036f00eb56ec1dcd193647e56a7577278417b8a86a78ac53199bc403000000056353006a53ffffffff04a25ce103000000000900ab5365656a526a63c8eff7030000000004526353537ab6db0200000000016a11a3fa02000000000651acacab526500000000", "53ac6aab6a6551", 0, 1117532791, "83c68b3c5a89260ce16ce8b4dbf02e1f573c532d9a72f5ea57ab419fa2630214"],
+ ["f7a09f10027250fc1b70398fb5c6bffd2be9718d3da727e841a73596fdd63810c9e4520a6a010000000963ac516a636a65acac1d2e2c57ab28d311edc4f858c1663972eebc3bbc93ed774801227fda65020a7ec1965f780200000005ac5252516a8299fddc01dcbf7200000000000463ac6551960fda03", "65acab51", 1, 2017321737, "9c5fa02abfd34d0f9dec32bf3edb1089fca70016debdb41f4f54affcb13a2a2a"],
+ ["6d97a9a5029220e04f4ccc342d8394c751282c328bf1c132167fc05551d4ca4da4795f6d4e02000000076a0052ab525165ffffffff9516a205e555fa2a16b73e6db6c223a9e759a7e09c9a149a8f376c0a7233fa1b0100000007acab51ab63ac6affffffff04868aed04000000000652ac65ac536a396edf01000000000044386c0000000000076aab5363655200894d48010000000001ab8ebefc23", "6351526aac51", 1, 1943666485, "f0bd4ca8e97203b9b4e86bc24bdc8a1a726db5e99b91000a14519dc83fc55c29"],
+ ["8e3fddfb028d9e566dfdda251cd874cd3ce72e9dde837f95343e90bd2a93fe21c5daeb5eed01000000045151525140517dc818181f1e7564b8b1013fd68a2f9a56bd89469686367a0e72c06be435cf99db750000000003635251ffffffff01c051780300000000096552ababac6a65acab099766eb", "5163ab6a52ababab51", 1, 1296295812, "5509eba029cc11d7dd2808b8c9eb47a19022b8d8b7778893459bbc19ab7ea820"],
+ ["a603f37b02a35e5f25aae73d0adc0b4b479e68a734cf722723fd4e0267a26644c36faefdab0200000000ffffffff43374ad26838bf733f8302585b0f9c22e5b8179888030de9bdda180160d770650200000001004c7309ce01379099040000000005526552536500000000", "abababab005153", 0, 1409936559, "4ca73da4fcd5f1b10da07998706ffe16408aa5dff7cec40b52081a6514e3827e"],
+ ["9eeedaa8034471a3a0e3165620d1743237986f060c4434f095c226114dcb4b4ec78274729f03000000086a5365510052ac6afb505af3736e347e3f299a58b1b968fce0d78f7457f4eab69240cbc40872fd61b5bf8b120200000002ac52df8247cf979b95a4c97ecb8edf26b3833f967020cd2fb25146a70e60f82c9ee4b14e88b103000000008459e2fa0125cbcd05000000000000000000", "52ab5352006353516a", 0, -1832576682, "fb018ae54206fdd20c83ae5873ec82b8e320a27ed0d0662db09cda8a071f9852"],
+ ["05921d7c048cf26f76c1219d0237c226454c2a713c18bf152acc83c8b0647a94b13477c07f0300000003ac526afffffffff2f494453afa0cabffd1ba0a626c56f90681087a5c1bd81d6adeb89184b27b7402000000036a6352ffffffff0ad10e2d3ce355481d1b215030820da411d3f571c3f15e8daf22fe15342fed04000000000095f29f7b93ff814a9836f54dc6852ec414e9c4e16a506636715f569151559100ccfec1d100000000055263656a53ffffffff04f4ffef010000000008ac6a6aabacabab6a0e6689040000000006ab536a5352abe364d005000000000965536363655251ab53807e00010000000004526aab63f18003e3", "6363ac51", 3, -375891099, "001b0b176f0451dfe2d9787b42097ceb62c70d324e925ead4c58b09eebdf7f67"],
+ ["b9b44d9f04b9f15e787d7704e6797d51bc46382190c36d8845ec68dfd63ee64cf7a467b21e00000000096aac00530052ab636aba1bcb110a80c5cbe073f12c739e3b20836aa217a4507648d133a8eedd3f02cb55c132b203000000076a000063526352b1c288e3a9ff1f2da603f230b32ef7c0d402bdcf652545e2322ac01d725d75f5024048ad0100000000ffffffffffd882d963be559569c94febc0ef241801d09dc69527c9490210f098ed8203c700000000056a006300ab9109298d01719d9a0300000000066a52ab006365d7894c5b", "ac6351650063636a", 3, -622355349, "ac87b1b93a6baab6b2c6624f10e8ebf6849b0378ef9660a3329073e8f5553c8d"],
+ ["ff60473b02574f46d3e49814c484081d1adb9b15367ba8487291fc6714fd6e3383d5b335f001000000026a6ae0b82da3dc77e5030db23d77b58c3c20fa0b70aa7d341a0f95f3f72912165d751afd57230300000008ac536563516a6363ffffffff04f86c0200000000000553acab636ab13111000000000003510065f0d3f305000000000951ab516a65516aabab730a3a010000000002515200000000", "ac6a", 1, 1895032314, "0767e09bba8cd66d55915677a1c781acd5054f530d5cf6de2d34320d6c467d80"],
+ ["f218026204f4f4fc3d3bd0eada07c57b88570d544a0436ae9f8b753792c0c239810bb30fbc0200000002536affffffff8a468928d6ec4cc10aa0f73047697970e99fa64ae8a3b4dca7551deb0b639149010000000851ab520052650051ffffffffa98dc5df357289c9f6873d0f5afcb5b030d629e8f23aa082cf06ec9a95f3b0cf0000000000ffffffffea2c2850c5107705fd380d6f29b03f533482fd036db88739122aac9eff04e0aa010000000365536a03bd37db034ac4c4020000000007515152655200ac33b27705000000000151efb71e0000000000007b65425b", "515151", 3, -1772252043, "de35c84a58f2458c33f564b9e58bc57c3e028d629f961ad1b3c10ee020166e5a"],
+ ["48e7d42103b260b27577b70530d1ac2fed2551e9dd607cbcf66dca34bb8c03862cf8f5fd5401000000075151526aacab00ffffffff1e3d3b841552f7c6a83ee379d9d66636836673ce0b0eda95af8f2d2523c91813030000000665acac006365ffffffff388b3c386cd8c9ef67c83f3eaddc79f1ff910342602c9152ffe8003bce51b28b0100000008636363006a636a52ffffffff04b8f67703000000000852005353ac6552520cef720200000000085151ab6352ab00ab5096d6030000000005516a005100662582020000000001ac6c137280", "6a65", 1, 1513618429, "e2fa3e1976aed82c0987ab30d4542da2cb1cffc2f73be13480132da8c8558d5c"],
+ ["91ebc4cf01bc1e068d958d72ee6e954b196f1d85b3faf75a521b88a78021c543a06e056279000000000265ab7c12df0503832121030000000000cc41a6010000000005ab5263516540a951050000000006ab63ab65acac00000000", "526a0065636a6a6aac", 0, -614046478, "7de4ba875b2e584a7b658818c112e51ee5e86226f5a80e5f6b15528c86400573"],
+ ["3cd4474201be7a6c25403bf00ca62e2aa8f8f4f700154e1bb4d18c66f7bb7f9b975649f0dc0100000006535151535153ffffffff01febbeb000000000006005151006aac00000000", "", 0, -1674687131, "6b77ca70cc452cc89acb83b69857cda98efbfc221688fe816ef4cb4faf152f86"],
+ ["92fc95f00307a6b3e2572e228011b9c9ed41e58ddbaefe3b139343dbfb3b34182e9fcdc3f50200000002acab847bf1935fde8bcfe41c7dd99683289292770e7f163ad09deff0e0665ed473cd2b56b0f40300000006516551ab6351294dab312dd87b9327ce2e95eb44b712cfae0e50fda15b07816c8282e8365b643390eaab01000000026aacffffffff016e0b6b040000000001ac00000000", "650065acac005300", 2, -1885164012, "bd7d26bb3a98fc8c90c972500618bf894cb1b4fe37bf5481ff60eef439d3b970"],
+ ["4db591ab018adcef5f4f3f2060e41f7829ce3a07ea41d681e8cb70a0e37685561e4767ac3b0000000005000052acabd280e63601ae6ef20000000000036a636326c908f7", "ac6a51526300630052", 0, 862877446, "355ccaf30697c9c5b966e619a554d3323d7494c3ea280a9b0dfb73f953f5c1cb"],
+ ["503fd5ef029e1beb7b242d10032ac2768f9a1aca0b0faffe51cec24770664ec707ef7ede4f01000000045253ac53375e350cc77741b8e96eb1ce2d3ca91858c052e5f5830a0193200ae2a45b413dda31541f0000000003516553ffffffff0175a5ba0500000000015200000000", "6aab65510053ab65", 1, 1603081205, "353ca9619ccb0210ae18b24d0e57efa7abf8e58fa6f7102738e51e8e72c9f0c4"],
+ ["c80abebd042cfec3f5c1958ee6970d2b4586e0abec8305e1d99eb9ee69ecc6c2cbd76374380000000007ac53006300ac510acee933b44817db79320df8094af039fd82111c7726da3b33269d3820123694d849ee5001000000056a65ab526562699bea8530dc916f5d61f0babea709dac578774e8a4dcd9c640ec3aceb6cb2443f24f302000000020063ea780e9e57d1e4245c1e5df19b4582f1bf704049c5654f426d783069bcc039f2d8fa659f030000000851ab53635200006a8d00de0b03654e8500000000000463ab635178ebbb0400000000055100636aab239f1d030000000006ab006300536500000000", "6565ac515100", 3, 1460851377, "b35bb1b72d02fab866ed6bbbea9726ab32d968d33a776686df3ac16aa445871e"],
+ ["0337b2d5043eb6949a76d6632b8bb393efc7fe26130d7409ef248576708e2d7f9d0ced9d3102000000075352636a5163007034384dfa200f52160690fea6ce6c82a475c0ef1caf5c9e5a39f8f9ddc1c8297a5aa0eb02000000026a51ffffffff38e536298799631550f793357795d432fb2d4231f4effa183c4e2f61a816bcf0030000000463ac5300706f1cd3454344e521fde05b59b96e875c8295294da5d81d6cc7efcfe8128f150aa54d6503000000008f4a98c704c1561600000000000072cfa6000000000000e43def01000000000100cf31cc0500000000066365526a6500cbaa8e2e", "", 3, 2029506437, "7615b4a7b3be865633a31e346bc3db0bcc410502c8358a65b8127089d81b01f8"],
+ ["59f6cffd034733f4616a20fe19ea6aaf6abddb30b408a3a6bd86cd343ab6fe90dc58300cc90200000000ffffffffc835430a04c3882066abe7deeb0fa1fdaef035d3233460c67d9eabdb05e95e5a02000000080065ac535353ab00ffffffff4b9a043e89ad1b4a129c8777b0e8d87a014a0ab6a3d03e131c27337bbdcb43b402000000066a5100abac6ad9e9bf62014bb118010000000001526cbe484f", "ab526352ab65", 0, 2103515652, "4f2ccf981598639bec57f885b4c3d8ea8db445ea6e61cfd45789c69374862e5e"],
+ ["cbc79b10020b15d605680a24ee11d8098ad94ae5203cb6b0589e432832e20c27b72a926af20300000006ab65516a53acbb854f3146e55c508ece25fa3d99dbfde641a58ed88c051a8a51f3dacdffb1afb827814b02000000026352c43e6ef30302410a020000000000ff4bd90100000000065100ab63000008aa8e0400000000095265526565ac5365abc52c8a77", "53526aac0051", 0, 202662340, "984efe0d8d12e43827b9e4b27e97b3777ece930fd1f589d616c6f9b71dab710e"],
+ ["7c07419202fa756d29288c57b5c2b83f3c847a807f4a9a651a3f6cd6c46034ae0aa3a7446b0200000004ab6a6365ffffffff9da83cf4219bb96c76f2d77d5df31c1411a421171d9b59ec02e5c1218f29935403000000008c13879002f8b1ac0400000000086a63536a636553653c584f02000000000000000000", "abac53ab656363", 1, -1038419525, "4a74f365a161bc6c9bddd249cbd70f5dadbe3de70ef4bd745dcb6ee1cd299fbd"],
+ ["351cbb57021346e076d2a2889d491e9bfa28c54388c91b46ee8695874ad9aa576f1241874d0200000008ab6563525300516affffffffe13e61b8880b8cd52be4a59e00f9723a4722ea58013ec579f5b3693b9e115b1100000000096363abac5252635351ffffffff027fee02040000000008ab6a5200ab006a65b85f130200000000086a52630053ab52ab00000000", "ab6aab65", 1, 586415826, "08bbb746a596991ab7f53a76e19acad087f19cf3e1db54054aab403c43682d09"],
+ ["a8252ea903f1e8ff953adb16c1d1455a5036222c6ea98207fc21818f0ece2e1fac310f9a0100000000095163ac635363ac0000be6619e9fffcde50a0413078821283ce3340b3993ad00b59950bae7a9f931a9b0a3a035f010000000463005300b8b0583fbd6049a1715e7adacf770162811989f2be20af33f5f60f26eba653dc26b024a00000000006525351636552ffffffff046d2acc030000000002636a9a2d430500000000080065005165ab53abecf63204000000000052b9ed050000000008acacac53ab65656500000000", "65ab53635253636a51", 2, 1442639059, "8ca11838775822f9a5beee57bdb352f4ee548f122de4a5ca61c21b01a1d50325"],
+ ["2f1a425c0471a5239068c4f38f9df135b1d24bf52d730d4461144b97ea637504495aec360801000000055300515365c71801dd1f49f376dd134a9f523e0b4ae611a4bb122d8b26de66d95203f181d09037974300000000025152ffffffff9bdcea7bc72b6e5262e242c94851e3a5bf8f314b3e5de0e389fc9e5b3eadac030000000009525265655151005153ffffffffdbb53ce99b5a2320a4e6e2d13b01e88ed885a0957d222e508e9ec8e4f83496cb0200000007635200abac63ac04c96237020cc5490100000000080000516a51ac6553074a360200000000025152225520ca", "6551ab65ac65516a", 1, -489869549, "9bc5bb772c553831fb40abe466074e59a469154679c7dee042b8ea3001c20393"],
+ ["ef3acfd4024defb48def411b8f8ba2dc408dc9ee97a4e8bde4d6cb8e10280f29c98a6e8e9103000000035100513d5389e3d67e075469dfd9f204a7d16175653a149bd7851619610d7ca6eece85a516b2df0300000005516aac6552ca678bdf02f477f003000000000057e45b0300000000055252525252af35c20a", "5165ac53ab", 1, -1900839569, "78eb6b24365ac1edc386aa4ffd15772f601059581c8776c34f92f8a7763c9ccf"],
+ ["ff4468dc0108475fc8d4959a9562879ce4ab4867a419664bf6e065f17ae25043e6016c70480100000000ffffffff02133c6f0400000000000bd0a8020000000004006a520035afa4f6", "51ac65ab", 0, -537664660, "f6da59b9deac63e83728850ac791de61f5dfcaeed384ebcbb20e44afcd8c8910"],
+ ["4e8594d803b1d0a26911a2bcdd46d7cbc987b7095a763885b1a97ca9cbb747d32c5ab9aa91030000000353ac53a0cc4b215e07f1d648b6eeb5cdbe9fa32b07400aa773b9696f582cebfd9930ade067b2b200000000060065abab6500fc99833216b8e27a02defd9be47fafae4e4a97f52a9d2a210d08148d2a4e5d02730bcd460100000004516351ac37ce3ae1033baa55040000000006006a636a63acc63c990400000000025265eb1919030000000005656a6a516a00000000", "", 1, -75217178, "04c5ee48514cd033b82a28e336c4d051074f477ef2675ce0ce4bafe565ee9049"],
+ ["a88830a7023f13ed19ab14fd757358eb6af10d6520f9a54923a6d613ac4f2c11e249cda8aa030000000851630065abababacffffffff8f5fe0bc04a33504c4b47e3991d25118947a0261a9fa520356731eeabd561dd3020000000363ababffffffff038404bd010000000008ab5153516aab6a63d33a5601000000000263004642dc020000000009655152acac636352004be6f3af", "5253536565006aab6a", 0, 1174417836, "2e42ead953c9f4f81b72c27557e6dc7d48c37ff2f5c46c1dbe9778fb0d79f5b2"],
+ ["44e1a2b4010762af23d2027864c784e34ef322b6e24c70308a28c8f2157d90d17b99cd94a401000000085163656565006300ffffffff0198233d020000000002000000000000", "52525153656365", 0, 1119696980, "d9096de94d70c6337da6202e6e588166f31bff5d51bb5adc9468594559d65695"],
+ ["44ca65b901259245abd50a745037b17eb51d9ce1f41aa7056b4888285f48c6f26cb97b7a25020000000552636363abffffffff047820350400000000040053acab14f3e603000000000652635100ab630ce66c03000000000001bdc704000000000765650065ac51ac3e886381", "51", 0, -263340864, "ed5622ac642d11f90e68c0feea6a2fe36d880ecae6b8c0d89c4ea4b3d162bd90"],
+ ["cfa147d2017fe84122122b4dda2f0d6318e59e60a7207a2d00737b5d89694d480a2c26324b0000000006006351526552ffffffff0456b5b804000000000800516aab525363ab166633000000000004655363ab254c0e02000000000952ab6a6a00ab525151097c1b020000000009656a52ac6300530065ad0d6e50", "6a535165ac6a536500", 0, -574683184, "f926d4036eac7f019a2b0b65356c4ee2fe50e089dd7a70f1843a9f7bc6997b35"],
+ ["91c5d5f6022fea6f230cc4ae446ce040d8313071c5ac1749c82982cc1988c94cb1738aa48503000000016a19e204f30cb45dd29e68ff4ae160da037e5fc93538e21a11b92d9dd51cf0b5efacba4dd70000000005656a6aac51ffffffff03db126905000000000953006a53ab6563636a36a273030000000006656a52656552b03ede00000000000352516500000000", "530052526a00", 1, 1437328441, "255c125b60ee85f4718b2972174c83588ee214958c3627f51f13b5fb56c8c317"],
+ ["03f20dc202c886907b607e278731ebc5d7373c348c8c66cac167560f19b341b782dfb634cb03000000076a51ac6aab63abea3e8de7adb9f599c9caba95aa3fa852e947fc88ed97ee50e0a0ec0d14d164f44c0115c10100000004ab5153516fdd679e0414edbd000000000005ac636a53512021f2040000000007006a0051536a52c73db2050000000005525265ac5369046e000000000003ab006a1ef7bd1e", "52656a", 0, 1360223035, "5a0a05e32ce4cd0558aabd5d79cd5fcbffa95c07137506e875a9afcba4bef5a2"],
+ ["d9611140036881b61e01627078512bc3378386e1d4761f959d480fdb9d9710bebddba2079d020000000763536aab5153ab819271b41e228f5b04daa1d4e72c8e1955230accd790640b81783cfc165116a9f535a74c000000000163ffffffffa2e7bb9a28e810624c251ff5ba6b0f07a356ac082048cf9f39ec036bba3d431a02000000076a000000ac65acffffffff01678a820000000000085363515153ac635100000000", "535353", 2, -82213851, "52b9e0778206af68998cbc4ebdaad5a9469e04d0a0a6cef251abfdbb74e2f031"],
+ ["98b3a0bf034233afdcf0df9d46ac65be84ef839e58ee9fa59f32daaa7d684b6bdac30081c60200000007636351acabababffffffffc71cf82ded4d1593e5825618dc1d5752ae30560ecfaa07f192731d68ea768d0f0100000006650052636563f3a2888deb5ddd161430177ce298242c1a86844619bc60ca2590d98243b5385bc52a5b8f00000000095365acacab520052ac50d4722801c3b8a60300000000035165517e563b65", "51", 1, -168940690, "b6b684e2d2ecec8a8dce4ed3fc1147f8b2e45732444222aa8f52d860c2a27a9d"],
+ ["97be4f7702dc20b087a1fdd533c7de762a3f2867a8f439bddf0dcec9a374dfd0276f9c55cc0300000000cdfb1dbe6582499569127bda6ca4aaff02c132dc73e15dcd91d73da77e92a32a13d1a0ba0200000002ab51ffffffff048cfbe202000000000900516351515363ac535128ce0100000000076aac5365ab6aabc84e8302000000000863536a53ab6a6552f051230500000000066aac535153510848d813", "ac51", 0, 229541474, "e5da9a416ea883be1f8b8b2d178463633f19de3fa82ae25d44ffb531e35bdbc8"],
+ ["085b6e04040b5bff81e29b646f0ed4a45e05890a8d32780c49d09643e69cdccb5bd81357670100000001abffffffffa5c981fe758307648e783217e3b4349e31a557602225e237f62b636ec26df1a80300000004650052ab4792e1da2930cc90822a8d2a0a91ea343317bce5356b6aa8aae6c3956076aa33a5351a9c0300000004abac5265e27ddbcd472a2f13325cc6be40049d53f3e266ac082172f17f6df817db1936d9ff48c02b000000000152ffffffff021aa7670500000000085353635163ab51ac14d584000000000001aca4d136cc", "6a525300536352536a", 0, -1398925877, "41ecca1e8152ec55074f4c39f8f2a7204dda48e9ec1e7f99d5e7e4044d159d43"],
+ ["eec32fff03c6a18b12cd7b60b7bdc2dd74a08977e53fdd756000af221228fe736bd9c42d870100000007005353ac515265ffffffff037929791a188e9980e8b9cc154ad1b0d05fb322932501698195ab5b219488fc02000000070063510065ab6a0bfc176aa7e84f771ea3d45a6b9c24887ceea715a0ff10ede63db8f089e97d927075b4f1000000000551abab63abffffffff02eb933c000000000000262c420000000000036563632549c2b6", "6352", 2, 1480445874, "ff8a4016dfdd918f53a45d3a1f62b12c407cd147d68ca5c92b7520e12c353ff5"],
+ ["98ea7eac0313d9fb03573fb2b8e718180c70ce647bebcf49b97a8403837a2556cb8c9377f30000000004ac53ac65ffffffff8caac77a5e52f0d8213ef6ce998bedbb50cfdf108954771031c0e0cd2a78423900000000010066e99a44937ebb37015be3693761078ad5c73aa73ec623ac7300b45375cc8eef36087eb80000000007515352acac5100ffffffff0114a51b02000000000000000000", "6aacab", 0, 243527074, "bad77967f98941af4dd52a8517d5ad1e32307c0d511e15461e86465e1b8b5273"],
+ ["3ab70f4604e8fc7f9de395ec3e4c3de0d560212e84a63f8d75333b604237aa52a10da17196000000000763526a6553ac63a25de6fd66563d71471716fe59087be0dde98e969e2b359282cf11f82f14b00f1c0ac70f02000000050052516aacdffed6bb6889a13e46956f4b8af20752f10185838fd4654e3191bf49579c961f5597c36c0100000005ac636363abc3a1785bae5b8a1b4be5d0cbfadc240b4f7acaa7dfed6a66e852835df5eb9ac3c553766801000000036a65630733b7530218569602000000000952006a6a6a51acab52777f06030000000007ac0063530052abc08267c9", "000000536aac0000", 1, 1919096509, "df1c87cf3ba70e754d19618a39fdbd2970def0c1bfc4576260cba5f025b87532"],
+ ["bdb6b4d704af0b7234ced671c04ba57421aba7ead0a117d925d7ebd6ca078ec6e7b93eea6600000000026565ffffffff3270f5ad8f46495d69b9d71d4ab0238cbf86cc4908927fbb70a71fa3043108e6010000000700516a65655152ffffffff6085a0fdc03ae8567d0562c584e8bfe13a1bd1094c518690ebcb2b7c6ce5f04502000000095251530052536a53aba576a37f2c516aad9911f687fe83d0ae7983686b6269b4dd54701cb5ce9ec91f0e6828390300000000ffffffff04cc76cc020000000002656a01ffb702000000000253ab534610040000000009acab006565516a00521f55f5040000000000389dfee9", "6a525165", 0, 1336204763, "71c294523c48fd7747eebefbf3ca06e25db7b36bff6d95b41c522fecb264a919"],
+ ["54258edd017d22b274fbf0317555aaf11318affef5a5f0ae45a43d9ca4aa652c6e85f8a040010000000953ac65ab5251656500ffffffff03321d450000000000085265526a51526a529ede8b030000000003635151ce6065020000000001534c56ec1b", "acac", 0, 2094130012, "110d90fea9470dfe6c5048f45c3af5e8cc0cb77dd58fd13d338268e1c24b1ccc"],
+ ["ce0d322e04f0ffc7774218b251530a7b64ebefca55c90db3d0624c0ff4b3f03f918e8cf6f60300000003656500ffffffff9cce943872da8d8af29022d0b6321af5fefc004a281d07b598b95f6dcc07b1830200000007abab515351acab8d926410e69d76b7e584aad1470a97b14b9c879c8b43f9a9238e52a2c2fefc2001c56af8010000000400ab5253cd2cd1fe192ce3a93b5478af82fa250c27064df82ba416dfb0debf4f0eb307a746b6928901000000096500abacac6a0063514214524502947efc0200000000035251652c40340100000000096a6aab52000052656a5231c54c", "51", 2, -2090320538, "0322ca570446869ec7ec6ad66d9838cff95405002d474c0d3c17708c7ee039c6"],
+ ["47ac54940313430712ebb32004679d3a512242c2b33d549bf5bbc8420ec1fd0850ed50eb6d0300000009536aac6a65acacab51ffffffffb843e44266ce2462f92e6bff54316661048c8c17ecb092cb493b39bfca9117850000000001519ab348c05e74ebc3f67423724a3371dd99e3bceb4f098f8860148f48ad70000313c4c223000000000653006565656512c2d8dc033f3c97010000000002636aa993aa010000000006526365ab526ab7cf560300000000076a0065ac6a526500000000", "005352535300ab6a", 2, 59531991, "8b5b3d00d9c658f062fe6c5298e54b1fe4ed3a3eab2a87af4f3119edc47b1691"],
+ ["233cd90b043916fc41eb870c64543f0111fb31f3c486dc72457689dea58f75c16ae59e9eb2000000000500536a6a6affffffff9ae30de76be7cd57fb81220fce78d74a13b2dbcad4d023f3cadb3c9a0e45a3ce000000000965ac6353ac5165515130834512dfb293f87cb1879d8d1b20ebad9d7d3d5c3e399a291ce86a3b4d30e4e32368a9020000000453005165ffffffff26d84ae93eb58c81158c9b3c3cbc24a84614d731094f38d0eea8686dec02824d0300000005636a65abacf02c784001a0bd5d03000000000900655351ab65ac516a416ef503", "", 1, -295106477, "b79f31c289e95d9dadec48ebf88e27c1d920661e50d090e422957f90ff94cb6e"],
+ ["9200e26b03ff36bc4bf908143de5f97d4d02358db642bd5a8541e6ff709c420d1482d471b70000000008abab65536a636553ffffffff61ba6d15f5453b5079fb494af4c48de713a0c3e7f6454d7450074a2a80cb6d880300000007ac6a00ab5165515dfb7574fbce822892c2acb5d978188b1d65f969e4fe874b08db4c791d176113272a5cc10100000000ffffffff0420958d000000000009ac63516a0063516353dd885505000000000465ac00007b79e901000000000066d8bf010000000005525252006a00000000", "ac5152", 0, 2089531339, "89ec7fab7cfe7d8d7d96956613c49dc48bf295269cfb4ea44f7333d88c170e62"],
+ ["45f335ba01ce2073a8b0273884eb5b48f56df474fc3dff310d9706a8ac7202cf5ac188272103000000025363ffffffff049d859502000000000365ab6a8e98b1030000000002ac51f3a80603000000000752535151ac00000306e30300000000020051b58b2b3a", "", 0, 1899564574, "78e01310a228f645c23a2ad0acbb8d91cedff4ecdf7ca997662c6031eb702b11"],
+ ["d8f652a6043b4faeada05e14b81756cd6920cfcf332e97f4086961d49232ad6ffb6bc6c097000000000453526563ffffffff1ea4d60e5e91193fbbc1a476c8785a79a4c11ec5e5d6c9950c668ceacfe07a15020000000352ab51fffffffffe029a374595c4edd382875a8dd3f20b9820abb3e93f877b622598d11d0b09e503000000095351000052ac515152ffffffff9d65fea491b979699ceb13caf2479cd42a354bd674ded3925e760758e85a756803000000046365acabffffffff0169001d00000000000651636a65656300000000", "ab0063630000ac", 3, 1050965951, "4cc85cbc2863ee7dbce15490d8ca2c5ded61998257b9eeaff968fe38e9f009ae"],
+ ["718662be026e1dcf672869ac658fd0c87d6835cfbb34bd854c44e577d5708a7faecda96e260300000004526a636a489493073353b678549adc7640281b9cbcb225037f84007c57e55b874366bb7b0fa03bdc00000000095165ababac65ac00008ab7f2a802eaa53d000000000007acac516aac526ae92f380100000000056aac00536500000000", "ab00", 1, 43296088, "2d642ceee910abff0af2116af75b2e117ffb7469b2f19ad8fef08f558416d8f7"],
+ ["94083c840288d40a6983faca876d452f7c52a07de9268ad892e70a81e150d602a773c175ad03000000007ec3637d7e1103e2e7e0c61896cbbf8d7e205b2ecc93dd0d6d7527d39cdbf6d335789f660300000000ffffffff019e1f7b03000000000800ac0051acac0053539cb363", "", 1, -183614058, "a17b66d6bb427f42653d08207a22b02353dd19ccf2c7de6a9a3a2bdb7c49c9e7"],
+ ["30e0d4d20493d0cd0e640b757c9c47a823120e012b3b64c9c1890f9a087ae4f2001ca22a61010000000152f8f05468303b8fcfaad1fb60534a08fe90daa79bff51675472528ebe1438b6f60e7f60c10100000009526aab6551ac510053ffffffffaaab73957ea2133e32329795221ed44548a0d3a54d1cf9c96827e7cffd1706df0200000009ab00526a005265526affffffffd19a6fe54352015bf170119742821696f64083b5f14fb5c7d1b5a721a3d7786801000000085265abababac53abffffffff020f39bd030000000004ab6aac52049f6c050000000004ab52516aba5b4c60", "6a6365516a6a655253", 0, -624256405, "8e221a6c4bf81ca0d8a0464562674dcd14a76a32a4b7baf99450dd9195d411e6"],
+ ["f9c69d940276ec00f65f9fe08120fc89385d7350388508fd80f4a6ba2b5d4597a9e21c884f010000000663ab63ababab15473ae6d82c744c07fc876ecd53bd0f3018b2dbedad77d757d5bdf3811b23d294e8c0170000000001abafababe00157ede2050000000006ac6a5263635300000000", "ab53", 1, 606547088, "714d8b14699835b26b2f94c58b6ea4c53da3f7adf0c62ea9966b1e1758272c47"],
+ ["5c0ac112032d6885b7a9071d3c5f493aa16c610a4a57228b2491258c38de8302014276e8be030000000300ab6a17468315215262ad5c7393bb5e0c5a6429fd1911f78f6f72dafbbbb78f3149a5073e24740300000003ac5100ffffffff33c7a14a062bdea1be3c9c8e973f54ade53fe4a69dcb5ab019df5f3345050be00100000008ac63655163526aab428defc0033ec36203000000000765516365536a00ae55b2000000000002ab53f4c0080400000000095265516a536563536a00000000", "6a005151006a", 2, 272749594, "91082410630337a5d89ff19145097090f25d4a20bdd657b4b953927b2f62c73b"],
+ ["e3683329026720010b08d4bec0faa244f159ae10aa582252dd0f3f80046a4e145207d54d31000000000852acac52656aacac3aaf2a5017438ad6adfa3f9d05f53ebed9ceb1b10d809d507bcf75e0604254a8259fc29c020000000653526552ab51f926e52c04b44918030000000000f7679c0100000000090000525152005365539e3f48050000000009516500ab635363ab008396c905000000000253650591024f", "6a6365", 0, 908746924, "458aec3b5089a585b6bad9f99fd37a2b443dc5a2eefac2b7e8c5b06705efc9db"],
+ ["48c4afb204204209e1df6805f0697edaa42c0450bbbd767941fe125b9bc40614d63d757e2203000000066a5363005152dc8b6a605a6d1088e631af3c94b8164e36e61445e2c60130292d81dabd30d15f54b355a802000000036a6353ffffffff1d05dcec4f3dedcfd02c042ce5d230587ee92cb22b52b1e59863f3717df2362f0300000005536552ac52ffffffffd4d71c4f0a7d53ba47bb0289ca79b1e33d4c569c1e951dd611fc9c9c1ca8bc6c030000000865536a65ab51abacffffffff042f9aa905000000000753655153656351ab93d8010000000002655337440e0300000000005d4c690000000000015278587acb", "ab006565526a51", 0, 1502064227, "bbed77ff0f808aa8abd946ba9e7ec1ddb003a969fa223dee0af779643cb841a9"],
+ ["00b20fd104dd59705b84d67441019fa26c4c3dec5fd3b50eca1aa549e750ef9ddb774dcabe000000000651ac656aac65ffffffff52d4246f2db568fc9eea143e4d260c698a319f0d0670f84c9c83341204fde48b0200000000ffffffffb8aeabb85d3bcbc67b132f1fd815b451ea12dcf7fc169c1bc2e2cf433eb6777a03000000086a51ac6aab6563acd510d209f413da2cf036a31b0def1e4dcd8115abf2e511afbcccb5ddf41d9702f28c52900100000006ac52ab6a0065ffffffff039c8276000000000008ab53655200656a52401561010000000003acab0082b7160100000000035100ab00000000", "535265", 1, -947367579, "3212c6d6dd8d9d3b2ac959dec11f4638ccde9be6ed5d36955769294e23343da0"],
+ ["455131860220abbaa72015519090a666faf137a0febce7edd49da1eada41feab1505a0028b02000000036365ab453ead4225724eb69beb590f2ec56a7693a608871e0ab0c34f5e96157f90e0a96148f3c502000000085251ab51535163acffffffff022d1249040000000009abac00acac6565630088b310040000000000e3920e59", "5152ab6a52ac5152", 0, 294375737, "c40fd7dfa72321ac79516502500478d09a35cc22cc264d652c7d18b14400b739"],
+ ["624d28cb02c8747915e9af2b13c79b417eb34d2fa2a73547897770ace08c6dd9de528848d3030000000651ab63abab533c69d3f9b75b6ef8ed2df50c2210fd0bf4e889c42477d58682f711cbaece1a626194bb85030000000765acab53ac5353ffffffff018cc280040000000009abacabac52636352ac6859409e", "ac51ac", 1, 1005144875, "919144aada50db8675b7f9a6849c9d263b86450570293a03c245bd1e3095e292"],
+ ["8f28471d02f7d41b2e70e9b4c804f2d90d23fb24d53426fa746bcdcfffea864925bdeabe3e0200000001acffffffff76d1d35d04db0e64d65810c808fe40168f8d1f2143902a1cc551034fd193be0e0000000001acffffffff048a5565000000000005005151516afafb610400000000045263ac53648bb30500000000086363516a6a5165513245de01000000000000000000", "6a0053510053", 1, -1525137460, "305fc8ff5dc04ebd9b6448b03c9a3d945a11567206c8d5214666b30ec6d0d6cc"],
+ ["10ec50d7046b8b40e4222a3c6449490ebe41513aad2eca7848284a08f3069f3352c2a9954f0000000009526aac656352acac53ffffffff0d979f236155aa972472d43ee6f8ce22a2d052c740f10b59211454ff22cb7fd00200000007acacacab63ab53ffffffffbbf97ebde8969b35725b2e240092a986a2cbfd58de48c4475fe077bdd493a20c010000000663ab5365ababffffffff4600722d33b8dba300d3ad037bcfc6038b1db8abfe8008a15a1de2da2264007302000000035351ac6dbdafaf020d0ccf04000000000663ab6a51ab6ae06e5e0200000000036aabab00000000", "", 0, -1658960232, "2420dd722e229eccafae8508e7b8d75c6920bfdb3b5bac7cb8e23419480637c2"],
+ ["fef98b7101bf99277b08a6eff17d08f3fcb862e20e13138a77d66fba55d54f26304143e5360100000006515365abab00ffffffff04265965030000000004655252ace2c775010000000001002b23b4040000000007516a5153ab53ac456a7a00000000000753ab525251acacba521291", "526aacacab00abab53", 0, -1614097109, "4370d05c07e231d6515c7e454a4e401000b99329d22ed7def323976fa1d2eeb5"],
+ ["34a2b8830253661b373b519546552a2c3bff7414ea0060df183b1052683d78d8f54e842442000000000152ffffffffd961a8e34cf374151058dfcddc86509b33832bc57267c63489f69ff01199697c0300000002abacba856cfb01b17c2f050000000008515365ac53ab000000000000", "5263ab656a", 1, -2104480987, "2f9993e0a84a6ca560d6d1cc2b63ffe7fd71236d9cfe7d809491cef62bbfad84"],
+ ["43559290038f32fda86580dd8a4bc4422db88dd22a626b8bd4f10f1c9dd325c8dc49bf479f01000000026351ffffffff401339530e1ed3ffe996578a17c3ec9d6fccb0723dd63e7b3f39e2c44b976b7b0300000006ab6a65656a51ffffffff6fb9ba041c96b886482009f56c09c22e7b0d33091f2ac5418d05708951816ce7000000000551ac525100ffffffff020921e40500000000035365533986f40500000000016a00000000", "52ac51", 0, 1769771809, "02040283ef2291d8e1f79bb71bdabe7c1546c40d7ed615c375643000a8b9600d"],
+ ["6878a6bd02e7e1c8082d5e3ee1b746cfebfac9e8b97e61caa9e0759d8a8ecb3743e36a30de0100000002ab532a911b0f12b73e0071f5d50b6bdaf783f4b9a6ce90ec0cad9eecca27d5abae188241ddec0200000001651c7758d803f7457b0500000000036551515f4e90000000000001007022080200000000035365acc86b6946", "6351ab", 0, -1929374995, "f24be499c58295f3a07f5f1c6e5084496ae160450bd61fdb2934e615289448f1"],
+ ["35b6fc06047ebad04783a5167ab5fc9878a00c4eb5e7d70ef297c33d5abd5137a2dea9912402000000036aacacffffffff21dc291763419a584bdb3ed4f6f8c60b218aaa5b99784e4ba8acfec04993e50c03000000046a00ac6affffffff69e04d77e4b662a82db71a68dd72ef0af48ca5bebdcb40f5edf0caf591bb41020200000000b5db78a16d93f5f24d7d932f93a29bb4b784febd0cbb1943f90216dc80bba15a0567684b000000000853ab52ab5100006a1be2208a02f6bdc103000000000265ab8550ea04000000000365636a00000000", "", 0, -1114114836, "1c8655969b241e717b841526f87e6bd68b2329905ba3fc9e9f72526c0b3ea20c"],
+ ["bebb90c302bf91fd4501d33555a5fc5f2e1be281d9b7743680979b65c3c919108cc2f517510100000003abab00ffffffff969c30053f1276550532d0aa33cfe80ca63758cd215b740448a9c08a84826f3303000000056565ab5153ffffffff04bf6f2a04000000000565ab5265ab903e760100000000026a6a7103fa020000000006526553525365b05b2c000000000006ab000000535300000000", "51510053ab63635153", 1, 1081291172, "94338cd47a4639be30a71e21a7103cee4c99ef7297e0edd56aaf57a068b004de"],
+ ["af48319f031b4eeb4319714a285f44244f283cbff30dcb9275b06f2348ccd0d7f015b54f8500000000066363ac65ac6affffffff2560a9817ebbc738ad01d0c9b9cf657b8f9179b1a7f073eb0b67517409d108180200000005ac6365ab52ffffffff0bdd67cd4ecae96249a2e2a96db1490ee645f042fd9d5579de945e22b799f4d003000000086552ab515153ab00cf187c8202e51abf0300000000066552006a00abadf37d000000000004ac6a535100000000", "63ab65", 1, -1855554446, "60caf46a7625f303c04706cec515a44b68ec319ee92273acb566cca4f66861c1"],
+ ["f35befbc03faf8c25cc4bc0b92f6239f477e663b44b83065c9cb7cf231243032cf367ce3130000000005ab65526a517c4c334149a9c9edc39e29276a4b3ffbbab337de7908ea6f88af331228bd90086a6900ba020000000151279d19950d2fe81979b72ce3a33c6d82ebb92f9a2e164b6471ac857f3bbd3c0ea213b542010000000953ab51635363520065052657c20300a9ba04000000000452636a6a0516ea020000000008535253656365ababcfdd3f01000000000865ac516aac00530000000000", "", 2, -99793521, "c834a5485e68dc13edb6c79948784712122440d7fa5bbaa5cd2fc3d4dac8185d"],
+ ["d3da18520216601acf885414538ce2fb4d910997eeb91582cac42eb6982c9381589587794f0300000000fffffffff1b1c9880356852e10cf41c02e928748dd8fae2e988be4e1c4cb32d0bfaea6f7000000000465ab6aabffffffff02fb0d69050000000002ababeda8580500000000085163526565ac52522b913c95", "ac", 1, -1247973017, "99b32b5679d91e0f9cdd6737afeb07459806e5acd7630c6a3b9ab5d550d0c003"],
+ ["8218eb740229c695c252e3630fc6257c42624f974bc856b7af8208df643a6c520ef681bfd00000000002510066f30f270a09b2b420e274c14d07430008e7886ec621ba45665057120afce58befca96010300000004525153ab84c380a9015d96100000000000076a5300acac526500000000", "ac005263", 0, -1855679695, "5071f8acf96aea41c7518bd1b5b6bbe16258b529df0c03f9e374b83c66b742c6"],
+ ["1123e7010240310013c74e5def60d8e14dd67aedff5a57d07a24abc84d933483431b8cf8ea0300000003530051fc6775ff1a23c627a2e605dd2560e84e27f4208300071e90f4589e762ad9c9fe8d0da95e020000000465655200ffffffff04251598030000000004ab65ab639d28d90400000000096563636aacac525153474df801000000000851525165ac51006a75e23b040000000000e5bd3a4a", "6363636565", 0, -467124448, "9cb0dd04e9fe287b112e94a1647590d27e8b164ca13c4fe70c610fd13f82c2fd"],
+ ["fd92fe1003083c5179f97e77bf7d71975788138147adbdb283306802e261c0aee080fa22630200000000860c643ba9a1816b9badf36077b4554d11720e284e395a1121bc45279e148b2064c65e49020000000651ab6a53636a2c713088d20f4bc4001264d972cce05b9fe004dc33376ad24d0d013e417b91a5f1b6734e000000000100ffffffff02e3064c0500000000066552006a5165b86e8705000000000665ab65ab53522052eadb", "00ab53525265", 0, 776203277, "47207b48777727532f62e09afcd4104ea6687e723c7657c30504fa2081331cc8"],
+ ["d1b6a703038f14d41fcc5cc45455faa135a5322be4bf0f5cbcd526578fc270a236cacb853f0200000001abffffffff135aeff902fa38f202ccf5bd34437ff89c9dc57a028b62447a0a38579383e8ef0000000000ffffffffadf398d2c818d0b90bc474f540c3618a4a643482eeab73d36101987e2ec0335900000000004bd3323504e69fc10000000000055151535251790ada02000000000563ab6aab521337a704000000000963ac63abacac52656a1e9862010000000007656500ac51ab6a8f4ee672", "ab5251656565ac63", 2, 82008394, "b8f3d255549909c07588ecba10a02e55a2d6f2206d831af9da1a7dae64cfbc8b"],
+ ["81dadaa7011556683db3fe95262f4fdb20391b7e75b7ffcee51b176af64d83c06f85545d620200000005ab5151ab52ffffffff044805ef0300000000065353516352639702c802000000000900516351515252ab5270db08040000000009ac516aab526553abac4aabc90500000000096365ab0052636a525100000000", "6565ab6a5152", 0, -2126294159, "ad01ec9d6dbae325ec3a8e1fd98e2d03b1188378210efef093dd8b0b0ef3f19d"],
+ ["3b937e05032b8895d2f4945cb7e3679be2fbd15311e2414f4184706dbfc0558cf7de7b4d000000000001638b91a12668a3c3ce349788c961c26aa893c862f1e630f18d80e7843686b6e1e6fc396310000000000852635353ab65ac51eeb09dd1c9605391258ee6f74b9ae17b5e8c2ef010dc721c5433dcdc6e93a1593e3b6d1700000000085365ac6553526351ffffffff0308b18e04000000000253acb6dd00040000000008536aac5153ac516ab0a88201000000000500ac006500804e3ff2", "", 0, 416167343, "595a3c02254564634e8085283ec4ea7c23808da97ce9c5da7aecd7b553e7fd7f"],
+ ["a48f27ca047997470da74c8ee086ddad82f36d9c22e790bd6f8603ee6e27ad4d3174ea875403000000095153ac636aab6aacabffffffffefc936294e468d2c9a99e09909ba599978a8c0891ad47dc00ba424761627cef202000000056a51630053ffffffff304cae7ed2d3dbb4f2fbd679da442aed06221ffda9aee460a28ceec5a9399f4e0200000000f5bddf82c9c25fc29c5729274c1ff0b43934303e5f595ce86316fc66ad263b96ca46ab8d0100000003536500d7cf226b0146b00c04000000000200ac5c2014ce", "515100636563", 0, 1991799059, "9c051a7092fe17fa62b1720bc2c4cb2ffc1527d9fb0b006d2e142bb8fe07bf3c"],
+ ["180cd53101c5074cf0b7f089d139e837fe49932791f73fa2342bd823c6df6a2f72fe6dba1303000000076a6a63ac53acabffffffff03853bc1020000000007ac526a6a6a6a003c4a8903000000000453515163a0fbbd030000000005ab656a5253253d64cf", "ac65", 0, -1548453970, "4d8efb3b99b9064d2f6be33b194a903ffabb9d0e7baa97a48fcec038072aac06"],
+ ["c21ec8b60376c47e057f2c71caa90269888d0ffd5c46a471649144a920d0b409e56f190b700000000008acac6a526a536365ffffffff5d315d9da8bf643a9ba11299450b1f87272e6030fdb0c8adc04e6c1bfc87de9a0000000000ea43a9a142e5830c96b0ce827663af36b23b0277244658f8f606e95384574b91750b8e940000000007516a63ac0063acffffffff023c61be0400000000055165ab5263313cc8020000000006006a53526551ed8c3d56", "6a", 1, 1160627414, "a638cc17fd91f4b1e77877e8d82448c84b2a4e100df1373f779de7ad32695112"],
+ ["128cd90f04b66a4cbc78bf48748f6eec0f08d5193ee8d0a6f2e8d3e5f138ed12c2c87d01a301000000085200ab6aac00ab00ffffffff09fc88bb1851e3dfb3d30179c38e15aeb1b39929c7c74f6acd071994ed4806490300000000e7fc5ea12ec56f56c0d758ecf4bb88aa95f3b08176b336db3b9bec2f6e27336dce28adbe030000000400530051fffffffffd6ff1adcf1fbe0d883451ee46904f1b7e8820243d395559b2d4ee8190a6e891000000000080fb1ae702f85b400000000000035200ab8d9651010000000006ab6a52536aab00000000", "ab", 1, 1667598199, "c10ccc9db8a92d7d4b133a2980782dab9d9d1d633d0dde9f9612ada57771fd89"],
+ ["da9695a403493d3511c10e1fe1286f954db0366b7667c91ef18ae4578056c1bf752114ac5901000000035351519788d91dd1f9c62dc005d80ea54eb13f7131ca5aace3d5d29f9b58ccc5fbc9a27e779950010000000453ac6a00ffffffffe2556ff29ebe83eb42a32c7a8d93bc598043578f491b5935805a33608538845a030000000252ab65d21b3b018f26c4030000000006acab51535352e1cbcb10", "006565ab52", 2, -1550927794, "0ca673a1ee66f9625ceb9ab278ebef772c113c188112b02824570c17fdf48194"],
+ ["b240517501334021240427adb0b413433641555424f6d24647211e3e6bfbb22a8045cbda2f000000000071bac8630112717802000000000000000000", "6a5165abac52656551", 0, 1790414254, "2c8be597620d95abd88f9c1cf4967c1ae3ca2309f3afec8928058c9598660e9e"],
+ ["96bac43903044a199b4b3efeeec5d196ee23fb05495541fa2cd6fb6405a9432d1723363660010000000151ffffffffe6ce2b66ce1488918a3e880bebb0e750123f007c7bcbac8fcd67ce75cb6fbae80300000000ffffffff9c0955aa07f506455834895c0c56be5a095398f47c62a3d431fe125b161d666a0200000005520000abac7ffdbc540216f2f004000000000165a26dce010000000001ab00000000", "5151ab656a656a6a63", 0, -707123065, "26b22e18d5d9081fde9631594a4f7c49069ed2e429f3d08caf9d834f685ccab2"],
+ ["b8fd394001ed255f49ad491fecc990b7f38688e9c837ccbc7714ddbbf5404f42524e68c18f0000000007ab6353535363ab081e15ee02706f7d050000000008515200535351526364c7ec040000000005636a53acac9206cbe1", "655352ac", 0, -1251578838, "8e0697d8cd8a9ccea837fd798cc6c5ed29f6fbd1892ee9bcb6c944772778af19"],
+ ["e42a76740264677829e30ed610864160c7f97232c16528fe5610fc08814b21c34eefcea69d010000000653006a6a0052ffffffff647046cf44f217d040e6a8ff3f295312ab4dd5a0df231c66968ad1c6d8f4428000000000025352ffffffff0199a7f900000000000000000000", "655263006a005163", 1, 1122505713, "7cda43f1ff9191c646c56a4e29b1a8c6cb3f7b331da6883ef2f0480a515d0861"],
+ ["0f034f32027a8e094119443aa9cfe11737c6d7dda9a52b839bc073dcc0235b847b28e0fab60200000006ac53ac536a63eee63447dfdad80476994b68706e916df1bd9d7cb4f3a4f6b14369de84564bea2e8688bd030000000565636a65acf8434663020b35fe01000000000800abab655163acabb3d6a103000000000353acab345eeda0", "526a51ac63ab51", 1, 66020215, "4435e62ff6531ac73529aac9cf878a7219e0b6e6cac79af8487c5355d1ad6d43"],
+ ["a2dfa4690214c1ab25331815a5128f143219de51a47abdc7ce2d367e683eeb93960a31af9f010000000363636affffffff8be0628abb1861b078fcc19c236bc4cc726fa49068b88ad170adb2a97862e7460200000004ac655363ffffffff0441f11103000000000153dbab0c000000000009ab53ac5365526aab63abbb95050000000004ab52516a29a029040000000003ac526a00000000", "6a52ac63", 1, -1302210567, "913060c7454e6c80f5ba3835454b54db2188e37dc4ce72a16b37d11a430b3d23"],
+ ["9dbc591f04521670af83fb3bb591c5d4da99206f5d38e020289f7db95414390dddbbeb56680100000004ac5100acffffffffb6a40b5e29d5e459f8e72d39f800089529f0889006cad3d734011991da8ef09d0100000009526a5100acab536a515fc427436df97cc51dc8497642ffc868857ee245314d28b356bd70adba671bd6071301fc0000000000ffffffff487efde2f620566a9b017b2e6e6d42525e4070f73a602f85c6dfd58304518db30000000005516353006a8d8090180244904a0200000000046a65656ab1e9c203000000000451ab63aba06a5449", "", 0, -1414953913, "bae189eb3d64aedbc28a6c28f6c0ccbd58472caaf0cf45a5aabae3e031dd1fea"],
+ ["1345fb2c04bb21a35ae33a3f9f295bece34650308a9d8984a989dfe4c977790b0c21ff9a7f0000000006ac52ac6a0053ffffffff7baee9e8717d81d375a43b691e91579be53875350dfe23ba0058ea950029fcb7020000000753ab53ab63ab52ffffffff684b6b3828dfb4c8a92043b49b8cb15dd3a7c98b978da1d314dce5b9570dadd202000000086353ab6a5200ac63d1a8647bf667ceb2eae7ec75569ca249fbfd5d1b582acfbd7e1fcf5886121fca699c011d0100000003ac006affffffff049b1eb00300000000001e46dc0100000000080065ab6a6a630065ca95b40300000000030051520c8499010000000006ab6aac526a6500000000", "53526aac636300", 2, 1809978100, "cfeaa36790bc398783d4ca45e6354e1ea52ee74e005df7f9ebd10a680e9607bf"],
+ ["7d75dc8f011e5f9f7313ba6aedef8dbe10d0a471aca88bbfc0c4a448ce424a2c5580cda1560300000003ab5152ffffffff01997f8e0200000000096552ac6a65656563530d93bbcc", "00656a6563", 0, 1414485913, "ec91eda1149f75bffb97612569a78855498c5d5386d473752a2c81454f297fa7"],
+ ["1459179504b69f01c066e8ade5e124c748ae5652566b34ed673eea38568c483a5a4c4836ca0100000008ac5352006563656affffffff5d4e037880ab1975ce95ea378d2874dcd49d5e01e1cdbfae3343a01f383fa35800000000095251ac52ac6aac6500ffffffff7de3ae7d97373b7f2aeb4c55137b5e947b2d5fb325e892530cb589bc4f92abd503000000086563ac53ab520052ffffffffb4db36a32d6e543ef49f4bafde46053cb85b2a6c4f0e19fa0860d9083901a1190300000003ab51531bbcfe5504a6dbda040000000008536a5365abac6500d660c80300000000096565abab6a53536a6a54e84e010000000003acac52df2ccf0500000000025351220c857e", "", 2, 1879181631, "3aad18a209fab8db44954eb55fd3cc7689b5ec9c77373a4d5f4dae8f7ae58d14"],
+ ["d98b777f04b1b3f4de16b07a05c31d79965579d0edda05600c118908d7cf642c9cd670093f020000000953005351ac65ab5363a268caad6733b7d1718008997f249e1375eb3ab9fe68ab0fe170d8e745ea24f54ce67f9b00000000066500516a5151ffffffff7ef8040dfcc86a0651f5907e8bfd1017c940f51cf8d57e3d3fe78d57e40b1e610200000003535263ffffffff39846cfed4babc098ff465256ba3820c30d710581316afcb67cd31c623b703360300000001acffffffff03d405120100000000056300006a5201a73d050000000004ab636a6a294c8c000000000006ac65536553ac00000000", "63525351abac", 1, 2018694761, "86970af23c89b72a4f9d6281e46b9ef5220816bed71ebf1ae20df53f38fe16ff"],
+ ["cabb1b06045a895e6dcfc0c1e971e94130c46feace286759f69a16d298c8b0f6fd0afef8f20300000004ac006352ffffffffa299f5edac903072bfb7d29b663c1dd1345c2a33546a508ba5cf17aab911234602000000056a65515365ffffffff89a20dc2ee0524b361231092a070ace03343b162e7162479c96b757739c8394a0300000002abab92ec524daf73fabee63f95c1b79fa8b84e92d0e8bac57295e1d0adc55dc7af5534ebea410200000001534d70e79b04674f6f00000000000600abacab53517d60cc0200000000035265ab96c51d040000000004ac6300ac62a787050000000008006a516563ab63639e2e7ff7", "6551ac6351ac", 3, 1942663262, "d0c4a780e4e0bc22e2f231e23f01c9d536b09f6e5be51c123d218e906ec518be"],
+ ["8b96d7a30132f6005b5bd33ea82aa325e2bcb441f46f63b5fca159ac7094499f380f6b7e2e00000000076aacabac6300acffffffff0158056700000000000465005100c319e6d0", "52006a", 0, -1100733473, "fb4bd26a91b5cf225dd3f170eb09bad0eac314bc1e74503cc2a3f376833f183e"],
+ ["112191b7013cfbe18a175eaf09af7a43cbac2c396f3695bbe050e1e5f4250603056d60910e02000000001c8a5bba03738a22010000000005525352656a77a149010000000002510003b52302000000000351ac52722be8e6", "65ac6565", 0, -1847972737, "8e795aeef18f510d117dfa2b9f4a2bd2e2847a343205276cedd2ba14548fd63f"],
+ ["ce6e1a9e04b4c746318424705ea69517e5e0343357d131ad55d071562d0b6ebfedafd6cb840100000003656553ffffffff67bd2fa78e2f52d9f8900c58b84c27ef9d7679f67a0a6f78645ce61b883fb8de000000000100d699a56b9861d99be2838e8504884af4d30b909b1911639dd0c5ad47c557a0773155d4d303000000046a5151abffffffff9fdb84b77c326921a8266854f7bbd5a71305b54385e747fe41af8a397e78b7fa010000000863acac6a51ab00ac0d2e9b9d049b8173010000000007ac53526a650063ba9b7e010000000008526a00525263acac0ab3fd030000000000ea8a0303000000000200aca61a97b9", "", 1, -1276952681, "b6ed4a3721be3c3c7305a5128c9d418efa58e419580cec0d83f133a93e3a22c5"],
+ ["a7721d94021652d90c79aaf5022d98219337d50f836382403ed313adb1116ba507ac28b0b0010000000551ac6300ab89e6d64a7aa81fb9595368f04d1b36d7020e7adf5807535c80d015f994cce29554fe869b01000000065353ab636500ffffffff024944c90100000000046300635369df9f01000000000000000000", "656a536551ab", 0, -1740151687, "935892c6f02948f3b08bcd463b6acb769b02c1912be4450126768b055e8f183a"],
+ ["2f7353dd02e395b0a4d16da0f7472db618857cd3de5b9e2789232952a9b154d249102245fd030000000151617fd88f103280b85b0a198198e438e7cab1a4c92ba58409709997cc7a65a619eb9eec3c0200000003636aabffffffff0397481c0200000000045300636a0dc97803000000000009d389030000000003ac6a53134007bb", "0000536552526a", 0, -1912746174, "30c4cd4bd6b291f7e9489cc4b4440a083f93a7664ea1f93e77a9597dab8ded9c"],
+ ["7d95473604fd5267d0e1bb8c9b8be06d7e83ff18ad597e7a568a0aa033fa5b4e1e2b6f1007020000000465006a6affffffffaee008503bfc5708bd557c7e78d2eab4878216a9f19daa87555f175490c40aaf000000000263abffffffffabd74f0cff6e7ceb9acc2ee25e65af1abcebb50c08306e6c78fa8171c37613dd010000000552acacababffffffff54a3069393f7930fa1b331cdff0cb945ec21c11d4605d8eedba1d3e094c6ae1f01000000026300ffffffff0182edeb050000000009526353ab5153530065a247e8cd", "51516aab00", 2, -426210430, "2707ca714af09494bb4cf0794abe33c6cba5f29891d619e76070269d1fa8e690"],
+ ["221d4718023d9ca9fe1af178dbfce02b2b369bf823ea3f43f00891b7fef98e215c06b94fdd000000000951005153ab000051acffffffffb1c7ad1c64b7441bf5e70cd0f6eb4ec96821d67fc4997d9e6dfdceadecd36dde01000000070051536a635153ffffffff04e883cd00000000000851ab536553ab0052bbb2f70400000000002f1b2e03000000000165259fcb00000000000010dbde99", "ab", 1, 665721280, "4abce77432a86dfe608e7c1646c18b5253a373392ff962e288e3ab96bba1ba1d"],
+ ["6f66c0b3013e6ae6aabae9382a4326df31c981eac169b6bc4f746edaa7fc1f8c796ef4e374000000000665ab6aabac6affffffff0191c8d6030000000002525300000000", "6a5352516a635352ab", 0, -1299629906, "48411efeb133c6b7fec4e7bdbe613f827093cb06ea0dbcc2ffcfde3a9ac4356c"],
+ ["89e7928c04363cb520eff4465251fd8e41550cbd0d2cdf18c456a0be3d634382abcfd4a2130200000006ac516a6a656355042a796061ed72db52ae47d1607b1ceef6ca6aea3b7eea48e7e02429f382b378c4e51901000000085351ab6352ab5252ffffffff53631cbda79b40183000d6ede011c778f70147dc6fa1aed3395d4ce9f7a8e69701000000096a6553ab52516a52abad0de418d80afe059aab5da73237e0beb60af4ac490c3394c12d66665d1bac13bdf29aa8000000000153f2b59ab6027a33eb040000000007005351ac5100ac88b941030000000003ab0052e1e8a143", "63656a", 0, 1258533326, "b575a04b0bb56e38bbf26e1a396a76b99fb09db01527651673a073a75f0a7a34"],
+ ["ca356e2004bea08ec2dd2df203dc275765dc3f6073f55c46513a588a7abcc4cbde2ff011c7020000000553525100003aefec4860ef5d6c1c6be93e13bd2d2a40c6fb7361694136a7620b020ecbaca9413bcd2a030000000965ac00536352535100ace4289e00e97caaea741f2b89c1143060011a1f93090dc230bee3f05e34fbd8d8b6c399010000000365526affffffff48fc444238bda7a757cb6a98cb89fb44338829d3e24e46a60a36d4e24ba05d9002000000026a53ffffffff03d70b440200000000056a6a526aac853c97010000000002515335552202000000000351635300000000", "0052", 3, -528192467, "fc93cc056c70d5e033933d730965f36ad81ef64f1762e57f0bc5506c5b507e24"],
+ ["82d4fa65017958d53e562fac073df233ab154bd0cf6e5a18f57f4badea8200b217975e31030200000004636aab51ac0891a204227cc9050000000006635200655365bfef8802000000000865650051635252acfc2d09050000000006ab65ac51516380195e030000000007ac52525352510063d50572", "53", 0, -713567171, "e095003ca82af89738c1863f0f5488ec56a96fb81ea7df334f9344fcb1d0cf40"],
+ ["75f6949503e0e47dd70426ef32002d6cdb564a45abedc1575425a18a8828bf385fa8e808e600000000036aabab82f9fd14e9647d7a1b5284e6c55169c8bd228a7ea335987cef0195841e83da45ec28aa2e0300000002516350dc6fe239d150efdb1b51aa288fe85f9b9f741c72956c11d9dcd176889963d699abd63f0000000001ab429a63f502777d20010000000007abac52ac516a53d081d9020000000003acac630c3cc3a8", "535152516551510000", 1, 973814968, "c6ec1b7cb5c16a1bfd8a3790db227d2acc836300534564252b57bd66acf95092"],
+ ["24f24cd90132b2162f938f1c22d3ca5e7daa83515883f31a61a5177aebf99d7db6bdfc398c010000000163ffffffff01d5562d0100000000016300000000", "5265ac5165ac5252ab", 0, 1055129103, "5eeb03e03806cd7bfd44bbba69c30f84c2c5120df9e68cd8facc605fcfbc9693"],
+ ["5ff2cac201423064a4d87a96b88f1669b33adddc6fa9acdc840c0d8a243671e0e6de49a5b00300000005ac6353655353b91db50180db5a03000000000663535151006a047a3aff", "52ab51ab5365005163", 0, -1336626596, "b8db8d57fe40ab3a99cf2f8ed57da7a65050fcc1d34d4280e25faf10108d3110"],
+ ["10011f150220ad76a50ccc7bb1a015eda0ff987e64cd447f84b0afb8dc3060bdae5b36a6900200000000ffffffff1e92dd814dfafa830187bc8e5b9258de2445ec07b02c420ee5181d0b203bb334000000000565ab536a65ffffffff0124e65401000000000800ab636553ab53ac00000000", "53abab0051", 0, 440222748, "c6675bf229737e005b5c8ffa6f81d9e2c4396840921b6151316f67c4315a4270"],
+ ["8b95ec900456648d820a9b8df1d8f816db647df8a8dc9f6e7151ebf6079d90ee3f6861352a02000000085200ab00ac535151ffffffff039b10b845f961225ac0bcaac4f5fe1991029a051aa3d06a3811b5762977a67403000000035252abffffffff8559d65f40d5e261f45aec8aad3d2c56c6114b22b26f7ee54a06f0881be3a7f5010000000765635252536363ffffffff38f8b003b50f6412feb2322b06b270197f81ad69c36af02ca5008b94eee5f650020000000165ffffffff01ae2b00010000000001638eb153a2", "0053ab5300ac53", 2, 1266056769, "205f3653f0142b35ce3ef39625442efebae98cde8cbf0516b97b51073bb0479f"],
+ ["babbb7ea01ab5d584727cb44393b17cf66521606dc81e25d85273be0d57bad43e8f6b6d43501000000036a656aba83a68803fb0f4a000000000005536353ab633fcfe4020000000009ac00acab6351006a65182a0c03000000000453ac5363bee74f44", "536a6a6a6365ac51ab", 0, -799187625, "3275e98dca37243b977525a07b5d8e369d6c3bdc08cb948029a635547d0d1a4e"],
+ ["e86a24bc03e4fae784cdf81b24d120348cb5e52d937cd9055402fdba7e43281e482e77a1c100000000046363006affffffffa5447e9bdcdab22bd20d88b19795d4c8fb263fbbf7ce8f4f9a85f865953a6325020000000663ac53535253ffffffff9f8b693bc84e0101fc73748e0513a8cecdc264270d8a4ee1a1b6717607ee1eaa00000000026a513417bf980158d82c020000000009005253005351acac5200000000", "6353516365536a6a", 2, -563792735, "508129278ef07b43112ac32faf00170ad38a500eed97615a860fd58baaad174b"],
+ ["53bd749603798ed78798ef0f1861b498fc61dcee2ee0f2b37cddb115b118e73bc6a5a47a0201000000096a63656a6aab6a000007ff674a0d74f8b4be9d2e8e654840e99d533263adbdd0cf083fa1d5dd38e44d2d163d900100000007abab5251ac6a51c8b6b63f744a9b9273ccfdd47ceb05d3be6400c1ed0f7283d32b34a7f4f0889cccf06be30000000009516a52636551ab516a9ac1fe63030c677e05000000000027bc610000000000086565636a635100526e2dc60200000000015300000000", "6552536a515351ab", 1, -1617066878, "fe516df92299e995b8e6489be824c6839543071ec5e9286060b2600935bf1f20"],
+ ["691bf9fc028ca3099020b79184e70039cf53b3c7b3fe695d661fd62d7b433e65feda2150610000000003ac63abffffffff2c814c15b142bc944192bddccb90a392cd05b968b599c1d8cd99a55a28a243fd0100000009ab5300526a5200abac98516a5803dfd3540500000000046552ac522838120100000000040053ab6a4409a903000000000665636a5300658759621b", "65ac5165ab", 0, -359941441, "d582c442e0ecc400c7ba33a56c93ad9c8cfd45af820350a13623594b793486f0"],
+ ["536bc5e60232eb60954587667d6bcdd19a49048d67a027383cc0c2a29a48b960dc38c5a0370300000005ac636300abffffffff8f1cfc102f39b1c9348a2195d496e602c77d9f57e0769dabde7eaaedf9c69e250100000006acabab6a6351ffffffff0432f56f0400000000046a5365517fd54b0400000000035265539484e4050000000003536a5376dc25020000000008ac536aab6aab536ab978e686", "ac0051006a006a006a", 0, -273074082, "f151f1ec305f698d9fdce18ea292b145a58d931f1518cf2a4c83484d9a429638"],
+ ["74606eba01c2f98b86c29ba5a32dc7a7807c2abe6ed8d89435b3da875d87c12ae05329e6070200000003510052ffffffff02a1e2c4020000000006516563526a63c68bae04000000000952ab6363ab00006363fe19ae4f", "63ababacac5365", 0, 112323400, "d1b1d79001b4a0324962607b739972d6f39c1493c4500ce814fd3bd72d32a5a0"],
+ ["2ed805e20399e52b5bcc9dc075dad5cf19049ff5d7f3de1a77aee9288e59c5f4986751483f020000000165ffffffff967531a5726e7a653a9db75bd3d5208fa3e2c5e6cd5970c4d3aba84eb644c72c0300000000ffffffffd79030d20c65e5f8d3c55b5692e5bdaa2ae78cfa1935a0282efb97515feac43f030000000400006365261ab88c02bdf66a000000000003ab6351d6ad8b000000000005525152abac00000000", "630053ab5265", 0, 2072814938, "1d25d16d84d5793be1ad5cda2de9c9cf70e04a66c3dae618f1a7ca4026198e7f"],
+ ["fab796ee03f737f07669160d1f1c8bf0800041157e3ac7961fea33a293f976d79ce49c02ab0200000003ac5252eb097ea1a6d1a7ae9dace338505ba559e579a1ee98a2e9ad96f30696d6337adcda5a85f403000000096500abab656a6a656396d5d41a9b11f571d91e4242ddc0cf2420eca796ad4882ef1251e84e42b930398ec69dd80100000005526551ac6a8e5d0de804f763bb0400000000015288271a010000000001acf2bf2905000000000300ab51c9641500000000000952655363636365ac5100000000", "00ac536552", 0, -1854521113, "f3bbab70b759fe6cfae1bf349ce10716dbc64f6e9b32916904be4386eb461f1f"],
+ ["f2b539a401e4e8402869d5e1502dbc3156dbce93583f516a4947b333260d5af1a34810c6a00200000003525363ffffffff01d305e2000000000005acab535200a265fe77", "", 0, -1435650456, "41617b27321a830c712638dbb156dae23d4ef181c7a06728ccbf3153ec53d7dd"],
+ ["9f10b1d8033aee81ac04d84ceee0c03416a784d1017a2af8f8a34d2f56b767aea28ff88c8f02000000025352ffffffff748cb29843bea8e9c44ed5ff258df1faf55fbb9146870b8d76454786c4549de100000000016a5ba089417305424d05112c0ca445bc7107339083e7da15e430050d578f034ec0c589223b0200000007abac53ac6565abffffffff025a4ecd010000000006636563ab65ab40d2700000000000056a6553526333fa296c", "", 0, -395044364, "20fd0eee5b5716d6cbc0ddf852614b686e7a1534693570809f6719b6fcb0a626"],
+ ["ab81755f02b325cbd2377acd416374806aa51482f9cc5c3b72991e64f459a25d0ddb52e66703000000036a00ab8727056d48c00cc6e6222be6608c721bc2b1e69d0ffbadd51d131f05ec54bcd83003aac5000000000003f2cdb60454630e020000000007526aac63000000e9e25c040000000003516a0088c97e0000000000076a535265655263771b5805000000000851ab00ac6565515100000000", "5151ab00ac", 0, -230931127, "ba0a2c987fcdd74b6915f6462f62c3f126a0750aa70048f7aa20f70726e6a20b"],
+ ["7a17e0ef0378dab4c601240639139335da3b7d684600fa682f59b7346ef39386fe9abd69350000000004ac5252ab807f26fb3249326813e18260a603b9ad66f41f05eaa8146f66bcca452162a502aac4aa8b02000000026a534ea460faa7e3d7854ec6c70d7e797025697b547ec500b2c09c873b4d5517767d3f3720660300000000ffffffff01b12e7a02000000000900ab006aab65656a63991c03e2", "6aab6a", 1, -1577994103, "62cd3413d9d819fb7355336365cf8a2a997f7436cc050a7143972044343b3281"],
+ ["ff2ecc09041b4cf5abb7b760e910b775268abee2792c7f21cc5301dd3fecc1b4233ee70a2c0200000009acac5300006a51526affffffffeb39c195a5426afff38379fc85369771e4933587218ef4968f3f05c51d6b7c92000000000165453a5f039b8dbef7c1ffdc70ac383b481f72f99f52b0b3a5903c825c45cfa5d2c0642cd50200000001654b5038e6c49daea8c0a9ac8611cfe904fc206dad03a41fb4e5b1d6d85b1ecad73ecd4c0102000000096a51000053ab656565bdb5548302cc719200000000000452655265214a3603000000000300ab6a00000000", "52516a006a63", 1, -2113289251, "37ed6fae36fcb3360c69cac8b359daa62230fc1419b2cf992a32d8f3e079dcff"],
+ ["70a8577804e553e462a859375957db68cfdf724d68caeacf08995e80d7fa93db7ebc04519d02000000045352ab53619f4f2a428109c5fcf9fee634a2ab92f4a09dc01a5015e8ecb3fc0d9279c4a77fb27e900000000006ab6a51006a6affffffff3ed1a0a0d03f25c5e8d279bb5d931b7eb7e99c8203306a6c310db113419a69ad010000000565516300abffffffff6bf668d4ff5005ef73a1b0c51f32e8235e67ab31fe019bf131e1382050b39a630000000004536a6563ffffffff02faf0bb00000000000163cf2b4b05000000000752ac635363acac15ab369f", "ac", 0, -1175809030, "1c9d6816c20865849078f9777544b5ddf37c8620fe7bd1618e4b72fb72dddca1"],
+ ["a3604e5304caa5a6ba3c257c20b45dcd468f2c732a8ca59016e77b6476ac741ce8b16ca8360200000004acac6553ffffffff695e7006495517e0b79bd4770f955040610e74d35f01e41c9932ab8ccfa3b55d0300000007ac5253515365acffffffff6153120efc5d73cd959d72566fc829a4eb00b3ef1a5bd3559677fb5aae116e38000000000400abab52c29e7abd06ff98372a3a06227386609adc7665a602e511cadcb06377cc6ac0b8f63d4fdb03000000055100acabacffffffff04209073050000000009ab5163ac525253ab6514462e05000000000952abacab636300656a20672c0400000000025153b276990000000000056565ab6a5300000000", "5351", 0, 1460890590, "249c4513a49076c6618aabf736dfd5ae2172be4311844a62cf313950b4ba94be"],
+ ["c6a72ed403313b7d027f6864e705ec6b5fa52eb99169f8ea7cd884f5cdb830a150cebade870100000009ac63ab516565ab6a51ffffffff398d5838735ff43c390ca418593dbe43f3445ba69394a6d665b5dc3b4769b5d700000000075265acab515365ffffffff7ee5616a1ee105fd18189806a477300e2a9cf836bf8035464e8192a0d785eea3030000000700ac6a51516a52ffffffff018075fd0000000000015100000000", "005251acac5252", 2, -656067295, "2cc1c7514fdc512fd45ca7ba4f7be8a9fe6d3318328bc1a61ae6e7675047e654"],
+ ["93c12cc30270fc4370c960665b8f774e07942a627c83e58e860e38bd6b0aa2cb7a2c1e060901000000036300abffffffff4d9b618035f9175f564837f733a2b108c0f462f28818093372eec070d9f0a5440300000001acffffffff039c2137020000000001525500990100000000055265ab636a07980e0300000000005ba0e9d1", "656a5100", 1, 18954182, "6beca0e0388f824ca33bf3589087a3c8ad0857f9fe7b7609ae3704bef0eb83e2"],
+ ["97bddc63015f1767619d56598ad0eb5c7e9f880b24a928fea1e040e95429c930c1dc653bdb0100000008ac53acac00005152aaa94eb90235ed10040000000000287bdd0400000000016a8077673a", "acac6a536352655252", 0, -813649781, "5990b139451847343c9bb89cdba0e6daee6850b60e5b7ea505b04efba15f5d92"],
+ ["cc3c9dd303637839fb727270261d8e9ddb8a21b7f6cbdcf07015ba1e5cf01dc3c3a327745d0300000000d2d7804fe20a9fca9659a0e49f258800304580499e8753046276062f69dbbde85d17cd2201000000096352536a520000acabffffffffbc75dfa9b5f81f3552e4143e08f485dfb97ae6187330e6cd6752de6c21bdfd21030000000600ab53650063ffffffff0313d0140400000000096565515253526aacac167f0a040000000008acab00535263536a9a52f8030000000006abab5151ab63f75b66f2", "6a635353636a65ac65", 1, 377286607, "dbc7935d718328d23d73f8a6dc4f53a267b8d4d9816d0091f33823bd1f0233e9"],
+ ["236f91b702b8ffea3b890700b6f91af713480769dda5a085ae219c8737ebae90ff25915a3203000000056300ac6300811a6a10230f12c9faa28dae5be2ebe93f37c06a79e76214feba49bb017fb25305ff84eb020000000100ffffffff041e351703000000000351ac004ff53e050000000003ab53636c1460010000000000cb55f701000000000651520051ab0000000000", "acac636a6aac5300", 0, 406448919, "793a3d3c37f6494fab79ff10c16702de002f63e34be25dd8561f424b0ea938c4"],
+ ["22e10d2003ab4ea9849a2801921113583b7c35c3710ff49a6003489395789a7cfb1e6051900100000006526a65535151ffffffff82f21e249ec60db33831d33b9ead0d56f6496db64337dcb7f1c3327c47729c4a020000000253abffffffff138f098f0e6a4cf51dc3e7a3b749f487d1ebde71b73b731d1d02ad1180ac7b8c02000000036563acda215011027a9484020000000007635165530000ac4bf6cb0400000000066aacabab65ab3ce3f32c", "ab0052ab", 2, 1136359457, "b5bd080bbcb8cd652f440484311d7a3cb6a973cd48f03c5c00fd6beb52dfc061"],
+ ["c47d5ad60485cb2f7a825587b95ea665a593769191382852f3514a486d7a7a11d220b62c54000000000663655253acab8c3cf32b0285b040e50dcf6987ddf7c385b3665048ad2f9317b9e0c5ba0405d8fde4129b00000000095251ab00ac65635300ffffffff549fe963ee410d6435bb2ed3042a7c294d0c7382a83edefba8582a2064af3265000000000152fffffffff7737a85e0e94c2d19cd1cde47328ece04b3e33cd60f24a8a345da7f2a96a6d0000000000865ab6a0051656aab28ff30d5049613ea020000000005ac51000063f06df1050000000008ac63516aabac5153afef5901000000000700656500655253688bc00000000000086aab5352526a53521ff1d5ff", "51ac52", 2, -1296011911, "0c1fd44476ff28bf603ad4f306e8b6c7f0135a441dc3194a6f227cb54598642a"],
+ ["0b43f122032f182366541e7ee18562eb5f39bc7a8e5e0d3c398f7e306e551cdef773941918030000000863006351ac51acabffffffffae586660c8ff43355b685dfa8676a370799865fbc4b641c5a962f0849a13d8250100000005abab63acabffffffff0b2b6b800d8e77807cf130de6286b237717957658443674df047a2ab18e413860100000008ab6aac655200ab63ffffffff04f1dbca03000000000800635253ab656a52a6eefd0300000000036365655d8ca90200000000005a0d530400000000015300000000", "65ac65acac", 0, 351448685, "86f26e23822afd1bdfc9fff92840fc1e60089f12f54439e3ab9e5167d0361dcf"],
+ ["4b0ecc0c03ba35700d2a30a71f28e432ff6ac7e357533b49f4e97cf28f1071119ad6b97f3e0300000008acab516363ac63acffffffffcd6a2019d99b5c2d639ddca0b1aa5ea7c1326a071255ea226960bd88f45ca57d00000000085253655363005353ffffffffba257635191c9f216de3277be548cb5a2313114cb1a4c563b03b4ef6c0f4f7040300000001abda542edf0495cdc40100000000026353c049e903000000000752516a53ab65512b0f9304000000000963ab516aac65516552fa9ece050000000009acab6500005152530000000000", "65ab51525352510052", 1, -1355414590, "3cd85f84aae6d702436f3f9b8980adcc1f8f202e957759540a27da0a32fc6c87"],
+ ["adaac0a803f66811346271c733036d6e0d45e15a9b602092e2e04ad93564f196e7f020b088000000000600526a636a00700ec3f9db07a3a6ce910bf318c7ec87a876e1f2a3366cc69f20cde09203b99c1cb9d15800000000050000ac636a4d0de554ebe95c6cc14faf5ff6361d1deba9474b8b0fd3b93c011cd96aec783abb3f36830200000005ab65005251ffffffff0464eb10050000000007520000ab6a65ab1beaa80300000000005a2f31050000000006526aab65ac52ba7db10000000000045251ab6a0cfb46e7", "ab0051ac52636a", 1, -184733716, "961ff413850336d3987c550404fc1d923266ca36cc9ffee7113edb3a9fea7f30"],
+ ["af1c4ab301ec462f76ee69ba419b1b2557b7ded639f3442a3522d4f9170b2d6859765c3df402000000016affffffff01a5ca6c000000000008ab52536aab00005300000000", "6a6351", 0, 110304602, "e88ed2eea9143f2517b15c03db00767eb01a5ce12193b99b964a35700607e5f4"],
+ ["0bfd34210451c92cdfa02125a62ba365448e11ff1db3fb8bc84f1c7e5615da40233a8cd368010000000252ac9a070cd88dec5cf9aed1eab10d19529720e12c52d3a21b92c6fdb589d056908e43ea910e0200000009ac516a52656a6a5165ffffffffc3edcca8d2f61f34a5296c405c5f6bc58276416c720c956ff277f1fb81541ddd00000000030063abffffffff811247905cdfc973d179c03014c01e37d44e78f087233444dfdce1d1389d97c302000000065163000063ab1724a26e02ca37c902000000000851ab53525352ac529012a90100000000085200525253535353fa32575b", "5352ac6351", 1, -1087700448, "b8f1e1f35e3e1368bd17008c756e59cced216b3c699bcd7bebdb5b6c8eec4697"],
+ ["2c84c0640487a4a695751d3e4be48019dbaea85a6e854f796881697383ea455347d2b2769001000000055265526500ffffffff6aac176d8aa00778d496a7231eeb7d3334f20c512d3db1683276402100d98de5030000000700536a5263526ac1ee9ceb171c0c984ebaf12c234fd1487fbf3b3d73aa0756907f26837efba78d1bed33200300000001ab4d9e8ec0bed837cb929bbed76ee848959cec59de44bd7667b7631a744f880d5c71a20cfd0100000007005363515300abffffffff023753fb0000000000036565532d3873050000000009005152ab6a63acab5200000000", "ab650053ab", 0, -877941183, "c49af297dffe2d80deddf10ceea84b99f8554bd2d55bbdc34e449728c31f0835"],
+ ["1f7e4b1b045d3efa6cd7a11d7873a8bab886c19bd11fcb6712f0948f2db3a7be76ff76c8f100000000095265ab6a0065ac5363ffffffffdaafcfa6029336c997680a541725190f09a6f6da21e54560eca4b5b8ae987da1000000000952ac52acac52515165ffffffff825a38d3b1e5bb4d10f33653ab3ab6882c7abdaec74460257d1528ce7be3f98e0100000007526a006a656a63c14adc8f04953a5d3d3f89237f38b857dd357713896d36215f7e8b77b11d98ea3cdc93df02000000015212484f6104bfafae0300000000025263a2b0120000000000056563ab00516c4d2605000000000653ac6500655301cc93030000000002acab14643b1f", "63acac53ab", 0, 333824258, "18da6ceb011cd36f15ad7dd6c55ef07e6f6ed48881ce3bb31416d3c290d9a0e9"],
+ ["467a3e7602e6d1a7a531106791845ec3908a29b833598e41f610ef83d02a7da3a1900bf2960000000005ab6a636353ffffffff031db6dac6f0bafafe723b9199420217ad2c94221b6880654f2b35114f44b1df010000000965ab52636a63ac6352ffffffff02b3b95c0100000000026300703216030000000001ab3261c0aa", "6a", 0, 2110869267, "3078b1d1a7713c6d101c64afe35adfae0977a5ab4c7e07a0b170b041258adbf2"],
+ ["8713bc4f01b411149d575ebae575f5dd7e456198d61d238695df459dd9b86c4e3b2734b62e0300000004abac6363ffffffff03b58049050000000002ac653c714c04000000000953656a005151526a527b5a9e03000000000652ac5100525300000000", "52", 0, -647281251, "0e0bed1bf2ff255aef6e5c587f879ae0be6222ab33bd75ee365ec6fbb8acbe38"],
+ ["f2ba8a8701b9c401efe3dd0695d655e20532b90ac0142768cee4a3bb0a89646758f544aa8102000000036a52527899f4e4040c6f0b030000000008636565ab530051ab52b60c000000000009515200ab630053ac53a49c5f040000000008ab53ab516300ab63fa27340300000000015100000000", "ac63abab5251", 0, -1328936437, "ab61497afd39e61fe06bc5677326919716f9b20083c9f3417dcea905090e0411"],
+ ["b5a7df6102107beded33ae7f1dec0531d4829dff7477260925aa2cba54119b7a07d92d5a1d02000000046a516a52803b625c334c1d2107a326538a3db92c6c6ae3f7c3516cd90a09b619ec6f58d10e77bd6703000000056563006a63ffffffff0117484b03000000000853acab52526a65abc1b548a1", "ac006a525100", 0, 2074359913, "680336db57347d8183b8898cd27a83f1ba5884155aeae5ce20b4840b75e12871"],
+ ["278cb16204b9dadf400266106392c4aa9df01ba03af988c8139dae4c1818ac009f13fc5f1a00000000065200ac656a52ffffffffd006bbebd8cbd7bdead24cddc9badfcc6bc0c2e63c037e5c29aa858f5d0f3e7d01000000046a0051acffffffffbc62a5f57e58da0b67956003ae81ac97cb4cbd1d694c914fc41515c008c4d8fd020000000165e329c844bcc16164be64b64a81cbf4ffd41ed2934e0daa0040ccb8365bab0b2a9e401c180300000003ab52abffffffff02588460030000000000a25a12030000000005535100005300000000", "6553ab6a5300acab51", 3, 989407546, "1c29f110576f4a3b257f67454d99dfc0dee62ef5517ca702848ce4bd2ea1a1d7"],
+ ["49eb2178020a04fca08612c34959fd41447319c190fb7ffed9f71c235aa77bec28703aa1820200000003ac6353abaff326071f07ec6b77fb651af06e8e8bd171068ec96b52ed584de1d71437fed186aecf0300000001acffffffff03da3dbe02000000000652ac63ac6aab8f3b680400000000096a536a65636a53516a5175470100000000016500000000", "6a536365", 0, 1283691249, "c670219a93234929f662ecb9aa148a85a2d281e83f4e53d10509461cdea47979"],
+ ["0f96cea9019b4b3233c0485d5b1bad770c246fe8d4a58fb24c3b7dfdb3b0fd90ea4e8e947f0300000006006a5163515303571e1e01906956030000000005ab635353abadc0fbbe", "acac", 0, -1491469027, "716a8180e417228f769dcb49e0491e3fda63badf3d5ea0ceeac7970d483dd7e2"],
+ ["9a7d858604577171f5fe3f3fd3e5e039c4b0a06717a5381e9977d80e9f53e025e0f16d2877020000000752636565536353ffffffff5862bd028e8276e63f044be1dddcbb8d0c3fa097678308abf2b0f45104a93dbd0100000001531200667ba8fdd3b28e98a35da73d3ddfe51e210303d8eb580f923de988ee632d77793892030000000752526363526563ffffffffe9744eb44db2658f120847c77f47786d268c302120d269e6004455aa3ea5f5e20200000009ab6300636aab656551ffffffff03c61a3c020000000009ab516a6aab6aab53ab737f1a05000000000853acabab655365ab92a4a00400000000016367edf6c8", "535352ab", 3, 659348595, "d36ee79fc80db2e63e05cdc50357d186181b40ae20e3720878284228a13ee8b3"],
+ ["148e68480196eb52529af8e83e14127cbfdbd4a174e60a86ac2d86eac9665f46f4447cf7aa01000000045200ac538f8f871401cf240c0300000000065252ab52656a5266cf61", "", 0, -344314825, "eacc47c5a53734d6ae3aedbc6a7c0a75a1565310851b29ef0342dc4745ceb607"],
+ ["e2bc29d4013660631ba14ecf75c60ec5e9bed7237524d8c10f66d0675daa66d1492cb834530200000004ac510065e42d0c9e04f2b26c01000000000951525152acac65ababa35b7504000000000953ac6aac00650053ab94688c0400000000056365526553a1bced0300000000016a00000000", "65ab0063655353", 0, -888431789, "59a34b3ed3a1cce0b104de8f7d733f2d386ffc7445efae67680cd90bc915f7e0"],
+ ["0c8a70d70494dca6ab05b2bc941b5b431c43a292bd8f2f02eab5e240a408ca73a676044a4103000000056a51ab006affffffff84496004e54836c035821f14439149f22e1db834f315b24588ba2f031511926c0100000000ffffffffbbc5e70ed1c3060ba1bfe99c1656a3158a7307c3ce8eb362ec32c668596d2bd30000000009636563635351abab00b039344c6fc4f9bec24322e45407af271b2d3dfec5f259ee2fc7227bc5285e22b3be85b40100000009ac00ab53abac6a5352e5ddfcff02d50231020000000005006a51536ab086d9020000000006ababac51ac6a00000000", "abab636565acac6a", 3, 241546088, "643a7b4c8d832e14d5c10762e74ec84f2c3f7ed96c03053157f1bed226614911"],
+ ["f98f79cf0274b745e1d6f36da7cbe205a79132a7ad462bdc434cfb1dcd62a6977c3d2a5dbc010000000553516a5365ffffffff4f89f485b53cdad7fb80cc1b7e314b9735b9383bc92c1248bb0e5c6173a55c0d010000000353655293f9b014045ad96d02000000000963ac526a53ac636365f4c27904000000000952536563635152526a2788f0030000000002516aff5add01000000000863530051655351abd04716ba", "ab6552536a53", 1, -2128899945, "56d29f5e300ddfed2cd8dcce5d79826e193981d0b70dc7487772c8a0b3b8d7b1"],
+ ["6c7913f902aa3f5f939dd1615114ce961beda7c1e0dd195be36a2f0d9d047c28ac62738c3a020000000453abac00ffffffff477bf2c5b5c6733881447ac1ecaff3a6f80d7016eee3513f382ad7f554015b970100000007ab6563acab5152ffffffff04e58fe1040000000009ab00526aabab526553e59790010000000002ab525a834b03000000000035fdaf0200000000086551ac65515200ab00000000", "63ac53", 1, 1285478169, "1536da582a0b6de017862445e91ba14181bd6bf953f4de2f46b040d351a747c9"],
+ ["4624aa9204584f06a8a325c84e3b108cafb97a387af62dc9eab9afd85ae5e2c71e593a3b690200000003636a005eb2b44eabbaeca6257c442fea00107c80e32e8715a1293cc164a42e62ce14fea146220c020000000090b9ee38106e3310037bfc519fd209bdbd21c588522a0e96df5fba4e979392bc993bfe9f01000000086363636a635353ab6f1907d218ef6f3c729d9200e23c1dbff2df58b8b1282c6717b26cf760ee4c880d23f4d100000000086a516a536a525163ffffffff01d6f162050000000000ebbab208", "525365ab0053", 1, -1515409325, "6cf9cd409b7185b1f118171f0a34217af5b612ea54195ea186505b667c19337f"],
+ ["16562fc503f1cf9113987040c408bfd4523f1512da699a2ca6ba122dc65677a4c9bf7763830000000003636552ffffffff1ec1fab5ff099d1c8e6b068156f4e39b5543286bab53c6d61e2582d1e07c96cf02000000045163656affffffffd0ef40003524d54c08cb4d13a5ee61c84fbb28cde9eca7a6d11ba3a9335d8c620100000007635153536a6300fbb84fc2012003a601000000000363ab6a00000000", "63636a006a6aab", 0, -1310262675, "1efbf3d37a92bc03d9eb950b792f307e95504f7c4998f668aa250707ebb752ac"],
+ ["531665d701f86bacbdb881c317ef60d9cd1baeffb2475e57d3b282cd9225e2a3bf9cbe0ded01000000086300ac515263acabffffffff0453a8500100000000086353acab516a6565e5e9200500000000026a52a44caa00000000000453ac000065e41b0500000000076500ac0065526ab4476f4d", "006563006aab00636a", 0, 1770013777, "0898b26dd3ca08632a5131fa48eb55b44386d0c5070c24d6e329673d5e3693b8"],
+ ["0f1227a20140655a3da36e413b9b5d108a866f6f147eb4940f032f5a89854eae6d7c3a91600100000009525363515153515253e37a79480161ab61020000000001ab00000000", "ab65005200", 0, -1996383599, "979782dc3f36d908d37d7e4046a38d306b4b08ddc60a5eba355fe3d6da1b29a9"],
+ ["063ff6eb01aff98d0d2a6db224475010edb634c2f3b46257084676adeb84165a4ff8558d7601000000066353006a5165deb3262c042d109c0000000000076363ab52ac005200b9c4050000000007516300ac510063cfffc800000000000200639e815501000000000700526a52ac6365ac7b07b8", "656552abac6500", 0, -1559847112, "674a4bcb04247f8dc98780f1792cac86b8aee41a800fc1e6f5032f6e1dccde65"],
+ ["3320f6730132f830c4681d0cae542188e4177cad5d526fae84565c60ceb5c0118e844f90bd030000000163ffffffff0257ec5a040000000005525251ac6538344d000000000002515200000000", "5352656a53ac516a65", 0, 788050308, "3afacaca0ef6be9d39e71d7b1b118994f99e4ea5973c9107ca687d28d8eba485"],
+ ["c13aa4b702eedd7cde09d0416e649a890d40e675aa9b5b6d6912686e20e9b9e10dbd40abb1000000000863ab6353515351ac11d24dc4cc22ded7cdbc13edd3f87bd4b226eda3e4408853a57bcd1becf2df2a1671fd1600000000045165516affffffff01baea300100000000076aab52ab53005300000000", "0065", 0, -1195908377, "241a23e7b1982d5f78917ed97a8678087acbbffe7f624b81df78a5fe5e41e754"],
+ ["d9a6f20e019dd1b5fae897fb472843903f9c3c2293a0ffb59cff2b413bae6eceab574aaf9d030000000663ab006a515102f54939032df5100100000000056a51ab65530ec28f010000000004ac5100007e874905000000000651005265ac6a00000000", "abacab63acacabab", 0, 271463254, "1326a46f4c21e7619f30a992719a905aa1632aaf481a57e1cbd7d7c22139b41e"],
+ ["157c81bf0490432b3fcb3f9a5b79e5f91f67f05efb89fa1c8740a3fe7e9bdc18d7cb6acd2203000000026351ffffffff912e48e72bbcf8a540b693cf8b028e532a950e6e63a28801f6eaad1afcc52ad00000000000b1a4b170a2b9e60e0cad88a0085137309f6807d25d5afb5c1e1d32aa10ba1cdf7df596dd0000000009525165656a51ab65ab3674fba32a76fe09b273618d5f14124465933f4190ba4e0fd09d838daafc6223b31642ac00000000086a53536551ac6565ffffffff01fe9fb6030000000008ab51656a5165636a00000000", "ab00ab6a6551", 3, -64357617, "1ddaab7f973551d71f16bd70c4c4edbf7225e64e784a6da0ee7f7a9fe4f12a0b"],
+ ["a2692fff03b2387f5bacd5640c86ba7df574a0ee9ed7f66f22c73cccaef3907eae791cbd230200000004536363abffffffff4d9fe7e5b375de88ba48925d9b2005447a69ea2e00495a96eafb2f144ad475b40000000008000053000052636537259bee3cedd3dcc07c8f423739690c590dc195274a7d398fa196af37f3e9b4a1413f810000000006ac63acac52abffffffff04c65fe60200000000075151536365ab657236fc020000000009005263ab00656a6a5195b8b6030000000007ac5165636aac6a7d7b66010000000002acab00000000", "51", 2, -826546582, "925037c7dc7625f3f12dc83904755a37016560de8e1cdd153c88270a7201cf15"],
+ ["2c5b003201b88654ac2d02ff6762446cb5a4af77586f05e65ee5d54680cea13291efcf930d0100000005ab536a006a37423d2504100367000000000004536a515335149800000000000152166aeb03000000000452510063226c8e03000000000000000000", "635251", 0, 1060344799, "7e058ca5dd07640e4aae7dea731cfb7d7fef1bfd0d6d7b6ce109d041f4ca2a31"],
+ ["f981b9e104acb93b9a7e2375080f3ea0e7a94ce54cd8fb25c57992fa8042bdf4378572859f0100000002630008604febba7e4837da77084d5d1b81965e0ea0deb6d61278b6be8627b0d9a2ecd7aeb06a0300000005ac5353536a42af3ef15ce7a2cd60482fc0d191c4236e66b4b48c9018d7dbe4db820f5925aad0e8b52a0300000008ab0063510052516301863715efc8608bf69c0343f18fb81a8b0c720898a3563eca8fe630736c0440a179129d03000000086aac6a52ac6a63ac44fec4c00408320a03000000000062c21c030000000007ac6a655263006553835f0100000000015303cd60000000000005535263536558b596e0", "00", 0, -2140385880, "49870a961263354c9baf108c6979b28261f99b374e97605baa532d9fa3848797"],
+ ["e7416df901269b7af14a13d9d0507709b3cd751f586ce9d5da8d16a121e1bd481f5a086e1103000000056aab005200ffffffff01aa269c040000000006acac6a6a5263ee718de6", "ab525363", 0, 1309186551, "eea7d2212bda2d408fff146f9ae5e85e6b640a93b9362622bb9d5e6e36798389"],
+ ["402a815902193073625ab13d876190d1bbb72aecb0ea733c3330f2a4c2fe6146f322d8843a0300000008656aab0000535363fffffffff9dccdec5d8509d9297d26dfcb1e789cf02236c77dc4b90ebccbf94d1b5821150300000001510bf1f96a03c5c145000000000002ac6ae11b1c0100000000055163516a5239c8a600000000000365636300000000", "63536aacab", 0, -1811424955, "0090803a20102a778ab967a74532faee13e03b702083b090b1497bc2267ee2fe"],
+ ["c4b702e502f1a54f235224f0e6de961d2e53b506ab45b9a40805d1dacd35148f0acf24ca5e00000000085200ac65ac53acabf34ba6099135658460de9d9b433b84a8562032723635baf21ca1db561dce1c13a06f4407000000000851ac006a63516aabffffffff02a853a603000000000163d17a67030000000005ab63006a5200000000", "ac5363515153", 1, 480734903, "5c46f7ac3d6460af0da28468fcc5b3c87f2b9093d0f837954b7c8174b4d7b6e7"],
+ ["9b83f78704f492b9b353a3faad8d93f688e885030c274856e4037818848b99e490afef27770200000000ffffffff36b60675a5888c0ef4d9e11744ecd90d9fe9e6d8abb4cff5666c898fdce98d9e00000000056aab656352596370fca7a7c139752971e169a1af3e67d7656fc4fc7fd3b98408e607c2f2c836c9f27c030000000653ac51ab6300a0761de7e158947f401b3595b7dc0fe7b75fa9c833d13f1af57b9206e4012de0c41b8124030000000953656a53ab53510052242e5f5601bf83b301000000000465516a6300000000", "63515200ac656365", 3, -150879312, "9cf05990421ea853782e4a2c67118e03434629e7d52ab3f1d55c37cf7d72cdc4"],
+ ["f492a9da04f80b679708c01224f68203d5ea2668b1f442ebba16b1aa4301d2fe5b4e2568f3010000000953005351525263ab65ffffffff93b34c3f37d4a66df255b514419105b56d7d60c24bf395415eda3d3d8aa5cd0101000000020065ffffffff9dba34dabdc4f1643b372b6b77fdf2b482b33ed425914bb4b1a61e4fad33cf390000000002ab52ffffffffbbf3dc82f397ef3ee902c5146c8a80d9a1344fa6e38b7abce0f157be7adaefae0000000009515351005365006a51ffffffff021359ba010000000000403fea0200000000095200ac6353abac635300000000", "00ac51acacac", 0, -2115078404, "fd44fc98639ca32c927929196fc3f3594578f4c4bd248156a25c04a65bf3a9f3"],
+ ["2f73e0b304f154d3a00fde2fdd40e791295e28d6cb76af9c0fd8547acf3771a02e3a92ba37030000000852ac6351ab6565639aa95467b065cec61b6e7dc4d6192b5536a7c569315fb43f470078b31ed22a55dab8265f02000000080065636a6aab6a53ffffffff9e3addbff52b2aaf9fe49c67017395198a9b71f0aa668c5cb354d06c295a691a0100000000ffffffff45c2b4019abaf05c5e484df982a4a07459204d1343a6ee5badade358141f8f990300000007ac516a6aacac6308655cd601f3bc2f0000000000015200000000", "", 0, -2082053939, "9a95e692e1f78efd3e46bb98f178a1e3a0ef60bd0301d9f064c0e5703dc879c2"],
+ ["5a60b9b503553f3c099f775db56af3456330f1e44e67355c4ab290d22764b9144a7b5f959003000000030052acbd63e0564decc8659aa53868be48c1bfcda0a8c9857b0db32a217bc8b46d9e7323fe9649020000000553ac6551abd0ecf806211db989bead96c09c7f3ec5f73c1411d3329d47d12f9e46678f09bac0dc383e0200000000ffffffff01494bb202000000000500516551ac00000000", "ac", 0, 1169947809, "62a36c6e8da037202fa8aeae03e533665376d5a4e0a854fc4624a75ec52e4eb1"],
+ ["7e98d353045569c52347ca0ff2fdba608829e744f61eb779ffdb5830aae0e6d6857ab2690e03000000075365acab656352ffffffffa890dd37818776d12da8dca53d02d243ef23b4535c67016f4c58103eed85360f030000000093dbacdc25ca65d2951e047d6102c4a7da5e37f3d5e3c8b87c29b489360725dcd117ee2003000000056a6300ac53c7e99fa1dc2b8b51733034e6555f6d6de47dbbf1026effac7db80cb2080678687380dc1e02000000075352005263516affffffff04423272040000000008ab6353ab65510051e0f53b0500000000086300516552635152f74a5f04000000000853acab0053ab52ab0e8e5f00000000000951ac5363516a6aabab00000000", "6a5163ab52", 3, 890006103, "476868cecd1763c91dade98f17defa42d31049547df45acffa1cc5ae5c3d75d6"],
+ ["e3649aa40405e6ffe377dbb1bbbb672a40d8424c430fa6512c6165273a2b9b6afa9949ec430200000007630052ab655153a365f62f2792fa90c784efe3f0981134d72aac0b1e1578097132c7f0406671457c332b84020000000353ab6ad780f40cf51be22bb4ff755434779c7f1def4999e4f289d2bd23d142f36b66fbe5cfbb4b01000000076a5252abac52ab1430ffdc67127c9c0fc97dcd4b578dab64f4fb9550d2b59d599773962077a563e8b6732c02000000016affffffff04cb2687000000000002ab636e320904000000000252acf70e9401000000000100dc3393050000000006ab0063536aacbc231765", "65520053", 3, -2016196547, "f64f805f0ff7f237359fa6b0e58085f3c766d1859003332223444fd29144112a"],
+ ["1d033569040700441686672832b531ab55db89b50dc1f9fc00fb72218b652da9dcfbc83be901000000066551ac526a632b390f9ad068e5fdee6563e88e2a8e4e09763c861072713dc069893dc6bbc9db3f00e26502000000096a5363526565525252ffffffff8a36bdd0aaf38f6707592d203e14476ca9f259021e487135c7e8324244057ed90300000000ed3fb2a3dfd4d46b5f3603fe0148653911988457bd0ed7f742b07c452f5476c228ff9f600200000007526aac00525152ffffffff04b88e48030000000000c753d602000000000853510000006553518fda2603000000000853ac52acac5263534839f1030000000006ac006aacac5300000000", "516553635300ab0052", 1, 2075958316, "c2cefaec2293134acbcf6d2a8bf2b3eb42e4ec04ee8f8bf30ff23e65680677c1"],
+ ["4c4be7540344050e3044f0f1d628039a334a7c1f7b4573469cfea46101d6888bb6161fe9710200000000ffffffffac85a4fdad641d8e28523f78cf5b0f4dc74e6c5d903c10b358dd13a5a1fd8a06000000000163e0ae75d05616b72467b691dc207fe2e65ea35e2eadb7e06ea442b2adb9715f212c0924f10200000000ffffffff0194ddfe02000000000265ac00000000", "00006500", 1, -479922562, "d66924d49f03a6960d3ca479f3415d638c45889ce9ab05e25b65ac260b51d634"],
+ ["202c18eb012bc0a987e69e205aea63f0f0c089f96dd8f0e9fcde199f2f37892b1d4e6da90302000000055352ac6565ffffffff0257e5450100000000025300ad257203000000000000000000", "520052ac6a005265", 0, 168054797, "502967a6f999f7ee25610a443caf8653dda288e6d644a77537bcc115a8a29894"],
+ ["32fa0b0804e6ea101e137665a041cc2350b794e59bf42d9b09088b01cde806ec1bbea077df0200000008515153650000006506a11c55904258fa418e57b88b12724b81153260d3f4c9f080439789a391ab147aabb0fa0000000007000052ac51ab510986f2a15c0d5e05d20dc876dd2dafa435276d53da7b47c393f20900e55f163b97ce0b800000000008ab526a520065636a8087df7d4d9c985fb42308fb09dce704650719140aa6050e8955fa5d2ea46b464a333f870000000009636300636a6565006affffffff01994a0d040000000002536500000000", "516563530065", 2, -163068286, "f58637277d2bc42e18358dc55f7e87e7043f5e33f4ce1fc974e715ef0d3d1c2a"],
+ ["ae23424d040cd884ebfb9a815d8f17176980ab8015285e03fdde899449f4ae71e04275e9a80100000007ab006553530053ffffffff018e06db6af519dadc5280c07791c0fd33251500955e43fe4ac747a4df5c54df020000000251ac330e977c0fec6149a1768e0d312fdb53ed9953a3737d7b5d06aad4d86e9970346a4feeb5030000000951ab51ac6563ab526a67cabc431ee3d8111224d5ecdbb7d717aa8fe82ce4a63842c9bd1aa848f111910e5ae1eb0100000004ac515300bfb7e0d7048acddc030000000009636a5253636a655363a3428e040000000001525b99c6050000000004655265ab717e6e020000000000d99011eb", "ac6a6a516565", 1, -716251549, "b098eb9aff1bbd375c70a0cbb9497882ab51f3abfebbf4e1f8d74c0739dc7717"],
+ ["030f44fc01b4a9267335a95677bd190c1c12655e64df74addc53b753641259af1a54146baa020000000152e004b56c04ba11780300000000026a53f125f001000000000251acd2cc7c03000000000763536563655363c9b9e50500000000015200000000", "ac", 0, -1351818298, "19dd32190ed2a37be22f0224a9b55b91e37290577c6c346d36d32774db0219a3"],
+ ["c05f448f02817740b30652c5681a3b128322f9dc97d166bd4402d39c37c0b14506d8adb5890300000003536353ffffffffa188b430357055ba291c648f951cd2f9b28a2e76353bef391b71a889ba68d5fc02000000056565526a6affffffff02745f73010000000001ab3ec34c0400000000036aac5200000000", "516551510053", 0, -267877178, "3a1c6742d4c374f061b1ebe330b1e169a113a19792a1fdde979b53e094cc4a3c"],
+ ["163ba45703dd8c2c5a1c1f8b806afdc710a2a8fc40c0138e2d83e329e0e02a9b6c837ff6b8000000000700655151ab6a522b48b8f134eb1a7e6f5a6fa319ce9d11b36327ba427b7d65ead3b4a6a69f85cda8bbcd22030000000563656552acffffffffdbcf4955232bd11eef0cc6954f3f6279675b2956b9bcc24f08c360894027a60201000000066500006500abffffffff04d0ce9d0200000000008380650000000000015233f360040000000003006aabedcf0801000000000000000000", "000065006500ac", 0, 216965323, "9afe3f4978df6a86e9a8ebd62ef6a9d48a2203f02629349f1864ef2b8b92fd55"],
+ ["07f7f5530453a12ad0c7eb8fbc3f140c7ab6818144d67d2d8752600ca5d9a9358e2dff87d4000000000663526aab526a9e599c379d455e2da36d0cde88d931a863a3e97e01e93b9edb65856f3d958dc08b92b720000000000165bbc8d66dae3b1b170a6e2457f5b161465cb8706e0e6ffc6af55deb918365f14c5f40d4890100000000a7bd77c069ee4b48638e2363fcf2a86b02bea022047bd9fcb16d2b94ad068308d19b31cb00000000066aab5300ab529672aa8f01dbd8a205000000000663536353006a02e99901", "ac006351006a63ab63", 1, 119789359, "6629a1e75c6ae8f4f9d5f734246b6a71682a5ea57246040ef0584f6b97916175"],
+ ["fe647f950311bf8f3a4d90afd7517df306e04a344d2b2a2fea368935faf11fa6882505890d0000000005ab5100516affffffff43c140947d9778718919c49c0535667fc6cc727f5876851cb8f7b6460710c7f60100000000ffffffffce4aa5d90d7ab93cbec2e9626a435afcf2a68dd693c15b0e1ece81a9fcbe025e0300000000ffffffff02f34806020000000002515262e54403000000000965635151ac655363636de5ce24", "6a005100ac516351", 2, 989643518, "818a7ceaf963f52b5c48a7f01681ac6653c26b63a9f491856f090d9d60f2ffe3"],
+ ["a1050f8604d0f9d2feefcdb5051ae0052f38e21bf39daf583fd0c3900faa3eab5d431c0bbe030000000653536a005151683d27e5c6e0da8f22125823f32d5d98477d8098ef36263b9694d61d4d85d3f2ac02b7570200000007000052005165abffffffff0cad981542bcb54a87d9400aa63e514c7c6fab7158c2b1fb37821ea755eb162a0200000000b94feb5100e5ef3bf8ed8d43356c8a8d5ac6c7e80d7ff6040f4f0aa19abbe783f4f461240200000007636500000052655686fd70042be3ad02000000000465ab636a15680b000000000004acac53511277c705000000000452635252d27a0102000000000000000000", "6a6aacab65655251", 1, -982144648, "dfcf484111801989eb6df8dc2bafb944d7365ffeb36a575a08f3270d3ef24c9f"],
+ ["cef7316804c3e77fe67fc6207a1ea6ae6eb06b3bf1b3a4010a45ae5c7ad677bb8a4ebd16d90200000009ac536a5152ac5263005301ab8a0da2b3e0654d31a30264f9356ba1851c820a403be2948d35cafc7f9fe67a06960300000006526a63636a53ffffffffbada0d85465199fa4232c6e4222df790470c5b7afd54704595a48eedd7a4916b030000000865ab63ac006a006ab28dba4ad55e58b5375053f78b8cdf4879f723ea4068aed3dd4138766cb4d80aab0aff3d0300000003ac6a00ffffffff010f5dd6010000000006ab006aab51ab00000000", "", 1, 889284257, "d0f32a6db43378af84b063a6706d614e2d647031cf066997c48c04de3b493a94"],
+ ["7b3ff28004ba3c7590ed6e36f45453ebb3f16636fe716acb2418bb2963df596a50ed954d2e03000000065251515265abffffffff706ee16e32e22179400c9841013971645dabf63a3a6d2d5feb42f83aa468983e030000000653ac51ac5152ffffffffa03a16e5e5de65dfa848b9a64ee8bf8656cc1f96b06a15d35bd5f3d32629876e020000000043c1a3965448b3b46f0f0689f1368f3b2981208a368ec5c30defb35595ef9cf95ffd10e902000000036aac65253a5bbe042e907204000000000800006565656352634203b4020000000002656336b3b7010000000001ab7a063f0100000000026500a233cb76", "006551636a53ac5251", 1, -1144216171, "68c7bd717b399b1ee33a6562a916825a2fed3019cdf4920418bb72ffd7403c8c"],
+ ["d5c1b16f0248c60a3ddccf7ebd1b3f260360bbdf2230577d1c236891a1993725e262e1b6cb000000000363636affffffff0a32362cfe68d25b243a015fc9aa172ea9c6b087c9e231474bb01824fd6bd8bc0300000005ab52ab516affffffff0420d9a70200000000045152656a45765d0000000000055252536a5277bad100000000000252ab3f3f3803000000000463acac5200000000", "52636a52ab65", 1, 1305123906, "978dc178ecd03d403b048213d904653979d11c51730381c96c4208e3ea24243a"],
+ ["1be8ee5604a9937ebecffc832155d9ba7860d0ca451eaced58ca3688945a31d93420c27c460100000006abac5300535288b65458af2f17cbbf7c5fbcdcfb334ffd84c1510d5500dc7d25a43c36679b702e850f7c0200000003005300ffffffff7c237281cb859653eb5bb0a66dbb7aeb2ac11d99ba9ed0f12c766a8ae2a2157203000000086aabac526365acabfffffffff09d3d6639849f442a6a52ad10a5d0e4cb1f4a6b22a98a8f442f60280c9e5be80200000007ab00ab6565ab52ffffffff0398fe83030000000005526aababacbdd6ec010000000005535252ab6a82c1e6040000000001652b71c40c", "6563526353656351", 2, -853634888, "0d936cceda2f56c7bb87d90a7b508f6208577014ff280910a710580357df25f3"],
+ ["9e0f99c504fbca858c209c6d9371ddd78985be1ab52845db0720af9ae5e2664d352f5037d4010000000552ac53636affffffff0e0ce866bc3f5b0a49748f597c18fa47a2483b8a94cef1d7295d9a5d36d31ae7030000000663515263ac635bb5d1698325164cdd3f7f3f7831635a3588f26d47cc30bf0fefd56cd87dc4e84f162ab702000000036a6365ffffffff85c2b1a61de4bcbd1d5332d5f59f338dd5e8accbc466fd860f96eef1f54c28ec030000000165ffffffff04f5cabd010000000007000052ac526563c18f1502000000000465510051dc9157050000000008655363ac525253ac506bb600000000000865656a53ab63006a00000000", "006a6a0052", 0, 1186324483, "2f9b7348600336512686e7271c53015d1cb096ab1a5e0bce49acd35bceb42bc8"],
+ ["11ce51f90164b4b54b9278f0337d95c50d16f6828fcb641df9c7a041a2b274aa70b1250f2b0000000008ab6a6a65006551524c9fe7f604af44be050000000005525365006521f79a0300000000015306bb4e04000000000265ac99611a05000000000765acab656500006dc866d0", "", 0, -1710478768, "cfa4b7573559b3b199478880c8013fa713ca81ca8754a3fd68a6d7ee6147dc5a"],
+ ["86bc233e02ba3c647e356558e7252481a7769491fb46e883dd547a4ce9898fc9a1ca1b77790000000006ab5351abab51f0c1d09c37696d5c7c257788f5dff5583f4700687bcb7d4acfb48521dc953659e325fa390300000003acac5280f29523027225af03000000000963abac0065ab65acab7e59d90400000000016549dac846", "53006aac52acac", 0, 711159875, "880330ccde00991503ea598a6dfd81135c6cda9d317820352781417f89134d85"],
+ ["beac155d03a853bf18cd5c490bb2a245b3b2a501a3ce5967945b0bf388fec2ba9f04c03d68030000000012fe96283aec4d3aafed8f888b0f1534bd903f9cd1af86a7e64006a2fa0d2d30711af770010000000163ffffffffd963a19d19a292104b9021c535d3e302925543fb3b5ed39fb2124ee23a9db00302000000056500ac63acffffffff01ad67f503000000000300ac5189f78db2", "53536a636500", 2, 748992863, "bde3dd0575164d7ece3b5783ce0783ffddb7df98f178fe6468683230314f285a"],
+ ["81dab34a039c9e225ba8ef421ec8e0e9d46b5172e892058a9ade579fe0eb239f7d9c97d45b0300000009ac65655351ab526363ffffffff10c0faaf7f597fc8b00bbc67c3fd4c6b70ca6b22718d15946bf6b032e62dae570000000005536a00ab6a02cddec3acf985bbe62c96fccf17012a87026ed63fc6756fa39e286eb4c2dd79b59d37400300000002516affffffff04f18b8d03000000000753abab5152636564411c02000000000400ab6300e965750300000000001bd2cf02000000000565ab526aab00000000", "006551ab", 0, -1488174485, "a3d65a8cd0c1eea8558d01396b929520a2221c29d9f25f29035b8abae874447f"],
+ ["489ebbf10478e260ba88c0168bd7509a651b36aaee983e400c7063da39c93bf28100011f280100000004abab63ab2fc856f05f59b257a4445253e0d91b6dffe32302d520ac8e7f6f2467f7f6b4b65f2f59e903000000096353abacab6351656affffffff0122d9480db6c45a2c6fd68b7bc57246edffbf6330c39ccd36aa3aa45ec108fc030000000265ab9a7e78a69aadd6b030b12602dff0739bbc346b466c7c0129b34f50ae1f61e634e11e9f3d0000000006516a53525100ffffffff011271070000000000086563ab6353536352c4dd0e2c", "", 0, -293358504, "4eba3055bc2b58765593ec6e11775cea4b6493d8f785e28d01e2d5470ea71575"],
+ ["6911195d04f449e8eade3bc49fd09b6fb4b7b7ec86529918b8593a9f6c34c2f2d301ec378b000000000263ab49162266af054643505b572c24ff6f8e4c920e601b23b3c42095881857d00caf56b28acd030000000565525200ac3ac4d24cb59ee8cfec0950312dcdcc14d1b360ab343e834004a5628d629642422f3c5acc02000000035100accf99b663e3c74787aba1272129a34130668a877cc6516bfb7574af9fa6d07f9b4197303400000000085351ab5152635252ffffffff042b3c95000000000000ff92330200000000046a5252ab884a2402000000000853530065520063000d78be03000000000953abab52ab53ac65aba72cb34b", "6a", 2, -637739405, "6b80d74eb0e7ee59d14f06f30ba7d72a48d3a8ff2d68d3b99e770dec23e9284f"],
+ ["746347cf03faa548f4c0b9d2bd96504d2e780292730f690bf0475b188493fb67ca58dcca4f0000000002005336e3521bfb94c254058e852a32fc4cf50d99f9cc7215f7c632b251922104f638aa0b9d080100000008656aac5351635251ffffffff4da22a678bb5bb3ad1a29f97f6f7e5b5de11bb80bcf2f7bb96b67b9f1ac44d09030000000365ababffffffff036f02b30000000000076353ab6aac63ac50b72a050000000002acaba8abf804000000000663006a6a6353797eb999", "acac5100", 1, -1484493812, "164c32a263f357e385bd744619b91c3f9e3ce6c256d6a827d6defcbdff38fa75"],
+ ["e17149010239dd33f847bf1f57896db60e955117d8cf013e7553fae6baa9acd3d0f1412ad90200000006516500516500cb7b32a8a67d58dddfb6ceb5897e75ef1c1ff812d8cd73875856487826dec4a4e2d2422a0100000004ac525365196dbb69039229270400000000070000535351636a8b7596020000000006ab51ac52655131e99d040000000003516551ee437f5c", "ac656a53", 1, 1102662601, "8858bb47a042243f369f27d9ab4a9cd6216adeac1c1ac413ed0890e46f23d3f3"],
+ ["144971940223597a2d1dec49c7d4ec557e4f4bd207428618bafa3c96c411752d494249e1fb0100000004526a5151ffffffff340a545b1080d4f7e2225ff1c9831f283a7d4ca4d3d0a29d12e07d86d6826f7f0200000003006553ffffffff03c36965000000000000dfa9af00000000000451636aac7f7d140300000000016300000000", "", 1, -108117779, "c84fcaf9d779df736a26cc3cabd04d0e61150d4d5472dd5358d6626e610be57f"],
+ ["b11b6752044e650b9c4744fb9c930819227d2ac4040d8c91a133080e090b042a142e93906e0000000003650053ffffffff6b9ce7e29550d3c1676b702e5e1537567354b002c8b7bb3d3535e63ad03b50ea01000000055100516300fffffffffcf7b252fea3ad5a108af3640a9bc2cd724a7a3ce22a760fba95496e88e2f2e801000000036a00ac7c58df5efba193d33d9549547f6ca839f93e14fa0e111f780c28c60cc938f785b363941b000000000863ab51516552ac5265e51fcd0308e9830400000000036a00abab72190300000000016a63d0710000000000050051ab6a6300000000", "53005165ac51ab65", 0, 229563932, "e562579d1a2b10d1c5e45c06513456002a6bec157d7eb42511d30b118103c052"],
+ ["2aee6b9a02172a8288e02fac654520c9dd9ab93cf514d73163701f4788b4caeeb9297d2e250300000004ab6363008fb36695528d7482710ea2926412f877a3b20acae31e9d3091406bfa6b62ebf9d9d2a6470100000009535165536a63520065ffffffff03f7b560050000000003acab6a9a8338050000000000206ce90000000000056552516a5100000000", "5252", 1, -1102319963, "fa4676c374ae3a417124b4c970d1ed3319dc3ac91fb36efca1aa9ed981a8aa1b"],
+ ["9554595203ad5d687f34474685425c1919e3d2cd05cf2dac89d5f33cd3963e5bb43f8706480100000000ffffffff9de2539c2fe3000d59afbd376cb46cefa8bd01dbc43938ff6089b63d68acdc2b02000000096553655251536a6500fffffffff9695e4016cd4dfeb5f7dadf00968e6a409ef048f81922cec231efed4ac78f5d010000000763abab6a5365006caaf0070162cc640200000000045163ab5100000000", "", 0, -1105256289, "e8e10ed162b1a43bfd23bd06b74a6c2f138b8dc1ab094ffb2fa11d5b22869bee"],
+ ["04f51f2a0484cba53d63de1cb0efdcb222999cdf2dd9d19b3542a896ca96e23a643dfc45f00200000007acac53510063002b091fd0bfc0cfb386edf7b9e694f1927d7a3cf4e1d2ce937c1e01610313729ef6419ae7030000000165a3372a913c59b8b3da458335dc1714805c0db98992fd0d93f16a7f28c55dc747fe66a5b503000000095351ab65ab52536351ffffffff5650b318b3e236802a4e41ed9bc0a19c32b7aa3f9b2cda1178f84499963a0cde000000000165ffffffff0383954f04000000000553ac536363a8fc90030000000000a2e315000000000005acab00ab5100000000", "0053", 2, -1424653648, "a5bc0356f56b2b41a2314ec05bee7b91ef57f1074bcd2efc4da442222269d1a3"],
+ ["5e4fab42024a27f0544fe11abc781f46596f75086730be9d16ce948b04cc36f86db7ad50fd01000000026a00613330f4916285b5305cc2d3de6f0293946aa6362fc087727e5203e558c676b314ef8dd401000000001af590d202ba496f040000000001009e3c9604000000000351ac51943d64d3", "51acabab5100ab52", 1, -129301207, "556c3f90aa81f9b4df5b92a23399fe6432cf8fecf7bba66fd8fdb0246440036c"],
+ ["a115284704b88b45a5f060af429a3a8eab10b26b7c15ed421258f5320fa22f4882817d6c2b0300000003005300ffffffff4162f4d738e973e5d26991452769b2e1be4b2b5b7e8cbeab79b9cf9df2882c040000000006636aac63ac5194abc8aa22f8ddc8a7ab102a58e39671683d1891799d19bd1308d24ea6d365e571172f1e030000000700515352515153ffffffff4da7ad75ce6d8541acbb0226e9818a1784e9c97c54b7d1ff82f791df1c6578f60000000000ffffffff01b1f265040000000009ab0051ac656a516a5300000000", "51abab6352535265", 0, -1269106800, "0ef7b6e87c782fa33fe109aab157a2d9cddc4472864f629510a1c92fa1fe7fc1"],
+ ["f3f771ae02939752bfe309d6c652c0d271b7cab14107e98032f269d92b2a8c8853ab057da8010000000563ab6a6365670c305c38f458e30a7c0ab45ee9abd9a8dc03bae1860f965ffced879cb2e5d0bb156821020000000153ffffffff025dc619050000000002ac51ec0d250100000000076a5200636a6363333aecd8", "650053ac515100ab", 1, 1812404608, "a7aa34bf8a5644f03c6dd8801f9b15ba2e07e07256dbf1e02dad59f0d3e17ea9"],
+ ["fd3e267203ae7d6d3975e738ca84f12540229bb237dd228d5f688e9d5ba53fce4302b0334d01000000026353ffffffff602a3ab75af7aa951d93093e345ef0037a2863f3f580a9b1a575fffe68e677450300000000239e476d1e8f81e8b6313880d8a49b27c1b00af467f29756e76f675f084a5676539636ab030000000765ab6351acac52d9217747044d773204000000000752ac51526353acc33e45050000000005516500005115d889040000000004ab5163510cbbbd0200000000016500000000", "65ac526aac6a53ab52", 2, -886179388, "bc46f3f83058ddf5bebd9e1f2c117a673847c4dc5e31cfb24bac91adf30877cf"],
+ ["f380ae23033646af5dfc186f6599098015139e961919aea28502ea2d69474413d94a555ea2000000000853635265abacac5314da394b99b07733341ddba9e86022637be3b76492992fb0f58f23c915098979250a96620300000003ab6300ffffffff4bb6d1c0a0d84eac7f770d3ad0fdc5369ae42a21bbe4c06e0b5060d5990776220300000000ffffffff0486fd70020000000007ac6500635252acf3fd72010000000005656a6a6551212de90500000000096365006a63635153000fa33100000000000600535151656300000000", "ab52", 2, -740890152, "f804fc4d81f039009ed1f2cccb5c91da797543f235ac71b214c20e763a6d86d7"],
+ ["5c45d09801bb4d8e7679d857b86b97697472d514f8b76d862460e7421e8617b15a2df217c6010000000863acacab6565006affffffff01156dbc03000000000952ac63516551ac6aac00000000", "6aabac", 0, 1310125891, "270445ab77258ced2e5e22a6d0d8c36ac7c30fff9beefa4b3e981867b03fa0ad"],
+ ["4ecc6bde030ca0f83c0ed3d4b777f94c0c88708c6c933fe1df6874f296d425cac95355c23d0000000006ac6a51536a52f286a0969d6170e20f2a8000193807f5bc556770e9d82341ef8e17b0035eace89c76edd50200000007ac65525100656affffffff5bade6e462fac1927f078d69d3a981f5b4c1e59311a38efcb9a910aa436afaa80000000007ac6a006352ab52ffffffff0331e58902000000000763ac53636352abb8b3ca000000000001637a1d26040000000009535263ac6a5352ab655ae34a39", "6a65ab", 2, 2142728517, "4a3415eb1677ae4e0c939644a4cfd5dc6299780b55cd0dc735967057b6b1526a"],
+ ["a59484b501eb50114be0fc79e72ab9bc9f4a5f7acdf274a56d6b68684eb68cf8b07ec5d1c2000000000765abab00ab00639e09aa940141e3530200000000046500ac6500000000", "00516565ab", 0, -1561622405, "d60bbadd2cc0674100baa08d0e0493ee4248f0304b3eb778da942041f503a896"],
+ ["53dc1a88046531c7b57a35f4d9adf101d068bf8d63fbbedaf4741dba8bc5e92c8725def571030000000453655251fcdf116a226b3ec240739c4c7493800e4edfe67275234e371a227721eac43d3d9ecaf1b50300000003ac0052ffffffff2c9279ffeea4718d167e9499bd067600715c14484e373ef93ae4a31d2f5671ab0000000009516553ac636a6a65001977752eeba95a8f16b88c571a459c2f2a204e23d48cc7090e4f4cc35846ca7fc0a455ce00000000055165ac0063188143f80205972902000000000765ac63ac516353c7b6a50000000000036a510000000000", "655351536a", 0, 103806788, "b276584d3514e5b4e058167c41dc02915b9d97f6795936a51f40e894ed8508bc"],
+ ["53f8959f01ddb36afdcd20167edcbb75a63d18654fdcf10bc0004c761ab450fe236d79cb2702000000065151650063653435003a033a5e34050000000009ac52516a630000516ab86db3030000000002006344ac090500000000046363ab00f3644537", "5263abab63ac656353", 0, -218513553, "f1f2a489682e42a6fc20025dfc89584d17f150b2d7ae3ddedd2bf43d5e24f37f"],
+ ["5a06cb4602dcfc85f49b8d14513f33c48f67146f2ee44959bbca092788e6823b2719f3160b0200000001ab3c013f2518035b9ea635f9a1c74ec1a3fb7496a160f46aae2e09bfc5cd5111a0f20969e003000000015158c89ab7049f20d6010000000008ac6a52abac53515349765e00000000000300ab638292630100000000045351ab0086da09010000000006656a6365525300000000", "526a63", 1, 1502936586, "bdfaff8a4e775379c5dc26e024968efa805f923de53fa8272dd53ec582afa0c5"],
+ ["ca9d84fa0129011e1bf27d7cb71819650b59fb292b053d625c6f02b0339249b498ff7fd4b601000000025352ffffffff032173a0040000000008525253abab5152639473bb030000000009005153526a53535151d085bd0000000000086a5365ab5165655300000000", "005152ac51", 0, 580353445, "c629d93b02037f40aa110e46d903edb34107f64806aa0c418d435926feef68b8"],
+ ["e3cdbfb4014d90ae6a4401e85f7ac717adc2c035858bf6ff48979dd399d155bce1f150daea0300000002ac51a67a0d39017f6c71040000000005535200535200000000", "", 0, -1899950911, "c1c7df8206e661d593f6455db1d61a364a249407f88e99ecad05346e495b38d7"],
+ ["b2b6b9ab0283d9d73eeae3d847f41439cd88279c166aa805e44f8243adeb3b09e584efb1df00000000026300ffffffff7dfe653bd67ca094f8dab51007c6adaced09de2af745e175b9714ca1f5c68d050000000003ac6500aa8e596903fd3f3204000000000553ac6a6a533a2e210500000000075253acabab526392d0ee020000000008520065635200ab5200000000", "65acacac65005365", 0, 28298553, "39c2aaa2496212b3ab120ab7d7f37c5e852bfe38d20f5226413a2268663eeae8"],
+ ["f30c5c3d01a6edb9e10fafaf7e85db14e7fec558b9dca4a80b05d7c3a2944d282c5018f4680200000003005263ffffffff04aac3530300000000026551bc2419010000000009005163acab6a5100658e7085050000000000c5e4ec050000000007656a6a635365ab2d8e8882", "abac53ab005251ac52", 0, -490287546, "877e347ec7487497769e2581142276d1a8d813b652e4483cf9cc993d16354417"],
+ ["4314339e01de40faabcb1b970245a7f19eedbc17c507dac86cf986c2973715035cf95736ae0200000007abababababab65bde67b900151510b04000000000853ac00655200535300000000", "52", 0, 399070095, "47585dc25469d04ff3a60939d0a03779e3e81a411bf0ca18b91bb925ebd30718"],
+ ["2d4cf4e9031b3e175b2ff18cd933151379d9cfac4713d8bd0e63b70bd4a92277aa7af901ab000000000565515353abffffffff557666c7f3be9cdecdad44c3df206eb63a2da4ed1f159d21193882a9f0340081020000000963ab53ab5252ac63abffffffff8a8c897bdb87e93886aad5ded9d82a13101d5476554386373646ca5e23612e450300000009006a526552abab6a635ac03fc00198bb02040000000009525100526a6563636a1d052834", "ab52ac00acac6a", 0, -1469882480, "09ed6563a454814ab7e3b4c28d56d8751162b77df1825b37ba66c6147750b2a3"],
+ ["f063171b03e1830fdc1d685a30a377537363ccafdc68b42bf2e3acb908dac61ee24b37595c020000000765ac5100ab6aacf447bc8e037b89d6cadd62d960cc442d5ced901d188867b5122b42a862929ce45e7b628d010000000253aba009a1ba42b00f1490b0b857052820976c675f335491cda838fb7934d5eea0257684a2a202000000001e83cf2401a7f777030000000008ab6553526a53526a00000000", "", 2, 1984790332, "c19caada8e71535e29a86fa29cfd9b74a0c7412003fc722a121005e461e01636"],
+ ["cf7bdc250249e22cbe23baf6b648328d31773ea0e771b3b76a48b4748d7fbd390e88a004d30000000003ac536a4ab8cce0e097136c90b2037f231b7fde2063017facd40ed4e5896da7ad00e9c71dd70ae600000000096a0063516352525365ffffffff01b71e3e00000000000300536a00000000", "", 1, 546970113, "6a815ba155270af102322c882f26d22da11c5330a751f520807936b320b9af5d"],
+ ["ac7a125a0269d35f5dbdab9948c48674616e7507413cd10e1acebeaf85b369cd8c88301b7c030000000963656aac6a530053abffffffffed94c39a582e1a46ce4c6bffda2ccdb16cda485f3a0d94b06206066da12aecfe010000000752abab63536363ef71dcfb02ee07fa0400000000016a6908c802000000000751656a6551abac688c2c2d", "6a6351526551", 0, 858400684, "552ff97d7924f51cda6d1b94be53483153ef725cc0a3a107adbef220c753f9a6"],
+ ["3a1f454a03a4591e46cf1f7605a3a130b631bf4dfd81bd2443dc4fac1e0a224e74112884fe0000000005516aac6a53a87e78b55548601ffc941f91d75eab263aa79cd498c88c37fdf275a64feff89fc1710efe03000000016a39d7ef6f2a52c00378b4f8f8301853b61c54792c0f1c4e2cd18a08cb97a7668caa008d970200000002656affffffff017642b20100000000096a63535253abac6a6528271998", "51", 2, 1459585400, "e9a7f21fc2d38be7be47095fbc8f1bf8923660aa4d71df6d797ae0ba5ca4d5b0"],
+ ["f59366cc0114c2a18e6bd1347ed9470f2522284e9e835dd5c5f7ef243639ebea95d9b232b6020000000153474b62eb045c00170500000000096352ab516352ab5200038a520400000000086aab5253656a63005b968904000000000963536353ac0053635387106002000000000000000000", "ab52526300ab51", 0, 1834116153, "cdf51f6e3a9dc2be5a59ea4c00f5aac1e1426a5202c325e6cf2567d07d8d8de4"],
+ ["6269e0fa0173e76e89657ca495913f1b86af5b8f1c1586bcd6c960aede9bc759718dfd5044000000000352ac530e2c7bd90219849b000000000007ab00ab6a53006319f281000000000007ab00515165ac5200000000", "6a", 0, -2039568300, "62094f98234a05bf1b9c7078c5275ed085656856fb5bdfd1b48090e86b53dd85"],
+ ["eb2bc00604815b9ced1c604960d54beea4a3a74b5c0035d4a8b6bfec5d0c9108f143c0e99a0000000000ffffffff22645b6e8da5f11d90e5130fd0a0df8cf79829b2647957471d881c2372c527d8010000000263acffffffff1179dbaf17404109f706ae27ad7ba61e860346f63f0c81cb235d2b05d14f2c1003000000025300264cb23aaffdc4d6fa8ec0bb94eff3a2e50a83418a8e9473a16aaa4ef8b855625ed77ef40100000003ac51acf8414ad404dd328901000000000652526500006ab6261c000000000002526a72a4c9020000000006ac526500656586d2e7000000000006656aac00ac5279cd8908", "51", 1, -399279379, "d37532e7b2b8e7db5c7c534197600397ebcc15a750e3af07a3e2d2e4f84b024f"],
+ ["dc9fe6a8038b84209bbdae5d848e8c040433237f415437592907aa798bf30d9dbbddf0ff85010000000153ffffffff23269a7ea29fcf788db483b8d4c4b35669e582608644259e950ce152b0fa6e050000000003acababffffffff65de94857897ae9ea3aa0b938ba6e5adf374d48469922d2b36dbb83d3b8c8261010000000452ac5200ffffffff02856e9b0300000000026a51980c8e02000000000365ab63d2648db4", "00ab0051ac526565", 2, 1562581941, "5cef9d8e18a2d5a70448f17b465d411a19dab78f0ddf1672ffd518b188f52433"],
+ ["eba8b0de04ac276293c272d0d3636e81400b1aaa60db5f11561480592f99e6f6fa13ad387002000000070053acab536563bebb23d66fd17d98271b182019864a90e60a54f5a615e40b643a54f8408fa8512cfac927030000000963ac6a6aabac65ababffffffff890a72192bc01255058314f376bab1dc72b5fea104c154a15d6faee75dfa5dba020000000100592b3559b0085387ac7575c05b29b1f35d9a2c26a0c27903cc0f43e7e6e37d5a60d8305a030000000252abffffffff0126518f05000000000000000000", "005300635252635351", 1, 664344756, "26dc2cba4bd5334e5c0b3a520b44cc1640c6b923d10e576062f1197171724097"],
+ ["91bd040802c92f6fe97411b159df2cd60fb9571764b001f31657f2d616964637605875c2a901000000055263006a65ffffffff3651df372645f50cf4e32fdf6e61c766e912e16335db2b40c5d52fe89eefe7cd00000000040065ab65ffffffff03ca8625030000000009ab51ac63530052ab52c6bf14020000000006ab00ab52005167d270000000000007ab53525351636a00000000", "5151ab63005252ac", 1, 1983087664, "3e5aa0200248d8d86ede3b315ca1b857018b89184a4bd023bd88ab12e499f6e1"],
+ ["185cda1a01ecf7a8a8c28466725b60431545fc7a3367ab68e34d486e8ea85ee3128e0d8384000000000465ac63abec88b7bb031c56eb04000000000965636a51005252006a7c78d5040000000007acac63abac51ac3024a40500000000086300526a51abac51464c0e8c", "0065535265515352", 0, 1594558917, "b5280b9610c0625a65b36a8c2402a95019a7bbb9dd3de77f7c3cb1d82c3263ba"],
+ ["a9531f07034091668b65fea8b1a79700d586ac9e2f42ca0455a26abe41f9e1805d009a0f5702000000096365516365ac5263ab3619bac643a9e28ee47855118cf80c3a74531cdf198835d206d0fe41804e325a4f9f105e03000000016a58e3ab0d46375d98994daf0fa7c600d2bb4669e726fca0e3a3f21ea0d9e777396740328f0100000008636a5363ab526a538d3ea7700304cb66030000000007515163ab52ab510184030500000000085353636565ac0051d9cff402000000000751ab52ab5352abf0e36254", "ab5353ac5365acab", 2, 1633101834, "04c9ef72f33668ca449c0415becf62cc0b8e0c75f9c8813852d42a58acf107c8"],
+ ["6b5ecc7903fe0ba37ea551df92a59e12bad0a3065846ba69179a8f4a741a2b4fcf679aac810200000004535263529a3d343293b99ab425e7ef8529549d84f480bcd92472bab972ea380a302128ae14dfcd0200000000025163ffffffff24636e4545cab9bf87009119b7fc3ec4d5ee9e206b90f35d1df8a563b6cd097a010000000852abac53005153abc64467860406e832020000000009526300006a53ac6352ac1395010000000002ac53b117f300000000000863655351acab00651edf02030000000008ab51ac6353535252628ef71d", "ab63ab6a52ac526563", 2, -1559697626, "8f07ece7d65e509f1e0780584ef8d271c1c61a13b10335d5faafc7afc8b5b8ec"],
+ ["92c9fb780138abc472e589d5b59489303f234acc838ca66ffcdf0164517a8679bb622a4267020000000153468e373d04de03fa020000000009ac006a5265ab5163006af649050000000007515153006a00658ceb59030000000001ac36afa0020000000009ab53006351ab51000000000000", "6a", 0, 2059357502, "e2358dfb51831ee81d7b0bc602a65287d6cd2dbfacf55106e2bf597e22a4b573"],
+ ["6f62138301436f33a00b84a26a0457ccbfc0f82403288b9cbae39986b34357cb2ff9b889b302000000045253655335a7ff6701bac9960400000000086552ab656352635200000000", "6aac51", 0, 1444414211, "502a2435fd02898d2ff3ab08a3c19078414b32ec9b73d64a944834efc9dae10c"],
+ ["9981143a040a88c2484ac3abe053849e72d04862120f424f373753161997dd40505dcb4783030000000700536365536565a2e10da3f4b1c1ad049d97b33f0ae0ea48c5d7c30cc8810e144ad93be97789706a5ead180100000003636a00ffffffffbdcbac84c4bcc87f03d0ad83fbe13b369d7e42ddb3aecf40870a37e814ad8bb5010000000963536a5100636a53abffffffff883609905a80e34202101544f69b58a0b4576fb7391e12a769f890eef90ffb72020000000651656352526affffffff04243660000000000004ab5352534a9ce001000000000863656363ab6a53652df19d030000000003ac65acedc51700000000000000000000", "ac6300acac", 2, 293672388, "7ba99b289c04718a7283f150d831175ed6303081e191a0608ea81f78926c5bdf"],
+ ["a2bb630b01989bc5d643f2da4fb9b55c0cdf846ba06d1dbe372893024dbbe5b9b8a1900af802000000055265ac63aca7a68d2f04916c74010000000003abac007077f0040000000001007d4127010000000005ac516aac000f31e8030000000000571079c9", "65ab0051ac", 0, -1103627693, "92d53b4390262e6b288e8a32e0cfc36cd5adfdfabfe96c7bfd4a19d65e233761"],
+ ["49f7d0b6037bba276e910ad3cd74966c7b3bc197ffbcfefd6108d6587006947e97789835ea0300000008526a52006a650053ffffffff8d7b6c07cd10f4c4010eac7946f61aff7fb5f3920bdf3467e939e58a1d4100ab03000000076aac63ac535351ffffffff8f48c3ba2d52ad67fbcdc90d8778f3c8a3894e3c35b9730562d7176b81af23c80100000003ab5265ffffffff0301e3ef0300000000046a525353e899ac0500000000075153ab6a65abac259bea0400000000007b739972", "53516aacac6aac", 1, 955403557, "5d366a7f4346ae18aeb7c9fc4dab5af71173184aa20ed22fcb4ea8511ad25449"],
+ ["58a4fed801fbd8d92db9dfcb2e26b6ff10b120204243fee954d7dcb3b4b9b53380e7bb8fb60100000003006351ffffffff02a0795b050000000006536351ac6aac2718d00200000000075151acabac515354d21ba1", "005363515351", 0, -1322430665, "bbee941bbad950424bf40e3623457db47f60ed29deaa43c99dec702317cb3326"],
+ ["32765a0b02e455793d9ce530e9f6a44bcbc612e893a875b5da61d822dc56d8245166c398b403000000085353abac6300006a6bdee2a78d0d0b6a5ea666eed70b9bfea99d1d612ba3878f615c4da10d4a521cba27155002000000035363abffffffff043cd42401000000000551656a53653685320100000000030000511881bc0500000000065165abab636a20169f010000000007acab656aac63acdb0706a8", "65ac53ab53", 0, 1936499176, "5c5a9c3a5de7dc7a82bc171c9d3505913b8bcc450bc8b2d11772c1a1d781210b"],
+ ["17fad0d303da0d764fedf9f2887a91ea625331b28704940f41e39adf3903d8e75683ef6d46020000000151ffffffffff376eea4e880bcf0f03d33999104aafed2b3daf4907950bb06496af6b51720a020000000900636a63525253525196521684f3b08497bad2c660b00b43a6a517edc58217876eb5e478aa3b5fda0f29ee1bea00000000046aacab6affffffff03dde8e2050000000007ac5365ac51516a14772e000000000005630000abacbbb360010000000006ab5251ab656a50f180f0", "0053", 0, -1043701251, "a3bdf8771c8990971bff9b4e7d59b7829b067ed0b8d3ac1ec203429811384668"],
+ ["236c32850300045e292c84ede2b9ab5733ba08315a2bb09ab234c4b4e8894808edbdac0d3b020000000653635363abacffffffffd3f696bb31fdd18a72f3fc2bb9ae54b416a253fc37c1a0f0180b52d35bad49440100000004650053abffffffffa85c75a2406d82a93b12e555b66641c1896a4e83ae41ef1038218311e38ace060200000006abab006a51ac104b5e6701e2842c04000000000800630051ac0000ab00000000", "ab63ac6a516a", 1, -1709887524, "8c29ea8ef60c5a927fccdba8ea385db6b6b84d98e891db45f5d4ee3148d3f5a7"],
+ ["b78d5fd601345f3100af494cdf447e7d4076179f940035b0ebe8962587d4d0c9c6c9fc34ee0300000003516a6affffffff03dc5c890100000000085353ac53ac6a52534ac941040000000007ac63656a51ab51d4266b0100000000036aacac70731f2d", "005351ab0053", 0, -1789071265, "d5f1c1cb35956a5711d67bfb4cedbc67e77c089b912d688ad440ff735adb390d"],
+ ["5a2257df03554550b774e677f348939b37f8e765a212e566ce6b60b4ea8fed4c9504b7f7d1000000000653655265ab5258b67bb931df15b041177cf9599b0604160b79e30f3d7a594e7826bae2c29700f6d8f8f40300000005515300ac6a159cf8808a41f504eb5c2e0e8a9279f3801a5b5d7bc6a70515fbf1c5edc875bb4c9ffac500000000050063510052ffffffff0422a90105000000000965006a650000516a006417d2020000000006526363ab00524d969d0100000000035153acc4f077040000000005ac5200636500000000", "6a52", 1, -1482463464, "37b794b05d0687c9b93d5917ab068f6b2f0e38406ff04e7154d104fc1fb14cdc"],
+ ["e0032ad601269154b3fa72d3888a3151da0aed32fb2e1a15b3ae7bee57c3ddcffff76a1321010000000100110d93ae03f5bd080100000000075263516a6551002871e60100000000046a005252eaa753040000000004ab6aab526e325c71", "630052", 0, -1857873018, "ea117348e94de86381bb8ad1c7f93b8c623f0272104341701bb54e6cb433596c"],
+ ["014b2a5304d46764817aca180dca50f5ab25f2e0d5749f21bb74a2f8bf6b8b7b3fa8189cb7030000000965ac5165ab6a51ac6360ecd91e8abc7e700a4c36c1a708a494c94bb20cbe695c408543146566ab22be43beae9103000000045163ab00ffffffffffa48066012829629a9ec06ccd4905a05df0e2b745b966f6a269c9c8e13451fc00000000026565ffffffffc40ccadc21e65fe8a4b1e072f4994738ccaf4881ae6fede2a2844d7da4d199ab02000000065152ab536aabffffffff01b6e054030000000004515352ab3e063432", "", 0, 1056459916, "a7aff48f3b8aeb7a4bfe2e6017c80a84168487a69b69e46681e0d0d8e63a84b6"],
+ ["c4ef04c103c5dde65410fced19bf6a569549ecf01ceb0db4867db11f2a3a3eef0320c9e8e001000000085100536a53516aabffffffff2a0354fa5bd96f1e28835ffe30f52e19bd7d5150c687d255021a6bec03cf4cfd03000000056a006300514900c5b01d3d4ae1b97370ff1155b9dd0510e198d266c356d6168109c54c11b4c283dca00300000002ababffffffff02e19e3003000000000451655351fa5c0003000000000163ef1fc64b", "51636a51ab630065", 1, -1754709177, "0a281172d306b6a32e166e6fb2a2cc52c505c5d60ea448e9ba7029aa0a2211e1"],
+ ["29083fe00398bd2bb76ceb178f22c51b49b5c029336a51357442ed1bac35b67e1ae6fdf13100000000066a6500acab51ffffffffe4ca45c9dc84fd2c9c47c7281575c2ba4bf33b0b45c7eca8a2a483f9e3ebe4b3010000000200abffffffffdf47ad2b8c263fafb1e3908158b18146357c3a6e0832f718cd464518a219d18303000000096352ac656351ac0052daddfb3b0231c36f00000000000400526a5275c7e0020000000001ab00000000", "acab536aac52", 2, 300802386, "82ebc07b16cff0077e9c1a279373185b3494e39d08fd3194aae6a4a019377509"],
+ ["1201ab5d04f89f07c0077abd009762e59db4bb0d86048383ba9e1dad2c9c2ad96ef660e6d00200000007ab6a65ac5200652466fa5143ab13d55886b6cdc3d0f226f47ec1c3020c1c6e32602cd3428aceab544ef43e00000000086a6a6a526a6a5263ffffffffd5be0b0be13ab75001243749c839d779716f46687e2e9978bd6c9e2fe457ee48020000000365abab1e1bac0f72005cf638f71a3df2e3bbc0fa35bf00f32d9c7dc9c39a5e8909f7d53170c8ae0200000008ab6a51516363516affffffff02f0a6210500000000036300ac867356010000000009acab65ac6353536a659356d367", "ac53535252", 0, 917543338, "418acc156c2bc76a5d7baa58db29f1b4cf6c266c9222ed167ef5b4d47f0e0f41"],
+ ["344fa11e01c19c4dd232c77742f0dd0aeb3695f18f76da627628741d0ee362b0ea1fb3a2180200000007635151005100529bab25af01937c1f0500000000055153ab53656e7630af", "6351005163ac51", 0, -629732125, "228ca52a0a376fe0527a61cfa8da6d7baf87486bba92d49dfd3899cac8a1034f"],
+ ["b2fda1950191358a2b855f5626a0ebc830ab625bea7480f09f9cd3b388102e35c0f303124c030000000565ac65ab53ffffffff03f9c5ec04000000000765ab51516551650e2b9f0500000000045365525284e8f6040000000001ac00000000", "ac51655253", 0, 1433027632, "d2fa7e13c34cecda5105156bd2424c9b84ee0a07162642b0706f83243ff811a8"],
+ ["a4a6bbd201aa5d882957ac94f2c74d4747ae32d69fdc765add4acc2b68abd1bdb8ee333d6e0300000008516a6552515152abffffffff02c353cb040000000007ac6351ab51536588bd320500000000066552525253ac00000000", "", 0, 1702060459, "499da7d74032388f820645191ac3c8d20f9dba8e8ded7fa3a5401ea2942392a1"],
+ ["584e8d6c035a6b2f9dac2791b980a485994bf38e876d9dda9b77ad156eee02fa39e19224a60300000003ab636529db326cc8686a339b79ab6b6e82794a18e0aabc19d9ad13f31dee9d7aad8eff38288588020000000452530052ffffffff09a41f07755c16cea1c7e193c765807d18cadddca6ec1c2ed7f5dcdca99e90e80000000001acffffffff01cba62305000000000451ac63acccdf1f67", "ab536a6363", 2, -27393461, "1125645b49202dca2df2d76dae51877387903a096a9d3f66b5ac80e042c95788"],
+ ["83a583d204d926f2ee587a83dd526cf1e25a44bb668e45370798f91a2907d184f7cddcbbc7030000000700ab6565536a539f71d3776300dffdfa0cdd1c3784c9a1f773e34041ca400193612341a9c42df64e3f550e01000000050052515251ffffffff52dab2034ab0648553a1bb8fc4e924b2c89ed97c18dfc8a63e248b454035564b01000000015139ab54708c7d4d2c2886290f08a5221cf69592a810fd1979d7b63d35c271961e710424fd0300000005ac65ac5251ffffffff01168f7c030000000000a85e5fb0", "6a536353656a00", 0, 179595345, "5350a31ac954a0b49931239d0ecafbf34d035a537fd0c545816b8fdc355e9961"],
+ ["ffd35d51042f290108fcb6ea49a560ba0a6560f9181da7453a55dfdbdfe672dc800b39e7320200000006630065516a65f2166db2e3827f44457e86dddfd27a8af3a19074e216348daa0204717d61825f198ec0030100000006ab51abab00abffffffffdf41807adb7dff7db9f14d95fd6dc4e65f8402c002d009a3f1ddedf6f4895fc8030000000500ab006a65a5a848345052f860620abd5fcd074195548ce3bd0839fa9ad8642ed80627bf43a0d47dbd010000000765ab006a656a53b38cdd6502a186da05000000000765ab00ab006a53527c0e0100000000085365ab51acacac52534bd1b1", "6a635253ac0000", 0, 1095082149, "3c05473a816621a3613f0e903faa1a1e44891dd40862b029e41fc520776350fa"],
+ ["6c9a4b98013c8f1cae1b1df9f0f2de518d0c50206a0ab871603ac682155504c0e0ce946f460100000000ffffffff04e9266305000000000753535100ac6aacded39e04000000000365ac6ab93ccd010000000002515397bf3d050000000003ab636300000000", "63520052ac656353", 0, -352633155, "936eff8cdfd771be24124da87c7b24feb48da7cbc2c25fb5ba13d1a23255d902"],
+ ["e01dc7f0021dc07928906b2946ca3e9ac95f14ad4026887101e2d722c26982c27dc2b59fdb0000000005ac5200516ab5a31ffadcbe74957a5a3f97d7f1475cc6423fc6dbc4f96471bd44c70cc736e7dec0d1ea020000000951636a526a52abac53ffffffff04bc2edd05000000000252ab528c7b02000000000952ac51526500525353324820040000000002005380c713000000000009630065ab00ac525252451bbb48", "53ab65ac", 0, -552384418, "69c0b30f4c630a6c878fde6ea6b74dae94f4eb3bcfbde2dc3649e1a9ada00757"],
+ ["009046a1023f266d0113556d604931374d7932b4d6a7952d08fbd9c9b87cbd83f4f4c178b4030000000452ac526346e73b438c4516c60edd5488023131f07acb5f9ea1540b3e84de92f4e3c432289781ea4900000000046500655357dfd6da02baef910100000000026a007d101703000000000800516500abacac5100000000", "6aab6553ac", 0, -802456605, "f8757fbb4448ca34e0cd41b997685b37238d331e70316659a9cc9087d116169d"],
+ ["df76ec0801a3fcf3d18862c5f686b878266dd5083f16cf655facab888b4cb3123b3ce5db7e01000000010010e7ac6a0233c83803000000000365ac51faf14a040000000004ac51655100000000", "6353acab", 0, 15705861, "e7d873aa079a19ec712b269a37d2670f60d8cb334c4f97e2e3fd10eeb8ee5f5e"],
+ ["828fd3e0031084051ccef9cfdd97fae4d9cc50c0dae36bd22a3ff332881f17e9756c3e288e0200000004ab535363961a2ccccaf0218ec6a16ba0c1d8b5e93cfd025c95b6e72bc629ec0a3f47da7a4c396dad01000000025353ffffffff19ad28747fb32b4caf7b5dbd9b2da5a264bedb6c86d3a4805cd294ae53a86ac40200000009ab53535351ab6551abffffffff04a41650030000000005656aab6aab8331a304000000000700516365ac516a0d2a47010000000007abac516353abacdebc19040000000006ab5300636a6300000000", "51ab52ab53ac52", 0, 1866105980, "311094b4d73e31aefc77e97859ef07ca2f07a7b7e4d7def80c69d3f5d58527e5"],
+ ["c4b80f850323022205b3e1582f1ed097911a81be593471a8dce93d5c3a7bded92ef6c7c1260100000002006affffffff70294d62f37c3da7c5eae5d67dce6e1b28fedd7316d03f4f48e1829f78a88ae801000000096a5200530000516351f6b7b544f7c39189d3a2106ca58ce4130605328ce7795204be592a90acd81bef517d6f170200000000ffffffff012ab8080000000000075100006365006335454c1e", "53ac6a536aacac", 0, -1124103895, "06277201504e6bf8b8c94136fad81b6e3dadacb9d4a2c21a8e10017bfa929e0e"],
+ ["8ab69ed50351b47b6e04ac05e12320984a63801716739ed7a940b3429c9c9fed44d3398ad40300000006536a516a52638171ef3a46a2adb8025a4884b453889bc457d63499971307a7e834b0e76eec69c943038a0300000000ffffffff566bb96f94904ed8d43d9d44a4a6301073cef2c011bf5a12a89bedbaa03e4724030000000265acb606affd01edea38050000000008515252516aacac6300000000", "65000000006365ac53", 0, -1338942849, "7912573937824058103cb921a59a7f910a854bf2682f4116a393a2045045a8c3"],
+ ["2484991e047f1cf3cfe38eab071f915fe86ebd45d111463b315217bf9481daf0e0d10902a402000000006e71a424eb1347ffa638363604c0d5eccbc90447ff371e000bf52fc743ec832851bb564a0100000001abffffffffef7d014fad3ae7927948edbbb3afe247c1bcbe7c4c8f5d6cf97c799696412612020000000851536a5353006a001dfee0d7a0dd46ada63b925709e141863f7338f34f7aebde85d39268ae21b77c3068c01d0000000008535151ab00636563ffffffff018478070200000000095200635365ac52ab5341b08cd3", "", 3, 265623923, "24cb420a53b4f8bb477f7cbb293caabfd2fc47cc400ce37dbbab07f92d3a9575"],
+ ["54839ef9026f65db30fc9cfcb71f5f84d7bb3c48731ab9d63351a1b3c7bc1e7da22bbd508e0300000000442ad138f170e446d427d1f64040016032f36d8325c3b2f7a4078766bdd8fb106e52e8d20000000003656500ffffffff02219aa101000000000851ababac52ab00659646bd02000000000552acacabac24c394a5", "ac", 0, 906807497, "69264faadcd1a581f7000570a239a0a26b82f2ad40374c5b9c1f58730514de96"],
+ ["5036d7080434eb4eef93efda86b9131b0b4c6a0c421e1e5feb099a28ff9dd8477728639f77030000000951516aab535152ab5391429be9cce85d9f3d358c5605cf8c3666f034af42740e94d495e28b9aaa1001ba0c87580300000008006552ab00ab006affffffffd838978e10c0c78f1cd0a0830d6815f38cdcc631408649c32a25170099669daa0000000002acab8984227e804ad268b5b367285edcdf102d382d027789250a2c0641892b480c21bf84e3fb0100000000b518041e023d8653010000000001004040fb0100000000080051ac5200636a6300000000", "52ac", 0, 366357656, "bd0e88829afa6bdc1e192bb8b2d9d14db69298a4d81d464cbd34df0302c634c6"],
+ ["9ad5ccf503fa4facf6a27b538bc910cce83c118d6dfd82f3fb1b8ae364a1aff4dcefabd38f03000000096365655263ac655300807c48130c5937190a996105a69a8eba585e0bd32fadfc57d24029cbed6446d30ebc1f100100000004000053650f0ccfca1356768df7f9210cbf078a53c72e0712736d9a7a238e0115faac0ca383f219d0010000000600ab536552002799982b0221b8280000000000000c41320000000000086552ac6365636a6595f233a3", "6a5152", 2, 553208588, "f99c29a79f1d73d2a69c59abbb5798e987639e36d4c44125d8dc78a94ddcfb13"],
+ ["669538a204047214ce058aed6a07ca5ad4866c821c41ac1642c7d63ed0054f84677077a84f030000000853abacab6a655353ffffffff70c2a071c115282924e3cb678b13800c1d29b6a028b3c989a598c491bc7c76c5030000000752ac52ac5163ac80420e8a6e43d39af0163271580df6b936237f15de998e9589ec39fe717553d415ac02a4030000000463635153184ad8a5a4e69a8969f71288c331aff3c2b7d1b677d2ebafad47234840454b624bf7ac1d03000000056a63abab63df38c24a02fbc63a040000000002ab535ec3dc050000000002536500000000", "635153", 3, -190399351, "9615541884dfb1feeb08073a6a6aa73ef694bc5076e52187fdf4138a369f94d9"],
+ ["a7f139e502af5894be88158853b7cbea49ba08417fbbca876ca6614b5a41432be34499987b000000000765635165abac63ffffffff8b8d70e96c7f54eb70da0229b548ced438e1ca2ba5ddd648a027f72277ee1efc0100000001abffffffff044f2c4204000000000165e93f550100000000050000526a6a94550304000000000365536aadc21c0300000000016300000000", "6aacac6363ab5265ac", 1, 2143189425, "6e3f97955490d93d6a107c18d7fe402f1cada79993bb0ff0d096357261b3a724"],
+ ["3b94438f0366f9f53579a9989b86a95d134256ce271da63ca7cd16f7dd5e4bffa17d35133f010000000100ffffffff1aaad0c721e06ec00d07e61a84fb6dc840b9a968002ce7e142f943f06fd143a10100000008535151ac51ab0053b68b8e9c672daf66041332163e04db3f6048534bd718e1940b3fc3811c4eef5b7a56888b01000000001d58e38c012e38e700000000000852ab53ac6365536a00000000", "ab655352", 1, -935223304, "b3b336de141d4f071313a2207b2a0c7cf54a070dd8d234a511b7f1d13e23b0c4"],
+ ["e5dca8a20456de0a67e185fa6ea94085ceae478d2c15c73cb931a500db3a1b6735dd1649ec0200000005ab536aabab32d11bbdcb81361202681df06a6b824b12b5cb40bb1a672cf9af8f2a836e4d95b7839327030000000951005365ab65abacabb345085932939eef0c724adef8a57f9e1bf5813852d957c039b6a12d9c2f201ea520fb030000000009ac5352005165acac6a5efc6072f1a421dc7dc714fc6368f6d763a5d76d0278b95fc0503b9268ccfadb48213a2500000000026a53ffffffff039ee1c4020000000009ac5353ab6353535163184018000000000005655265526a9a4a8a050000000001ac00000000", "65ab53ab6a00ab6553", 2, 1902561212, "7928ae8e86c0b0cad1b2c120ea313087437974382ee6d46443ca5ac3f5878b88"],
+ ["972128b904e7b673517e96e98d80c0c8ceceae76e2f5c126d63da77ffd7893fb53308bb2da0300000006ac6552ab52acffffffff4cac767c797d297c079a93d06dc8569f016b4bf7a7d79b605c526e1d36a40e2202000000095365ab636aac6a6a6a69928d2eddc836133a690cfb72ec2d3115bf50fb3b0d10708fa5d2ebb09b4810c426a1db01000000060052526300001e8e89585da7e77b2dd2e30625887f0660accdf29e53a614d23cf698e6fc8ab03310e87700000000076a520051acac6555231ddb0330ec2d03000000000200abfaf457040000000004ab6a6352bdc42400000000000153d6dd2f04", "", 0, 209234698, "4a92fec1eb03f5bd754ee9bfd70707dc4420cc13737374f4675f48529be518e4"],
+ ["1fb4085b022c6cfb848f8af7ba3ba8d21bd23ffa9f0bfd181cb68bcaaf2074e66d4974a31602000000090000006a6a6500acab6c12c07d9f3dbd2d93295c3a49e3757119767097e7fd5371f7d1ba9ba32f1a67a5a426f00000000000ffffffff018fd2fc04000000000363ac5100000000", "65ab006a6aab526a", 0, 1431502299, "8b7dd0ff12ca0d8f4dbf9abf0abba00e897c2f6fd3b92c79f5f6a534e0b33b32"],
+ ["5374f0c603d727f63006078bd6c3dce48bd5d0a4b6ea00a47e5832292d86af258ea0825c260000000009655353636352526a6af2221067297d42a9f8933dfe07f61a574048ff9d3a44a3535cd8eb7de79fb7c45b6f47320200000003ac006affffffff153d917c447d367e75693c5591e0abf4c94bbdd88a98ab8ad7f75bfe69a08c470200000005ac65516365ffffffff037b5b7b000000000001515dc4d904000000000004bb26010000000004536a6aac00000000", "516552516352ac", 2, 328538756, "8bb7a0129eaf4b8fc23e911c531b9b7637a21ab11a246352c6c053ff6e93fcb6"],
+ ["c441132102cc82101b6f31c1025066ab089f28108c95f18fa67db179610247086350c163bd010000000651525263ab00ffffffff9b8d56b1f16746f075249b215bdb3516cbbe190fef6292c75b1ad8a8988897c3000000000751ab6553abab00ffffffff02f9078b000000000009ab0053ac51ac00ab51c0422105000000000651006563525200000000", "ac51", 0, -197051790, "55acd8293ed0be6792150a3d7ced6c5ccd153ca7daf09cee035c1b0dac92bb96"],
+ ["ab82ad3b04545bd86b3bb937eb1af304d3ef1a6d1343ed809b4346cafb79b7297c09e1648202000000086351ac5200535353ffffffff95d32795bbaaf5977a81c2128a9ec0b3c7551b9b1c3d952876fcb423b2dfb9e80000000005515363acac47a7d050ec1a603627ce6cd606b3af314fa7964abcc579d92e19c7aba00cf6c3090d6d4601000000056a516551633e794768bfe39277ebc0db18b5afb5f0c8117dde9b4dfd5697e9027210eca76a9be20d63000000000700520063ab6aacffffffff01ec2ddc050000000008ac52ac65ac65ac5100000000", "536300abab", 1, -2070209841, "b362da5634f20be7267de78b545d81773d711b82fe9310f23cd0414a8280801d"],
+ ["8bff9d170419fa6d556c65fa227a185fe066efc1decf8a1c490bc5cbb9f742d68da2ab7f320100000007ab000053525365a7a43a80ab9593b9e8b6130a7849603b14b5c9397a190008d89d362250c3a2257504eb810200000007acabacac00ab51ee141be418f003e75b127fd3883dbf4e8c3f6cd05ca4afcaac52edd25dd3027ae70a62a00000000008ac52526a5200536affffffffb8058f4e1d7f220a1d1fa17e96d81dfb9a304a2de4e004250c9a576963a586ae0300000005abacac5363b9bc856c039c01d804000000000951656aac53005365acb0724e00000000000565abab63acea7c7a0000000000036a00ac00000000", "6565", 1, -1349282084, "2b822737c2affeefae13451d7c9db22ff98e06490005aba57013f6b9bbc97250"],
+ ["0e1633b4041c50f656e882a53fde964e7f0c853b0ada0964fc89ae124a2b7ffc5bc97ea6230100000006ac6aacacabacffffffff2e35f4dfcad2d53ea1c8ada8041d13ea6c65880860d96a14835b025f76b1fbd9000000000351515121270867ef6bf63a91adbaf790a43465c61a096acc5a776b8e5215d4e5cd1492e611f761000000000600ac6aab5265ffffffff63b5fc39bcac83ca80ac36124abafc5caee608f9f63a12479b68473bd4bae769000000000965ac52acac5263acabffffffff0163153e020000000008ab005165ab65515300000000", "6a6aac00", 0, -968477862, "20732d5073805419f275c53784e78db45e53332ee618a9fcf60a3417a6e2ca69"],
+ ["2b052c24022369e956a8d318e38780ef73b487ba6a8f674a56bdb80a9a63634c6110fb5154010000000251acffffffff48fe138fb7fdaa014d67044bc05940f4127e70c113c6744fbd13f8d51d45143e01000000005710db3804e01aa9030000000008acac6a516a5152abfd55aa01000000000751ab510000ac636d6026010000000000b97da9000000000000fddf3b53", "006552", 0, 595461670, "685d67d84755906d67a007a7d4fa311519467b9bdc6a351913246a41e082a29f"],
+ ["073bc856015245f03b2ea2da62ccedc44ecb99e4250c7042f596bcb23b294c9dc92cfceb6b02000000095163abab52abab636afe292fb303b7c3f001000000000352636af3c49502000000000400ac6a535851850100000000066aac6553ab6500000000", "ab6aab53006aab52", 0, 247114317, "123916c6485cf23bfea95654a8815fbf04ce4d21a3b7f862805c241472906658"],
+ ["7888b71403f6d522e414d4ca2e12786247acf3e78f1918f6d727d081a79813d129ee8befce0100000009ab516a6353ab6365abffffffff4a882791bf6400fda7a8209fb2c83c6eef51831bdf0f5dacde648859090797ec030000000153ffffffffbb08957d59fa15303b681bad19ccf670d7d913697a2f4f51584bf85fcf91f1f30200000008526565ac52ac63acffffffff0227c0e8050000000001ac361dc801000000000800515165ab00ab0000000000", "656a", 2, 1869281295, "f43378a0b7822ad672773944884e866d7a46579ee34f9afc17b20afc1f6cf197"],
+ ["cc4dda57047bd0ca6806243a6a4b108f7ced43d8042a1acaa28083c9160911cf47eab910c40200000007526a0000ab6a63e4154e581fcf52567836c9a455e8b41b162a78c85906ccc1c2b2b300b4c69caaaa2ba0230300000008ab5152ac5100ab65ffffffff69696b523ed4bd41ecd4d65b4af73c9cf77edf0e066138712a8e60a04614ea1c0300000004ab6a000016c9045c7df7836e05ac4b2e397e2dd72a5708f4a8bf6d2bc36adc5af3cacefcf074b8b403000000065352ac5252acffffffff01d7e380050000000000cf4e699a", "525163656351", 1, -776533694, "ff18c5bffd086e00917c2234f880034d24e7ea2d1e1933a28973d134ca9e35d2"],
+ ["b7877f82019c832707a60cf14fba44cfa254d787501fdd676bd58c744f6e951dbba0b3b77f0200000009ac515263ac53525300a5a36e500148f89c0500000000085265ac6a6a65acab00000000", "6563", 0, -1785108415, "cb6e4322955af12eb29613c70e1a00ddbb559c887ba844df0bcdebed736dffbd"],
+ ["aeb14046045a28cc59f244c2347134d3434faaf980961019a084f7547218785a2bd03916f3000000000165f852e6104304955bda5fa0b75826ee176211acc4a78209816bbb4419feff984377b2352200000000003a94a5032df1e0d60390715b4b188c330e4bb7b995f07cdef11ced9d17ee0f60bb7ffc8e0100000002516513e343a5c1dc1c80cd4561e9dddad22391a2dbf9c8d2b6048e519343ca1925a9c6f0800a020000000665516365ac513180144a0290db27000000000006ab655151ab5138b187010000000007ab5363abac516a9e5cd98a", "53ac", 0, 478591320, "e8d89a302ae626898d4775d103867a8d9e81f4fd387af07212adab99946311ef"],
+ ["c9270fe004c7911b791a00999d108ce42f9f1b19ec59143f7b7b04a67400888808487bd59103000000066a0052ac6565b905e76687be2dd7723b22c5e8269bc0f2000a332a289cfc40bc0d617cfe3214a61a85a30300000007ac63ac00635251560871209f21eb0268f175b8b4a06edd0b04162a974cf8b5dada43e499a1f22380d35ede0300000000792213fc58b6342cc8100079f9f5f046fb89f2d92cf0a2cb6d07304d32d9da858757037c0000000008abab51636565516affffffff02c72a8b03000000000452acac530dfb9f05000000000096f94307", "5253ab536351", 3, 543688436, "0278adbcc476d135493ae9bdcd7b3c2002df17f2d81c17d631c50c73e546c264"],
+ ["57a5a04c0278c8c8e243d2df4bb716f81d41ac41e2df153e7096f5682380c4f441888d9d260300000004ab63ab6afdbe4203525dff42a7b1e628fe22bccaa5edbb34d8ab02faff198e085580ea5fcdb0c61b0000000002ac6affffffff03375e6c05000000000663ab516a6a513cb6260400000000007ca328020000000006516a636a52ab94701cc7", "0053ac5152", 0, -550925626, "b7ca991ab2e20d0158168df2d3dd842a57ab4a3b67cca8f45b07c4b7d1d11126"],
+ ["072b75a504ad2550c2e9a02614bc9b2a2f50b5b553af7b87c0ef07c64ddc8d8934c96d216401000000036aabaca1387242a5bcd21099b016ad6045bed7dce603472757d9822cc5f602caa4ae20414d378b02000000026a63e4ac816734acdc969538d6f70b8ab43a2589f55e0177a4dc471bdd0eb61d59f0f46f6bb801000000065351526aab52d9f2977be76a492c3a7617b7a16dc29a3b0a7618f328c2f7d4fd9bafe760dc427a5066ef000000000465635165ffffffff02c5793600000000000165296820050000000002ac6300000000", "53006a6aac0052ab", 2, 66084636, "437e89bb6f70fd2ed2feef33350b6f6483b891305e574da03e580b3efd81ae13"],
+ ["7e27c42d0279c1a05eeb9b9faedcc9be0cab6303bde351a19e5cbb26dd0d594b9d74f40d2b020000000200518c8689a08a01e862d5c4dcb294a2331912ff11c13785be7dce3092f154a005624970f84e0200000000500cf5a601e74c1f0000000000076aab52636a6a5200000000", "6500006a5351", 0, 449533391, "535ba819d74770d4d613ee19369001576f98837e18e1777b8246238ff2381dd0"],
+ ["11414de403d7f6c0135a9df01cb108c1359b8d4e105be50a3dcba5e6be595c8817217490b20000000003005263ffffffff0c6becb9c3ad301c8dcd92f5cbc07c8bed7973573806d1489316fc77a829da03030000000700005253535352ffffffff2346d74ff9e12e5111aa8779a2025981850d4bf788a48de72baa2e321e4bc9ca00000000056352acab63cc585b64045e0385050000000009ab5253ab516aacac00efa9cf0300000000065200635151acbe80330400000000070063635100ab000be159050000000007525300655300ac00000000", "51656a0051ab", 0, 683137826, "d4737f3b58f3e5081b35f36f91acde89dda00a6a09d447e516b523e7a99264d5"],
+ ["1c6b5f29033fc139338658237a42456123727c8430019ca25bd71c6168a9e35a2bf54538d80100000008536aac52ac6a6a52ffffffff3fb36be74036ff0c940a0247c451d923c65f826793d0ac2bb3f01ecbec8033290100000007ab000051ab6363ffffffff5d9eca0cf711685105bd060bf7a67321eaef95367acffab36ce8dedddd632ee2000000000652ac6a63ac517167319e032d26de040000000003516363dc38fb010000000000b37b00000000000006ab520051ac534baba51f", "636300ababac6563", 0, -2049129935, "3282a2ec6b8c87c9303e6060c17b421687db1bd35fbfa0345b48f2490e15b6cc"],
+ ["978b9dad0214cfc7ce392d74d9dcc507350dc34007d72e4125861c63071ebf2cc0a6fd4856020000000651ac6a6aab52ffffffff47f20734e3370e733f87a6edab95a7a268ae44db7a8974e255614836b22938720200000008635265ac51516553ffffffff0137b2560100000000035252ac2f3363e9", "006aab6352", 1, 2014249801, "55611a5fb1483bce4c14c33ed15198130e788b72cd8929b2ceef4dd68b1806bf"],
+ ["442f1c8703ab39876153c241ab3d69f432ba6db4732bea5002be45c8ca10c3a2356fe0e9590300000001accb2b679cab7c58a660cb6d4b3452c21cd7251a1b77a52c300f655f5baeb6fa27ff5b79880300000003005252e5ccf55712bc8ed6179f6726f8a78f3018a7a0391594b7e286ef5ee99efdcde302a102cc0200000009006352526351536a63ffffffff04443f63030000000006536a63ab63651405fb020000000009ac535351525300ab6a9f172b000000000004ab535263ad5c50050000000008656a65ab630000ac00000000", "65636aab006552", 2, 2125838294, "b3ff10f21e71ebc8b25fe058c4074c42f08617e0dcc03f9e75d20539d3242644"],
+ ["2b3470dd028083910117f86614cdcfb459ee56d876572510be4df24c72e8f58c70d5f5948b03000000066aab65635265da2c3aac9d42c9baafd4b655c2f3efc181784d8cba5418e053482132ee798408ba43ccf90300000000ffffffff047dda4703000000000765516a52ac53009384a603000000000651636a63ab6a8cf57a03000000000352ab6a8cf6a405000000000952636a6a6565525100661e09cb", "ac520063ac6a6a52", 1, 1405647183, "9b360c3310d55c845ef537125662b9fe56840c72136891274e9fedfef56f9bb5"],
+ ["d74282b501be95d3c19a5d9da3d49c8a88a7049c573f3788f2c42fc6fa594f59715560b9b00000000009655353525265ac52ac9772121f028f8303030000000003510065af5f47040000000007ac516a6551630000000000", "acab53006363ac", 0, -1113209770, "2f482b97178f17286f693796a756f4d7bd2dfcdbecd4142528eec1c7a3e5101a"],
+ ["3a5644a9010f199f253f858d65782d3caec0ac64c3262b56893022b9796086275c9d4d097b02000000009d168f7603a67b30050000000007ac51536a0053acd9d88a050000000007655363535263ab3cf1f403000000000352ac6a00000000", "005363536565acac6a", 0, -1383947195, "6390ab0963cf611e0cea35a71dc958b494b084e6fd71d22217fdc5524787ade6"],
+ ["67b3cc43049d13007485a8133b90d94648bcf30e83ba174f5486ab42c9107c69c5530c5e1f0000000003005100ffffffff9870ebb65c14263282ea8d41e4f4f40df16b565c2cf86f1d22a9494cad03a67f01000000016a5a121bee5e359da548e808ae1ad6dfccae7c67cbb8898d811638a1f455a671e822f228ef030000000151c1fcc9f9825f27c0dde27ea709da62a80a2ff9f6b1b86a5874c50d6c37d39ae31fb6c8a0030000000163553b8786020ca74a00000000000665635153ab5275c0760000000000020052e659b05d", "636aab6a6a", 0, -342795451, "f77c3322c97b1681c17b1eba461fa27b07e04c1534e8aaf735a49cab72c7c2e2"],
+ ["bda1ff6804a3c228b7a12799a4c20917301dd501c67847d35da497533a606701ad31bf9d5e0300000001ac16a6c5d03cf516cd7364e4cbbf5aeccd62f8fd03cb6675883a0636a7daeb650423cb1291010000000500656553ac4a63c30b6a835606909c9efbae1b2597e9db020c5ecfc0642da6dc583fba4e84167539a8020000000865525353515200acffffffff990807720a5803c305b7da08a9f24b92abe343c42ac9e917a84e1f335aad785d00000000026a52ffffffff04981f20030000000001ab8c762200000000000253ab690b9605000000000151ce88b301000000000753526a6a51006500000000", "000052ac52530000", 1, -1809193140, "5299b0fb7fc16f40a5d6b337e71fcd1eb04d2600aefd22c06fe9c71fe0b0ba54"],
+ ["2ead28ff0243b3ab285e5d1067f0ec8724224402b21b9cef9be962a8b0d153d401be99bbee0000000004ac635153ffffffff6985987b7c1360c9fa8406dd6e0a61141709f0d5195f946da55ed83be4e3895301000000020053ffffffff016503d20500000000085251ac6a65656a6a00000000", "51abab", 1, 1723793403, "67483ee62516be17a2431a163e96fd88a08ff2ce8634a52e42c1bc04e30f3f8a"],
+ ["db4904e6026b6dd8d898f278c6428a176410d1ffbde75a4fa37cda12263108ccd4ca6137440100000007656a0000515263ffffffff1db7d5005c1c40da0ed17b74cf6b2a6ee2c33c9e0bacda76c0da2017dcac2fc70200000004abab6a53ffffffff0454cf2103000000000153463aef000000000009ab6a630065ab52636387e0ed050000000000e8d16f05000000000352ac63e4521b22", "", 1, 1027042424, "48315a95e49277ab6a2d561ee4626820b7bab919eea372b6bf4e9931ab221d04"],
+ ["dca31ad10461ead74751e83d9a81dcee08db778d3d79ad9a6d079cfdb93919ac1b0b61871102000000086500525365ab51ac7f7e9aed78e1ef8d213d40a1c50145403d196019985c837ffe83836222fe3e5955e177e70100000006525152525300ffffffff5e98482883cc08a6fe946f674cca479822f0576a43bf4113de9cbf414ca628060100000006ac53516a5253ffffffff07490b0b898198ec16c23b75d606e14fa16aa3107ef9818594f72d5776805ec502000000036a0052ffffffff01932a2803000000000865ab6551ac6a516a2687aa06", "635300ac", 2, -1880362326, "74d6a2fa7866fd8b74b2e34693e2d6fd690410384b7afdcd6461b1ae71d265ce"],
+ ["e14e1a9f0442ab44dfc5f6d945ad1ff8a376bc966aad5515421e96ddbe49e529614995cafc03000000055165515165fffffffff97582b8290e5a5cfeb2b0f018882dbe1b43f60b7f45e4dd21dbd3a8b0cfca3b0200000000daa267726fe075db282d694b9fee7d6216d17a8c1f00b2229085495c5dc5b260c8f8cd5d000000000363ac6affffffffaab083d22d0465471c896a438c6ac3abf4d383ae79420617a8e0ba8b9baa872b010000000963526563ac5363ababd948b5ce022113440200000000076a636552006a53229017040000000000e6f62ac8", "526353636a65", 3, -485265025, "1bc8ad76f9b7c366c5d052dc479d6a8a2015566d3a42e93ab12f727692c89d65"],
+ ["720d4693025ca3d347360e219e9bc746ef8f7bc88e8795162e5e2f0b0fc99dc17116fc937100000000046353520045cb1fd79824a100d30b6946eab9b219daea2b0cdca6c86367c0c36af98f19ac64f3575002000000008a1c881003ed16f3050000000008536a63630000abac45e0e704000000000151f6551a05000000000963536565515363abab00000000", "6553ab6a6a510000ab", 1, 1249091393, "a575fa4f59a8e90cd07de012c78fe8f981183bb170b9c50fcc292b8c164cbc3b"],
+ ["69df842a04c1410bfca10896467ce664cfa31c681a5dac10106b34d4b9d4d6d0dc1eac01c1000000000551536a5165269835ca4ad7268667b16d0a2df154ec81e304290d5ed69e0069b43f8c89e673328005e200000000076a5153006aacabffffffffc9314bd80b176488f3d634360fcba90c3a659e74a52e100ac91d3897072e3509010000000765abac51636363ffffffff0e0768b13f10f0fbd2fa3f68e4b4841809b3b5ba0e53987c3aaffcf09eee12bf0300000008ac535263526a53ac514f4c2402da8fab0400000000001ef15201000000000451526a52d0ec9aca", "525365ac52", 1, 313967049, "a72a760b361af41832d2c667c7488dc9702091918d11e344afc234a4aea3ec44"],
+ ["adf2340d03af5c589cb5d28c06635ac07dd0757b884d4777ba85a6a7c410408ad5efa8b19001000000045100ab00ffffffff808dc0231c96e6667c04786865727013922bcb7db20739b686f0c17f5ba70e8f0300000000fd2332a654b580881a5e2bfec8313f5aa878ae94312f37441bf2d226e7fc953dcf0c77ab000000000163aa73dc580412f8c2050000000005636aacac63da02d502000000000153e74b52020000000001536b293d030000000009636552ababacab526500000000", "000052ab52ababab", 0, -568651175, "2c45d021db545df7167ac03c9ee56473f2398d9b2b739cf3ff3e074501d324f8"],
+ ["e4fec9f10378a95199c1dd23c6228732c9de0d7997bf1c83918a5cfd36012476c0c3cba24002000000085165536500ac0000ad08ab93fb49d77d12a7ccdbb596bc5110876451b53a79fdce43104ff1c316ad63501de801000000046a6352ab76af9908463444aeecd32516a04dd5803e02680ed7f16307242a794024d93287595250f4000000000089807279041a82e603000000000200521429100200000000055253636a63f20b940400000000004049ed04000000000500ab5265ab43dfaf7d", "6563526aac", 2, -1923470368, "32f3c012eca9a823bebb9b282240aec40ca65df9f38da43b1dcfa0cac0c0df7e"],
+ ["4000d3600100b7a3ff5b41ec8d6ccdc8b2775ad034765bad505192f05d1f55d2bc39d0cbe10100000007ab5165ac6a5163ffffffff034949150100000000026a6a92c9f6000000000008ab6553ab6aab635200e697040000000007636a5353525365237ae7d2", "52000063", 0, -880046683, "c76146f68f43037289aaeb2bacf47408cddc0fb326b350eb4f5ef6f0f8564793"],
+ ["eabc0aa701fe489c0e4e6222d72b52f083166b49d63ad1410fb98caed027b6a71c02ab830c03000000075253ab63530065ffffffff01a5dc0b05000000000253533e820177", "", 0, 954499283, "1d849b92eedb9bf26bd4ced52ce9cb0595164295b0526842ab1096001fcd31b1"],
+ ["d48d55d304aad0139783b44789a771539d052db565379f668def5084daba0dfd348f7dcf6b00000000006826f59e5ffba0dd0ccbac89c1e2d69a346531d7f995dea2ca6d7e6d9225d81aec257c6003000000096a655200ac656552acffffffffa188ffbd5365cae844c8e0dea6213c4d1b2407274ae287b769ab0bf293e049eb0300000005ac6a6aab51ad1c407c5b116ca8f65ed496b476183f85f072c5f8a0193a4273e2015b1cc288bf03e9e2030000000252abffffffff04076f44040000000006655353abab53be6500050000000003ac65ac3c15040500000000095100ab536353516a52ed3aba04000000000900ac53ab53636aabac00000000", "5253526563acac", 2, -1506108646, "bbee17c8582514744bab5df50012c94b0db4aff5984d2e13a8d09421674404e2"],
+ ["9746f45b039bfe723258fdb6be77eb85917af808211eb9d43b15475ee0b01253d33fc3bfc502000000065163006a655312b12562dc9c54e11299210266428632a7d0ee31d04dfc7375dcad2da6e9c11947ced0e000000000009074095a5ac4df057554566dd04740c61490e1d3826000ad9d8f777a93373c8dddc4918a00000000025351ffffffff01287564030000000004636a00ab00000000", "52", 2, -1380411075, "84af1623366c4db68d81f452b86346832344734492b9c23fbb89015e516c60b2"],
+ ["8731b64903d735ba16da64af537eaf487b57d73977f390baac57c7b567cb2770dfa2ef65870100000001635aedd990c42645482340eacb0bfa4a0a9e888057389c728b5b6a8691cdeb1a6a67b45e140200000008ac53526a52516551ffffffff45c4f567c47b8d999916fd49642cbc5d10d43c304b99e32d044d35091679cb860100000003006a51ffffffff0176d6c200000000000000000000", "ab6a65ab53", 2, -1221546710, "ccfdba36d9445f4451fb7cbf0752cc89c23d4fc6fff0f3930d20e116f9db0b95"],
+ ["f5cfc52f016209ab1385e890c2865a74e93076595d1ca77cbe8fbf2022a2f2061a90fb0f3e010000000253acffffffff027de73f0200000000085252ac510052acac49cd6a020000000000e6c2cb56", "516552535300ab63", 0, -1195302704, "5532717402a2da01a1da912d824964024185ca7e8d4ad1748659dc393a14182b"],
+ ["df0a32ae01c4672fd1abd0b2623aae0a1a8256028df57e532f9a472d1a9ceb194267b6ee190200000009536a6a51516a525251b545f9e803469a2302000000000465526500810631040000000000441f5b050000000006530051006aaceb183c76", "536a635252ac6a", 0, 1601138113, "9a0435996cc58bdba09643927fe48c1fc908d491a050abbef8daec87f323c58f"],
+ ["d102d10c028b9c721abb259fe70bc68962f6cae384dabd77477c59cbeb1fb26266e091ba3e0100000002516affffffffe8d7305a74f43e30c772109849f4cd6fb867c7216e6d92e27605e69a0818899700000000026a65ecf82d58027db4620500000000026552c28ed3010000000001ab00000000", "0051ab515365", 1, -131815460, "1d1757a782cb5860302128bcbe9398243124a2f82d671a113f74f8e582c7a182"],
+ ["cef930ed01c36fcb1d62ceef931bef57098f27a77a4299904cc0cbb44504802d535fb11557010000000153ffffffff02c8657403000000000863ac655253520063d593380400000000046aab536a00000000", "656a0051ab6365ab53", 0, -351313308, "e69dba3efb5c02af2ab1087d0a990678784671f4744d01ca097d71aec14dd8e9"],
+ ["b1c0b71804dff30812b92eefb533ac77c4b9fdb9ab2f77120a76128d7da43ad70c20bbfb990200000002536392693e6001bc59411aebf15a3dc62a6566ec71a302141b0c730a3ecc8de5d76538b30f55010000000665535252ac514b740c6271fb9fe69fdf82bf98b459a7faa8a3b62f3af34943ad55df4881e0d93d3ce0ac0200000000c4158866eb9fb73da252102d1e64a3ce611b52e873533be43e6883137d0aaa0f63966f060000000001abffffffff04a605b604000000000851006a656a630052f49a0300000000000252515a94e1050000000009abac65ab0052abab00fd8dd002000000000651535163526a2566852d", "ac5363", 0, -1718831517, "b0dc030661783dd9939e4bf1a6dfcba809da2017e1b315a6312e5942d714cf05"],
+ ["6a270ee404ebc8d137cfd4bb6b92aa3702213a3139a579c1fc6f56fbc7edd9574ef17b13f30100000009ab00ab656565ababacffffffffaa65b1ab6c6d87260d9e27a472edceb7dd212483e72d90f08857abf1dbfd46d10100000000fffffffff93c4c9c84c4dbbe8a912b99a2830cfe3401aebc919041de063d660e585fc9f002000000096aabacab52ac6a53acfa6dcef3f28355a8d98eee53839455445eeee83eecd2c854e784efa53cee699dbfecaebd0100000003ab6a51ffffffff04f7d71b050000000009ac6a536aac6a6365513c37650500000000065265abab6a53fa742002000000000039ed82030000000009516aac635165ab51ab2fdabd17", "ab535252526563", 1, -1326210506, "1dec0d5eb921bf5b2df39c8576e19c38d0c17254a4a0b78ac4b5422bcc426258"],
+ ["3657e4260304ccdc19936e47bdf058d36167ee3d4eb145c52b224eff04c9eb5d1b4e434dfc0000000001ab58aefe57707c66328d3cceef2e6f56ab6b7465e587410c5f73555a513ace2b232793a74400000000036a006522e69d3a785b61ad41a635d59b3a06b2780a92173f85f8ed428491d0aaa436619baa9c4501000000046351abab2609629902eb7793050000000000a1b967040000000003525353a34d6192", "516a", 0, -1761874713, "0a2ff41f6d155d8d0e37cd9438f3b270df9f9214cda8e95c76d5a239ca189df2"],
+ ["a0eb6dc402994e493c787b45d1f946d267b09c596c5edde043e620ce3d59e95b2b5b93d43002000000096a5252526aac63ab6555694287a279e29ee491c177a801cd685b8744a2eab83824255a3bcd08fc0e3ea13fb8820000000009abab6365ab52ab0063ffffffff029e424a040000000008acab53ab516a636a23830f0400000000016adf49c1f9", "ac0065ac6500005252", 1, 669294500, "e05e3d383631a7ed1b78210c13c2eb26564e5577db7ddfcea2583c7c014091d4"],
+ ["6e67c0d3027701ef71082204c85ed63c700ef1400c65efb62ce3580d187fb348376a23e9710200000001655b91369d3155ba916a0bc6fe4f5d94cad461d899bb8aaac3699a755838bfc229d6828920010000000765536353526a52ffffffff04c0c792000000000005650052535372f79e000000000001527fc0ee010000000005ac5300ab65d1b3e902000000000251aba942b278", "6a5151", 0, 1741407676, "e657e2c8ec4ebc769ddd3198a83267b47d4f2a419fc737e813812acefad92ff7"],
+ ["8f53639901f1d643e01fc631f632b7a16e831d846a0184cdcda289b8fa7767f0c292eb221a00000000046a53abacffffffff037a2daa01000000000553ac6a6a51eac349020000000005ac526552638421b3040000000007006a005100ac63048a1492", "ac65", 0, 1033685559, "da86c260d42a692358f46893d6f91563985d86eeb9ea9e21cd38c2d8ffcfcc4d"],
+ ["491f99cb01bdfba1aa235e5538dac081fae9ce55f9622de483afe7e65105c2b0db75d360d200000000045251636340b60f0f041421330300000000096351ac000051636553ce2822040000000005516a00ac5180c8e40300000000025100caa8570400000000020000cfdc8da6", "6a5100516aab655365", 0, -953727341, "397c68803b7ce953666830b0221a5e2bcf897aa2ded8e36a6b76c497dcb1a2e1"],
+ ["b3cad3a7041c2c17d90a2cd994f6c37307753fa3635e9ef05ab8b1ff121ca11239a0902e700300000009ab635300006aac5163ffffffffcec91722c7468156dce4664f3c783afef147f0e6f80739c83b5f09d5a09a57040200000004516a6552ffffffff969d1c6daf8ef53a70b7cdf1b4102fb3240055a8eaeaed2489617cd84cfd56cf020000000352ab53ffffffff46598b6579494a77b593681c33422a99559b9993d77ca2fa97833508b0c169f80200000009655300655365516351ffffffff04d7ddf800000000000853536a65ac6351ab09f3420300000000056aab65abac33589d04000000000952656a65655151acac944d6f0400000000006a8004ba", "005165", 1, 1035865506, "fe1dc9e8554deecf8f50c417c670b839cc9d650722ebaaf36572418756075d58"],
+ ["e1cfd73b0125add9e9d699f5a45dca458355af175a7bd4486ebef28f1928d87864384d02df02000000036a0051ffffffff0357df030100000000036a5365777e2d04000000000763ab6a00005265f434a601000000000351655100000000", "ab53ab", 0, -1936500914, "950f4b4f72ccdf8a6a0f381265d6c8842fdb7e8b3df3e9742905f643b2432b69"],
+ ["cf781855040a755f5ba85eef93837236b34a5d3daeb2dbbdcf58bb811828d806ed05754ab8010000000351ac53ffffffffda1e264727cf55c67f06ebcc56dfe7fa12ac2a994fecd0180ce09ee15c480f7d00000000096351516a51acac00ab53dd49ff9f334befd6d6f87f1a832cddfd826a90b78fd8cf19a52cb8287788af94e939d6020000000700525251ac526310d54a7e8900ed633f0f6f0841145aae7ee0cbbb1e2a0cae724ee4558dbabfdc58ba6855010000000552536a53abfd1b101102c51f910500000000096300656a525252656a300bee010000000009ac52005263635151abe19235c9", "53005365", 2, 1422854188, "d5981bd4467817c1330da72ddb8760d6c2556cd809264b2d85e6d274609fc3a3"],
+ ["fea256ce01272d125e577c0a09570a71366898280dda279b021000db1325f27edda41a53460100000002ab53c752c21c013c2b3a01000000000000000000", "65", 0, 1145543262, "076b9f844f6ae429de228a2c337c704df1652c292b6c6494882190638dad9efd"]
+]
diff --git a/src/test/data/tt-delin1-out.hex b/src/test/data/tt-delin1-out.hex
new file mode 100644
index 0000000000..42ad840f43
--- /dev/null
+++ b/src/test/data/tt-delin1-out.hex
@@ -0,0 +1 @@
+0100000014fd5c23522d31761c50175453daa6edaabe47a602a592d39ce933d8271a1a87274c0100006c493046022100b4251ecd63778a3dde0155abe4cd162947620ae9ee45a874353551092325b116022100db307baf4ff3781ec520bd18f387948cedd15dc27bafe17c894b0fe6ffffcafa012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffc1b37ae964f605978022f94ce2f3f676d66a46d1aef7c2c17d6315b9697f2f75010000006a473044022079bd62ee09621a3be96b760c39e8ef78170101d46313923c6b07ae60a95c90670220238e51ea29fc70b04b65508450523caedbb11cb4dd5aa608c81487de798925ba0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34ffffffffedd005dc7790ef65c206abd1ab718e75252a40f4b1310e4102cd692eca9cacb0d10000006b48304502207722d6f9038673c86a1019b1c4de2d687ae246477cd4ca7002762be0299de385022100e594a11e3a313942595f7666dcf7078bcb14f1330f4206b95c917e7ec0e82fac012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffdf28d6e26fb7a85a1e6a229b972c1bae0edc1c11cb9ca51e4caf5e59fbea35a1000000006b483045022100a63a4788027b79b65c6f9d9e054f68cf3b4eed19efd82a2d53f70dcbe64683390220526f243671425b2bd05745fcf2729361f985cfe84ea80c7cfc817b93d8134374012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52ffffffffae2a2320a1582faa24469eff3024a6b98bfe00eb4f554d8a0b1421ba53bfd6a5010000006c493046022100b200ac6db16842f76dab9abe807ce423c992805879bc50abd46ed8275a59d9cf022100c0d518e85dd345b3c29dd4dc47b9a420d3ce817b18720e94966d2fe23413a408012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffb3cc5a12548aa1794b4d2bbf076838cfd7fbafb7716da51ee8221a4ff19c291b000000006b483045022100ededc441c3103a6f2bd6cab7639421af0f6ec5e60503bce1e603cf34f00aee1c02205cb75f3f519a13fb348783b21db3085cb5ec7552c59e394fdbc3e1feea43f967012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52ffffffff85145367313888d2cf2747274a32e20b2df074027bafd6f970003fcbcdf11d07150000006b483045022100d9eed5413d2a4b4b98625aa6e3169edc4fb4663e7862316d69224454e70cd8ca022061e506521d5ced51dd0ea36496e75904d756a4c4f9fb111568555075d5f68d9a012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff8292c11f6d35abab5bac3ebb627a4ff949e8ecd62d33ed137adf7aeb00e512b0090000006b48304502207e84b27139c4c19c828cb1e30c349bba88e4d9b59be97286960793b5ddc0a2af0221008cdc7a951e7f31c20953ed5635fbabf228e80b7047f32faaa0313e7693005177012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff883dcf9a86063db088ad064d0953258d4b0ff3425857402d2f3f839cee0f84581e0000006a4730440220426540dfed9c4ab5812e5f06df705b8bcf307dd7d20f7fa6512298b2a6314f420220064055096e3ca62f6c7352c66a5447767c53f946acdf35025ab3807ddb2fa404012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff6697dbb3ed98afe481b568459fa67e503f8a4254532465a670e54669d19c9fe6720000006a47304402200a5e673996f2fc88e21cc8613611f08a650bc0370338803591d85d0ec5663764022040b6664a0d1ec83a7f01975b8fde5232992b8ca58bf48af6725d2f92a936ab2e012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff023ffc2182517e1d3fa0896c5b0bd7b4d2ef8a1e42655abe2ced54f657125d59670000006c493046022100d93b30219c5735f673be5c3b4688366d96f545561c74cb62c6958c00f6960806022100ec8200adcb028f2184fa2a4f6faac7f8bb57cb4503bb7584ac11051fece31b3d012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff16f8c77166b0df3d7cc8b5b2ce825afbea9309ad7acd8e2461a255958f81fc06010000006b483045022100a13934e68d3f5b22b130c4cb33f4da468cffc52323a47fbfbe06b64858162246022047081e0a70ff770e64a2e2d31e5d520d9102268b57a47009a72fe73ec766901801210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cdffffffff197b96f3c87a3adfaa17f63fddc2a738a690ca665439f9431dbbd655816c41fb000000006c49304602210097f1f35d5bdc1a3a60390a1b015b8e7c4f916aa3847aafd969e04975e15bbe70022100a9052eb25517d481f1fda1b129eb1b534da50ea1a51f3ee012dca3601c11b86a0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34ffffffff20d9a261ee27aa1bd92e7db2fdca935909a40b648e974cd24a10d63b68b94039dd0000006b483045022012b3138c591bf7154b6fef457f2c4a3c7162225003788ac0024a99355865ff13022100b71b125ae1ffb2e1d1571f580cd3ebc8cd049a2d7a8a41f138ba94aeb982106f012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff50f179d5d16cd872f9a63c26c448464ae9bd95cd9421c0476113b5d314571b71010000006b483045022100f834ccc8b22ee72712a3e5e6ef4acb8b2fb791b5385b70e2cd4332674d6667f4022024fbda0a997e0c253503f217501f508a4d56edce2c813ecdd9ad796dbeba907401210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cdffffffff551b865d1568ac0a305e5f9c5dae6c540982334efbe789074318e0efc5b564631b0000006b48304502203b2fd1e39ae0e469d7a15768f262661b0de41470daf0fe8c4fd0c26542a0870002210081c57e331f9a2d214457d953e3542904727ee412c63028113635d7224da3dccc012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff57503e5a016189d407a721791459280875264f908ca2c5d4862c01386e7fb50b470400006b48304502206947a9c54f0664ece4430fd4ae999891dc50bb6126bc36b6a15a3189f29d25e9022100a86cfc4e2fdd9e39a20e305cfd1b76509c67b3e313e0f118229105caa0e823c9012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff3f16c1fb9d3e1a26d872933e955df85ee7f3f817711062b00b54a2144827349b250000006b483045022100c7128fe10b2d38744ae8177776054c29fc8ec13f07207723e70766ab7164847402201d2cf09009b9596de74c0183d1ab832e5edddb7a9965880bb400097e850850f8012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff4142a69d85b8498af214f0dd427b6ab29c240a0b8577e2944d37a7d8c05c6bb8140000006b48304502203b89a71628a28cc3703d170ca3be77786cff6b867e38a18b719705f8a326578f022100b2a9879e1acf621faa6466c207746a7f3eb4c8514c1482969aba3f2a957f1321012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff36e2feecc0a4bff7480015d42c12121932db389025ed0ac1d344ecee53230a3df20000006c493046022100ef794a8ef7fd6752d2a183c18866ff6e8dc0f5bd889a63e2c21cf303a6302461022100c1b09662d9e92988c3f9fcf17d1bcc79b5403647095d7212b9f8a1278a532d68012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff0260f73608000000001976a9148fd139bb39ced713f231c58a4d07bf6954d1c20188ac41420f00000000001976a9146c772e9cf96371bba3da8cb733da70a2fcf2007888ac00000000
diff --git a/src/test/data/tt-delout1-out.hex b/src/test/data/tt-delout1-out.hex
new file mode 100644
index 0000000000..cc60c3fac6
--- /dev/null
+++ b/src/test/data/tt-delout1-out.hex
@@ -0,0 +1 @@
+0100000015fd5c23522d31761c50175453daa6edaabe47a602a592d39ce933d8271a1a87274c0100006c493046022100b4251ecd63778a3dde0155abe4cd162947620ae9ee45a874353551092325b116022100db307baf4ff3781ec520bd18f387948cedd15dc27bafe17c894b0fe6ffffcafa012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffcb4ed1baba3a1eb2171e00ddec8e5b72b346dd8c07f9c2b0d122d0d06bc92ea7000000006c493046022100a9b617843b68c284715d3e02fd120479cd0d96a6c43bf01e697fb0a460a21a3a022100ba0a12fbe8b993d4e7911fa3467615765dbe421ddf5c51b57a9c1ee19dcc00ba012103e633b4fa4ceb705c2da712390767199be8ef2448b3095dc01652e11b2b751505ffffffffc1b37ae964f605978022f94ce2f3f676d66a46d1aef7c2c17d6315b9697f2f75010000006a473044022079bd62ee09621a3be96b760c39e8ef78170101d46313923c6b07ae60a95c90670220238e51ea29fc70b04b65508450523caedbb11cb4dd5aa608c81487de798925ba0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34ffffffffedd005dc7790ef65c206abd1ab718e75252a40f4b1310e4102cd692eca9cacb0d10000006b48304502207722d6f9038673c86a1019b1c4de2d687ae246477cd4ca7002762be0299de385022100e594a11e3a313942595f7666dcf7078bcb14f1330f4206b95c917e7ec0e82fac012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffdf28d6e26fb7a85a1e6a229b972c1bae0edc1c11cb9ca51e4caf5e59fbea35a1000000006b483045022100a63a4788027b79b65c6f9d9e054f68cf3b4eed19efd82a2d53f70dcbe64683390220526f243671425b2bd05745fcf2729361f985cfe84ea80c7cfc817b93d8134374012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52ffffffffae2a2320a1582faa24469eff3024a6b98bfe00eb4f554d8a0b1421ba53bfd6a5010000006c493046022100b200ac6db16842f76dab9abe807ce423c992805879bc50abd46ed8275a59d9cf022100c0d518e85dd345b3c29dd4dc47b9a420d3ce817b18720e94966d2fe23413a408012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffb3cc5a12548aa1794b4d2bbf076838cfd7fbafb7716da51ee8221a4ff19c291b000000006b483045022100ededc441c3103a6f2bd6cab7639421af0f6ec5e60503bce1e603cf34f00aee1c02205cb75f3f519a13fb348783b21db3085cb5ec7552c59e394fdbc3e1feea43f967012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52ffffffff85145367313888d2cf2747274a32e20b2df074027bafd6f970003fcbcdf11d07150000006b483045022100d9eed5413d2a4b4b98625aa6e3169edc4fb4663e7862316d69224454e70cd8ca022061e506521d5ced51dd0ea36496e75904d756a4c4f9fb111568555075d5f68d9a012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff8292c11f6d35abab5bac3ebb627a4ff949e8ecd62d33ed137adf7aeb00e512b0090000006b48304502207e84b27139c4c19c828cb1e30c349bba88e4d9b59be97286960793b5ddc0a2af0221008cdc7a951e7f31c20953ed5635fbabf228e80b7047f32faaa0313e7693005177012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff883dcf9a86063db088ad064d0953258d4b0ff3425857402d2f3f839cee0f84581e0000006a4730440220426540dfed9c4ab5812e5f06df705b8bcf307dd7d20f7fa6512298b2a6314f420220064055096e3ca62f6c7352c66a5447767c53f946acdf35025ab3807ddb2fa404012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff6697dbb3ed98afe481b568459fa67e503f8a4254532465a670e54669d19c9fe6720000006a47304402200a5e673996f2fc88e21cc8613611f08a650bc0370338803591d85d0ec5663764022040b6664a0d1ec83a7f01975b8fde5232992b8ca58bf48af6725d2f92a936ab2e012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff023ffc2182517e1d3fa0896c5b0bd7b4d2ef8a1e42655abe2ced54f657125d59670000006c493046022100d93b30219c5735f673be5c3b4688366d96f545561c74cb62c6958c00f6960806022100ec8200adcb028f2184fa2a4f6faac7f8bb57cb4503bb7584ac11051fece31b3d012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff16f8c77166b0df3d7cc8b5b2ce825afbea9309ad7acd8e2461a255958f81fc06010000006b483045022100a13934e68d3f5b22b130c4cb33f4da468cffc52323a47fbfbe06b64858162246022047081e0a70ff770e64a2e2d31e5d520d9102268b57a47009a72fe73ec766901801210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cdffffffff197b96f3c87a3adfaa17f63fddc2a738a690ca665439f9431dbbd655816c41fb000000006c49304602210097f1f35d5bdc1a3a60390a1b015b8e7c4f916aa3847aafd969e04975e15bbe70022100a9052eb25517d481f1fda1b129eb1b534da50ea1a51f3ee012dca3601c11b86a0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34ffffffff20d9a261ee27aa1bd92e7db2fdca935909a40b648e974cd24a10d63b68b94039dd0000006b483045022012b3138c591bf7154b6fef457f2c4a3c7162225003788ac0024a99355865ff13022100b71b125ae1ffb2e1d1571f580cd3ebc8cd049a2d7a8a41f138ba94aeb982106f012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff50f179d5d16cd872f9a63c26c448464ae9bd95cd9421c0476113b5d314571b71010000006b483045022100f834ccc8b22ee72712a3e5e6ef4acb8b2fb791b5385b70e2cd4332674d6667f4022024fbda0a997e0c253503f217501f508a4d56edce2c813ecdd9ad796dbeba907401210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cdffffffff551b865d1568ac0a305e5f9c5dae6c540982334efbe789074318e0efc5b564631b0000006b48304502203b2fd1e39ae0e469d7a15768f262661b0de41470daf0fe8c4fd0c26542a0870002210081c57e331f9a2d214457d953e3542904727ee412c63028113635d7224da3dccc012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff57503e5a016189d407a721791459280875264f908ca2c5d4862c01386e7fb50b470400006b48304502206947a9c54f0664ece4430fd4ae999891dc50bb6126bc36b6a15a3189f29d25e9022100a86cfc4e2fdd9e39a20e305cfd1b76509c67b3e313e0f118229105caa0e823c9012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff3f16c1fb9d3e1a26d872933e955df85ee7f3f817711062b00b54a2144827349b250000006b483045022100c7128fe10b2d38744ae8177776054c29fc8ec13f07207723e70766ab7164847402201d2cf09009b9596de74c0183d1ab832e5edddb7a9965880bb400097e850850f8012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff4142a69d85b8498af214f0dd427b6ab29c240a0b8577e2944d37a7d8c05c6bb8140000006b48304502203b89a71628a28cc3703d170ca3be77786cff6b867e38a18b719705f8a326578f022100b2a9879e1acf621faa6466c207746a7f3eb4c8514c1482969aba3f2a957f1321012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff36e2feecc0a4bff7480015d42c12121932db389025ed0ac1d344ecee53230a3df20000006c493046022100ef794a8ef7fd6752d2a183c18866ff6e8dc0f5bd889a63e2c21cf303a6302461022100c1b09662d9e92988c3f9fcf17d1bcc79b5403647095d7212b9f8a1278a532d68012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff0160f73608000000001976a9148fd139bb39ced713f231c58a4d07bf6954d1c20188ac00000000
diff --git a/src/test/data/tt-locktime317000-out.hex b/src/test/data/tt-locktime317000-out.hex
new file mode 100644
index 0000000000..287f420a40
--- /dev/null
+++ b/src/test/data/tt-locktime317000-out.hex
@@ -0,0 +1 @@
+0100000015fd5c23522d31761c50175453daa6edaabe47a602a592d39ce933d8271a1a87274c0100006c493046022100b4251ecd63778a3dde0155abe4cd162947620ae9ee45a874353551092325b116022100db307baf4ff3781ec520bd18f387948cedd15dc27bafe17c894b0fe6ffffcafa012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffcb4ed1baba3a1eb2171e00ddec8e5b72b346dd8c07f9c2b0d122d0d06bc92ea7000000006c493046022100a9b617843b68c284715d3e02fd120479cd0d96a6c43bf01e697fb0a460a21a3a022100ba0a12fbe8b993d4e7911fa3467615765dbe421ddf5c51b57a9c1ee19dcc00ba012103e633b4fa4ceb705c2da712390767199be8ef2448b3095dc01652e11b2b751505ffffffffc1b37ae964f605978022f94ce2f3f676d66a46d1aef7c2c17d6315b9697f2f75010000006a473044022079bd62ee09621a3be96b760c39e8ef78170101d46313923c6b07ae60a95c90670220238e51ea29fc70b04b65508450523caedbb11cb4dd5aa608c81487de798925ba0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34ffffffffedd005dc7790ef65c206abd1ab718e75252a40f4b1310e4102cd692eca9cacb0d10000006b48304502207722d6f9038673c86a1019b1c4de2d687ae246477cd4ca7002762be0299de385022100e594a11e3a313942595f7666dcf7078bcb14f1330f4206b95c917e7ec0e82fac012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffdf28d6e26fb7a85a1e6a229b972c1bae0edc1c11cb9ca51e4caf5e59fbea35a1000000006b483045022100a63a4788027b79b65c6f9d9e054f68cf3b4eed19efd82a2d53f70dcbe64683390220526f243671425b2bd05745fcf2729361f985cfe84ea80c7cfc817b93d8134374012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52ffffffffae2a2320a1582faa24469eff3024a6b98bfe00eb4f554d8a0b1421ba53bfd6a5010000006c493046022100b200ac6db16842f76dab9abe807ce423c992805879bc50abd46ed8275a59d9cf022100c0d518e85dd345b3c29dd4dc47b9a420d3ce817b18720e94966d2fe23413a408012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffb3cc5a12548aa1794b4d2bbf076838cfd7fbafb7716da51ee8221a4ff19c291b000000006b483045022100ededc441c3103a6f2bd6cab7639421af0f6ec5e60503bce1e603cf34f00aee1c02205cb75f3f519a13fb348783b21db3085cb5ec7552c59e394fdbc3e1feea43f967012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52ffffffff85145367313888d2cf2747274a32e20b2df074027bafd6f970003fcbcdf11d07150000006b483045022100d9eed5413d2a4b4b98625aa6e3169edc4fb4663e7862316d69224454e70cd8ca022061e506521d5ced51dd0ea36496e75904d756a4c4f9fb111568555075d5f68d9a012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff8292c11f6d35abab5bac3ebb627a4ff949e8ecd62d33ed137adf7aeb00e512b0090000006b48304502207e84b27139c4c19c828cb1e30c349bba88e4d9b59be97286960793b5ddc0a2af0221008cdc7a951e7f31c20953ed5635fbabf228e80b7047f32faaa0313e7693005177012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff883dcf9a86063db088ad064d0953258d4b0ff3425857402d2f3f839cee0f84581e0000006a4730440220426540dfed9c4ab5812e5f06df705b8bcf307dd7d20f7fa6512298b2a6314f420220064055096e3ca62f6c7352c66a5447767c53f946acdf35025ab3807ddb2fa404012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff6697dbb3ed98afe481b568459fa67e503f8a4254532465a670e54669d19c9fe6720000006a47304402200a5e673996f2fc88e21cc8613611f08a650bc0370338803591d85d0ec5663764022040b6664a0d1ec83a7f01975b8fde5232992b8ca58bf48af6725d2f92a936ab2e012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff023ffc2182517e1d3fa0896c5b0bd7b4d2ef8a1e42655abe2ced54f657125d59670000006c493046022100d93b30219c5735f673be5c3b4688366d96f545561c74cb62c6958c00f6960806022100ec8200adcb028f2184fa2a4f6faac7f8bb57cb4503bb7584ac11051fece31b3d012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff16f8c77166b0df3d7cc8b5b2ce825afbea9309ad7acd8e2461a255958f81fc06010000006b483045022100a13934e68d3f5b22b130c4cb33f4da468cffc52323a47fbfbe06b64858162246022047081e0a70ff770e64a2e2d31e5d520d9102268b57a47009a72fe73ec766901801210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cdffffffff197b96f3c87a3adfaa17f63fddc2a738a690ca665439f9431dbbd655816c41fb000000006c49304602210097f1f35d5bdc1a3a60390a1b015b8e7c4f916aa3847aafd969e04975e15bbe70022100a9052eb25517d481f1fda1b129eb1b534da50ea1a51f3ee012dca3601c11b86a0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34ffffffff20d9a261ee27aa1bd92e7db2fdca935909a40b648e974cd24a10d63b68b94039dd0000006b483045022012b3138c591bf7154b6fef457f2c4a3c7162225003788ac0024a99355865ff13022100b71b125ae1ffb2e1d1571f580cd3ebc8cd049a2d7a8a41f138ba94aeb982106f012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff50f179d5d16cd872f9a63c26c448464ae9bd95cd9421c0476113b5d314571b71010000006b483045022100f834ccc8b22ee72712a3e5e6ef4acb8b2fb791b5385b70e2cd4332674d6667f4022024fbda0a997e0c253503f217501f508a4d56edce2c813ecdd9ad796dbeba907401210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cdffffffff551b865d1568ac0a305e5f9c5dae6c540982334efbe789074318e0efc5b564631b0000006b48304502203b2fd1e39ae0e469d7a15768f262661b0de41470daf0fe8c4fd0c26542a0870002210081c57e331f9a2d214457d953e3542904727ee412c63028113635d7224da3dccc012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff57503e5a016189d407a721791459280875264f908ca2c5d4862c01386e7fb50b470400006b48304502206947a9c54f0664ece4430fd4ae999891dc50bb6126bc36b6a15a3189f29d25e9022100a86cfc4e2fdd9e39a20e305cfd1b76509c67b3e313e0f118229105caa0e823c9012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff3f16c1fb9d3e1a26d872933e955df85ee7f3f817711062b00b54a2144827349b250000006b483045022100c7128fe10b2d38744ae8177776054c29fc8ec13f07207723e70766ab7164847402201d2cf09009b9596de74c0183d1ab832e5edddb7a9965880bb400097e850850f8012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff4142a69d85b8498af214f0dd427b6ab29c240a0b8577e2944d37a7d8c05c6bb8140000006b48304502203b89a71628a28cc3703d170ca3be77786cff6b867e38a18b719705f8a326578f022100b2a9879e1acf621faa6466c207746a7f3eb4c8514c1482969aba3f2a957f1321012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff36e2feecc0a4bff7480015d42c12121932db389025ed0ac1d344ecee53230a3df20000006c493046022100ef794a8ef7fd6752d2a183c18866ff6e8dc0f5bd889a63e2c21cf303a6302461022100c1b09662d9e92988c3f9fcf17d1bcc79b5403647095d7212b9f8a1278a532d68012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff0260f73608000000001976a9148fd139bb39ced713f231c58a4d07bf6954d1c20188ac41420f00000000001976a9146c772e9cf96371bba3da8cb733da70a2fcf2007888ac48d60400
diff --git a/src/test/data/tx394b54bb.hex b/src/test/data/tx394b54bb.hex
new file mode 100644
index 0000000000..33f26cb4d6
--- /dev/null
+++ b/src/test/data/tx394b54bb.hex
@@ -0,0 +1 @@
+0100000015fd5c23522d31761c50175453daa6edaabe47a602a592d39ce933d8271a1a87274c0100006c493046022100b4251ecd63778a3dde0155abe4cd162947620ae9ee45a874353551092325b116022100db307baf4ff3781ec520bd18f387948cedd15dc27bafe17c894b0fe6ffffcafa012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffcb4ed1baba3a1eb2171e00ddec8e5b72b346dd8c07f9c2b0d122d0d06bc92ea7000000006c493046022100a9b617843b68c284715d3e02fd120479cd0d96a6c43bf01e697fb0a460a21a3a022100ba0a12fbe8b993d4e7911fa3467615765dbe421ddf5c51b57a9c1ee19dcc00ba012103e633b4fa4ceb705c2da712390767199be8ef2448b3095dc01652e11b2b751505ffffffffc1b37ae964f605978022f94ce2f3f676d66a46d1aef7c2c17d6315b9697f2f75010000006a473044022079bd62ee09621a3be96b760c39e8ef78170101d46313923c6b07ae60a95c90670220238e51ea29fc70b04b65508450523caedbb11cb4dd5aa608c81487de798925ba0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34ffffffffedd005dc7790ef65c206abd1ab718e75252a40f4b1310e4102cd692eca9cacb0d10000006b48304502207722d6f9038673c86a1019b1c4de2d687ae246477cd4ca7002762be0299de385022100e594a11e3a313942595f7666dcf7078bcb14f1330f4206b95c917e7ec0e82fac012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffdf28d6e26fb7a85a1e6a229b972c1bae0edc1c11cb9ca51e4caf5e59fbea35a1000000006b483045022100a63a4788027b79b65c6f9d9e054f68cf3b4eed19efd82a2d53f70dcbe64683390220526f243671425b2bd05745fcf2729361f985cfe84ea80c7cfc817b93d8134374012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52ffffffffae2a2320a1582faa24469eff3024a6b98bfe00eb4f554d8a0b1421ba53bfd6a5010000006c493046022100b200ac6db16842f76dab9abe807ce423c992805879bc50abd46ed8275a59d9cf022100c0d518e85dd345b3c29dd4dc47b9a420d3ce817b18720e94966d2fe23413a408012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffb3cc5a12548aa1794b4d2bbf076838cfd7fbafb7716da51ee8221a4ff19c291b000000006b483045022100ededc441c3103a6f2bd6cab7639421af0f6ec5e60503bce1e603cf34f00aee1c02205cb75f3f519a13fb348783b21db3085cb5ec7552c59e394fdbc3e1feea43f967012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52ffffffff85145367313888d2cf2747274a32e20b2df074027bafd6f970003fcbcdf11d07150000006b483045022100d9eed5413d2a4b4b98625aa6e3169edc4fb4663e7862316d69224454e70cd8ca022061e506521d5ced51dd0ea36496e75904d756a4c4f9fb111568555075d5f68d9a012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff8292c11f6d35abab5bac3ebb627a4ff949e8ecd62d33ed137adf7aeb00e512b0090000006b48304502207e84b27139c4c19c828cb1e30c349bba88e4d9b59be97286960793b5ddc0a2af0221008cdc7a951e7f31c20953ed5635fbabf228e80b7047f32faaa0313e7693005177012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff883dcf9a86063db088ad064d0953258d4b0ff3425857402d2f3f839cee0f84581e0000006a4730440220426540dfed9c4ab5812e5f06df705b8bcf307dd7d20f7fa6512298b2a6314f420220064055096e3ca62f6c7352c66a5447767c53f946acdf35025ab3807ddb2fa404012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff6697dbb3ed98afe481b568459fa67e503f8a4254532465a670e54669d19c9fe6720000006a47304402200a5e673996f2fc88e21cc8613611f08a650bc0370338803591d85d0ec5663764022040b6664a0d1ec83a7f01975b8fde5232992b8ca58bf48af6725d2f92a936ab2e012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff023ffc2182517e1d3fa0896c5b0bd7b4d2ef8a1e42655abe2ced54f657125d59670000006c493046022100d93b30219c5735f673be5c3b4688366d96f545561c74cb62c6958c00f6960806022100ec8200adcb028f2184fa2a4f6faac7f8bb57cb4503bb7584ac11051fece31b3d012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff16f8c77166b0df3d7cc8b5b2ce825afbea9309ad7acd8e2461a255958f81fc06010000006b483045022100a13934e68d3f5b22b130c4cb33f4da468cffc52323a47fbfbe06b64858162246022047081e0a70ff770e64a2e2d31e5d520d9102268b57a47009a72fe73ec766901801210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cdffffffff197b96f3c87a3adfaa17f63fddc2a738a690ca665439f9431dbbd655816c41fb000000006c49304602210097f1f35d5bdc1a3a60390a1b015b8e7c4f916aa3847aafd969e04975e15bbe70022100a9052eb25517d481f1fda1b129eb1b534da50ea1a51f3ee012dca3601c11b86a0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34ffffffff20d9a261ee27aa1bd92e7db2fdca935909a40b648e974cd24a10d63b68b94039dd0000006b483045022012b3138c591bf7154b6fef457f2c4a3c7162225003788ac0024a99355865ff13022100b71b125ae1ffb2e1d1571f580cd3ebc8cd049a2d7a8a41f138ba94aeb982106f012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff50f179d5d16cd872f9a63c26c448464ae9bd95cd9421c0476113b5d314571b71010000006b483045022100f834ccc8b22ee72712a3e5e6ef4acb8b2fb791b5385b70e2cd4332674d6667f4022024fbda0a997e0c253503f217501f508a4d56edce2c813ecdd9ad796dbeba907401210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cdffffffff551b865d1568ac0a305e5f9c5dae6c540982334efbe789074318e0efc5b564631b0000006b48304502203b2fd1e39ae0e469d7a15768f262661b0de41470daf0fe8c4fd0c26542a0870002210081c57e331f9a2d214457d953e3542904727ee412c63028113635d7224da3dccc012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff57503e5a016189d407a721791459280875264f908ca2c5d4862c01386e7fb50b470400006b48304502206947a9c54f0664ece4430fd4ae999891dc50bb6126bc36b6a15a3189f29d25e9022100a86cfc4e2fdd9e39a20e305cfd1b76509c67b3e313e0f118229105caa0e823c9012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff3f16c1fb9d3e1a26d872933e955df85ee7f3f817711062b00b54a2144827349b250000006b483045022100c7128fe10b2d38744ae8177776054c29fc8ec13f07207723e70766ab7164847402201d2cf09009b9596de74c0183d1ab832e5edddb7a9965880bb400097e850850f8012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff4142a69d85b8498af214f0dd427b6ab29c240a0b8577e2944d37a7d8c05c6bb8140000006b48304502203b89a71628a28cc3703d170ca3be77786cff6b867e38a18b719705f8a326578f022100b2a9879e1acf621faa6466c207746a7f3eb4c8514c1482969aba3f2a957f1321012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff36e2feecc0a4bff7480015d42c12121932db389025ed0ac1d344ecee53230a3df20000006c493046022100ef794a8ef7fd6752d2a183c18866ff6e8dc0f5bd889a63e2c21cf303a6302461022100c1b09662d9e92988c3f9fcf17d1bcc79b5403647095d7212b9f8a1278a532d68012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff0260f73608000000001976a9148fd139bb39ced713f231c58a4d07bf6954d1c20188ac41420f00000000001976a9146c772e9cf96371bba3da8cb733da70a2fcf2007888ac00000000
diff --git a/src/test/data/tx_invalid.json b/src/test/data/tx_invalid.json
new file mode 100644
index 0000000000..20bdbd08a5
--- /dev/null
+++ b/src/test/data/tx_invalid.json
@@ -0,0 +1,197 @@
+[
+["The following are deserialized transactions which are invalid."],
+["They are in the form"],
+["[[[prevout hash, prevout index, prevout scriptPubKey], [input 2], ...],"],
+["serializedTransaction, verifyFlags]"],
+["Objects that are only a single string (like this one) are ignored"],
+
+["0e1b5688cf179cd9f7cbda1fac0090f6e684bbf8cd946660120197c3f3681809 but with extra junk appended to the end of the scriptPubKey"],
+[[["6ca7ec7b1847f6bdbd737176050e6a08d66ccd55bb94ad24f4018024107a5827", 0, "0x41 0x043b640e983c9690a14c039a2037ecc3467b27a0dcd58f19d76c7bc118d09fec45adc5370a1c5bf8067ca9f5557a4cf885fdb0fe0dcc9c3a7137226106fbc779a5 CHECKSIG VERIFY 1"]],
+"010000000127587a10248001f424ad94bb55cd6cd6086a0e05767173bdbdf647187beca76c000000004948304502201b822ad10d6adc1a341ae8835be3f70a25201bbff31f59cbb9c5353a5f0eca18022100ea7b2f7074e9aa9cf70aa8d0ffee13e6b45dddabf1ab961bda378bcdb778fa4701ffffffff0100f2052a010000001976a914fc50c5907d86fed474ba5ce8b12a66e0a4c139d888ac00000000", "P2SH"],
+
+["This is the nearly-standard transaction with CHECKSIGVERIFY 1 instead of CHECKSIG from tx_valid.json"],
+["but with the signature duplicated in the scriptPubKey with a non-standard pushdata prefix"],
+["See FindAndDelete, which will only remove if it uses the same pushdata prefix as is standard"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "DUP HASH160 0x14 0x5b6462475454710f3c22f5fdf0b40704c92f25c3 EQUALVERIFY CHECKSIGVERIFY 1 0x4c 0x47 0x3044022067288ea50aa799543a536ff9306f8e1cba05b9c6b10951175b924f96732555ed022026d7b5265f38d21541519e4a1e55044d5b9e17e15cdbaf29ae3792e99e883e7a01"]],
+"01000000010001000000000000000000000000000000000000000000000000000000000000000000006a473044022067288ea50aa799543a536ff9306f8e1cba05b9c6b10951175b924f96732555ed022026d7b5265f38d21541519e4a1e55044d5b9e17e15cdbaf29ae3792e99e883e7a012103ba8c8b86dea131c22ab967e6dd99bdae8eff7a1f75a2c35f1f944109e3fe5e22ffffffff010000000000000000015100000000", "P2SH"],
+
+["Same as above, but with the sig in the scriptSig also pushed with the same non-standard OP_PUSHDATA"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "DUP HASH160 0x14 0x5b6462475454710f3c22f5fdf0b40704c92f25c3 EQUALVERIFY CHECKSIGVERIFY 1 0x4c 0x47 0x3044022067288ea50aa799543a536ff9306f8e1cba05b9c6b10951175b924f96732555ed022026d7b5265f38d21541519e4a1e55044d5b9e17e15cdbaf29ae3792e99e883e7a01"]],
+"01000000010001000000000000000000000000000000000000000000000000000000000000000000006b4c473044022067288ea50aa799543a536ff9306f8e1cba05b9c6b10951175b924f96732555ed022026d7b5265f38d21541519e4a1e55044d5b9e17e15cdbaf29ae3792e99e883e7a012103ba8c8b86dea131c22ab967e6dd99bdae8eff7a1f75a2c35f1f944109e3fe5e22ffffffff010000000000000000015100000000", "P2SH"],
+
+["This is the nearly-standard transaction with CHECKSIGVERIFY 1 instead of CHECKSIG from tx_valid.json"],
+["but with the signature duplicated in the scriptPubKey with a different hashtype suffix"],
+["See FindAndDelete, which will only remove if the signature, including the hash type, matches"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "DUP HASH160 0x14 0x5b6462475454710f3c22f5fdf0b40704c92f25c3 EQUALVERIFY CHECKSIGVERIFY 1 0x47 0x3044022067288ea50aa799543a536ff9306f8e1cba05b9c6b10951175b924f96732555ed022026d7b5265f38d21541519e4a1e55044d5b9e17e15cdbaf29ae3792e99e883e7a81"]],
+"01000000010001000000000000000000000000000000000000000000000000000000000000000000006a473044022067288ea50aa799543a536ff9306f8e1cba05b9c6b10951175b924f96732555ed022026d7b5265f38d21541519e4a1e55044d5b9e17e15cdbaf29ae3792e99e883e7a012103ba8c8b86dea131c22ab967e6dd99bdae8eff7a1f75a2c35f1f944109e3fe5e22ffffffff010000000000000000015100000000", "P2SH"],
+
+["An invalid P2SH Transaction"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x7a052c840ba73af26755de42cf01cc9e0a49fef0 EQUAL"]],
+"010000000100010000000000000000000000000000000000000000000000000000000000000000000009085768617420697320ffffffff010000000000000000015100000000", "P2SH"],
+
+["Tests for CheckTransaction()"],
+["No inputs"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x7a052c840ba73af26755de42cf01cc9e0a49fef0 EQUAL"]],
+"0100000000010000000000000000015100000000", "P2SH"],
+
+["No outputs"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x05ab9e14d983742513f0f451e105ffb4198d1dd4 EQUAL"]],
+"01000000010001000000000000000000000000000000000000000000000000000000000000000000006d483045022100f16703104aab4e4088317c862daec83440242411b039d14280e03dd33b487ab802201318a7be236672c5c56083eb7a5a195bc57a40af7923ff8545016cd3b571e2a601232103c40e5d339df3f30bf753e7e04450ae4ef76c9e45587d1d993bdc4cd06f0651c7acffffffff0000000000", "P2SH"],
+
+["Negative output"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0xae609aca8061d77c5e111f6bb62501a6bbe2bfdb EQUAL"]],
+"01000000010001000000000000000000000000000000000000000000000000000000000000000000006d4830450220063222cbb128731fc09de0d7323746539166544d6c1df84d867ccea84bcc8903022100bf568e8552844de664cd41648a031554327aa8844af34b4f27397c65b92c04de0123210243ec37dee0e2e053a9c976f43147e79bc7d9dc606ea51010af1ac80db6b069e1acffffffff01ffffffffffffffff015100000000", "P2SH"],
+
+["MAX_MONEY + 1 output"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x32afac281462b822adbec5094b8d4d337dd5bd6a EQUAL"]],
+"01000000010001000000000000000000000000000000000000000000000000000000000000000000006e493046022100e1eadba00d9296c743cb6ecc703fd9ddc9b3cd12906176a226ae4c18d6b00796022100a71aef7d2874deff681ba6080f1b278bac7bb99c61b08a85f4311970ffe7f63f012321030c0588dc44d92bdcbf8e72093466766fdc265ead8db64517b0c542275b70fffbacffffffff010140075af0750700015100000000", "P2SH"],
+
+["MAX_MONEY output + 1 output"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0xb558cbf4930954aa6a344363a15668d7477ae716 EQUAL"]],
+"01000000010001000000000000000000000000000000000000000000000000000000000000000000006d483045022027deccc14aa6668e78a8c9da3484fbcd4f9dcc9bb7d1b85146314b21b9ae4d86022100d0b43dece8cfb07348de0ca8bc5b86276fa88f7f2138381128b7c36ab2e42264012321029bb13463ddd5d2cc05da6e84e37536cb9525703cfd8f43afdb414988987a92f6acffffffff020040075af075070001510001000000000000015100000000", "P2SH"],
+
+["Duplicate inputs"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x236d0639db62b0773fd8ac34dc85ae19e9aba80a EQUAL"]],
+"01000000020001000000000000000000000000000000000000000000000000000000000000000000006c47304402204bb1197053d0d7799bf1b30cd503c44b58d6240cccbdc85b6fe76d087980208f02204beeed78200178ffc6c74237bb74b3f276bbb4098b5605d814304fe128bf1431012321039e8815e15952a7c3fada1905f8cf55419837133bd7756c0ef14fc8dfe50c0deaacffffffff0001000000000000000000000000000000000000000000000000000000000000000000006c47304402202306489afef52a6f62e90bf750bbcdf40c06f5c6b138286e6b6b86176bb9341802200dba98486ea68380f47ebb19a7df173b99e6bc9c681d6ccf3bde31465d1f16b3012321039e8815e15952a7c3fada1905f8cf55419837133bd7756c0ef14fc8dfe50c0deaacffffffff010000000000000000015100000000", "P2SH"],
+
+["Coinbase of size 1"],
+["Note the input is just required to make the tester happy"],
+[[["0000000000000000000000000000000000000000000000000000000000000000", -1, "1"]],
+"01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0151ffffffff010000000000000000015100000000", "P2SH"],
+
+["Coinbase of size 101"],
+["Note the input is just required to make the tester happy"],
+[[["0000000000000000000000000000000000000000000000000000000000000000", -1, "1"]],
+"01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff655151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151ffffffff010000000000000000015100000000", "P2SH"],
+
+["Null txin"],
+[[["0000000000000000000000000000000000000000000000000000000000000000", -1, "HASH160 0x14 0x02dae7dbbda56097959cba59b1989dd3e47937bf EQUAL"]],
+"01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff6e49304602210086f39e028e46dafa8e1e3be63906465f4cf038fbe5ed6403dc3e74ae876e6431022100c4625c675cfc5c7e3a0e0d7eaec92ac24da20c73a88eb40d09253e51ac6def5201232103a183ddc41e84753aca47723c965d1b5c8b0e2b537963518355e6dd6cf8415e50acffffffff010000000000000000015100000000", "P2SH"],
+
+["Same as the transactions in valid with one input SIGHASH_ALL and one SIGHASH_ANYONECANPAY, but we set the _ANYONECANPAY sequence number, invalidating the SIGHASH_ALL signature"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x21 0x035e7f0d4d0841bcd56c39337ed086b1a633ee770c1ffdd94ac552a95ac2ce0efc CHECKSIG"],
+ ["0000000000000000000000000000000000000000000000000000000000000200", 0, "0x21 0x035e7f0d4d0841bcd56c39337ed086b1a633ee770c1ffdd94ac552a95ac2ce0efc CHECKSIG"]],
+ "01000000020001000000000000000000000000000000000000000000000000000000000000000000004948304502203a0f5f0e1f2bdbcd04db3061d18f3af70e07f4f467cbc1b8116f267025f5360b022100c792b6e215afc5afc721a351ec413e714305cb749aae3d7fee76621313418df10101000000000200000000000000000000000000000000000000000000000000000000000000000000484730440220201dc2d030e380e8f9cfb41b442d930fa5a685bb2c8db5906671f865507d0670022018d9e7a8d4c8d86a73c2a724ee38ef983ec249827e0e464841735955c707ece98101000000010100000000000000015100000000", "P2SH"],
+
+["CHECKMULTISIG with incorrect signature order"],
+["Note the input is just required to make the tester happy"],
+[[["b3da01dd4aae683c7aee4d5d8b52a540a508e1115f77cd7fa9a291243f501223", 0, "HASH160 0x14 0xb1ce99298d5f07364b57b1e5c9cc00be0b04a954 EQUAL"]],
+"01000000012312503f2491a2a97fcd775f11e108a540a5528b5d4dee7a3c68ae4add01dab300000000fdfe000048304502207aacee820e08b0b174e248abd8d7a34ed63b5da3abedb99934df9fddd65c05c4022100dfe87896ab5ee3df476c2655f9fbe5bd089dccbef3e4ea05b5d121169fe7f5f401483045022100f6649b0eddfdfd4ad55426663385090d51ee86c3481bdc6b0c18ea6c0ece2c0b0220561c315b07cffa6f7dd9df96dbae9200c2dee09bf93cc35ca05e6cdf613340aa014c695221031d11db38972b712a9fe1fc023577c7ae3ddb4a3004187d41c45121eecfdbb5b7210207ec36911b6ad2382860d32989c7b8728e9489d7bbc94a6b5509ef0029be128821024ea9fac06f666a4adc3fc1357b7bec1fd0bdece2b9d08579226a8ebde53058e453aeffffffff0180380100000000001976a914c9b99cddf847d10685a4fabaa0baf505f7c3dfab88ac00000000", "P2SH"],
+
+
+["The following is a tweaked form of 23b397edccd3740a74adb603c9756370fafcde9bcc4483eb271ecad09a94dd63"],
+["It is an OP_CHECKMULTISIG with the dummy value missing"],
+[[["60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1", 0, "1 0x41 0x04cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaff7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4 0x41 0x0461cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d76519aecc62770f5b0e4ef8551946d8a540911abe3e7854a26f39f58b25c15342af 2 OP_CHECKMULTISIG"]],
+"0100000001b14bdcbc3e01bdaad36cc08e81e69c82e1060bc14e518db2b49aa43ad90ba260000000004847304402203f16c6f40162ab686621ef3000b04e75418a0c0cb2d8aebeac894ae360ac1e780220ddc15ecdfc3507ac48e1681a33eb60996631bf6bf5bc0a0682c4db743ce7ca2b01ffffffff0140420f00000000001976a914660d4ef3a743e3e696ad990364e555c271ad504b88ac00000000", "P2SH"],
+
+
+["CHECKMULTISIG SCRIPT_VERIFY_NULLDUMMY tests:"],
+
+["The following is a tweaked form of 23b397edccd3740a74adb603c9756370fafcde9bcc4483eb271ecad09a94dd63"],
+["It is an OP_CHECKMULTISIG with the dummy value set to something other than an empty string"],
+[[["60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1", 0, "1 0x41 0x04cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaff7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4 0x41 0x0461cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d76519aecc62770f5b0e4ef8551946d8a540911abe3e7854a26f39f58b25c15342af 2 OP_CHECKMULTISIG"]],
+"0100000001b14bdcbc3e01bdaad36cc08e81e69c82e1060bc14e518db2b49aa43ad90ba260000000004a010047304402203f16c6f40162ab686621ef3000b04e75418a0c0cb2d8aebeac894ae360ac1e780220ddc15ecdfc3507ac48e1681a33eb60996631bf6bf5bc0a0682c4db743ce7ca2b01ffffffff0140420f00000000001976a914660d4ef3a743e3e696ad990364e555c271ad504b88ac00000000", "P2SH,NULLDUMMY"],
+
+["As above, but using a OP_1"],
+[[["60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1", 0, "1 0x41 0x04cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaff7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4 0x41 0x0461cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d76519aecc62770f5b0e4ef8551946d8a540911abe3e7854a26f39f58b25c15342af 2 OP_CHECKMULTISIG"]],
+"0100000001b14bdcbc3e01bdaad36cc08e81e69c82e1060bc14e518db2b49aa43ad90ba26000000000495147304402203f16c6f40162ab686621ef3000b04e75418a0c0cb2d8aebeac894ae360ac1e780220ddc15ecdfc3507ac48e1681a33eb60996631bf6bf5bc0a0682c4db743ce7ca2b01ffffffff0140420f00000000001976a914660d4ef3a743e3e696ad990364e555c271ad504b88ac00000000", "P2SH,NULLDUMMY"],
+
+["As above, but using a OP_1NEGATE"],
+[[["60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1", 0, "1 0x41 0x04cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaff7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4 0x41 0x0461cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d76519aecc62770f5b0e4ef8551946d8a540911abe3e7854a26f39f58b25c15342af 2 OP_CHECKMULTISIG"]],
+"0100000001b14bdcbc3e01bdaad36cc08e81e69c82e1060bc14e518db2b49aa43ad90ba26000000000494f47304402203f16c6f40162ab686621ef3000b04e75418a0c0cb2d8aebeac894ae360ac1e780220ddc15ecdfc3507ac48e1681a33eb60996631bf6bf5bc0a0682c4db743ce7ca2b01ffffffff0140420f00000000001976a914660d4ef3a743e3e696ad990364e555c271ad504b88ac00000000", "P2SH,NULLDUMMY"],
+
+["As above, but with the dummy byte missing"],
+[[["60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1", 0, "1 0x41 0x04cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaff7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4 0x41 0x0461cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d76519aecc62770f5b0e4ef8551946d8a540911abe3e7854a26f39f58b25c15342af 2 OP_CHECKMULTISIG"]],
+"0100000001b14bdcbc3e01bdaad36cc08e81e69c82e1060bc14e518db2b49aa43ad90ba260000000004847304402203f16c6f40162ab686621ef3000b04e75418a0c0cb2d8aebeac894ae360ac1e780220ddc15ecdfc3507ac48e1681a33eb60996631bf6bf5bc0a0682c4db743ce7ca2b01ffffffff0140420f00000000001976a914660d4ef3a743e3e696ad990364e555c271ad504b88ac00000000", "P2SH,NULLDUMMY"],
+
+
+["Empty stack when we try to run CHECKSIG"],
+[[["ad503f72c18df5801ee64d76090afe4c607fb2b822e9b7b63c5826c50e22fc3b", 0, "0x21 0x027c3a97665bf283a102a587a62a30a0c102d4d3b141015e2cae6f64e2543113e5 CHECKSIG NOT"]],
+"01000000013bfc220ec526583cb6b7e922b8b27f604cfe0a09764de61e80f58dc1723f50ad0000000000ffffffff0101000000000000002321027c3a97665bf283a102a587a62a30a0c102d4d3b141015e2cae6f64e2543113e5ac00000000", "P2SH"],
+
+
+["Inverted versions of tx_valid CODESEPARATOR IF block tests"],
+
+["CODESEPARATOR in an unexecuted IF block does not change what is hashed"],
+[[["a955032f4d6b0c9bfe8cad8f00a8933790b9c1dc28c82e0f48e75b35da0e4944", 0, "IF CODESEPARATOR ENDIF 0x21 0x0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71 CHECKSIGVERIFY CODESEPARATOR 1"]],
+"010000000144490eda355be7480f2ec828dcc1b9903793a8008fad8cfe9b0c6b4d2f0355a9000000004a48304502207a6974a77c591fa13dff60cabbb85a0de9e025c09c65a4b2285e47ce8e22f761022100f0efaac9ff8ac36b10721e0aae1fb975c90500b50c56e8a0cc52b0403f0425dd0151ffffffff010000000000000000016a00000000", "P2SH"],
+
+["As above, with the IF block executed"],
+[[["a955032f4d6b0c9bfe8cad8f00a8933790b9c1dc28c82e0f48e75b35da0e4944", 0, "IF CODESEPARATOR ENDIF 0x21 0x0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71 CHECKSIGVERIFY CODESEPARATOR 1"]],
+"010000000144490eda355be7480f2ec828dcc1b9903793a8008fad8cfe9b0c6b4d2f0355a9000000004a483045022100fa4a74ba9fd59c59f46c3960cf90cbe0d2b743c471d24a3d5d6db6002af5eebb02204d70ec490fd0f7055a7c45f86514336e3a7f03503dacecabb247fc23f15c83510100ffffffff010000000000000000016a00000000", "P2SH"],
+
+["CHECKLOCKTIMEVERIFY tests"],
+
+["By-height locks, with argument just beyond tx nLockTime"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1 NOP2 1"]],
+"010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 NOP2 1"]],
+"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000fe64cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
+
+["By-time locks, with argument just beyond tx nLockTime (but within numerical boundries)"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000001 NOP2 1"]],
+"01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 NOP2 1"]],
+"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000feffffff", "P2SH,CHECKLOCKTIMEVERIFY"],
+
+["Argument missing"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "NOP2 1"]],
+"010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1"]],
+"010000000100010000000000000000000000000000000000000000000000000000000000000000000001b1010000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
+
+["Argument negative with by-blockheight nLockTime=0"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "-1 NOP2 1"]],
+"010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
+
+["Argument negative with by-blocktime nLockTime=500,000,000"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "-1 NOP2 1"]],
+"01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1"]],
+"010000000100010000000000000000000000000000000000000000000000000000000000000000000004005194b1010000000100000000000000000002000000", "P2SH,CHECKLOCKTIMEVERIFY"],
+
+["Input locked"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"]],
+"010000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff0100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0"]],
+"01000000010001000000000000000000000000000000000000000000000000000000000000000000000251b1ffffffff0100000000000000000002000000", "P2SH,CHECKLOCKTIMEVERIFY"],
+
+["Another input being unlocked isn't sufficient; the CHECKLOCKTIMEVERIFY-using input must be unlocked"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"] ,
+ ["0000000000000000000000000000000000000000000000000000000000000200", 1, "1"]],
+"010000000200010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00020000000000000000000000000000000000000000000000000000000000000100000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
+
+["Argument/tx height/time mismatch, both versions"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"]],
+"01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0"]],
+"01000000010001000000000000000000000000000000000000000000000000000000000000000000000251b100000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 NOP2 1"]],
+"01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 NOP2 1"]],
+"010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 NOP2 1"]],
+"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ff64cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
+
+["Argument 2^32 with nLockTime=2^32-1"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967296 NOP2 1"]],
+"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ffffffff", "P2SH,CHECKLOCKTIMEVERIFY"],
+
+["Same, but with nLockTime=2^31-1"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483648 NOP2 1"]],
+"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ffffff7f", "P2SH,CHECKLOCKTIMEVERIFY"],
+
+["6 byte non-minimally-encoded arguments are invalid even in their contents are valid"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x06 0x000000000000 NOP2 1"]],
+"010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
+
+["Failure due to failing CHECKLOCKTIMEVERIFY in scriptSig"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1"]],
+"01000000010001000000000000000000000000000000000000000000000000000000000000000000000251b1000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
+
+["Failure due to failing CHECKLOCKTIMEVERIFY in redeemScript"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0xc5b93064159b3b2d6ab506a41b1f50463771b988 EQUAL"]],
+"0100000001000100000000000000000000000000000000000000000000000000000000000000000000030251b1000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
+
+["Make diffs cleaner by leaving a comment here without comma at the end"]
+]
diff --git a/src/test/data/tx_valid.json b/src/test/data/tx_valid.json
new file mode 100644
index 0000000000..24fff575c1
--- /dev/null
+++ b/src/test/data/tx_valid.json
@@ -0,0 +1,233 @@
+[
+["The following are deserialized transactions which are valid."],
+["They are in the form"],
+["[[[prevout hash, prevout index, prevout scriptPubKey], [input 2], ...],"],
+["serializedTransaction, verifyFlags]"],
+["Objects that are only a single string (like this one) are ignored"],
+
+["The following is 23b397edccd3740a74adb603c9756370fafcde9bcc4483eb271ecad09a94dd63"],
+["It is of particular interest because it contains an invalidly-encoded signature which OpenSSL accepts"],
+["See http://r6.ca/blog/20111119T211504Z.html"],
+["It is also the first OP_CHECKMULTISIG transaction in standard form"],
+[[["60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1", 0, "1 0x41 0x04cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaff7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4 0x41 0x0461cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d76519aecc62770f5b0e4ef8551946d8a540911abe3e7854a26f39f58b25c15342af 2 OP_CHECKMULTISIG"]],
+"0100000001b14bdcbc3e01bdaad36cc08e81e69c82e1060bc14e518db2b49aa43ad90ba26000000000490047304402203f16c6f40162ab686621ef3000b04e75418a0c0cb2d8aebeac894ae360ac1e780220ddc15ecdfc3507ac48e1681a33eb60996631bf6bf5bc0a0682c4db743ce7ca2b01ffffffff0140420f00000000001976a914660d4ef3a743e3e696ad990364e555c271ad504b88ac00000000", "P2SH"],
+
+["The following is a tweaked form of 23b397edccd3740a74adb603c9756370fafcde9bcc4483eb271ecad09a94dd63"],
+["It is an OP_CHECKMULTISIG with an arbitrary extra byte stuffed into the signature at pos length - 2"],
+["The dummy byte is fine however, so the NULLDUMMY flag should be happy"],
+[[["60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1", 0, "1 0x41 0x04cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaff7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4 0x41 0x0461cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d76519aecc62770f5b0e4ef8551946d8a540911abe3e7854a26f39f58b25c15342af 2 OP_CHECKMULTISIG"]],
+"0100000001b14bdcbc3e01bdaad36cc08e81e69c82e1060bc14e518db2b49aa43ad90ba260000000004a0048304402203f16c6f40162ab686621ef3000b04e75418a0c0cb2d8aebeac894ae360ac1e780220ddc15ecdfc3507ac48e1681a33eb60996631bf6bf5bc0a0682c4db743ce7ca2bab01ffffffff0140420f00000000001976a914660d4ef3a743e3e696ad990364e555c271ad504b88ac00000000", "P2SH,NULLDUMMY"],
+
+["The following is a tweaked form of 23b397edccd3740a74adb603c9756370fafcde9bcc4483eb271ecad09a94dd63"],
+["It is an OP_CHECKMULTISIG with the dummy value set to something other than an empty string"],
+[[["60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1", 0, "1 0x41 0x04cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaff7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4 0x41 0x0461cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d76519aecc62770f5b0e4ef8551946d8a540911abe3e7854a26f39f58b25c15342af 2 OP_CHECKMULTISIG"]],
+"0100000001b14bdcbc3e01bdaad36cc08e81e69c82e1060bc14e518db2b49aa43ad90ba260000000004a01ff47304402203f16c6f40162ab686621ef3000b04e75418a0c0cb2d8aebeac894ae360ac1e780220ddc15ecdfc3507ac48e1681a33eb60996631bf6bf5bc0a0682c4db743ce7ca2b01ffffffff0140420f00000000001976a914660d4ef3a743e3e696ad990364e555c271ad504b88ac00000000", "P2SH"],
+
+["As above, but using a OP_1"],
+[[["60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1", 0, "1 0x41 0x04cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaff7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4 0x41 0x0461cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d76519aecc62770f5b0e4ef8551946d8a540911abe3e7854a26f39f58b25c15342af 2 OP_CHECKMULTISIG"]],
+"0100000001b14bdcbc3e01bdaad36cc08e81e69c82e1060bc14e518db2b49aa43ad90ba26000000000495147304402203f16c6f40162ab686621ef3000b04e75418a0c0cb2d8aebeac894ae360ac1e780220ddc15ecdfc3507ac48e1681a33eb60996631bf6bf5bc0a0682c4db743ce7ca2b01ffffffff0140420f00000000001976a914660d4ef3a743e3e696ad990364e555c271ad504b88ac00000000", "P2SH"],
+
+["As above, but using a OP_1NEGATE"],
+[[["60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1", 0, "1 0x41 0x04cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaff7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4 0x41 0x0461cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d76519aecc62770f5b0e4ef8551946d8a540911abe3e7854a26f39f58b25c15342af 2 OP_CHECKMULTISIG"]],
+"0100000001b14bdcbc3e01bdaad36cc08e81e69c82e1060bc14e518db2b49aa43ad90ba26000000000494f47304402203f16c6f40162ab686621ef3000b04e75418a0c0cb2d8aebeac894ae360ac1e780220ddc15ecdfc3507ac48e1681a33eb60996631bf6bf5bc0a0682c4db743ce7ca2b01ffffffff0140420f00000000001976a914660d4ef3a743e3e696ad990364e555c271ad504b88ac00000000", "P2SH"],
+
+["The following is c99c49da4c38af669dea436d3e73780dfdb6c1ecf9958baa52960e8baee30e73"],
+["It is of interest because it contains a 0-sequence as well as a signature of SIGHASH type 0 (which is not a real type)"],
+[[["406b2b06bcd34d3c8733e6b79f7a394c8a431fbf4ff5ac705c93f4076bb77602", 0, "DUP HASH160 0x14 0xdc44b1164188067c3a32d4780f5996fa14a4f2d9 EQUALVERIFY CHECKSIG"]],
+"01000000010276b76b07f4935c70acf54fbf1f438a4c397a9fb7e633873c4dd3bc062b6b40000000008c493046022100d23459d03ed7e9511a47d13292d3430a04627de6235b6e51a40f9cd386f2abe3022100e7d25b080f0bb8d8d5f878bba7d54ad2fda650ea8d158a33ee3cbd11768191fd004104b0e2c879e4daf7b9ab68350228c159766676a14f5815084ba166432aab46198d4cca98fa3e9981d0a90b2effc514b76279476550ba3663fdcaff94c38420e9d5000000000100093d00000000001976a9149a7b0f3b80c6baaeedce0a0842553800f832ba1f88ac00000000", "P2SH"],
+
+["A nearly-standard transaction with CHECKSIGVERIFY 1 instead of CHECKSIG"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "DUP HASH160 0x14 0x5b6462475454710f3c22f5fdf0b40704c92f25c3 EQUALVERIFY CHECKSIGVERIFY 1"]],
+"01000000010001000000000000000000000000000000000000000000000000000000000000000000006a473044022067288ea50aa799543a536ff9306f8e1cba05b9c6b10951175b924f96732555ed022026d7b5265f38d21541519e4a1e55044d5b9e17e15cdbaf29ae3792e99e883e7a012103ba8c8b86dea131c22ab967e6dd99bdae8eff7a1f75a2c35f1f944109e3fe5e22ffffffff010000000000000000015100000000", "P2SH"],
+
+["Same as above, but with the signature duplicated in the scriptPubKey with the proper pushdata prefix"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "DUP HASH160 0x14 0x5b6462475454710f3c22f5fdf0b40704c92f25c3 EQUALVERIFY CHECKSIGVERIFY 1 0x47 0x3044022067288ea50aa799543a536ff9306f8e1cba05b9c6b10951175b924f96732555ed022026d7b5265f38d21541519e4a1e55044d5b9e17e15cdbaf29ae3792e99e883e7a01"]],
+"01000000010001000000000000000000000000000000000000000000000000000000000000000000006a473044022067288ea50aa799543a536ff9306f8e1cba05b9c6b10951175b924f96732555ed022026d7b5265f38d21541519e4a1e55044d5b9e17e15cdbaf29ae3792e99e883e7a012103ba8c8b86dea131c22ab967e6dd99bdae8eff7a1f75a2c35f1f944109e3fe5e22ffffffff010000000000000000015100000000", "P2SH"],
+
+["The following is f7fdd091fa6d8f5e7a8c2458f5c38faffff2d3f1406b6e4fe2c99dcc0d2d1cbb"],
+["It caught a bug in the workaround for 23b397edccd3740a74adb603c9756370fafcde9bcc4483eb271ecad09a94dd63 in an overly simple implementation"],
+[[["b464e85df2a238416f8bdae11d120add610380ea07f4ef19c5f9dfd472f96c3d", 0, "DUP HASH160 0x14 0xbef80ecf3a44500fda1bc92176e442891662aed2 EQUALVERIFY CHECKSIG"],
+["b7978cc96e59a8b13e0865d3f95657561a7f725be952438637475920bac9eb21", 1, "DUP HASH160 0x14 0xbef80ecf3a44500fda1bc92176e442891662aed2 EQUALVERIFY CHECKSIG"]],
+"01000000023d6cf972d4dff9c519eff407ea800361dd0a121de1da8b6f4138a2f25de864b4000000008a4730440220ffda47bfc776bcd269da4832626ac332adfca6dd835e8ecd83cd1ebe7d709b0e022049cffa1cdc102a0b56e0e04913606c70af702a1149dc3b305ab9439288fee090014104266abb36d66eb4218a6dd31f09bb92cf3cfa803c7ea72c1fc80a50f919273e613f895b855fb7465ccbc8919ad1bd4a306c783f22cd3227327694c4fa4c1c439affffffff21ebc9ba20594737864352e95b727f1a565756f9d365083eb1a8596ec98c97b7010000008a4730440220503ff10e9f1e0de731407a4a245531c9ff17676eda461f8ceeb8c06049fa2c810220c008ac34694510298fa60b3f000df01caa244f165b727d4896eb84f81e46bcc4014104266abb36d66eb4218a6dd31f09bb92cf3cfa803c7ea72c1fc80a50f919273e613f895b855fb7465ccbc8919ad1bd4a306c783f22cd3227327694c4fa4c1c439affffffff01f0da5200000000001976a914857ccd42dded6df32949d4646dfa10a92458cfaa88ac00000000", "P2SH"],
+
+["The following tests for the presence of a bug in the handling of SIGHASH_SINGLE"],
+["It results in signing the constant 1, instead of something generated based on the transaction,"],
+["when the input doing the signing has an index greater than the maximum output index"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "DUP HASH160 0x14 0xe52b482f2faa8ecbf0db344f93c84ac908557f33 EQUALVERIFY CHECKSIG"], ["0000000000000000000000000000000000000000000000000000000000000200", 0, "1"]],
+"01000000020002000000000000000000000000000000000000000000000000000000000000000000000151ffffffff0001000000000000000000000000000000000000000000000000000000000000000000006b483045022100c9cdd08798a28af9d1baf44a6c77bcc7e279f47dc487c8c899911bc48feaffcc0220503c5c50ae3998a733263c5c0f7061b483e2b56c4c41b456e7d2f5a78a74c077032102d5c25adb51b61339d2b05315791e21bbe80ea470a49db0135720983c905aace0ffffffff010000000000000000015100000000", "P2SH"],
+
+["An invalid P2SH Transaction"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x7a052c840ba73af26755de42cf01cc9e0a49fef0 EQUAL"]],
+"010000000100010000000000000000000000000000000000000000000000000000000000000000000009085768617420697320ffffffff010000000000000000015100000000", "NONE"],
+
+["A valid P2SH Transaction using the standard transaction type put forth in BIP 16"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x8febbed40483661de6958d957412f82deed8e2f7 EQUAL"]],
+"01000000010001000000000000000000000000000000000000000000000000000000000000000000006e493046022100c66c9cdf4c43609586d15424c54707156e316d88b0a1534c9e6b0d4f311406310221009c0fe51dbc9c4ab7cc25d3fdbeccf6679fe6827f08edf2b4a9f16ee3eb0e438a0123210338e8034509af564c62644c07691942e0c056752008a173c89f60ab2a88ac2ebfacffffffff010000000000000000015100000000", "P2SH"],
+
+["Tests for CheckTransaction()"],
+["MAX_MONEY output"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x32afac281462b822adbec5094b8d4d337dd5bd6a EQUAL"]],
+"01000000010001000000000000000000000000000000000000000000000000000000000000000000006e493046022100e1eadba00d9296c743cb6ecc703fd9ddc9b3cd12906176a226ae4c18d6b00796022100a71aef7d2874deff681ba6080f1b278bac7bb99c61b08a85f4311970ffe7f63f012321030c0588dc44d92bdcbf8e72093466766fdc265ead8db64517b0c542275b70fffbacffffffff010040075af0750700015100000000", "P2SH"],
+
+["MAX_MONEY output + 0 output"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0xb558cbf4930954aa6a344363a15668d7477ae716 EQUAL"]],
+"01000000010001000000000000000000000000000000000000000000000000000000000000000000006d483045022027deccc14aa6668e78a8c9da3484fbcd4f9dcc9bb7d1b85146314b21b9ae4d86022100d0b43dece8cfb07348de0ca8bc5b86276fa88f7f2138381128b7c36ab2e42264012321029bb13463ddd5d2cc05da6e84e37536cb9525703cfd8f43afdb414988987a92f6acffffffff020040075af075070001510000000000000000015100000000", "P2SH"],
+
+["Coinbase of size 2"],
+["Note the input is just required to make the tester happy"],
+[[["0000000000000000000000000000000000000000000000000000000000000000", -1, "1"]],
+"01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff025151ffffffff010000000000000000015100000000", "P2SH"],
+
+["Coinbase of size 100"],
+["Note the input is just required to make the tester happy"],
+[[["0000000000000000000000000000000000000000000000000000000000000000", -1, "1"]],
+"01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff6451515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151ffffffff010000000000000000015100000000", "P2SH"],
+
+["Simple transaction with first input is signed with SIGHASH_ALL, second with SIGHASH_ANYONECANPAY"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x21 0x035e7f0d4d0841bcd56c39337ed086b1a633ee770c1ffdd94ac552a95ac2ce0efc CHECKSIG"],
+ ["0000000000000000000000000000000000000000000000000000000000000200", 0, "0x21 0x035e7f0d4d0841bcd56c39337ed086b1a633ee770c1ffdd94ac552a95ac2ce0efc CHECKSIG"]],
+ "010000000200010000000000000000000000000000000000000000000000000000000000000000000049483045022100d180fd2eb9140aeb4210c9204d3f358766eb53842b2a9473db687fa24b12a3cc022079781799cd4f038b85135bbe49ec2b57f306b2bb17101b17f71f000fcab2b6fb01ffffffff0002000000000000000000000000000000000000000000000000000000000000000000004847304402205f7530653eea9b38699e476320ab135b74771e1c48b81a5d041e2ca84b9be7a802200ac8d1f40fb026674fe5a5edd3dea715c27baa9baca51ed45ea750ac9dc0a55e81ffffffff010100000000000000015100000000", "P2SH"],
+
+["Same as above, but we change the sequence number of the first input to check that SIGHASH_ANYONECANPAY is being followed"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x21 0x035e7f0d4d0841bcd56c39337ed086b1a633ee770c1ffdd94ac552a95ac2ce0efc CHECKSIG"],
+ ["0000000000000000000000000000000000000000000000000000000000000200", 0, "0x21 0x035e7f0d4d0841bcd56c39337ed086b1a633ee770c1ffdd94ac552a95ac2ce0efc CHECKSIG"]],
+ "01000000020001000000000000000000000000000000000000000000000000000000000000000000004948304502203a0f5f0e1f2bdbcd04db3061d18f3af70e07f4f467cbc1b8116f267025f5360b022100c792b6e215afc5afc721a351ec413e714305cb749aae3d7fee76621313418df101010000000002000000000000000000000000000000000000000000000000000000000000000000004847304402205f7530653eea9b38699e476320ab135b74771e1c48b81a5d041e2ca84b9be7a802200ac8d1f40fb026674fe5a5edd3dea715c27baa9baca51ed45ea750ac9dc0a55e81ffffffff010100000000000000015100000000", "P2SH"],
+
+["afd9c17f8913577ec3509520bd6e5d63e9c0fd2a5f70c787993b097ba6ca9fae which has several SIGHASH_SINGLE signatures"],
+[[["63cfa5a09dc540bf63e53713b82d9ea3692ca97cd608c384f2aa88e51a0aac70", 0, "DUP HASH160 0x14 0xdcf72c4fd02f5a987cf9b02f2fabfcac3341a87d EQUALVERIFY CHECKSIG"],
+ ["04e8d0fcf3846c6734477b98f0f3d4badfb78f020ee097a0be5fe347645b817d", 1, "DUP HASH160 0x14 0xdcf72c4fd02f5a987cf9b02f2fabfcac3341a87d EQUALVERIFY CHECKSIG"],
+ ["ee1377aff5d0579909e11782e1d2f5f7b84d26537be7f5516dd4e43373091f3f", 1, "DUP HASH160 0x14 0xdcf72c4fd02f5a987cf9b02f2fabfcac3341a87d EQUALVERIFY CHECKSIG"]],
+ "010000000370ac0a1ae588aaf284c308d67ca92c69a39e2db81337e563bf40c59da0a5cf63000000006a4730440220360d20baff382059040ba9be98947fd678fb08aab2bb0c172efa996fd8ece9b702201b4fb0de67f015c90e7ac8a193aeab486a1f587e0f54d0fb9552ef7f5ce6caec032103579ca2e6d107522f012cd00b52b9a65fb46f0c57b9b8b6e377c48f526a44741affffffff7d815b6447e35fbea097e00e028fb7dfbad4f3f0987b4734676c84f3fcd0e804010000006b483045022100c714310be1e3a9ff1c5f7cacc65c2d8e781fc3a88ceb063c6153bf950650802102200b2d0979c76e12bb480da635f192cc8dc6f905380dd4ac1ff35a4f68f462fffd032103579ca2e6d107522f012cd00b52b9a65fb46f0c57b9b8b6e377c48f526a44741affffffff3f1f097333e4d46d51f5e77b53264db8f7f5d2e18217e1099957d0f5af7713ee010000006c493046022100b663499ef73273a3788dea342717c2640ac43c5a1cf862c9e09b206fcb3f6bb8022100b09972e75972d9148f2bdd462e5cb69b57c1214b88fc55ca638676c07cfc10d8032103579ca2e6d107522f012cd00b52b9a65fb46f0c57b9b8b6e377c48f526a44741affffffff0380841e00000000001976a914bfb282c70c4191f45b5a6665cad1682f2c9cfdfb88ac80841e00000000001976a9149857cc07bed33a5cf12b9c5e0500b675d500c81188ace0fd1c00000000001976a91443c52850606c872403c0601e69fa34b26f62db4a88ac00000000", "P2SH"],
+
+ ["ddc454a1c0c35c188c98976b17670f69e586d9c0f3593ea879928332f0a069e7, which spends an input that pushes using a PUSHDATA1 that is negative when read as signed"],
+ [[["c5510a5dd97a25f43175af1fe649b707b1df8e1a41489bac33a23087027a2f48", 0, "0x4c 0xae 0x606563686f2022553246736447566b58312b5a536e587574356542793066794778625456415675534a6c376a6a334878416945325364667657734f53474f36633338584d7439435c6e543249584967306a486956304f376e775236644546673d3d22203e20743b206f70656e73736c20656e63202d7061737320706173733a5b314a564d7751432d707269766b65792d6865785d202d64202d6165732d3235362d636263202d61202d696e207460 DROP DUP HASH160 0x14 0xbfd7436b6265aa9de506f8a994f881ff08cc2872 EQUALVERIFY CHECKSIG"]],
+ "0100000001482f7a028730a233ac9b48411a8edfb107b749e61faf7531f4257ad95d0a51c5000000008b483045022100bf0bbae9bde51ad2b222e87fbf67530fbafc25c903519a1e5dcc52a32ff5844e022028c4d9ad49b006dd59974372a54291d5764be541574bb0c4dc208ec51f80b7190141049dd4aad62741dc27d5f267f7b70682eee22e7e9c1923b9c0957bdae0b96374569b460eb8d5b40d972e8c7c0ad441de3d94c4a29864b212d56050acb980b72b2bffffffff0180969800000000001976a914e336d0017a9d28de99d16472f6ca6d5a3a8ebc9988ac00000000", "P2SH"],
+
+["Correct signature order"],
+["Note the input is just required to make the tester happy"],
+[[["b3da01dd4aae683c7aee4d5d8b52a540a508e1115f77cd7fa9a291243f501223", 0, "HASH160 0x14 0xb1ce99298d5f07364b57b1e5c9cc00be0b04a954 EQUAL"]],
+"01000000012312503f2491a2a97fcd775f11e108a540a5528b5d4dee7a3c68ae4add01dab300000000fdfe0000483045022100f6649b0eddfdfd4ad55426663385090d51ee86c3481bdc6b0c18ea6c0ece2c0b0220561c315b07cffa6f7dd9df96dbae9200c2dee09bf93cc35ca05e6cdf613340aa0148304502207aacee820e08b0b174e248abd8d7a34ed63b5da3abedb99934df9fddd65c05c4022100dfe87896ab5ee3df476c2655f9fbe5bd089dccbef3e4ea05b5d121169fe7f5f4014c695221031d11db38972b712a9fe1fc023577c7ae3ddb4a3004187d41c45121eecfdbb5b7210207ec36911b6ad2382860d32989c7b8728e9489d7bbc94a6b5509ef0029be128821024ea9fac06f666a4adc3fc1357b7bec1fd0bdece2b9d08579226a8ebde53058e453aeffffffff0180380100000000001976a914c9b99cddf847d10685a4fabaa0baf505f7c3dfab88ac00000000", "P2SH"],
+
+["cc60b1f899ec0a69b7c3f25ddf32c4524096a9c5b01cbd84c6d0312a0c478984, which is a fairly strange transaction which relies on OP_CHECKSIG returning 0 when checking a completely invalid sig of length 0"],
+[[["cbebc4da731e8995fe97f6fadcd731b36ad40e5ecb31e38e904f6e5982fa09f7", 0, "0x2102085c6600657566acc2d6382a47bc3f324008d2aa10940dd7705a48aa2a5a5e33ac7c2103f5d0fb955f95dd6be6115ce85661db412ec6a08abcbfce7da0ba8297c6cc0ec4ac7c5379a820d68df9e32a147cffa36193c6f7c43a1c8c69cda530e1c6db354bfabdcfefaf3c875379a820f531f3041d3136701ea09067c53e7159c8f9b2746a56c3d82966c54bbc553226879a5479827701200122a59a5379827701200122a59a6353798277537982778779679a68"]],
+"0100000001f709fa82596e4f908ee331cb5e0ed46ab331d7dcfaf697fe95891e73dac4ebcb000000008c20ca42095840735e89283fec298e62ac2ddea9b5f34a8cbb7097ad965b87568100201b1b01dc829177da4a14551d2fc96a9db00c6501edfa12f22cd9cefd335c227f483045022100a9df60536df5733dd0de6bc921fab0b3eee6426501b43a228afa2c90072eb5ca02201c78b74266fac7d1db5deff080d8a403743203f109fbcabf6d5a760bf87386d20100ffffffff01c075790000000000232103611f9a45c18f28f06f19076ad571c344c82ce8fcfe34464cf8085217a2d294a6ac00000000", "P2SH"],
+
+["Empty pubkey"],
+[[["229257c295e7f555421c1bfec8538dd30a4b5c37c1c8810bbe83cafa7811652c", 0, "0x00 CHECKSIG NOT"]],
+"01000000012c651178faca83be0b81c8c1375c4b0ad38d53c8fe1b1c4255f5e795c25792220000000049483045022100d6044562284ac76c985018fc4a90127847708c9edb280996c507b28babdc4b2a02203d74eca3f1a4d1eea7ff77b528fde6d5dc324ec2dbfdb964ba885f643b9704cd01ffffffff010100000000000000232102c2410f8891ae918cab4ffc4bb4a3b0881be67c7a1e7faa8b5acf9ab8932ec30cac00000000", "P2SH"],
+
+["Empty signature"],
+[[["9ca93cfd8e3806b9d9e2ba1cf64e3cc6946ee0119670b1796a09928d14ea25f7", 0, "0x21 0x028a1d66975dbdf97897e3a4aef450ebeb5b5293e4a0b4a6d3a2daaa0b2b110e02 CHECKSIG NOT"]],
+"0100000001f725ea148d92096a79b1709611e06e94c63c4ef61cbae2d9b906388efd3ca99c000000000100ffffffff0101000000000000002321028a1d66975dbdf97897e3a4aef450ebeb5b5293e4a0b4a6d3a2daaa0b2b110e02ac00000000", "P2SH"],
+
+[[["444e00ed7840d41f20ecd9c11d3f91982326c731a02f3c05748414a4fa9e59be", 0, "1 0x00 0x21 0x02136b04758b0b6e363e7a6fbe83aaf527a153db2b060d36cc29f7f8309ba6e458 2 CHECKMULTISIG"]],
+"0100000001be599efaa4148474053c2fa031c7262398913f1dc1d9ec201fd44078ed004e44000000004900473044022022b29706cb2ed9ef0cb3c97b72677ca2dfd7b4160f7b4beb3ba806aa856c401502202d1e52582412eba2ed474f1f437a427640306fd3838725fab173ade7fe4eae4a01ffffffff010100000000000000232103ac4bba7e7ca3e873eea49e08132ad30c7f03640b6539e9b59903cf14fd016bbbac00000000", "P2SH"],
+
+[[["e16abbe80bf30c080f63830c8dbf669deaef08957446e95940227d8c5e6db612", 0, "1 0x21 0x03905380c7013e36e6e19d305311c1b81fce6581f5ee1c86ef0627c68c9362fc9f 0x00 2 CHECKMULTISIG"]],
+"010000000112b66d5e8c7d224059e946749508efea9d66bf8d0c83630f080cf30be8bb6ae100000000490047304402206ffe3f14caf38ad5c1544428e99da76ffa5455675ec8d9780fac215ca17953520220779502985e194d84baa36b9bd40a0dbd981163fa191eb884ae83fc5bd1c86b1101ffffffff010100000000000000232103905380c7013e36e6e19d305311c1b81fce6581f5ee1c86ef0627c68c9362fc9fac00000000", "P2SH"],
+
+[[["ebbcf4bfce13292bd791d6a65a2a858d59adbf737e387e40370d4e64cc70efb0", 0, "2 0x21 0x033bcaa0a602f0d44cc9d5637c6e515b0471db514c020883830b7cefd73af04194 0x21 0x03a88b326f8767f4f192ce252afe33c94d25ab1d24f27f159b3cb3aa691ffe1423 2 CHECKMULTISIG NOT"]],
+"0100000001b0ef70cc644e0d37407e387e73bfad598d852a5aa6d691d72b2913cebff4bceb000000004a00473044022068cd4851fc7f9a892ab910df7a24e616f293bcb5c5fbdfbc304a194b26b60fba022078e6da13d8cb881a22939b952c24f88b97afd06b4c47a47d7f804c9a352a6d6d0100ffffffff0101000000000000002321033bcaa0a602f0d44cc9d5637c6e515b0471db514c020883830b7cefd73af04194ac00000000", "P2SH"],
+
+[[["ba4cd7ae2ad4d4d13ebfc8ab1d93a63e4a6563f25089a18bf0fc68f282aa88c1", 0, "2 0x21 0x037c615d761e71d38903609bf4f46847266edc2fb37532047d747ba47eaae5ffe1 0x21 0x02edc823cd634f2c4033d94f5755207cb6b60c4b1f1f056ad7471c47de5f2e4d50 2 CHECKMULTISIG NOT"]],
+"0100000001c188aa82f268fcf08ba18950f263654a3ea6931dabc8bf3ed1d4d42aaed74cba000000004b0000483045022100940378576e069aca261a6b26fb38344e4497ca6751bb10905c76bb689f4222b002204833806b014c26fd801727b792b1260003c55710f87c5adbd7a9cb57446dbc9801ffffffff0101000000000000002321037c615d761e71d38903609bf4f46847266edc2fb37532047d747ba47eaae5ffe1ac00000000", "P2SH"],
+
+
+["OP_CODESEPARATOR tests"],
+
+["Test that SignatureHash() removes OP_CODESEPARATOR with FindAndDelete()"],
+[[["bc7fd132fcf817918334822ee6d9bd95c889099c96e07ca2c1eb2cc70db63224", 0, "CODESEPARATOR 0x21 0x038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f22041 CHECKSIG"]],
+"01000000012432b60dc72cebc1a27ce0969c0989c895bdd9e62e8234839117f8fc32d17fbc000000004a493046022100a576b52051962c25e642c0fd3d77ee6c92487048e5d90818bcf5b51abaccd7900221008204f8fb121be4ec3b24483b1f92d89b1b0548513a134e345c5442e86e8617a501ffffffff010000000000000000016a00000000", "P2SH"],
+[[["83e194f90b6ef21fa2e3a365b63794fb5daa844bdc9b25de30899fcfe7b01047", 0, "CODESEPARATOR CODESEPARATOR 0x21 0x038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f22041 CHECKSIG"]],
+"01000000014710b0e7cf9f8930de259bdc4b84aa5dfb9437b665a3e3a21ff26e0bf994e183000000004a493046022100a166121a61b4eeb19d8f922b978ff6ab58ead8a5a5552bf9be73dc9c156873ea02210092ad9bc43ee647da4f6652c320800debcf08ec20a094a0aaf085f63ecb37a17201ffffffff010000000000000000016a00000000", "P2SH"],
+
+["Hashed data starts at the CODESEPARATOR"],
+[[["326882a7f22b5191f1a0cc9962ca4b878cd969cf3b3a70887aece4d801a0ba5e", 0, "0x21 0x038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f22041 CODESEPARATOR CHECKSIG"]],
+"01000000015ebaa001d8e4ec7a88703a3bcf69d98c874bca6299cca0f191512bf2a7826832000000004948304502203bf754d1c6732fbf87c5dcd81258aefd30f2060d7bd8ac4a5696f7927091dad1022100f5bcb726c4cf5ed0ed34cc13dadeedf628ae1045b7cb34421bc60b89f4cecae701ffffffff010000000000000000016a00000000", "P2SH"],
+
+["But only if execution has reached it"],
+[[["a955032f4d6b0c9bfe8cad8f00a8933790b9c1dc28c82e0f48e75b35da0e4944", 0, "0x21 0x038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f22041 CHECKSIGVERIFY CODESEPARATOR 0x21 0x038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f22041 CHECKSIGVERIFY CODESEPARATOR 1"]],
+"010000000144490eda355be7480f2ec828dcc1b9903793a8008fad8cfe9b0c6b4d2f0355a900000000924830450221009c0a27f886a1d8cb87f6f595fbc3163d28f7a81ec3c4b252ee7f3ac77fd13ffa02203caa8dfa09713c8c4d7ef575c75ed97812072405d932bd11e6a1593a98b679370148304502201e3861ef39a526406bad1e20ecad06be7375ad40ddb582c9be42d26c3a0d7b240221009d0a3985e96522e59635d19cc4448547477396ce0ef17a58e7d74c3ef464292301ffffffff010000000000000000016a00000000", "P2SH"],
+
+["CODESEPARATOR in an unexecuted IF block does not change what is hashed"],
+[[["a955032f4d6b0c9bfe8cad8f00a8933790b9c1dc28c82e0f48e75b35da0e4944", 0, "IF CODESEPARATOR ENDIF 0x21 0x0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71 CHECKSIGVERIFY CODESEPARATOR 1"]],
+"010000000144490eda355be7480f2ec828dcc1b9903793a8008fad8cfe9b0c6b4d2f0355a9000000004a48304502207a6974a77c591fa13dff60cabbb85a0de9e025c09c65a4b2285e47ce8e22f761022100f0efaac9ff8ac36b10721e0aae1fb975c90500b50c56e8a0cc52b0403f0425dd0100ffffffff010000000000000000016a00000000", "P2SH"],
+
+["As above, with the IF block executed"],
+[[["a955032f4d6b0c9bfe8cad8f00a8933790b9c1dc28c82e0f48e75b35da0e4944", 0, "IF CODESEPARATOR ENDIF 0x21 0x0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71 CHECKSIGVERIFY CODESEPARATOR 1"]],
+"010000000144490eda355be7480f2ec828dcc1b9903793a8008fad8cfe9b0c6b4d2f0355a9000000004a483045022100fa4a74ba9fd59c59f46c3960cf90cbe0d2b743c471d24a3d5d6db6002af5eebb02204d70ec490fd0f7055a7c45f86514336e3a7f03503dacecabb247fc23f15c83510151ffffffff010000000000000000016a00000000", "P2SH"],
+
+
+["CHECKSIG is legal in scriptSigs"],
+[[["ccf7f4053a02e653c36ac75c891b7496d0dc5ce5214f6c913d9cf8f1329ebee0", 0, "DUP HASH160 0x14 0xee5a6aa40facefb2655ac23c0c28c57c65c41f9b EQUALVERIFY CHECKSIG"]],
+"0100000001e0be9e32f1f89c3d916c4f21e55cdcd096741b895cc76ac353e6023a05f4f7cc00000000d86149304602210086e5f736a2c3622ebb62bd9d93d8e5d76508b98be922b97160edc3dcca6d8c47022100b23c312ac232a4473f19d2aeb95ab7bdf2b65518911a0d72d50e38b5dd31dc820121038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f22041ac4730440220508fa761865c8abd81244a168392876ee1d94e8ed83897066b5e2df2400dad24022043f5ee7538e87e9c6aef7ef55133d3e51da7cc522830a9c4d736977a76ef755c0121038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f22041ffffffff010000000000000000016a00000000", "P2SH"],
+
+["Same semantics for OP_CODESEPARATOR"],
+[[["10c9f0effe83e97f80f067de2b11c6a00c3088a4bce42c5ae761519af9306f3c", 1, "DUP HASH160 0x14 0xee5a6aa40facefb2655ac23c0c28c57c65c41f9b EQUALVERIFY CHECKSIG"]],
+"01000000013c6f30f99a5161e75a2ce4bca488300ca0c6112bde67f0807fe983feeff0c91001000000e608646561646265656675ab61493046022100ce18d384221a731c993939015e3d1bcebafb16e8c0b5b5d14097ec8177ae6f28022100bcab227af90bab33c3fe0a9abfee03ba976ee25dc6ce542526e9b2e56e14b7f10121038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f22041ac493046022100c3b93edcc0fd6250eb32f2dd8a0bba1754b0f6c3be8ed4100ed582f3db73eba2022100bf75b5bd2eff4d6bf2bda2e34a40fcc07d4aa3cf862ceaa77b47b81eff829f9a01ab21038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f22041ffffffff010000000000000000016a00000000", "P2SH"],
+
+["Signatures are removed from the script they are in by FindAndDelete() in the CHECKSIG code; even multiple instances of one signature can be removed."],
+[[["6056ebd549003b10cbbd915cea0d82209fe40b8617104be917a26fa92cbe3d6f", 0, "DUP HASH160 0x14 0xee5a6aa40facefb2655ac23c0c28c57c65c41f9b EQUALVERIFY CHECKSIG"]],
+"01000000016f3dbe2ca96fa217e94b1017860be49f20820dea5c91bdcb103b0049d5eb566000000000fd1d0147304402203989ac8f9ad36b5d0919d97fa0a7f70c5272abee3b14477dc646288a8b976df5022027d19da84a066af9053ad3d1d7459d171b7e3a80bc6c4ef7a330677a6be548140147304402203989ac8f9ad36b5d0919d97fa0a7f70c5272abee3b14477dc646288a8b976df5022027d19da84a066af9053ad3d1d7459d171b7e3a80bc6c4ef7a330677a6be548140121038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f22041ac47304402203757e937ba807e4a5da8534c17f9d121176056406a6465054bdd260457515c1a02200f02eccf1bec0f3a0d65df37889143c2e88ab7acec61a7b6f5aa264139141a2b0121038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f22041ffffffff010000000000000000016a00000000", "P2SH"],
+
+["That also includes ahead of the opcode being executed."],
+[[["5a6b0021a6042a686b6b94abc36b387bef9109847774e8b1e51eb8cc55c53921", 1, "DUP HASH160 0x14 0xee5a6aa40facefb2655ac23c0c28c57c65c41f9b EQUALVERIFY CHECKSIG"]],
+"01000000012139c555ccb81ee5b1e87477840991ef7b386bc3ab946b6b682a04a621006b5a01000000fdb40148304502201723e692e5f409a7151db386291b63524c5eb2030df652b1f53022fd8207349f022100b90d9bbf2f3366ce176e5e780a00433da67d9e5c79312c6388312a296a5800390148304502201723e692e5f409a7151db386291b63524c5eb2030df652b1f53022fd8207349f022100b90d9bbf2f3366ce176e5e780a00433da67d9e5c79312c6388312a296a5800390121038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f2204148304502201723e692e5f409a7151db386291b63524c5eb2030df652b1f53022fd8207349f022100b90d9bbf2f3366ce176e5e780a00433da67d9e5c79312c6388312a296a5800390175ac4830450220646b72c35beeec51f4d5bc1cbae01863825750d7f490864af354e6ea4f625e9c022100f04b98432df3a9641719dbced53393022e7249fb59db993af1118539830aab870148304502201723e692e5f409a7151db386291b63524c5eb2030df652b1f53022fd8207349f022100b90d9bbf2f3366ce176e5e780a00433da67d9e5c79312c6388312a296a580039017521038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f22041ffffffff010000000000000000016a00000000", "P2SH"],
+
+["Finally CHECKMULTISIG removes all signatures prior to hashing the script containing those signatures. In conjunction with the SIGHASH_SINGLE bug this lets us test whether or not FindAndDelete() is actually present in scriptPubKey/redeemScript evaluation by including a signature of the digest 0x01 We can compute in advance for our pubkey, embed it it in the scriptPubKey, and then also using a normal SIGHASH_ALL signature. If FindAndDelete() wasn't run, the 'bugged' signature would still be in the hashed script, and the normal signature would fail."],
+
+["Here's an example on mainnet within a P2SH redeemScript. Remarkably it's a standard transaction in <0.9"],
+[[["b5b598de91787439afd5938116654e0b16b7a0d0f82742ba37564219c5afcbf9", 0, "DUP HASH160 0x14 0xf6f365c40f0739b61de827a44751e5e99032ed8f EQUALVERIFY CHECKSIG"],
+ ["ab9805c6d57d7070d9a42c5176e47bb705023e6b67249fb6760880548298e742", 0, "HASH160 0x14 0xd8dacdadb7462ae15cd906f1878706d0da8660e6 EQUAL"]],
+"0100000002f9cbafc519425637ba4227f8d0a0b7160b4e65168193d5af39747891de98b5b5000000006b4830450221008dd619c563e527c47d9bd53534a770b102e40faa87f61433580e04e271ef2f960220029886434e18122b53d5decd25f1f4acb2480659fea20aabd856987ba3c3907e0121022b78b756e2258af13779c1a1f37ea6800259716ca4b7f0b87610e0bf3ab52a01ffffffff42e7988254800876b69f24676b3e0205b77be476512ca4d970707dd5c60598ab00000000fd260100483045022015bd0139bcccf990a6af6ec5c1c52ed8222e03a0d51c334df139968525d2fcd20221009f9efe325476eb64c3958e4713e9eefe49bf1d820ed58d2112721b134e2a1a53034930460221008431bdfa72bc67f9d41fe72e94c88fb8f359ffa30b33c72c121c5a877d922e1002210089ef5fc22dd8bfc6bf9ffdb01a9862d27687d424d1fefbab9e9c7176844a187a014c9052483045022015bd0139bcccf990a6af6ec5c1c52ed8222e03a0d51c334df139968525d2fcd20221009f9efe325476eb64c3958e4713e9eefe49bf1d820ed58d2112721b134e2a1a5303210378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71210378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c7153aeffffffff01a08601000000000017a914d8dacdadb7462ae15cd906f1878706d0da8660e68700000000", "P2SH"],
+
+["Same idea, but with bare CHECKMULTISIG"],
+[[["ceafe58e0f6e7d67c0409fbbf673c84c166e3c5d3c24af58f7175b18df3bb3db", 0, "DUP HASH160 0x14 0xf6f365c40f0739b61de827a44751e5e99032ed8f EQUALVERIFY CHECKSIG"],
+ ["ceafe58e0f6e7d67c0409fbbf673c84c166e3c5d3c24af58f7175b18df3bb3db", 1, "2 0x48 0x3045022015bd0139bcccf990a6af6ec5c1c52ed8222e03a0d51c334df139968525d2fcd20221009f9efe325476eb64c3958e4713e9eefe49bf1d820ed58d2112721b134e2a1a5303 0x21 0x0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71 0x21 0x0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71 3 CHECKMULTISIG"]],
+"0100000002dbb33bdf185b17f758af243c5d3c6e164cc873f6bb9f40c0677d6e0f8ee5afce000000006b4830450221009627444320dc5ef8d7f68f35010b4c050a6ed0d96b67a84db99fda9c9de58b1e02203e4b4aaa019e012e65d69b487fdf8719df72f488fa91506a80c49a33929f1fd50121022b78b756e2258af13779c1a1f37ea6800259716ca4b7f0b87610e0bf3ab52a01ffffffffdbb33bdf185b17f758af243c5d3c6e164cc873f6bb9f40c0677d6e0f8ee5afce010000009300483045022015bd0139bcccf990a6af6ec5c1c52ed8222e03a0d51c334df139968525d2fcd20221009f9efe325476eb64c3958e4713e9eefe49bf1d820ed58d2112721b134e2a1a5303483045022015bd0139bcccf990a6af6ec5c1c52ed8222e03a0d51c334df139968525d2fcd20221009f9efe325476eb64c3958e4713e9eefe49bf1d820ed58d2112721b134e2a1a5303ffffffff01a0860100000000001976a9149bc0bbdd3024da4d0c38ed1aecf5c68dd1d3fa1288ac00000000", "P2SH"],
+
+
+["CHECKLOCKTIMEVERIFY tests"],
+
+["By-height locks, with argument == 0 and == tx nLockTime"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"]],
+"010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 NOP2 1"]],
+"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ff64cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"]],
+"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ff64cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
+
+["By-time locks, with argument just beyond tx nLockTime (but within numerical boundries)"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 NOP2 1"]],
+"01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 NOP2 1"]],
+"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ffffffff", "P2SH,CHECKLOCKTIMEVERIFY"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 NOP2 1"]],
+"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ffffffff", "P2SH,CHECKLOCKTIMEVERIFY"],
+
+["Any non-maxint nSequence is fine"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"]],
+"010000000100010000000000000000000000000000000000000000000000000000000000000000000000feffffff0100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
+
+["The argument can be calculated rather than created directly by a PUSHDATA"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 1ADD NOP2 1"]],
+"01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
+
+["Perhaps even by an ADD producing a 5-byte result that is out of bounds for other opcodes"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483647 2147483647 ADD NOP2 1"]],
+"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000feffffff", "P2SH,CHECKLOCKTIMEVERIFY"],
+
+["5 byte non-minimally-encoded arguments are valid"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x05 0x0000000000 NOP2 1"]],
+"010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
+
+["Valid CHECKLOCKTIMEVERIFY in scriptSig"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1"]],
+"01000000010001000000000000000000000000000000000000000000000000000000000000000000000251b1000000000100000000000000000001000000", "P2SH,CHECKLOCKTIMEVERIFY"],
+
+["Valid CHECKLOCKTIMEVERIFY in redeemScript"],
+[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0xc5b93064159b3b2d6ab506a41b1f50463771b988 EQUAL"]],
+"0100000001000100000000000000000000000000000000000000000000000000000000000000000000030251b1000000000100000000000000000001000000", "P2SH,CHECKLOCKTIMEVERIFY"],
+
+["Make diffs cleaner by leaving a comment here without comma at the end"]
+]
diff --git a/src/test/data/txcreate1.hex b/src/test/data/txcreate1.hex
new file mode 100644
index 0000000000..e2981a51c9
--- /dev/null
+++ b/src/test/data/txcreate1.hex
@@ -0,0 +1 @@
+01000000031f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000ffffffff7cca453133921c50d5025878f7f738d1df891fd359763331935784cf6b9c82bf1200000000fffffffffccd319e04a996c96cfc0bf4c07539aa90bd0b1a700ef72fae535d6504f9a6220100000000ffffffff0280a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac0084d717000000001976a914f2d4db28cad6502226ee484ae24505c2885cb12d88ac00000000
diff --git a/src/test/data/txcreate2.hex b/src/test/data/txcreate2.hex
new file mode 100644
index 0000000000..5243c2d02e
--- /dev/null
+++ b/src/test/data/txcreate2.hex
@@ -0,0 +1 @@
+01000000000100000000000000000000000000
diff --git a/src/test/data/txcreatesign.hex b/src/test/data/txcreatesign.hex
new file mode 100644
index 0000000000..56ce28a865
--- /dev/null
+++ b/src/test/data/txcreatesign.hex
@@ -0,0 +1 @@
+01000000018594c5bdcaec8f06b78b596f31cd292a294fd031e24eec716f43dac91ea7494d0000000000ffffffff01a0860100000000001976a9145834479edbbe0539b31ffd3a8f8ebadc2165ed0188ac00000000
diff --git a/src/test/getarg_tests.cpp b/src/test/getarg_tests.cpp
new file mode 100644
index 0000000000..a0c5592a95
--- /dev/null
+++ b/src/test/getarg_tests.cpp
@@ -0,0 +1,162 @@
+// Copyright (c) 2012-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "util.h"
+#include "test/test_bitcoin.h"
+
+#include <string>
+#include <vector>
+
+#include <boost/algorithm/string.hpp>
+#include <boost/foreach.hpp>
+#include <boost/test/unit_test.hpp>
+
+BOOST_FIXTURE_TEST_SUITE(getarg_tests, BasicTestingSetup)
+
+static void ResetArgs(const std::string& strArg)
+{
+ std::vector<std::string> vecArg;
+ if (strArg.size())
+ 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<const char*> 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", false));
+ BOOST_CHECK(GetBoolArg("-foo", true));
+
+ BOOST_CHECK(!GetBoolArg("-fo", false));
+ BOOST_CHECK(GetBoolArg("-fo", true));
+
+ BOOST_CHECK(!GetBoolArg("-fooo", false));
+ BOOST_CHECK(GetBoolArg("-fooo", true));
+
+ ResetArgs("-foo=0");
+ BOOST_CHECK(!GetBoolArg("-foo", false));
+ BOOST_CHECK(!GetBoolArg("-foo", true));
+
+ ResetArgs("-foo=1");
+ 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", false));
+ BOOST_CHECK(!GetBoolArg("-foo", true));
+
+ ResetArgs("-nofoo=1");
+ BOOST_CHECK(!GetBoolArg("-foo", false));
+ BOOST_CHECK(!GetBoolArg("-foo", true));
+
+ ResetArgs("-foo -nofoo"); // -foo should win
+ BOOST_CHECK(GetBoolArg("-foo", false));
+ BOOST_CHECK(GetBoolArg("-foo", true));
+
+ ResetArgs("-foo=1 -nofoo=1"); // -foo should win
+ BOOST_CHECK(GetBoolArg("-foo", false));
+ BOOST_CHECK(GetBoolArg("-foo", true));
+
+ ResetArgs("-foo=0 -nofoo=0"); // -foo should win
+ BOOST_CHECK(!GetBoolArg("-foo", false));
+ BOOST_CHECK(!GetBoolArg("-foo", true));
+
+ // New 0.6 feature: treat -- same as -:
+ ResetArgs("--foo=1");
+ BOOST_CHECK(GetBoolArg("-foo", false));
+ BOOST_CHECK(GetBoolArg("-foo", true));
+
+ ResetArgs("--nofoo=1");
+ 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", false), 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", true));
+ BOOST_CHECK(!GetBoolArg("-foo", false));
+
+ ResetArgs("-nofoo=1");
+ BOOST_CHECK(!GetBoolArg("-foo", true));
+ BOOST_CHECK(!GetBoolArg("-foo", false));
+
+ ResetArgs("-nofoo=0");
+ BOOST_CHECK(GetBoolArg("-foo", true));
+ BOOST_CHECK(GetBoolArg("-foo", false));
+
+ ResetArgs("-foo --nofoo");
+ BOOST_CHECK(GetBoolArg("-foo", true));
+ BOOST_CHECK(GetBoolArg("-foo", false));
+
+ ResetArgs("-nofoo -foo"); // foo always wins:
+ BOOST_CHECK(GetBoolArg("-foo", true));
+ BOOST_CHECK(GetBoolArg("-foo", false));
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/hash_tests.cpp b/src/test/hash_tests.cpp
new file mode 100644
index 0000000000..e5d2e5a439
--- /dev/null
+++ b/src/test/hash_tests.cpp
@@ -0,0 +1,50 @@
+// Copyright (c) 2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "hash.h"
+#include "utilstrencodings.h"
+#include "test/test_bitcoin.h"
+
+#include <vector>
+
+#include <boost/test/unit_test.hpp>
+
+using namespace std;
+
+BOOST_FIXTURE_TEST_SUITE(hash_tests, BasicTestingSetup)
+
+BOOST_AUTO_TEST_CASE(murmurhash3)
+{
+
+#define T(expected, seed, data) BOOST_CHECK_EQUAL(MurmurHash3(seed, ParseHex(data)), expected)
+
+ // Test MurmurHash3 with various inputs. Of course this is retested in the
+ // bloom filter tests - they would fail if MurmurHash3() had any problems -
+ // but is useful for those trying to implement Bitcoin libraries as a
+ // source of test data for their MurmurHash3() primitive during
+ // development.
+ //
+ // The magic number 0xFBA4C795 comes from CBloomFilter::Hash()
+
+ T(0x00000000, 0x00000000, "");
+ T(0x6a396f08, 0xFBA4C795, "");
+ T(0x81f16f39, 0xffffffff, "");
+
+ T(0x514e28b7, 0x00000000, "00");
+ T(0xea3f0b17, 0xFBA4C795, "00");
+ T(0xfd6cf10d, 0x00000000, "ff");
+
+ T(0x16c6b7ab, 0x00000000, "0011");
+ T(0x8eb51c3d, 0x00000000, "001122");
+ T(0xb4471bf8, 0x00000000, "00112233");
+ T(0xe2301fa8, 0x00000000, "0011223344");
+ T(0xfc2e4a15, 0x00000000, "001122334455");
+ T(0xb074502c, 0x00000000, "00112233445566");
+ T(0x8034d2a0, 0x00000000, "0011223344556677");
+ T(0xb4698def, 0x00000000, "001122334455667788");
+
+#undef T
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/key_tests.cpp b/src/test/key_tests.cpp
new file mode 100644
index 0000000000..13ca949469
--- /dev/null
+++ b/src/test/key_tests.cpp
@@ -0,0 +1,191 @@
+// Copyright (c) 2012-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "key.h"
+
+#include "base58.h"
+#include "script/script.h"
+#include "uint256.h"
+#include "util.h"
+#include "utilstrencodings.h"
+#include "test/test_bitcoin.h"
+
+#include <string>
+#include <vector>
+
+#include <boost/test/unit_test.hpp>
+
+using namespace std;
+
+static const string strSecret1 ("5HxWvvfubhXpYYpS3tJkw6fq9jE9j18THftkZjHHfmFiWtmAbrj");
+static const string strSecret2 ("5KC4ejrDjv152FGwP386VD1i2NYc5KkfSMyv1nGy1VGDxGHqVY3");
+static const string strSecret1C ("Kwr371tjA9u2rFSMZjTNun2PXXP3WPZu2afRHTcta6KxEUdm1vEw");
+static const string strSecret2C ("L3Hq7a8FEQwJkW1M2GNKDW28546Vp5miewcCzSqUD9kCAXrJdS3g");
+static const CBitcoinAddress addr1 ("1QFqqMUD55ZV3PJEJZtaKCsQmjLT6JkjvJ");
+static const CBitcoinAddress addr2 ("1F5y5E5FMc5YzdJtB9hLaUe43GDxEKXENJ");
+static const CBitcoinAddress addr1C("1NoJrossxPBKfCHuJXT4HadJrXRE9Fxiqs");
+static const CBitcoinAddress addr2C("1CRj2HyM1CXWzHAXLQtiGLyggNT9WQqsDs");
+
+
+static const string strAddressBad("1HV9Lc3sNHZxwj4Zk6fB38tEmBryq2cBiF");
+
+
+#ifdef KEY_TESTS_DUMPINFO
+void dumpKeyInfo(uint256 privkey)
+{
+ CKey key;
+ key.resize(32);
+ memcpy(&secret[0], &privkey, 32);
+ vector<unsigned char> 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<unsigned char> vchPubKey = key.GetPubKey();
+ printf(" * pubkey (hex): %s\n", HexStr(vchPubKey).c_str());
+ printf(" * address (base58): %s\n", CBitcoinAddress(vchPubKey).ToString().c_str());
+ }
+}
+#endif
+
+
+BOOST_FIXTURE_TEST_SUITE(key_tests, BasicTestingSetup)
+
+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));
+
+ CKey key1 = bsecret1.GetKey();
+ BOOST_CHECK(key1.IsCompressed() == false);
+ CKey key2 = bsecret2.GetKey();
+ BOOST_CHECK(key2.IsCompressed() == false);
+ CKey key1C = bsecret1C.GetKey();
+ BOOST_CHECK(key1C.IsCompressed() == true);
+ CKey key2C = bsecret2C.GetKey();
+ BOOST_CHECK(key2C.IsCompressed() == true);
+
+ CPubKey pubkey1 = key1. GetPubKey();
+ CPubKey pubkey2 = key2. GetPubKey();
+ CPubKey pubkey1C = key1C.GetPubKey();
+ CPubKey pubkey2C = key2C.GetPubKey();
+
+ BOOST_CHECK(key1.VerifyPubKey(pubkey1));
+ BOOST_CHECK(!key1.VerifyPubKey(pubkey1C));
+ BOOST_CHECK(!key1.VerifyPubKey(pubkey2));
+ BOOST_CHECK(!key1.VerifyPubKey(pubkey2C));
+
+ BOOST_CHECK(!key1C.VerifyPubKey(pubkey1));
+ BOOST_CHECK(key1C.VerifyPubKey(pubkey1C));
+ BOOST_CHECK(!key1C.VerifyPubKey(pubkey2));
+ BOOST_CHECK(!key1C.VerifyPubKey(pubkey2C));
+
+ BOOST_CHECK(!key2.VerifyPubKey(pubkey1));
+ BOOST_CHECK(!key2.VerifyPubKey(pubkey1C));
+ BOOST_CHECK(key2.VerifyPubKey(pubkey2));
+ BOOST_CHECK(!key2.VerifyPubKey(pubkey2C));
+
+ BOOST_CHECK(!key2C.VerifyPubKey(pubkey1));
+ BOOST_CHECK(!key2C.VerifyPubKey(pubkey1C));
+ BOOST_CHECK(!key2C.VerifyPubKey(pubkey2));
+ BOOST_CHECK(key2C.VerifyPubKey(pubkey2C));
+
+ BOOST_CHECK(addr1.Get() == CTxDestination(pubkey1.GetID()));
+ BOOST_CHECK(addr2.Get() == CTxDestination(pubkey2.GetID()));
+ BOOST_CHECK(addr1C.Get() == CTxDestination(pubkey1C.GetID()));
+ BOOST_CHECK(addr2C.Get() == CTxDestination(pubkey2C.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<unsigned char> 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( pubkey1.Verify(hashMsg, sign1));
+ BOOST_CHECK(!pubkey1.Verify(hashMsg, sign2));
+ BOOST_CHECK( pubkey1.Verify(hashMsg, sign1C));
+ BOOST_CHECK(!pubkey1.Verify(hashMsg, sign2C));
+
+ BOOST_CHECK(!pubkey2.Verify(hashMsg, sign1));
+ BOOST_CHECK( pubkey2.Verify(hashMsg, sign2));
+ BOOST_CHECK(!pubkey2.Verify(hashMsg, sign1C));
+ BOOST_CHECK( pubkey2.Verify(hashMsg, sign2C));
+
+ BOOST_CHECK( pubkey1C.Verify(hashMsg, sign1));
+ BOOST_CHECK(!pubkey1C.Verify(hashMsg, sign2));
+ BOOST_CHECK( pubkey1C.Verify(hashMsg, sign1C));
+ BOOST_CHECK(!pubkey1C.Verify(hashMsg, sign2C));
+
+ BOOST_CHECK(!pubkey2C.Verify(hashMsg, sign1));
+ BOOST_CHECK( pubkey2C.Verify(hashMsg, sign2));
+ BOOST_CHECK(!pubkey2C.Verify(hashMsg, sign1C));
+ BOOST_CHECK( pubkey2C.Verify(hashMsg, sign2C));
+
+ // compact signatures (with key recovery)
+
+ vector<unsigned char> 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));
+
+ CPubKey rkey1, rkey2, rkey1C, rkey2C;
+
+ BOOST_CHECK(rkey1.RecoverCompact (hashMsg, csign1));
+ BOOST_CHECK(rkey2.RecoverCompact (hashMsg, csign2));
+ BOOST_CHECK(rkey1C.RecoverCompact(hashMsg, csign1C));
+ BOOST_CHECK(rkey2C.RecoverCompact(hashMsg, csign2C));
+
+ BOOST_CHECK(rkey1 == pubkey1);
+ BOOST_CHECK(rkey2 == pubkey2);
+ BOOST_CHECK(rkey1C == pubkey1C);
+ BOOST_CHECK(rkey2C == pubkey2C);
+ }
+
+ // test deterministic signing
+
+ std::vector<unsigned char> detsig, detsigc;
+ string strMsg = "Very deterministic message";
+ uint256 hashMsg = Hash(strMsg.begin(), strMsg.end());
+ BOOST_CHECK(key1.Sign(hashMsg, detsig));
+ BOOST_CHECK(key1C.Sign(hashMsg, detsigc));
+ BOOST_CHECK(detsig == detsigc);
+ BOOST_CHECK(detsig == ParseHex("304402205dbbddda71772d95ce91cd2d14b592cfbc1dd0aabd6a394b6c2d377bbe59d31d022014ddda21494a4e221f0824f0b8b924c43fa43c0ad57dccdaa11f81a6bd4582f6"));
+ BOOST_CHECK(key2.Sign(hashMsg, detsig));
+ BOOST_CHECK(key2C.Sign(hashMsg, detsigc));
+ BOOST_CHECK(detsig == detsigc);
+ BOOST_CHECK(detsig == ParseHex("3044022052d8a32079c11e79db95af63bb9600c5b04f21a9ca33dc129c2bfa8ac9dc1cd5022061d8ae5e0f6c1a16bde3719c64c2fd70e404b6428ab9a69566962e8771b5944d"));
+ BOOST_CHECK(key1.SignCompact(hashMsg, detsig));
+ BOOST_CHECK(key1C.SignCompact(hashMsg, detsigc));
+ BOOST_CHECK(detsig == ParseHex("1c5dbbddda71772d95ce91cd2d14b592cfbc1dd0aabd6a394b6c2d377bbe59d31d14ddda21494a4e221f0824f0b8b924c43fa43c0ad57dccdaa11f81a6bd4582f6"));
+ BOOST_CHECK(detsigc == ParseHex("205dbbddda71772d95ce91cd2d14b592cfbc1dd0aabd6a394b6c2d377bbe59d31d14ddda21494a4e221f0824f0b8b924c43fa43c0ad57dccdaa11f81a6bd4582f6"));
+ BOOST_CHECK(key2.SignCompact(hashMsg, detsig));
+ BOOST_CHECK(key2C.SignCompact(hashMsg, detsigc));
+ BOOST_CHECK(detsig == ParseHex("1c52d8a32079c11e79db95af63bb9600c5b04f21a9ca33dc129c2bfa8ac9dc1cd561d8ae5e0f6c1a16bde3719c64c2fd70e404b6428ab9a69566962e8771b5944d"));
+ BOOST_CHECK(detsigc == ParseHex("2052d8a32079c11e79db95af63bb9600c5b04f21a9ca33dc129c2bfa8ac9dc1cd561d8ae5e0f6c1a16bde3719c64c2fd70e404b6428ab9a69566962e8771b5944d"));
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/main_tests.cpp b/src/test/main_tests.cpp
new file mode 100644
index 0000000000..21ae46d6e9
--- /dev/null
+++ b/src/test/main_tests.cpp
@@ -0,0 +1,76 @@
+// Copyright (c) 2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "chainparams.h"
+#include "main.h"
+
+#include "test/test_bitcoin.h"
+
+#include <boost/signals2/signal.hpp>
+#include <boost/test/unit_test.hpp>
+
+BOOST_FIXTURE_TEST_SUITE(main_tests, TestingSetup)
+
+static void TestBlockSubsidyHalvings(const Consensus::Params& consensusParams)
+{
+ int maxHalvings = 64;
+ CAmount nInitialSubsidy = 50 * COIN;
+
+ CAmount nPreviousSubsidy = nInitialSubsidy * 2; // for height == 0
+ BOOST_CHECK_EQUAL(nPreviousSubsidy, nInitialSubsidy * 2);
+ for (int nHalvings = 0; nHalvings < maxHalvings; nHalvings++) {
+ int nHeight = nHalvings * consensusParams.nSubsidyHalvingInterval;
+ CAmount nSubsidy = GetBlockSubsidy(nHeight, consensusParams);
+ BOOST_CHECK(nSubsidy <= nInitialSubsidy);
+ BOOST_CHECK_EQUAL(nSubsidy, nPreviousSubsidy / 2);
+ nPreviousSubsidy = nSubsidy;
+ }
+ BOOST_CHECK_EQUAL(GetBlockSubsidy(maxHalvings * consensusParams.nSubsidyHalvingInterval, consensusParams), 0);
+}
+
+static void TestBlockSubsidyHalvings(int nSubsidyHalvingInterval)
+{
+ Consensus::Params consensusParams;
+ consensusParams.nSubsidyHalvingInterval = nSubsidyHalvingInterval;
+ TestBlockSubsidyHalvings(consensusParams);
+}
+
+BOOST_AUTO_TEST_CASE(block_subsidy_test)
+{
+ TestBlockSubsidyHalvings(Params(CBaseChainParams::MAIN).GetConsensus()); // As in main
+ TestBlockSubsidyHalvings(150); // As in regtest
+ TestBlockSubsidyHalvings(1000); // Just another interval
+}
+
+BOOST_AUTO_TEST_CASE(subsidy_limit_test)
+{
+ const Consensus::Params& consensusParams = Params(CBaseChainParams::MAIN).GetConsensus();
+ CAmount nSum = 0;
+ for (int nHeight = 0; nHeight < 14000000; nHeight += 1000) {
+ CAmount nSubsidy = GetBlockSubsidy(nHeight, consensusParams);
+ BOOST_CHECK(nSubsidy <= 50 * COIN);
+ nSum += nSubsidy * 1000;
+ BOOST_CHECK(MoneyRange(nSum));
+ }
+ BOOST_CHECK_EQUAL(nSum, 2099999997690000ULL);
+}
+
+bool ReturnFalse() { return false; }
+bool ReturnTrue() { return true; }
+
+BOOST_AUTO_TEST_CASE(test_combiner_all)
+{
+ boost::signals2::signal<bool (), CombinerAll> Test;
+ BOOST_CHECK(Test());
+ Test.connect(&ReturnFalse);
+ BOOST_CHECK(!Test());
+ Test.connect(&ReturnTrue);
+ BOOST_CHECK(!Test());
+ Test.disconnect(&ReturnFalse);
+ BOOST_CHECK(Test());
+ Test.disconnect(&ReturnTrue);
+ BOOST_CHECK(Test());
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/mempool_tests.cpp b/src/test/mempool_tests.cpp
new file mode 100644
index 0000000000..0996e13c48
--- /dev/null
+++ b/src/test/mempool_tests.cpp
@@ -0,0 +1,104 @@
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "main.h"
+#include "txmempool.h"
+#include "util.h"
+
+#include "test/test_bitcoin.h"
+
+#include <boost/test/unit_test.hpp>
+#include <list>
+
+BOOST_FIXTURE_TEST_SUITE(mempool_tests, TestingSetup)
+
+BOOST_AUTO_TEST_CASE(MempoolRemoveTest)
+{
+ // Test CTxMemPool::remove functionality
+
+ // Parent transaction with three children,
+ // and three grand-children:
+ CMutableTransaction txParent;
+ txParent.vin.resize(1);
+ txParent.vin[0].scriptSig = CScript() << OP_11;
+ txParent.vout.resize(3);
+ for (int i = 0; i < 3; i++)
+ {
+ txParent.vout[i].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
+ txParent.vout[i].nValue = 33000LL;
+ }
+ CMutableTransaction txChild[3];
+ for (int i = 0; i < 3; i++)
+ {
+ txChild[i].vin.resize(1);
+ txChild[i].vin[0].scriptSig = CScript() << OP_11;
+ txChild[i].vin[0].prevout.hash = txParent.GetHash();
+ txChild[i].vin[0].prevout.n = i;
+ txChild[i].vout.resize(1);
+ txChild[i].vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
+ txChild[i].vout[0].nValue = 11000LL;
+ }
+ CMutableTransaction txGrandChild[3];
+ for (int i = 0; i < 3; i++)
+ {
+ txGrandChild[i].vin.resize(1);
+ txGrandChild[i].vin[0].scriptSig = CScript() << OP_11;
+ txGrandChild[i].vin[0].prevout.hash = txChild[i].GetHash();
+ txGrandChild[i].vin[0].prevout.n = 0;
+ txGrandChild[i].vout.resize(1);
+ txGrandChild[i].vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
+ txGrandChild[i].vout[0].nValue = 11000LL;
+ }
+
+
+ CTxMemPool testPool(CFeeRate(0));
+ std::list<CTransaction> removed;
+
+ // Nothing in pool, remove should do nothing:
+ testPool.remove(txParent, removed, true);
+ BOOST_CHECK_EQUAL(removed.size(), 0);
+
+ // Just the parent:
+ testPool.addUnchecked(txParent.GetHash(), CTxMemPoolEntry(txParent, 0, 0, 0.0, 1));
+ testPool.remove(txParent, removed, true);
+ BOOST_CHECK_EQUAL(removed.size(), 1);
+ removed.clear();
+
+ // Parent, children, grandchildren:
+ testPool.addUnchecked(txParent.GetHash(), CTxMemPoolEntry(txParent, 0, 0, 0.0, 1));
+ for (int i = 0; i < 3; i++)
+ {
+ testPool.addUnchecked(txChild[i].GetHash(), CTxMemPoolEntry(txChild[i], 0, 0, 0.0, 1));
+ testPool.addUnchecked(txGrandChild[i].GetHash(), CTxMemPoolEntry(txGrandChild[i], 0, 0, 0.0, 1));
+ }
+ // Remove Child[0], GrandChild[0] should be removed:
+ testPool.remove(txChild[0], removed, true);
+ BOOST_CHECK_EQUAL(removed.size(), 2);
+ removed.clear();
+ // ... make sure grandchild and child are gone:
+ testPool.remove(txGrandChild[0], removed, true);
+ BOOST_CHECK_EQUAL(removed.size(), 0);
+ testPool.remove(txChild[0], removed, true);
+ BOOST_CHECK_EQUAL(removed.size(), 0);
+ // Remove parent, all children/grandchildren should go:
+ testPool.remove(txParent, removed, true);
+ BOOST_CHECK_EQUAL(removed.size(), 5);
+ BOOST_CHECK_EQUAL(testPool.size(), 0);
+ removed.clear();
+
+ // Add children and grandchildren, but NOT the parent (simulate the parent being in a block)
+ for (int i = 0; i < 3; i++)
+ {
+ testPool.addUnchecked(txChild[i].GetHash(), CTxMemPoolEntry(txChild[i], 0, 0, 0.0, 1));
+ testPool.addUnchecked(txGrandChild[i].GetHash(), CTxMemPoolEntry(txGrandChild[i], 0, 0, 0.0, 1));
+ }
+ // Now remove the parent, as might happen if a block-re-org occurs but the parent cannot be
+ // put into the mempool (maybe because it is non-standard):
+ testPool.remove(txParent, removed, true);
+ BOOST_CHECK_EQUAL(removed.size(), 6);
+ BOOST_CHECK_EQUAL(testPool.size(), 0);
+ removed.clear();
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp
new file mode 100644
index 0000000000..9e4fd8513e
--- /dev/null
+++ b/src/test/miner_tests.cpp
@@ -0,0 +1,271 @@
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "consensus/validation.h"
+#include "main.h"
+#include "miner.h"
+#include "pubkey.h"
+#include "uint256.h"
+#include "util.h"
+
+#include "test/test_bitcoin.h"
+
+#include <boost/test/unit_test.hpp>
+
+BOOST_FIXTURE_TEST_SUITE(miner_tests, TestingSetup)
+
+static
+struct {
+ unsigned char extranonce;
+ unsigned int nonce;
+} blockinfo[] = {
+ {4, 0xa4a3e223}, {2, 0x15c32f9e}, {1, 0x0375b547}, {1, 0x7004a8a5},
+ {2, 0xce440296}, {2, 0x52cfe198}, {1, 0x77a72cd0}, {2, 0xbb5d6f84},
+ {2, 0x83f30c2c}, {1, 0x48a73d5b}, {1, 0xef7dcd01}, {2, 0x6809c6c4},
+ {2, 0x0883ab3c}, {1, 0x087bbbe2}, {2, 0x2104a814}, {2, 0xdffb6daa},
+ {1, 0xee8a0a08}, {2, 0xba4237c1}, {1, 0xa70349dc}, {1, 0x344722bb},
+ {3, 0xd6294733}, {2, 0xec9f5c94}, {2, 0xca2fbc28}, {1, 0x6ba4f406},
+ {2, 0x015d4532}, {1, 0x6e119b7c}, {2, 0x43e8f314}, {2, 0x27962f38},
+ {2, 0xb571b51b}, {2, 0xb36bee23}, {2, 0xd17924a8}, {2, 0x6bc212d9},
+ {1, 0x630d4948}, {2, 0x9a4c4ebb}, {2, 0x554be537}, {1, 0xd63ddfc7},
+ {2, 0xa10acc11}, {1, 0x759a8363}, {2, 0xfb73090d}, {1, 0xe82c6a34},
+ {1, 0xe33e92d7}, {3, 0x658ef5cb}, {2, 0xba32ff22}, {5, 0x0227a10c},
+ {1, 0xa9a70155}, {5, 0xd096d809}, {1, 0x37176174}, {1, 0x830b8d0f},
+ {1, 0xc6e3910e}, {2, 0x823f3ca8}, {1, 0x99850849}, {1, 0x7521fb81},
+ {1, 0xaacaabab}, {1, 0xd645a2eb}, {5, 0x7aea1781}, {5, 0x9d6e4b78},
+ {1, 0x4ce90fd8}, {1, 0xabdc832d}, {6, 0x4a34f32a}, {2, 0xf2524c1c},
+ {2, 0x1bbeb08a}, {1, 0xad47f480}, {1, 0x9f026aeb}, {1, 0x15a95049},
+ {2, 0xd1cb95b2}, {2, 0xf84bbda5}, {1, 0x0fa62cd1}, {1, 0xe05f9169},
+ {1, 0x78d194a9}, {5, 0x3e38147b}, {5, 0x737ba0d4}, {1, 0x63378e10},
+ {1, 0x6d5f91cf}, {2, 0x88612eb8}, {2, 0xe9639484}, {1, 0xb7fabc9d},
+ {2, 0x19b01592}, {1, 0x5a90dd31}, {2, 0x5bd7e028}, {2, 0x94d00323},
+ {1, 0xa9b9c01a}, {1, 0x3a40de61}, {1, 0x56e7eec7}, {5, 0x859f7ef6},
+ {1, 0xfd8e5630}, {1, 0x2b0c9f7f}, {1, 0xba700e26}, {1, 0x7170a408},
+ {1, 0x70de86a8}, {1, 0x74d64cd5}, {1, 0x49e738a1}, {2, 0x6910b602},
+ {0, 0x643c565f}, {1, 0x54264b3f}, {2, 0x97ea6396}, {2, 0x55174459},
+ {2, 0x03e8779a}, {1, 0x98f34d8f}, {1, 0xc07b2b07}, {1, 0xdfe29668},
+ {1, 0x3141c7c1}, {1, 0xb3b595f4}, {1, 0x735abf08}, {5, 0x623bfbce},
+ {2, 0xd351e722}, {1, 0xf4ca48c9}, {1, 0x5b19c670}, {1, 0xa164bf0e},
+ {2, 0xbbbeb305}, {2, 0xfe1c810a},
+};
+
+// NOTE: These tests rely on CreateNewBlock doing its own self-validation!
+BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
+{
+ CScript scriptPubKey = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG;
+ CBlockTemplate *pblocktemplate;
+ CMutableTransaction tx,tx2;
+ CScript script;
+ uint256 hash;
+
+ LOCK(cs_main);
+ fCheckpointsEnabled = false;
+
+ // Simple block creation, nothing special yet:
+ BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey));
+
+ // We can't make transactions until we have inputs
+ // Therefore, load 100 blocks :)
+ std::vector<CTransaction*>txFirst;
+ for (unsigned int i = 0; i < sizeof(blockinfo)/sizeof(*blockinfo); ++i)
+ {
+ CBlock *pblock = &pblocktemplate->block; // pointer for convenience
+ pblock->nVersion = 1;
+ pblock->nTime = chainActive.Tip()->GetMedianTimePast()+1;
+ CMutableTransaction txCoinbase(pblock->vtx[0]);
+ txCoinbase.vin[0].scriptSig = CScript();
+ txCoinbase.vin[0].scriptSig.push_back(blockinfo[i].extranonce);
+ txCoinbase.vin[0].scriptSig.push_back(chainActive.Height());
+ txCoinbase.vout[0].scriptPubKey = CScript();
+ pblock->vtx[0] = CTransaction(txCoinbase);
+ if (txFirst.size() < 2)
+ txFirst.push_back(new CTransaction(pblock->vtx[0]));
+ pblock->hashMerkleRoot = pblock->BuildMerkleTree();
+ pblock->nNonce = blockinfo[i].nonce;
+ CValidationState state;
+ BOOST_CHECK(ProcessNewBlock(state, NULL, pblock, true, NULL));
+ BOOST_CHECK(state.IsValid());
+ pblock->hashPrevBlock = pblock->GetHash();
+ }
+ delete pblocktemplate;
+
+ // Just to make sure we can still make simple blocks
+ BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey));
+ delete pblocktemplate;
+
+ // block sigops > limit: 1000 CHECKMULTISIG + 1
+ tx.vin.resize(1);
+ // NOTE: OP_NOP is used to force 20 SigOps for the CHECKMULTISIG
+ tx.vin[0].scriptSig = CScript() << OP_0 << OP_0 << OP_0 << OP_NOP << OP_CHECKMULTISIG << OP_1;
+ tx.vin[0].prevout.hash = txFirst[0]->GetHash();
+ tx.vin[0].prevout.n = 0;
+ tx.vout.resize(1);
+ tx.vout[0].nValue = 5000000000LL;
+ for (unsigned int i = 0; i < 1001; ++i)
+ {
+ tx.vout[0].nValue -= 1000000;
+ hash = tx.GetHash();
+ mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
+ tx.vin[0].prevout.hash = hash;
+ }
+ BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey));
+ delete pblocktemplate;
+ mempool.clear();
+
+ // block size > limit
+ tx.vin[0].scriptSig = CScript();
+ // 18 * (520char + DROP) + OP_1 = 9433 bytes
+ std::vector<unsigned char> vchData(520);
+ for (unsigned int i = 0; i < 18; ++i)
+ tx.vin[0].scriptSig << vchData << OP_DROP;
+ tx.vin[0].scriptSig << OP_1;
+ tx.vin[0].prevout.hash = txFirst[0]->GetHash();
+ tx.vout[0].nValue = 5000000000LL;
+ for (unsigned int i = 0; i < 128; ++i)
+ {
+ tx.vout[0].nValue -= 10000000;
+ hash = tx.GetHash();
+ mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
+ tx.vin[0].prevout.hash = hash;
+ }
+ BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey));
+ delete pblocktemplate;
+ mempool.clear();
+
+ // orphan in mempool
+ hash = tx.GetHash();
+ mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
+ BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey));
+ delete pblocktemplate;
+ mempool.clear();
+
+ // child with higher priority than parent
+ tx.vin[0].scriptSig = CScript() << OP_1;
+ tx.vin[0].prevout.hash = txFirst[1]->GetHash();
+ tx.vout[0].nValue = 4900000000LL;
+ hash = tx.GetHash();
+ mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
+ tx.vin[0].prevout.hash = hash;
+ tx.vin.resize(2);
+ tx.vin[1].scriptSig = CScript() << OP_1;
+ tx.vin[1].prevout.hash = txFirst[0]->GetHash();
+ tx.vin[1].prevout.n = 0;
+ tx.vout[0].nValue = 5900000000LL;
+ hash = tx.GetHash();
+ mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
+ BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey));
+ delete pblocktemplate;
+ mempool.clear();
+
+ // coinbase in mempool
+ tx.vin.resize(1);
+ tx.vin[0].prevout.SetNull();
+ tx.vin[0].scriptSig = CScript() << OP_0 << OP_1;
+ tx.vout[0].nValue = 0;
+ hash = tx.GetHash();
+ mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
+ BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey));
+ delete pblocktemplate;
+ mempool.clear();
+
+ // invalid (pre-p2sh) txn in mempool
+ tx.vin[0].prevout.hash = txFirst[0]->GetHash();
+ tx.vin[0].prevout.n = 0;
+ tx.vin[0].scriptSig = CScript() << OP_1;
+ tx.vout[0].nValue = 4900000000LL;
+ script = CScript() << OP_0;
+ tx.vout[0].scriptPubKey = GetScriptForDestination(CScriptID(script));
+ hash = tx.GetHash();
+ mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
+ tx.vin[0].prevout.hash = hash;
+ tx.vin[0].scriptSig = CScript() << (std::vector<unsigned char>)script;
+ tx.vout[0].nValue -= 1000000;
+ hash = tx.GetHash();
+ mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
+ BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey));
+ delete pblocktemplate;
+ mempool.clear();
+
+ // double spend txn pair in mempool
+ tx.vin[0].prevout.hash = txFirst[0]->GetHash();
+ tx.vin[0].scriptSig = CScript() << OP_1;
+ tx.vout[0].nValue = 4900000000LL;
+ tx.vout[0].scriptPubKey = CScript() << OP_1;
+ hash = tx.GetHash();
+ mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
+ tx.vout[0].scriptPubKey = CScript() << OP_2;
+ hash = tx.GetHash();
+ mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
+ BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey));
+ delete pblocktemplate;
+ mempool.clear();
+
+ // subsidy changing
+ int nHeight = chainActive.Height();
+ chainActive.Tip()->nHeight = 209999;
+ BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey));
+ delete pblocktemplate;
+ chainActive.Tip()->nHeight = 210000;
+ BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey));
+ delete pblocktemplate;
+ chainActive.Tip()->nHeight = nHeight;
+
+ // non-final txs in mempool
+ SetMockTime(chainActive.Tip()->GetMedianTimePast()+1);
+
+ // height locked
+ tx.vin[0].prevout.hash = txFirst[0]->GetHash();
+ tx.vin[0].scriptSig = CScript() << OP_1;
+ tx.vin[0].nSequence = 0;
+ tx.vout[0].nValue = 4900000000LL;
+ tx.vout[0].scriptPubKey = CScript() << OP_1;
+ tx.nLockTime = chainActive.Tip()->nHeight+1;
+ hash = tx.GetHash();
+ mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
+ BOOST_CHECK(!CheckFinalTx(tx));
+
+ // time locked
+ tx2.vin.resize(1);
+ tx2.vin[0].prevout.hash = txFirst[1]->GetHash();
+ tx2.vin[0].prevout.n = 0;
+ tx2.vin[0].scriptSig = CScript() << OP_1;
+ tx2.vin[0].nSequence = 0;
+ tx2.vout.resize(1);
+ tx2.vout[0].nValue = 4900000000LL;
+ tx2.vout[0].scriptPubKey = CScript() << OP_1;
+ tx2.nLockTime = chainActive.Tip()->GetMedianTimePast()+1;
+ hash = tx2.GetHash();
+ mempool.addUnchecked(hash, CTxMemPoolEntry(tx2, 11, GetTime(), 111.0, 11));
+ BOOST_CHECK(!CheckFinalTx(tx2));
+
+ BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey));
+
+ // Neither tx should have make it into the template.
+ BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 1);
+ delete pblocktemplate;
+
+ // However if we advance height and time by one, both will.
+ chainActive.Tip()->nHeight++;
+ SetMockTime(chainActive.Tip()->GetMedianTimePast()+2);
+
+ // FIXME: we should *actually* create a new block so the following test
+ // works; CheckFinalTx() isn't fooled by monkey-patching nHeight.
+ //BOOST_CHECK(CheckFinalTx(tx));
+ //BOOST_CHECK(CheckFinalTx(tx2));
+
+ BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey));
+ BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 3);
+ delete pblocktemplate;
+
+ chainActive.Tip()->nHeight--;
+ SetMockTime(0);
+ mempool.clear();
+
+ BOOST_FOREACH(CTransaction *tx, txFirst)
+ delete tx;
+
+ fCheckpointsEnabled = true;
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/mruset_tests.cpp b/src/test/mruset_tests.cpp
new file mode 100644
index 0000000000..2b68f8899e
--- /dev/null
+++ b/src/test/mruset_tests.cpp
@@ -0,0 +1,81 @@
+// Copyright (c) 2012-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "mruset.h"
+
+#include "random.h"
+#include "util.h"
+#include "test/test_bitcoin.h"
+
+#include <set>
+
+#include <boost/test/unit_test.hpp>
+
+#define NUM_TESTS 16
+#define MAX_SIZE 100
+
+using namespace std;
+
+BOOST_FIXTURE_TEST_SUITE(mruset_tests, BasicTestingSetup)
+
+BOOST_AUTO_TEST_CASE(mruset_test)
+{
+ // The mruset being tested.
+ mruset<int> mru(5000);
+
+ // Run the test 10 times.
+ for (int test = 0; test < 10; test++) {
+ // Reset mru.
+ mru.clear();
+
+ // A deque + set to simulate the mruset.
+ std::deque<int> rep;
+ std::set<int> all;
+
+ // Insert 10000 random integers below 15000.
+ for (int j=0; j<10000; j++) {
+ int add = GetRandInt(15000);
+ mru.insert(add);
+
+ // Add the number to rep/all as well.
+ if (all.count(add) == 0) {
+ all.insert(add);
+ rep.push_back(add);
+ if (all.size() == 5001) {
+ all.erase(rep.front());
+ rep.pop_front();
+ }
+ }
+
+ // Do a full comparison between mru and the simulated mru every 1000 and every 5001 elements.
+ if (j % 1000 == 0 || j % 5001 == 0) {
+ mruset<int> mru2 = mru; // Also try making a copy
+
+ // Check that all elements that should be in there, are in there.
+ BOOST_FOREACH(int x, rep) {
+ BOOST_CHECK(mru.count(x));
+ BOOST_CHECK(mru2.count(x));
+ }
+
+ // Check that all elements that are in there, should be in there.
+ BOOST_FOREACH(int x, mru) {
+ BOOST_CHECK(all.count(x));
+ }
+
+ // Check that all elements that are in there, should be in there.
+ BOOST_FOREACH(int x, mru2) {
+ BOOST_CHECK(all.count(x));
+ }
+
+ for (int t = 0; t < 10; t++) {
+ int r = GetRandInt(15000);
+ BOOST_CHECK(all.count(r) == mru.count(r));
+ BOOST_CHECK(all.count(r) == mru2.count(r));
+ }
+ }
+ }
+ }
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/multisig_tests.cpp b/src/test/multisig_tests.cpp
new file mode 100644
index 0000000000..6b189a6b55
--- /dev/null
+++ b/src/test/multisig_tests.cpp
@@ -0,0 +1,320 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "key.h"
+#include "keystore.h"
+#include "main.h"
+#include "script/script.h"
+#include "script/script_error.h"
+#include "script/interpreter.h"
+#include "script/sign.h"
+#include "uint256.h"
+#include "test/test_bitcoin.h"
+
+#ifdef ENABLE_WALLET
+#include "wallet/wallet_ismine.h"
+#endif
+
+#include <boost/foreach.hpp>
+#include <boost/test/unit_test.hpp>
+
+using namespace std;
+
+typedef vector<unsigned char> valtype;
+
+BOOST_FIXTURE_TEST_SUITE(multisig_tests, BasicTestingSetup)
+
+CScript
+sign_multisig(CScript scriptPubKey, vector<CKey> keys, CTransaction transaction, int whichIn)
+{
+ uint256 hash = SignatureHash(scriptPubKey, transaction, whichIn, SIGHASH_ALL);
+
+ CScript result;
+ result << OP_0; // CHECKMULTISIG bug workaround
+ BOOST_FOREACH(const CKey &key, keys)
+ {
+ vector<unsigned char> vchSig;
+ BOOST_CHECK(key.Sign(hash, vchSig));
+ vchSig.push_back((unsigned char)SIGHASH_ALL);
+ result << vchSig;
+ }
+ return result;
+}
+
+BOOST_AUTO_TEST_CASE(multisig_verify)
+{
+ unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC;
+
+ ScriptError err;
+ CKey key[4];
+ for (int i = 0; i < 4; i++)
+ key[i].MakeNewKey(true);
+
+ CScript a_and_b;
+ a_and_b << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
+
+ CScript a_or_b;
+ a_or_b << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
+
+ CScript escrow;
+ escrow << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << ToByteVector(key[2].GetPubKey()) << OP_3 << OP_CHECKMULTISIG;
+
+ CMutableTransaction 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;
+
+ CMutableTransaction 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<CKey> keys;
+ CScript s;
+
+ // Test a AND b:
+ keys.assign(1,key[0]);
+ keys.push_back(key[1]);
+ s = sign_multisig(a_and_b, keys, txTo[0], 0);
+ BOOST_CHECK(VerifyScript(s, a_and_b, flags, MutableTransactionSignatureChecker(&txTo[0], 0), &err));
+ BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
+
+ for (int i = 0; i < 4; i++)
+ {
+ keys.assign(1,key[i]);
+ s = sign_multisig(a_and_b, keys, txTo[0], 0);
+ BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, flags, MutableTransactionSignatureChecker(&txTo[0], 0), &err), strprintf("a&b 1: %d", i));
+ BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err));
+
+ keys.assign(1,key[1]);
+ keys.push_back(key[i]);
+ s = sign_multisig(a_and_b, keys, txTo[0], 0);
+ BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, flags, MutableTransactionSignatureChecker(&txTo[0], 0), &err), strprintf("a&b 2: %d", i));
+ BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
+ }
+
+ // Test a OR b:
+ for (int i = 0; i < 4; i++)
+ {
+ keys.assign(1,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, flags, MutableTransactionSignatureChecker(&txTo[1], 0), &err), strprintf("a|b: %d", i));
+ BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
+ }
+ else
+ {
+ BOOST_CHECK_MESSAGE(!VerifyScript(s, a_or_b, flags, MutableTransactionSignatureChecker(&txTo[1], 0), &err), strprintf("a|b: %d", i));
+ BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
+ }
+ }
+ s.clear();
+ s << OP_0 << OP_1;
+ BOOST_CHECK(!VerifyScript(s, a_or_b, flags, MutableTransactionSignatureChecker(&txTo[1], 0), &err));
+ BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_SIG_DER, ScriptErrorString(err));
+
+
+ for (int i = 0; i < 4; i++)
+ for (int j = 0; j < 4; j++)
+ {
+ keys.assign(1,key[i]);
+ keys.push_back(key[j]);
+ s = sign_multisig(escrow, keys, txTo[2], 0);
+ if (i < j && i < 3 && j < 3)
+ {
+ BOOST_CHECK_MESSAGE(VerifyScript(s, escrow, flags, MutableTransactionSignatureChecker(&txTo[2], 0), &err), strprintf("escrow 1: %d %d", i, j));
+ BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
+ }
+ else
+ {
+ BOOST_CHECK_MESSAGE(!VerifyScript(s, escrow, flags, MutableTransactionSignatureChecker(&txTo[2], 0), &err), strprintf("escrow 2: %d %d", i, j));
+ BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
+ }
+ }
+}
+
+BOOST_AUTO_TEST_CASE(multisig_IsStandard)
+{
+ CKey key[4];
+ for (int i = 0; i < 4; i++)
+ key[i].MakeNewKey(true);
+
+ txnouttype whichType;
+
+ CScript a_and_b;
+ a_and_b << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
+ BOOST_CHECK(::IsStandard(a_and_b, whichType));
+
+ CScript a_or_b;
+ a_or_b << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
+ BOOST_CHECK(::IsStandard(a_or_b, whichType));
+
+ CScript escrow;
+ escrow << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << ToByteVector(key[2].GetPubKey()) << OP_3 << OP_CHECKMULTISIG;
+ BOOST_CHECK(::IsStandard(escrow, whichType));
+
+ CScript one_of_four;
+ one_of_four << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << ToByteVector(key[2].GetPubKey()) << ToByteVector(key[3].GetPubKey()) << OP_4 << OP_CHECKMULTISIG;
+ BOOST_CHECK(!::IsStandard(one_of_four, whichType));
+
+ CScript malformed[6];
+ malformed[0] << OP_3 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
+ malformed[1] << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_3 << OP_CHECKMULTISIG;
+ malformed[2] << OP_0 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
+ malformed[3] << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_0 << OP_CHECKMULTISIG;
+ malformed[4] << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_CHECKMULTISIG;
+ malformed[5] << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey());
+
+ for (int i = 0; i < 6; i++)
+ BOOST_CHECK(!::IsStandard(malformed[i], whichType));
+}
+
+BOOST_AUTO_TEST_CASE(multisig_Solver1)
+{
+ // Tests Solver() that returns lists of keys that are
+ // required to satisfy a ScriptPubKey
+ //
+ // Also tests IsMine() and ExtractDestination()
+ //
+ // Note: ExtractDestination 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<valtype> solutions;
+ txnouttype whichType;
+ CScript s;
+ s << ToByteVector(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]);
+#ifdef ENABLE_WALLET
+ BOOST_CHECK(IsMine(keystore, s));
+ BOOST_CHECK(!IsMine(emptykeystore, s));
+#endif
+ }
+ {
+ vector<valtype> solutions;
+ txnouttype whichType;
+ CScript s;
+ s << OP_DUP << OP_HASH160 << ToByteVector(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]);
+#ifdef ENABLE_WALLET
+ BOOST_CHECK(IsMine(keystore, s));
+ BOOST_CHECK(!IsMine(emptykeystore, s));
+#endif
+ }
+ {
+ vector<valtype> solutions;
+ txnouttype whichType;
+ CScript s;
+ s << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
+ BOOST_CHECK(Solver(s, whichType, solutions));
+ BOOST_CHECK_EQUAL(solutions.size(), 4U);
+ CTxDestination addr;
+ BOOST_CHECK(!ExtractDestination(s, addr));
+#ifdef ENABLE_WALLET
+ BOOST_CHECK(IsMine(keystore, s));
+ BOOST_CHECK(!IsMine(emptykeystore, s));
+ BOOST_CHECK(!IsMine(partialkeystore, s));
+#endif
+ }
+ {
+ vector<valtype> solutions;
+ txnouttype whichType;
+ CScript s;
+ s << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
+ BOOST_CHECK(Solver(s, whichType, solutions));
+ BOOST_CHECK_EQUAL(solutions.size(), 4U);
+ vector<CTxDestination> 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);
+#ifdef ENABLE_WALLET
+ BOOST_CHECK(IsMine(keystore, s));
+ BOOST_CHECK(!IsMine(emptykeystore, s));
+ BOOST_CHECK(!IsMine(partialkeystore, s));
+#endif
+ }
+ {
+ vector<valtype> solutions;
+ txnouttype whichType;
+ CScript s;
+ s << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << ToByteVector(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 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
+
+ CScript a_or_b;
+ a_or_b << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
+
+ CScript escrow;
+ escrow << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << ToByteVector(key[2].GetPubKey()) << OP_3 << OP_CHECKMULTISIG;
+
+ CMutableTransaction 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;
+
+ CMutableTransaction 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 0000000000..40b32a7b37
--- /dev/null
+++ b/src/test/netbase_tests.cpp
@@ -0,0 +1,165 @@
+// Copyright (c) 2012-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "netbase.h"
+#include "test/test_bitcoin.h"
+
+#include <string>
+
+#include <boost/assign/list_of.hpp>
+#include <boost/test/unit_test.hpp>
+
+using namespace std;
+
+BOOST_FIXTURE_TEST_SUITE(netbase_tests, BasicTestingSetup)
+
+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.bitcoin.org", "www.bitcoin.org", -1));
+ BOOST_CHECK(TestSplitHost("[www.bitcoin.org]", "www.bitcoin.org", -1));
+ BOOST_CHECK(TestSplitHost("www.bitcoin.org:80", "www.bitcoin.org", 80));
+ BOOST_CHECK(TestSplitHost("[www.bitcoin.org]:80", "www.bitcoin.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 https://web.archive.org/web/20121122003543/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_CASE(subnet_test)
+{
+ BOOST_CHECK(CSubNet("1.2.3.0/24") == CSubNet("1.2.3.0/255.255.255.0"));
+ BOOST_CHECK(CSubNet("1.2.3.0/24") != CSubNet("1.2.4.0/255.255.255.0"));
+ BOOST_CHECK(CSubNet("1.2.3.0/24").Match(CNetAddr("1.2.3.4")));
+ BOOST_CHECK(!CSubNet("1.2.2.0/24").Match(CNetAddr("1.2.3.4")));
+ BOOST_CHECK(CSubNet("1.2.3.4").Match(CNetAddr("1.2.3.4")));
+ BOOST_CHECK(CSubNet("1.2.3.4/32").Match(CNetAddr("1.2.3.4")));
+ BOOST_CHECK(!CSubNet("1.2.3.4").Match(CNetAddr("5.6.7.8")));
+ BOOST_CHECK(!CSubNet("1.2.3.4/32").Match(CNetAddr("5.6.7.8")));
+ BOOST_CHECK(CSubNet("::ffff:127.0.0.1").Match(CNetAddr("127.0.0.1")));
+ BOOST_CHECK(CSubNet("1:2:3:4:5:6:7:8").Match(CNetAddr("1:2:3:4:5:6:7:8")));
+ BOOST_CHECK(!CSubNet("1:2:3:4:5:6:7:8").Match(CNetAddr("1:2:3:4:5:6:7:9")));
+ BOOST_CHECK(CSubNet("1:2:3:4:5:6:7:0/112").Match(CNetAddr("1:2:3:4:5:6:7:1234")));
+ BOOST_CHECK(CSubNet("192.168.0.1/24").Match(CNetAddr("192.168.0.2")));
+ BOOST_CHECK(CSubNet("192.168.0.20/29").Match(CNetAddr("192.168.0.18")));
+ BOOST_CHECK(CSubNet("1.2.2.1/24").Match(CNetAddr("1.2.2.4")));
+ BOOST_CHECK(CSubNet("1.2.2.110/31").Match(CNetAddr("1.2.2.111")));
+ BOOST_CHECK(CSubNet("1.2.2.20/26").Match(CNetAddr("1.2.2.63")));
+ // All-Matching IPv6 Matches arbitrary IPv4 and IPv6
+ BOOST_CHECK(CSubNet("::/0").Match(CNetAddr("1:2:3:4:5:6:7:1234")));
+ BOOST_CHECK(CSubNet("::/0").Match(CNetAddr("1.2.3.4")));
+ // All-Matching IPv4 does not Match IPv6
+ BOOST_CHECK(!CSubNet("0.0.0.0/0").Match(CNetAddr("1:2:3:4:5:6:7:1234")));
+ // Invalid subnets Match nothing (not even invalid addresses)
+ BOOST_CHECK(!CSubNet().Match(CNetAddr("1.2.3.4")));
+ BOOST_CHECK(!CSubNet("").Match(CNetAddr("4.5.6.7")));
+ BOOST_CHECK(!CSubNet("bloop").Match(CNetAddr("0.0.0.0")));
+ BOOST_CHECK(!CSubNet("bloop").Match(CNetAddr("hab")));
+ // Check valid/invalid
+ BOOST_CHECK(CSubNet("1.2.3.0/0").IsValid());
+ BOOST_CHECK(!CSubNet("1.2.3.0/-1").IsValid());
+ BOOST_CHECK(CSubNet("1.2.3.0/32").IsValid());
+ BOOST_CHECK(!CSubNet("1.2.3.0/33").IsValid());
+ BOOST_CHECK(CSubNet("1:2:3:4:5:6:7:8/0").IsValid());
+ BOOST_CHECK(CSubNet("1:2:3:4:5:6:7:8/33").IsValid());
+ BOOST_CHECK(!CSubNet("1:2:3:4:5:6:7:8/-1").IsValid());
+ BOOST_CHECK(CSubNet("1:2:3:4:5:6:7:8/128").IsValid());
+ BOOST_CHECK(!CSubNet("1:2:3:4:5:6:7:8/129").IsValid());
+ BOOST_CHECK(!CSubNet("fuzzy").IsValid());
+}
+
+BOOST_AUTO_TEST_CASE(netbase_getgroup)
+{
+ BOOST_CHECK(CNetAddr("127.0.0.1").GetGroup() == boost::assign::list_of(0)); // Local -> !Routable()
+ BOOST_CHECK(CNetAddr("257.0.0.1").GetGroup() == boost::assign::list_of(0)); // !Valid -> !Routable()
+ BOOST_CHECK(CNetAddr("10.0.0.1").GetGroup() == boost::assign::list_of(0)); // RFC1918 -> !Routable()
+ BOOST_CHECK(CNetAddr("169.254.1.1").GetGroup() == boost::assign::list_of(0)); // RFC3927 -> !Routable()
+ BOOST_CHECK(CNetAddr("1.2.3.4").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // IPv4
+ BOOST_CHECK(CNetAddr("::FFFF:0:102:304").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // RFC6145
+ BOOST_CHECK(CNetAddr("64:FF9B::102:304").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // RFC6052
+ BOOST_CHECK(CNetAddr("2002:102:304:9999:9999:9999:9999:9999").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // RFC3964
+ BOOST_CHECK(CNetAddr("2001:0:9999:9999:9999:9999:FEFD:FCFB").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // RFC4380
+ BOOST_CHECK(CNetAddr("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca").GetGroup() == boost::assign::list_of((unsigned char)NET_TOR)(239)); // Tor
+ BOOST_CHECK(CNetAddr("2001:470:abcd:9999:9999:9999:9999:9999").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV6)(32)(1)(4)(112)(175)); //he.net
+ BOOST_CHECK(CNetAddr("2001:2001:9999:9999:9999:9999:9999:9999").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV6)(32)(1)(32)(1)); //IPv6
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/pmt_tests.cpp b/src/test/pmt_tests.cpp
new file mode 100644
index 0000000000..f6d06d6805
--- /dev/null
+++ b/src/test/pmt_tests.cpp
@@ -0,0 +1,127 @@
+// Copyright (c) 2012-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "merkleblock.h"
+#include "serialize.h"
+#include "streams.h"
+#include "uint256.h"
+#include "arith_uint256.h"
+#include "version.h"
+#include "random.h"
+#include "test/test_bitcoin.h"
+
+#include <vector>
+
+#include <boost/assign/list_of.hpp>
+#include <boost/test/unit_test.hpp>
+
+using namespace std;
+
+class CPartialMerkleTreeTester : public CPartialMerkleTree
+{
+public:
+ // flip one bit in one of the hashes - this should break the authentication
+ void Damage() {
+ unsigned int n = insecure_rand() % vHash.size();
+ int bit = insecure_rand() % 256;
+ *(vHash[n].begin() + (bit>>3)) ^= 1<<(bit&7);
+ }
+};
+
+BOOST_FIXTURE_TEST_SUITE(pmt_tests, BasicTestingSetup)
+
+BOOST_AUTO_TEST_CASE(pmt_test1)
+{
+ seed_insecure_rand(false);
+ static const unsigned int nTxCounts[] = {1, 4, 7, 17, 56, 100, 127, 256, 312, 513, 1000, 4095};
+
+ for (int n = 0; n < 12; n++) {
+ unsigned int nTx = nTxCounts[n];
+
+ // build a block with some dummy transactions
+ CBlock block;
+ for (unsigned int j=0; j<nTx; j++) {
+ CMutableTransaction tx;
+ tx.nLockTime = j; // actual transaction data doesn't matter; just make the nLockTime's unique
+ block.vtx.push_back(CTransaction(tx));
+ }
+
+ // calculate actual merkle root and height
+ uint256 merkleRoot1 = block.BuildMerkleTree();
+ std::vector<uint256> vTxid(nTx, uint256());
+ for (unsigned int j=0; j<nTx; j++)
+ vTxid[j] = block.vtx[j].GetHash();
+ int nHeight = 1, nTx_ = nTx;
+ while (nTx_ > 1) {
+ nTx_ = (nTx_+1)/2;
+ nHeight++;
+ }
+
+ // check with random subsets with inclusion chances 1, 1/2, 1/4, ..., 1/128
+ for (int att = 1; att < 15; att++) {
+ // build random subset of txid's
+ std::vector<bool> vMatch(nTx, false);
+ std::vector<uint256> vMatchTxid1;
+ for (unsigned int j=0; j<nTx; j++) {
+ bool fInclude = (insecure_rand() & ((1 << (att/2)) - 1)) == 0;
+ vMatch[j] = fInclude;
+ if (fInclude)
+ vMatchTxid1.push_back(vTxid[j]);
+ }
+
+ // build the partial merkle tree
+ CPartialMerkleTree pmt1(vTxid, vMatch);
+
+ // serialize
+ CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
+ ss << pmt1;
+
+ // verify CPartialMerkleTree's size guarantees
+ unsigned int n = std::min<unsigned int>(nTx, 1 + vMatchTxid1.size()*nHeight);
+ BOOST_CHECK(ss.size() <= 10 + (258*n+7)/8);
+
+ // deserialize into a tester copy
+ CPartialMerkleTreeTester pmt2;
+ ss >> pmt2;
+
+ // extract merkle root and matched txids from copy
+ std::vector<uint256> vMatchTxid2;
+ uint256 merkleRoot2 = pmt2.ExtractMatches(vMatchTxid2);
+
+ // check that it has the same merkle root as the original, and a valid one
+ BOOST_CHECK(merkleRoot1 == merkleRoot2);
+ BOOST_CHECK(!merkleRoot2.IsNull());
+
+ // check that it contains the matched transactions (in the same order!)
+ BOOST_CHECK(vMatchTxid1 == vMatchTxid2);
+
+ // check that random bit flips break the authentication
+ for (int j=0; j<4; j++) {
+ CPartialMerkleTreeTester pmt3(pmt2);
+ pmt3.Damage();
+ std::vector<uint256> vMatchTxid3;
+ uint256 merkleRoot3 = pmt3.ExtractMatches(vMatchTxid3);
+ BOOST_CHECK(merkleRoot3 != merkleRoot1);
+ }
+ }
+ }
+}
+
+BOOST_AUTO_TEST_CASE(pmt_malleability)
+{
+ std::vector<uint256> vTxid = boost::assign::list_of
+ (ArithToUint256(1))(ArithToUint256(2))
+ (ArithToUint256(3))(ArithToUint256(4))
+ (ArithToUint256(5))(ArithToUint256(6))
+ (ArithToUint256(7))(ArithToUint256(8))
+ (ArithToUint256(9))(ArithToUint256(10))
+ (ArithToUint256(9))(ArithToUint256(10));
+ std::vector<bool> vMatch = boost::assign::list_of(false)(false)(false)(false)(false)(false)(false)(false)(false)(true)(true)(false);
+
+ CPartialMerkleTree tree(vTxid, vMatch);
+ std::vector<uint256> vTxid2;
+ BOOST_CHECK(tree.ExtractMatches(vTxid).IsNull());
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/policyestimator_tests.cpp b/src/test/policyestimator_tests.cpp
new file mode 100644
index 0000000000..cb64ee7c69
--- /dev/null
+++ b/src/test/policyestimator_tests.cpp
@@ -0,0 +1,186 @@
+// Copyright (c) 2011-2015 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "policy/fees.h"
+#include "txmempool.h"
+#include "uint256.h"
+#include "util.h"
+
+#include "test/test_bitcoin.h"
+
+#include <boost/test/unit_test.hpp>
+
+BOOST_FIXTURE_TEST_SUITE(policyestimator_tests, BasicTestingSetup)
+
+BOOST_AUTO_TEST_CASE(BlockPolicyEstimates)
+{
+ CTxMemPool mpool(CFeeRate(1000));
+ CAmount basefee(2000);
+ double basepri = 1e6;
+ CAmount deltaFee(100);
+ double deltaPri=5e5;
+ std::vector<CAmount> feeV[2];
+ std::vector<double> priV[2];
+
+ // Populate vectors of increasing fees or priorities
+ for (int j = 0; j < 10; j++) {
+ //V[0] is for fee transactions
+ feeV[0].push_back(basefee * (j+1));
+ priV[0].push_back(0);
+ //V[1] is for priority transactions
+ feeV[1].push_back(CAmount(0));
+ priV[1].push_back(basepri * pow(10, j+1));
+ }
+
+ // Store the hashes of transactions that have been
+ // added to the mempool by their associate fee/pri
+ // txHashes[j] is populated with transactions either of
+ // fee = basefee * (j+1) OR pri = 10^6 * 10^(j+1)
+ std::vector<uint256> txHashes[10];
+
+ // Create a transaction template
+ CScript garbage;
+ for (unsigned int i = 0; i < 128; i++)
+ garbage.push_back('X');
+ CMutableTransaction tx;
+ std::list<CTransaction> dummyConflicted;
+ tx.vin.resize(1);
+ tx.vin[0].scriptSig = garbage;
+ tx.vout.resize(1);
+ tx.vout[0].nValue=0LL;
+ CFeeRate baseRate(basefee, ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION));
+
+ // Create a fake block
+ std::vector<CTransaction> block;
+ int blocknum = 0;
+
+ // Loop through 200 blocks
+ // At a decay .998 and 4 fee transactions per block
+ // This makes the tx count about 1.33 per bucket, above the 1 threshold
+ while (blocknum < 200) {
+ for (int j = 0; j < 10; j++) { // For each fee/pri multiple
+ for (int k = 0; k < 5; k++) { // add 4 fee txs for every priority tx
+ tx.vin[0].prevout.n = 10000*blocknum+100*j+k; // make transaction unique
+ uint256 hash = tx.GetHash();
+ mpool.addUnchecked(hash, CTxMemPoolEntry(tx, feeV[k/4][j], GetTime(), priV[k/4][j], blocknum, mpool.HasNoInputsOf(tx)));
+ txHashes[j].push_back(hash);
+ }
+ }
+ //Create blocks where higher fee/pri txs are included more often
+ for (int h = 0; h <= blocknum%10; h++) {
+ // 10/10 blocks add highest fee/pri transactions
+ // 9/10 blocks add 2nd highest and so on until ...
+ // 1/10 blocks add lowest fee/pri transactions
+ while (txHashes[9-h].size()) {
+ CTransaction btx;
+ if (mpool.lookup(txHashes[9-h].back(), btx))
+ block.push_back(btx);
+ txHashes[9-h].pop_back();
+ }
+ }
+ mpool.removeForBlock(block, ++blocknum, dummyConflicted);
+ block.clear();
+ if (blocknum == 30) {
+ // At this point we should need to combine 5 buckets to get enough data points
+ // So estimateFee(1) should fail and estimateFee(2) should return somewhere around
+ // 8*baserate
+ BOOST_CHECK(mpool.estimateFee(1) == CFeeRate(0));
+ BOOST_CHECK(mpool.estimateFee(2).GetFeePerK() < 8*baseRate.GetFeePerK() + deltaFee);
+ BOOST_CHECK(mpool.estimateFee(2).GetFeePerK() > 8*baseRate.GetFeePerK() - deltaFee);
+ }
+ }
+
+ std::vector<CAmount> origFeeEst;
+ std::vector<double> origPriEst;
+ // Highest feerate is 10*baseRate and gets in all blocks,
+ // second highest feerate is 9*baseRate and gets in 9/10 blocks = 90%,
+ // third highest feerate is 8*base rate, and gets in 8/10 blocks = 80%,
+ // so estimateFee(1) should return 9*baseRate.
+ // Third highest feerate has 90% chance of being included by 2 blocks,
+ // so estimateFee(2) should return 8*baseRate etc...
+ for (int i = 1; i < 10;i++) {
+ origFeeEst.push_back(mpool.estimateFee(i).GetFeePerK());
+ origPriEst.push_back(mpool.estimatePriority(i));
+ if (i > 1) { // Fee estimates should be monotonically decreasing
+ BOOST_CHECK(origFeeEst[i-1] <= origFeeEst[i-2]);
+ BOOST_CHECK(origPriEst[i-1] <= origPriEst[i-2]);
+ }
+ BOOST_CHECK(origFeeEst[i-1] < (10-i)*baseRate.GetFeePerK() + deltaFee);
+ BOOST_CHECK(origFeeEst[i-1] > (10-i)*baseRate.GetFeePerK() - deltaFee);
+ BOOST_CHECK(origPriEst[i-1] < pow(10,10-i) * basepri + deltaPri);
+ BOOST_CHECK(origPriEst[i-1] > pow(10,10-i) * basepri - deltaPri);
+ }
+
+ // Mine 50 more blocks with no transactions happening, estimates shouldn't change
+ // We haven't decayed the moving average enough so we still have enough data points in every bucket
+ while (blocknum < 250)
+ mpool.removeForBlock(block, ++blocknum, dummyConflicted);
+
+ for (int i = 1; i < 10;i++) {
+ BOOST_CHECK(mpool.estimateFee(i).GetFeePerK() < origFeeEst[i-1] + deltaFee);
+ BOOST_CHECK(mpool.estimateFee(i).GetFeePerK() > origFeeEst[i-1] - deltaFee);
+ BOOST_CHECK(mpool.estimatePriority(i) < origPriEst[i-1] + deltaPri);
+ BOOST_CHECK(mpool.estimatePriority(i) > origPriEst[i-1] - deltaPri);
+ }
+
+
+ // Mine 15 more blocks with lots of transactions happening and not getting mined
+ // Estimates should go up
+ while (blocknum < 265) {
+ for (int j = 0; j < 10; j++) { // For each fee/pri multiple
+ for (int k = 0; k < 5; k++) { // add 4 fee txs for every priority tx
+ tx.vin[0].prevout.n = 10000*blocknum+100*j+k;
+ uint256 hash = tx.GetHash();
+ mpool.addUnchecked(hash, CTxMemPoolEntry(tx, feeV[k/4][j], GetTime(), priV[k/4][j], blocknum, mpool.HasNoInputsOf(tx)));
+ txHashes[j].push_back(hash);
+ }
+ }
+ mpool.removeForBlock(block, ++blocknum, dummyConflicted);
+ }
+
+ for (int i = 1; i < 10;i++) {
+ BOOST_CHECK(mpool.estimateFee(i).GetFeePerK() > origFeeEst[i-1] - deltaFee);
+ BOOST_CHECK(mpool.estimatePriority(i) > origPriEst[i-1] - deltaPri);
+ }
+
+ // Mine all those transactions
+ // Estimates should still not be below original
+ for (int j = 0; j < 10; j++) {
+ while(txHashes[j].size()) {
+ CTransaction btx;
+ if (mpool.lookup(txHashes[j].back(), btx))
+ block.push_back(btx);
+ txHashes[j].pop_back();
+ }
+ }
+ mpool.removeForBlock(block, 265, dummyConflicted);
+ block.clear();
+ for (int i = 1; i < 10;i++) {
+ BOOST_CHECK(mpool.estimateFee(i).GetFeePerK() > origFeeEst[i-1] - deltaFee);
+ BOOST_CHECK(mpool.estimatePriority(i) > origPriEst[i-1] - deltaPri);
+ }
+
+ // Mine 100 more blocks where everything is mined every block
+ // Estimates should be below original estimates (not possible for last estimate)
+ while (blocknum < 365) {
+ for (int j = 0; j < 10; j++) { // For each fee/pri multiple
+ for (int k = 0; k < 5; k++) { // add 4 fee txs for every priority tx
+ tx.vin[0].prevout.n = 10000*blocknum+100*j+k;
+ uint256 hash = tx.GetHash();
+ mpool.addUnchecked(hash, CTxMemPoolEntry(tx, feeV[k/4][j], GetTime(), priV[k/4][j], blocknum, mpool.HasNoInputsOf(tx)));
+ CTransaction btx;
+ if (mpool.lookup(hash, btx))
+ block.push_back(btx);
+ }
+ }
+ mpool.removeForBlock(block, ++blocknum, dummyConflicted);
+ block.clear();
+ }
+ for (int i = 1; i < 9; i++) {
+ BOOST_CHECK(mpool.estimateFee(i).GetFeePerK() < origFeeEst[i-1] - deltaFee);
+ BOOST_CHECK(mpool.estimatePriority(i) < origPriEst[i-1] - deltaPri);
+ }
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/pow_tests.cpp b/src/test/pow_tests.cpp
new file mode 100644
index 0000000000..a436749287
--- /dev/null
+++ b/src/test/pow_tests.cpp
@@ -0,0 +1,96 @@
+// Copyright (c) 2015 The Bitcoin Core 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 "pow.h"
+#include "util.h"
+#include "test/test_bitcoin.h"
+
+#include <boost/test/unit_test.hpp>
+
+using namespace std;
+
+BOOST_FIXTURE_TEST_SUITE(pow_tests, BasicTestingSetup)
+
+/* Test calculation of next difficulty target with no constraints applying */
+BOOST_AUTO_TEST_CASE(get_next_work)
+{
+ SelectParams(CBaseChainParams::MAIN);
+ const Consensus::Params& params = Params().GetConsensus();
+
+ int64_t nLastRetargetTime = 1261130161; // Block #30240
+ CBlockIndex pindexLast;
+ pindexLast.nHeight = 32255;
+ pindexLast.nTime = 1262152739; // Block #32255
+ pindexLast.nBits = 0x1d00ffff;
+ BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, params), 0x1d00d86a);
+}
+
+/* Test the constraint on the upper bound for next work */
+BOOST_AUTO_TEST_CASE(get_next_work_pow_limit)
+{
+ SelectParams(CBaseChainParams::MAIN);
+ const Consensus::Params& params = Params().GetConsensus();
+
+ int64_t nLastRetargetTime = 1231006505; // Block #0
+ CBlockIndex pindexLast;
+ pindexLast.nHeight = 2015;
+ pindexLast.nTime = 1233061996; // Block #2015
+ pindexLast.nBits = 0x1d00ffff;
+ BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, params), 0x1d00ffff);
+}
+
+/* Test the constraint on the lower bound for actual time taken */
+BOOST_AUTO_TEST_CASE(get_next_work_lower_limit_actual)
+{
+ SelectParams(CBaseChainParams::MAIN);
+ const Consensus::Params& params = Params().GetConsensus();
+
+ int64_t nLastRetargetTime = 1279008237; // Block #66528
+ CBlockIndex pindexLast;
+ pindexLast.nHeight = 68543;
+ pindexLast.nTime = 1279297671; // Block #68543
+ pindexLast.nBits = 0x1c05a3f4;
+ BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, params), 0x1c0168fd);
+}
+
+/* Test the constraint on the upper bound for actual time taken */
+BOOST_AUTO_TEST_CASE(get_next_work_upper_limit_actual)
+{
+ SelectParams(CBaseChainParams::MAIN);
+ const Consensus::Params& params = Params().GetConsensus();
+
+ int64_t nLastRetargetTime = 1263163443; // NOTE: Not an actual block time
+ CBlockIndex pindexLast;
+ pindexLast.nHeight = 46367;
+ pindexLast.nTime = 1269211443; // Block #46367
+ pindexLast.nBits = 0x1c387f6f;
+ BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, params), 0x1d00e1fd);
+}
+
+BOOST_AUTO_TEST_CASE(GetBlockProofEquivalentTime_test)
+{
+ SelectParams(CBaseChainParams::MAIN);
+ const Consensus::Params& params = Params().GetConsensus();
+
+ std::vector<CBlockIndex> blocks(10000);
+ for (int i = 0; i < 10000; i++) {
+ blocks[i].pprev = i ? &blocks[i - 1] : NULL;
+ blocks[i].nHeight = i;
+ blocks[i].nTime = 1269211443 + i * params.nPowTargetSpacing;
+ blocks[i].nBits = 0x207fffff; /* target 0x7fffff000... */
+ blocks[i].nChainWork = i ? blocks[i - 1].nChainWork + GetBlockProof(blocks[i - 1]) : arith_uint256(0);
+ }
+
+ for (int j = 0; j < 1000; j++) {
+ CBlockIndex *p1 = &blocks[GetRand(10000)];
+ CBlockIndex *p2 = &blocks[GetRand(10000)];
+ CBlockIndex *p3 = &blocks[GetRand(10000)];
+
+ int64_t tdiff = GetBlockProofEquivalentTime(*p1, *p2, *p3, params);
+ BOOST_CHECK_EQUAL(tdiff, p1->GetBlockTime() - p2->GetBlockTime());
+ }
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/reverselock_tests.cpp b/src/test/reverselock_tests.cpp
new file mode 100644
index 0000000000..e7e627ae0f
--- /dev/null
+++ b/src/test/reverselock_tests.cpp
@@ -0,0 +1,64 @@
+// Copyright (c) 2015 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "reverselock.h"
+#include "test/test_bitcoin.h"
+
+#include <boost/test/unit_test.hpp>
+
+BOOST_FIXTURE_TEST_SUITE(reverselock_tests, BasicTestingSetup)
+
+BOOST_AUTO_TEST_CASE(reverselock_basics)
+{
+ boost::mutex mutex;
+ boost::unique_lock<boost::mutex> lock(mutex);
+
+ BOOST_CHECK(lock.owns_lock());
+ {
+ reverse_lock<boost::unique_lock<boost::mutex> > rlock(lock);
+ BOOST_CHECK(!lock.owns_lock());
+ }
+ BOOST_CHECK(lock.owns_lock());
+}
+
+BOOST_AUTO_TEST_CASE(reverselock_errors)
+{
+ boost::mutex mutex;
+ boost::unique_lock<boost::mutex> lock(mutex);
+
+ // Make sure trying to reverse lock an unlocked lock fails
+ lock.unlock();
+
+ BOOST_CHECK(!lock.owns_lock());
+
+ bool failed = false;
+ try {
+ reverse_lock<boost::unique_lock<boost::mutex> > rlock(lock);
+ } catch(...) {
+ failed = true;
+ }
+
+ BOOST_CHECK(failed);
+ BOOST_CHECK(!lock.owns_lock());
+
+ // Make sure trying to lock a lock after it has been reverse locked fails
+ failed = false;
+ bool locked = false;
+
+ lock.lock();
+ BOOST_CHECK(lock.owns_lock());
+
+ try {
+ reverse_lock<boost::unique_lock<boost::mutex> > rlock(lock);
+ lock.lock();
+ locked = true;
+ } catch(...) {
+ failed = true;
+ }
+
+ BOOST_CHECK(locked && failed);
+ BOOST_CHECK(lock.owns_lock());
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp
new file mode 100644
index 0000000000..5899671d2f
--- /dev/null
+++ b/src/test/rpc_tests.cpp
@@ -0,0 +1,176 @@
+// Copyright (c) 2012-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "rpcserver.h"
+#include "rpcclient.h"
+
+#include "base58.h"
+#include "netbase.h"
+
+#include "test/test_bitcoin.h"
+
+#include <boost/algorithm/string.hpp>
+#include <boost/test/unit_test.hpp>
+
+using namespace std;
+using namespace json_spirit;
+
+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(address2);
+ result.push_back(addresses);
+ return result;
+}
+
+Value CallRPC(string args)
+{
+ vector<string> vArgs;
+ boost::split(vArgs, args, boost::is_any_of(" \t"));
+ string strMethod = vArgs[0];
+ vArgs.erase(vArgs.begin());
+ Array params = RPCConvertValues(strMethod, vArgs);
+
+ rpcfn_type method = tableRPC[strMethod]->actor;
+ try {
+ Value result = (*method)(params, false);
+ return result;
+ }
+ catch (const Object& objError) {
+ throw runtime_error(find_value(objError, "message").get_str());
+ }
+}
+
+
+BOOST_FIXTURE_TEST_SUITE(rpc_tests, TestingSetup)
+
+BOOST_AUTO_TEST_CASE(rpc_rawparams)
+{
+ // Test raw transaction API argument handling
+ Value r;
+
+ BOOST_CHECK_THROW(CallRPC("getrawtransaction"), runtime_error);
+ BOOST_CHECK_THROW(CallRPC("getrawtransaction not_hex"), runtime_error);
+ BOOST_CHECK_THROW(CallRPC("getrawtransaction a3b807410df0b60fcb9736768df5823938b2f838694939ba45f3c0a1bff150ed not_int"), runtime_error);
+
+ BOOST_CHECK_THROW(CallRPC("createrawtransaction"), runtime_error);
+ BOOST_CHECK_THROW(CallRPC("createrawtransaction null null"), runtime_error);
+ BOOST_CHECK_THROW(CallRPC("createrawtransaction not_array"), runtime_error);
+ BOOST_CHECK_THROW(CallRPC("createrawtransaction [] []"), runtime_error);
+ BOOST_CHECK_THROW(CallRPC("createrawtransaction {} {}"), runtime_error);
+ BOOST_CHECK_NO_THROW(CallRPC("createrawtransaction [] {}"));
+ BOOST_CHECK_THROW(CallRPC("createrawtransaction [] {} extra"), runtime_error);
+
+ BOOST_CHECK_THROW(CallRPC("decoderawtransaction"), runtime_error);
+ BOOST_CHECK_THROW(CallRPC("decoderawtransaction null"), runtime_error);
+ BOOST_CHECK_THROW(CallRPC("decoderawtransaction DEADBEEF"), runtime_error);
+ string rawtx = "0100000001a15d57094aa7a21a28cb20b59aab8fc7d1149a3bdbcddba9c622e4f5f6a99ece010000006c493046022100f93bb0e7d8db7bd46e40132d1f8242026e045f03a0efe71bbb8e3f475e970d790221009337cd7f1f929f00cc6ff01f03729b069a7c21b59b1736ddfee5db5946c5da8c0121033b9b137ee87d5a812d6f506efdd37f0affa7ffc310711c06c7f3e097c9447c52ffffffff0100e1f505000000001976a9140389035a9225b3839e2bbf32d826a1e222031fd888ac00000000";
+ BOOST_CHECK_NO_THROW(r = CallRPC(string("decoderawtransaction ")+rawtx));
+ BOOST_CHECK_EQUAL(find_value(r.get_obj(), "version").get_int(), 1);
+ BOOST_CHECK_EQUAL(find_value(r.get_obj(), "locktime").get_int(), 0);
+ BOOST_CHECK_THROW(r = CallRPC(string("decoderawtransaction ")+rawtx+" extra"), runtime_error);
+
+ BOOST_CHECK_THROW(CallRPC("signrawtransaction"), runtime_error);
+ BOOST_CHECK_THROW(CallRPC("signrawtransaction null"), runtime_error);
+ BOOST_CHECK_THROW(CallRPC("signrawtransaction ff00"), runtime_error);
+ BOOST_CHECK_NO_THROW(CallRPC(string("signrawtransaction ")+rawtx));
+ BOOST_CHECK_NO_THROW(CallRPC(string("signrawtransaction ")+rawtx+" null null NONE|ANYONECANPAY"));
+ BOOST_CHECK_NO_THROW(CallRPC(string("signrawtransaction ")+rawtx+" [] [] NONE|ANYONECANPAY"));
+ BOOST_CHECK_THROW(CallRPC(string("signrawtransaction ")+rawtx+" null null badenum"), runtime_error);
+
+ // Only check failure cases for sendrawtransaction, there's no network to send to...
+ BOOST_CHECK_THROW(CallRPC("sendrawtransaction"), runtime_error);
+ BOOST_CHECK_THROW(CallRPC("sendrawtransaction null"), runtime_error);
+ BOOST_CHECK_THROW(CallRPC("sendrawtransaction DEADBEEF"), runtime_error);
+ BOOST_CHECK_THROW(CallRPC(string("sendrawtransaction ")+rawtx+" extra"), runtime_error);
+}
+
+BOOST_AUTO_TEST_CASE(rpc_rawsign)
+{
+ Value r;
+ // input is a 1-of-2 multisig (so is output):
+ string prevout =
+ "[{\"txid\":\"b4cc287e58f87cdae59417329f710f3ecd75a4ee1d2872b7248f50977c8493f3\","
+ "\"vout\":1,\"scriptPubKey\":\"a914b10c9df5f7edf436c697f02f1efdba4cf399615187\","
+ "\"redeemScript\":\"512103debedc17b3df2badbcdd86d5feb4562b86fe182e5998abd8bcd4f122c6155b1b21027e940bb73ab8732bfdf7f9216ecefca5b94d6df834e77e108f68e66f126044c052ae\"}]";
+ r = CallRPC(string("createrawtransaction ")+prevout+" "+
+ "{\"3HqAe9LtNBjnsfM4CyYaWTnvCaUYT7v4oZ\":11}");
+ string notsigned = r.get_str();
+ string privkey1 = "\"KzsXybp9jX64P5ekX1KUxRQ79Jht9uzW7LorgwE65i5rWACL6LQe\"";
+ string privkey2 = "\"Kyhdf5LuKTRx4ge69ybABsiUAWjVRK4XGxAKk2FQLp2HjGMy87Z4\"";
+ r = CallRPC(string("signrawtransaction ")+notsigned+" "+prevout+" "+"[]");
+ BOOST_CHECK(find_value(r.get_obj(), "complete").get_bool() == false);
+ r = CallRPC(string("signrawtransaction ")+notsigned+" "+prevout+" "+"["+privkey1+","+privkey2+"]");
+ BOOST_CHECK(find_value(r.get_obj(), "complete").get_bool() == true);
+}
+
+BOOST_AUTO_TEST_CASE(rpc_format_monetary_values)
+{
+ BOOST_CHECK_EQUAL(write_string(ValueFromAmount(0LL), false), "0.00000000");
+ BOOST_CHECK_EQUAL(write_string(ValueFromAmount(1LL), false), "0.00000001");
+ BOOST_CHECK_EQUAL(write_string(ValueFromAmount(17622195LL), false), "0.17622195");
+ BOOST_CHECK_EQUAL(write_string(ValueFromAmount(50000000LL), false), "0.50000000");
+ BOOST_CHECK_EQUAL(write_string(ValueFromAmount(89898989LL), false), "0.89898989");
+ BOOST_CHECK_EQUAL(write_string(ValueFromAmount(100000000LL), false), "1.00000000");
+ BOOST_CHECK_EQUAL(write_string(ValueFromAmount(2099999999999990LL), false), "20999999.99999990");
+ BOOST_CHECK_EQUAL(write_string(ValueFromAmount(2099999999999999LL), false), "20999999.99999999");
+}
+
+static Value ValueFromString(const std::string &str)
+{
+ Value value;
+ BOOST_CHECK(read_string(str, value));
+ return value;
+}
+
+BOOST_AUTO_TEST_CASE(rpc_parse_monetary_values)
+{
+ BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0.00000001")), 1LL);
+ BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0.17622195")), 17622195LL);
+ BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0.5")), 50000000LL);
+ BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0.50000000")), 50000000LL);
+ BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0.89898989")), 89898989LL);
+ BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("1.00000000")), 100000000LL);
+ BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("20999999.9999999")), 2099999999999990LL);
+ BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("20999999.99999999")), 2099999999999999LL);
+}
+
+BOOST_AUTO_TEST_CASE(json_parse_errors)
+{
+ Value value;
+ // Valid
+ BOOST_CHECK_EQUAL(read_string(std::string("1.0"), value), true);
+ // Valid, with trailing whitespace
+ BOOST_CHECK_EQUAL(read_string(std::string("1.0 "), value), true);
+ // Invalid, initial garbage
+ BOOST_CHECK_EQUAL(read_string(std::string("[1.0"), value), false);
+ BOOST_CHECK_EQUAL(read_string(std::string("a1.0"), value), false);
+ // Invalid, trailing garbage
+ BOOST_CHECK_EQUAL(read_string(std::string("1.0sds"), value), false);
+ BOOST_CHECK_EQUAL(read_string(std::string("1.0]"), value), false);
+ // BTC addresses should fail parsing
+ BOOST_CHECK_EQUAL(read_string(std::string("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W"), value), false);
+ BOOST_CHECK_EQUAL(read_string(std::string("3J98t1WpEZ73CNmQviecrnyiWrnqRhWNL"), value), false);
+}
+
+BOOST_AUTO_TEST_CASE(rpc_boostasiotocnetaddr)
+{
+ // Check IPv4 addresses
+ BOOST_CHECK_EQUAL(BoostAsioToCNetAddr(boost::asio::ip::address::from_string("1.2.3.4")).ToString(), "1.2.3.4");
+ BOOST_CHECK_EQUAL(BoostAsioToCNetAddr(boost::asio::ip::address::from_string("127.0.0.1")).ToString(), "127.0.0.1");
+ // Check IPv6 addresses
+ BOOST_CHECK_EQUAL(BoostAsioToCNetAddr(boost::asio::ip::address::from_string("::1")).ToString(), "::1");
+ BOOST_CHECK_EQUAL(BoostAsioToCNetAddr(boost::asio::ip::address::from_string("123:4567:89ab:cdef:123:4567:89ab:cdef")).ToString(),
+ "123:4567:89ab:cdef:123:4567:89ab:cdef");
+ // v4 compatible must be interpreted as IPv4
+ BOOST_CHECK_EQUAL(BoostAsioToCNetAddr(boost::asio::ip::address::from_string("::0:127.0.0.1")).ToString(), "127.0.0.1");
+ // v4 mapped must be interpreted as IPv4
+ BOOST_CHECK_EQUAL(BoostAsioToCNetAddr(boost::asio::ip::address::from_string("::ffff:127.0.0.1")).ToString(), "127.0.0.1");
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/rpc_wallet_tests.cpp b/src/test/rpc_wallet_tests.cpp
new file mode 100644
index 0000000000..4d5e92cbd4
--- /dev/null
+++ b/src/test/rpc_wallet_tests.cpp
@@ -0,0 +1,221 @@
+// Copyright (c) 2013-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "rpcserver.h"
+#include "rpcclient.h"
+
+#include "base58.h"
+#include "main.h"
+#include "wallet/wallet.h"
+
+#include "test/test_bitcoin.h"
+
+#include <boost/algorithm/string.hpp>
+#include <boost/test/unit_test.hpp>
+
+using namespace std;
+using namespace json_spirit;
+
+extern Array createArgs(int nRequired, const char* address1 = NULL, const char* address2 = NULL);
+extern Value CallRPC(string args);
+
+extern CWallet* pwalletMain;
+
+BOOST_FIXTURE_TEST_SUITE(rpc_wallet_tests, TestingSetup)
+
+BOOST_AUTO_TEST_CASE(rpc_addmultisig)
+{
+ LOCK(pwalletMain->cs_wallet);
+
+ 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_CASE(rpc_wallet)
+{
+ // Test RPC calls for various wallet statistics
+ Value r;
+
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
+ CPubKey demoPubkey = pwalletMain->GenerateNewKey();
+ CBitcoinAddress demoAddress = CBitcoinAddress(CTxDestination(demoPubkey.GetID()));
+ Value retValue;
+ string strAccount = "walletDemoAccount";
+ string strPurpose = "receive";
+ BOOST_CHECK_NO_THROW({ /*Initialize Wallet with an account */
+ CWalletDB walletdb(pwalletMain->strWalletFile);
+ CAccount account;
+ account.vchPubKey = demoPubkey;
+ pwalletMain->SetAddressBook(account.vchPubKey.GetID(), strAccount, strPurpose);
+ walletdb.WriteAccount(strAccount, account);
+ });
+
+ CPubKey setaccountDemoPubkey = pwalletMain->GenerateNewKey();
+ CBitcoinAddress setaccountDemoAddress = CBitcoinAddress(CTxDestination(setaccountDemoPubkey.GetID()));
+
+ /*********************************
+ * setaccount
+ *********************************/
+ BOOST_CHECK_NO_THROW(CallRPC("setaccount " + setaccountDemoAddress.ToString() + " nullaccount"));
+ /* 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ is not owned by the test wallet. */
+ BOOST_CHECK_THROW(CallRPC("setaccount 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ nullaccount"), runtime_error);
+ BOOST_CHECK_THROW(CallRPC("setaccount"), runtime_error);
+ /* 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4X (33 chars) is an illegal address (should be 34 chars) */
+ BOOST_CHECK_THROW(CallRPC("setaccount 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4X nullaccount"), runtime_error);
+
+
+ /*********************************
+ * getbalance
+ *********************************/
+ BOOST_CHECK_NO_THROW(CallRPC("getbalance"));
+ BOOST_CHECK_NO_THROW(CallRPC("getbalance " + demoAddress.ToString()));
+
+ /*********************************
+ * listunspent
+ *********************************/
+ BOOST_CHECK_NO_THROW(CallRPC("listunspent"));
+ BOOST_CHECK_THROW(CallRPC("listunspent string"), runtime_error);
+ BOOST_CHECK_THROW(CallRPC("listunspent 0 string"), runtime_error);
+ BOOST_CHECK_THROW(CallRPC("listunspent 0 1 not_array"), runtime_error);
+ BOOST_CHECK_THROW(CallRPC("listunspent 0 1 [] extra"), runtime_error);
+ BOOST_CHECK_NO_THROW(r = CallRPC("listunspent 0 1 []"));
+ BOOST_CHECK(r.get_array().empty());
+
+ /*********************************
+ * listreceivedbyaddress
+ *********************************/
+ BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaddress"));
+ BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaddress 0"));
+ BOOST_CHECK_THROW(CallRPC("listreceivedbyaddress not_int"), runtime_error);
+ BOOST_CHECK_THROW(CallRPC("listreceivedbyaddress 0 not_bool"), runtime_error);
+ BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaddress 0 true"));
+ BOOST_CHECK_THROW(CallRPC("listreceivedbyaddress 0 true extra"), runtime_error);
+
+ /*********************************
+ * listreceivedbyaccount
+ *********************************/
+ BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaccount"));
+ BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaccount 0"));
+ BOOST_CHECK_THROW(CallRPC("listreceivedbyaccount not_int"), runtime_error);
+ BOOST_CHECK_THROW(CallRPC("listreceivedbyaccount 0 not_bool"), runtime_error);
+ BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaccount 0 true"));
+ BOOST_CHECK_THROW(CallRPC("listreceivedbyaccount 0 true extra"), runtime_error);
+
+ /*********************************
+ * listsinceblock
+ *********************************/
+ BOOST_CHECK_NO_THROW(CallRPC("listsinceblock"));
+
+ /*********************************
+ * listtransactions
+ *********************************/
+ BOOST_CHECK_NO_THROW(CallRPC("listtransactions"));
+ BOOST_CHECK_NO_THROW(CallRPC("listtransactions " + demoAddress.ToString()));
+ BOOST_CHECK_NO_THROW(CallRPC("listtransactions " + demoAddress.ToString() + " 20"));
+ BOOST_CHECK_NO_THROW(CallRPC("listtransactions " + demoAddress.ToString() + " 20 0"));
+ BOOST_CHECK_THROW(CallRPC("listtransactions " + demoAddress.ToString() + " not_int"), runtime_error);
+
+ /*********************************
+ * listlockunspent
+ *********************************/
+ BOOST_CHECK_NO_THROW(CallRPC("listlockunspent"));
+
+ /*********************************
+ * listaccounts
+ *********************************/
+ BOOST_CHECK_NO_THROW(CallRPC("listaccounts"));
+
+ /*********************************
+ * listaddressgroupings
+ *********************************/
+ BOOST_CHECK_NO_THROW(CallRPC("listaddressgroupings"));
+
+ /*********************************
+ * getrawchangeaddress
+ *********************************/
+ BOOST_CHECK_NO_THROW(CallRPC("getrawchangeaddress"));
+
+ /*********************************
+ * getnewaddress
+ *********************************/
+ BOOST_CHECK_NO_THROW(CallRPC("getnewaddress"));
+ BOOST_CHECK_NO_THROW(CallRPC("getnewaddress getnewaddress_demoaccount"));
+
+ /*********************************
+ * getaccountaddress
+ *********************************/
+ BOOST_CHECK_NO_THROW(CallRPC("getaccountaddress \"\""));
+ BOOST_CHECK_NO_THROW(CallRPC("getaccountaddress accountThatDoesntExists")); // Should generate a new account
+ BOOST_CHECK_NO_THROW(retValue = CallRPC("getaccountaddress " + strAccount));
+ BOOST_CHECK(CBitcoinAddress(retValue.get_str()).Get() == demoAddress.Get());
+
+ /*********************************
+ * getaccount
+ *********************************/
+ BOOST_CHECK_THROW(CallRPC("getaccount"), runtime_error);
+ BOOST_CHECK_NO_THROW(CallRPC("getaccount " + demoAddress.ToString()));
+
+ /*********************************
+ * signmessage + verifymessage
+ *********************************/
+ BOOST_CHECK_NO_THROW(retValue = CallRPC("signmessage " + demoAddress.ToString() + " mymessage"));
+ BOOST_CHECK_THROW(CallRPC("signmessage"), runtime_error);
+ /* Should throw error because this address is not loaded in the wallet */
+ BOOST_CHECK_THROW(CallRPC("signmessage 1QFqqMUD55ZV3PJEJZtaKCsQmjLT6JkjvJ mymessage"), runtime_error);
+
+ /* missing arguments */
+ BOOST_CHECK_THROW(CallRPC("verifymessage " + demoAddress.ToString()), runtime_error);
+ BOOST_CHECK_THROW(CallRPC("verifymessage " + demoAddress.ToString() + " " + retValue.get_str()), runtime_error);
+ /* Illegal address */
+ BOOST_CHECK_THROW(CallRPC("verifymessage 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4X " + retValue.get_str() + " mymessage"), runtime_error);
+ /* wrong address */
+ BOOST_CHECK(CallRPC("verifymessage 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ " + retValue.get_str() + " mymessage").get_bool() == false);
+ /* Correct address and signature but wrong message */
+ BOOST_CHECK(CallRPC("verifymessage " + demoAddress.ToString() + " " + retValue.get_str() + " wrongmessage").get_bool() == false);
+ /* Correct address, message and signature*/
+ BOOST_CHECK(CallRPC("verifymessage " + demoAddress.ToString() + " " + retValue.get_str() + " mymessage").get_bool() == true);
+
+ /*********************************
+ * getaddressesbyaccount
+ *********************************/
+ BOOST_CHECK_THROW(CallRPC("getaddressesbyaccount"), runtime_error);
+ BOOST_CHECK_NO_THROW(retValue = CallRPC("getaddressesbyaccount " + strAccount));
+ Array arr = retValue.get_array();
+ BOOST_CHECK(arr.size() > 0);
+ BOOST_CHECK(CBitcoinAddress(arr[0].get_str()).Get() == demoAddress.Get());
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/sanity_tests.cpp b/src/test/sanity_tests.cpp
new file mode 100644
index 0000000000..f5f7f381d3
--- /dev/null
+++ b/src/test/sanity_tests.cpp
@@ -0,0 +1,20 @@
+// Copyright (c) 2012-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "compat/sanity.h"
+#include "key.h"
+#include "test/test_bitcoin.h"
+
+#include <boost/test/unit_test.hpp>
+
+BOOST_FIXTURE_TEST_SUITE(sanity_tests, BasicTestingSetup)
+
+BOOST_AUTO_TEST_CASE(basic_sanity)
+{
+ BOOST_CHECK_MESSAGE(glibc_sanity_test() == true, "libc sanity test");
+ BOOST_CHECK_MESSAGE(glibcxx_sanity_test() == true, "stdlib sanity test");
+ BOOST_CHECK_MESSAGE(ECC_InitSanityCheck() == true, "openssl ECC test");
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/scheduler_tests.cpp b/src/test/scheduler_tests.cpp
new file mode 100644
index 0000000000..cb1a427db0
--- /dev/null
+++ b/src/test/scheduler_tests.cpp
@@ -0,0 +1,119 @@
+// Copyright (c) 2012-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "random.h"
+#include "scheduler.h"
+
+#include "test/test_bitcoin.h"
+
+#include <boost/bind.hpp>
+#include <boost/random/mersenne_twister.hpp>
+#include <boost/random/uniform_int_distribution.hpp>
+#include <boost/thread.hpp>
+#include <boost/test/unit_test.hpp>
+
+BOOST_AUTO_TEST_SUITE(scheduler_tests)
+
+static void microTask(CScheduler& s, boost::mutex& mutex, int& counter, int delta, boost::chrono::system_clock::time_point rescheduleTime)
+{
+ {
+ boost::unique_lock<boost::mutex> lock(mutex);
+ counter += delta;
+ }
+ boost::chrono::system_clock::time_point noTime = boost::chrono::system_clock::time_point::min();
+ if (rescheduleTime != noTime) {
+ CScheduler::Function f = boost::bind(&microTask, boost::ref(s), boost::ref(mutex), boost::ref(counter), -delta + 1, noTime);
+ s.schedule(f, rescheduleTime);
+ }
+}
+
+static void MicroSleep(uint64_t n)
+{
+#if defined(HAVE_WORKING_BOOST_SLEEP_FOR)
+ boost::this_thread::sleep_for(boost::chrono::microseconds(n));
+#elif defined(HAVE_WORKING_BOOST_SLEEP)
+ boost::this_thread::sleep(boost::posix_time::microseconds(n));
+#else
+ //should never get here
+ #error missing boost sleep implementation
+#endif
+}
+
+BOOST_AUTO_TEST_CASE(manythreads)
+{
+ seed_insecure_rand(false);
+
+ // Stress test: hundreds of microsecond-scheduled tasks,
+ // serviced by 10 threads.
+ //
+ // So... ten shared counters, which if all the tasks execute
+ // properly will sum to the number of tasks done.
+ // Each task adds or subtracts from one of the counters a
+ // random amount, and then schedules another task 0-1000
+ // microseconds in the future to subtract or add from
+ // the counter -random_amount+1, so in the end the shared
+ // counters should sum to the number of initial tasks performed.
+ CScheduler microTasks;
+
+ boost::mutex counterMutex[10];
+ int counter[10] = { 0 };
+ boost::random::mt19937 rng(insecure_rand());
+ boost::random::uniform_int_distribution<> zeroToNine(0, 9);
+ boost::random::uniform_int_distribution<> randomMsec(-11, 1000);
+ boost::random::uniform_int_distribution<> randomDelta(-1000, 1000);
+
+ boost::chrono::system_clock::time_point start = boost::chrono::system_clock::now();
+ boost::chrono::system_clock::time_point now = start;
+ boost::chrono::system_clock::time_point first, last;
+ size_t nTasks = microTasks.getQueueInfo(first, last);
+ BOOST_CHECK(nTasks == 0);
+
+ for (int i = 0; i < 100; i++) {
+ boost::chrono::system_clock::time_point t = now + boost::chrono::microseconds(randomMsec(rng));
+ boost::chrono::system_clock::time_point tReschedule = now + boost::chrono::microseconds(500 + randomMsec(rng));
+ int whichCounter = zeroToNine(rng);
+ CScheduler::Function f = boost::bind(&microTask, boost::ref(microTasks),
+ boost::ref(counterMutex[whichCounter]), boost::ref(counter[whichCounter]),
+ randomDelta(rng), tReschedule);
+ microTasks.schedule(f, t);
+ }
+ nTasks = microTasks.getQueueInfo(first, last);
+ BOOST_CHECK(nTasks == 100);
+ BOOST_CHECK(first < last);
+ BOOST_CHECK(last > now);
+
+ // As soon as these are created they will start running and servicing the queue
+ boost::thread_group microThreads;
+ for (int i = 0; i < 5; i++)
+ microThreads.create_thread(boost::bind(&CScheduler::serviceQueue, &microTasks));
+
+ MicroSleep(600);
+ now = boost::chrono::system_clock::now();
+
+ // More threads and more tasks:
+ for (int i = 0; i < 5; i++)
+ microThreads.create_thread(boost::bind(&CScheduler::serviceQueue, &microTasks));
+ for (int i = 0; i < 100; i++) {
+ boost::chrono::system_clock::time_point t = now + boost::chrono::microseconds(randomMsec(rng));
+ boost::chrono::system_clock::time_point tReschedule = now + boost::chrono::microseconds(500 + randomMsec(rng));
+ int whichCounter = zeroToNine(rng);
+ CScheduler::Function f = boost::bind(&microTask, boost::ref(microTasks),
+ boost::ref(counterMutex[whichCounter]), boost::ref(counter[whichCounter]),
+ randomDelta(rng), tReschedule);
+ microTasks.schedule(f, t);
+ }
+
+ // Drain the task queue then exit threads
+ microTasks.stop(true);
+ microThreads.join_all(); // ... wait until all the threads are done
+
+ int counterSum = 0;
+ for (int i = 0; i < 10; i++) {
+ BOOST_CHECK(counter[i] != 0);
+ counterSum += counter[i];
+ }
+ BOOST_CHECK_EQUAL(counterSum, 200);
+}
+
+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 0000000000..c8cfe28729
--- /dev/null
+++ b/src/test/script_P2SH_tests.cpp
@@ -0,0 +1,382 @@
+// Copyright (c) 2012-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "key.h"
+#include "keystore.h"
+#include "main.h"
+#include "script/script.h"
+#include "script/script_error.h"
+#include "script/sign.h"
+#include "test/test_bitcoin.h"
+
+#ifdef ENABLE_WALLET
+#include "wallet/wallet_ismine.h"
+#endif
+
+#include <vector>
+
+#include <boost/test/unit_test.hpp>
+
+using namespace std;
+
+// Helpers:
+static std::vector<unsigned char>
+Serialize(const CScript& s)
+{
+ std::vector<unsigned char> sSerialized(s);
+ return sSerialized;
+}
+
+static bool
+Verify(const CScript& scriptSig, const CScript& scriptPubKey, bool fStrict, ScriptError& err)
+{
+ // Create dummy to/from transactions:
+ CMutableTransaction txFrom;
+ txFrom.vout.resize(1);
+ txFrom.vout[0].scriptPubKey = scriptPubKey;
+
+ CMutableTransaction 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, fStrict ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE, MutableTransactionSignatureChecker(&txTo, 0), &err);
+}
+
+
+BOOST_FIXTURE_TEST_SUITE(script_P2SH_tests, BasicTestingSetup)
+
+BOOST_AUTO_TEST_CASE(sign)
+{
+ LOCK(cs_main);
+ // Pay-to-script-hash looks like this:
+ // scriptSig: <sig> <sig...> <serialized_script>
+ // scriptPubKey: HASH160 <hash> 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] << ToByteVector(key[0].GetPubKey()) << OP_CHECKSIG;
+ standardScripts[1] = GetScriptForDestination(key[1].GetPubKey().GetID());
+ standardScripts[2] << ToByteVector(key[1].GetPubKey()) << OP_CHECKSIG;
+ standardScripts[3] = GetScriptForDestination(key[2].GetPubKey().GetID());
+ CScript evalScripts[4];
+ for (int i = 0; i < 4; i++)
+ {
+ keystore.AddCScript(standardScripts[i]);
+ evalScripts[i] = GetScriptForDestination(CScriptID(standardScripts[i]));
+ }
+
+ CMutableTransaction txFrom; // Funding transaction:
+ string reason;
+ txFrom.vout.resize(8);
+ for (int i = 0; i < 4; i++)
+ {
+ txFrom.vout[i].scriptPubKey = evalScripts[i];
+ txFrom.vout[i].nValue = COIN;
+ txFrom.vout[i+4].scriptPubKey = standardScripts[i];
+ txFrom.vout[i+4].nValue = COIN;
+ }
+ BOOST_CHECK(IsStandardTx(txFrom, reason));
+
+ CMutableTransaction 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;
+#ifdef ENABLE_WALLET
+ BOOST_CHECK_MESSAGE(IsMine(keystore, txFrom.vout[i].scriptPubKey), strprintf("IsMine %d", i));
+#endif
+ }
+ 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 = CScriptCheck(CCoins(txFrom, 0), txTo[i], 0, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC, false)();
+ 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)
+{
+ ScriptError err;
+ // Make sure only the outer pay-to-script-hash does the
+ // extra-validation thing:
+ CScript invalidAsScript;
+ invalidAsScript << OP_INVALIDOPCODE << OP_INVALIDOPCODE;
+
+ CScript p2sh = GetScriptForDestination(CScriptID(invalidAsScript));
+
+ CScript scriptSig;
+ scriptSig << Serialize(invalidAsScript);
+
+ // Should not verify, because it will try to execute OP_INVALIDOPCODE
+ BOOST_CHECK(!Verify(scriptSig, p2sh, true, err));
+ BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_BAD_OPCODE, ScriptErrorString(err));
+
+ // Try to recur, and verification should succeed because
+ // the inner HASH160 <> EQUAL should only check the hash:
+ CScript p2sh2 = GetScriptForDestination(CScriptID(p2sh));
+ CScript scriptSig2;
+ scriptSig2 << Serialize(invalidAsScript) << Serialize(p2sh);
+
+ BOOST_CHECK(Verify(scriptSig2, p2sh2, true, err));
+ BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
+}
+
+BOOST_AUTO_TEST_CASE(set)
+{
+ LOCK(cs_main);
+ // Test the CScript::Set* methods
+ CBasicKeyStore keystore;
+ CKey key[4];
+ std::vector<CPubKey> keys;
+ for (int i = 0; i < 4; i++)
+ {
+ key[i].MakeNewKey(true);
+ keystore.AddKey(key[i]);
+ keys.push_back(key[i].GetPubKey());
+ }
+
+ CScript inner[4];
+ inner[0] = GetScriptForDestination(key[0].GetPubKey().GetID());
+ inner[1] = GetScriptForMultisig(2, std::vector<CPubKey>(keys.begin(), keys.begin()+2));
+ inner[2] = GetScriptForMultisig(1, std::vector<CPubKey>(keys.begin(), keys.begin()+2));
+ inner[3] = GetScriptForMultisig(2, std::vector<CPubKey>(keys.begin(), keys.begin()+3));
+
+ CScript outer[4];
+ for (int i = 0; i < 4; i++)
+ {
+ outer[i] = GetScriptForDestination(CScriptID(inner[i]));
+ keystore.AddCScript(inner[i]);
+ }
+
+ CMutableTransaction txFrom; // Funding transaction:
+ string reason;
+ txFrom.vout.resize(4);
+ for (int i = 0; i < 4; i++)
+ {
+ txFrom.vout[i].scriptPubKey = outer[i];
+ txFrom.vout[i].nValue = CENT;
+ }
+ BOOST_CHECK(IsStandardTx(txFrom, reason));
+
+ CMutableTransaction 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*CENT;
+ txTo[i].vout[0].scriptPubKey = inner[i];
+#ifdef ENABLE_WALLET
+ BOOST_CHECK_MESSAGE(IsMine(keystore, txFrom.vout[i].scriptPubKey), strprintf("IsMine %d", i));
+#endif
+ }
+ for (int i = 0; i < 4; i++)
+ {
+ BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], 0), strprintf("SignSignature %d", i));
+ BOOST_CHECK_MESSAGE(IsStandardTx(txTo[i], reason), strprintf("txTo[%d].IsStandard", i));
+ }
+}
+
+BOOST_AUTO_TEST_CASE(is)
+{
+ // Test CScript::IsPayToScriptHash()
+ uint160 dummy;
+ CScript p2sh;
+ p2sh << OP_HASH160 << ToByteVector(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 << ToByteVector(dummy) << ToByteVector(dummy) << OP_EQUAL;
+ BOOST_CHECK(!not_p2sh.IsPayToScriptHash());
+
+ not_p2sh.clear(); not_p2sh << OP_NOP << ToByteVector(dummy) << OP_EQUAL;
+ BOOST_CHECK(!not_p2sh.IsPayToScriptHash());
+
+ not_p2sh.clear(); not_p2sh << OP_HASH160 << ToByteVector(dummy) << OP_CHECKSIG;
+ BOOST_CHECK(!not_p2sh.IsPayToScriptHash());
+}
+
+BOOST_AUTO_TEST_CASE(switchover)
+{
+ // Test switch over code
+ CScript notValid;
+ ScriptError err;
+ notValid << OP_11 << OP_12 << OP_EQUALVERIFY;
+ CScript scriptSig;
+ scriptSig << Serialize(notValid);
+
+ CScript fund = GetScriptForDestination(CScriptID(notValid));
+
+
+ // Validation should succeed under old rules (hash is correct):
+ BOOST_CHECK(Verify(scriptSig, fund, false, err));
+ BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
+ // Fail under new:
+ BOOST_CHECK(!Verify(scriptSig, fund, true, err));
+ BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EQUALVERIFY, ScriptErrorString(err));
+}
+
+BOOST_AUTO_TEST_CASE(AreInputsStandard)
+{
+ LOCK(cs_main);
+ CCoinsView coinsDummy;
+ CCoinsViewCache coins(&coinsDummy);
+ CBasicKeyStore keystore;
+ CKey key[6];
+ vector<CPubKey> keys;
+ for (int i = 0; i < 6; i++)
+ {
+ key[i].MakeNewKey(true);
+ keystore.AddKey(key[i]);
+ }
+ for (int i = 0; i < 3; i++)
+ keys.push_back(key[i].GetPubKey());
+
+ CMutableTransaction txFrom;
+ txFrom.vout.resize(7);
+
+ // First three are standard:
+ CScript pay1 = GetScriptForDestination(key[0].GetPubKey().GetID());
+ keystore.AddCScript(pay1);
+ CScript pay1of3 = GetScriptForMultisig(1, keys);
+
+ txFrom.vout[0].scriptPubKey = GetScriptForDestination(CScriptID(pay1)); // P2SH (OP_CHECKSIG)
+ txFrom.vout[0].nValue = 1000;
+ txFrom.vout[1].scriptPubKey = pay1; // ordinary OP_CHECKSIG
+ txFrom.vout[1].nValue = 2000;
+ txFrom.vout[2].scriptPubKey = pay1of3; // ordinary OP_CHECKMULTISIG
+ txFrom.vout[2].nValue = 3000;
+
+ // vout[3] is complicated 1-of-3 AND 2-of-3
+ // ... that is OK if wrapped in P2SH:
+ CScript oneAndTwo;
+ oneAndTwo << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << ToByteVector(key[2].GetPubKey());
+ oneAndTwo << OP_3 << OP_CHECKMULTISIGVERIFY;
+ oneAndTwo << OP_2 << ToByteVector(key[3].GetPubKey()) << ToByteVector(key[4].GetPubKey()) << ToByteVector(key[5].GetPubKey());
+ oneAndTwo << OP_3 << OP_CHECKMULTISIG;
+ keystore.AddCScript(oneAndTwo);
+ txFrom.vout[3].scriptPubKey = GetScriptForDestination(CScriptID(oneAndTwo));
+ txFrom.vout[3].nValue = 4000;
+
+ // vout[4] is max sigops:
+ CScript fifteenSigops; fifteenSigops << OP_1;
+ for (unsigned i = 0; i < MAX_P2SH_SIGOPS; i++)
+ fifteenSigops << ToByteVector(key[i%3].GetPubKey());
+ fifteenSigops << OP_15 << OP_CHECKMULTISIG;
+ keystore.AddCScript(fifteenSigops);
+ txFrom.vout[4].scriptPubKey = GetScriptForDestination(CScriptID(fifteenSigops));
+ txFrom.vout[4].nValue = 5000;
+
+ // vout[5/6] are non-standard because they exceed MAX_P2SH_SIGOPS
+ CScript sixteenSigops; sixteenSigops << OP_16 << OP_CHECKMULTISIG;
+ keystore.AddCScript(sixteenSigops);
+ txFrom.vout[5].scriptPubKey = GetScriptForDestination(CScriptID(fifteenSigops));
+ txFrom.vout[5].nValue = 5000;
+ CScript twentySigops; twentySigops << OP_CHECKMULTISIG;
+ keystore.AddCScript(twentySigops);
+ txFrom.vout[6].scriptPubKey = GetScriptForDestination(CScriptID(twentySigops));
+ txFrom.vout[6].nValue = 6000;
+
+ coins.ModifyCoins(txFrom.GetHash())->FromTx(txFrom, 0);
+
+ CMutableTransaction txTo;
+ txTo.vout.resize(1);
+ txTo.vout[0].scriptPubKey = GetScriptForDestination(key[1].GetPubKey().GetID());
+
+ txTo.vin.resize(5);
+ for (int i = 0; i < 5; i++)
+ {
+ txTo.vin[i].prevout.n = i;
+ txTo.vin[i].prevout.hash = txFrom.GetHash();
+ }
+ BOOST_CHECK(SignSignature(keystore, txFrom, txTo, 0));
+ BOOST_CHECK(SignSignature(keystore, txFrom, txTo, 1));
+ BOOST_CHECK(SignSignature(keystore, txFrom, txTo, 2));
+ // SignSignature doesn't know how to sign these. We're
+ // not testing validating signatures, so just create
+ // dummy signatures that DO include the correct P2SH scripts:
+ txTo.vin[3].scriptSig << OP_11 << OP_11 << static_cast<vector<unsigned char> >(oneAndTwo);
+ txTo.vin[4].scriptSig << static_cast<vector<unsigned char> >(fifteenSigops);
+
+ BOOST_CHECK(::AreInputsStandard(txTo, coins));
+ // 22 P2SH sigops for all inputs (1 for vin[0], 6 for vin[3], 15 for vin[4]
+ BOOST_CHECK_EQUAL(GetP2SHSigOpCount(txTo, coins), 22U);
+
+ // 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(!::AreInputsStandard(txTo, coins));
+ txTo.vin[i].scriptSig = t;
+ }
+
+ CMutableTransaction txToNonStd1;
+ txToNonStd1.vout.resize(1);
+ txToNonStd1.vout[0].scriptPubKey = GetScriptForDestination(key[1].GetPubKey().GetID());
+ txToNonStd1.vout[0].nValue = 1000;
+ txToNonStd1.vin.resize(1);
+ txToNonStd1.vin[0].prevout.n = 5;
+ txToNonStd1.vin[0].prevout.hash = txFrom.GetHash();
+ txToNonStd1.vin[0].scriptSig << static_cast<vector<unsigned char> >(sixteenSigops);
+
+ BOOST_CHECK(!::AreInputsStandard(txToNonStd1, coins));
+ BOOST_CHECK_EQUAL(GetP2SHSigOpCount(txToNonStd1, coins), 16U);
+
+ CMutableTransaction txToNonStd2;
+ txToNonStd2.vout.resize(1);
+ txToNonStd2.vout[0].scriptPubKey = GetScriptForDestination(key[1].GetPubKey().GetID());
+ txToNonStd2.vout[0].nValue = 1000;
+ txToNonStd2.vin.resize(1);
+ txToNonStd2.vin[0].prevout.n = 6;
+ txToNonStd2.vin[0].prevout.hash = txFrom.GetHash();
+ txToNonStd2.vin[0].scriptSig << static_cast<vector<unsigned char> >(twentySigops);
+
+ BOOST_CHECK(!::AreInputsStandard(txToNonStd2, coins));
+ BOOST_CHECK_EQUAL(GetP2SHSigOpCount(txToNonStd2, coins), 20U);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp
new file mode 100644
index 0000000000..c0614cca43
--- /dev/null
+++ b/src/test/script_tests.cpp
@@ -0,0 +1,988 @@
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "data/script_invalid.json.h"
+#include "data/script_valid.json.h"
+
+#include "core_io.h"
+#include "key.h"
+#include "keystore.h"
+#include "main.h"
+#include "script/script.h"
+#include "script/script_error.h"
+#include "script/sign.h"
+#include "util.h"
+#include "test/test_bitcoin.h"
+
+#if defined(HAVE_CONSENSUS_LIB)
+#include "script/bitcoinconsensus.h"
+#endif
+
+#include <fstream>
+#include <stdint.h>
+#include <string>
+#include <vector>
+
+#include <boost/foreach.hpp>
+#include <boost/test/unit_test.hpp>
+#include "json/json_spirit_reader_template.h"
+#include "json/json_spirit_utils.h"
+#include "json/json_spirit_writer_template.h"
+
+using namespace std;
+using namespace json_spirit;
+
+// Uncomment if you want to output updated JSON tests.
+// #define UPDATE_JSON_TESTS
+
+static const unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC;
+
+unsigned int ParseScriptFlags(string strFlags);
+string FormatScriptFlags(unsigned int flags);
+
+Array
+read_json(const std::string& jsondata)
+{
+ Value v;
+
+ if (!read_string(jsondata, v) || v.type() != array_type)
+ {
+ BOOST_ERROR("Parse error.");
+ return Array();
+ }
+ return v.get_array();
+}
+
+BOOST_FIXTURE_TEST_SUITE(script_tests, BasicTestingSetup)
+
+CMutableTransaction BuildCreditingTransaction(const CScript& scriptPubKey)
+{
+ CMutableTransaction txCredit;
+ txCredit.nVersion = 1;
+ txCredit.nLockTime = 0;
+ txCredit.vin.resize(1);
+ txCredit.vout.resize(1);
+ txCredit.vin[0].prevout.SetNull();
+ txCredit.vin[0].scriptSig = CScript() << CScriptNum(0) << CScriptNum(0);
+ txCredit.vin[0].nSequence = std::numeric_limits<unsigned int>::max();
+ txCredit.vout[0].scriptPubKey = scriptPubKey;
+ txCredit.vout[0].nValue = 0;
+
+ return txCredit;
+}
+
+CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CMutableTransaction& txCredit)
+{
+ CMutableTransaction txSpend;
+ txSpend.nVersion = 1;
+ txSpend.nLockTime = 0;
+ txSpend.vin.resize(1);
+ txSpend.vout.resize(1);
+ txSpend.vin[0].prevout.hash = txCredit.GetHash();
+ txSpend.vin[0].prevout.n = 0;
+ txSpend.vin[0].scriptSig = scriptSig;
+ txSpend.vin[0].nSequence = std::numeric_limits<unsigned int>::max();
+ txSpend.vout[0].scriptPubKey = CScript();
+ txSpend.vout[0].nValue = 0;
+
+ return txSpend;
+}
+
+void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, int flags, bool expect, const std::string& message)
+{
+ ScriptError err;
+ CMutableTransaction tx = BuildSpendingTransaction(scriptSig, BuildCreditingTransaction(scriptPubKey));
+ CMutableTransaction tx2 = tx;
+ BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, flags, MutableTransactionSignatureChecker(&tx, 0), &err) == expect, message);
+ BOOST_CHECK_MESSAGE(expect == (err == SCRIPT_ERR_OK), std::string(ScriptErrorString(err)) + ": " + message);
+#if defined(HAVE_CONSENSUS_LIB)
+ CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
+ stream << tx2;
+ BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script(begin_ptr(scriptPubKey), scriptPubKey.size(), (const unsigned char*)&stream[0], stream.size(), 0, flags, NULL) == expect,message);
+#endif
+}
+
+void static NegateSignatureS(std::vector<unsigned char>& vchSig) {
+ // Parse the signature.
+ std::vector<unsigned char> r, s;
+ r = std::vector<unsigned char>(vchSig.begin() + 4, vchSig.begin() + 4 + vchSig[3]);
+ s = std::vector<unsigned char>(vchSig.begin() + 6 + vchSig[3], vchSig.begin() + 6 + vchSig[3] + vchSig[5 + vchSig[3]]);
+
+ // Really ugly to implement mod-n negation here, but it would be feature creep to expose such functionality from libsecp256k1.
+ static const unsigned char order[33] = {
+ 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
+ 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B,
+ 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41
+ };
+ while (s.size() < 33) {
+ s.insert(s.begin(), 0x00);
+ }
+ int carry = 0;
+ for (int p = 32; p >= 1; p--) {
+ int n = (int)order[p] - s[p] - carry;
+ s[p] = (n + 256) & 0xFF;
+ carry = (n < 0);
+ }
+ assert(carry == 0);
+ if (s.size() > 1 && s[0] == 0 && s[1] < 0x80) {
+ s.erase(s.begin());
+ }
+
+ // Reconstruct the signature.
+ vchSig.clear();
+ vchSig.push_back(0x30);
+ vchSig.push_back(4 + r.size() + s.size());
+ vchSig.push_back(0x02);
+ vchSig.push_back(r.size());
+ vchSig.insert(vchSig.end(), r.begin(), r.end());
+ vchSig.push_back(0x02);
+ vchSig.push_back(s.size());
+ vchSig.insert(vchSig.end(), s.begin(), s.end());
+}
+
+namespace
+{
+const unsigned char vchKey0[32] = {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};
+const unsigned char vchKey1[32] = {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,0};
+const unsigned char vchKey2[32] = {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,0,0};
+
+struct KeyData
+{
+ CKey key0, key0C, key1, key1C, key2, key2C;
+ CPubKey pubkey0, pubkey0C, pubkey0H;
+ CPubKey pubkey1, pubkey1C;
+ CPubKey pubkey2, pubkey2C;
+
+ KeyData()
+ {
+
+ key0.Set(vchKey0, vchKey0 + 32, false);
+ key0C.Set(vchKey0, vchKey0 + 32, true);
+ pubkey0 = key0.GetPubKey();
+ pubkey0H = key0.GetPubKey();
+ pubkey0C = key0C.GetPubKey();
+ *const_cast<unsigned char*>(&pubkey0H[0]) = 0x06 | (pubkey0H[64] & 1);
+
+ key1.Set(vchKey1, vchKey1 + 32, false);
+ key1C.Set(vchKey1, vchKey1 + 32, true);
+ pubkey1 = key1.GetPubKey();
+ pubkey1C = key1C.GetPubKey();
+
+ key2.Set(vchKey2, vchKey2 + 32, false);
+ key2C.Set(vchKey2, vchKey2 + 32, true);
+ pubkey2 = key2.GetPubKey();
+ pubkey2C = key2C.GetPubKey();
+ }
+};
+
+
+class TestBuilder
+{
+private:
+ CScript scriptPubKey;
+ CTransaction creditTx;
+ CMutableTransaction spendTx;
+ bool havePush;
+ std::vector<unsigned char> push;
+ std::string comment;
+ int flags;
+
+ void DoPush()
+ {
+ if (havePush) {
+ spendTx.vin[0].scriptSig << push;
+ havePush = false;
+ }
+ }
+
+ void DoPush(const std::vector<unsigned char>& data)
+ {
+ DoPush();
+ push = data;
+ havePush = true;
+ }
+
+public:
+ TestBuilder(const CScript& redeemScript, const std::string& comment_, int flags_, bool P2SH = false) : scriptPubKey(redeemScript), havePush(false), comment(comment_), flags(flags_)
+ {
+ if (P2SH) {
+ creditTx = BuildCreditingTransaction(CScript() << OP_HASH160 << ToByteVector(CScriptID(redeemScript)) << OP_EQUAL);
+ } else {
+ creditTx = BuildCreditingTransaction(redeemScript);
+ }
+ spendTx = BuildSpendingTransaction(CScript(), creditTx);
+ }
+
+ TestBuilder& Add(const CScript& script)
+ {
+ DoPush();
+ spendTx.vin[0].scriptSig += script;
+ return *this;
+ }
+
+ TestBuilder& Num(int num)
+ {
+ DoPush();
+ spendTx.vin[0].scriptSig << num;
+ return *this;
+ }
+
+ TestBuilder& Push(const std::string& hex)
+ {
+ DoPush(ParseHex(hex));
+ return *this;
+ }
+
+ TestBuilder& PushSig(const CKey& key, int nHashType = SIGHASH_ALL, unsigned int lenR = 32, unsigned int lenS = 32)
+ {
+ uint256 hash = SignatureHash(scriptPubKey, spendTx, 0, nHashType);
+ std::vector<unsigned char> vchSig, r, s;
+ uint32_t iter = 0;
+ do {
+ key.Sign(hash, vchSig, iter++);
+ if ((lenS == 33) != (vchSig[5 + vchSig[3]] == 33)) {
+ NegateSignatureS(vchSig);
+ }
+ r = std::vector<unsigned char>(vchSig.begin() + 4, vchSig.begin() + 4 + vchSig[3]);
+ s = std::vector<unsigned char>(vchSig.begin() + 6 + vchSig[3], vchSig.begin() + 6 + vchSig[3] + vchSig[5 + vchSig[3]]);
+ } while (lenR != r.size() || lenS != s.size());
+ vchSig.push_back(static_cast<unsigned char>(nHashType));
+ DoPush(vchSig);
+ return *this;
+ }
+
+ TestBuilder& Push(const CPubKey& pubkey)
+ {
+ DoPush(std::vector<unsigned char>(pubkey.begin(), pubkey.end()));
+ return *this;
+ }
+
+ TestBuilder& PushRedeem()
+ {
+ DoPush(static_cast<std::vector<unsigned char> >(scriptPubKey));
+ return *this;
+ }
+
+ TestBuilder& EditPush(unsigned int pos, const std::string& hexin, const std::string& hexout)
+ {
+ assert(havePush);
+ std::vector<unsigned char> datain = ParseHex(hexin);
+ std::vector<unsigned char> dataout = ParseHex(hexout);
+ assert(pos + datain.size() <= push.size());
+ BOOST_CHECK_MESSAGE(std::vector<unsigned char>(push.begin() + pos, push.begin() + pos + datain.size()) == datain, comment);
+ push.erase(push.begin() + pos, push.begin() + pos + datain.size());
+ push.insert(push.begin() + pos, dataout.begin(), dataout.end());
+ return *this;
+ }
+
+ TestBuilder& DamagePush(unsigned int pos)
+ {
+ assert(havePush);
+ assert(pos < push.size());
+ push[pos] ^= 1;
+ return *this;
+ }
+
+ TestBuilder& Test(bool expect)
+ {
+ TestBuilder copy = *this; // Make a copy so we can rollback the push.
+ DoPush();
+ DoTest(creditTx.vout[0].scriptPubKey, spendTx.vin[0].scriptSig, flags, expect, comment);
+ *this = copy;
+ return *this;
+ }
+
+ Array GetJSON()
+ {
+ DoPush();
+ Array array;
+ array.push_back(FormatScript(spendTx.vin[0].scriptSig));
+ array.push_back(FormatScript(creditTx.vout[0].scriptPubKey));
+ array.push_back(FormatScriptFlags(flags));
+ array.push_back(comment);
+ return array;
+ }
+
+ std::string GetComment()
+ {
+ return comment;
+ }
+
+ const CScript& GetScriptPubKey()
+ {
+ return creditTx.vout[0].scriptPubKey;
+ }
+};
+}
+
+BOOST_AUTO_TEST_CASE(script_build)
+{
+ const KeyData keys;
+
+ std::vector<TestBuilder> good;
+ std::vector<TestBuilder> bad;
+
+ good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
+ "P2PK", 0
+ ).PushSig(keys.key0));
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
+ "P2PK, bad sig", 0
+ ).PushSig(keys.key0).DamagePush(10));
+
+ good.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160 << ToByteVector(keys.pubkey1C.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG,
+ "P2PKH", 0
+ ).PushSig(keys.key1).Push(keys.pubkey1C));
+ bad.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160 << ToByteVector(keys.pubkey2C.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG,
+ "P2PKH, bad pubkey", 0
+ ).PushSig(keys.key2).Push(keys.pubkey2C).DamagePush(5));
+
+ good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG,
+ "P2PK anyonecanpay", 0
+ ).PushSig(keys.key1, SIGHASH_ALL | SIGHASH_ANYONECANPAY));
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG,
+ "P2PK anyonecanpay marked with normal hashtype", 0
+ ).PushSig(keys.key1, SIGHASH_ALL | SIGHASH_ANYONECANPAY).EditPush(70, "81", "01"));
+
+ good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0C) << OP_CHECKSIG,
+ "P2SH(P2PK)", SCRIPT_VERIFY_P2SH, true
+ ).PushSig(keys.key0).PushRedeem());
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0C) << OP_CHECKSIG,
+ "P2SH(P2PK), bad redeemscript", SCRIPT_VERIFY_P2SH, true
+ ).PushSig(keys.key0).PushRedeem().DamagePush(10));
+
+ good.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160 << ToByteVector(keys.pubkey1.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG,
+ "P2SH(P2PKH), bad sig but no VERIFY_P2SH", 0, true
+ ).PushSig(keys.key0).DamagePush(10).PushRedeem());
+ bad.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160 << ToByteVector(keys.pubkey1.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG,
+ "P2SH(P2PKH), bad sig", SCRIPT_VERIFY_P2SH, true
+ ).PushSig(keys.key0).DamagePush(10).PushRedeem());
+
+ good.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG,
+ "3-of-3", 0
+ ).Num(0).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2));
+ bad.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG,
+ "3-of-3, 2 sigs", 0
+ ).Num(0).PushSig(keys.key0).PushSig(keys.key1).Num(0));
+
+ good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG,
+ "P2SH(2-of-3)", SCRIPT_VERIFY_P2SH, true
+ ).Num(0).PushSig(keys.key1).PushSig(keys.key2).PushRedeem());
+ bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG,
+ "P2SH(2-of-3), 1 sig", SCRIPT_VERIFY_P2SH, true
+ ).Num(0).PushSig(keys.key1).Num(0).PushRedeem());
+
+ good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
+ "P2PK with too much R padding but no DERSIG", 0
+ ).PushSig(keys.key1, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000"));
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
+ "P2PK with too much R padding", SCRIPT_VERIFY_DERSIG
+ ).PushSig(keys.key1, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000"));
+ good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
+ "P2PK with too much S padding but no DERSIG", 0
+ ).PushSig(keys.key1, SIGHASH_ALL).EditPush(1, "44", "45").EditPush(37, "20", "2100"));
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
+ "P2PK with too much S padding", SCRIPT_VERIFY_DERSIG
+ ).PushSig(keys.key1, SIGHASH_ALL).EditPush(1, "44", "45").EditPush(37, "20", "2100"));
+ good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
+ "P2PK with too little R padding but no DERSIG", 0
+ ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220"));
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
+ "P2PK with too little R padding", SCRIPT_VERIFY_DERSIG
+ ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220"));
+ good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG << OP_NOT,
+ "P2PK NOT with bad sig with too much R padding but no DERSIG", 0
+ ).PushSig(keys.key2, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000").DamagePush(10));
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG << OP_NOT,
+ "P2PK NOT with bad sig with too much R padding", SCRIPT_VERIFY_DERSIG
+ ).PushSig(keys.key2, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000").DamagePush(10));
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG << OP_NOT,
+ "P2PK NOT with too much R padding but no DERSIG", 0
+ ).PushSig(keys.key2, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000"));
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG << OP_NOT,
+ "P2PK NOT with too much R padding", SCRIPT_VERIFY_DERSIG
+ ).PushSig(keys.key2, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000"));
+
+ good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
+ "BIP66 example 1, without DERSIG", 0
+ ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220"));
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
+ "BIP66 example 1, with DERSIG", SCRIPT_VERIFY_DERSIG
+ ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220"));
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT,
+ "BIP66 example 2, without DERSIG", 0
+ ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220"));
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT,
+ "BIP66 example 2, with DERSIG", SCRIPT_VERIFY_DERSIG
+ ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220"));
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
+ "BIP66 example 3, without DERSIG", 0
+ ).Num(0));
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
+ "BIP66 example 3, with DERSIG", SCRIPT_VERIFY_DERSIG
+ ).Num(0));
+ good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT,
+ "BIP66 example 4, without DERSIG", 0
+ ).Num(0));
+ good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT,
+ "BIP66 example 4, with DERSIG", SCRIPT_VERIFY_DERSIG
+ ).Num(0));
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
+ "BIP66 example 5, without DERSIG", 0
+ ).Num(1));
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
+ "BIP66 example 5, with DERSIG", SCRIPT_VERIFY_DERSIG
+ ).Num(1));
+ good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT,
+ "BIP66 example 6, without DERSIG", 0
+ ).Num(1));
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT,
+ "BIP66 example 6, with DERSIG", SCRIPT_VERIFY_DERSIG
+ ).Num(1));
+ good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG,
+ "BIP66 example 7, without DERSIG", 0
+ ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2));
+ bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG,
+ "BIP66 example 7, with DERSIG", SCRIPT_VERIFY_DERSIG
+ ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2));
+ bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT,
+ "BIP66 example 8, without DERSIG", 0
+ ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2));
+ bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT,
+ "BIP66 example 8, with DERSIG", SCRIPT_VERIFY_DERSIG
+ ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2));
+ bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG,
+ "BIP66 example 9, without DERSIG", 0
+ ).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220"));
+ bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG,
+ "BIP66 example 9, with DERSIG", SCRIPT_VERIFY_DERSIG
+ ).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220"));
+ good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT,
+ "BIP66 example 10, without DERSIG", 0
+ ).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220"));
+ bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT,
+ "BIP66 example 10, with DERSIG", SCRIPT_VERIFY_DERSIG
+ ).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220"));
+ bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG,
+ "BIP66 example 11, without DERSIG", 0
+ ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").Num(0));
+ bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG,
+ "BIP66 example 11, with DERSIG", SCRIPT_VERIFY_DERSIG
+ ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").Num(0));
+ good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT,
+ "BIP66 example 12, without DERSIG", 0
+ ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").Num(0));
+ good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT,
+ "BIP66 example 12, with DERSIG", SCRIPT_VERIFY_DERSIG
+ ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").Num(0));
+ good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG,
+ "P2PK with multi-byte hashtype, without DERSIG", 0
+ ).PushSig(keys.key2, SIGHASH_ALL).EditPush(70, "01", "0101"));
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG,
+ "P2PK with multi-byte hashtype, with DERSIG", SCRIPT_VERIFY_DERSIG
+ ).PushSig(keys.key2, SIGHASH_ALL).EditPush(70, "01", "0101"));
+
+ good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG,
+ "P2PK with high S but no LOW_S", 0
+ ).PushSig(keys.key2, SIGHASH_ALL, 32, 33));
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG,
+ "P2PK with high S", SCRIPT_VERIFY_LOW_S
+ ).PushSig(keys.key2, SIGHASH_ALL, 32, 33));
+
+ good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG,
+ "P2PK with hybrid pubkey but no STRICTENC", 0
+ ).PushSig(keys.key0, SIGHASH_ALL));
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG,
+ "P2PK with hybrid pubkey", SCRIPT_VERIFY_STRICTENC
+ ).PushSig(keys.key0, SIGHASH_ALL));
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG << OP_NOT,
+ "P2PK NOT with hybrid pubkey but no STRICTENC", 0
+ ).PushSig(keys.key0, SIGHASH_ALL));
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG << OP_NOT,
+ "P2PK NOT with hybrid pubkey", SCRIPT_VERIFY_STRICTENC
+ ).PushSig(keys.key0, SIGHASH_ALL));
+ good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG << OP_NOT,
+ "P2PK NOT with invalid hybrid pubkey but no STRICTENC", 0
+ ).PushSig(keys.key0, SIGHASH_ALL).DamagePush(10));
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG << OP_NOT,
+ "P2PK NOT with invalid hybrid pubkey", SCRIPT_VERIFY_STRICTENC
+ ).PushSig(keys.key0, SIGHASH_ALL).DamagePush(10));
+ good.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey0H) << ToByteVector(keys.pubkey1C) << OP_2 << OP_CHECKMULTISIG,
+ "1-of-2 with the second 1 hybrid pubkey and no STRICTENC", 0
+ ).Num(0).PushSig(keys.key1, SIGHASH_ALL));
+ good.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey0H) << ToByteVector(keys.pubkey1C) << OP_2 << OP_CHECKMULTISIG,
+ "1-of-2 with the second 1 hybrid pubkey", SCRIPT_VERIFY_STRICTENC
+ ).Num(0).PushSig(keys.key1, SIGHASH_ALL));
+ bad.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0H) << OP_2 << OP_CHECKMULTISIG,
+ "1-of-2 with the first 1 hybrid pubkey", SCRIPT_VERIFY_STRICTENC
+ ).Num(0).PushSig(keys.key1, SIGHASH_ALL));
+
+ good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG,
+ "P2PK with undefined hashtype but no STRICTENC", 0
+ ).PushSig(keys.key1, 5));
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG,
+ "P2PK with undefined hashtype", SCRIPT_VERIFY_STRICTENC
+ ).PushSig(keys.key1, 5));
+ good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG << OP_NOT,
+ "P2PK NOT with invalid sig and undefined hashtype but no STRICTENC", 0
+ ).PushSig(keys.key1, 5).DamagePush(10));
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG << OP_NOT,
+ "P2PK NOT with invalid sig and undefined hashtype", SCRIPT_VERIFY_STRICTENC
+ ).PushSig(keys.key1, 5).DamagePush(10));
+
+ good.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG,
+ "3-of-3 with nonzero dummy but no NULLDUMMY", 0
+ ).Num(1).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2));
+ bad.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG,
+ "3-of-3 with nonzero dummy", SCRIPT_VERIFY_NULLDUMMY
+ ).Num(1).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2));
+ good.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG << OP_NOT,
+ "3-of-3 NOT with invalid sig and nonzero dummy but no NULLDUMMY", 0
+ ).Num(1).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2).DamagePush(10));
+ bad.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG << OP_NOT,
+ "3-of-3 NOT with invalid sig with nonzero dummy", SCRIPT_VERIFY_NULLDUMMY
+ ).Num(1).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2).DamagePush(10));
+
+ good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey1C) << OP_2 << OP_CHECKMULTISIG,
+ "2-of-2 with two identical keys and sigs pushed using OP_DUP but no SIGPUSHONLY", 0
+ ).Num(0).PushSig(keys.key1).Add(CScript() << OP_DUP));
+ bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey1C) << OP_2 << OP_CHECKMULTISIG,
+ "2-of-2 with two identical keys and sigs pushed using OP_DUP", SCRIPT_VERIFY_SIGPUSHONLY
+ ).Num(0).PushSig(keys.key1).Add(CScript() << OP_DUP));
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG,
+ "P2SH(P2PK) with non-push scriptSig but no SIGPUSHONLY", 0
+ ).PushSig(keys.key2).PushRedeem());
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG,
+ "P2SH(P2PK) with non-push scriptSig", SCRIPT_VERIFY_SIGPUSHONLY
+ ).PushSig(keys.key2).PushRedeem());
+ good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey1C) << OP_2 << OP_CHECKMULTISIG,
+ "2-of-2 with two identical keys and sigs pushed", SCRIPT_VERIFY_SIGPUSHONLY
+ ).Num(0).PushSig(keys.key1).PushSig(keys.key1));
+
+ good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
+ "P2PK with unnecessary input but no CLEANSTACK", SCRIPT_VERIFY_P2SH
+ ).Num(11).PushSig(keys.key0));
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
+ "P2PK with unnecessary input", SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_P2SH
+ ).Num(11).PushSig(keys.key0));
+ good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
+ "P2SH with unnecessary input but no CLEANSTACK", SCRIPT_VERIFY_P2SH, true
+ ).Num(11).PushSig(keys.key0).PushRedeem());
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
+ "P2SH with unnecessary input", SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_P2SH, true
+ ).Num(11).PushSig(keys.key0).PushRedeem());
+ good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
+ "P2SH with CLEANSTACK", SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_P2SH, true
+ ).PushSig(keys.key0).PushRedeem());
+
+
+ std::set<std::string> tests_good;
+ std::set<std::string> tests_bad;
+
+ {
+ Array json_good = read_json(std::string(json_tests::script_valid, json_tests::script_valid + sizeof(json_tests::script_valid)));
+ Array json_bad = read_json(std::string(json_tests::script_invalid, json_tests::script_invalid + sizeof(json_tests::script_invalid)));
+
+ BOOST_FOREACH(Value& tv, json_good) {
+ tests_good.insert(write_string(Value(tv.get_array()), true));
+ }
+ BOOST_FOREACH(Value& tv, json_bad) {
+ tests_bad.insert(write_string(Value(tv.get_array()), true));
+ }
+ }
+
+ std::string strGood;
+ std::string strBad;
+
+ BOOST_FOREACH(TestBuilder& test, good) {
+ test.Test(true);
+ std::string str = write_string(Value(test.GetJSON()), true);
+#ifndef UPDATE_JSON_TESTS
+ if (tests_good.count(str) == 0) {
+ BOOST_CHECK_MESSAGE(false, "Missing auto script_valid test: " + test.GetComment());
+ }
+#endif
+ strGood += str + ",\n";
+ }
+ BOOST_FOREACH(TestBuilder& test, bad) {
+ test.Test(false);
+ std::string str = write_string(Value(test.GetJSON()), true);
+#ifndef UPDATE_JSON_TESTS
+ if (tests_bad.count(str) == 0) {
+ BOOST_CHECK_MESSAGE(false, "Missing auto script_invalid test: " + test.GetComment());
+ }
+#endif
+ strBad += str + ",\n";
+ }
+
+#ifdef UPDATE_JSON_TESTS
+ FILE* valid = fopen("script_valid.json.gen", "w");
+ fputs(strGood.c_str(), valid);
+ fclose(valid);
+ FILE* invalid = fopen("script_invalid.json.gen", "w");
+ fputs(strBad.c_str(), invalid);
+ fclose(invalid);
+#endif
+}
+
+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", "flags" ]
+ // ... where scriptSig and scriptPubKey are stringified
+ // scripts.
+ Array tests = read_json(std::string(json_tests::script_valid, json_tests::script_valid + sizeof(json_tests::script_valid)));
+
+ BOOST_FOREACH(Value& tv, tests)
+ {
+ Array test = tv.get_array();
+ string strTest = write_string(tv, false);
+ if (test.size() < 3) // Allow size > 3; extra stuff ignored (useful for comments)
+ {
+ if (test.size() != 1) {
+ 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);
+ unsigned int scriptflags = ParseScriptFlags(test[2].get_str());
+
+ DoTest(scriptPubKey, scriptSig, scriptflags, true, strTest);
+ }
+}
+
+BOOST_AUTO_TEST_CASE(script_invalid)
+{
+ // Scripts that should evaluate as invalid
+ Array tests = read_json(std::string(json_tests::script_invalid, json_tests::script_invalid + sizeof(json_tests::script_invalid)));
+
+ BOOST_FOREACH(Value& tv, tests)
+ {
+ Array test = tv.get_array();
+ string strTest = write_string(tv, false);
+ if (test.size() < 3) // Allow size > 3; extra stuff ignored (useful for comments)
+ {
+ if (test.size() != 1) {
+ 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);
+ unsigned int scriptflags = ParseScriptFlags(test[2].get_str());
+
+ DoTest(scriptPubKey, scriptSig, scriptflags, false, 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 };
+
+ ScriptError err;
+ vector<vector<unsigned char> > directStack;
+ BOOST_CHECK(EvalScript(directStack, CScript(&direct[0], &direct[sizeof(direct)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), &err));
+ BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
+
+ vector<vector<unsigned char> > pushdata1Stack;
+ BOOST_CHECK(EvalScript(pushdata1Stack, CScript(&pushdata1[0], &pushdata1[sizeof(pushdata1)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), &err));
+ BOOST_CHECK(pushdata1Stack == directStack);
+ BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
+
+ vector<vector<unsigned char> > pushdata2Stack;
+ BOOST_CHECK(EvalScript(pushdata2Stack, CScript(&pushdata2[0], &pushdata2[sizeof(pushdata2)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), &err));
+ BOOST_CHECK(pushdata2Stack == directStack);
+ BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
+
+ vector<vector<unsigned char> > pushdata4Stack;
+ BOOST_CHECK(EvalScript(pushdata4Stack, CScript(&pushdata4[0], &pushdata4[sizeof(pushdata4)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), &err));
+ BOOST_CHECK(pushdata4Stack == directStack);
+ BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
+}
+
+CScript
+sign_multisig(CScript scriptPubKey, std::vector<CKey> 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 block chain (old
+ // clients would not accept new CHECKMULTISIG transactions,
+ // and vice-versa)
+ //
+ result << OP_0;
+ BOOST_FOREACH(const CKey &key, keys)
+ {
+ vector<unsigned char> vchSig;
+ BOOST_CHECK(key.Sign(hash, vchSig));
+ vchSig.push_back((unsigned char)SIGHASH_ALL);
+ result << vchSig;
+ }
+ return result;
+}
+CScript
+sign_multisig(CScript scriptPubKey, const CKey &key, CTransaction transaction)
+{
+ std::vector<CKey> keys;
+ keys.push_back(key);
+ return sign_multisig(scriptPubKey, keys, transaction);
+}
+
+BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG12)
+{
+ ScriptError err;
+ CKey key1, key2, key3;
+ key1.MakeNewKey(true);
+ key2.MakeNewKey(false);
+ key3.MakeNewKey(true);
+
+ CScript scriptPubKey12;
+ scriptPubKey12 << OP_1 << ToByteVector(key1.GetPubKey()) << ToByteVector(key2.GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
+
+ CMutableTransaction txFrom12 = BuildCreditingTransaction(scriptPubKey12);
+ CMutableTransaction txTo12 = BuildSpendingTransaction(CScript(), txFrom12);
+
+ CScript goodsig1 = sign_multisig(scriptPubKey12, key1, txTo12);
+ BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err));
+ BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
+ txTo12.vout[0].nValue = 2;
+ BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err));
+ BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
+
+ CScript goodsig2 = sign_multisig(scriptPubKey12, key2, txTo12);
+ BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err));
+ BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
+
+ CScript badsig1 = sign_multisig(scriptPubKey12, key3, txTo12);
+ BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err));
+ BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
+}
+
+BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG23)
+{
+ ScriptError err;
+ CKey key1, key2, key3, key4;
+ key1.MakeNewKey(true);
+ key2.MakeNewKey(false);
+ key3.MakeNewKey(true);
+ key4.MakeNewKey(false);
+
+ CScript scriptPubKey23;
+ scriptPubKey23 << OP_2 << ToByteVector(key1.GetPubKey()) << ToByteVector(key2.GetPubKey()) << ToByteVector(key3.GetPubKey()) << OP_3 << OP_CHECKMULTISIG;
+
+ CMutableTransaction txFrom23 = BuildCreditingTransaction(scriptPubKey23);
+ CMutableTransaction txTo23 = BuildSpendingTransaction(CScript(), txFrom23);
+
+ std::vector<CKey> keys;
+ keys.push_back(key1); keys.push_back(key2);
+ CScript goodsig1 = sign_multisig(scriptPubKey23, keys, txTo23);
+ BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
+ BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
+
+ keys.clear();
+ keys.push_back(key1); keys.push_back(key3);
+ CScript goodsig2 = sign_multisig(scriptPubKey23, keys, txTo23);
+ BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
+ BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
+
+ keys.clear();
+ keys.push_back(key2); keys.push_back(key3);
+ CScript goodsig3 = sign_multisig(scriptPubKey23, keys, txTo23);
+ BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
+ BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
+
+ 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, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
+ BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
+
+ 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, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
+ BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
+
+ 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, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
+ BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
+
+ 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, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
+ BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
+
+ 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, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
+ BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
+
+ keys.clear(); // Must have signatures
+ CScript badsig6 = sign_multisig(scriptPubKey23, keys, txTo23);
+ BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
+ BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err));
+}
+
+BOOST_AUTO_TEST_CASE(script_combineSigs)
+{
+ // Test the CombineSignatures function
+ CBasicKeyStore keystore;
+ vector<CKey> keys;
+ vector<CPubKey> pubkeys;
+ for (int i = 0; i < 3; i++)
+ {
+ CKey key;
+ key.MakeNewKey(i%2 == 1);
+ keys.push_back(key);
+ pubkeys.push_back(key.GetPubKey());
+ keystore.AddKey(key);
+ }
+
+ CMutableTransaction txFrom = BuildCreditingTransaction(GetScriptForDestination(keys[0].GetPubKey().GetID()));
+ CMutableTransaction txTo = BuildSpendingTransaction(CScript(), txFrom);
+ CScript& scriptPubKey = txFrom.vout[0].scriptPubKey;
+ CScript& scriptSig = txTo.vin[0].scriptSig;
+
+ 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 << ToByteVector(keys[0].GetPubKey()) << OP_CHECKSIG;
+ keystore.AddCScript(pkSingle);
+ scriptPubKey = GetScriptForDestination(CScriptID(pkSingle));
+ 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<vector<unsigned char> >(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 = GetScriptForMultisig(2, pubkeys);
+ 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<unsigned char> sig1;
+ uint256 hash1 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_ALL);
+ BOOST_CHECK(keys[0].Sign(hash1, sig1));
+ sig1.push_back(SIGHASH_ALL);
+ vector<unsigned char> sig2;
+ uint256 hash2 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_NONE);
+ BOOST_CHECK(keys[1].Sign(hash2, sig2));
+ sig2.push_back(SIGHASH_NONE);
+ vector<unsigned char> 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_CASE(script_standard_push)
+{
+ ScriptError err;
+ for (int i=0; i<67000; i++) {
+ CScript script;
+ script << i;
+ BOOST_CHECK_MESSAGE(script.IsPushOnly(), "Number " << i << " is not pure push.");
+ BOOST_CHECK_MESSAGE(VerifyScript(script, CScript() << OP_1, SCRIPT_VERIFY_MINIMALDATA, BaseSignatureChecker(), &err), "Number " << i << " push is not minimal data.");
+ BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
+ }
+
+ for (unsigned int i=0; i<=MAX_SCRIPT_ELEMENT_SIZE; i++) {
+ std::vector<unsigned char> data(i, '\111');
+ CScript script;
+ script << data;
+ BOOST_CHECK_MESSAGE(script.IsPushOnly(), "Length " << i << " is not pure push.");
+ BOOST_CHECK_MESSAGE(VerifyScript(script, CScript() << OP_1, SCRIPT_VERIFY_MINIMALDATA, BaseSignatureChecker(), &err), "Length " << i << " push is not minimal data.");
+ BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
+ }
+}
+
+BOOST_AUTO_TEST_CASE(script_IsPushOnly_on_invalid_scripts)
+{
+ // IsPushOnly returns false when given a script containing only pushes that
+ // are invalid due to truncation. IsPushOnly() is consensus critical
+ // because P2SH evaluation uses it, although this specific behavior should
+ // not be consensus critical as the P2SH evaluation would fail first due to
+ // the invalid push. Still, it doesn't hurt to test it explicitly.
+ static const unsigned char direct[] = { 1 };
+ BOOST_CHECK(!CScript(direct, direct+sizeof(direct)).IsPushOnly());
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/scriptnum_tests.cpp b/src/test/scriptnum_tests.cpp
new file mode 100644
index 0000000000..d95724dbe1
--- /dev/null
+++ b/src/test/scriptnum_tests.cpp
@@ -0,0 +1,199 @@
+// Copyright (c) 2012-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "bignum.h"
+#include "script/script.h"
+#include "test/test_bitcoin.h"
+
+#include <boost/test/unit_test.hpp>
+#include <limits.h>
+#include <stdint.h>
+
+BOOST_FIXTURE_TEST_SUITE(scriptnum_tests, BasicTestingSetup)
+
+static const int64_t values[] = \
+{ 0, 1, CHAR_MIN, CHAR_MAX, UCHAR_MAX, SHRT_MIN, USHRT_MAX, INT_MIN, INT_MAX, UINT_MAX, LONG_MIN, LONG_MAX };
+static const int64_t offsets[] = { 1, 0x79, 0x80, 0x81, 0xFF, 0x7FFF, 0x8000, 0xFFFF, 0x10000};
+
+static bool verify(const CBigNum& bignum, const CScriptNum& scriptnum)
+{
+ return bignum.getvch() == scriptnum.getvch() && bignum.getint() == scriptnum.getint();
+}
+
+static void CheckCreateVch(const int64_t& num)
+{
+ CBigNum bignum(num);
+ CScriptNum scriptnum(num);
+ BOOST_CHECK(verify(bignum, scriptnum));
+
+ CBigNum bignum2(bignum.getvch());
+ CScriptNum scriptnum2(scriptnum.getvch(), false);
+ BOOST_CHECK(verify(bignum2, scriptnum2));
+
+ CBigNum bignum3(scriptnum2.getvch());
+ CScriptNum scriptnum3(bignum2.getvch(), false);
+ BOOST_CHECK(verify(bignum3, scriptnum3));
+}
+
+static void CheckCreateInt(const int64_t& num)
+{
+ CBigNum bignum(num);
+ CScriptNum scriptnum(num);
+ BOOST_CHECK(verify(bignum, scriptnum));
+ BOOST_CHECK(verify(bignum.getint(), CScriptNum(scriptnum.getint())));
+ BOOST_CHECK(verify(scriptnum.getint(), CScriptNum(bignum.getint())));
+ BOOST_CHECK(verify(CBigNum(scriptnum.getint()).getint(), CScriptNum(CScriptNum(bignum.getint()).getint())));
+}
+
+
+static void CheckAdd(const int64_t& num1, const int64_t& num2)
+{
+ const CBigNum bignum1(num1);
+ const CBigNum bignum2(num2);
+ const CScriptNum scriptnum1(num1);
+ const CScriptNum scriptnum2(num2);
+ CBigNum bignum3(num1);
+ CBigNum bignum4(num1);
+ CScriptNum scriptnum3(num1);
+ CScriptNum scriptnum4(num1);
+
+ // int64_t overflow is undefined.
+ bool invalid = (((num2 > 0) && (num1 > (std::numeric_limits<int64_t>::max() - num2))) ||
+ ((num2 < 0) && (num1 < (std::numeric_limits<int64_t>::min() - num2))));
+ if (!invalid)
+ {
+ BOOST_CHECK(verify(bignum1 + bignum2, scriptnum1 + scriptnum2));
+ BOOST_CHECK(verify(bignum1 + bignum2, scriptnum1 + num2));
+ BOOST_CHECK(verify(bignum1 + bignum2, scriptnum2 + num1));
+ }
+}
+
+static void CheckNegate(const int64_t& num)
+{
+ const CBigNum bignum(num);
+ const CScriptNum scriptnum(num);
+
+ // -INT64_MIN is undefined
+ if (num != std::numeric_limits<int64_t>::min())
+ BOOST_CHECK(verify(-bignum, -scriptnum));
+}
+
+static void CheckSubtract(const int64_t& num1, const int64_t& num2)
+{
+ const CBigNum bignum1(num1);
+ const CBigNum bignum2(num2);
+ const CScriptNum scriptnum1(num1);
+ const CScriptNum scriptnum2(num2);
+ bool invalid = false;
+
+ // int64_t overflow is undefined.
+ invalid = ((num2 > 0 && num1 < std::numeric_limits<int64_t>::min() + num2) ||
+ (num2 < 0 && num1 > std::numeric_limits<int64_t>::max() + num2));
+ if (!invalid)
+ {
+ BOOST_CHECK(verify(bignum1 - bignum2, scriptnum1 - scriptnum2));
+ BOOST_CHECK(verify(bignum1 - bignum2, scriptnum1 - num2));
+ }
+
+ invalid = ((num1 > 0 && num2 < std::numeric_limits<int64_t>::min() + num1) ||
+ (num1 < 0 && num2 > std::numeric_limits<int64_t>::max() + num1));
+ if (!invalid)
+ {
+ BOOST_CHECK(verify(bignum2 - bignum1, scriptnum2 - scriptnum1));
+ BOOST_CHECK(verify(bignum2 - bignum1, scriptnum2 - num1));
+ }
+}
+
+static void CheckCompare(const int64_t& num1, const int64_t& num2)
+{
+ const CBigNum bignum1(num1);
+ const CBigNum bignum2(num2);
+ const CScriptNum scriptnum1(num1);
+ const CScriptNum scriptnum2(num2);
+
+ BOOST_CHECK((bignum1 == bignum1) == (scriptnum1 == scriptnum1));
+ BOOST_CHECK((bignum1 != bignum1) == (scriptnum1 != scriptnum1));
+ BOOST_CHECK((bignum1 < bignum1) == (scriptnum1 < scriptnum1));
+ BOOST_CHECK((bignum1 > bignum1) == (scriptnum1 > scriptnum1));
+ BOOST_CHECK((bignum1 >= bignum1) == (scriptnum1 >= scriptnum1));
+ BOOST_CHECK((bignum1 <= bignum1) == (scriptnum1 <= scriptnum1));
+
+ BOOST_CHECK((bignum1 == bignum1) == (scriptnum1 == num1));
+ BOOST_CHECK((bignum1 != bignum1) == (scriptnum1 != num1));
+ BOOST_CHECK((bignum1 < bignum1) == (scriptnum1 < num1));
+ BOOST_CHECK((bignum1 > bignum1) == (scriptnum1 > num1));
+ BOOST_CHECK((bignum1 >= bignum1) == (scriptnum1 >= num1));
+ BOOST_CHECK((bignum1 <= bignum1) == (scriptnum1 <= num1));
+
+ BOOST_CHECK((bignum1 == bignum2) == (scriptnum1 == scriptnum2));
+ BOOST_CHECK((bignum1 != bignum2) == (scriptnum1 != scriptnum2));
+ BOOST_CHECK((bignum1 < bignum2) == (scriptnum1 < scriptnum2));
+ BOOST_CHECK((bignum1 > bignum2) == (scriptnum1 > scriptnum2));
+ BOOST_CHECK((bignum1 >= bignum2) == (scriptnum1 >= scriptnum2));
+ BOOST_CHECK((bignum1 <= bignum2) == (scriptnum1 <= scriptnum2));
+
+ BOOST_CHECK((bignum1 == bignum2) == (scriptnum1 == num2));
+ BOOST_CHECK((bignum1 != bignum2) == (scriptnum1 != num2));
+ BOOST_CHECK((bignum1 < bignum2) == (scriptnum1 < num2));
+ BOOST_CHECK((bignum1 > bignum2) == (scriptnum1 > num2));
+ BOOST_CHECK((bignum1 >= bignum2) == (scriptnum1 >= num2));
+ BOOST_CHECK((bignum1 <= bignum2) == (scriptnum1 <= num2));
+}
+
+static void RunCreate(const int64_t& num)
+{
+ CheckCreateInt(num);
+ CScriptNum scriptnum(num);
+ if (scriptnum.getvch().size() <= CScriptNum::nDefaultMaxNumSize)
+ CheckCreateVch(num);
+ else
+ {
+ BOOST_CHECK_THROW (CheckCreateVch(num), scriptnum_error);
+ }
+}
+
+static void RunOperators(const int64_t& num1, const int64_t& num2)
+{
+ CheckAdd(num1, num2);
+ CheckSubtract(num1, num2);
+ CheckNegate(num1);
+ CheckCompare(num1, num2);
+}
+
+BOOST_AUTO_TEST_CASE(creation)
+{
+ for(size_t i = 0; i < sizeof(values) / sizeof(values[0]); ++i)
+ {
+ for(size_t j = 0; j < sizeof(offsets) / sizeof(offsets[0]); ++j)
+ {
+ RunCreate(values[i]);
+ RunCreate(values[i] + offsets[j]);
+ RunCreate(values[i] - offsets[j]);
+ }
+ }
+}
+
+BOOST_AUTO_TEST_CASE(operators)
+{
+ for(size_t i = 0; i < sizeof(values) / sizeof(values[0]); ++i)
+ {
+ for(size_t j = 0; j < sizeof(offsets) / sizeof(offsets[0]); ++j)
+ {
+ RunOperators(values[i], values[i]);
+ RunOperators(values[i], -values[i]);
+ RunOperators(values[i], values[j]);
+ RunOperators(values[i], -values[j]);
+ RunOperators(values[i] + values[j], values[j]);
+ RunOperators(values[i] + values[j], -values[j]);
+ RunOperators(values[i] - values[j], values[j]);
+ RunOperators(values[i] - values[j], -values[j]);
+ RunOperators(values[i] + values[j], values[i] + values[j]);
+ RunOperators(values[i] + values[j], values[i] - values[j]);
+ RunOperators(values[i] - values[j], values[i] + values[j]);
+ RunOperators(values[i] - values[j], values[i] - values[j]);
+ }
+ }
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/serialize_tests.cpp b/src/test/serialize_tests.cpp
new file mode 100644
index 0000000000..cc8f2b788d
--- /dev/null
+++ b/src/test/serialize_tests.cpp
@@ -0,0 +1,279 @@
+// Copyright (c) 2012-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "serialize.h"
+#include "streams.h"
+#include "hash.h"
+#include "test/test_bitcoin.h"
+
+#include <stdint.h>
+
+#include <boost/test/unit_test.hpp>
+
+using namespace std;
+
+BOOST_FIXTURE_TEST_SUITE(serialize_tests, BasicTestingSetup)
+
+BOOST_AUTO_TEST_CASE(sizes)
+{
+ BOOST_CHECK_EQUAL(sizeof(char), GetSerializeSize(char(0), 0));
+ BOOST_CHECK_EQUAL(sizeof(int8_t), GetSerializeSize(int8_t(0), 0));
+ BOOST_CHECK_EQUAL(sizeof(uint8_t), GetSerializeSize(uint8_t(0), 0));
+ BOOST_CHECK_EQUAL(sizeof(int16_t), GetSerializeSize(int16_t(0), 0));
+ BOOST_CHECK_EQUAL(sizeof(uint16_t), GetSerializeSize(uint16_t(0), 0));
+ BOOST_CHECK_EQUAL(sizeof(int32_t), GetSerializeSize(int32_t(0), 0));
+ BOOST_CHECK_EQUAL(sizeof(uint32_t), GetSerializeSize(uint32_t(0), 0));
+ BOOST_CHECK_EQUAL(sizeof(int64_t), GetSerializeSize(int64_t(0), 0));
+ BOOST_CHECK_EQUAL(sizeof(uint64_t), GetSerializeSize(uint64_t(0), 0));
+ BOOST_CHECK_EQUAL(sizeof(float), GetSerializeSize(float(0), 0));
+ BOOST_CHECK_EQUAL(sizeof(double), GetSerializeSize(double(0), 0));
+ // Bool is serialized as char
+ BOOST_CHECK_EQUAL(sizeof(char), GetSerializeSize(bool(0), 0));
+
+ // Sanity-check GetSerializeSize and c++ type matching
+ BOOST_CHECK_EQUAL(GetSerializeSize(char(0), 0), 1);
+ BOOST_CHECK_EQUAL(GetSerializeSize(int8_t(0), 0), 1);
+ BOOST_CHECK_EQUAL(GetSerializeSize(uint8_t(0), 0), 1);
+ BOOST_CHECK_EQUAL(GetSerializeSize(int16_t(0), 0), 2);
+ BOOST_CHECK_EQUAL(GetSerializeSize(uint16_t(0), 0), 2);
+ BOOST_CHECK_EQUAL(GetSerializeSize(int32_t(0), 0), 4);
+ BOOST_CHECK_EQUAL(GetSerializeSize(uint32_t(0), 0), 4);
+ BOOST_CHECK_EQUAL(GetSerializeSize(int64_t(0), 0), 8);
+ BOOST_CHECK_EQUAL(GetSerializeSize(uint64_t(0), 0), 8);
+ BOOST_CHECK_EQUAL(GetSerializeSize(float(0), 0), 4);
+ BOOST_CHECK_EQUAL(GetSerializeSize(double(0), 0), 8);
+ BOOST_CHECK_EQUAL(GetSerializeSize(bool(0), 0), 1);
+}
+
+BOOST_AUTO_TEST_CASE(floats_conversion)
+{
+ // Choose values that map unambigiously to binary floating point to avoid
+ // rounding issues at the compiler side.
+ BOOST_CHECK_EQUAL(ser_uint32_to_float(0x00000000), 0.0F);
+ BOOST_CHECK_EQUAL(ser_uint32_to_float(0x3f000000), 0.5F);
+ BOOST_CHECK_EQUAL(ser_uint32_to_float(0x3f800000), 1.0F);
+ BOOST_CHECK_EQUAL(ser_uint32_to_float(0x40000000), 2.0F);
+ BOOST_CHECK_EQUAL(ser_uint32_to_float(0x40800000), 4.0F);
+ BOOST_CHECK_EQUAL(ser_uint32_to_float(0x44444444), 785.066650390625F);
+
+ BOOST_CHECK_EQUAL(ser_float_to_uint32(0.0F), 0x00000000);
+ BOOST_CHECK_EQUAL(ser_float_to_uint32(0.5F), 0x3f000000);
+ BOOST_CHECK_EQUAL(ser_float_to_uint32(1.0F), 0x3f800000);
+ BOOST_CHECK_EQUAL(ser_float_to_uint32(2.0F), 0x40000000);
+ BOOST_CHECK_EQUAL(ser_float_to_uint32(4.0F), 0x40800000);
+ BOOST_CHECK_EQUAL(ser_float_to_uint32(785.066650390625F), 0x44444444);
+}
+
+BOOST_AUTO_TEST_CASE(doubles_conversion)
+{
+ // Choose values that map unambigiously to binary floating point to avoid
+ // rounding issues at the compiler side.
+ BOOST_CHECK_EQUAL(ser_uint64_to_double(0x0000000000000000ULL), 0.0);
+ BOOST_CHECK_EQUAL(ser_uint64_to_double(0x3fe0000000000000ULL), 0.5);
+ BOOST_CHECK_EQUAL(ser_uint64_to_double(0x3ff0000000000000ULL), 1.0);
+ BOOST_CHECK_EQUAL(ser_uint64_to_double(0x4000000000000000ULL), 2.0);
+ BOOST_CHECK_EQUAL(ser_uint64_to_double(0x4010000000000000ULL), 4.0);
+ BOOST_CHECK_EQUAL(ser_uint64_to_double(0x4088888880000000ULL), 785.066650390625);
+
+ BOOST_CHECK_EQUAL(ser_double_to_uint64(0.0), 0x0000000000000000ULL);
+ BOOST_CHECK_EQUAL(ser_double_to_uint64(0.5), 0x3fe0000000000000ULL);
+ BOOST_CHECK_EQUAL(ser_double_to_uint64(1.0), 0x3ff0000000000000ULL);
+ BOOST_CHECK_EQUAL(ser_double_to_uint64(2.0), 0x4000000000000000ULL);
+ BOOST_CHECK_EQUAL(ser_double_to_uint64(4.0), 0x4010000000000000ULL);
+ BOOST_CHECK_EQUAL(ser_double_to_uint64(785.066650390625), 0x4088888880000000ULL);
+}
+/*
+Python code to generate the below hashes:
+
+ def reversed_hex(x):
+ return binascii.hexlify(''.join(reversed(x)))
+ def dsha256(x):
+ return hashlib.sha256(hashlib.sha256(x).digest()).digest()
+
+ reversed_hex(dsha256(''.join(struct.pack('<f', x) for x in range(0,1000)))) == '8e8b4cf3e4df8b332057e3e23af42ebc663b61e0495d5e7e32d85099d7f3fe0c'
+ reversed_hex(dsha256(''.join(struct.pack('<d', x) for x in range(0,1000)))) == '43d0c82591953c4eafe114590d392676a01585d25b25d433557f0d7878b23f96'
+*/
+BOOST_AUTO_TEST_CASE(floats)
+{
+ CDataStream ss(SER_DISK, 0);
+ // encode
+ for (int i = 0; i < 1000; i++) {
+ ss << float(i);
+ }
+ BOOST_CHECK(Hash(ss.begin(), ss.end()) == uint256S("8e8b4cf3e4df8b332057e3e23af42ebc663b61e0495d5e7e32d85099d7f3fe0c"));
+
+ // decode
+ for (int i = 0; i < 1000; i++) {
+ float j;
+ ss >> j;
+ BOOST_CHECK_MESSAGE(i == j, "decoded:" << j << " expected:" << i);
+ }
+}
+
+BOOST_AUTO_TEST_CASE(doubles)
+{
+ CDataStream ss(SER_DISK, 0);
+ // encode
+ for (int i = 0; i < 1000; i++) {
+ ss << double(i);
+ }
+ BOOST_CHECK(Hash(ss.begin(), ss.end()) == uint256S("43d0c82591953c4eafe114590d392676a01585d25b25d433557f0d7878b23f96"));
+
+ // decode
+ for (int i = 0; i < 1000; i++) {
+ double j;
+ ss >> j;
+ BOOST_CHECK_MESSAGE(i == j, "decoded:" << j << " expected:" << i);
+ }
+}
+
+BOOST_AUTO_TEST_CASE(varints)
+{
+ // encode
+
+ CDataStream ss(SER_DISK, 0);
+ CDataStream::size_type size = 0;
+ for (int i = 0; i < 100000; i++) {
+ ss << VARINT(i);
+ size += ::GetSerializeSize(VARINT(i), 0, 0);
+ BOOST_CHECK(size == ss.size());
+ }
+
+ for (uint64_t i = 0; i < 100000000000ULL; i += 999999937) {
+ ss << VARINT(i);
+ size += ::GetSerializeSize(VARINT(i), 0, 0);
+ BOOST_CHECK(size == ss.size());
+ }
+
+ // decode
+ for (int i = 0; i < 100000; i++) {
+ int j = -1;
+ ss >> VARINT(j);
+ BOOST_CHECK_MESSAGE(i == j, "decoded:" << j << " expected:" << i);
+ }
+
+ for (uint64_t i = 0; i < 100000000000ULL; i += 999999937) {
+ uint64_t j = -1;
+ ss >> VARINT(j);
+ BOOST_CHECK_MESSAGE(i == j, "decoded:" << j << " expected:" << i);
+ }
+}
+
+BOOST_AUTO_TEST_CASE(compactsize)
+{
+ CDataStream ss(SER_DISK, 0);
+ vector<char>::size_type i, j;
+
+ for (i = 1; i <= MAX_SIZE; i *= 2)
+ {
+ WriteCompactSize(ss, i-1);
+ WriteCompactSize(ss, i);
+ }
+ for (i = 1; i <= MAX_SIZE; i *= 2)
+ {
+ j = ReadCompactSize(ss);
+ BOOST_CHECK_MESSAGE((i-1) == j, "decoded:" << j << " expected:" << (i-1));
+ j = ReadCompactSize(ss);
+ BOOST_CHECK_MESSAGE(i == j, "decoded:" << j << " expected:" << i);
+ }
+}
+
+static bool isCanonicalException(const std::ios_base::failure& ex)
+{
+ std::ios_base::failure expectedException("non-canonical ReadCompactSize()");
+
+ // The string returned by what() can be different for different platforms.
+ // Instead of directly comparing the ex.what() with an expected string,
+ // create an instance of exception to see if ex.what() matches
+ // the expected explanatory string returned by the exception instance.
+ return strcmp(expectedException.what(), ex.what()) == 0;
+}
+
+
+BOOST_AUTO_TEST_CASE(noncanonical)
+{
+ // Write some non-canonical CompactSize encodings, and
+ // make sure an exception is thrown when read back.
+ CDataStream ss(SER_DISK, 0);
+ vector<char>::size_type n;
+
+ // zero encoded with three bytes:
+ ss.write("\xfd\x00\x00", 3);
+ BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException);
+
+ // 0xfc encoded with three bytes:
+ ss.write("\xfd\xfc\x00", 3);
+ BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException);
+
+ // 0xfd encoded with three bytes is OK:
+ ss.write("\xfd\xfd\x00", 3);
+ n = ReadCompactSize(ss);
+ BOOST_CHECK(n == 0xfd);
+
+ // zero encoded with five bytes:
+ ss.write("\xfe\x00\x00\x00\x00", 5);
+ BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException);
+
+ // 0xffff encoded with five bytes:
+ ss.write("\xfe\xff\xff\x00\x00", 5);
+ BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException);
+
+ // zero encoded with nine bytes:
+ ss.write("\xff\x00\x00\x00\x00\x00\x00\x00\x00", 9);
+ BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException);
+
+ // 0x01ffffff encoded with nine bytes:
+ ss.write("\xff\xff\xff\xff\x01\x00\x00\x00\x00", 9);
+ BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException);
+}
+
+BOOST_AUTO_TEST_CASE(insert_delete)
+{
+ // Test inserting/deleting bytes.
+ CDataStream ss(SER_DISK, 0);
+ BOOST_CHECK_EQUAL(ss.size(), 0);
+
+ ss.write("\x00\x01\x02\xff", 4);
+ BOOST_CHECK_EQUAL(ss.size(), 4);
+
+ char c = (char)11;
+
+ // Inserting at beginning/end/middle:
+ ss.insert(ss.begin(), c);
+ BOOST_CHECK_EQUAL(ss.size(), 5);
+ BOOST_CHECK_EQUAL(ss[0], c);
+ BOOST_CHECK_EQUAL(ss[1], 0);
+
+ ss.insert(ss.end(), c);
+ BOOST_CHECK_EQUAL(ss.size(), 6);
+ BOOST_CHECK_EQUAL(ss[4], (char)0xff);
+ BOOST_CHECK_EQUAL(ss[5], c);
+
+ ss.insert(ss.begin()+2, c);
+ BOOST_CHECK_EQUAL(ss.size(), 7);
+ BOOST_CHECK_EQUAL(ss[2], c);
+
+ // Delete at beginning/end/middle
+ ss.erase(ss.begin());
+ BOOST_CHECK_EQUAL(ss.size(), 6);
+ BOOST_CHECK_EQUAL(ss[0], 0);
+
+ ss.erase(ss.begin()+ss.size()-1);
+ BOOST_CHECK_EQUAL(ss.size(), 5);
+ BOOST_CHECK_EQUAL(ss[4], (char)0xff);
+
+ ss.erase(ss.begin()+1);
+ BOOST_CHECK_EQUAL(ss.size(), 4);
+ BOOST_CHECK_EQUAL(ss[0], 0);
+ BOOST_CHECK_EQUAL(ss[1], 1);
+ BOOST_CHECK_EQUAL(ss[2], 2);
+ BOOST_CHECK_EQUAL(ss[3], (char)0xff);
+
+ // Make sure GetAndClear does the right thing:
+ CSerializeData d;
+ ss.GetAndClear(d);
+ BOOST_CHECK_EQUAL(ss.size(), 0);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp
new file mode 100644
index 0000000000..87be2217c4
--- /dev/null
+++ b/src/test/sighash_tests.cpp
@@ -0,0 +1,217 @@
+// Copyright (c) 2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "consensus/validation.h"
+#include "data/sighash.json.h"
+#include "main.h"
+#include "random.h"
+#include "script/interpreter.h"
+#include "script/script.h"
+#include "serialize.h"
+#include "test/test_bitcoin.h"
+#include "util.h"
+#include "version.h"
+
+#include <iostream>
+
+#include <boost/test/unit_test.hpp>
+#include "json/json_spirit_reader_template.h"
+#include "json/json_spirit_utils.h"
+#include "json/json_spirit_writer_template.h"
+
+using namespace json_spirit;
+extern Array read_json(const std::string& jsondata);
+
+// Old script.cpp SignatureHash function
+uint256 static SignatureHashOld(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType)
+{
+ static const uint256 one(uint256S("0000000000000000000000000000000000000000000000000000000000000001"));
+ if (nIn >= txTo.vin.size())
+ {
+ printf("ERROR: SignatureHash(): nIn=%d out of range\n", nIn);
+ return one;
+ }
+ CMutableTransaction 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 lock-in 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 one;
+ }
+ 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
+ CHashWriter ss(SER_GETHASH, 0);
+ ss << txTmp << nHashType;
+ return ss.GetHash();
+}
+
+void static RandomScript(CScript &script) {
+ static const opcodetype oplist[] = {OP_FALSE, OP_1, OP_2, OP_3, OP_CHECKSIG, OP_IF, OP_VERIF, OP_RETURN, OP_CODESEPARATOR};
+ script = CScript();
+ int ops = (insecure_rand() % 10);
+ for (int i=0; i<ops; i++)
+ script << oplist[insecure_rand() % (sizeof(oplist)/sizeof(oplist[0]))];
+}
+
+void static RandomTransaction(CMutableTransaction &tx, bool fSingle) {
+ tx.nVersion = insecure_rand();
+ tx.vin.clear();
+ tx.vout.clear();
+ tx.nLockTime = (insecure_rand() % 2) ? insecure_rand() : 0;
+ int ins = (insecure_rand() % 4) + 1;
+ int outs = fSingle ? ins : (insecure_rand() % 4) + 1;
+ for (int in = 0; in < ins; in++) {
+ tx.vin.push_back(CTxIn());
+ CTxIn &txin = tx.vin.back();
+ txin.prevout.hash = GetRandHash();
+ txin.prevout.n = insecure_rand() % 4;
+ RandomScript(txin.scriptSig);
+ txin.nSequence = (insecure_rand() % 2) ? insecure_rand() : (unsigned int)-1;
+ }
+ for (int out = 0; out < outs; out++) {
+ tx.vout.push_back(CTxOut());
+ CTxOut &txout = tx.vout.back();
+ txout.nValue = insecure_rand() % 100000000;
+ RandomScript(txout.scriptPubKey);
+ }
+}
+
+BOOST_FIXTURE_TEST_SUITE(sighash_tests, BasicTestingSetup)
+
+BOOST_AUTO_TEST_CASE(sighash_test)
+{
+ seed_insecure_rand(false);
+
+ #if defined(PRINT_SIGHASH_JSON)
+ std::cout << "[\n";
+ std::cout << "\t[\"raw_transaction, script, input_index, hashType, signature_hash (result)\"],\n";
+ #endif
+ int nRandomTests = 50000;
+
+ #if defined(PRINT_SIGHASH_JSON)
+ nRandomTests = 500;
+ #endif
+ for (int i=0; i<nRandomTests; i++) {
+ int nHashType = insecure_rand();
+ CMutableTransaction txTo;
+ RandomTransaction(txTo, (nHashType & 0x1f) == SIGHASH_SINGLE);
+ CScript scriptCode;
+ RandomScript(scriptCode);
+ int nIn = insecure_rand() % txTo.vin.size();
+
+ uint256 sh, sho;
+ sho = SignatureHashOld(scriptCode, txTo, nIn, nHashType);
+ sh = SignatureHash(scriptCode, txTo, nIn, nHashType);
+ #if defined(PRINT_SIGHASH_JSON)
+ CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
+ ss << txTo;
+
+ std::cout << "\t[\"" ;
+ std::cout << HexStr(ss.begin(), ss.end()) << "\", \"";
+ std::cout << HexStr(scriptCode) << "\", ";
+ std::cout << nIn << ", ";
+ std::cout << nHashType << ", \"";
+ std::cout << sho.GetHex() << "\"]";
+ if (i+1 != nRandomTests) {
+ std::cout << ",";
+ }
+ std::cout << "\n";
+ #endif
+ BOOST_CHECK(sh == sho);
+ }
+ #if defined(PRINT_SIGHASH_JSON)
+ std::cout << "]\n";
+ #endif
+}
+
+// Goal: check that SignatureHash generates correct hash
+BOOST_AUTO_TEST_CASE(sighash_from_data)
+{
+ Array tests = read_json(std::string(json_tests::sighash, json_tests::sighash + sizeof(json_tests::sighash)));
+
+ BOOST_FOREACH(Value& tv, tests)
+ {
+ Array test = tv.get_array();
+ std::string strTest = write_string(tv, false);
+ if (test.size() < 1) // Allow for extra stuff (useful for comments)
+ {
+ BOOST_ERROR("Bad test: " << strTest);
+ continue;
+ }
+ if (test.size() == 1) continue; // comment
+
+ std::string raw_tx, raw_script, sigHashHex;
+ int nIn, nHashType;
+ uint256 sh;
+ CTransaction tx;
+ CScript scriptCode = CScript();
+
+ try {
+ // deserialize test data
+ raw_tx = test[0].get_str();
+ raw_script = test[1].get_str();
+ nIn = test[2].get_int();
+ nHashType = test[3].get_int();
+ sigHashHex = test[4].get_str();
+
+ uint256 sh;
+ CDataStream stream(ParseHex(raw_tx), SER_NETWORK, PROTOCOL_VERSION);
+ stream >> tx;
+
+ CValidationState state;
+ BOOST_CHECK_MESSAGE(CheckTransaction(tx, state), strTest);
+ BOOST_CHECK(state.IsValid());
+
+ std::vector<unsigned char> raw = ParseHex(raw_script);
+ scriptCode.insert(scriptCode.end(), raw.begin(), raw.end());
+ } catch (...) {
+ BOOST_ERROR("Bad test, couldn't deserialize data: " << strTest);
+ continue;
+ }
+
+ sh = SignatureHash(scriptCode, tx, nIn, nHashType);
+ BOOST_CHECK_MESSAGE(sh.GetHex() == sigHashHex, strTest);
+ }
+}
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/sigopcount_tests.cpp b/src/test/sigopcount_tests.cpp
new file mode 100644
index 0000000000..b26fed99f2
--- /dev/null
+++ b/src/test/sigopcount_tests.cpp
@@ -0,0 +1,67 @@
+// Copyright (c) 2012-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "pubkey.h"
+#include "key.h"
+#include "script/script.h"
+#include "script/standard.h"
+#include "uint256.h"
+#include "test/test_bitcoin.h"
+
+#include <vector>
+
+#include <boost/foreach.hpp>
+#include <boost/test/unit_test.hpp>
+
+using namespace std;
+
+// Helpers:
+static std::vector<unsigned char>
+Serialize(const CScript& s)
+{
+ std::vector<unsigned char> sSerialized(s);
+ return sSerialized;
+}
+
+BOOST_FIXTURE_TEST_SUITE(sigopcount_tests, BasicTestingSetup)
+
+BOOST_AUTO_TEST_CASE(GetSigOpCount)
+{
+ // Test CScript::GetSigOpCount()
+ CScript s1;
+ BOOST_CHECK_EQUAL(s1.GetSigOpCount(false), 0U);
+ BOOST_CHECK_EQUAL(s1.GetSigOpCount(true), 0U);
+
+ uint160 dummy;
+ s1 << OP_1 << ToByteVector(dummy) << ToByteVector(dummy) << OP_2 << OP_CHECKMULTISIG;
+ BOOST_CHECK_EQUAL(s1.GetSigOpCount(true), 2U);
+ s1 << OP_IF << OP_CHECKSIG << OP_ENDIF;
+ BOOST_CHECK_EQUAL(s1.GetSigOpCount(true), 3U);
+ BOOST_CHECK_EQUAL(s1.GetSigOpCount(false), 21U);
+
+ CScript p2sh = GetScriptForDestination(CScriptID(s1));
+ CScript scriptSig;
+ scriptSig << OP_0 << Serialize(s1);
+ BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(scriptSig), 3U);
+
+ std::vector<CPubKey> keys;
+ for (int i = 0; i < 3; i++)
+ {
+ CKey k;
+ k.MakeNewKey(true);
+ keys.push_back(k.GetPubKey());
+ }
+ CScript s2 = GetScriptForMultisig(1, keys);
+ BOOST_CHECK_EQUAL(s2.GetSigOpCount(true), 3U);
+ BOOST_CHECK_EQUAL(s2.GetSigOpCount(false), 20U);
+
+ p2sh = GetScriptForDestination(CScriptID(s2));
+ BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(true), 0U);
+ BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(false), 0U);
+ CScript scriptSig2;
+ scriptSig2 << OP_1 << ToByteVector(dummy) << ToByteVector(dummy) << Serialize(s2);
+ BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(scriptSig2), 3U);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/skiplist_tests.cpp b/src/test/skiplist_tests.cpp
new file mode 100644
index 0000000000..86a4bc6727
--- /dev/null
+++ b/src/test/skiplist_tests.cpp
@@ -0,0 +1,103 @@
+// Copyright (c) 2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "main.h"
+#include "random.h"
+#include "util.h"
+#include "test/test_bitcoin.h"
+
+#include <vector>
+
+#include <boost/test/unit_test.hpp>
+
+#define SKIPLIST_LENGTH 300000
+
+BOOST_FIXTURE_TEST_SUITE(skiplist_tests, BasicTestingSetup)
+
+BOOST_AUTO_TEST_CASE(skiplist_test)
+{
+ std::vector<CBlockIndex> vIndex(SKIPLIST_LENGTH);
+
+ for (int i=0; i<SKIPLIST_LENGTH; i++) {
+ vIndex[i].nHeight = i;
+ vIndex[i].pprev = (i == 0) ? NULL : &vIndex[i - 1];
+ vIndex[i].BuildSkip();
+ }
+
+ for (int i=0; i<SKIPLIST_LENGTH; i++) {
+ if (i > 0) {
+ BOOST_CHECK(vIndex[i].pskip == &vIndex[vIndex[i].pskip->nHeight]);
+ BOOST_CHECK(vIndex[i].pskip->nHeight < i);
+ } else {
+ BOOST_CHECK(vIndex[i].pskip == NULL);
+ }
+ }
+
+ for (int i=0; i < 1000; i++) {
+ int from = insecure_rand() % (SKIPLIST_LENGTH - 1);
+ int to = insecure_rand() % (from + 1);
+
+ BOOST_CHECK(vIndex[SKIPLIST_LENGTH - 1].GetAncestor(from) == &vIndex[from]);
+ BOOST_CHECK(vIndex[from].GetAncestor(to) == &vIndex[to]);
+ BOOST_CHECK(vIndex[from].GetAncestor(0) == &vIndex[0]);
+ }
+}
+
+BOOST_AUTO_TEST_CASE(getlocator_test)
+{
+ // Build a main chain 100000 blocks long.
+ std::vector<uint256> vHashMain(100000);
+ std::vector<CBlockIndex> vBlocksMain(100000);
+ for (unsigned int i=0; i<vBlocksMain.size(); i++) {
+ vHashMain[i] = ArithToUint256(i); // Set the hash equal to the height, so we can quickly check the distances.
+ vBlocksMain[i].nHeight = i;
+ vBlocksMain[i].pprev = i ? &vBlocksMain[i - 1] : NULL;
+ vBlocksMain[i].phashBlock = &vHashMain[i];
+ vBlocksMain[i].BuildSkip();
+ BOOST_CHECK_EQUAL((int)UintToArith256(vBlocksMain[i].GetBlockHash()).GetLow64(), vBlocksMain[i].nHeight);
+ BOOST_CHECK(vBlocksMain[i].pprev == NULL || vBlocksMain[i].nHeight == vBlocksMain[i].pprev->nHeight + 1);
+ }
+
+ // Build a branch that splits off at block 49999, 50000 blocks long.
+ std::vector<uint256> vHashSide(50000);
+ std::vector<CBlockIndex> vBlocksSide(50000);
+ for (unsigned int i=0; i<vBlocksSide.size(); i++) {
+ vHashSide[i] = ArithToUint256(i + 50000 + (arith_uint256(1) << 128)); // Add 1<<128 to the hashes, so GetLow64() still returns the height.
+ vBlocksSide[i].nHeight = i + 50000;
+ vBlocksSide[i].pprev = i ? &vBlocksSide[i - 1] : &vBlocksMain[49999];
+ vBlocksSide[i].phashBlock = &vHashSide[i];
+ vBlocksSide[i].BuildSkip();
+ BOOST_CHECK_EQUAL((int)UintToArith256(vBlocksSide[i].GetBlockHash()).GetLow64(), vBlocksSide[i].nHeight);
+ BOOST_CHECK(vBlocksSide[i].pprev == NULL || vBlocksSide[i].nHeight == vBlocksSide[i].pprev->nHeight + 1);
+ }
+
+ // Build a CChain for the main branch.
+ CChain chain;
+ chain.SetTip(&vBlocksMain.back());
+
+ // Test 100 random starting points for locators.
+ for (int n=0; n<100; n++) {
+ int r = insecure_rand() % 150000;
+ CBlockIndex* tip = (r < 100000) ? &vBlocksMain[r] : &vBlocksSide[r - 100000];
+ CBlockLocator locator = chain.GetLocator(tip);
+
+ // The first result must be the block itself, the last one must be genesis.
+ BOOST_CHECK(locator.vHave.front() == tip->GetBlockHash());
+ BOOST_CHECK(locator.vHave.back() == vBlocksMain[0].GetBlockHash());
+
+ // Entries 1 through 11 (inclusive) go back one step each.
+ for (unsigned int i = 1; i < 12 && i < locator.vHave.size() - 1; i++) {
+ BOOST_CHECK_EQUAL(UintToArith256(locator.vHave[i]).GetLow64(), tip->nHeight - i);
+ }
+
+ // The further ones (excluding the last one) go back with exponential steps.
+ unsigned int dist = 2;
+ for (unsigned int i = 12; i < locator.vHave.size() - 1; i++) {
+ BOOST_CHECK_EQUAL(UintToArith256(locator.vHave[i - 1]).GetLow64() - UintToArith256(locator.vHave[i]).GetLow64(), dist);
+ dist *= 2;
+ }
+ }
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp
new file mode 100644
index 0000000000..c727303ea1
--- /dev/null
+++ b/src/test/test_bitcoin.cpp
@@ -0,0 +1,102 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#define BOOST_TEST_MODULE Bitcoin Test Suite
+
+#include "test_bitcoin.h"
+
+#include "key.h"
+#include "main.h"
+#include "random.h"
+#include "txdb.h"
+#include "ui_interface.h"
+#include "util.h"
+#ifdef ENABLE_WALLET
+#include "wallet/db.h"
+#include "wallet/wallet.h"
+#endif
+
+#include <boost/filesystem.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/thread.hpp>
+
+CClientUIInterface uiInterface; // Declared but not defined in ui_interface.h
+CWallet* pwalletMain;
+
+extern bool fPrintToConsole;
+extern void noui_connect();
+
+BasicTestingSetup::BasicTestingSetup()
+{
+ ECC_Start();
+ SetupEnvironment();
+ fPrintToDebugLog = false; // don't want to write to debug.log file
+ fCheckBlockIndex = true;
+ SelectParams(CBaseChainParams::MAIN);
+}
+BasicTestingSetup::~BasicTestingSetup()
+{
+ ECC_Stop();
+}
+
+TestingSetup::TestingSetup()
+{
+#ifdef ENABLE_WALLET
+ bitdb.MakeMock();
+#endif
+ ClearDatadirCache();
+ pathTemp = GetTempPath() / strprintf("test_bitcoin_%lu_%i", (unsigned long)GetTime(), (int)(GetRand(100000)));
+ boost::filesystem::create_directories(pathTemp);
+ mapArgs["-datadir"] = pathTemp.string();
+ pblocktree = new CBlockTreeDB(1 << 20, true);
+ pcoinsdbview = new CCoinsViewDB(1 << 23, true);
+ pcoinsTip = new CCoinsViewCache(pcoinsdbview);
+ InitBlockIndex();
+#ifdef ENABLE_WALLET
+ bool fFirstRun;
+ pwalletMain = new CWallet("wallet.dat");
+ pwalletMain->LoadWallet(fFirstRun);
+ RegisterValidationInterface(pwalletMain);
+#endif
+ nScriptCheckThreads = 3;
+ for (int i=0; i < nScriptCheckThreads-1; i++)
+ threadGroup.create_thread(&ThreadScriptCheck);
+ RegisterNodeSignals(GetNodeSignals());
+}
+
+TestingSetup::~TestingSetup()
+{
+ UnregisterNodeSignals(GetNodeSignals());
+ threadGroup.interrupt_all();
+ threadGroup.join_all();
+#ifdef ENABLE_WALLET
+ UnregisterValidationInterface(pwalletMain);
+ delete pwalletMain;
+ pwalletMain = NULL;
+#endif
+ UnloadBlockIndex();
+ delete pcoinsTip;
+ delete pcoinsdbview;
+ delete pblocktree;
+#ifdef ENABLE_WALLET
+ bitdb.Flush(true);
+ bitdb.Reset();
+#endif
+ boost::filesystem::remove_all(pathTemp);
+}
+
+void Shutdown(void* parg)
+{
+ exit(0);
+}
+
+void StartShutdown()
+{
+ exit(0);
+}
+
+bool ShutdownRequested()
+{
+ return false;
+}
diff --git a/src/test/test_bitcoin.h b/src/test/test_bitcoin.h
new file mode 100644
index 0000000000..2f75332d40
--- /dev/null
+++ b/src/test/test_bitcoin.h
@@ -0,0 +1,30 @@
+#ifndef BITCOIN_TEST_TEST_BITCOIN_H
+#define BITCOIN_TEST_TEST_BITCOIN_H
+
+#include "txdb.h"
+
+#include <boost/filesystem.hpp>
+#include <boost/thread.hpp>
+
+/** Basic testing setup.
+ * This just configures logging and chain parameters.
+ */
+struct BasicTestingSetup {
+ BasicTestingSetup();
+ ~BasicTestingSetup();
+};
+
+/** Testing setup that configures a complete environment.
+ * Included are data directory, coins database, script check threads
+ * and wallet (if enabled) setup.
+ */
+struct TestingSetup: public BasicTestingSetup {
+ CCoinsViewDB *pcoinsdbview;
+ boost::filesystem::path pathTemp;
+ boost::thread_group threadGroup;
+
+ TestingSetup();
+ ~TestingSetup();
+};
+
+#endif
diff --git a/src/test/timedata_tests.cpp b/src/test/timedata_tests.cpp
new file mode 100644
index 0000000000..887cfb4761
--- /dev/null
+++ b/src/test/timedata_tests.cpp
@@ -0,0 +1,39 @@
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+//
+#include "timedata.h"
+#include "test/test_bitcoin.h"
+
+#include <boost/test/unit_test.hpp>
+
+using namespace std;
+
+BOOST_FIXTURE_TEST_SUITE(timedata_tests, BasicTestingSetup)
+
+BOOST_AUTO_TEST_CASE(util_MedianFilter)
+{
+ CMedianFilter<int> 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);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp
new file mode 100644
index 0000000000..28152c64a2
--- /dev/null
+++ b/src/test/transaction_tests.cpp
@@ -0,0 +1,381 @@
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "data/tx_invalid.json.h"
+#include "data/tx_valid.json.h"
+#include "test/test_bitcoin.h"
+
+#include "clientversion.h"
+#include "consensus/validation.h"
+#include "core_io.h"
+#include "key.h"
+#include "keystore.h"
+#include "main.h"
+#include "script/script.h"
+#include "script/script_error.h"
+
+#include <map>
+#include <string>
+
+#include <boost/algorithm/string/classification.hpp>
+#include <boost/algorithm/string/split.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/assign/list_of.hpp>
+#include "json/json_spirit_writer_template.h"
+
+using namespace std;
+using namespace json_spirit;
+
+// In script_tests.cpp
+extern Array read_json(const std::string& jsondata);
+
+static std::map<string, unsigned int> mapFlagNames = boost::assign::map_list_of
+ (string("NONE"), (unsigned int)SCRIPT_VERIFY_NONE)
+ (string("P2SH"), (unsigned int)SCRIPT_VERIFY_P2SH)
+ (string("STRICTENC"), (unsigned int)SCRIPT_VERIFY_STRICTENC)
+ (string("DERSIG"), (unsigned int)SCRIPT_VERIFY_DERSIG)
+ (string("LOW_S"), (unsigned int)SCRIPT_VERIFY_LOW_S)
+ (string("SIGPUSHONLY"), (unsigned int)SCRIPT_VERIFY_SIGPUSHONLY)
+ (string("MINIMALDATA"), (unsigned int)SCRIPT_VERIFY_MINIMALDATA)
+ (string("NULLDUMMY"), (unsigned int)SCRIPT_VERIFY_NULLDUMMY)
+ (string("DISCOURAGE_UPGRADABLE_NOPS"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS)
+ (string("CLEANSTACK"), (unsigned int)SCRIPT_VERIFY_CLEANSTACK)
+ (string("CHECKLOCKTIMEVERIFY"), (unsigned int)SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY);
+
+unsigned int ParseScriptFlags(string strFlags)
+{
+ if (strFlags.empty()) {
+ return 0;
+ }
+ unsigned int flags = 0;
+ vector<string> words;
+ boost::algorithm::split(words, strFlags, boost::algorithm::is_any_of(","));
+
+ BOOST_FOREACH(string word, words)
+ {
+ if (!mapFlagNames.count(word))
+ BOOST_ERROR("Bad test: unknown verification flag '" << word << "'");
+ flags |= mapFlagNames[word];
+ }
+
+ return flags;
+}
+
+string FormatScriptFlags(unsigned int flags)
+{
+ if (flags == 0) {
+ return "";
+ }
+ string ret;
+ std::map<string, unsigned int>::const_iterator it = mapFlagNames.begin();
+ while (it != mapFlagNames.end()) {
+ if (flags & it->second) {
+ ret += it->first + ",";
+ }
+ it++;
+ }
+ return ret.substr(0, ret.size() - 1);
+}
+
+BOOST_FIXTURE_TEST_SUITE(transaction_tests, BasicTestingSetup)
+
+BOOST_AUTO_TEST_CASE(tx_valid)
+{
+ // Read tests from test/data/tx_valid.json
+ // Format is an array of arrays
+ // Inner arrays are either [ "comment" ]
+ // or [[[prevout hash, prevout index, prevout scriptPubKey], [input 2], ...],"], serializedTransaction, verifyFlags
+ // ... where all scripts are stringified scripts.
+ //
+ // verifyFlags is a comma separated list of script verification flags to apply, or "NONE"
+ Array tests = read_json(std::string(json_tests::tx_valid, json_tests::tx_valid + sizeof(json_tests::tx_valid)));
+
+ ScriptError err;
+ BOOST_FOREACH(Value& tv, tests)
+ {
+ Array test = tv.get_array();
+ string strTest = write_string(tv, false);
+ if (test[0].type() == array_type)
+ {
+ if (test.size() != 3 || test[1].type() != str_type || test[2].type() != str_type)
+ {
+ BOOST_ERROR("Bad test: " << strTest);
+ continue;
+ }
+
+ map<COutPoint, CScript> mapprevOutScriptPubKeys;
+ Array inputs = test[0].get_array();
+ bool fValid = true;
+ BOOST_FOREACH(Value& input, inputs)
+ {
+ if (input.type() != array_type)
+ {
+ fValid = false;
+ break;
+ }
+ Array vinput = input.get_array();
+ if (vinput.size() != 3)
+ {
+ fValid = false;
+ break;
+ }
+
+ mapprevOutScriptPubKeys[COutPoint(uint256S(vinput[0].get_str()), vinput[1].get_int())] = ParseScript(vinput[2].get_str());
+ }
+ if (!fValid)
+ {
+ BOOST_ERROR("Bad test: " << strTest);
+ continue;
+ }
+
+ string transaction = test[1].get_str();
+ CDataStream stream(ParseHex(transaction), SER_NETWORK, PROTOCOL_VERSION);
+ CTransaction tx;
+ stream >> tx;
+
+ CValidationState state;
+ BOOST_CHECK_MESSAGE(CheckTransaction(tx, state), strTest);
+ BOOST_CHECK(state.IsValid());
+
+ for (unsigned int i = 0; i < tx.vin.size(); i++)
+ {
+ if (!mapprevOutScriptPubKeys.count(tx.vin[i].prevout))
+ {
+ BOOST_ERROR("Bad test: " << strTest);
+ break;
+ }
+
+ unsigned int verify_flags = ParseScriptFlags(test[2].get_str());
+ BOOST_CHECK_MESSAGE(VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout],
+ verify_flags, TransactionSignatureChecker(&tx, i), &err),
+ strTest);
+ BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
+ }
+ }
+ }
+}
+
+BOOST_AUTO_TEST_CASE(tx_invalid)
+{
+ // Read tests from test/data/tx_invalid.json
+ // Format is an array of arrays
+ // Inner arrays are either [ "comment" ]
+ // or [[[prevout hash, prevout index, prevout scriptPubKey], [input 2], ...],"], serializedTransaction, verifyFlags
+ // ... where all scripts are stringified scripts.
+ //
+ // verifyFlags is a comma separated list of script verification flags to apply, or "NONE"
+ Array tests = read_json(std::string(json_tests::tx_invalid, json_tests::tx_invalid + sizeof(json_tests::tx_invalid)));
+
+ ScriptError err;
+ BOOST_FOREACH(Value& tv, tests)
+ {
+ Array test = tv.get_array();
+ string strTest = write_string(tv, false);
+ if (test[0].type() == array_type)
+ {
+ if (test.size() != 3 || test[1].type() != str_type || test[2].type() != str_type)
+ {
+ BOOST_ERROR("Bad test: " << strTest);
+ continue;
+ }
+
+ map<COutPoint, CScript> mapprevOutScriptPubKeys;
+ Array inputs = test[0].get_array();
+ bool fValid = true;
+ BOOST_FOREACH(Value& input, inputs)
+ {
+ if (input.type() != array_type)
+ {
+ fValid = false;
+ break;
+ }
+ Array vinput = input.get_array();
+ if (vinput.size() != 3)
+ {
+ fValid = false;
+ break;
+ }
+
+ mapprevOutScriptPubKeys[COutPoint(uint256S(vinput[0].get_str()), vinput[1].get_int())] = ParseScript(vinput[2].get_str());
+ }
+ if (!fValid)
+ {
+ BOOST_ERROR("Bad test: " << strTest);
+ continue;
+ }
+
+ string transaction = test[1].get_str();
+ CDataStream stream(ParseHex(transaction), SER_NETWORK, PROTOCOL_VERSION);
+ CTransaction tx;
+ stream >> tx;
+
+ CValidationState state;
+ fValid = CheckTransaction(tx, state) && state.IsValid();
+
+ for (unsigned int i = 0; i < tx.vin.size() && fValid; i++)
+ {
+ if (!mapprevOutScriptPubKeys.count(tx.vin[i].prevout))
+ {
+ BOOST_ERROR("Bad test: " << strTest);
+ break;
+ }
+
+ unsigned int verify_flags = ParseScriptFlags(test[2].get_str());
+ fValid = VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout],
+ verify_flags, TransactionSignatureChecker(&tx, i), &err);
+ }
+ BOOST_CHECK_MESSAGE(!fValid, strTest);
+ BOOST_CHECK_MESSAGE(err != SCRIPT_ERR_OK, ScriptErrorString(err));
+ }
+ }
+}
+
+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<unsigned char> vch(ch, ch + sizeof(ch) -1);
+ CDataStream stream(vch, SER_DISK, CLIENT_VERSION);
+ CMutableTransaction tx;
+ stream >> tx;
+ CValidationState state;
+ BOOST_CHECK_MESSAGE(CheckTransaction(tx, state) && state.IsValid(), "Simple deserialized transaction should be valid.");
+
+ // Check that duplicate txins fail
+ tx.vin.push_back(tx.vin[0]);
+ BOOST_CHECK_MESSAGE(!CheckTransaction(tx, state) || !state.IsValid(), "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<CMutableTransaction>
+SetupDummyInputs(CBasicKeyStore& keystoreRet, CCoinsViewCache& coinsRet)
+{
+ std::vector<CMutableTransaction> 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 << ToByteVector(key[0].GetPubKey()) << OP_CHECKSIG;
+ dummyTransactions[0].vout[1].nValue = 50*CENT;
+ dummyTransactions[0].vout[1].scriptPubKey << ToByteVector(key[1].GetPubKey()) << OP_CHECKSIG;
+ coinsRet.ModifyCoins(dummyTransactions[0].GetHash())->FromTx(dummyTransactions[0], 0);
+
+ dummyTransactions[1].vout.resize(2);
+ dummyTransactions[1].vout[0].nValue = 21*CENT;
+ dummyTransactions[1].vout[0].scriptPubKey = GetScriptForDestination(key[2].GetPubKey().GetID());
+ dummyTransactions[1].vout[1].nValue = 22*CENT;
+ dummyTransactions[1].vout[1].scriptPubKey = GetScriptForDestination(key[3].GetPubKey().GetID());
+ coinsRet.ModifyCoins(dummyTransactions[1].GetHash())->FromTx(dummyTransactions[1], 0);
+
+ return dummyTransactions;
+}
+
+BOOST_AUTO_TEST_CASE(test_Get)
+{
+ CBasicKeyStore keystore;
+ CCoinsView coinsDummy;
+ CCoinsViewCache coins(&coinsDummy);
+ std::vector<CMutableTransaction> dummyTransactions = SetupDummyInputs(keystore, coins);
+
+ CMutableTransaction 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<unsigned char>(65, 0);
+ t1.vin[1].prevout.hash = dummyTransactions[1].GetHash();
+ t1.vin[1].prevout.n = 0;
+ t1.vin[1].scriptSig << std::vector<unsigned char>(65, 0) << std::vector<unsigned char>(33, 4);
+ t1.vin[2].prevout.hash = dummyTransactions[1].GetHash();
+ t1.vin[2].prevout.n = 1;
+ t1.vin[2].scriptSig << std::vector<unsigned char>(65, 0) << std::vector<unsigned char>(33, 4);
+ t1.vout.resize(2);
+ t1.vout[0].nValue = 90*CENT;
+ t1.vout[0].scriptPubKey << OP_1;
+
+ BOOST_CHECK(AreInputsStandard(t1, coins));
+ BOOST_CHECK_EQUAL(coins.GetValueIn(t1), (50+21+22)*CENT);
+
+ // Adding extra junk to the scriptSig should make it non-standard:
+ t1.vin[0].scriptSig << OP_11;
+ BOOST_CHECK(!AreInputsStandard(t1, coins));
+
+ // ... as should not having enough:
+ t1.vin[0].scriptSig = CScript();
+ BOOST_CHECK(!AreInputsStandard(t1, coins));
+}
+
+BOOST_AUTO_TEST_CASE(test_IsStandard)
+{
+ LOCK(cs_main);
+ CBasicKeyStore keystore;
+ CCoinsView coinsDummy;
+ CCoinsViewCache coins(&coinsDummy);
+ std::vector<CMutableTransaction> dummyTransactions = SetupDummyInputs(keystore, coins);
+
+ CMutableTransaction t;
+ t.vin.resize(1);
+ t.vin[0].prevout.hash = dummyTransactions[0].GetHash();
+ t.vin[0].prevout.n = 1;
+ t.vin[0].scriptSig << std::vector<unsigned char>(65, 0);
+ t.vout.resize(1);
+ t.vout[0].nValue = 90*CENT;
+ CKey key;
+ key.MakeNewKey(true);
+ t.vout[0].scriptPubKey = GetScriptForDestination(key.GetPubKey().GetID());
+
+ string reason;
+ BOOST_CHECK(IsStandardTx(t, reason));
+
+ t.vout[0].nValue = 501; // dust
+ BOOST_CHECK(!IsStandardTx(t, reason));
+
+ t.vout[0].nValue = 2730; // not dust
+ BOOST_CHECK(IsStandardTx(t, reason));
+
+ t.vout[0].scriptPubKey = CScript() << OP_1;
+ BOOST_CHECK(!IsStandardTx(t, reason));
+
+ // 80-byte TX_NULL_DATA (standard)
+ t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3804678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38");
+ BOOST_CHECK(IsStandardTx(t, reason));
+
+ // 81-byte TX_NULL_DATA (non-standard)
+ t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3804678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3800");
+ BOOST_CHECK(!IsStandardTx(t, reason));
+
+ // TX_NULL_DATA w/o PUSHDATA
+ t.vout.resize(1);
+ t.vout[0].scriptPubKey = CScript() << OP_RETURN;
+ BOOST_CHECK(IsStandardTx(t, reason));
+
+ // Only one TX_NULL_DATA permitted in all cases
+ t.vout.resize(2);
+ t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38");
+ t.vout[1].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38");
+ BOOST_CHECK(!IsStandardTx(t, reason));
+
+ t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38");
+ t.vout[1].scriptPubKey = CScript() << OP_RETURN;
+ BOOST_CHECK(!IsStandardTx(t, reason));
+
+ t.vout[0].scriptPubKey = CScript() << OP_RETURN;
+ t.vout[1].scriptPubKey = CScript() << OP_RETURN;
+ BOOST_CHECK(!IsStandardTx(t, reason));
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/uint256_tests.cpp b/src/test/uint256_tests.cpp
new file mode 100644
index 0000000000..426d296a9a
--- /dev/null
+++ b/src/test/uint256_tests.cpp
@@ -0,0 +1,269 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#include "arith_uint256.h"
+#include "uint256.h"
+#include "version.h"
+#include "test/test_bitcoin.h"
+
+#include <boost/test/unit_test.hpp>
+#include <stdint.h>
+#include <sstream>
+#include <iomanip>
+#include <limits>
+#include <cmath>
+#include <string>
+#include <stdio.h>
+
+BOOST_FIXTURE_TEST_SUITE(uint256_tests, BasicTestingSetup)
+
+const unsigned char R1Array[] =
+ "\x9c\x52\x4a\xdb\xcf\x56\x11\x12\x2b\x29\x12\x5e\x5d\x35\xd2\xd2"
+ "\x22\x81\xaa\xb5\x33\xf0\x08\x32\xd5\x56\xb1\xf9\xea\xe5\x1d\x7d";
+const char R1ArrayHex[] = "7D1DE5EAF9B156D53208F033B5AA8122D2d2355d5e12292b121156cfdb4a529c";
+const uint256 R1L = uint256(std::vector<unsigned char>(R1Array,R1Array+32));
+const uint160 R1S = uint160(std::vector<unsigned char>(R1Array,R1Array+20));
+
+const unsigned char R2Array[] =
+ "\x70\x32\x1d\x7c\x47\xa5\x6b\x40\x26\x7e\x0a\xc3\xa6\x9c\xb6\xbf"
+ "\x13\x30\x47\xa3\x19\x2d\xda\x71\x49\x13\x72\xf0\xb4\xca\x81\xd7";
+const uint256 R2L = uint256(std::vector<unsigned char>(R2Array,R2Array+32));
+const uint160 R2S = uint160(std::vector<unsigned char>(R2Array,R2Array+20));
+
+const unsigned char ZeroArray[] =
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
+const uint256 ZeroL = uint256(std::vector<unsigned char>(ZeroArray,ZeroArray+32));
+const uint160 ZeroS = uint160(std::vector<unsigned char>(ZeroArray,ZeroArray+20));
+
+const unsigned char OneArray[] =
+ "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
+const uint256 OneL = uint256(std::vector<unsigned char>(OneArray,OneArray+32));
+const uint160 OneS = uint160(std::vector<unsigned char>(OneArray,OneArray+20));
+
+const unsigned char MaxArray[] =
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff";
+const uint256 MaxL = uint256(std::vector<unsigned char>(MaxArray,MaxArray+32));
+const uint160 MaxS = uint160(std::vector<unsigned char>(MaxArray,MaxArray+20));
+
+std::string ArrayToString(const unsigned char A[], unsigned int width)
+{
+ std::stringstream Stream;
+ Stream << std::hex;
+ for (unsigned int i = 0; i < width; ++i)
+ {
+ Stream<<std::setw(2)<<std::setfill('0')<<(unsigned int)A[width-i-1];
+ }
+ return Stream.str();
+}
+
+inline uint160 uint160S(const char *str)
+{
+ uint160 rv;
+ rv.SetHex(str);
+ return rv;
+}
+inline uint160 uint160S(const std::string& str)
+{
+ uint160 rv;
+ rv.SetHex(str);
+ return rv;
+}
+
+BOOST_AUTO_TEST_CASE( basics ) // constructors, equality, inequality
+{
+ BOOST_CHECK(1 == 0+1);
+ // constructor uint256(vector<char>):
+ BOOST_CHECK(R1L.ToString() == ArrayToString(R1Array,32));
+ BOOST_CHECK(R1S.ToString() == ArrayToString(R1Array,20));
+ BOOST_CHECK(R2L.ToString() == ArrayToString(R2Array,32));
+ BOOST_CHECK(R2S.ToString() == ArrayToString(R2Array,20));
+ BOOST_CHECK(ZeroL.ToString() == ArrayToString(ZeroArray,32));
+ BOOST_CHECK(ZeroS.ToString() == ArrayToString(ZeroArray,20));
+ BOOST_CHECK(OneL.ToString() == ArrayToString(OneArray,32));
+ BOOST_CHECK(OneS.ToString() == ArrayToString(OneArray,20));
+ BOOST_CHECK(MaxL.ToString() == ArrayToString(MaxArray,32));
+ BOOST_CHECK(MaxS.ToString() == ArrayToString(MaxArray,20));
+ BOOST_CHECK(OneL.ToString() != ArrayToString(ZeroArray,32));
+ BOOST_CHECK(OneS.ToString() != ArrayToString(ZeroArray,20));
+
+ // == and !=
+ BOOST_CHECK(R1L != R2L && R1S != R2S);
+ BOOST_CHECK(ZeroL != OneL && ZeroS != OneS);
+ BOOST_CHECK(OneL != ZeroL && OneS != ZeroS);
+ BOOST_CHECK(MaxL != ZeroL && MaxS != ZeroS);
+
+ // String Constructor and Copy Constructor
+ BOOST_CHECK(uint256S("0x"+R1L.ToString()) == R1L);
+ BOOST_CHECK(uint256S("0x"+R2L.ToString()) == R2L);
+ BOOST_CHECK(uint256S("0x"+ZeroL.ToString()) == ZeroL);
+ BOOST_CHECK(uint256S("0x"+OneL.ToString()) == OneL);
+ BOOST_CHECK(uint256S("0x"+MaxL.ToString()) == MaxL);
+ BOOST_CHECK(uint256S(R1L.ToString()) == R1L);
+ BOOST_CHECK(uint256S(" 0x"+R1L.ToString()+" ") == R1L);
+ BOOST_CHECK(uint256S("") == ZeroL);
+ BOOST_CHECK(R1L == uint256S(R1ArrayHex));
+ BOOST_CHECK(uint256(R1L) == R1L);
+ BOOST_CHECK(uint256(ZeroL) == ZeroL);
+ BOOST_CHECK(uint256(OneL) == OneL);
+
+ BOOST_CHECK(uint160S("0x"+R1S.ToString()) == R1S);
+ BOOST_CHECK(uint160S("0x"+R2S.ToString()) == R2S);
+ BOOST_CHECK(uint160S("0x"+ZeroS.ToString()) == ZeroS);
+ BOOST_CHECK(uint160S("0x"+OneS.ToString()) == OneS);
+ BOOST_CHECK(uint160S("0x"+MaxS.ToString()) == MaxS);
+ BOOST_CHECK(uint160S(R1S.ToString()) == R1S);
+ BOOST_CHECK(uint160S(" 0x"+R1S.ToString()+" ") == R1S);
+ BOOST_CHECK(uint160S("") == ZeroS);
+ BOOST_CHECK(R1S == uint160S(R1ArrayHex));
+
+ BOOST_CHECK(uint160(R1S) == R1S);
+ BOOST_CHECK(uint160(ZeroS) == ZeroS);
+ BOOST_CHECK(uint160(OneS) == OneS);
+}
+
+BOOST_AUTO_TEST_CASE( comparison ) // <= >= < >
+{
+ uint256 LastL;
+ for (int i = 255; i >= 0; --i) {
+ uint256 TmpL;
+ *(TmpL.begin() + (i>>3)) |= 1<<(7-(i&7));
+ BOOST_CHECK( LastL < TmpL );
+ LastL = TmpL;
+ }
+
+ BOOST_CHECK( ZeroL < R1L );
+ BOOST_CHECK( R2L < R1L );
+ BOOST_CHECK( ZeroL < OneL );
+ BOOST_CHECK( OneL < MaxL );
+ BOOST_CHECK( R1L < MaxL );
+ BOOST_CHECK( R2L < MaxL );
+
+ uint160 LastS;
+ for (int i = 159; i >= 0; --i) {
+ uint160 TmpS;
+ *(TmpS.begin() + (i>>3)) |= 1<<(7-(i&7));
+ BOOST_CHECK( LastS < TmpS );
+ LastS = TmpS;
+ }
+ BOOST_CHECK( ZeroS < R1S );
+ BOOST_CHECK( R2S < R1S );
+ BOOST_CHECK( ZeroS < OneS );
+ BOOST_CHECK( OneS < MaxS );
+ BOOST_CHECK( R1S < MaxS );
+ BOOST_CHECK( R2S < MaxS );
+}
+
+BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex begin() end() size() GetLow64 GetSerializeSize, Serialize, Unserialize
+{
+ BOOST_CHECK(R1L.GetHex() == R1L.ToString());
+ BOOST_CHECK(R2L.GetHex() == R2L.ToString());
+ BOOST_CHECK(OneL.GetHex() == OneL.ToString());
+ BOOST_CHECK(MaxL.GetHex() == MaxL.ToString());
+ uint256 TmpL(R1L);
+ BOOST_CHECK(TmpL == R1L);
+ TmpL.SetHex(R2L.ToString()); BOOST_CHECK(TmpL == R2L);
+ TmpL.SetHex(ZeroL.ToString()); BOOST_CHECK(TmpL == uint256());
+
+ TmpL.SetHex(R1L.ToString());
+ BOOST_CHECK(memcmp(R1L.begin(), R1Array, 32)==0);
+ BOOST_CHECK(memcmp(TmpL.begin(), R1Array, 32)==0);
+ BOOST_CHECK(memcmp(R2L.begin(), R2Array, 32)==0);
+ BOOST_CHECK(memcmp(ZeroL.begin(), ZeroArray, 32)==0);
+ BOOST_CHECK(memcmp(OneL.begin(), OneArray, 32)==0);
+ BOOST_CHECK(R1L.size() == sizeof(R1L));
+ BOOST_CHECK(sizeof(R1L) == 32);
+ BOOST_CHECK(R1L.size() == 32);
+ BOOST_CHECK(R2L.size() == 32);
+ BOOST_CHECK(ZeroL.size() == 32);
+ BOOST_CHECK(MaxL.size() == 32);
+ BOOST_CHECK(R1L.begin() + 32 == R1L.end());
+ BOOST_CHECK(R2L.begin() + 32 == R2L.end());
+ BOOST_CHECK(OneL.begin() + 32 == OneL.end());
+ BOOST_CHECK(MaxL.begin() + 32 == MaxL.end());
+ BOOST_CHECK(TmpL.begin() + 32 == TmpL.end());
+ BOOST_CHECK(R1L.GetSerializeSize(0,PROTOCOL_VERSION) == 32);
+ BOOST_CHECK(ZeroL.GetSerializeSize(0,PROTOCOL_VERSION) == 32);
+
+ std::stringstream ss;
+ R1L.Serialize(ss,0,PROTOCOL_VERSION);
+ BOOST_CHECK(ss.str() == std::string(R1Array,R1Array+32));
+ TmpL.Unserialize(ss,0,PROTOCOL_VERSION);
+ BOOST_CHECK(R1L == TmpL);
+ ss.str("");
+ ZeroL.Serialize(ss,0,PROTOCOL_VERSION);
+ BOOST_CHECK(ss.str() == std::string(ZeroArray,ZeroArray+32));
+ TmpL.Unserialize(ss,0,PROTOCOL_VERSION);
+ BOOST_CHECK(ZeroL == TmpL);
+ ss.str("");
+ MaxL.Serialize(ss,0,PROTOCOL_VERSION);
+ BOOST_CHECK(ss.str() == std::string(MaxArray,MaxArray+32));
+ TmpL.Unserialize(ss,0,PROTOCOL_VERSION);
+ BOOST_CHECK(MaxL == TmpL);
+ ss.str("");
+
+ BOOST_CHECK(R1S.GetHex() == R1S.ToString());
+ BOOST_CHECK(R2S.GetHex() == R2S.ToString());
+ BOOST_CHECK(OneS.GetHex() == OneS.ToString());
+ BOOST_CHECK(MaxS.GetHex() == MaxS.ToString());
+ uint160 TmpS(R1S);
+ BOOST_CHECK(TmpS == R1S);
+ TmpS.SetHex(R2S.ToString()); BOOST_CHECK(TmpS == R2S);
+ TmpS.SetHex(ZeroS.ToString()); BOOST_CHECK(TmpS == uint160());
+
+ TmpS.SetHex(R1S.ToString());
+ BOOST_CHECK(memcmp(R1S.begin(), R1Array, 20)==0);
+ BOOST_CHECK(memcmp(TmpS.begin(), R1Array, 20)==0);
+ BOOST_CHECK(memcmp(R2S.begin(), R2Array, 20)==0);
+ BOOST_CHECK(memcmp(ZeroS.begin(), ZeroArray, 20)==0);
+ BOOST_CHECK(memcmp(OneS.begin(), OneArray, 20)==0);
+ BOOST_CHECK(R1S.size() == sizeof(R1S));
+ BOOST_CHECK(sizeof(R1S) == 20);
+ BOOST_CHECK(R1S.size() == 20);
+ BOOST_CHECK(R2S.size() == 20);
+ BOOST_CHECK(ZeroS.size() == 20);
+ BOOST_CHECK(MaxS.size() == 20);
+ BOOST_CHECK(R1S.begin() + 20 == R1S.end());
+ BOOST_CHECK(R2S.begin() + 20 == R2S.end());
+ BOOST_CHECK(OneS.begin() + 20 == OneS.end());
+ BOOST_CHECK(MaxS.begin() + 20 == MaxS.end());
+ BOOST_CHECK(TmpS.begin() + 20 == TmpS.end());
+ BOOST_CHECK(R1S.GetSerializeSize(0,PROTOCOL_VERSION) == 20);
+ BOOST_CHECK(ZeroS.GetSerializeSize(0,PROTOCOL_VERSION) == 20);
+
+ R1S.Serialize(ss,0,PROTOCOL_VERSION);
+ BOOST_CHECK(ss.str() == std::string(R1Array,R1Array+20));
+ TmpS.Unserialize(ss,0,PROTOCOL_VERSION);
+ BOOST_CHECK(R1S == TmpS);
+ ss.str("");
+ ZeroS.Serialize(ss,0,PROTOCOL_VERSION);
+ BOOST_CHECK(ss.str() == std::string(ZeroArray,ZeroArray+20));
+ TmpS.Unserialize(ss,0,PROTOCOL_VERSION);
+ BOOST_CHECK(ZeroS == TmpS);
+ ss.str("");
+ MaxS.Serialize(ss,0,PROTOCOL_VERSION);
+ BOOST_CHECK(ss.str() == std::string(MaxArray,MaxArray+20));
+ TmpS.Unserialize(ss,0,PROTOCOL_VERSION);
+ BOOST_CHECK(MaxS == TmpS);
+ ss.str("");
+}
+
+BOOST_AUTO_TEST_CASE( conversion )
+{
+ BOOST_CHECK(ArithToUint256(UintToArith256(ZeroL)) == ZeroL);
+ BOOST_CHECK(ArithToUint256(UintToArith256(OneL)) == OneL);
+ BOOST_CHECK(ArithToUint256(UintToArith256(R1L)) == R1L);
+ BOOST_CHECK(ArithToUint256(UintToArith256(R2L)) == R2L);
+ BOOST_CHECK(UintToArith256(ZeroL) == 0);
+ BOOST_CHECK(UintToArith256(OneL) == 1);
+ BOOST_CHECK(ArithToUint256(0) == ZeroL);
+ BOOST_CHECK(ArithToUint256(1) == OneL);
+ BOOST_CHECK(arith_uint256(R1L.GetHex()) == UintToArith256(R1L));
+ BOOST_CHECK(arith_uint256(R2L.GetHex()) == UintToArith256(R2L));
+ BOOST_CHECK(R1L.GetHex() == UintToArith256(R1L).GetHex());
+ BOOST_CHECK(R2L.GetHex() == UintToArith256(R2L).GetHex());
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/univalue_tests.cpp b/src/test/univalue_tests.cpp
new file mode 100644
index 0000000000..8cecfbf651
--- /dev/null
+++ b/src/test/univalue_tests.cpp
@@ -0,0 +1,276 @@
+// Copyright 2014 BitPay, Inc.
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include <stdint.h>
+#include <vector>
+#include <string>
+#include <map>
+#include "univalue/univalue.h"
+#include "test/test_bitcoin.h"
+
+#include <boost/test/unit_test.hpp>
+
+using namespace std;
+
+BOOST_FIXTURE_TEST_SUITE(univalue_tests, BasicTestingSetup)
+
+BOOST_AUTO_TEST_CASE(univalue_constructor)
+{
+ UniValue v1;
+ BOOST_CHECK(v1.isNull());
+
+ UniValue v2(UniValue::VSTR);
+ BOOST_CHECK(v2.isStr());
+
+ UniValue v3(UniValue::VSTR, "foo");
+ BOOST_CHECK(v3.isStr());
+ BOOST_CHECK_EQUAL(v3.getValStr(), "foo");
+
+ UniValue numTest;
+ BOOST_CHECK(numTest.setNumStr("82"));
+ BOOST_CHECK(numTest.isNum());
+ BOOST_CHECK_EQUAL(numTest.getValStr(), "82");
+
+ uint64_t vu64 = 82;
+ UniValue v4(vu64);
+ BOOST_CHECK(v4.isNum());
+ BOOST_CHECK_EQUAL(v4.getValStr(), "82");
+
+ int64_t vi64 = -82;
+ UniValue v5(vi64);
+ BOOST_CHECK(v5.isNum());
+ BOOST_CHECK_EQUAL(v5.getValStr(), "-82");
+
+ int vi = -688;
+ UniValue v6(vi);
+ BOOST_CHECK(v6.isNum());
+ BOOST_CHECK_EQUAL(v6.getValStr(), "-688");
+
+ double vd = -7.21;
+ UniValue v7(vd);
+ BOOST_CHECK(v7.isNum());
+ BOOST_CHECK_EQUAL(v7.getValStr(), "-7.21");
+
+ string vs("yawn");
+ UniValue v8(vs);
+ BOOST_CHECK(v8.isStr());
+ BOOST_CHECK_EQUAL(v8.getValStr(), "yawn");
+
+ const char *vcs = "zappa";
+ UniValue v9(vcs);
+ BOOST_CHECK(v9.isStr());
+ BOOST_CHECK_EQUAL(v9.getValStr(), "zappa");
+}
+
+BOOST_AUTO_TEST_CASE(univalue_set)
+{
+ UniValue v(UniValue::VSTR, "foo");
+ v.clear();
+ BOOST_CHECK(v.isNull());
+ BOOST_CHECK_EQUAL(v.getValStr(), "");
+
+ BOOST_CHECK(v.setObject());
+ BOOST_CHECK(v.isObject());
+ BOOST_CHECK_EQUAL(v.count(), 0);
+ BOOST_CHECK_EQUAL(v.getType(), UniValue::VOBJ);
+ BOOST_CHECK(v.empty());
+
+ BOOST_CHECK(v.setArray());
+ BOOST_CHECK(v.isArray());
+ BOOST_CHECK_EQUAL(v.count(), 0);
+
+ BOOST_CHECK(v.setStr("zum"));
+ BOOST_CHECK(v.isStr());
+ BOOST_CHECK_EQUAL(v.getValStr(), "zum");
+
+ BOOST_CHECK(v.setFloat(-1.01));
+ BOOST_CHECK(v.isNum());
+ BOOST_CHECK_EQUAL(v.getValStr(), "-1.01");
+
+ BOOST_CHECK(v.setInt((int)1023));
+ BOOST_CHECK(v.isNum());
+ BOOST_CHECK_EQUAL(v.getValStr(), "1023");
+
+ BOOST_CHECK(v.setInt((int64_t)-1023LL));
+ BOOST_CHECK(v.isNum());
+ BOOST_CHECK_EQUAL(v.getValStr(), "-1023");
+
+ BOOST_CHECK(v.setInt((uint64_t)1023ULL));
+ BOOST_CHECK(v.isNum());
+ BOOST_CHECK_EQUAL(v.getValStr(), "1023");
+
+ BOOST_CHECK(v.setNumStr("-688"));
+ BOOST_CHECK(v.isNum());
+ BOOST_CHECK_EQUAL(v.getValStr(), "-688");
+
+ BOOST_CHECK(v.setBool(false));
+ BOOST_CHECK_EQUAL(v.isBool(), true);
+ BOOST_CHECK_EQUAL(v.isTrue(), false);
+ BOOST_CHECK_EQUAL(v.isFalse(), true);
+ BOOST_CHECK_EQUAL(v.getBool(), false);
+
+ BOOST_CHECK(v.setBool(true));
+ BOOST_CHECK_EQUAL(v.isBool(), true);
+ BOOST_CHECK_EQUAL(v.isTrue(), true);
+ BOOST_CHECK_EQUAL(v.isFalse(), false);
+ BOOST_CHECK_EQUAL(v.getBool(), true);
+
+ BOOST_CHECK(!v.setNumStr("zombocom"));
+
+ BOOST_CHECK(v.setNull());
+ BOOST_CHECK(v.isNull());
+}
+
+BOOST_AUTO_TEST_CASE(univalue_array)
+{
+ UniValue arr(UniValue::VARR);
+
+ UniValue v((int64_t)1023LL);
+ BOOST_CHECK(arr.push_back(v));
+
+ string vStr("zippy");
+ BOOST_CHECK(arr.push_back(vStr));
+
+ const char *s = "pippy";
+ BOOST_CHECK(arr.push_back(s));
+
+ vector<UniValue> vec;
+ v.setStr("boing");
+ vec.push_back(v);
+
+ v.setStr("going");
+ vec.push_back(v);
+
+ BOOST_CHECK(arr.push_backV(vec));
+
+ BOOST_CHECK_EQUAL(arr.empty(), false);
+ BOOST_CHECK_EQUAL(arr.count(), 5);
+
+ BOOST_CHECK_EQUAL(arr[0].getValStr(), "1023");
+ BOOST_CHECK_EQUAL(arr[1].getValStr(), "zippy");
+ BOOST_CHECK_EQUAL(arr[2].getValStr(), "pippy");
+ BOOST_CHECK_EQUAL(arr[3].getValStr(), "boing");
+ BOOST_CHECK_EQUAL(arr[4].getValStr(), "going");
+
+ BOOST_CHECK_EQUAL(arr[999].getValStr(), "");
+
+ arr.clear();
+ BOOST_CHECK(arr.empty());
+ BOOST_CHECK_EQUAL(arr.count(), 0);
+}
+
+BOOST_AUTO_TEST_CASE(univalue_object)
+{
+ UniValue obj(UniValue::VOBJ);
+ string strKey, strVal;
+ UniValue v;
+
+ strKey = "age";
+ v.setInt(100);
+ BOOST_CHECK(obj.pushKV(strKey, v));
+
+ strKey = "first";
+ strVal = "John";
+ BOOST_CHECK(obj.pushKV(strKey, strVal));
+
+ strKey = "last";
+ const char *cVal = "Smith";
+ BOOST_CHECK(obj.pushKV(strKey, cVal));
+
+ strKey = "distance";
+ BOOST_CHECK(obj.pushKV(strKey, (int64_t) 25));
+
+ strKey = "time";
+ BOOST_CHECK(obj.pushKV(strKey, (uint64_t) 3600));
+
+ strKey = "calories";
+ BOOST_CHECK(obj.pushKV(strKey, (int) 12));
+
+ strKey = "temperature";
+ BOOST_CHECK(obj.pushKV(strKey, (double) 90.012));
+
+ UniValue obj2(UniValue::VOBJ);
+ BOOST_CHECK(obj2.pushKV("cat1", 9000));
+ BOOST_CHECK(obj2.pushKV("cat2", 12345));
+
+ BOOST_CHECK(obj.pushKVs(obj2));
+
+ BOOST_CHECK_EQUAL(obj.empty(), false);
+ BOOST_CHECK_EQUAL(obj.count(), 9);
+
+ BOOST_CHECK_EQUAL(obj["age"].getValStr(), "100");
+ BOOST_CHECK_EQUAL(obj["first"].getValStr(), "John");
+ BOOST_CHECK_EQUAL(obj["last"].getValStr(), "Smith");
+ BOOST_CHECK_EQUAL(obj["distance"].getValStr(), "25");
+ BOOST_CHECK_EQUAL(obj["time"].getValStr(), "3600");
+ BOOST_CHECK_EQUAL(obj["calories"].getValStr(), "12");
+ BOOST_CHECK_EQUAL(obj["temperature"].getValStr(), "90.012");
+ BOOST_CHECK_EQUAL(obj["cat1"].getValStr(), "9000");
+ BOOST_CHECK_EQUAL(obj["cat2"].getValStr(), "12345");
+
+ BOOST_CHECK_EQUAL(obj["nyuknyuknyuk"].getValStr(), "");
+
+ BOOST_CHECK(obj.exists("age"));
+ BOOST_CHECK(obj.exists("first"));
+ BOOST_CHECK(obj.exists("last"));
+ BOOST_CHECK(obj.exists("distance"));
+ BOOST_CHECK(obj.exists("time"));
+ BOOST_CHECK(obj.exists("calories"));
+ BOOST_CHECK(obj.exists("temperature"));
+ BOOST_CHECK(obj.exists("cat1"));
+ BOOST_CHECK(obj.exists("cat2"));
+
+ BOOST_CHECK(!obj.exists("nyuknyuknyuk"));
+
+ map<string, UniValue::VType> objTypes;
+ objTypes["age"] = UniValue::VNUM;
+ objTypes["first"] = UniValue::VSTR;
+ objTypes["last"] = UniValue::VSTR;
+ objTypes["distance"] = UniValue::VNUM;
+ objTypes["time"] = UniValue::VNUM;
+ objTypes["calories"] = UniValue::VNUM;
+ objTypes["temperature"] = UniValue::VNUM;
+ objTypes["cat1"] = UniValue::VNUM;
+ objTypes["cat2"] = UniValue::VNUM;
+ BOOST_CHECK(obj.checkObject(objTypes));
+
+ objTypes["cat2"] = UniValue::VSTR;
+ BOOST_CHECK(!obj.checkObject(objTypes));
+
+ obj.clear();
+ BOOST_CHECK(obj.empty());
+ BOOST_CHECK_EQUAL(obj.count(), 0);
+}
+
+static const char *json1 =
+"[1.1,{\"key1\":\"str\",\"key2\":800,\"key3\":{\"name\":\"martian\"}}]";
+
+BOOST_AUTO_TEST_CASE(univalue_readwrite)
+{
+ UniValue v;
+ BOOST_CHECK(v.read(json1));
+
+ string strJson1(json1);
+ BOOST_CHECK(v.read(strJson1));
+
+ BOOST_CHECK(v.isArray());
+ BOOST_CHECK_EQUAL(v.count(), 2);
+
+ BOOST_CHECK_EQUAL(v[0].getValStr(), "1.1");
+
+ UniValue obj = v[1];
+ BOOST_CHECK(obj.isObject());
+ BOOST_CHECK_EQUAL(obj.count(), 3);
+
+ BOOST_CHECK(obj["key1"].isStr());
+ BOOST_CHECK_EQUAL(obj["key1"].getValStr(), "str");
+ BOOST_CHECK(obj["key2"].isNum());
+ BOOST_CHECK_EQUAL(obj["key2"].getValStr(), "800");
+ BOOST_CHECK(obj["key3"].isObject());
+
+ BOOST_CHECK_EQUAL(strJson1, v.write());
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp
new file mode 100644
index 0000000000..3309e2e387
--- /dev/null
+++ b/src/test/util_tests.cpp
@@ -0,0 +1,358 @@
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "util.h"
+
+#include "clientversion.h"
+#include "primitives/transaction.h"
+#include "random.h"
+#include "sync.h"
+#include "utilstrencodings.h"
+#include "utilmoneystr.h"
+#include "test/test_bitcoin.h"
+
+#include <stdint.h>
+#include <vector>
+
+#include <boost/test/unit_test.hpp>
+
+using namespace std;
+
+BOOST_FIXTURE_TEST_SUITE(util_tests, BasicTestingSetup)
+
+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);
+}
+
+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<unsigned char> result;
+ std::vector<unsigned char> 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<unsigned char> 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("%Y-%m-%d %H:%M:%S", 0), "1970-01-01 00:00:00");
+ BOOST_CHECK_EQUAL(DateTimeStrFormat("%Y-%m-%d %H:%M:%S", 0x7FFFFFFF), "2038-01-19 03:14:07");
+ BOOST_CHECK_EQUAL(DateTimeStrFormat("%Y-%m-%d %H:%M:%S", 1317425777), "2011-09-30 23:36:17");
+ BOOST_CHECK_EQUAL(DateTimeStrFormat("%Y-%m-%d %H:%M", 1317425777), "2011-09-30 23:36");
+ BOOST_CHECK_EQUAL(DateTimeStrFormat("%a, %d %b %Y %H:%M:%S +0000", 1317425777), "Fri, 30 Sep 2011 23:36:17 +0000");
+}
+
+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", false), true);
+ BOOST_CHECK_EQUAL(GetBoolArg("booltest2", false), false);
+ BOOST_CHECK_EQUAL(GetBoolArg("booltest3", false), false);
+ BOOST_CHECK_EQUAL(GetBoolArg("booltest4", false), true);
+}
+
+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)
+{
+ CAmount 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_CASE(util_seed_insecure_rand)
+{
+ int i;
+ int count=0;
+
+ seed_insecure_rand(true);
+
+ for (int mod=2;mod<11;mod++)
+ {
+ int mask = 1;
+ // Really rough binomal confidence approximation.
+ int err = 30*10000./mod*sqrt((1./mod*(1-1./mod))/10000.);
+ //mask is 2^ceil(log2(mod))-1
+ while(mask<mod-1)mask=(mask<<1)+1;
+
+ count = 0;
+ //How often does it get a zero from the uniform range [0,mod)?
+ for (i=0;i<10000;i++)
+ {
+ uint32_t rval;
+ do{
+ rval=insecure_rand()&mask;
+ }while(rval>=(uint32_t)mod);
+ count += rval==0;
+ }
+ BOOST_CHECK(count<=10000/mod+err);
+ BOOST_CHECK(count>=10000/mod-err);
+ }
+}
+
+BOOST_AUTO_TEST_CASE(util_TimingResistantEqual)
+{
+ BOOST_CHECK(TimingResistantEqual(std::string(""), std::string("")));
+ BOOST_CHECK(!TimingResistantEqual(std::string("abc"), std::string("")));
+ BOOST_CHECK(!TimingResistantEqual(std::string(""), std::string("abc")));
+ BOOST_CHECK(!TimingResistantEqual(std::string("a"), std::string("aa")));
+ BOOST_CHECK(!TimingResistantEqual(std::string("aa"), std::string("a")));
+ BOOST_CHECK(TimingResistantEqual(std::string("abc"), std::string("abc")));
+ BOOST_CHECK(!TimingResistantEqual(std::string("abc"), std::string("aba")));
+}
+
+/* Test strprintf formatting directives.
+ * Put a string before and after to ensure sanity of element sizes on stack. */
+#define B "check_prefix"
+#define E "check_postfix"
+BOOST_AUTO_TEST_CASE(strprintf_numbers)
+{
+ int64_t s64t = -9223372036854775807LL; /* signed 64 bit test value */
+ uint64_t u64t = 18446744073709551615ULL; /* unsigned 64 bit test value */
+ BOOST_CHECK(strprintf("%s %d %s", B, s64t, E) == B" -9223372036854775807 " E);
+ BOOST_CHECK(strprintf("%s %u %s", B, u64t, E) == B" 18446744073709551615 " E);
+ BOOST_CHECK(strprintf("%s %x %s", B, u64t, E) == B" ffffffffffffffff " E);
+
+ size_t st = 12345678; /* unsigned size_t test value */
+ ssize_t sst = -12345678; /* signed size_t test value */
+ BOOST_CHECK(strprintf("%s %d %s", B, sst, E) == B" -12345678 " E);
+ BOOST_CHECK(strprintf("%s %u %s", B, st, E) == B" 12345678 " E);
+ BOOST_CHECK(strprintf("%s %x %s", B, st, E) == B" bc614e " E);
+
+ ptrdiff_t pt = 87654321; /* positive ptrdiff_t test value */
+ ptrdiff_t spt = -87654321; /* negative ptrdiff_t test value */
+ BOOST_CHECK(strprintf("%s %d %s", B, spt, E) == B" -87654321 " E);
+ BOOST_CHECK(strprintf("%s %u %s", B, pt, E) == B" 87654321 " E);
+ BOOST_CHECK(strprintf("%s %x %s", B, pt, E) == B" 5397fb1 " E);
+}
+#undef B
+#undef E
+
+/* Check for mingw/wine issue #3494
+ * Remove this test before time.ctime(0xffffffff) == 'Sun Feb 7 07:28:15 2106'
+ */
+BOOST_AUTO_TEST_CASE(gettime)
+{
+ BOOST_CHECK((GetTime() & ~0xFFFFFFFFLL) == 0);
+}
+
+BOOST_AUTO_TEST_CASE(test_ParseInt32)
+{
+ int32_t n;
+ // Valid values
+ BOOST_CHECK(ParseInt32("1234", NULL));
+ BOOST_CHECK(ParseInt32("0", &n) && n == 0);
+ BOOST_CHECK(ParseInt32("1234", &n) && n == 1234);
+ BOOST_CHECK(ParseInt32("01234", &n) && n == 1234); // no octal
+ BOOST_CHECK(ParseInt32("2147483647", &n) && n == 2147483647);
+ BOOST_CHECK(ParseInt32("-2147483648", &n) && n == -2147483648);
+ BOOST_CHECK(ParseInt32("-1234", &n) && n == -1234);
+ // Invalid values
+ BOOST_CHECK(!ParseInt32("1a", &n));
+ BOOST_CHECK(!ParseInt32("aap", &n));
+ BOOST_CHECK(!ParseInt32("0x1", &n)); // no hex
+ // Overflow and underflow
+ BOOST_CHECK(!ParseInt32("-2147483649", NULL));
+ BOOST_CHECK(!ParseInt32("2147483648", NULL));
+ BOOST_CHECK(!ParseInt32("-32482348723847471234", NULL));
+ BOOST_CHECK(!ParseInt32("32482348723847471234", NULL));
+}
+
+BOOST_AUTO_TEST_CASE(test_FormatParagraph)
+{
+ BOOST_CHECK_EQUAL(FormatParagraph("", 79, 0), "");
+ BOOST_CHECK_EQUAL(FormatParagraph("test", 79, 0), "test");
+ BOOST_CHECK_EQUAL(FormatParagraph(" test", 79, 0), "test");
+ BOOST_CHECK_EQUAL(FormatParagraph("test test", 79, 0), "test test");
+ BOOST_CHECK_EQUAL(FormatParagraph("test test", 4, 0), "test\ntest");
+ BOOST_CHECK_EQUAL(FormatParagraph("testerde test ", 4, 0), "testerde\ntest");
+ BOOST_CHECK_EQUAL(FormatParagraph("test test", 4, 4), "test\n test");
+ BOOST_CHECK_EQUAL(FormatParagraph("This is a very long test string. This is a second sentence in the very long test string."), "This is a very long test string. This is a second sentence in the very long\ntest string.");
+}
+
+BOOST_AUTO_TEST_CASE(test_FormatSubVersion)
+{
+ std::vector<std::string> comments;
+ comments.push_back(std::string("comment1"));
+ std::vector<std::string> comments2;
+ comments2.push_back(std::string("comment1"));
+ comments2.push_back(std::string("comment2"));
+ BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, std::vector<std::string>()),std::string("/Test:0.9.99/"));
+ BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, comments),std::string("/Test:0.9.99(comment1)/"));
+ BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, comments2),std::string("/Test:0.9.99(comment1; comment2)/"));
+}
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/threadsafety.h b/src/threadsafety.h
new file mode 100644
index 0000000000..d01c50abb6
--- /dev/null
+++ b/src/threadsafety.h
@@ -0,0 +1,55 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2012 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_THREADSAFETY_H
+#define BITCOIN_THREADSAFETY_H
+
+#ifdef __clang__
+// TL;DR Add GUARDED_BY(mutex) to member variables. The others are
+// rarely necessary. Ex: int nFoo GUARDED_BY(cs_foo);
+//
+// See http://clang.llvm.org/docs/LanguageExtensions.html#threadsafety
+// for documentation. The clang compiler can do advanced static analysis
+// of locking when given the -Wthread-safety option.
+#define LOCKABLE __attribute__((lockable))
+#define SCOPED_LOCKABLE __attribute__((scoped_lockable))
+#define GUARDED_BY(x) __attribute__((guarded_by(x)))
+#define GUARDED_VAR __attribute__((guarded_var))
+#define PT_GUARDED_BY(x) __attribute__((pt_guarded_by(x)))
+#define PT_GUARDED_VAR __attribute__((pt_guarded_var))
+#define ACQUIRED_AFTER(...) __attribute__((acquired_after(__VA_ARGS__)))
+#define ACQUIRED_BEFORE(...) __attribute__((acquired_before(__VA_ARGS__)))
+#define EXCLUSIVE_LOCK_FUNCTION(...) __attribute__((exclusive_lock_function(__VA_ARGS__)))
+#define SHARED_LOCK_FUNCTION(...) __attribute__((shared_lock_function(__VA_ARGS__)))
+#define EXCLUSIVE_TRYLOCK_FUNCTION(...) __attribute__((exclusive_trylock_function(__VA_ARGS__)))
+#define SHARED_TRYLOCK_FUNCTION(...) __attribute__((shared_trylock_function(__VA_ARGS__)))
+#define UNLOCK_FUNCTION(...) __attribute__((unlock_function(__VA_ARGS__)))
+#define LOCK_RETURNED(x) __attribute__((lock_returned(x)))
+#define LOCKS_EXCLUDED(...) __attribute__((locks_excluded(__VA_ARGS__)))
+#define EXCLUSIVE_LOCKS_REQUIRED(...) __attribute__((exclusive_locks_required(__VA_ARGS__)))
+#define SHARED_LOCKS_REQUIRED(...) __attribute__((shared_locks_required(__VA_ARGS__)))
+#define NO_THREAD_SAFETY_ANALYSIS __attribute__((no_thread_safety_analysis))
+#else
+#define LOCKABLE
+#define SCOPED_LOCKABLE
+#define GUARDED_BY(x)
+#define GUARDED_VAR
+#define PT_GUARDED_BY(x)
+#define PT_GUARDED_VAR
+#define ACQUIRED_AFTER(...)
+#define ACQUIRED_BEFORE(...)
+#define EXCLUSIVE_LOCK_FUNCTION(...)
+#define SHARED_LOCK_FUNCTION(...)
+#define EXCLUSIVE_TRYLOCK_FUNCTION(...)
+#define SHARED_TRYLOCK_FUNCTION(...)
+#define UNLOCK_FUNCTION(...)
+#define LOCK_RETURNED(x)
+#define LOCKS_EXCLUDED(...)
+#define EXCLUSIVE_LOCKS_REQUIRED(...)
+#define SHARED_LOCKS_REQUIRED(...)
+#define NO_THREAD_SAFETY_ANALYSIS
+#endif // __GNUC__
+
+#endif // BITCOIN_THREADSAFETY_H
diff --git a/src/timedata.cpp b/src/timedata.cpp
new file mode 100644
index 0000000000..a14d69c116
--- /dev/null
+++ b/src/timedata.cpp
@@ -0,0 +1,116 @@
+// Copyright (c) 2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "timedata.h"
+
+#include "netbase.h"
+#include "sync.h"
+#include "ui_interface.h"
+#include "util.h"
+#include "utilstrencodings.h"
+
+#include <boost/foreach.hpp>
+
+using namespace std;
+
+static CCriticalSection cs_nTimeOffset;
+static int64_t nTimeOffset = 0;
+
+/**
+ * "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)
+ */
+int64_t GetTimeOffset()
+{
+ LOCK(cs_nTimeOffset);
+ return nTimeOffset;
+}
+
+int64_t GetAdjustedTime()
+{
+ return GetTime() + GetTimeOffset();
+}
+
+static int64_t abs64(int64_t n)
+{
+ return (n >= 0 ? n : -n);
+}
+
+#define BITCOIN_TIMEDATA_MAX_SAMPLES 200
+
+void AddTimeData(const CNetAddr& ip, int64_t nOffsetSample)
+{
+ LOCK(cs_nTimeOffset);
+ // Ignore duplicates
+ static set<CNetAddr> setKnown;
+ if (setKnown.size() == BITCOIN_TIMEDATA_MAX_SAMPLES)
+ return;
+ if (!setKnown.insert(ip).second)
+ return;
+
+ // Add data
+ static CMedianFilter<int64_t> vTimeOffsets(BITCOIN_TIMEDATA_MAX_SAMPLES, 0);
+ vTimeOffsets.input(nOffsetSample);
+ LogPrintf("Added time data, samples %d, offset %+d (%+d minutes)\n", vTimeOffsets.size(), nOffsetSample, nOffsetSample/60);
+
+ // There is a known issue here (see issue #4521):
+ //
+ // - The structure vTimeOffsets contains up to 200 elements, after which
+ // any new element added to it will not increase its size, replacing the
+ // oldest element.
+ //
+ // - The condition to update nTimeOffset includes checking whether the
+ // number of elements in vTimeOffsets is odd, which will never happen after
+ // there are 200 elements.
+ //
+ // But in this case the 'bug' is protective against some attacks, and may
+ // actually explain why we've never seen attacks which manipulate the
+ // clock offset.
+ //
+ // So we should hold off on fixing this and clean it up as part of
+ // a timing cleanup that strengthens it in a number of other ways.
+ //
+ if (vTimeOffsets.size() >= 5 && vTimeOffsets.size() % 2 == 1)
+ {
+ int64_t nMedian = vTimeOffsets.median();
+ std::vector<int64_t> vSorted = vTimeOffsets.sorted();
+ // Only let other nodes change our time by so much
+ if (abs64(nMedian) < 70 * 60)
+ {
+ 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_t 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 Bitcoin Core will not work properly.");
+ strMiscWarning = strMessage;
+ LogPrintf("*** %s\n", strMessage);
+ uiInterface.ThreadSafeMessageBox(strMessage, "", CClientUIInterface::MSG_WARNING);
+ }
+ }
+ }
+ if (fDebug) {
+ BOOST_FOREACH(int64_t n, vSorted)
+ LogPrintf("%+d ", n);
+ LogPrintf("| ");
+ }
+ LogPrintf("nTimeOffset = %+d (%+d minutes)\n", nTimeOffset, nTimeOffset/60);
+ }
+}
diff --git a/src/timedata.h b/src/timedata.h
new file mode 100644
index 0000000000..2296baf11b
--- /dev/null
+++ b/src/timedata.h
@@ -0,0 +1,76 @@
+// Copyright (c) 2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_TIMEDATA_H
+#define BITCOIN_TIMEDATA_H
+
+#include <algorithm>
+#include <assert.h>
+#include <stdint.h>
+#include <vector>
+
+class CNetAddr;
+
+/**
+ * Median filter over a stream of values.
+ * Returns the median of the last N numbers
+ */
+template <typename T>
+class CMedianFilter
+{
+private:
+ std::vector<T> vValues;
+ std::vector<T> 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<T> sorted() const
+ {
+ return vSorted;
+ }
+};
+
+/** Functions to keep track of adjusted P2P time */
+int64_t GetTimeOffset();
+int64_t GetAdjustedTime();
+void AddTimeData(const CNetAddr& ip, int64_t nTime);
+
+#endif // BITCOIN_TIMEDATA_H
diff --git a/src/tinyformat.h b/src/tinyformat.h
new file mode 100644
index 0000000000..73d49a1fe4
--- /dev/null
+++ b/src/tinyformat.h
@@ -0,0 +1,1013 @@
+// tinyformat.h
+// Copyright (C) 2011, Chris Foster [chris42f (at) gmail (d0t) com]
+//
+// Boost Software License - Version 1.0
+//
+// Permission is hereby granted, free of charge, to any person or organization
+// obtaining a copy of the software and accompanying documentation covered by
+// this license (the "Software") to use, reproduce, display, distribute,
+// execute, and transmit the Software, and to prepare derivative works of the
+// Software, and to permit third-parties to whom the Software is furnished to
+// do so, all subject to the following:
+//
+// The copyright notices in the Software and this entire statement, including
+// the above license grant, this restriction and the following disclaimer,
+// must be included in all copies of the Software, in whole or in part, and
+// all derivative works of the Software, unless such copies or derivative
+// works are solely in the form of machine-executable object code generated by
+// a source language processor.
+//
+// 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+//------------------------------------------------------------------------------
+// Tinyformat: A minimal type safe printf replacement
+//
+// tinyformat.h is a type safe printf replacement library in a single C++
+// header file. Design goals include:
+//
+// * Type safety and extensibility for user defined types.
+// * C99 printf() compatibility, to the extent possible using std::ostream
+// * Simplicity and minimalism. A single header file to include and distribute
+// with your projects.
+// * Augment rather than replace the standard stream formatting mechanism
+// * C++98 support, with optional C++11 niceties
+//
+//
+// Main interface example usage
+// ----------------------------
+//
+// To print a date to std::cout:
+//
+// std::string weekday = "Wednesday";
+// const char* month = "July";
+// size_t day = 27;
+// long hour = 14;
+// int min = 44;
+//
+// tfm::printf("%s, %s %d, %.2d:%.2d\n", weekday, month, day, hour, min);
+//
+// The strange types here emphasize the type safety of the interface; it is
+// possible to print a std::string using the "%s" conversion, and a
+// size_t using the "%d" conversion. A similar result could be achieved
+// using either of the tfm::format() functions. One prints on a user provided
+// stream:
+//
+// tfm::format(std::cerr, "%s, %s %d, %.2d:%.2d\n",
+// weekday, month, day, hour, min);
+//
+// The other returns a std::string:
+//
+// std::string date = tfm::format("%s, %s %d, %.2d:%.2d\n",
+// weekday, month, day, hour, min);
+// std::cout << date;
+//
+// These are the three primary interface functions.
+//
+//
+// User defined format functions
+// -----------------------------
+//
+// Simulating variadic templates in C++98 is pretty painful since it requires
+// writing out the same function for each desired number of arguments. To make
+// this bearable tinyformat comes with a set of macros which are used
+// internally to generate the API, but which may also be used in user code.
+//
+// The three macros TINYFORMAT_ARGTYPES(n), TINYFORMAT_VARARGS(n) and
+// TINYFORMAT_PASSARGS(n) will generate a list of n argument types,
+// type/name pairs and argument names respectively when called with an integer
+// n between 1 and 16. We can use these to define a macro which generates the
+// desired user defined function with n arguments. To generate all 16 user
+// defined function bodies, use the macro TINYFORMAT_FOREACH_ARGNUM. For an
+// example, see the implementation of printf() at the end of the source file.
+//
+//
+// Additional API information
+// --------------------------
+//
+// Error handling: Define TINYFORMAT_ERROR to customize the error handling for
+// format strings which are unsupported or have the wrong number of format
+// specifiers (calls assert() by default).
+//
+// User defined types: Uses operator<< for user defined types by default.
+// Overload formatValue() for more control.
+
+
+#ifndef TINYFORMAT_H_INCLUDED
+#define TINYFORMAT_H_INCLUDED
+
+namespace tinyformat {}
+//------------------------------------------------------------------------------
+// Config section. Customize to your liking!
+
+// Namespace alias to encourage brevity
+namespace tfm = tinyformat;
+
+// Error handling; calls assert() by default.
+#define TINYFORMAT_ERROR(reasonString) throw std::runtime_error(reasonString)
+
+// Define for C++11 variadic templates which make the code shorter & more
+// general. If you don't define this, C++11 support is autodetected below.
+// #define TINYFORMAT_USE_VARIADIC_TEMPLATES
+
+
+//------------------------------------------------------------------------------
+// Implementation details.
+#include <cassert>
+#include <iostream>
+#include <sstream>
+#include <stdexcept>
+
+#ifndef TINYFORMAT_ERROR
+# define TINYFORMAT_ERROR(reason) assert(0 && reason)
+#endif
+
+#if !defined(TINYFORMAT_USE_VARIADIC_TEMPLATES) && !defined(TINYFORMAT_NO_VARIADIC_TEMPLATES)
+# ifdef __GXX_EXPERIMENTAL_CXX0X__
+# define TINYFORMAT_USE_VARIADIC_TEMPLATES
+# endif
+#endif
+
+#ifdef __GNUC__
+# define TINYFORMAT_NOINLINE __attribute__((noinline))
+#elif defined(_MSC_VER)
+# define TINYFORMAT_NOINLINE __declspec(noinline)
+#else
+# define TINYFORMAT_NOINLINE
+#endif
+
+#if defined(__GLIBCXX__) && __GLIBCXX__ < 20080201
+// std::showpos is broken on old libstdc++ as provided with OSX. See
+// http://gcc.gnu.org/ml/libstdc++/2007-11/msg00075.html
+# define TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND
+#endif
+
+namespace tinyformat {
+
+//------------------------------------------------------------------------------
+namespace detail {
+
+// Test whether type T1 is convertible to type T2
+template <typename T1, typename T2>
+struct is_convertible
+{
+ private:
+ // two types of different size
+ struct fail { char dummy[2]; };
+ struct succeed { char dummy; };
+ // Try to convert a T1 to a T2 by plugging into tryConvert
+ static fail tryConvert(...);
+ static succeed tryConvert(const T2&);
+ static const T1& makeT1();
+ public:
+# ifdef _MSC_VER
+ // Disable spurious loss of precision warnings in tryConvert(makeT1())
+# pragma warning(push)
+# pragma warning(disable:4244)
+# pragma warning(disable:4267)
+# endif
+ // Standard trick: the (...) version of tryConvert will be chosen from
+ // the overload set only if the version taking a T2 doesn't match.
+ // Then we compare the sizes of the return types to check which
+ // function matched. Very neat, in a disgusting kind of way :)
+ static const bool value =
+ sizeof(tryConvert(makeT1())) == sizeof(succeed);
+# ifdef _MSC_VER
+# pragma warning(pop)
+# endif
+};
+
+
+// Detect when a type is not a wchar_t string
+template<typename T> struct is_wchar { typedef int tinyformat_wchar_is_not_supported; };
+template<> struct is_wchar<wchar_t*> {};
+template<> struct is_wchar<const wchar_t*> {};
+template<int n> struct is_wchar<const wchar_t[n]> {};
+template<int n> struct is_wchar<wchar_t[n]> {};
+
+
+// Format the value by casting to type fmtT. This default implementation
+// should never be called.
+template<typename T, typename fmtT, bool convertible = is_convertible<T, fmtT>::value>
+struct formatValueAsType
+{
+ static void invoke(std::ostream& /*out*/, const T& /*value*/) { assert(0); }
+};
+// Specialized version for types that can actually be converted to fmtT, as
+// indicated by the "convertible" template parameter.
+template<typename T, typename fmtT>
+struct formatValueAsType<T,fmtT,true>
+{
+ static void invoke(std::ostream& out, const T& value)
+ { out << static_cast<fmtT>(value); }
+};
+
+#ifdef TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND
+template<typename T, bool convertible = is_convertible<T, int>::value>
+struct formatZeroIntegerWorkaround
+{
+ static bool invoke(std::ostream& /**/, const T& /**/) { return false; }
+};
+template<typename T>
+struct formatZeroIntegerWorkaround<T,true>
+{
+ static bool invoke(std::ostream& out, const T& value)
+ {
+ if (static_cast<int>(value) == 0 && out.flags() & std::ios::showpos)
+ {
+ out << "+0";
+ return true;
+ }
+ return false;
+ }
+};
+#endif // TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND
+
+// Convert an arbitrary type to integer. The version with convertible=false
+// throws an error.
+template<typename T, bool convertible = is_convertible<T,int>::value>
+struct convertToInt
+{
+ static int invoke(const T& /*value*/)
+ {
+ TINYFORMAT_ERROR("tinyformat: Cannot convert from argument type to "
+ "integer for use as variable width or precision");
+ return 0;
+ }
+};
+// Specialization for convertToInt when conversion is possible
+template<typename T>
+struct convertToInt<T,true>
+{
+ static int invoke(const T& value) { return static_cast<int>(value); }
+};
+
+} // namespace detail
+
+
+//------------------------------------------------------------------------------
+// Variable formatting functions. May be overridden for user-defined types if
+// desired.
+
+
+// Format a value into a stream. Called from format() for all types by default.
+//
+// Users may override this for their own types. When this function is called,
+// the stream flags will have been modified according to the format string.
+// The format specification is provided in the range [fmtBegin, fmtEnd).
+//
+// By default, formatValue() uses the usual stream insertion operator
+// operator<< to format the type T, with special cases for the %c and %p
+// conversions.
+template<typename T>
+inline void formatValue(std::ostream& out, const char* /*fmtBegin*/,
+ const char* fmtEnd, const T& value)
+{
+#ifndef TINYFORMAT_ALLOW_WCHAR_STRINGS
+ // Since we don't support printing of wchar_t using "%ls", make it fail at
+ // compile time in preference to printing as a void* at runtime.
+ typedef typename detail::is_wchar<T>::tinyformat_wchar_is_not_supported DummyType;
+ (void) DummyType(); // avoid unused type warning with gcc-4.8
+#endif
+ // The mess here is to support the %c and %p conversions: if these
+ // conversions are active we try to convert the type to a char or const
+ // void* respectively and format that instead of the value itself. For the
+ // %p conversion it's important to avoid dereferencing the pointer, which
+ // could otherwise lead to a crash when printing a dangling (const char*).
+ const bool canConvertToChar = detail::is_convertible<T,char>::value;
+ const bool canConvertToVoidPtr = detail::is_convertible<T, const void*>::value;
+ if(canConvertToChar && *(fmtEnd-1) == 'c')
+ detail::formatValueAsType<T, char>::invoke(out, value);
+ else if(canConvertToVoidPtr && *(fmtEnd-1) == 'p')
+ detail::formatValueAsType<T, const void*>::invoke(out, value);
+#ifdef TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND
+ else if(detail::formatZeroIntegerWorkaround<T>::invoke(out, value)) /**/;
+#endif
+ else
+ out << value;
+}
+
+
+// Overloaded version for char types to support printing as an integer
+#define TINYFORMAT_DEFINE_FORMATVALUE_CHAR(charType) \
+inline void formatValue(std::ostream& out, const char* /*fmtBegin*/, \
+ const char* fmtEnd, charType value) \
+{ \
+ switch(*(fmtEnd-1)) \
+ { \
+ case 'u': case 'd': case 'i': case 'o': case 'X': case 'x': \
+ out << static_cast<int>(value); break; \
+ default: \
+ out << value; break; \
+ } \
+}
+// per 3.9.1: char, signed char and unsigned char are all distinct types
+TINYFORMAT_DEFINE_FORMATVALUE_CHAR(char)
+TINYFORMAT_DEFINE_FORMATVALUE_CHAR(signed char)
+TINYFORMAT_DEFINE_FORMATVALUE_CHAR(unsigned char)
+#undef TINYFORMAT_DEFINE_FORMATVALUE_CHAR
+
+
+//------------------------------------------------------------------------------
+// Tools for emulating variadic templates in C++98. The basic idea here is
+// stolen from the boost preprocessor metaprogramming library and cut down to
+// be just general enough for what we need.
+
+#define TINYFORMAT_ARGTYPES(n) TINYFORMAT_ARGTYPES_ ## n
+#define TINYFORMAT_VARARGS(n) TINYFORMAT_VARARGS_ ## n
+#define TINYFORMAT_PASSARGS(n) TINYFORMAT_PASSARGS_ ## n
+#define TINYFORMAT_PASSARGS_TAIL(n) TINYFORMAT_PASSARGS_TAIL_ ## n
+
+// To keep it as transparent as possible, the macros below have been generated
+// using python via the excellent cog.py code generation script. This avoids
+// the need for a bunch of complex (but more general) preprocessor tricks as
+// used in boost.preprocessor.
+//
+// To rerun the code generation in place, use `cog.py -r tinyformat.h`
+// (see http://nedbatchelder.com/code/cog). Alternatively you can just create
+// extra versions by hand.
+
+/*[[[cog
+maxParams = 16
+
+def makeCommaSepLists(lineTemplate, elemTemplate, startInd=1):
+ for j in range(startInd,maxParams+1):
+ list = ', '.join([elemTemplate % {'i':i} for i in range(startInd,j+1)])
+ cog.outl(lineTemplate % {'j':j, 'list':list})
+
+makeCommaSepLists('#define TINYFORMAT_ARGTYPES_%(j)d %(list)s',
+ 'class T%(i)d')
+
+cog.outl()
+makeCommaSepLists('#define TINYFORMAT_VARARGS_%(j)d %(list)s',
+ 'const T%(i)d& v%(i)d')
+
+cog.outl()
+makeCommaSepLists('#define TINYFORMAT_PASSARGS_%(j)d %(list)s', 'v%(i)d')
+
+cog.outl()
+cog.outl('#define TINYFORMAT_PASSARGS_TAIL_1')
+makeCommaSepLists('#define TINYFORMAT_PASSARGS_TAIL_%(j)d , %(list)s',
+ 'v%(i)d', startInd = 2)
+
+cog.outl()
+cog.outl('#define TINYFORMAT_FOREACH_ARGNUM(m) \\\n ' +
+ ' '.join(['m(%d)' % (j,) for j in range(1,maxParams+1)]))
+]]]*/
+#define TINYFORMAT_ARGTYPES_1 class T1
+#define TINYFORMAT_ARGTYPES_2 class T1, class T2
+#define TINYFORMAT_ARGTYPES_3 class T1, class T2, class T3
+#define TINYFORMAT_ARGTYPES_4 class T1, class T2, class T3, class T4
+#define TINYFORMAT_ARGTYPES_5 class T1, class T2, class T3, class T4, class T5
+#define TINYFORMAT_ARGTYPES_6 class T1, class T2, class T3, class T4, class T5, class T6
+#define TINYFORMAT_ARGTYPES_7 class T1, class T2, class T3, class T4, class T5, class T6, class T7
+#define TINYFORMAT_ARGTYPES_8 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8
+#define TINYFORMAT_ARGTYPES_9 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9
+#define TINYFORMAT_ARGTYPES_10 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10
+#define TINYFORMAT_ARGTYPES_11 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11
+#define TINYFORMAT_ARGTYPES_12 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12
+#define TINYFORMAT_ARGTYPES_13 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13
+#define TINYFORMAT_ARGTYPES_14 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14
+#define TINYFORMAT_ARGTYPES_15 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15
+#define TINYFORMAT_ARGTYPES_16 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15, class T16
+
+#define TINYFORMAT_VARARGS_1 const T1& v1
+#define TINYFORMAT_VARARGS_2 const T1& v1, const T2& v2
+#define TINYFORMAT_VARARGS_3 const T1& v1, const T2& v2, const T3& v3
+#define TINYFORMAT_VARARGS_4 const T1& v1, const T2& v2, const T3& v3, const T4& v4
+#define TINYFORMAT_VARARGS_5 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5
+#define TINYFORMAT_VARARGS_6 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6
+#define TINYFORMAT_VARARGS_7 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7
+#define TINYFORMAT_VARARGS_8 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7, const T8& v8
+#define TINYFORMAT_VARARGS_9 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7, const T8& v8, const T9& v9
+#define TINYFORMAT_VARARGS_10 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7, const T8& v8, const T9& v9, const T10& v10
+#define TINYFORMAT_VARARGS_11 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7, const T8& v8, const T9& v9, const T10& v10, const T11& v11
+#define TINYFORMAT_VARARGS_12 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7, const T8& v8, const T9& v9, const T10& v10, const T11& v11, const T12& v12
+#define TINYFORMAT_VARARGS_13 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7, const T8& v8, const T9& v9, const T10& v10, const T11& v11, const T12& v12, const T13& v13
+#define TINYFORMAT_VARARGS_14 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7, const T8& v8, const T9& v9, const T10& v10, const T11& v11, const T12& v12, const T13& v13, const T14& v14
+#define TINYFORMAT_VARARGS_15 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7, const T8& v8, const T9& v9, const T10& v10, const T11& v11, const T12& v12, const T13& v13, const T14& v14, const T15& v15
+#define TINYFORMAT_VARARGS_16 const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7, const T8& v8, const T9& v9, const T10& v10, const T11& v11, const T12& v12, const T13& v13, const T14& v14, const T15& v15, const T16& v16
+
+#define TINYFORMAT_PASSARGS_1 v1
+#define TINYFORMAT_PASSARGS_2 v1, v2
+#define TINYFORMAT_PASSARGS_3 v1, v2, v3
+#define TINYFORMAT_PASSARGS_4 v1, v2, v3, v4
+#define TINYFORMAT_PASSARGS_5 v1, v2, v3, v4, v5
+#define TINYFORMAT_PASSARGS_6 v1, v2, v3, v4, v5, v6
+#define TINYFORMAT_PASSARGS_7 v1, v2, v3, v4, v5, v6, v7
+#define TINYFORMAT_PASSARGS_8 v1, v2, v3, v4, v5, v6, v7, v8
+#define TINYFORMAT_PASSARGS_9 v1, v2, v3, v4, v5, v6, v7, v8, v9
+#define TINYFORMAT_PASSARGS_10 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10
+#define TINYFORMAT_PASSARGS_11 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11
+#define TINYFORMAT_PASSARGS_12 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12
+#define TINYFORMAT_PASSARGS_13 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13
+#define TINYFORMAT_PASSARGS_14 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14
+#define TINYFORMAT_PASSARGS_15 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15
+#define TINYFORMAT_PASSARGS_16 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16
+
+#define TINYFORMAT_PASSARGS_TAIL_1
+#define TINYFORMAT_PASSARGS_TAIL_2 , v2
+#define TINYFORMAT_PASSARGS_TAIL_3 , v2, v3
+#define TINYFORMAT_PASSARGS_TAIL_4 , v2, v3, v4
+#define TINYFORMAT_PASSARGS_TAIL_5 , v2, v3, v4, v5
+#define TINYFORMAT_PASSARGS_TAIL_6 , v2, v3, v4, v5, v6
+#define TINYFORMAT_PASSARGS_TAIL_7 , v2, v3, v4, v5, v6, v7
+#define TINYFORMAT_PASSARGS_TAIL_8 , v2, v3, v4, v5, v6, v7, v8
+#define TINYFORMAT_PASSARGS_TAIL_9 , v2, v3, v4, v5, v6, v7, v8, v9
+#define TINYFORMAT_PASSARGS_TAIL_10 , v2, v3, v4, v5, v6, v7, v8, v9, v10
+#define TINYFORMAT_PASSARGS_TAIL_11 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11
+#define TINYFORMAT_PASSARGS_TAIL_12 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12
+#define TINYFORMAT_PASSARGS_TAIL_13 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13
+#define TINYFORMAT_PASSARGS_TAIL_14 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14
+#define TINYFORMAT_PASSARGS_TAIL_15 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15
+#define TINYFORMAT_PASSARGS_TAIL_16 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16
+
+#define TINYFORMAT_FOREACH_ARGNUM(m) \
+ m(1) m(2) m(3) m(4) m(5) m(6) m(7) m(8) m(9) m(10) m(11) m(12) m(13) m(14) m(15) m(16)
+//[[[end]]]
+
+
+
+namespace detail {
+
+// Class holding current position in format string and an output stream into
+// which arguments are formatted.
+class FormatIterator
+{
+ public:
+ // Flags for features not representable with standard stream state
+ enum ExtraFormatFlags
+ {
+ Flag_None = 0,
+ Flag_TruncateToPrecision = 1<<0, // truncate length to stream precision()
+ Flag_SpacePadPositive = 1<<1, // pad positive values with spaces
+ Flag_VariableWidth = 1<<2, // variable field width in arg list
+ Flag_VariablePrecision = 1<<3 // variable field precision in arg list
+ };
+
+ // out is the output stream, fmt is the full format string
+ FormatIterator(std::ostream& out, const char* fmt)
+ : m_out(out),
+ m_fmt(fmt),
+ m_extraFlags(Flag_None),
+ m_wantWidth(false),
+ m_wantPrecision(false),
+ m_variableWidth(0),
+ m_variablePrecision(0),
+ m_origWidth(out.width()),
+ m_origPrecision(out.precision()),
+ m_origFlags(out.flags()),
+ m_origFill(out.fill())
+ { }
+
+ // Print remaining part of format string.
+ void finish()
+ {
+ // It would be nice if we could do this from the destructor, but we
+ // can't if TINFORMAT_ERROR is used to throw an exception!
+ m_fmt = printFormatStringLiteral(m_out, m_fmt);
+ if(*m_fmt != '\0')
+ TINYFORMAT_ERROR("tinyformat: Too many conversion specifiers in format string");
+ }
+
+ ~FormatIterator()
+ {
+ // Restore stream state
+ m_out.width(m_origWidth);
+ m_out.precision(m_origPrecision);
+ m_out.flags(m_origFlags);
+ m_out.fill(m_origFill);
+ }
+
+ template<typename T>
+ void accept(const T& value);
+
+ private:
+ // Parse and return an integer from the string c, as atoi()
+ // On return, c is set to one past the end of the integer.
+ static int parseIntAndAdvance(const char*& c)
+ {
+ int i = 0;
+ for(;*c >= '0' && *c <= '9'; ++c)
+ i = 10*i + (*c - '0');
+ return i;
+ }
+
+ // Format at most truncLen characters of a C string to the given
+ // stream. Return true if formatting proceeded (generic version always
+ // returns false)
+ template<typename T>
+ static bool formatCStringTruncate(std::ostream& /*out*/, const T& /*value*/,
+ std::streamsize /*truncLen*/)
+ {
+ return false;
+ }
+# define TINYFORMAT_DEFINE_FORMAT_C_STRING_TRUNCATE(type) \
+ static bool formatCStringTruncate(std::ostream& out, type* value, \
+ std::streamsize truncLen) \
+ { \
+ std::streamsize len = 0; \
+ while(len < truncLen && value[len] != 0) \
+ ++len; \
+ out.write(value, len); \
+ return true; \
+ }
+ // Overload for const char* and char*. Could overload for signed &
+ // unsigned char too, but these are technically unneeded for printf
+ // compatibility.
+ TINYFORMAT_DEFINE_FORMAT_C_STRING_TRUNCATE(const char)
+ TINYFORMAT_DEFINE_FORMAT_C_STRING_TRUNCATE(char)
+# undef TINYFORMAT_DEFINE_FORMAT_C_STRING_TRUNCATE
+
+ // Print literal part of format string and return next format spec
+ // position.
+ //
+ // Skips over any occurrences of '%%', printing a literal '%' to the
+ // output. The position of the first % character of the next
+ // nontrivial format spec is returned, or the end of string.
+ static const char* printFormatStringLiteral(std::ostream& out,
+ const char* fmt)
+ {
+ const char* c = fmt;
+ for(; true; ++c)
+ {
+ switch(*c)
+ {
+ case '\0':
+ out.write(fmt, static_cast<std::streamsize>(c - fmt));
+ return c;
+ case '%':
+ out.write(fmt, static_cast<std::streamsize>(c - fmt));
+ if(*(c+1) != '%')
+ return c;
+ // for "%%", tack trailing % onto next literal section.
+ fmt = ++c;
+ break;
+ }
+ }
+ }
+
+ static const char* streamStateFromFormat(std::ostream& out,
+ unsigned int& extraFlags,
+ const char* fmtStart,
+ int variableWidth,
+ int variablePrecision);
+
+ // Private copy & assign: Kill gcc warnings with -Weffc++
+ FormatIterator(const FormatIterator&);
+ FormatIterator& operator=(const FormatIterator&);
+
+ // Stream, current format string & state
+ std::ostream& m_out;
+ const char* m_fmt;
+ unsigned int m_extraFlags;
+ // State machine info for handling of variable width & precision
+ bool m_wantWidth;
+ bool m_wantPrecision;
+ int m_variableWidth;
+ int m_variablePrecision;
+ // Saved stream state
+ std::streamsize m_origWidth;
+ std::streamsize m_origPrecision;
+ std::ios::fmtflags m_origFlags;
+ char m_origFill;
+};
+
+
+// Accept a value for formatting into the internal stream.
+template<typename T>
+TINYFORMAT_NOINLINE // < greatly reduces bloat in optimized builds
+void FormatIterator::accept(const T& value)
+{
+ // Parse the format string
+ const char* fmtEnd = 0;
+ if(m_extraFlags == Flag_None && !m_wantWidth && !m_wantPrecision)
+ {
+ m_fmt = printFormatStringLiteral(m_out, m_fmt);
+ fmtEnd = streamStateFromFormat(m_out, m_extraFlags, m_fmt, 0, 0);
+ m_wantWidth = (m_extraFlags & Flag_VariableWidth) != 0;
+ m_wantPrecision = (m_extraFlags & Flag_VariablePrecision) != 0;
+ }
+ // Consume value as variable width and precision specifier if necessary
+ if(m_extraFlags & (Flag_VariableWidth | Flag_VariablePrecision))
+ {
+ if(m_wantWidth || m_wantPrecision)
+ {
+ int v = convertToInt<T>::invoke(value);
+ if(m_wantWidth)
+ {
+ m_variableWidth = v;
+ m_wantWidth = false;
+ }
+ else if(m_wantPrecision)
+ {
+ m_variablePrecision = v;
+ m_wantPrecision = false;
+ }
+ return;
+ }
+ // If we get here, we've set both the variable precision and width as
+ // required and we need to rerun the stream state setup to insert these.
+ fmtEnd = streamStateFromFormat(m_out, m_extraFlags, m_fmt,
+ m_variableWidth, m_variablePrecision);
+ }
+
+ // Format the value into the stream.
+ if(!(m_extraFlags & (Flag_SpacePadPositive | Flag_TruncateToPrecision)))
+ formatValue(m_out, m_fmt, fmtEnd, value);
+ else
+ {
+ // The following are special cases where there's no direct
+ // correspondence between stream formatting and the printf() behaviour.
+ // Instead, we simulate the behaviour crudely by formatting into a
+ // temporary string stream and munging the resulting string.
+ std::ostringstream tmpStream;
+ tmpStream.copyfmt(m_out);
+ if(m_extraFlags & Flag_SpacePadPositive)
+ tmpStream.setf(std::ios::showpos);
+ // formatCStringTruncate is required for truncating conversions like
+ // "%.4s" where at most 4 characters of the c-string should be read.
+ // If we didn't include this special case, we might read off the end.
+ if(!( (m_extraFlags & Flag_TruncateToPrecision) &&
+ formatCStringTruncate(tmpStream, value, m_out.precision()) ))
+ {
+ // Not a truncated c-string; just format normally.
+ formatValue(tmpStream, m_fmt, fmtEnd, value);
+ }
+ std::string result = tmpStream.str(); // allocates... yuck.
+ if(m_extraFlags & Flag_SpacePadPositive)
+ {
+ for(size_t i = 0, iend = result.size(); i < iend; ++i)
+ if(result[i] == '+')
+ result[i] = ' ';
+ }
+ if((m_extraFlags & Flag_TruncateToPrecision) &&
+ (int)result.size() > (int)m_out.precision())
+ m_out.write(result.c_str(), m_out.precision());
+ else
+ m_out << result;
+ }
+ m_extraFlags = Flag_None;
+ m_fmt = fmtEnd;
+}
+
+
+// Parse a format string and set the stream state accordingly.
+//
+// The format mini-language recognized here is meant to be the one from C99,
+// with the form "%[flags][width][.precision][length]type".
+//
+// Formatting options which can't be natively represented using the ostream
+// state are returned in the extraFlags parameter which is a bitwise
+// combination of values from the ExtraFormatFlags enum.
+inline const char* FormatIterator::streamStateFromFormat(std::ostream& out,
+ unsigned int& extraFlags,
+ const char* fmtStart,
+ int variableWidth,
+ int variablePrecision)
+{
+ if(*fmtStart != '%')
+ {
+ TINYFORMAT_ERROR("tinyformat: Not enough conversion specifiers in format string");
+ return fmtStart;
+ }
+ // Reset stream state to defaults.
+ out.width(0);
+ out.precision(6);
+ out.fill(' ');
+ // Reset most flags; ignore irrelevant unitbuf & skipws.
+ out.unsetf(std::ios::adjustfield | std::ios::basefield |
+ std::ios::floatfield | std::ios::showbase | std::ios::boolalpha |
+ std::ios::showpoint | std::ios::showpos | std::ios::uppercase);
+ extraFlags = Flag_None;
+ bool precisionSet = false;
+ bool widthSet = false;
+ const char* c = fmtStart + 1;
+ // 1) Parse flags
+ for(;; ++c)
+ {
+ switch(*c)
+ {
+ case '#':
+ out.setf(std::ios::showpoint | std::ios::showbase);
+ continue;
+ case '0':
+ // overridden by left alignment ('-' flag)
+ if(!(out.flags() & std::ios::left))
+ {
+ // Use internal padding so that numeric values are
+ // formatted correctly, eg -00010 rather than 000-10
+ out.fill('0');
+ out.setf(std::ios::internal, std::ios::adjustfield);
+ }
+ continue;
+ case '-':
+ out.fill(' ');
+ out.setf(std::ios::left, std::ios::adjustfield);
+ continue;
+ case ' ':
+ // overridden by show positive sign, '+' flag.
+ if(!(out.flags() & std::ios::showpos))
+ extraFlags |= Flag_SpacePadPositive;
+ continue;
+ case '+':
+ out.setf(std::ios::showpos);
+ extraFlags &= ~Flag_SpacePadPositive;
+ continue;
+ }
+ break;
+ }
+ // 2) Parse width
+ if(*c >= '0' && *c <= '9')
+ {
+ widthSet = true;
+ out.width(parseIntAndAdvance(c));
+ }
+ if(*c == '*')
+ {
+ widthSet = true;
+ if(variableWidth < 0)
+ {
+ // negative widths correspond to '-' flag set
+ out.fill(' ');
+ out.setf(std::ios::left, std::ios::adjustfield);
+ variableWidth = -variableWidth;
+ }
+ out.width(variableWidth);
+ extraFlags |= Flag_VariableWidth;
+ ++c;
+ }
+ // 3) Parse precision
+ if(*c == '.')
+ {
+ ++c;
+ int precision = 0;
+ if(*c == '*')
+ {
+ ++c;
+ extraFlags |= Flag_VariablePrecision;
+ precision = variablePrecision;
+ }
+ else
+ {
+ if(*c >= '0' && *c <= '9')
+ precision = parseIntAndAdvance(c);
+ else if(*c == '-') // negative precisions ignored, treated as zero.
+ parseIntAndAdvance(++c);
+ }
+ out.precision(precision);
+ precisionSet = true;
+ }
+ // 4) Ignore any C99 length modifier
+ while(*c == 'l' || *c == 'h' || *c == 'L' ||
+ *c == 'j' || *c == 'z' || *c == 't')
+ ++c;
+ // 5) We're up to the conversion specifier character.
+ // Set stream flags based on conversion specifier (thanks to the
+ // boost::format class for forging the way here).
+ bool intConversion = false;
+ switch(*c)
+ {
+ case 'u': case 'd': case 'i':
+ out.setf(std::ios::dec, std::ios::basefield);
+ intConversion = true;
+ break;
+ case 'o':
+ out.setf(std::ios::oct, std::ios::basefield);
+ intConversion = true;
+ break;
+ case 'X':
+ out.setf(std::ios::uppercase);
+ case 'x': case 'p':
+ out.setf(std::ios::hex, std::ios::basefield);
+ intConversion = true;
+ break;
+ case 'E':
+ out.setf(std::ios::uppercase);
+ case 'e':
+ out.setf(std::ios::scientific, std::ios::floatfield);
+ out.setf(std::ios::dec, std::ios::basefield);
+ break;
+ case 'F':
+ out.setf(std::ios::uppercase);
+ case 'f':
+ out.setf(std::ios::fixed, std::ios::floatfield);
+ break;
+ case 'G':
+ out.setf(std::ios::uppercase);
+ case 'g':
+ out.setf(std::ios::dec, std::ios::basefield);
+ // As in boost::format, let stream decide float format.
+ out.flags(out.flags() & ~std::ios::floatfield);
+ break;
+ case 'a': case 'A':
+ TINYFORMAT_ERROR("tinyformat: the %a and %A conversion specs "
+ "are not supported");
+ break;
+ case 'c':
+ // Handled as special case inside formatValue()
+ break;
+ case 's':
+ if(precisionSet)
+ extraFlags |= Flag_TruncateToPrecision;
+ // Make %s print booleans as "true" and "false"
+ out.setf(std::ios::boolalpha);
+ break;
+ case 'n':
+ // Not supported - will cause problems!
+ TINYFORMAT_ERROR("tinyformat: %n conversion spec not supported");
+ break;
+ case '\0':
+ TINYFORMAT_ERROR("tinyformat: Conversion spec incorrectly "
+ "terminated by end of string");
+ return c;
+ }
+ if(intConversion && precisionSet && !widthSet)
+ {
+ // "precision" for integers gives the minimum number of digits (to be
+ // padded with zeros on the left). This isn't really supported by the
+ // iostreams, but we can approximately simulate it with the width if
+ // the width isn't otherwise used.
+ out.width(out.precision());
+ out.setf(std::ios::internal, std::ios::adjustfield);
+ out.fill('0');
+ }
+ return c+1;
+}
+
+
+
+//------------------------------------------------------------------------------
+// Private format function on top of which the public interface is implemented.
+// We enforce a mimimum of one value to be formatted to prevent bugs looking like
+//
+// const char* myStr = "100% broken";
+// printf(myStr); // Parses % as a format specifier
+#ifdef TINYFORMAT_USE_VARIADIC_TEMPLATES
+
+template<typename T1>
+void format(FormatIterator& fmtIter, const T1& value1)
+{
+ fmtIter.accept(value1);
+ fmtIter.finish();
+}
+
+// General version for C++11
+template<typename T1, typename... Args>
+void format(FormatIterator& fmtIter, const T1& value1, const Args&... args)
+{
+ fmtIter.accept(value1);
+ format(fmtIter, args...);
+}
+
+#else
+
+inline void format(FormatIterator& fmtIter)
+{
+ fmtIter.finish();
+}
+
+// General version for C++98
+#define TINYFORMAT_MAKE_FORMAT_DETAIL(n) \
+template<TINYFORMAT_ARGTYPES(n)> \
+void format(detail::FormatIterator& fmtIter, TINYFORMAT_VARARGS(n)) \
+{ \
+ fmtIter.accept(v1); \
+ format(fmtIter TINYFORMAT_PASSARGS_TAIL(n)); \
+}
+
+TINYFORMAT_FOREACH_ARGNUM(TINYFORMAT_MAKE_FORMAT_DETAIL)
+#undef TINYFORMAT_MAKE_FORMAT_DETAIL
+
+#endif // End C++98 variadic template emulation for format()
+
+} // namespace detail
+
+
+//------------------------------------------------------------------------------
+// Implement all the main interface functions here in terms of detail::format()
+
+#ifdef TINYFORMAT_USE_VARIADIC_TEMPLATES
+
+// C++11 - the simple case
+template<typename T1, typename... Args>
+void format(std::ostream& out, const char* fmt, const T1& v1, const Args&... args)
+{
+ detail::FormatIterator fmtIter(out, fmt);
+ format(fmtIter, v1, args...);
+}
+
+template<typename T1, typename... Args>
+std::string format(const char* fmt, const T1& v1, const Args&... args)
+{
+ std::ostringstream oss;
+ format(oss, fmt, v1, args...);
+ return oss.str();
+}
+
+template<typename T1, typename... Args>
+std::string format(const std::string &fmt, const T1& v1, const Args&... args)
+{
+ std::ostringstream oss;
+ format(oss, fmt.c_str(), v1, args...);
+ return oss.str();
+}
+
+template<typename T1, typename... Args>
+void printf(const char* fmt, const T1& v1, const Args&... args)
+{
+ format(std::cout, fmt, v1, args...);
+}
+
+#else
+
+// C++98 - define the interface functions using the wrapping macros
+#define TINYFORMAT_MAKE_FORMAT_FUNCS(n) \
+ \
+template<TINYFORMAT_ARGTYPES(n)> \
+void format(std::ostream& out, const char* fmt, TINYFORMAT_VARARGS(n)) \
+{ \
+ tinyformat::detail::FormatIterator fmtIter(out, fmt); \
+ tinyformat::detail::format(fmtIter, TINYFORMAT_PASSARGS(n)); \
+} \
+ \
+template<TINYFORMAT_ARGTYPES(n)> \
+std::string format(const char* fmt, TINYFORMAT_VARARGS(n)) \
+{ \
+ std::ostringstream oss; \
+ tinyformat::format(oss, fmt, TINYFORMAT_PASSARGS(n)); \
+ return oss.str(); \
+} \
+ \
+template<TINYFORMAT_ARGTYPES(n)> \
+std::string format(const std::string &fmt, TINYFORMAT_VARARGS(n)) \
+{ \
+ std::ostringstream oss; \
+ tinyformat::format(oss, fmt.c_str(), TINYFORMAT_PASSARGS(n)); \
+ return oss.str(); \
+} \
+ \
+template<TINYFORMAT_ARGTYPES(n)> \
+void printf(const char* fmt, TINYFORMAT_VARARGS(n)) \
+{ \
+ tinyformat::format(std::cout, fmt, TINYFORMAT_PASSARGS(n)); \
+}
+
+TINYFORMAT_FOREACH_ARGNUM(TINYFORMAT_MAKE_FORMAT_FUNCS)
+#undef TINYFORMAT_MAKE_FORMAT_FUNCS
+#endif
+
+
+//------------------------------------------------------------------------------
+// Define deprecated wrapping macro for backward compatibility in tinyformat
+// 1.x. Will be removed in version 2!
+#define TINYFORMAT_WRAP_FORMAT_EXTRA_ARGS
+#define TINYFORMAT_WRAP_FORMAT_N(n, returnType, funcName, funcDeclSuffix, \
+ bodyPrefix, streamName, bodySuffix) \
+template<TINYFORMAT_ARGTYPES(n)> \
+returnType funcName(TINYFORMAT_WRAP_FORMAT_EXTRA_ARGS const char* fmt, \
+ TINYFORMAT_VARARGS(n)) funcDeclSuffix \
+{ \
+ bodyPrefix \
+ tinyformat::format(streamName, fmt, TINYFORMAT_PASSARGS(n)); \
+ bodySuffix \
+} \
+
+#define TINYFORMAT_WRAP_FORMAT(returnType, funcName, funcDeclSuffix, \
+ bodyPrefix, streamName, bodySuffix) \
+inline \
+returnType funcName(TINYFORMAT_WRAP_FORMAT_EXTRA_ARGS const char* fmt \
+ ) funcDeclSuffix \
+{ \
+ bodyPrefix \
+ tinyformat::detail::FormatIterator(streamName, fmt).finish(); \
+ bodySuffix \
+} \
+TINYFORMAT_WRAP_FORMAT_N(1 , returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \
+TINYFORMAT_WRAP_FORMAT_N(2 , returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \
+TINYFORMAT_WRAP_FORMAT_N(3 , returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \
+TINYFORMAT_WRAP_FORMAT_N(4 , returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \
+TINYFORMAT_WRAP_FORMAT_N(5 , returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \
+TINYFORMAT_WRAP_FORMAT_N(6 , returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \
+TINYFORMAT_WRAP_FORMAT_N(7 , returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \
+TINYFORMAT_WRAP_FORMAT_N(8 , returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \
+TINYFORMAT_WRAP_FORMAT_N(9 , returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \
+TINYFORMAT_WRAP_FORMAT_N(10, returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \
+TINYFORMAT_WRAP_FORMAT_N(11, returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \
+TINYFORMAT_WRAP_FORMAT_N(12, returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \
+TINYFORMAT_WRAP_FORMAT_N(13, returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \
+TINYFORMAT_WRAP_FORMAT_N(14, returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \
+TINYFORMAT_WRAP_FORMAT_N(15, returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \
+TINYFORMAT_WRAP_FORMAT_N(16, returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \
+
+
+} // namespace tinyformat
+
+#define strprintf tfm::format
+
+#endif // TINYFORMAT_H_INCLUDED
diff --git a/src/txdb.cpp b/src/txdb.cpp
new file mode 100644
index 0000000000..df9ff8d8c9
--- /dev/null
+++ b/src/txdb.cpp
@@ -0,0 +1,241 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "txdb.h"
+
+#include "chainparams.h"
+#include "hash.h"
+#include "main.h"
+#include "pow.h"
+#include "uint256.h"
+
+#include <stdint.h>
+
+#include <boost/thread.hpp>
+
+using namespace std;
+
+static const char DB_COINS = 'c';
+static const char DB_BLOCK_FILES = 'f';
+static const char DB_TXINDEX = 't';
+static const char DB_BLOCK_INDEX = 'b';
+
+static const char DB_BEST_BLOCK = 'B';
+static const char DB_FLAG = 'F';
+static const char DB_REINDEX_FLAG = 'R';
+static const char DB_LAST_BLOCK = 'l';
+
+
+void static BatchWriteCoins(CLevelDBBatch &batch, const uint256 &hash, const CCoins &coins) {
+ if (coins.IsPruned())
+ batch.Erase(make_pair(DB_COINS, hash));
+ else
+ batch.Write(make_pair(DB_COINS, hash), coins);
+}
+
+void static BatchWriteHashBestChain(CLevelDBBatch &batch, const uint256 &hash) {
+ batch.Write(DB_BEST_BLOCK, hash);
+}
+
+CCoinsViewDB::CCoinsViewDB(size_t nCacheSize, bool fMemory, bool fWipe) : db(GetDataDir() / "chainstate", nCacheSize, fMemory, fWipe) {
+}
+
+bool CCoinsViewDB::GetCoins(const uint256 &txid, CCoins &coins) const {
+ return db.Read(make_pair(DB_COINS, txid), coins);
+}
+
+bool CCoinsViewDB::HaveCoins(const uint256 &txid) const {
+ return db.Exists(make_pair(DB_COINS, txid));
+}
+
+uint256 CCoinsViewDB::GetBestBlock() const {
+ uint256 hashBestChain;
+ if (!db.Read(DB_BEST_BLOCK, hashBestChain))
+ return uint256();
+ return hashBestChain;
+}
+
+bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) {
+ CLevelDBBatch batch;
+ size_t count = 0;
+ size_t changed = 0;
+ for (CCoinsMap::iterator it = mapCoins.begin(); it != mapCoins.end();) {
+ if (it->second.flags & CCoinsCacheEntry::DIRTY) {
+ BatchWriteCoins(batch, it->first, it->second.coins);
+ changed++;
+ }
+ count++;
+ CCoinsMap::iterator itOld = it++;
+ mapCoins.erase(itOld);
+ }
+ if (!hashBlock.IsNull())
+ BatchWriteHashBestChain(batch, hashBlock);
+
+ LogPrint("coindb", "Committing %u changed transactions (out of %u) to coin database...\n", (unsigned int)changed, (unsigned int)count);
+ return db.WriteBatch(batch);
+}
+
+CBlockTreeDB::CBlockTreeDB(size_t nCacheSize, bool fMemory, bool fWipe) : CLevelDBWrapper(GetDataDir() / "blocks" / "index", nCacheSize, fMemory, fWipe) {
+}
+
+bool CBlockTreeDB::ReadBlockFileInfo(int nFile, CBlockFileInfo &info) {
+ return Read(make_pair(DB_BLOCK_FILES, nFile), info);
+}
+
+bool CBlockTreeDB::WriteReindexing(bool fReindexing) {
+ if (fReindexing)
+ return Write(DB_REINDEX_FLAG, '1');
+ else
+ return Erase(DB_REINDEX_FLAG);
+}
+
+bool CBlockTreeDB::ReadReindexing(bool &fReindexing) {
+ fReindexing = Exists(DB_REINDEX_FLAG);
+ return true;
+}
+
+bool CBlockTreeDB::ReadLastBlockFile(int &nFile) {
+ return Read(DB_LAST_BLOCK, nFile);
+}
+
+bool CCoinsViewDB::GetStats(CCoinsStats &stats) const {
+ /* It seems that there are no "const iterators" for LevelDB. Since we
+ only need read operations on it, use a const-cast to get around
+ that restriction. */
+ boost::scoped_ptr<leveldb::Iterator> pcursor(const_cast<CLevelDBWrapper*>(&db)->NewIterator());
+ pcursor->SeekToFirst();
+
+ CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
+ stats.hashBlock = GetBestBlock();
+ ss << stats.hashBlock;
+ CAmount nTotalAmount = 0;
+ while (pcursor->Valid()) {
+ boost::this_thread::interruption_point();
+ try {
+ leveldb::Slice slKey = pcursor->key();
+ CDataStream ssKey(slKey.data(), slKey.data()+slKey.size(), SER_DISK, CLIENT_VERSION);
+ char chType;
+ ssKey >> chType;
+ if (chType == DB_COINS) {
+ leveldb::Slice slValue = pcursor->value();
+ CDataStream ssValue(slValue.data(), slValue.data()+slValue.size(), SER_DISK, CLIENT_VERSION);
+ CCoins coins;
+ ssValue >> coins;
+ uint256 txhash;
+ ssKey >> txhash;
+ ss << txhash;
+ ss << VARINT(coins.nVersion);
+ ss << (coins.fCoinBase ? 'c' : 'n');
+ ss << VARINT(coins.nHeight);
+ stats.nTransactions++;
+ for (unsigned int i=0; i<coins.vout.size(); i++) {
+ const CTxOut &out = coins.vout[i];
+ if (!out.IsNull()) {
+ stats.nTransactionOutputs++;
+ ss << VARINT(i+1);
+ ss << out;
+ nTotalAmount += out.nValue;
+ }
+ }
+ stats.nSerializedSize += 32 + slValue.size();
+ ss << VARINT(0);
+ }
+ pcursor->Next();
+ } catch (const std::exception& e) {
+ return error("%s: Deserialize or I/O error - %s", __func__, e.what());
+ }
+ }
+ stats.nHeight = mapBlockIndex.find(GetBestBlock())->second->nHeight;
+ stats.hashSerialized = ss.GetHash();
+ stats.nTotalAmount = nTotalAmount;
+ return true;
+}
+
+bool CBlockTreeDB::WriteBatchSync(const std::vector<std::pair<int, const CBlockFileInfo*> >& fileInfo, int nLastFile, const std::vector<const CBlockIndex*>& blockinfo) {
+ CLevelDBBatch batch;
+ for (std::vector<std::pair<int, const CBlockFileInfo*> >::const_iterator it=fileInfo.begin(); it != fileInfo.end(); it++) {
+ batch.Write(make_pair(DB_BLOCK_FILES, it->first), *it->second);
+ }
+ batch.Write(DB_LAST_BLOCK, nLastFile);
+ for (std::vector<const CBlockIndex*>::const_iterator it=blockinfo.begin(); it != blockinfo.end(); it++) {
+ batch.Write(make_pair(DB_BLOCK_INDEX, (*it)->GetBlockHash()), CDiskBlockIndex(*it));
+ }
+ return WriteBatch(batch, true);
+}
+
+bool CBlockTreeDB::ReadTxIndex(const uint256 &txid, CDiskTxPos &pos) {
+ return Read(make_pair(DB_TXINDEX, txid), pos);
+}
+
+bool CBlockTreeDB::WriteTxIndex(const std::vector<std::pair<uint256, CDiskTxPos> >&vect) {
+ CLevelDBBatch batch;
+ for (std::vector<std::pair<uint256,CDiskTxPos> >::const_iterator it=vect.begin(); it!=vect.end(); it++)
+ batch.Write(make_pair(DB_TXINDEX, it->first), it->second);
+ return WriteBatch(batch);
+}
+
+bool CBlockTreeDB::WriteFlag(const std::string &name, bool fValue) {
+ return Write(std::make_pair(DB_FLAG, name), fValue ? '1' : '0');
+}
+
+bool CBlockTreeDB::ReadFlag(const std::string &name, bool &fValue) {
+ char ch;
+ if (!Read(std::make_pair(DB_FLAG, name), ch))
+ return false;
+ fValue = ch == '1';
+ return true;
+}
+
+bool CBlockTreeDB::LoadBlockIndexGuts()
+{
+ boost::scoped_ptr<leveldb::Iterator> pcursor(NewIterator());
+
+ CDataStream ssKeySet(SER_DISK, CLIENT_VERSION);
+ ssKeySet << make_pair(DB_BLOCK_INDEX, uint256());
+ pcursor->Seek(ssKeySet.str());
+
+ // Load mapBlockIndex
+ while (pcursor->Valid()) {
+ boost::this_thread::interruption_point();
+ try {
+ leveldb::Slice slKey = pcursor->key();
+ CDataStream ssKey(slKey.data(), slKey.data()+slKey.size(), SER_DISK, CLIENT_VERSION);
+ char chType;
+ ssKey >> chType;
+ if (chType == DB_BLOCK_INDEX) {
+ leveldb::Slice slValue = pcursor->value();
+ CDataStream ssValue(slValue.data(), slValue.data()+slValue.size(), SER_DISK, CLIENT_VERSION);
+ CDiskBlockIndex diskindex;
+ ssValue >> diskindex;
+
+ // Construct block index object
+ CBlockIndex* pindexNew = InsertBlockIndex(diskindex.GetBlockHash());
+ pindexNew->pprev = InsertBlockIndex(diskindex.hashPrev);
+ pindexNew->nHeight = diskindex.nHeight;
+ pindexNew->nFile = diskindex.nFile;
+ pindexNew->nDataPos = diskindex.nDataPos;
+ pindexNew->nUndoPos = diskindex.nUndoPos;
+ pindexNew->nVersion = diskindex.nVersion;
+ pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot;
+ pindexNew->nTime = diskindex.nTime;
+ pindexNew->nBits = diskindex.nBits;
+ pindexNew->nNonce = diskindex.nNonce;
+ pindexNew->nStatus = diskindex.nStatus;
+ pindexNew->nTx = diskindex.nTx;
+
+ if (!CheckProofOfWork(pindexNew->GetBlockHash(), pindexNew->nBits, Params().GetConsensus()))
+ return error("LoadBlockIndex(): CheckProofOfWork failed: %s", pindexNew->ToString());
+
+ pcursor->Next();
+ } else {
+ break; // if shutdown requested or finished loading block index
+ }
+ } catch (const std::exception& e) {
+ return error("%s: Deserialize or I/O error - %s", __func__, e.what());
+ }
+ }
+
+ return true;
+}
diff --git a/src/txdb.h b/src/txdb.h
new file mode 100644
index 0000000000..bef5dc9fd1
--- /dev/null
+++ b/src/txdb.h
@@ -0,0 +1,65 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_TXDB_H
+#define BITCOIN_TXDB_H
+
+#include "coins.h"
+#include "leveldbwrapper.h"
+
+#include <map>
+#include <string>
+#include <utility>
+#include <vector>
+
+class CBlockFileInfo;
+class CBlockIndex;
+struct CDiskTxPos;
+class uint256;
+
+//! -dbcache default (MiB)
+static const int64_t nDefaultDbCache = 100;
+//! max. -dbcache in (MiB)
+static const int64_t nMaxDbCache = sizeof(void*) > 4 ? 16384 : 1024;
+//! min. -dbcache in (MiB)
+static const int64_t nMinDbCache = 4;
+
+/** CCoinsView backed by the LevelDB coin database (chainstate/) */
+class CCoinsViewDB : public CCoinsView
+{
+protected:
+ CLevelDBWrapper db;
+public:
+ CCoinsViewDB(size_t nCacheSize, bool fMemory = false, bool fWipe = false);
+
+ bool GetCoins(const uint256 &txid, CCoins &coins) const;
+ bool HaveCoins(const uint256 &txid) const;
+ uint256 GetBestBlock() const;
+ bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock);
+ bool GetStats(CCoinsStats &stats) const;
+};
+
+/** Access to the block database (blocks/index/) */
+class CBlockTreeDB : public CLevelDBWrapper
+{
+public:
+ CBlockTreeDB(size_t nCacheSize, bool fMemory = false, bool fWipe = false);
+private:
+ CBlockTreeDB(const CBlockTreeDB&);
+ void operator=(const CBlockTreeDB&);
+public:
+ bool WriteBatchSync(const std::vector<std::pair<int, const CBlockFileInfo*> >& fileInfo, int nLastFile, const std::vector<const CBlockIndex*>& blockinfo);
+ bool ReadBlockFileInfo(int nFile, CBlockFileInfo &fileinfo);
+ bool ReadLastBlockFile(int &nFile);
+ bool WriteReindexing(bool fReindex);
+ bool ReadReindexing(bool &fReindex);
+ bool ReadTxIndex(const uint256 &txid, CDiskTxPos &pos);
+ bool WriteTxIndex(const std::vector<std::pair<uint256, CDiskTxPos> > &list);
+ bool WriteFlag(const std::string &name, bool fValue);
+ bool ReadFlag(const std::string &name, bool &fValue);
+ bool LoadBlockIndexGuts();
+};
+
+#endif // BITCOIN_TXDB_H
diff --git a/src/txmempool.cpp b/src/txmempool.cpp
new file mode 100644
index 0000000000..c3d1b60cb6
--- /dev/null
+++ b/src/txmempool.cpp
@@ -0,0 +1,421 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "txmempool.h"
+
+#include "clientversion.h"
+#include "consensus/consensus.h"
+#include "consensus/validation.h"
+#include "main.h"
+#include "policy/fees.h"
+#include "streams.h"
+#include "util.h"
+#include "utilmoneystr.h"
+#include "version.h"
+
+using namespace std;
+
+CTxMemPoolEntry::CTxMemPoolEntry():
+ nFee(0), nTxSize(0), nModSize(0), nTime(0), dPriority(0.0), hadNoDependencies(false)
+{
+ nHeight = MEMPOOL_HEIGHT;
+}
+
+CTxMemPoolEntry::CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee,
+ int64_t _nTime, double _dPriority,
+ unsigned int _nHeight, bool poolHasNoInputsOf):
+ tx(_tx), nFee(_nFee), nTime(_nTime), dPriority(_dPriority), nHeight(_nHeight),
+ hadNoDependencies(poolHasNoInputsOf)
+{
+ nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
+ nModSize = tx.CalculateModifiedSize(nTxSize);
+}
+
+CTxMemPoolEntry::CTxMemPoolEntry(const CTxMemPoolEntry& other)
+{
+ *this = other;
+}
+
+double
+CTxMemPoolEntry::GetPriority(unsigned int currentHeight) const
+{
+ CAmount nValueIn = tx.GetValueOut()+nFee;
+ double deltaPriority = ((double)(currentHeight-nHeight)*nValueIn)/nModSize;
+ double dResult = dPriority + deltaPriority;
+ return dResult;
+}
+
+CTxMemPool::CTxMemPool(const CFeeRate& _minRelayFee) :
+ nTransactionsUpdated(0)
+{
+ // Sanity checks off by default for performance, because otherwise
+ // accepting transactions becomes O(N^2) where N is the number
+ // of transactions in the pool
+ fSanityCheck = false;
+
+ minerPolicyEstimator = new CBlockPolicyEstimator(_minRelayFee);
+}
+
+CTxMemPool::~CTxMemPool()
+{
+ delete minerPolicyEstimator;
+}
+
+void CTxMemPool::pruneSpent(const uint256 &hashTx, CCoins &coins)
+{
+ LOCK(cs);
+
+ std::map<COutPoint, CInPoint>::iterator it = mapNextTx.lower_bound(COutPoint(hashTx, 0));
+
+ // iterate over all COutPoints in mapNextTx whose hash equals the provided hashTx
+ while (it != mapNextTx.end() && it->first.hash == hashTx) {
+ coins.Spend(it->first.n); // and remove those outputs from coins
+ it++;
+ }
+}
+
+unsigned int CTxMemPool::GetTransactionsUpdated() const
+{
+ LOCK(cs);
+ return nTransactionsUpdated;
+}
+
+void CTxMemPool::AddTransactionsUpdated(unsigned int n)
+{
+ LOCK(cs);
+ nTransactionsUpdated += n;
+}
+
+
+bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, bool fCurrentEstimate)
+{
+ // Add to memory pool without checking anything.
+ // Used by main.cpp AcceptToMemoryPool(), which DOES do
+ // all the appropriate checks.
+ LOCK(cs);
+ mapTx[hash] = entry;
+ const CTransaction& tx = mapTx[hash].GetTx();
+ for (unsigned int i = 0; i < tx.vin.size(); i++)
+ mapNextTx[tx.vin[i].prevout] = CInPoint(&tx, i);
+ nTransactionsUpdated++;
+ totalTxSize += entry.GetTxSize();
+ minerPolicyEstimator->processTransaction(entry, fCurrentEstimate);
+
+ return true;
+}
+
+
+void CTxMemPool::remove(const CTransaction &origTx, std::list<CTransaction>& removed, bool fRecursive)
+{
+ // Remove transaction from memory pool
+ {
+ LOCK(cs);
+ std::deque<uint256> txToRemove;
+ txToRemove.push_back(origTx.GetHash());
+ if (fRecursive && !mapTx.count(origTx.GetHash())) {
+ // If recursively removing but origTx isn't in the mempool
+ // be sure to remove any children that are in the pool. This can
+ // happen during chain re-orgs if origTx isn't re-accepted into
+ // the mempool for any reason.
+ for (unsigned int i = 0; i < origTx.vout.size(); i++) {
+ std::map<COutPoint, CInPoint>::iterator it = mapNextTx.find(COutPoint(origTx.GetHash(), i));
+ if (it == mapNextTx.end())
+ continue;
+ txToRemove.push_back(it->second.ptx->GetHash());
+ }
+ }
+ while (!txToRemove.empty())
+ {
+ uint256 hash = txToRemove.front();
+ txToRemove.pop_front();
+ if (!mapTx.count(hash))
+ continue;
+ const CTransaction& tx = mapTx[hash].GetTx();
+ if (fRecursive) {
+ for (unsigned int i = 0; i < tx.vout.size(); i++) {
+ std::map<COutPoint, CInPoint>::iterator it = mapNextTx.find(COutPoint(hash, i));
+ if (it == mapNextTx.end())
+ continue;
+ txToRemove.push_back(it->second.ptx->GetHash());
+ }
+ }
+ BOOST_FOREACH(const CTxIn& txin, tx.vin)
+ mapNextTx.erase(txin.prevout);
+
+ removed.push_back(tx);
+ totalTxSize -= mapTx[hash].GetTxSize();
+ mapTx.erase(hash);
+ nTransactionsUpdated++;
+ minerPolicyEstimator->removeTx(hash);
+ }
+ }
+}
+
+void CTxMemPool::removeCoinbaseSpends(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight)
+{
+ // Remove transactions spending a coinbase which are now immature
+ LOCK(cs);
+ list<CTransaction> transactionsToRemove;
+ for (std::map<uint256, CTxMemPoolEntry>::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) {
+ const CTransaction& tx = it->second.GetTx();
+ BOOST_FOREACH(const CTxIn& txin, tx.vin) {
+ std::map<uint256, CTxMemPoolEntry>::const_iterator it2 = mapTx.find(txin.prevout.hash);
+ if (it2 != mapTx.end())
+ continue;
+ const CCoins *coins = pcoins->AccessCoins(txin.prevout.hash);
+ if (fSanityCheck) assert(coins);
+ if (!coins || (coins->IsCoinBase() && nMemPoolHeight - coins->nHeight < COINBASE_MATURITY)) {
+ transactionsToRemove.push_back(tx);
+ break;
+ }
+ }
+ }
+ BOOST_FOREACH(const CTransaction& tx, transactionsToRemove) {
+ list<CTransaction> removed;
+ remove(tx, removed, true);
+ }
+}
+
+void CTxMemPool::removeConflicts(const CTransaction &tx, std::list<CTransaction>& removed)
+{
+ // Remove transactions which depend on inputs of tx, recursively
+ list<CTransaction> result;
+ LOCK(cs);
+ BOOST_FOREACH(const CTxIn &txin, tx.vin) {
+ std::map<COutPoint, CInPoint>::iterator it = mapNextTx.find(txin.prevout);
+ if (it != mapNextTx.end()) {
+ const CTransaction &txConflict = *it->second.ptx;
+ if (txConflict != tx)
+ {
+ remove(txConflict, removed, true);
+ }
+ }
+ }
+}
+
+/**
+ * Called when a block is connected. Removes from mempool and updates the miner fee estimator.
+ */
+void CTxMemPool::removeForBlock(const std::vector<CTransaction>& vtx, unsigned int nBlockHeight,
+ std::list<CTransaction>& conflicts, bool fCurrentEstimate)
+{
+ LOCK(cs);
+ std::vector<CTxMemPoolEntry> entries;
+ BOOST_FOREACH(const CTransaction& tx, vtx)
+ {
+ uint256 hash = tx.GetHash();
+ if (mapTx.count(hash))
+ entries.push_back(mapTx[hash]);
+ }
+ BOOST_FOREACH(const CTransaction& tx, vtx)
+ {
+ std::list<CTransaction> dummy;
+ remove(tx, dummy, false);
+ removeConflicts(tx, conflicts);
+ ClearPrioritisation(tx.GetHash());
+ }
+ // After the txs in the new block have been removed from the mempool, update policy estimates
+ minerPolicyEstimator->processBlock(nBlockHeight, entries, fCurrentEstimate);
+}
+
+void CTxMemPool::clear()
+{
+ LOCK(cs);
+ mapTx.clear();
+ mapNextTx.clear();
+ totalTxSize = 0;
+ ++nTransactionsUpdated;
+}
+
+void CTxMemPool::check(const CCoinsViewCache *pcoins) const
+{
+ if (!fSanityCheck)
+ return;
+
+ LogPrint("mempool", "Checking mempool with %u transactions and %u inputs\n", (unsigned int)mapTx.size(), (unsigned int)mapNextTx.size());
+
+ uint64_t checkTotal = 0;
+
+ CCoinsViewCache mempoolDuplicate(const_cast<CCoinsViewCache*>(pcoins));
+
+ LOCK(cs);
+ list<const CTxMemPoolEntry*> waitingOnDependants;
+ for (std::map<uint256, CTxMemPoolEntry>::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) {
+ unsigned int i = 0;
+ checkTotal += it->second.GetTxSize();
+ const CTransaction& tx = it->second.GetTx();
+ bool fDependsWait = false;
+ BOOST_FOREACH(const CTxIn &txin, tx.vin) {
+ // Check that every mempool transaction's inputs refer to available coins, or other mempool tx's.
+ std::map<uint256, CTxMemPoolEntry>::const_iterator it2 = mapTx.find(txin.prevout.hash);
+ if (it2 != mapTx.end()) {
+ const CTransaction& tx2 = it2->second.GetTx();
+ assert(tx2.vout.size() > txin.prevout.n && !tx2.vout[txin.prevout.n].IsNull());
+ fDependsWait = true;
+ } else {
+ const CCoins* coins = pcoins->AccessCoins(txin.prevout.hash);
+ assert(coins && coins->IsAvailable(txin.prevout.n));
+ }
+ // Check whether its inputs are marked in mapNextTx.
+ std::map<COutPoint, CInPoint>::const_iterator it3 = mapNextTx.find(txin.prevout);
+ assert(it3 != mapNextTx.end());
+ assert(it3->second.ptx == &tx);
+ assert(it3->second.n == i);
+ i++;
+ }
+ if (fDependsWait)
+ waitingOnDependants.push_back(&it->second);
+ else {
+ CValidationState state;
+ assert(CheckInputs(tx, state, mempoolDuplicate, false, 0, false, NULL));
+ UpdateCoins(tx, state, mempoolDuplicate, 1000000);
+ }
+ }
+ unsigned int stepsSinceLastRemove = 0;
+ while (!waitingOnDependants.empty()) {
+ const CTxMemPoolEntry* entry = waitingOnDependants.front();
+ waitingOnDependants.pop_front();
+ CValidationState state;
+ if (!mempoolDuplicate.HaveInputs(entry->GetTx())) {
+ waitingOnDependants.push_back(entry);
+ stepsSinceLastRemove++;
+ assert(stepsSinceLastRemove < waitingOnDependants.size());
+ } else {
+ assert(CheckInputs(entry->GetTx(), state, mempoolDuplicate, false, 0, false, NULL));
+ UpdateCoins(entry->GetTx(), state, mempoolDuplicate, 1000000);
+ stepsSinceLastRemove = 0;
+ }
+ }
+ for (std::map<COutPoint, CInPoint>::const_iterator it = mapNextTx.begin(); it != mapNextTx.end(); it++) {
+ uint256 hash = it->second.ptx->GetHash();
+ map<uint256, CTxMemPoolEntry>::const_iterator it2 = mapTx.find(hash);
+ const CTransaction& tx = it2->second.GetTx();
+ assert(it2 != mapTx.end());
+ assert(&tx == it->second.ptx);
+ assert(tx.vin.size() > it->second.n);
+ assert(it->first == it->second.ptx->vin[it->second.n].prevout);
+ }
+
+ assert(totalTxSize == checkTotal);
+}
+
+void CTxMemPool::queryHashes(vector<uint256>& vtxid)
+{
+ vtxid.clear();
+
+ LOCK(cs);
+ vtxid.reserve(mapTx.size());
+ for (map<uint256, CTxMemPoolEntry>::iterator mi = mapTx.begin(); mi != mapTx.end(); ++mi)
+ vtxid.push_back((*mi).first);
+}
+
+bool CTxMemPool::lookup(uint256 hash, CTransaction& result) const
+{
+ LOCK(cs);
+ map<uint256, CTxMemPoolEntry>::const_iterator i = mapTx.find(hash);
+ if (i == mapTx.end()) return false;
+ result = i->second.GetTx();
+ return true;
+}
+
+CFeeRate CTxMemPool::estimateFee(int nBlocks) const
+{
+ LOCK(cs);
+ return minerPolicyEstimator->estimateFee(nBlocks);
+}
+double CTxMemPool::estimatePriority(int nBlocks) const
+{
+ LOCK(cs);
+ return minerPolicyEstimator->estimatePriority(nBlocks);
+}
+
+bool
+CTxMemPool::WriteFeeEstimates(CAutoFile& fileout) const
+{
+ try {
+ LOCK(cs);
+ fileout << 109900; // version required to read: 0.10.99 or later
+ fileout << CLIENT_VERSION; // version that wrote the file
+ minerPolicyEstimator->Write(fileout);
+ }
+ catch (const std::exception&) {
+ LogPrintf("CTxMemPool::WriteFeeEstimates(): unable to write policy estimator data (non-fatal)\n");
+ return false;
+ }
+ return true;
+}
+
+bool
+CTxMemPool::ReadFeeEstimates(CAutoFile& filein)
+{
+ try {
+ int nVersionRequired, nVersionThatWrote;
+ filein >> nVersionRequired >> nVersionThatWrote;
+ if (nVersionRequired > CLIENT_VERSION)
+ return error("CTxMemPool::ReadFeeEstimates(): up-version (%d) fee estimate file", nVersionRequired);
+
+ LOCK(cs);
+ minerPolicyEstimator->Read(filein);
+ }
+ catch (const std::exception&) {
+ LogPrintf("CTxMemPool::ReadFeeEstimates(): unable to read policy estimator data (non-fatal)\n");
+ return false;
+ }
+ return true;
+}
+
+void CTxMemPool::PrioritiseTransaction(const uint256 hash, const string strHash, double dPriorityDelta, const CAmount& nFeeDelta)
+{
+ {
+ LOCK(cs);
+ std::pair<double, CAmount> &deltas = mapDeltas[hash];
+ deltas.first += dPriorityDelta;
+ deltas.second += nFeeDelta;
+ }
+ LogPrintf("PrioritiseTransaction: %s priority += %f, fee += %d\n", strHash, dPriorityDelta, FormatMoney(nFeeDelta));
+}
+
+void CTxMemPool::ApplyDeltas(const uint256 hash, double &dPriorityDelta, CAmount &nFeeDelta)
+{
+ LOCK(cs);
+ std::map<uint256, std::pair<double, CAmount> >::iterator pos = mapDeltas.find(hash);
+ if (pos == mapDeltas.end())
+ return;
+ const std::pair<double, CAmount> &deltas = pos->second;
+ dPriorityDelta += deltas.first;
+ nFeeDelta += deltas.second;
+}
+
+void CTxMemPool::ClearPrioritisation(const uint256 hash)
+{
+ LOCK(cs);
+ mapDeltas.erase(hash);
+}
+
+bool CTxMemPool::HasNoInputsOf(const CTransaction &tx) const
+{
+ for (unsigned int i = 0; i < tx.vin.size(); i++)
+ if (exists(tx.vin[i].prevout.hash))
+ return false;
+ return true;
+}
+
+CCoinsViewMemPool::CCoinsViewMemPool(CCoinsView *baseIn, CTxMemPool &mempoolIn) : CCoinsViewBacked(baseIn), mempool(mempoolIn) { }
+
+bool CCoinsViewMemPool::GetCoins(const uint256 &txid, CCoins &coins) const {
+ // If an entry in the mempool exists, always return that one, as it's guaranteed to never
+ // conflict with the underlying cache, and it cannot have pruned entries (as it contains full)
+ // transactions. First checking the underlying cache risks returning a pruned entry instead.
+ CTransaction tx;
+ if (mempool.lookup(txid, tx)) {
+ coins = CCoins(tx, MEMPOOL_HEIGHT);
+ return true;
+ }
+ return (base->GetCoins(txid, coins) && !coins.IsPruned());
+}
+
+bool CCoinsViewMemPool::HaveCoins(const uint256 &txid) const {
+ return mempool.exists(txid) || base->HaveCoins(txid);
+}
diff --git a/src/txmempool.h b/src/txmempool.h
new file mode 100644
index 0000000000..7271a5f603
--- /dev/null
+++ b/src/txmempool.h
@@ -0,0 +1,182 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_TXMEMPOOL_H
+#define BITCOIN_TXMEMPOOL_H
+
+#include <list>
+
+#include "amount.h"
+#include "coins.h"
+#include "primitives/transaction.h"
+#include "sync.h"
+
+class CAutoFile;
+
+inline double AllowFreeThreshold()
+{
+ return COIN * 144 / 250;
+}
+
+inline bool AllowFree(double dPriority)
+{
+ // Large (in bytes) low-priority (new, small-coin) transactions
+ // need a fee.
+ return dPriority > AllowFreeThreshold();
+}
+
+/** Fake height value used in CCoins to signify they are only in the memory pool (since 0.8) */
+static const unsigned int MEMPOOL_HEIGHT = 0x7FFFFFFF;
+
+/**
+ * CTxMemPool stores these:
+ */
+class CTxMemPoolEntry
+{
+private:
+ CTransaction tx;
+ CAmount nFee; //! Cached to avoid expensive parent-transaction lookups
+ size_t nTxSize; //! ... and avoid recomputing tx size
+ size_t nModSize; //! ... and modified size for priority
+ int64_t nTime; //! Local time when entering the mempool
+ double dPriority; //! Priority when entering the mempool
+ unsigned int nHeight; //! Chain height when entering the mempool
+ bool hadNoDependencies; //! Not dependent on any other txs when it entered the mempool
+
+public:
+ CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee,
+ int64_t _nTime, double _dPriority, unsigned int _nHeight, bool poolHasNoInputsOf = false);
+ CTxMemPoolEntry();
+ CTxMemPoolEntry(const CTxMemPoolEntry& other);
+
+ const CTransaction& GetTx() const { return this->tx; }
+ double GetPriority(unsigned int currentHeight) const;
+ CAmount GetFee() const { return nFee; }
+ size_t GetTxSize() const { return nTxSize; }
+ int64_t GetTime() const { return nTime; }
+ unsigned int GetHeight() const { return nHeight; }
+ bool WasClearAtEntry() const { return hadNoDependencies; }
+};
+
+class CBlockPolicyEstimator;
+
+/** An inpoint - a combination of a transaction and an index n into its vin */
+class CInPoint
+{
+public:
+ const CTransaction* ptx;
+ uint32_t n;
+
+ CInPoint() { SetNull(); }
+ CInPoint(const CTransaction* ptxIn, uint32_t nIn) { ptx = ptxIn; n = nIn; }
+ void SetNull() { ptx = NULL; n = (uint32_t) -1; }
+ bool IsNull() const { return (ptx == NULL && n == (uint32_t) -1); }
+};
+
+/**
+ * CTxMemPool stores valid-according-to-the-current-best-chain
+ * transactions that may be included in the next block.
+ *
+ * Transactions are added when they are seen on the network
+ * (or created by the local node), but not all transactions seen
+ * are added to the pool: if a new transaction double-spends
+ * an input of a transaction in the pool, it is dropped,
+ * as are non-standard transactions.
+ */
+class CTxMemPool
+{
+private:
+ bool fSanityCheck; //! Normally false, true if -checkmempool or -regtest
+ unsigned int nTransactionsUpdated;
+ CBlockPolicyEstimator* minerPolicyEstimator;
+
+ uint64_t totalTxSize; //! sum of all mempool tx' byte sizes
+
+public:
+ mutable CCriticalSection cs;
+ std::map<uint256, CTxMemPoolEntry> mapTx;
+ std::map<COutPoint, CInPoint> mapNextTx;
+ std::map<uint256, std::pair<double, CAmount> > mapDeltas;
+
+ CTxMemPool(const CFeeRate& _minRelayFee);
+ ~CTxMemPool();
+
+ /**
+ * If sanity-checking is turned on, check makes sure the pool is
+ * consistent (does not contain two transactions that spend the same inputs,
+ * all inputs are in the mapNextTx array). If sanity-checking is turned off,
+ * check does nothing.
+ */
+ void check(const CCoinsViewCache *pcoins) const;
+ void setSanityCheck(bool _fSanityCheck) { fSanityCheck = _fSanityCheck; }
+
+ bool addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, bool fCurrentEstimate = true);
+ void remove(const CTransaction &tx, std::list<CTransaction>& removed, bool fRecursive = false);
+ void removeCoinbaseSpends(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight);
+ void removeConflicts(const CTransaction &tx, std::list<CTransaction>& removed);
+ void removeForBlock(const std::vector<CTransaction>& vtx, unsigned int nBlockHeight,
+ std::list<CTransaction>& conflicts, bool fCurrentEstimate = true);
+ void clear();
+ void queryHashes(std::vector<uint256>& vtxid);
+ void pruneSpent(const uint256& hash, CCoins &coins);
+ unsigned int GetTransactionsUpdated() const;
+ void AddTransactionsUpdated(unsigned int n);
+ /**
+ * Check that none of this transactions inputs are in the mempool, and thus
+ * the tx is not dependent on other mempool transactions to be included in a block.
+ */
+ bool HasNoInputsOf(const CTransaction& tx) const;
+
+ /** Affect CreateNewBlock prioritisation of transactions */
+ void PrioritiseTransaction(const uint256 hash, const std::string strHash, double dPriorityDelta, const CAmount& nFeeDelta);
+ void ApplyDeltas(const uint256 hash, double &dPriorityDelta, CAmount &nFeeDelta);
+ void ClearPrioritisation(const uint256 hash);
+
+ unsigned long size()
+ {
+ LOCK(cs);
+ return mapTx.size();
+ }
+ uint64_t GetTotalTxSize()
+ {
+ LOCK(cs);
+ return totalTxSize;
+ }
+
+ bool exists(uint256 hash) const
+ {
+ LOCK(cs);
+ return (mapTx.count(hash) != 0);
+ }
+
+ bool lookup(uint256 hash, CTransaction& result) const;
+
+ /** Estimate fee rate needed to get into the next nBlocks */
+ CFeeRate estimateFee(int nBlocks) const;
+
+ /** Estimate priority needed to get into the next nBlocks */
+ double estimatePriority(int nBlocks) const;
+
+ /** Write/Read estimates to disk */
+ bool WriteFeeEstimates(CAutoFile& fileout) const;
+ bool ReadFeeEstimates(CAutoFile& filein);
+};
+
+/**
+ * CCoinsView that brings transactions from a memorypool into view.
+ * It does not check for spendings by memory pool transactions.
+ */
+class CCoinsViewMemPool : public CCoinsViewBacked
+{
+protected:
+ CTxMemPool &mempool;
+
+public:
+ CCoinsViewMemPool(CCoinsView *baseIn, CTxMemPool &mempoolIn);
+ bool GetCoins(const uint256 &txid, CCoins &coins) const;
+ bool HaveCoins(const uint256 &txid) const;
+};
+
+#endif // BITCOIN_TXMEMPOOL_H
diff --git a/src/ui_interface.h b/src/ui_interface.h
new file mode 100644
index 0000000000..32a92a4b81
--- /dev/null
+++ b/src/ui_interface.h
@@ -0,0 +1,102 @@
+// Copyright (c) 2010 Satoshi Nakamoto
+// Copyright (c) 2012 The Bitcoin Core developers
+// Distributed under the MIT 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 <stdint.h>
+#include <string>
+
+#include <boost/signals2/last_value.hpp>
+#include <boost/signals2/signal.hpp>
+
+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
+ {
+ ICON_INFORMATION = 0,
+ ICON_WARNING = (1U << 0),
+ ICON_ERROR = (1U << 1),
+ /**
+ * Mask of all available icons in CClientUIInterface::MessageBoxFlags
+ * This needs to be updated, when icons are changed there!
+ */
+ ICON_MASK = (ICON_INFORMATION | ICON_WARNING | ICON_ERROR),
+
+ /** These values are taken from qmessagebox.h "enum StandardButton" to be directly usable */
+ BTN_OK = 0x00000400U, // QMessageBox::Ok
+ BTN_YES = 0x00004000U, // QMessageBox::Yes
+ BTN_NO = 0x00010000U, // QMessageBox::No
+ BTN_ABORT = 0x00040000U, // QMessageBox::Abort
+ BTN_RETRY = 0x00080000U, // QMessageBox::Retry
+ BTN_IGNORE = 0x00100000U, // QMessageBox::Ignore
+ BTN_CLOSE = 0x00200000U, // QMessageBox::Close
+ BTN_CANCEL = 0x00400000U, // QMessageBox::Cancel
+ BTN_DISCARD = 0x00800000U, // QMessageBox::Discard
+ BTN_HELP = 0x01000000U, // QMessageBox::Help
+ BTN_APPLY = 0x02000000U, // QMessageBox::Apply
+ BTN_RESET = 0x04000000U, // QMessageBox::Reset
+ /**
+ * Mask of all available buttons in CClientUIInterface::MessageBoxFlags
+ * This needs to be updated, when buttons are changed there!
+ */
+ BTN_MASK = (BTN_OK | BTN_YES | BTN_NO | BTN_ABORT | BTN_RETRY | BTN_IGNORE |
+ BTN_CLOSE | BTN_CANCEL | BTN_DISCARD | BTN_HELP | BTN_APPLY | BTN_RESET),
+
+ /** Force blocking, modal message box dialog (not just OS notification) */
+ MODAL = 0x10000000U,
+
+ /** Do not print contents of message to debug log */
+ SECURE = 0x40000000U,
+
+ /** Predefined combinations for certain default usage cases */
+ MSG_INFORMATION = ICON_INFORMATION,
+ MSG_WARNING = (ICON_WARNING | BTN_OK | MODAL),
+ MSG_ERROR = (ICON_ERROR | BTN_OK | MODAL)
+ };
+
+ /** Show message box. */
+ boost::signals2::signal<bool (const std::string& message, const std::string& caption, unsigned int style), boost::signals2::last_value<bool> > ThreadSafeMessageBox;
+
+ /** Progress message during initialization. */
+ boost::signals2::signal<void (const std::string &message)> InitMessage;
+
+ /** Number of network connections changed. */
+ boost::signals2::signal<void (int newNumConnections)> NotifyNumConnectionsChanged;
+
+ /**
+ * New, updated or cancelled alert.
+ * @note called with lock cs_mapAlerts held.
+ */
+ boost::signals2::signal<void (const uint256 &hash, ChangeType status)> NotifyAlertChanged;
+
+ /** A wallet has been loaded. */
+ boost::signals2::signal<void (CWallet* wallet)> LoadWallet;
+
+ /** Show progress e.g. for verifychain */
+ boost::signals2::signal<void (const std::string &title, int nProgress)> ShowProgress;
+
+ /** New block has been accepted */
+ boost::signals2::signal<void (const uint256& hash)> NotifyBlockTip;
+};
+
+extern CClientUIInterface uiInterface;
+
+#endif // BITCOIN_UI_INTERFACE_H
diff --git a/src/uint256.cpp b/src/uint256.cpp
new file mode 100644
index 0000000000..25148808c6
--- /dev/null
+++ b/src/uint256.cpp
@@ -0,0 +1,146 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "uint256.h"
+
+#include "utilstrencodings.h"
+
+#include <stdio.h>
+#include <string.h>
+
+template <unsigned int BITS>
+base_blob<BITS>::base_blob(const std::vector<unsigned char>& vch)
+{
+ assert(vch.size() == sizeof(data));
+ memcpy(data, &vch[0], sizeof(data));
+}
+
+template <unsigned int BITS>
+std::string base_blob<BITS>::GetHex() const
+{
+ char psz[sizeof(data) * 2 + 1];
+ for (unsigned int i = 0; i < sizeof(data); i++)
+ sprintf(psz + i * 2, "%02x", data[sizeof(data) - i - 1]);
+ return std::string(psz, psz + sizeof(data) * 2);
+}
+
+template <unsigned int BITS>
+void base_blob<BITS>::SetHex(const char* psz)
+{
+ memset(data, 0, sizeof(data));
+
+ // skip leading spaces
+ while (isspace(*psz))
+ psz++;
+
+ // skip 0x
+ if (psz[0] == '0' && tolower(psz[1]) == 'x')
+ psz += 2;
+
+ // hex string to uint
+ const char* pbegin = psz;
+ while (::HexDigit(*psz) != -1)
+ psz++;
+ psz--;
+ unsigned char* p1 = (unsigned char*)data;
+ unsigned char* pend = p1 + WIDTH;
+ while (psz >= pbegin && p1 < pend) {
+ *p1 = ::HexDigit(*psz--);
+ if (psz >= pbegin) {
+ *p1 |= ((unsigned char)::HexDigit(*psz--) << 4);
+ p1++;
+ }
+ }
+}
+
+template <unsigned int BITS>
+void base_blob<BITS>::SetHex(const std::string& str)
+{
+ SetHex(str.c_str());
+}
+
+template <unsigned int BITS>
+std::string base_blob<BITS>::ToString() const
+{
+ return (GetHex());
+}
+
+// Explicit instantiations for base_blob<160>
+template base_blob<160>::base_blob(const std::vector<unsigned char>&);
+template std::string base_blob<160>::GetHex() const;
+template std::string base_blob<160>::ToString() const;
+template void base_blob<160>::SetHex(const char*);
+template void base_blob<160>::SetHex(const std::string&);
+
+// Explicit instantiations for base_blob<256>
+template base_blob<256>::base_blob(const std::vector<unsigned char>&);
+template std::string base_blob<256>::GetHex() const;
+template std::string base_blob<256>::ToString() const;
+template void base_blob<256>::SetHex(const char*);
+template void base_blob<256>::SetHex(const std::string&);
+
+static void inline HashMix(uint32_t& a, uint32_t& b, uint32_t& c)
+{
+ // Taken from lookup3, by Bob Jenkins.
+ a -= c;
+ a ^= ((c << 4) | (c >> 28));
+ c += b;
+ b -= a;
+ b ^= ((a << 6) | (a >> 26));
+ a += c;
+ c -= b;
+ c ^= ((b << 8) | (b >> 24));
+ b += a;
+ a -= c;
+ a ^= ((c << 16) | (c >> 16));
+ c += b;
+ b -= a;
+ b ^= ((a << 19) | (a >> 13));
+ a += c;
+ c -= b;
+ c ^= ((b << 4) | (b >> 28));
+ b += a;
+}
+
+static void inline HashFinal(uint32_t& a, uint32_t& b, uint32_t& c)
+{
+ // Taken from lookup3, by Bob Jenkins.
+ c ^= b;
+ c -= ((b << 14) | (b >> 18));
+ a ^= c;
+ a -= ((c << 11) | (c >> 21));
+ b ^= a;
+ b -= ((a << 25) | (a >> 7));
+ c ^= b;
+ c -= ((b << 16) | (b >> 16));
+ a ^= c;
+ a -= ((c << 4) | (c >> 28));
+ b ^= a;
+ b -= ((a << 14) | (a >> 18));
+ c ^= b;
+ c -= ((b << 24) | (b >> 8));
+}
+
+uint64_t uint256::GetHash(const uint256& salt) const
+{
+ uint32_t a, b, c;
+ const uint32_t *pn = (const uint32_t*)data;
+ const uint32_t *salt_pn = (const uint32_t*)salt.data;
+ a = b = c = 0xdeadbeef + WIDTH;
+
+ a += pn[0] ^ salt_pn[0];
+ b += pn[1] ^ salt_pn[1];
+ c += pn[2] ^ salt_pn[2];
+ HashMix(a, b, c);
+ a += pn[3] ^ salt_pn[3];
+ b += pn[4] ^ salt_pn[4];
+ c += pn[5] ^ salt_pn[5];
+ HashMix(a, b, c);
+ a += pn[6] ^ salt_pn[6];
+ b += pn[7] ^ salt_pn[7];
+ HashFinal(a, b, c);
+
+ return ((((uint64_t)b) << 32) | c);
+}
diff --git a/src/uint256.h b/src/uint256.h
new file mode 100644
index 0000000000..6d016ab164
--- /dev/null
+++ b/src/uint256.h
@@ -0,0 +1,158 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT 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 <assert.h>
+#include <cstring>
+#include <stdexcept>
+#include <stdint.h>
+#include <string>
+#include <vector>
+
+/** Template base class for fixed-sized opaque blobs. */
+template<unsigned int BITS>
+class base_blob
+{
+protected:
+ enum { WIDTH=BITS/8 };
+ uint8_t data[WIDTH];
+public:
+ base_blob()
+ {
+ memset(data, 0, sizeof(data));
+ }
+
+ explicit base_blob(const std::vector<unsigned char>& vch);
+
+ bool IsNull() const
+ {
+ for (int i = 0; i < WIDTH; i++)
+ if (data[i] != 0)
+ return false;
+ return true;
+ }
+
+ void SetNull()
+ {
+ memset(data, 0, sizeof(data));
+ }
+
+ friend inline bool operator==(const base_blob& a, const base_blob& b) { return memcmp(a.data, b.data, sizeof(a.data)) == 0; }
+ friend inline bool operator!=(const base_blob& a, const base_blob& b) { return memcmp(a.data, b.data, sizeof(a.data)) != 0; }
+ friend inline bool operator<(const base_blob& a, const base_blob& b) { return memcmp(a.data, b.data, sizeof(a.data)) < 0; }
+
+ std::string GetHex() const;
+ void SetHex(const char* psz);
+ void SetHex(const std::string& str);
+ std::string ToString() const;
+
+ unsigned char* begin()
+ {
+ return &data[0];
+ }
+
+ unsigned char* end()
+ {
+ return &data[WIDTH];
+ }
+
+ const unsigned char* begin() const
+ {
+ return &data[0];
+ }
+
+ const unsigned char* end() const
+ {
+ return &data[WIDTH];
+ }
+
+ unsigned int size() const
+ {
+ return sizeof(data);
+ }
+
+ unsigned int GetSerializeSize(int nType, int nVersion) const
+ {
+ return sizeof(data);
+ }
+
+ template<typename Stream>
+ void Serialize(Stream& s, int nType, int nVersion) const
+ {
+ s.write((char*)data, sizeof(data));
+ }
+
+ template<typename Stream>
+ void Unserialize(Stream& s, int nType, int nVersion)
+ {
+ s.read((char*)data, sizeof(data));
+ }
+};
+
+/** 160-bit opaque blob.
+ * @note This type is called uint160 for historical reasons only. It is an opaque
+ * blob of 160 bits and has no integer operations.
+ */
+class uint160 : public base_blob<160> {
+public:
+ uint160() {}
+ uint160(const base_blob<160>& b) : base_blob<160>(b) {}
+ explicit uint160(const std::vector<unsigned char>& vch) : base_blob<160>(vch) {}
+};
+
+/** 256-bit opaque blob.
+ * @note This type is called uint256 for historical reasons only. It is an
+ * opaque blob of 256 bits and has no integer operations. Use arith_uint256 if
+ * those are required.
+ */
+class uint256 : public base_blob<256> {
+public:
+ uint256() {}
+ uint256(const base_blob<256>& b) : base_blob<256>(b) {}
+ explicit uint256(const std::vector<unsigned char>& vch) : base_blob<256>(vch) {}
+
+ /** A cheap hash function that just returns 64 bits from the result, it can be
+ * used when the contents are considered uniformly random. It is not appropriate
+ * when the value can easily be influenced from outside as e.g. a network adversary could
+ * provide values to trigger worst-case behavior.
+ * @note The result of this function is not stable between little and big endian.
+ */
+ uint64_t GetCheapHash() const
+ {
+ uint64_t result;
+ memcpy((void*)&result, (void*)data, 8);
+ return result;
+ }
+
+ /** A more secure, salted hash function.
+ * @note This hash is not stable between little and big endian.
+ */
+ uint64_t GetHash(const uint256& salt) const;
+};
+
+/* uint256 from const char *.
+ * This is a separate function because the constructor uint256(const char*) can result
+ * in dangerously catching uint256(0).
+ */
+inline uint256 uint256S(const char *str)
+{
+ uint256 rv;
+ rv.SetHex(str);
+ return rv;
+}
+/* uint256 from std::string.
+ * This is a separate function because the constructor uint256(const std::string &str) can result
+ * in dangerously catching uint256(0) via std::string(const char*).
+ */
+inline uint256 uint256S(const std::string& str)
+{
+ uint256 rv;
+ rv.SetHex(str);
+ return rv;
+}
+
+#endif // BITCOIN_UINT256_H
diff --git a/src/undo.h b/src/undo.h
new file mode 100644
index 0000000000..1c4ed95bf2
--- /dev/null
+++ b/src/undo.h
@@ -0,0 +1,85 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_UNDO_H
+#define BITCOIN_UNDO_H
+
+#include "compressor.h"
+#include "primitives/transaction.h"
+#include "serialize.h"
+
+/** Undo information for a CTxIn
+ *
+ * Contains the prevout's CTxOut being spent, and if this was the
+ * last output of the affected transaction, its metadata as well
+ * (coinbase or not, height, transaction version)
+ */
+class CTxInUndo
+{
+public:
+ CTxOut txout; // the txout data before being spent
+ bool fCoinBase; // if the outpoint was the last unspent: whether it belonged to a coinbase
+ unsigned int nHeight; // if the outpoint was the last unspent: its height
+ int nVersion; // if the outpoint was the last unspent: its version
+
+ CTxInUndo() : txout(), fCoinBase(false), nHeight(0), nVersion(0) {}
+ CTxInUndo(const CTxOut &txoutIn, bool fCoinBaseIn = false, unsigned int nHeightIn = 0, int nVersionIn = 0) : txout(txoutIn), fCoinBase(fCoinBaseIn), nHeight(nHeightIn), nVersion(nVersionIn) { }
+
+ unsigned int GetSerializeSize(int nType, int nVersion) const {
+ return ::GetSerializeSize(VARINT(nHeight*2+(fCoinBase ? 1 : 0)), nType, nVersion) +
+ (nHeight > 0 ? ::GetSerializeSize(VARINT(this->nVersion), nType, nVersion) : 0) +
+ ::GetSerializeSize(CTxOutCompressor(REF(txout)), nType, nVersion);
+ }
+
+ template<typename Stream>
+ void Serialize(Stream &s, int nType, int nVersion) const {
+ ::Serialize(s, VARINT(nHeight*2+(fCoinBase ? 1 : 0)), nType, nVersion);
+ if (nHeight > 0)
+ ::Serialize(s, VARINT(this->nVersion), nType, nVersion);
+ ::Serialize(s, CTxOutCompressor(REF(txout)), nType, nVersion);
+ }
+
+ template<typename Stream>
+ void Unserialize(Stream &s, int nType, int nVersion) {
+ unsigned int nCode = 0;
+ ::Unserialize(s, VARINT(nCode), nType, nVersion);
+ nHeight = nCode / 2;
+ fCoinBase = nCode & 1;
+ if (nHeight > 0)
+ ::Unserialize(s, VARINT(this->nVersion), nType, nVersion);
+ ::Unserialize(s, REF(CTxOutCompressor(REF(txout))), nType, nVersion);
+ }
+};
+
+/** Undo information for a CTransaction */
+class CTxUndo
+{
+public:
+ // undo information for all txins
+ std::vector<CTxInUndo> vprevout;
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ READWRITE(vprevout);
+ }
+};
+
+/** Undo information for a CBlock */
+class CBlockUndo
+{
+public:
+ std::vector<CTxUndo> vtxundo; // for all but the coinbase
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ READWRITE(vtxundo);
+ }
+};
+
+#endif // BITCOIN_UNDO_H
diff --git a/src/univalue/gen.cpp b/src/univalue/gen.cpp
new file mode 100644
index 0000000000..abebe88634
--- /dev/null
+++ b/src/univalue/gen.cpp
@@ -0,0 +1,78 @@
+// Copyright 2014 BitPay Inc.
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+//
+// To re-create univalue_escapes.h:
+// $ g++ -o gen gen.cpp
+// $ ./gen > univalue_escapes.h
+//
+
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+#include "univalue.h"
+
+using namespace std;
+
+static bool initEscapes;
+static const char *escapes[256];
+
+static void initJsonEscape()
+{
+ escapes[(int)'"'] = "\\\"";
+ escapes[(int)'\\'] = "\\\\";
+ escapes[(int)'/'] = "\\/";
+ escapes[(int)'\b'] = "\\b";
+ escapes[(int)'\f'] = "\\f";
+ escapes[(int)'\n'] = "\\n";
+ escapes[(int)'\r'] = "\\r";
+ escapes[(int)'\t'] = "\\t";
+
+ initEscapes = true;
+}
+
+static void outputEscape()
+{
+ printf( "// Automatically generated file. Do not modify.\n"
+ "#ifndef BITCOIN_UNIVALUE_UNIVALUE_ESCAPES_H\n"
+ "#define BITCOIN_UNIVALUE_UNIVALUE_ESCAPES_H\n"
+ "static const char *escapes[256] = {\n");
+
+ for (unsigned int i = 0; i < 256; i++) {
+ if (!escapes[i]) {
+ printf("\tNULL,\n");
+ } else {
+ printf("\t\"");
+
+ unsigned int si;
+ for (si = 0; si < strlen(escapes[i]); si++) {
+ char ch = escapes[i][si];
+ switch (ch) {
+ case '"':
+ printf("\\\"");
+ break;
+ case '\\':
+ printf("\\\\");
+ break;
+ default:
+ printf("%c", escapes[i][si]);
+ break;
+ }
+ }
+
+ printf("\",\n");
+ }
+ }
+
+ printf( "};\n"
+ "#endif // BITCOIN_UNIVALUE_UNIVALUE_ESCAPES_H\n");
+}
+
+int main (int argc, char *argv[])
+{
+ initJsonEscape();
+ outputEscape();
+ return 0;
+}
+
diff --git a/src/univalue/univalue.cpp b/src/univalue/univalue.cpp
new file mode 100644
index 0000000000..4e445a542a
--- /dev/null
+++ b/src/univalue/univalue.cpp
@@ -0,0 +1,211 @@
+// Copyright 2014 BitPay Inc.
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include <stdint.h>
+#include <ctype.h>
+#include <sstream>
+#include "univalue.h"
+
+using namespace std;
+
+static const UniValue nullValue;
+
+void UniValue::clear()
+{
+ typ = VNULL;
+ val.clear();
+ keys.clear();
+ values.clear();
+}
+
+bool UniValue::setNull()
+{
+ clear();
+ return true;
+}
+
+bool UniValue::setBool(bool val_)
+{
+ clear();
+ typ = VBOOL;
+ if (val_)
+ val = "1";
+ return true;
+}
+
+static bool validNumStr(const string& s)
+{
+ string tokenVal;
+ unsigned int consumed;
+ enum jtokentype tt = getJsonToken(tokenVal, consumed, s.c_str());
+ return (tt == JTOK_NUMBER);
+}
+
+bool UniValue::setNumStr(const string& val_)
+{
+ if (!validNumStr(val_))
+ return false;
+
+ clear();
+ typ = VNUM;
+ val = val_;
+ return true;
+}
+
+bool UniValue::setInt(uint64_t val)
+{
+ string s;
+ ostringstream oss;
+
+ oss << val;
+
+ return setNumStr(oss.str());
+}
+
+bool UniValue::setInt(int64_t val)
+{
+ string s;
+ ostringstream oss;
+
+ oss << val;
+
+ return setNumStr(oss.str());
+}
+
+bool UniValue::setFloat(double val)
+{
+ string s;
+ ostringstream oss;
+
+ oss << val;
+
+ return setNumStr(oss.str());
+}
+
+bool UniValue::setStr(const string& val_)
+{
+ clear();
+ typ = VSTR;
+ val = val_;
+ return true;
+}
+
+bool UniValue::setArray()
+{
+ clear();
+ typ = VARR;
+ return true;
+}
+
+bool UniValue::setObject()
+{
+ clear();
+ typ = VOBJ;
+ return true;
+}
+
+bool UniValue::push_back(const UniValue& val)
+{
+ if (typ != VARR)
+ return false;
+
+ values.push_back(val);
+ return true;
+}
+
+bool UniValue::push_backV(const std::vector<UniValue>& vec)
+{
+ if (typ != VARR)
+ return false;
+
+ values.insert(values.end(), vec.begin(), vec.end());
+
+ return true;
+}
+
+bool UniValue::pushKV(const std::string& key, const UniValue& val)
+{
+ if (typ != VOBJ)
+ return false;
+
+ keys.push_back(key);
+ values.push_back(val);
+ return true;
+}
+
+bool UniValue::pushKVs(const UniValue& obj)
+{
+ if (typ != VOBJ || obj.typ != VOBJ)
+ return false;
+
+ for (unsigned int i = 0; i < obj.keys.size(); i++) {
+ keys.push_back(obj.keys[i]);
+ values.push_back(obj.values[i]);
+ }
+
+ return true;
+}
+
+int UniValue::findKey(const std::string& key) const
+{
+ for (unsigned int i = 0; i < keys.size(); i++) {
+ if (keys[i] == key)
+ return (int) i;
+ }
+
+ return -1;
+}
+
+bool UniValue::checkObject(const std::map<std::string,UniValue::VType>& t)
+{
+ for (std::map<std::string,UniValue::VType>::const_iterator it = t.begin();
+ it != t.end(); it++) {
+ int idx = findKey(it->first);
+ if (idx < 0)
+ return false;
+
+ if (values[idx].getType() != it->second)
+ return false;
+ }
+
+ return true;
+}
+
+const UniValue& UniValue::operator[](const std::string& key) const
+{
+ if (typ != VOBJ)
+ return nullValue;
+
+ int index = findKey(key);
+ if (index < 0)
+ return nullValue;
+
+ return values[index];
+}
+
+const UniValue& UniValue::operator[](unsigned int index) const
+{
+ if (typ != VOBJ && typ != VARR)
+ return nullValue;
+ if (index >= values.size())
+ return nullValue;
+
+ return values[index];
+}
+
+const char *uvTypeName(UniValue::VType t)
+{
+ switch (t) {
+ case UniValue::VNULL: return "null";
+ case UniValue::VBOOL: return "bool";
+ case UniValue::VOBJ: return "object";
+ case UniValue::VARR: return "array";
+ case UniValue::VSTR: return "string";
+ case UniValue::VNUM: return "number";
+ }
+
+ // not reached
+ return NULL;
+}
+
diff --git a/src/univalue/univalue.h b/src/univalue/univalue.h
new file mode 100644
index 0000000000..88d73b8c64
--- /dev/null
+++ b/src/univalue/univalue.h
@@ -0,0 +1,155 @@
+// Copyright 2014 BitPay Inc.
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_UNIVALUE_UNIVALUE_H
+#define BITCOIN_UNIVALUE_UNIVALUE_H
+
+#include <stdint.h>
+#include <string>
+#include <vector>
+#include <map>
+#include <cassert>
+
+class UniValue {
+public:
+ enum VType { VNULL, VOBJ, VARR, VSTR, VNUM, VBOOL, };
+
+ UniValue() { typ = VNULL; }
+ UniValue(UniValue::VType initialType, const std::string& initialStr = "") {
+ typ = initialType;
+ val = initialStr;
+ }
+ UniValue(uint64_t val_) {
+ setInt(val_);
+ }
+ UniValue(int64_t val_) {
+ setInt(val_);
+ }
+ UniValue(int val_) {
+ setInt(val_);
+ }
+ UniValue(double val_) {
+ setFloat(val_);
+ }
+ UniValue(const std::string& val_) {
+ setStr(val_);
+ }
+ UniValue(const char *val_) {
+ std::string s(val_);
+ setStr(s);
+ }
+ ~UniValue() {}
+
+ void clear();
+
+ bool setNull();
+ bool setBool(bool val);
+ bool setNumStr(const std::string& val);
+ bool setInt(uint64_t val);
+ bool setInt(int64_t val);
+ bool setInt(int val) { return setInt((int64_t)val); }
+ bool setFloat(double val);
+ bool setStr(const std::string& val);
+ bool setArray();
+ bool setObject();
+
+ enum VType getType() const { return typ; }
+ std::string getValStr() const { return val; }
+ bool empty() const { return (values.size() == 0); }
+
+ size_t count() const { return values.size(); }
+
+ bool getBool() const { return isTrue(); }
+ bool checkObject(const std::map<std::string,UniValue::VType>& memberTypes);
+ const UniValue& operator[](const std::string& key) const;
+ const UniValue& operator[](unsigned int index) const;
+ bool exists(const std::string& key) const { return (findKey(key) >= 0); }
+
+ bool isNull() const { return (typ == VNULL); }
+ bool isTrue() const { return (typ == VBOOL) && (val == "1"); }
+ bool isFalse() const { return (!isTrue()); }
+ bool isBool() const { return (typ == VBOOL); }
+ bool isStr() const { return (typ == VSTR); }
+ bool isNum() const { return (typ == VNUM); }
+ bool isArray() const { return (typ == VARR); }
+ bool isObject() const { return (typ == VOBJ); }
+
+ bool push_back(const UniValue& val);
+ bool push_back(const std::string& val_) {
+ UniValue tmpVal(VSTR, val_);
+ return push_back(tmpVal);
+ }
+ bool push_back(const char *val_) {
+ std::string s(val_);
+ return push_back(s);
+ }
+ bool push_backV(const std::vector<UniValue>& vec);
+
+ bool pushKV(const std::string& key, const UniValue& val);
+ bool pushKV(const std::string& key, const std::string& val) {
+ UniValue tmpVal(VSTR, val);
+ return pushKV(key, tmpVal);
+ }
+ bool pushKV(const std::string& key, const char *val_) {
+ std::string val(val_);
+ return pushKV(key, val);
+ }
+ bool pushKV(const std::string& key, int64_t val) {
+ UniValue tmpVal(val);
+ return pushKV(key, tmpVal);
+ }
+ bool pushKV(const std::string& key, uint64_t val) {
+ UniValue tmpVal(val);
+ return pushKV(key, tmpVal);
+ }
+ bool pushKV(const std::string& key, int val) {
+ UniValue tmpVal((int64_t)val);
+ return pushKV(key, tmpVal);
+ }
+ bool pushKV(const std::string& key, double val) {
+ UniValue tmpVal(val);
+ return pushKV(key, tmpVal);
+ }
+ bool pushKVs(const UniValue& obj);
+
+ std::string write(unsigned int prettyIndent = 0,
+ unsigned int indentLevel = 0) const;
+
+ bool read(const char *raw);
+ bool read(const std::string& rawStr) {
+ return read(rawStr.c_str());
+ }
+
+private:
+ UniValue::VType typ;
+ std::string val; // numbers are stored as C++ strings
+ std::vector<std::string> keys;
+ std::vector<UniValue> values;
+
+ int findKey(const std::string& key) const;
+ void writeArray(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) const;
+ void writeObject(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) const;
+};
+
+enum jtokentype {
+ JTOK_ERR = -1,
+ JTOK_NONE = 0, // eof
+ JTOK_OBJ_OPEN,
+ JTOK_OBJ_CLOSE,
+ JTOK_ARR_OPEN,
+ JTOK_ARR_CLOSE,
+ JTOK_COLON,
+ JTOK_COMMA,
+ JTOK_KW_NULL,
+ JTOK_KW_TRUE,
+ JTOK_KW_FALSE,
+ JTOK_NUMBER,
+ JTOK_STRING,
+};
+
+extern enum jtokentype getJsonToken(std::string& tokenVal,
+ unsigned int& consumed, const char *raw);
+extern const char *uvTypeName(UniValue::VType t);
+
+#endif // BITCOIN_UNIVALUE_UNIVALUE_H
diff --git a/src/univalue/univalue_escapes.h b/src/univalue/univalue_escapes.h
new file mode 100644
index 0000000000..0514118285
--- /dev/null
+++ b/src/univalue/univalue_escapes.h
@@ -0,0 +1,262 @@
+// Automatically generated file. Do not modify.
+#ifndef BITCOIN_UNIVALUE_UNIVALUE_ESCAPES_H
+#define BITCOIN_UNIVALUE_UNIVALUE_ESCAPES_H
+static const char *escapes[256] = {
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "\\b",
+ "\\t",
+ "\\n",
+ NULL,
+ "\\f",
+ "\\r",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "\\\"",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "\\/",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "\\\\",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+};
+#endif // BITCOIN_UNIVALUE_UNIVALUE_ESCAPES_H
diff --git a/src/univalue/univalue_read.cpp b/src/univalue/univalue_read.cpp
new file mode 100644
index 0000000000..5cea778996
--- /dev/null
+++ b/src/univalue/univalue_read.cpp
@@ -0,0 +1,390 @@
+// Copyright 2014 BitPay Inc.
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include <string.h>
+#include <vector>
+#include <stdio.h>
+#include "univalue.h"
+
+using namespace std;
+
+// convert hexadecimal string to unsigned integer
+static const char *hatoui(const char *first, const char *last,
+ unsigned int& out)
+{
+ unsigned int result = 0;
+ for (; first != last; ++first)
+ {
+ int digit;
+ if (isdigit(*first))
+ digit = *first - '0';
+
+ else if (*first >= 'a' && *first <= 'f')
+ digit = *first - 'a' + 10;
+
+ else if (*first >= 'A' && *first <= 'F')
+ digit = *first - 'A' + 10;
+
+ else
+ break;
+
+ result = 16 * result + digit;
+ }
+ out = result;
+
+ return first;
+}
+
+enum jtokentype getJsonToken(string& tokenVal, unsigned int& consumed,
+ const char *raw)
+{
+ tokenVal.clear();
+ consumed = 0;
+
+ const char *rawStart = raw;
+
+ while ((*raw) && (isspace(*raw))) // skip whitespace
+ raw++;
+
+ switch (*raw) {
+
+ case 0:
+ return JTOK_NONE;
+
+ case '{':
+ raw++;
+ consumed = (raw - rawStart);
+ return JTOK_OBJ_OPEN;
+ case '}':
+ raw++;
+ consumed = (raw - rawStart);
+ return JTOK_OBJ_CLOSE;
+ case '[':
+ raw++;
+ consumed = (raw - rawStart);
+ return JTOK_ARR_OPEN;
+ case ']':
+ raw++;
+ consumed = (raw - rawStart);
+ return JTOK_ARR_CLOSE;
+
+ case ':':
+ raw++;
+ consumed = (raw - rawStart);
+ return JTOK_COLON;
+ case ',':
+ raw++;
+ consumed = (raw - rawStart);
+ return JTOK_COMMA;
+
+ case 'n':
+ case 't':
+ case 'f':
+ if (!strncmp(raw, "null", 4)) {
+ raw += 4;
+ consumed = (raw - rawStart);
+ return JTOK_KW_NULL;
+ } else if (!strncmp(raw, "true", 4)) {
+ raw += 4;
+ consumed = (raw - rawStart);
+ return JTOK_KW_TRUE;
+ } else if (!strncmp(raw, "false", 5)) {
+ raw += 5;
+ consumed = (raw - rawStart);
+ return JTOK_KW_FALSE;
+ } else
+ return JTOK_ERR;
+
+ case '-':
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9': {
+ // part 1: int
+ string numStr;
+
+ const char *first = raw;
+
+ const char *firstDigit = first;
+ if (!isdigit(*firstDigit))
+ firstDigit++;
+ if ((*firstDigit == '0') && isdigit(firstDigit[1]))
+ return JTOK_ERR;
+
+ numStr += *raw; // copy first char
+ raw++;
+
+ if ((*first == '-') && (!isdigit(*raw)))
+ return JTOK_ERR;
+
+ while ((*raw) && isdigit(*raw)) { // copy digits
+ numStr += *raw;
+ raw++;
+ }
+
+ // part 2: frac
+ if (*raw == '.') {
+ numStr += *raw; // copy .
+ raw++;
+
+ if (!isdigit(*raw))
+ return JTOK_ERR;
+ while ((*raw) && isdigit(*raw)) { // copy digits
+ numStr += *raw;
+ raw++;
+ }
+ }
+
+ // part 3: exp
+ if (*raw == 'e' || *raw == 'E') {
+ numStr += *raw; // copy E
+ raw++;
+
+ if (*raw == '-' || *raw == '+') { // copy +/-
+ numStr += *raw;
+ raw++;
+ }
+
+ if (!isdigit(*raw))
+ return JTOK_ERR;
+ while ((*raw) && isdigit(*raw)) { // copy digits
+ numStr += *raw;
+ raw++;
+ }
+ }
+
+ tokenVal = numStr;
+ consumed = (raw - rawStart);
+ return JTOK_NUMBER;
+ }
+
+ case '"': {
+ raw++; // skip "
+
+ string valStr;
+
+ while (*raw) {
+ if (*raw < 0x20)
+ return JTOK_ERR;
+
+ else if (*raw == '\\') {
+ raw++; // skip backslash
+
+ switch (*raw) {
+ case '"': valStr += "\""; break;
+ case '\\': valStr += "\\"; break;
+ case '/': valStr += "/"; break;
+ case 'b': valStr += "\b"; break;
+ case 'f': valStr += "\f"; break;
+ case 'n': valStr += "\n"; break;
+ case 'r': valStr += "\r"; break;
+ case 't': valStr += "\t"; break;
+
+ case 'u': {
+ char buf[4] = {0,0,0,0};
+ char *last = &buf[0];
+ unsigned int codepoint;
+ if (hatoui(raw + 1, raw + 1 + 4, codepoint) !=
+ raw + 1 + 4)
+ return JTOK_ERR;
+
+ if (codepoint <= 0x7f)
+ *last = (char)codepoint;
+ else if (codepoint <= 0x7FF) {
+ *last++ = (char)(0xC0 | (codepoint >> 6));
+ *last = (char)(0x80 | (codepoint & 0x3F));
+ } else if (codepoint <= 0xFFFF) {
+ *last++ = (char)(0xE0 | (codepoint >> 12));
+ *last++ = (char)(0x80 | ((codepoint >> 6) & 0x3F));
+ *last = (char)(0x80 | (codepoint & 0x3F));
+ }
+
+ valStr += buf;
+ raw += 4;
+ break;
+ }
+ default:
+ return JTOK_ERR;
+
+ }
+
+ raw++; // skip esc'd char
+ }
+
+ else if (*raw == '"') {
+ raw++; // skip "
+ break; // stop scanning
+ }
+
+ else {
+ valStr += *raw;
+ raw++;
+ }
+ }
+
+ tokenVal = valStr;
+ consumed = (raw - rawStart);
+ return JTOK_STRING;
+ }
+
+ default:
+ return JTOK_ERR;
+ }
+}
+
+bool UniValue::read(const char *raw)
+{
+ clear();
+
+ bool expectName = false;
+ bool expectColon = false;
+ vector<UniValue*> stack;
+
+ enum jtokentype tok = JTOK_NONE;
+ enum jtokentype last_tok = JTOK_NONE;
+ while (1) {
+ last_tok = tok;
+
+ string tokenVal;
+ unsigned int consumed;
+ tok = getJsonToken(tokenVal, consumed, raw);
+ if (tok == JTOK_NONE || tok == JTOK_ERR)
+ break;
+ raw += consumed;
+
+ switch (tok) {
+
+ case JTOK_OBJ_OPEN:
+ case JTOK_ARR_OPEN: {
+ VType utyp = (tok == JTOK_OBJ_OPEN ? VOBJ : VARR);
+ if (!stack.size()) {
+ if (utyp == VOBJ)
+ setObject();
+ else
+ setArray();
+ stack.push_back(this);
+ } else {
+ UniValue tmpVal(utyp);
+ UniValue *top = stack.back();
+ top->values.push_back(tmpVal);
+
+ UniValue *newTop = &(top->values.back());
+ stack.push_back(newTop);
+ }
+
+ if (utyp == VOBJ)
+ expectName = true;
+ break;
+ }
+
+ case JTOK_OBJ_CLOSE:
+ case JTOK_ARR_CLOSE: {
+ if (!stack.size() || expectColon || (last_tok == JTOK_COMMA))
+ return false;
+
+ VType utyp = (tok == JTOK_OBJ_CLOSE ? VOBJ : VARR);
+ UniValue *top = stack.back();
+ if (utyp != top->getType())
+ return false;
+
+ stack.pop_back();
+ expectName = false;
+ break;
+ }
+
+ case JTOK_COLON: {
+ if (!stack.size() || expectName || !expectColon)
+ return false;
+
+ UniValue *top = stack.back();
+ if (top->getType() != VOBJ)
+ return false;
+
+ expectColon = false;
+ break;
+ }
+
+ case JTOK_COMMA: {
+ if (!stack.size() || expectName || expectColon ||
+ (last_tok == JTOK_COMMA) || (last_tok == JTOK_ARR_OPEN))
+ return false;
+
+ UniValue *top = stack.back();
+ if (top->getType() == VOBJ)
+ expectName = true;
+ break;
+ }
+
+ case JTOK_KW_NULL:
+ case JTOK_KW_TRUE:
+ case JTOK_KW_FALSE: {
+ if (!stack.size() || expectName || expectColon)
+ return false;
+
+ UniValue tmpVal;
+ switch (tok) {
+ case JTOK_KW_NULL:
+ // do nothing more
+ break;
+ case JTOK_KW_TRUE:
+ tmpVal.setBool(true);
+ break;
+ case JTOK_KW_FALSE:
+ tmpVal.setBool(false);
+ break;
+ default: /* impossible */ break;
+ }
+
+ UniValue *top = stack.back();
+ top->values.push_back(tmpVal);
+
+ break;
+ }
+
+ case JTOK_NUMBER: {
+ if (!stack.size() || expectName || expectColon)
+ return false;
+
+ UniValue tmpVal(VNUM, tokenVal);
+ UniValue *top = stack.back();
+ top->values.push_back(tmpVal);
+
+ break;
+ }
+
+ case JTOK_STRING: {
+ if (!stack.size())
+ return false;
+
+ UniValue *top = stack.back();
+
+ if (expectName) {
+ top->keys.push_back(tokenVal);
+ expectName = false;
+ expectColon = true;
+ } else {
+ UniValue tmpVal(VSTR, tokenVal);
+ top->values.push_back(tmpVal);
+ }
+
+ break;
+ }
+
+ default:
+ return false;
+ }
+ }
+
+ if (stack.size() != 0)
+ return false;
+
+ return true;
+}
+
diff --git a/src/univalue/univalue_write.cpp b/src/univalue/univalue_write.cpp
new file mode 100644
index 0000000000..9a1d364c95
--- /dev/null
+++ b/src/univalue/univalue_write.cpp
@@ -0,0 +1,125 @@
+// Copyright 2014 BitPay Inc.
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include <ctype.h>
+#include <stdio.h>
+#include "univalue.h"
+#include "univalue_escapes.h"
+
+// TODO: Using UTF8
+
+using namespace std;
+
+static string json_escape(const string& inS)
+{
+ string outS;
+ outS.reserve(inS.size() * 2);
+
+ for (unsigned int i = 0; i < inS.size(); i++) {
+ unsigned char ch = inS[i];
+ const char *escStr = escapes[ch];
+
+ if (escStr)
+ outS += escStr;
+
+ else if (isprint(ch))
+ outS += ch;
+
+ else {
+ char tmpesc[16];
+ sprintf(tmpesc, "\\u%04x", ch);
+ outS += tmpesc;
+ }
+ }
+
+ return outS;
+}
+
+string UniValue::write(unsigned int prettyIndent,
+ unsigned int indentLevel) const
+{
+ string s;
+ s.reserve(1024);
+
+ unsigned int modIndent = indentLevel;
+ if (modIndent == 0)
+ modIndent = 1;
+
+ switch (typ) {
+ case VNULL:
+ s += "null";
+ break;
+ case VOBJ:
+ writeObject(prettyIndent, modIndent, s);
+ break;
+ case VARR:
+ writeArray(prettyIndent, modIndent, s);
+ break;
+ case VSTR:
+ s += "\"" + json_escape(val) + "\"";
+ break;
+ case VNUM:
+ s += val;
+ break;
+ case VBOOL:
+ s += (val == "1" ? "true" : "false");
+ break;
+ }
+
+ return s;
+}
+
+static void indentStr(unsigned int prettyIndent, unsigned int indentLevel, string& s)
+{
+ s.append(prettyIndent * indentLevel, ' ');
+}
+
+void UniValue::writeArray(unsigned int prettyIndent, unsigned int indentLevel, string& s) const
+{
+ s += "[";
+ if (prettyIndent)
+ s += "\n";
+
+ for (unsigned int i = 0; i < values.size(); i++) {
+ if (prettyIndent)
+ indentStr(prettyIndent, indentLevel, s);
+ s += values[i].write(prettyIndent, indentLevel + 1);
+ if (i != (values.size() - 1)) {
+ s += ",";
+ if (prettyIndent)
+ s += " ";
+ }
+ if (prettyIndent)
+ s += "\n";
+ }
+
+ if (prettyIndent)
+ indentStr(prettyIndent, indentLevel - 1, s);
+ s += "]";
+}
+
+void UniValue::writeObject(unsigned int prettyIndent, unsigned int indentLevel, string& s) const
+{
+ s += "{";
+ if (prettyIndent)
+ s += "\n";
+
+ for (unsigned int i = 0; i < keys.size(); i++) {
+ if (prettyIndent)
+ indentStr(prettyIndent, indentLevel, s);
+ s += "\"" + json_escape(keys[i]) + "\":";
+ if (prettyIndent)
+ s += " ";
+ s += values[i].write(prettyIndent, indentLevel + 1);
+ if (i != (values.size() - 1))
+ s += ",";
+ if (prettyIndent)
+ s += "\n";
+ }
+
+ if (prettyIndent)
+ indentStr(prettyIndent, indentLevel - 1, s);
+ s += "}";
+}
+
diff --git a/src/util.cpp b/src/util.cpp
new file mode 100644
index 0000000000..b64dffb57f
--- /dev/null
+++ b/src/util.cpp
@@ -0,0 +1,765 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#if defined(HAVE_CONFIG_H)
+#include "config/bitcoin-config.h"
+#endif
+
+#include "util.h"
+
+#include "chainparamsbase.h"
+#include "random.h"
+#include "serialize.h"
+#include "sync.h"
+#include "utilstrencodings.h"
+#include "utiltime.h"
+
+#include <stdarg.h>
+
+#if (defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__))
+#include <pthread.h>
+#include <pthread_np.h>
+#endif
+
+#ifndef WIN32
+// for posix_fallocate
+#ifdef __linux__
+
+#ifdef _POSIX_C_SOURCE
+#undef _POSIX_C_SOURCE
+#endif
+
+#define _POSIX_C_SOURCE 200112L
+
+#endif // __linux__
+
+#include <algorithm>
+#include <fcntl.h>
+#include <sys/resource.h>
+#include <sys/stat.h>
+
+#else
+
+#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 <io.h> /* for _commit */
+#include <shlobj.h>
+#endif
+
+#ifdef HAVE_SYS_PRCTL_H
+#include <sys/prctl.h>
+#endif
+
+#include <boost/algorithm/string/case_conv.hpp> // for to_lower()
+#include <boost/algorithm/string/join.hpp>
+#include <boost/algorithm/string/predicate.hpp> // for startswith() and endswith()
+#include <boost/filesystem.hpp>
+#include <boost/filesystem/fstream.hpp>
+#include <boost/foreach.hpp>
+#include <boost/program_options/detail/config_file.hpp>
+#include <boost/program_options/parsers.hpp>
+#include <boost/thread.hpp>
+#include <openssl/crypto.h>
+#include <openssl/rand.h>
+#include <openssl/conf.h>
+
+// 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&);
+ }
+
+} // namespace boost
+
+using namespace std;
+
+map<string, string> mapArgs;
+map<string, vector<string> > mapMultiArgs;
+bool fDebug = false;
+bool fPrintToConsole = false;
+bool fPrintToDebugLog = true;
+bool fDaemon = false;
+bool fServer = false;
+string strMiscWarning;
+bool fLogTimestamps = false;
+bool fLogIPs = false;
+volatile bool fReopenDebugLog = false;
+CTranslationInterface translationInterface;
+
+/** Init OpenSSL library multithreading support */
+static CCriticalSection** ppmutexOpenSSL;
+void locking_callback(int mode, int i, const char* file, int line) NO_THREAD_SAFETY_ANALYSIS
+{
+ 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);
+
+ // OpenSSL can optionally load a config file which lists optional loadable modules and engines.
+ // We don't use them so we don't require the config. However some of our libs may call functions
+ // which attempt to load the config file, possibly resulting in an exit() or crash if it is missing
+ // or corrupt. Explicitly tell OpenSSL not to try to load the file. The result for our libs will be
+ // that the config appears to have been loaded and there are no modules/engines available.
+ OPENSSL_no_config();
+
+#ifdef WIN32
+ // Seed OpenSSL PRNG with current contents of the screen
+ RAND_screen();
+#endif
+
+ // Seed OpenSSL PRNG with performance counter
+ RandAddSeed();
+ }
+ ~CInit()
+ {
+ // Securely erase the memory used by the PRNG
+ RAND_cleanup();
+ // 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;
+
+/**
+ * LogPrintf() has been broken a couple of times now
+ * by well-meaning people adding mutexes in the most straightforward way.
+ * It breaks because it may be called by global destructors during shutdown.
+ * Since the order of destruction of static/global objects is undefined,
+ * defining a mutex as a global object doesn't work (the mutex gets
+ * destroyed, and then some later destructor calls OutputDebugStringF,
+ * maybe indirectly, and you get a core dump at shutdown trying to lock
+ * the mutex).
+ */
+
+static boost::once_flag debugPrintInitFlag = BOOST_ONCE_INIT;
+/**
+ * We use boost::call_once() to make sure these are initialized
+ * in a thread-safe manner the first time called:
+ */
+static FILE* fileout = NULL;
+static boost::mutex* mutexDebugLog = NULL;
+
+static void DebugPrintInit()
+{
+ assert(fileout == NULL);
+ assert(mutexDebugLog == NULL);
+
+ boost::filesystem::path pathDebug = GetDataDir() / "debug.log";
+ fileout = fopen(pathDebug.string().c_str(), "a");
+ if (fileout) setbuf(fileout, NULL); // unbuffered
+
+ mutexDebugLog = new boost::mutex();
+}
+
+bool LogAcceptCategory(const char* category)
+{
+ if (category != NULL)
+ {
+ if (!fDebug)
+ return false;
+
+ // Give each thread quick access to -debug settings.
+ // This helps prevent issues debugging global destructors,
+ // where mapMultiArgs might be deleted before another
+ // global destructor calls LogPrint()
+ static boost::thread_specific_ptr<set<string> > ptrCategory;
+ if (ptrCategory.get() == NULL)
+ {
+ const vector<string>& categories = mapMultiArgs["-debug"];
+ ptrCategory.reset(new set<string>(categories.begin(), categories.end()));
+ // thread_specific_ptr automatically deletes the set when the thread ends.
+ }
+ const set<string>& setCategories = *ptrCategory.get();
+
+ // if not debugging everything and not debugging specific category, LogPrint does nothing.
+ if (setCategories.count(string("")) == 0 &&
+ setCategories.count(string(category)) == 0)
+ return false;
+ }
+ return true;
+}
+
+int LogPrintStr(const std::string &str)
+{
+ int ret = 0; // Returns total number of characters written
+ if (fPrintToConsole)
+ {
+ // print to console
+ ret = fwrite(str.data(), 1, str.size(), stdout);
+ fflush(stdout);
+ }
+ else if (fPrintToDebugLog && AreBaseParamsConfigured())
+ {
+ static bool fStartedNewLine = true;
+ boost::call_once(&DebugPrintInit, debugPrintInitFlag);
+
+ if (fileout == NULL)
+ return ret;
+
+ 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)
+ ret += fprintf(fileout, "%s ", DateTimeStrFormat("%Y-%m-%d %H:%M:%S", GetTime()).c_str());
+ if (!str.empty() && str[str.size()-1] == '\n')
+ fStartedNewLine = true;
+ else
+ fStartedNewLine = false;
+
+ ret = fwrite(str.data(), 1, str.size(), fileout);
+ }
+
+ return ret;
+}
+
+static void InterpretNegativeSetting(string name, map<string, string>& 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, false);
+ mapSettingsRet[positive] = (value ? "1" : "0");
+ }
+ }
+}
+
+void ParseParameters(int argc, const char* const argv[])
+{
+ mapArgs.clear();
+ mapMultiArgs.clear();
+
+ for (int i = 1; i < argc; i++)
+ {
+ std::string str(argv[i]);
+ std::string strValue;
+ size_t is_index = str.find('=');
+ if (is_index != std::string::npos)
+ {
+ strValue = str.substr(is_index+1);
+ str = str.substr(0, is_index);
+ }
+#ifdef WIN32
+ boost::to_lower(str);
+ if (boost::algorithm::starts_with(str, "/"))
+ str = "-" + str.substr(1);
+#endif
+
+ if (str[0] != '-')
+ break;
+
+ // Interpret --foo as -foo.
+ // If both --foo and -foo are set, the last takes effect.
+ if (str.length() > 1 && str[1] == '-')
+ str = str.substr(1);
+
+ mapArgs[str] = strValue;
+ mapMultiArgs[str].push_back(strValue);
+ }
+
+ // New 0.6 features:
+ BOOST_FOREACH(const PAIRTYPE(string,string)& entry, mapArgs)
+ {
+ // interpret -nofoo as -foo=0 (and -nofoo=0 as -foo=1) as long as -foo not set
+ InterpretNegativeSetting(entry.first, mapArgs);
+ }
+}
+
+std::string GetArg(const std::string& strArg, const std::string& strDefault)
+{
+ if (mapArgs.count(strArg))
+ return mapArgs[strArg];
+ return strDefault;
+}
+
+int64_t GetArg(const std::string& strArg, int64_t 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"));
+}
+
+static const int screenWidth = 79;
+static const int optIndent = 2;
+static const int msgIndent = 7;
+
+std::string HelpMessageGroup(const std::string &message) {
+ return std::string(message) + std::string("\n\n");
+}
+
+std::string HelpMessageOpt(const std::string &option, const std::string &message) {
+ return std::string(optIndent,' ') + std::string(option) +
+ std::string("\n") + std::string(msgIndent,' ') +
+ FormatParagraph(message, screenWidth - msgIndent, msgIndent) +
+ std::string("\n\n");
+}
+
+static std::string FormatException(const std::exception* pex, const char* pszThread)
+{
+#ifdef WIN32
+ char pszModule[MAX_PATH] = "";
+ GetModuleFileNameA(NULL, pszModule, sizeof(pszModule));
+#else
+ const char* pszModule = "bitcoin";
+#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 PrintExceptionContinue(const std::exception* pex, const char* pszThread)
+{
+ std::string message = FormatException(pex, pszThread);
+ LogPrintf("\n\n************************\n%s\n", message);
+ 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\Bitcoin
+ // Windows >= Vista: C:\Users\Username\AppData\Roaming\Bitcoin
+ // Mac: ~/Library/Application Support/Bitcoin
+ // Unix: ~/.bitcoin
+#ifdef WIN32
+ // Windows
+ return GetSpecialFolderPath(CSIDL_APPDATA) / "Bitcoin";
+#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";
+ TryCreateDirectory(pathRet);
+ return pathRet / "Bitcoin";
+#else
+ // Unix
+ return pathRet / ".bitcoin";
+#endif
+#endif
+}
+
+static boost::filesystem::path pathCached;
+static boost::filesystem::path pathCachedNetSpecific;
+static CCriticalSection csPathCached;
+
+const boost::filesystem::path &GetDataDir(bool fNetSpecific)
+{
+ namespace fs = boost::filesystem;
+
+ LOCK(csPathCached);
+
+ fs::path &path = fNetSpecific ? pathCachedNetSpecific : pathCached;
+
+ // This can be called during exceptions by LogPrintf(), so we cache the
+ // value so we don't have to do memory allocations after that.
+ if (!path.empty())
+ return path;
+
+ if (mapArgs.count("-datadir")) {
+ path = fs::system_complete(mapArgs["-datadir"]);
+ if (!fs::is_directory(path)) {
+ path = "";
+ return path;
+ }
+ } else {
+ path = GetDefaultDataDir();
+ }
+ if (fNetSpecific)
+ path /= BaseParams().DataDir();
+
+ fs::create_directories(path);
+
+ return path;
+}
+
+void ClearDatadirCache()
+{
+ pathCached = boost::filesystem::path();
+ pathCachedNetSpecific = boost::filesystem::path();
+}
+
+boost::filesystem::path GetConfigFile()
+{
+ boost::filesystem::path pathConfigFile(GetArg("-conf", "bitcoin.conf"));
+ if (!pathConfigFile.is_complete())
+ pathConfigFile = GetDataDir(false) / pathConfigFile;
+
+ return pathConfigFile;
+}
+
+void ReadConfigFile(map<string, string>& mapSettingsRet,
+ map<string, vector<string> >& mapMultiSettingsRet)
+{
+ boost::filesystem::ifstream streamConfig(GetConfigFile());
+ if (!streamConfig.good())
+ return; // No bitcoin.conf file is OK
+
+ set<string> 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 bitcoin.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]);
+ }
+ // If datadir is changed in .conf file:
+ ClearDatadirCache();
+}
+
+#ifndef WIN32
+boost::filesystem::path GetPidFile()
+{
+ boost::filesystem::path pathPidFile(GetArg("-pid", "bitcoind.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);
+ }
+}
+#endif
+
+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) != 0;
+#else
+ int rc = std::rename(src.string().c_str(), dest.string().c_str());
+ return (rc == 0);
+#endif /* WIN32 */
+}
+
+/**
+ * Ignores exceptions thrown by Boost's create_directory if the requested directory exists.
+ * Specifically handles case where path p exists, but it wasn't possible for the user to
+ * write to the parent directory.
+ */
+bool TryCreateDirectory(const boost::filesystem::path& p)
+{
+ try
+ {
+ return boost::filesystem::create_directory(p);
+ } catch (const boost::filesystem::filesystem_error&) {
+ if (!boost::filesystem::exists(p) || !boost::filesystem::is_directory(p))
+ throw;
+ }
+
+ // create_directory didn't create the directory, it had to have existed already
+ return false;
+}
+
+void FileCommit(FILE *fileout)
+{
+ fflush(fileout); // harmless if redundantly called
+#ifdef WIN32
+ HANDLE hFile = (HANDLE)_get_osfhandle(_fileno(fileout));
+ FlushFileBuffers(hFile);
+#else
+ #if defined(__linux__) || defined(__NetBSD__)
+ fdatasync(fileno(fileout));
+ #elif defined(__APPLE__) && defined(F_FULLFSYNC)
+ fcntl(fileno(fileout), F_FULLFSYNC, 0);
+ #else
+ fsync(fileno(fileout));
+ #endif
+#endif
+}
+
+bool TruncateFile(FILE *file, unsigned int length) {
+#if defined(WIN32)
+ return _chsize(_fileno(file), length) == 0;
+#else
+ return ftruncate(fileno(file), length) == 0;
+#endif
+}
+
+/**
+ * this function tries to raise the file descriptor limit to the requested number.
+ * It returns the actual file descriptor limit (which may be more or less than nMinFD)
+ */
+int RaiseFileDescriptorLimit(int nMinFD) {
+#if defined(WIN32)
+ return 2048;
+#else
+ struct rlimit limitFD;
+ if (getrlimit(RLIMIT_NOFILE, &limitFD) != -1) {
+ if (limitFD.rlim_cur < (rlim_t)nMinFD) {
+ limitFD.rlim_cur = nMinFD;
+ if (limitFD.rlim_cur > limitFD.rlim_max)
+ limitFD.rlim_cur = limitFD.rlim_max;
+ setrlimit(RLIMIT_NOFILE, &limitFD);
+ getrlimit(RLIMIT_NOFILE, &limitFD);
+ }
+ return limitFD.rlim_cur;
+ }
+ return nMinFD; // getrlimit failed, assume it's fine
+#endif
+}
+
+/**
+ * this function tries to make a particular range of a file allocated (corresponding to disk space)
+ * it is advisory, and the range specified in the arguments will never contain live data
+ */
+void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length) {
+#if defined(WIN32)
+ // Windows-specific version
+ HANDLE hFile = (HANDLE)_get_osfhandle(_fileno(file));
+ LARGE_INTEGER nFileSize;
+ int64_t nEndPos = (int64_t)offset + length;
+ nFileSize.u.LowPart = nEndPos & 0xFFFFFFFF;
+ nFileSize.u.HighPart = nEndPos >> 32;
+ SetFilePointerEx(hFile, nFileSize, 0, FILE_BEGIN);
+ SetEndOfFile(hFile);
+#elif defined(MAC_OSX)
+ // OSX specific version
+ fstore_t fst;
+ fst.fst_flags = F_ALLOCATECONTIG;
+ fst.fst_posmode = F_PEOFPOSMODE;
+ fst.fst_offset = 0;
+ fst.fst_length = (off_t)offset + length;
+ fst.fst_bytesalloc = 0;
+ if (fcntl(fileno(file), F_PREALLOCATE, &fst) == -1) {
+ fst.fst_flags = F_ALLOCATEALL;
+ fcntl(fileno(file), F_PREALLOCATE, &fst);
+ }
+ ftruncate(fileno(file), fst.fst_length);
+#elif defined(__linux__)
+ // Version using posix_fallocate
+ off_t nEndPos = (off_t)offset + length;
+ posix_fallocate(fileno(file), 0, nEndPos);
+#else
+ // Fallback version
+ // TODO: just write one byte per block
+ static const char buf[65536] = {};
+ fseek(file, offset, SEEK_SET);
+ while (length > 0) {
+ unsigned int now = 65536;
+ if (length < now)
+ now = length;
+ fwrite(buf, 1, now, file); // allowed to fail; this function is advisory anyway
+ length -= now;
+ }
+#endif
+}
+
+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 && boost::filesystem::file_size(pathLog) > 10 * 1000000)
+ {
+ // Restart the file with some of the end
+ std::vector <char> vch(200000,0);
+ fseek(file, -((long)vch.size()), SEEK_END);
+ int nBytes = fread(begin_ptr(vch), 1, vch.size(), file);
+ fclose(file);
+
+ file = fopen(pathLog.string().c_str(), "w");
+ if (file)
+ {
+ fwrite(begin_ptr(vch), 1, nBytes, file);
+ fclose(file);
+ }
+ }
+ else if (file != NULL)
+ fclose(file);
+}
+
+#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);
+ }
+
+ LogPrintf("SHGetSpecialFolderPathA() failed, could not obtain requested path.\n");
+ return fs::path("");
+}
+#endif
+
+boost::filesystem::path GetTempPath() {
+#if BOOST_FILESYSTEM_VERSION == 3
+ return boost::filesystem::temp_directory_path();
+#else
+ // TODO: remove when we don't support filesystem v2 anymore
+ boost::filesystem::path path;
+#ifdef WIN32
+ char pszPath[MAX_PATH] = "";
+
+ if (GetTempPathA(MAX_PATH, pszPath))
+ path = boost::filesystem::path(pszPath);
+#else
+ path = boost::filesystem::path("/tmp");
+#endif
+ if (path.empty() || !boost::filesystem::is_directory(path)) {
+ LogPrintf("GetTempPath(): failed to find temp path\n");
+ return boost::filesystem::path("");
+ }
+ return path;
+#endif
+}
+
+void runCommand(std::string strCommand)
+{
+ int nErr = ::system(strCommand.c_str());
+ if (nErr)
+ LogPrintf("runCommand error: system(%s) returned %d\n", strCommand, 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 (defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__))
+ pthread_set_name_np(pthread_self(), name);
+
+#elif defined(MAC_OSX)
+ pthread_setname_np(name);
+#else
+ // Prevent warnings for unused parameters...
+ (void)name;
+#endif
+}
+
+void SetupEnvironment()
+{
+ // On most POSIX systems (e.g. Linux, but not BSD) the environment's locale
+ // may be invalid, in which case the "C" locale is used as fallback.
+#if !defined(WIN32) && !defined(MAC_OSX) && !defined(__FreeBSD__) && !defined(__OpenBSD__)
+ try {
+ std::locale(""); // Raises a runtime error if current locale is invalid
+ } catch (const std::runtime_error&) {
+ setenv("LC_ALL", "C", 1);
+ }
+#endif
+ // The path locale is lazy initialized and to avoid deinitialization errors
+ // in multithreading environments, it is set explicitly by the main thread.
+ // A dummy locale is used to extract the internal default locale, used by
+ // boost::filesystem::path, which is then used to explicitly imbue the path.
+ std::locale loc = boost::filesystem::path::imbue(std::locale::classic());
+ boost::filesystem::path::imbue(loc);
+}
+
+void SetThreadPriority(int nPriority)
+{
+#ifdef WIN32
+ SetThreadPriority(GetCurrentThread(), nPriority);
+#else // WIN32
+#ifdef PRIO_THREAD
+ setpriority(PRIO_THREAD, 0, nPriority);
+#else // PRIO_THREAD
+ setpriority(PRIO_PROCESS, 0, nPriority);
+#endif // PRIO_THREAD
+#endif // WIN32
+}
diff --git a/src/util.h b/src/util.h
new file mode 100644
index 0000000000..4cc0faf4d7
--- /dev/null
+++ b/src/util.h
@@ -0,0 +1,233 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+/**
+ * Server/client environment: argument handling, config file parsing,
+ * logging, thread wrappers
+ */
+#ifndef BITCOIN_UTIL_H
+#define BITCOIN_UTIL_H
+
+#if defined(HAVE_CONFIG_H)
+#include "config/bitcoin-config.h"
+#endif
+
+#include "compat.h"
+#include "tinyformat.h"
+#include "utiltime.h"
+
+#include <exception>
+#include <map>
+#include <stdint.h>
+#include <string>
+#include <vector>
+
+#include <boost/filesystem/path.hpp>
+#include <boost/signals2/signal.hpp>
+#include <boost/thread/exceptions.hpp>
+
+/** Signals for translation. */
+class CTranslationInterface
+{
+public:
+ /** Translate a message to the native language of the user. */
+ boost::signals2::signal<std::string (const char* psz)> Translate;
+};
+
+extern std::map<std::string, std::string> mapArgs;
+extern std::map<std::string, std::vector<std::string> > mapMultiArgs;
+extern bool fDebug;
+extern bool fPrintToConsole;
+extern bool fPrintToDebugLog;
+extern bool fServer;
+extern std::string strMiscWarning;
+extern bool fLogTimestamps;
+extern bool fLogIPs;
+extern volatile bool fReopenDebugLog;
+extern CTranslationInterface translationInterface;
+
+/**
+ * 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<std::string> rv = translationInterface.Translate(psz);
+ return rv ? (*rv) : psz;
+}
+
+void SetupEnvironment();
+
+/** Return true if log accepts specified category */
+bool LogAcceptCategory(const char* category);
+/** Send a string to the log output */
+int LogPrintStr(const std::string &str);
+
+#define LogPrintf(...) LogPrint(NULL, __VA_ARGS__)
+
+/**
+ * When we switch to C++11, this can be switched to variadic templates instead
+ * of this macro-based construction (see tinyformat.h).
+ */
+#define MAKE_ERROR_AND_LOG_FUNC(n) \
+ /** Print to debug.log if -debug=category switch is given OR category is NULL. */ \
+ template<TINYFORMAT_ARGTYPES(n)> \
+ static inline int LogPrint(const char* category, const char* format, TINYFORMAT_VARARGS(n)) \
+ { \
+ if(!LogAcceptCategory(category)) return 0; \
+ return LogPrintStr(tfm::format(format, TINYFORMAT_PASSARGS(n))); \
+ } \
+ /** Log error and return false */ \
+ template<TINYFORMAT_ARGTYPES(n)> \
+ static inline bool error(const char* format, TINYFORMAT_VARARGS(n)) \
+ { \
+ LogPrintStr("ERROR: " + tfm::format(format, TINYFORMAT_PASSARGS(n)) + "\n"); \
+ return false; \
+ }
+
+TINYFORMAT_FOREACH_ARGNUM(MAKE_ERROR_AND_LOG_FUNC)
+
+/**
+ * Zero-arg versions of logging and error, these are not covered by
+ * TINYFORMAT_FOREACH_ARGNUM
+ */
+static inline int LogPrint(const char* category, const char* format)
+{
+ if(!LogAcceptCategory(category)) return 0;
+ return LogPrintStr(format);
+}
+static inline bool error(const char* format)
+{
+ LogPrintStr(std::string("ERROR: ") + format + "\n");
+ return false;
+}
+
+void PrintExceptionContinue(const std::exception *pex, const char* pszThread);
+void ParseParameters(int argc, const char*const argv[]);
+void FileCommit(FILE *fileout);
+bool TruncateFile(FILE *file, unsigned int length);
+int RaiseFileDescriptorLimit(int nMinFD);
+void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length);
+bool RenameOver(boost::filesystem::path src, boost::filesystem::path dest);
+bool TryCreateDirectory(const boost::filesystem::path& p);
+boost::filesystem::path GetDefaultDataDir();
+const boost::filesystem::path &GetDataDir(bool fNetSpecific = true);
+void ClearDatadirCache();
+boost::filesystem::path GetConfigFile();
+#ifndef WIN32
+boost::filesystem::path GetPidFile();
+void CreatePidFile(const boost::filesystem::path &path, pid_t pid);
+#endif
+void ReadConfigFile(std::map<std::string, std::string>& mapSettingsRet, std::map<std::string, std::vector<std::string> >& mapMultiSettingsRet);
+#ifdef WIN32
+boost::filesystem::path GetSpecialFolderPath(int nFolder, bool fCreate = true);
+#endif
+boost::filesystem::path GetTempPath();
+void ShrinkDebugFile();
+void runCommand(std::string strCommand);
+
+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_t GetArg(const std::string& strArg, int64_t 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);
+
+/**
+ * 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);
+
+/**
+ * Format a string to be used as group of options in help messages
+ *
+ * @param message Group name (e.g. "RPC server options:")
+ * @return the formatted string
+ */
+std::string HelpMessageGroup(const std::string& message);
+
+/**
+ * Format a string to be used as option description in help messages
+ *
+ * @param option Option message (e.g. "-rpcuser=<user>")
+ * @param message Option description (e.g. "Username for JSON-RPC connections")
+ * @return the formatted string
+ */
+std::string HelpMessageOpt(const std::string& option, const std::string& message);
+
+void SetThreadPriority(int nPriority);
+void RenameThread(const char* name);
+
+/**
+ * .. and a wrapper that just calls func once
+ */
+template <typename Callable> void TraceThread(const char* name, Callable func)
+{
+ std::string s = strprintf("bitcoin-%s", name);
+ RenameThread(s.c_str());
+ try
+ {
+ LogPrintf("%s thread start\n", name);
+ func();
+ LogPrintf("%s thread exit\n", name);
+ }
+ catch (const boost::thread_interrupted&)
+ {
+ LogPrintf("%s thread interrupt\n", name);
+ throw;
+ }
+ catch (const std::exception& e) {
+ PrintExceptionContinue(&e, name);
+ throw;
+ }
+ catch (...) {
+ PrintExceptionContinue(NULL, name);
+ throw;
+ }
+}
+
+#endif // BITCOIN_UTIL_H
diff --git a/src/utilmoneystr.cpp b/src/utilmoneystr.cpp
new file mode 100644
index 0000000000..2fbc048878
--- /dev/null
+++ b/src/utilmoneystr.cpp
@@ -0,0 +1,81 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "utilmoneystr.h"
+
+#include "primitives/transaction.h"
+#include "tinyformat.h"
+#include "utilstrencodings.h"
+
+using namespace std;
+
+string FormatMoney(const CAmount& n, bool fPlus)
+{
+ // Note: not using straight sprintf here because we do NOT want
+ // localized number formatting.
+ int64_t n_abs = (n > 0 ? n : -n);
+ int64_t quotient = n_abs/COIN;
+ int64_t remainder = n_abs%COIN;
+ string str = strprintf("%d.%08d", quotient, remainder);
+
+ // Right-trim excess zeros 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, CAmount& nRet)
+{
+ return ParseMoney(str.c_str(), nRet);
+}
+
+bool ParseMoney(const char* pszIn, CAmount& nRet)
+{
+ string strWhole;
+ int64_t nUnits = 0;
+ const char* p = pszIn;
+ while (isspace(*p))
+ p++;
+ for (; *p; p++)
+ {
+ if (*p == '.')
+ {
+ p++;
+ int64_t 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_t nWhole = atoi64(strWhole);
+ CAmount nValue = nWhole*COIN + nUnits;
+
+ nRet = nValue;
+ return true;
+}
diff --git a/src/utilmoneystr.h b/src/utilmoneystr.h
new file mode 100644
index 0000000000..cd9b04810d
--- /dev/null
+++ b/src/utilmoneystr.h
@@ -0,0 +1,21 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+/**
+ * Money parsing/formatting utilities.
+ */
+#ifndef BITCOIN_UTILMONEYSTR_H
+#define BITCOIN_UTILMONEYSTR_H
+
+#include <stdint.h>
+#include <string>
+
+#include "amount.h"
+
+std::string FormatMoney(const CAmount& n, bool fPlus=false);
+bool ParseMoney(const std::string& str, CAmount& nRet);
+bool ParseMoney(const char* pszIn, CAmount& nRet);
+
+#endif // BITCOIN_UTILMONEYSTR_H
diff --git a/src/utilstrencodings.cpp b/src/utilstrencodings.cpp
new file mode 100644
index 0000000000..c15bddc6fb
--- /dev/null
+++ b/src/utilstrencodings.cpp
@@ -0,0 +1,499 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "utilstrencodings.h"
+
+#include "tinyformat.h"
+
+#include <cstdlib>
+#include <cstring>
+#include <errno.h>
+#include <limits>
+
+using namespace std;
+
+string SanitizeString(const string& str)
+{
+ /**
+ * safeChars chosen to allow simple messages/URLs/email addresses, but avoid anything
+ * even possibly remotely dangerous like & or >
+ */
+ static string safeChars("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890 .,;_/:?@()");
+ string strResult;
+ for (std::string::size_type i = 0; i < str.size(); i++)
+ {
+ if (safeChars.find(str[i]) != std::string::npos)
+ strResult.push_back(str[i]);
+ }
+ return strResult;
+}
+
+const signed char p_util_hexdigit[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, };
+
+signed char HexDigit(char c)
+{
+ return p_util_hexdigit[(unsigned char)c];
+}
+
+bool IsHex(const string& str)
+{
+ for(std::string::const_iterator it(str.begin()); it != str.end(); ++it)
+ {
+ if (HexDigit(*it) < 0)
+ return false;
+ }
+ return (str.size() > 0) && (str.size()%2 == 0);
+}
+
+vector<unsigned char> ParseHex(const char* psz)
+{
+ // convert hex dump to vector
+ vector<unsigned char> vch;
+ while (true)
+ {
+ while (isspace(*psz))
+ psz++;
+ signed char c = HexDigit(*psz++);
+ if (c == (signed char)-1)
+ break;
+ unsigned char n = (c << 4);
+ c = HexDigit(*psz++);
+ if (c == (signed char)-1)
+ break;
+ n |= c;
+ vch.push_back(n);
+ }
+ return vch;
+}
+
+vector<unsigned char> ParseHex(const string& str)
+{
+ return ParseHex(str.c_str());
+}
+
+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<pchEnd)
+ {
+ int enc = *(pch++);
+ switch (mode)
+ {
+ case 0: // we have no bits
+ strRet += pbase64[enc >> 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<unsigned char> 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<unsigned char> 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<unsigned char> vchRet = DecodeBase64(str.c_str());
+ return (vchRet.size() == 0) ? string() : 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<pchEnd)
+ {
+ int enc = *(pch++);
+ switch (mode)
+ {
+ case 0: // we have no bits
+ strRet += pbase32[enc >> 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<nPadding[mode]; n++)
+ strRet += '=';
+ }
+
+ return strRet;
+}
+
+string EncodeBase32(const string& str)
+{
+ return EncodeBase32((const unsigned char*)str.c_str(), str.size());
+}
+
+vector<unsigned char> 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<unsigned char> 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<unsigned char> vchRet = DecodeBase32(str.c_str());
+ return (vchRet.size() == 0) ? string() : string((const char*)&vchRet[0], vchRet.size());
+}
+
+bool ParseInt32(const std::string& str, int32_t *out)
+{
+ char *endp = NULL;
+ errno = 0; // strtol will not set errno if valid
+ long int n = strtol(str.c_str(), &endp, 10);
+ if(out) *out = (int)n;
+ // Note that strtol returns a *long int*, so even if strtol doesn't report a over/underflow
+ // we still have to check that the returned value is within the range of an *int32_t*. On 64-bit
+ // platforms the size of these types may be different.
+ return endp && *endp == 0 && !errno &&
+ n >= std::numeric_limits<int32_t>::min() &&
+ n <= std::numeric_limits<int32_t>::max();
+}
+
+std::string FormatParagraph(const std::string in, size_t width, size_t indent)
+{
+ std::stringstream out;
+ size_t col = 0;
+ size_t ptr = 0;
+ while(ptr < in.size())
+ {
+ // Find beginning of next word
+ ptr = in.find_first_not_of(' ', ptr);
+ if (ptr == std::string::npos)
+ break;
+ // Find end of next word
+ size_t endword = in.find_first_of(' ', ptr);
+ if (endword == std::string::npos)
+ endword = in.size();
+ // Add newline and indentation if this wraps over the allowed width
+ if (col > 0)
+ {
+ if ((col + endword - ptr) > width)
+ {
+ out << '\n';
+ for(size_t i=0; i<indent; ++i)
+ out << ' ';
+ col = 0;
+ } else
+ out << ' ';
+ }
+ // Append word
+ out << in.substr(ptr, endword - ptr);
+ col += endword - ptr + 1;
+ ptr = endword;
+ }
+ return out.str();
+}
+
+std::string i64tostr(int64_t n)
+{
+ return strprintf("%d", n);
+}
+
+std::string itostr(int n)
+{
+ return strprintf("%d", n);
+}
+
+int64_t atoi64(const char* psz)
+{
+#ifdef _MSC_VER
+ return _atoi64(psz);
+#else
+ return strtoll(psz, NULL, 10);
+#endif
+}
+
+int64_t atoi64(const std::string& str)
+{
+#ifdef _MSC_VER
+ return _atoi64(str.c_str());
+#else
+ return strtoll(str.c_str(), NULL, 10);
+#endif
+}
+
+int atoi(const std::string& str)
+{
+ return atoi(str.c_str());
+}
diff --git a/src/utilstrencodings.h b/src/utilstrencodings.h
new file mode 100644
index 0000000000..b0edd8b542
--- /dev/null
+++ b/src/utilstrencodings.h
@@ -0,0 +1,98 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+/**
+ * Utilities for converting data from/to strings.
+ */
+#ifndef BITCOIN_UTILSTRENCODINGS_H
+#define BITCOIN_UTILSTRENCODINGS_H
+
+#include <stdint.h>
+#include <string>
+#include <vector>
+
+#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]))
+
+/** This is needed because the foreach macro can't get over the comma in pair<t1, t2> */
+#define PAIRTYPE(t1, t2) std::pair<t1, t2>
+
+std::string SanitizeString(const std::string& str);
+std::vector<unsigned char> ParseHex(const char* psz);
+std::vector<unsigned char> ParseHex(const std::string& str);
+signed char HexDigit(char c);
+bool IsHex(const std::string& str);
+std::vector<unsigned char> 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<unsigned char> 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);
+
+std::string i64tostr(int64_t n);
+std::string itostr(int n);
+int64_t atoi64(const char* psz);
+int64_t atoi64(const std::string& str);
+int atoi(const std::string& str);
+
+/**
+ * Convert string to signed 32-bit integer with strict parse error feedback.
+ * @returns true if the entire string could be parsed as valid integer,
+ * false if not the entire string could be parsed or when overflow or underflow occurred.
+ */
+bool ParseInt32(const std::string& str, int32_t *out);
+
+template<typename T>
+std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
+{
+ std::string rv;
+ static const 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 rv;
+}
+
+template<typename T>
+inline std::string HexStr(const T& vch, bool fSpaces=false)
+{
+ return HexStr(vch.begin(), vch.end(), fSpaces);
+}
+
+/**
+ * Format a paragraph of text to a fixed width, adding spaces for
+ * indentation to any added line.
+ */
+std::string FormatParagraph(const std::string in, size_t width=79, size_t indent=0);
+
+/**
+ * Timing-attack-resistant comparison.
+ * Takes time proportional to length
+ * of first argument.
+ */
+template <typename T>
+bool TimingResistantEqual(const T& a, const T& b)
+{
+ if (b.size() == 0) return a.size() == 0;
+ size_t accumulator = a.size() ^ b.size();
+ for (size_t i = 0; i < a.size(); i++)
+ accumulator |= a[i] ^ b[i%b.size()];
+ return accumulator == 0;
+}
+
+#endif // BITCOIN_UTILSTRENCODINGS_H
diff --git a/src/utiltime.cpp b/src/utiltime.cpp
new file mode 100644
index 0000000000..d316288999
--- /dev/null
+++ b/src/utiltime.cpp
@@ -0,0 +1,69 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#if defined(HAVE_CONFIG_H)
+#include "config/bitcoin-config.h"
+#endif
+
+#include "utiltime.h"
+
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include <boost/thread.hpp>
+
+using namespace std;
+
+static int64_t nMockTime = 0; //! For unit testing
+
+int64_t GetTime()
+{
+ if (nMockTime) return nMockTime;
+
+ return time(NULL);
+}
+
+void SetMockTime(int64_t nMockTimeIn)
+{
+ nMockTime = nMockTimeIn;
+}
+
+int64_t GetTimeMillis()
+{
+ return (boost::posix_time::microsec_clock::universal_time() -
+ boost::posix_time::ptime(boost::gregorian::date(1970,1,1))).total_milliseconds();
+}
+
+int64_t GetTimeMicros()
+{
+ return (boost::posix_time::microsec_clock::universal_time() -
+ boost::posix_time::ptime(boost::gregorian::date(1970,1,1))).total_microseconds();
+}
+
+void MilliSleep(int64_t n)
+{
+
+/**
+ * Boost's sleep_for was uninterruptable when backed by nanosleep from 1.50
+ * until fixed in 1.52. Use the deprecated sleep method for the broken case.
+ * See: https://svn.boost.org/trac/boost/ticket/7238
+ */
+#if defined(HAVE_WORKING_BOOST_SLEEP_FOR)
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(n));
+#elif defined(HAVE_WORKING_BOOST_SLEEP)
+ boost::this_thread::sleep(boost::posix_time::milliseconds(n));
+#else
+//should never get here
+#error missing boost sleep implementation
+#endif
+}
+
+std::string DateTimeStrFormat(const char* pszFormat, int64_t nTime)
+{
+ // std::locale takes ownership of the pointer
+ std::locale loc(std::locale::classic(), new boost::posix_time::time_facet(pszFormat));
+ std::stringstream ss;
+ ss.imbue(loc);
+ ss << boost::posix_time::from_time_t(nTime);
+ return ss.str();
+}
diff --git a/src/utiltime.h b/src/utiltime.h
new file mode 100644
index 0000000000..900992f871
--- /dev/null
+++ b/src/utiltime.h
@@ -0,0 +1,20 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_UTILTIME_H
+#define BITCOIN_UTILTIME_H
+
+#include <stdint.h>
+#include <string>
+
+int64_t GetTime();
+int64_t GetTimeMillis();
+int64_t GetTimeMicros();
+void SetMockTime(int64_t nMockTimeIn);
+void MilliSleep(int64_t n);
+
+std::string DateTimeStrFormat(const char* pszFormat, int64_t nTime);
+
+#endif // BITCOIN_UTILTIME_H
diff --git a/src/validationinterface.cpp b/src/validationinterface.cpp
new file mode 100644
index 0000000000..aa9aefb0de
--- /dev/null
+++ b/src/validationinterface.cpp
@@ -0,0 +1,47 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "validationinterface.h"
+
+static CMainSignals g_signals;
+
+CMainSignals& GetMainSignals()
+{
+ return g_signals;
+}
+
+void RegisterValidationInterface(CValidationInterface* pwalletIn) {
+ g_signals.SyncTransaction.connect(boost::bind(&CValidationInterface::SyncTransaction, pwalletIn, _1, _2));
+ g_signals.EraseTransaction.connect(boost::bind(&CValidationInterface::EraseFromWallet, pwalletIn, _1));
+ g_signals.UpdatedTransaction.connect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1));
+ g_signals.SetBestChain.connect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1));
+ g_signals.Inventory.connect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1));
+ g_signals.Broadcast.connect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, _1));
+ g_signals.BlockChecked.connect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2));
+}
+
+void UnregisterValidationInterface(CValidationInterface* pwalletIn) {
+ g_signals.BlockChecked.disconnect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2));
+ g_signals.Broadcast.disconnect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, _1));
+ g_signals.Inventory.disconnect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1));
+ g_signals.SetBestChain.disconnect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1));
+ g_signals.UpdatedTransaction.disconnect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1));
+ g_signals.EraseTransaction.disconnect(boost::bind(&CValidationInterface::EraseFromWallet, pwalletIn, _1));
+ g_signals.SyncTransaction.disconnect(boost::bind(&CValidationInterface::SyncTransaction, pwalletIn, _1, _2));
+}
+
+void UnregisterAllValidationInterfaces() {
+ g_signals.BlockChecked.disconnect_all_slots();
+ g_signals.Broadcast.disconnect_all_slots();
+ g_signals.Inventory.disconnect_all_slots();
+ g_signals.SetBestChain.disconnect_all_slots();
+ g_signals.UpdatedTransaction.disconnect_all_slots();
+ g_signals.EraseTransaction.disconnect_all_slots();
+ g_signals.SyncTransaction.disconnect_all_slots();
+}
+
+void SyncWithWallets(const CTransaction &tx, const CBlock *pblock) {
+ g_signals.SyncTransaction(tx, pblock);
+}
diff --git a/src/validationinterface.h b/src/validationinterface.h
new file mode 100644
index 0000000000..2a4c7ecceb
--- /dev/null
+++ b/src/validationinterface.h
@@ -0,0 +1,62 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_VALIDATIONINTERFACE_H
+#define BITCOIN_VALIDATIONINTERFACE_H
+
+#include <boost/signals2/signal.hpp>
+
+class CBlock;
+struct CBlockLocator;
+class CTransaction;
+class CValidationInterface;
+class CValidationState;
+class uint256;
+
+// These functions dispatch to one or all registered wallets
+
+/** Register a wallet to receive updates from core */
+void RegisterValidationInterface(CValidationInterface* pwalletIn);
+/** Unregister a wallet from core */
+void UnregisterValidationInterface(CValidationInterface* pwalletIn);
+/** Unregister all wallets from core */
+void UnregisterAllValidationInterfaces();
+/** Push an updated transaction to all registered wallets */
+void SyncWithWallets(const CTransaction& tx, const CBlock* pblock = NULL);
+
+class CValidationInterface {
+protected:
+ virtual void SyncTransaction(const CTransaction &tx, const CBlock *pblock) {}
+ virtual void EraseFromWallet(const uint256 &hash) {}
+ virtual void SetBestChain(const CBlockLocator &locator) {}
+ virtual void UpdatedTransaction(const uint256 &hash) {}
+ virtual void Inventory(const uint256 &hash) {}
+ virtual void ResendWalletTransactions(int64_t nBestBlockTime) {}
+ virtual void BlockChecked(const CBlock&, const CValidationState&) {}
+ friend void ::RegisterValidationInterface(CValidationInterface*);
+ friend void ::UnregisterValidationInterface(CValidationInterface*);
+ friend void ::UnregisterAllValidationInterfaces();
+};
+
+struct CMainSignals {
+ /** Notifies listeners of updated transaction data (transaction, and optionally the block it is found in. */
+ boost::signals2::signal<void (const CTransaction &, const CBlock *)> SyncTransaction;
+ /** Notifies listeners of an erased transaction (currently disabled, requires transaction replacement). */
+ boost::signals2::signal<void (const uint256 &)> EraseTransaction;
+ /** Notifies listeners of an updated transaction without new data (for now: a coinbase potentially becoming visible). */
+ boost::signals2::signal<void (const uint256 &)> UpdatedTransaction;
+ /** Notifies listeners of a new active block chain. */
+ boost::signals2::signal<void (const CBlockLocator &)> SetBestChain;
+ /** Notifies listeners about an inventory item being seen on the network. */
+ boost::signals2::signal<void (const uint256 &)> Inventory;
+ /** Tells listeners to broadcast their data. */
+ boost::signals2::signal<void (int64_t nBestBlockTime)> Broadcast;
+ /** Notifies listeners of a block validation result */
+ boost::signals2::signal<void (const CBlock&, const CValidationState&)> BlockChecked;
+};
+
+CMainSignals& GetMainSignals();
+
+#endif // BITCOIN_VALIDATIONINTERFACE_H
diff --git a/src/version.h b/src/version.h
new file mode 100644
index 0000000000..38b3d2e734
--- /dev/null
+++ b/src/version.h
@@ -0,0 +1,37 @@
+// Copyright (c) 2012-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_VERSION_H
+#define BITCOIN_VERSION_H
+
+/**
+ * network protocol versioning
+ */
+
+static const int PROTOCOL_VERSION = 70002;
+
+//! initial proto version, to be increased after version/verack negotiation
+static const int INIT_PROTO_VERSION = 209;
+
+//! In this version, 'getheaders' was introduced.
+static const int GETHEADERS_VERSION = 31800;
+
+//! disconnect from peers older than this proto version
+static const int MIN_PEER_PROTO_VERSION = GETHEADERS_VERSION;
+
+//! 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;
+
+//! "mempool" command, enhanced "getdata" behavior starts with this version
+static const int MEMPOOL_GD_VERSION = 60002;
+
+#endif // BITCOIN_VERSION_H
diff --git a/src/wallet/crypter.cpp b/src/wallet/crypter.cpp
new file mode 100644
index 0000000000..0b0fb562e0
--- /dev/null
+++ b/src/wallet/crypter.cpp
@@ -0,0 +1,292 @@
+// Copyright (c) 2009-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "crypter.h"
+
+#include "script/script.h"
+#include "script/standard.h"
+#include "util.h"
+
+#include <string>
+#include <vector>
+#include <boost/foreach.hpp>
+#include <openssl/aes.h>
+#include <openssl/evp.h>
+
+bool CCrypter::SetKeyFromPassphrase(const SecureString& strKeyData, const std::vector<unsigned char>& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod)
+{
+ if (nRounds < 1 || chSalt.size() != WALLET_CRYPTO_SALT_SIZE)
+ return false;
+
+ 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)
+ {
+ memory_cleanse(chKey, sizeof(chKey));
+ memory_cleanse(chIV, sizeof(chIV));
+ return false;
+ }
+
+ fKeySet = true;
+ return true;
+}
+
+bool CCrypter::SetKey(const CKeyingMaterial& chNewKey, const std::vector<unsigned char>& chNewIV)
+{
+ if (chNewKey.size() != WALLET_CRYPTO_KEY_SIZE || chNewIV.size() != WALLET_CRYPTO_KEY_SIZE)
+ return false;
+
+ 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<unsigned char> &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<unsigned char> (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) != 0;
+ if (fOk) fOk = EVP_EncryptUpdate(&ctx, &vchCiphertext[0], &nCLen, &vchPlaintext[0], nLen) != 0;
+ if (fOk) fOk = EVP_EncryptFinal_ex(&ctx, (&vchCiphertext[0]) + nCLen, &nFLen) != 0;
+ EVP_CIPHER_CTX_cleanup(&ctx);
+
+ if (!fOk) return false;
+
+ vchCiphertext.resize(nCLen + nFLen);
+ return true;
+}
+
+bool CCrypter::Decrypt(const std::vector<unsigned char>& 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) != 0;
+ if (fOk) fOk = EVP_DecryptUpdate(&ctx, &vchPlaintext[0], &nPLen, &vchCiphertext[0], nLen) != 0;
+ if (fOk) fOk = EVP_DecryptFinal_ex(&ctx, (&vchPlaintext[0]) + nPLen, &nFLen) != 0;
+ EVP_CIPHER_CTX_cleanup(&ctx);
+
+ if (!fOk) return false;
+
+ vchPlaintext.resize(nPLen + nFLen);
+ return true;
+}
+
+
+static bool EncryptSecret(const CKeyingMaterial& vMasterKey, const CKeyingMaterial &vchPlaintext, const uint256& nIV, std::vector<unsigned char> &vchCiphertext)
+{
+ CCrypter cKeyCrypter;
+ std::vector<unsigned char> chIV(WALLET_CRYPTO_KEY_SIZE);
+ memcpy(&chIV[0], &nIV, WALLET_CRYPTO_KEY_SIZE);
+ if(!cKeyCrypter.SetKey(vMasterKey, chIV))
+ return false;
+ return cKeyCrypter.Encrypt(*((const CKeyingMaterial*)&vchPlaintext), vchCiphertext);
+}
+
+static bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector<unsigned char>& vchCiphertext, const uint256& nIV, CKeyingMaterial& vchPlaintext)
+{
+ CCrypter cKeyCrypter;
+ std::vector<unsigned char> 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));
+}
+
+static bool DecryptKey(const CKeyingMaterial& vMasterKey, const std::vector<unsigned char>& vchCryptedSecret, const CPubKey& vchPubKey, CKey& key)
+{
+ CKeyingMaterial vchSecret;
+ if(!DecryptSecret(vMasterKey, vchCryptedSecret, vchPubKey.GetHash(), vchSecret))
+ return false;
+
+ if (vchSecret.size() != 32)
+ return false;
+
+ key.Set(vchSecret.begin(), vchSecret.end(), vchPubKey.IsCompressed());
+ return key.VerifyPubKey(vchPubKey);
+}
+
+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;
+
+ bool keyPass = false;
+ bool keyFail = false;
+ CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin();
+ for (; mi != mapCryptedKeys.end(); ++mi)
+ {
+ const CPubKey &vchPubKey = (*mi).second.first;
+ const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
+ CKey key;
+ if (!DecryptKey(vMasterKeyIn, vchCryptedSecret, vchPubKey, key))
+ {
+ keyFail = true;
+ break;
+ }
+ keyPass = true;
+ if (fDecryptionThoroughlyChecked)
+ break;
+ }
+ if (keyPass && keyFail)
+ {
+ LogPrintf("The wallet is probably corrupted: Some keys decrypt but not all.\n");
+ assert(false);
+ }
+ if (keyFail || !keyPass)
+ return false;
+ vMasterKey = vMasterKeyIn;
+ fDecryptionThoroughlyChecked = true;
+ }
+ NotifyStatusChanged(this);
+ return true;
+}
+
+bool CCryptoKeyStore::AddKeyPubKey(const CKey& key, const CPubKey &pubkey)
+{
+ {
+ LOCK(cs_KeyStore);
+ if (!IsCrypted())
+ return CBasicKeyStore::AddKeyPubKey(key, pubkey);
+
+ if (IsLocked())
+ return false;
+
+ std::vector<unsigned char> vchCryptedSecret;
+ CKeyingMaterial vchSecret(key.begin(), key.end());
+ if (!EncryptSecret(vMasterKey, vchSecret, pubkey.GetHash(), vchCryptedSecret))
+ return false;
+
+ if (!AddCryptedKey(pubkey, vchCryptedSecret))
+ return false;
+ }
+ return true;
+}
+
+
+bool CCryptoKeyStore::AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &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<unsigned char> &vchCryptedSecret = (*mi).second.second;
+ return DecryptKey(vMasterKey, vchCryptedSecret, vchPubKey, keyOut);
+ }
+ }
+ 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)
+ {
+ const CKey &key = mKey.second;
+ CPubKey vchPubKey = key.GetPubKey();
+ CKeyingMaterial vchSecret(key.begin(), key.end());
+ std::vector<unsigned char> vchCryptedSecret;
+ if (!EncryptSecret(vMasterKeyIn, vchSecret, vchPubKey.GetHash(), vchCryptedSecret))
+ return false;
+ if (!AddCryptedKey(vchPubKey, vchCryptedSecret))
+ return false;
+ }
+ mapKeys.clear();
+ }
+ return true;
+}
diff --git a/src/wallet/crypter.h b/src/wallet/crypter.h
new file mode 100644
index 0000000000..70aeb76723
--- /dev/null
+++ b/src/wallet/crypter.h
@@ -0,0 +1,196 @@
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_WALLET_CRYPTER_H
+#define BITCOIN_WALLET_CRYPTER_H
+
+#include "keystore.h"
+#include "serialize.h"
+#include "support/allocators/secure.h"
+
+class uint256;
+
+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<unsigned char> vchCryptedKey;
+ std::vector<unsigned char> 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<unsigned char> vchOtherDerivationParameters;
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ 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<unsigned char>(0);
+ }
+};
+
+typedef std::vector<unsigned char, secure_allocator<unsigned char> > 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<unsigned char>& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod);
+ bool Encrypt(const CKeyingMaterial& vchPlaintext, std::vector<unsigned char> &vchCiphertext);
+ bool Decrypt(const std::vector<unsigned char>& vchCiphertext, CKeyingMaterial& vchPlaintext);
+ bool SetKey(const CKeyingMaterial& chNewKey, const std::vector<unsigned char>& chNewIV);
+
+ void CleanKey()
+ {
+ memory_cleanse(chKey, sizeof(chKey));
+ memory_cleanse(chIV, sizeof(chIV));
+ fKeySet = false;
+ }
+
+ CCrypter()
+ {
+ fKeySet = false;
+
+ // Try to keep the key data 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.
+ LockedPageManager::Instance().LockRange(&chKey[0], sizeof chKey);
+ LockedPageManager::Instance().LockRange(&chIV[0], sizeof chIV);
+ }
+
+ ~CCrypter()
+ {
+ CleanKey();
+
+ LockedPageManager::Instance().UnlockRange(&chKey[0], sizeof chKey);
+ LockedPageManager::Instance().UnlockRange(&chIV[0], sizeof chIV);
+ }
+};
+
+/** 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;
+
+ //! keeps track of whether Unlock has run a thorough check before
+ bool fDecryptionThoroughlyChecked;
+
+protected:
+ bool SetCrypted();
+
+ //! will encrypt previously unencrypted keys
+ bool EncryptKeys(CKeyingMaterial& vMasterKeyIn);
+
+ bool Unlock(const CKeyingMaterial& vMasterKeyIn);
+
+public:
+ CCryptoKeyStore() : fUseCrypto(false), fDecryptionThoroughlyChecked(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<unsigned char> &vchCryptedSecret);
+ bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey);
+ 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<CKeyID> &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<void (CCryptoKeyStore* wallet)> NotifyStatusChanged;
+};
+
+#endif // BITCOIN_WALLET_CRYPTER_H
diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp
new file mode 100644
index 0000000000..e5bc653c33
--- /dev/null
+++ b/src/wallet/db.cpp
@@ -0,0 +1,462 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "db.h"
+
+#include "addrman.h"
+#include "hash.h"
+#include "protocol.h"
+#include "util.h"
+#include "utilstrencodings.h"
+
+#include <stdint.h>
+
+#ifndef WIN32
+#include <sys/stat.h>
+#endif
+
+#include <boost/filesystem.hpp>
+#include <boost/thread.hpp>
+#include <boost/version.hpp>
+
+using namespace std;
+
+
+unsigned int nWalletDBUpdated;
+
+
+//
+// CDB
+//
+
+CDBEnv bitdb;
+
+void CDBEnv::EnvShutdown()
+{
+ if (!fDbEnvInit)
+ return;
+
+ fDbEnvInit = false;
+ int ret = dbenv->close(0);
+ if (ret != 0)
+ LogPrintf("CDBEnv::EnvShutdown: Error %d shutting down database environment: %s\n", ret, DbEnv::strerror(ret));
+ if (!fMockDb)
+ DbEnv(0).remove(strPath.c_str(), 0);
+}
+
+void CDBEnv::Reset()
+{
+ delete dbenv;
+ dbenv = new DbEnv(DB_CXX_NO_EXCEPTIONS);
+ fDbEnvInit = false;
+ fMockDb = false;
+}
+
+CDBEnv::CDBEnv() : dbenv(NULL)
+{
+ Reset();
+}
+
+CDBEnv::~CDBEnv()
+{
+ EnvShutdown();
+ delete dbenv;
+ dbenv = NULL;
+}
+
+void CDBEnv::Close()
+{
+ EnvShutdown();
+}
+
+bool CDBEnv::Open(const boost::filesystem::path& pathIn)
+{
+ if (fDbEnvInit)
+ return true;
+
+ boost::this_thread::interruption_point();
+
+ strPath = pathIn.string();
+ boost::filesystem::path pathLogDir = pathIn / "database";
+ TryCreateDirectory(pathLogDir);
+ boost::filesystem::path pathErrorFile = pathIn / "db.log";
+ LogPrintf("CDBEnv::Open: LogDir=%s ErrorFile=%s\n", pathLogDir.string(), pathErrorFile.string());
+
+ unsigned int nEnvFlags = 0;
+ if (GetBoolArg("-privdb", true))
+ nEnvFlags |= DB_PRIVATE;
+
+ dbenv->set_lg_dir(pathLogDir.string().c_str());
+ dbenv->set_cachesize(0, 0x100000, 1); // 1 MiB should be enough for just the wallet
+ dbenv->set_lg_bsize(0x10000);
+ dbenv->set_lg_max(1048576);
+ dbenv->set_lk_max_locks(40000);
+ dbenv->set_lk_max_objects(40000);
+ 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(strPath.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("CDBEnv::Open: Error %d opening database environment: %s\n", ret, DbEnv::strerror(ret));
+
+ fDbEnvInit = true;
+ fMockDb = false;
+ return true;
+}
+
+void CDBEnv::MakeMock()
+{
+ if (fDbEnvInit)
+ throw runtime_error("CDBEnv::MakeMock: Already initialized");
+
+ boost::this_thread::interruption_point();
+
+ LogPrint("db", "CDBEnv::MakeMock\n");
+
+ dbenv->set_cachesize(1, 0, 1);
+ dbenv->set_lg_bsize(10485760 * 4);
+ dbenv->set_lg_max(10485760);
+ dbenv->set_lk_max_locks(10000);
+ dbenv->set_lk_max_objects(10000);
+ dbenv->set_flags(DB_AUTO_COMMIT, 1);
+ dbenv->log_set_config(DB_LOG_IN_MEMORY, 1);
+ int ret = dbenv->open(NULL,
+ DB_CREATE |
+ DB_INIT_LOCK |
+ DB_INIT_LOG |
+ DB_INIT_MPOOL |
+ DB_INIT_TXN |
+ DB_THREAD |
+ DB_PRIVATE,
+ S_IRUSR | S_IWUSR);
+ if (ret > 0)
+ throw runtime_error(strprintf("CDBEnv::MakeMock: Error %d opening database environment.", ret));
+
+ fDbEnvInit = true;
+ fMockDb = true;
+}
+
+CDBEnv::VerifyResult CDBEnv::Verify(const std::string& strFile, bool (*recoverFunc)(CDBEnv& dbenv, const std::string& strFile))
+{
+ LOCK(cs_db);
+ assert(mapFileUseCount.count(strFile) == 0);
+
+ Db db(dbenv, 0);
+ int result = db.verify(strFile.c_str(), NULL, NULL, 0);
+ if (result == 0)
+ return VERIFY_OK;
+ else if (recoverFunc == NULL)
+ return RECOVER_FAIL;
+
+ // Try to recover:
+ bool fRecovered = (*recoverFunc)(*this, strFile);
+ return (fRecovered ? RECOVER_OK : RECOVER_FAIL);
+}
+
+bool CDBEnv::Salvage(const std::string& strFile, bool fAggressive, std::vector<CDBEnv::KeyValPair>& vResult)
+{
+ LOCK(cs_db);
+ assert(mapFileUseCount.count(strFile) == 0);
+
+ u_int32_t flags = DB_SALVAGE;
+ if (fAggressive)
+ flags |= DB_AGGRESSIVE;
+
+ stringstream strDump;
+
+ Db db(dbenv, 0);
+ int result = db.verify(strFile.c_str(), NULL, &strDump, flags);
+ if (result == DB_VERIFY_BAD) {
+ LogPrintf("CDBEnv::Salvage: Database salvage found errors, all data may not be recoverable.\n");
+ if (!fAggressive) {
+ LogPrintf("CDBEnv::Salvage: Rerun with aggressive mode to ignore errors and continue.\n");
+ return false;
+ }
+ }
+ if (result != 0 && result != DB_VERIFY_BAD) {
+ LogPrintf("CDBEnv::Salvage: Database salvage failed with result %d.\n", result);
+ return false;
+ }
+
+ // Format of bdb dump is ascii lines:
+ // header lines...
+ // HEADER=END
+ // hexadecimal key
+ // hexadecimal value
+ // ... repeated
+ // DATA=END
+
+ string strLine;
+ while (!strDump.eof() && strLine != "HEADER=END")
+ getline(strDump, strLine); // Skip past header
+
+ std::string keyHex, valueHex;
+ while (!strDump.eof() && keyHex != "DATA=END") {
+ getline(strDump, keyHex);
+ if (keyHex != "DATA_END") {
+ getline(strDump, valueHex);
+ vResult.push_back(make_pair(ParseHex(keyHex), ParseHex(valueHex)));
+ }
+ }
+
+ return (result == 0);
+}
+
+
+void CDBEnv::CheckpointLSN(const std::string& strFile)
+{
+ dbenv->txn_checkpoint(0, 0, 0);
+ if (fMockDb)
+ return;
+ dbenv->lsn_reset(strFile.c_str(), 0);
+}
+
+
+CDB::CDB(const std::string& strFilename, const char* pszMode, bool fFlushOnCloseIn) : pdb(NULL), activeTxn(NULL)
+{
+ int ret;
+ fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w'));
+ fFlushOnClose = fFlushOnCloseIn;
+ if (strFilename.empty())
+ return;
+
+ bool fCreate = strchr(pszMode, 'c') != NULL;
+ unsigned int nFlags = DB_THREAD;
+ if (fCreate)
+ nFlags |= DB_CREATE;
+
+ {
+ LOCK(bitdb.cs_db);
+ if (!bitdb.Open(GetDataDir()))
+ throw runtime_error("CDB: Failed to open database environment.");
+
+ strFile = strFilename;
+ ++bitdb.mapFileUseCount[strFile];
+ pdb = bitdb.mapDb[strFile];
+ if (pdb == NULL) {
+ pdb = new Db(bitdb.dbenv, 0);
+
+ bool fMockDb = bitdb.IsMock();
+ if (fMockDb) {
+ DbMpoolFile* mpf = pdb->get_mpf();
+ ret = mpf->set_flags(DB_MPOOL_NOFILE, 1);
+ if (ret != 0)
+ throw runtime_error(strprintf("CDB: Failed to configure for no temp file backing for database %s", strFile));
+ }
+
+ ret = pdb->open(NULL, // Txn pointer
+ fMockDb ? NULL : strFile.c_str(), // Filename
+ fMockDb ? strFile.c_str() : "main", // Logical db name
+ DB_BTREE, // Database type
+ nFlags, // Flags
+ 0);
+
+ if (ret != 0) {
+ delete pdb;
+ pdb = NULL;
+ --bitdb.mapFileUseCount[strFile];
+ strFile = "";
+ throw runtime_error(strprintf("CDB: Error %d, can't open database %s", ret, strFile));
+ }
+
+ if (fCreate && !Exists(string("version"))) {
+ bool fTmp = fReadOnly;
+ fReadOnly = false;
+ WriteVersion(CLIENT_VERSION);
+ fReadOnly = fTmp;
+ }
+
+ bitdb.mapDb[strFile] = pdb;
+ }
+ }
+}
+
+void CDB::Flush()
+{
+ if (activeTxn)
+ return;
+
+ // Flush database activity from memory pool to disk log
+ unsigned int nMinutes = 0;
+ if (fReadOnly)
+ nMinutes = 1;
+
+ bitdb.dbenv->txn_checkpoint(nMinutes ? GetArg("-dblogsize", 100) * 1024 : 0, nMinutes, 0);
+}
+
+void CDB::Close()
+{
+ if (!pdb)
+ return;
+ if (activeTxn)
+ activeTxn->abort();
+ activeTxn = NULL;
+ pdb = NULL;
+
+ if (fFlushOnClose)
+ Flush();
+
+ {
+ 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 CDBEnv::RemoveDb(const string& strFile)
+{
+ this->CloseDb(strFile);
+
+ LOCK(cs_db);
+ int rc = dbenv->dbremove(NULL, strFile.c_str(), NULL, DB_AUTO_COMMIT);
+ return (rc == 0);
+}
+
+bool CDB::Rewrite(const string& strFile, const char* pszSkip)
+{
+ while (true) {
+ {
+ 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;
+ LogPrintf("CDB::Rewrite: Rewriting %s...\n", strFile);
+ 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) {
+ LogPrintf("CDB::Rewrite: Can't create database file %s\n", strFileRes);
+ 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)
+ LogPrintf("CDB::Rewrite: Failed to rewrite database file %s\n", strFileRes);
+ return fSuccess;
+ }
+ }
+ MilliSleep(100);
+ }
+ return false;
+}
+
+
+void CDBEnv::Flush(bool fShutdown)
+{
+ int64_t nStart = GetTimeMillis();
+ // Flush log data to the actual data file on all files that are not in use
+ LogPrint("db", "CDBEnv::Flush: Flush(%s)%s\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " database not started");
+ if (!fDbEnvInit)
+ return;
+ {
+ LOCK(cs_db);
+ map<string, int>::iterator mi = mapFileUseCount.begin();
+ while (mi != mapFileUseCount.end()) {
+ string strFile = (*mi).first;
+ int nRefCount = (*mi).second;
+ LogPrint("db", "CDBEnv::Flush: Flushing %s (refcount = %d)...\n", strFile, nRefCount);
+ if (nRefCount == 0) {
+ // Move log data to the dat file
+ CloseDb(strFile);
+ LogPrint("db", "CDBEnv::Flush: %s checkpoint\n", strFile);
+ dbenv->txn_checkpoint(0, 0, 0);
+ LogPrint("db", "CDBEnv::Flush: %s detach\n", strFile);
+ if (!fMockDb)
+ dbenv->lsn_reset(strFile.c_str(), 0);
+ LogPrint("db", "CDBEnv::Flush: %s closed\n", strFile);
+ mapFileUseCount.erase(mi++);
+ } else
+ mi++;
+ }
+ LogPrint("db", "CDBEnv::Flush: Flush(%s)%s took %15dms\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " database not started", GetTimeMillis() - nStart);
+ if (fShutdown) {
+ char** listp;
+ if (mapFileUseCount.empty()) {
+ dbenv->log_archive(&listp, DB_ARCH_REMOVE);
+ Close();
+ if (!fMockDb)
+ boost::filesystem::remove_all(boost::filesystem::path(strPath) / "database");
+ }
+ }
+ }
+}
diff --git a/src/wallet/db.h b/src/wallet/db.h
new file mode 100644
index 0000000000..64071caa3a
--- /dev/null
+++ b/src/wallet/db.h
@@ -0,0 +1,309 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_WALLET_DB_H
+#define BITCOIN_WALLET_DB_H
+
+#include "clientversion.h"
+#include "serialize.h"
+#include "streams.h"
+#include "sync.h"
+#include "version.h"
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include <boost/filesystem/path.hpp>
+
+#include <db_cxx.h>
+
+extern unsigned int nWalletDBUpdated;
+
+class CDBEnv
+{
+private:
+ bool fDbEnvInit;
+ bool fMockDb;
+ // Don't change into boost::filesystem::path, as that can result in
+ // shutdown problems/crashes caused by a static initialized internal pointer.
+ std::string strPath;
+
+ void EnvShutdown();
+
+public:
+ mutable CCriticalSection cs_db;
+ DbEnv *dbenv;
+ std::map<std::string, int> mapFileUseCount;
+ std::map<std::string, Db*> mapDb;
+
+ CDBEnv();
+ ~CDBEnv();
+ void Reset();
+
+ void MakeMock();
+ bool IsMock() { return fMockDb; }
+
+ /**
+ * Verify that database file strFile is OK. If it is not,
+ * call the callback to try to recover.
+ * This must be called BEFORE strFile is opened.
+ * Returns true if strFile is OK.
+ */
+ enum VerifyResult { VERIFY_OK,
+ RECOVER_OK,
+ RECOVER_FAIL };
+ VerifyResult Verify(const std::string& strFile, bool (*recoverFunc)(CDBEnv& dbenv, const std::string& strFile));
+ /**
+ * Salvage data from a file that Verify says is bad.
+ * fAggressive sets the DB_AGGRESSIVE flag (see berkeley DB->verify() method documentation).
+ * Appends binary key/value pairs to vResult, returns true if successful.
+ * NOTE: reads the entire database into memory, so cannot be used
+ * for huge databases.
+ */
+ typedef std::pair<std::vector<unsigned char>, std::vector<unsigned char> > KeyValPair;
+ bool Salvage(const std::string& strFile, bool fAggressive, std::vector<KeyValPair>& vResult);
+
+ bool Open(const boost::filesystem::path& path);
+ void Close();
+ void Flush(bool fShutdown);
+ void CheckpointLSN(const std::string& strFile);
+
+ void CloseDb(const std::string& strFile);
+ bool RemoveDb(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;
+ bool fFlushOnClose;
+
+ explicit CDB(const std::string& strFilename, const char* pszMode = "r+", bool fFlushOnCloseIn=true);
+ ~CDB() { Close(); }
+
+public:
+ void Flush();
+ void Close();
+
+private:
+ CDB(const CDB&);
+ void operator=(const CDB&);
+
+protected:
+ template <typename K, typename T>
+ 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 (const std::exception&) {
+ return false;
+ }
+
+ // Clear and free memory
+ memset(datValue.get_data(), 0, datValue.get_size());
+ free(datValue.get_data());
+ return (ret == 0);
+ }
+
+ template <typename K, typename T>
+ 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 <typename K>
+ 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 <typename K>
+ 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);
+};
+
+#endif // BITCOIN_WALLET_DB_H
diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp
new file mode 100644
index 0000000000..ab951d1d7d
--- /dev/null
+++ b/src/wallet/rpcdump.cpp
@@ -0,0 +1,425 @@
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "base58.h"
+#include "rpcserver.h"
+#include "init.h"
+#include "main.h"
+#include "script/script.h"
+#include "script/standard.h"
+#include "sync.h"
+#include "util.h"
+#include "utiltime.h"
+#include "wallet.h"
+
+#include <fstream>
+#include <stdint.h>
+
+#include <boost/algorithm/string.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
+
+#include "json/json_spirit_value.h"
+
+using namespace json_spirit;
+using namespace std;
+
+void EnsureWalletIsUnlocked();
+bool EnsureWalletIsAvailable(bool avoidException);
+
+std::string static EncodeDumpTime(int64_t nTime) {
+ return DateTimeStrFormat("%Y-%m-%dT%H:%M:%SZ", nTime);
+}
+
+int64_t static DecodeDumpTime(const std::string &str) {
+ static const boost::posix_time::ptime epoch = boost::posix_time::from_time_t(0);
+ static const std::locale loc(std::locale::classic(),
+ new boost::posix_time::time_input_facet("%Y-%m-%dT%H:%M:%SZ"));
+ std::istringstream iss(str);
+ iss.imbue(loc);
+ boost::posix_time::ptime ptime(boost::date_time::not_a_date_time);
+ iss >> ptime;
+ if (ptime.is_not_a_date_time())
+ return 0;
+ return (ptime - epoch).total_seconds();
+}
+
+std::string static EncodeDumpString(const std::string &str) {
+ std::stringstream ret;
+ BOOST_FOREACH(unsigned char c, str) {
+ if (c <= 32 || c >= 128 || c == '%') {
+ ret << '%' << HexStr(&c, &c + 1);
+ } else {
+ ret << c;
+ }
+ }
+ return ret.str();
+}
+
+std::string DecodeDumpString(const std::string &str) {
+ std::stringstream ret;
+ for (unsigned int pos = 0; pos < str.length(); pos++) {
+ unsigned char c = str[pos];
+ if (c == '%' && pos+2 < str.length()) {
+ c = (((str[pos+1]>>6)*9+((str[pos+1]-'0')&15)) << 4) |
+ ((str[pos+2]>>6)*9+((str[pos+2]-'0')&15));
+ pos += 2;
+ }
+ ret << c;
+ }
+ return ret.str();
+}
+
+Value importprivkey(const Array& params, bool fHelp)
+{
+ if (!EnsureWalletIsAvailable(fHelp))
+ return Value::null;
+
+ if (fHelp || params.size() < 1 || params.size() > 3)
+ throw runtime_error(
+ "importprivkey \"bitcoinprivkey\" ( \"label\" rescan )\n"
+ "\nAdds a private key (as returned by dumpprivkey) to your wallet.\n"
+ "\nArguments:\n"
+ "1. \"bitcoinprivkey\" (string, required) The private key (see dumpprivkey)\n"
+ "2. \"label\" (string, optional, default=\"\") An optional label\n"
+ "3. rescan (boolean, optional, default=true) Rescan the wallet for transactions\n"
+ "\nNote: This call can take minutes to complete if rescan is true.\n"
+ "\nExamples:\n"
+ "\nDump a private key\n"
+ + HelpExampleCli("dumpprivkey", "\"myaddress\"") +
+ "\nImport the private key with rescan\n"
+ + HelpExampleCli("importprivkey", "\"mykey\"") +
+ "\nImport using a label and without rescan\n"
+ + HelpExampleCli("importprivkey", "\"mykey\" \"testing\" false") +
+ "\nAs a JSON-RPC call\n"
+ + HelpExampleRpc("importprivkey", "\"mykey\", \"testing\", false")
+ );
+
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
+ EnsureWalletIsUnlocked();
+
+ string strSecret = params[0].get_str();
+ string strLabel = "";
+ if (params.size() > 1)
+ strLabel = params[1].get_str();
+
+ // Whether to perform rescan after import
+ bool fRescan = true;
+ if (params.size() > 2)
+ fRescan = params[2].get_bool();
+
+ CBitcoinSecret vchSecret;
+ bool fGood = vchSecret.SetString(strSecret);
+
+ if (!fGood) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key encoding");
+
+ CKey key = vchSecret.GetKey();
+ if (!key.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Private key outside allowed range");
+
+ CPubKey pubkey = key.GetPubKey();
+ assert(key.VerifyPubKey(pubkey));
+ CKeyID vchAddress = pubkey.GetID();
+ {
+ pwalletMain->MarkDirty();
+ pwalletMain->SetAddressBook(vchAddress, strLabel, "receive");
+
+ // Don't throw error in case a key is already there
+ if (pwalletMain->HaveKey(vchAddress))
+ return Value::null;
+
+ pwalletMain->mapKeyMetadata[vchAddress].nCreateTime = 1;
+
+ if (!pwalletMain->AddKeyPubKey(key, pubkey))
+ throw JSONRPCError(RPC_WALLET_ERROR, "Error adding key to wallet");
+
+ // whenever a key is imported, we need to scan the whole chain
+ pwalletMain->nTimeFirstKey = 1; // 0 would be considered 'no value'
+
+ if (fRescan) {
+ pwalletMain->ScanForWalletTransactions(chainActive.Genesis(), true);
+ }
+ }
+
+ return Value::null;
+}
+
+Value importaddress(const Array& params, bool fHelp)
+{
+ if (!EnsureWalletIsAvailable(fHelp))
+ return Value::null;
+
+ if (fHelp || params.size() < 1 || params.size() > 3)
+ throw runtime_error(
+ "importaddress \"address\" ( \"label\" rescan )\n"
+ "\nAdds an address or script (in hex) that can be watched as if it were in your wallet but cannot be used to spend.\n"
+ "\nArguments:\n"
+ "1. \"address\" (string, required) The address\n"
+ "2. \"label\" (string, optional, default=\"\") An optional label\n"
+ "3. rescan (boolean, optional, default=true) Rescan the wallet for transactions\n"
+ "\nNote: This call can take minutes to complete if rescan is true.\n"
+ "\nExamples:\n"
+ "\nImport an address with rescan\n"
+ + HelpExampleCli("importaddress", "\"myaddress\"") +
+ "\nImport using a label without rescan\n"
+ + HelpExampleCli("importaddress", "\"myaddress\" \"testing\" false") +
+ "\nAs a JSON-RPC call\n"
+ + HelpExampleRpc("importaddress", "\"myaddress\", \"testing\", false")
+ );
+
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
+ CScript script;
+
+ CBitcoinAddress address(params[0].get_str());
+ if (address.IsValid()) {
+ script = GetScriptForDestination(address.Get());
+ } else if (IsHex(params[0].get_str())) {
+ std::vector<unsigned char> data(ParseHex(params[0].get_str()));
+ script = CScript(data.begin(), data.end());
+ } else {
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address or script");
+ }
+
+ string strLabel = "";
+ if (params.size() > 1)
+ strLabel = params[1].get_str();
+
+ // Whether to perform rescan after import
+ bool fRescan = true;
+ if (params.size() > 2)
+ fRescan = params[2].get_bool();
+
+ {
+ if (::IsMine(*pwalletMain, script) == ISMINE_SPENDABLE)
+ throw JSONRPCError(RPC_WALLET_ERROR, "The wallet already contains the private key for this address or script");
+
+ // add to address book or update label
+ if (address.IsValid())
+ pwalletMain->SetAddressBook(address.Get(), strLabel, "receive");
+
+ // Don't throw error in case an address is already there
+ if (pwalletMain->HaveWatchOnly(script))
+ return Value::null;
+
+ pwalletMain->MarkDirty();
+
+ if (!pwalletMain->AddWatchOnly(script))
+ throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
+
+ if (fRescan)
+ {
+ pwalletMain->ScanForWalletTransactions(chainActive.Genesis(), true);
+ pwalletMain->ReacceptWalletTransactions();
+ }
+ }
+
+ return Value::null;
+}
+
+Value importwallet(const Array& params, bool fHelp)
+{
+ if (!EnsureWalletIsAvailable(fHelp))
+ return Value::null;
+
+ if (fHelp || params.size() != 1)
+ throw runtime_error(
+ "importwallet \"filename\"\n"
+ "\nImports keys from a wallet dump file (see dumpwallet).\n"
+ "\nArguments:\n"
+ "1. \"filename\" (string, required) The wallet file\n"
+ "\nExamples:\n"
+ "\nDump the wallet\n"
+ + HelpExampleCli("dumpwallet", "\"test\"") +
+ "\nImport the wallet\n"
+ + HelpExampleCli("importwallet", "\"test\"") +
+ "\nImport using the json rpc call\n"
+ + HelpExampleRpc("importwallet", "\"test\"")
+ );
+
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
+ EnsureWalletIsUnlocked();
+
+ ifstream file;
+ file.open(params[0].get_str().c_str(), std::ios::in | std::ios::ate);
+ if (!file.is_open())
+ throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot open wallet dump file");
+
+ int64_t nTimeBegin = chainActive.Tip()->GetBlockTime();
+
+ bool fGood = true;
+
+ int64_t nFilesize = std::max((int64_t)1, (int64_t)file.tellg());
+ file.seekg(0, file.beg);
+
+ pwalletMain->ShowProgress(_("Importing..."), 0); // show progress dialog in GUI
+ while (file.good()) {
+ pwalletMain->ShowProgress("", std::max(1, std::min(99, (int)(((double)file.tellg() / (double)nFilesize) * 100))));
+ std::string line;
+ std::getline(file, line);
+ if (line.empty() || line[0] == '#')
+ continue;
+
+ std::vector<std::string> vstr;
+ boost::split(vstr, line, boost::is_any_of(" "));
+ if (vstr.size() < 2)
+ continue;
+ CBitcoinSecret vchSecret;
+ if (!vchSecret.SetString(vstr[0]))
+ continue;
+ CKey key = vchSecret.GetKey();
+ CPubKey pubkey = key.GetPubKey();
+ assert(key.VerifyPubKey(pubkey));
+ CKeyID keyid = pubkey.GetID();
+ if (pwalletMain->HaveKey(keyid)) {
+ LogPrintf("Skipping import of %s (key already present)\n", CBitcoinAddress(keyid).ToString());
+ continue;
+ }
+ int64_t nTime = DecodeDumpTime(vstr[1]);
+ std::string strLabel;
+ bool fLabel = true;
+ for (unsigned int nStr = 2; nStr < vstr.size(); nStr++) {
+ if (boost::algorithm::starts_with(vstr[nStr], "#"))
+ break;
+ if (vstr[nStr] == "change=1")
+ fLabel = false;
+ if (vstr[nStr] == "reserve=1")
+ fLabel = false;
+ if (boost::algorithm::starts_with(vstr[nStr], "label=")) {
+ strLabel = DecodeDumpString(vstr[nStr].substr(6));
+ fLabel = true;
+ }
+ }
+ LogPrintf("Importing %s...\n", CBitcoinAddress(keyid).ToString());
+ if (!pwalletMain->AddKeyPubKey(key, pubkey)) {
+ fGood = false;
+ continue;
+ }
+ pwalletMain->mapKeyMetadata[keyid].nCreateTime = nTime;
+ if (fLabel)
+ pwalletMain->SetAddressBook(keyid, strLabel, "receive");
+ nTimeBegin = std::min(nTimeBegin, nTime);
+ }
+ file.close();
+ pwalletMain->ShowProgress("", 100); // hide progress dialog in GUI
+
+ CBlockIndex *pindex = chainActive.Tip();
+ while (pindex && pindex->pprev && pindex->GetBlockTime() > nTimeBegin - 7200)
+ pindex = pindex->pprev;
+
+ if (!pwalletMain->nTimeFirstKey || nTimeBegin < pwalletMain->nTimeFirstKey)
+ pwalletMain->nTimeFirstKey = nTimeBegin;
+
+ LogPrintf("Rescanning last %i blocks\n", chainActive.Height() - pindex->nHeight + 1);
+ pwalletMain->ScanForWalletTransactions(pindex);
+ pwalletMain->MarkDirty();
+
+ if (!fGood)
+ throw JSONRPCError(RPC_WALLET_ERROR, "Error adding some keys to wallet");
+
+ return Value::null;
+}
+
+Value dumpprivkey(const Array& params, bool fHelp)
+{
+ if (!EnsureWalletIsAvailable(fHelp))
+ return Value::null;
+
+ if (fHelp || params.size() != 1)
+ throw runtime_error(
+ "dumpprivkey \"bitcoinaddress\"\n"
+ "\nReveals the private key corresponding to 'bitcoinaddress'.\n"
+ "Then the importprivkey can be used with this output\n"
+ "\nArguments:\n"
+ "1. \"bitcoinaddress\" (string, required) The bitcoin address for the private key\n"
+ "\nResult:\n"
+ "\"key\" (string) The private key\n"
+ "\nExamples:\n"
+ + HelpExampleCli("dumpprivkey", "\"myaddress\"")
+ + HelpExampleCli("importprivkey", "\"mykey\"")
+ + HelpExampleRpc("dumpprivkey", "\"myaddress\"")
+ );
+
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
+ EnsureWalletIsUnlocked();
+
+ string strAddress = params[0].get_str();
+ CBitcoinAddress address;
+ if (!address.SetString(strAddress))
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
+ CKeyID keyID;
+ if (!address.GetKeyID(keyID))
+ throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to a key");
+ CKey vchSecret;
+ if (!pwalletMain->GetKey(keyID, vchSecret))
+ throw JSONRPCError(RPC_WALLET_ERROR, "Private key for address " + strAddress + " is not known");
+ return CBitcoinSecret(vchSecret).ToString();
+}
+
+
+Value dumpwallet(const Array& params, bool fHelp)
+{
+ if (!EnsureWalletIsAvailable(fHelp))
+ return Value::null;
+
+ if (fHelp || params.size() != 1)
+ throw runtime_error(
+ "dumpwallet \"filename\"\n"
+ "\nDumps all wallet keys in a human-readable format.\n"
+ "\nArguments:\n"
+ "1. \"filename\" (string, required) The filename\n"
+ "\nExamples:\n"
+ + HelpExampleCli("dumpwallet", "\"test\"")
+ + HelpExampleRpc("dumpwallet", "\"test\"")
+ );
+
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
+ EnsureWalletIsUnlocked();
+
+ ofstream file;
+ file.open(params[0].get_str().c_str());
+ if (!file.is_open())
+ throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot open wallet dump file");
+
+ std::map<CKeyID, int64_t> mapKeyBirth;
+ std::set<CKeyID> setKeyPool;
+ pwalletMain->GetKeyBirthTimes(mapKeyBirth);
+ pwalletMain->GetAllReserveKeys(setKeyPool);
+
+ // sort time/key pairs
+ std::vector<std::pair<int64_t, CKeyID> > vKeyBirth;
+ for (std::map<CKeyID, int64_t>::const_iterator it = mapKeyBirth.begin(); it != mapKeyBirth.end(); it++) {
+ vKeyBirth.push_back(std::make_pair(it->second, it->first));
+ }
+ mapKeyBirth.clear();
+ std::sort(vKeyBirth.begin(), vKeyBirth.end());
+
+ // produce output
+ file << strprintf("# Wallet dump created by Bitcoin %s (%s)\n", CLIENT_BUILD, CLIENT_DATE);
+ file << strprintf("# * Created on %s\n", EncodeDumpTime(GetTime()));
+ file << strprintf("# * Best block at time of backup was %i (%s),\n", chainActive.Height(), chainActive.Tip()->GetBlockHash().ToString());
+ file << strprintf("# mined on %s\n", EncodeDumpTime(chainActive.Tip()->GetBlockTime()));
+ file << "\n";
+ for (std::vector<std::pair<int64_t, CKeyID> >::const_iterator it = vKeyBirth.begin(); it != vKeyBirth.end(); it++) {
+ const CKeyID &keyid = it->second;
+ std::string strTime = EncodeDumpTime(it->first);
+ std::string strAddr = CBitcoinAddress(keyid).ToString();
+ CKey key;
+ if (pwalletMain->GetKey(keyid, key)) {
+ if (pwalletMain->mapAddressBook.count(keyid)) {
+ file << strprintf("%s %s label=%s # addr=%s\n", CBitcoinSecret(key).ToString(), strTime, EncodeDumpString(pwalletMain->mapAddressBook[keyid].name), strAddr);
+ } else if (setKeyPool.count(keyid)) {
+ file << strprintf("%s %s reserve=1 # addr=%s\n", CBitcoinSecret(key).ToString(), strTime, strAddr);
+ } else {
+ file << strprintf("%s %s change=1 # addr=%s\n", CBitcoinSecret(key).ToString(), strTime, strAddr);
+ }
+ }
+ }
+ file << "\n";
+ file << "# End of dump\n";
+ file.close();
+ return Value::null;
+}
diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp
new file mode 100644
index 0000000000..626997160a
--- /dev/null
+++ b/src/wallet/rpcwallet.cpp
@@ -0,0 +1,2345 @@
+// Copyright (c) 2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "amount.h"
+#include "base58.h"
+#include "core_io.h"
+#include "init.h"
+#include "main.h"
+#include "net.h"
+#include "netbase.h"
+#include "rpcserver.h"
+#include "timedata.h"
+#include "util.h"
+#include "utilmoneystr.h"
+#include "wallet.h"
+#include "walletdb.h"
+
+#include <stdint.h>
+
+#include <boost/assign/list_of.hpp>
+
+#include "json/json_spirit_utils.h"
+#include "json/json_spirit_value.h"
+
+using namespace std;
+using namespace json_spirit;
+
+int64_t nWalletUnlockTime;
+static CCriticalSection cs_nWalletUnlockTime;
+
+std::string HelpRequiringPassphrase()
+{
+ return pwalletMain && pwalletMain->IsCrypted()
+ ? "\nRequires wallet passphrase to be set with walletpassphrase call."
+ : "";
+}
+
+bool EnsureWalletIsAvailable(bool avoidException)
+{
+ if (!pwalletMain)
+ {
+ if (!avoidException)
+ throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)");
+ else
+ return false;
+ }
+ return true;
+}
+
+void EnsureWalletIsUnlocked()
+{
+ if (pwalletMain->IsLocked())
+ throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "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 (wtx.IsCoinBase())
+ entry.push_back(Pair("generated", true));
+ if (confirms > 0)
+ {
+ entry.push_back(Pair("blockhash", wtx.hashBlock.GetHex()));
+ entry.push_back(Pair("blockindex", wtx.nIndex));
+ entry.push_back(Pair("blocktime", mapBlockIndex[wtx.hashBlock]->GetBlockTime()));
+ }
+ uint256 hash = wtx.GetHash();
+ entry.push_back(Pair("txid", hash.GetHex()));
+ Array conflicts;
+ BOOST_FOREACH(const uint256& conflict, wtx.GetConflicts())
+ conflicts.push_back(conflict.GetHex());
+ entry.push_back(Pair("walletconflicts", conflicts));
+ entry.push_back(Pair("time", wtx.GetTxTime()));
+ entry.push_back(Pair("timereceived", (int64_t)wtx.nTimeReceived));
+ 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(RPC_WALLET_INVALID_ACCOUNT_NAME, "Invalid account name");
+ return strAccount;
+}
+
+Value getnewaddress(const Array& params, bool fHelp)
+{
+ if (!EnsureWalletIsAvailable(fHelp))
+ return Value::null;
+
+ if (fHelp || params.size() > 1)
+ throw runtime_error(
+ "getnewaddress ( \"account\" )\n"
+ "\nReturns a new Bitcoin address for receiving payments.\n"
+ "If 'account' is specified (DEPRECATED), it is added to the address book \n"
+ "so payments received with the address will be credited to 'account'.\n"
+ "\nArguments:\n"
+ "1. \"account\" (string, optional) DEPRECATED. The account name for the address to be linked to. If not provided, the default account \"\" is used. It can also be set to the empty string \"\" to represent the default account. The account does not need to exist, it will be created if there is no account by the given name.\n"
+ "\nResult:\n"
+ "\"bitcoinaddress\" (string) The new bitcoin address\n"
+ "\nExamples:\n"
+ + HelpExampleCli("getnewaddress", "")
+ + HelpExampleRpc("getnewaddress", "")
+ );
+
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
+ // 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))
+ throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
+ CKeyID keyID = newKey.GetID();
+
+ pwalletMain->SetAddressBook(keyID, strAccount, "receive");
+
+ 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 = GetScriptForDestination(account.vchPubKey.GetID());
+ for (map<uint256, CWalletTx>::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))
+ throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
+
+ pwalletMain->SetAddressBook(account.vchPubKey.GetID(), strAccount, "receive");
+ walletdb.WriteAccount(strAccount, account);
+ }
+
+ return CBitcoinAddress(account.vchPubKey.GetID());
+}
+
+Value getaccountaddress(const Array& params, bool fHelp)
+{
+ if (!EnsureWalletIsAvailable(fHelp))
+ return Value::null;
+
+ if (fHelp || params.size() != 1)
+ throw runtime_error(
+ "getaccountaddress \"account\"\n"
+ "\nDEPRECATED. Returns the current Bitcoin address for receiving payments to this account.\n"
+ "\nArguments:\n"
+ "1. \"account\" (string, required) The account name for the address. It can also be set to the empty string \"\" to represent the default account. The account does not need to exist, it will be created and a new address created if there is no account by the given name.\n"
+ "\nResult:\n"
+ "\"bitcoinaddress\" (string) The account bitcoin address\n"
+ "\nExamples:\n"
+ + HelpExampleCli("getaccountaddress", "")
+ + HelpExampleCli("getaccountaddress", "\"\"")
+ + HelpExampleCli("getaccountaddress", "\"myaccount\"")
+ + HelpExampleRpc("getaccountaddress", "\"myaccount\"")
+ );
+
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
+ // 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 getrawchangeaddress(const Array& params, bool fHelp)
+{
+ if (!EnsureWalletIsAvailable(fHelp))
+ return Value::null;
+
+ if (fHelp || params.size() > 1)
+ throw runtime_error(
+ "getrawchangeaddress\n"
+ "\nReturns a new Bitcoin address, for receiving change.\n"
+ "This is for use with raw transactions, NOT normal use.\n"
+ "\nResult:\n"
+ "\"address\" (string) The address\n"
+ "\nExamples:\n"
+ + HelpExampleCli("getrawchangeaddress", "")
+ + HelpExampleRpc("getrawchangeaddress", "")
+ );
+
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
+ if (!pwalletMain->IsLocked())
+ pwalletMain->TopUpKeyPool();
+
+ CReserveKey reservekey(pwalletMain);
+ CPubKey vchPubKey;
+ if (!reservekey.GetReservedKey(vchPubKey))
+ throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
+
+ reservekey.KeepKey();
+
+ CKeyID keyID = vchPubKey.GetID();
+
+ return CBitcoinAddress(keyID).ToString();
+}
+
+
+Value setaccount(const Array& params, bool fHelp)
+{
+ if (!EnsureWalletIsAvailable(fHelp))
+ return Value::null;
+
+ if (fHelp || params.size() < 1 || params.size() > 2)
+ throw runtime_error(
+ "setaccount \"bitcoinaddress\" \"account\"\n"
+ "\nDEPRECATED. Sets the account associated with the given address.\n"
+ "\nArguments:\n"
+ "1. \"bitcoinaddress\" (string, required) The bitcoin address to be associated with an account.\n"
+ "2. \"account\" (string, required) The account to assign the address to.\n"
+ "\nExamples:\n"
+ + HelpExampleCli("setaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"tabby\"")
+ + HelpExampleRpc("setaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", \"tabby\"")
+ );
+
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
+ CBitcoinAddress address(params[0].get_str());
+ if (!address.IsValid())
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
+
+ string strAccount;
+ if (params.size() > 1)
+ strAccount = AccountFromValue(params[1]);
+
+ // Only add the account if the address is yours.
+ if (IsMine(*pwalletMain, address.Get()))
+ {
+ // 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()].name;
+ if (address == GetAccountAddress(strOldAccount))
+ GetAccountAddress(strOldAccount, true);
+ }
+ pwalletMain->SetAddressBook(address.Get(), strAccount, "receive");
+ }
+ else
+ throw JSONRPCError(RPC_MISC_ERROR, "setaccount can only be used with own address");
+
+ return Value::null;
+}
+
+
+Value getaccount(const Array& params, bool fHelp)
+{
+ if (!EnsureWalletIsAvailable(fHelp))
+ return Value::null;
+
+ if (fHelp || params.size() != 1)
+ throw runtime_error(
+ "getaccount \"bitcoinaddress\"\n"
+ "\nDEPRECATED. Returns the account associated with the given address.\n"
+ "\nArguments:\n"
+ "1. \"bitcoinaddress\" (string, required) The bitcoin address for account lookup.\n"
+ "\nResult:\n"
+ "\"accountname\" (string) the account address\n"
+ "\nExamples:\n"
+ + HelpExampleCli("getaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\"")
+ + HelpExampleRpc("getaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\"")
+ );
+
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
+ CBitcoinAddress address(params[0].get_str());
+ if (!address.IsValid())
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
+
+ string strAccount;
+ map<CTxDestination, CAddressBookData>::iterator mi = pwalletMain->mapAddressBook.find(address.Get());
+ if (mi != pwalletMain->mapAddressBook.end() && !(*mi).second.name.empty())
+ strAccount = (*mi).second.name;
+ return strAccount;
+}
+
+
+Value getaddressesbyaccount(const Array& params, bool fHelp)
+{
+ if (!EnsureWalletIsAvailable(fHelp))
+ return Value::null;
+
+ if (fHelp || params.size() != 1)
+ throw runtime_error(
+ "getaddressesbyaccount \"account\"\n"
+ "\nDEPRECATED. Returns the list of addresses for the given account.\n"
+ "\nArguments:\n"
+ "1. \"account\" (string, required) The account name.\n"
+ "\nResult:\n"
+ "[ (json array of string)\n"
+ " \"bitcoinaddress\" (string) a bitcoin address associated with the given account\n"
+ " ,...\n"
+ "]\n"
+ "\nExamples:\n"
+ + HelpExampleCli("getaddressesbyaccount", "\"tabby\"")
+ + HelpExampleRpc("getaddressesbyaccount", "\"tabby\"")
+ );
+
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
+ string strAccount = AccountFromValue(params[0]);
+
+ // Find all addresses that have the given account
+ Array ret;
+ BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, CAddressBookData)& item, pwalletMain->mapAddressBook)
+ {
+ const CBitcoinAddress& address = item.first;
+ const string& strName = item.second.name;
+ if (strName == strAccount)
+ ret.push_back(address.ToString());
+ }
+ return ret;
+}
+
+static void SendMoney(const CTxDestination &address, CAmount nValue, bool fSubtractFeeFromAmount, CWalletTx& wtxNew)
+{
+ CAmount curBalance = pwalletMain->GetBalance();
+
+ // Check amount
+ if (nValue <= 0)
+ throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid amount");
+
+ if (nValue > curBalance)
+ throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds");
+
+ // Parse Bitcoin address
+ CScript scriptPubKey = GetScriptForDestination(address);
+
+ // Create and send the transaction
+ CReserveKey reservekey(pwalletMain);
+ CAmount nFeeRequired;
+ std::string strError;
+ vector<CRecipient> vecSend;
+ int nChangePosRet = -1;
+ CRecipient recipient = {scriptPubKey, nValue, fSubtractFeeFromAmount};
+ vecSend.push_back(recipient);
+ if (!pwalletMain->CreateTransaction(vecSend, wtxNew, reservekey, nFeeRequired, nChangePosRet, strError)) {
+ if (!fSubtractFeeFromAmount && nValue + nFeeRequired > pwalletMain->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));
+ throw JSONRPCError(RPC_WALLET_ERROR, strError);
+ }
+ if (!pwalletMain->CommitTransaction(wtxNew, reservekey))
+ throw JSONRPCError(RPC_WALLET_ERROR, "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.");
+}
+
+Value sendtoaddress(const Array& params, bool fHelp)
+{
+ if (!EnsureWalletIsAvailable(fHelp))
+ return Value::null;
+
+ if (fHelp || params.size() < 2 || params.size() > 5)
+ throw runtime_error(
+ "sendtoaddress \"bitcoinaddress\" amount ( \"comment\" \"comment-to\" subtractfeefromamount )\n"
+ "\nSend an amount to a given address. The amount is a real and is rounded to the nearest 0.00000001\n"
+ + HelpRequiringPassphrase() +
+ "\nArguments:\n"
+ "1. \"bitcoinaddress\" (string, required) The bitcoin address to send to.\n"
+ "2. \"amount\" (numeric, required) The amount in btc to send. eg 0.1\n"
+ "3. \"comment\" (string, optional) A comment used to store what the transaction is for. \n"
+ " This is not part of the transaction, just kept in your wallet.\n"
+ "4. \"comment-to\" (string, optional) A comment to store the name of the person or organization \n"
+ " to which you're sending the transaction. This is not part of the \n"
+ " transaction, just kept in your wallet.\n"
+ "5. subtractfeefromamount (boolean, optional, default=false) The fee will be deducted from the amount being sent.\n"
+ " The recipient will receive less bitcoins than you enter in the amount field.\n"
+ "\nResult:\n"
+ "\"transactionid\" (string) The transaction id.\n"
+ "\nExamples:\n"
+ + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1")
+ + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1 \"donation\" \"seans outpost\"")
+ + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1 \"\" \"\" true")
+ + HelpExampleRpc("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", 0.1, \"donation\", \"seans outpost\"")
+ );
+
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
+ CBitcoinAddress address(params[0].get_str());
+ if (!address.IsValid())
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
+
+ // Amount
+ CAmount 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();
+
+ bool fSubtractFeeFromAmount = false;
+ if (params.size() > 4)
+ fSubtractFeeFromAmount = params[4].get_bool();
+
+ EnsureWalletIsUnlocked();
+
+ SendMoney(address.Get(), nAmount, fSubtractFeeFromAmount, wtx);
+
+ return wtx.GetHash().GetHex();
+}
+
+Value listaddressgroupings(const Array& params, bool fHelp)
+{
+ if (!EnsureWalletIsAvailable(fHelp))
+ return Value::null;
+
+ if (fHelp)
+ throw runtime_error(
+ "listaddressgroupings\n"
+ "\nLists groups of addresses which have had their common ownership\n"
+ "made public by common use as inputs or as the resulting change\n"
+ "in past transactions\n"
+ "\nResult:\n"
+ "[\n"
+ " [\n"
+ " [\n"
+ " \"bitcoinaddress\", (string) The bitcoin address\n"
+ " amount, (numeric) The amount in btc\n"
+ " \"account\" (string, optional) The account (DEPRECATED)\n"
+ " ]\n"
+ " ,...\n"
+ " ]\n"
+ " ,...\n"
+ "]\n"
+ "\nExamples:\n"
+ + HelpExampleCli("listaddressgroupings", "")
+ + HelpExampleRpc("listaddressgroupings", "")
+ );
+
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
+ Array jsonGroupings;
+ map<CTxDestination, CAmount> balances = pwalletMain->GetAddressBalances();
+ BOOST_FOREACH(set<CTxDestination> grouping, pwalletMain->GetAddressGroupings())
+ {
+ Array jsonGrouping;
+ BOOST_FOREACH(CTxDestination address, grouping)
+ {
+ Array addressInfo;
+ addressInfo.push_back(CBitcoinAddress(address).ToString());
+ addressInfo.push_back(ValueFromAmount(balances[address]));
+ {
+ if (pwalletMain->mapAddressBook.find(CBitcoinAddress(address).Get()) != pwalletMain->mapAddressBook.end())
+ addressInfo.push_back(pwalletMain->mapAddressBook.find(CBitcoinAddress(address).Get())->second.name);
+ }
+ jsonGrouping.push_back(addressInfo);
+ }
+ jsonGroupings.push_back(jsonGrouping);
+ }
+ return jsonGroupings;
+}
+
+Value signmessage(const Array& params, bool fHelp)
+{
+ if (!EnsureWalletIsAvailable(fHelp))
+ return Value::null;
+
+ if (fHelp || params.size() != 2)
+ throw runtime_error(
+ "signmessage \"bitcoinaddress\" \"message\"\n"
+ "\nSign a message with the private key of an address"
+ + HelpRequiringPassphrase() + "\n"
+ "\nArguments:\n"
+ "1. \"bitcoinaddress\" (string, required) The bitcoin address to use for the private key.\n"
+ "2. \"message\" (string, required) The message to create a signature of.\n"
+ "\nResult:\n"
+ "\"signature\" (string) The signature of the message encoded in base 64\n"
+ "\nExamples:\n"
+ "\nUnlock the wallet for 30 seconds\n"
+ + HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") +
+ "\nCreate the signature\n"
+ + HelpExampleCli("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"my message\"") +
+ "\nVerify the signature\n"
+ + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"signature\" \"my message\"") +
+ "\nAs json rpc\n"
+ + HelpExampleRpc("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", \"my message\"")
+ );
+
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
+ EnsureWalletIsUnlocked();
+
+ string strAddress = params[0].get_str();
+ string strMessage = params[1].get_str();
+
+ CBitcoinAddress addr(strAddress);
+ if (!addr.IsValid())
+ throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address");
+
+ CKeyID keyID;
+ if (!addr.GetKeyID(keyID))
+ throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key");
+
+ CKey key;
+ if (!pwalletMain->GetKey(keyID, key))
+ throw JSONRPCError(RPC_WALLET_ERROR, "Private key not available");
+
+ CHashWriter ss(SER_GETHASH, 0);
+ ss << strMessageMagic;
+ ss << strMessage;
+
+ vector<unsigned char> vchSig;
+ if (!key.SignCompact(ss.GetHash(), vchSig))
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Sign failed");
+
+ return EncodeBase64(&vchSig[0], vchSig.size());
+}
+
+Value getreceivedbyaddress(const Array& params, bool fHelp)
+{
+ if (!EnsureWalletIsAvailable(fHelp))
+ return Value::null;
+
+ if (fHelp || params.size() < 1 || params.size() > 2)
+ throw runtime_error(
+ "getreceivedbyaddress \"bitcoinaddress\" ( minconf )\n"
+ "\nReturns the total amount received by the given bitcoinaddress in transactions with at least minconf confirmations.\n"
+ "\nArguments:\n"
+ "1. \"bitcoinaddress\" (string, required) The bitcoin address for transactions.\n"
+ "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
+ "\nResult:\n"
+ "amount (numeric) The total amount in btc received at this address.\n"
+ "\nExamples:\n"
+ "\nThe amount from transactions with at least 1 confirmation\n"
+ + HelpExampleCli("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\"") +
+ "\nThe amount including unconfirmed transactions, zero confirmations\n"
+ + HelpExampleCli("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" 0") +
+ "\nThe amount with at least 6 confirmation, very safe\n"
+ + HelpExampleCli("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" 6") +
+ "\nAs a json rpc call\n"
+ + HelpExampleRpc("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", 6")
+ );
+
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
+ // Bitcoin address
+ CBitcoinAddress address = CBitcoinAddress(params[0].get_str());
+ if (!address.IsValid())
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
+ CScript scriptPubKey = GetScriptForDestination(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
+ CAmount nAmount = 0;
+ for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
+ {
+ const CWalletTx& wtx = (*it).second;
+ if (wtx.IsCoinBase() || !CheckFinalTx(wtx))
+ continue;
+
+ BOOST_FOREACH(const CTxOut& txout, wtx.vout)
+ if (txout.scriptPubKey == scriptPubKey)
+ if (wtx.GetDepthInMainChain() >= nMinDepth)
+ nAmount += txout.nValue;
+ }
+
+ return ValueFromAmount(nAmount);
+}
+
+
+Value getreceivedbyaccount(const Array& params, bool fHelp)
+{
+ if (!EnsureWalletIsAvailable(fHelp))
+ return Value::null;
+
+ if (fHelp || params.size() < 1 || params.size() > 2)
+ throw runtime_error(
+ "getreceivedbyaccount \"account\" ( minconf )\n"
+ "\nDEPRECATED. Returns the total amount received by addresses with <account> in transactions with at least [minconf] confirmations.\n"
+ "\nArguments:\n"
+ "1. \"account\" (string, required) The selected account, may be the default account using \"\".\n"
+ "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
+ "\nResult:\n"
+ "amount (numeric) The total amount in btc received for this account.\n"
+ "\nExamples:\n"
+ "\nAmount received by the default account with at least 1 confirmation\n"
+ + HelpExampleCli("getreceivedbyaccount", "\"\"") +
+ "\nAmount received at the tabby account including unconfirmed amounts with zero confirmations\n"
+ + HelpExampleCli("getreceivedbyaccount", "\"tabby\" 0") +
+ "\nThe amount with at least 6 confirmation, very safe\n"
+ + HelpExampleCli("getreceivedbyaccount", "\"tabby\" 6") +
+ "\nAs a json rpc call\n"
+ + HelpExampleRpc("getreceivedbyaccount", "\"tabby\", 6")
+ );
+
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
+ // 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<CTxDestination> setAddress = pwalletMain->GetAccountAddresses(strAccount);
+
+ // Tally
+ CAmount nAmount = 0;
+ for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
+ {
+ const CWalletTx& wtx = (*it).second;
+ if (wtx.IsCoinBase() || !CheckFinalTx(wtx))
+ 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;
+}
+
+
+CAmount GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMinDepth, const isminefilter& filter)
+{
+ CAmount nBalance = 0;
+
+ // Tally wallet transactions
+ for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
+ {
+ const CWalletTx& wtx = (*it).second;
+ if (!CheckFinalTx(wtx) || wtx.GetBlocksToMaturity() > 0 || wtx.GetDepthInMainChain() < 0)
+ continue;
+
+ CAmount nReceived, nSent, nFee;
+ wtx.GetAccountAmounts(strAccount, nReceived, nSent, nFee, filter);
+
+ if (nReceived != 0 && wtx.GetDepthInMainChain() >= nMinDepth)
+ nBalance += nReceived;
+ nBalance -= nSent + nFee;
+ }
+
+ // Tally internal accounting entries
+ nBalance += walletdb.GetAccountCreditDebit(strAccount);
+
+ return nBalance;
+}
+
+CAmount GetAccountBalance(const string& strAccount, int nMinDepth, const isminefilter& filter)
+{
+ CWalletDB walletdb(pwalletMain->strWalletFile);
+ return GetAccountBalance(walletdb, strAccount, nMinDepth, filter);
+}
+
+
+Value getbalance(const Array& params, bool fHelp)
+{
+ if (!EnsureWalletIsAvailable(fHelp))
+ return Value::null;
+
+ if (fHelp || params.size() > 3)
+ throw runtime_error(
+ "getbalance ( \"account\" minconf includeWatchonly )\n"
+ "\nIf account is not specified, returns the server's total available balance.\n"
+ "If account is specified (DEPRECATED), returns the balance in the account.\n"
+ "Note that the account \"\" is not the same as leaving the parameter out.\n"
+ "The server total may be different to the balance in the default \"\" account.\n"
+ "\nArguments:\n"
+ "1. \"account\" (string, optional) DEPRECATED. The selected account, or \"*\" for entire wallet. It may be the default account using \"\".\n"
+ "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
+ "3. includeWatchonly (bool, optional, default=false) Also include balance in watchonly addresses (see 'importaddress')\n"
+ "\nResult:\n"
+ "amount (numeric) The total amount in btc received for this account.\n"
+ "\nExamples:\n"
+ "\nThe total amount in the wallet\n"
+ + HelpExampleCli("getbalance", "") +
+ "\nThe total amount in the wallet at least 5 blocks confirmed\n"
+ + HelpExampleCli("getbalance", "\"*\" 6") +
+ "\nAs a json rpc call\n"
+ + HelpExampleRpc("getbalance", "\"*\", 6")
+ );
+
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
+ if (params.size() == 0)
+ return ValueFromAmount(pwalletMain->GetBalance());
+
+ int nMinDepth = 1;
+ if (params.size() > 1)
+ nMinDepth = params[1].get_int();
+ isminefilter filter = ISMINE_SPENDABLE;
+ if(params.size() > 2)
+ if(params[2].get_bool())
+ filter = filter | ISMINE_WATCH_ONLY;
+
+ if (params[0].get_str() == "*") {
+ // Calculate total balance a different way from GetBalance()
+ // (GetBalance() sums up all unspent TxOuts)
+ // getbalance and "getbalance * 1 true" should return the same number
+ CAmount nBalance = 0;
+ for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
+ {
+ const CWalletTx& wtx = (*it).second;
+ if (!CheckFinalTx(wtx) || wtx.GetBlocksToMaturity() > 0 || wtx.GetDepthInMainChain() < 0)
+ continue;
+
+ CAmount allFee;
+ string strSentAccount;
+ list<COutputEntry> listReceived;
+ list<COutputEntry> listSent;
+ wtx.GetAmounts(listReceived, listSent, allFee, strSentAccount, filter);
+ if (wtx.GetDepthInMainChain() >= nMinDepth)
+ {
+ BOOST_FOREACH(const COutputEntry& r, listReceived)
+ nBalance += r.amount;
+ }
+ BOOST_FOREACH(const COutputEntry& s, listSent)
+ nBalance -= s.amount;
+ nBalance -= allFee;
+ }
+ return ValueFromAmount(nBalance);
+ }
+
+ string strAccount = AccountFromValue(params[0]);
+
+ CAmount nBalance = GetAccountBalance(strAccount, nMinDepth, filter);
+
+ return ValueFromAmount(nBalance);
+}
+
+Value getunconfirmedbalance(const Array &params, bool fHelp)
+{
+ if (!EnsureWalletIsAvailable(fHelp))
+ return Value::null;
+
+ if (fHelp || params.size() > 0)
+ throw runtime_error(
+ "getunconfirmedbalance\n"
+ "Returns the server's total unconfirmed balance\n");
+
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
+ return ValueFromAmount(pwalletMain->GetUnconfirmedBalance());
+}
+
+
+Value movecmd(const Array& params, bool fHelp)
+{
+ if (!EnsureWalletIsAvailable(fHelp))
+ return Value::null;
+
+ if (fHelp || params.size() < 3 || params.size() > 5)
+ throw runtime_error(
+ "move \"fromaccount\" \"toaccount\" amount ( minconf \"comment\" )\n"
+ "\nDEPRECATED. Move a specified amount from one account in your wallet to another.\n"
+ "\nArguments:\n"
+ "1. \"fromaccount\" (string, required) The name of the account to move funds from. May be the default account using \"\".\n"
+ "2. \"toaccount\" (string, required) The name of the account to move funds to. May be the default account using \"\".\n"
+ "3. minconf (numeric, optional, default=1) Only use funds with at least this many confirmations.\n"
+ "4. \"comment\" (string, optional) An optional comment, stored in the wallet only.\n"
+ "\nResult:\n"
+ "true|false (boolean) true if successful.\n"
+ "\nExamples:\n"
+ "\nMove 0.01 btc from the default account to the account named tabby\n"
+ + HelpExampleCli("move", "\"\" \"tabby\" 0.01") +
+ "\nMove 0.01 btc timotei to akiko with a comment and funds have 6 confirmations\n"
+ + HelpExampleCli("move", "\"timotei\" \"akiko\" 0.01 6 \"happy birthday!\"") +
+ "\nAs a json rpc call\n"
+ + HelpExampleRpc("move", "\"timotei\", \"akiko\", 0.01, 6, \"happy birthday!\"")
+ );
+
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
+ string strFrom = AccountFromValue(params[0]);
+ string strTo = AccountFromValue(params[1]);
+ CAmount 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(RPC_DATABASE_ERROR, "database error");
+
+ int64_t nNow = GetAdjustedTime();
+
+ // Debit
+ CAccountingEntry debit;
+ debit.nOrderPos = pwalletMain->IncOrderPosNext(&walletdb);
+ debit.strAccount = strFrom;
+ debit.nCreditDebit = -nAmount;
+ debit.nTime = nNow;
+ debit.strOtherAccount = strTo;
+ debit.strComment = strComment;
+ walletdb.WriteAccountingEntry(debit);
+
+ // Credit
+ CAccountingEntry credit;
+ credit.nOrderPos = pwalletMain->IncOrderPosNext(&walletdb);
+ credit.strAccount = strTo;
+ credit.nCreditDebit = nAmount;
+ credit.nTime = nNow;
+ credit.strOtherAccount = strFrom;
+ credit.strComment = strComment;
+ walletdb.WriteAccountingEntry(credit);
+
+ if (!walletdb.TxnCommit())
+ throw JSONRPCError(RPC_DATABASE_ERROR, "database error");
+
+ return true;
+}
+
+
+Value sendfrom(const Array& params, bool fHelp)
+{
+ if (!EnsureWalletIsAvailable(fHelp))
+ return Value::null;
+
+ if (fHelp || params.size() < 3 || params.size() > 6)
+ throw runtime_error(
+ "sendfrom \"fromaccount\" \"tobitcoinaddress\" amount ( minconf \"comment\" \"comment-to\" )\n"
+ "\nDEPRECATED (use sendtoaddress). Sent an amount from an account to a bitcoin address.\n"
+ "The amount is a real and is rounded to the nearest 0.00000001."
+ + HelpRequiringPassphrase() + "\n"
+ "\nArguments:\n"
+ "1. \"fromaccount\" (string, required) The name of the account to send funds from. May be the default account using \"\".\n"
+ "2. \"tobitcoinaddress\" (string, required) The bitcoin address to send funds to.\n"
+ "3. amount (numeric, required) The amount in btc. (transaction fee is added on top).\n"
+ "4. minconf (numeric, optional, default=1) Only use funds with at least this many confirmations.\n"
+ "5. \"comment\" (string, optional) A comment used to store what the transaction is for. \n"
+ " This is not part of the transaction, just kept in your wallet.\n"
+ "6. \"comment-to\" (string, optional) An optional comment to store the name of the person or organization \n"
+ " to which you're sending the transaction. This is not part of the transaction, \n"
+ " it is just kept in your wallet.\n"
+ "\nResult:\n"
+ "\"transactionid\" (string) The transaction id.\n"
+ "\nExamples:\n"
+ "\nSend 0.01 btc from the default account to the address, must have at least 1 confirmation\n"
+ + HelpExampleCli("sendfrom", "\"\" \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.01") +
+ "\nSend 0.01 from the tabby account to the given address, funds must have at least 6 confirmations\n"
+ + HelpExampleCli("sendfrom", "\"tabby\" \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.01 6 \"donation\" \"seans outpost\"") +
+ "\nAs a json rpc call\n"
+ + HelpExampleRpc("sendfrom", "\"tabby\", \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", 0.01, 6, \"donation\", \"seans outpost\"")
+ );
+
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
+ string strAccount = AccountFromValue(params[0]);
+ CBitcoinAddress address(params[1].get_str());
+ if (!address.IsValid())
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
+ CAmount 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
+ CAmount nBalance = GetAccountBalance(strAccount, nMinDepth, ISMINE_SPENDABLE);
+ if (nAmount > nBalance)
+ throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds");
+
+ SendMoney(address.Get(), nAmount, false, wtx);
+
+ return wtx.GetHash().GetHex();
+}
+
+
+Value sendmany(const Array& params, bool fHelp)
+{
+ if (!EnsureWalletIsAvailable(fHelp))
+ return Value::null;
+
+ if (fHelp || params.size() < 2 || params.size() > 5)
+ throw runtime_error(
+ "sendmany \"fromaccount\" {\"address\":amount,...} ( minconf \"comment\" [\"address\",...] )\n"
+ "\nSend multiple times. Amounts are double-precision floating point numbers."
+ + HelpRequiringPassphrase() + "\n"
+ "\nArguments:\n"
+ "1. \"fromaccount\" (string, required) DEPRECATED. The account to send the funds from. Should be \"\" for the default account\n"
+ "2. \"amounts\" (string, required) A json object with addresses and amounts\n"
+ " {\n"
+ " \"address\":amount (numeric) The bitcoin address is the key, the numeric amount in btc is the value\n"
+ " ,...\n"
+ " }\n"
+ "3. minconf (numeric, optional, default=1) Only use the balance confirmed at least this many times.\n"
+ "4. \"comment\" (string, optional) A comment\n"
+ "5. subtractfeefromamount (string, optional) A json array with addresses.\n"
+ " The fee will be equally deducted from the amount of each selected address.\n"
+ " Those recipients will receive less bitcoins than you enter in their corresponding amount field.\n"
+ " If no addresses are specified here, the sender pays the fee.\n"
+ " [\n"
+ " \"address\" (string) Subtract fee from this address\n"
+ " ,...\n"
+ " ]\n"
+ "\nResult:\n"
+ "\"transactionid\" (string) The transaction id for the send. Only 1 transaction is created regardless of \n"
+ " the number of addresses.\n"
+ "\nExamples:\n"
+ "\nSend two amounts to two different addresses:\n"
+ + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\"") +
+ "\nSend two amounts to two different addresses setting the confirmation and comment:\n"
+ + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 6 \"testing\"") +
+ "\nSend two amounts to two different addresses, subtract fee from amount:\n"
+ + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 1 \"\" \"[\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\",\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\"]\"") +
+ "\nAs a json rpc call\n"
+ + HelpExampleRpc("sendmany", "\"\", \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\", 6, \"testing\"")
+ );
+
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
+ 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();
+
+ Array subtractFeeFromAmount;
+ if (params.size() > 4)
+ subtractFeeFromAmount = params[4].get_array();
+
+ set<CBitcoinAddress> setAddress;
+ vector<CRecipient> vecSend;
+
+ CAmount totalAmount = 0;
+ BOOST_FOREACH(const Pair& s, sendTo)
+ {
+ CBitcoinAddress address(s.name_);
+ if (!address.IsValid())
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+s.name_);
+
+ if (setAddress.count(address))
+ throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+s.name_);
+ setAddress.insert(address);
+
+ CScript scriptPubKey = GetScriptForDestination(address.Get());
+ CAmount nAmount = AmountFromValue(s.value_);
+ totalAmount += nAmount;
+
+ bool fSubtractFeeFromAmount = false;
+ BOOST_FOREACH(const Value& addr, subtractFeeFromAmount)
+ if (addr.get_str() == s.name_)
+ fSubtractFeeFromAmount = true;
+
+ CRecipient recipient = {scriptPubKey, nAmount, fSubtractFeeFromAmount};
+ vecSend.push_back(recipient);
+ }
+
+ EnsureWalletIsUnlocked();
+
+ // Check funds
+ CAmount nBalance = GetAccountBalance(strAccount, nMinDepth, ISMINE_SPENDABLE);
+ if (totalAmount > nBalance)
+ throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds");
+
+ // Send
+ CReserveKey keyChange(pwalletMain);
+ CAmount nFeeRequired = 0;
+ int nChangePosRet = -1;
+ string strFailReason;
+ bool fCreated = pwalletMain->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired, nChangePosRet, strFailReason);
+ if (!fCreated)
+ throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, strFailReason);
+ if (!pwalletMain->CommitTransaction(wtx, keyChange))
+ throw JSONRPCError(RPC_WALLET_ERROR, "Transaction commit failed");
+
+ return wtx.GetHash().GetHex();
+}
+
+// Defined in rpcmisc.cpp
+extern CScript _createmultisig_redeemScript(const Array& params);
+
+Value addmultisigaddress(const Array& params, bool fHelp)
+{
+ if (!EnsureWalletIsAvailable(fHelp))
+ return Value::null;
+
+ if (fHelp || params.size() < 2 || params.size() > 3)
+ {
+ string msg = "addmultisigaddress nrequired [\"key\",...] ( \"account\" )\n"
+ "\nAdd a nrequired-to-sign multisignature address to the wallet.\n"
+ "Each key is a Bitcoin address or hex-encoded public key.\n"
+ "If 'account' is specified (DEPRECATED), assign address to that account.\n"
+
+ "\nArguments:\n"
+ "1. nrequired (numeric, required) The number of required signatures out of the n keys or addresses.\n"
+ "2. \"keysobject\" (string, required) A json array of bitcoin addresses or hex-encoded public keys\n"
+ " [\n"
+ " \"address\" (string) bitcoin address or hex-encoded public key\n"
+ " ...,\n"
+ " ]\n"
+ "3. \"account\" (string, optional) DEPRECATED. An account to assign the addresses to.\n"
+
+ "\nResult:\n"
+ "\"bitcoinaddress\" (string) A bitcoin address associated with the keys.\n"
+
+ "\nExamples:\n"
+ "\nAdd a multisig address from 2 addresses\n"
+ + HelpExampleCli("addmultisigaddress", "2 \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"") +
+ "\nAs json rpc call\n"
+ + HelpExampleRpc("addmultisigaddress", "2, \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"")
+ ;
+ throw runtime_error(msg);
+ }
+
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
+ string strAccount;
+ if (params.size() > 2)
+ strAccount = AccountFromValue(params[2]);
+
+ // Construct using pay-to-script-hash:
+ CScript inner = _createmultisig_redeemScript(params);
+ CScriptID innerID(inner);
+ pwalletMain->AddCScript(inner);
+
+ pwalletMain->SetAddressBook(innerID, strAccount, "send");
+ return CBitcoinAddress(innerID).ToString();
+}
+
+
+struct tallyitem
+{
+ CAmount nAmount;
+ int nConf;
+ vector<uint256> txids;
+ bool fIsWatchonly;
+ tallyitem()
+ {
+ nAmount = 0;
+ nConf = std::numeric_limits<int>::max();
+ fIsWatchonly = false;
+ }
+};
+
+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();
+
+ isminefilter filter = ISMINE_SPENDABLE;
+ if(params.size() > 2)
+ if(params[2].get_bool())
+ filter = filter | ISMINE_WATCH_ONLY;
+
+ // Tally
+ map<CBitcoinAddress, tallyitem> mapTally;
+ for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
+ {
+ const CWalletTx& wtx = (*it).second;
+
+ if (wtx.IsCoinBase() || !CheckFinalTx(wtx))
+ continue;
+
+ int nDepth = wtx.GetDepthInMainChain();
+ if (nDepth < nMinDepth)
+ continue;
+
+ BOOST_FOREACH(const CTxOut& txout, wtx.vout)
+ {
+ CTxDestination address;
+ if (!ExtractDestination(txout.scriptPubKey, address))
+ continue;
+
+ isminefilter mine = IsMine(*pwalletMain, address);
+ if(!(mine & filter))
+ continue;
+
+ tallyitem& item = mapTally[address];
+ item.nAmount += txout.nValue;
+ item.nConf = min(item.nConf, nDepth);
+ item.txids.push_back(wtx.GetHash());
+ if (mine & ISMINE_WATCH_ONLY)
+ item.fIsWatchonly = true;
+ }
+ }
+
+ // Reply
+ Array ret;
+ map<string, tallyitem> mapAccountTally;
+ BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, CAddressBookData)& item, pwalletMain->mapAddressBook)
+ {
+ const CBitcoinAddress& address = item.first;
+ const string& strAccount = item.second.name;
+ map<CBitcoinAddress, tallyitem>::iterator it = mapTally.find(address);
+ if (it == mapTally.end() && !fIncludeEmpty)
+ continue;
+
+ CAmount nAmount = 0;
+ int nConf = std::numeric_limits<int>::max();
+ bool fIsWatchonly = false;
+ if (it != mapTally.end())
+ {
+ nAmount = (*it).second.nAmount;
+ nConf = (*it).second.nConf;
+ fIsWatchonly = (*it).second.fIsWatchonly;
+ }
+
+ if (fByAccounts)
+ {
+ tallyitem& item = mapAccountTally[strAccount];
+ item.nAmount += nAmount;
+ item.nConf = min(item.nConf, nConf);
+ item.fIsWatchonly = fIsWatchonly;
+ }
+ else
+ {
+ Object obj;
+ if(fIsWatchonly)
+ obj.push_back(Pair("involvesWatchonly", true));
+ 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<int>::max() ? 0 : nConf)));
+ Array transactions;
+ if (it != mapTally.end())
+ {
+ BOOST_FOREACH(const uint256& item, (*it).second.txids)
+ {
+ transactions.push_back(item.GetHex());
+ }
+ }
+ obj.push_back(Pair("txids", transactions));
+ ret.push_back(obj);
+ }
+ }
+
+ if (fByAccounts)
+ {
+ for (map<string, tallyitem>::iterator it = mapAccountTally.begin(); it != mapAccountTally.end(); ++it)
+ {
+ CAmount nAmount = (*it).second.nAmount;
+ int nConf = (*it).second.nConf;
+ Object obj;
+ if((*it).second.fIsWatchonly)
+ obj.push_back(Pair("involvesWatchonly", true));
+ obj.push_back(Pair("account", (*it).first));
+ obj.push_back(Pair("amount", ValueFromAmount(nAmount)));
+ obj.push_back(Pair("confirmations", (nConf == std::numeric_limits<int>::max() ? 0 : nConf)));
+ ret.push_back(obj);
+ }
+ }
+
+ return ret;
+}
+
+Value listreceivedbyaddress(const Array& params, bool fHelp)
+{
+ if (!EnsureWalletIsAvailable(fHelp))
+ return Value::null;
+
+ if (fHelp || params.size() > 3)
+ throw runtime_error(
+ "listreceivedbyaddress ( minconf includeempty includeWatchonly)\n"
+ "\nList balances by receiving address.\n"
+ "\nArguments:\n"
+ "1. minconf (numeric, optional, default=1) The minimum number of confirmations before payments are included.\n"
+ "2. includeempty (numeric, optional, default=false) Whether to include addresses that haven't received any payments.\n"
+ "3. includeWatchonly (bool, optional, default=false) Whether to include watchonly addresses (see 'importaddress').\n"
+
+ "\nResult:\n"
+ "[\n"
+ " {\n"
+ " \"involvesWatchonly\" : true, (bool) Only returned if imported addresses were involved in transaction\n"
+ " \"address\" : \"receivingaddress\", (string) The receiving address\n"
+ " \"account\" : \"accountname\", (string) DEPRECATED. The account of the receiving address. The default account is \"\".\n"
+ " \"amount\" : x.xxx, (numeric) The total amount in btc received by the address\n"
+ " \"confirmations\" : n (numeric) The number of confirmations of the most recent transaction included\n"
+ " }\n"
+ " ,...\n"
+ "]\n"
+
+ "\nExamples:\n"
+ + HelpExampleCli("listreceivedbyaddress", "")
+ + HelpExampleCli("listreceivedbyaddress", "6 true")
+ + HelpExampleRpc("listreceivedbyaddress", "6, true, true")
+ );
+
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
+ return ListReceived(params, false);
+}
+
+Value listreceivedbyaccount(const Array& params, bool fHelp)
+{
+ if (!EnsureWalletIsAvailable(fHelp))
+ return Value::null;
+
+ if (fHelp || params.size() > 3)
+ throw runtime_error(
+ "listreceivedbyaccount ( minconf includeempty includeWatchonly)\n"
+ "\nDEPRECATED. List balances by account.\n"
+ "\nArguments:\n"
+ "1. minconf (numeric, optional, default=1) The minimum number of confirmations before payments are included.\n"
+ "2. includeempty (boolean, optional, default=false) Whether to include accounts that haven't received any payments.\n"
+ "3. includeWatchonly (bool, optional, default=false) Whether to include watchonly addresses (see 'importaddress').\n"
+
+ "\nResult:\n"
+ "[\n"
+ " {\n"
+ " \"involvesWatchonly\" : true, (bool) Only returned if imported addresses were involved in transaction\n"
+ " \"account\" : \"accountname\", (string) The account name of the receiving account\n"
+ " \"amount\" : x.xxx, (numeric) The total amount received by addresses with this account\n"
+ " \"confirmations\" : n (numeric) The number of confirmations of the most recent transaction included\n"
+ " }\n"
+ " ,...\n"
+ "]\n"
+
+ "\nExamples:\n"
+ + HelpExampleCli("listreceivedbyaccount", "")
+ + HelpExampleCli("listreceivedbyaccount", "6 true")
+ + HelpExampleRpc("listreceivedbyaccount", "6, true, true")
+ );
+
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
+ return ListReceived(params, true);
+}
+
+static void MaybePushAddress(Object & entry, const CTxDestination &dest)
+{
+ CBitcoinAddress addr;
+ if (addr.Set(dest))
+ entry.push_back(Pair("address", addr.ToString()));
+}
+
+void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, Array& ret, const isminefilter& filter)
+{
+ CAmount nFee;
+ string strSentAccount;
+ list<COutputEntry> listReceived;
+ list<COutputEntry> listSent;
+
+ wtx.GetAmounts(listReceived, listSent, nFee, strSentAccount, filter);
+
+ bool fAllAccounts = (strAccount == string("*"));
+ bool involvesWatchonly = wtx.IsFromMe(ISMINE_WATCH_ONLY);
+
+ // Sent
+ if ((!listSent.empty() || nFee != 0) && (fAllAccounts || strAccount == strSentAccount))
+ {
+ BOOST_FOREACH(const COutputEntry& s, listSent)
+ {
+ Object entry;
+ if(involvesWatchonly || (::IsMine(*pwalletMain, s.destination) & ISMINE_WATCH_ONLY))
+ entry.push_back(Pair("involvesWatchonly", true));
+ entry.push_back(Pair("account", strSentAccount));
+ MaybePushAddress(entry, s.destination);
+ entry.push_back(Pair("category", "send"));
+ entry.push_back(Pair("amount", ValueFromAmount(-s.amount)));
+ entry.push_back(Pair("vout", s.vout));
+ 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 COutputEntry& r, listReceived)
+ {
+ string account;
+ if (pwalletMain->mapAddressBook.count(r.destination))
+ account = pwalletMain->mapAddressBook[r.destination].name;
+ if (fAllAccounts || (account == strAccount))
+ {
+ Object entry;
+ if(involvesWatchonly || (::IsMine(*pwalletMain, r.destination) & ISMINE_WATCH_ONLY))
+ entry.push_back(Pair("involvesWatchonly", true));
+ entry.push_back(Pair("account", account));
+ MaybePushAddress(entry, r.destination);
+ if (wtx.IsCoinBase())
+ {
+ if (wtx.GetDepthInMainChain() < 1)
+ entry.push_back(Pair("category", "orphan"));
+ else if (wtx.GetBlocksToMaturity() > 0)
+ entry.push_back(Pair("category", "immature"));
+ else
+ entry.push_back(Pair("category", "generate"));
+ }
+ else
+ {
+ entry.push_back(Pair("category", "receive"));
+ }
+ entry.push_back(Pair("amount", ValueFromAmount(r.amount)));
+ entry.push_back(Pair("vout", r.vout));
+ 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", 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 (!EnsureWalletIsAvailable(fHelp))
+ return Value::null;
+
+ if (fHelp || params.size() > 4)
+ throw runtime_error(
+ "listtransactions ( \"account\" count from includeWatchonly)\n"
+ "\nReturns up to 'count' most recent transactions skipping the first 'from' transactions for account 'account'.\n"
+ "\nArguments:\n"
+ "1. \"account\" (string, optional) DEPRECATED. The account name. Should be \"*\".\n"
+ "2. count (numeric, optional, default=10) The number of transactions to return\n"
+ "3. from (numeric, optional, default=0) The number of transactions to skip\n"
+ "4. includeWatchonly (bool, optional, default=false) Include transactions to watchonly addresses (see 'importaddress')\n"
+ "\nResult:\n"
+ "[\n"
+ " {\n"
+ " \"account\":\"accountname\", (string) DEPRECATED. The account name associated with the transaction. \n"
+ " It will be \"\" for the default account.\n"
+ " \"address\":\"bitcoinaddress\", (string) The bitcoin address of the transaction. Not present for \n"
+ " move transactions (category = move).\n"
+ " \"category\":\"send|receive|move\", (string) The transaction category. 'move' is a local (off blockchain)\n"
+ " transaction between accounts, and not associated with an address,\n"
+ " transaction id or block. 'send' and 'receive' transactions are \n"
+ " associated with an address, transaction id and block details\n"
+ " \"amount\": x.xxx, (numeric) The amount in btc. This is negative for the 'send' category, and for the\n"
+ " 'move' category for moves outbound. It is positive for the 'receive' category,\n"
+ " and for the 'move' category for inbound funds.\n"
+ " \"vout\" : n, (numeric) the vout value\n"
+ " \"fee\": x.xxx, (numeric) The amount of the fee in btc. This is negative and only available for the \n"
+ " 'send' category of transactions.\n"
+ " \"confirmations\": n, (numeric) The number of confirmations for the transaction. Available for 'send' and \n"
+ " 'receive' category of transactions.\n"
+ " \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction. Available for 'send' and 'receive'\n"
+ " category of transactions.\n"
+ " \"blockindex\": n, (numeric) The block index containing the transaction. Available for 'send' and 'receive'\n"
+ " category of transactions.\n"
+ " \"txid\": \"transactionid\", (string) The transaction id. Available for 'send' and 'receive' category of transactions.\n"
+ " \"time\": xxx, (numeric) The transaction time in seconds since epoch (midnight Jan 1 1970 GMT).\n"
+ " \"timereceived\": xxx, (numeric) The time received in seconds since epoch (midnight Jan 1 1970 GMT). Available \n"
+ " for 'send' and 'receive' category of transactions.\n"
+ " \"comment\": \"...\", (string) If a comment is associated with the transaction.\n"
+ " \"otheraccount\": \"accountname\", (string) For the 'move' category of transactions, the account the funds came \n"
+ " from (for receiving funds, positive amounts), or went to (for sending funds,\n"
+ " negative amounts).\n"
+ " }\n"
+ "]\n"
+
+ "\nExamples:\n"
+ "\nList the most recent 10 transactions in the systems\n"
+ + HelpExampleCli("listtransactions", "") +
+ "\nList transactions 100 to 120\n"
+ + HelpExampleCli("listtransactions", "\"*\" 20 100") +
+ "\nAs a json rpc call\n"
+ + HelpExampleRpc("listtransactions", "\"*\", 20, 100")
+ );
+
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
+ 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();
+ isminefilter filter = ISMINE_SPENDABLE;
+ if(params.size() > 3)
+ if(params[3].get_bool())
+ filter = filter | ISMINE_WATCH_ONLY;
+
+ if (nCount < 0)
+ throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative count");
+ if (nFrom < 0)
+ throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative from");
+
+ Array ret;
+
+ std::list<CAccountingEntry> acentries;
+ CWallet::TxItems txOrdered = pwalletMain->OrderedTxItems(acentries, strAccount);
+
+ // iterate backwards until we have nCount items to return:
+ for (CWallet::TxItems::reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it)
+ {
+ CWalletTx *const pwtx = (*it).second.first;
+ if (pwtx != 0)
+ ListTransactions(*pwtx, strAccount, 0, true, ret, filter);
+ 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 (!EnsureWalletIsAvailable(fHelp))
+ return Value::null;
+
+ if (fHelp || params.size() > 2)
+ throw runtime_error(
+ "listaccounts ( minconf includeWatchonly)\n"
+ "\nDEPRECATED. Returns Object that has account names as keys, account balances as values.\n"
+ "\nArguments:\n"
+ "1. minconf (numeric, optional, default=1) Only include transactions with at least this many confirmations\n"
+ "2. includeWatchonly (bool, optional, default=false) Include balances in watchonly addresses (see 'importaddress')\n"
+ "\nResult:\n"
+ "{ (json object where keys are account names, and values are numeric balances\n"
+ " \"account\": x.xxx, (numeric) The property name is the account name, and the value is the total balance for the account.\n"
+ " ...\n"
+ "}\n"
+ "\nExamples:\n"
+ "\nList account balances where there at least 1 confirmation\n"
+ + HelpExampleCli("listaccounts", "") +
+ "\nList account balances including zero confirmation transactions\n"
+ + HelpExampleCli("listaccounts", "0") +
+ "\nList account balances for 6 or more confirmations\n"
+ + HelpExampleCli("listaccounts", "6") +
+ "\nAs json rpc call\n"
+ + HelpExampleRpc("listaccounts", "6")
+ );
+
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
+ int nMinDepth = 1;
+ if (params.size() > 0)
+ nMinDepth = params[0].get_int();
+ isminefilter includeWatchonly = ISMINE_SPENDABLE;
+ if(params.size() > 1)
+ if(params[1].get_bool())
+ includeWatchonly = includeWatchonly | ISMINE_WATCH_ONLY;
+
+ map<string, CAmount> mapAccountBalances;
+ BOOST_FOREACH(const PAIRTYPE(CTxDestination, CAddressBookData)& entry, pwalletMain->mapAddressBook) {
+ if (IsMine(*pwalletMain, entry.first) & includeWatchonly) // This address belongs to me
+ mapAccountBalances[entry.second.name] = 0;
+ }
+
+ for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
+ {
+ const CWalletTx& wtx = (*it).second;
+ CAmount nFee;
+ string strSentAccount;
+ list<COutputEntry> listReceived;
+ list<COutputEntry> listSent;
+ int nDepth = wtx.GetDepthInMainChain();
+ if (wtx.GetBlocksToMaturity() > 0 || nDepth < 0)
+ continue;
+ wtx.GetAmounts(listReceived, listSent, nFee, strSentAccount, includeWatchonly);
+ mapAccountBalances[strSentAccount] -= nFee;
+ BOOST_FOREACH(const COutputEntry& s, listSent)
+ mapAccountBalances[strSentAccount] -= s.amount;
+ if (nDepth >= nMinDepth)
+ {
+ BOOST_FOREACH(const COutputEntry& r, listReceived)
+ if (pwalletMain->mapAddressBook.count(r.destination))
+ mapAccountBalances[pwalletMain->mapAddressBook[r.destination].name] += r.amount;
+ else
+ mapAccountBalances[""] += r.amount;
+ }
+ }
+
+ list<CAccountingEntry> acentries;
+ CWalletDB(pwalletMain->strWalletFile).ListAccountCreditDebit("*", acentries);
+ BOOST_FOREACH(const CAccountingEntry& entry, acentries)
+ mapAccountBalances[entry.strAccount] += entry.nCreditDebit;
+
+ Object ret;
+ BOOST_FOREACH(const PAIRTYPE(string, CAmount)& accountBalance, mapAccountBalances) {
+ ret.push_back(Pair(accountBalance.first, ValueFromAmount(accountBalance.second)));
+ }
+ return ret;
+}
+
+Value listsinceblock(const Array& params, bool fHelp)
+{
+ if (!EnsureWalletIsAvailable(fHelp))
+ return Value::null;
+
+ if (fHelp)
+ throw runtime_error(
+ "listsinceblock ( \"blockhash\" target-confirmations includeWatchonly)\n"
+ "\nGet all transactions in blocks since block [blockhash], or all transactions if omitted\n"
+ "\nArguments:\n"
+ "1. \"blockhash\" (string, optional) The block hash to list transactions since\n"
+ "2. target-confirmations: (numeric, optional) The confirmations required, must be 1 or more\n"
+ "3. includeWatchonly: (bool, optional, default=false) Include transactions to watchonly addresses (see 'importaddress')"
+ "\nResult:\n"
+ "{\n"
+ " \"transactions\": [\n"
+ " \"account\":\"accountname\", (string) DEPRECATED. The account name associated with the transaction. Will be \"\" for the default account.\n"
+ " \"address\":\"bitcoinaddress\", (string) The bitcoin address of the transaction. Not present for move transactions (category = move).\n"
+ " \"category\":\"send|receive\", (string) The transaction category. 'send' has negative amounts, 'receive' has positive amounts.\n"
+ " \"amount\": x.xxx, (numeric) The amount in btc. This is negative for the 'send' category, and for the 'move' category for moves \n"
+ " outbound. It is positive for the 'receive' category, and for the 'move' category for inbound funds.\n"
+ " \"vout\" : n, (numeric) the vout value\n"
+ " \"fee\": x.xxx, (numeric) The amount of the fee in btc. This is negative and only available for the 'send' category of transactions.\n"
+ " \"confirmations\": n, (numeric) The number of confirmations for the transaction. Available for 'send' and 'receive' category of transactions.\n"
+ " \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction. Available for 'send' and 'receive' category of transactions.\n"
+ " \"blockindex\": n, (numeric) The block index containing the transaction. Available for 'send' and 'receive' category of transactions.\n"
+ " \"blocktime\": xxx, (numeric) The block time in seconds since epoch (1 Jan 1970 GMT).\n"
+ " \"txid\": \"transactionid\", (string) The transaction id. Available for 'send' and 'receive' category of transactions.\n"
+ " \"time\": xxx, (numeric) The transaction time in seconds since epoch (Jan 1 1970 GMT).\n"
+ " \"timereceived\": xxx, (numeric) The time received in seconds since epoch (Jan 1 1970 GMT). Available for 'send' and 'receive' category of transactions.\n"
+ " \"comment\": \"...\", (string) If a comment is associated with the transaction.\n"
+ " \"to\": \"...\", (string) If a comment to is associated with the transaction.\n"
+ " ],\n"
+ " \"lastblock\": \"lastblockhash\" (string) The hash of the last block\n"
+ "}\n"
+ "\nExamples:\n"
+ + HelpExampleCli("listsinceblock", "")
+ + HelpExampleCli("listsinceblock", "\"000000000000000bacf66f7497b7dc45ef753ee9a7d38571037cdb1a57f663ad\" 6")
+ + HelpExampleRpc("listsinceblock", "\"000000000000000bacf66f7497b7dc45ef753ee9a7d38571037cdb1a57f663ad\", 6")
+ );
+
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
+ CBlockIndex *pindex = NULL;
+ int target_confirms = 1;
+ isminefilter filter = ISMINE_SPENDABLE;
+
+ if (params.size() > 0)
+ {
+ uint256 blockId;
+
+ blockId.SetHex(params[0].get_str());
+ BlockMap::iterator it = mapBlockIndex.find(blockId);
+ if (it != mapBlockIndex.end())
+ pindex = it->second;
+ }
+
+ if (params.size() > 1)
+ {
+ target_confirms = params[1].get_int();
+
+ if (target_confirms < 1)
+ throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter");
+ }
+
+ if(params.size() > 2)
+ if(params[2].get_bool())
+ filter = filter | ISMINE_WATCH_ONLY;
+
+ int depth = pindex ? (1 + chainActive.Height() - pindex->nHeight) : -1;
+
+ Array transactions;
+
+ for (map<uint256, CWalletTx>::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, filter);
+ }
+
+ CBlockIndex *pblockLast = chainActive[chainActive.Height() + 1 - target_confirms];
+ uint256 lastblock = pblockLast ? pblockLast->GetBlockHash() : uint256();
+
+ 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 (!EnsureWalletIsAvailable(fHelp))
+ return Value::null;
+
+ if (fHelp || params.size() < 1 || params.size() > 2)
+ throw runtime_error(
+ "gettransaction \"txid\" ( includeWatchonly )\n"
+ "\nGet detailed information about in-wallet transaction <txid>\n"
+ "\nArguments:\n"
+ "1. \"txid\" (string, required) The transaction id\n"
+ "2. \"includeWatchonly\" (bool, optional, default=false) Whether to include watchonly addresses in balance calculation and details[]\n"
+ "\nResult:\n"
+ "{\n"
+ " \"amount\" : x.xxx, (numeric) The transaction amount in btc\n"
+ " \"confirmations\" : n, (numeric) The number of confirmations\n"
+ " \"blockhash\" : \"hash\", (string) The block hash\n"
+ " \"blockindex\" : xx, (numeric) The block index\n"
+ " \"blocktime\" : ttt, (numeric) The time in seconds since epoch (1 Jan 1970 GMT)\n"
+ " \"txid\" : \"transactionid\", (string) The transaction id.\n"
+ " \"time\" : ttt, (numeric) The transaction time in seconds since epoch (1 Jan 1970 GMT)\n"
+ " \"timereceived\" : ttt, (numeric) The time received in seconds since epoch (1 Jan 1970 GMT)\n"
+ " \"details\" : [\n"
+ " {\n"
+ " \"account\" : \"accountname\", (string) DEPRECATED. The account name involved in the transaction, can be \"\" for the default account.\n"
+ " \"address\" : \"bitcoinaddress\", (string) The bitcoin address involved in the transaction\n"
+ " \"category\" : \"send|receive\", (string) The category, either 'send' or 'receive'\n"
+ " \"amount\" : x.xxx (numeric) The amount in btc\n"
+ " \"vout\" : n, (numeric) the vout value\n"
+ " }\n"
+ " ,...\n"
+ " ],\n"
+ " \"hex\" : \"data\" (string) Raw data for transaction\n"
+ "}\n"
+
+ "\nExamples:\n"
+ + HelpExampleCli("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
+ + HelpExampleCli("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\" true")
+ + HelpExampleRpc("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
+ );
+
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
+ uint256 hash;
+ hash.SetHex(params[0].get_str());
+
+ isminefilter filter = ISMINE_SPENDABLE;
+ if(params.size() > 1)
+ if(params[1].get_bool())
+ filter = filter | ISMINE_WATCH_ONLY;
+
+ Object entry;
+ if (!pwalletMain->mapWallet.count(hash))
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id");
+ const CWalletTx& wtx = pwalletMain->mapWallet[hash];
+
+ CAmount nCredit = wtx.GetCredit(filter);
+ CAmount nDebit = wtx.GetDebit(filter);
+ CAmount nNet = nCredit - nDebit;
+ CAmount nFee = (wtx.IsFromMe(filter) ? wtx.GetValueOut() - nDebit : 0);
+
+ entry.push_back(Pair("amount", ValueFromAmount(nNet - nFee)));
+ if (wtx.IsFromMe(filter))
+ entry.push_back(Pair("fee", ValueFromAmount(nFee)));
+
+ WalletTxToJSON(wtx, entry);
+
+ Array details;
+ ListTransactions(wtx, "*", 0, false, details, filter);
+ entry.push_back(Pair("details", details));
+
+ string strHex = EncodeHexTx(static_cast<CTransaction>(wtx));
+ entry.push_back(Pair("hex", strHex));
+
+ return entry;
+}
+
+
+Value backupwallet(const Array& params, bool fHelp)
+{
+ if (!EnsureWalletIsAvailable(fHelp))
+ return Value::null;
+
+ if (fHelp || params.size() != 1)
+ throw runtime_error(
+ "backupwallet \"destination\"\n"
+ "\nSafely copies wallet.dat to destination, which can be a directory or a path with filename.\n"
+ "\nArguments:\n"
+ "1. \"destination\" (string) The destination directory or file\n"
+ "\nExamples:\n"
+ + HelpExampleCli("backupwallet", "\"backup.dat\"")
+ + HelpExampleRpc("backupwallet", "\"backup.dat\"")
+ );
+
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
+ string strDest = params[0].get_str();
+ if (!BackupWallet(*pwalletMain, strDest))
+ throw JSONRPCError(RPC_WALLET_ERROR, "Error: Wallet backup failed!");
+
+ return Value::null;
+}
+
+
+Value keypoolrefill(const Array& params, bool fHelp)
+{
+ if (!EnsureWalletIsAvailable(fHelp))
+ return Value::null;
+
+ if (fHelp || params.size() > 1)
+ throw runtime_error(
+ "keypoolrefill ( newsize )\n"
+ "\nFills the keypool."
+ + HelpRequiringPassphrase() + "\n"
+ "\nArguments\n"
+ "1. newsize (numeric, optional, default=100) The new keypool size\n"
+ "\nExamples:\n"
+ + HelpExampleCli("keypoolrefill", "")
+ + HelpExampleRpc("keypoolrefill", "")
+ );
+
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
+ // 0 is interpreted by TopUpKeyPool() as the default keypool size given by -keypool
+ unsigned int kpSize = 0;
+ if (params.size() > 0) {
+ if (params[0].get_int() < 0)
+ throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected valid size.");
+ kpSize = (unsigned int)params[0].get_int();
+ }
+
+ EnsureWalletIsUnlocked();
+ pwalletMain->TopUpKeyPool(kpSize);
+
+ if (pwalletMain->GetKeyPoolSize() < kpSize)
+ throw JSONRPCError(RPC_WALLET_ERROR, "Error refreshing keypool.");
+
+ return Value::null;
+}
+
+
+static void LockWallet(CWallet* pWallet)
+{
+ LOCK(cs_nWalletUnlockTime);
+ nWalletUnlockTime = 0;
+ pWallet->Lock();
+}
+
+Value walletpassphrase(const Array& params, bool fHelp)
+{
+ if (!EnsureWalletIsAvailable(fHelp))
+ return Value::null;
+
+ if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2))
+ throw runtime_error(
+ "walletpassphrase \"passphrase\" timeout\n"
+ "\nStores the wallet decryption key in memory for 'timeout' seconds.\n"
+ "This is needed prior to performing transactions related to private keys such as sending bitcoins\n"
+ "\nArguments:\n"
+ "1. \"passphrase\" (string, required) The wallet passphrase\n"
+ "2. timeout (numeric, required) The time to keep the decryption key in seconds.\n"
+ "\nNote:\n"
+ "Issuing the walletpassphrase command while the wallet is already unlocked will set a new unlock\n"
+ "time that overrides the old one.\n"
+ "\nExamples:\n"
+ "\nunlock the wallet for 60 seconds\n"
+ + HelpExampleCli("walletpassphrase", "\"my pass phrase\" 60") +
+ "\nLock the wallet again (before 60 seconds)\n"
+ + HelpExampleCli("walletlock", "") +
+ "\nAs json rpc call\n"
+ + HelpExampleRpc("walletpassphrase", "\"my pass phrase\", 60")
+ );
+
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
+ if (fHelp)
+ return true;
+ if (!pwalletMain->IsCrypted())
+ throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletpassphrase was called.");
+
+ // 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(RPC_WALLET_PASSPHRASE_INCORRECT, "Error: The wallet passphrase entered was incorrect.");
+ }
+ else
+ throw runtime_error(
+ "walletpassphrase <passphrase> <timeout>\n"
+ "Stores the wallet decryption key in memory for <timeout> seconds.");
+
+ pwalletMain->TopUpKeyPool();
+
+ int64_t nSleepTime = params[1].get_int64();
+ LOCK(cs_nWalletUnlockTime);
+ nWalletUnlockTime = GetTime() + nSleepTime;
+ RPCRunLater("lockwallet", boost::bind(LockWallet, pwalletMain), nSleepTime);
+
+ return Value::null;
+}
+
+
+Value walletpassphrasechange(const Array& params, bool fHelp)
+{
+ if (!EnsureWalletIsAvailable(fHelp))
+ return Value::null;
+
+ if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2))
+ throw runtime_error(
+ "walletpassphrasechange \"oldpassphrase\" \"newpassphrase\"\n"
+ "\nChanges the wallet passphrase from 'oldpassphrase' to 'newpassphrase'.\n"
+ "\nArguments:\n"
+ "1. \"oldpassphrase\" (string) The current passphrase\n"
+ "2. \"newpassphrase\" (string) The new passphrase\n"
+ "\nExamples:\n"
+ + HelpExampleCli("walletpassphrasechange", "\"old one\" \"new one\"")
+ + HelpExampleRpc("walletpassphrasechange", "\"old one\", \"new one\"")
+ );
+
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
+ if (fHelp)
+ return true;
+ if (!pwalletMain->IsCrypted())
+ throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "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 <oldpassphrase> <newpassphrase>\n"
+ "Changes the wallet passphrase from <oldpassphrase> to <newpassphrase>.");
+
+ if (!pwalletMain->ChangeWalletPassphrase(strOldWalletPass, strNewWalletPass))
+ throw JSONRPCError(RPC_WALLET_PASSPHRASE_INCORRECT, "Error: The wallet passphrase entered was incorrect.");
+
+ return Value::null;
+}
+
+
+Value walletlock(const Array& params, bool fHelp)
+{
+ if (!EnsureWalletIsAvailable(fHelp))
+ return Value::null;
+
+ if (pwalletMain->IsCrypted() && (fHelp || params.size() != 0))
+ throw runtime_error(
+ "walletlock\n"
+ "\nRemoves 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.\n"
+ "\nExamples:\n"
+ "\nSet the passphrase for 2 minutes to perform a transaction\n"
+ + HelpExampleCli("walletpassphrase", "\"my pass phrase\" 120") +
+ "\nPerform a send (requires passphrase set)\n"
+ + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 1.0") +
+ "\nClear the passphrase since we are done before 2 minutes is up\n"
+ + HelpExampleCli("walletlock", "") +
+ "\nAs json rpc call\n"
+ + HelpExampleRpc("walletlock", "")
+ );
+
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
+ if (fHelp)
+ return true;
+ if (!pwalletMain->IsCrypted())
+ throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "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 (!EnsureWalletIsAvailable(fHelp))
+ return Value::null;
+
+ if (!pwalletMain->IsCrypted() && (fHelp || params.size() != 1))
+ throw runtime_error(
+ "encryptwallet \"passphrase\"\n"
+ "\nEncrypts the wallet with 'passphrase'. This is for first time encryption.\n"
+ "After this, any calls that interact with private keys such as sending or signing \n"
+ "will require the passphrase to be set prior the making these calls.\n"
+ "Use the walletpassphrase call for this, and then walletlock call.\n"
+ "If the wallet is already encrypted, use the walletpassphrasechange call.\n"
+ "Note that this will shutdown the server.\n"
+ "\nArguments:\n"
+ "1. \"passphrase\" (string) The pass phrase to encrypt the wallet with. It must be at least 1 character, but should be long.\n"
+ "\nExamples:\n"
+ "\nEncrypt you wallet\n"
+ + HelpExampleCli("encryptwallet", "\"my pass phrase\"") +
+ "\nNow set the passphrase to use the wallet, such as for signing or sending bitcoin\n"
+ + HelpExampleCli("walletpassphrase", "\"my pass phrase\"") +
+ "\nNow we can so something like sign\n"
+ + HelpExampleCli("signmessage", "\"bitcoinaddress\" \"test message\"") +
+ "\nNow lock the wallet again by removing the passphrase\n"
+ + HelpExampleCli("walletlock", "") +
+ "\nAs a json rpc call\n"
+ + HelpExampleRpc("encryptwallet", "\"my pass phrase\"")
+ );
+
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
+ if (fHelp)
+ return true;
+ if (pwalletMain->IsCrypted())
+ throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "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 <passphrase>\n"
+ "Encrypts the wallet with <passphrase>.");
+
+ if (!pwalletMain->EncryptWallet(strWalletPass))
+ throw JSONRPCError(RPC_WALLET_ENCRYPTION_FAILED, "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; Bitcoin server stopping, restart to run with encrypted wallet. The keypool has been flushed, you need to make a new backup.";
+}
+
+Value lockunspent(const Array& params, bool fHelp)
+{
+ if (!EnsureWalletIsAvailable(fHelp))
+ return Value::null;
+
+ if (fHelp || params.size() < 1 || params.size() > 2)
+ throw runtime_error(
+ "lockunspent unlock [{\"txid\":\"txid\",\"vout\":n},...]\n"
+ "\nUpdates list of temporarily unspendable outputs.\n"
+ "Temporarily lock (unlock=false) or unlock (unlock=true) specified transaction outputs.\n"
+ "A locked transaction output will not be chosen by automatic coin selection, when spending bitcoins.\n"
+ "Locks are stored in memory only. Nodes start with zero locked outputs, and the locked output list\n"
+ "is always cleared (by virtue of process exit) when a node stops or fails.\n"
+ "Also see the listunspent call\n"
+ "\nArguments:\n"
+ "1. unlock (boolean, required) Whether to unlock (true) or lock (false) the specified transactions\n"
+ "2. \"transactions\" (string, required) A json array of objects. Each object the txid (string) vout (numeric)\n"
+ " [ (json array of json objects)\n"
+ " {\n"
+ " \"txid\":\"id\", (string) The transaction id\n"
+ " \"vout\": n (numeric) The output number\n"
+ " }\n"
+ " ,...\n"
+ " ]\n"
+
+ "\nResult:\n"
+ "true|false (boolean) Whether the command was successful or not\n"
+
+ "\nExamples:\n"
+ "\nList the unspent transactions\n"
+ + HelpExampleCli("listunspent", "") +
+ "\nLock an unspent transaction\n"
+ + HelpExampleCli("lockunspent", "false \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +
+ "\nList the locked transactions\n"
+ + HelpExampleCli("listlockunspent", "") +
+ "\nUnlock the transaction again\n"
+ + HelpExampleCli("lockunspent", "true \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +
+ "\nAs a json rpc call\n"
+ + HelpExampleRpc("lockunspent", "false, \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"")
+ );
+
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
+ if (params.size() == 1)
+ RPCTypeCheck(params, boost::assign::list_of(bool_type));
+ else
+ RPCTypeCheck(params, boost::assign::list_of(bool_type)(array_type));
+
+ bool fUnlock = params[0].get_bool();
+
+ if (params.size() == 1) {
+ if (fUnlock)
+ pwalletMain->UnlockAllCoins();
+ return true;
+ }
+
+ Array outputs = params[1].get_array();
+ BOOST_FOREACH(Value& output, outputs)
+ {
+ if (output.type() != obj_type)
+ throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected object");
+ const Object& o = output.get_obj();
+
+ RPCTypeCheck(o, boost::assign::map_list_of("txid", str_type)("vout", int_type));
+
+ string txid = find_value(o, "txid").get_str();
+ if (!IsHex(txid))
+ throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected hex txid");
+
+ int nOutput = find_value(o, "vout").get_int();
+ if (nOutput < 0)
+ throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive");
+
+ COutPoint outpt(uint256S(txid), nOutput);
+
+ if (fUnlock)
+ pwalletMain->UnlockCoin(outpt);
+ else
+ pwalletMain->LockCoin(outpt);
+ }
+
+ return true;
+}
+
+Value listlockunspent(const Array& params, bool fHelp)
+{
+ if (!EnsureWalletIsAvailable(fHelp))
+ return Value::null;
+
+ if (fHelp || params.size() > 0)
+ throw runtime_error(
+ "listlockunspent\n"
+ "\nReturns list of temporarily unspendable outputs.\n"
+ "See the lockunspent call to lock and unlock transactions for spending.\n"
+ "\nResult:\n"
+ "[\n"
+ " {\n"
+ " \"txid\" : \"transactionid\", (string) The transaction id locked\n"
+ " \"vout\" : n (numeric) The vout value\n"
+ " }\n"
+ " ,...\n"
+ "]\n"
+ "\nExamples:\n"
+ "\nList the unspent transactions\n"
+ + HelpExampleCli("listunspent", "") +
+ "\nLock an unspent transaction\n"
+ + HelpExampleCli("lockunspent", "false \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +
+ "\nList the locked transactions\n"
+ + HelpExampleCli("listlockunspent", "") +
+ "\nUnlock the transaction again\n"
+ + HelpExampleCli("lockunspent", "true \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +
+ "\nAs a json rpc call\n"
+ + HelpExampleRpc("listlockunspent", "")
+ );
+
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
+ vector<COutPoint> vOutpts;
+ pwalletMain->ListLockedCoins(vOutpts);
+
+ Array ret;
+
+ BOOST_FOREACH(COutPoint &outpt, vOutpts) {
+ Object o;
+
+ o.push_back(Pair("txid", outpt.hash.GetHex()));
+ o.push_back(Pair("vout", (int)outpt.n));
+ ret.push_back(o);
+ }
+
+ return ret;
+}
+
+Value settxfee(const Array& params, bool fHelp)
+{
+ if (!EnsureWalletIsAvailable(fHelp))
+ return Value::null;
+
+ if (fHelp || params.size() < 1 || params.size() > 1)
+ throw runtime_error(
+ "settxfee amount\n"
+ "\nSet the transaction fee per kB.\n"
+ "\nArguments:\n"
+ "1. amount (numeric, required) The transaction fee in BTC/kB rounded to the nearest 0.00000001\n"
+ "\nResult\n"
+ "true|false (boolean) Returns true if successful\n"
+ "\nExamples:\n"
+ + HelpExampleCli("settxfee", "0.00001")
+ + HelpExampleRpc("settxfee", "0.00001")
+ );
+
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
+ // Amount
+ CAmount nAmount = 0;
+ if (params[0].get_real() != 0.0)
+ nAmount = AmountFromValue(params[0]); // rejects 0.0 amounts
+
+ payTxFee = CFeeRate(nAmount, 1000);
+ return true;
+}
+
+Value getwalletinfo(const Array& params, bool fHelp)
+{
+ if (!EnsureWalletIsAvailable(fHelp))
+ return Value::null;
+
+ if (fHelp || params.size() != 0)
+ throw runtime_error(
+ "getwalletinfo\n"
+ "Returns an object containing various wallet state info.\n"
+ "\nResult:\n"
+ "{\n"
+ " \"walletversion\": xxxxx, (numeric) the wallet version\n"
+ " \"balance\": xxxxxxx, (numeric) the total confirmed bitcoin balance of the wallet\n"
+ " \"unconfirmed_balance\": xxx, (numeric) the total unconfirmed bitcoin balance of the wallet\n"
+ " \"immature_balance\": xxxxxx, (numeric) the total immature balance of the wallet\n"
+ " \"txcount\": xxxxxxx, (numeric) the total number of transactions in the wallet\n"
+ " \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since GMT epoch) of the oldest pre-generated key in the key pool\n"
+ " \"keypoolsize\": xxxx, (numeric) how many new keys are pre-generated\n"
+ " \"unlocked_until\": ttt, (numeric) the timestamp in seconds since epoch (midnight Jan 1 1970 GMT) that the wallet is unlocked for transfers, or 0 if the wallet is locked\n"
+ "}\n"
+ "\nExamples:\n"
+ + HelpExampleCli("getwalletinfo", "")
+ + HelpExampleRpc("getwalletinfo", "")
+ );
+
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
+ Object obj;
+ obj.push_back(Pair("walletversion", pwalletMain->GetVersion()));
+ obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance())));
+ obj.push_back(Pair("unconfirmed_balance", ValueFromAmount(pwalletMain->GetUnconfirmedBalance())));
+ obj.push_back(Pair("immature_balance", ValueFromAmount(pwalletMain->GetImmatureBalance())));
+ obj.push_back(Pair("txcount", (int)pwalletMain->mapWallet.size()));
+ obj.push_back(Pair("keypoololdest", pwalletMain->GetOldestKeyPoolTime()));
+ obj.push_back(Pair("keypoolsize", (int)pwalletMain->GetKeyPoolSize()));
+ if (pwalletMain->IsCrypted())
+ obj.push_back(Pair("unlocked_until", nWalletUnlockTime));
+ return obj;
+}
+
+Value resendwallettransactions(const Array& params, bool fHelp)
+{
+ if (!EnsureWalletIsAvailable(fHelp))
+ return Value::null;
+
+ if (fHelp || params.size() != 0)
+ throw runtime_error(
+ "resendwallettransactions\n"
+ "Immediately re-broadcast unconfirmed wallet transactions to all peers.\n"
+ "Intended only for testing; the wallet code periodically re-broadcasts\n"
+ "automatically.\n"
+ "Returns array of transaction ids that were re-broadcast.\n"
+ );
+
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
+ std::vector<uint256> txids = pwalletMain->ResendWalletTransactionsBefore(GetTime());
+ Array result;
+ BOOST_FOREACH(const uint256& txid, txids)
+ {
+ result.push_back(txid.ToString());
+ }
+ return result;
+}
+
+Value listunspent(const Array& params, bool fHelp)
+{
+ if (!EnsureWalletIsAvailable(fHelp))
+ return Value::null;
+
+ if (fHelp || params.size() > 3)
+ throw runtime_error(
+ "listunspent ( minconf maxconf [\"address\",...] )\n"
+ "\nReturns array of unspent transaction outputs\n"
+ "with between minconf and maxconf (inclusive) confirmations.\n"
+ "Optionally filter to only include txouts paid to specified addresses.\n"
+ "Results are an array of Objects, each of which has:\n"
+ "{txid, vout, scriptPubKey, amount, confirmations}\n"
+ "\nArguments:\n"
+ "1. minconf (numeric, optional, default=1) The minimum confirmations to filter\n"
+ "2. maxconf (numeric, optional, default=9999999) The maximum confirmations to filter\n"
+ "3. \"addresses\" (string) A json array of bitcoin addresses to filter\n"
+ " [\n"
+ " \"address\" (string) bitcoin address\n"
+ " ,...\n"
+ " ]\n"
+ "\nResult\n"
+ "[ (array of json object)\n"
+ " {\n"
+ " \"txid\" : \"txid\", (string) the transaction id \n"
+ " \"vout\" : n, (numeric) the vout value\n"
+ " \"address\" : \"address\", (string) the bitcoin address\n"
+ " \"account\" : \"account\", (string) DEPRECATED. The associated account, or \"\" for the default account\n"
+ " \"scriptPubKey\" : \"key\", (string) the script key\n"
+ " \"amount\" : x.xxx, (numeric) the transaction amount in btc\n"
+ " \"confirmations\" : n (numeric) The number of confirmations\n"
+ " }\n"
+ " ,...\n"
+ "]\n"
+
+ "\nExamples\n"
+ + HelpExampleCli("listunspent", "")
+ + HelpExampleCli("listunspent", "6 9999999 \"[\\\"1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"")
+ + HelpExampleRpc("listunspent", "6, 9999999 \"[\\\"1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"")
+ );
+
+ RPCTypeCheck(params, boost::assign::list_of(int_type)(int_type)(array_type));
+
+ int nMinDepth = 1;
+ if (params.size() > 0)
+ nMinDepth = params[0].get_int();
+
+ int nMaxDepth = 9999999;
+ if (params.size() > 1)
+ nMaxDepth = params[1].get_int();
+
+ set<CBitcoinAddress> setAddress;
+ if (params.size() > 2) {
+ Array inputs = params[2].get_array();
+ BOOST_FOREACH(Value& input, inputs) {
+ CBitcoinAddress address(input.get_str());
+ if (!address.IsValid())
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+input.get_str());
+ if (setAddress.count(address))
+ throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+input.get_str());
+ setAddress.insert(address);
+ }
+ }
+
+ Array results;
+ vector<COutput> vecOutputs;
+ assert(pwalletMain != NULL);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+ pwalletMain->AvailableCoins(vecOutputs, false, NULL, true);
+ BOOST_FOREACH(const COutput& out, vecOutputs) {
+ if (out.nDepth < nMinDepth || out.nDepth > nMaxDepth)
+ continue;
+
+ if (setAddress.size()) {
+ CTxDestination address;
+ if (!ExtractDestination(out.tx->vout[out.i].scriptPubKey, address))
+ continue;
+
+ if (!setAddress.count(address))
+ continue;
+ }
+
+ CAmount 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));
+ CTxDestination address;
+ if (ExtractDestination(out.tx->vout[out.i].scriptPubKey, address)) {
+ entry.push_back(Pair("address", CBitcoinAddress(address).ToString()));
+ if (pwalletMain->mapAddressBook.count(address))
+ entry.push_back(Pair("account", pwalletMain->mapAddressBook[address].name));
+ }
+ entry.push_back(Pair("scriptPubKey", HexStr(pk.begin(), pk.end())));
+ if (pk.IsPayToScriptHash()) {
+ CTxDestination address;
+ if (ExtractDestination(pk, address)) {
+ const CScriptID& hash = boost::get<CScriptID>(address);
+ CScript redeemScript;
+ if (pwalletMain->GetCScript(hash, redeemScript))
+ entry.push_back(Pair("redeemScript", HexStr(redeemScript.begin(), redeemScript.end())));
+ }
+ }
+ entry.push_back(Pair("amount",ValueFromAmount(nValue)));
+ entry.push_back(Pair("confirmations",out.nDepth));
+ entry.push_back(Pair("spendable", out.fSpendable));
+ results.push_back(entry);
+ }
+
+ return results;
+}
diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp
new file mode 100644
index 0000000000..a5bc52b8dc
--- /dev/null
+++ b/src/wallet/test/wallet_tests.cpp
@@ -0,0 +1,310 @@
+// Copyright (c) 2012-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "wallet/wallet.h"
+
+#include <set>
+#include <stdint.h>
+#include <utility>
+#include <vector>
+
+#include "test/test_bitcoin.h"
+
+#include <boost/foreach.hpp>
+#include <boost/test/unit_test.hpp>
+
+// 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<pair<const CWalletTx*,unsigned int> > CoinSet;
+
+BOOST_FIXTURE_TEST_SUITE(wallet_tests, TestingSetup)
+
+static CWallet wallet;
+static vector<COutput> vCoins;
+
+static void add_coin(const CAmount& nValue, int nAge = 6*24, bool fIsFromMe = false, int nInput=0)
+{
+ static int nextLockTime = 0;
+ CMutableTransaction tx;
+ tx.nLockTime = nextLockTime++; // so all transactions get different hashes
+ tx.vout.resize(nInput+1);
+ tx.vout[nInput].nValue = nValue;
+ 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()
+ tx.vin.resize(1);
+ }
+ CWalletTx* wtx = new CWalletTx(&wallet, tx);
+ if (fIsFromMe)
+ {
+ wtx->fDebitCached = true;
+ wtx->nDebitCached = 1;
+ }
+ COutput output(wtx, nInput, nAge, true);
+ 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<CoinSet::iterator, CoinSet::iterator> ret = mismatch(a.begin(), a.end(), b.begin());
+ return ret.first == a.end() && ret.second == b.end();
+}
+
+BOOST_AUTO_TEST_CASE(coin_selection_tests)
+{
+ CoinSet setCoinsRet, setCoinsRet2;
+ CAmount nValueRet;
+
+ LOCK(wallet.cs_wallet);
+
+ // 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(), 3U); // 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(), 2U);
+
+ // 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(), 3U);
+
+ // 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(), 1U);
+
+ // 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(), 1U);
+
+ 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(), 3U);
+
+ 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(), 1U); // 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(), 2U);
+
+ // 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 BTC in 1 coin
+ BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U);
+
+ BOOST_CHECK( wallet.SelectCoinsMinConf(195 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet));
+ BOOST_CHECK_EQUAL(nValueRet, 2 * COIN); // we should get 2 BTC in 1 coin
+ BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U);
+
+ // 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(), 10U); // 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(), 1U);
+
+ // 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(), 2U); // 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(), 3U);
+
+ // 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(), 2U);
+
+ // 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);
+ }
+ }
+ empty_wallet();
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
new file mode 100644
index 0000000000..f412e471e2
--- /dev/null
+++ b/src/wallet/wallet.cpp
@@ -0,0 +1,2759 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "wallet/wallet.h"
+
+#include "base58.h"
+#include "checkpoints.h"
+#include "coincontrol.h"
+#include "consensus/consensus.h"
+#include "consensus/validation.h"
+#include "main.h"
+#include "net.h"
+#include "script/script.h"
+#include "script/sign.h"
+#include "timedata.h"
+#include "util.h"
+#include "utilmoneystr.h"
+
+#include <assert.h>
+
+#include <boost/algorithm/string/replace.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/thread.hpp>
+
+using namespace std;
+
+/**
+ * Settings
+ */
+CFeeRate payTxFee(DEFAULT_TRANSACTION_FEE);
+CAmount maxTxFee = DEFAULT_TRANSACTION_MAXFEE;
+unsigned int nTxConfirmTarget = DEFAULT_TX_CONFIRM_TARGET;
+bool bSpendZeroConfChange = true;
+bool fSendFreeTransactions = false;
+bool fPayAtLeastCustomFee = true;
+
+/**
+ * Fees smaller than this (in satoshi) are considered zero fee (for transaction creation)
+ * Override with -mintxfee
+ */
+CFeeRate CWallet::minTxFee = CFeeRate(1000);
+
+/** @defgroup mapWallet
+ *
+ * @{
+ */
+
+struct CompareValueOnly
+{
+ bool operator()(const pair<CAmount, pair<const CWalletTx*, unsigned int> >& t1,
+ const pair<CAmount, pair<const CWalletTx*, unsigned int> >& t2) const
+ {
+ return t1.first < t2.first;
+ }
+};
+
+std::string COutput::ToString() const
+{
+ return strprintf("COutput(%s, %d, %d) [%s]", tx->GetHash().ToString(), i, nDepth, FormatMoney(tx->vout[i].nValue));
+}
+
+const CWalletTx* CWallet::GetWalletTx(const uint256& hash) const
+{
+ LOCK(cs_wallet);
+ std::map<uint256, CWalletTx>::const_iterator it = mapWallet.find(hash);
+ if (it == mapWallet.end())
+ return NULL;
+ return &(it->second);
+}
+
+CPubKey CWallet::GenerateNewKey()
+{
+ AssertLockHeld(cs_wallet); // mapKeyMetadata
+ bool fCompressed = CanSupportFeature(FEATURE_COMPRPUBKEY); // default to compressed public keys if we want 0.6.0 wallets
+
+ CKey secret;
+ secret.MakeNewKey(fCompressed);
+
+ // Compressed public keys were introduced in version 0.6.0
+ if (fCompressed)
+ SetMinVersion(FEATURE_COMPRPUBKEY);
+
+ CPubKey pubkey = secret.GetPubKey();
+ assert(secret.VerifyPubKey(pubkey));
+
+ // Create new metadata
+ int64_t nCreationTime = GetTime();
+ mapKeyMetadata[pubkey.GetID()] = CKeyMetadata(nCreationTime);
+ if (!nTimeFirstKey || nCreationTime < nTimeFirstKey)
+ nTimeFirstKey = nCreationTime;
+
+ if (!AddKeyPubKey(secret, pubkey))
+ throw std::runtime_error("CWallet::GenerateNewKey(): AddKey failed");
+ return pubkey;
+}
+
+bool CWallet::AddKeyPubKey(const CKey& secret, const CPubKey &pubkey)
+{
+ AssertLockHeld(cs_wallet); // mapKeyMetadata
+ if (!CCryptoKeyStore::AddKeyPubKey(secret, pubkey))
+ return false;
+
+ // check if we need to remove from watch-only
+ CScript script;
+ script = GetScriptForDestination(pubkey.GetID());
+ if (HaveWatchOnly(script))
+ RemoveWatchOnly(script);
+
+ if (!fFileBacked)
+ return true;
+ if (!IsCrypted()) {
+ return CWalletDB(strWalletFile).WriteKey(pubkey,
+ secret.GetPrivKey(),
+ mapKeyMetadata[pubkey.GetID()]);
+ }
+ return true;
+}
+
+bool CWallet::AddCryptedKey(const CPubKey &vchPubKey,
+ const vector<unsigned char> &vchCryptedSecret)
+{
+ if (!CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret))
+ return false;
+ if (!fFileBacked)
+ return true;
+ {
+ LOCK(cs_wallet);
+ if (pwalletdbEncryption)
+ return pwalletdbEncryption->WriteCryptedKey(vchPubKey,
+ vchCryptedSecret,
+ mapKeyMetadata[vchPubKey.GetID()]);
+ else
+ return CWalletDB(strWalletFile).WriteCryptedKey(vchPubKey,
+ vchCryptedSecret,
+ mapKeyMetadata[vchPubKey.GetID()]);
+ }
+ return false;
+}
+
+bool CWallet::LoadKeyMetadata(const CPubKey &pubkey, const CKeyMetadata &meta)
+{
+ AssertLockHeld(cs_wallet); // mapKeyMetadata
+ if (meta.nCreateTime && (!nTimeFirstKey || meta.nCreateTime < nTimeFirstKey))
+ nTimeFirstKey = meta.nCreateTime;
+
+ mapKeyMetadata[pubkey.GetID()] = meta;
+ return true;
+}
+
+bool CWallet::LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret)
+{
+ return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret);
+}
+
+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::LoadCScript(const CScript& redeemScript)
+{
+ /* A sanity check was added in pull #3843 to avoid adding redeemScripts
+ * that never can be redeemed. However, old wallets may still contain
+ * these. Do not add them to the wallet and warn. */
+ if (redeemScript.size() > MAX_SCRIPT_ELEMENT_SIZE)
+ {
+ std::string strAddr = CBitcoinAddress(CScriptID(redeemScript)).ToString();
+ LogPrintf("%s: Warning: This wallet contains a redeemScript of size %i which exceeds maximum size %i thus can never be redeemed. Do not use address %s.\n",
+ __func__, redeemScript.size(), MAX_SCRIPT_ELEMENT_SIZE, strAddr);
+ return true;
+ }
+
+ return CCryptoKeyStore::AddCScript(redeemScript);
+}
+
+bool CWallet::AddWatchOnly(const CScript &dest)
+{
+ if (!CCryptoKeyStore::AddWatchOnly(dest))
+ return false;
+ nTimeFirstKey = 1; // No birthday information for watch-only keys.
+ NotifyWatchonlyChanged(true);
+ if (!fFileBacked)
+ return true;
+ return CWalletDB(strWalletFile).WriteWatchOnly(dest);
+}
+
+bool CWallet::RemoveWatchOnly(const CScript &dest)
+{
+ AssertLockHeld(cs_wallet);
+ if (!CCryptoKeyStore::RemoveWatchOnly(dest))
+ return false;
+ if (!HaveWatchOnly())
+ NotifyWatchonlyChanged(false);
+ if (fFileBacked)
+ if (!CWalletDB(strWalletFile).EraseWatchOnly(dest))
+ return false;
+
+ return true;
+}
+
+bool CWallet::LoadWatchOnly(const CScript &dest)
+{
+ return CCryptoKeyStore::AddWatchOnly(dest);
+}
+
+bool CWallet::Unlock(const SecureString& strWalletPassphrase)
+{
+ 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))
+ continue; // try another master key
+ 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_t 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;
+
+ LogPrintf("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);
+}
+
+bool CWallet::SetMinVersion(enum WalletFeature nVersion, CWalletDB* pwalletdbIn, bool fExplicit)
+{
+ LOCK(cs_wallet); // nWalletVersion
+ 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)
+ pwalletdb->WriteMinVersion(nWalletVersion);
+ if (!pwalletdbIn)
+ delete pwalletdb;
+ }
+
+ return true;
+}
+
+bool CWallet::SetMaxVersion(int nVersion)
+{
+ LOCK(cs_wallet); // nWalletVersion, nWalletMaxVersion
+ // cannot downgrade below current version
+ if (nWalletVersion > nVersion)
+ return false;
+
+ nWalletMaxVersion = nVersion;
+
+ return true;
+}
+
+set<uint256> CWallet::GetConflicts(const uint256& txid) const
+{
+ set<uint256> result;
+ AssertLockHeld(cs_wallet);
+
+ std::map<uint256, CWalletTx>::const_iterator it = mapWallet.find(txid);
+ if (it == mapWallet.end())
+ return result;
+ const CWalletTx& wtx = it->second;
+
+ std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range;
+
+ BOOST_FOREACH(const CTxIn& txin, wtx.vin)
+ {
+ if (mapTxSpends.count(txin.prevout) <= 1)
+ continue; // No conflict if zero or one spends
+ range = mapTxSpends.equal_range(txin.prevout);
+ for (TxSpends::const_iterator it = range.first; it != range.second; ++it)
+ result.insert(it->second);
+ }
+ return result;
+}
+
+void CWallet::Flush(bool shutdown)
+{
+ bitdb.Flush(shutdown);
+}
+
+bool CWallet::Verify(const string& walletFile, string& warningString, string& errorString)
+{
+ if (!bitdb.Open(GetDataDir()))
+ {
+ // try moving the database env out of the way
+ boost::filesystem::path pathDatabase = GetDataDir() / "database";
+ boost::filesystem::path pathDatabaseBak = GetDataDir() / strprintf("database.%d.bak", GetTime());
+ try {
+ boost::filesystem::rename(pathDatabase, pathDatabaseBak);
+ LogPrintf("Moved old %s to %s. Retrying.\n", pathDatabase.string(), pathDatabaseBak.string());
+ } catch (const boost::filesystem::filesystem_error&) {
+ // failure is ok (well, not really, but it's not worse than what we started with)
+ }
+
+ // try again
+ if (!bitdb.Open(GetDataDir())) {
+ // if it still fails, it probably means we can't even create the database env
+ string msg = strprintf(_("Error initializing wallet database environment %s!"), GetDataDir());
+ errorString += msg;
+ return true;
+ }
+ }
+
+ if (GetBoolArg("-salvagewallet", false))
+ {
+ // Recover readable keypairs:
+ if (!CWalletDB::Recover(bitdb, walletFile, true))
+ return false;
+ }
+
+ if (boost::filesystem::exists(GetDataDir() / walletFile))
+ {
+ CDBEnv::VerifyResult r = bitdb.Verify(walletFile, CWalletDB::Recover);
+ if (r == CDBEnv::RECOVER_OK)
+ {
+ warningString += strprintf(_("Warning: wallet.dat corrupt, data salvaged!"
+ " Original wallet.dat saved as wallet.{timestamp}.bak in %s; if"
+ " your balance or transactions are incorrect you should"
+ " restore from a backup."), GetDataDir());
+ }
+ if (r == CDBEnv::RECOVER_FAIL)
+ errorString += _("wallet.dat corrupt, salvage failed");
+ }
+
+ return true;
+}
+
+void CWallet::SyncMetaData(pair<TxSpends::iterator, TxSpends::iterator> range)
+{
+ // We want all the wallet transactions in range to have the same metadata as
+ // the oldest (smallest nOrderPos).
+ // So: find smallest nOrderPos:
+
+ int nMinOrderPos = std::numeric_limits<int>::max();
+ const CWalletTx* copyFrom = NULL;
+ for (TxSpends::iterator it = range.first; it != range.second; ++it)
+ {
+ const uint256& hash = it->second;
+ int n = mapWallet[hash].nOrderPos;
+ if (n < nMinOrderPos)
+ {
+ nMinOrderPos = n;
+ copyFrom = &mapWallet[hash];
+ }
+ }
+ // Now copy data from copyFrom to rest:
+ for (TxSpends::iterator it = range.first; it != range.second; ++it)
+ {
+ const uint256& hash = it->second;
+ CWalletTx* copyTo = &mapWallet[hash];
+ if (copyFrom == copyTo) continue;
+ copyTo->mapValue = copyFrom->mapValue;
+ copyTo->vOrderForm = copyFrom->vOrderForm;
+ // fTimeReceivedIsTxTime not copied on purpose
+ // nTimeReceived not copied on purpose
+ copyTo->nTimeSmart = copyFrom->nTimeSmart;
+ copyTo->fFromMe = copyFrom->fFromMe;
+ copyTo->strFromAccount = copyFrom->strFromAccount;
+ // nOrderPos not copied on purpose
+ // cached members not copied on purpose
+ }
+}
+
+/**
+ * Outpoint is spent if any non-conflicted transaction
+ * spends it:
+ */
+bool CWallet::IsSpent(const uint256& hash, unsigned int n) const
+{
+ const COutPoint outpoint(hash, n);
+ pair<TxSpends::const_iterator, TxSpends::const_iterator> range;
+ range = mapTxSpends.equal_range(outpoint);
+
+ for (TxSpends::const_iterator it = range.first; it != range.second; ++it)
+ {
+ const uint256& wtxid = it->second;
+ std::map<uint256, CWalletTx>::const_iterator mit = mapWallet.find(wtxid);
+ if (mit != mapWallet.end() && mit->second.GetDepthInMainChain() >= 0)
+ return true; // Spent
+ }
+ return false;
+}
+
+void CWallet::AddToSpends(const COutPoint& outpoint, const uint256& wtxid)
+{
+ mapTxSpends.insert(make_pair(outpoint, wtxid));
+
+ pair<TxSpends::iterator, TxSpends::iterator> range;
+ range = mapTxSpends.equal_range(outpoint);
+ SyncMetaData(range);
+}
+
+
+void CWallet::AddToSpends(const uint256& wtxid)
+{
+ assert(mapWallet.count(wtxid));
+ CWalletTx& thisTx = mapWallet[wtxid];
+ if (thisTx.IsCoinBase()) // Coinbases don't spend anything!
+ return;
+
+ BOOST_FOREACH(const CTxIn& txin, thisTx.vin)
+ AddToSpends(txin.prevout, wtxid);
+}
+
+bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
+{
+ if (IsCrypted())
+ return false;
+
+ CKeyingMaterial vMasterKey;
+ RandAddSeedPerfmon();
+
+ vMasterKey.resize(WALLET_CRYPTO_KEY_SIZE);
+ GetRandBytes(&vMasterKey[0], WALLET_CRYPTO_KEY_SIZE);
+
+ CMasterKey kMasterKey;
+ RandAddSeedPerfmon();
+
+ kMasterKey.vchSalt.resize(WALLET_CRYPTO_SALT_SIZE);
+ GetRandBytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE);
+
+ CCrypter crypter;
+ int64_t 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;
+
+ LogPrintf("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)
+ {
+ assert(!pwalletdbEncryption);
+ pwalletdbEncryption = new CWalletDB(strWalletFile);
+ if (!pwalletdbEncryption->TxnBegin()) {
+ delete pwalletdbEncryption;
+ pwalletdbEncryption = NULL;
+ return false;
+ }
+ pwalletdbEncryption->WriteMasterKey(nMasterKeyMaxID, kMasterKey);
+ }
+
+ if (!EncryptKeys(vMasterKey))
+ {
+ if (fFileBacked) {
+ pwalletdbEncryption->TxnAbort();
+ delete pwalletdbEncryption;
+ }
+ // We now probably have half of our keys encrypted in memory, and half not...
+ // die and let the user reload the unencrypted wallet.
+ assert(false);
+ }
+
+ // Encryption was introduced in version 0.4.0
+ SetMinVersion(FEATURE_WALLETCRYPT, pwalletdbEncryption, true);
+
+ if (fFileBacked)
+ {
+ if (!pwalletdbEncryption->TxnCommit()) {
+ delete pwalletdbEncryption;
+ // We now have keys encrypted in memory, but not on disk...
+ // die to avoid confusion and let the user reload the unencrypted wallet.
+ assert(false);
+ }
+
+ 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;
+}
+
+int64_t CWallet::IncOrderPosNext(CWalletDB *pwalletdb)
+{
+ AssertLockHeld(cs_wallet); // nOrderPosNext
+ int64_t nRet = nOrderPosNext++;
+ if (pwalletdb) {
+ pwalletdb->WriteOrderPosNext(nOrderPosNext);
+ } else {
+ CWalletDB(strWalletFile).WriteOrderPosNext(nOrderPosNext);
+ }
+ return nRet;
+}
+
+CWallet::TxItems CWallet::OrderedTxItems(std::list<CAccountingEntry>& acentries, std::string strAccount)
+{
+ AssertLockHeld(cs_wallet); // mapWallet
+ CWalletDB walletdb(strWalletFile);
+
+ // First: get all CWalletTx and CAccountingEntry into a sorted-by-order multimap.
+ TxItems txOrdered;
+
+ // 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<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
+ {
+ CWalletTx* wtx = &((*it).second);
+ txOrdered.insert(make_pair(wtx->nOrderPos, TxPair(wtx, (CAccountingEntry*)0)));
+ }
+ acentries.clear();
+ walletdb.ListAccountCreditDebit(strAccount, acentries);
+ BOOST_FOREACH(CAccountingEntry& entry, acentries)
+ {
+ txOrdered.insert(make_pair(entry.nOrderPos, TxPair((CWalletTx*)0, &entry)));
+ }
+
+ return txOrdered;
+}
+
+void CWallet::MarkDirty()
+{
+ {
+ LOCK(cs_wallet);
+ BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
+ item.second.MarkDirty();
+ }
+}
+
+bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletDB* pwalletdb)
+{
+ uint256 hash = wtxIn.GetHash();
+
+ if (fFromLoadWallet)
+ {
+ mapWallet[hash] = wtxIn;
+ mapWallet[hash].BindWallet(this);
+ AddToSpends(hash);
+ }
+ else
+ {
+ LOCK(cs_wallet);
+ // Inserts only if not already there, returns tx inserted or tx found
+ pair<map<uint256, CWalletTx>::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();
+ wtx.nOrderPos = IncOrderPosNext(pwalletdb);
+
+ wtx.nTimeSmart = wtx.nTimeReceived;
+ if (!wtxIn.hashBlock.IsNull())
+ {
+ if (mapBlockIndex.count(wtxIn.hashBlock))
+ {
+ int64_t latestNow = wtx.nTimeReceived;
+ int64_t latestEntry = 0;
+ {
+ // Tolerate times up to the last timestamp in the wallet not more than 5 minutes into the future
+ int64_t latestTolerated = latestNow + 300;
+ std::list<CAccountingEntry> acentries;
+ TxItems txOrdered = OrderedTxItems(acentries);
+ for (TxItems::reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it)
+ {
+ CWalletTx *const pwtx = (*it).second.first;
+ if (pwtx == &wtx)
+ continue;
+ CAccountingEntry *const pacentry = (*it).second.second;
+ int64_t nSmartTime;
+ if (pwtx)
+ {
+ nSmartTime = pwtx->nTimeSmart;
+ if (!nSmartTime)
+ nSmartTime = pwtx->nTimeReceived;
+ }
+ else
+ nSmartTime = pacentry->nTime;
+ if (nSmartTime <= latestTolerated)
+ {
+ latestEntry = nSmartTime;
+ if (nSmartTime > latestNow)
+ latestNow = nSmartTime;
+ break;
+ }
+ }
+ }
+
+ int64_t blocktime = mapBlockIndex[wtxIn.hashBlock]->GetBlockTime();
+ wtx.nTimeSmart = std::max(latestEntry, std::min(blocktime, latestNow));
+ }
+ else
+ LogPrintf("AddToWallet(): found %s in block %s not in index\n",
+ wtxIn.GetHash().ToString(),
+ wtxIn.hashBlock.ToString());
+ }
+ AddToSpends(hash);
+ }
+
+ bool fUpdated = false;
+ if (!fInsertedNew)
+ {
+ // Merge
+ if (!wtxIn.hashBlock.IsNull() && 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;
+ }
+ }
+
+ //// debug print
+ LogPrintf("AddToWallet %s %s%s\n", wtxIn.GetHash().ToString(), (fInsertedNew ? "new" : ""), (fUpdated ? "update" : ""));
+
+ // Write to disk
+ if (fInsertedNew || fUpdated)
+ if (!wtx.WriteToDisk(pwalletdb))
+ return false;
+
+ // Break debit/credit balance caches:
+ wtx.MarkDirty();
+
+ // Notify UI of new or updated transaction
+ NotifyTransactionChanged(this, hash, fInsertedNew ? CT_NEW : CT_UPDATED);
+
+ // notify an external script when a wallet transaction comes in or is updated
+ std::string strCmd = GetArg("-walletnotify", "");
+
+ if ( !strCmd.empty())
+ {
+ boost::replace_all(strCmd, "%s", wtxIn.GetHash().GetHex());
+ boost::thread t(runCommand, strCmd); // thread runs free
+ }
+
+ }
+ 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)
+{
+ {
+ AssertLockHeld(cs_wallet);
+ bool fExisted = mapWallet.count(tx.GetHash()) != 0;
+ 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);
+
+ // Do not flush the wallet here for performance reasons
+ // this is safe, as in case of a crash, we rescan the necessary blocks on startup through our SetBestChain-mechanism
+ CWalletDB walletdb(strWalletFile, "r+", false);
+
+ return AddToWallet(wtx, false, &walletdb);
+ }
+ }
+ return false;
+}
+
+void CWallet::SyncTransaction(const CTransaction& tx, const CBlock* pblock)
+{
+ LOCK2(cs_main, cs_wallet);
+ if (!AddToWalletIfInvolvingMe(tx, pblock, true))
+ return; // Not one of ours
+
+ // If a transaction changes 'conflicted' state, that changes the balance
+ // available of the outputs it spends. So force those to be
+ // recomputed, also:
+ BOOST_FOREACH(const CTxIn& txin, tx.vin)
+ {
+ if (mapWallet.count(txin.prevout.hash))
+ mapWallet[txin.prevout.hash].MarkDirty();
+ }
+}
+
+void CWallet::EraseFromWallet(const uint256 &hash)
+{
+ if (!fFileBacked)
+ return;
+ {
+ LOCK(cs_wallet);
+ if (mapWallet.erase(hash))
+ CWalletDB(strWalletFile).EraseTx(hash);
+ }
+ return;
+}
+
+
+isminetype CWallet::IsMine(const CTxIn &txin) const
+{
+ {
+ LOCK(cs_wallet);
+ map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
+ if (mi != mapWallet.end())
+ {
+ const CWalletTx& prev = (*mi).second;
+ if (txin.prevout.n < prev.vout.size())
+ return IsMine(prev.vout[txin.prevout.n]);
+ }
+ }
+ return ISMINE_NO;
+}
+
+CAmount CWallet::GetDebit(const CTxIn &txin, const isminefilter& filter) const
+{
+ {
+ LOCK(cs_wallet);
+ map<uint256, CWalletTx>::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]) & filter)
+ return prev.vout[txin.prevout.n].nValue;
+ }
+ }
+ return 0;
+}
+
+isminetype CWallet::IsMine(const CTxOut& txout) const
+{
+ return ::IsMine(*this, txout.scriptPubKey);
+}
+
+CAmount CWallet::GetCredit(const CTxOut& txout, const isminefilter& filter) const
+{
+ if (!MoneyRange(txout.nValue))
+ throw std::runtime_error("CWallet::GetCredit(): value out of range");
+ return ((IsMine(txout) & filter) ? txout.nValue : 0);
+}
+
+bool CWallet::IsChange(const CTxOut& txout) const
+{
+ // TODO: fix handling of 'change' outputs. The assumption is that any
+ // payment to a script that is ours, but is not 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 (::IsMine(*this, txout.scriptPubKey))
+ {
+ CTxDestination address;
+ if (!ExtractDestination(txout.scriptPubKey, address))
+ return true;
+
+ LOCK(cs_wallet);
+ if (!mapAddressBook.count(address))
+ return true;
+ }
+ return false;
+}
+
+CAmount CWallet::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 CWallet::IsMine(const CTransaction& tx) const
+{
+ BOOST_FOREACH(const CTxOut& txout, tx.vout)
+ if (IsMine(txout))
+ return true;
+ return false;
+}
+
+bool CWallet::IsFromMe(const CTransaction& tx) const
+{
+ return (GetDebit(tx, ISMINE_ALL) > 0);
+}
+
+CAmount CWallet::GetDebit(const CTransaction& tx, const isminefilter& filter) const
+{
+ CAmount nDebit = 0;
+ BOOST_FOREACH(const CTxIn& txin, tx.vin)
+ {
+ nDebit += GetDebit(txin, filter);
+ if (!MoneyRange(nDebit))
+ throw std::runtime_error("CWallet::GetDebit(): value out of range");
+ }
+ return nDebit;
+}
+
+CAmount CWallet::GetCredit(const CTransaction& tx, const isminefilter& filter) const
+{
+ CAmount nCredit = 0;
+ BOOST_FOREACH(const CTxOut& txout, tx.vout)
+ {
+ nCredit += GetCredit(txout, filter);
+ if (!MoneyRange(nCredit))
+ throw std::runtime_error("CWallet::GetCredit(): value out of range");
+ }
+ return nCredit;
+}
+
+CAmount CWallet::GetChange(const CTransaction& tx) const
+{
+ CAmount 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;
+}
+
+int64_t CWalletTx::GetTxTime() const
+{
+ int64_t n = nTimeSmart;
+ return n ? n : 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.IsNull())
+ {
+ map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock);
+ if (mi != pwallet->mapRequestCount.end())
+ nRequests = (*mi).second;
+ }
+ }
+ else
+ {
+ // Did anyone request this transaction?
+ map<uint256, int>::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.IsNull())
+ {
+ map<uint256, int>::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(list<COutputEntry>& listReceived,
+ list<COutputEntry>& listSent, CAmount& nFee, string& strSentAccount, const isminefilter& filter) const
+{
+ nFee = 0;
+ listReceived.clear();
+ listSent.clear();
+ strSentAccount = strFromAccount;
+
+ // Compute fee:
+ CAmount nDebit = GetDebit(filter);
+ if (nDebit > 0) // debit>0 means we signed/sent this transaction
+ {
+ CAmount nValueOut = GetValueOut();
+ nFee = nDebit - nValueOut;
+ }
+
+ // Sent/received.
+ for (unsigned int i = 0; i < vout.size(); ++i)
+ {
+ const CTxOut& txout = vout[i];
+ isminetype fIsMine = pwallet->IsMine(txout);
+ // Only need to handle txouts if AT LEAST one of these is true:
+ // 1) they debit from us (sent)
+ // 2) the output is to us (received)
+ if (nDebit > 0)
+ {
+ // Don't report 'change' txouts
+ if (pwallet->IsChange(txout))
+ continue;
+ }
+ else if (!(fIsMine & filter))
+ continue;
+
+ // In either case, we need to get the destination address
+ CTxDestination address;
+ if (!ExtractDestination(txout.scriptPubKey, address))
+ {
+ LogPrintf("CWalletTx::GetAmounts: Unknown transaction type found, txid %s\n",
+ this->GetHash().ToString());
+ address = CNoDestination();
+ }
+
+ COutputEntry output = {address, txout.nValue, (int)i};
+
+ // If we are debited by the transaction, add the output as a "sent" entry
+ if (nDebit > 0)
+ listSent.push_back(output);
+
+ // If we are receiving the output, add it as a "received" entry
+ if (fIsMine & filter)
+ listReceived.push_back(output);
+ }
+
+}
+
+void CWalletTx::GetAccountAmounts(const string& strAccount, CAmount& nReceived,
+ CAmount& nSent, CAmount& nFee, const isminefilter& filter) const
+{
+ nReceived = nSent = nFee = 0;
+
+ CAmount allFee;
+ string strSentAccount;
+ list<COutputEntry> listReceived;
+ list<COutputEntry> listSent;
+ GetAmounts(listReceived, listSent, allFee, strSentAccount, filter);
+
+ if (strAccount == strSentAccount)
+ {
+ BOOST_FOREACH(const COutputEntry& s, listSent)
+ nSent += s.amount;
+ nFee = allFee;
+ }
+ {
+ LOCK(pwallet->cs_wallet);
+ BOOST_FOREACH(const COutputEntry& r, listReceived)
+ {
+ if (pwallet->mapAddressBook.count(r.destination))
+ {
+ map<CTxDestination, CAddressBookData>::const_iterator mi = pwallet->mapAddressBook.find(r.destination);
+ if (mi != pwallet->mapAddressBook.end() && (*mi).second.name == strAccount)
+ nReceived += r.amount;
+ }
+ else if (strAccount.empty())
+ {
+ nReceived += r.amount;
+ }
+ }
+ }
+}
+
+
+bool CWalletTx::WriteToDisk(CWalletDB *pwalletdb)
+{
+ return pwalletdb->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;
+ int64_t nNow = GetTime();
+ const CChainParams& chainParams = Params();
+
+ CBlockIndex* pindex = pindexStart;
+ {
+ LOCK2(cs_main, cs_wallet);
+
+ // no need to read and scan block, if block was created before
+ // our wallet birthday (as adjusted for block time variability)
+ while (pindex && nTimeFirstKey && (pindex->GetBlockTime() < (nTimeFirstKey - 7200)))
+ pindex = chainActive.Next(pindex);
+
+ ShowProgress(_("Rescanning..."), 0); // show rescan progress in GUI as dialog or on splashscreen, if -rescan on startup
+ double dProgressStart = Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), pindex, false);
+ double dProgressTip = Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), chainActive.Tip(), false);
+ while (pindex)
+ {
+ if (pindex->nHeight % 100 == 0 && dProgressTip - dProgressStart > 0.0)
+ ShowProgress(_("Rescanning..."), std::max(1, std::min(99, (int)((Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), pindex, false) - dProgressStart) / (dProgressTip - dProgressStart) * 100))));
+
+ CBlock block;
+ ReadBlockFromDisk(block, pindex);
+ BOOST_FOREACH(CTransaction& tx, block.vtx)
+ {
+ if (AddToWalletIfInvolvingMe(tx, &block, fUpdate))
+ ret++;
+ }
+ pindex = chainActive.Next(pindex);
+ if (GetTime() >= nNow + 60) {
+ nNow = GetTime();
+ LogPrintf("Still rescanning. At block %d. Progress=%f\n", pindex->nHeight, Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), pindex));
+ }
+ }
+ ShowProgress(_("Rescanning..."), 100); // hide progress dialog in GUI
+ }
+ return ret;
+}
+
+void CWallet::ReacceptWalletTransactions()
+{
+ // If transactions aren't being broadcasted, don't let them into local mempool either
+ if (!fBroadcastTransactions)
+ return;
+ LOCK2(cs_main, cs_wallet);
+ std::map<int64_t, CWalletTx*> mapSorted;
+
+ // Sort pending wallet transactions based on their initial wallet insertion order
+ BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
+ {
+ const uint256& wtxid = item.first;
+ CWalletTx& wtx = item.second;
+ assert(wtx.GetHash() == wtxid);
+
+ int nDepth = wtx.GetDepthInMainChain();
+
+ if (!wtx.IsCoinBase() && nDepth < 0) {
+ mapSorted.insert(std::make_pair(wtx.nOrderPos, &wtx));
+ }
+ }
+
+ // Try to add wallet transactions to memory pool
+ BOOST_FOREACH(PAIRTYPE(const int64_t, CWalletTx*)& item, mapSorted)
+ {
+ CWalletTx& wtx = *(item.second);
+
+ LOCK(mempool.cs);
+ wtx.AcceptToMemoryPool(false);
+ }
+}
+
+bool CWalletTx::RelayWalletTransaction()
+{
+ assert(pwallet->GetBroadcastTransactions());
+ if (!IsCoinBase())
+ {
+ if (GetDepthInMainChain() == 0) {
+ LogPrintf("Relaying wtx %s\n", GetHash().ToString());
+ RelayTransaction((CTransaction)*this);
+ return true;
+ }
+ }
+ return false;
+}
+
+set<uint256> CWalletTx::GetConflicts() const
+{
+ set<uint256> result;
+ if (pwallet != NULL)
+ {
+ uint256 myHash = GetHash();
+ result = pwallet->GetConflicts(myHash);
+ result.erase(myHash);
+ }
+ return result;
+}
+
+CAmount CWalletTx::GetDebit(const isminefilter& filter) const
+{
+ if (vin.empty())
+ return 0;
+
+ CAmount debit = 0;
+ if(filter & ISMINE_SPENDABLE)
+ {
+ if (fDebitCached)
+ debit += nDebitCached;
+ else
+ {
+ nDebitCached = pwallet->GetDebit(*this, ISMINE_SPENDABLE);
+ fDebitCached = true;
+ debit += nDebitCached;
+ }
+ }
+ if(filter & ISMINE_WATCH_ONLY)
+ {
+ if(fWatchDebitCached)
+ debit += nWatchDebitCached;
+ else
+ {
+ nWatchDebitCached = pwallet->GetDebit(*this, ISMINE_WATCH_ONLY);
+ fWatchDebitCached = true;
+ debit += nWatchDebitCached;
+ }
+ }
+ return debit;
+}
+
+CAmount CWalletTx::GetCredit(const isminefilter& filter) const
+{
+ // Must wait until coinbase is safely deep enough in the chain before valuing it
+ if (IsCoinBase() && GetBlocksToMaturity() > 0)
+ return 0;
+
+ int64_t credit = 0;
+ if (filter & ISMINE_SPENDABLE)
+ {
+ // GetBalance can assume transactions in mapWallet won't change
+ if (fCreditCached)
+ credit += nCreditCached;
+ else
+ {
+ nCreditCached = pwallet->GetCredit(*this, ISMINE_SPENDABLE);
+ fCreditCached = true;
+ credit += nCreditCached;
+ }
+ }
+ if (filter & ISMINE_WATCH_ONLY)
+ {
+ if (fWatchCreditCached)
+ credit += nWatchCreditCached;
+ else
+ {
+ nWatchCreditCached = pwallet->GetCredit(*this, ISMINE_WATCH_ONLY);
+ fWatchCreditCached = true;
+ credit += nWatchCreditCached;
+ }
+ }
+ return credit;
+}
+
+CAmount CWalletTx::GetImmatureCredit(bool fUseCache) const
+{
+ if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain())
+ {
+ if (fUseCache && fImmatureCreditCached)
+ return nImmatureCreditCached;
+ nImmatureCreditCached = pwallet->GetCredit(*this, ISMINE_SPENDABLE);
+ fImmatureCreditCached = true;
+ return nImmatureCreditCached;
+ }
+
+ return 0;
+}
+
+CAmount CWalletTx::GetAvailableCredit(bool fUseCache) const
+{
+ if (pwallet == 0)
+ return 0;
+
+ // 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;
+
+ CAmount nCredit = 0;
+ uint256 hashTx = GetHash();
+ for (unsigned int i = 0; i < vout.size(); i++)
+ {
+ if (!pwallet->IsSpent(hashTx, i))
+ {
+ const CTxOut &txout = vout[i];
+ nCredit += pwallet->GetCredit(txout, ISMINE_SPENDABLE);
+ if (!MoneyRange(nCredit))
+ throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range");
+ }
+ }
+
+ nAvailableCreditCached = nCredit;
+ fAvailableCreditCached = true;
+ return nCredit;
+}
+
+CAmount CWalletTx::GetImmatureWatchOnlyCredit(const bool& fUseCache) const
+{
+ if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain())
+ {
+ if (fUseCache && fImmatureWatchCreditCached)
+ return nImmatureWatchCreditCached;
+ nImmatureWatchCreditCached = pwallet->GetCredit(*this, ISMINE_WATCH_ONLY);
+ fImmatureWatchCreditCached = true;
+ return nImmatureWatchCreditCached;
+ }
+
+ return 0;
+}
+
+CAmount CWalletTx::GetAvailableWatchOnlyCredit(const bool& fUseCache) const
+{
+ if (pwallet == 0)
+ return 0;
+
+ // Must wait until coinbase is safely deep enough in the chain before valuing it
+ if (IsCoinBase() && GetBlocksToMaturity() > 0)
+ return 0;
+
+ if (fUseCache && fAvailableWatchCreditCached)
+ return nAvailableWatchCreditCached;
+
+ CAmount nCredit = 0;
+ for (unsigned int i = 0; i < vout.size(); i++)
+ {
+ if (!pwallet->IsSpent(GetHash(), i))
+ {
+ const CTxOut &txout = vout[i];
+ nCredit += pwallet->GetCredit(txout, ISMINE_WATCH_ONLY);
+ if (!MoneyRange(nCredit))
+ throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range");
+ }
+ }
+
+ nAvailableWatchCreditCached = nCredit;
+ fAvailableWatchCreditCached = true;
+ return nCredit;
+}
+
+CAmount CWalletTx::GetChange() const
+{
+ if (fChangeCached)
+ return nChangeCached;
+ nChangeCached = pwallet->GetChange(*this);
+ fChangeCached = true;
+ return nChangeCached;
+}
+
+bool CWalletTx::IsTrusted() const
+{
+ // Quick answer in most cases
+ if (!CheckFinalTx(*this))
+ return false;
+ int nDepth = GetDepthInMainChain();
+ if (nDepth >= 1)
+ return true;
+ if (nDepth < 0)
+ return false;
+ if (!bSpendZeroConfChange || !IsFromMe(ISMINE_ALL)) // using wtx's cached debit
+ return false;
+
+ // Trusted if all inputs are from us and are in the mempool:
+ BOOST_FOREACH(const CTxIn& txin, vin)
+ {
+ // Transactions not sent by us: not trusted
+ const CWalletTx* parent = pwallet->GetWalletTx(txin.prevout.hash);
+ if (parent == NULL)
+ return false;
+ const CTxOut& parentOut = parent->vout[txin.prevout.n];
+ if (pwallet->IsMine(parentOut) != ISMINE_SPENDABLE)
+ return false;
+ }
+ return true;
+}
+
+std::vector<uint256> CWallet::ResendWalletTransactionsBefore(int64_t nTime)
+{
+ std::vector<uint256> result;
+
+ LOCK(cs_wallet);
+ // Sort them in chronological order
+ multimap<unsigned int, CWalletTx*> mapSorted;
+ BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
+ {
+ CWalletTx& wtx = item.second;
+ // Don't rebroadcast if newer than nTime:
+ if (wtx.nTimeReceived > nTime)
+ continue;
+ mapSorted.insert(make_pair(wtx.nTimeReceived, &wtx));
+ }
+ BOOST_FOREACH(PAIRTYPE(const unsigned int, CWalletTx*)& item, mapSorted)
+ {
+ CWalletTx& wtx = *item.second;
+ if (wtx.RelayWalletTransaction())
+ result.push_back(wtx.GetHash());
+ }
+ return result;
+}
+
+void CWallet::ResendWalletTransactions(int64_t nBestBlockTime)
+{
+ // Do this infrequently and randomly to avoid giving away
+ // that these are our transactions.
+ if (GetTime() < nNextResend || !fBroadcastTransactions)
+ return;
+ bool fFirst = (nNextResend == 0);
+ nNextResend = GetTime() + GetRand(30 * 60);
+ if (fFirst)
+ return;
+
+ // Only do it if there's been a new block since last time
+ if (nBestBlockTime < nLastResend)
+ return;
+ nLastResend = GetTime();
+
+ // Rebroadcast unconfirmed txes older than 5 minutes before the last
+ // block was found:
+ std::vector<uint256> relayed = ResendWalletTransactionsBefore(nBestBlockTime-5*60);
+ if (!relayed.empty())
+ LogPrintf("%s: rebroadcast %u unconfirmed transactions\n", __func__, relayed.size());
+}
+
+/** @} */ // end of mapWallet
+
+
+
+
+/** @defgroup Actions
+ *
+ * @{
+ */
+
+
+CAmount CWallet::GetBalance() const
+{
+ CAmount nTotal = 0;
+ {
+ LOCK2(cs_main, cs_wallet);
+ for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
+ {
+ const CWalletTx* pcoin = &(*it).second;
+ if (pcoin->IsTrusted())
+ nTotal += pcoin->GetAvailableCredit();
+ }
+ }
+
+ return nTotal;
+}
+
+CAmount CWallet::GetUnconfirmedBalance() const
+{
+ CAmount nTotal = 0;
+ {
+ LOCK2(cs_main, cs_wallet);
+ for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
+ {
+ const CWalletTx* pcoin = &(*it).second;
+ if (!CheckFinalTx(*pcoin) || (!pcoin->IsTrusted() && pcoin->GetDepthInMainChain() == 0))
+ nTotal += pcoin->GetAvailableCredit();
+ }
+ }
+ return nTotal;
+}
+
+CAmount CWallet::GetImmatureBalance() const
+{
+ CAmount nTotal = 0;
+ {
+ LOCK2(cs_main, cs_wallet);
+ for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
+ {
+ const CWalletTx* pcoin = &(*it).second;
+ nTotal += pcoin->GetImmatureCredit();
+ }
+ }
+ return nTotal;
+}
+
+CAmount CWallet::GetWatchOnlyBalance() const
+{
+ CAmount nTotal = 0;
+ {
+ LOCK2(cs_main, cs_wallet);
+ for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
+ {
+ const CWalletTx* pcoin = &(*it).second;
+ if (pcoin->IsTrusted())
+ nTotal += pcoin->GetAvailableWatchOnlyCredit();
+ }
+ }
+
+ return nTotal;
+}
+
+CAmount CWallet::GetUnconfirmedWatchOnlyBalance() const
+{
+ CAmount nTotal = 0;
+ {
+ LOCK2(cs_main, cs_wallet);
+ for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
+ {
+ const CWalletTx* pcoin = &(*it).second;
+ if (!CheckFinalTx(*pcoin) || (!pcoin->IsTrusted() && pcoin->GetDepthInMainChain() == 0))
+ nTotal += pcoin->GetAvailableWatchOnlyCredit();
+ }
+ }
+ return nTotal;
+}
+
+CAmount CWallet::GetImmatureWatchOnlyBalance() const
+{
+ CAmount nTotal = 0;
+ {
+ LOCK2(cs_main, cs_wallet);
+ for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
+ {
+ const CWalletTx* pcoin = &(*it).second;
+ nTotal += pcoin->GetImmatureWatchOnlyCredit();
+ }
+ }
+ return nTotal;
+}
+
+/**
+ * populate vCoins with vector of available COutputs.
+ */
+void CWallet::AvailableCoins(vector<COutput>& vCoins, bool fOnlyConfirmed, const CCoinControl *coinControl, bool fIncludeZeroValue) const
+{
+ vCoins.clear();
+
+ {
+ LOCK2(cs_main, cs_wallet);
+ for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
+ {
+ const uint256& wtxid = it->first;
+ const CWalletTx* pcoin = &(*it).second;
+
+ if (!CheckFinalTx(*pcoin))
+ continue;
+
+ if (fOnlyConfirmed && !pcoin->IsTrusted())
+ continue;
+
+ if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0)
+ continue;
+
+ int nDepth = pcoin->GetDepthInMainChain();
+ if (nDepth < 0)
+ continue;
+
+ for (unsigned int i = 0; i < pcoin->vout.size(); i++) {
+ isminetype mine = IsMine(pcoin->vout[i]);
+ if (!(IsSpent(wtxid, i)) && mine != ISMINE_NO &&
+ !IsLockedCoin((*it).first, i) && (pcoin->vout[i].nValue > 0 || fIncludeZeroValue) &&
+ (!coinControl || !coinControl->HasSelected() || coinControl->IsSelected((*it).first, i)))
+ vCoins.push_back(COutput(pcoin, i, nDepth, (mine & ISMINE_SPENDABLE) != ISMINE_NO));
+ }
+ }
+ }
+}
+
+static void ApproximateBestSubset(vector<pair<CAmount, pair<const CWalletTx*,unsigned int> > >vValue, const CAmount& nTotalLower, const CAmount& nTargetValue,
+ vector<char>& vfBest, CAmount& nBest, int iterations = 1000)
+{
+ vector<char> vfIncluded;
+
+ vfBest.assign(vValue.size(), true);
+ nBest = nTotalLower;
+
+ seed_insecure_rand();
+
+ for (int nRep = 0; nRep < iterations && nBest != nTargetValue; nRep++)
+ {
+ vfIncluded.assign(vValue.size(), false);
+ CAmount nTotal = 0;
+ bool fReachedTarget = false;
+ for (int nPass = 0; nPass < 2 && !fReachedTarget; nPass++)
+ {
+ for (unsigned int i = 0; i < vValue.size(); i++)
+ {
+ //The solver here uses a randomized algorithm,
+ //the randomness serves no real security purpose but is just
+ //needed to prevent degenerate behavior and it is important
+ //that the rng is fast. We do not use a constant random sequence,
+ //because there may be some privacy improvement by making
+ //the selection random.
+ if (nPass == 0 ? insecure_rand()&1 : !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(const CAmount& nTargetValue, int nConfMine, int nConfTheirs, vector<COutput> vCoins,
+ set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet) const
+{
+ setCoinsRet.clear();
+ nValueRet = 0;
+
+ // List of values less than target
+ pair<CAmount, pair<const CWalletTx*,unsigned int> > coinLowestLarger;
+ coinLowestLarger.first = std::numeric_limits<CAmount>::max();
+ coinLowestLarger.second.first = NULL;
+ vector<pair<CAmount, pair<const CWalletTx*,unsigned int> > > vValue;
+ CAmount nTotalLower = 0;
+
+ random_shuffle(vCoins.begin(), vCoins.end(), GetRandInt);
+
+ BOOST_FOREACH(const COutput &output, vCoins)
+ {
+ if (!output.fSpendable)
+ continue;
+
+ const CWalletTx *pcoin = output.tx;
+
+ if (output.nDepth < (pcoin->IsFromMe(ISMINE_ALL) ? nConfMine : nConfTheirs))
+ continue;
+
+ int i = output.i;
+ CAmount n = pcoin->vout[i].nValue;
+
+ pair<CAmount,pair<const CWalletTx*,unsigned int> > 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<char> vfBest;
+ CAmount 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;
+ }
+
+ LogPrint("selectcoins", "SelectCoins() best subset: ");
+ for (unsigned int i = 0; i < vValue.size(); i++)
+ if (vfBest[i])
+ LogPrint("selectcoins", "%s ", FormatMoney(vValue[i].first));
+ LogPrint("selectcoins", "total %s\n", FormatMoney(nBest));
+ }
+
+ return true;
+}
+
+bool CWallet::SelectCoins(const CAmount& nTargetValue, set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet, const CCoinControl* coinControl) const
+{
+ vector<COutput> vCoins;
+ AvailableCoins(vCoins, true, coinControl);
+
+ // coin control -> return all selected outputs (we want all selected to go into the transaction for sure)
+ if (coinControl && coinControl->HasSelected())
+ {
+ BOOST_FOREACH(const COutput& out, vCoins)
+ {
+ if(!out.fSpendable)
+ continue;
+ nValueRet += out.tx->vout[out.i].nValue;
+ setCoinsRet.insert(make_pair(out.tx, out.i));
+ }
+ return (nValueRet >= nTargetValue);
+ }
+
+ return (SelectCoinsMinConf(nTargetValue, 1, 6, vCoins, setCoinsRet, nValueRet) ||
+ SelectCoinsMinConf(nTargetValue, 1, 1, vCoins, setCoinsRet, nValueRet) ||
+ (bSpendZeroConfChange && SelectCoinsMinConf(nTargetValue, 0, 1, vCoins, setCoinsRet, nValueRet)));
+}
+
+bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend,
+ CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosRet, std::string& strFailReason, const CCoinControl* coinControl)
+{
+ CAmount nValue = 0;
+ unsigned int nSubtractFeeFromAmount = 0;
+ BOOST_FOREACH (const CRecipient& recipient, vecSend)
+ {
+ if (nValue < 0 || recipient.nAmount < 0)
+ {
+ strFailReason = _("Transaction amounts must be positive");
+ return false;
+ }
+ nValue += recipient.nAmount;
+
+ if (recipient.fSubtractFeeFromAmount)
+ nSubtractFeeFromAmount++;
+ }
+ if (vecSend.empty() || nValue < 0)
+ {
+ strFailReason = _("Transaction amounts must be positive");
+ return false;
+ }
+
+ wtxNew.fTimeReceivedIsTxTime = true;
+ wtxNew.BindWallet(this);
+ CMutableTransaction txNew;
+
+ // Discourage fee sniping.
+ //
+ // However because of a off-by-one-error in previous versions we need to
+ // neuter it by setting nLockTime to at least one less than nBestHeight.
+ // Secondly currently propagation of transactions created for block heights
+ // corresponding to blocks that were just mined may be iffy - transactions
+ // aren't re-accepted into the mempool - we additionally neuter the code by
+ // going ten blocks back. Doesn't yet do anything for sniping, but does act
+ // to shake out wallet bugs like not showing nLockTime'd transactions at
+ // all.
+ txNew.nLockTime = std::max(0, chainActive.Height() - 10);
+
+ // Secondly occasionally randomly pick a nLockTime even further back, so
+ // that transactions that are delayed after signing for whatever reason,
+ // e.g. high-latency mix networks and some CoinJoin implementations, have
+ // better privacy.
+ if (GetRandInt(10) == 0)
+ txNew.nLockTime = std::max(0, (int)txNew.nLockTime - GetRandInt(100));
+
+ assert(txNew.nLockTime <= (unsigned int)chainActive.Height());
+ assert(txNew.nLockTime < LOCKTIME_THRESHOLD);
+
+ {
+ LOCK2(cs_main, cs_wallet);
+ {
+ nFeeRet = 0;
+ while (true)
+ {
+ txNew.vin.clear();
+ txNew.vout.clear();
+ wtxNew.fFromMe = true;
+ nChangePosRet = -1;
+ bool fFirst = true;
+
+ CAmount nTotalValue = nValue;
+ if (nSubtractFeeFromAmount == 0)
+ nTotalValue += nFeeRet;
+ double dPriority = 0;
+ // vouts to the payees
+ BOOST_FOREACH (const CRecipient& recipient, vecSend)
+ {
+ CTxOut txout(recipient.nAmount, recipient.scriptPubKey);
+
+ if (recipient.fSubtractFeeFromAmount)
+ {
+ txout.nValue -= nFeeRet / nSubtractFeeFromAmount; // Subtract fee equally from each selected recipient
+
+ if (fFirst) // first receiver pays the remainder not divisible by output count
+ {
+ fFirst = false;
+ txout.nValue -= nFeeRet % nSubtractFeeFromAmount;
+ }
+ }
+
+ if (txout.IsDust(::minRelayTxFee))
+ {
+ if (recipient.fSubtractFeeFromAmount && nFeeRet > 0)
+ {
+ if (txout.nValue < 0)
+ strFailReason = _("The transaction amount is too small to pay the fee");
+ else
+ strFailReason = _("The transaction amount is too small to send after the fee has been deducted");
+ }
+ else
+ strFailReason = _("Transaction amount too small");
+ return false;
+ }
+ txNew.vout.push_back(txout);
+ }
+
+ // Choose coins to use
+ set<pair<const CWalletTx*,unsigned int> > setCoins;
+ CAmount nValueIn = 0;
+ if (!SelectCoins(nTotalValue, setCoins, nValueIn, coinControl))
+ {
+ strFailReason = _("Insufficient funds");
+ return false;
+ }
+ BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins)
+ {
+ CAmount nCredit = pcoin.first->vout[pcoin.second].nValue;
+ //The coin age after the next block (depth+1) is used instead of the current,
+ //reflecting an assumption the user would accept a bit more delay for
+ //a chance at a free transaction.
+ //But mempool inputs might still be in the mempool, so their age stays 0
+ int age = pcoin.first->GetDepthInMainChain();
+ if (age != 0)
+ age += 1;
+ dPriority += (double)nCredit * age;
+ }
+
+ CAmount nChange = nValueIn - nValue;
+ if (nSubtractFeeFromAmount == 0)
+ nChange -= nFeeRet;
+
+ if (nChange > 0)
+ {
+ // Fill a vout to ourself
+ // TODO: pass in scriptChange instead of reservekey so
+ // change transaction isn't always pay-to-bitcoin-address
+ CScript scriptChange;
+
+ // coin control: send change to custom address
+ if (coinControl && !boost::get<CNoDestination>(&coinControl->destChange))
+ scriptChange = GetScriptForDestination(coinControl->destChange);
+
+ // no coin control: send change to newly generated address
+ else
+ {
+ // 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;
+ bool ret;
+ ret = reservekey.GetReservedKey(vchPubKey);
+ assert(ret); // should never fail, as we just unlocked
+
+ scriptChange = GetScriptForDestination(vchPubKey.GetID());
+ }
+
+ CTxOut newTxOut(nChange, scriptChange);
+
+ // We do not move dust-change to fees, because the sender would end up paying more than requested.
+ // This would be against the purpose of the all-inclusive feature.
+ // So instead we raise the change and deduct from the recipient.
+ if (nSubtractFeeFromAmount > 0 && newTxOut.IsDust(::minRelayTxFee))
+ {
+ CAmount nDust = newTxOut.GetDustThreshold(::minRelayTxFee) - newTxOut.nValue;
+ newTxOut.nValue += nDust; // raise change until no more dust
+ for (unsigned int i = 0; i < vecSend.size(); i++) // subtract from first recipient
+ {
+ if (vecSend[i].fSubtractFeeFromAmount)
+ {
+ txNew.vout[i].nValue -= nDust;
+ if (txNew.vout[i].IsDust(::minRelayTxFee))
+ {
+ strFailReason = _("The transaction amount is too small to send after the fee has been deducted");
+ return false;
+ }
+ break;
+ }
+ }
+ }
+
+ // Never create dust outputs; if we would, just
+ // add the dust to the fee.
+ if (newTxOut.IsDust(::minRelayTxFee))
+ {
+ nFeeRet += nChange;
+ reservekey.ReturnKey();
+ }
+ else
+ {
+ // Insert change txn at random position:
+ nChangePosRet = GetRandInt(txNew.vout.size()+1);
+ vector<CTxOut>::iterator position = txNew.vout.begin()+nChangePosRet;
+ txNew.vout.insert(position, newTxOut);
+ }
+ }
+ else
+ reservekey.ReturnKey();
+
+ // Fill vin
+ //
+ // Note how the sequence number is set to max()-1 so that the
+ // nLockTime set above actually works.
+ BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
+ txNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second,CScript(),
+ std::numeric_limits<unsigned int>::max()-1));
+
+ // Sign
+ int nIn = 0;
+ BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
+ if (!SignSignature(*this, *coin.first, txNew, nIn++))
+ {
+ strFailReason = _("Signing transaction failed");
+ return false;
+ }
+
+ // Embed the constructed transaction data in wtxNew.
+ *static_cast<CTransaction*>(&wtxNew) = CTransaction(txNew);
+
+ // Limit size
+ unsigned int nBytes = ::GetSerializeSize(*(CTransaction*)&wtxNew, SER_NETWORK, PROTOCOL_VERSION);
+ if (nBytes >= MAX_STANDARD_TX_SIZE)
+ {
+ strFailReason = _("Transaction too large");
+ return false;
+ }
+ dPriority = wtxNew.ComputePriority(dPriority, nBytes);
+
+ // Can we complete this as a free transaction?
+ if (fSendFreeTransactions && nBytes <= MAX_FREE_TRANSACTION_CREATE_SIZE)
+ {
+ // Not enough fee: enough priority?
+ double dPriorityNeeded = mempool.estimatePriority(nTxConfirmTarget);
+ // Not enough mempool history to estimate: use hard-coded AllowFree.
+ if (dPriorityNeeded <= 0 && AllowFree(dPriority))
+ break;
+
+ // Small enough, and priority high enough, to send for free
+ if (dPriorityNeeded > 0 && dPriority >= dPriorityNeeded)
+ break;
+ }
+
+ CAmount nFeeNeeded = GetMinimumFee(nBytes, nTxConfirmTarget, mempool);
+
+ // If we made it here and we aren't even able to meet the relay fee on the next pass, give up
+ // because we must be at the maximum allowed fee.
+ if (nFeeNeeded < ::minRelayTxFee.GetFee(nBytes))
+ {
+ strFailReason = _("Transaction too large for fee policy");
+ return false;
+ }
+
+ if (nFeeRet >= nFeeNeeded)
+ break; // Done, enough fee included.
+
+ // Include more fee and try again.
+ nFeeRet = nFeeNeeded;
+ continue;
+ }
+ }
+ }
+
+ return true;
+}
+
+/**
+ * Call after CreateTransaction unless you want to abort
+ */
+bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey)
+{
+ {
+ LOCK2(cs_main, cs_wallet);
+ LogPrintf("CommitTransaction:\n%s", wtxNew.ToString());
+ {
+ // 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, false, pwalletdb);
+
+ // Notify that old coins are spent
+ set<CWalletTx*> setCoins;
+ BOOST_FOREACH(const CTxIn& txin, wtxNew.vin)
+ {
+ CWalletTx &coin = mapWallet[txin.prevout.hash];
+ coin.BindWallet(this);
+ NotifyTransactionChanged(this, coin.GetHash(), CT_UPDATED);
+ }
+
+ if (fFileBacked)
+ delete pwalletdb;
+ }
+
+ // Track how many getdata requests our transaction gets
+ mapRequestCount[wtxNew.GetHash()] = 0;
+
+ if (fBroadcastTransactions)
+ {
+ // Broadcast
+ if (!wtxNew.AcceptToMemoryPool(false))
+ {
+ // This must not fail. The transaction has already been signed and recorded.
+ LogPrintf("CommitTransaction(): Error: Transaction not valid\n");
+ return false;
+ }
+ wtxNew.RelayWalletTransaction();
+ }
+ }
+ return true;
+}
+
+CAmount CWallet::GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool)
+{
+ // payTxFee is user-set "I want to pay this much"
+ CAmount nFeeNeeded = payTxFee.GetFee(nTxBytes);
+ // user selected total at least (default=true)
+ if (fPayAtLeastCustomFee && nFeeNeeded > 0 && nFeeNeeded < payTxFee.GetFeePerK())
+ nFeeNeeded = payTxFee.GetFeePerK();
+ // User didn't set: use -txconfirmtarget to estimate...
+ if (nFeeNeeded == 0)
+ nFeeNeeded = pool.estimateFee(nConfirmTarget).GetFee(nTxBytes);
+ // ... unless we don't have enough mempool data, in which case fall
+ // back to a hard-coded fee
+ if (nFeeNeeded == 0)
+ nFeeNeeded = minTxFee.GetFee(nTxBytes);
+ // prevent user from paying a non-sense fee (like 1 satoshi): 0 < fee < minRelayFee
+ if (nFeeNeeded < ::minRelayTxFee.GetFee(nTxBytes))
+ nFeeNeeded = ::minRelayTxFee.GetFee(nTxBytes);
+ // But always obey the maximum
+ if (nFeeNeeded > maxTxFee)
+ nFeeNeeded = maxTxFee;
+ return nFeeNeeded;
+}
+
+
+
+
+DBErrors CWallet::LoadWallet(bool& fFirstRunRet)
+{
+ if (!fFileBacked)
+ return DB_LOAD_OK;
+ fFirstRunRet = false;
+ DBErrors nLoadWalletRet = CWalletDB(strWalletFile,"cr+").LoadWallet(this);
+ if (nLoadWalletRet == DB_NEED_REWRITE)
+ {
+ if (CDB::Rewrite(strWalletFile, "\x04pool"))
+ {
+ LOCK(cs_wallet);
+ setKeyPool.clear();
+ // Note: can't top-up keypool here, because wallet is locked.
+ // User will be prompted to unlock wallet the next operation
+ // that requires a new key.
+ }
+ }
+
+ if (nLoadWalletRet != DB_LOAD_OK)
+ return nLoadWalletRet;
+ fFirstRunRet = !vchDefaultKey.IsValid();
+
+ uiInterface.LoadWallet(this);
+
+ return DB_LOAD_OK;
+}
+
+
+DBErrors CWallet::ZapWalletTx(std::vector<CWalletTx>& vWtx)
+{
+ if (!fFileBacked)
+ return DB_LOAD_OK;
+ DBErrors nZapWalletTxRet = CWalletDB(strWalletFile,"cr+").ZapWalletTx(this, vWtx);
+ if (nZapWalletTxRet == DB_NEED_REWRITE)
+ {
+ if (CDB::Rewrite(strWalletFile, "\x04pool"))
+ {
+ LOCK(cs_wallet);
+ setKeyPool.clear();
+ // Note: can't top-up keypool here, because wallet is locked.
+ // User will be prompted to unlock wallet the next operation
+ // that requires a new key.
+ }
+ }
+
+ if (nZapWalletTxRet != DB_LOAD_OK)
+ return nZapWalletTxRet;
+
+ return DB_LOAD_OK;
+}
+
+
+bool CWallet::SetAddressBook(const CTxDestination& address, const string& strName, const string& strPurpose)
+{
+ bool fUpdated = false;
+ {
+ LOCK(cs_wallet); // mapAddressBook
+ std::map<CTxDestination, CAddressBookData>::iterator mi = mapAddressBook.find(address);
+ fUpdated = mi != mapAddressBook.end();
+ mapAddressBook[address].name = strName;
+ if (!strPurpose.empty()) /* update purpose only if requested */
+ mapAddressBook[address].purpose = strPurpose;
+ }
+ NotifyAddressBookChanged(this, address, strName, ::IsMine(*this, address) != ISMINE_NO,
+ strPurpose, (fUpdated ? CT_UPDATED : CT_NEW) );
+ if (!fFileBacked)
+ return false;
+ if (!strPurpose.empty() && !CWalletDB(strWalletFile).WritePurpose(CBitcoinAddress(address).ToString(), strPurpose))
+ return false;
+ return CWalletDB(strWalletFile).WriteName(CBitcoinAddress(address).ToString(), strName);
+}
+
+bool CWallet::DelAddressBook(const CTxDestination& address)
+{
+ {
+ LOCK(cs_wallet); // mapAddressBook
+
+ if(fFileBacked)
+ {
+ // Delete destdata tuples associated with address
+ std::string strAddress = CBitcoinAddress(address).ToString();
+ BOOST_FOREACH(const PAIRTYPE(string, string) &item, mapAddressBook[address].destdata)
+ {
+ CWalletDB(strWalletFile).EraseDestData(strAddress, item.first);
+ }
+ }
+ mapAddressBook.erase(address);
+ }
+
+ NotifyAddressBookChanged(this, address, "", ::IsMine(*this, address) != ISMINE_NO, "", CT_DELETED);
+
+ if (!fFileBacked)
+ return false;
+ CWalletDB(strWalletFile).ErasePurpose(CBitcoinAddress(address).ToString());
+ return CWalletDB(strWalletFile).EraseName(CBitcoinAddress(address).ToString());
+}
+
+bool CWallet::SetDefaultKey(const CPubKey &vchPubKey)
+{
+ if (fFileBacked)
+ {
+ if (!CWalletDB(strWalletFile).WriteDefaultKey(vchPubKey))
+ return false;
+ }
+ vchDefaultKey = vchPubKey;
+ 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_t nIndex, setKeyPool)
+ walletdb.ErasePool(nIndex);
+ setKeyPool.clear();
+
+ if (IsLocked())
+ return false;
+
+ int64_t nKeys = max(GetArg("-keypool", 100), (int64_t)0);
+ for (int i = 0; i < nKeys; i++)
+ {
+ int64_t nIndex = i+1;
+ walletdb.WritePool(nIndex, CKeyPool(GenerateNewKey()));
+ setKeyPool.insert(nIndex);
+ }
+ LogPrintf("CWallet::NewKeyPool wrote %d new keys\n", nKeys);
+ }
+ return true;
+}
+
+bool CWallet::TopUpKeyPool(unsigned int kpSize)
+{
+ {
+ LOCK(cs_wallet);
+
+ if (IsLocked())
+ return false;
+
+ CWalletDB walletdb(strWalletFile);
+
+ // Top up key pool
+ unsigned int nTargetSize;
+ if (kpSize > 0)
+ nTargetSize = kpSize;
+ else
+ nTargetSize = max(GetArg("-keypool", 100), (int64_t) 0);
+
+ while (setKeyPool.size() < (nTargetSize + 1))
+ {
+ int64_t 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);
+ LogPrintf("keypool added key %d, size=%u\n", nEnd, setKeyPool.size());
+ }
+ }
+ return true;
+}
+
+void CWallet::ReserveKeyFromKeyPool(int64_t& 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());
+ LogPrintf("keypool reserve %d\n", nIndex);
+ }
+}
+
+void CWallet::KeepKey(int64_t nIndex)
+{
+ // Remove from key pool
+ if (fFileBacked)
+ {
+ CWalletDB walletdb(strWalletFile);
+ walletdb.ErasePool(nIndex);
+ }
+ LogPrintf("keypool keep %d\n", nIndex);
+}
+
+void CWallet::ReturnKey(int64_t nIndex)
+{
+ // Return to key pool
+ {
+ LOCK(cs_wallet);
+ setKeyPool.insert(nIndex);
+ }
+ LogPrintf("keypool return %d\n", nIndex);
+}
+
+bool CWallet::GetKeyFromPool(CPubKey& result)
+{
+ int64_t nIndex = 0;
+ CKeyPool keypool;
+ {
+ LOCK(cs_wallet);
+ ReserveKeyFromKeyPool(nIndex, keypool);
+ if (nIndex == -1)
+ {
+ if (IsLocked()) return false;
+ result = GenerateNewKey();
+ return true;
+ }
+ KeepKey(nIndex);
+ result = keypool.vchPubKey;
+ }
+ return true;
+}
+
+int64_t CWallet::GetOldestKeyPoolTime()
+{
+ int64_t nIndex = 0;
+ CKeyPool keypool;
+ ReserveKeyFromKeyPool(nIndex, keypool);
+ if (nIndex == -1)
+ return GetTime();
+ ReturnKey(nIndex);
+ return keypool.nTime;
+}
+
+std::map<CTxDestination, CAmount> CWallet::GetAddressBalances()
+{
+ map<CTxDestination, CAmount> balances;
+
+ {
+ LOCK(cs_wallet);
+ BOOST_FOREACH(PAIRTYPE(uint256, CWalletTx) walletEntry, mapWallet)
+ {
+ CWalletTx *pcoin = &walletEntry.second;
+
+ if (!CheckFinalTx(*pcoin) || !pcoin->IsTrusted())
+ continue;
+
+ if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0)
+ continue;
+
+ int nDepth = pcoin->GetDepthInMainChain();
+ if (nDepth < (pcoin->IsFromMe(ISMINE_ALL) ? 0 : 1))
+ continue;
+
+ for (unsigned int i = 0; i < pcoin->vout.size(); i++)
+ {
+ CTxDestination addr;
+ if (!IsMine(pcoin->vout[i]))
+ continue;
+ if(!ExtractDestination(pcoin->vout[i].scriptPubKey, addr))
+ continue;
+
+ CAmount n = IsSpent(walletEntry.first, i) ? 0 : pcoin->vout[i].nValue;
+
+ if (!balances.count(addr))
+ balances[addr] = 0;
+ balances[addr] += n;
+ }
+ }
+ }
+
+ return balances;
+}
+
+set< set<CTxDestination> > CWallet::GetAddressGroupings()
+{
+ AssertLockHeld(cs_wallet); // mapWallet
+ set< set<CTxDestination> > groupings;
+ set<CTxDestination> grouping;
+
+ BOOST_FOREACH(PAIRTYPE(uint256, CWalletTx) walletEntry, mapWallet)
+ {
+ CWalletTx *pcoin = &walletEntry.second;
+
+ if (pcoin->vin.size() > 0)
+ {
+ bool any_mine = false;
+ // group all input addresses with each other
+ BOOST_FOREACH(CTxIn txin, pcoin->vin)
+ {
+ CTxDestination address;
+ if(!IsMine(txin)) /* If this input isn't mine, ignore it */
+ continue;
+ if(!ExtractDestination(mapWallet[txin.prevout.hash].vout[txin.prevout.n].scriptPubKey, address))
+ continue;
+ grouping.insert(address);
+ any_mine = true;
+ }
+
+ // group change with input addresses
+ if (any_mine)
+ {
+ BOOST_FOREACH(CTxOut txout, pcoin->vout)
+ if (IsChange(txout))
+ {
+ CTxDestination txoutAddr;
+ if(!ExtractDestination(txout.scriptPubKey, txoutAddr))
+ continue;
+ grouping.insert(txoutAddr);
+ }
+ }
+ if (grouping.size() > 0)
+ {
+ groupings.insert(grouping);
+ grouping.clear();
+ }
+ }
+
+ // group lone addrs by themselves
+ for (unsigned int i = 0; i < pcoin->vout.size(); i++)
+ if (IsMine(pcoin->vout[i]))
+ {
+ CTxDestination address;
+ if(!ExtractDestination(pcoin->vout[i].scriptPubKey, address))
+ continue;
+ grouping.insert(address);
+ groupings.insert(grouping);
+ grouping.clear();
+ }
+ }
+
+ set< set<CTxDestination>* > uniqueGroupings; // a set of pointers to groups of addresses
+ map< CTxDestination, set<CTxDestination>* > setmap; // map addresses to the unique group containing it
+ BOOST_FOREACH(set<CTxDestination> grouping, groupings)
+ {
+ // make a set of all the groups hit by this new group
+ set< set<CTxDestination>* > hits;
+ map< CTxDestination, set<CTxDestination>* >::iterator it;
+ BOOST_FOREACH(CTxDestination address, grouping)
+ if ((it = setmap.find(address)) != setmap.end())
+ hits.insert((*it).second);
+
+ // merge all hit groups into a new single group and delete old groups
+ set<CTxDestination>* merged = new set<CTxDestination>(grouping);
+ BOOST_FOREACH(set<CTxDestination>* hit, hits)
+ {
+ merged->insert(hit->begin(), hit->end());
+ uniqueGroupings.erase(hit);
+ delete hit;
+ }
+ uniqueGroupings.insert(merged);
+
+ // update setmap
+ BOOST_FOREACH(CTxDestination element, *merged)
+ setmap[element] = merged;
+ }
+
+ set< set<CTxDestination> > ret;
+ BOOST_FOREACH(set<CTxDestination>* uniqueGrouping, uniqueGroupings)
+ {
+ ret.insert(*uniqueGrouping);
+ delete uniqueGrouping;
+ }
+
+ return ret;
+}
+
+set<CTxDestination> CWallet::GetAccountAddresses(string strAccount) const
+{
+ LOCK(cs_wallet);
+ set<CTxDestination> result;
+ BOOST_FOREACH(const PAIRTYPE(CTxDestination, CAddressBookData)& item, mapAddressBook)
+ {
+ const CTxDestination& address = item.first;
+ const string& strName = item.second.name;
+ if (strName == strAccount)
+ result.insert(address);
+ }
+ return result;
+}
+
+bool CReserveKey::GetReservedKey(CPubKey& pubkey)
+{
+ if (nIndex == -1)
+ {
+ CKeyPool keypool;
+ pwallet->ReserveKeyFromKeyPool(nIndex, keypool);
+ if (nIndex != -1)
+ vchPubKey = keypool.vchPubKey;
+ else {
+ return false;
+ }
+ }
+ assert(vchPubKey.IsValid());
+ pubkey = vchPubKey;
+ return true;
+}
+
+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<CKeyID>& setAddress) const
+{
+ setAddress.clear();
+
+ CWalletDB walletdb(strWalletFile);
+
+ LOCK2(cs_main, cs_wallet);
+ BOOST_FOREACH(const int64_t& 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<uint256, CWalletTx>::const_iterator mi = mapWallet.find(hashTx);
+ if (mi != mapWallet.end())
+ NotifyTransactionChanged(this, hashTx, CT_UPDATED);
+ }
+}
+
+void CWallet::LockCoin(COutPoint& output)
+{
+ AssertLockHeld(cs_wallet); // setLockedCoins
+ setLockedCoins.insert(output);
+}
+
+void CWallet::UnlockCoin(COutPoint& output)
+{
+ AssertLockHeld(cs_wallet); // setLockedCoins
+ setLockedCoins.erase(output);
+}
+
+void CWallet::UnlockAllCoins()
+{
+ AssertLockHeld(cs_wallet); // setLockedCoins
+ setLockedCoins.clear();
+}
+
+bool CWallet::IsLockedCoin(uint256 hash, unsigned int n) const
+{
+ AssertLockHeld(cs_wallet); // setLockedCoins
+ COutPoint outpt(hash, n);
+
+ return (setLockedCoins.count(outpt) > 0);
+}
+
+void CWallet::ListLockedCoins(std::vector<COutPoint>& vOutpts)
+{
+ AssertLockHeld(cs_wallet); // setLockedCoins
+ for (std::set<COutPoint>::iterator it = setLockedCoins.begin();
+ it != setLockedCoins.end(); it++) {
+ COutPoint outpt = (*it);
+ vOutpts.push_back(outpt);
+ }
+}
+
+/** @} */ // end of Actions
+
+class CAffectedKeysVisitor : public boost::static_visitor<void> {
+private:
+ const CKeyStore &keystore;
+ std::vector<CKeyID> &vKeys;
+
+public:
+ CAffectedKeysVisitor(const CKeyStore &keystoreIn, std::vector<CKeyID> &vKeysIn) : keystore(keystoreIn), vKeys(vKeysIn) {}
+
+ void Process(const CScript &script) {
+ txnouttype type;
+ std::vector<CTxDestination> vDest;
+ int nRequired;
+ if (ExtractDestinations(script, type, vDest, nRequired)) {
+ BOOST_FOREACH(const CTxDestination &dest, vDest)
+ boost::apply_visitor(*this, dest);
+ }
+ }
+
+ void operator()(const CKeyID &keyId) {
+ if (keystore.HaveKey(keyId))
+ vKeys.push_back(keyId);
+ }
+
+ void operator()(const CScriptID &scriptId) {
+ CScript script;
+ if (keystore.GetCScript(scriptId, script))
+ Process(script);
+ }
+
+ void operator()(const CNoDestination &none) {}
+};
+
+void CWallet::GetKeyBirthTimes(std::map<CKeyID, int64_t> &mapKeyBirth) const {
+ AssertLockHeld(cs_wallet); // mapKeyMetadata
+ mapKeyBirth.clear();
+
+ // get birth times for keys with metadata
+ for (std::map<CKeyID, CKeyMetadata>::const_iterator it = mapKeyMetadata.begin(); it != mapKeyMetadata.end(); it++)
+ if (it->second.nCreateTime)
+ mapKeyBirth[it->first] = it->second.nCreateTime;
+
+ // map in which we'll infer heights of other keys
+ CBlockIndex *pindexMax = chainActive[std::max(0, chainActive.Height() - 144)]; // the tip can be reorganised; use a 144-block safety margin
+ std::map<CKeyID, CBlockIndex*> mapKeyFirstBlock;
+ std::set<CKeyID> setKeys;
+ GetKeys(setKeys);
+ BOOST_FOREACH(const CKeyID &keyid, setKeys) {
+ if (mapKeyBirth.count(keyid) == 0)
+ mapKeyFirstBlock[keyid] = pindexMax;
+ }
+ setKeys.clear();
+
+ // if there are no such keys, we're done
+ if (mapKeyFirstBlock.empty())
+ return;
+
+ // find first block that affects those keys, if there are any left
+ std::vector<CKeyID> vAffected;
+ for (std::map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); it++) {
+ // iterate over all wallet transactions...
+ const CWalletTx &wtx = (*it).second;
+ BlockMap::const_iterator blit = mapBlockIndex.find(wtx.hashBlock);
+ if (blit != mapBlockIndex.end() && chainActive.Contains(blit->second)) {
+ // ... which are already in a block
+ int nHeight = blit->second->nHeight;
+ BOOST_FOREACH(const CTxOut &txout, wtx.vout) {
+ // iterate over all their outputs
+ CAffectedKeysVisitor(*this, vAffected).Process(txout.scriptPubKey);
+ BOOST_FOREACH(const CKeyID &keyid, vAffected) {
+ // ... and all their affected keys
+ std::map<CKeyID, CBlockIndex*>::iterator rit = mapKeyFirstBlock.find(keyid);
+ if (rit != mapKeyFirstBlock.end() && nHeight < rit->second->nHeight)
+ rit->second = blit->second;
+ }
+ vAffected.clear();
+ }
+ }
+ }
+
+ // Extract block timestamps for those keys
+ for (std::map<CKeyID, CBlockIndex*>::const_iterator it = mapKeyFirstBlock.begin(); it != mapKeyFirstBlock.end(); it++)
+ mapKeyBirth[it->first] = it->second->GetBlockTime() - 7200; // block times can be 2h off
+}
+
+bool CWallet::AddDestData(const CTxDestination &dest, const std::string &key, const std::string &value)
+{
+ if (boost::get<CNoDestination>(&dest))
+ return false;
+
+ mapAddressBook[dest].destdata.insert(std::make_pair(key, value));
+ if (!fFileBacked)
+ return true;
+ return CWalletDB(strWalletFile).WriteDestData(CBitcoinAddress(dest).ToString(), key, value);
+}
+
+bool CWallet::EraseDestData(const CTxDestination &dest, const std::string &key)
+{
+ if (!mapAddressBook[dest].destdata.erase(key))
+ return false;
+ if (!fFileBacked)
+ return true;
+ return CWalletDB(strWalletFile).EraseDestData(CBitcoinAddress(dest).ToString(), key);
+}
+
+bool CWallet::LoadDestData(const CTxDestination &dest, const std::string &key, const std::string &value)
+{
+ mapAddressBook[dest].destdata.insert(std::make_pair(key, value));
+ return true;
+}
+
+bool CWallet::GetDestData(const CTxDestination &dest, const std::string &key, std::string *value) const
+{
+ std::map<CTxDestination, CAddressBookData>::const_iterator i = mapAddressBook.find(dest);
+ if(i != mapAddressBook.end())
+ {
+ CAddressBookData::StringMap::const_iterator j = i->second.destdata.find(key);
+ if(j != i->second.destdata.end())
+ {
+ if(value)
+ *value = j->second;
+ return true;
+ }
+ }
+ return false;
+}
+
+CKeyPool::CKeyPool()
+{
+ nTime = GetTime();
+}
+
+CKeyPool::CKeyPool(const CPubKey& vchPubKeyIn)
+{
+ nTime = GetTime();
+ vchPubKey = vchPubKeyIn;
+}
+
+CWalletKey::CWalletKey(int64_t nExpires)
+{
+ nTimeCreated = (nExpires ? GetTime() : 0);
+ nTimeExpires = nExpires;
+}
+
+int CMerkleTx::SetMerkleBranch(const CBlock& block)
+{
+ AssertLockHeld(cs_main);
+ CBlock blockTmp;
+
+ // Update the tx's hashBlock
+ hashBlock = block.GetHash();
+
+ // Locate the transaction
+ for (nIndex = 0; nIndex < (int)block.vtx.size(); nIndex++)
+ if (block.vtx[nIndex] == *(CTransaction*)this)
+ break;
+ if (nIndex == (int)block.vtx.size())
+ {
+ vMerkleBranch.clear();
+ nIndex = -1;
+ LogPrintf("ERROR: SetMerkleBranch(): couldn't find tx in block\n");
+ return 0;
+ }
+
+ // Fill in merkle branch
+ vMerkleBranch = block.GetMerkleBranch(nIndex);
+
+ // Is the tx in a block that's in the main chain
+ BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
+ if (mi == mapBlockIndex.end())
+ return 0;
+ const CBlockIndex* pindex = (*mi).second;
+ if (!pindex || !chainActive.Contains(pindex))
+ return 0;
+
+ return chainActive.Height() - pindex->nHeight + 1;
+}
+
+int CMerkleTx::GetDepthInMainChainINTERNAL(const CBlockIndex* &pindexRet) const
+{
+ if (hashBlock.IsNull() || nIndex == -1)
+ return 0;
+ AssertLockHeld(cs_main);
+
+ // Find the block it claims to be in
+ BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
+ if (mi == mapBlockIndex.end())
+ return 0;
+ CBlockIndex* pindex = (*mi).second;
+ if (!pindex || !chainActive.Contains(pindex))
+ 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 chainActive.Height() - pindex->nHeight + 1;
+}
+
+int CMerkleTx::GetDepthInMainChain(const CBlockIndex* &pindexRet) const
+{
+ AssertLockHeld(cs_main);
+ int nResult = GetDepthInMainChainINTERNAL(pindexRet);
+ if (nResult == 0 && !mempool.exists(GetHash()))
+ return -1; // Not in chain, not in mempool
+
+ return nResult;
+}
+
+int CMerkleTx::GetBlocksToMaturity() const
+{
+ if (!IsCoinBase())
+ return 0;
+ return max(0, (COINBASE_MATURITY+1) - GetDepthInMainChain());
+}
+
+
+bool CMerkleTx::AcceptToMemoryPool(bool fLimitFree, bool fRejectAbsurdFee)
+{
+ CValidationState state;
+ return ::AcceptToMemoryPool(mempool, state, *this, fLimitFree, NULL, fRejectAbsurdFee);
+}
+
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
new file mode 100644
index 0000000000..b0da92cfd1
--- /dev/null
+++ b/src/wallet/wallet.h
@@ -0,0 +1,874 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_WALLET_WALLET_H
+#define BITCOIN_WALLET_WALLET_H
+
+#include "amount.h"
+#include "key.h"
+#include "keystore.h"
+#include "primitives/block.h"
+#include "primitives/transaction.h"
+#include "tinyformat.h"
+#include "ui_interface.h"
+#include "utilstrencodings.h"
+#include "validationinterface.h"
+#include "wallet/crypter.h"
+#include "wallet/wallet_ismine.h"
+#include "wallet/walletdb.h"
+
+#include <algorithm>
+#include <map>
+#include <set>
+#include <stdexcept>
+#include <stdint.h>
+#include <string>
+#include <utility>
+#include <vector>
+
+/**
+ * Settings
+ */
+extern CFeeRate payTxFee;
+extern CAmount maxTxFee;
+extern unsigned int nTxConfirmTarget;
+extern bool bSpendZeroConfChange;
+extern bool fSendFreeTransactions;
+extern bool fPayAtLeastCustomFee;
+
+//! -paytxfee default
+static const CAmount DEFAULT_TRANSACTION_FEE = 0;
+//! -paytxfee will warn if called with a higher fee than this amount (in satoshis) per KB
+static const CAmount nHighTransactionFeeWarning = 0.01 * COIN;
+//! -maxtxfee default
+static const CAmount DEFAULT_TRANSACTION_MAXFEE = 0.1 * COIN;
+//! -txconfirmtarget default
+static const unsigned int DEFAULT_TX_CONFIRM_TARGET = 2;
+//! -maxtxfee will warn if called with a higher fee than this amount (in satoshis)
+static const CAmount nHighTransactionMaxFeeWarning = 100 * nHighTransactionFeeWarning;
+//! Largest (in bytes) free transaction we're willing to create
+static const unsigned int MAX_FREE_TRANSACTION_CREATE_SIZE = 1000;
+
+class CAccountingEntry;
+class CBlockIndex;
+class CCoinControl;
+class COutput;
+class CReserveKey;
+class CScript;
+class CTxMemPool;
+class CWalletTx;
+
+/** (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_t nTime;
+ CPubKey vchPubKey;
+
+ CKeyPool();
+ CKeyPool(const CPubKey& vchPubKeyIn);
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ if (!(nType & SER_GETHASH))
+ READWRITE(nVersion);
+ READWRITE(nTime);
+ READWRITE(vchPubKey);
+ }
+};
+
+/** Address book data */
+class CAddressBookData
+{
+public:
+ std::string name;
+ std::string purpose;
+
+ CAddressBookData()
+ {
+ purpose = "unknown";
+ }
+
+ typedef std::map<std::string, std::string> StringMap;
+ StringMap destdata;
+};
+
+struct CRecipient
+{
+ CScript scriptPubKey;
+ CAmount nAmount;
+ bool fSubtractFeeFromAmount;
+};
+
+typedef std::map<std::string, std::string> mapValue_t;
+
+
+static void ReadOrderPos(int64_t& nOrderPos, mapValue_t& mapValue)
+{
+ if (!mapValue.count("n"))
+ {
+ nOrderPos = -1; // TODO: calculate elsewhere
+ return;
+ }
+ nOrderPos = atoi64(mapValue["n"].c_str());
+}
+
+
+static void WriteOrderPos(const int64_t& nOrderPos, mapValue_t& mapValue)
+{
+ if (nOrderPos == -1)
+ return;
+ mapValue["n"] = i64tostr(nOrderPos);
+}
+
+struct COutputEntry
+{
+ CTxDestination destination;
+ CAmount amount;
+ int vout;
+};
+
+/** A transaction with a merkle branch linking it to the block chain. */
+class CMerkleTx : public CTransaction
+{
+private:
+ int GetDepthInMainChainINTERNAL(const CBlockIndex* &pindexRet) const;
+
+public:
+ uint256 hashBlock;
+ std::vector<uint256> vMerkleBranch;
+ int nIndex;
+
+ // memory only
+ mutable bool fMerkleVerified;
+
+
+ CMerkleTx()
+ {
+ Init();
+ }
+
+ CMerkleTx(const CTransaction& txIn) : CTransaction(txIn)
+ {
+ Init();
+ }
+
+ void Init()
+ {
+ hashBlock = uint256();
+ nIndex = -1;
+ fMerkleVerified = false;
+ }
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ READWRITE(*(CTransaction*)this);
+ nVersion = this->nVersion;
+ READWRITE(hashBlock);
+ READWRITE(vMerkleBranch);
+ READWRITE(nIndex);
+ }
+
+ int SetMerkleBranch(const CBlock& block);
+
+
+ /**
+ * Return depth of transaction in blockchain:
+ * -1 : not in blockchain, and not in memory pool (conflicted transaction)
+ * 0 : in memory pool, waiting to be included in a block
+ * >=1 : this many blocks deep in the main chain
+ */
+ int GetDepthInMainChain(const CBlockIndex* &pindexRet) const;
+ int GetDepthInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet); }
+ bool IsInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChainINTERNAL(pindexRet) > 0; }
+ int GetBlocksToMaturity() const;
+ bool AcceptToMemoryPool(bool fLimitFree=true, bool fRejectAbsurdFee=true);
+};
+
+/**
+ * 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:
+ mapValue_t mapValue;
+ std::vector<std::pair<std::string, std::string> > vOrderForm;
+ unsigned int fTimeReceivedIsTxTime;
+ unsigned int nTimeReceived; //! time received by this node
+ unsigned int nTimeSmart;
+ char fFromMe;
+ std::string strFromAccount;
+ int64_t nOrderPos; //! position in ordered transaction list
+
+ // memory only
+ mutable bool fDebitCached;
+ mutable bool fCreditCached;
+ mutable bool fImmatureCreditCached;
+ mutable bool fAvailableCreditCached;
+ mutable bool fWatchDebitCached;
+ mutable bool fWatchCreditCached;
+ mutable bool fImmatureWatchCreditCached;
+ mutable bool fAvailableWatchCreditCached;
+ mutable bool fChangeCached;
+ mutable CAmount nDebitCached;
+ mutable CAmount nCreditCached;
+ mutable CAmount nImmatureCreditCached;
+ mutable CAmount nAvailableCreditCached;
+ mutable CAmount nWatchDebitCached;
+ mutable CAmount nWatchCreditCached;
+ mutable CAmount nImmatureWatchCreditCached;
+ mutable CAmount nAvailableWatchCreditCached;
+ mutable CAmount 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;
+ mapValue.clear();
+ vOrderForm.clear();
+ fTimeReceivedIsTxTime = false;
+ nTimeReceived = 0;
+ nTimeSmart = 0;
+ fFromMe = false;
+ strFromAccount.clear();
+ fDebitCached = false;
+ fCreditCached = false;
+ fImmatureCreditCached = false;
+ fAvailableCreditCached = false;
+ fWatchDebitCached = false;
+ fWatchCreditCached = false;
+ fImmatureWatchCreditCached = false;
+ fAvailableWatchCreditCached = false;
+ fChangeCached = false;
+ nDebitCached = 0;
+ nCreditCached = 0;
+ nImmatureCreditCached = 0;
+ nAvailableCreditCached = 0;
+ nWatchDebitCached = 0;
+ nWatchCreditCached = 0;
+ nAvailableWatchCreditCached = 0;
+ nImmatureWatchCreditCached = 0;
+ nChangeCached = 0;
+ nOrderPos = -1;
+ }
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ if (ser_action.ForRead())
+ Init(NULL);
+ char fSpent = false;
+
+ if (!ser_action.ForRead())
+ {
+ mapValue["fromaccount"] = strFromAccount;
+
+ WriteOrderPos(nOrderPos, mapValue);
+
+ if (nTimeSmart)
+ mapValue["timesmart"] = strprintf("%u", nTimeSmart);
+ }
+
+ READWRITE(*(CMerkleTx*)this);
+ std::vector<CMerkleTx> vUnused; //! Used to be vtxPrev
+ READWRITE(vUnused);
+ READWRITE(mapValue);
+ READWRITE(vOrderForm);
+ READWRITE(fTimeReceivedIsTxTime);
+ READWRITE(nTimeReceived);
+ READWRITE(fFromMe);
+ READWRITE(fSpent);
+
+ if (ser_action.ForRead())
+ {
+ strFromAccount = mapValue["fromaccount"];
+
+ ReadOrderPos(nOrderPos, mapValue);
+
+ nTimeSmart = mapValue.count("timesmart") ? (unsigned int)atoi64(mapValue["timesmart"]) : 0;
+ }
+
+ mapValue.erase("fromaccount");
+ mapValue.erase("version");
+ mapValue.erase("spent");
+ mapValue.erase("n");
+ mapValue.erase("timesmart");
+ }
+
+ //! make sure balances are recalculated
+ void MarkDirty()
+ {
+ fCreditCached = false;
+ fAvailableCreditCached = false;
+ fWatchDebitCached = false;
+ fWatchCreditCached = false;
+ fAvailableWatchCreditCached = false;
+ fImmatureWatchCreditCached = false;
+ fDebitCached = false;
+ fChangeCached = false;
+ }
+
+ void BindWallet(CWallet *pwalletIn)
+ {
+ pwallet = pwalletIn;
+ MarkDirty();
+ }
+
+ //! filter decides which addresses will count towards the debit
+ CAmount GetDebit(const isminefilter& filter) const;
+ CAmount GetCredit(const isminefilter& filter) const;
+ CAmount GetImmatureCredit(bool fUseCache=true) const;
+ CAmount GetAvailableCredit(bool fUseCache=true) const;
+ CAmount GetImmatureWatchOnlyCredit(const bool& fUseCache=true) const;
+ CAmount GetAvailableWatchOnlyCredit(const bool& fUseCache=true) const;
+ CAmount GetChange() const;
+
+ void GetAmounts(std::list<COutputEntry>& listReceived,
+ std::list<COutputEntry>& listSent, CAmount& nFee, std::string& strSentAccount, const isminefilter& filter) const;
+
+ void GetAccountAmounts(const std::string& strAccount, CAmount& nReceived,
+ CAmount& nSent, CAmount& nFee, const isminefilter& filter) const;
+
+ bool IsFromMe(const isminefilter& filter) const
+ {
+ return (GetDebit(filter) > 0);
+ }
+
+ bool IsTrusted() const;
+
+ bool WriteToDisk(CWalletDB *pwalletdb);
+
+ int64_t GetTxTime() const;
+ int GetRequestCount() const;
+
+ bool RelayWalletTransaction();
+
+ std::set<uint256> GetConflicts() const;
+};
+
+
+
+
+class COutput
+{
+public:
+ const CWalletTx *tx;
+ int i;
+ int nDepth;
+ bool fSpendable;
+
+ COutput(const CWalletTx *txIn, int iIn, int nDepthIn, bool fSpendableIn)
+ {
+ tx = txIn; i = iIn; nDepth = nDepthIn; fSpendable = fSpendableIn;
+ }
+
+ std::string ToString() const;
+};
+
+
+
+
+/** Private key that includes an expiration date in case it never gets used. */
+class CWalletKey
+{
+public:
+ CPrivKey vchPrivKey;
+ int64_t nTimeCreated;
+ int64_t nTimeExpires;
+ std::string strComment;
+ //! todo: add something to note what created it (user, getnewaddress, change)
+ //! maybe should have a map<string, string> property map
+
+ CWalletKey(int64_t nExpires=0);
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ if (!(nType & SER_GETHASH))
+ READWRITE(nVersion);
+ READWRITE(vchPrivKey);
+ READWRITE(nTimeCreated);
+ READWRITE(nTimeExpires);
+ READWRITE(LIMITED_STRING(strComment, 65536));
+ }
+};
+
+
+
+/**
+ * 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, public CValidationInterface
+{
+private:
+ bool SelectCoins(const CAmount& nTargetValue, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet, const CCoinControl *coinControl = NULL) 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;
+
+ int64_t nNextResend;
+ int64_t nLastResend;
+ bool fBroadcastTransactions;
+
+ /**
+ * Used to keep track of spent outpoints, and
+ * detect and report conflicts (double-spends or
+ * mutated transactions where the mutant gets mined).
+ */
+ typedef std::multimap<COutPoint, uint256> TxSpends;
+ TxSpends mapTxSpends;
+ void AddToSpends(const COutPoint& outpoint, const uint256& wtxid);
+ void AddToSpends(const uint256& wtxid);
+
+ void SyncMetaData(std::pair<TxSpends::iterator, TxSpends::iterator>);
+
+public:
+ /*
+ * Main wallet lock.
+ * This lock protects all the fields added by CWallet
+ * except for:
+ * fFileBacked (immutable after instantiation)
+ * strWalletFile (immutable after instantiation)
+ */
+ mutable CCriticalSection cs_wallet;
+
+ bool fFileBacked;
+ std::string strWalletFile;
+
+ std::set<int64_t> setKeyPool;
+ std::map<CKeyID, CKeyMetadata> mapKeyMetadata;
+
+ typedef std::map<unsigned int, CMasterKey> MasterKeyMap;
+ MasterKeyMap mapMasterKeys;
+ unsigned int nMasterKeyMaxID;
+
+ CWallet()
+ {
+ SetNull();
+ }
+
+ CWallet(std::string strWalletFileIn)
+ {
+ SetNull();
+
+ strWalletFile = strWalletFileIn;
+ fFileBacked = true;
+ }
+
+ ~CWallet()
+ {
+ delete pwalletdbEncryption;
+ pwalletdbEncryption = NULL;
+ }
+
+ void SetNull()
+ {
+ nWalletVersion = FEATURE_BASE;
+ nWalletMaxVersion = FEATURE_BASE;
+ fFileBacked = false;
+ nMasterKeyMaxID = 0;
+ pwalletdbEncryption = NULL;
+ nOrderPosNext = 0;
+ nNextResend = 0;
+ nLastResend = 0;
+ nTimeFirstKey = 0;
+ fBroadcastTransactions = false;
+ }
+
+ std::map<uint256, CWalletTx> mapWallet;
+
+ int64_t nOrderPosNext;
+ std::map<uint256, int> mapRequestCount;
+
+ std::map<CTxDestination, CAddressBookData> mapAddressBook;
+
+ CPubKey vchDefaultKey;
+
+ std::set<COutPoint> setLockedCoins;
+
+ int64_t nTimeFirstKey;
+
+ const CWalletTx* GetWalletTx(const uint256& hash) const;
+
+ //! check whether we are allowed to upgrade (or already support) to the named feature
+ bool CanSupportFeature(enum WalletFeature wf) { AssertLockHeld(cs_wallet); return nWalletMaxVersion >= wf; }
+
+ void AvailableCoins(std::vector<COutput>& vCoins, bool fOnlyConfirmed=true, const CCoinControl *coinControl = NULL, bool fIncludeZeroValue=false) const;
+ bool SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int nConfTheirs, std::vector<COutput> vCoins, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet) const;
+
+ bool IsSpent(const uint256& hash, unsigned int n) const;
+
+ bool IsLockedCoin(uint256 hash, unsigned int n) const;
+ void LockCoin(COutPoint& output);
+ void UnlockCoin(COutPoint& output);
+ void UnlockAllCoins();
+ void ListLockedCoins(std::vector<COutPoint>& vOutpts);
+
+ /**
+ * keystore implementation
+ * Generate a new key
+ */
+ CPubKey GenerateNewKey();
+ //! Adds a key to the store, and saves it to disk.
+ bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey);
+ //! Adds a key to the store, without saving it to disk (used by LoadWallet)
+ bool LoadKey(const CKey& key, const CPubKey &pubkey) { return CCryptoKeyStore::AddKeyPubKey(key, pubkey); }
+ //! Load metadata (used by LoadWallet)
+ bool LoadKeyMetadata(const CPubKey &pubkey, const CKeyMetadata &metadata);
+
+ bool LoadMinVersion(int nVersion) { AssertLockHeld(cs_wallet); nWalletVersion = nVersion; nWalletMaxVersion = std::max(nWalletMaxVersion, nVersion); return true; }
+
+ //! Adds an encrypted key to the store, and saves it to disk.
+ bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
+ //! Adds an encrypted key to the store, without saving it to disk (used by LoadWallet)
+ bool LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
+ bool AddCScript(const CScript& redeemScript);
+ bool LoadCScript(const CScript& redeemScript);
+
+ //! Adds a destination data tuple to the store, and saves it to disk
+ bool AddDestData(const CTxDestination &dest, const std::string &key, const std::string &value);
+ //! Erases a destination data tuple in the store and on disk
+ bool EraseDestData(const CTxDestination &dest, const std::string &key);
+ //! Adds a destination data tuple to the store, without saving it to disk
+ bool LoadDestData(const CTxDestination &dest, const std::string &key, const std::string &value);
+ //! Look up a destination data tuple in the store, return true if found false otherwise
+ bool GetDestData(const CTxDestination &dest, const std::string &key, std::string *value) const;
+
+ //! Adds a watch-only address to the store, and saves it to disk.
+ bool AddWatchOnly(const CScript &dest);
+ bool RemoveWatchOnly(const CScript &dest);
+ //! Adds a watch-only address to the store, without saving it to disk (used by LoadWallet)
+ bool LoadWatchOnly(const CScript &dest);
+
+ bool Unlock(const SecureString& strWalletPassphrase);
+ bool ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase);
+ bool EncryptWallet(const SecureString& strWalletPassphrase);
+
+ void GetKeyBirthTimes(std::map<CKeyID, int64_t> &mapKeyBirth) const;
+
+ /**
+ * Increment the next transaction order id
+ * @return next transaction order id
+ */
+ int64_t IncOrderPosNext(CWalletDB *pwalletdb = NULL);
+
+ typedef std::pair<CWalletTx*, CAccountingEntry*> TxPair;
+ typedef std::multimap<int64_t, TxPair > TxItems;
+
+ /**
+ * Get the wallet's activity log
+ * @return multimap of ordered transactions and accounting entries
+ * @warning Returned pointers are *only* valid within the scope of passed acentries
+ */
+ TxItems OrderedTxItems(std::list<CAccountingEntry>& acentries, std::string strAccount = "");
+
+ void MarkDirty();
+ bool AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletDB* pwalletdb);
+ void SyncTransaction(const CTransaction& tx, const CBlock* pblock);
+ bool AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate);
+ void EraseFromWallet(const uint256 &hash);
+ int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false);
+ void ReacceptWalletTransactions();
+ void ResendWalletTransactions(int64_t nBestBlockTime);
+ std::vector<uint256> ResendWalletTransactionsBefore(int64_t nTime);
+ CAmount GetBalance() const;
+ CAmount GetUnconfirmedBalance() const;
+ CAmount GetImmatureBalance() const;
+ CAmount GetWatchOnlyBalance() const;
+ CAmount GetUnconfirmedWatchOnlyBalance() const;
+ CAmount GetImmatureWatchOnlyBalance() const;
+ bool CreateTransaction(const std::vector<CRecipient>& vecSend,
+ CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosRet, std::string& strFailReason, const CCoinControl *coinControl = NULL);
+ bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey);
+
+ static CFeeRate minTxFee;
+ static CAmount GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool);
+
+ bool NewKeyPool();
+ bool TopUpKeyPool(unsigned int kpSize = 0);
+ void ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool);
+ void KeepKey(int64_t nIndex);
+ void ReturnKey(int64_t nIndex);
+ bool GetKeyFromPool(CPubKey &key);
+ int64_t GetOldestKeyPoolTime();
+ void GetAllReserveKeys(std::set<CKeyID>& setAddress) const;
+
+ std::set< std::set<CTxDestination> > GetAddressGroupings();
+ std::map<CTxDestination, CAmount> GetAddressBalances();
+
+ std::set<CTxDestination> GetAccountAddresses(std::string strAccount) const;
+
+ isminetype IsMine(const CTxIn& txin) const;
+ CAmount GetDebit(const CTxIn& txin, const isminefilter& filter) const;
+ isminetype IsMine(const CTxOut& txout) const;
+ CAmount GetCredit(const CTxOut& txout, const isminefilter& filter) const;
+ bool IsChange(const CTxOut& txout) const;
+ CAmount GetChange(const CTxOut& txout) const;
+ bool IsMine(const CTransaction& tx) const;
+ /** should probably be renamed to IsRelevantToMe */
+ bool IsFromMe(const CTransaction& tx) const;
+ CAmount GetDebit(const CTransaction& tx, const isminefilter& filter) const;
+ CAmount GetCredit(const CTransaction& tx, const isminefilter& filter) const;
+ CAmount GetChange(const CTransaction& tx) const;
+ void SetBestChain(const CBlockLocator& loc);
+
+ DBErrors LoadWallet(bool& fFirstRunRet);
+ DBErrors ZapWalletTx(std::vector<CWalletTx>& vWtx);
+
+ bool SetAddressBook(const CTxDestination& address, const std::string& strName, const std::string& purpose);
+
+ bool DelAddressBook(const CTxDestination& address);
+
+ void UpdatedTransaction(const uint256 &hashTx);
+
+ void Inventory(const uint256 &hash)
+ {
+ {
+ LOCK(cs_wallet);
+ std::map<uint256, int>::iterator mi = mapRequestCount.find(hash);
+ if (mi != mapRequestCount.end())
+ (*mi).second++;
+ }
+ }
+
+ unsigned int GetKeyPoolSize()
+ {
+ AssertLockHeld(cs_wallet); // setKeyPool
+ return setKeyPool.size();
+ }
+
+ 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() { LOCK(cs_wallet); return nWalletVersion; }
+
+ //! Get wallet transactions that conflict with given transaction (spend same outputs)
+ std::set<uint256> GetConflicts(const uint256& txid) const;
+
+ //! Flush wallet (bitdb flush)
+ void Flush(bool shutdown=false);
+
+ //! Verify the wallet database and perform salvage if required
+ static bool Verify(const std::string& walletFile, std::string& warningString, std::string& errorString);
+
+ /**
+ * Address book entry changed.
+ * @note called with lock cs_wallet held.
+ */
+ boost::signals2::signal<void (CWallet *wallet, const CTxDestination
+ &address, const std::string &label, bool isMine,
+ const std::string &purpose,
+ ChangeType status)> NotifyAddressBookChanged;
+
+ /**
+ * Wallet transaction added, removed or updated.
+ * @note called with lock cs_wallet held.
+ */
+ boost::signals2::signal<void (CWallet *wallet, const uint256 &hashTx,
+ ChangeType status)> NotifyTransactionChanged;
+
+ /** Show progress e.g. for rescan */
+ boost::signals2::signal<void (const std::string &title, int nProgress)> ShowProgress;
+
+ /** Watch-only address added */
+ boost::signals2::signal<void (bool fHaveWatchOnly)> NotifyWatchonlyChanged;
+
+ /** Inquire whether this wallet broadcasts transactions. */
+ bool GetBroadcastTransactions() const { return fBroadcastTransactions; }
+ /** Set whether this wallet broadcasts transactions. */
+ void SetBroadcastTransactions(bool broadcast) { fBroadcastTransactions = broadcast; }
+};
+
+/** A key allocated from the key pool. */
+class CReserveKey
+{
+protected:
+ CWallet* pwallet;
+ int64_t nIndex;
+ CPubKey vchPubKey;
+public:
+ CReserveKey(CWallet* pwalletIn)
+ {
+ nIndex = -1;
+ pwallet = pwalletIn;
+ }
+
+ ~CReserveKey()
+ {
+ ReturnKey();
+ }
+
+ void ReturnKey();
+ bool GetReservedKey(CPubKey &pubkey);
+ void KeepKey();
+};
+
+
+/**
+ * Account information.
+ * Stored in wallet with key "acc"+string account name.
+ */
+class CAccount
+{
+public:
+ CPubKey vchPubKey;
+
+ CAccount()
+ {
+ SetNull();
+ }
+
+ void SetNull()
+ {
+ vchPubKey = CPubKey();
+ }
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ if (!(nType & SER_GETHASH))
+ READWRITE(nVersion);
+ READWRITE(vchPubKey);
+ }
+};
+
+
+
+/**
+ * Internal transfers.
+ * Database key is acentry<account><counter>.
+ */
+class CAccountingEntry
+{
+public:
+ std::string strAccount;
+ CAmount nCreditDebit;
+ int64_t nTime;
+ std::string strOtherAccount;
+ std::string strComment;
+ mapValue_t mapValue;
+ int64_t nOrderPos; //! position in ordered transaction list
+ uint64_t nEntryNo;
+
+ CAccountingEntry()
+ {
+ SetNull();
+ }
+
+ void SetNull()
+ {
+ nCreditDebit = 0;
+ nTime = 0;
+ strAccount.clear();
+ strOtherAccount.clear();
+ strComment.clear();
+ nOrderPos = -1;
+ nEntryNo = 0;
+ }
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ if (!(nType & SER_GETHASH))
+ READWRITE(nVersion);
+ //! Note: strAccount is serialized as part of the key, not here.
+ READWRITE(nCreditDebit);
+ READWRITE(nTime);
+ READWRITE(LIMITED_STRING(strOtherAccount, 65536));
+
+ if (!ser_action.ForRead())
+ {
+ WriteOrderPos(nOrderPos, mapValue);
+
+ if (!(mapValue.empty() && _ssExtra.empty()))
+ {
+ CDataStream ss(nType, nVersion);
+ ss.insert(ss.begin(), '\0');
+ ss << mapValue;
+ ss.insert(ss.end(), _ssExtra.begin(), _ssExtra.end());
+ strComment.append(ss.str());
+ }
+ }
+
+ READWRITE(LIMITED_STRING(strComment, 65536));
+
+ size_t nSepPos = strComment.find("\0", 0, 1);
+ if (ser_action.ForRead())
+ {
+ mapValue.clear();
+ if (std::string::npos != nSepPos)
+ {
+ CDataStream ss(std::vector<char>(strComment.begin() + nSepPos + 1, strComment.end()), nType, nVersion);
+ ss >> mapValue;
+ _ssExtra = std::vector<char>(ss.begin(), ss.end());
+ }
+ ReadOrderPos(nOrderPos, mapValue);
+ }
+ if (std::string::npos != nSepPos)
+ strComment.erase(nSepPos);
+
+ mapValue.erase("n");
+ }
+
+private:
+ std::vector<char> _ssExtra;
+};
+
+#endif // BITCOIN_WALLET_WALLET_H
diff --git a/src/wallet/wallet_ismine.cpp b/src/wallet/wallet_ismine.cpp
new file mode 100644
index 0000000000..5482348e35
--- /dev/null
+++ b/src/wallet/wallet_ismine.cpp
@@ -0,0 +1,91 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "wallet_ismine.h"
+
+#include "key.h"
+#include "keystore.h"
+#include "script/script.h"
+#include "script/standard.h"
+
+#include <boost/foreach.hpp>
+
+using namespace std;
+
+typedef vector<unsigned char> valtype;
+
+unsigned int HaveKeys(const vector<valtype>& 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;
+}
+
+isminetype IsMine(const CKeyStore &keystore, const CTxDestination& dest)
+{
+ CScript script = GetScriptForDestination(dest);
+ return IsMine(keystore, script);
+}
+
+isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey)
+{
+ vector<valtype> vSolutions;
+ txnouttype whichType;
+ if (!Solver(scriptPubKey, whichType, vSolutions)) {
+ if (keystore.HaveWatchOnly(scriptPubKey))
+ return ISMINE_WATCH_ONLY;
+ return ISMINE_NO;
+ }
+
+ CKeyID keyID;
+ switch (whichType)
+ {
+ case TX_NONSTANDARD:
+ case TX_NULL_DATA:
+ break;
+ case TX_PUBKEY:
+ keyID = CPubKey(vSolutions[0]).GetID();
+ if (keystore.HaveKey(keyID))
+ return ISMINE_SPENDABLE;
+ break;
+ case TX_PUBKEYHASH:
+ keyID = CKeyID(uint160(vSolutions[0]));
+ if (keystore.HaveKey(keyID))
+ return ISMINE_SPENDABLE;
+ break;
+ case TX_SCRIPTHASH:
+ {
+ CScriptID scriptID = CScriptID(uint160(vSolutions[0]));
+ CScript subscript;
+ if (keystore.GetCScript(scriptID, subscript)) {
+ isminetype ret = IsMine(keystore, subscript);
+ if (ret == ISMINE_SPENDABLE)
+ return ret;
+ }
+ break;
+ }
+ 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<valtype> keys(vSolutions.begin()+1, vSolutions.begin()+vSolutions.size()-1);
+ if (HaveKeys(keys, keystore) == keys.size())
+ return ISMINE_SPENDABLE;
+ break;
+ }
+ }
+
+ if (keystore.HaveWatchOnly(scriptPubKey))
+ return ISMINE_WATCH_ONLY;
+ return ISMINE_NO;
+}
diff --git a/src/wallet/wallet_ismine.h b/src/wallet/wallet_ismine.h
new file mode 100644
index 0000000000..5b9b0e0841
--- /dev/null
+++ b/src/wallet/wallet_ismine.h
@@ -0,0 +1,29 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_WALLET_WALLET_ISMINE_H
+#define BITCOIN_WALLET_WALLET_ISMINE_H
+
+#include "key.h"
+#include "script/standard.h"
+
+class CKeyStore;
+class CScript;
+
+/** IsMine() return codes */
+enum isminetype
+{
+ ISMINE_NO = 0,
+ ISMINE_WATCH_ONLY = 1,
+ ISMINE_SPENDABLE = 2,
+ ISMINE_ALL = ISMINE_WATCH_ONLY | ISMINE_SPENDABLE
+};
+/** used for bitflags of isminetype */
+typedef uint8_t isminefilter;
+
+isminetype IsMine(const CKeyStore& keystore, const CScript& scriptPubKey);
+isminetype IsMine(const CKeyStore& keystore, const CTxDestination& dest);
+
+#endif // BITCOIN_WALLET_WALLET_ISMINE_H
diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp
new file mode 100644
index 0000000000..f777926e72
--- /dev/null
+++ b/src/wallet/walletdb.cpp
@@ -0,0 +1,987 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "wallet/walletdb.h"
+
+#include "base58.h"
+#include "consensus/validation.h"
+#include "main.h"
+#include "protocol.h"
+#include "serialize.h"
+#include "sync.h"
+#include "util.h"
+#include "utiltime.h"
+#include "wallet/wallet.h"
+
+#include <boost/filesystem.hpp>
+#include <boost/foreach.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <boost/thread.hpp>
+
+using namespace std;
+
+static uint64_t 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::WritePurpose(const string& strAddress, const string& strPurpose)
+{
+ nWalletDBUpdated++;
+ return Write(make_pair(string("purpose"), strAddress), strPurpose);
+}
+
+bool CWalletDB::ErasePurpose(const string& strPurpose)
+{
+ nWalletDBUpdated++;
+ return Erase(make_pair(string("purpose"), strPurpose));
+}
+
+bool CWalletDB::WriteTx(uint256 hash, const CWalletTx& wtx)
+{
+ nWalletDBUpdated++;
+ return Write(std::make_pair(std::string("tx"), hash), wtx);
+}
+
+bool CWalletDB::EraseTx(uint256 hash)
+{
+ nWalletDBUpdated++;
+ return Erase(std::make_pair(std::string("tx"), hash));
+}
+
+bool CWalletDB::WriteKey(const CPubKey& vchPubKey, const CPrivKey& vchPrivKey, const CKeyMetadata& keyMeta)
+{
+ nWalletDBUpdated++;
+
+ if (!Write(std::make_pair(std::string("keymeta"), vchPubKey),
+ keyMeta, false))
+ return false;
+
+ // hash pubkey/privkey to accelerate wallet load
+ std::vector<unsigned char> vchKey;
+ vchKey.reserve(vchPubKey.size() + vchPrivKey.size());
+ vchKey.insert(vchKey.end(), vchPubKey.begin(), vchPubKey.end());
+ vchKey.insert(vchKey.end(), vchPrivKey.begin(), vchPrivKey.end());
+
+ return Write(std::make_pair(std::string("key"), vchPubKey), std::make_pair(vchPrivKey, Hash(vchKey.begin(), vchKey.end())), false);
+}
+
+bool CWalletDB::WriteCryptedKey(const CPubKey& vchPubKey,
+ const std::vector<unsigned char>& vchCryptedSecret,
+ const CKeyMetadata &keyMeta)
+{
+ const bool fEraseUnencryptedKey = true;
+ nWalletDBUpdated++;
+
+ if (!Write(std::make_pair(std::string("keymeta"), vchPubKey),
+ keyMeta))
+ return false;
+
+ if (!Write(std::make_pair(std::string("ckey"), vchPubKey), vchCryptedSecret, false))
+ return false;
+ if (fEraseUnencryptedKey)
+ {
+ Erase(std::make_pair(std::string("key"), vchPubKey));
+ Erase(std::make_pair(std::string("wkey"), vchPubKey));
+ }
+ return true;
+}
+
+bool CWalletDB::WriteMasterKey(unsigned int nID, const CMasterKey& kMasterKey)
+{
+ nWalletDBUpdated++;
+ return Write(std::make_pair(std::string("mkey"), nID), kMasterKey, true);
+}
+
+bool CWalletDB::WriteCScript(const uint160& hash, const CScript& redeemScript)
+{
+ nWalletDBUpdated++;
+ return Write(std::make_pair(std::string("cscript"), hash), redeemScript, false);
+}
+
+bool CWalletDB::WriteWatchOnly(const CScript &dest)
+{
+ nWalletDBUpdated++;
+ return Write(std::make_pair(std::string("watchs"), dest), '1');
+}
+
+bool CWalletDB::EraseWatchOnly(const CScript &dest)
+{
+ nWalletDBUpdated++;
+ return Erase(std::make_pair(std::string("watchs"), dest));
+}
+
+bool CWalletDB::WriteBestBlock(const CBlockLocator& locator)
+{
+ nWalletDBUpdated++;
+ return Write(std::string("bestblock"), locator);
+}
+
+bool CWalletDB::ReadBestBlock(CBlockLocator& locator)
+{
+ return Read(std::string("bestblock"), locator);
+}
+
+bool CWalletDB::WriteOrderPosNext(int64_t nOrderPosNext)
+{
+ nWalletDBUpdated++;
+ return Write(std::string("orderposnext"), nOrderPosNext);
+}
+
+bool CWalletDB::WriteDefaultKey(const CPubKey& vchPubKey)
+{
+ nWalletDBUpdated++;
+ return Write(std::string("defaultkey"), vchPubKey);
+}
+
+bool CWalletDB::ReadPool(int64_t nPool, CKeyPool& keypool)
+{
+ return Read(std::make_pair(std::string("pool"), nPool), keypool);
+}
+
+bool CWalletDB::WritePool(int64_t nPool, const CKeyPool& keypool)
+{
+ nWalletDBUpdated++;
+ return Write(std::make_pair(std::string("pool"), nPool), keypool);
+}
+
+bool CWalletDB::ErasePool(int64_t nPool)
+{
+ nWalletDBUpdated++;
+ return Erase(std::make_pair(std::string("pool"), nPool));
+}
+
+bool CWalletDB::WriteMinVersion(int nVersion)
+{
+ return Write(std::string("minversion"), nVersion);
+}
+
+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 uint64_t nAccEntryNum, const CAccountingEntry& acentry)
+{
+ return Write(std::make_pair(std::string("acentry"), std::make_pair(acentry.strAccount, nAccEntryNum)), acentry);
+}
+
+bool CWalletDB::WriteAccountingEntry(const CAccountingEntry& acentry)
+{
+ return WriteAccountingEntry(++nAccountingEntryNumber, acentry);
+}
+
+CAmount CWalletDB::GetAccountCreditDebit(const string& strAccount)
+{
+ list<CAccountingEntry> entries;
+ ListAccountCreditDebit(strAccount, entries);
+
+ CAmount nCreditDebit = 0;
+ BOOST_FOREACH (const CAccountingEntry& entry, entries)
+ nCreditDebit += entry.nCreditDebit;
+
+ return nCreditDebit;
+}
+
+void CWalletDB::ListAccountCreditDebit(const string& strAccount, list<CAccountingEntry>& entries)
+{
+ bool fAllAccounts = (strAccount == "*");
+
+ Dbc* pcursor = GetCursor();
+ if (!pcursor)
+ throw runtime_error("CWalletDB::ListAccountCreditDebit(): cannot create DB cursor");
+ unsigned int fFlags = DB_SET_RANGE;
+ while (true)
+ {
+ // Read next record
+ CDataStream ssKey(SER_DISK, CLIENT_VERSION);
+ if (fFlags == DB_SET_RANGE)
+ ssKey << std::make_pair(std::string("acentry"), std::make_pair((fAllAccounts ? string("") : strAccount), uint64_t(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;
+ ssKey >> acentry.nEntryNo;
+ entries.push_back(acentry);
+ }
+
+ pcursor->close();
+}
+
+DBErrors CWalletDB::ReorderTransactions(CWallet* pwallet)
+{
+ LOCK(pwallet->cs_wallet);
+ // Old wallets didn't have any defined order for transactions
+ // Probably a bad idea to change the output of this
+
+ // First: get all CWalletTx and CAccountingEntry into a sorted-by-time multimap.
+ typedef pair<CWalletTx*, CAccountingEntry*> TxPair;
+ typedef multimap<int64_t, TxPair > TxItems;
+ TxItems txByTime;
+
+ for (map<uint256, CWalletTx>::iterator it = pwallet->mapWallet.begin(); it != pwallet->mapWallet.end(); ++it)
+ {
+ CWalletTx* wtx = &((*it).second);
+ txByTime.insert(make_pair(wtx->nTimeReceived, TxPair(wtx, (CAccountingEntry*)0)));
+ }
+ list<CAccountingEntry> acentries;
+ ListAccountCreditDebit("", acentries);
+ BOOST_FOREACH(CAccountingEntry& entry, acentries)
+ {
+ txByTime.insert(make_pair(entry.nTime, TxPair((CWalletTx*)0, &entry)));
+ }
+
+ int64_t& nOrderPosNext = pwallet->nOrderPosNext;
+ nOrderPosNext = 0;
+ std::vector<int64_t> nOrderPosOffsets;
+ for (TxItems::iterator it = txByTime.begin(); it != txByTime.end(); ++it)
+ {
+ CWalletTx *const pwtx = (*it).second.first;
+ CAccountingEntry *const pacentry = (*it).second.second;
+ int64_t& nOrderPos = (pwtx != 0) ? pwtx->nOrderPos : pacentry->nOrderPos;
+
+ if (nOrderPos == -1)
+ {
+ nOrderPos = nOrderPosNext++;
+ nOrderPosOffsets.push_back(nOrderPos);
+
+ if (pwtx)
+ {
+ if (!WriteTx(pwtx->GetHash(), *pwtx))
+ return DB_LOAD_FAIL;
+ }
+ else
+ if (!WriteAccountingEntry(pacentry->nEntryNo, *pacentry))
+ return DB_LOAD_FAIL;
+ }
+ else
+ {
+ int64_t nOrderPosOff = 0;
+ BOOST_FOREACH(const int64_t& nOffsetStart, nOrderPosOffsets)
+ {
+ if (nOrderPos >= nOffsetStart)
+ ++nOrderPosOff;
+ }
+ nOrderPos += nOrderPosOff;
+ nOrderPosNext = std::max(nOrderPosNext, nOrderPos + 1);
+
+ if (!nOrderPosOff)
+ continue;
+
+ // Since we're changing the order, write it back
+ if (pwtx)
+ {
+ if (!WriteTx(pwtx->GetHash(), *pwtx))
+ return DB_LOAD_FAIL;
+ }
+ else
+ if (!WriteAccountingEntry(pacentry->nEntryNo, *pacentry))
+ return DB_LOAD_FAIL;
+ }
+ }
+ WriteOrderPosNext(nOrderPosNext);
+
+ return DB_LOAD_OK;
+}
+
+class CWalletScanState {
+public:
+ unsigned int nKeys;
+ unsigned int nCKeys;
+ unsigned int nKeyMeta;
+ bool fIsEncrypted;
+ bool fAnyUnordered;
+ int nFileVersion;
+ vector<uint256> vWalletUpgrade;
+
+ CWalletScanState() {
+ nKeys = nCKeys = nKeyMeta = 0;
+ fIsEncrypted = false;
+ fAnyUnordered = false;
+ nFileVersion = 0;
+ }
+};
+
+bool
+ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
+ CWalletScanState &wss, string& strType, string& strErr)
+{
+ try {
+ // Unserialize
+ // Taking advantage of the fact that pair serialization
+ // is just the two items serialized one after the other
+ ssKey >> strType;
+ if (strType == "name")
+ {
+ string strAddress;
+ ssKey >> strAddress;
+ ssValue >> pwallet->mapAddressBook[CBitcoinAddress(strAddress).Get()].name;
+ }
+ else if (strType == "purpose")
+ {
+ string strAddress;
+ ssKey >> strAddress;
+ ssValue >> pwallet->mapAddressBook[CBitcoinAddress(strAddress).Get()].purpose;
+ }
+ else if (strType == "tx")
+ {
+ uint256 hash;
+ ssKey >> hash;
+ CWalletTx wtx;
+ ssValue >> wtx;
+ CValidationState state;
+ if (!(CheckTransaction(wtx, state) && (wtx.GetHash() == hash) && state.IsValid()))
+ return false;
+
+ // Undo serialize changes in 31600
+ if (31404 <= wtx.fTimeReceivedIsTxTime && wtx.fTimeReceivedIsTxTime <= 31703)
+ {
+ if (!ssValue.empty())
+ {
+ char fTmp;
+ char fUnused;
+ ssValue >> fTmp >> fUnused >> wtx.strFromAccount;
+ strErr = strprintf("LoadWallet() upgrading tx ver=%d %d '%s' %s",
+ wtx.fTimeReceivedIsTxTime, fTmp, wtx.strFromAccount, hash.ToString());
+ wtx.fTimeReceivedIsTxTime = fTmp;
+ }
+ else
+ {
+ strErr = strprintf("LoadWallet() repairing tx ver=%d %s", wtx.fTimeReceivedIsTxTime, hash.ToString());
+ wtx.fTimeReceivedIsTxTime = 0;
+ }
+ wss.vWalletUpgrade.push_back(hash);
+ }
+
+ if (wtx.nOrderPos == -1)
+ wss.fAnyUnordered = true;
+
+ pwallet->AddToWallet(wtx, true, NULL);
+ }
+ else if (strType == "acentry")
+ {
+ string strAccount;
+ ssKey >> strAccount;
+ uint64_t nNumber;
+ ssKey >> nNumber;
+ if (nNumber > nAccountingEntryNumber)
+ nAccountingEntryNumber = nNumber;
+
+ if (!wss.fAnyUnordered)
+ {
+ CAccountingEntry acentry;
+ ssValue >> acentry;
+ if (acentry.nOrderPos == -1)
+ wss.fAnyUnordered = true;
+ }
+ }
+ else if (strType == "watchs")
+ {
+ CScript script;
+ ssKey >> script;
+ char fYes;
+ ssValue >> fYes;
+ if (fYes == '1')
+ pwallet->LoadWatchOnly(script);
+
+ // Watch-only addresses have no birthday information for now,
+ // so set the wallet birthday to the beginning of time.
+ pwallet->nTimeFirstKey = 1;
+ }
+ else if (strType == "key" || strType == "wkey")
+ {
+ CPubKey vchPubKey;
+ ssKey >> vchPubKey;
+ if (!vchPubKey.IsValid())
+ {
+ strErr = "Error reading wallet database: CPubKey corrupt";
+ return false;
+ }
+ CKey key;
+ CPrivKey pkey;
+ uint256 hash;
+
+ if (strType == "key")
+ {
+ wss.nKeys++;
+ ssValue >> pkey;
+ } else {
+ CWalletKey wkey;
+ ssValue >> wkey;
+ pkey = wkey.vchPrivKey;
+ }
+
+ // Old wallets store keys as "key" [pubkey] => [privkey]
+ // ... which was slow for wallets with lots of keys, because the public key is re-derived from the private key
+ // using EC operations as a checksum.
+ // Newer wallets store keys as "key"[pubkey] => [privkey][hash(pubkey,privkey)], which is much faster while
+ // remaining backwards-compatible.
+ try
+ {
+ ssValue >> hash;
+ }
+ catch (...) {}
+
+ bool fSkipCheck = false;
+
+ if (!hash.IsNull())
+ {
+ // hash pubkey/privkey to accelerate wallet load
+ std::vector<unsigned char> vchKey;
+ vchKey.reserve(vchPubKey.size() + pkey.size());
+ vchKey.insert(vchKey.end(), vchPubKey.begin(), vchPubKey.end());
+ vchKey.insert(vchKey.end(), pkey.begin(), pkey.end());
+
+ if (Hash(vchKey.begin(), vchKey.end()) != hash)
+ {
+ strErr = "Error reading wallet database: CPubKey/CPrivKey corrupt";
+ return false;
+ }
+
+ fSkipCheck = true;
+ }
+
+ if (!key.Load(pkey, vchPubKey, fSkipCheck))
+ {
+ strErr = "Error reading wallet database: CPrivKey corrupt";
+ return false;
+ }
+ if (!pwallet->LoadKey(key, vchPubKey))
+ {
+ strErr = "Error reading wallet database: LoadKey failed";
+ return false;
+ }
+ }
+ else if (strType == "mkey")
+ {
+ unsigned int nID;
+ ssKey >> nID;
+ CMasterKey kMasterKey;
+ ssValue >> kMasterKey;
+ if(pwallet->mapMasterKeys.count(nID) != 0)
+ {
+ strErr = strprintf("Error reading wallet database: duplicate CMasterKey id %u", nID);
+ return false;
+ }
+ pwallet->mapMasterKeys[nID] = kMasterKey;
+ if (pwallet->nMasterKeyMaxID < nID)
+ pwallet->nMasterKeyMaxID = nID;
+ }
+ else if (strType == "ckey")
+ {
+ vector<unsigned char> vchPubKey;
+ ssKey >> vchPubKey;
+ vector<unsigned char> vchPrivKey;
+ ssValue >> vchPrivKey;
+ wss.nCKeys++;
+
+ if (!pwallet->LoadCryptedKey(vchPubKey, vchPrivKey))
+ {
+ strErr = "Error reading wallet database: LoadCryptedKey failed";
+ return false;
+ }
+ wss.fIsEncrypted = true;
+ }
+ else if (strType == "keymeta")
+ {
+ CPubKey vchPubKey;
+ ssKey >> vchPubKey;
+ CKeyMetadata keyMeta;
+ ssValue >> keyMeta;
+ wss.nKeyMeta++;
+
+ pwallet->LoadKeyMetadata(vchPubKey, keyMeta);
+
+ // find earliest key creation time, as wallet birthday
+ if (!pwallet->nTimeFirstKey ||
+ (keyMeta.nCreateTime < pwallet->nTimeFirstKey))
+ pwallet->nTimeFirstKey = keyMeta.nCreateTime;
+ }
+ else if (strType == "defaultkey")
+ {
+ ssValue >> pwallet->vchDefaultKey;
+ }
+ else if (strType == "pool")
+ {
+ int64_t nIndex;
+ ssKey >> nIndex;
+ CKeyPool keypool;
+ ssValue >> keypool;
+ pwallet->setKeyPool.insert(nIndex);
+
+ // If no metadata exists yet, create a default with the pool key's
+ // creation time. Note that this may be overwritten by actually
+ // stored metadata for that key later, which is fine.
+ CKeyID keyid = keypool.vchPubKey.GetID();
+ if (pwallet->mapKeyMetadata.count(keyid) == 0)
+ pwallet->mapKeyMetadata[keyid] = CKeyMetadata(keypool.nTime);
+ }
+ else if (strType == "version")
+ {
+ ssValue >> wss.nFileVersion;
+ if (wss.nFileVersion == 10300)
+ wss.nFileVersion = 300;
+ }
+ else if (strType == "cscript")
+ {
+ uint160 hash;
+ ssKey >> hash;
+ CScript script;
+ ssValue >> script;
+ if (!pwallet->LoadCScript(script))
+ {
+ strErr = "Error reading wallet database: LoadCScript failed";
+ return false;
+ }
+ }
+ else if (strType == "orderposnext")
+ {
+ ssValue >> pwallet->nOrderPosNext;
+ }
+ else if (strType == "destdata")
+ {
+ std::string strAddress, strKey, strValue;
+ ssKey >> strAddress;
+ ssKey >> strKey;
+ ssValue >> strValue;
+ if (!pwallet->LoadDestData(CBitcoinAddress(strAddress).Get(), strKey, strValue))
+ {
+ strErr = "Error reading wallet database: LoadDestData failed";
+ return false;
+ }
+ }
+ } catch (...)
+ {
+ return false;
+ }
+ return true;
+}
+
+static bool IsKeyType(string strType)
+{
+ return (strType== "key" || strType == "wkey" ||
+ strType == "mkey" || strType == "ckey");
+}
+
+DBErrors CWalletDB::LoadWallet(CWallet* pwallet)
+{
+ pwallet->vchDefaultKey = CPubKey();
+ CWalletScanState wss;
+ bool fNoncriticalErrors = false;
+ DBErrors result = DB_LOAD_OK;
+
+ try {
+ 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)
+ {
+ LogPrintf("Error getting wallet database cursor\n");
+ return DB_CORRUPT;
+ }
+
+ while (true)
+ {
+ // 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)
+ {
+ LogPrintf("Error reading next record from wallet database\n");
+ return DB_CORRUPT;
+ }
+
+ // Try to be tolerant of single corrupt records:
+ string strType, strErr;
+ if (!ReadKeyValue(pwallet, ssKey, ssValue, wss, strType, strErr))
+ {
+ // losing keys is considered a catastrophic error, anything else
+ // we assume the user can live with:
+ if (IsKeyType(strType))
+ result = DB_CORRUPT;
+ else
+ {
+ // Leave other errors alone, if we try to fix them we might make things worse.
+ fNoncriticalErrors = true; // ... but do warn the user there is something wrong.
+ if (strType == "tx")
+ // Rescan if there is a bad transaction record:
+ SoftSetBoolArg("-rescan", true);
+ }
+ }
+ if (!strErr.empty())
+ LogPrintf("%s\n", strErr);
+ }
+ pcursor->close();
+ }
+ catch (const boost::thread_interrupted&) {
+ throw;
+ }
+ catch (...) {
+ result = DB_CORRUPT;
+ }
+
+ if (fNoncriticalErrors && result == DB_LOAD_OK)
+ result = DB_NONCRITICAL_ERROR;
+
+ // Any wallet corruption at all: skip any rewriting or
+ // upgrading, we don't want to make it worse.
+ if (result != DB_LOAD_OK)
+ return result;
+
+ LogPrintf("nFileVersion = %d\n", wss.nFileVersion);
+
+ LogPrintf("Keys: %u plaintext, %u encrypted, %u w/ metadata, %u total\n",
+ wss.nKeys, wss.nCKeys, wss.nKeyMeta, wss.nKeys + wss.nCKeys);
+
+ // nTimeFirstKey is only reliable if all keys have metadata
+ if ((wss.nKeys + wss.nCKeys) != wss.nKeyMeta)
+ pwallet->nTimeFirstKey = 1; // 0 would be considered 'no value'
+
+ BOOST_FOREACH(uint256 hash, wss.vWalletUpgrade)
+ WriteTx(hash, pwallet->mapWallet[hash]);
+
+ // Rewrite encrypted wallets of versions 0.4.0 and 0.5.0rc:
+ if (wss.fIsEncrypted && (wss.nFileVersion == 40000 || wss.nFileVersion == 50000))
+ return DB_NEED_REWRITE;
+
+ if (wss.nFileVersion < CLIENT_VERSION) // Update
+ WriteVersion(CLIENT_VERSION);
+
+ if (wss.fAnyUnordered)
+ result = ReorderTransactions(pwallet);
+
+ return result;
+}
+
+DBErrors CWalletDB::FindWalletTx(CWallet* pwallet, vector<uint256>& vTxHash, vector<CWalletTx>& vWtx)
+{
+ pwallet->vchDefaultKey = CPubKey();
+ bool fNoncriticalErrors = false;
+ DBErrors result = DB_LOAD_OK;
+
+ try {
+ 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)
+ {
+ LogPrintf("Error getting wallet database cursor\n");
+ return DB_CORRUPT;
+ }
+
+ while (true)
+ {
+ // 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)
+ {
+ LogPrintf("Error reading next record from wallet database\n");
+ return DB_CORRUPT;
+ }
+
+ string strType;
+ ssKey >> strType;
+ if (strType == "tx") {
+ uint256 hash;
+ ssKey >> hash;
+
+ CWalletTx wtx;
+ ssValue >> wtx;
+
+ vTxHash.push_back(hash);
+ vWtx.push_back(wtx);
+ }
+ }
+ pcursor->close();
+ }
+ catch (const boost::thread_interrupted&) {
+ throw;
+ }
+ catch (...) {
+ result = DB_CORRUPT;
+ }
+
+ if (fNoncriticalErrors && result == DB_LOAD_OK)
+ result = DB_NONCRITICAL_ERROR;
+
+ return result;
+}
+
+DBErrors CWalletDB::ZapWalletTx(CWallet* pwallet, vector<CWalletTx>& vWtx)
+{
+ // build list of wallet TXs
+ vector<uint256> vTxHash;
+ DBErrors err = FindWalletTx(pwallet, vTxHash, vWtx);
+ if (err != DB_LOAD_OK)
+ return err;
+
+ // erase each wallet TX
+ BOOST_FOREACH (uint256& hash, vTxHash) {
+ if (!EraseTx(hash))
+ return DB_CORRUPT;
+ }
+
+ return DB_LOAD_OK;
+}
+
+void ThreadFlushWalletDB(const string& strFile)
+{
+ // Make this thread recognisable as the wallet flushing thread
+ RenameThread("bitcoin-wallet");
+
+ static bool fOneThread;
+ if (fOneThread)
+ return;
+ fOneThread = true;
+ if (!GetBoolArg("-flushwallet", true))
+ return;
+
+ unsigned int nLastSeen = nWalletDBUpdated;
+ unsigned int nLastFlushed = nWalletDBUpdated;
+ int64_t nLastWalletUpdate = GetTime();
+ while (true)
+ {
+ MilliSleep(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<string, int>::iterator mi = bitdb.mapFileUseCount.begin();
+ while (mi != bitdb.mapFileUseCount.end())
+ {
+ nRefCount += (*mi).second;
+ mi++;
+ }
+
+ if (nRefCount == 0)
+ {
+ boost::this_thread::interruption_point();
+ map<string, int>::iterator mi = bitdb.mapFileUseCount.find(strFile);
+ if (mi != bitdb.mapFileUseCount.end())
+ {
+ LogPrint("db", "Flushing wallet.dat\n");
+ nLastFlushed = nWalletDBUpdated;
+ int64_t nStart = GetTimeMillis();
+
+ // Flush wallet.dat so it's self contained
+ bitdb.CloseDb(strFile);
+ bitdb.CheckpointLSN(strFile);
+
+ bitdb.mapFileUseCount.erase(mi++);
+ LogPrint("db", "Flushed wallet.dat %dms\n", GetTimeMillis() - nStart);
+ }
+ }
+ }
+ }
+ }
+}
+
+bool BackupWallet(const CWallet& wallet, const string& strDest)
+{
+ if (!wallet.fFileBacked)
+ return false;
+ while (true)
+ {
+ {
+ 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
+ boost::filesystem::path pathSrc = GetDataDir() / wallet.strWalletFile;
+ boost::filesystem::path pathDest(strDest);
+ if (boost::filesystem::is_directory(pathDest))
+ pathDest /= wallet.strWalletFile;
+
+ try {
+#if BOOST_VERSION >= 104000
+ boost::filesystem::copy_file(pathSrc, pathDest, boost::filesystem::copy_option::overwrite_if_exists);
+#else
+ boost::filesystem::copy_file(pathSrc, pathDest);
+#endif
+ LogPrintf("copied wallet.dat to %s\n", pathDest.string());
+ return true;
+ } catch (const boost::filesystem::filesystem_error& e) {
+ LogPrintf("error copying wallet.dat to %s - %s\n", pathDest.string(), e.what());
+ return false;
+ }
+ }
+ }
+ MilliSleep(100);
+ }
+ return false;
+}
+
+//
+// Try to (very carefully!) recover wallet.dat if there is a problem.
+//
+bool CWalletDB::Recover(CDBEnv& dbenv, const std::string& filename, bool fOnlyKeys)
+{
+ // Recovery procedure:
+ // move wallet.dat to wallet.timestamp.bak
+ // Call Salvage with fAggressive=true to
+ // get as much data as possible.
+ // Rewrite salvaged data to wallet.dat
+ // Set -rescan so any missing transactions will be
+ // found.
+ int64_t now = GetTime();
+ std::string newFilename = strprintf("wallet.%d.bak", now);
+
+ int result = dbenv.dbenv->dbrename(NULL, filename.c_str(), NULL,
+ newFilename.c_str(), DB_AUTO_COMMIT);
+ if (result == 0)
+ LogPrintf("Renamed %s to %s\n", filename, newFilename);
+ else
+ {
+ LogPrintf("Failed to rename %s to %s\n", filename, newFilename);
+ return false;
+ }
+
+ std::vector<CDBEnv::KeyValPair> salvagedData;
+ bool fSuccess = dbenv.Salvage(newFilename, true, salvagedData);
+ if (salvagedData.empty())
+ {
+ LogPrintf("Salvage(aggressive) found no records in %s.\n", newFilename);
+ return false;
+ }
+ LogPrintf("Salvage(aggressive) found %u records\n", salvagedData.size());
+
+ boost::scoped_ptr<Db> pdbCopy(new Db(dbenv.dbenv, 0));
+ int ret = pdbCopy->open(NULL, // Txn pointer
+ filename.c_str(), // Filename
+ "main", // Logical db name
+ DB_BTREE, // Database type
+ DB_CREATE, // Flags
+ 0);
+ if (ret > 0)
+ {
+ LogPrintf("Cannot create database file %s\n", filename);
+ return false;
+ }
+ CWallet dummyWallet;
+ CWalletScanState wss;
+
+ DbTxn* ptxn = dbenv.TxnBegin();
+ BOOST_FOREACH(CDBEnv::KeyValPair& row, salvagedData)
+ {
+ if (fOnlyKeys)
+ {
+ CDataStream ssKey(row.first, SER_DISK, CLIENT_VERSION);
+ CDataStream ssValue(row.second, SER_DISK, CLIENT_VERSION);
+ string strType, strErr;
+ bool fReadOK = ReadKeyValue(&dummyWallet, ssKey, ssValue,
+ wss, strType, strErr);
+ if (!IsKeyType(strType))
+ continue;
+ if (!fReadOK)
+ {
+ LogPrintf("WARNING: CWalletDB::Recover skipping %s: %s\n", strType, strErr);
+ continue;
+ }
+ }
+ Dbt datKey(&row.first[0], row.first.size());
+ Dbt datValue(&row.second[0], row.second.size());
+ int ret2 = pdbCopy->put(ptxn, &datKey, &datValue, DB_NOOVERWRITE);
+ if (ret2 > 0)
+ fSuccess = false;
+ }
+ ptxn->commit(0);
+ pdbCopy->close(0);
+
+ return fSuccess;
+}
+
+bool CWalletDB::Recover(CDBEnv& dbenv, const std::string& filename)
+{
+ return CWalletDB::Recover(dbenv, filename, false);
+}
+
+bool CWalletDB::WriteDestData(const std::string &address, const std::string &key, const std::string &value)
+{
+ nWalletDBUpdated++;
+ return Write(std::make_pair(std::string("destdata"), std::make_pair(address, key)), value);
+}
+
+bool CWalletDB::EraseDestData(const std::string &address, const std::string &key)
+{
+ nWalletDBUpdated++;
+ return Erase(std::make_pair(std::string("destdata"), std::make_pair(address, key)));
+}
diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h
new file mode 100644
index 0000000000..bc1a104b5b
--- /dev/null
+++ b/src/wallet/walletdb.h
@@ -0,0 +1,143 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_WALLET_WALLETDB_H
+#define BITCOIN_WALLET_WALLETDB_H
+
+#include "amount.h"
+#include "wallet/db.h"
+#include "key.h"
+#include "keystore.h"
+
+#include <list>
+#include <stdint.h>
+#include <string>
+#include <utility>
+#include <vector>
+
+class CAccount;
+class CAccountingEntry;
+struct CBlockLocator;
+class CKeyPool;
+class CMasterKey;
+class CScript;
+class CWallet;
+class CWalletTx;
+class uint160;
+class uint256;
+
+/** Error statuses for the wallet database */
+enum DBErrors
+{
+ DB_LOAD_OK,
+ DB_CORRUPT,
+ DB_NONCRITICAL_ERROR,
+ DB_TOO_NEW,
+ DB_LOAD_FAIL,
+ DB_NEED_REWRITE
+};
+
+class CKeyMetadata
+{
+public:
+ static const int CURRENT_VERSION=1;
+ int nVersion;
+ int64_t nCreateTime; // 0 means unknown
+
+ CKeyMetadata()
+ {
+ SetNull();
+ }
+ CKeyMetadata(int64_t nCreateTime_)
+ {
+ nVersion = CKeyMetadata::CURRENT_VERSION;
+ nCreateTime = nCreateTime_;
+ }
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ READWRITE(this->nVersion);
+ nVersion = this->nVersion;
+ READWRITE(nCreateTime);
+ }
+
+ void SetNull()
+ {
+ nVersion = CKeyMetadata::CURRENT_VERSION;
+ nCreateTime = 0;
+ }
+};
+
+/** Access to the wallet database (wallet.dat) */
+class CWalletDB : public CDB
+{
+public:
+ CWalletDB(const std::string& strFilename, const char* pszMode = "r+", bool fFlushOnClose = true) : CDB(strFilename, pszMode, fFlushOnClose)
+ {
+ }
+
+ bool WriteName(const std::string& strAddress, const std::string& strName);
+ bool EraseName(const std::string& strAddress);
+
+ bool WritePurpose(const std::string& strAddress, const std::string& purpose);
+ bool ErasePurpose(const std::string& strAddress);
+
+ bool WriteTx(uint256 hash, const CWalletTx& wtx);
+ bool EraseTx(uint256 hash);
+
+ bool WriteKey(const CPubKey& vchPubKey, const CPrivKey& vchPrivKey, const CKeyMetadata &keyMeta);
+ bool WriteCryptedKey(const CPubKey& vchPubKey, const std::vector<unsigned char>& vchCryptedSecret, const CKeyMetadata &keyMeta);
+ bool WriteMasterKey(unsigned int nID, const CMasterKey& kMasterKey);
+
+ bool WriteCScript(const uint160& hash, const CScript& redeemScript);
+
+ bool WriteWatchOnly(const CScript &script);
+ bool EraseWatchOnly(const CScript &script);
+
+ bool WriteBestBlock(const CBlockLocator& locator);
+ bool ReadBestBlock(CBlockLocator& locator);
+
+ bool WriteOrderPosNext(int64_t nOrderPosNext);
+
+ bool WriteDefaultKey(const CPubKey& vchPubKey);
+
+ bool ReadPool(int64_t nPool, CKeyPool& keypool);
+ bool WritePool(int64_t nPool, const CKeyPool& keypool);
+ bool ErasePool(int64_t nPool);
+
+ bool WriteMinVersion(int nVersion);
+
+ bool ReadAccount(const std::string& strAccount, CAccount& account);
+ bool WriteAccount(const std::string& strAccount, const CAccount& account);
+
+ /// Write destination data key,value tuple to database
+ bool WriteDestData(const std::string &address, const std::string &key, const std::string &value);
+ /// Erase destination data tuple from wallet database
+ bool EraseDestData(const std::string &address, const std::string &key);
+
+ bool WriteAccountingEntry(const CAccountingEntry& acentry);
+ CAmount GetAccountCreditDebit(const std::string& strAccount);
+ void ListAccountCreditDebit(const std::string& strAccount, std::list<CAccountingEntry>& acentries);
+
+ DBErrors ReorderTransactions(CWallet* pwallet);
+ DBErrors LoadWallet(CWallet* pwallet);
+ DBErrors FindWalletTx(CWallet* pwallet, std::vector<uint256>& vTxHash, std::vector<CWalletTx>& vWtx);
+ DBErrors ZapWalletTx(CWallet* pwallet, std::vector<CWalletTx>& vWtx);
+ static bool Recover(CDBEnv& dbenv, const std::string& filename, bool fOnlyKeys);
+ static bool Recover(CDBEnv& dbenv, const std::string& filename);
+
+private:
+ CWalletDB(const CWalletDB&);
+ void operator=(const CWalletDB&);
+
+ bool WriteAccountingEntry(const uint64_t nAccEntryNum, const CAccountingEntry& acentry);
+};
+
+bool BackupWallet(const CWallet& wallet, const std::string& strDest);
+void ThreadFlushWalletDB(const std::string& strFile);
+
+#endif // BITCOIN_WALLET_WALLETDB_H